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, ©_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, ©_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, ©_array)); 2773196072fSJeremy L Thompson CeedCallBackend(CeedHostCopyStrided_Hip(impl->h_array, start, step, length, copy_array)); 2783196072fSJeremy L Thompson CeedCallBackend(CeedVectorRestoreArray(vec_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