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 user data 180 //------------------------------------------------------------------------------ 181 static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) { 182 int ierr; 183 CeedQFunctionContext_Memcheck *impl; 184 ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 185 CeedQFunctionContextDataDestroyUser data_destroy_function; 186 CeedMemType data_destroy_mem_type; 187 ierr = CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, 188 &data_destroy_function); CeedChk(ierr); 189 Ceed ceed; 190 ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 191 192 if (data_destroy_mem_type != CEED_MEM_HOST) 193 // LCOV_EXCL_START 194 return CeedError(ceed, CEED_ERROR_BACKEND, 195 "Can only destroy HOST memory for this backend"); 196 // LCOV_EXCL_STOP 197 198 if (data_destroy_function) { 199 ierr = data_destroy_function(impl->data_borrowed ? impl->data_borrowed : 200 impl->data_owned); CeedChk(ierr); 201 } 202 ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr); 203 204 return CEED_ERROR_SUCCESS; 205 } 206 207 //------------------------------------------------------------------------------ 208 // QFunctionContext Destroy 209 //------------------------------------------------------------------------------ 210 static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) { 211 int ierr; 212 CeedQFunctionContext_Memcheck *impl; 213 ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 214 215 ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr); 216 ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr); 217 ierr = CeedFree(&impl); CeedChkBackend(ierr); 218 return CEED_ERROR_SUCCESS; 219 } 220 221 //------------------------------------------------------------------------------ 222 // QFunctionContext Create 223 //------------------------------------------------------------------------------ 224 int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) { 225 int ierr; 226 CeedQFunctionContext_Memcheck *impl; 227 Ceed ceed; 228 ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 229 230 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", 231 CeedQFunctionContextHasValidData_Memcheck); 232 CeedChkBackend(ierr); 233 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, 234 "HasBorrowedDataOfType", 235 CeedQFunctionContextHasBorrowedDataOfType_Memcheck); 236 CeedChkBackend(ierr); 237 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", 238 CeedQFunctionContextSetData_Memcheck); CeedChkBackend(ierr); 239 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", 240 CeedQFunctionContextTakeData_Memcheck); CeedChkBackend(ierr); 241 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", 242 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr); 243 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", 244 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr); 245 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", 246 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr); 247 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", 248 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr); 249 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", 250 CeedQFunctionContextDataDestroy_Memcheck); CeedChkBackend(ierr); 251 ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", 252 CeedQFunctionContextDestroy_Memcheck); CeedChkBackend(ierr); 253 254 ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr); 255 ierr = CeedQFunctionContextSetBackendData(ctx, impl); CeedChkBackend(ierr); 256 257 return CEED_ERROR_SUCCESS; 258 } 259 //------------------------------------------------------------------------------ 260