xref: /libCEED/rust/libceed-sys/c-src/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision ea61e9ac44808524e4667c1525a05976f536c19c)
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 
80f58c348SJeremy L Thompson #include <ceed/backend.h>
92b730f8bSJeremy L Thompson #include <ceed/ceed.h>
100f58c348SJeremy L Thompson #include <string.h>
110f58c348SJeremy L Thompson #include <valgrind/memcheck.h>
122b730f8bSJeremy L Thompson 
130f58c348SJeremy L Thompson #include "ceed-memcheck.h"
140f58c348SJeremy L Thompson 
150f58c348SJeremy L Thompson //------------------------------------------------------------------------------
160f58c348SJeremy L Thompson // QFunctionContext has valid data
170f58c348SJeremy L Thompson //------------------------------------------------------------------------------
182b730f8bSJeremy L Thompson static int CeedQFunctionContextHasValidData_Memcheck(CeedQFunctionContext ctx, bool *has_valid_data) {
190f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
202b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
210f58c348SJeremy L Thompson 
220f58c348SJeremy L Thompson   *has_valid_data = !!impl->data;
230f58c348SJeremy L Thompson 
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   CeedQFunctionContext_Memcheck *impl;
322b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
330f58c348SJeremy L Thompson   Ceed ceed;
342b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
350f58c348SJeremy L Thompson 
360f58c348SJeremy L Thompson   switch (mem_type) {
370f58c348SJeremy L Thompson     case CEED_MEM_HOST:
380f58c348SJeremy L Thompson       *has_borrowed_data_of_type = !!impl->data_borrowed;
390f58c348SJeremy L Thompson       break;
400f58c348SJeremy L Thompson     default:
410f58c348SJeremy L Thompson       // LCOV_EXCL_START
422b730f8bSJeremy L Thompson       return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend");
430f58c348SJeremy L Thompson       // LCOV_EXCL_STOP
440f58c348SJeremy L Thompson       break;
450f58c348SJeremy L Thompson   }
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   CeedQFunctionContext_Memcheck *impl;
552b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
560f58c348SJeremy L Thompson   size_t ctx_size;
572b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
580f58c348SJeremy L Thompson   Ceed ceed;
592b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
600f58c348SJeremy L Thompson 
612b730f8bSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
620f58c348SJeremy L Thompson     // LCOV_EXCL_START
632b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend");
640f58c348SJeremy L Thompson     // LCOV_EXCL_STOP
652b730f8bSJeremy L Thompson   }
660f58c348SJeremy L Thompson 
672b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
682b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_owned));
690f58c348SJeremy L Thompson   switch (copy_mode) {
700f58c348SJeremy L Thompson     case CEED_COPY_VALUES:
712b730f8bSJeremy L Thompson       CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_owned));
720f58c348SJeremy L Thompson       impl->data_borrowed = NULL;
730f58c348SJeremy L Thompson       impl->data          = impl->data_owned;
740f58c348SJeremy L Thompson       memcpy(impl->data, data, ctx_size);
750f58c348SJeremy L Thompson       break;
760f58c348SJeremy L Thompson     case CEED_OWN_POINTER:
770f58c348SJeremy L Thompson       impl->data_owned    = data;
780f58c348SJeremy L Thompson       impl->data_borrowed = NULL;
790f58c348SJeremy L Thompson       impl->data          = data;
800f58c348SJeremy L Thompson       break;
810f58c348SJeremy L Thompson     case CEED_USE_POINTER:
820f58c348SJeremy L Thompson       impl->data_borrowed = data;
830f58c348SJeremy L Thompson       impl->data          = data;
840f58c348SJeremy L Thompson   }
850f58c348SJeremy L Thompson   // Copy data to check ctx_size bounds
862b730f8bSJeremy L Thompson   CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_allocated));
870f58c348SJeremy L Thompson   memcpy(impl->data_allocated, impl->data, ctx_size);
880f58c348SJeremy L Thompson   impl->data = impl->data_allocated;
890f58c348SJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
902b730f8bSJeremy L Thompson   impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size, "'QFunction backend context data copy'");
910f58c348SJeremy L Thompson 
920f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
930f58c348SJeremy L Thompson }
940f58c348SJeremy L Thompson 
950f58c348SJeremy L Thompson //------------------------------------------------------------------------------
960f58c348SJeremy L Thompson // QFunctionContext Take Data
970f58c348SJeremy L Thompson //------------------------------------------------------------------------------
982b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
990f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1002b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1010f58c348SJeremy L Thompson   Ceed ceed;
1022b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1030f58c348SJeremy L Thompson 
1042b730f8bSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
1050f58c348SJeremy L Thompson     // LCOV_EXCL_START
1062b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
1070f58c348SJeremy L Thompson     // LCOV_EXCL_STOP
1082b730f8bSJeremy L Thompson   }
1090f58c348SJeremy L Thompson 
1100f58c348SJeremy L Thompson   *(void **)data      = impl->data_borrowed;
1110f58c348SJeremy L Thompson   impl->data_borrowed = NULL;
1120f58c348SJeremy L Thompson   impl->data          = NULL;
1130f58c348SJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
1142b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
1150f58c348SJeremy L Thompson 
1160f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1170f58c348SJeremy L Thompson }
1180f58c348SJeremy L Thompson 
1190f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1200f58c348SJeremy L Thompson // QFunctionContext Get Data
1210f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1222b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
1230f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1242b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1250f58c348SJeremy L Thompson   Ceed ceed;
1262b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1270f58c348SJeremy L Thompson 
1282b730f8bSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
1290f58c348SJeremy L Thompson     // LCOV_EXCL_START
1302b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
1310f58c348SJeremy L Thompson     // LCOV_EXCL_STOP
1322b730f8bSJeremy L Thompson   }
1330f58c348SJeremy L Thompson 
1340f58c348SJeremy L Thompson   *(void **)data = impl->data;
1350f58c348SJeremy L Thompson 
1360f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1370f58c348SJeremy L Thompson }
1380f58c348SJeremy L Thompson 
1390f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1408e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only
1418e457467SJeremy L Thompson //------------------------------------------------------------------------------
1422b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
1438e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1442b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1458e457467SJeremy L Thompson   size_t ctx_size;
1462b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1478e457467SJeremy L Thompson   Ceed ceed;
1482b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1498e457467SJeremy L Thompson 
1502b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data));
1518e457467SJeremy L Thompson 
152*ea61e9acSJeremy L Thompson   // Make copy to verify no write occurred
1532b730f8bSJeremy L Thompson   CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_read_only_copy));
1548e457467SJeremy L Thompson   memcpy(impl->data_read_only_copy, *(void **)data, ctx_size);
1558e457467SJeremy L Thompson 
1568e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1578e457467SJeremy L Thompson }
1588e457467SJeremy L Thompson 
1598e457467SJeremy L Thompson //------------------------------------------------------------------------------
1600f58c348SJeremy L Thompson // QFunctionContext Restore Data
1610f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1620f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) {
1630f58c348SJeremy L Thompson   size_t ctx_size;
1642b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1650f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1662b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1670f58c348SJeremy L Thompson 
1680f58c348SJeremy L Thompson   if (impl->data_borrowed) {
1690f58c348SJeremy L Thompson     memcpy(impl->data_borrowed, impl->data, ctx_size);
1700f58c348SJeremy L Thompson   }
1710f58c348SJeremy L Thompson   if (impl->data_owned) {
1720f58c348SJeremy L Thompson     memcpy(impl->data_owned, impl->data, ctx_size);
1730f58c348SJeremy L Thompson   }
1740f58c348SJeremy L Thompson 
1750f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1760f58c348SJeremy L Thompson }
1770f58c348SJeremy L Thompson 
1780f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1798e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only
1808e457467SJeremy L Thompson //------------------------------------------------------------------------------
1812b730f8bSJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(CeedQFunctionContext ctx) {
1828e457467SJeremy L Thompson   size_t ctx_size;
1832b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1848e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1852b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1868e457467SJeremy L Thompson   Ceed ceed;
1872b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1888e457467SJeremy L Thompson 
1892b730f8bSJeremy L Thompson   if (memcmp(impl->data, impl->data_read_only_copy, ctx_size)) {
1908e457467SJeremy L Thompson     // LCOV_EXCL_START
1912b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Context data changed while accessed in read-only mode");
1928e457467SJeremy L Thompson     // LCOV_EXCL_STOP
1932b730f8bSJeremy L Thompson   }
1948e457467SJeremy L Thompson 
1952b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_read_only_copy));
1968e457467SJeremy L Thompson 
1978e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1988e457467SJeremy L Thompson }
1998e457467SJeremy L Thompson 
2008e457467SJeremy L Thompson //------------------------------------------------------------------------------
2012e64a2b9SJeremy L Thompson // QFunctionContext destroy user data
2022e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
2032e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) {
2042e64a2b9SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2052b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2062e64a2b9SJeremy L Thompson   CeedQFunctionContextDataDestroyUser data_destroy_function;
2072e64a2b9SJeremy L Thompson   CeedMemType                         data_destroy_mem_type;
2082b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
2092e64a2b9SJeremy L Thompson   Ceed ceed;
2102b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2112e64a2b9SJeremy L Thompson 
2122b730f8bSJeremy L Thompson   if (data_destroy_mem_type != CEED_MEM_HOST) {
2132e64a2b9SJeremy L Thompson     // LCOV_EXCL_START
2142b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only destroy HOST memory for this backend");
2152e64a2b9SJeremy L Thompson     // LCOV_EXCL_STOP
2162b730f8bSJeremy L Thompson   }
2172e64a2b9SJeremy L Thompson 
2182e64a2b9SJeremy L Thompson   if (data_destroy_function) {
2192b730f8bSJeremy L Thompson     CeedCallBackend(data_destroy_function(impl->data_borrowed ? impl->data_borrowed : impl->data_owned));
2202e64a2b9SJeremy L Thompson   }
2212b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
2222e64a2b9SJeremy L Thompson 
2232e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2242e64a2b9SJeremy L Thompson }
2252e64a2b9SJeremy L Thompson 
2262e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
2270f58c348SJeremy L Thompson // QFunctionContext Destroy
2280f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2290f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) {
2300f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2312b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2320f58c348SJeremy L Thompson 
2332b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
2342b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_owned));
2352b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
2360f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2370f58c348SJeremy L Thompson }
2380f58c348SJeremy L Thompson 
2390f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2400f58c348SJeremy L Thompson // QFunctionContext Create
2410f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2420f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) {
2430f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2440f58c348SJeremy L Thompson   Ceed                           ceed;
2452b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2460f58c348SJeremy L Thompson 
2472b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Memcheck));
2482b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Memcheck));
2492b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Memcheck));
2502b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Memcheck));
2512b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Memcheck));
2522b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Memcheck));
2532b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", CeedQFunctionContextRestoreData_Memcheck));
2542b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", CeedQFunctionContextRestoreDataRead_Memcheck));
2552b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", CeedQFunctionContextDataDestroy_Memcheck));
2562b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Memcheck));
2570f58c348SJeremy L Thompson 
2582b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
2592b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl));
2600f58c348SJeremy L Thompson 
2610f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2620f58c348SJeremy L Thompson }
2630f58c348SJeremy L Thompson //------------------------------------------------------------------------------
264