xref: /libCEED/rust/libceed-sys/c-src/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision 6e536b992ff6bc401c55631f1bc4464446496b52)
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 
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));
34*6e536b99SJeremy 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 
49*6e536b99SJeremy 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 
86*6e536b99SJeremy 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 
104*6e536b99SJeremy 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 
152*6e536b99SJeremy 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 
170*6e536b99SJeremy L Thompson   CeedCheck(data_destroy_mem_type == CEED_MEM_HOST, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND,
171*6e536b99SJeremy 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