xref: /libCEED/rust/libceed-sys/c-src/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision ad70ee2c7083010521460a681a248527200af770)
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