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