xref: /libCEED/rust/libceed-sys/c-src/backends/hip-ref/ceed-hip-ref-vector.c (revision 2b730f8b5a9c809740a0b3b302db43a719c636b1)
13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
30d0321e0SJeremy L Thompson //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
50d0321e0SJeremy L Thompson //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
70d0321e0SJeremy L Thompson 
80d0321e0SJeremy L Thompson #include <ceed/backend.h>
9*2b730f8bSJeremy L Thompson #include <ceed/ceed.h>
100d0321e0SJeremy L Thompson #include <hip/hip_runtime.h>
110d0321e0SJeremy L Thompson #include <math.h>
120d0321e0SJeremy L Thompson #include <string.h>
130d0321e0SJeremy L Thompson 
14*2b730f8bSJeremy L Thompson #include "ceed-hip-ref.h"
15f48ed27dSnbeams 
16f48ed27dSnbeams //------------------------------------------------------------------------------
17f48ed27dSnbeams // Check if host/device sync is needed
18f48ed27dSnbeams //------------------------------------------------------------------------------
19*2b730f8bSJeremy L Thompson static inline int CeedVectorNeedSync_Hip(const CeedVector vec, CeedMemType mem_type, bool *need_sync) {
20f48ed27dSnbeams   CeedVector_Hip *impl;
21*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
22f48ed27dSnbeams 
23f48ed27dSnbeams   bool has_valid_array = false;
24*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorHasValidArray(vec, &has_valid_array));
25f48ed27dSnbeams   switch (mem_type) {
26f48ed27dSnbeams     case CEED_MEM_HOST:
27f48ed27dSnbeams       *need_sync = has_valid_array && !impl->h_array;
28f48ed27dSnbeams       break;
29f48ed27dSnbeams     case CEED_MEM_DEVICE:
30f48ed27dSnbeams       *need_sync = has_valid_array && !impl->d_array;
31f48ed27dSnbeams       break;
32f48ed27dSnbeams   }
33f48ed27dSnbeams 
34f48ed27dSnbeams   return CEED_ERROR_SUCCESS;
35f48ed27dSnbeams }
36f48ed27dSnbeams 
370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
380d0321e0SJeremy L Thompson // Sync host to device
390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
400d0321e0SJeremy L Thompson static inline int CeedVectorSyncH2D_Hip(const CeedVector vec) {
410d0321e0SJeremy L Thompson   Ceed ceed;
42*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
430d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
44*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
450d0321e0SJeremy L Thompson 
46539ec17dSJeremy L Thompson   CeedSize length;
47*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
48539ec17dSJeremy L Thompson   size_t bytes = length * sizeof(CeedScalar);
49539ec17dSJeremy L Thompson 
50*2b730f8bSJeremy L Thompson   if (!impl->h_array) {
510d0321e0SJeremy L Thompson     // LCOV_EXCL_START
52*2b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "No valid host data to sync to device");
530d0321e0SJeremy L Thompson     // LCOV_EXCL_STOP
54*2b730f8bSJeremy L Thompson   }
550d0321e0SJeremy L Thompson 
560d0321e0SJeremy L Thompson   if (impl->d_array_borrowed) {
570d0321e0SJeremy L Thompson     impl->d_array = impl->d_array_borrowed;
580d0321e0SJeremy L Thompson   } else if (impl->d_array_owned) {
590d0321e0SJeremy L Thompson     impl->d_array = impl->d_array_owned;
600d0321e0SJeremy L Thompson   } else {
61*2b730f8bSJeremy L Thompson     CeedCallHip(ceed, hipMalloc((void **)&impl->d_array_owned, bytes));
620d0321e0SJeremy L Thompson     impl->d_array = impl->d_array_owned;
630d0321e0SJeremy L Thompson   }
640d0321e0SJeremy L Thompson 
65*2b730f8bSJeremy L Thompson   CeedCallHip(ceed, hipMemcpy(impl->d_array, impl->h_array, bytes, hipMemcpyHostToDevice));
660d0321e0SJeremy L Thompson 
670d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
680d0321e0SJeremy L Thompson }
690d0321e0SJeremy L Thompson 
700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
710d0321e0SJeremy L Thompson // Sync device to host
720d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
730d0321e0SJeremy L Thompson static inline int CeedVectorSyncD2H_Hip(const CeedVector vec) {
740d0321e0SJeremy L Thompson   Ceed ceed;
75*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
760d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
77*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
780d0321e0SJeremy L Thompson 
79*2b730f8bSJeremy L Thompson   if (!impl->d_array) {
800d0321e0SJeremy L Thompson     // LCOV_EXCL_START
81*2b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "No valid device data to sync to host");
820d0321e0SJeremy L Thompson     // LCOV_EXCL_STOP
83*2b730f8bSJeremy L Thompson   }
840d0321e0SJeremy L Thompson 
850d0321e0SJeremy L Thompson   if (impl->h_array_borrowed) {
860d0321e0SJeremy L Thompson     impl->h_array = impl->h_array_borrowed;
870d0321e0SJeremy L Thompson   } else if (impl->h_array_owned) {
880d0321e0SJeremy L Thompson     impl->h_array = impl->h_array_owned;
890d0321e0SJeremy L Thompson   } else {
901f9221feSJeremy L Thompson     CeedSize length;
91*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetLength(vec, &length));
92*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedCalloc(length, &impl->h_array_owned));
930d0321e0SJeremy L Thompson     impl->h_array = impl->h_array_owned;
940d0321e0SJeremy L Thompson   }
950d0321e0SJeremy L Thompson 
96539ec17dSJeremy L Thompson   CeedSize length;
97*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
98539ec17dSJeremy L Thompson   size_t bytes = length * sizeof(CeedScalar);
99*2b730f8bSJeremy L Thompson   CeedCallHip(ceed, hipMemcpy(impl->h_array, impl->d_array, bytes, hipMemcpyDeviceToHost));
1000d0321e0SJeremy L Thompson 
1010d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1020d0321e0SJeremy L Thompson }
1030d0321e0SJeremy L Thompson 
1040d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1050d0321e0SJeremy L Thompson // Sync arrays
1060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
107*2b730f8bSJeremy L Thompson static int CeedVectorSyncArray_Hip(const CeedVector vec, CeedMemType mem_type) {
108f48ed27dSnbeams   // Check whether device/host sync is needed
109f48ed27dSnbeams   bool need_sync = false;
110*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorNeedSync_Hip(vec, mem_type, &need_sync));
111*2b730f8bSJeremy L Thompson   if (!need_sync) return CEED_ERROR_SUCCESS;
112f48ed27dSnbeams 
11343c928f4SJeremy L Thompson   switch (mem_type) {
114*2b730f8bSJeremy L Thompson     case CEED_MEM_HOST:
115*2b730f8bSJeremy L Thompson       return CeedVectorSyncD2H_Hip(vec);
116*2b730f8bSJeremy L Thompson     case CEED_MEM_DEVICE:
117*2b730f8bSJeremy L Thompson       return CeedVectorSyncH2D_Hip(vec);
1180d0321e0SJeremy L Thompson   }
1190d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
1200d0321e0SJeremy L Thompson }
1210d0321e0SJeremy L Thompson 
1220d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1230d0321e0SJeremy L Thompson // Set all pointers as invalid
1240d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1250d0321e0SJeremy L Thompson static inline int CeedVectorSetAllInvalid_Hip(const CeedVector vec) {
1260d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
127*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
1280d0321e0SJeremy L Thompson 
1290d0321e0SJeremy L Thompson   impl->h_array = NULL;
1300d0321e0SJeremy L Thompson   impl->d_array = NULL;
1310d0321e0SJeremy L Thompson 
1320d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1330d0321e0SJeremy L Thompson }
1340d0321e0SJeremy L Thompson 
1350d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1360d0321e0SJeremy L Thompson // Check if CeedVector has any valid pointers
1370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
138*2b730f8bSJeremy L Thompson static inline int CeedVectorHasValidArray_Hip(const CeedVector vec, bool *has_valid_array) {
1390d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
140*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
1410d0321e0SJeremy L Thompson 
1420d0321e0SJeremy L Thompson   *has_valid_array = !!impl->h_array || !!impl->d_array;
1430d0321e0SJeremy L Thompson 
1440d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1450d0321e0SJeremy L Thompson }
1460d0321e0SJeremy L Thompson 
1470d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1480d0321e0SJeremy L Thompson // Check if has any array of given type
1490d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
150*2b730f8bSJeremy L Thompson static inline int CeedVectorHasArrayOfType_Hip(const CeedVector vec, CeedMemType mem_type, bool *has_array_of_type) {
1510d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
152*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
1530d0321e0SJeremy L Thompson 
15443c928f4SJeremy L Thompson   switch (mem_type) {
1550d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1560d0321e0SJeremy L Thompson       *has_array_of_type = !!impl->h_array_borrowed || !!impl->h_array_owned;
1570d0321e0SJeremy L Thompson       break;
1580d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1590d0321e0SJeremy L Thompson       *has_array_of_type = !!impl->d_array_borrowed || !!impl->d_array_owned;
1600d0321e0SJeremy L Thompson       break;
1610d0321e0SJeremy L Thompson   }
1620d0321e0SJeremy L Thompson 
1630d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1640d0321e0SJeremy L Thompson }
1650d0321e0SJeremy L Thompson 
1660d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1670d0321e0SJeremy L Thompson // Check if has borrowed array of given type
1680d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
169*2b730f8bSJeremy L Thompson static inline int CeedVectorHasBorrowedArrayOfType_Hip(const CeedVector vec, CeedMemType mem_type, bool *has_borrowed_array_of_type) {
1700d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
171*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
1720d0321e0SJeremy L Thompson 
17343c928f4SJeremy L Thompson   switch (mem_type) {
1740d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1750d0321e0SJeremy L Thompson       *has_borrowed_array_of_type = !!impl->h_array_borrowed;
1760d0321e0SJeremy L Thompson       break;
1770d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1780d0321e0SJeremy L Thompson       *has_borrowed_array_of_type = !!impl->d_array_borrowed;
1790d0321e0SJeremy L Thompson       break;
1800d0321e0SJeremy L Thompson   }
1810d0321e0SJeremy L Thompson 
1820d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1830d0321e0SJeremy L Thompson }
1840d0321e0SJeremy L Thompson 
1850d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1860d0321e0SJeremy L Thompson // Set array from host
1870d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
188*2b730f8bSJeremy L Thompson static int CeedVectorSetArrayHost_Hip(const CeedVector vec, const CeedCopyMode copy_mode, CeedScalar *array) {
1890d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
190*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
1910d0321e0SJeremy L Thompson 
19243c928f4SJeremy L Thompson   switch (copy_mode) {
1930d0321e0SJeremy L Thompson     case CEED_COPY_VALUES: {
1941f9221feSJeremy L Thompson       CeedSize length;
1950d0321e0SJeremy L Thompson       if (!impl->h_array_owned) {
196*2b730f8bSJeremy L Thompson         CeedCallBackend(CeedVectorGetLength(vec, &length));
197*2b730f8bSJeremy L Thompson         CeedCallBackend(CeedMalloc(length, &impl->h_array_owned));
1980d0321e0SJeremy L Thompson       }
1990d0321e0SJeremy L Thompson       impl->h_array_borrowed = NULL;
2000d0321e0SJeremy L Thompson       impl->h_array          = impl->h_array_owned;
201539ec17dSJeremy L Thompson       if (array) {
202539ec17dSJeremy L Thompson         CeedSize length;
203*2b730f8bSJeremy L Thompson         CeedCallBackend(CeedVectorGetLength(vec, &length));
204539ec17dSJeremy L Thompson         size_t bytes = length * sizeof(CeedScalar);
205539ec17dSJeremy L Thompson         memcpy(impl->h_array, array, bytes);
206539ec17dSJeremy L Thompson       }
2070d0321e0SJeremy L Thompson     } break;
2080d0321e0SJeremy L Thompson     case CEED_OWN_POINTER:
209*2b730f8bSJeremy L Thompson       CeedCallBackend(CeedFree(&impl->h_array_owned));
2100d0321e0SJeremy L Thompson       impl->h_array_owned    = array;
2110d0321e0SJeremy L Thompson       impl->h_array_borrowed = NULL;
2120d0321e0SJeremy L Thompson       impl->h_array          = array;
2130d0321e0SJeremy L Thompson       break;
2140d0321e0SJeremy L Thompson     case CEED_USE_POINTER:
215*2b730f8bSJeremy L Thompson       CeedCallBackend(CeedFree(&impl->h_array_owned));
2160d0321e0SJeremy L Thompson       impl->h_array_borrowed = array;
2170d0321e0SJeremy L Thompson       impl->h_array          = array;
2180d0321e0SJeremy L Thompson       break;
2190d0321e0SJeremy L Thompson   }
2200d0321e0SJeremy L Thompson 
2210d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2220d0321e0SJeremy L Thompson }
2230d0321e0SJeremy L Thompson 
2240d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2250d0321e0SJeremy L Thompson // Set array from device
2260d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
227*2b730f8bSJeremy L Thompson static int CeedVectorSetArrayDevice_Hip(const CeedVector vec, const CeedCopyMode copy_mode, CeedScalar *array) {
2280d0321e0SJeremy L Thompson   Ceed ceed;
229*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
2300d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
231*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
2320d0321e0SJeremy L Thompson 
23343c928f4SJeremy L Thompson   switch (copy_mode) {
234539ec17dSJeremy L Thompson     case CEED_COPY_VALUES: {
235539ec17dSJeremy L Thompson       CeedSize length;
236*2b730f8bSJeremy L Thompson       CeedCallBackend(CeedVectorGetLength(vec, &length));
237539ec17dSJeremy L Thompson       size_t bytes = length * sizeof(CeedScalar);
2380d0321e0SJeremy L Thompson       if (!impl->d_array_owned) {
239*2b730f8bSJeremy L Thompson         CeedCallHip(ceed, hipMalloc((void **)&impl->d_array_owned, bytes));
2400d0321e0SJeremy L Thompson       }
2410d0321e0SJeremy L Thompson       impl->d_array_borrowed = NULL;
2420d0321e0SJeremy L Thompson       impl->d_array          = impl->d_array_owned;
2430d0321e0SJeremy L Thompson       if (array) {
244*2b730f8bSJeremy L Thompson         CeedCallHip(ceed, hipMemcpy(impl->d_array, array, bytes, hipMemcpyDeviceToDevice));
2450d0321e0SJeremy L Thompson       }
246539ec17dSJeremy L Thompson     } break;
2470d0321e0SJeremy L Thompson     case CEED_OWN_POINTER:
248*2b730f8bSJeremy L Thompson       CeedCallHip(ceed, hipFree(impl->d_array_owned));
2490d0321e0SJeremy L Thompson       impl->d_array_owned    = array;
2500d0321e0SJeremy L Thompson       impl->d_array_borrowed = NULL;
2510d0321e0SJeremy L Thompson       impl->d_array          = array;
2520d0321e0SJeremy L Thompson       break;
2530d0321e0SJeremy L Thompson     case CEED_USE_POINTER:
254*2b730f8bSJeremy L Thompson       CeedCallHip(ceed, hipFree(impl->d_array_owned));
2550d0321e0SJeremy L Thompson       impl->d_array_owned    = NULL;
2560d0321e0SJeremy L Thompson       impl->d_array_borrowed = array;
2570d0321e0SJeremy L Thompson       impl->d_array          = array;
2580d0321e0SJeremy L Thompson       break;
2590d0321e0SJeremy L Thompson   }
2600d0321e0SJeremy L Thompson 
2610d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2620d0321e0SJeremy L Thompson }
2630d0321e0SJeremy L Thompson 
2640d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2650d0321e0SJeremy L Thompson // Set the array used by a vector,
2660d0321e0SJeremy L Thompson //   freeing any previously allocated array if applicable
2670d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
268*2b730f8bSJeremy L Thompson static int CeedVectorSetArray_Hip(const CeedVector vec, const CeedMemType mem_type, const CeedCopyMode copy_mode, CeedScalar *array) {
2690d0321e0SJeremy L Thompson   Ceed ceed;
270*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
2710d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
272*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
2730d0321e0SJeremy L Thompson 
274*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSetAllInvalid_Hip(vec));
27543c928f4SJeremy L Thompson   switch (mem_type) {
2760d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
27743c928f4SJeremy L Thompson       return CeedVectorSetArrayHost_Hip(vec, copy_mode, array);
2780d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
27943c928f4SJeremy L Thompson       return CeedVectorSetArrayDevice_Hip(vec, copy_mode, array);
2800d0321e0SJeremy L Thompson   }
2810d0321e0SJeremy L Thompson 
2820d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
2830d0321e0SJeremy L Thompson }
2840d0321e0SJeremy L Thompson 
2850d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2860d0321e0SJeremy L Thompson // Set host array to value
2870d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
288*2b730f8bSJeremy L Thompson static int CeedHostSetValue_Hip(CeedScalar *h_array, CeedInt length, CeedScalar val) {
289*2b730f8bSJeremy L Thompson   for (int i = 0; i < length; i++) h_array[i] = val;
2900d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2910d0321e0SJeremy L Thompson }
2920d0321e0SJeremy L Thompson 
2930d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2940d0321e0SJeremy L Thompson // Set device array to value (impl in .hip file)
2950d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2960d0321e0SJeremy L Thompson int CeedDeviceSetValue_Hip(CeedScalar *d_array, CeedInt length, CeedScalar val);
2970d0321e0SJeremy L Thompson 
2980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2990d0321e0SJeremy L Thompson // Set a vector to a value,
3000d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3010d0321e0SJeremy L Thompson static int CeedVectorSetValue_Hip(CeedVector vec, CeedScalar val) {
3020d0321e0SJeremy L Thompson   Ceed ceed;
303*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
3040d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
305*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
3061f9221feSJeremy L Thompson   CeedSize length;
307*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
3080d0321e0SJeremy L Thompson 
3090d0321e0SJeremy L Thompson   // Set value for synced device/host array
3100d0321e0SJeremy L Thompson   if (!impl->d_array && !impl->h_array) {
3110d0321e0SJeremy L Thompson     if (impl->d_array_borrowed) {
3120d0321e0SJeremy L Thompson       impl->d_array = impl->d_array_borrowed;
3130d0321e0SJeremy L Thompson     } else if (impl->h_array_borrowed) {
3140d0321e0SJeremy L Thompson       impl->h_array = impl->h_array_borrowed;
3150d0321e0SJeremy L Thompson     } else if (impl->d_array_owned) {
3160d0321e0SJeremy L Thompson       impl->d_array = impl->d_array_owned;
3170d0321e0SJeremy L Thompson     } else if (impl->h_array_owned) {
3180d0321e0SJeremy L Thompson       impl->h_array = impl->h_array_owned;
3190d0321e0SJeremy L Thompson     } else {
320*2b730f8bSJeremy L Thompson       CeedCallBackend(CeedVectorSetArray(vec, CEED_MEM_DEVICE, CEED_COPY_VALUES, NULL));
3210d0321e0SJeremy L Thompson     }
3220d0321e0SJeremy L Thompson   }
3230d0321e0SJeremy L Thompson   if (impl->d_array) {
324*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedDeviceSetValue_Hip(impl->d_array, length, val));
3250d0321e0SJeremy L Thompson   }
3260d0321e0SJeremy L Thompson   if (impl->h_array) {
327*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedHostSetValue_Hip(impl->h_array, length, val));
3280d0321e0SJeremy L Thompson   }
3290d0321e0SJeremy L Thompson 
3300d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3310d0321e0SJeremy L Thompson }
3320d0321e0SJeremy L Thompson 
3330d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3340d0321e0SJeremy L Thompson // Vector Take Array
3350d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
336*2b730f8bSJeremy L Thompson static int CeedVectorTakeArray_Hip(CeedVector vec, CeedMemType mem_type, CeedScalar **array) {
3370d0321e0SJeremy L Thompson   Ceed ceed;
338*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
3390d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
340*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
3410d0321e0SJeremy L Thompson 
34243c928f4SJeremy L Thompson   // Sync array to requested mem_type
343*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSyncArray(vec, mem_type));
3440d0321e0SJeremy L Thompson 
3450d0321e0SJeremy L Thompson   // Update pointer
34643c928f4SJeremy L Thompson   switch (mem_type) {
3470d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
3480d0321e0SJeremy L Thompson       (*array)               = impl->h_array_borrowed;
3490d0321e0SJeremy L Thompson       impl->h_array_borrowed = NULL;
3500d0321e0SJeremy L Thompson       impl->h_array          = NULL;
3510d0321e0SJeremy L Thompson       break;
3520d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
3530d0321e0SJeremy L Thompson       (*array)               = impl->d_array_borrowed;
3540d0321e0SJeremy L Thompson       impl->d_array_borrowed = NULL;
3550d0321e0SJeremy L Thompson       impl->d_array          = NULL;
3560d0321e0SJeremy L Thompson       break;
3570d0321e0SJeremy L Thompson   }
3580d0321e0SJeremy L Thompson 
3590d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3600d0321e0SJeremy L Thompson }
3610d0321e0SJeremy L Thompson 
3620d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3630d0321e0SJeremy L Thompson // Core logic for array syncronization for GetArray.
3640d0321e0SJeremy L Thompson //   If a different memory type is most up to date, this will perform a copy
3650d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
366*2b730f8bSJeremy L Thompson static int CeedVectorGetArrayCore_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) {
3670d0321e0SJeremy L Thompson   Ceed ceed;
368*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
3690d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
370*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
3710d0321e0SJeremy L Thompson 
37243c928f4SJeremy L Thompson   // Sync array to requested mem_type
373*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSyncArray(vec, mem_type));
3740d0321e0SJeremy L Thompson 
3750d0321e0SJeremy L Thompson   // Update pointer
37643c928f4SJeremy L Thompson   switch (mem_type) {
3770d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
3780d0321e0SJeremy L Thompson       *array = impl->h_array;
3790d0321e0SJeremy L Thompson       break;
3800d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
3810d0321e0SJeremy L Thompson       *array = impl->d_array;
3820d0321e0SJeremy L Thompson       break;
3830d0321e0SJeremy L Thompson   }
3840d0321e0SJeremy L Thompson 
3850d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3860d0321e0SJeremy L Thompson }
3870d0321e0SJeremy L Thompson 
3880d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
38943c928f4SJeremy L Thompson // Get read-only access to a vector via the specified mem_type
3900d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
391*2b730f8bSJeremy L Thompson static int CeedVectorGetArrayRead_Hip(const CeedVector vec, const CeedMemType mem_type, const CeedScalar **array) {
39243c928f4SJeremy L Thompson   return CeedVectorGetArrayCore_Hip(vec, mem_type, (CeedScalar **)array);
3930d0321e0SJeremy L Thompson }
3940d0321e0SJeremy L Thompson 
3950d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
39643c928f4SJeremy L Thompson // Get read/write access to a vector via the specified mem_type
3970d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
398*2b730f8bSJeremy L Thompson static int CeedVectorGetArray_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) {
3990d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
400*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
4010d0321e0SJeremy L Thompson 
402*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetArrayCore_Hip(vec, mem_type, array));
4030d0321e0SJeremy L Thompson 
404*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSetAllInvalid_Hip(vec));
40543c928f4SJeremy L Thompson   switch (mem_type) {
4060d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
4070d0321e0SJeremy L Thompson       impl->h_array = *array;
4080d0321e0SJeremy L Thompson       break;
4090d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
4100d0321e0SJeremy L Thompson       impl->d_array = *array;
4110d0321e0SJeremy L Thompson       break;
4120d0321e0SJeremy L Thompson   }
4130d0321e0SJeremy L Thompson 
4140d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4150d0321e0SJeremy L Thompson }
4160d0321e0SJeremy L Thompson 
4170d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
41843c928f4SJeremy L Thompson // Get write access to a vector via the specified mem_type
4190d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
420*2b730f8bSJeremy L Thompson static int CeedVectorGetArrayWrite_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) {
4210d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
422*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
4230d0321e0SJeremy L Thompson 
4240d0321e0SJeremy L Thompson   bool has_array_of_type = true;
425*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorHasArrayOfType_Hip(vec, mem_type, &has_array_of_type));
4260d0321e0SJeremy L Thompson   if (!has_array_of_type) {
4270d0321e0SJeremy L Thompson     // Allocate if array is not yet allocated
428*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSetArray(vec, mem_type, CEED_COPY_VALUES, NULL));
4290d0321e0SJeremy L Thompson   } else {
4300d0321e0SJeremy L Thompson     // Select dirty array
43143c928f4SJeremy L Thompson     switch (mem_type) {
4320d0321e0SJeremy L Thompson       case CEED_MEM_HOST:
433*2b730f8bSJeremy L Thompson         if (impl->h_array_borrowed) impl->h_array = impl->h_array_borrowed;
434*2b730f8bSJeremy L Thompson         else impl->h_array = impl->h_array_owned;
4350d0321e0SJeremy L Thompson         break;
4360d0321e0SJeremy L Thompson       case CEED_MEM_DEVICE:
437*2b730f8bSJeremy L Thompson         if (impl->d_array_borrowed) impl->d_array = impl->d_array_borrowed;
438*2b730f8bSJeremy L Thompson         else impl->d_array = impl->d_array_owned;
4390d0321e0SJeremy L Thompson     }
4400d0321e0SJeremy L Thompson   }
4410d0321e0SJeremy L Thompson 
44243c928f4SJeremy L Thompson   return CeedVectorGetArray_Hip(vec, mem_type, array);
4430d0321e0SJeremy L Thompson }
4440d0321e0SJeremy L Thompson 
4450d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4460d0321e0SJeremy L Thompson // Get the norm of a CeedVector
4470d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
448*2b730f8bSJeremy L Thompson static int CeedVectorNorm_Hip(CeedVector vec, CeedNormType type, CeedScalar *norm) {
4490d0321e0SJeremy L Thompson   Ceed ceed;
450*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
4510d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
452*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
4531f9221feSJeremy L Thompson   CeedSize length;
454*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
4550d0321e0SJeremy L Thompson   hipblasHandle_t handle;
456*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedHipGetHipblasHandle(ceed, &handle));
4570d0321e0SJeremy L Thompson 
4580d0321e0SJeremy L Thompson   // Compute norm
4590d0321e0SJeremy L Thompson   const CeedScalar *d_array;
460*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetArrayRead(vec, CEED_MEM_DEVICE, &d_array));
4610d0321e0SJeremy L Thompson   switch (type) {
4620d0321e0SJeremy L Thompson     case CEED_NORM_1: {
4630d0321e0SJeremy L Thompson       if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) {
464*2b730f8bSJeremy L Thompson         CeedCallHipblas(ceed, hipblasSasum(handle, length, (float *)d_array, 1, (float *)norm));
4650d0321e0SJeremy L Thompson       } else {
466*2b730f8bSJeremy L Thompson         CeedCallHipblas(ceed, hipblasDasum(handle, length, (double *)d_array, 1, (double *)norm));
4670d0321e0SJeremy L Thompson       }
4680d0321e0SJeremy L Thompson       break;
4690d0321e0SJeremy L Thompson     }
4700d0321e0SJeremy L Thompson     case CEED_NORM_2: {
4710d0321e0SJeremy L Thompson       if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) {
472*2b730f8bSJeremy L Thompson         CeedCallHipblas(ceed, hipblasSnrm2(handle, length, (float *)d_array, 1, (float *)norm));
4730d0321e0SJeremy L Thompson       } else {
474*2b730f8bSJeremy L Thompson         CeedCallHipblas(ceed, hipblasDnrm2(handle, length, (double *)d_array, 1, (double *)norm));
4750d0321e0SJeremy L Thompson       }
4760d0321e0SJeremy L Thompson       break;
4770d0321e0SJeremy L Thompson     }
4780d0321e0SJeremy L Thompson     case CEED_NORM_MAX: {
4790d0321e0SJeremy L Thompson       CeedInt indx;
4800d0321e0SJeremy L Thompson       if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) {
481*2b730f8bSJeremy L Thompson         CeedCallHipblas(ceed, hipblasIsamax(handle, length, (float *)d_array, 1, &indx));
4820d0321e0SJeremy L Thompson       } else {
483*2b730f8bSJeremy L Thompson         CeedCallHipblas(ceed, hipblasIdamax(handle, length, (double *)d_array, 1, &indx));
4840d0321e0SJeremy L Thompson       }
4850d0321e0SJeremy L Thompson       CeedScalar normNoAbs;
486*2b730f8bSJeremy L Thompson       CeedCallHip(ceed, hipMemcpy(&normNoAbs, impl->d_array + indx - 1, sizeof(CeedScalar), hipMemcpyDeviceToHost));
4870d0321e0SJeremy L Thompson       *norm = fabs(normNoAbs);
4880d0321e0SJeremy L Thompson       break;
4890d0321e0SJeremy L Thompson     }
4900d0321e0SJeremy L Thompson   }
491*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorRestoreArrayRead(vec, &d_array));
4920d0321e0SJeremy L Thompson 
4930d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4940d0321e0SJeremy L Thompson }
4950d0321e0SJeremy L Thompson 
4960d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4970d0321e0SJeremy L Thompson // Take reciprocal of a vector on host
4980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4990d0321e0SJeremy L Thompson static int CeedHostReciprocal_Hip(CeedScalar *h_array, CeedInt length) {
500*2b730f8bSJeremy L Thompson   for (int i = 0; i < length; i++) {
501*2b730f8bSJeremy L Thompson     if (fabs(h_array[i]) > CEED_EPSILON) h_array[i] = 1. / h_array[i];
502*2b730f8bSJeremy L Thompson   }
5030d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5040d0321e0SJeremy L Thompson }
5050d0321e0SJeremy L Thompson 
5060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5070d0321e0SJeremy L Thompson // Take reciprocal of a vector on device (impl in .cu file)
5080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5090d0321e0SJeremy L Thompson int CeedDeviceReciprocal_Hip(CeedScalar *d_array, CeedInt length);
5100d0321e0SJeremy L Thompson 
5110d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5120d0321e0SJeremy L Thompson // Take reciprocal of a vector
5130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5140d0321e0SJeremy L Thompson static int CeedVectorReciprocal_Hip(CeedVector vec) {
5150d0321e0SJeremy L Thompson   Ceed ceed;
516*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
5170d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
518*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
5191f9221feSJeremy L Thompson   CeedSize length;
520*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
5210d0321e0SJeremy L Thompson 
5220d0321e0SJeremy L Thompson   // Set value for synced device/host array
523*2b730f8bSJeremy L Thompson   if (impl->d_array) CeedCallBackend(CeedDeviceReciprocal_Hip(impl->d_array, length));
524*2b730f8bSJeremy L Thompson   if (impl->h_array) CeedCallBackend(CeedHostReciprocal_Hip(impl->h_array, length));
5250d0321e0SJeremy L Thompson 
5260d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5270d0321e0SJeremy L Thompson }
5280d0321e0SJeremy L Thompson 
5290d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5300d0321e0SJeremy L Thompson // Compute x = alpha x on the host
5310d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
532*2b730f8bSJeremy L Thompson static int CeedHostScale_Hip(CeedScalar *x_array, CeedScalar alpha, CeedInt length) {
533*2b730f8bSJeremy L Thompson   for (int i = 0; i < length; i++) x_array[i] *= alpha;
5340d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5350d0321e0SJeremy L Thompson }
5360d0321e0SJeremy L Thompson 
5370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5380d0321e0SJeremy L Thompson // Compute x = alpha x on device (impl in .cu file)
5390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
540*2b730f8bSJeremy L Thompson int CeedDeviceScale_Hip(CeedScalar *x_array, CeedScalar alpha, CeedInt length);
5410d0321e0SJeremy L Thompson 
5420d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5430d0321e0SJeremy L Thompson // Compute x = alpha x
5440d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5450d0321e0SJeremy L Thompson static int CeedVectorScale_Hip(CeedVector x, CeedScalar alpha) {
5460d0321e0SJeremy L Thompson   Ceed ceed;
547*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(x, &ceed));
5480d0321e0SJeremy L Thompson   CeedVector_Hip *x_impl;
549*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(x, &x_impl));
5501f9221feSJeremy L Thompson   CeedSize length;
551*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(x, &length));
5520d0321e0SJeremy L Thompson 
5530d0321e0SJeremy L Thompson   // Set value for synced device/host array
554*2b730f8bSJeremy L Thompson   if (x_impl->d_array) CeedCallBackend(CeedDeviceScale_Hip(x_impl->d_array, alpha, length));
555*2b730f8bSJeremy L Thompson   if (x_impl->h_array) CeedCallBackend(CeedHostScale_Hip(x_impl->h_array, alpha, length));
5560d0321e0SJeremy L Thompson 
5570d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5580d0321e0SJeremy L Thompson }
5590d0321e0SJeremy L Thompson 
5600d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5610d0321e0SJeremy L Thompson // Compute y = alpha x + y on the host
5620d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
563*2b730f8bSJeremy L Thompson static int CeedHostAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar *x_array, CeedInt length) {
564*2b730f8bSJeremy L Thompson   for (int i = 0; i < length; i++) y_array[i] += alpha * x_array[i];
5650d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5660d0321e0SJeremy L Thompson }
5670d0321e0SJeremy L Thompson 
5680d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5690d0321e0SJeremy L Thompson // Compute y = alpha x + y on device (impl in .cu file)
5700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
571*2b730f8bSJeremy L Thompson int CeedDeviceAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar *x_array, CeedInt length);
5720d0321e0SJeremy L Thompson 
5730d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5740d0321e0SJeremy L Thompson // Compute y = alpha x + y
5750d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5760d0321e0SJeremy L Thompson static int CeedVectorAXPY_Hip(CeedVector y, CeedScalar alpha, CeedVector x) {
5770d0321e0SJeremy L Thompson   Ceed ceed;
578*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(y, &ceed));
5790d0321e0SJeremy L Thompson   CeedVector_Hip *y_impl, *x_impl;
580*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(y, &y_impl));
581*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(x, &x_impl));
5821f9221feSJeremy L Thompson   CeedSize length;
583*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(y, &length));
5840d0321e0SJeremy L Thompson 
5850d0321e0SJeremy L Thompson   // Set value for synced device/host array
5860d0321e0SJeremy L Thompson   if (y_impl->d_array) {
587*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE));
588*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedDeviceAXPY_Hip(y_impl->d_array, alpha, x_impl->d_array, length));
5890d0321e0SJeremy L Thompson   }
5900d0321e0SJeremy L Thompson   if (y_impl->h_array) {
591*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST));
592*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedHostAXPY_Hip(y_impl->h_array, alpha, x_impl->h_array, length));
5930d0321e0SJeremy L Thompson   }
5940d0321e0SJeremy L Thompson 
5950d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5960d0321e0SJeremy L Thompson }
5970d0321e0SJeremy L Thompson 
5980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
5990d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on the host
6000d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
601*2b730f8bSJeremy L Thompson static int CeedHostPointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, CeedScalar *y_array, CeedInt length) {
602*2b730f8bSJeremy L Thompson   for (int i = 0; i < length; i++) w_array[i] = x_array[i] * y_array[i];
6030d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6040d0321e0SJeremy L Thompson }
6050d0321e0SJeremy L Thompson 
6060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6070d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on device (impl in .cu file)
6080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
609*2b730f8bSJeremy L Thompson int CeedDevicePointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, CeedScalar *y_array, CeedInt length);
6100d0321e0SJeremy L Thompson 
6110d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6120d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y
6130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
614*2b730f8bSJeremy L Thompson static int CeedVectorPointwiseMult_Hip(CeedVector w, CeedVector x, CeedVector y) {
6150d0321e0SJeremy L Thompson   Ceed ceed;
616*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(w, &ceed));
6170d0321e0SJeremy L Thompson   CeedVector_Hip *w_impl, *x_impl, *y_impl;
618*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(w, &w_impl));
619*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(x, &x_impl));
620*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(y, &y_impl));
6211f9221feSJeremy L Thompson   CeedSize length;
622*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(w, &length));
6230d0321e0SJeremy L Thompson 
6240d0321e0SJeremy L Thompson   // Set value for synced device/host array
6250d0321e0SJeremy L Thompson   if (!w_impl->d_array && !w_impl->h_array) {
626*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSetValue(w, 0.0));
6270d0321e0SJeremy L Thompson   }
6280d0321e0SJeremy L Thompson   if (w_impl->d_array) {
629*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE));
630*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(y, CEED_MEM_DEVICE));
631*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedDevicePointwiseMult_Hip(w_impl->d_array, x_impl->d_array, y_impl->d_array, length));
6320d0321e0SJeremy L Thompson   }
6330d0321e0SJeremy L Thompson   if (w_impl->h_array) {
634*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST));
635*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(y, CEED_MEM_HOST));
636*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedHostPointwiseMult_Hip(w_impl->h_array, x_impl->h_array, y_impl->h_array, length));
6370d0321e0SJeremy L Thompson   }
6380d0321e0SJeremy L Thompson 
6390d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6400d0321e0SJeremy L Thompson }
6410d0321e0SJeremy L Thompson 
6420d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6430d0321e0SJeremy L Thompson // Destroy the vector
6440d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6450d0321e0SJeremy L Thompson static int CeedVectorDestroy_Hip(const CeedVector vec) {
6460d0321e0SJeremy L Thompson   Ceed ceed;
647*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
6480d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
649*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
6500d0321e0SJeremy L Thompson 
651*2b730f8bSJeremy L Thompson   CeedCallHip(ceed, hipFree(impl->d_array_owned));
652*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_array_owned));
653*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
6540d0321e0SJeremy L Thompson 
6550d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6560d0321e0SJeremy L Thompson }
6570d0321e0SJeremy L Thompson 
6580d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6590d0321e0SJeremy L Thompson // Create a vector of the specified length (does not allocate memory)
6600d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6611f9221feSJeremy L Thompson int CeedVectorCreate_Hip(CeedSize n, CeedVector vec) {
6620d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
6630d0321e0SJeremy L Thompson   Ceed            ceed;
664*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
6650d0321e0SJeremy L Thompson 
666*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", CeedVectorHasValidArray_Hip));
667*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", CeedVectorHasBorrowedArrayOfType_Hip));
668*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", CeedVectorSetArray_Hip));
669*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", CeedVectorTakeArray_Hip));
670*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetValue", (int (*)())(CeedVectorSetValue_Hip)));
671*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SyncArray", CeedVectorSyncArray_Hip));
672*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", CeedVectorGetArray_Hip));
673*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", CeedVectorGetArrayRead_Hip));
674*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", CeedVectorGetArrayWrite_Hip));
675*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Norm", CeedVectorNorm_Hip));
676*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Reciprocal", CeedVectorReciprocal_Hip));
677*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Scale", (int (*)())(CeedVectorScale_Hip)));
678*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "AXPY", (int (*)())(CeedVectorAXPY_Hip)));
679*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "PointwiseMult", CeedVectorPointwiseMult_Hip));
680*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", CeedVectorDestroy_Hip));
6810d0321e0SJeremy L Thompson 
682*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
683*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSetData(vec, impl));
6840d0321e0SJeremy L Thompson 
6850d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6860d0321e0SJeremy L Thompson }
687