1*5aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, 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 849aac155SJeremy L Thompson #include <ceed.h> 90f58c348SJeremy L Thompson #include <ceed/backend.h> 1049aac155SJeremy L Thompson #include <stdbool.h> 110f58c348SJeremy L Thompson #include <string.h> 120f58c348SJeremy L Thompson #include <valgrind/memcheck.h> 132b730f8bSJeremy L Thompson 140f58c348SJeremy L Thompson #include "ceed-memcheck.h" 150f58c348SJeremy L Thompson 160f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 170f58c348SJeremy L Thompson // QFunctionContext has valid data 180f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 192b730f8bSJeremy L Thompson static int CeedQFunctionContextHasValidData_Memcheck(CeedQFunctionContext ctx, bool *has_valid_data) { 200f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 21ad70ee2cSJeremy L Thompson 229a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 231c66c397SJeremy L Thompson *has_valid_data = impl->data; 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 //------------------------------------------------------------------------------ 302b730f8bSJeremy L Thompson static int CeedQFunctionContextHasBorrowedDataOfType_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) { 31ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 32ad70ee2cSJeremy L Thompson 339a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 346e536b99SJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 351c66c397SJeremy L Thompson *has_borrowed_data_of_type = impl->data_borrowed; 360f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 370f58c348SJeremy L Thompson } 380f58c348SJeremy L Thompson 390f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 400f58c348SJeremy L Thompson // QFunctionContext Set Data 410f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 422b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, void *data) { 43ad70ee2cSJeremy L Thompson size_t ctx_size; 44ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 45ad70ee2cSJeremy L Thompson 469a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 47ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 480f58c348SJeremy L Thompson 496e536b99SJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 500f58c348SJeremy L Thompson 512b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 522b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 530f58c348SJeremy L Thompson switch (copy_mode) { 540f58c348SJeremy L Thompson case CEED_COPY_VALUES: 552b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_owned)); 560f58c348SJeremy L Thompson impl->data_borrowed = NULL; 570f58c348SJeremy L Thompson impl->data = impl->data_owned; 580f58c348SJeremy L Thompson memcpy(impl->data, data, ctx_size); 590f58c348SJeremy L Thompson break; 600f58c348SJeremy L Thompson case CEED_OWN_POINTER: 610f58c348SJeremy L Thompson impl->data_owned = data; 620f58c348SJeremy L Thompson impl->data_borrowed = NULL; 630f58c348SJeremy L Thompson impl->data = data; 640f58c348SJeremy L Thompson break; 650f58c348SJeremy L Thompson case CEED_USE_POINTER: 660f58c348SJeremy L Thompson impl->data_borrowed = data; 670f58c348SJeremy L Thompson impl->data = data; 680f58c348SJeremy L Thompson } 690f58c348SJeremy L Thompson // Copy data to check ctx_size bounds 702b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_allocated)); 710f58c348SJeremy L Thompson memcpy(impl->data_allocated, impl->data, ctx_size); 720f58c348SJeremy L Thompson impl->data = impl->data_allocated; 730f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 742b730f8bSJeremy L Thompson impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size, "'QFunction backend context data copy'"); 750f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 760f58c348SJeremy L Thompson } 770f58c348SJeremy L Thompson 780f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 790f58c348SJeremy L Thompson // QFunctionContext Take Data 800f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 812b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 82ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 83ad70ee2cSJeremy L Thompson 849a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 850f58c348SJeremy L Thompson 866e536b99SJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 870f58c348SJeremy L Thompson 880f58c348SJeremy L Thompson *(void **)data = impl->data_borrowed; 890f58c348SJeremy L Thompson impl->data_borrowed = NULL; 900f58c348SJeremy L Thompson impl->data = NULL; 910f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 922b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 930f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 940f58c348SJeremy L Thompson } 950f58c348SJeremy L Thompson 960f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 970f58c348SJeremy L Thompson // QFunctionContext Get Data 980f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 992b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 100ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 101ad70ee2cSJeremy L Thompson 1029a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1030f58c348SJeremy L Thompson 1046e536b99SJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 1050f58c348SJeremy L Thompson 1060f58c348SJeremy L Thompson *(void **)data = impl->data; 1070f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1080f58c348SJeremy L Thompson } 1090f58c348SJeremy L Thompson 1100f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1118e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only 1128e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1132b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 114ad70ee2cSJeremy L Thompson size_t ctx_size; 115ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 1168e457467SJeremy L Thompson 1179a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 118ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 1192b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data)); 1208e457467SJeremy L Thompson 121ea61e9acSJeremy L Thompson // Make copy to verify no write occurred 1222b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_read_only_copy)); 1238e457467SJeremy L Thompson memcpy(impl->data_read_only_copy, *(void **)data, ctx_size); 1248e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1258e457467SJeremy L Thompson } 1268e457467SJeremy L Thompson 1278e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1280f58c348SJeremy L Thompson // QFunctionContext Restore Data 1290f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1300f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) { 1310f58c348SJeremy L Thompson size_t ctx_size; 1320f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 133ad70ee2cSJeremy L Thompson 134ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 1359a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1360f58c348SJeremy L Thompson 137ad70ee2cSJeremy L Thompson if (impl->data_borrowed) memcpy(impl->data_borrowed, impl->data, ctx_size); 138ad70ee2cSJeremy L Thompson if (impl->data_owned) memcpy(impl->data_owned, impl->data, ctx_size); 1390f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1400f58c348SJeremy L Thompson } 1410f58c348SJeremy L Thompson 1420f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1438e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only 1448e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1452b730f8bSJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(CeedQFunctionContext ctx) { 146ad70ee2cSJeremy L Thompson size_t ctx_size; 147ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 148ad70ee2cSJeremy L Thompson 149ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 1509a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1518e457467SJeremy L Thompson 1526e536b99SJeremy L Thompson CeedCheck(!memcmp(impl->data, impl->data_read_only_copy, ctx_size), CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, 1536574a04fSJeremy L Thompson "Context data changed while accessed in read-only mode"); 1548e457467SJeremy L Thompson 1552b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_read_only_copy)); 1568e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1578e457467SJeremy L Thompson } 1588e457467SJeremy L Thompson 1598e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1602e64a2b9SJeremy L Thompson // QFunctionContext destroy user data 1612e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 1622e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) { 163ad70ee2cSJeremy L Thompson CeedMemType data_destroy_mem_type; 164ad70ee2cSJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 165ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 166ad70ee2cSJeremy L Thompson 167ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 168ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1692e64a2b9SJeremy L Thompson 1706e536b99SJeremy L Thompson CeedCheck(data_destroy_mem_type == CEED_MEM_HOST, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, 1716e536b99SJeremy L Thompson "Can only destroy HOST memory for this backend"); 1722e64a2b9SJeremy L Thompson 1732e64a2b9SJeremy L Thompson if (data_destroy_function) { 1742b730f8bSJeremy L Thompson CeedCallBackend(data_destroy_function(impl->data_borrowed ? impl->data_borrowed : impl->data_owned)); 1752e64a2b9SJeremy L Thompson } 1762b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 1772e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 1782e64a2b9SJeremy L Thompson } 1792e64a2b9SJeremy L Thompson 1802e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 1810f58c348SJeremy L Thompson // QFunctionContext Destroy 1820f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1830f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) { 1840f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 1850f58c348SJeremy L Thompson 186ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1872b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 1882b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 1892b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl)); 1900f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1910f58c348SJeremy L Thompson } 1920f58c348SJeremy L Thompson 1930f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1940f58c348SJeremy L Thompson // QFunctionContext Create 1950f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1960f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) { 1970f58c348SJeremy L Thompson Ceed ceed; 198ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 1990f58c348SJeremy L Thompson 200ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2012b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Memcheck)); 2022b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Memcheck)); 2032b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Memcheck)); 2042b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Memcheck)); 2052b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Memcheck)); 2062b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Memcheck)); 2072b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", CeedQFunctionContextRestoreData_Memcheck)); 2082b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", CeedQFunctionContextRestoreDataRead_Memcheck)); 2092b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", CeedQFunctionContextDataDestroy_Memcheck)); 2102b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Memcheck)); 2112b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl)); 2122b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl)); 2130f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 2140f58c348SJeremy L Thompson } 2152a86cc9dSSebastian Grimberg 2160f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 217