13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 30d0321e0SJeremy L Thompson // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 50d0321e0SJeremy L Thompson // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 70d0321e0SJeremy L Thompson 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> 13*c85e8640SSebastian 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; 232b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 24f48ed27dSnbeams 25f48ed27dSnbeams bool has_valid_array = false; 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 36f48ed27dSnbeams return CEED_ERROR_SUCCESS; 37f48ed27dSnbeams } 38f48ed27dSnbeams 390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 400d0321e0SJeremy L Thompson // Sync host to device 410d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 420d0321e0SJeremy L Thompson static inline int CeedVectorSyncH2D_Hip(const CeedVector vec) { 430d0321e0SJeremy L Thompson Ceed ceed; 442b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 450d0321e0SJeremy L Thompson CeedVector_Hip *impl; 462b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 470d0321e0SJeremy L Thompson 48539ec17dSJeremy L Thompson CeedSize length; 492b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 50539ec17dSJeremy L Thompson size_t bytes = length * sizeof(CeedScalar); 51539ec17dSJeremy L Thompson 522b730f8bSJeremy L Thompson if (!impl->h_array) { 530d0321e0SJeremy L Thompson // LCOV_EXCL_START 542b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "No valid host data to sync to device"); 550d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 562b730f8bSJeremy L Thompson } 570d0321e0SJeremy L Thompson 580d0321e0SJeremy L Thompson if (impl->d_array_borrowed) { 590d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 600d0321e0SJeremy L Thompson } else if (impl->d_array_owned) { 610d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 620d0321e0SJeremy L Thompson } else { 632b730f8bSJeremy L Thompson CeedCallHip(ceed, hipMalloc((void **)&impl->d_array_owned, bytes)); 640d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 650d0321e0SJeremy L Thompson } 660d0321e0SJeremy L Thompson 672b730f8bSJeremy L Thompson CeedCallHip(ceed, hipMemcpy(impl->d_array, impl->h_array, bytes, hipMemcpyHostToDevice)); 680d0321e0SJeremy L Thompson 690d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 700d0321e0SJeremy L Thompson } 710d0321e0SJeremy L Thompson 720d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 730d0321e0SJeremy L Thompson // Sync device to host 740d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 750d0321e0SJeremy L Thompson static inline int CeedVectorSyncD2H_Hip(const CeedVector vec) { 760d0321e0SJeremy L Thompson Ceed ceed; 772b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 780d0321e0SJeremy L Thompson CeedVector_Hip *impl; 792b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 800d0321e0SJeremy L Thompson 812b730f8bSJeremy L Thompson if (!impl->d_array) { 820d0321e0SJeremy L Thompson // LCOV_EXCL_START 832b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, "No valid device data to sync to host"); 840d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 852b730f8bSJeremy L Thompson } 860d0321e0SJeremy L Thompson 870d0321e0SJeremy L Thompson if (impl->h_array_borrowed) { 880d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 890d0321e0SJeremy L Thompson } else if (impl->h_array_owned) { 900d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 910d0321e0SJeremy L Thompson } else { 921f9221feSJeremy L Thompson CeedSize length; 932b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 942b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(length, &impl->h_array_owned)); 950d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 960d0321e0SJeremy L Thompson } 970d0321e0SJeremy L Thompson 98539ec17dSJeremy L Thompson CeedSize length; 992b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 100539ec17dSJeremy L Thompson size_t bytes = length * sizeof(CeedScalar); 1012b730f8bSJeremy L Thompson CeedCallHip(ceed, hipMemcpy(impl->h_array, impl->d_array, bytes, hipMemcpyDeviceToHost)); 1020d0321e0SJeremy L Thompson 1030d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1040d0321e0SJeremy L Thompson } 1050d0321e0SJeremy L Thompson 1060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1070d0321e0SJeremy L Thompson // Sync arrays 1080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1092b730f8bSJeremy L Thompson static int CeedVectorSyncArray_Hip(const CeedVector vec, CeedMemType mem_type) { 110f48ed27dSnbeams // Check whether device/host sync is needed 111f48ed27dSnbeams bool need_sync = false; 1122b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorNeedSync_Hip(vec, mem_type, &need_sync)); 1132b730f8bSJeremy L Thompson if (!need_sync) return CEED_ERROR_SUCCESS; 114f48ed27dSnbeams 11543c928f4SJeremy L Thompson switch (mem_type) { 1162b730f8bSJeremy L Thompson case CEED_MEM_HOST: 1172b730f8bSJeremy L Thompson return CeedVectorSyncD2H_Hip(vec); 1182b730f8bSJeremy L Thompson case CEED_MEM_DEVICE: 1192b730f8bSJeremy L Thompson return CeedVectorSyncH2D_Hip(vec); 1200d0321e0SJeremy L Thompson } 1210d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 1220d0321e0SJeremy L Thompson } 1230d0321e0SJeremy L Thompson 1240d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1250d0321e0SJeremy L Thompson // Set all pointers as invalid 1260d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1270d0321e0SJeremy L Thompson static inline int CeedVectorSetAllInvalid_Hip(const CeedVector vec) { 1280d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1292b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 1300d0321e0SJeremy L Thompson 1310d0321e0SJeremy L Thompson impl->h_array = NULL; 1320d0321e0SJeremy L Thompson impl->d_array = NULL; 1330d0321e0SJeremy L Thompson 1340d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1350d0321e0SJeremy L Thompson } 1360d0321e0SJeremy L Thompson 1370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1380d0321e0SJeremy L Thompson // Check if CeedVector has any valid pointers 1390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1402b730f8bSJeremy L Thompson static inline int CeedVectorHasValidArray_Hip(const CeedVector vec, bool *has_valid_array) { 1410d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1422b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 1430d0321e0SJeremy L Thompson 1440d0321e0SJeremy L Thompson *has_valid_array = !!impl->h_array || !!impl->d_array; 1450d0321e0SJeremy L Thompson 1460d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1470d0321e0SJeremy L Thompson } 1480d0321e0SJeremy L Thompson 1490d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1500d0321e0SJeremy L Thompson // Check if has any array of given type 1510d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1522b730f8bSJeremy L Thompson static inline int CeedVectorHasArrayOfType_Hip(const CeedVector vec, CeedMemType mem_type, bool *has_array_of_type) { 1530d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1542b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 1550d0321e0SJeremy L Thompson 15643c928f4SJeremy L Thompson switch (mem_type) { 1570d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1580d0321e0SJeremy L Thompson *has_array_of_type = !!impl->h_array_borrowed || !!impl->h_array_owned; 1590d0321e0SJeremy L Thompson break; 1600d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1610d0321e0SJeremy L Thompson *has_array_of_type = !!impl->d_array_borrowed || !!impl->d_array_owned; 1620d0321e0SJeremy L Thompson break; 1630d0321e0SJeremy L Thompson } 1640d0321e0SJeremy L Thompson 1650d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1660d0321e0SJeremy L Thompson } 1670d0321e0SJeremy L Thompson 1680d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1690d0321e0SJeremy L Thompson // Check if has borrowed array of given type 1700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1712b730f8bSJeremy L Thompson static inline int CeedVectorHasBorrowedArrayOfType_Hip(const CeedVector vec, CeedMemType mem_type, bool *has_borrowed_array_of_type) { 1720d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1732b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 1740d0321e0SJeremy L Thompson 17543c928f4SJeremy L Thompson switch (mem_type) { 1760d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1770d0321e0SJeremy L Thompson *has_borrowed_array_of_type = !!impl->h_array_borrowed; 1780d0321e0SJeremy L Thompson break; 1790d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1800d0321e0SJeremy L Thompson *has_borrowed_array_of_type = !!impl->d_array_borrowed; 1810d0321e0SJeremy L Thompson break; 1820d0321e0SJeremy L Thompson } 1830d0321e0SJeremy L Thompson 1840d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1850d0321e0SJeremy L Thompson } 1860d0321e0SJeremy L Thompson 1870d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1880d0321e0SJeremy L Thompson // Set array from host 1890d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1902b730f8bSJeremy L Thompson static int CeedVectorSetArrayHost_Hip(const CeedVector vec, const CeedCopyMode copy_mode, CeedScalar *array) { 1910d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1922b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 1930d0321e0SJeremy L Thompson 19443c928f4SJeremy L Thompson switch (copy_mode) { 1950d0321e0SJeremy L Thompson case CEED_COPY_VALUES: { 1961f9221feSJeremy L Thompson CeedSize length; 1970d0321e0SJeremy L Thompson if (!impl->h_array_owned) { 1982b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 1992b730f8bSJeremy L Thompson CeedCallBackend(CeedMalloc(length, &impl->h_array_owned)); 2000d0321e0SJeremy L Thompson } 2010d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 2020d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 203539ec17dSJeremy L Thompson if (array) { 204539ec17dSJeremy L Thompson CeedSize length; 2052b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 206539ec17dSJeremy L Thompson size_t bytes = length * sizeof(CeedScalar); 207539ec17dSJeremy L Thompson memcpy(impl->h_array, array, bytes); 208539ec17dSJeremy L Thompson } 2090d0321e0SJeremy L Thompson } break; 2100d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 2112b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_array_owned)); 2120d0321e0SJeremy L Thompson impl->h_array_owned = array; 2130d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 2140d0321e0SJeremy L Thompson impl->h_array = array; 2150d0321e0SJeremy L Thompson break; 2160d0321e0SJeremy L Thompson case CEED_USE_POINTER: 2172b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_array_owned)); 2180d0321e0SJeremy L Thompson impl->h_array_borrowed = array; 2190d0321e0SJeremy L Thompson impl->h_array = array; 2200d0321e0SJeremy L Thompson break; 2210d0321e0SJeremy L Thompson } 2220d0321e0SJeremy L Thompson 2230d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2240d0321e0SJeremy L Thompson } 2250d0321e0SJeremy L Thompson 2260d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2270d0321e0SJeremy L Thompson // Set array from device 2280d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2292b730f8bSJeremy L Thompson static int CeedVectorSetArrayDevice_Hip(const CeedVector vec, const CeedCopyMode copy_mode, CeedScalar *array) { 2300d0321e0SJeremy L Thompson Ceed ceed; 2312b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 2320d0321e0SJeremy L Thompson CeedVector_Hip *impl; 2332b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 2340d0321e0SJeremy L Thompson 23543c928f4SJeremy L Thompson switch (copy_mode) { 236539ec17dSJeremy L Thompson case CEED_COPY_VALUES: { 237539ec17dSJeremy L Thompson CeedSize length; 2382b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 239539ec17dSJeremy L Thompson size_t bytes = length * sizeof(CeedScalar); 2400d0321e0SJeremy L Thompson if (!impl->d_array_owned) { 2412b730f8bSJeremy L Thompson CeedCallHip(ceed, hipMalloc((void **)&impl->d_array_owned, bytes)); 2420d0321e0SJeremy L Thompson } 2430d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 2440d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 2450d0321e0SJeremy L Thompson if (array) { 2462b730f8bSJeremy L Thompson CeedCallHip(ceed, hipMemcpy(impl->d_array, array, bytes, hipMemcpyDeviceToDevice)); 2470d0321e0SJeremy L Thompson } 248539ec17dSJeremy L Thompson } break; 2490d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 2502b730f8bSJeremy L Thompson CeedCallHip(ceed, hipFree(impl->d_array_owned)); 2510d0321e0SJeremy L Thompson impl->d_array_owned = array; 2520d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 2530d0321e0SJeremy L Thompson impl->d_array = array; 2540d0321e0SJeremy L Thompson break; 2550d0321e0SJeremy L Thompson case CEED_USE_POINTER: 2562b730f8bSJeremy L Thompson CeedCallHip(ceed, hipFree(impl->d_array_owned)); 2570d0321e0SJeremy L Thompson impl->d_array_owned = NULL; 2580d0321e0SJeremy L Thompson impl->d_array_borrowed = array; 2590d0321e0SJeremy L Thompson impl->d_array = array; 2600d0321e0SJeremy L Thompson break; 2610d0321e0SJeremy L Thompson } 2620d0321e0SJeremy L Thompson 2630d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2640d0321e0SJeremy L Thompson } 2650d0321e0SJeremy L Thompson 2660d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2670d0321e0SJeremy L Thompson // Set the array used by a vector, 2680d0321e0SJeremy L Thompson // freeing any previously allocated array if applicable 2690d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2702b730f8bSJeremy L Thompson static int CeedVectorSetArray_Hip(const CeedVector vec, const CeedMemType mem_type, const CeedCopyMode copy_mode, CeedScalar *array) { 2710d0321e0SJeremy L Thompson Ceed ceed; 2722b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 2730d0321e0SJeremy L Thompson CeedVector_Hip *impl; 2742b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 2750d0321e0SJeremy L Thompson 2762b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSetAllInvalid_Hip(vec)); 27743c928f4SJeremy L Thompson switch (mem_type) { 2780d0321e0SJeremy L Thompson case CEED_MEM_HOST: 27943c928f4SJeremy L Thompson return CeedVectorSetArrayHost_Hip(vec, copy_mode, array); 2800d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 28143c928f4SJeremy L Thompson return CeedVectorSetArrayDevice_Hip(vec, copy_mode, array); 2820d0321e0SJeremy L Thompson } 2830d0321e0SJeremy L Thompson 2840d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 2850d0321e0SJeremy L Thompson } 2860d0321e0SJeremy L Thompson 2870d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2880d0321e0SJeremy L Thompson // Set host array to value 2890d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2902b730f8bSJeremy L Thompson static int CeedHostSetValue_Hip(CeedScalar *h_array, CeedInt length, CeedScalar val) { 2912b730f8bSJeremy L Thompson for (int i = 0; i < length; i++) h_array[i] = val; 2920d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2930d0321e0SJeremy L Thompson } 2940d0321e0SJeremy L Thompson 2950d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2960d0321e0SJeremy L Thompson // Set device array to value (impl in .hip file) 2970d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2980d0321e0SJeremy L Thompson int CeedDeviceSetValue_Hip(CeedScalar *d_array, CeedInt length, CeedScalar val); 2990d0321e0SJeremy L Thompson 3000d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3010d0321e0SJeremy L Thompson // Set a vector to a value, 3020d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3030d0321e0SJeremy L Thompson static int CeedVectorSetValue_Hip(CeedVector vec, CeedScalar val) { 3040d0321e0SJeremy L Thompson Ceed ceed; 3052b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 3060d0321e0SJeremy L Thompson CeedVector_Hip *impl; 3072b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 3081f9221feSJeremy L Thompson CeedSize length; 3092b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 3100d0321e0SJeremy L Thompson 3110d0321e0SJeremy L Thompson // Set value for synced device/host array 3120d0321e0SJeremy L Thompson if (!impl->d_array && !impl->h_array) { 3130d0321e0SJeremy L Thompson if (impl->d_array_borrowed) { 3140d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 3150d0321e0SJeremy L Thompson } else if (impl->h_array_borrowed) { 3160d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 3170d0321e0SJeremy L Thompson } else if (impl->d_array_owned) { 3180d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 3190d0321e0SJeremy L Thompson } else if (impl->h_array_owned) { 3200d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 3210d0321e0SJeremy L Thompson } else { 3222b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSetArray(vec, CEED_MEM_DEVICE, CEED_COPY_VALUES, NULL)); 3230d0321e0SJeremy L Thompson } 3240d0321e0SJeremy L Thompson } 3250d0321e0SJeremy L Thompson if (impl->d_array) { 3262b730f8bSJeremy L Thompson CeedCallBackend(CeedDeviceSetValue_Hip(impl->d_array, length, val)); 3270d0321e0SJeremy L Thompson } 3280d0321e0SJeremy L Thompson if (impl->h_array) { 3292b730f8bSJeremy L Thompson CeedCallBackend(CeedHostSetValue_Hip(impl->h_array, length, val)); 3300d0321e0SJeremy L Thompson } 3310d0321e0SJeremy L Thompson 3320d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3330d0321e0SJeremy L Thompson } 3340d0321e0SJeremy L Thompson 3350d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3360d0321e0SJeremy L Thompson // Vector Take Array 3370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3382b730f8bSJeremy L Thompson static int CeedVectorTakeArray_Hip(CeedVector vec, CeedMemType mem_type, CeedScalar **array) { 3390d0321e0SJeremy L Thompson Ceed ceed; 3402b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 3410d0321e0SJeremy L Thompson CeedVector_Hip *impl; 3422b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 3430d0321e0SJeremy L Thompson 34443c928f4SJeremy L Thompson // Sync array to requested mem_type 3452b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(vec, mem_type)); 3460d0321e0SJeremy L Thompson 3470d0321e0SJeremy L Thompson // Update pointer 34843c928f4SJeremy L Thompson switch (mem_type) { 3490d0321e0SJeremy L Thompson case CEED_MEM_HOST: 3500d0321e0SJeremy L Thompson (*array) = impl->h_array_borrowed; 3510d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 3520d0321e0SJeremy L Thompson impl->h_array = NULL; 3530d0321e0SJeremy L Thompson break; 3540d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 3550d0321e0SJeremy L Thompson (*array) = impl->d_array_borrowed; 3560d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 3570d0321e0SJeremy L Thompson impl->d_array = NULL; 3580d0321e0SJeremy L Thompson break; 3590d0321e0SJeremy L Thompson } 3600d0321e0SJeremy L Thompson 3610d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3620d0321e0SJeremy L Thompson } 3630d0321e0SJeremy L Thompson 3640d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3650d0321e0SJeremy L Thompson // Core logic for array syncronization for GetArray. 3660d0321e0SJeremy L Thompson // If a different memory type is most up to date, this will perform a copy 3670d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3682b730f8bSJeremy L Thompson static int CeedVectorGetArrayCore_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) { 3690d0321e0SJeremy L Thompson Ceed ceed; 3702b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 3710d0321e0SJeremy L Thompson CeedVector_Hip *impl; 3722b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 3730d0321e0SJeremy L Thompson 37443c928f4SJeremy L Thompson // Sync array to requested mem_type 3752b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(vec, mem_type)); 3760d0321e0SJeremy L Thompson 3770d0321e0SJeremy L Thompson // Update pointer 37843c928f4SJeremy L Thompson switch (mem_type) { 3790d0321e0SJeremy L Thompson case CEED_MEM_HOST: 3800d0321e0SJeremy L Thompson *array = impl->h_array; 3810d0321e0SJeremy L Thompson break; 3820d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 3830d0321e0SJeremy L Thompson *array = impl->d_array; 3840d0321e0SJeremy L Thompson break; 3850d0321e0SJeremy L Thompson } 3860d0321e0SJeremy L Thompson 3870d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3880d0321e0SJeremy L Thompson } 3890d0321e0SJeremy L Thompson 3900d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 39143c928f4SJeremy L Thompson // Get read-only access to a vector via the specified mem_type 3920d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3932b730f8bSJeremy L Thompson static int CeedVectorGetArrayRead_Hip(const CeedVector vec, const CeedMemType mem_type, const CeedScalar **array) { 39443c928f4SJeremy L Thompson return CeedVectorGetArrayCore_Hip(vec, mem_type, (CeedScalar **)array); 3950d0321e0SJeremy L Thompson } 3960d0321e0SJeremy L Thompson 3970d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 39843c928f4SJeremy L Thompson // Get read/write access to a vector via the specified mem_type 3990d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4002b730f8bSJeremy L Thompson static int CeedVectorGetArray_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) { 4010d0321e0SJeremy L Thompson CeedVector_Hip *impl; 4022b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 4030d0321e0SJeremy L Thompson 4042b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetArrayCore_Hip(vec, mem_type, array)); 4050d0321e0SJeremy L Thompson 4062b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSetAllInvalid_Hip(vec)); 40743c928f4SJeremy L Thompson switch (mem_type) { 4080d0321e0SJeremy L Thompson case CEED_MEM_HOST: 4090d0321e0SJeremy L Thompson impl->h_array = *array; 4100d0321e0SJeremy L Thompson break; 4110d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 4120d0321e0SJeremy L Thompson impl->d_array = *array; 4130d0321e0SJeremy L Thompson break; 4140d0321e0SJeremy L Thompson } 4150d0321e0SJeremy L Thompson 4160d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4170d0321e0SJeremy L Thompson } 4180d0321e0SJeremy L Thompson 4190d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 42043c928f4SJeremy L Thompson // Get write access to a vector via the specified mem_type 4210d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4222b730f8bSJeremy L Thompson static int CeedVectorGetArrayWrite_Hip(const CeedVector vec, const CeedMemType mem_type, CeedScalar **array) { 4230d0321e0SJeremy L Thompson CeedVector_Hip *impl; 4242b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 4250d0321e0SJeremy L Thompson 4260d0321e0SJeremy L Thompson bool has_array_of_type = true; 4272b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorHasArrayOfType_Hip(vec, mem_type, &has_array_of_type)); 4280d0321e0SJeremy L Thompson if (!has_array_of_type) { 4290d0321e0SJeremy L Thompson // Allocate if array is not yet allocated 4302b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSetArray(vec, mem_type, CEED_COPY_VALUES, NULL)); 4310d0321e0SJeremy L Thompson } else { 4320d0321e0SJeremy L Thompson // Select dirty array 43343c928f4SJeremy L Thompson switch (mem_type) { 4340d0321e0SJeremy L Thompson case CEED_MEM_HOST: 4352b730f8bSJeremy L Thompson if (impl->h_array_borrowed) impl->h_array = impl->h_array_borrowed; 4362b730f8bSJeremy L Thompson else impl->h_array = impl->h_array_owned; 4370d0321e0SJeremy L Thompson break; 4380d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 4392b730f8bSJeremy L Thompson if (impl->d_array_borrowed) impl->d_array = impl->d_array_borrowed; 4402b730f8bSJeremy L Thompson else impl->d_array = impl->d_array_owned; 4410d0321e0SJeremy L Thompson } 4420d0321e0SJeremy L Thompson } 4430d0321e0SJeremy L Thompson 44443c928f4SJeremy L Thompson return CeedVectorGetArray_Hip(vec, mem_type, array); 4450d0321e0SJeremy L Thompson } 4460d0321e0SJeremy L Thompson 4470d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4480d0321e0SJeremy L Thompson // Get the norm of a CeedVector 4490d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4502b730f8bSJeremy L Thompson static int CeedVectorNorm_Hip(CeedVector vec, CeedNormType type, CeedScalar *norm) { 4510d0321e0SJeremy L Thompson Ceed ceed; 4522b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 4530d0321e0SJeremy L Thompson CeedVector_Hip *impl; 4542b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 4551f9221feSJeremy L Thompson CeedSize length; 4562b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 4570d0321e0SJeremy L Thompson hipblasHandle_t handle; 4582b730f8bSJeremy L Thompson CeedCallBackend(CeedHipGetHipblasHandle(ceed, &handle)); 4590d0321e0SJeremy L Thompson 4600d0321e0SJeremy L Thompson // Compute norm 4610d0321e0SJeremy L Thompson const CeedScalar *d_array; 4622b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetArrayRead(vec, CEED_MEM_DEVICE, &d_array)); 4630d0321e0SJeremy L Thompson switch (type) { 4640d0321e0SJeremy L Thompson case CEED_NORM_1: { 4650d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 4662b730f8bSJeremy L Thompson CeedCallHipblas(ceed, hipblasSasum(handle, length, (float *)d_array, 1, (float *)norm)); 4670d0321e0SJeremy L Thompson } else { 4682b730f8bSJeremy L Thompson CeedCallHipblas(ceed, hipblasDasum(handle, length, (double *)d_array, 1, (double *)norm)); 4690d0321e0SJeremy L Thompson } 4700d0321e0SJeremy L Thompson break; 4710d0321e0SJeremy L Thompson } 4720d0321e0SJeremy L Thompson case CEED_NORM_2: { 4730d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 4742b730f8bSJeremy L Thompson CeedCallHipblas(ceed, hipblasSnrm2(handle, length, (float *)d_array, 1, (float *)norm)); 4750d0321e0SJeremy L Thompson } else { 4762b730f8bSJeremy L Thompson CeedCallHipblas(ceed, hipblasDnrm2(handle, length, (double *)d_array, 1, (double *)norm)); 4770d0321e0SJeremy L Thompson } 4780d0321e0SJeremy L Thompson break; 4790d0321e0SJeremy L Thompson } 4800d0321e0SJeremy L Thompson case CEED_NORM_MAX: { 4810d0321e0SJeremy L Thompson CeedInt indx; 4820d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 4832b730f8bSJeremy L Thompson CeedCallHipblas(ceed, hipblasIsamax(handle, length, (float *)d_array, 1, &indx)); 4840d0321e0SJeremy L Thompson } else { 4852b730f8bSJeremy L Thompson CeedCallHipblas(ceed, hipblasIdamax(handle, length, (double *)d_array, 1, &indx)); 4860d0321e0SJeremy L Thompson } 4870d0321e0SJeremy L Thompson CeedScalar normNoAbs; 4882b730f8bSJeremy L Thompson CeedCallHip(ceed, hipMemcpy(&normNoAbs, impl->d_array + indx - 1, sizeof(CeedScalar), hipMemcpyDeviceToHost)); 4890d0321e0SJeremy L Thompson *norm = fabs(normNoAbs); 4900d0321e0SJeremy L Thompson break; 4910d0321e0SJeremy L Thompson } 4920d0321e0SJeremy L Thompson } 4932b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorRestoreArrayRead(vec, &d_array)); 4940d0321e0SJeremy L Thompson 4950d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4960d0321e0SJeremy L Thompson } 4970d0321e0SJeremy L Thompson 4980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4990d0321e0SJeremy L Thompson // Take reciprocal of a vector on host 5000d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5010d0321e0SJeremy L Thompson static int CeedHostReciprocal_Hip(CeedScalar *h_array, CeedInt length) { 5022b730f8bSJeremy L Thompson for (int i = 0; i < length; i++) { 5032b730f8bSJeremy L Thompson if (fabs(h_array[i]) > CEED_EPSILON) h_array[i] = 1. / h_array[i]; 5042b730f8bSJeremy L Thompson } 5050d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5060d0321e0SJeremy L Thompson } 5070d0321e0SJeremy L Thompson 5080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5090d0321e0SJeremy L Thompson // Take reciprocal of a vector on device (impl in .cu file) 5100d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5110d0321e0SJeremy L Thompson int CeedDeviceReciprocal_Hip(CeedScalar *d_array, CeedInt length); 5120d0321e0SJeremy L Thompson 5130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5140d0321e0SJeremy L Thompson // Take reciprocal of a vector 5150d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5160d0321e0SJeremy L Thompson static int CeedVectorReciprocal_Hip(CeedVector vec) { 5170d0321e0SJeremy L Thompson Ceed ceed; 5182b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 5190d0321e0SJeremy L Thompson CeedVector_Hip *impl; 5202b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 5211f9221feSJeremy L Thompson CeedSize length; 5222b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(vec, &length)); 5230d0321e0SJeremy L Thompson 5240d0321e0SJeremy L Thompson // Set value for synced device/host array 5252b730f8bSJeremy L Thompson if (impl->d_array) CeedCallBackend(CeedDeviceReciprocal_Hip(impl->d_array, length)); 5262b730f8bSJeremy L Thompson if (impl->h_array) CeedCallBackend(CeedHostReciprocal_Hip(impl->h_array, length)); 5270d0321e0SJeremy L Thompson 5280d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5290d0321e0SJeremy L Thompson } 5300d0321e0SJeremy L Thompson 5310d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5320d0321e0SJeremy L Thompson // Compute x = alpha x on the host 5330d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5342b730f8bSJeremy L Thompson static int CeedHostScale_Hip(CeedScalar *x_array, CeedScalar alpha, CeedInt length) { 5352b730f8bSJeremy L Thompson for (int i = 0; i < length; i++) x_array[i] *= alpha; 5360d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5370d0321e0SJeremy L Thompson } 5380d0321e0SJeremy L Thompson 5390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5400d0321e0SJeremy L Thompson // Compute x = alpha x on device (impl in .cu file) 5410d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5422b730f8bSJeremy L Thompson int CeedDeviceScale_Hip(CeedScalar *x_array, CeedScalar alpha, CeedInt length); 5430d0321e0SJeremy L Thompson 5440d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5450d0321e0SJeremy L Thompson // Compute x = alpha x 5460d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5470d0321e0SJeremy L Thompson static int CeedVectorScale_Hip(CeedVector x, CeedScalar alpha) { 5480d0321e0SJeremy L Thompson Ceed ceed; 5492b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(x, &ceed)); 5500d0321e0SJeremy L Thompson CeedVector_Hip *x_impl; 5512b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(x, &x_impl)); 5521f9221feSJeremy L Thompson CeedSize length; 5532b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(x, &length)); 5540d0321e0SJeremy L Thompson 5550d0321e0SJeremy L Thompson // Set value for synced device/host array 5562b730f8bSJeremy L Thompson if (x_impl->d_array) CeedCallBackend(CeedDeviceScale_Hip(x_impl->d_array, alpha, length)); 5572b730f8bSJeremy L Thompson if (x_impl->h_array) CeedCallBackend(CeedHostScale_Hip(x_impl->h_array, alpha, length)); 5580d0321e0SJeremy L Thompson 5590d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5600d0321e0SJeremy L Thompson } 5610d0321e0SJeremy L Thompson 5620d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5630d0321e0SJeremy L Thompson // Compute y = alpha x + y on the host 5640d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5652b730f8bSJeremy L Thompson static int CeedHostAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar *x_array, CeedInt length) { 5662b730f8bSJeremy L Thompson for (int i = 0; i < length; i++) y_array[i] += alpha * x_array[i]; 5670d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5680d0321e0SJeremy L Thompson } 5690d0321e0SJeremy L Thompson 5700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5710d0321e0SJeremy L Thompson // Compute y = alpha x + y on device (impl in .cu file) 5720d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5732b730f8bSJeremy L Thompson int CeedDeviceAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar *x_array, CeedInt length); 5740d0321e0SJeremy L Thompson 5750d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5760d0321e0SJeremy L Thompson // Compute y = alpha x + y 5770d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5780d0321e0SJeremy L Thompson static int CeedVectorAXPY_Hip(CeedVector y, CeedScalar alpha, CeedVector x) { 5790d0321e0SJeremy L Thompson Ceed ceed; 5802b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(y, &ceed)); 5810d0321e0SJeremy L Thompson CeedVector_Hip *y_impl, *x_impl; 5822b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(y, &y_impl)); 5832b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(x, &x_impl)); 5841f9221feSJeremy L Thompson CeedSize length; 5852b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(y, &length)); 5860d0321e0SJeremy L Thompson 5870d0321e0SJeremy L Thompson // Set value for synced device/host array 5880d0321e0SJeremy L Thompson if (y_impl->d_array) { 5892b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE)); 5902b730f8bSJeremy L Thompson CeedCallBackend(CeedDeviceAXPY_Hip(y_impl->d_array, alpha, x_impl->d_array, length)); 5910d0321e0SJeremy L Thompson } 5920d0321e0SJeremy L Thompson if (y_impl->h_array) { 5932b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST)); 5942b730f8bSJeremy L Thompson CeedCallBackend(CeedHostAXPY_Hip(y_impl->h_array, alpha, x_impl->h_array, length)); 5950d0321e0SJeremy L Thompson } 5960d0321e0SJeremy L Thompson 5970d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5980d0321e0SJeremy L Thompson } 5995fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------ 6005fb68f37SKaren (Ren) Stengel // Compute y = alpha x + beta y on the host 6015fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------ 6025fb68f37SKaren (Ren) Stengel static int CeedHostAXPBY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar beta, CeedScalar *x_array, CeedInt length) { 6035fb68f37SKaren (Ren) Stengel for (int i = 0; i < length; i++) y_array[i] += alpha * x_array[i] + beta * y_array[i]; 6045fb68f37SKaren (Ren) Stengel return CEED_ERROR_SUCCESS; 6055fb68f37SKaren (Ren) Stengel } 6065fb68f37SKaren (Ren) Stengel 6075fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------ 6085fb68f37SKaren (Ren) Stengel // Compute y = alpha x + beta y on device (impl in .cu file) 6095fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------ 6105fb68f37SKaren (Ren) Stengel int CeedDeviceAXPBY_Hip(CeedScalar *y_array, CeedScalar alpha, CeedScalar beta, CeedScalar *x_array, CeedInt length); 6115fb68f37SKaren (Ren) Stengel 6125fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------ 6135fb68f37SKaren (Ren) Stengel // Compute y = alpha x + beta y 6145fb68f37SKaren (Ren) Stengel //------------------------------------------------------------------------------ 6155fb68f37SKaren (Ren) Stengel static int CeedVectorAXPBY_Hip(CeedVector y, CeedScalar alpha, CeedScalar beta, CeedVector x) { 6165fb68f37SKaren (Ren) Stengel Ceed ceed; 6175fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedVectorGetCeed(y, &ceed)); 6185fb68f37SKaren (Ren) Stengel CeedVector_Hip *y_impl, *x_impl; 6195fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedVectorGetData(y, &y_impl)); 6205fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedVectorGetData(x, &x_impl)); 6215fb68f37SKaren (Ren) Stengel CeedSize length; 6225fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedVectorGetLength(y, &length)); 6235fb68f37SKaren (Ren) Stengel 6245fb68f37SKaren (Ren) Stengel // Set value for synced device/host array 6255fb68f37SKaren (Ren) Stengel if (y_impl->d_array) { 6265fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE)); 6275fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedDeviceAXPBY_Hip(y_impl->d_array, alpha, beta, x_impl->d_array, length)); 6285fb68f37SKaren (Ren) Stengel } 6295fb68f37SKaren (Ren) Stengel if (y_impl->h_array) { 6305fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST)); 6315fb68f37SKaren (Ren) Stengel CeedCallBackend(CeedHostAXPBY_Hip(y_impl->h_array, alpha, beta, x_impl->h_array, length)); 6325fb68f37SKaren (Ren) Stengel } 6335fb68f37SKaren (Ren) Stengel 6345fb68f37SKaren (Ren) Stengel return CEED_ERROR_SUCCESS; 6355fb68f37SKaren (Ren) Stengel } 6360d0321e0SJeremy L Thompson 6370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6380d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on the host 6390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6402b730f8bSJeremy L Thompson static int CeedHostPointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, CeedScalar *y_array, CeedInt length) { 6412b730f8bSJeremy L Thompson for (int i = 0; i < length; i++) w_array[i] = x_array[i] * y_array[i]; 6420d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6430d0321e0SJeremy L Thompson } 6440d0321e0SJeremy L Thompson 6450d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6460d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on device (impl in .cu file) 6470d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6482b730f8bSJeremy L Thompson int CeedDevicePointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, CeedScalar *y_array, CeedInt length); 6490d0321e0SJeremy L Thompson 6500d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6510d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y 6520d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6532b730f8bSJeremy L Thompson static int CeedVectorPointwiseMult_Hip(CeedVector w, CeedVector x, CeedVector y) { 6540d0321e0SJeremy L Thompson Ceed ceed; 6552b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(w, &ceed)); 6560d0321e0SJeremy L Thompson CeedVector_Hip *w_impl, *x_impl, *y_impl; 6572b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(w, &w_impl)); 6582b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(x, &x_impl)); 6592b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(y, &y_impl)); 6601f9221feSJeremy L Thompson CeedSize length; 6612b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetLength(w, &length)); 6620d0321e0SJeremy L Thompson 6630d0321e0SJeremy L Thompson // Set value for synced device/host array 6640d0321e0SJeremy L Thompson if (!w_impl->d_array && !w_impl->h_array) { 6652b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSetValue(w, 0.0)); 6660d0321e0SJeremy L Thompson } 6670d0321e0SJeremy L Thompson if (w_impl->d_array) { 6682b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_DEVICE)); 6692b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(y, CEED_MEM_DEVICE)); 6702b730f8bSJeremy L Thompson CeedCallBackend(CeedDevicePointwiseMult_Hip(w_impl->d_array, x_impl->d_array, y_impl->d_array, length)); 6710d0321e0SJeremy L Thompson } 6720d0321e0SJeremy L Thompson if (w_impl->h_array) { 6732b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(x, CEED_MEM_HOST)); 6742b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSyncArray(y, CEED_MEM_HOST)); 6752b730f8bSJeremy L Thompson CeedCallBackend(CeedHostPointwiseMult_Hip(w_impl->h_array, x_impl->h_array, y_impl->h_array, length)); 6760d0321e0SJeremy L Thompson } 6770d0321e0SJeremy L Thompson 6780d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6790d0321e0SJeremy L Thompson } 6800d0321e0SJeremy L Thompson 6810d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6820d0321e0SJeremy L Thompson // Destroy the vector 6830d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6840d0321e0SJeremy L Thompson static int CeedVectorDestroy_Hip(const CeedVector vec) { 6850d0321e0SJeremy L Thompson Ceed ceed; 6862b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 6870d0321e0SJeremy L Thompson CeedVector_Hip *impl; 6882b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetData(vec, &impl)); 6890d0321e0SJeremy L Thompson 6902b730f8bSJeremy L Thompson CeedCallHip(ceed, hipFree(impl->d_array_owned)); 6912b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_array_owned)); 6922b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl)); 6930d0321e0SJeremy L Thompson 6940d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6950d0321e0SJeremy L Thompson } 6960d0321e0SJeremy L Thompson 6970d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6980d0321e0SJeremy L Thompson // Create a vector of the specified length (does not allocate memory) 6990d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7001f9221feSJeremy L Thompson int CeedVectorCreate_Hip(CeedSize n, CeedVector vec) { 7010d0321e0SJeremy L Thompson CeedVector_Hip *impl; 7020d0321e0SJeremy L Thompson Ceed ceed; 7032b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 7040d0321e0SJeremy L Thompson 7052b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", CeedVectorHasValidArray_Hip)); 7062b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", CeedVectorHasBorrowedArrayOfType_Hip)); 7072b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", CeedVectorSetArray_Hip)); 7082b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", CeedVectorTakeArray_Hip)); 7096fb6c846SJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetValue", CeedVectorSetValue_Hip)); 7102b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SyncArray", CeedVectorSyncArray_Hip)); 7112b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", CeedVectorGetArray_Hip)); 7122b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", CeedVectorGetArrayRead_Hip)); 7132b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", CeedVectorGetArrayWrite_Hip)); 7142b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Norm", CeedVectorNorm_Hip)); 7152b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Reciprocal", CeedVectorReciprocal_Hip)); 7166fb6c846SJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Scale", CeedVectorScale_Hip)); 7176fb6c846SJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "AXPY", CeedVectorAXPY_Hip)); 7186fb6c846SJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "AXPBY", CeedVectorAXPBY_Hip)); 7192b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "PointwiseMult", CeedVectorPointwiseMult_Hip)); 7202b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", CeedVectorDestroy_Hip)); 7210d0321e0SJeremy L Thompson 7222b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl)); 7232b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorSetData(vec, impl)); 7240d0321e0SJeremy L Thompson 7250d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7260d0321e0SJeremy L Thompson } 7272a86cc9dSSebastian Grimberg 7282a86cc9dSSebastian Grimberg //------------------------------------------------------------------------------ 729