1*9ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, 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 //------------------------------------------------------------------------------
CeedQFunctionApply_Memcheck(CeedQFunction qf,CeedInt Q,CeedVector * U,CeedVector * V)192b730f8bSJeremy L Thompson static int CeedQFunctionApply_Memcheck(CeedQFunction qf, CeedInt Q, CeedVector *U, CeedVector *V) {
20fb02a165SJeremy L Thompson void *ctx_data = NULL;
213345ba21SJeremy L Thompson int input_block_ids[CEED_FIELD_MAX], output_block_ids[CEED_FIELD_MAX];
22d1d35e2fSjeremylt CeedInt num_in, num_out;
23ad70ee2cSJeremy L Thompson CeedQFunctionUser f = NULL;
2451d50b59SJeremy L Thompson CeedQFunctionField *output_fields;
25ad70ee2cSJeremy L Thompson CeedQFunction_Memcheck *impl;
26ad70ee2cSJeremy L Thompson
27ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionGetData(qf, &impl));
28ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionGetContextData(qf, CEED_MEM_HOST, &ctx_data));
29ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionGetUserFunction(qf, &f));
302b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionGetNumArgs(qf, &num_in, &num_out));
31fc7cf9a0Sjeremylt
323345ba21SJeremy L Thompson // Get input arrays
33edc819a1SJeremy L Thompson for (CeedInt i = 0; i < num_in; i++) {
343345ba21SJeremy L Thompson CeedSize len;
353345ba21SJeremy L Thompson char name[32] = "";
363345ba21SJeremy L Thompson
372b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetArrayRead(U[i], CEED_MEM_HOST, &impl->inputs[i]));
383345ba21SJeremy L Thompson
393345ba21SJeremy L Thompson CeedCallBackend(CeedVectorGetLength(U[i], &len));
403345ba21SJeremy L Thompson
413345ba21SJeremy L Thompson snprintf(name, 32, "QFunction input %" CeedInt_FMT, i);
423345ba21SJeremy L Thompson input_block_ids[i] = VALGRIND_CREATE_BLOCK(impl->inputs[i], len, name);
43fc7cf9a0Sjeremylt }
443345ba21SJeremy L Thompson
453345ba21SJeremy L Thompson // Get output arrays
46edc819a1SJeremy L Thompson for (CeedInt i = 0; i < num_out; i++) {
47edc819a1SJeremy L Thompson CeedSize len;
488e6aa226SJed Brown char name[32] = "";
49edc819a1SJeremy L Thompson
502b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetArrayWrite(V[i], CEED_MEM_HOST, &impl->outputs[i]));
51edc819a1SJeremy L Thompson
522b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(V[i], &len));
53fc7cf9a0Sjeremylt VALGRIND_MAKE_MEM_UNDEFINED(impl->outputs[i], len);
54edc819a1SJeremy L Thompson
553345ba21SJeremy L Thompson snprintf(name, 32, "QFunction output %" CeedInt_FMT, i);
563345ba21SJeremy L Thompson output_block_ids[i] = VALGRIND_CREATE_BLOCK(impl->outputs[i], len, name);
57fc7cf9a0Sjeremylt }
58fc7cf9a0Sjeremylt
5951d50b59SJeremy L Thompson // Call user function
602b730f8bSJeremy L Thompson CeedCallBackend(f(ctx_data, Q, impl->inputs, impl->outputs));
61fc7cf9a0Sjeremylt
6251d50b59SJeremy L Thompson // Restore input arrays
63edc819a1SJeremy L Thompson for (CeedInt i = 0; i < num_in; i++) {
642b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorRestoreArrayRead(U[i], &impl->inputs[i]));
653345ba21SJeremy L Thompson VALGRIND_DISCARD(input_block_ids[i]);
66fc7cf9a0Sjeremylt }
673345ba21SJeremy L Thompson
683345ba21SJeremy L Thompson // Check for unset output values and restore arrays
69739ab3b4SJames Wright {
7034ffed21SJeremy L Thompson const char *kernel_name, *kernel_path;
71739ab3b4SJames Wright
72739ab3b4SJames Wright CeedCallBackend(CeedQFunctionGetSourcePath(qf, &kernel_path));
73739ab3b4SJames Wright CeedCallBackend(CeedQFunctionGetKernelName(qf, &kernel_name));
7451d50b59SJeremy L Thompson CeedCallBackend(CeedQFunctionGetFields(qf, NULL, NULL, NULL, &output_fields));
75edc819a1SJeremy L Thompson for (CeedInt i = 0; i < num_out; i++) {
762bf66f3bSJeremy L Thompson const char *field_name;
7751d50b59SJeremy L Thompson CeedInt field_size;
788811b53cSJeremy L Thompson
7951d50b59SJeremy L Thompson // Note: need field size because vector may be longer than needed for output
8051d50b59SJeremy L Thompson CeedCallBackend(CeedQFunctionFieldGetSize(output_fields[i], &field_size));
812bf66f3bSJeremy L Thompson CeedCallBackend(CeedQFunctionFieldGetName(output_fields[i], &field_name));
82249f8407SJeremy L Thompson for (CeedSize j = 0; j < field_size * (CeedSize)Q; j++) {
839bc66399SJeremy L Thompson CeedCheck(!isnan(impl->outputs[i][j]), CeedQFunctionReturnCeed(qf), CEED_ERROR_BACKEND,
842bf66f3bSJeremy L Thompson "QFunction output %" CeedInt_FMT " '%s' entry %" CeedSize_FMT " is NaN after restoring write-only access: %s:%s ", i, field_name, j,
852bf66f3bSJeremy L Thompson kernel_path, kernel_name);
868811b53cSJeremy L Thompson }
872b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorRestoreArray(V[i], &impl->outputs[i]));
883345ba21SJeremy L Thompson VALGRIND_DISCARD(output_block_ids[i]);
89fc7cf9a0Sjeremylt }
90739ab3b4SJames Wright }
912b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionRestoreContextData(qf, &ctx_data));
92e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
93fc7cf9a0Sjeremylt }
94fc7cf9a0Sjeremylt
95f10650afSjeremylt //------------------------------------------------------------------------------
96f10650afSjeremylt // QFunction Destroy
97f10650afSjeremylt //------------------------------------------------------------------------------
CeedQFunctionDestroy_Memcheck(CeedQFunction qf)98fc7cf9a0Sjeremylt static int CeedQFunctionDestroy_Memcheck(CeedQFunction qf) {
99fc7cf9a0Sjeremylt CeedQFunction_Memcheck *impl;
100fc7cf9a0Sjeremylt
1019a25c351SJeremy L Thompson CeedCallBackend(CeedQFunctionGetData(qf, &impl));
1022b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->inputs));
1032b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->outputs));
1042b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl));
105e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
106fc7cf9a0Sjeremylt }
107fc7cf9a0Sjeremylt
108f10650afSjeremylt //------------------------------------------------------------------------------
109f10650afSjeremylt // QFunction Create
110f10650afSjeremylt //------------------------------------------------------------------------------
CeedQFunctionCreate_Memcheck(CeedQFunction qf)111fc7cf9a0Sjeremylt int CeedQFunctionCreate_Memcheck(CeedQFunction qf) {
112fc7cf9a0Sjeremylt Ceed ceed;
113fc7cf9a0Sjeremylt CeedQFunction_Memcheck *impl;
114ad70ee2cSJeremy L Thompson
115ad70ee2cSJeremy L Thompson CeedCallBackend(CeedQFunctionGetCeed(qf, &ceed));
1162b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl));
1172b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(CEED_FIELD_MAX, &impl->inputs));
1182b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(CEED_FIELD_MAX, &impl->outputs));
1192b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionSetData(qf, impl));
1202b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunction", qf, "Apply", CeedQFunctionApply_Memcheck));
1212b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunction", qf, "Destroy", CeedQFunctionDestroy_Memcheck));
1229bc66399SJeremy L Thompson CeedCallBackend(CeedDestroy(&ceed));
123e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
124fc7cf9a0Sjeremylt }
1252a86cc9dSSebastian Grimberg
126f10650afSjeremylt //------------------------------------------------------------------------------
127