10d0321e0SJeremy L Thompson // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 20d0321e0SJeremy L Thompson // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 30d0321e0SJeremy L Thompson // All Rights reserved. See files LICENSE and NOTICE for details. 40d0321e0SJeremy L Thompson // 50d0321e0SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software 60d0321e0SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral 70d0321e0SJeremy L Thompson // element discretizations for exascale applications. For more information and 80d0321e0SJeremy L Thompson // source code availability see http://github.com/ceed. 90d0321e0SJeremy L Thompson // 100d0321e0SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 110d0321e0SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office 120d0321e0SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for 130d0321e0SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including 140d0321e0SJeremy L Thompson // software, applications, hardware, advanced system engineering and early 150d0321e0SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative. 160d0321e0SJeremy L Thompson 170d0321e0SJeremy L Thompson #include <ceed/ceed.h> 180d0321e0SJeremy L Thompson #include <ceed/backend.h> 190d0321e0SJeremy L Thompson #include <hip/hip_runtime.h> 200d0321e0SJeremy L Thompson #include <hipblas.h> 210d0321e0SJeremy L Thompson #include <math.h> 220d0321e0SJeremy L Thompson #include <string.h> 230d0321e0SJeremy L Thompson #include "ceed-hip-ref.h" 240d0321e0SJeremy L Thompson 250d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 260d0321e0SJeremy L Thompson // * Bytes used 270d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 280d0321e0SJeremy L Thompson static inline size_t bytes(const CeedVector vec) { 290d0321e0SJeremy L Thompson int ierr; 300d0321e0SJeremy L Thompson CeedInt length; 310d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 320d0321e0SJeremy L Thompson return length * sizeof(CeedScalar); 330d0321e0SJeremy L Thompson } 340d0321e0SJeremy L Thompson 350d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 360d0321e0SJeremy L Thompson // Sync host to device 370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 380d0321e0SJeremy L Thompson static inline int CeedVectorSyncH2D_Hip(const CeedVector vec) { 390d0321e0SJeremy L Thompson int ierr; 400d0321e0SJeremy L Thompson Ceed ceed; 410d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 420d0321e0SJeremy L Thompson CeedVector_Hip *impl; 430d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 440d0321e0SJeremy L Thompson 450d0321e0SJeremy L Thompson if (!impl->h_array) 460d0321e0SJeremy L Thompson // LCOV_EXCL_START 470d0321e0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, 480d0321e0SJeremy L Thompson "No valid host data to sync to device"); 490d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 500d0321e0SJeremy L Thompson 510d0321e0SJeremy L Thompson if (impl->d_array_borrowed) { 520d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 530d0321e0SJeremy L Thompson } else if (impl->d_array_owned) { 540d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 550d0321e0SJeremy L Thompson } else { 560d0321e0SJeremy L Thompson ierr = hipMalloc((void **)&impl->d_array_owned, bytes(vec)); 570d0321e0SJeremy L Thompson CeedChk_Hip(ceed, ierr); 580d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 590d0321e0SJeremy L Thompson } 600d0321e0SJeremy L Thompson 610d0321e0SJeremy L Thompson ierr = hipMemcpy(impl->d_array, impl->h_array, bytes(vec), 620d0321e0SJeremy L Thompson hipMemcpyHostToDevice); CeedChk_Hip(ceed, ierr); 630d0321e0SJeremy L Thompson 640d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 650d0321e0SJeremy L Thompson } 660d0321e0SJeremy L Thompson 670d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 680d0321e0SJeremy L Thompson // Sync device to host 690d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 700d0321e0SJeremy L Thompson static inline int CeedVectorSyncD2H_Hip(const CeedVector vec) { 710d0321e0SJeremy L Thompson int ierr; 720d0321e0SJeremy L Thompson Ceed ceed; 730d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 740d0321e0SJeremy L Thompson CeedVector_Hip *impl; 750d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 760d0321e0SJeremy L Thompson 770d0321e0SJeremy L Thompson if (!impl->d_array) 780d0321e0SJeremy L Thompson // LCOV_EXCL_START 790d0321e0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, 800d0321e0SJeremy L Thompson "No valid device data to sync to host"); 810d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 820d0321e0SJeremy L Thompson 830d0321e0SJeremy L Thompson if (impl->h_array_borrowed) { 840d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 850d0321e0SJeremy L Thompson } else if (impl->h_array_owned) { 860d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 870d0321e0SJeremy L Thompson } else { 880d0321e0SJeremy L Thompson CeedInt length; 890d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 900d0321e0SJeremy L Thompson ierr = CeedCalloc(length, &impl->h_array_owned); CeedChkBackend(ierr); 910d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 920d0321e0SJeremy L Thompson } 930d0321e0SJeremy L Thompson 940d0321e0SJeremy L Thompson ierr = hipMemcpy(impl->h_array, impl->d_array, bytes(vec), 950d0321e0SJeremy L Thompson hipMemcpyDeviceToHost); CeedChk_Hip(ceed, ierr); 960d0321e0SJeremy L Thompson 970d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 980d0321e0SJeremy L Thompson } 990d0321e0SJeremy L Thompson 1000d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1010d0321e0SJeremy L Thompson // Sync arrays 1020d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 103*43c928f4SJeremy L Thompson static inline int CeedVectorSync_Hip(const CeedVector vec, 104*43c928f4SJeremy L Thompson CeedMemType mem_type) { 105*43c928f4SJeremy L Thompson switch (mem_type) { 1060d0321e0SJeremy L Thompson case CEED_MEM_HOST: return CeedVectorSyncD2H_Hip(vec); 1070d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: return CeedVectorSyncH2D_Hip(vec); 1080d0321e0SJeremy L Thompson } 1090d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 1100d0321e0SJeremy L Thompson } 1110d0321e0SJeremy L Thompson 1120d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1130d0321e0SJeremy L Thompson // Set all pointers as invalid 1140d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1150d0321e0SJeremy L Thompson static inline int CeedVectorSetAllInvalid_Hip(const CeedVector vec) { 1160d0321e0SJeremy L Thompson int ierr; 1170d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1180d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 1190d0321e0SJeremy L Thompson 1200d0321e0SJeremy L Thompson impl->h_array = NULL; 1210d0321e0SJeremy L Thompson impl->d_array = NULL; 1220d0321e0SJeremy L Thompson 1230d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1240d0321e0SJeremy L Thompson } 1250d0321e0SJeremy L Thompson 1260d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1270d0321e0SJeremy L Thompson // Check if CeedVector has any valid pointers 1280d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1290d0321e0SJeremy L Thompson static inline int CeedVectorHasValidArray_Hip(const CeedVector vec, 1300d0321e0SJeremy L Thompson bool *has_valid_array) { 1310d0321e0SJeremy L Thompson int ierr; 1320d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1330d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 1340d0321e0SJeremy L Thompson 1350d0321e0SJeremy L Thompson *has_valid_array = !!impl->h_array || !!impl->d_array; 1360d0321e0SJeremy L Thompson 1370d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1380d0321e0SJeremy L Thompson } 1390d0321e0SJeremy L Thompson 1400d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1410d0321e0SJeremy L Thompson // Check if has any array of given type 1420d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1430d0321e0SJeremy L Thompson static inline int CeedVectorHasArrayOfType_Hip(const CeedVector vec, 144*43c928f4SJeremy L Thompson CeedMemType mem_type, bool *has_array_of_type) { 1450d0321e0SJeremy L Thompson int ierr; 1460d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1470d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 1480d0321e0SJeremy L Thompson 149*43c928f4SJeremy L Thompson switch (mem_type) { 1500d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1510d0321e0SJeremy L Thompson *has_array_of_type = !!impl->h_array_borrowed || !!impl->h_array_owned; 1520d0321e0SJeremy L Thompson break; 1530d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1540d0321e0SJeremy L Thompson *has_array_of_type = !!impl->d_array_borrowed || !!impl->d_array_owned; 1550d0321e0SJeremy L Thompson break; 1560d0321e0SJeremy L Thompson } 1570d0321e0SJeremy L Thompson 1580d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1590d0321e0SJeremy L Thompson } 1600d0321e0SJeremy L Thompson 1610d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1620d0321e0SJeremy L Thompson // Check if has borrowed array of given type 1630d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1640d0321e0SJeremy L Thompson static inline int CeedVectorHasBorrowedArrayOfType_Hip(const CeedVector vec, 165*43c928f4SJeremy L Thompson CeedMemType mem_type, bool *has_borrowed_array_of_type) { 1660d0321e0SJeremy L Thompson int ierr; 1670d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1680d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 1690d0321e0SJeremy L Thompson 170*43c928f4SJeremy L Thompson switch (mem_type) { 1710d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1720d0321e0SJeremy L Thompson *has_borrowed_array_of_type = !!impl->h_array_borrowed; 1730d0321e0SJeremy L Thompson break; 1740d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1750d0321e0SJeremy L Thompson *has_borrowed_array_of_type = !!impl->d_array_borrowed; 1760d0321e0SJeremy L Thompson break; 1770d0321e0SJeremy L Thompson } 1780d0321e0SJeremy L Thompson 1790d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1800d0321e0SJeremy L Thompson } 1810d0321e0SJeremy L Thompson 1820d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1830d0321e0SJeremy L Thompson // Sync array of given type 1840d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1850d0321e0SJeremy L Thompson static inline int CeedVectorNeedSync_Hip(const CeedVector vec, 186*43c928f4SJeremy L Thompson CeedMemType mem_type, bool *need_sync) { 1870d0321e0SJeremy L Thompson int ierr; 1880d0321e0SJeremy L Thompson CeedVector_Hip *impl; 1890d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 1900d0321e0SJeremy L Thompson 1910d0321e0SJeremy L Thompson bool has_valid_array = false; 1920d0321e0SJeremy L Thompson ierr = CeedVectorHasValidArray(vec, &has_valid_array); CeedChkBackend(ierr); 193*43c928f4SJeremy L Thompson switch (mem_type) { 1940d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1950d0321e0SJeremy L Thompson *need_sync = has_valid_array && !impl->h_array; 1960d0321e0SJeremy L Thompson break; 1970d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1980d0321e0SJeremy L Thompson *need_sync = has_valid_array && !impl->d_array; 1990d0321e0SJeremy L Thompson break; 2000d0321e0SJeremy L Thompson } 2010d0321e0SJeremy L Thompson 2020d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2030d0321e0SJeremy L Thompson } 2040d0321e0SJeremy L Thompson 2050d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2060d0321e0SJeremy L Thompson // Set array from host 2070d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2080d0321e0SJeremy L Thompson static int CeedVectorSetArrayHost_Hip(const CeedVector vec, 209*43c928f4SJeremy L Thompson const CeedCopyMode copy_mode, CeedScalar *array) { 2100d0321e0SJeremy L Thompson int ierr; 2110d0321e0SJeremy L Thompson CeedVector_Hip *impl; 2120d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 2130d0321e0SJeremy L Thompson 214*43c928f4SJeremy L Thompson switch (copy_mode) { 2150d0321e0SJeremy L Thompson case CEED_COPY_VALUES: { 2160d0321e0SJeremy L Thompson CeedInt length; 2170d0321e0SJeremy L Thompson if (!impl->h_array_owned) { 2180d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 2190d0321e0SJeremy L Thompson ierr = CeedMalloc(length, &impl->h_array_owned); CeedChkBackend(ierr); 2200d0321e0SJeremy L Thompson } 2210d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 2220d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 2230d0321e0SJeremy L Thompson if (array) 2240d0321e0SJeremy L Thompson memcpy(impl->h_array, array, bytes(vec)); 2250d0321e0SJeremy L Thompson } break; 2260d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 2270d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_array_owned); CeedChkBackend(ierr); 2280d0321e0SJeremy L Thompson impl->h_array_owned = array; 2290d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 2300d0321e0SJeremy L Thompson impl->h_array = array; 2310d0321e0SJeremy L Thompson break; 2320d0321e0SJeremy L Thompson case CEED_USE_POINTER: 2330d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_array_owned); CeedChkBackend(ierr); 2340d0321e0SJeremy L Thompson impl->h_array_borrowed = array; 2350d0321e0SJeremy L Thompson impl->h_array = array; 2360d0321e0SJeremy L Thompson break; 2370d0321e0SJeremy L Thompson } 2380d0321e0SJeremy L Thompson 2390d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2400d0321e0SJeremy L Thompson } 2410d0321e0SJeremy L Thompson 2420d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2430d0321e0SJeremy L Thompson // Set array from device 2440d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2450d0321e0SJeremy L Thompson static int CeedVectorSetArrayDevice_Hip(const CeedVector vec, 246*43c928f4SJeremy L Thompson const CeedCopyMode copy_mode, CeedScalar *array) { 2470d0321e0SJeremy L Thompson int ierr; 2480d0321e0SJeremy L Thompson Ceed ceed; 2490d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 2500d0321e0SJeremy L Thompson CeedVector_Hip *impl; 2510d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 2520d0321e0SJeremy L Thompson 253*43c928f4SJeremy L Thompson switch (copy_mode) { 2540d0321e0SJeremy L Thompson case CEED_COPY_VALUES: 2550d0321e0SJeremy L Thompson if (!impl->d_array_owned) { 2560d0321e0SJeremy L Thompson ierr = hipMalloc((void **)&impl->d_array_owned, bytes(vec)); 2570d0321e0SJeremy L Thompson CeedChk_Hip(ceed, ierr); 2580d0321e0SJeremy L Thompson } 2590d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 2600d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 2610d0321e0SJeremy L Thompson if (array) { 2620d0321e0SJeremy L Thompson ierr = hipMemcpy(impl->d_array, array, bytes(vec), 2630d0321e0SJeremy L Thompson hipMemcpyDeviceToDevice); CeedChk_Hip(ceed, ierr); 2640d0321e0SJeremy L Thompson } 2650d0321e0SJeremy L Thompson break; 2660d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 2670d0321e0SJeremy L Thompson ierr = hipFree(impl->d_array_owned); CeedChk_Hip(ceed, ierr); 2680d0321e0SJeremy L Thompson impl->d_array_owned = array; 2690d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 2700d0321e0SJeremy L Thompson impl->d_array = array; 2710d0321e0SJeremy L Thompson break; 2720d0321e0SJeremy L Thompson case CEED_USE_POINTER: 2730d0321e0SJeremy L Thompson ierr = hipFree(impl->d_array_owned); CeedChk_Hip(ceed, ierr); 2740d0321e0SJeremy L Thompson impl->d_array_owned = NULL; 2750d0321e0SJeremy L Thompson impl->d_array_borrowed = array; 2760d0321e0SJeremy L Thompson impl->d_array = array; 2770d0321e0SJeremy L Thompson break; 2780d0321e0SJeremy L Thompson } 2790d0321e0SJeremy L Thompson 2800d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2810d0321e0SJeremy L Thompson } 2820d0321e0SJeremy L Thompson 2830d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2840d0321e0SJeremy L Thompson // Set the array used by a vector, 2850d0321e0SJeremy L Thompson // freeing any previously allocated array if applicable 2860d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 287*43c928f4SJeremy L Thompson static int CeedVectorSetArray_Hip(const CeedVector vec, 288*43c928f4SJeremy L Thompson const CeedMemType mem_type, 289*43c928f4SJeremy L Thompson const CeedCopyMode copy_mode, CeedScalar *array) { 2900d0321e0SJeremy L Thompson int ierr; 2910d0321e0SJeremy L Thompson Ceed ceed; 2920d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 2930d0321e0SJeremy L Thompson CeedVector_Hip *impl; 2940d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 2950d0321e0SJeremy L Thompson 2960d0321e0SJeremy L Thompson ierr = CeedVectorSetAllInvalid_Hip(vec); CeedChkBackend(ierr); 297*43c928f4SJeremy L Thompson switch (mem_type) { 2980d0321e0SJeremy L Thompson case CEED_MEM_HOST: 299*43c928f4SJeremy L Thompson return CeedVectorSetArrayHost_Hip(vec, copy_mode, array); 3000d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 301*43c928f4SJeremy L Thompson return CeedVectorSetArrayDevice_Hip(vec, copy_mode, array); 3020d0321e0SJeremy L Thompson } 3030d0321e0SJeremy L Thompson 3040d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 3050d0321e0SJeremy L Thompson } 3060d0321e0SJeremy L Thompson 3070d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3080d0321e0SJeremy L Thompson // Set host array to value 3090d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3100d0321e0SJeremy L Thompson static int CeedHostSetValue_Hip(CeedScalar *h_array, CeedInt length, 3110d0321e0SJeremy L Thompson CeedScalar val) { 3120d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 3130d0321e0SJeremy L Thompson h_array[i] = val; 3140d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3150d0321e0SJeremy L Thompson } 3160d0321e0SJeremy L Thompson 3170d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3180d0321e0SJeremy L Thompson // Set device array to value (impl in .hip file) 3190d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3200d0321e0SJeremy L Thompson int CeedDeviceSetValue_Hip(CeedScalar *d_array, CeedInt length, CeedScalar val); 3210d0321e0SJeremy L Thompson 3220d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3230d0321e0SJeremy L Thompson // Set a vector to a value, 3240d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3250d0321e0SJeremy L Thompson static int CeedVectorSetValue_Hip(CeedVector vec, CeedScalar val) { 3260d0321e0SJeremy L Thompson int ierr; 3270d0321e0SJeremy L Thompson Ceed ceed; 3280d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 3290d0321e0SJeremy L Thompson CeedVector_Hip *impl; 3300d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 3310d0321e0SJeremy L Thompson CeedInt length; 3320d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 3330d0321e0SJeremy L Thompson 3340d0321e0SJeremy L Thompson // Set value for synced device/host array 3350d0321e0SJeremy L Thompson if (!impl->d_array && !impl->h_array) { 3360d0321e0SJeremy L Thompson if (impl->d_array_borrowed) { 3370d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 3380d0321e0SJeremy L Thompson } else if (impl->h_array_borrowed) { 3390d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 3400d0321e0SJeremy L Thompson } else if (impl->d_array_owned) { 3410d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 3420d0321e0SJeremy L Thompson } else if (impl->h_array_owned) { 3430d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 3440d0321e0SJeremy L Thompson } else { 3450d0321e0SJeremy L Thompson ierr = CeedVectorSetArray(vec, CEED_MEM_DEVICE, CEED_COPY_VALUES, NULL); 3460d0321e0SJeremy L Thompson CeedChkBackend(ierr); 3470d0321e0SJeremy L Thompson } 3480d0321e0SJeremy L Thompson } 3490d0321e0SJeremy L Thompson if (impl->d_array) { 3500d0321e0SJeremy L Thompson ierr = CeedDeviceSetValue_Hip(impl->d_array, length, val); CeedChkBackend(ierr); 3510d0321e0SJeremy L Thompson } 3520d0321e0SJeremy L Thompson if (impl->h_array) { 3530d0321e0SJeremy L Thompson ierr = CeedHostSetValue_Hip(impl->h_array, length, val); CeedChkBackend(ierr); 3540d0321e0SJeremy L Thompson } 3550d0321e0SJeremy L Thompson 3560d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3570d0321e0SJeremy L Thompson } 3580d0321e0SJeremy L Thompson 3590d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3600d0321e0SJeremy L Thompson // Vector Take Array 3610d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 362*43c928f4SJeremy L Thompson static int CeedVectorTakeArray_Hip(CeedVector vec, CeedMemType mem_type, 3630d0321e0SJeremy L Thompson CeedScalar **array) { 3640d0321e0SJeremy L Thompson int ierr; 3650d0321e0SJeremy L Thompson Ceed ceed; 3660d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 3670d0321e0SJeremy L Thompson CeedVector_Hip *impl; 3680d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 3690d0321e0SJeremy L Thompson 370*43c928f4SJeremy L Thompson // Sync array to requested mem_type 3710d0321e0SJeremy L Thompson bool need_sync = false; 372*43c928f4SJeremy L Thompson ierr = CeedVectorNeedSync_Hip(vec, mem_type, &need_sync); CeedChkBackend(ierr); 3730d0321e0SJeremy L Thompson if (need_sync) { 374*43c928f4SJeremy L Thompson ierr = CeedVectorSync_Hip(vec, mem_type); CeedChkBackend(ierr); 3750d0321e0SJeremy L Thompson } 3760d0321e0SJeremy L Thompson 3770d0321e0SJeremy L Thompson // Update pointer 378*43c928f4SJeremy L Thompson switch (mem_type) { 3790d0321e0SJeremy L Thompson case CEED_MEM_HOST: 3800d0321e0SJeremy L Thompson (*array) = impl->h_array_borrowed; 3810d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 3820d0321e0SJeremy L Thompson impl->h_array = NULL; 3830d0321e0SJeremy L Thompson break; 3840d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 3850d0321e0SJeremy L Thompson (*array) = impl->d_array_borrowed; 3860d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 3870d0321e0SJeremy L Thompson impl->d_array = NULL; 3880d0321e0SJeremy L Thompson break; 3890d0321e0SJeremy L Thompson } 3900d0321e0SJeremy L Thompson 3910d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3920d0321e0SJeremy L Thompson } 3930d0321e0SJeremy L Thompson 3940d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3950d0321e0SJeremy L Thompson // Core logic for array syncronization for GetArray. 3960d0321e0SJeremy L Thompson // If a different memory type is most up to date, this will perform a copy 3970d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3980d0321e0SJeremy L Thompson static int CeedVectorGetArrayCore_Hip(const CeedVector vec, 399*43c928f4SJeremy L Thompson const CeedMemType mem_type, CeedScalar **array) { 4000d0321e0SJeremy L Thompson int ierr; 4010d0321e0SJeremy L Thompson Ceed ceed; 4020d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 4030d0321e0SJeremy L Thompson CeedVector_Hip *impl; 4040d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 4050d0321e0SJeremy L Thompson 4060d0321e0SJeremy L Thompson bool need_sync = false; 407*43c928f4SJeremy L Thompson ierr = CeedVectorNeedSync_Hip(vec, mem_type, &need_sync); CeedChkBackend(ierr); 4080d0321e0SJeremy L Thompson CeedChkBackend(ierr); 4090d0321e0SJeremy L Thompson if (need_sync) { 410*43c928f4SJeremy L Thompson // Sync array to requested mem_type 411*43c928f4SJeremy L Thompson ierr = CeedVectorSync_Hip(vec, mem_type); CeedChkBackend(ierr); 4120d0321e0SJeremy L Thompson } 4130d0321e0SJeremy L Thompson 4140d0321e0SJeremy L Thompson // Update pointer 415*43c928f4SJeremy L Thompson switch (mem_type) { 4160d0321e0SJeremy L Thompson case CEED_MEM_HOST: 4170d0321e0SJeremy L Thompson *array = impl->h_array; 4180d0321e0SJeremy L Thompson break; 4190d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 4200d0321e0SJeremy L Thompson *array = impl->d_array; 4210d0321e0SJeremy L Thompson break; 4220d0321e0SJeremy L Thompson } 4230d0321e0SJeremy L Thompson 4240d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4250d0321e0SJeremy L Thompson } 4260d0321e0SJeremy L Thompson 4270d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 428*43c928f4SJeremy L Thompson // Get read-only access to a vector via the specified mem_type 4290d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4300d0321e0SJeremy L Thompson static int CeedVectorGetArrayRead_Hip(const CeedVector vec, 431*43c928f4SJeremy L Thompson const CeedMemType mem_type, const CeedScalar **array) { 432*43c928f4SJeremy L Thompson return CeedVectorGetArrayCore_Hip(vec, mem_type, (CeedScalar **)array); 4330d0321e0SJeremy L Thompson } 4340d0321e0SJeremy L Thompson 4350d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 436*43c928f4SJeremy L Thompson // Get read/write access to a vector via the specified mem_type 4370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 438*43c928f4SJeremy L Thompson static int CeedVectorGetArray_Hip(const CeedVector vec, 439*43c928f4SJeremy L Thompson const CeedMemType mem_type, 4400d0321e0SJeremy L Thompson CeedScalar **array) { 4410d0321e0SJeremy L Thompson int ierr; 4420d0321e0SJeremy L Thompson CeedVector_Hip *impl; 4430d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 4440d0321e0SJeremy L Thompson 445*43c928f4SJeremy L Thompson ierr = CeedVectorGetArrayCore_Hip(vec, mem_type, array); CeedChkBackend(ierr); 4460d0321e0SJeremy L Thompson 4470d0321e0SJeremy L Thompson ierr = CeedVectorSetAllInvalid_Hip(vec); CeedChkBackend(ierr); 448*43c928f4SJeremy L Thompson switch (mem_type) { 4490d0321e0SJeremy L Thompson case CEED_MEM_HOST: 4500d0321e0SJeremy L Thompson impl->h_array = *array; 4510d0321e0SJeremy L Thompson break; 4520d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 4530d0321e0SJeremy L Thompson impl->d_array = *array; 4540d0321e0SJeremy L Thompson break; 4550d0321e0SJeremy L Thompson } 4560d0321e0SJeremy L Thompson 4570d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4580d0321e0SJeremy L Thompson } 4590d0321e0SJeremy L Thompson 4600d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 461*43c928f4SJeremy L Thompson // Get write access to a vector via the specified mem_type 4620d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4630d0321e0SJeremy L Thompson static int CeedVectorGetArrayWrite_Hip(const CeedVector vec, 464*43c928f4SJeremy L Thompson const CeedMemType mem_type, CeedScalar **array) { 4650d0321e0SJeremy L Thompson int ierr; 4660d0321e0SJeremy L Thompson CeedVector_Hip *impl; 4670d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 4680d0321e0SJeremy L Thompson 4690d0321e0SJeremy L Thompson bool has_array_of_type = true; 470*43c928f4SJeremy L Thompson ierr = CeedVectorHasArrayOfType_Hip(vec, mem_type, &has_array_of_type); 4710d0321e0SJeremy L Thompson CeedChkBackend(ierr); 4720d0321e0SJeremy L Thompson if (!has_array_of_type) { 4730d0321e0SJeremy L Thompson // Allocate if array is not yet allocated 474*43c928f4SJeremy L Thompson ierr = CeedVectorSetArray(vec, mem_type, CEED_COPY_VALUES, NULL); 4750d0321e0SJeremy L Thompson CeedChkBackend(ierr); 4760d0321e0SJeremy L Thompson } else { 4770d0321e0SJeremy L Thompson // Select dirty array 478*43c928f4SJeremy L Thompson switch (mem_type) { 4790d0321e0SJeremy L Thompson case CEED_MEM_HOST: 4800d0321e0SJeremy L Thompson if (impl->h_array_borrowed) 4810d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 4820d0321e0SJeremy L Thompson else 4830d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 4840d0321e0SJeremy L Thompson break; 4850d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 4860d0321e0SJeremy L Thompson if (impl->d_array_borrowed) 4870d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 4880d0321e0SJeremy L Thompson else 4890d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 4900d0321e0SJeremy L Thompson } 4910d0321e0SJeremy L Thompson } 4920d0321e0SJeremy L Thompson 493*43c928f4SJeremy L Thompson return CeedVectorGetArray_Hip(vec, mem_type, array); 4940d0321e0SJeremy L Thompson } 4950d0321e0SJeremy L Thompson 4960d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4970d0321e0SJeremy L Thompson // Restore an array obtained using CeedVectorGetArrayRead() 4980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 4990d0321e0SJeremy L Thompson static int CeedVectorRestoreArrayRead_Hip(const CeedVector vec) { 5000d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5010d0321e0SJeremy L Thompson } 5020d0321e0SJeremy L Thompson 5030d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5040d0321e0SJeremy L Thompson // Restore an array obtained using CeedVectorGetArray() 5050d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5060d0321e0SJeremy L Thompson static int CeedVectorRestoreArray_Hip(const CeedVector vec) { 5070d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5080d0321e0SJeremy L Thompson } 5090d0321e0SJeremy L Thompson 5100d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5110d0321e0SJeremy L Thompson // Get the norm of a CeedVector 5120d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5130d0321e0SJeremy L Thompson static int CeedVectorNorm_Hip(CeedVector vec, CeedNormType type, 5140d0321e0SJeremy L Thompson CeedScalar *norm) { 5150d0321e0SJeremy L Thompson int ierr; 5160d0321e0SJeremy L Thompson Ceed ceed; 5170d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 5180d0321e0SJeremy L Thompson CeedVector_Hip *impl; 5190d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 5200d0321e0SJeremy L Thompson CeedInt length; 5210d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 5220d0321e0SJeremy L Thompson hipblasHandle_t handle; 5230d0321e0SJeremy L Thompson ierr = CeedHipGetHipblasHandle(ceed, &handle); CeedChkBackend(ierr); 5240d0321e0SJeremy L Thompson 5250d0321e0SJeremy L Thompson // Compute norm 5260d0321e0SJeremy L Thompson const CeedScalar *d_array; 5270d0321e0SJeremy L Thompson ierr = CeedVectorGetArrayRead(vec, CEED_MEM_DEVICE, &d_array); 5280d0321e0SJeremy L Thompson CeedChkBackend(ierr); 5290d0321e0SJeremy L Thompson switch (type) { 5300d0321e0SJeremy L Thompson case CEED_NORM_1: { 5310d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 5320d0321e0SJeremy L Thompson ierr = hipblasSasum(handle, length, (float *) d_array, 1, (float *) norm); 5330d0321e0SJeremy L Thompson } else { 5340d0321e0SJeremy L Thompson ierr = hipblasDasum(handle, length, (double *) d_array, 1, (double *) norm); 5350d0321e0SJeremy L Thompson } 5360d0321e0SJeremy L Thompson CeedChk_Hipblas(ceed, ierr); 5370d0321e0SJeremy L Thompson break; 5380d0321e0SJeremy L Thompson } 5390d0321e0SJeremy L Thompson case CEED_NORM_2: { 5400d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 5410d0321e0SJeremy L Thompson ierr = hipblasSnrm2(handle, length, (float *) d_array, 1, (float *) norm); 5420d0321e0SJeremy L Thompson } else { 5430d0321e0SJeremy L Thompson ierr = hipblasDnrm2(handle, length, (double *) d_array, 1, (double *) norm); 5440d0321e0SJeremy L Thompson } 5450d0321e0SJeremy L Thompson CeedChk_Hipblas(ceed, ierr); 5460d0321e0SJeremy L Thompson break; 5470d0321e0SJeremy L Thompson } 5480d0321e0SJeremy L Thompson case CEED_NORM_MAX: { 5490d0321e0SJeremy L Thompson CeedInt indx; 5500d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 5510d0321e0SJeremy L Thompson ierr = hipblasIsamax(handle, length, (float *) d_array, 1, &indx); 5520d0321e0SJeremy L Thompson } else { 5530d0321e0SJeremy L Thompson ierr = hipblasIdamax(handle, length, (double *) d_array, 1, &indx); 5540d0321e0SJeremy L Thompson } 5550d0321e0SJeremy L Thompson CeedChk_Hipblas(ceed, ierr); 5560d0321e0SJeremy L Thompson CeedScalar normNoAbs; 5570d0321e0SJeremy L Thompson ierr = hipMemcpy(&normNoAbs, impl->d_array+indx-1, sizeof(CeedScalar), 5580d0321e0SJeremy L Thompson hipMemcpyDeviceToHost); CeedChk_Hip(ceed, ierr); 5590d0321e0SJeremy L Thompson *norm = fabs(normNoAbs); 5600d0321e0SJeremy L Thompson break; 5610d0321e0SJeremy L Thompson } 5620d0321e0SJeremy L Thompson } 5630d0321e0SJeremy L Thompson ierr = CeedVectorRestoreArrayRead(vec, &d_array); CeedChkBackend(ierr); 5640d0321e0SJeremy L Thompson 5650d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5660d0321e0SJeremy L Thompson } 5670d0321e0SJeremy L Thompson 5680d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5690d0321e0SJeremy L Thompson // Take reciprocal of a vector on host 5700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5710d0321e0SJeremy L Thompson static int CeedHostReciprocal_Hip(CeedScalar *h_array, CeedInt length) { 5720d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 5730d0321e0SJeremy L Thompson if (fabs(h_array[i]) > CEED_EPSILON) 5740d0321e0SJeremy L Thompson h_array[i] = 1./h_array[i]; 5750d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5760d0321e0SJeremy L Thompson } 5770d0321e0SJeremy L Thompson 5780d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5790d0321e0SJeremy L Thompson // Take reciprocal of a vector on device (impl in .cu file) 5800d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5810d0321e0SJeremy L Thompson int CeedDeviceReciprocal_Hip(CeedScalar *d_array, CeedInt length); 5820d0321e0SJeremy L Thompson 5830d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5840d0321e0SJeremy L Thompson // Take reciprocal of a vector 5850d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 5860d0321e0SJeremy L Thompson static int CeedVectorReciprocal_Hip(CeedVector vec) { 5870d0321e0SJeremy L Thompson int ierr; 5880d0321e0SJeremy L Thompson Ceed ceed; 5890d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 5900d0321e0SJeremy L Thompson CeedVector_Hip *impl; 5910d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 5920d0321e0SJeremy L Thompson CeedInt length; 5930d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 5940d0321e0SJeremy L Thompson 5950d0321e0SJeremy L Thompson // Set value for synced device/host array 5960d0321e0SJeremy L Thompson if (impl->d_array) { 5970d0321e0SJeremy L Thompson ierr = CeedDeviceReciprocal_Hip(impl->d_array, length); CeedChkBackend(ierr); 5980d0321e0SJeremy L Thompson } 5990d0321e0SJeremy L Thompson if (impl->h_array) { 6000d0321e0SJeremy L Thompson ierr = CeedHostReciprocal_Hip(impl->h_array, length); CeedChkBackend(ierr); 6010d0321e0SJeremy L Thompson } 6020d0321e0SJeremy L Thompson 6030d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6040d0321e0SJeremy L Thompson } 6050d0321e0SJeremy L Thompson 6060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6070d0321e0SJeremy L Thompson // Compute x = alpha x on the host 6080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6090d0321e0SJeremy L Thompson static int CeedHostScale_Hip(CeedScalar *x_array, CeedScalar alpha, 6100d0321e0SJeremy L Thompson CeedInt length) { 6110d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 6120d0321e0SJeremy L Thompson x_array[i] *= alpha; 6130d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6140d0321e0SJeremy L Thompson } 6150d0321e0SJeremy L Thompson 6160d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6170d0321e0SJeremy L Thompson // Compute x = alpha x on device (impl in .cu file) 6180d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6190d0321e0SJeremy L Thompson int CeedDeviceScale_Hip(CeedScalar *x_array, CeedScalar alpha, 6200d0321e0SJeremy L Thompson CeedInt length); 6210d0321e0SJeremy L Thompson 6220d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6230d0321e0SJeremy L Thompson // Compute x = alpha x 6240d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6250d0321e0SJeremy L Thompson static int CeedVectorScale_Hip(CeedVector x, CeedScalar alpha) { 6260d0321e0SJeremy L Thompson int ierr; 6270d0321e0SJeremy L Thompson Ceed ceed; 6280d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(x, &ceed); CeedChkBackend(ierr); 6290d0321e0SJeremy L Thompson CeedVector_Hip *x_impl; 6300d0321e0SJeremy L Thompson ierr = CeedVectorGetData(x, &x_impl); CeedChkBackend(ierr); 6310d0321e0SJeremy L Thompson CeedInt length; 6320d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(x, &length); CeedChkBackend(ierr); 6330d0321e0SJeremy L Thompson 6340d0321e0SJeremy L Thompson // Set value for synced device/host array 6350d0321e0SJeremy L Thompson if (x_impl->d_array) { 6360d0321e0SJeremy L Thompson ierr = CeedDeviceScale_Hip(x_impl->d_array, alpha, length); 6370d0321e0SJeremy L Thompson CeedChkBackend(ierr); 6380d0321e0SJeremy L Thompson } 6390d0321e0SJeremy L Thompson if (x_impl->h_array) { 6400d0321e0SJeremy L Thompson ierr = CeedHostScale_Hip(x_impl->h_array, alpha, length); CeedChkBackend(ierr); 6410d0321e0SJeremy L Thompson } 6420d0321e0SJeremy L Thompson 6430d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6440d0321e0SJeremy L Thompson } 6450d0321e0SJeremy L Thompson 6460d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6470d0321e0SJeremy L Thompson // Compute y = alpha x + y on the host 6480d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6490d0321e0SJeremy L Thompson static int CeedHostAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, 6500d0321e0SJeremy L Thompson CeedScalar *x_array, CeedInt length) { 6510d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 6520d0321e0SJeremy L Thompson y_array[i] += alpha * x_array[i]; 6530d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6540d0321e0SJeremy L Thompson } 6550d0321e0SJeremy L Thompson 6560d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6570d0321e0SJeremy L Thompson // Compute y = alpha x + y on device (impl in .cu file) 6580d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6590d0321e0SJeremy L Thompson int CeedDeviceAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, 6600d0321e0SJeremy L Thompson CeedScalar *x_array, CeedInt length); 6610d0321e0SJeremy L Thompson 6620d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6630d0321e0SJeremy L Thompson // Compute y = alpha x + y 6640d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6650d0321e0SJeremy L Thompson static int CeedVectorAXPY_Hip(CeedVector y, CeedScalar alpha, CeedVector x) { 6660d0321e0SJeremy L Thompson int ierr; 6670d0321e0SJeremy L Thompson Ceed ceed; 6680d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(y, &ceed); CeedChkBackend(ierr); 6690d0321e0SJeremy L Thompson CeedVector_Hip *y_impl, *x_impl; 6700d0321e0SJeremy L Thompson ierr = CeedVectorGetData(y, &y_impl); CeedChkBackend(ierr); 6710d0321e0SJeremy L Thompson ierr = CeedVectorGetData(x, &x_impl); CeedChkBackend(ierr); 6720d0321e0SJeremy L Thompson CeedInt length; 6730d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(y, &length); CeedChkBackend(ierr); 6740d0321e0SJeremy L Thompson 6750d0321e0SJeremy L Thompson // Set value for synced device/host array 6760d0321e0SJeremy L Thompson if (y_impl->d_array) { 6770d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_DEVICE); CeedChkBackend(ierr); 6780d0321e0SJeremy L Thompson ierr = CeedDeviceAXPY_Hip(y_impl->d_array, alpha, x_impl->d_array, length); 6790d0321e0SJeremy L Thompson CeedChkBackend(ierr); 6800d0321e0SJeremy L Thompson } 6810d0321e0SJeremy L Thompson if (y_impl->h_array) { 6820d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_HOST); CeedChkBackend(ierr); 6830d0321e0SJeremy L Thompson ierr = CeedHostAXPY_Hip(y_impl->h_array, alpha, x_impl->h_array, length); 6840d0321e0SJeremy L Thompson CeedChkBackend(ierr); 6850d0321e0SJeremy L Thompson } 6860d0321e0SJeremy L Thompson 6870d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6880d0321e0SJeremy L Thompson } 6890d0321e0SJeremy L Thompson 6900d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6910d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on the host 6920d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 6930d0321e0SJeremy L Thompson static int CeedHostPointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, 6940d0321e0SJeremy L Thompson CeedScalar *y_array, CeedInt length) { 6950d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 6960d0321e0SJeremy L Thompson w_array[i] = x_array[i] * y_array[i]; 6970d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6980d0321e0SJeremy L Thompson } 6990d0321e0SJeremy L Thompson 7000d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7010d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on device (impl in .cu file) 7020d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7030d0321e0SJeremy L Thompson int CeedDevicePointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, 7040d0321e0SJeremy L Thompson CeedScalar *y_array, CeedInt length); 7050d0321e0SJeremy L Thompson 7060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7070d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y 7080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7090d0321e0SJeremy L Thompson static int CeedVectorPointwiseMult_Hip(CeedVector w, CeedVector x, 7100d0321e0SJeremy L Thompson CeedVector y) { 7110d0321e0SJeremy L Thompson int ierr; 7120d0321e0SJeremy L Thompson Ceed ceed; 7130d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(w, &ceed); CeedChkBackend(ierr); 7140d0321e0SJeremy L Thompson CeedVector_Hip *w_impl, *x_impl, *y_impl; 7150d0321e0SJeremy L Thompson ierr = CeedVectorGetData(w, &w_impl); CeedChkBackend(ierr); 7160d0321e0SJeremy L Thompson ierr = CeedVectorGetData(x, &x_impl); CeedChkBackend(ierr); 7170d0321e0SJeremy L Thompson ierr = CeedVectorGetData(y, &y_impl); CeedChkBackend(ierr); 7180d0321e0SJeremy L Thompson CeedInt length; 7190d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(w, &length); CeedChkBackend(ierr); 7200d0321e0SJeremy L Thompson 7210d0321e0SJeremy L Thompson // Set value for synced device/host array 7220d0321e0SJeremy L Thompson if (!w_impl->d_array && !w_impl->h_array) { 7230d0321e0SJeremy L Thompson ierr = CeedVectorSetValue(w, 0.0); CeedChkBackend(ierr); 7240d0321e0SJeremy L Thompson } 7250d0321e0SJeremy L Thompson if (w_impl->d_array) { 7260d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_DEVICE); CeedChkBackend(ierr); 7270d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(y, CEED_MEM_DEVICE); CeedChkBackend(ierr); 7280d0321e0SJeremy L Thompson ierr = CeedDevicePointwiseMult_Hip(w_impl->d_array, x_impl->d_array, 7290d0321e0SJeremy L Thompson y_impl->d_array, length); 7300d0321e0SJeremy L Thompson CeedChkBackend(ierr); 7310d0321e0SJeremy L Thompson } 7320d0321e0SJeremy L Thompson if (w_impl->h_array) { 7330d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_HOST); CeedChkBackend(ierr); 7340d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(y, CEED_MEM_HOST); CeedChkBackend(ierr); 7350d0321e0SJeremy L Thompson ierr = CeedHostPointwiseMult_Hip(w_impl->h_array, x_impl->h_array, 7360d0321e0SJeremy L Thompson y_impl->h_array, length); 7370d0321e0SJeremy L Thompson CeedChkBackend(ierr); 7380d0321e0SJeremy L Thompson } 7390d0321e0SJeremy L Thompson 7400d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7410d0321e0SJeremy L Thompson } 7420d0321e0SJeremy L Thompson 7430d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7440d0321e0SJeremy L Thompson // Destroy the vector 7450d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7460d0321e0SJeremy L Thompson static int CeedVectorDestroy_Hip(const CeedVector vec) { 7470d0321e0SJeremy L Thompson int ierr; 7480d0321e0SJeremy L Thompson Ceed ceed; 7490d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 7500d0321e0SJeremy L Thompson CeedVector_Hip *impl; 7510d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 7520d0321e0SJeremy L Thompson 7530d0321e0SJeremy L Thompson ierr = hipFree(impl->d_array_owned); CeedChk_Hip(ceed, ierr); 7540d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_array_owned); CeedChkBackend(ierr); 7550d0321e0SJeremy L Thompson ierr = CeedFree(&impl); CeedChkBackend(ierr); 7560d0321e0SJeremy L Thompson 7570d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7580d0321e0SJeremy L Thompson } 7590d0321e0SJeremy L Thompson 7600d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7610d0321e0SJeremy L Thompson // Create a vector of the specified length (does not allocate memory) 7620d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 7630d0321e0SJeremy L Thompson int CeedVectorCreate_Hip(CeedInt n, CeedVector vec) { 7640d0321e0SJeremy L Thompson CeedVector_Hip *impl; 7650d0321e0SJeremy L Thompson int ierr; 7660d0321e0SJeremy L Thompson Ceed ceed; 7670d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 7680d0321e0SJeremy L Thompson 7690d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", 7700d0321e0SJeremy L Thompson CeedVectorHasValidArray_Hip); CeedChkBackend(ierr); 7710d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", 7720d0321e0SJeremy L Thompson CeedVectorHasBorrowedArrayOfType_Hip); 7730d0321e0SJeremy L Thompson CeedChkBackend(ierr); 7740d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", 7750d0321e0SJeremy L Thompson CeedVectorSetArray_Hip); CeedChkBackend(ierr); 7760d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", 7770d0321e0SJeremy L Thompson CeedVectorTakeArray_Hip); CeedChkBackend(ierr); 7780d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "SetValue", 7790d0321e0SJeremy L Thompson (int (*)())(CeedVectorSetValue_Hip)); CeedChkBackend(ierr); 7800d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", 7810d0321e0SJeremy L Thompson CeedVectorGetArray_Hip); CeedChkBackend(ierr); 7820d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", 7830d0321e0SJeremy L Thompson CeedVectorGetArrayRead_Hip); CeedChkBackend(ierr); 7840d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", 7850d0321e0SJeremy L Thompson CeedVectorGetArrayWrite_Hip); CeedChkBackend(ierr); 7860d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArray", 7870d0321e0SJeremy L Thompson CeedVectorRestoreArray_Hip); CeedChkBackend(ierr); 7880d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArrayRead", 7890d0321e0SJeremy L Thompson CeedVectorRestoreArrayRead_Hip); CeedChkBackend(ierr); 7900d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Norm", 7910d0321e0SJeremy L Thompson CeedVectorNorm_Hip); CeedChkBackend(ierr); 7920d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Reciprocal", 7930d0321e0SJeremy L Thompson CeedVectorReciprocal_Hip); CeedChkBackend(ierr); 7940d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Scale", 7950d0321e0SJeremy L Thompson (int (*)())(CeedVectorScale_Hip)); CeedChkBackend(ierr); 7960d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "AXPY", 7970d0321e0SJeremy L Thompson (int (*)())(CeedVectorAXPY_Hip)); CeedChkBackend(ierr); 7980d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "PointwiseMult", 7990d0321e0SJeremy L Thompson CeedVectorPointwiseMult_Hip); CeedChkBackend(ierr); 8000d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", 8010d0321e0SJeremy L Thompson CeedVectorDestroy_Hip); CeedChkBackend(ierr); 8020d0321e0SJeremy L Thompson 8030d0321e0SJeremy L Thompson ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr); 8040d0321e0SJeremy L Thompson ierr = CeedVectorSetData(vec, impl); CeedChkBackend(ierr); 8050d0321e0SJeremy L Thompson 8060d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8070d0321e0SJeremy L Thompson } 808