xref: /libCEED/rust/libceed-sys/c-src/backends/memcheck/ceed-memcheck-qfunction.c (revision 2bf66f3ba75e883c03ae18c8a6b7ba12e94847f2)
15aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3fc7cf9a0Sjeremylt //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5fc7cf9a0Sjeremylt //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
7fc7cf9a0Sjeremylt 
849aac155SJeremy L Thompson #include <ceed.h>
9ec3da8bcSJed Brown #include <ceed/backend.h>
108811b53cSJeremy L Thompson #include <math.h>
1149aac155SJeremy L Thompson #include <stdio.h>
123d576824SJeremy L Thompson #include <valgrind/memcheck.h>
132b730f8bSJeremy L Thompson 
14fc7cf9a0Sjeremylt #include "ceed-memcheck.h"
15fc7cf9a0Sjeremylt 
16f10650afSjeremylt //------------------------------------------------------------------------------
17f10650afSjeremylt // QFunction Apply
18f10650afSjeremylt //------------------------------------------------------------------------------
192b730f8bSJeremy L Thompson static int CeedQFunctionApply_Memcheck(CeedQFunction qf, CeedInt Q, CeedVector *U, CeedVector *V) {
208811b53cSJeremy L Thompson   Ceed                    ceed;
21fb02a165SJeremy L Thompson   void                   *ctx_data = NULL;
223345ba21SJeremy L Thompson   int                     input_block_ids[CEED_FIELD_MAX], output_block_ids[CEED_FIELD_MAX];
23d1d35e2fSjeremylt   CeedInt                 num_in, num_out;
24ad70ee2cSJeremy L Thompson   CeedQFunctionUser       f = NULL;
2551d50b59SJeremy L Thompson   CeedQFunctionField     *output_fields;
26ad70ee2cSJeremy L Thompson   CeedQFunction_Memcheck *impl;
27ad70ee2cSJeremy L Thompson 
28ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedQFunctionGetCeed(qf, &ceed));
29ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedQFunctionGetData(qf, &impl));
30ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedQFunctionGetContextData(qf, CEED_MEM_HOST, &ctx_data));
31ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedQFunctionGetUserFunction(qf, &f));
322b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionGetNumArgs(qf, &num_in, &num_out));
33fc7cf9a0Sjeremylt 
343345ba21SJeremy L Thompson   // Get input arrays
35edc819a1SJeremy L Thompson   for (CeedInt i = 0; i < num_in; i++) {
363345ba21SJeremy L Thompson     CeedSize len;
373345ba21SJeremy L Thompson     char     name[32] = "";
383345ba21SJeremy L Thompson 
392b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetArrayRead(U[i], CEED_MEM_HOST, &impl->inputs[i]));
403345ba21SJeremy L Thompson 
413345ba21SJeremy L Thompson     CeedCallBackend(CeedVectorGetLength(U[i], &len));
423345ba21SJeremy L Thompson 
433345ba21SJeremy L Thompson     snprintf(name, 32, "QFunction input %" CeedInt_FMT, i);
443345ba21SJeremy L Thompson     input_block_ids[i] = VALGRIND_CREATE_BLOCK(impl->inputs[i], len, name);
45fc7cf9a0Sjeremylt   }
463345ba21SJeremy L Thompson 
473345ba21SJeremy L Thompson   // Get output arrays
48edc819a1SJeremy L Thompson   for (CeedInt i = 0; i < num_out; i++) {
49edc819a1SJeremy L Thompson     CeedSize len;
508e6aa226SJed Brown     char     name[32] = "";
51edc819a1SJeremy L Thompson 
522b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetArrayWrite(V[i], CEED_MEM_HOST, &impl->outputs[i]));
53edc819a1SJeremy L Thompson 
542b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetLength(V[i], &len));
55fc7cf9a0Sjeremylt     VALGRIND_MAKE_MEM_UNDEFINED(impl->outputs[i], len);
56edc819a1SJeremy L Thompson 
573345ba21SJeremy L Thompson     snprintf(name, 32, "QFunction output %" CeedInt_FMT, i);
583345ba21SJeremy L Thompson     output_block_ids[i] = VALGRIND_CREATE_BLOCK(impl->outputs[i], len, name);
59fc7cf9a0Sjeremylt   }
60fc7cf9a0Sjeremylt 
6151d50b59SJeremy L Thompson   // Call user function
622b730f8bSJeremy L Thompson   CeedCallBackend(f(ctx_data, Q, impl->inputs, impl->outputs));
63fc7cf9a0Sjeremylt 
6451d50b59SJeremy L Thompson   // Restore input arrays
65edc819a1SJeremy L Thompson   for (CeedInt i = 0; i < num_in; i++) {
662b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorRestoreArrayRead(U[i], &impl->inputs[i]));
673345ba21SJeremy L Thompson     VALGRIND_DISCARD(input_block_ids[i]);
68fc7cf9a0Sjeremylt   }
693345ba21SJeremy L Thompson 
703345ba21SJeremy L Thompson   // Check for unset output values and restore arrays
71739ab3b4SJames Wright   {
7234ffed21SJeremy L Thompson     const char *kernel_name, *kernel_path;
73739ab3b4SJames Wright 
74739ab3b4SJames Wright     CeedCallBackend(CeedQFunctionGetSourcePath(qf, &kernel_path));
75739ab3b4SJames Wright     CeedCallBackend(CeedQFunctionGetKernelName(qf, &kernel_name));
7651d50b59SJeremy L Thompson     CeedCallBackend(CeedQFunctionGetFields(qf, NULL, NULL, NULL, &output_fields));
77edc819a1SJeremy L Thompson     for (CeedInt i = 0; i < num_out; i++) {
78*2bf66f3bSJeremy L Thompson       const char *field_name;
7951d50b59SJeremy L Thompson       CeedInt     field_size;
808811b53cSJeremy L Thompson 
8151d50b59SJeremy L Thompson       // Note: need field size because vector may be longer than needed for output
8251d50b59SJeremy L Thompson       CeedCallBackend(CeedQFunctionFieldGetSize(output_fields[i], &field_size));
83*2bf66f3bSJeremy L Thompson       CeedCallBackend(CeedQFunctionFieldGetName(output_fields[i], &field_name));
84249f8407SJeremy L Thompson       for (CeedSize j = 0; j < field_size * (CeedSize)Q; j++) {
85739ab3b4SJames Wright         CeedCheck(!isnan(impl->outputs[i][j]), ceed, CEED_ERROR_BACKEND,
86*2bf66f3bSJeremy L Thompson                   "QFunction output %" CeedInt_FMT " '%s' entry %" CeedSize_FMT " is NaN after restoring write-only access: %s:%s ", i, field_name, j,
87*2bf66f3bSJeremy L Thompson                   kernel_path, kernel_name);
888811b53cSJeremy L Thompson       }
892b730f8bSJeremy L Thompson       CeedCallBackend(CeedVectorRestoreArray(V[i], &impl->outputs[i]));
903345ba21SJeremy L Thompson       VALGRIND_DISCARD(output_block_ids[i]);
91fc7cf9a0Sjeremylt     }
92739ab3b4SJames Wright   }
932b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionRestoreContextData(qf, &ctx_data));
94e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
95fc7cf9a0Sjeremylt }
96fc7cf9a0Sjeremylt 
97f10650afSjeremylt //------------------------------------------------------------------------------
98f10650afSjeremylt // QFunction Destroy
99f10650afSjeremylt //------------------------------------------------------------------------------
100fc7cf9a0Sjeremylt static int CeedQFunctionDestroy_Memcheck(CeedQFunction qf) {
101fc7cf9a0Sjeremylt   CeedQFunction_Memcheck *impl;
102fc7cf9a0Sjeremylt 
1039a25c351SJeremy L Thompson   CeedCallBackend(CeedQFunctionGetData(qf, &impl));
1042b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->inputs));
1052b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->outputs));
1062b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
107e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
108fc7cf9a0Sjeremylt }
109fc7cf9a0Sjeremylt 
110f10650afSjeremylt //------------------------------------------------------------------------------
111f10650afSjeremylt // QFunction Create
112f10650afSjeremylt //------------------------------------------------------------------------------
113fc7cf9a0Sjeremylt int CeedQFunctionCreate_Memcheck(CeedQFunction qf) {
114fc7cf9a0Sjeremylt   Ceed                    ceed;
115fc7cf9a0Sjeremylt   CeedQFunction_Memcheck *impl;
116ad70ee2cSJeremy L Thompson 
117ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedQFunctionGetCeed(qf, &ceed));
1182b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
1192b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(CEED_FIELD_MAX, &impl->inputs));
1202b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(CEED_FIELD_MAX, &impl->outputs));
1212b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionSetData(qf, impl));
1222b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunction", qf, "Apply", CeedQFunctionApply_Memcheck));
1232b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunction", qf, "Destroy", CeedQFunctionDestroy_Memcheck));
124e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
125fc7cf9a0Sjeremylt }
1262a86cc9dSSebastian Grimberg 
127f10650afSjeremylt //------------------------------------------------------------------------------
128