xref: /libCEED/backends/memcheck/ceed-memcheck-qfunctioncontext.c (revision 0f58c348267158b87d81b5a8b1a981eb0caf8b99)
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
180 //------------------------------------------------------------------------------
181 static int CeedQFunctionContextDestroy_Memcheck(CeedQFunctionContext ctx) {
182   int ierr;
183   CeedQFunctionContext_Memcheck *impl;
184   ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr);
185 
186   ierr = CeedFree(&impl->data_allocated); CeedChkBackend(ierr);
187   ierr = CeedFree(&impl->data_owned); CeedChkBackend(ierr);
188   ierr = CeedFree(&impl); CeedChkBackend(ierr);
189   return CEED_ERROR_SUCCESS;
190 }
191 
192 //------------------------------------------------------------------------------
193 // QFunctionContext Create
194 //------------------------------------------------------------------------------
195 int CeedQFunctionContextCreate_Memcheck(CeedQFunctionContext ctx) {
196   int ierr;
197   CeedQFunctionContext_Memcheck *impl;
198   Ceed ceed;
199   ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr);
200 
201   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData",
202                                 CeedQFunctionContextHasValidData_Memcheck);
203   CeedChkBackend(ierr);
204   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx,
205                                 "HasBorrowedDataOfType",
206                                 CeedQFunctionContextHasBorrowedDataOfType_Memcheck);
207   CeedChkBackend(ierr);
208   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData",
209                                 CeedQFunctionContextSetData_Memcheck); CeedChkBackend(ierr);
210   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData",
211                                 CeedQFunctionContextTakeData_Memcheck); CeedChkBackend(ierr);
212   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData",
213                                 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr);
214   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead",
215                                 CeedQFunctionContextGetData_Memcheck); CeedChkBackend(ierr);
216   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreData",
217                                 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr);
218   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "RestoreDataRead",
219                                 CeedQFunctionContextRestoreData_Memcheck); CeedChkBackend(ierr);
220   ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy",
221                                 CeedQFunctionContextDestroy_Memcheck); CeedChkBackend(ierr);
222 
223   ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr);
224   ierr = CeedQFunctionContextSetBackendData(ctx, impl); CeedChkBackend(ierr);
225 
226   return CEED_ERROR_SUCCESS;
227 }
228 //------------------------------------------------------------------------------
229