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 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 22*9a25c351SJeremy 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) { 310f58c348SJeremy L Thompson Ceed ceed; 32ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 33ad70ee2cSJeremy L Thompson 34*9a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 352b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 36bcbe1c99SJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 371c66c397SJeremy L Thompson *has_borrowed_data_of_type = impl->data_borrowed; 380f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 390f58c348SJeremy L Thompson } 400f58c348SJeremy L Thompson 410f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 420f58c348SJeremy L Thompson // QFunctionContext Set Data 430f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 442b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, void *data) { 450f58c348SJeremy L Thompson Ceed ceed; 46ad70ee2cSJeremy L Thompson size_t ctx_size; 47ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 48ad70ee2cSJeremy L Thompson 49*9a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 50ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 512b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 520f58c348SJeremy L Thompson 536574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 540f58c348SJeremy L Thompson 552b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 562b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 570f58c348SJeremy L Thompson switch (copy_mode) { 580f58c348SJeremy L Thompson case CEED_COPY_VALUES: 592b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_owned)); 600f58c348SJeremy L Thompson impl->data_borrowed = NULL; 610f58c348SJeremy L Thompson impl->data = impl->data_owned; 620f58c348SJeremy L Thompson memcpy(impl->data, data, ctx_size); 630f58c348SJeremy L Thompson break; 640f58c348SJeremy L Thompson case CEED_OWN_POINTER: 650f58c348SJeremy L Thompson impl->data_owned = data; 660f58c348SJeremy L Thompson impl->data_borrowed = NULL; 670f58c348SJeremy L Thompson impl->data = data; 680f58c348SJeremy L Thompson break; 690f58c348SJeremy L Thompson case CEED_USE_POINTER: 700f58c348SJeremy L Thompson impl->data_borrowed = data; 710f58c348SJeremy L Thompson impl->data = data; 720f58c348SJeremy L Thompson } 730f58c348SJeremy L Thompson // Copy data to check ctx_size bounds 742b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_allocated)); 750f58c348SJeremy L Thompson memcpy(impl->data_allocated, impl->data, ctx_size); 760f58c348SJeremy L Thompson impl->data = impl->data_allocated; 770f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 782b730f8bSJeremy L Thompson impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size, "'QFunction backend context data copy'"); 790f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 800f58c348SJeremy L Thompson } 810f58c348SJeremy L Thompson 820f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 830f58c348SJeremy L Thompson // QFunctionContext Take Data 840f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 852b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 860f58c348SJeremy L Thompson Ceed ceed; 87ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 88ad70ee2cSJeremy L Thompson 89*9a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 902b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 910f58c348SJeremy L Thompson 926574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 930f58c348SJeremy L Thompson 940f58c348SJeremy L Thompson *(void **)data = impl->data_borrowed; 950f58c348SJeremy L Thompson impl->data_borrowed = NULL; 960f58c348SJeremy L Thompson impl->data = NULL; 970f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 982b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 990f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1000f58c348SJeremy L Thompson } 1010f58c348SJeremy L Thompson 1020f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1030f58c348SJeremy L Thompson // QFunctionContext Get Data 1040f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1052b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 1060f58c348SJeremy L Thompson Ceed ceed; 107ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 108ad70ee2cSJeremy L Thompson 109*9a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1102b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1110f58c348SJeremy L Thompson 1126574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 1130f58c348SJeremy L Thompson 1140f58c348SJeremy L Thompson *(void **)data = impl->data; 1150f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1160f58c348SJeremy L Thompson } 1170f58c348SJeremy L Thompson 1180f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1198e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only 1208e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1212b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 1228e457467SJeremy L Thompson Ceed ceed; 123ad70ee2cSJeremy L Thompson size_t ctx_size; 124ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 1258e457467SJeremy L Thompson 126*9a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 127ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 128ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1292b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data)); 1308e457467SJeremy L Thompson 131ea61e9acSJeremy L Thompson // Make copy to verify no write occurred 1322b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_read_only_copy)); 1338e457467SJeremy L Thompson memcpy(impl->data_read_only_copy, *(void **)data, ctx_size); 1348e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1358e457467SJeremy L Thompson } 1368e457467SJeremy L Thompson 1378e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1380f58c348SJeremy L Thompson // QFunctionContext Restore Data 1390f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1400f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) { 1410f58c348SJeremy L Thompson size_t ctx_size; 1420f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 143ad70ee2cSJeremy L Thompson 144ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 145*9a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1460f58c348SJeremy L Thompson 147ad70ee2cSJeremy L Thompson if (impl->data_borrowed) memcpy(impl->data_borrowed, impl->data, ctx_size); 148ad70ee2cSJeremy L Thompson if (impl->data_owned) memcpy(impl->data_owned, impl->data, ctx_size); 1490f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1500f58c348SJeremy L Thompson } 1510f58c348SJeremy L Thompson 1520f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1538e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only 1548e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1552b730f8bSJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(CeedQFunctionContext ctx) { 1568e457467SJeremy L Thompson Ceed ceed; 157ad70ee2cSJeremy L Thompson size_t ctx_size; 158ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 159ad70ee2cSJeremy L Thompson 160ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 161*9a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1622b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1638e457467SJeremy L Thompson 1646574a04fSJeremy L Thompson CeedCheck(!memcmp(impl->data, impl->data_read_only_copy, ctx_size), ceed, CEED_ERROR_BACKEND, 1656574a04fSJeremy L Thompson "Context data changed while accessed in read-only mode"); 1668e457467SJeremy L Thompson 1672b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_read_only_copy)); 1688e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1698e457467SJeremy L Thompson } 1708e457467SJeremy L Thompson 1718e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1722e64a2b9SJeremy L Thompson // QFunctionContext destroy user data 1732e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 1742e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) { 1752e64a2b9SJeremy L Thompson Ceed ceed; 176ad70ee2cSJeremy L Thompson CeedMemType data_destroy_mem_type; 177ad70ee2cSJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 178ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 179ad70ee2cSJeremy L Thompson 180ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 181ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1822b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1832e64a2b9SJeremy L Thompson 1846574a04fSJeremy L Thompson CeedCheck(data_destroy_mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only destroy HOST memory for this backend"); 1852e64a2b9SJeremy L Thompson 1862e64a2b9SJeremy L Thompson if (data_destroy_function) { 1872b730f8bSJeremy L Thompson CeedCallBackend(data_destroy_function(impl->data_borrowed ? impl->data_borrowed : impl->data_owned)); 1882e64a2b9SJeremy L Thompson } 1892b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 1902e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 1912e64a2b9SJeremy L Thompson } 1922e64a2b9SJeremy L Thompson 1932e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 1940f58c348SJeremy L Thompson // QFunctionContext Destroy 1950f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1960f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) { 1970f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 1980f58c348SJeremy L Thompson 199ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 2002b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 2012b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 2022b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl)); 2030f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 2040f58c348SJeremy L Thompson } 2050f58c348SJeremy L Thompson 2060f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2070f58c348SJeremy L Thompson // QFunctionContext Create 2080f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2090f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) { 2100f58c348SJeremy L Thompson Ceed ceed; 211ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 2120f58c348SJeremy L Thompson 213ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2142b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Memcheck)); 2152b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Memcheck)); 2162b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Memcheck)); 2172b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Memcheck)); 2182b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Memcheck)); 2192b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Memcheck)); 2202b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", CeedQFunctionContextRestoreData_Memcheck)); 2212b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", CeedQFunctionContextRestoreDataRead_Memcheck)); 2222b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", CeedQFunctionContextDataDestroy_Memcheck)); 2232b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Memcheck)); 2242b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl)); 2252b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl)); 2260f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 2270f58c348SJeremy L Thompson } 2282a86cc9dSSebastian Grimberg 2290f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 230