xref: /libCEED/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision 8e45746727b209a3fedd7b4b820ee2a9aeea7f9a)
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/ceed.h>
90f58c348SJeremy L Thompson #include <ceed/backend.h>
100f58c348SJeremy L Thompson #include <string.h>
110f58c348SJeremy L Thompson #include <valgrind/memcheck.h>
120f58c348SJeremy L Thompson #include "ceed-memcheck.h"
130f58c348SJeremy L Thompson 
140f58c348SJeremy L Thompson //------------------------------------------------------------------------------
150f58c348SJeremy L Thompson // QFunctionContext has valid data
160f58c348SJeremy L Thompson //------------------------------------------------------------------------------
170f58c348SJeremy L Thompson static int CeedQFunctionContextHasValidData_Memcheck(CeedQFunctionContext ctx,
180f58c348SJeremy L Thompson     bool *has_valid_data) {
190f58c348SJeremy L Thompson   int ierr;
200f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
210f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
220f58c348SJeremy L Thompson   CeedChkBackend(ierr);
230f58c348SJeremy L Thompson 
240f58c348SJeremy L Thompson   *has_valid_data = !!impl->data;
250f58c348SJeremy L Thompson 
260f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
270f58c348SJeremy L Thompson }
280f58c348SJeremy L Thompson 
290f58c348SJeremy L Thompson //------------------------------------------------------------------------------
300f58c348SJeremy L Thompson // QFunctionContext has borrowed data
310f58c348SJeremy L Thompson //------------------------------------------------------------------------------
320f58c348SJeremy L Thompson static int CeedQFunctionContextHasBorrowedDataOfType_Memcheck(
330f58c348SJeremy L Thompson   CeedQFunctionContext ctx, CeedMemType mem_type,
340f58c348SJeremy L Thompson   bool *has_borrowed_data_of_type) {
350f58c348SJeremy L Thompson   int ierr;
360f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
370f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
380f58c348SJeremy L Thompson   CeedChkBackend(ierr);
390f58c348SJeremy L Thompson   Ceed ceed;
400f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
410f58c348SJeremy L Thompson 
420f58c348SJeremy L Thompson   switch (mem_type) {
430f58c348SJeremy L Thompson   case CEED_MEM_HOST:
440f58c348SJeremy L Thompson     *has_borrowed_data_of_type = !!impl->data_borrowed;
450f58c348SJeremy L Thompson     break;
460f58c348SJeremy L Thompson   default:
470f58c348SJeremy L Thompson     // LCOV_EXCL_START
480f58c348SJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND,
490f58c348SJeremy L Thompson                      "Can only set HOST memory for this backend");
500f58c348SJeremy L Thompson     // LCOV_EXCL_STOP
510f58c348SJeremy L Thompson     break;
520f58c348SJeremy L Thompson   }
530f58c348SJeremy L Thompson 
540f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
550f58c348SJeremy L Thompson }
560f58c348SJeremy L Thompson 
570f58c348SJeremy L Thompson //------------------------------------------------------------------------------
580f58c348SJeremy L Thompson // QFunctionContext Set Data
590f58c348SJeremy L Thompson //------------------------------------------------------------------------------
600f58c348SJeremy L Thompson static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx,
610f58c348SJeremy L Thompson     CeedMemType mem_type, CeedCopyMode copy_mode, void *data) {
620f58c348SJeremy L Thompson   int ierr;
630f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
640f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
650f58c348SJeremy L Thompson   CeedChkBackend(ierr);
660f58c348SJeremy L Thompson   size_t ctx_size;
670f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr);
680f58c348SJeremy L Thompson   Ceed ceed;
690f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
700f58c348SJeremy L Thompson 
710f58c348SJeremy L Thompson   if (mem_type != CEED_MEM_HOST)
720f58c348SJeremy L Thompson     // LCOV_EXCL_START
730f58c348SJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND,
740f58c348SJeremy L Thompson                      "Can only set HOST memory for this backend");
750f58c348SJeremy L Thompson   // LCOV_EXCL_STOP
760f58c348SJeremy L Thompson 
770f58c348SJeremy L Thompson   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
780f58c348SJeremy L Thompson   ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr);
790f58c348SJeremy L Thompson   switch (copy_mode) {
800f58c348SJeremy L Thompson   case CEED_COPY_VALUES:
810f58c348SJeremy L Thompson     ierr = CeedMallocArray(1, ctx_size, &impl->data_owned); CeedChkBackend(ierr);
820f58c348SJeremy L Thompson     impl->data_borrowed = NULL;
830f58c348SJeremy L Thompson     impl->data = impl->data_owned;
840f58c348SJeremy L Thompson     memcpy(impl->data, data, ctx_size);
850f58c348SJeremy L Thompson     break;
860f58c348SJeremy L Thompson   case CEED_OWN_POINTER:
870f58c348SJeremy L Thompson     impl->data_owned = data;
880f58c348SJeremy L Thompson     impl->data_borrowed = NULL;
890f58c348SJeremy L Thompson     impl->data = data;
900f58c348SJeremy L Thompson     break;
910f58c348SJeremy L Thompson   case CEED_USE_POINTER:
920f58c348SJeremy L Thompson     impl->data_borrowed = data;
930f58c348SJeremy L Thompson     impl->data = data;
940f58c348SJeremy L Thompson   }
950f58c348SJeremy L Thompson   // Copy data to check ctx_size bounds
960f58c348SJeremy L Thompson   ierr = CeedMallocArray(1, ctx_size, &impl->data_allocated);
970f58c348SJeremy L Thompson   CeedChkBackend(ierr);
980f58c348SJeremy L Thompson   memcpy(impl->data_allocated, impl->data, ctx_size);
990f58c348SJeremy L Thompson   impl->data = impl->data_allocated;
1000f58c348SJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
1010f58c348SJeremy L Thompson   impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size,
1020f58c348SJeremy L Thompson                        "'QFunction backend context data copy'");
1030f58c348SJeremy L Thompson 
1040f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1050f58c348SJeremy L Thompson }
1060f58c348SJeremy L Thompson 
1070f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1080f58c348SJeremy L Thompson // QFunctionContext Take Data
1090f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1100f58c348SJeremy L Thompson static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx,
1110f58c348SJeremy L Thompson     CeedMemType mem_type, void *data) {
1120f58c348SJeremy L Thompson   int ierr;
1130f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1140f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
1150f58c348SJeremy L Thompson   CeedChkBackend(ierr);
1160f58c348SJeremy L Thompson   Ceed ceed;
1170f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
1180f58c348SJeremy L Thompson 
1190f58c348SJeremy L Thompson   if (mem_type != CEED_MEM_HOST)
1200f58c348SJeremy L Thompson     // LCOV_EXCL_START
1210f58c348SJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND,
1220f58c348SJeremy L Thompson                      "Can only provide HOST memory for this backend");
1230f58c348SJeremy L Thompson   // LCOV_EXCL_STOP
1240f58c348SJeremy L Thompson 
1250f58c348SJeremy L Thompson   *(void **)data = impl->data_borrowed;
1260f58c348SJeremy L Thompson   impl->data_borrowed = NULL;
1270f58c348SJeremy L Thompson   impl->data = NULL;
1280f58c348SJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
1290f58c348SJeremy L Thompson   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
1300f58c348SJeremy L Thompson 
1310f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1320f58c348SJeremy L Thompson }
1330f58c348SJeremy L Thompson 
1340f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1350f58c348SJeremy L Thompson // QFunctionContext Get Data
1360f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1370f58c348SJeremy L Thompson static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx,
1380f58c348SJeremy L Thompson     CeedMemType mem_type, void *data) {
1390f58c348SJeremy L Thompson   int ierr;
1400f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1410f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
1420f58c348SJeremy L Thompson   CeedChkBackend(ierr);
1430f58c348SJeremy L Thompson   Ceed ceed;
1440f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
1450f58c348SJeremy L Thompson 
1460f58c348SJeremy L Thompson   if (mem_type != CEED_MEM_HOST)
1470f58c348SJeremy L Thompson     // LCOV_EXCL_START
1480f58c348SJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND,
1490f58c348SJeremy L Thompson                      "Can only provide HOST memory for this backend");
1500f58c348SJeremy L Thompson   // LCOV_EXCL_STOP
1510f58c348SJeremy L Thompson 
1520f58c348SJeremy L Thompson   *(void **)data = impl->data;
1530f58c348SJeremy L Thompson 
1540f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1550f58c348SJeremy L Thompson }
1560f58c348SJeremy L Thompson 
1570f58c348SJeremy L Thompson //------------------------------------------------------------------------------
158*8e457467SJeremy L Thompson // QFunctionContext Get Data Read-Only
159*8e457467SJeremy L Thompson //------------------------------------------------------------------------------
160*8e457467SJeremy L Thompson static int CeedQFunctionContextGetDataRead_Memcheck(CeedQFunctionContext ctx,
161*8e457467SJeremy L Thompson     CeedMemType mem_type, void *data) {
162*8e457467SJeremy L Thompson   int ierr;
163*8e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
164*8e457467SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
165*8e457467SJeremy L Thompson   CeedChkBackend(ierr);
166*8e457467SJeremy L Thompson   size_t ctx_size;
167*8e457467SJeremy L Thompson   ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr);
168*8e457467SJeremy L Thompson   Ceed ceed;
169*8e457467SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
170*8e457467SJeremy L Thompson 
171*8e457467SJeremy L Thompson   ierr = CeedQFunctionContextGetData_Memcheck(ctx, mem_type, data);
172*8e457467SJeremy L Thompson   CeedChkBackend(ierr);
173*8e457467SJeremy L Thompson 
174*8e457467SJeremy L Thompson   // Make copy to verify no write occured
175*8e457467SJeremy L Thompson   ierr = CeedMallocArray(1, ctx_size, &impl->data_read_only_copy);
176*8e457467SJeremy L Thompson   CeedChkBackend(ierr);
177*8e457467SJeremy L Thompson   memcpy(impl->data_read_only_copy, *(void **)data, ctx_size);
178*8e457467SJeremy L Thompson 
179*8e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
180*8e457467SJeremy L Thompson }
181*8e457467SJeremy L Thompson 
182*8e457467SJeremy L Thompson //------------------------------------------------------------------------------
1830f58c348SJeremy L Thompson // QFunctionContext Restore Data
1840f58c348SJeremy L Thompson //------------------------------------------------------------------------------
1850f58c348SJeremy L Thompson static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) {
1860f58c348SJeremy L Thompson   int ierr;
1870f58c348SJeremy L Thompson   size_t ctx_size;
1880f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr);
1890f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
1900f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
1910f58c348SJeremy L Thompson   CeedChkBackend(ierr);
1920f58c348SJeremy L Thompson 
1930f58c348SJeremy L Thompson   if (impl->data_borrowed) {
1940f58c348SJeremy L Thompson     memcpy(impl->data_borrowed, impl->data, ctx_size);
1950f58c348SJeremy L Thompson   }
1960f58c348SJeremy L Thompson   if (impl->data_owned) {
1970f58c348SJeremy L Thompson     memcpy(impl->data_owned, impl->data, ctx_size);
1980f58c348SJeremy L Thompson   }
1990f58c348SJeremy L Thompson 
2000f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2010f58c348SJeremy L Thompson }
2020f58c348SJeremy L Thompson 
2030f58c348SJeremy L Thompson //------------------------------------------------------------------------------
204*8e457467SJeremy L Thompson // QFunctionContext Restore Data Read-Only
205*8e457467SJeremy L Thompson //------------------------------------------------------------------------------
206*8e457467SJeremy L Thompson static int CeedQFunctionContextRestoreDataRead_Memcheck(
207*8e457467SJeremy L Thompson   CeedQFunctionContext ctx) {
208*8e457467SJeremy L Thompson   int ierr;
209*8e457467SJeremy L Thompson   size_t ctx_size;
210*8e457467SJeremy L Thompson   ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr);
211*8e457467SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
212*8e457467SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
213*8e457467SJeremy L Thompson   CeedChkBackend(ierr);
214*8e457467SJeremy L Thompson   Ceed ceed;
215*8e457467SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
216*8e457467SJeremy L Thompson 
217*8e457467SJeremy L Thompson   if (memcmp(impl->data, impl->data_read_only_copy, ctx_size))
218*8e457467SJeremy L Thompson     // LCOV_EXCL_START
219*8e457467SJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND,
220*8e457467SJeremy L Thompson                      "Context data changed while accessed in read-only mode");
221*8e457467SJeremy L Thompson   // LCOV_EXCL_STOP
222*8e457467SJeremy L Thompson 
223*8e457467SJeremy L Thompson   ierr = CeedFree(&impl->data_read_only_copy);
224*8e457467SJeremy L Thompson 
225*8e457467SJeremy L Thompson   return CEED_ERROR_SUCCESS;
226*8e457467SJeremy L Thompson }
227*8e457467SJeremy L Thompson 
228*8e457467SJeremy L Thompson //------------------------------------------------------------------------------
2292e64a2b9SJeremy L Thompson // QFunctionContext destroy user data
2302e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
2312e64a2b9SJeremy L Thompson static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) {
2322e64a2b9SJeremy L Thompson   int ierr;
2332e64a2b9SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2342e64a2b9SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr);
2352e64a2b9SJeremy L Thompson   CeedQFunctionContextDataDestroyUser data_destroy_function;
2362e64a2b9SJeremy L Thompson   CeedMemType data_destroy_mem_type;
2372e64a2b9SJeremy L Thompson   ierr = CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type,
2382e64a2b9SJeremy L Thompson          &data_destroy_function); CeedChk(ierr);
2392e64a2b9SJeremy L Thompson   Ceed ceed;
2402e64a2b9SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
2412e64a2b9SJeremy L Thompson 
2422e64a2b9SJeremy L Thompson   if (data_destroy_mem_type != CEED_MEM_HOST)
2432e64a2b9SJeremy L Thompson     // LCOV_EXCL_START
2442e64a2b9SJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND,
2452e64a2b9SJeremy L Thompson                      "Can only destroy HOST memory for this backend");
2462e64a2b9SJeremy L Thompson   // LCOV_EXCL_STOP
2472e64a2b9SJeremy L Thompson 
2482e64a2b9SJeremy L Thompson   if (data_destroy_function) {
2492e64a2b9SJeremy L Thompson     ierr = data_destroy_function(impl->data_borrowed ? impl->data_borrowed :
2502e64a2b9SJeremy L Thompson                                  impl->data_owned); CeedChk(ierr);
2512e64a2b9SJeremy L Thompson   }
2522e64a2b9SJeremy L Thompson   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
2532e64a2b9SJeremy L Thompson 
2542e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2552e64a2b9SJeremy L Thompson }
2562e64a2b9SJeremy L Thompson 
2572e64a2b9SJeremy L Thompson //------------------------------------------------------------------------------
2580f58c348SJeremy L Thompson // QFunctionContext Destroy
2590f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2600f58c348SJeremy L Thompson static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) {
2610f58c348SJeremy L Thompson   int ierr;
2620f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2630f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr);
2640f58c348SJeremy L Thompson 
2650f58c348SJeremy L Thompson   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
2660f58c348SJeremy L Thompson   ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr);
2670f58c348SJeremy L Thompson   ierr = CeedFree(&impl); CeedChkBackend(ierr);
2680f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2690f58c348SJeremy L Thompson }
2700f58c348SJeremy L Thompson 
2710f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2720f58c348SJeremy L Thompson // QFunctionContext Create
2730f58c348SJeremy L Thompson //------------------------------------------------------------------------------
2740f58c348SJeremy L Thompson int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) {
2750f58c348SJeremy L Thompson   int ierr;
2760f58c348SJeremy L Thompson   CeedQFunctionContext_Memcheck *impl;
2770f58c348SJeremy L Thompson   Ceed ceed;
2780f58c348SJeremy L Thompson   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
2790f58c348SJeremy L Thompson 
2800f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData",
2810f58c348SJeremy L Thompson                                 CeedQFunctionContextHasValidData_Memcheck);
2820f58c348SJeremy L Thompson   CeedChkBackend(ierr);
2830f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx,
2840f58c348SJeremy L Thompson                                 "HasBorrowedDataOfType",
2850f58c348SJeremy L Thompson                                 CeedQFunctionContextHasBorrowedDataOfType_Memcheck);
2860f58c348SJeremy L Thompson   CeedChkBackend(ierr);
2870f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData",
2880f58c348SJeremy L Thompson                                 CeedQFunctionContextSetData_Memcheck); CeedChkBackend(ierr);
2890f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData",
2900f58c348SJeremy L Thompson                                 CeedQFunctionContextTakeData_Memcheck); CeedChkBackend(ierr);
2910f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData",
2920f58c348SJeremy L Thompson                                 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr);
2930f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead",
294*8e457467SJeremy L Thompson                                 CeedQFunctionContextGetDataRead_Memcheck); CeedChkBackend(ierr);
2950f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData",
2960f58c348SJeremy L Thompson                                 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr);
2970f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead",
298*8e457467SJeremy L Thompson                                 CeedQFunctionContextRestoreDataRead_Memcheck); CeedChkBackend(ierr);
2992e64a2b9SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy",
3002e64a2b9SJeremy L Thompson                                 CeedQFunctionContextDataDestroy_Memcheck); CeedChkBackend(ierr);
3010f58c348SJeremy L Thompson   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy",
3020f58c348SJeremy L Thompson                                 CeedQFunctionContextDestroy_Memcheck); CeedChkBackend(ierr);
3030f58c348SJeremy L Thompson 
3040f58c348SJeremy L Thompson   ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr);
3050f58c348SJeremy L Thompson   ierr = CeedQFunctionContextSetBackendData(ctx, impl); CeedChkBackend(ierr);
3060f58c348SJeremy L Thompson 
3070f58c348SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3080f58c348SJeremy L Thompson }
3090f58c348SJeremy L Thompson //------------------------------------------------------------------------------
310