xref: /libCEED/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision 1c66c397a67401e1a222857807e6e5b7c45b88c0)
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;
212b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
220f58c348SJeremy L Thompson 
23*1c66c397SJeremy 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:
39*1c66c397SJeremy 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 
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 
890f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
900f58c348SJeremy L Thompson }
910f58c348SJeremy L Thompson 
920f58c348SJeremy L Thompson //------------------------------------------------------------------------------
930f58c348SJeremy L Thompson // QFunctionContext Take Data
940f58c348SJeremy L Thompson //------------------------------------------------------------------------------
952b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
960f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
972b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
980f58c348SJeremy L Thompson   Ceed ceed;
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 
1090f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1100f58c348SJeremy L Thompson }
1110f58c348SJeremy L Thompson 
1120f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1130f58c348SJeremy L Thompson // QFunctionContext Get Data
1140f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1152b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
1160f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1172b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1180f58c348SJeremy L Thompson   Ceed ceed;
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 
1250f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1260f58c348SJeremy L Thompson }
1270f58c348SJeremy L Thompson 
1280f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1298e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only
1308e457467SJeremy L Thompson //------------------------------------------------------------------------------
1312b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
1328e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1332b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1348e457467SJeremy L Thompson   size_t ctx_size;
1352b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1368e457467SJeremy L Thompson   Ceed ceed;
1372b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1388e457467SJeremy L Thompson 
1392b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data));
1408e457467SJeremy L Thompson 
141ea61e9acSJeremy L Thompson   // Make copy to verify no write occurred
1422b730f8bSJeremy L Thompson   CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->data_read_only_copy));
1438e457467SJeremy L Thompson   memcpy(impl->data_read_only_copy, *(void **)data, ctx_size);
1448e457467SJeremy L Thompson 
1458e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1468e457467SJeremy L Thompson }
1478e457467SJeremy L Thompson 
1488e457467SJeremy L Thompson //------------------------------------------------------------------------------
1490f58c348SJeremy L Thompson // QFunctionContext Restore Data
1500f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1510f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) {
1520f58c348SJeremy L Thompson   size_t ctx_size;
1532b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1540f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1552b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1560f58c348SJeremy L Thompson 
1570f58c348SJeremy L Thompson   if (impl->data_borrowed) {
1580f58c348SJeremy L Thompson     memcpy(impl->data_borrowed, impl->data, ctx_size);
1590f58c348SJeremy L Thompson   }
1600f58c348SJeremy L Thompson   if (impl->data_owned) {
1610f58c348SJeremy L Thompson     memcpy(impl->data_owned, impl->data, ctx_size);
1620f58c348SJeremy L Thompson   }
1630f58c348SJeremy L Thompson 
1640f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1650f58c348SJeremy L Thompson }
1660f58c348SJeremy L Thompson 
1670f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1688e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only
1698e457467SJeremy L Thompson //------------------------------------------------------------------------------
1702b730f8bSJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(CeedQFunctionContext ctx) {
1718e457467SJeremy L Thompson   size_t ctx_size;
1722b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
1738e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1742b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, (void *)&impl));
1758e457467SJeremy L Thompson   Ceed ceed;
1762b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1778e457467SJeremy L Thompson 
1786574a04fSJeremy L Thompson   CeedCheck(!memcmp(impl->data, impl->data_read_only_copy, ctx_size), ceed, CEED_ERROR_BACKEND,
1796574a04fSJeremy L Thompson             "Context data changed while accessed in read-only mode");
1808e457467SJeremy L Thompson 
1812b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_read_only_copy));
1828e457467SJeremy L Thompson 
1838e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1848e457467SJeremy L Thompson }
1858e457467SJeremy L Thompson 
1868e457467SJeremy L Thompson //------------------------------------------------------------------------------
1872e64a2b9SJeremy L Thompson // QFunctionContext destroy user data
1882e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
1892e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) {
1902e64a2b9SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1912b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1922e64a2b9SJeremy L Thompson   CeedQFunctionContextDataDestroyUser data_destroy_function;
1932e64a2b9SJeremy L Thompson   CeedMemType                         data_destroy_mem_type;
1942b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
1952e64a2b9SJeremy L Thompson   Ceed ceed;
1962b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1972e64a2b9SJeremy L Thompson 
1986574a04fSJeremy L Thompson   CeedCheck(data_destroy_mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only destroy HOST memory for this backend");
1992e64a2b9SJeremy L Thompson 
2002e64a2b9SJeremy L Thompson   if (data_destroy_function) {
2012b730f8bSJeremy L Thompson     CeedCallBackend(data_destroy_function(impl->data_borrowed ? impl->data_borrowed : impl->data_owned));
2022e64a2b9SJeremy L Thompson   }
2032b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
2042e64a2b9SJeremy L Thompson 
2052e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2062e64a2b9SJeremy L Thompson }
2072e64a2b9SJeremy L Thompson 
2082e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
2090f58c348SJeremy L Thompson // QFunctionContext Destroy
2100f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2110f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) {
2120f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2132b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2140f58c348SJeremy L Thompson 
2152b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_allocated));
2162b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->data_owned));
2172b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
2180f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2190f58c348SJeremy L Thompson }
2200f58c348SJeremy L Thompson 
2210f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2220f58c348SJeremy L Thompson // QFunctionContext Create
2230f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2240f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) {
2250f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2260f58c348SJeremy L Thompson   Ceed                           ceed;
2272b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2280f58c348SJeremy L Thompson 
2292b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Memcheck));
2302b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Memcheck));
2312b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Memcheck));
2322b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Memcheck));
2332b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Memcheck));
2342b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Memcheck));
2352b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData", CeedQFunctionContextRestoreData_Memcheck));
2362b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead", CeedQFunctionContextRestoreDataRead_Memcheck));
2372b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy", CeedQFunctionContextDataDestroy_Memcheck));
2382b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Memcheck));
2390f58c348SJeremy L Thompson 
2402b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
2412b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl));
2420f58c348SJeremy L Thompson 
2430f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2440f58c348SJeremy L Thompson }
2452a86cc9dSSebastian Grimberg 
2460f58c348SJeremy L Thompson //------------------------------------------------------------------------------
247