1 // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3 // 4 // SPDX-License-Identifier: BSD-2-Clause 5 // 6 // This file is part of CEED: http://github.com/ceed 7 8 #include <ceed.h> 9 #include <ceed/backend.h> 10 #include <math.h> 11 #include <stdio.h> 12 #include <valgrind/memcheck.h> 13 14 #include "ceed-memcheck.h" 15 16 //------------------------------------------------------------------------------ 17 // QFunction Apply 18 //------------------------------------------------------------------------------ 19 static int CeedQFunctionApply_Memcheck(CeedQFunction qf, CeedInt Q, CeedVector *U, CeedVector *V) { 20 Ceed ceed; 21 CeedCallBackend(CeedQFunctionGetCeed(qf, &ceed)); 22 23 CeedQFunction_Memcheck *impl; 24 CeedCallBackend(CeedQFunctionGetData(qf, &impl)); 25 26 void *ctx_data = NULL; 27 CeedCallBackend(CeedQFunctionGetContextData(qf, CEED_MEM_HOST, &ctx_data)); 28 29 CeedQFunctionUser f = NULL; 30 CeedCallBackend(CeedQFunctionGetUserFunction(qf, &f)); 31 32 CeedInt num_in, num_out; 33 CeedCallBackend(CeedQFunctionGetNumArgs(qf, &num_in, &num_out)); 34 35 for (CeedInt i = 0; i < num_in; i++) { 36 CeedCallBackend(CeedVectorGetArrayRead(U[i], CEED_MEM_HOST, &impl->inputs[i])); 37 } 38 int mem_block_ids[num_out]; 39 for (CeedInt i = 0; i < num_out; i++) { 40 CeedSize len; 41 char name[32] = ""; 42 43 CeedCallBackend(CeedVectorGetArrayWrite(V[i], CEED_MEM_HOST, &impl->outputs[i])); 44 45 CeedCallBackend(CeedVectorGetLength(V[i], &len)); 46 VALGRIND_MAKE_MEM_UNDEFINED(impl->outputs[i], len); 47 48 snprintf(name, 32, "'QFunction output %" CeedInt_FMT "'", i); 49 mem_block_ids[i] = VALGRIND_CREATE_BLOCK(impl->outputs[i], len, name); 50 } 51 52 CeedCallBackend(f(ctx_data, Q, impl->inputs, impl->outputs)); 53 54 for (CeedInt i = 0; i < num_in; i++) { 55 CeedCallBackend(CeedVectorRestoreArrayRead(U[i], &impl->inputs[i])); 56 } 57 for (CeedInt i = 0; i < num_out; i++) { 58 CeedSize length; 59 60 CeedCallBackend(CeedVectorGetLength(V[i], &length)); 61 for (CeedSize j = 0; j < length; j++) { 62 CeedCheck(!isnan(impl->outputs[i][j]), ceed, CEED_ERROR_BACKEND, "QFunction output %d entry %ld is NaN after restoring write-only access", i, 63 j); 64 } 65 CeedCallBackend(CeedVectorRestoreArray(V[i], &impl->outputs[i])); 66 VALGRIND_DISCARD(mem_block_ids[i]); 67 } 68 CeedCallBackend(CeedQFunctionRestoreContextData(qf, &ctx_data)); 69 70 return CEED_ERROR_SUCCESS; 71 } 72 73 //------------------------------------------------------------------------------ 74 // QFunction Destroy 75 //------------------------------------------------------------------------------ 76 static int CeedQFunctionDestroy_Memcheck(CeedQFunction qf) { 77 CeedQFunction_Memcheck *impl; 78 CeedCallBackend(CeedQFunctionGetData(qf, (void *)&impl)); 79 80 CeedCallBackend(CeedFree(&impl->inputs)); 81 CeedCallBackend(CeedFree(&impl->outputs)); 82 CeedCallBackend(CeedFree(&impl)); 83 84 return CEED_ERROR_SUCCESS; 85 } 86 87 //------------------------------------------------------------------------------ 88 // QFunction Create 89 //------------------------------------------------------------------------------ 90 int CeedQFunctionCreate_Memcheck(CeedQFunction qf) { 91 Ceed ceed; 92 CeedCallBackend(CeedQFunctionGetCeed(qf, &ceed)); 93 94 CeedQFunction_Memcheck *impl; 95 CeedCallBackend(CeedCalloc(1, &impl)); 96 CeedCallBackend(CeedCalloc(CEED_FIELD_MAX, &impl->inputs)); 97 CeedCallBackend(CeedCalloc(CEED_FIELD_MAX, &impl->outputs)); 98 CeedCallBackend(CeedQFunctionSetData(qf, impl)); 99 100 CeedCallBackend(CeedSetBackendFunction(ceed, "QFunction", qf, "Apply", CeedQFunctionApply_Memcheck)); 101 CeedCallBackend(CeedSetBackendFunction(ceed, "QFunction", qf, "Destroy", CeedQFunctionDestroy_Memcheck)); 102 103 return CEED_ERROR_SUCCESS; 104 } 105 106 //------------------------------------------------------------------------------ 107