10f58c348SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 20f58c348SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 30f58c348SJeremy L Thompson // 40f58c348SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 50f58c348SJeremy L Thompson // 60f58c348SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 70f58c348SJeremy L Thompson 80f58c348SJeremy L Thompson #include <ceed/backend.h> 9*2b730f8bSJeremy L Thompson #include <ceed/ceed.h> 100f58c348SJeremy L Thompson #include <string.h> 110f58c348SJeremy L Thompson #include <valgrind/memcheck.h> 12*2b730f8bSJeremy L Thompson 130f58c348SJeremy L Thompson #include "ceed-memcheck.h" 140f58c348SJeremy L Thompson 150f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 160f58c348SJeremy L Thompson // QFunctionContext has valid data 170f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 18*2b730f8bSJeremy L Thompson static int CeedQFunctionContextHasValidData_Memcheck(CeedQFunctionContext ctx, bool *has_valid_data) { 190f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 20*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 210f58c348SJeremy L Thompson 220f58c348SJeremy L Thompson *has_valid_data = !!impl->data; 230f58c348SJeremy L Thompson 240f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 250f58c348SJeremy L Thompson } 260f58c348SJeremy L Thompson 270f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 280f58c348SJeremy L Thompson // QFunctionContext has borrowed data 290f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 30*2b730f8bSJeremy L Thompson static int CeedQFunctionContextHasBorrowedDataOfType_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) { 310f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 32*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 330f58c348SJeremy L Thompson Ceed ceed; 34*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 350f58c348SJeremy L Thompson 360f58c348SJeremy L Thompson switch (mem_type) { 370f58c348SJeremy L Thompson case CEED_MEM_HOST: 380f58c348SJeremy L Thompson *has_borrowed_data_of_type = !!impl->data_borrowed; 390f58c348SJeremy L Thompson break; 400f58c348SJeremy L Thompson default: 410f58c348SJeremy L Thompson // LCOV_EXCL_START 42*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 430f58c348SJeremy L Thompson // LCOV_EXCL_STOP 440f58c348SJeremy L Thompson break; 450f58c348SJeremy L Thompson } 460f58c348SJeremy L Thompson 470f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 480f58c348SJeremy L Thompson } 490f58c348SJeremy L Thompson 500f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 510f58c348SJeremy L Thompson // QFunctionContext Set Data 520f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 53*2b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, void *data) { 540f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 55*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 560f58c348SJeremy L Thompson size_t ctx_size; 57*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 580f58c348SJeremy L Thompson Ceed ceed; 59*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 600f58c348SJeremy L Thompson 61*2b730f8bSJeremy L Thompson if (mem_type != CEED_MEM_HOST) { 620f58c348SJeremy L Thompson // LCOV_EXCL_START 63*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 640f58c348SJeremy L Thompson // LCOV_EXCL_STOP 65*2b730f8bSJeremy L Thompson } 660f58c348SJeremy L Thompson 67*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 68*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 690f58c348SJeremy L Thompson switch (copy_mode) { 700f58c348SJeremy L Thompson case CEED_COPY_VALUES: 71*2b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_owned)); 720f58c348SJeremy L Thompson impl->data_borrowed = NULL; 730f58c348SJeremy L Thompson impl->data = impl->data_owned; 740f58c348SJeremy L Thompson memcpy(impl->data, data, ctx_size); 750f58c348SJeremy L Thompson break; 760f58c348SJeremy L Thompson case CEED_OWN_POINTER: 770f58c348SJeremy L Thompson impl->data_owned = data; 780f58c348SJeremy L Thompson impl->data_borrowed = NULL; 790f58c348SJeremy L Thompson impl->data = data; 800f58c348SJeremy L Thompson break; 810f58c348SJeremy L Thompson case CEED_USE_POINTER: 820f58c348SJeremy L Thompson impl->data_borrowed = data; 830f58c348SJeremy L Thompson impl->data = data; 840f58c348SJeremy L Thompson } 850f58c348SJeremy L Thompson // Copy data to check ctx_size bounds 86*2b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_allocated)); 870f58c348SJeremy L Thompson memcpy(impl->data_allocated, impl->data, ctx_size); 880f58c348SJeremy L Thompson impl->data = impl->data_allocated; 890f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 90*2b730f8bSJeremy L Thompson impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size, "'QFunction backend context data copy'"); 910f58c348SJeremy L Thompson 920f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 930f58c348SJeremy L Thompson } 940f58c348SJeremy L Thompson 950f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 960f58c348SJeremy L Thompson // QFunctionContext Take Data 970f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 98*2b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 990f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 100*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1010f58c348SJeremy L Thompson Ceed ceed; 102*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1030f58c348SJeremy L Thompson 104*2b730f8bSJeremy L Thompson if (mem_type != CEED_MEM_HOST) { 1050f58c348SJeremy L Thompson // LCOV_EXCL_START 106*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 1070f58c348SJeremy L Thompson // LCOV_EXCL_STOP 108*2b730f8bSJeremy L Thompson } 1090f58c348SJeremy L Thompson 1100f58c348SJeremy L Thompson *(void **)data = impl->data_borrowed; 1110f58c348SJeremy L Thompson impl->data_borrowed = NULL; 1120f58c348SJeremy L Thompson impl->data = NULL; 1130f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 114*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 1150f58c348SJeremy L Thompson 1160f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1170f58c348SJeremy L Thompson } 1180f58c348SJeremy L Thompson 1190f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1200f58c348SJeremy L Thompson // QFunctionContext Get Data 1210f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 122*2b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 1230f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 124*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1250f58c348SJeremy L Thompson Ceed ceed; 126*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1270f58c348SJeremy L Thompson 128*2b730f8bSJeremy L Thompson if (mem_type != CEED_MEM_HOST) { 1290f58c348SJeremy L Thompson // LCOV_EXCL_START 130*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 1310f58c348SJeremy L Thompson // LCOV_EXCL_STOP 132*2b730f8bSJeremy L Thompson } 1330f58c348SJeremy L Thompson 1340f58c348SJeremy L Thompson *(void **)data = impl->data; 1350f58c348SJeremy L Thompson 1360f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1370f58c348SJeremy L Thompson } 1380f58c348SJeremy L Thompson 1390f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1408e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only 1418e457467SJeremy L Thompson //------------------------------------------------------------------------------ 142*2b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 1438e457467SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 144*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1458e457467SJeremy L Thompson size_t ctx_size; 146*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 1478e457467SJeremy L Thompson Ceed ceed; 148*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1498e457467SJeremy L Thompson 150*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data)); 1518e457467SJeremy L Thompson 1528e457467SJeremy L Thompson // Make copy to verify no write occured 153*2b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_read_only_copy)); 1548e457467SJeremy L Thompson memcpy(impl->data_read_only_copy, *(void **)data, ctx_size); 1558e457467SJeremy L Thompson 1568e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1578e457467SJeremy L Thompson } 1588e457467SJeremy L Thompson 1598e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1600f58c348SJeremy L Thompson // QFunctionContext Restore Data 1610f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1620f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) { 1630f58c348SJeremy L Thompson size_t ctx_size; 164*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 1650f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 166*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1670f58c348SJeremy L Thompson 1680f58c348SJeremy L Thompson if (impl->data_borrowed) { 1690f58c348SJeremy L Thompson memcpy(impl->data_borrowed, impl->data, ctx_size); 1700f58c348SJeremy L Thompson } 1710f58c348SJeremy L Thompson if (impl->data_owned) { 1720f58c348SJeremy L Thompson memcpy(impl->data_owned, impl->data, ctx_size); 1730f58c348SJeremy L Thompson } 1740f58c348SJeremy L Thompson 1750f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1760f58c348SJeremy L Thompson } 1770f58c348SJeremy L Thompson 1780f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1798e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only 1808e457467SJeremy L Thompson //------------------------------------------------------------------------------ 181*2b730f8bSJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(CeedQFunctionContext ctx) { 1828e457467SJeremy L Thompson size_t ctx_size; 183*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 1848e457467SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 185*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1868e457467SJeremy L Thompson Ceed ceed; 187*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1888e457467SJeremy L Thompson 189*2b730f8bSJeremy L Thompson if (memcmp(impl->data, impl->data_read_only_copy, ctx_size)) { 1908e457467SJeremy L Thompson // LCOV_EXCL_START 191*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "Context data changed while accessed in read-only mode"); 1928e457467SJeremy L Thompson // LCOV_EXCL_STOP 193*2b730f8bSJeremy L Thompson } 1948e457467SJeremy L Thompson 195*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_read_only_copy)); 1968e457467SJeremy L Thompson 1978e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1988e457467SJeremy L Thompson } 1998e457467SJeremy L Thompson 2008e457467SJeremy L Thompson //------------------------------------------------------------------------------ 2012e64a2b9SJeremy L Thompson // QFunctionContext destroy user data 2022e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 2032e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) { 2042e64a2b9SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 205*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 2062e64a2b9SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 2072e64a2b9SJeremy L Thompson CeedMemType data_destroy_mem_type; 208*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 2092e64a2b9SJeremy L Thompson Ceed ceed; 210*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2112e64a2b9SJeremy L Thompson 212*2b730f8bSJeremy L Thompson if (data_destroy_mem_type != CEED_MEM_HOST) { 2132e64a2b9SJeremy L Thompson // LCOV_EXCL_START 214*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "Can only destroy HOST memory for this backend"); 2152e64a2b9SJeremy L Thompson // LCOV_EXCL_STOP 216*2b730f8bSJeremy L Thompson } 2172e64a2b9SJeremy L Thompson 2182e64a2b9SJeremy L Thompson if (data_destroy_function) { 219*2b730f8bSJeremy L Thompson CeedCallBackend(data_destroy_function(impl->data_borrowed ? impl->data_borrowed : impl->data_owned)); 2202e64a2b9SJeremy L Thompson } 221*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 2222e64a2b9SJeremy L Thompson 2232e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 2242e64a2b9SJeremy L Thompson } 2252e64a2b9SJeremy L Thompson 2262e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 2270f58c348SJeremy L Thompson // QFunctionContext Destroy 2280f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2290f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) { 2300f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 231*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 2320f58c348SJeremy L Thompson 233*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 234*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 235*2b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl)); 2360f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 2370f58c348SJeremy L Thompson } 2380f58c348SJeremy L Thompson 2390f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2400f58c348SJeremy L Thompson // QFunctionContext Create 2410f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2420f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) { 2430f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 2440f58c348SJeremy L Thompson Ceed ceed; 245*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2460f58c348SJeremy L Thompson 247*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Memcheck)); 248*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Memcheck)); 249*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Memcheck)); 250*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Memcheck)); 251*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Memcheck)); 252*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Memcheck)); 253*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", CeedQFunctionContextRestoreData_Memcheck)); 254*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", CeedQFunctionContextRestoreDataRead_Memcheck)); 255*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", CeedQFunctionContextDataDestroy_Memcheck)); 256*2b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Memcheck)); 2570f58c348SJeremy L Thompson 258*2b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl)); 259*2b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl)); 2600f58c348SJeremy L Thompson 2610f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 2620f58c348SJeremy L Thompson } 2630f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 264