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