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