xref: /libCEED/backends/sycl-ref/ceed-sycl-ref-qfunctioncontext.sycl.cpp (revision bd882c8a454763a096666645dc9a6229d5263694)
1*bd882c8aSJames Wright // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2*bd882c8aSJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3*bd882c8aSJames Wright //
4*bd882c8aSJames Wright // SPDX-License-Identifier: BSD-2-Clause
5*bd882c8aSJames Wright //
6*bd882c8aSJames Wright // This file is part of CEED:  http://github.com/ceed
7*bd882c8aSJames Wright 
8*bd882c8aSJames Wright #include <ceed/backend.h>
9*bd882c8aSJames Wright #include <ceed/ceed.h>
10*bd882c8aSJames Wright 
11*bd882c8aSJames Wright #include <string>
12*bd882c8aSJames Wright #include <sycl/sycl.hpp>
13*bd882c8aSJames Wright 
14*bd882c8aSJames Wright #include "ceed-sycl-ref.hpp"
15*bd882c8aSJames Wright 
16*bd882c8aSJames Wright //------------------------------------------------------------------------------
17*bd882c8aSJames Wright // Sync host to device
18*bd882c8aSJames Wright //------------------------------------------------------------------------------
19*bd882c8aSJames Wright static inline int CeedQFunctionContextSyncH2D_Sycl(const CeedQFunctionContext ctx) {
20*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
21*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
22*bd882c8aSJames Wright   Ceed ceed;
23*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
24*bd882c8aSJames Wright   Ceed_Sycl *sycl_data;
25*bd882c8aSJames Wright   CeedCallBackend(CeedGetData(ceed, &sycl_data));
26*bd882c8aSJames Wright 
27*bd882c8aSJames Wright   if (!impl->h_data) {
28*bd882c8aSJames Wright     // LCOV_EXCL_START
29*bd882c8aSJames Wright     return CeedError(ceed, CEED_ERROR_BACKEND, "No valid host data to sync to device");
30*bd882c8aSJames Wright     // LCOV_EXCL_STOP
31*bd882c8aSJames Wright   }
32*bd882c8aSJames Wright 
33*bd882c8aSJames Wright   size_t ctxsize;
34*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
35*bd882c8aSJames Wright 
36*bd882c8aSJames Wright   if (impl->d_data_borrowed) {
37*bd882c8aSJames Wright     impl->d_data = impl->d_data_borrowed;
38*bd882c8aSJames Wright   } else if (impl->d_data_owned) {
39*bd882c8aSJames Wright     impl->d_data = impl->d_data_owned;
40*bd882c8aSJames Wright   } else {
41*bd882c8aSJames Wright     CeedCallSycl(ceed, impl->d_data_owned = sycl::malloc_device(ctxsize, sycl_data->sycl_device, sycl_data->sycl_context));
42*bd882c8aSJames Wright     impl->d_data = impl->d_data_owned;
43*bd882c8aSJames Wright   }
44*bd882c8aSJames Wright   // Order queue
45*bd882c8aSJames Wright   sycl::event e          = sycl_data->sycl_queue.ext_oneapi_submit_barrier();
46*bd882c8aSJames Wright   sycl::event copy_event = sycl_data->sycl_queue.memcpy(impl->d_data, impl->h_data, ctxsize, {e});
47*bd882c8aSJames Wright   CeedCallSycl(ceed, copy_event.wait_and_throw());
48*bd882c8aSJames Wright 
49*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
50*bd882c8aSJames Wright }
51*bd882c8aSJames Wright 
52*bd882c8aSJames Wright //------------------------------------------------------------------------------
53*bd882c8aSJames Wright // Sync device to host
54*bd882c8aSJames Wright //------------------------------------------------------------------------------
55*bd882c8aSJames Wright static inline int CeedQFunctionContextSyncD2H_Sycl(const CeedQFunctionContext ctx) {
56*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
57*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
58*bd882c8aSJames Wright   Ceed ceed;
59*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
60*bd882c8aSJames Wright   Ceed_Sycl *sycl_data;
61*bd882c8aSJames Wright   CeedCallBackend(CeedGetData(ceed, &sycl_data));
62*bd882c8aSJames Wright 
63*bd882c8aSJames Wright   if (!impl->d_data) {
64*bd882c8aSJames Wright     // LCOV_EXCL_START
65*bd882c8aSJames Wright     return CeedError(ceed, CEED_ERROR_BACKEND, "No valid device data to sync to host");
66*bd882c8aSJames Wright     // LCOV_EXCL_STOP
67*bd882c8aSJames Wright   }
68*bd882c8aSJames Wright 
69*bd882c8aSJames Wright   size_t ctxsize;
70*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
71*bd882c8aSJames Wright 
72*bd882c8aSJames Wright   if (impl->h_data_borrowed) {
73*bd882c8aSJames Wright     impl->h_data = impl->h_data_borrowed;
74*bd882c8aSJames Wright   } else if (impl->h_data_owned) {
75*bd882c8aSJames Wright     impl->h_data = impl->h_data_owned;
76*bd882c8aSJames Wright   } else {
77*bd882c8aSJames Wright     CeedCallBackend(CeedMallocArray(1, ctxsize, &impl->h_data_owned));
78*bd882c8aSJames Wright     impl->h_data = impl->h_data_owned;
79*bd882c8aSJames Wright   }
80*bd882c8aSJames Wright 
81*bd882c8aSJames Wright   // Order queue
82*bd882c8aSJames Wright   sycl::event e          = sycl_data->sycl_queue.ext_oneapi_submit_barrier();
83*bd882c8aSJames Wright   sycl::event copy_event = sycl_data->sycl_queue.memcpy(impl->h_data, impl->d_data, ctxsize, {e});
84*bd882c8aSJames Wright   CeedCallSycl(ceed, copy_event.wait_and_throw());
85*bd882c8aSJames Wright 
86*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
87*bd882c8aSJames Wright }
88*bd882c8aSJames Wright 
89*bd882c8aSJames Wright //------------------------------------------------------------------------------
90*bd882c8aSJames Wright // Sync data of type
91*bd882c8aSJames Wright //------------------------------------------------------------------------------
92*bd882c8aSJames Wright static inline int CeedQFunctionContextSync_Sycl(const CeedQFunctionContext ctx, CeedMemType mem_type) {
93*bd882c8aSJames Wright   switch (mem_type) {
94*bd882c8aSJames Wright     case CEED_MEM_HOST:
95*bd882c8aSJames Wright       return CeedQFunctionContextSyncD2H_Sycl(ctx);
96*bd882c8aSJames Wright     case CEED_MEM_DEVICE:
97*bd882c8aSJames Wright       return CeedQFunctionContextSyncH2D_Sycl(ctx);
98*bd882c8aSJames Wright   }
99*bd882c8aSJames Wright   return CEED_ERROR_UNSUPPORTED;
100*bd882c8aSJames Wright }
101*bd882c8aSJames Wright 
102*bd882c8aSJames Wright //------------------------------------------------------------------------------
103*bd882c8aSJames Wright // Set all pointers as invalid
104*bd882c8aSJames Wright //------------------------------------------------------------------------------
105*bd882c8aSJames Wright static inline int CeedQFunctionContextSetAllInvalid_Sycl(const CeedQFunctionContext ctx) {
106*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
107*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
108*bd882c8aSJames Wright 
109*bd882c8aSJames Wright   impl->h_data = NULL;
110*bd882c8aSJames Wright   impl->d_data = NULL;
111*bd882c8aSJames Wright 
112*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
113*bd882c8aSJames Wright }
114*bd882c8aSJames Wright 
115*bd882c8aSJames Wright //------------------------------------------------------------------------------
116*bd882c8aSJames Wright // Check if ctx has valid data
117*bd882c8aSJames Wright //------------------------------------------------------------------------------
118*bd882c8aSJames Wright static inline int CeedQFunctionContextHasValidData_Sycl(const CeedQFunctionContext ctx, bool *has_valid_data) {
119*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
120*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
121*bd882c8aSJames Wright 
122*bd882c8aSJames Wright   *has_valid_data = impl && (!!impl->h_data || !!impl->d_data);
123*bd882c8aSJames Wright 
124*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
125*bd882c8aSJames Wright }
126*bd882c8aSJames Wright 
127*bd882c8aSJames Wright //------------------------------------------------------------------------------
128*bd882c8aSJames Wright // Check if ctx has borrowed data
129*bd882c8aSJames Wright //------------------------------------------------------------------------------
130*bd882c8aSJames Wright static inline int CeedQFunctionContextHasBorrowedDataOfType_Sycl(const CeedQFunctionContext ctx, CeedMemType mem_type,
131*bd882c8aSJames Wright                                                                  bool *has_borrowed_data_of_type) {
132*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
133*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
134*bd882c8aSJames Wright 
135*bd882c8aSJames Wright   switch (mem_type) {
136*bd882c8aSJames Wright     case CEED_MEM_HOST:
137*bd882c8aSJames Wright       *has_borrowed_data_of_type = !!impl->h_data_borrowed;
138*bd882c8aSJames Wright       break;
139*bd882c8aSJames Wright     case CEED_MEM_DEVICE:
140*bd882c8aSJames Wright       *has_borrowed_data_of_type = !!impl->d_data_borrowed;
141*bd882c8aSJames Wright       break;
142*bd882c8aSJames Wright   }
143*bd882c8aSJames Wright 
144*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
145*bd882c8aSJames Wright }
146*bd882c8aSJames Wright 
147*bd882c8aSJames Wright //------------------------------------------------------------------------------
148*bd882c8aSJames Wright // Check if data of given type needs sync
149*bd882c8aSJames Wright //------------------------------------------------------------------------------
150*bd882c8aSJames Wright static inline int CeedQFunctionContextNeedSync_Sycl(const CeedQFunctionContext ctx, CeedMemType mem_type, bool *need_sync) {
151*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
152*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
153*bd882c8aSJames Wright 
154*bd882c8aSJames Wright   bool has_valid_data = true;
155*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
156*bd882c8aSJames Wright   switch (mem_type) {
157*bd882c8aSJames Wright     case CEED_MEM_HOST:
158*bd882c8aSJames Wright       *need_sync = has_valid_data && !impl->h_data;
159*bd882c8aSJames Wright       break;
160*bd882c8aSJames Wright     case CEED_MEM_DEVICE:
161*bd882c8aSJames Wright       *need_sync = has_valid_data && !impl->d_data;
162*bd882c8aSJames Wright       break;
163*bd882c8aSJames Wright   }
164*bd882c8aSJames Wright 
165*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
166*bd882c8aSJames Wright }
167*bd882c8aSJames Wright 
168*bd882c8aSJames Wright //------------------------------------------------------------------------------
169*bd882c8aSJames Wright // Set data from host
170*bd882c8aSJames Wright //------------------------------------------------------------------------------
171*bd882c8aSJames Wright static int CeedQFunctionContextSetDataHost_Sycl(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) {
172*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
173*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
174*bd882c8aSJames Wright 
175*bd882c8aSJames Wright   CeedCallBackend(CeedFree(&impl->h_data_owned));
176*bd882c8aSJames Wright   switch (copy_mode) {
177*bd882c8aSJames Wright     case CEED_COPY_VALUES:
178*bd882c8aSJames Wright       size_t ctxsize;
179*bd882c8aSJames Wright       CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
180*bd882c8aSJames Wright       CeedCallBackend(CeedMallocArray(1, ctxsize, &impl->h_data_owned));
181*bd882c8aSJames Wright       impl->h_data_borrowed = NULL;
182*bd882c8aSJames Wright       impl->h_data          = impl->h_data_owned;
183*bd882c8aSJames Wright       memcpy(impl->h_data, data, ctxsize);
184*bd882c8aSJames Wright       break;
185*bd882c8aSJames Wright     case CEED_OWN_POINTER:
186*bd882c8aSJames Wright       impl->h_data_owned    = data;
187*bd882c8aSJames Wright       impl->h_data_borrowed = NULL;
188*bd882c8aSJames Wright       impl->h_data          = data;
189*bd882c8aSJames Wright       break;
190*bd882c8aSJames Wright     case CEED_USE_POINTER:
191*bd882c8aSJames Wright       impl->h_data_borrowed = data;
192*bd882c8aSJames Wright       impl->h_data          = data;
193*bd882c8aSJames Wright       break;
194*bd882c8aSJames Wright   }
195*bd882c8aSJames Wright 
196*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
197*bd882c8aSJames Wright }
198*bd882c8aSJames Wright 
199*bd882c8aSJames Wright //------------------------------------------------------------------------------
200*bd882c8aSJames Wright // Set data from device
201*bd882c8aSJames Wright //------------------------------------------------------------------------------
202*bd882c8aSJames Wright static int CeedQFunctionContextSetDataDevice_Sycl(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) {
203*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
204*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
205*bd882c8aSJames Wright   Ceed ceed;
206*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
207*bd882c8aSJames Wright   Ceed_Sycl *sycl_data;
208*bd882c8aSJames Wright   CeedCallBackend(CeedGetData(ceed, &sycl_data));
209*bd882c8aSJames Wright 
210*bd882c8aSJames Wright   // Order queue
211*bd882c8aSJames Wright   sycl::event e = sycl_data->sycl_queue.ext_oneapi_submit_barrier();
212*bd882c8aSJames Wright 
213*bd882c8aSJames Wright   // Wait for all work to finish before freeing memory
214*bd882c8aSJames Wright   if (impl->d_data_owned) {
215*bd882c8aSJames Wright     CeedCallSycl(ceed, sycl_data->sycl_queue.wait_and_throw());
216*bd882c8aSJames Wright     CeedCallSycl(ceed, sycl::free(impl->d_data_owned, sycl_data->sycl_context));
217*bd882c8aSJames Wright     impl->d_data_owned = NULL;
218*bd882c8aSJames Wright   }
219*bd882c8aSJames Wright 
220*bd882c8aSJames Wright   switch (copy_mode) {
221*bd882c8aSJames Wright     case CEED_COPY_VALUES: {
222*bd882c8aSJames Wright       size_t ctxsize;
223*bd882c8aSJames Wright       CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
224*bd882c8aSJames Wright       CeedCallSycl(ceed, impl->d_data_owned = sycl::malloc_device(ctxsize, sycl_data->sycl_device, sycl_data->sycl_context));
225*bd882c8aSJames Wright       impl->d_data_borrowed  = NULL;
226*bd882c8aSJames Wright       impl->d_data           = impl->d_data_owned;
227*bd882c8aSJames Wright       sycl::event copy_event = sycl_data->sycl_queue.memcpy(impl->d_data, data, ctxsize, {e});
228*bd882c8aSJames Wright       CeedCallSycl(ceed, copy_event.wait_and_throw());
229*bd882c8aSJames Wright     } break;
230*bd882c8aSJames Wright     case CEED_OWN_POINTER: {
231*bd882c8aSJames Wright       impl->d_data_owned    = data;
232*bd882c8aSJames Wright       impl->d_data_borrowed = NULL;
233*bd882c8aSJames Wright       impl->d_data          = data;
234*bd882c8aSJames Wright     } break;
235*bd882c8aSJames Wright     case CEED_USE_POINTER: {
236*bd882c8aSJames Wright       impl->d_data_owned    = NULL;
237*bd882c8aSJames Wright       impl->d_data_borrowed = data;
238*bd882c8aSJames Wright       impl->d_data          = data;
239*bd882c8aSJames Wright     } break;
240*bd882c8aSJames Wright   }
241*bd882c8aSJames Wright 
242*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
243*bd882c8aSJames Wright }
244*bd882c8aSJames Wright 
245*bd882c8aSJames Wright //------------------------------------------------------------------------------
246*bd882c8aSJames Wright // Set the data used by a user context,
247*bd882c8aSJames Wright //   freeing any previously allocated data if applicable
248*bd882c8aSJames Wright //------------------------------------------------------------------------------
249*bd882c8aSJames Wright static int CeedQFunctionContextSetData_Sycl(const CeedQFunctionContext ctx, const CeedMemType mem_type, const CeedCopyMode copy_mode, void *data) {
250*bd882c8aSJames Wright   Ceed ceed;
251*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
252*bd882c8aSJames Wright 
253*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextSetAllInvalid_Sycl(ctx));
254*bd882c8aSJames Wright   switch (mem_type) {
255*bd882c8aSJames Wright     case CEED_MEM_HOST:
256*bd882c8aSJames Wright       return CeedQFunctionContextSetDataHost_Sycl(ctx, copy_mode, data);
257*bd882c8aSJames Wright     case CEED_MEM_DEVICE:
258*bd882c8aSJames Wright       return CeedQFunctionContextSetDataDevice_Sycl(ctx, copy_mode, data);
259*bd882c8aSJames Wright   }
260*bd882c8aSJames Wright 
261*bd882c8aSJames Wright   return CEED_ERROR_UNSUPPORTED;
262*bd882c8aSJames Wright }
263*bd882c8aSJames Wright 
264*bd882c8aSJames Wright //------------------------------------------------------------------------------
265*bd882c8aSJames Wright // Take data
266*bd882c8aSJames Wright //------------------------------------------------------------------------------
267*bd882c8aSJames Wright static int CeedQFunctionContextTakeData_Sycl(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
268*bd882c8aSJames Wright   Ceed ceed;
269*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
270*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
271*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
272*bd882c8aSJames Wright 
273*bd882c8aSJames Wright   Ceed_Sycl *ceedSycl;
274*bd882c8aSJames Wright   CeedCallBackend(CeedGetData(ceed, &ceedSycl));
275*bd882c8aSJames Wright 
276*bd882c8aSJames Wright   // Order queue
277*bd882c8aSJames Wright   ceedSycl->sycl_queue.ext_oneapi_submit_barrier();
278*bd882c8aSJames Wright 
279*bd882c8aSJames Wright   // Sync data to requested mem_type
280*bd882c8aSJames Wright   bool need_sync = false;
281*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextNeedSync_Sycl(ctx, mem_type, &need_sync));
282*bd882c8aSJames Wright   if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Sycl(ctx, mem_type));
283*bd882c8aSJames Wright 
284*bd882c8aSJames Wright   // Update pointer
285*bd882c8aSJames Wright   switch (mem_type) {
286*bd882c8aSJames Wright     case CEED_MEM_HOST:
287*bd882c8aSJames Wright       *(void **)data        = impl->h_data_borrowed;
288*bd882c8aSJames Wright       impl->h_data_borrowed = NULL;
289*bd882c8aSJames Wright       impl->h_data          = NULL;
290*bd882c8aSJames Wright       break;
291*bd882c8aSJames Wright     case CEED_MEM_DEVICE:
292*bd882c8aSJames Wright       *(void **)data        = impl->d_data_borrowed;
293*bd882c8aSJames Wright       impl->d_data_borrowed = NULL;
294*bd882c8aSJames Wright       impl->d_data          = NULL;
295*bd882c8aSJames Wright       break;
296*bd882c8aSJames Wright   }
297*bd882c8aSJames Wright 
298*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
299*bd882c8aSJames Wright }
300*bd882c8aSJames Wright 
301*bd882c8aSJames Wright //------------------------------------------------------------------------------
302*bd882c8aSJames Wright // Core logic for GetData.
303*bd882c8aSJames Wright //   If a different memory type is most up to date, this will perform a copy
304*bd882c8aSJames Wright //------------------------------------------------------------------------------
305*bd882c8aSJames Wright static int CeedQFunctionContextGetDataCore_Sycl(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
306*bd882c8aSJames Wright   Ceed ceed;
307*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
308*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
309*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
310*bd882c8aSJames Wright 
311*bd882c8aSJames Wright   // Sync data to requested mem_type
312*bd882c8aSJames Wright   bool need_sync = false;
313*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextNeedSync_Sycl(ctx, mem_type, &need_sync));
314*bd882c8aSJames Wright   if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Sycl(ctx, mem_type));
315*bd882c8aSJames Wright 
316*bd882c8aSJames Wright   // Update pointer
317*bd882c8aSJames Wright   switch (mem_type) {
318*bd882c8aSJames Wright     case CEED_MEM_HOST:
319*bd882c8aSJames Wright       *(void **)data = impl->h_data;
320*bd882c8aSJames Wright       break;
321*bd882c8aSJames Wright     case CEED_MEM_DEVICE:
322*bd882c8aSJames Wright       *(void **)data = impl->d_data;
323*bd882c8aSJames Wright       break;
324*bd882c8aSJames Wright   }
325*bd882c8aSJames Wright 
326*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
327*bd882c8aSJames Wright }
328*bd882c8aSJames Wright 
329*bd882c8aSJames Wright //------------------------------------------------------------------------------
330*bd882c8aSJames Wright // Get read-only access to the data
331*bd882c8aSJames Wright //------------------------------------------------------------------------------
332*bd882c8aSJames Wright static int CeedQFunctionContextGetDataRead_Sycl(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
333*bd882c8aSJames Wright   return CeedQFunctionContextGetDataCore_Sycl(ctx, mem_type, data);
334*bd882c8aSJames Wright }
335*bd882c8aSJames Wright 
336*bd882c8aSJames Wright //------------------------------------------------------------------------------
337*bd882c8aSJames Wright // Get read/write access to the data
338*bd882c8aSJames Wright //------------------------------------------------------------------------------
339*bd882c8aSJames Wright static int CeedQFunctionContextGetData_Sycl(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
340*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
341*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
342*bd882c8aSJames Wright   Ceed ceed;
343*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
344*bd882c8aSJames Wright 
345*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetDataCore_Sycl(ctx, mem_type, data));
346*bd882c8aSJames Wright 
347*bd882c8aSJames Wright   // Mark only pointer for requested memory as valid
348*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextSetAllInvalid_Sycl(ctx));
349*bd882c8aSJames Wright   switch (mem_type) {
350*bd882c8aSJames Wright     case CEED_MEM_HOST:
351*bd882c8aSJames Wright       impl->h_data = *(void **)data;
352*bd882c8aSJames Wright       break;
353*bd882c8aSJames Wright     case CEED_MEM_DEVICE:
354*bd882c8aSJames Wright       impl->d_data = *(void **)data;
355*bd882c8aSJames Wright       break;
356*bd882c8aSJames Wright   }
357*bd882c8aSJames Wright 
358*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
359*bd882c8aSJames Wright }
360*bd882c8aSJames Wright 
361*bd882c8aSJames Wright //------------------------------------------------------------------------------
362*bd882c8aSJames Wright // Destroy the user context
363*bd882c8aSJames Wright //------------------------------------------------------------------------------
364*bd882c8aSJames Wright static int CeedQFunctionContextDestroy_Sycl(const CeedQFunctionContext ctx) {
365*bd882c8aSJames Wright   Ceed ceed;
366*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
367*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
368*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
369*bd882c8aSJames Wright   Ceed_Sycl *sycl_data;
370*bd882c8aSJames Wright   CeedCallBackend(CeedGetData(ceed, &sycl_data));
371*bd882c8aSJames Wright 
372*bd882c8aSJames Wright   // Wait for all work to finish before freeing memory
373*bd882c8aSJames Wright   CeedCallSycl(ceed, sycl_data->sycl_queue.wait_and_throw());
374*bd882c8aSJames Wright   CeedCallSycl(ceed, sycl::free(impl->d_data_owned, sycl_data->sycl_context));
375*bd882c8aSJames Wright   CeedCallBackend(CeedFree(&impl->h_data_owned));
376*bd882c8aSJames Wright   CeedCallBackend(CeedFree(&impl));
377*bd882c8aSJames Wright 
378*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
379*bd882c8aSJames Wright }
380*bd882c8aSJames Wright 
381*bd882c8aSJames Wright //------------------------------------------------------------------------------
382*bd882c8aSJames Wright // QFunctionContext Create
383*bd882c8aSJames Wright //------------------------------------------------------------------------------
384*bd882c8aSJames Wright int CeedQFunctionContextCreate_Sycl(CeedQFunctionContext ctx) {
385*bd882c8aSJames Wright   CeedQFunctionContext_Sycl *impl;
386*bd882c8aSJames Wright   Ceed                       ceed;
387*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
388*bd882c8aSJames Wright 
389*bd882c8aSJames Wright   CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Sycl));
390*bd882c8aSJames Wright   CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Sycl));
391*bd882c8aSJames Wright   CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Sycl));
392*bd882c8aSJames Wright   CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Sycl));
393*bd882c8aSJames Wright   CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Sycl));
394*bd882c8aSJames Wright   CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Sycl));
395*bd882c8aSJames Wright   CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Sycl));
396*bd882c8aSJames Wright 
397*bd882c8aSJames Wright   CeedCallBackend(CeedCalloc(1, &impl));
398*bd882c8aSJames Wright   CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl));
399*bd882c8aSJames Wright 
400*bd882c8aSJames Wright   return CEED_ERROR_SUCCESS;
401*bd882c8aSJames Wright }
402*bd882c8aSJames Wright //------------------------------------------------------------------------------
403