xref: /libCEED/rust/libceed-sys/c-src/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision 49aac155e7a09736f56fb3abac0f57dab29f7cbf)
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 
8*49aac155SJeremy L Thompson #include <ceed.h>
90f58c348SJeremy L Thompson #include <ceed/backend.h>
10*49aac155SJeremy 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;
212b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
220f58c348SJeremy L Thompson 
230f58c348SJeremy L Thompson   *has_valid_data = !!impl->data;
240f58c348SJeremy L Thompson 
250f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
260f58c348SJeremy L Thompson }
270f58c348SJeremy L Thompson 
280f58c348SJeremy L Thompson //------------------------------------------------------------------------------
290f58c348SJeremy L Thompson // QFunctionContext has borrowed data
300f58c348SJeremy L Thompson //------------------------------------------------------------------------------
312b730f8bSJeremy L Thompson static int CeedQFunctionContextHasBorrowedDataOfType_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) {
320f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
332b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
340f58c348SJeremy L Thompson   Ceed ceed;
352b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
360f58c348SJeremy L Thompson 
370f58c348SJeremy L Thompson   switch (mem_type) {
380f58c348SJeremy L Thompson     case CEED_MEM_HOST:
390f58c348SJeremy 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 
480f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
490f58c348SJeremy L Thompson }
500f58c348SJeremy L Thompson 
510f58c348SJeremy L Thompson //------------------------------------------------------------------------------
520f58c348SJeremy L Thompson // QFunctionContext Set Data
530f58c348SJeremy L Thompson //------------------------------------------------------------------------------
542b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, void *data) {
550f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
562b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
570f58c348SJeremy L Thompson   size_t ctx_size;
582b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
590f58c348SJeremy L Thompson   Ceed ceed;
602b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
610f58c348SJeremy L Thompson 
622b730f8bSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
630f58c348SJeremy L Thompson     // LCOV_EXCL_START
642b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend");
650f58c348SJeremy L Thompson     // LCOV_EXCL_STOP
662b730f8bSJeremy L Thompson   }
670f58c348SJeremy L Thompson 
682b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
692b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_owned));
700f58c348SJeremy L Thompson   switch (copy_mode) {
710f58c348SJeremy L Thompson     case CEED_COPY_VALUES:
722b730f8bSJeremy L Thompson       CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_owned));
730f58c348SJeremy L Thompson       impl->data_borrowed = NULL;
740f58c348SJeremy L Thompson       impl->data          = impl->data_owned;
750f58c348SJeremy L Thompson       memcpy(impl->data, data, ctx_size);
760f58c348SJeremy L Thompson       break;
770f58c348SJeremy L Thompson     case CEED_OWN_POINTER:
780f58c348SJeremy L Thompson       impl->data_owned    = data;
790f58c348SJeremy L Thompson       impl->data_borrowed = NULL;
800f58c348SJeremy L Thompson       impl->data          = data;
810f58c348SJeremy L Thompson       break;
820f58c348SJeremy L Thompson     case CEED_USE_POINTER:
830f58c348SJeremy L Thompson       impl->data_borrowed = data;
840f58c348SJeremy L Thompson       impl->data          = data;
850f58c348SJeremy L Thompson   }
860f58c348SJeremy L Thompson   // Copy data to check ctx_size bounds
872b730f8bSJeremy L Thompson   CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_allocated));
880f58c348SJeremy L Thompson   memcpy(impl->data_allocated, impl->data, ctx_size);
890f58c348SJeremy L Thompson   impl->data = impl->data_allocated;
900f58c348SJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
912b730f8bSJeremy L Thompson   impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size, "'QFunction backend context data copy'");
920f58c348SJeremy L Thompson 
930f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
940f58c348SJeremy L Thompson }
950f58c348SJeremy L Thompson 
960f58c348SJeremy L Thompson //------------------------------------------------------------------------------
970f58c348SJeremy L Thompson // QFunctionContext Take Data
980f58c348SJeremy L Thompson //------------------------------------------------------------------------------
992b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
1000f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1012b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1020f58c348SJeremy L Thompson   Ceed ceed;
1032b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1040f58c348SJeremy L Thompson 
1052b730f8bSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
1060f58c348SJeremy L Thompson     // LCOV_EXCL_START
1072b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
1080f58c348SJeremy L Thompson     // LCOV_EXCL_STOP
1092b730f8bSJeremy L Thompson   }
1100f58c348SJeremy L Thompson 
1110f58c348SJeremy L Thompson   *(void **)data      = impl->data_borrowed;
1120f58c348SJeremy L Thompson   impl->data_borrowed = NULL;
1130f58c348SJeremy L Thompson   impl->data          = NULL;
1140f58c348SJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
1152b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
1160f58c348SJeremy L Thompson 
1170f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1180f58c348SJeremy L Thompson }
1190f58c348SJeremy L Thompson 
1200f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1210f58c348SJeremy L Thompson // QFunctionContext Get Data
1220f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1232b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
1240f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1252b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1260f58c348SJeremy L Thompson   Ceed ceed;
1272b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1280f58c348SJeremy L Thompson 
1292b730f8bSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
1300f58c348SJeremy L Thompson     // LCOV_EXCL_START
1312b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
1320f58c348SJeremy L Thompson     // LCOV_EXCL_STOP
1332b730f8bSJeremy L Thompson   }
1340f58c348SJeremy L Thompson 
1350f58c348SJeremy L Thompson   *(void **)data = impl->data;
1360f58c348SJeremy L Thompson 
1370f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1380f58c348SJeremy L Thompson }
1390f58c348SJeremy L Thompson 
1400f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1418e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only
1428e457467SJeremy L Thompson //------------------------------------------------------------------------------
1432b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
1448e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1452b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1468e457467SJeremy L Thompson   size_t ctx_size;
1472b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1488e457467SJeremy L Thompson   Ceed ceed;
1492b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1508e457467SJeremy L Thompson 
1512b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data));
1528e457467SJeremy L Thompson 
153ea61e9acSJeremy L Thompson   // Make copy to verify no write occurred
1542b730f8bSJeremy L Thompson   CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_read_only_copy));
1558e457467SJeremy L Thompson   memcpy(impl->data_read_only_copy, *(void **)data, ctx_size);
1568e457467SJeremy L Thompson 
1578e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1588e457467SJeremy L Thompson }
1598e457467SJeremy L Thompson 
1608e457467SJeremy L Thompson //------------------------------------------------------------------------------
1610f58c348SJeremy L Thompson // QFunctionContext Restore Data
1620f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1630f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) {
1640f58c348SJeremy L Thompson   size_t ctx_size;
1652b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1660f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1672b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1680f58c348SJeremy L Thompson 
1690f58c348SJeremy L Thompson   if (impl->data_borrowed) {
1700f58c348SJeremy L Thompson     memcpy(impl->data_borrowed, impl->data, ctx_size);
1710f58c348SJeremy L Thompson   }
1720f58c348SJeremy L Thompson   if (impl->data_owned) {
1730f58c348SJeremy L Thompson     memcpy(impl->data_owned, impl->data, ctx_size);
1740f58c348SJeremy L Thompson   }
1750f58c348SJeremy L Thompson 
1760f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1770f58c348SJeremy L Thompson }
1780f58c348SJeremy L Thompson 
1790f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1808e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only
1818e457467SJeremy L Thompson //------------------------------------------------------------------------------
1822b730f8bSJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(CeedQFunctionContext ctx) {
1838e457467SJeremy L Thompson   size_t ctx_size;
1842b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1858e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1862b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1878e457467SJeremy L Thompson   Ceed ceed;
1882b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1898e457467SJeremy L Thompson 
1902b730f8bSJeremy L Thompson   if (memcmp(impl->data, impl->data_read_only_copy, ctx_size)) {
1918e457467SJeremy L Thompson     // LCOV_EXCL_START
1922b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Context data changed while accessed in read-only mode");
1938e457467SJeremy L Thompson     // LCOV_EXCL_STOP
1942b730f8bSJeremy L Thompson   }
1958e457467SJeremy L Thompson 
1962b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_read_only_copy));
1978e457467SJeremy L Thompson 
1988e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1998e457467SJeremy L Thompson }
2008e457467SJeremy L Thompson 
2018e457467SJeremy L Thompson //------------------------------------------------------------------------------
2022e64a2b9SJeremy L Thompson // QFunctionContext destroy user data
2032e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
2042e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) {
2052e64a2b9SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2062b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2072e64a2b9SJeremy L Thompson   CeedQFunctionContextDataDestroyUser data_destroy_function;
2082e64a2b9SJeremy L Thompson   CeedMemType                         data_destroy_mem_type;
2092b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
2102e64a2b9SJeremy L Thompson   Ceed ceed;
2112b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2122e64a2b9SJeremy L Thompson 
2132b730f8bSJeremy L Thompson   if (data_destroy_mem_type != CEED_MEM_HOST) {
2142e64a2b9SJeremy L Thompson     // LCOV_EXCL_START
2152b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only destroy HOST memory for this backend");
2162e64a2b9SJeremy L Thompson     // LCOV_EXCL_STOP
2172b730f8bSJeremy L Thompson   }
2182e64a2b9SJeremy L Thompson 
2192e64a2b9SJeremy L Thompson   if (data_destroy_function) {
2202b730f8bSJeremy L Thompson     CeedCallBackend(data_destroy_function(impl->data_borrowed ? impl->data_borrowed : impl->data_owned));
2212e64a2b9SJeremy L Thompson   }
2222b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
2232e64a2b9SJeremy L Thompson 
2242e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2252e64a2b9SJeremy L Thompson }
2262e64a2b9SJeremy L Thompson 
2272e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
2280f58c348SJeremy L Thompson // QFunctionContext Destroy
2290f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2300f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) {
2310f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2322b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2330f58c348SJeremy L Thompson 
2342b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
2352b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_owned));
2362b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
2370f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2380f58c348SJeremy L Thompson }
2390f58c348SJeremy L Thompson 
2400f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2410f58c348SJeremy L Thompson // QFunctionContext Create
2420f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2430f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) {
2440f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2450f58c348SJeremy L Thompson   Ceed                           ceed;
2462b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2470f58c348SJeremy L Thompson 
2482b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Memcheck));
2492b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Memcheck));
2502b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Memcheck));
2512b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Memcheck));
2522b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Memcheck));
2532b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Memcheck));
2542b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", CeedQFunctionContextRestoreData_Memcheck));
2552b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", CeedQFunctionContextRestoreDataRead_Memcheck));
2562b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", CeedQFunctionContextDataDestroy_Memcheck));
2572b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Memcheck));
2580f58c348SJeremy L Thompson 
2592b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
2602b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl));
2610f58c348SJeremy L Thompson 
2620f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2630f58c348SJeremy L Thompson }
2640f58c348SJeremy L Thompson //------------------------------------------------------------------------------
265