xref: /libCEED/backends/memcheck/ceed-memcheck-qfunction.c (revision 6ca0f394dabdca92269b68ec74be8bebae3befa4)
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