xref: /libCEED/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision c082eca03950350b023f271dc47b90089562a0c5)
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/ceed.h>
9 #include <ceed/backend.h>
10 #include <string.h>
11 #include <valgrind/memcheck.h>
12 #include "ceed-memcheck.h"
13 
14 //------------------------------------------------------------------------------
15 // QFunctionContext has valid data
16 //------------------------------------------------------------------------------
17 static int CeedQFunctionContextHasValidData_Memcheck(CeedQFunctionContext ctx,
18     bool *has_valid_data) {
19   int ierr;
20   CeedQFunctionContext_Memcheck *impl;
21   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
22   CeedChkBackend(ierr);
23 
24   *has_valid_data = !!impl->data;
25 
26   return CEED_ERROR_SUCCESS;
27 }
28 
29 //------------------------------------------------------------------------------
30 // QFunctionContext has borrowed data
31 //------------------------------------------------------------------------------
32 static int CeedQFunctionContextHasBorrowedDataOfType_Memcheck(
33   CeedQFunctionContext ctx, CeedMemType mem_type,
34   bool *has_borrowed_data_of_type) {
35   int ierr;
36   CeedQFunctionContext_Memcheck *impl;
37   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
38   CeedChkBackend(ierr);
39   Ceed ceed;
40   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
41 
42   switch (mem_type) {
43   case CEED_MEM_HOST:
44     *has_borrowed_data_of_type = !!impl->data_borrowed;
45     break;
46   default:
47     // LCOV_EXCL_START
48     return CeedError(ceed, CEED_ERROR_BACKEND,
49                      "Can only set HOST memory for this backend");
50     // LCOV_EXCL_STOP
51     break;
52   }
53 
54   return CEED_ERROR_SUCCESS;
55 }
56 
57 //------------------------------------------------------------------------------
58 // QFunctionContext Set Data
59 //------------------------------------------------------------------------------
60 static int CeedQFunctionContextSetData_Memcheck(CeedQFunctionContext ctx,
61     CeedMemType mem_type, CeedCopyMode copy_mode, void *data) {
62   int ierr;
63   CeedQFunctionContext_Memcheck *impl;
64   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
65   CeedChkBackend(ierr);
66   size_t ctx_size;
67   ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr);
68   Ceed ceed;
69   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
70 
71   if (mem_type != CEED_MEM_HOST)
72     // LCOV_EXCL_START
73     return CeedError(ceed, CEED_ERROR_BACKEND,
74                      "Can only set HOST memory for this backend");
75   // LCOV_EXCL_STOP
76 
77   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
78   ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr);
79   switch (copy_mode) {
80   case CEED_COPY_VALUES:
81     ierr = CeedMallocArray(1, ctx_size, &impl->data_owned); CeedChkBackend(ierr);
82     impl->data_borrowed = NULL;
83     impl->data = impl->data_owned;
84     memcpy(impl->data, data, ctx_size);
85     break;
86   case CEED_OWN_POINTER:
87     impl->data_owned = data;
88     impl->data_borrowed = NULL;
89     impl->data = data;
90     break;
91   case CEED_USE_POINTER:
92     impl->data_borrowed = data;
93     impl->data = data;
94   }
95   // Copy data to check ctx_size bounds
96   ierr = CeedMallocArray(1, ctx_size, &impl->data_allocated);
97   CeedChkBackend(ierr);
98   memcpy(impl->data_allocated, impl->data, ctx_size);
99   impl->data = impl->data_allocated;
100   VALGRIND_DISCARD(impl->mem_block_id);
101   impl->mem_block_id = VALGRIND_CREATE_BLOCK(impl->data, ctx_size,
102                        "'QFunction backend context data copy'");
103 
104   return CEED_ERROR_SUCCESS;
105 }
106 
107 //------------------------------------------------------------------------------
108 // QFunctionContext Take Data
109 //------------------------------------------------------------------------------
110 static int CeedQFunctionContextTakeData_Memcheck(CeedQFunctionContext ctx,
111     CeedMemType mem_type, void *data) {
112   int ierr;
113   CeedQFunctionContext_Memcheck *impl;
114   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
115   CeedChkBackend(ierr);
116   Ceed ceed;
117   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
118 
119   if (mem_type != CEED_MEM_HOST)
120     // LCOV_EXCL_START
121     return CeedError(ceed, CEED_ERROR_BACKEND,
122                      "Can only provide HOST memory for this backend");
123   // LCOV_EXCL_STOP
124 
125   *(void **)data = impl->data_borrowed;
126   impl->data_borrowed = NULL;
127   impl->data = NULL;
128   VALGRIND_DISCARD(impl->mem_block_id);
129   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
130 
131   return CEED_ERROR_SUCCESS;
132 }
133 
134 //------------------------------------------------------------------------------
135 // QFunctionContext Get Data
136 //------------------------------------------------------------------------------
137 static int CeedQFunctionContextGetData_Memcheck(CeedQFunctionContext ctx,
138     CeedMemType mem_type, void *data) {
139   int ierr;
140   CeedQFunctionContext_Memcheck *impl;
141   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
142   CeedChkBackend(ierr);
143   Ceed ceed;
144   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
145 
146   if (mem_type != CEED_MEM_HOST)
147     // LCOV_EXCL_START
148     return CeedError(ceed, CEED_ERROR_BACKEND,
149                      "Can only provide HOST memory for this backend");
150   // LCOV_EXCL_STOP
151 
152   *(void **)data = impl->data;
153 
154   return CEED_ERROR_SUCCESS;
155 }
156 
157 //------------------------------------------------------------------------------
158 // QFunctionContext Restore Data
159 //------------------------------------------------------------------------------
160 static int CeedQFunctionContextRestoreData_Memcheck(CeedQFunctionContext ctx) {
161   int ierr;
162   size_t ctx_size;
163   ierr = CeedQFunctionContextGetContextSize(ctx, &ctx_size); CeedChkBackend(ierr);
164   CeedQFunctionContext_Memcheck *impl;
165   ierr = CeedQFunctionContextGetBackendData(ctx, (void *)&impl);
166   CeedChkBackend(ierr);
167 
168   if (impl->data_borrowed) {
169     memcpy(impl->data_borrowed, impl->data, ctx_size);
170   }
171   if (impl->data_owned) {
172     memcpy(impl->data_owned, impl->data, ctx_size);
173   }
174 
175   return CEED_ERROR_SUCCESS;
176 }
177 
178 //------------------------------------------------------------------------------
179 // QFunctionContext destroy user data
180 //------------------------------------------------------------------------------
181 static int CeedQFunctionContextDataDestroy_Memcheck(CeedQFunctionContext ctx) {
182   int ierr;
183   CeedQFunctionContext_Memcheck *impl;
184   ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr);
185   CeedQFunctionContextDataDestroyUser data_destroy_function;
186   CeedMemType data_destroy_mem_type;
187   ierr = CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type,
188          &data_destroy_function); CeedChk(ierr);
189   Ceed ceed;
190   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
191 
192   if (data_destroy_mem_type != CEED_MEM_HOST)
193     // LCOV_EXCL_START
194     return CeedError(ceed, CEED_ERROR_BACKEND,
195                      "Can only destroy HOST memory for this backend");
196   // LCOV_EXCL_STOP
197 
198   if (data_destroy_function) {
199     ierr = data_destroy_function(impl->data_borrowed ? impl->data_borrowed :
200                                  impl->data_owned); CeedChk(ierr);
201   }
202   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
203 
204   return CEED_ERROR_SUCCESS;
205 }
206 
207 //------------------------------------------------------------------------------
208 // QFunctionContext Destroy
209 //------------------------------------------------------------------------------
210 static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) {
211   int ierr;
212   CeedQFunctionContext_Memcheck *impl;
213   ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr);
214 
215   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
216   ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr);
217   ierr = CeedFree(&impl); CeedChkBackend(ierr);
218   return CEED_ERROR_SUCCESS;
219 }
220 
221 //------------------------------------------------------------------------------
222 // QFunctionContext Create
223 //------------------------------------------------------------------------------
224 int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) {
225   int ierr;
226   CeedQFunctionContext_Memcheck *impl;
227   Ceed ceed;
228   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
229 
230   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData",
231                                 CeedQFunctionContextHasValidData_Memcheck);
232   CeedChkBackend(ierr);
233   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx,
234                                 "HasBorrowedDataOfType",
235                                 CeedQFunctionContextHasBorrowedDataOfType_Memcheck);
236   CeedChkBackend(ierr);
237   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData",
238                                 CeedQFunctionContextSetData_Memcheck); CeedChkBackend(ierr);
239   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData",
240                                 CeedQFunctionContextTakeData_Memcheck); CeedChkBackend(ierr);
241   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData",
242                                 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr);
243   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead",
244                                 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr);
245   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData",
246                                 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr);
247   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead",
248                                 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr);
249   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "DataDestroy",
250                                 CeedQFunctionContextDataDestroy_Memcheck); CeedChkBackend(ierr);
251   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy",
252                                 CeedQFunctionContextDestroy_Memcheck); CeedChkBackend(ierr);
253 
254   ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr);
255   ierr = CeedQFunctionContextSetBackendData(ctx, impl); CeedChkBackend(ierr);
256 
257   return CEED_ERROR_SUCCESS;
258 }
259 //------------------------------------------------------------------------------
260