1 // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3 // 4 // SPDX-License-Identifier: BSD-2-Clause 5 // 6 // This file is part of CEED: http://github.com/ceed 7 8 #include <ceed/ceed.h> 9 #include <ceed/backend.h> 10 #include <string.h> 11 #include <valgrind/memcheck.h> 12 #include "ceed-memcheck.h" 13 14 //------------------------------------------------------------------------------ 15 // QFunctionContext has valid data 16 //------------------------------------------------------------------------------ 17 static int CeedQFunctionContextHasValidData_Memcheck(CeedQFunctionContext ctx, 18 bool *has_valid_data) { 19 int ierr; 20 CeedQFunctionContext_Memcheck *impl; 21 ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl); 22 CeedChkBackend(ierr); 23 24 *has_valid_data = !!impl->data; 25 26 return CEED_ERROR_SUCCESS; 27 } 28 29 //------------------------------------------------------------------------------ 30 // QFunctionContext has borrowed data 31 //------------------------------------------------------------------------------ 32 static int CeedQFunctionContextHasBorrowedDataOfType_Memcheck( 33 CeedQFunctionContext ctx, CeedMemType mem_type, 34 bool *has_borrowed_data_of_type) { 35 int ierr; 36 CeedQFunctionContext_Memcheck *impl; 37 ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl); 38 CeedChkBackend(ierr); 39 Ceed ceed; 40 ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 41 42 switch (mem_type) { 43 case CEED_MEM_HOST: 44 *has_borrowed_data_of_type = !!impl->data_borrowed; 45 break; 46 default: 47 // LCOV_EXCL_START 48 return CeedError(ceed, CEED_ERROR_BACKEND, 49 "Can only set HOST memory for this backend"); 50 // LCOV_EXCL_STOP 51 break; 52 } 53 54 return CEED_ERROR_SUCCESS; 55 } 56 57 //------------------------------------------------------------------------------ 58 // QFunctionContext Set Data 59 //------------------------------------------------------------------------------ 60 static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx, 61 CeedMemType mem_type, CeedCopyMode copy_mode, void *data) { 62 int ierr; 63 CeedQFunctionContext_Memcheck *impl; 64 ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl); 65 CeedChkBackend(ierr); 66 size_t ctx_size; 67 ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr); 68 Ceed ceed; 69 ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 70 71 if (mem_type != CEED_MEM_HOST) 72 // LCOV_EXCL_START 73 return CeedError(ceed, CEED_ERROR_BACKEND, 74 "Can only set HOST memory for this backend"); 75 // LCOV_EXCL_STOP 76 77 ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr); 78 ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr); 79 switch (copy_mode) { 80 case CEED_COPY_VALUES: 81 ierr = CeedMallocArray(1, ctx_size, &impl->data_owned); CeedChkBackend(ierr); 82 impl->data_borrowed = NULL; 83 impl->data = impl->data_owned; 84 memcpy(impl->data, data, ctx_size); 85 break; 86 case CEED_OWN_POINTER: 87 impl->data_owned = data; 88 impl->data_borrowed = NULL; 89 impl->data = data; 90 break; 91 case CEED_USE_POINTER: 92 impl->data_borrowed = data; 93 impl->data = data; 94 } 95 // Copy data to check ctx_size bounds 96 ierr = CeedMallocArray(1, ctx_size, &impl->data_allocated); 97 CeedChkBackend(ierr); 98 memcpy(impl->data_allocated, impl->data, ctx_size); 99 impl->data = impl->data_allocated; 100 VALGRIND_DISCARD(impl->mem_block_id); 101 impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size, 102 "'QFunction backend context data copy'"); 103 104 return CEED_ERROR_SUCCESS; 105 } 106 107 //------------------------------------------------------------------------------ 108 // QFunctionContext Take Data 109 //------------------------------------------------------------------------------ 110 static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, 111 CeedMemType mem_type, void *data) { 112 int ierr; 113 CeedQFunctionContext_Memcheck *impl; 114 ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl); 115 CeedChkBackend(ierr); 116 Ceed ceed; 117 ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 118 119 if (mem_type != CEED_MEM_HOST) 120 // LCOV_EXCL_START 121 return CeedError(ceed, CEED_ERROR_BACKEND, 122 "Can only provide HOST memory for this backend"); 123 // LCOV_EXCL_STOP 124 125 *(void **)data = impl->data_borrowed; 126 impl->data_borrowed = NULL; 127 impl->data = NULL; 128 VALGRIND_DISCARD(impl->mem_block_id); 129 ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr); 130 131 return CEED_ERROR_SUCCESS; 132 } 133 134 //------------------------------------------------------------------------------ 135 // QFunctionContext Get Data 136 //------------------------------------------------------------------------------ 137 static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, 138 CeedMemType mem_type, void *data) { 139 int ierr; 140 CeedQFunctionContext_Memcheck *impl; 141 ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl); 142 CeedChkBackend(ierr); 143 Ceed ceed; 144 ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 145 146 if (mem_type != CEED_MEM_HOST) 147 // LCOV_EXCL_START 148 return CeedError(ceed, CEED_ERROR_BACKEND, 149 "Can only provide HOST memory for this backend"); 150 // LCOV_EXCL_STOP 151 152 *(void **)data = impl->data; 153 154 return CEED_ERROR_SUCCESS; 155 } 156 157 //------------------------------------------------------------------------------ 158 // QFunctionContext Restore Data 159 //------------------------------------------------------------------------------ 160 static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) { 161 int ierr; 162 size_t ctx_size; 163 ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr); 164 CeedQFunctionContext_Memcheck *impl; 165 ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl); 166 CeedChkBackend(ierr); 167 168 if (impl->data_borrowed) { 169 memcpy(impl->data_borrowed, impl->data, ctx_size); 170 } 171 if (impl->data_owned) { 172 memcpy(impl->data_owned, impl->data, ctx_size); 173 } 174 175 return CEED_ERROR_SUCCESS; 176 } 177 178 //------------------------------------------------------------------------------ 179 // QFunctionContext Destroy 180 //------------------------------------------------------------------------------ 181 static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) { 182 int ierr; 183 CeedQFunctionContext_Memcheck *impl; 184 ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 185 186 ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr); 187 ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr); 188 ierr = CeedFree(&impl); CeedChkBackend(ierr); 189 return CEED_ERROR_SUCCESS; 190 } 191 192 //------------------------------------------------------------------------------ 193 // QFunctionContext Create 194 //------------------------------------------------------------------------------ 195 int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) { 196 int ierr; 197 CeedQFunctionContext_Memcheck *impl; 198 Ceed ceed; 199 ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 200 201 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", 202 CeedQFunctionContextHasValidData_Memcheck); 203 CeedChkBackend(ierr); 204 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, 205 "HasBorrowedDataOfType", 206 CeedQFunctionContextHasBorrowedDataOfType_Memcheck); 207 CeedChkBackend(ierr); 208 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", 209 CeedQFunctionContextSetData_Memcheck); CeedChkBackend(ierr); 210 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", 211 CeedQFunctionContextTakeData_Memcheck); CeedChkBackend(ierr); 212 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", 213 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr); 214 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", 215 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr); 216 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", 217 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr); 218 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", 219 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr); 220 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", 221 CeedQFunctionContextDestroy_Memcheck); CeedChkBackend(ierr); 222 223 ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr); 224 ierr = CeedQFunctionContextSetBackendData(ctx, impl); CeedChkBackend(ierr); 225 226 return CEED_ERROR_SUCCESS; 227 } 228 //------------------------------------------------------------------------------ 229