xref: /libCEED/backends/hip-ref/ceed-hip-ref-vector.c (revision e84c3ebc97a9b078c9a14c8bdeb2c2ebf4a01814)
15aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, 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 
849aac155SJeremy L Thompson #include <ceed.h>
90d0321e0SJeremy L Thompson #include <ceed/backend.h>
100d0321e0SJeremy L Thompson #include <math.h>
1149aac155SJeremy L Thompson #include <stdbool.h>
120d0321e0SJeremy L Thompson #include <string.h>
13c85e8640SSebastian Grimberg #include <hip/hip_runtime.h>
140d0321e0SJeremy L Thompson 
1549aac155SJeremy L Thompson #include "../hip/ceed-hip-common.h"
162b730f8bSJeremy L Thompson #include "ceed-hip-ref.h"
17f48ed27dSnbeams 
18f48ed27dSnbeams //------------------------------------------------------------------------------
19f48ed27dSnbeams // Check if host/device sync is needed
20f48ed27dSnbeams //------------------------------------------------------------------------------
212b730f8bSJeremy L Thompson static inline int CeedVectorNeedSync_Hip(const CeedVector vec, CeedMemType mem_type, bool *need_sync) {
22f48ed27dSnbeams   CeedVector_Hip *impl;
23f48ed27dSnbeams   bool            has_valid_array = false;
24b7453713SJeremy L Thompson 
25b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
262b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorHasValidArray(vec, &has_valid_array));
27f48ed27dSnbeams   switch (mem_type) {
28f48ed27dSnbeams     case CEED_MEM_HOST:
29f48ed27dSnbeams       *need_sync = has_valid_array && !impl->h_array;
30f48ed27dSnbeams       break;
31f48ed27dSnbeams     case CEED_MEM_DEVICE:
32f48ed27dSnbeams       *need_sync = has_valid_array && !impl->d_array;
33f48ed27dSnbeams       break;
34f48ed27dSnbeams   }
35f48ed27dSnbeams   return CEED_ERROR_SUCCESS;
36f48ed27dSnbeams }
37f48ed27dSnbeams 
380d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
390d0321e0SJeremy L Thompson // Sync host to device
400d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
410d0321e0SJeremy L Thompson static inline int CeedVectorSyncH2D_Hip(const CeedVector vec) {
42b7453713SJeremy L Thompson   CeedSize        length;
43672b0f2aSSebastian Grimberg   size_t          bytes;
440d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
45b7453713SJeremy L Thompson 
462b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
470d0321e0SJeremy L Thompson 
489bc66399SJeremy L Thompson   CeedCheck(impl->h_array, CeedVectorReturnCeed(vec), CEED_ERROR_BACKEND, "No valid host data to sync to device");
490d0321e0SJeremy L Thompson 
50672b0f2aSSebastian Grimberg   CeedCallBackend(CeedVectorGetLength(vec, &length));
51672b0f2aSSebastian Grimberg   bytes = length * sizeof(CeedScalar);
520d0321e0SJeremy L Thompson   if (impl->d_array_borrowed) {
530d0321e0SJeremy L Thompson     impl->d_array = impl->d_array_borrowed;
540d0321e0SJeremy L Thompson   } else if (impl->d_array_owned) {
550d0321e0SJeremy L Thompson     impl->d_array = impl->d_array_owned;
560d0321e0SJeremy L Thompson   } else {
579bc66399SJeremy L Thompson     CeedCallHip(CeedVectorReturnCeed(vec), hipMalloc((void **)&impl->d_array_owned, bytes));
580d0321e0SJeremy L Thompson     impl->d_array = impl->d_array_owned;
590d0321e0SJeremy L Thompson   }
609bc66399SJeremy L Thompson   CeedCallHip(CeedVectorReturnCeed(vec), hipMemcpy(impl->d_array, impl->h_array, bytes, hipMemcpyHostToDevice));
610d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
620d0321e0SJeremy L Thompson }
630d0321e0SJeremy L Thompson 
640d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
650d0321e0SJeremy L Thompson // Sync device to host
660d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
670d0321e0SJeremy L Thompson static inline int CeedVectorSyncD2H_Hip(const CeedVector vec) {
68b7453713SJeremy L Thompson   CeedSize        length;
69672b0f2aSSebastian Grimberg   size_t          bytes;
700d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
71b7453713SJeremy L Thompson 
722b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
730d0321e0SJeremy L Thompson 
749bc66399SJeremy L Thompson   CeedCheck(impl->d_array, CeedVectorReturnCeed(vec), CEED_ERROR_BACKEND, "No valid device data to sync to host");
750d0321e0SJeremy L Thompson 
760d0321e0SJeremy L Thompson   if (impl->h_array_borrowed) {
770d0321e0SJeremy L Thompson     impl->h_array = impl->h_array_borrowed;
780d0321e0SJeremy L Thompson   } else if (impl->h_array_owned) {
790d0321e0SJeremy L Thompson     impl->h_array = impl->h_array_owned;
800d0321e0SJeremy L Thompson   } else {
811f9221feSJeremy L Thompson     CeedSize length;
82672b0f2aSSebastian Grimberg 
832b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetLength(vec, &length));
842b730f8bSJeremy L Thompson     CeedCallBackend(CeedCalloc(length, &impl->h_array_owned));
850d0321e0SJeremy L Thompson     impl->h_array = impl->h_array_owned;
860d0321e0SJeremy L Thompson   }
870d0321e0SJeremy L Thompson 
882b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
89672b0f2aSSebastian Grimberg   bytes = length * sizeof(CeedScalar);
909bc66399SJeremy L Thompson   CeedCallHip(CeedVectorReturnCeed(vec), hipMemcpy(impl->h_array, impl->d_array, bytes, hipMemcpyDeviceToHost));
910d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
920d0321e0SJeremy L Thompson }
930d0321e0SJeremy L Thompson 
940d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
950d0321e0SJeremy L Thompson // Sync arrays
960d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
972b730f8bSJeremy L Thompson static int CeedVectorSyncArray_Hip(const CeedVector vec, CeedMemType mem_type) {
98f48ed27dSnbeams   bool need_sync = false;
99b7453713SJeremy L Thompson 
100b7453713SJeremy L Thompson   // Check whether device/host sync is needed
1012b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorNeedSync_Hip(vec, mem_type, &need_sync));
1022b730f8bSJeremy L Thompson   if (!need_sync) return CEED_ERROR_SUCCESS;
103f48ed27dSnbeams 
10443c928f4SJeremy L Thompson   switch (mem_type) {
1052b730f8bSJeremy L Thompson     case CEED_MEM_HOST:
1062b730f8bSJeremy L Thompson       return CeedVectorSyncD2H_Hip(vec);
1072b730f8bSJeremy L Thompson     case CEED_MEM_DEVICE:
1082b730f8bSJeremy L Thompson       return CeedVectorSyncH2D_Hip(vec);
1090d0321e0SJeremy L Thompson   }
1100d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
1110d0321e0SJeremy L Thompson }
1120d0321e0SJeremy L Thompson 
1130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1140d0321e0SJeremy L Thompson // Set all pointers as invalid
1150d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1160d0321e0SJeremy L Thompson static inline int CeedVectorSetAllInvalid_Hip(const CeedVector vec) {
1170d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
1180d0321e0SJeremy L Thompson 
119b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
1200d0321e0SJeremy L Thompson   impl->h_array = NULL;
1210d0321e0SJeremy L Thompson   impl->d_array = NULL;
1220d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1230d0321e0SJeremy L Thompson }
1240d0321e0SJeremy L Thompson 
1250d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
126b2165e7aSSebastian Grimberg // Check if CeedVector has any valid pointer
1270d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1282b730f8bSJeremy L Thompson static inline int CeedVectorHasValidArray_Hip(const CeedVector vec, bool *has_valid_array) {
1290d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
130b7453713SJeremy L Thompson 
1312b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
1321c66c397SJeremy L Thompson   *has_valid_array = impl->h_array || impl->d_array;
1330d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1340d0321e0SJeremy L Thompson }
1350d0321e0SJeremy L Thompson 
1360d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
137b2165e7aSSebastian Grimberg // Check if has array of given type
1380d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1392b730f8bSJeremy L Thompson static inline int CeedVectorHasArrayOfType_Hip(const CeedVector vec, CeedMemType mem_type, bool *has_array_of_type) {
1400d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
1410d0321e0SJeremy L Thompson 
142b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
14343c928f4SJeremy L Thompson   switch (mem_type) {
1440d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1451c66c397SJeremy L Thompson       *has_array_of_type = impl->h_array_borrowed || impl->h_array_owned;
1460d0321e0SJeremy L Thompson       break;
1470d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1481c66c397SJeremy L Thompson       *has_array_of_type = impl->d_array_borrowed || impl->d_array_owned;
1490d0321e0SJeremy L Thompson       break;
1500d0321e0SJeremy L Thompson   }
1510d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1520d0321e0SJeremy L Thompson }
1530d0321e0SJeremy L Thompson 
1540d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1550d0321e0SJeremy L Thompson // Check if has borrowed array of given type
1560d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1572b730f8bSJeremy L Thompson static inline int CeedVectorHasBorrowedArrayOfType_Hip(const CeedVector vec, CeedMemType mem_type, bool *has_borrowed_array_of_type) {
1580d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
1590d0321e0SJeremy L Thompson 
160b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
16143c928f4SJeremy L Thompson   switch (mem_type) {
1620d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1631c66c397SJeremy L Thompson       *has_borrowed_array_of_type = impl->h_array_borrowed;
1640d0321e0SJeremy L Thompson       break;
1650d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1661c66c397SJeremy L Thompson       *has_borrowed_array_of_type = impl->d_array_borrowed;
1670d0321e0SJeremy L Thompson       break;
1680d0321e0SJeremy L Thompson   }
1690d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1700d0321e0SJeremy L Thompson }
1710d0321e0SJeremy L Thompson 
1720d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1730d0321e0SJeremy L Thompson // Set array from host
1740d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1752b730f8bSJeremy L Thompson static int CeedVectorSetArrayHost_Hip(const CeedVector vec, const CeedCopyMode copy_mode, CeedScalar *array) {
176a267acd1SJeremy L Thompson   CeedSize        length;
1770d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
1780d0321e0SJeremy L Thompson 
179b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
180a267acd1SJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
181a267acd1SJeremy L Thompson 
182f5d1e504SJeremy L Thompson   CeedCallBackend(CeedSetHostCeedScalarArray(array, copy_mode, length, (const CeedScalar **)&impl->h_array_owned,
183f5d1e504SJeremy L Thompson                                              (const CeedScalar **)&impl->h_array_borrowed, (const CeedScalar **)&impl->h_array));
1840d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1850d0321e0SJeremy L Thompson }
1860d0321e0SJeremy L Thompson 
1870d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1880d0321e0SJeremy L Thompson // Set array from device
1890d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1902b730f8bSJeremy L Thompson static int CeedVectorSetArrayDevice_Hip(const CeedVector vec, const CeedCopyMode copy_mode, CeedScalar *array) {
191a267acd1SJeremy L Thompson   CeedSize        length;
1920d0321e0SJeremy L Thompson   Ceed            ceed;
1930d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
1940d0321e0SJeremy L Thompson 
195b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
196b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
197a267acd1SJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
198f5d1e504SJeremy L Thompson 
199f5d1e504SJeremy L Thompson   CeedCallBackend(CeedSetDeviceCeedScalarArray_Hip(ceed, array, copy_mode, length, (const CeedScalar **)&impl->d_array_owned,
200f5d1e504SJeremy L Thompson                                                    (const CeedScalar **)&impl->d_array_borrowed, (const CeedScalar **)&impl->d_array));
2019bc66399SJeremy L Thompson   CeedCallBackend(CeedDestroy(&ceed));
2020d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2030d0321e0SJeremy L Thompson }
2040d0321e0SJeremy L Thompson 
2050d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2060d0321e0SJeremy L Thompson // Set the array used by a vector,
2070d0321e0SJeremy L Thompson //   freeing any previously allocated array if applicable
2080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2092b730f8bSJeremy L Thompson static int CeedVectorSetArray_Hip(const CeedVector vec, const CeedMemType mem_type, const CeedCopyMode copy_mode, CeedScalar *array) {
2100d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
2110d0321e0SJeremy L Thompson 
212b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
2132b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSetAllInvalid_Hip(vec));
21443c928f4SJeremy L Thompson   switch (mem_type) {
2150d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
21643c928f4SJeremy L Thompson       return CeedVectorSetArrayHost_Hip(vec, copy_mode, array);
2170d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
21843c928f4SJeremy L Thompson       return CeedVectorSetArrayDevice_Hip(vec, copy_mode, array);
2190d0321e0SJeremy L Thompson   }
2200d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
2210d0321e0SJeremy L Thompson }
2220d0321e0SJeremy L Thompson 
2230d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2243196072fSJeremy L Thompson // Copy host array to value strided
2253196072fSJeremy L Thompson //------------------------------------------------------------------------------
2263196072fSJeremy L Thompson static int CeedHostCopyStrided_Hip(CeedScalar *h_array, CeedSize start, CeedSize step, CeedSize length, CeedScalar *h_copy_array) {
2273196072fSJeremy L Thompson   for (CeedSize i = start; i < length; i += step) h_copy_array[i] = h_array[i];
2283196072fSJeremy L Thompson   return CEED_ERROR_SUCCESS;
2293196072fSJeremy L Thompson }
2303196072fSJeremy L Thompson 
2313196072fSJeremy L Thompson //------------------------------------------------------------------------------
232956a3dbaSJeremy L Thompson // Copy device array to value strided (impl in .hip.cpp file)
2333196072fSJeremy L Thompson //------------------------------------------------------------------------------
2343196072fSJeremy L Thompson int CeedDeviceCopyStrided_Hip(CeedScalar *d_array, CeedSize start, CeedSize step, CeedSize length, CeedScalar *d_copy_array);
2353196072fSJeremy L Thompson 
2363196072fSJeremy L Thompson //------------------------------------------------------------------------------
2373196072fSJeremy L Thompson // Copy a vector to a value strided
2383196072fSJeremy L Thompson //------------------------------------------------------------------------------
2393196072fSJeremy L Thompson static int CeedVectorCopyStrided_Hip(CeedVector vec, CeedSize start, CeedSize step, CeedVector vec_copy) {
2403196072fSJeremy L Thompson   CeedSize        length;
2413196072fSJeremy L Thompson   CeedVector_Hip *impl;
2423196072fSJeremy L Thompson 
2433196072fSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
244a7efc114SJeremy L Thompson   {
245a7efc114SJeremy L Thompson     CeedSize length_vec, length_copy;
246a7efc114SJeremy L Thompson 
2475a5594ffSJeremy L Thompson     CeedCallBackend(CeedVectorGetLength(vec, &length_vec));
2485a5594ffSJeremy L Thompson     CeedCallBackend(CeedVectorGetLength(vec_copy, &length_copy));
249a7efc114SJeremy L Thompson     length = length_vec < length_copy ? length_vec : length_copy;
250a7efc114SJeremy L Thompson   }
2513196072fSJeremy L Thompson   // Set value for synced device/host array
2523196072fSJeremy L Thompson   if (impl->d_array) {
2533196072fSJeremy L Thompson     CeedScalar *copy_array;
2543196072fSJeremy L Thompson 
2553196072fSJeremy L Thompson     CeedCallBackend(CeedVectorGetArray(vec_copy, CEED_MEM_DEVICE, &copy_array));
256*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
257*e84c3ebcSJeremy L Thompson     hipblasHandle_t handle;
258*e84c3ebcSJeremy L Thompson     Ceed            ceed;
259*e84c3ebcSJeremy L Thompson 
260*e84c3ebcSJeremy L Thompson     CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
261*e84c3ebcSJeremy L Thompson     CeedCallBackend(CeedGetHipblasHandle_Hip(ceed, &handle));
262*e84c3ebcSJeremy L Thompson #if defined(CEED_SCALAR_IS_FP32)
263*e84c3ebcSJeremy L Thompson     CeedCallHipblas(ceed, hipblasScopy_64(handle, (int64_t)length, impl->d_array + start, (int64_t)step, copy_array + start, (int64_t)step));
264*e84c3ebcSJeremy L Thompson #else  /* CEED_SCALAR */
265*e84c3ebcSJeremy L Thompson     CeedCallHipblas(ceed, hipblasDcopy_64(handle, (int64_t)length, impl->d_array + start, (int64_t)step, copy_array + start, (int64_t)step));
266*e84c3ebcSJeremy L Thompson #endif /* CEED_SCALAR */
267*e84c3ebcSJeremy L Thompson #else  /* HIP_VERSION */
2683196072fSJeremy L Thompson     CeedCallBackend(CeedDeviceCopyStrided_Hip(impl->d_array, start, step, length, copy_array));
269*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
2703196072fSJeremy L Thompson     CeedCallBackend(CeedVectorRestoreArray(vec_copy, &copy_array));
271*e84c3ebcSJeremy L Thompson     impl->h_array = NULL;
272*e84c3ebcSJeremy L Thompson     CeedCallBackend(CeedDestroy(&ceed));
2733196072fSJeremy L Thompson   } else if (impl->h_array) {
2743196072fSJeremy L Thompson     CeedScalar *copy_array;
2753196072fSJeremy L Thompson 
2763196072fSJeremy L Thompson     CeedCallBackend(CeedVectorGetArray(vec_copy, CEED_MEM_HOST, &copy_array));
2773196072fSJeremy L Thompson     CeedCallBackend(CeedHostCopyStrided_Hip(impl->h_array, start, step, length, copy_array));
2783196072fSJeremy L Thompson     CeedCallBackend(CeedVectorRestoreArray(vec_copy, &copy_array));
279*e84c3ebcSJeremy L Thompson     impl->d_array = NULL;
2803196072fSJeremy L Thompson   } else {
2813196072fSJeremy L Thompson     return CeedError(CeedVectorReturnCeed(vec), CEED_ERROR_BACKEND, "CeedVector must have valid data set");
2823196072fSJeremy L Thompson   }
2833196072fSJeremy L Thompson   return CEED_ERROR_SUCCESS;
2843196072fSJeremy L Thompson }
2853196072fSJeremy L Thompson 
2863196072fSJeremy L Thompson //------------------------------------------------------------------------------
2870d0321e0SJeremy L Thompson // Set host array to value
2880d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2899330daecSnbeams static int CeedHostSetValue_Hip(CeedScalar *h_array, CeedSize length, CeedScalar val) {
2909330daecSnbeams   for (CeedSize i = 0; i < length; i++) h_array[i] = val;
2910d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2920d0321e0SJeremy L Thompson }
2930d0321e0SJeremy L Thompson 
2940d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2950d0321e0SJeremy L Thompson // Set device array to value (impl in .hip file)
2960d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2979330daecSnbeams int CeedDeviceSetValue_Hip(CeedScalar *d_array, CeedSize length, CeedScalar val);
2980d0321e0SJeremy L Thompson 
2990d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
300b2165e7aSSebastian Grimberg // Set a vector to a value
3010d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3020d0321e0SJeremy L Thompson static int CeedVectorSetValue_Hip(CeedVector vec, CeedScalar val) {
3031f9221feSJeremy L Thompson   CeedSize        length;
304b7453713SJeremy L Thompson   CeedVector_Hip *impl;
3050d0321e0SJeremy L Thompson 
306b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
307b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
3080d0321e0SJeremy L Thompson   // Set value for synced device/host array
3090d0321e0SJeremy L Thompson   if (!impl->d_array && !impl->h_array) {
3100d0321e0SJeremy L Thompson     if (impl->d_array_borrowed) {
3110d0321e0SJeremy L Thompson       impl->d_array = impl->d_array_borrowed;
3120d0321e0SJeremy L Thompson     } else if (impl->h_array_borrowed) {
3130d0321e0SJeremy L Thompson       impl->h_array = impl->h_array_borrowed;
3140d0321e0SJeremy L Thompson     } else if (impl->d_array_owned) {
3150d0321e0SJeremy L Thompson       impl->d_array = impl->d_array_owned;
3160d0321e0SJeremy L Thompson     } else if (impl->h_array_owned) {
3170d0321e0SJeremy L Thompson       impl->h_array = impl->h_array_owned;
3180d0321e0SJeremy L Thompson     } else {
3192b730f8bSJeremy L Thompson       CeedCallBackend(CeedVectorSetArray(vec, CEED_MEM_DEVICE, CEED_COPY_VALUES, NULL));
3200d0321e0SJeremy L Thompson     }
3210d0321e0SJeremy L Thompson   }
3220d0321e0SJeremy L Thompson   if (impl->d_array) {
323124cc107SJeremy L Thompson     if (val == 0) {
324124cc107SJeremy L Thompson       CeedCallHip(CeedVectorReturnCeed(vec), hipMemset(impl->d_array, 0, length * sizeof(CeedScalar)));
325124cc107SJeremy L Thompson     } else {
3262b730f8bSJeremy L Thompson       CeedCallBackend(CeedDeviceSetValue_Hip(impl->d_array, length, val));
3270d0321e0SJeremy L Thompson     }
328124cc107SJeremy L Thompson     impl->h_array = NULL;
329124cc107SJeremy L Thompson   } else if (impl->h_array) {
3302b730f8bSJeremy L Thompson     CeedCallBackend(CeedHostSetValue_Hip(impl->h_array, length, val));
331b2165e7aSSebastian Grimberg     impl->d_array = NULL;
3320d0321e0SJeremy L Thompson   }
3330d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3340d0321e0SJeremy L Thompson }
3350d0321e0SJeremy L Thompson 
3360d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3373196072fSJeremy L Thompson // Set host array to value strided
3383196072fSJeremy L Thompson //------------------------------------------------------------------------------
3393196072fSJeremy L Thompson static int CeedHostSetValueStrided_Hip(CeedScalar *h_array, CeedSize start, CeedSize step, CeedSize length, CeedScalar val) {
3403196072fSJeremy L Thompson   for (CeedSize i = start; i < length; i += step) h_array[i] = val;
3413196072fSJeremy L Thompson   return CEED_ERROR_SUCCESS;
3423196072fSJeremy L Thompson }
3433196072fSJeremy L Thompson 
3443196072fSJeremy L Thompson //------------------------------------------------------------------------------
345956a3dbaSJeremy L Thompson // Set device array to value strided (impl in .hip.cpp file)
3463196072fSJeremy L Thompson //------------------------------------------------------------------------------
3473196072fSJeremy L Thompson int CeedDeviceSetValueStrided_Hip(CeedScalar *d_array, CeedSize start, CeedSize step, CeedSize length, CeedScalar val);
3483196072fSJeremy L Thompson 
3493196072fSJeremy L Thompson //------------------------------------------------------------------------------
3503196072fSJeremy L Thompson // Set a vector to a value strided
3513196072fSJeremy L Thompson //------------------------------------------------------------------------------
3523196072fSJeremy L Thompson static int CeedVectorSetValueStrided_Hip(CeedVector vec, CeedSize start, CeedSize step, CeedScalar val) {
3533196072fSJeremy L Thompson   CeedSize        length;
3543196072fSJeremy L Thompson   CeedVector_Hip *impl;
3553196072fSJeremy L Thompson 
3563196072fSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
3573196072fSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
3583196072fSJeremy L Thompson   // Set value for synced device/host array
3593196072fSJeremy L Thompson   if (impl->d_array) {
3603196072fSJeremy L Thompson     CeedCallBackend(CeedDeviceSetValueStrided_Hip(impl->d_array, start, step, length, val));
3613196072fSJeremy L Thompson     impl->h_array = NULL;
3623196072fSJeremy L Thompson   } else if (impl->h_array) {
3633196072fSJeremy L Thompson     CeedCallBackend(CeedHostSetValueStrided_Hip(impl->h_array, start, step, length, val));
3643196072fSJeremy L Thompson     impl->d_array = NULL;
3653196072fSJeremy L Thompson   } else {
3663196072fSJeremy L Thompson     return CeedError(CeedVectorReturnCeed(vec), CEED_ERROR_BACKEND, "CeedVector must have valid data set");
3673196072fSJeremy L Thompson   }
3683196072fSJeremy L Thompson   return CEED_ERROR_SUCCESS;
3693196072fSJeremy L Thompson }
3703196072fSJeremy L Thompson 
3713196072fSJeremy L Thompson //------------------------------------------------------------------------------
3720d0321e0SJeremy L Thompson // Vector Take Array
3730d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3742b730f8bSJeremy L Thompson static int CeedVectorTakeArray_Hip(CeedVector vec, CeedMemType mem_type, CeedScalar **array) {
3750d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
376b7453713SJeremy L Thompson 
3772b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
3780d0321e0SJeremy L Thompson 
37943c928f4SJeremy L Thompson   // Sync array to requested mem_type
3802b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSyncArray(vec, mem_type));
3810d0321e0SJeremy L Thompson 
3820d0321e0SJeremy L Thompson   // Update pointer
38343c928f4SJeremy L Thompson   switch (mem_type) {
3840d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
3850d0321e0SJeremy L Thompson       (*array)               = impl->h_array_borrowed;
3860d0321e0SJeremy L Thompson       impl->h_array_borrowed = NULL;
3870d0321e0SJeremy L Thompson       impl->h_array          = NULL;
3880d0321e0SJeremy L Thompson       break;
3890d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
3900d0321e0SJeremy L Thompson       (*array)               = impl->d_array_borrowed;
3910d0321e0SJeremy L Thompson       impl->d_array_borrowed = NULL;
3920d0321e0SJeremy L Thompson       impl->d_array          = NULL;
3930d0321e0SJeremy L Thompson       break;
3940d0321e0SJeremy L Thompson   }
3950d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3960d0321e0SJeremy L Thompson }
3970d0321e0SJeremy L Thompson 
3980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3990d0321e0SJeremy L Thompson // Core logic for array syncronization for GetArray.
4000d0321e0SJeremy L Thompson //   If a different memory type is most up to date, this will perform a copy
4010d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4022b730f8bSJeremy L Thompson static int CeedVectorGetArrayCore_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) {
4030d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
404b7453713SJeremy L Thompson 
4052b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
4060d0321e0SJeremy L Thompson 
40743c928f4SJeremy L Thompson   // Sync array to requested mem_type
4082b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSyncArray(vec, mem_type));
4090d0321e0SJeremy L Thompson 
4100d0321e0SJeremy L Thompson   // Update pointer
41143c928f4SJeremy L Thompson   switch (mem_type) {
4120d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
4130d0321e0SJeremy L Thompson       *array = impl->h_array;
4140d0321e0SJeremy L Thompson       break;
4150d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
4160d0321e0SJeremy L Thompson       *array = impl->d_array;
4170d0321e0SJeremy L Thompson       break;
4180d0321e0SJeremy L Thompson   }
4190d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4200d0321e0SJeremy L Thompson }
4210d0321e0SJeremy L Thompson 
4220d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
42343c928f4SJeremy L Thompson // Get read-only access to a vector via the specified mem_type
4240d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4252b730f8bSJeremy L Thompson static int CeedVectorGetArrayRead_Hip(const CeedVector vec, const CeedMemType mem_type, const CeedScalar **array) {
42643c928f4SJeremy L Thompson   return CeedVectorGetArrayCore_Hip(vec, mem_type, (CeedScalar **)array);
4270d0321e0SJeremy L Thompson }
4280d0321e0SJeremy L Thompson 
4290d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
43043c928f4SJeremy L Thompson // Get read/write access to a vector via the specified mem_type
4310d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4322b730f8bSJeremy L Thompson static int CeedVectorGetArray_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) {
4330d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
434b7453713SJeremy L Thompson 
4352b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
4362b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetArrayCore_Hip(vec, mem_type, array));
4372b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSetAllInvalid_Hip(vec));
43843c928f4SJeremy L Thompson   switch (mem_type) {
4390d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
4400d0321e0SJeremy L Thompson       impl->h_array = *array;
4410d0321e0SJeremy L Thompson       break;
4420d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
4430d0321e0SJeremy L Thompson       impl->d_array = *array;
4440d0321e0SJeremy L Thompson       break;
4450d0321e0SJeremy L Thompson   }
4460d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4470d0321e0SJeremy L Thompson }
4480d0321e0SJeremy L Thompson 
4490d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
45043c928f4SJeremy L Thompson // Get write access to a vector via the specified mem_type
4510d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4522b730f8bSJeremy L Thompson static int CeedVectorGetArrayWrite_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) {
4530d0321e0SJeremy L Thompson   bool            has_array_of_type = true;
454b7453713SJeremy L Thompson   CeedVector_Hip *impl;
455b7453713SJeremy L Thompson 
456b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
4572b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorHasArrayOfType_Hip(vec, mem_type, &has_array_of_type));
4580d0321e0SJeremy L Thompson   if (!has_array_of_type) {
4590d0321e0SJeremy L Thompson     // Allocate if array is not yet allocated
4602b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSetArray(vec, mem_type, CEED_COPY_VALUES, NULL));
4610d0321e0SJeremy L Thompson   } else {
4620d0321e0SJeremy L Thompson     // Select dirty array
46343c928f4SJeremy L Thompson     switch (mem_type) {
4640d0321e0SJeremy L Thompson       case CEED_MEM_HOST:
4652b730f8bSJeremy L Thompson         if (impl->h_array_borrowed) impl->h_array = impl->h_array_borrowed;
4662b730f8bSJeremy L Thompson         else impl->h_array = impl->h_array_owned;
4670d0321e0SJeremy L Thompson         break;
4680d0321e0SJeremy L Thompson       case CEED_MEM_DEVICE:
4692b730f8bSJeremy L Thompson         if (impl->d_array_borrowed) impl->d_array = impl->d_array_borrowed;
4702b730f8bSJeremy L Thompson         else impl->d_array = impl->d_array_owned;
4710d0321e0SJeremy L Thompson     }
4720d0321e0SJeremy L Thompson   }
47343c928f4SJeremy L Thompson   return CeedVectorGetArray_Hip(vec, mem_type, array);
4740d0321e0SJeremy L Thompson }
4750d0321e0SJeremy L Thompson 
4760d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4770d0321e0SJeremy L Thompson // Get the norm of a CeedVector
4780d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4792b730f8bSJeremy L Thompson static int CeedVectorNorm_Hip(CeedVector vec, CeedNormType type, CeedScalar *norm) {
4800d0321e0SJeremy L Thompson   Ceed     ceed;
481*e84c3ebcSJeremy L Thompson   CeedSize length;
482*e84c3ebcSJeremy L Thompson #if (HIP_VERSION < 60000000)
483*e84c3ebcSJeremy L Thompson   CeedSize num_calls;
484*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
485b7453713SJeremy L Thompson   const CeedScalar *d_array;
486b7453713SJeremy L Thompson   CeedVector_Hip   *impl;
4870d0321e0SJeremy L Thompson   hipblasHandle_t   handle;
488b7453713SJeremy L Thompson 
489b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
490b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
491b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
492eb7e6cafSJeremy L Thompson   CeedCallBackend(CeedGetHipblasHandle_Hip(ceed, &handle));
4930d0321e0SJeremy L Thompson 
494*e84c3ebcSJeremy L Thompson #if (HIP_VERSION < 60000000)
495*e84c3ebcSJeremy L Thompson   // With ROCm 6, we can use the 64-bit integer interface. Prior to that,
496*e84c3ebcSJeremy L Thompson   // we need to check if the vector is too long to handle with int32,
497*e84c3ebcSJeremy L Thompson   // and if so, divide it into subsections for repeated hipBLAS calls.
498672b0f2aSSebastian Grimberg   num_calls = length / INT_MAX;
4999330daecSnbeams   if (length % INT_MAX > 0) num_calls += 1;
500*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
5019330daecSnbeams 
5020d0321e0SJeremy L Thompson   // Compute norm
5032b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetArrayRead(vec, CEED_MEM_DEVICE, &d_array));
5040d0321e0SJeremy L Thompson   switch (type) {
5050d0321e0SJeremy L Thompson     case CEED_NORM_1: {
506f6f49adbSnbeams       *norm = 0.0;
507*e84c3ebcSJeremy L Thompson #if defined(CEED_SCALAR_IS_FP32)
508*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)  // We have ROCm 6, and can use 64-bit integers
509*e84c3ebcSJeremy L Thompson       CeedCallHipblas(ceed, hipblasSasum_64(handle, (int64_t)length, (float *)d_array, 1, (float *)norm));
510*e84c3ebcSJeremy L Thompson #else  /* HIP_VERSION */
5119330daecSnbeams       float  sub_norm = 0.0;
5129330daecSnbeams       float *d_array_start;
513b7453713SJeremy L Thompson 
5149330daecSnbeams       for (CeedInt i = 0; i < num_calls; i++) {
5159330daecSnbeams         d_array_start             = (float *)d_array + (CeedSize)(i)*INT_MAX;
5169330daecSnbeams         CeedSize remaining_length = length - (CeedSize)(i)*INT_MAX;
5179330daecSnbeams         CeedInt  sub_length       = (i == num_calls - 1) ? (CeedInt)(remaining_length) : INT_MAX;
518b7453713SJeremy L Thompson 
519*e84c3ebcSJeremy L Thompson         CeedCallHipblas(ceed, cublasSasum(handle, (CeedInt)sub_length, (float *)d_array_start, 1, &sub_norm));
5209330daecSnbeams         *norm += sub_norm;
5219330daecSnbeams       }
522*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
523*e84c3ebcSJeremy L Thompson #else  /* CEED_SCALAR */
524*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
525*e84c3ebcSJeremy L Thompson       CeedCallHipblas(ceed, hipblasDasum_64(handle, (int64_t)length, (double *)d_array, 1, (double *)norm));
526*e84c3ebcSJeremy L Thompson #else  /* HIP_VERSION */
5279330daecSnbeams       double  sub_norm = 0.0;
5289330daecSnbeams       double *d_array_start;
529b7453713SJeremy L Thompson 
5309330daecSnbeams       for (CeedInt i = 0; i < num_calls; i++) {
5319330daecSnbeams         d_array_start             = (double *)d_array + (CeedSize)(i)*INT_MAX;
5329330daecSnbeams         CeedSize remaining_length = length - (CeedSize)(i)*INT_MAX;
5339330daecSnbeams         CeedInt  sub_length       = (i == num_calls - 1) ? (CeedInt)(remaining_length) : INT_MAX;
534b7453713SJeremy L Thompson 
5359330daecSnbeams         CeedCallHipblas(ceed, hipblasDasum(handle, (CeedInt)sub_length, (double *)d_array_start, 1, &sub_norm));
5369330daecSnbeams         *norm += sub_norm;
5379330daecSnbeams       }
538*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
539*e84c3ebcSJeremy L Thompson #endif /* CEED_SCALAR */
5400d0321e0SJeremy L Thompson       break;
5410d0321e0SJeremy L Thompson     }
5420d0321e0SJeremy L Thompson     case CEED_NORM_2: {
543*e84c3ebcSJeremy L Thompson #if defined(CEED_SCALAR_IS_FP32)
544*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
545*e84c3ebcSJeremy L Thompson       CeedCallHipblas(ceed, hipblasSnrm2_64(handle, (int64_t)length, (float *)d_array, 1, (float *)norm));
546*e84c3ebcSJeremy L Thompson #else  /* CUDA_VERSION */
5479330daecSnbeams       float  sub_norm = 0.0, norm_sum = 0.0;
5489330daecSnbeams       float *d_array_start;
549b7453713SJeremy L Thompson 
5509330daecSnbeams       for (CeedInt i = 0; i < num_calls; i++) {
5519330daecSnbeams         d_array_start             = (float *)d_array + (CeedSize)(i)*INT_MAX;
5529330daecSnbeams         CeedSize remaining_length = length - (CeedSize)(i)*INT_MAX;
5539330daecSnbeams         CeedInt  sub_length       = (i == num_calls - 1) ? (CeedInt)(remaining_length) : INT_MAX;
554b7453713SJeremy L Thompson 
5559330daecSnbeams         CeedCallHipblas(ceed, hipblasSnrm2(handle, (CeedInt)sub_length, (float *)d_array_start, 1, &sub_norm));
5569330daecSnbeams         norm_sum += sub_norm * sub_norm;
5579330daecSnbeams       }
5589330daecSnbeams       *norm = sqrt(norm_sum);
559*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
560*e84c3ebcSJeremy L Thompson #else  /* CEED_SCALAR */
561*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
562*e84c3ebcSJeremy L Thompson       CeedCallHipblas(ceed, hipblasDnrm2_64(handle, (int64_t)length, (double *)d_array, 1, (double *)norm));
563*e84c3ebcSJeremy L Thompson #else  /* CUDA_VERSION */
5649330daecSnbeams       double  sub_norm = 0.0, norm_sum = 0.0;
5659330daecSnbeams       double *d_array_start;
566b7453713SJeremy L Thompson 
5679330daecSnbeams       for (CeedInt i = 0; i < num_calls; i++) {
5689330daecSnbeams         d_array_start             = (double *)d_array + (CeedSize)(i)*INT_MAX;
5699330daecSnbeams         CeedSize remaining_length = length - (CeedSize)(i)*INT_MAX;
5709330daecSnbeams         CeedInt  sub_length       = (i == num_calls - 1) ? (CeedInt)(remaining_length) : INT_MAX;
571b7453713SJeremy L Thompson 
5729330daecSnbeams         CeedCallHipblas(ceed, hipblasDnrm2(handle, (CeedInt)sub_length, (double *)d_array_start, 1, &sub_norm));
5739330daecSnbeams         norm_sum += sub_norm * sub_norm;
5749330daecSnbeams       }
5759330daecSnbeams       *norm = sqrt(norm_sum);
576*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
577*e84c3ebcSJeremy L Thompson #endif /* CEED_SCALAR */
5780d0321e0SJeremy L Thompson       break;
5790d0321e0SJeremy L Thompson     }
5800d0321e0SJeremy L Thompson     case CEED_NORM_MAX: {
581*e84c3ebcSJeremy L Thompson #if defined(CEED_SCALAR_IS_FP32)
582*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
583*e84c3ebcSJeremy L Thompson       int64_t    index;
584*e84c3ebcSJeremy L Thompson       CeedScalar norm_no_abs;
585b7453713SJeremy L Thompson 
586*e84c3ebcSJeremy L Thompson       CeedCallHipblas(ceed, hipblasIsamax_64(handle, (int64_t)length, (float *)d_array, 1, &index));
587*e84c3ebcSJeremy L Thompson       CeedCallHip(ceed, hipMemcpy(&norm_no_abs, impl->d_array + index - 1, sizeof(CeedScalar), hipMemcpyDeviceToHost));
588*e84c3ebcSJeremy L Thompson       *norm = fabs(norm_no_abs);
589*e84c3ebcSJeremy L Thompson #else  /* HIP_VERSION */
590*e84c3ebcSJeremy L Thompson       CeedInt index;
5919330daecSnbeams       float   sub_max = 0.0, current_max = 0.0;
5929330daecSnbeams       float  *d_array_start;
593*e84c3ebcSJeremy L Thompson 
5949330daecSnbeams       for (CeedInt i = 0; i < num_calls; i++) {
5959330daecSnbeams         d_array_start             = (float *)d_array + (CeedSize)(i)*INT_MAX;
5969330daecSnbeams         CeedSize remaining_length = length - (CeedSize)(i)*INT_MAX;
5979330daecSnbeams         CeedInt  sub_length       = (i == num_calls - 1) ? (CeedInt)(remaining_length) : INT_MAX;
598b7453713SJeremy L Thompson 
599b7453713SJeremy L Thompson         CeedCallHipblas(ceed, hipblasIsamax(handle, (CeedInt)sub_length, (float *)d_array_start, 1, &index));
600b7453713SJeremy L Thompson         CeedCallHip(ceed, hipMemcpy(&sub_max, d_array_start + index - 1, sizeof(CeedScalar), hipMemcpyDeviceToHost));
6019330daecSnbeams         if (fabs(sub_max) > current_max) current_max = fabs(sub_max);
6029330daecSnbeams       }
6039330daecSnbeams       *norm = current_max;
604*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
605*e84c3ebcSJeremy L Thompson #else  /* CEED_SCALAR */
606*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
607*e84c3ebcSJeremy L Thompson       int64_t    index;
608*e84c3ebcSJeremy L Thompson       CeedScalar norm_no_abs;
609*e84c3ebcSJeremy L Thompson 
610*e84c3ebcSJeremy L Thompson       CeedCallHipblas(ceed, hipblasIdamax_64(handle, (int64_t)length, (double *)d_array, 1, &index));
611*e84c3ebcSJeremy L Thompson       CeedCallHip(ceed, hipMemcpy(&norm_no_abs, impl->d_array + index - 1, sizeof(CeedScalar), hipMemcpyDeviceToHost));
612*e84c3ebcSJeremy L Thompson       *norm = fabs(norm_no_abs);
613*e84c3ebcSJeremy L Thompson #else  /* HIP_VERSION */
614*e84c3ebcSJeremy L Thompson       CeedInt index;
6159330daecSnbeams       double  sub_max = 0.0, current_max = 0.0;
6169330daecSnbeams       double *d_array_start;
617b7453713SJeremy L Thompson 
6189330daecSnbeams       for (CeedInt i = 0; i < num_calls; i++) {
6199330daecSnbeams         d_array_start             = (double *)d_array + (CeedSize)(i)*INT_MAX;
6209330daecSnbeams         CeedSize remaining_length = length - (CeedSize)(i)*INT_MAX;
6219330daecSnbeams         CeedInt  sub_length       = (i == num_calls - 1) ? (CeedInt)(remaining_length) : INT_MAX;
622b7453713SJeremy L Thompson 
623b7453713SJeremy L Thompson         CeedCallHipblas(ceed, hipblasIdamax(handle, (CeedInt)sub_length, (double *)d_array_start, 1, &index));
624b7453713SJeremy L Thompson         CeedCallHip(ceed, hipMemcpy(&sub_max, d_array_start + index - 1, sizeof(CeedScalar), hipMemcpyDeviceToHost));
6259330daecSnbeams         if (fabs(sub_max) > current_max) current_max = fabs(sub_max);
6269330daecSnbeams       }
6279330daecSnbeams       *norm = current_max;
628*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
629*e84c3ebcSJeremy L Thompson #endif /* CEED_SCALAR */
6300d0321e0SJeremy L Thompson       break;
6310d0321e0SJeremy L Thompson     }
6320d0321e0SJeremy L Thompson   }
6332b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorRestoreArrayRead(vec, &d_array));
6349bc66399SJeremy L Thompson   CeedCallBackend(CeedDestroy(&ceed));
6350d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6360d0321e0SJeremy L Thompson }
6370d0321e0SJeremy L Thompson 
6380d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6390d0321e0SJeremy L Thompson // Take reciprocal of a vector on host
6400d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6419330daecSnbeams static int CeedHostReciprocal_Hip(CeedScalar *h_array, CeedSize length) {
6429330daecSnbeams   for (CeedSize i = 0; i < length; i++) {
6432b730f8bSJeremy L Thompson     if (fabs(h_array[i]) > CEED_EPSILON) h_array[i] = 1. / h_array[i];
6442b730f8bSJeremy L Thompson   }
6450d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6460d0321e0SJeremy L Thompson }
6470d0321e0SJeremy L Thompson 
6480d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
649956a3dbaSJeremy L Thompson // Take reciprocal of a vector on device (impl in .hip.cpp file)
6500d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6519330daecSnbeams int CeedDeviceReciprocal_Hip(CeedScalar *d_array, CeedSize length);
6520d0321e0SJeremy L Thompson 
6530d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6540d0321e0SJeremy L Thompson // Take reciprocal of a vector
6550d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6560d0321e0SJeremy L Thompson static int CeedVectorReciprocal_Hip(CeedVector vec) {
6571f9221feSJeremy L Thompson   CeedSize        length;
658b7453713SJeremy L Thompson   CeedVector_Hip *impl;
6590d0321e0SJeremy L Thompson 
660b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
661b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(vec, &length));
6620d0321e0SJeremy L Thompson   // Set value for synced device/host array
6632b730f8bSJeremy L Thompson   if (impl->d_array) CeedCallBackend(CeedDeviceReciprocal_Hip(impl->d_array, length));
6642b730f8bSJeremy L Thompson   if (impl->h_array) CeedCallBackend(CeedHostReciprocal_Hip(impl->h_array, length));
6650d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6660d0321e0SJeremy L Thompson }
6670d0321e0SJeremy L Thompson 
6680d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6690d0321e0SJeremy L Thompson // Compute x = alpha x on the host
6700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6719330daecSnbeams static int CeedHostScale_Hip(CeedScalar *x_array, CeedScalar alpha, CeedSize length) {
6729330daecSnbeams   for (CeedSize i = 0; i < length; i++) x_array[i] *= alpha;
6730d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6740d0321e0SJeremy L Thompson }
6750d0321e0SJeremy L Thompson 
6760d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
677956a3dbaSJeremy L Thompson // Compute x = alpha x on device (impl in .hip.cpp file)
6780d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6799330daecSnbeams int CeedDeviceScale_Hip(CeedScalar *x_array, CeedScalar alpha, CeedSize length);
6800d0321e0SJeremy L Thompson 
6810d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6820d0321e0SJeremy L Thompson // Compute x = alpha x
6830d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
6840d0321e0SJeremy L Thompson static int CeedVectorScale_Hip(CeedVector x, CeedScalar alpha) {
6851f9221feSJeremy L Thompson   CeedSize        length;
686*e84c3ebcSJeremy L Thompson   CeedVector_Hip *impl;
6870d0321e0SJeremy L Thompson 
688*e84c3ebcSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(x, &impl));
689b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(x, &length));
6900d0321e0SJeremy L Thompson   // Set value for synced device/host array
691*e84c3ebcSJeremy L Thompson   if (impl->d_array) {
692*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
693*e84c3ebcSJeremy L Thompson     hipblasHandle_t handle;
694*e84c3ebcSJeremy L Thompson 
695*e84c3ebcSJeremy L Thompson     CeedCallBackend(CeedGetHipblasHandle_Hip(CeedVectorReturnCeed(x), &handle));
696*e84c3ebcSJeremy L Thompson #if defined(CEED_SCALAR_IS_FP32)
697*e84c3ebcSJeremy L Thompson     CeedCallHipblas(CeedVectorReturnCeed(x), hipblasSscal_64(handle, (int64_t)length, &alpha, impl->d_array, 1));
698*e84c3ebcSJeremy L Thompson #else  /* CEED_SCALAR */
699*e84c3ebcSJeremy L Thompson     CeedCallHipblas(CeedVectorReturnCeed(x), hipblasDscal_64(handle, (int64_t)length, &alpha, impl->d_array, 1));
700*e84c3ebcSJeremy L Thompson #endif /* CEED_SCALAR */
701*e84c3ebcSJeremy L Thompson #else  /* HIP_VERSION */
702*e84c3ebcSJeremy L Thompson     CeedCallBackend(CeedDeviceScale_Hip(impl->d_array, alpha, length));
703*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
704*e84c3ebcSJeremy L Thompson     impl->h_array = NULL;
705*e84c3ebcSJeremy L Thompson   }
706*e84c3ebcSJeremy L Thompson   if (impl->h_array) {
707*e84c3ebcSJeremy L Thompson     CeedCallBackend(CeedHostScale_Hip(impl->h_array, alpha, length));
708*e84c3ebcSJeremy L Thompson     impl->d_array = NULL;
709*e84c3ebcSJeremy L Thompson   }
7100d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
7110d0321e0SJeremy L Thompson }
7120d0321e0SJeremy L Thompson 
7130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
7140d0321e0SJeremy L Thompson // Compute y = alpha x + y on the host
7150d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
7169330daecSnbeams static int CeedHostAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar *x_array, CeedSize length) {
7179330daecSnbeams   for (CeedSize i = 0; i < length; i++) y_array[i] += alpha * x_array[i];
7180d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
7190d0321e0SJeremy L Thompson }
7200d0321e0SJeremy L Thompson 
7210d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
722956a3dbaSJeremy L Thompson // Compute y = alpha x + y on device (impl in .hip.cpp file)
7230d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
7249330daecSnbeams int CeedDeviceAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar *x_array, CeedSize length);
7250d0321e0SJeremy L Thompson 
7260d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
7270d0321e0SJeremy L Thompson // Compute y = alpha x + y
7280d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
7290d0321e0SJeremy L Thompson static int CeedVectorAXPY_Hip(CeedVector y, CeedScalar alpha, CeedVector x) {
730b7453713SJeremy L Thompson   CeedSize        length;
7310d0321e0SJeremy L Thompson   CeedVector_Hip *y_impl, *x_impl;
732b7453713SJeremy L Thompson 
7332b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(y, &y_impl));
7342b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(x, &x_impl));
7352b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(y, &length));
7360d0321e0SJeremy L Thompson   // Set value for synced device/host array
7370d0321e0SJeremy L Thompson   if (y_impl->d_array) {
7382b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE));
739*e84c3ebcSJeremy L Thompson #if (HIP_VERSION >= 60000000)
740*e84c3ebcSJeremy L Thompson     hipblasHandle_t handle;
741*e84c3ebcSJeremy L Thompson 
742*e84c3ebcSJeremy L Thompson     CeedCallBackend(CeedGetHipblasHandle_Hip(CeedVectorReturnCeed(y), &handle));
743*e84c3ebcSJeremy L Thompson #if defined(CEED_SCALAR_IS_FP32)
744*e84c3ebcSJeremy L Thompson     CeedCallHipblas(CeedVectorReturnCeed(y), hipblasSaxpy_64(handle, (int64_t)length, &alpha, x_impl->d_array, 1, y_impl->d_array, 1));
745*e84c3ebcSJeremy L Thompson #else  /* CEED_SCALAR */
746*e84c3ebcSJeremy L Thompson     CeedCallHipblas(CeedVectorReturnCeed(y), hipblasDaxpy_64(handle, (int64_t)length, &alpha, x_impl->d_array, 1, y_impl->d_array, 1));
747*e84c3ebcSJeremy L Thompson #endif /* CEED_SCALAR */
748*e84c3ebcSJeremy L Thompson #else  /* HIP_VERSION */
7492b730f8bSJeremy L Thompson     CeedCallBackend(CeedDeviceAXPY_Hip(y_impl->d_array, alpha, x_impl->d_array, length));
750*e84c3ebcSJeremy L Thompson #endif /* HIP_VERSION */
751*e84c3ebcSJeremy L Thompson     y_impl->h_array = NULL;
752*e84c3ebcSJeremy L Thompson   } else if (y_impl->h_array) {
7532b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST));
7542b730f8bSJeremy L Thompson     CeedCallBackend(CeedHostAXPY_Hip(y_impl->h_array, alpha, x_impl->h_array, length));
755*e84c3ebcSJeremy L Thompson     y_impl->d_array = NULL;
7560d0321e0SJeremy L Thompson   }
7570d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
7580d0321e0SJeremy L Thompson }
759ff1e7120SSebastian Grimberg 
7605fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------
7615fb68f37SKaren (Ren) Stengel // Compute y = alpha x + beta y on the host
7625fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------
7639330daecSnbeams static int CeedHostAXPBY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar beta, CeedScalar *x_array, CeedSize length) {
764aa67b842SZach Atkins   for (CeedSize i = 0; i < length; i++) y_array[i] = alpha * x_array[i] + beta * y_array[i];
7655fb68f37SKaren (Ren) Stengel   return CEED_ERROR_SUCCESS;
7665fb68f37SKaren (Ren) Stengel }
7675fb68f37SKaren (Ren) Stengel 
7685fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------
769956a3dbaSJeremy L Thompson // Compute y = alpha x + beta y on device (impl in .hip.cpp file)
7705fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------
7719330daecSnbeams int CeedDeviceAXPBY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar beta, CeedScalar *x_array, CeedSize length);
7725fb68f37SKaren (Ren) Stengel 
7735fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------
7745fb68f37SKaren (Ren) Stengel // Compute y = alpha x + beta y
7755fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------
7765fb68f37SKaren (Ren) Stengel static int CeedVectorAXPBY_Hip(CeedVector y, CeedScalar alpha, CeedScalar beta, CeedVector x) {
777b7453713SJeremy L Thompson   CeedSize        length;
7785fb68f37SKaren (Ren) Stengel   CeedVector_Hip *y_impl, *x_impl;
779b7453713SJeremy L Thompson 
7805fb68f37SKaren (Ren) Stengel   CeedCallBackend(CeedVectorGetData(y, &y_impl));
7815fb68f37SKaren (Ren) Stengel   CeedCallBackend(CeedVectorGetData(x, &x_impl));
7825fb68f37SKaren (Ren) Stengel   CeedCallBackend(CeedVectorGetLength(y, &length));
7835fb68f37SKaren (Ren) Stengel   // Set value for synced device/host array
7845fb68f37SKaren (Ren) Stengel   if (y_impl->d_array) {
7855fb68f37SKaren (Ren) Stengel     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE));
7865fb68f37SKaren (Ren) Stengel     CeedCallBackend(CeedDeviceAXPBY_Hip(y_impl->d_array, alpha, beta, x_impl->d_array, length));
7875fb68f37SKaren (Ren) Stengel   }
7885fb68f37SKaren (Ren) Stengel   if (y_impl->h_array) {
7895fb68f37SKaren (Ren) Stengel     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST));
7905fb68f37SKaren (Ren) Stengel     CeedCallBackend(CeedHostAXPBY_Hip(y_impl->h_array, alpha, beta, x_impl->h_array, length));
7915fb68f37SKaren (Ren) Stengel   }
7925fb68f37SKaren (Ren) Stengel   return CEED_ERROR_SUCCESS;
7935fb68f37SKaren (Ren) Stengel }
7940d0321e0SJeremy L Thompson 
7950d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
7960d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on the host
7970d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
7989330daecSnbeams static int CeedHostPointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, CeedScalar *y_array, CeedSize length) {
7999330daecSnbeams   for (CeedSize i = 0; i < length; i++) w_array[i] = x_array[i] * y_array[i];
8000d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8010d0321e0SJeremy L Thompson }
8020d0321e0SJeremy L Thompson 
8030d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
804956a3dbaSJeremy L Thompson // Compute the pointwise multiplication w = x .* y on device (impl in .hip.cpp file)
8050d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
8069330daecSnbeams int CeedDevicePointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, CeedScalar *y_array, CeedSize length);
8070d0321e0SJeremy L Thompson 
8080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
8090d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y
8100d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
8112b730f8bSJeremy L Thompson static int CeedVectorPointwiseMult_Hip(CeedVector w, CeedVector x, CeedVector y) {
812b7453713SJeremy L Thompson   CeedSize        length;
8130d0321e0SJeremy L Thompson   CeedVector_Hip *w_impl, *x_impl, *y_impl;
814b7453713SJeremy L Thompson 
8152b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(w, &w_impl));
8162b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(x, &x_impl));
8172b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetData(y, &y_impl));
8182b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetLength(w, &length));
8190d0321e0SJeremy L Thompson 
8200d0321e0SJeremy L Thompson   // Set value for synced device/host array
8210d0321e0SJeremy L Thompson   if (!w_impl->d_array && !w_impl->h_array) {
8222b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSetValue(w, 0.0));
8230d0321e0SJeremy L Thompson   }
8240d0321e0SJeremy L Thompson   if (w_impl->d_array) {
8252b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE));
8262b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(y, CEED_MEM_DEVICE));
8272b730f8bSJeremy L Thompson     CeedCallBackend(CeedDevicePointwiseMult_Hip(w_impl->d_array, x_impl->d_array, y_impl->d_array, length));
8280d0321e0SJeremy L Thompson   }
8290d0321e0SJeremy L Thompson   if (w_impl->h_array) {
8302b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST));
8312b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorSyncArray(y, CEED_MEM_HOST));
8322b730f8bSJeremy L Thompson     CeedCallBackend(CeedHostPointwiseMult_Hip(w_impl->h_array, x_impl->h_array, y_impl->h_array, length));
8330d0321e0SJeremy L Thompson   }
8340d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8350d0321e0SJeremy L Thompson }
8360d0321e0SJeremy L Thompson 
8370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
8380d0321e0SJeremy L Thompson // Destroy the vector
8390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
8400d0321e0SJeremy L Thompson static int CeedVectorDestroy_Hip(const CeedVector vec) {
8410d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
8420d0321e0SJeremy L Thompson 
843b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetData(vec, &impl));
8446e536b99SJeremy L Thompson   CeedCallHip(CeedVectorReturnCeed(vec), hipFree(impl->d_array_owned));
8452b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_array_owned));
8462b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
8470d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8480d0321e0SJeremy L Thompson }
8490d0321e0SJeremy L Thompson 
8500d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
8510d0321e0SJeremy L Thompson // Create a vector of the specified length (does not allocate memory)
8520d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
8531f9221feSJeremy L Thompson int CeedVectorCreate_Hip(CeedSize n, CeedVector vec) {
8540d0321e0SJeremy L Thompson   CeedVector_Hip *impl;
8550d0321e0SJeremy L Thompson   Ceed            ceed;
8560d0321e0SJeremy L Thompson 
857b7453713SJeremy L Thompson   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
8582b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", CeedVectorHasValidArray_Hip));
8592b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", CeedVectorHasBorrowedArrayOfType_Hip));
8602b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", CeedVectorSetArray_Hip));
8612b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", CeedVectorTakeArray_Hip));
8623e961e14SJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "CopyStrided", CeedVectorCopyStrided_Hip));
8633e961e14SJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetValue", CeedVectorSetValue_Hip));
8643e961e14SJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetValueStrided", CeedVectorSetValueStrided_Hip));
8652b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SyncArray", CeedVectorSyncArray_Hip));
8662b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", CeedVectorGetArray_Hip));
8672b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", CeedVectorGetArrayRead_Hip));
8682b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", CeedVectorGetArrayWrite_Hip));
8692b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Norm", CeedVectorNorm_Hip));
8702b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Reciprocal", CeedVectorReciprocal_Hip));
8713e961e14SJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Scale", CeedVectorScale_Hip));
8723e961e14SJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "AXPY", CeedVectorAXPY_Hip));
8733e961e14SJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "AXPBY", CeedVectorAXPBY_Hip));
8742b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "PointwiseMult", CeedVectorPointwiseMult_Hip));
8752b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", CeedVectorDestroy_Hip));
8769bc66399SJeremy L Thompson   CeedCallBackend(CeedDestroy(&ceed));
8772b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
8782b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorSetData(vec, impl));
8790d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8800d0321e0SJeremy L Thompson }
8812a86cc9dSSebastian Grimberg 
8822a86cc9dSSebastian Grimberg //------------------------------------------------------------------------------
883