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; 21*ad70ee2cSJeremy L Thompson 222b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&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; 32*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 33*ad70ee2cSJeremy L Thompson 34*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 352b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 360f58c348SJeremy L Thompson 370f58c348SJeremy L Thompson switch (mem_type) { 380f58c348SJeremy L Thompson case CEED_MEM_HOST: 391c66c397SJeremy L Thompson *has_borrowed_data_of_type = impl->data_borrowed; 400f58c348SJeremy L Thompson break; 410f58c348SJeremy L Thompson default: 420f58c348SJeremy L Thompson // LCOV_EXCL_START 432b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 440f58c348SJeremy L Thompson // LCOV_EXCL_STOP 450f58c348SJeremy L Thompson break; 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 //------------------------------------------------------------------------------ 532b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, void *data) { 540f58c348SJeremy L Thompson Ceed ceed; 55*ad70ee2cSJeremy L Thompson size_t ctx_size; 56*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 57*ad70ee2cSJeremy L Thompson 58*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 59*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 602b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 610f58c348SJeremy L Thompson 626574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 630f58c348SJeremy L Thompson 642b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 652b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 660f58c348SJeremy L Thompson switch (copy_mode) { 670f58c348SJeremy L Thompson case CEED_COPY_VALUES: 682b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_owned)); 690f58c348SJeremy L Thompson impl->data_borrowed = NULL; 700f58c348SJeremy L Thompson impl->data = impl->data_owned; 710f58c348SJeremy L Thompson memcpy(impl->data, data, ctx_size); 720f58c348SJeremy L Thompson break; 730f58c348SJeremy L Thompson case CEED_OWN_POINTER: 740f58c348SJeremy L Thompson impl->data_owned = data; 750f58c348SJeremy L Thompson impl->data_borrowed = NULL; 760f58c348SJeremy L Thompson impl->data = data; 770f58c348SJeremy L Thompson break; 780f58c348SJeremy L Thompson case CEED_USE_POINTER: 790f58c348SJeremy L Thompson impl->data_borrowed = data; 800f58c348SJeremy L Thompson impl->data = data; 810f58c348SJeremy L Thompson } 820f58c348SJeremy L Thompson // Copy data to check ctx_size bounds 832b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_allocated)); 840f58c348SJeremy L Thompson memcpy(impl->data_allocated, impl->data, ctx_size); 850f58c348SJeremy L Thompson impl->data = impl->data_allocated; 860f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 872b730f8bSJeremy L Thompson impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size, "'QFunction backend context data copy'"); 880f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 890f58c348SJeremy L Thompson } 900f58c348SJeremy L Thompson 910f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 920f58c348SJeremy L Thompson // QFunctionContext Take Data 930f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 942b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 950f58c348SJeremy L Thompson Ceed ceed; 96*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 97*ad70ee2cSJeremy L Thompson 98*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 992b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1000f58c348SJeremy L Thompson 1016574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 1020f58c348SJeremy L Thompson 1030f58c348SJeremy L Thompson *(void **)data = impl->data_borrowed; 1040f58c348SJeremy L Thompson impl->data_borrowed = NULL; 1050f58c348SJeremy L Thompson impl->data = NULL; 1060f58c348SJeremy L Thompson VALGRIND_DISCARD(impl->mem_block_id); 1072b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 1080f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1090f58c348SJeremy L Thompson } 1100f58c348SJeremy L Thompson 1110f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1120f58c348SJeremy L Thompson // QFunctionContext Get Data 1130f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1142b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 1150f58c348SJeremy L Thompson Ceed ceed; 116*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 117*ad70ee2cSJeremy L Thompson 118*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1192b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1200f58c348SJeremy L Thompson 1216574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 1220f58c348SJeremy L Thompson 1230f58c348SJeremy L Thompson *(void **)data = impl->data; 1240f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1250f58c348SJeremy L Thompson } 1260f58c348SJeremy L Thompson 1270f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1288e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only 1298e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1302b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 1318e457467SJeremy L Thompson Ceed ceed; 132*ad70ee2cSJeremy L Thompson size_t ctx_size; 133*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 1348e457467SJeremy L Thompson 135*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 136*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 137*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1382b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data)); 1398e457467SJeremy L Thompson 140ea61e9acSJeremy L Thompson // Make copy to verify no write occurred 1412b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_read_only_copy)); 1428e457467SJeremy L Thompson memcpy(impl->data_read_only_copy, *(void **)data, ctx_size); 1438e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1448e457467SJeremy L Thompson } 1458e457467SJeremy L Thompson 1468e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1470f58c348SJeremy L Thompson // QFunctionContext Restore Data 1480f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1490f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) { 1500f58c348SJeremy L Thompson size_t ctx_size; 1510f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 152*ad70ee2cSJeremy L Thompson 153*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 1542b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1550f58c348SJeremy L Thompson 156*ad70ee2cSJeremy L Thompson if (impl->data_borrowed) memcpy(impl->data_borrowed, impl->data, ctx_size); 157*ad70ee2cSJeremy L Thompson if (impl->data_owned) memcpy(impl->data_owned, impl->data, ctx_size); 1580f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 1590f58c348SJeremy L Thompson } 1600f58c348SJeremy L Thompson 1610f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 1628e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only 1638e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1642b730f8bSJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(CeedQFunctionContext ctx) { 1658e457467SJeremy L Thompson Ceed ceed; 166*ad70ee2cSJeremy L Thompson size_t ctx_size; 167*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 168*ad70ee2cSJeremy L Thompson 169*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size)); 170*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl)); 1712b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1728e457467SJeremy L Thompson 1736574a04fSJeremy L Thompson CeedCheck(!memcmp(impl->data, impl->data_read_only_copy, ctx_size), ceed, CEED_ERROR_BACKEND, 1746574a04fSJeremy L Thompson "Context data changed while accessed in read-only mode"); 1758e457467SJeremy L Thompson 1762b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_read_only_copy)); 1778e457467SJeremy L Thompson return CEED_ERROR_SUCCESS; 1788e457467SJeremy L Thompson } 1798e457467SJeremy L Thompson 1808e457467SJeremy L Thompson //------------------------------------------------------------------------------ 1812e64a2b9SJeremy L Thompson // QFunctionContext destroy user data 1822e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 1832e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) { 1842e64a2b9SJeremy L Thompson Ceed ceed; 185*ad70ee2cSJeremy L Thompson CeedMemType data_destroy_mem_type; 186*ad70ee2cSJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 187*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 188*ad70ee2cSJeremy L Thompson 189*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 190*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1912b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1922e64a2b9SJeremy L Thompson 1936574a04fSJeremy L Thompson CeedCheck(data_destroy_mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only destroy HOST memory for this backend"); 1942e64a2b9SJeremy L Thompson 1952e64a2b9SJeremy L Thompson if (data_destroy_function) { 1962b730f8bSJeremy L Thompson CeedCallBackend(data_destroy_function(impl->data_borrowed ? impl->data_borrowed : impl->data_owned)); 1972e64a2b9SJeremy L Thompson } 1982b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 1992e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 2002e64a2b9SJeremy L Thompson } 2012e64a2b9SJeremy L Thompson 2022e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------ 2030f58c348SJeremy L Thompson // QFunctionContext Destroy 2040f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2050f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) { 2060f58c348SJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 2070f58c348SJeremy L Thompson 208*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 2092b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_allocated)); 2102b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->data_owned)); 2112b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl)); 2120f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 2130f58c348SJeremy L Thompson } 2140f58c348SJeremy L Thompson 2150f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2160f58c348SJeremy L Thompson // QFunctionContext Create 2170f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 2180f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) { 2190f58c348SJeremy L Thompson Ceed ceed; 220*ad70ee2cSJeremy L Thompson CeedQFunctionContext_Memcheck *impl; 2210f58c348SJeremy L Thompson 222*ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2232b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Memcheck)); 2242b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Memcheck)); 2252b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Memcheck)); 2262b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Memcheck)); 2272b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Memcheck)); 2282b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Memcheck)); 2292b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", CeedQFunctionContextRestoreData_Memcheck)); 2302b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", CeedQFunctionContextRestoreDataRead_Memcheck)); 2312b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", CeedQFunctionContextDataDestroy_Memcheck)); 2322b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Memcheck)); 2332b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl)); 2342b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl)); 2350f58c348SJeremy L Thompson return CEED_ERROR_SUCCESS; 2360f58c348SJeremy L Thompson } 2372a86cc9dSSebastian Grimberg 2380f58c348SJeremy L Thompson //------------------------------------------------------------------------------ 239