xref: /libCEED/rust/libceed-sys/c-src/backends/memcheck/ceed-memcheck-vector.c (revision 9798701e55d35a37cb56bc409caf84c06b238a40)
1*9798701eSJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2*9798701eSJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3*9798701eSJeremy L Thompson //
4*9798701eSJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5*9798701eSJeremy L Thompson //
6*9798701eSJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
7*9798701eSJeremy L Thompson 
8*9798701eSJeremy L Thompson #include <ceed/backend.h>
9*9798701eSJeremy L Thompson #include <ceed/ceed.h>
10*9798701eSJeremy L Thompson #include <math.h>
11*9798701eSJeremy L Thompson #include <string.h>
12*9798701eSJeremy L Thompson #include <valgrind/memcheck.h>
13*9798701eSJeremy L Thompson 
14*9798701eSJeremy L Thompson #include "ceed-memcheck.h"
15*9798701eSJeremy L Thompson 
16*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
17*9798701eSJeremy L Thompson // Has Valid Array
18*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
19*9798701eSJeremy L Thompson static int CeedVectorHasValidArray_Memcheck(CeedVector vec, bool *has_valid_array) {
20*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
21*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
22*9798701eSJeremy L Thompson 
23*9798701eSJeremy L Thompson   *has_valid_array = !!impl->array;
24*9798701eSJeremy L Thompson 
25*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
26*9798701eSJeremy L Thompson }
27*9798701eSJeremy L Thompson 
28*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
29*9798701eSJeremy L Thompson // Check if has borrowed array of given type
30*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
31*9798701eSJeremy L Thompson static inline int CeedVectorHasBorrowedArrayOfType_Memcheck(const CeedVector vec, CeedMemType mem_type, bool *has_borrowed_array_of_type) {
32*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
33*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
34*9798701eSJeremy L Thompson   Ceed ceed;
35*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
36*9798701eSJeremy L Thompson 
37*9798701eSJeremy L Thompson   switch (mem_type) {
38*9798701eSJeremy L Thompson     case CEED_MEM_HOST:
39*9798701eSJeremy L Thompson       *has_borrowed_array_of_type = !!impl->array_borrowed;
40*9798701eSJeremy L Thompson       break;
41*9798701eSJeremy L Thompson     default:
42*9798701eSJeremy L Thompson       // LCOV_EXCL_START
43*9798701eSJeremy L Thompson       return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend");
44*9798701eSJeremy L Thompson       // LCOV_EXCL_STOP
45*9798701eSJeremy L Thompson       break;
46*9798701eSJeremy L Thompson   }
47*9798701eSJeremy L Thompson 
48*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
49*9798701eSJeremy L Thompson }
50*9798701eSJeremy L Thompson 
51*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
52*9798701eSJeremy L Thompson // Vector Set Array
53*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
54*9798701eSJeremy L Thompson static int CeedVectorSetArray_Memcheck(CeedVector vec, CeedMemType mem_type, CeedCopyMode copy_mode, CeedScalar *array) {
55*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
56*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
57*9798701eSJeremy L Thompson   CeedSize length;
58*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
59*9798701eSJeremy L Thompson   Ceed ceed;
60*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
61*9798701eSJeremy L Thompson 
62*9798701eSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
63*9798701eSJeremy L Thompson     // LCOV_EXCL_START
64*9798701eSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend");
65*9798701eSJeremy L Thompson     // LCOV_EXCL_STOP
66*9798701eSJeremy L Thompson   }
67*9798701eSJeremy L Thompson 
68*9798701eSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->array_allocated));
69*9798701eSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->array_owned));
70*9798701eSJeremy L Thompson   switch (copy_mode) {
71*9798701eSJeremy L Thompson     case CEED_COPY_VALUES:
72*9798701eSJeremy L Thompson       CeedCallBackend(CeedCalloc(length, &impl->array_owned));
73*9798701eSJeremy L Thompson       impl->array_borrowed = NULL;
74*9798701eSJeremy L Thompson       impl->array          = impl->array_owned;
75*9798701eSJeremy L Thompson       if (array) {
76*9798701eSJeremy L Thompson         memcpy(impl->array, array, length * sizeof(array[0]));
77*9798701eSJeremy L Thompson       } else {
78*9798701eSJeremy L Thompson         for (CeedInt i = 0; i < length; i++) impl->array[i] = NAN;
79*9798701eSJeremy L Thompson       }
80*9798701eSJeremy L Thompson       break;
81*9798701eSJeremy L Thompson     case CEED_OWN_POINTER:
82*9798701eSJeremy L Thompson       impl->array_owned    = array;
83*9798701eSJeremy L Thompson       impl->array_borrowed = NULL;
84*9798701eSJeremy L Thompson       impl->array          = array;
85*9798701eSJeremy L Thompson       break;
86*9798701eSJeremy L Thompson     case CEED_USE_POINTER:
87*9798701eSJeremy L Thompson       impl->array_borrowed = array;
88*9798701eSJeremy L Thompson       impl->array          = array;
89*9798701eSJeremy L Thompson   }
90*9798701eSJeremy L Thompson   // Copy data to check access
91*9798701eSJeremy L Thompson   CeedCallBackend(CeedCalloc(length, &impl->array_allocated));
92*9798701eSJeremy L Thompson   memcpy(impl->array_allocated, impl->array, length * sizeof(array[0]));
93*9798701eSJeremy L Thompson   impl->array = impl->array_allocated;
94*9798701eSJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
95*9798701eSJeremy L Thompson   impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->array, length * sizeof(array[0]), "'Vector backend array data copy'");
96*9798701eSJeremy L Thompson 
97*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
98*9798701eSJeremy L Thompson }
99*9798701eSJeremy L Thompson 
100*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
101*9798701eSJeremy L Thompson // Vector Take Array
102*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
103*9798701eSJeremy L Thompson static int CeedVectorTakeArray_Memcheck(CeedVector vec, CeedMemType mem_type, CeedScalar **array) {
104*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
105*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
106*9798701eSJeremy L Thompson   Ceed ceed;
107*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
108*9798701eSJeremy L Thompson 
109*9798701eSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
110*9798701eSJeremy L Thompson     // LCOV_EXCL_START
111*9798701eSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
112*9798701eSJeremy L Thompson     // LCOV_EXCL_STOP
113*9798701eSJeremy L Thompson   }
114*9798701eSJeremy L Thompson 
115*9798701eSJeremy L Thompson   (*array)             = impl->array_borrowed;
116*9798701eSJeremy L Thompson   impl->array_borrowed = NULL;
117*9798701eSJeremy L Thompson   impl->array          = NULL;
118*9798701eSJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
119*9798701eSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->array_allocated));
120*9798701eSJeremy L Thompson 
121*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
122*9798701eSJeremy L Thompson }
123*9798701eSJeremy L Thompson 
124*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
125*9798701eSJeremy L Thompson // Vector Get Array
126*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
127*9798701eSJeremy L Thompson static int CeedVectorGetArray_Memcheck(CeedVector vec, CeedMemType mem_type, CeedScalar **array) {
128*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
129*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
130*9798701eSJeremy L Thompson   Ceed ceed;
131*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
132*9798701eSJeremy L Thompson 
133*9798701eSJeremy L Thompson   if (mem_type != CEED_MEM_HOST) {
134*9798701eSJeremy L Thompson     // LCOV_EXCL_START
135*9798701eSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
136*9798701eSJeremy L Thompson     // LCOV_EXCL_STOP
137*9798701eSJeremy L Thompson   }
138*9798701eSJeremy L Thompson 
139*9798701eSJeremy L Thompson   *array = impl->array;
140*9798701eSJeremy L Thompson 
141*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
142*9798701eSJeremy L Thompson }
143*9798701eSJeremy L Thompson 
144*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
145*9798701eSJeremy L Thompson // Vector Get Array Read
146*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
147*9798701eSJeremy L Thompson static int CeedVectorGetArrayRead_Memcheck(CeedVector vec, CeedMemType mem_type, const CeedScalar **array) {
148*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
149*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
150*9798701eSJeremy L Thompson   CeedSize length;
151*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
152*9798701eSJeremy L Thompson   Ceed ceed;
153*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
154*9798701eSJeremy L Thompson 
155*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetArray_Memcheck(vec, mem_type, (CeedScalar **)array));
156*9798701eSJeremy L Thompson 
157*9798701eSJeremy L Thompson   // Make copy to verify no write occurred
158*9798701eSJeremy L Thompson   CeedCallBackend(CeedCalloc(length, &impl->array_read_only_copy));
159*9798701eSJeremy L Thompson   memcpy(impl->array_read_only_copy, *array, length * sizeof((*array)[0]));
160*9798701eSJeremy L Thompson 
161*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
162*9798701eSJeremy L Thompson }
163*9798701eSJeremy L Thompson 
164*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
165*9798701eSJeremy L Thompson // Vector Get Array Write
166*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
167*9798701eSJeremy L Thompson static int CeedVectorGetArrayWrite_Memcheck(CeedVector vec, CeedMemType mem_type, CeedScalar **array) {
168*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
169*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
170*9798701eSJeremy L Thompson   CeedSize length;
171*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
172*9798701eSJeremy L Thompson   Ceed ceed;
173*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
174*9798701eSJeremy L Thompson 
175*9798701eSJeremy L Thompson   // Invalidate data to make sure no read occurs
176*9798701eSJeremy L Thompson   if (!impl->array) CeedCallBackend(CeedVectorSetArray_Memcheck(vec, mem_type, CEED_COPY_VALUES, NULL));
177*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetArray_Memcheck(vec, mem_type, array));
178*9798701eSJeremy L Thompson   for (CeedInt i = 0; i < length; i++) (*array)[i] = NAN;
179*9798701eSJeremy L Thompson 
180*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
181*9798701eSJeremy L Thompson }
182*9798701eSJeremy L Thompson 
183*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
184*9798701eSJeremy L Thompson // Vector Restore Array
185*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
186*9798701eSJeremy L Thompson static int CeedVectorRestoreArray_Memcheck(CeedVector vec) {
187*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
188*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
189*9798701eSJeremy L Thompson   CeedSize length;
190*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
191*9798701eSJeremy L Thompson   Ceed ceed;
192*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
193*9798701eSJeremy L Thompson 
194*9798701eSJeremy L Thompson   if (impl->array_borrowed) {
195*9798701eSJeremy L Thompson     memcpy(impl->array_borrowed, impl->array, length * sizeof(impl->array[0]));
196*9798701eSJeremy L Thompson   }
197*9798701eSJeremy L Thompson   if (impl->array_owned) {
198*9798701eSJeremy L Thompson     memcpy(impl->array_owned, impl->array, length * sizeof(impl->array[0]));
199*9798701eSJeremy L Thompson   }
200*9798701eSJeremy L Thompson 
201*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
202*9798701eSJeremy L Thompson }
203*9798701eSJeremy L Thompson 
204*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
205*9798701eSJeremy L Thompson // Vector Restore Array Read-Only
206*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
207*9798701eSJeremy L Thompson static int CeedVectorRestoreArrayRead_Memcheck(CeedVector vec) {
208*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
209*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
210*9798701eSJeremy L Thompson   CeedSize length;
211*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
212*9798701eSJeremy L Thompson   Ceed ceed;
213*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
214*9798701eSJeremy L Thompson 
215*9798701eSJeremy L Thompson   if (memcmp(impl->array, impl->array_read_only_copy, length * sizeof(impl->array[0]))) {
216*9798701eSJeremy L Thompson     // LCOV_EXCL_START
217*9798701eSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "Array data changed while accessed in read-only mode");
218*9798701eSJeremy L Thompson     // LCOV_EXCL_STOP
219*9798701eSJeremy L Thompson   }
220*9798701eSJeremy L Thompson 
221*9798701eSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->array_read_only_copy));
222*9798701eSJeremy L Thompson 
223*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
224*9798701eSJeremy L Thompson }
225*9798701eSJeremy L Thompson 
226*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
227*9798701eSJeremy L Thompson // Vector Destroy
228*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
229*9798701eSJeremy L Thompson static int CeedVectorDestroy_Memcheck(CeedVector vec) {
230*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
231*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
232*9798701eSJeremy L Thompson 
233*9798701eSJeremy L Thompson   VALGRIND_DISCARD(impl->mem_block_id);
234*9798701eSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->array_allocated));
235*9798701eSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->array_owned));
236*9798701eSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
237*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
238*9798701eSJeremy L Thompson }
239*9798701eSJeremy L Thompson 
240*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
241*9798701eSJeremy L Thompson // Vector Create
242*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
243*9798701eSJeremy L Thompson int CeedVectorCreate_Memcheck(CeedSize n, CeedVector vec) {
244*9798701eSJeremy L Thompson   CeedVector_Memcheck *impl;
245*9798701eSJeremy L Thompson   Ceed                 ceed;
246*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
247*9798701eSJeremy L Thompson 
248*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", CeedVectorHasValidArray_Memcheck));
249*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", CeedVectorHasBorrowedArrayOfType_Memcheck));
250*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", CeedVectorSetArray_Memcheck));
251*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", CeedVectorTakeArray_Memcheck));
252*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", CeedVectorGetArray_Memcheck));
253*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", CeedVectorGetArrayRead_Memcheck));
254*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", CeedVectorGetArrayWrite_Memcheck));
255*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArray", CeedVectorRestoreArray_Memcheck));
256*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArrayRead", CeedVectorRestoreArrayRead_Memcheck));
257*9798701eSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", CeedVectorDestroy_Memcheck));
258*9798701eSJeremy L Thompson 
259*9798701eSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
260*9798701eSJeremy L Thompson   CeedCallBackend(CeedVectorSetData(vec, impl));
261*9798701eSJeremy L Thompson 
262*9798701eSJeremy L Thompson   return CEED_ERROR_SUCCESS;
263*9798701eSJeremy L Thompson }
264*9798701eSJeremy L Thompson //------------------------------------------------------------------------------
265