1*0d0321e0SJeremy L Thompson // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 2*0d0321e0SJeremy L Thompson // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 3*0d0321e0SJeremy L Thompson // All Rights reserved. See files LICENSE and NOTICE for details. 4*0d0321e0SJeremy L Thompson // 5*0d0321e0SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software 6*0d0321e0SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral 7*0d0321e0SJeremy L Thompson // element discretizations for exascale applications. For more information and 8*0d0321e0SJeremy L Thompson // source code availability see http://github.com/ceed. 9*0d0321e0SJeremy L Thompson // 10*0d0321e0SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*0d0321e0SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office 12*0d0321e0SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for 13*0d0321e0SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including 14*0d0321e0SJeremy L Thompson // software, applications, hardware, advanced system engineering and early 15*0d0321e0SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative. 16*0d0321e0SJeremy L Thompson 17*0d0321e0SJeremy L Thompson #include <ceed/ceed.h> 18*0d0321e0SJeremy L Thompson #include <ceed/backend.h> 19*0d0321e0SJeremy L Thompson #include <hip/hip_runtime.h> 20*0d0321e0SJeremy L Thompson #include <hipblas.h> 21*0d0321e0SJeremy L Thompson #include <math.h> 22*0d0321e0SJeremy L Thompson #include <string.h> 23*0d0321e0SJeremy L Thompson #include "ceed-hip-ref.h" 24*0d0321e0SJeremy L Thompson 25*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 26*0d0321e0SJeremy L Thompson // * Bytes used 27*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 28*0d0321e0SJeremy L Thompson static inline size_t bytes(const CeedVector vec) { 29*0d0321e0SJeremy L Thompson int ierr; 30*0d0321e0SJeremy L Thompson CeedInt length; 31*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 32*0d0321e0SJeremy L Thompson return length * sizeof(CeedScalar); 33*0d0321e0SJeremy L Thompson } 34*0d0321e0SJeremy L Thompson 35*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 36*0d0321e0SJeremy L Thompson // Sync host to device 37*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 38*0d0321e0SJeremy L Thompson static inline int CeedVectorSyncH2D_Hip(const CeedVector vec) { 39*0d0321e0SJeremy L Thompson int ierr; 40*0d0321e0SJeremy L Thompson Ceed ceed; 41*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 42*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 43*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 44*0d0321e0SJeremy L Thompson 45*0d0321e0SJeremy L Thompson if (!impl->h_array) 46*0d0321e0SJeremy L Thompson // LCOV_EXCL_START 47*0d0321e0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, 48*0d0321e0SJeremy L Thompson "No valid host data to sync to device"); 49*0d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 50*0d0321e0SJeremy L Thompson 51*0d0321e0SJeremy L Thompson if (impl->d_array_borrowed) { 52*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 53*0d0321e0SJeremy L Thompson } else if (impl->d_array_owned) { 54*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 55*0d0321e0SJeremy L Thompson } else { 56*0d0321e0SJeremy L Thompson ierr = hipMalloc((void **)&impl->d_array_owned, bytes(vec)); 57*0d0321e0SJeremy L Thompson CeedChk_Hip(ceed, ierr); 58*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 59*0d0321e0SJeremy L Thompson } 60*0d0321e0SJeremy L Thompson 61*0d0321e0SJeremy L Thompson ierr = hipMemcpy(impl->d_array, impl->h_array, bytes(vec), 62*0d0321e0SJeremy L Thompson hipMemcpyHostToDevice); CeedChk_Hip(ceed, ierr); 63*0d0321e0SJeremy L Thompson 64*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 65*0d0321e0SJeremy L Thompson } 66*0d0321e0SJeremy L Thompson 67*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 68*0d0321e0SJeremy L Thompson // Sync device to host 69*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 70*0d0321e0SJeremy L Thompson static inline int CeedVectorSyncD2H_Hip(const CeedVector vec) { 71*0d0321e0SJeremy L Thompson int ierr; 72*0d0321e0SJeremy L Thompson Ceed ceed; 73*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 74*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 75*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 76*0d0321e0SJeremy L Thompson 77*0d0321e0SJeremy L Thompson if (!impl->d_array) 78*0d0321e0SJeremy L Thompson // LCOV_EXCL_START 79*0d0321e0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, 80*0d0321e0SJeremy L Thompson "No valid device data to sync to host"); 81*0d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 82*0d0321e0SJeremy L Thompson 83*0d0321e0SJeremy L Thompson if (impl->h_array_borrowed) { 84*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 85*0d0321e0SJeremy L Thompson } else if (impl->h_array_owned) { 86*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 87*0d0321e0SJeremy L Thompson } else { 88*0d0321e0SJeremy L Thompson CeedInt length; 89*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 90*0d0321e0SJeremy L Thompson ierr = CeedCalloc(length, &impl->h_array_owned); CeedChkBackend(ierr); 91*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 92*0d0321e0SJeremy L Thompson } 93*0d0321e0SJeremy L Thompson 94*0d0321e0SJeremy L Thompson ierr = hipMemcpy(impl->h_array, impl->d_array, bytes(vec), 95*0d0321e0SJeremy L Thompson hipMemcpyDeviceToHost); CeedChk_Hip(ceed, ierr); 96*0d0321e0SJeremy L Thompson 97*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 98*0d0321e0SJeremy L Thompson } 99*0d0321e0SJeremy L Thompson 100*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 101*0d0321e0SJeremy L Thompson // Sync arrays 102*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 103*0d0321e0SJeremy L Thompson static inline int CeedVectorSync_Hip(const CeedVector vec, CeedMemType mtype) { 104*0d0321e0SJeremy L Thompson switch (mtype) { 105*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: return CeedVectorSyncD2H_Hip(vec); 106*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: return CeedVectorSyncH2D_Hip(vec); 107*0d0321e0SJeremy L Thompson } 108*0d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 109*0d0321e0SJeremy L Thompson } 110*0d0321e0SJeremy L Thompson 111*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 112*0d0321e0SJeremy L Thompson // Set all pointers as invalid 113*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 114*0d0321e0SJeremy L Thompson static inline int CeedVectorSetAllInvalid_Hip(const CeedVector vec) { 115*0d0321e0SJeremy L Thompson int ierr; 116*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 117*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 118*0d0321e0SJeremy L Thompson 119*0d0321e0SJeremy L Thompson impl->h_array = NULL; 120*0d0321e0SJeremy L Thompson impl->d_array = NULL; 121*0d0321e0SJeremy L Thompson 122*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 123*0d0321e0SJeremy L Thompson } 124*0d0321e0SJeremy L Thompson 125*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 126*0d0321e0SJeremy L Thompson // Check if CeedVector has any valid pointers 127*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 128*0d0321e0SJeremy L Thompson static inline int CeedVectorHasValidArray_Hip(const CeedVector vec, 129*0d0321e0SJeremy L Thompson bool *has_valid_array) { 130*0d0321e0SJeremy L Thompson int ierr; 131*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 132*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 133*0d0321e0SJeremy L Thompson 134*0d0321e0SJeremy L Thompson *has_valid_array = !!impl->h_array || !!impl->d_array; 135*0d0321e0SJeremy L Thompson 136*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 137*0d0321e0SJeremy L Thompson } 138*0d0321e0SJeremy L Thompson 139*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 140*0d0321e0SJeremy L Thompson // Check if has any array of given type 141*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 142*0d0321e0SJeremy L Thompson static inline int CeedVectorHasArrayOfType_Hip(const CeedVector vec, 143*0d0321e0SJeremy L Thompson CeedMemType mtype, bool *has_array_of_type) { 144*0d0321e0SJeremy L Thompson int ierr; 145*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 146*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 147*0d0321e0SJeremy L Thompson 148*0d0321e0SJeremy L Thompson switch (mtype) { 149*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 150*0d0321e0SJeremy L Thompson *has_array_of_type = !!impl->h_array_borrowed || !!impl->h_array_owned; 151*0d0321e0SJeremy L Thompson break; 152*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 153*0d0321e0SJeremy L Thompson *has_array_of_type = !!impl->d_array_borrowed || !!impl->d_array_owned; 154*0d0321e0SJeremy L Thompson break; 155*0d0321e0SJeremy L Thompson } 156*0d0321e0SJeremy L Thompson 157*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 158*0d0321e0SJeremy L Thompson } 159*0d0321e0SJeremy L Thompson 160*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 161*0d0321e0SJeremy L Thompson // Check if has borrowed array of given type 162*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 163*0d0321e0SJeremy L Thompson static inline int CeedVectorHasBorrowedArrayOfType_Hip(const CeedVector vec, 164*0d0321e0SJeremy L Thompson CeedMemType mtype, bool *has_borrowed_array_of_type) { 165*0d0321e0SJeremy L Thompson int ierr; 166*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 167*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 168*0d0321e0SJeremy L Thompson 169*0d0321e0SJeremy L Thompson switch (mtype) { 170*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 171*0d0321e0SJeremy L Thompson *has_borrowed_array_of_type = !!impl->h_array_borrowed; 172*0d0321e0SJeremy L Thompson break; 173*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 174*0d0321e0SJeremy L Thompson *has_borrowed_array_of_type = !!impl->d_array_borrowed; 175*0d0321e0SJeremy L Thompson break; 176*0d0321e0SJeremy L Thompson } 177*0d0321e0SJeremy L Thompson 178*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 179*0d0321e0SJeremy L Thompson } 180*0d0321e0SJeremy L Thompson 181*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 182*0d0321e0SJeremy L Thompson // Sync array of given type 183*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 184*0d0321e0SJeremy L Thompson static inline int CeedVectorNeedSync_Hip(const CeedVector vec, 185*0d0321e0SJeremy L Thompson CeedMemType mtype, bool *need_sync) { 186*0d0321e0SJeremy L Thompson int ierr; 187*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 188*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 189*0d0321e0SJeremy L Thompson 190*0d0321e0SJeremy L Thompson bool has_valid_array = false; 191*0d0321e0SJeremy L Thompson ierr = CeedVectorHasValidArray(vec, &has_valid_array); CeedChkBackend(ierr); 192*0d0321e0SJeremy L Thompson switch (mtype) { 193*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 194*0d0321e0SJeremy L Thompson *need_sync = has_valid_array && !impl->h_array; 195*0d0321e0SJeremy L Thompson break; 196*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 197*0d0321e0SJeremy L Thompson *need_sync = has_valid_array && !impl->d_array; 198*0d0321e0SJeremy L Thompson break; 199*0d0321e0SJeremy L Thompson } 200*0d0321e0SJeremy L Thompson 201*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 202*0d0321e0SJeremy L Thompson } 203*0d0321e0SJeremy L Thompson 204*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 205*0d0321e0SJeremy L Thompson // Set array from host 206*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 207*0d0321e0SJeremy L Thompson static int CeedVectorSetArrayHost_Hip(const CeedVector vec, 208*0d0321e0SJeremy L Thompson const CeedCopyMode cmode, CeedScalar *array) { 209*0d0321e0SJeremy L Thompson int ierr; 210*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 211*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 212*0d0321e0SJeremy L Thompson 213*0d0321e0SJeremy L Thompson switch (cmode) { 214*0d0321e0SJeremy L Thompson case CEED_COPY_VALUES: { 215*0d0321e0SJeremy L Thompson CeedInt length; 216*0d0321e0SJeremy L Thompson if (!impl->h_array_owned) { 217*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 218*0d0321e0SJeremy L Thompson ierr = CeedMalloc(length, &impl->h_array_owned); CeedChkBackend(ierr); 219*0d0321e0SJeremy L Thompson } 220*0d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 221*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 222*0d0321e0SJeremy L Thompson if (array) 223*0d0321e0SJeremy L Thompson memcpy(impl->h_array, array, bytes(vec)); 224*0d0321e0SJeremy L Thompson } break; 225*0d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 226*0d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_array_owned); CeedChkBackend(ierr); 227*0d0321e0SJeremy L Thompson impl->h_array_owned = array; 228*0d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 229*0d0321e0SJeremy L Thompson impl->h_array = array; 230*0d0321e0SJeremy L Thompson break; 231*0d0321e0SJeremy L Thompson case CEED_USE_POINTER: 232*0d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_array_owned); CeedChkBackend(ierr); 233*0d0321e0SJeremy L Thompson impl->h_array_borrowed = array; 234*0d0321e0SJeremy L Thompson impl->h_array = array; 235*0d0321e0SJeremy L Thompson break; 236*0d0321e0SJeremy L Thompson } 237*0d0321e0SJeremy L Thompson 238*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 239*0d0321e0SJeremy L Thompson } 240*0d0321e0SJeremy L Thompson 241*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 242*0d0321e0SJeremy L Thompson // Set array from device 243*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 244*0d0321e0SJeremy L Thompson static int CeedVectorSetArrayDevice_Hip(const CeedVector vec, 245*0d0321e0SJeremy L Thompson const CeedCopyMode cmode, CeedScalar *array) { 246*0d0321e0SJeremy L Thompson int ierr; 247*0d0321e0SJeremy L Thompson Ceed ceed; 248*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 249*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 250*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 251*0d0321e0SJeremy L Thompson 252*0d0321e0SJeremy L Thompson switch (cmode) { 253*0d0321e0SJeremy L Thompson case CEED_COPY_VALUES: 254*0d0321e0SJeremy L Thompson if (!impl->d_array_owned) { 255*0d0321e0SJeremy L Thompson ierr = hipMalloc((void **)&impl->d_array_owned, bytes(vec)); 256*0d0321e0SJeremy L Thompson CeedChk_Hip(ceed, ierr); 257*0d0321e0SJeremy L Thompson } 258*0d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 259*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 260*0d0321e0SJeremy L Thompson if (array) { 261*0d0321e0SJeremy L Thompson ierr = hipMemcpy(impl->d_array, array, bytes(vec), 262*0d0321e0SJeremy L Thompson hipMemcpyDeviceToDevice); CeedChk_Hip(ceed, ierr); 263*0d0321e0SJeremy L Thompson } 264*0d0321e0SJeremy L Thompson break; 265*0d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 266*0d0321e0SJeremy L Thompson ierr = hipFree(impl->d_array_owned); CeedChk_Hip(ceed, ierr); 267*0d0321e0SJeremy L Thompson impl->d_array_owned = array; 268*0d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 269*0d0321e0SJeremy L Thompson impl->d_array = array; 270*0d0321e0SJeremy L Thompson break; 271*0d0321e0SJeremy L Thompson case CEED_USE_POINTER: 272*0d0321e0SJeremy L Thompson ierr = hipFree(impl->d_array_owned); CeedChk_Hip(ceed, ierr); 273*0d0321e0SJeremy L Thompson impl->d_array_owned = NULL; 274*0d0321e0SJeremy L Thompson impl->d_array_borrowed = array; 275*0d0321e0SJeremy L Thompson impl->d_array = array; 276*0d0321e0SJeremy L Thompson break; 277*0d0321e0SJeremy L Thompson } 278*0d0321e0SJeremy L Thompson 279*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 280*0d0321e0SJeremy L Thompson } 281*0d0321e0SJeremy L Thompson 282*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 283*0d0321e0SJeremy L Thompson // Set the array used by a vector, 284*0d0321e0SJeremy L Thompson // freeing any previously allocated array if applicable 285*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 286*0d0321e0SJeremy L Thompson static int CeedVectorSetArray_Hip(const CeedVector vec, const CeedMemType mtype, 287*0d0321e0SJeremy L Thompson const CeedCopyMode cmode, CeedScalar *array) { 288*0d0321e0SJeremy L Thompson int ierr; 289*0d0321e0SJeremy L Thompson Ceed ceed; 290*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 291*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 292*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 293*0d0321e0SJeremy L Thompson 294*0d0321e0SJeremy L Thompson ierr = CeedVectorSetAllInvalid_Hip(vec); CeedChkBackend(ierr); 295*0d0321e0SJeremy L Thompson switch (mtype) { 296*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 297*0d0321e0SJeremy L Thompson return CeedVectorSetArrayHost_Hip(vec, cmode, array); 298*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 299*0d0321e0SJeremy L Thompson return CeedVectorSetArrayDevice_Hip(vec, cmode, array); 300*0d0321e0SJeremy L Thompson } 301*0d0321e0SJeremy L Thompson 302*0d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 303*0d0321e0SJeremy L Thompson } 304*0d0321e0SJeremy L Thompson 305*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 306*0d0321e0SJeremy L Thompson // Set host array to value 307*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 308*0d0321e0SJeremy L Thompson static int CeedHostSetValue_Hip(CeedScalar *h_array, CeedInt length, 309*0d0321e0SJeremy L Thompson CeedScalar val) { 310*0d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 311*0d0321e0SJeremy L Thompson h_array[i] = val; 312*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 313*0d0321e0SJeremy L Thompson } 314*0d0321e0SJeremy L Thompson 315*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 316*0d0321e0SJeremy L Thompson // Set device array to value (impl in .hip file) 317*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 318*0d0321e0SJeremy L Thompson int CeedDeviceSetValue_Hip(CeedScalar *d_array, CeedInt length, CeedScalar val); 319*0d0321e0SJeremy L Thompson 320*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 321*0d0321e0SJeremy L Thompson // Set a vector to a value, 322*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 323*0d0321e0SJeremy L Thompson static int CeedVectorSetValue_Hip(CeedVector vec, CeedScalar val) { 324*0d0321e0SJeremy L Thompson int ierr; 325*0d0321e0SJeremy L Thompson Ceed ceed; 326*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 327*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 328*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 329*0d0321e0SJeremy L Thompson CeedInt length; 330*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 331*0d0321e0SJeremy L Thompson 332*0d0321e0SJeremy L Thompson // Set value for synced device/host array 333*0d0321e0SJeremy L Thompson if (!impl->d_array && !impl->h_array) { 334*0d0321e0SJeremy L Thompson if (impl->d_array_borrowed) { 335*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 336*0d0321e0SJeremy L Thompson } else if (impl->h_array_borrowed) { 337*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 338*0d0321e0SJeremy L Thompson } else if (impl->d_array_owned) { 339*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 340*0d0321e0SJeremy L Thompson } else if (impl->h_array_owned) { 341*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 342*0d0321e0SJeremy L Thompson } else { 343*0d0321e0SJeremy L Thompson ierr = CeedVectorSetArray(vec, CEED_MEM_DEVICE, CEED_COPY_VALUES, NULL); 344*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 345*0d0321e0SJeremy L Thompson } 346*0d0321e0SJeremy L Thompson } 347*0d0321e0SJeremy L Thompson if (impl->d_array) { 348*0d0321e0SJeremy L Thompson ierr = CeedDeviceSetValue_Hip(impl->d_array, length, val); CeedChkBackend(ierr); 349*0d0321e0SJeremy L Thompson } 350*0d0321e0SJeremy L Thompson if (impl->h_array) { 351*0d0321e0SJeremy L Thompson ierr = CeedHostSetValue_Hip(impl->h_array, length, val); CeedChkBackend(ierr); 352*0d0321e0SJeremy L Thompson } 353*0d0321e0SJeremy L Thompson 354*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 355*0d0321e0SJeremy L Thompson } 356*0d0321e0SJeremy L Thompson 357*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 358*0d0321e0SJeremy L Thompson // Vector Take Array 359*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 360*0d0321e0SJeremy L Thompson static int CeedVectorTakeArray_Hip(CeedVector vec, CeedMemType mtype, 361*0d0321e0SJeremy L Thompson CeedScalar **array) { 362*0d0321e0SJeremy L Thompson int ierr; 363*0d0321e0SJeremy L Thompson Ceed ceed; 364*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 365*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 366*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 367*0d0321e0SJeremy L Thompson 368*0d0321e0SJeremy L Thompson // Sync array to requested memtype 369*0d0321e0SJeremy L Thompson bool need_sync = false; 370*0d0321e0SJeremy L Thompson ierr = CeedVectorNeedSync_Hip(vec, mtype, &need_sync); CeedChkBackend(ierr); 371*0d0321e0SJeremy L Thompson if (need_sync) { 372*0d0321e0SJeremy L Thompson ierr = CeedVectorSync_Hip(vec, mtype); CeedChkBackend(ierr); 373*0d0321e0SJeremy L Thompson } 374*0d0321e0SJeremy L Thompson 375*0d0321e0SJeremy L Thompson // Update pointer 376*0d0321e0SJeremy L Thompson switch (mtype) { 377*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 378*0d0321e0SJeremy L Thompson (*array) = impl->h_array_borrowed; 379*0d0321e0SJeremy L Thompson impl->h_array_borrowed = NULL; 380*0d0321e0SJeremy L Thompson impl->h_array = NULL; 381*0d0321e0SJeremy L Thompson break; 382*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 383*0d0321e0SJeremy L Thompson (*array) = impl->d_array_borrowed; 384*0d0321e0SJeremy L Thompson impl->d_array_borrowed = NULL; 385*0d0321e0SJeremy L Thompson impl->d_array = NULL; 386*0d0321e0SJeremy L Thompson break; 387*0d0321e0SJeremy L Thompson } 388*0d0321e0SJeremy L Thompson 389*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 390*0d0321e0SJeremy L Thompson } 391*0d0321e0SJeremy L Thompson 392*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 393*0d0321e0SJeremy L Thompson // Core logic for array syncronization for GetArray. 394*0d0321e0SJeremy L Thompson // If a different memory type is most up to date, this will perform a copy 395*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 396*0d0321e0SJeremy L Thompson static int CeedVectorGetArrayCore_Hip(const CeedVector vec, 397*0d0321e0SJeremy L Thompson const CeedMemType mtype, CeedScalar **array) { 398*0d0321e0SJeremy L Thompson int ierr; 399*0d0321e0SJeremy L Thompson Ceed ceed; 400*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 401*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 402*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 403*0d0321e0SJeremy L Thompson 404*0d0321e0SJeremy L Thompson bool need_sync = false; 405*0d0321e0SJeremy L Thompson ierr = CeedVectorNeedSync_Hip(vec, mtype, &need_sync); CeedChkBackend(ierr); 406*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 407*0d0321e0SJeremy L Thompson if (need_sync) { 408*0d0321e0SJeremy L Thompson // Sync array to requested memtype 409*0d0321e0SJeremy L Thompson ierr = CeedVectorSync_Hip(vec, mtype); CeedChkBackend(ierr); 410*0d0321e0SJeremy L Thompson } 411*0d0321e0SJeremy L Thompson 412*0d0321e0SJeremy L Thompson // Update pointer 413*0d0321e0SJeremy L Thompson switch (mtype) { 414*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 415*0d0321e0SJeremy L Thompson *array = impl->h_array; 416*0d0321e0SJeremy L Thompson break; 417*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 418*0d0321e0SJeremy L Thompson *array = impl->d_array; 419*0d0321e0SJeremy L Thompson break; 420*0d0321e0SJeremy L Thompson } 421*0d0321e0SJeremy L Thompson 422*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 423*0d0321e0SJeremy L Thompson } 424*0d0321e0SJeremy L Thompson 425*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 426*0d0321e0SJeremy L Thompson // Get read-only access to a vector via the specified mtype 427*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 428*0d0321e0SJeremy L Thompson static int CeedVectorGetArrayRead_Hip(const CeedVector vec, 429*0d0321e0SJeremy L Thompson const CeedMemType mtype, const CeedScalar **array) { 430*0d0321e0SJeremy L Thompson return CeedVectorGetArrayCore_Hip(vec, mtype, (CeedScalar **)array); 431*0d0321e0SJeremy L Thompson } 432*0d0321e0SJeremy L Thompson 433*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 434*0d0321e0SJeremy L Thompson // Get read/write access to a vector via the specified mtype 435*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 436*0d0321e0SJeremy L Thompson static int CeedVectorGetArray_Hip(const CeedVector vec, const CeedMemType mtype, 437*0d0321e0SJeremy L Thompson CeedScalar **array) { 438*0d0321e0SJeremy L Thompson int ierr; 439*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 440*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 441*0d0321e0SJeremy L Thompson 442*0d0321e0SJeremy L Thompson ierr = CeedVectorGetArrayCore_Hip(vec, mtype, array); CeedChkBackend(ierr); 443*0d0321e0SJeremy L Thompson 444*0d0321e0SJeremy L Thompson ierr = CeedVectorSetAllInvalid_Hip(vec); CeedChkBackend(ierr); 445*0d0321e0SJeremy L Thompson switch (mtype) { 446*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 447*0d0321e0SJeremy L Thompson impl->h_array = *array; 448*0d0321e0SJeremy L Thompson break; 449*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 450*0d0321e0SJeremy L Thompson impl->d_array = *array; 451*0d0321e0SJeremy L Thompson break; 452*0d0321e0SJeremy L Thompson } 453*0d0321e0SJeremy L Thompson 454*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 455*0d0321e0SJeremy L Thompson } 456*0d0321e0SJeremy L Thompson 457*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 458*0d0321e0SJeremy L Thompson // Get write access to a vector via the specified mtype 459*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 460*0d0321e0SJeremy L Thompson static int CeedVectorGetArrayWrite_Hip(const CeedVector vec, 461*0d0321e0SJeremy L Thompson const CeedMemType mtype, CeedScalar **array) { 462*0d0321e0SJeremy L Thompson int ierr; 463*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 464*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 465*0d0321e0SJeremy L Thompson 466*0d0321e0SJeremy L Thompson bool has_array_of_type = true; 467*0d0321e0SJeremy L Thompson ierr = CeedVectorHasArrayOfType_Hip(vec, mtype, &has_array_of_type); 468*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 469*0d0321e0SJeremy L Thompson if (!has_array_of_type) { 470*0d0321e0SJeremy L Thompson // Allocate if array is not yet allocated 471*0d0321e0SJeremy L Thompson ierr = CeedVectorSetArray(vec, mtype, CEED_COPY_VALUES, NULL); 472*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 473*0d0321e0SJeremy L Thompson } else { 474*0d0321e0SJeremy L Thompson // Select dirty array 475*0d0321e0SJeremy L Thompson switch (mtype) { 476*0d0321e0SJeremy L Thompson case CEED_MEM_HOST: 477*0d0321e0SJeremy L Thompson if (impl->h_array_borrowed) 478*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_borrowed; 479*0d0321e0SJeremy L Thompson else 480*0d0321e0SJeremy L Thompson impl->h_array = impl->h_array_owned; 481*0d0321e0SJeremy L Thompson break; 482*0d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 483*0d0321e0SJeremy L Thompson if (impl->d_array_borrowed) 484*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_borrowed; 485*0d0321e0SJeremy L Thompson else 486*0d0321e0SJeremy L Thompson impl->d_array = impl->d_array_owned; 487*0d0321e0SJeremy L Thompson } 488*0d0321e0SJeremy L Thompson } 489*0d0321e0SJeremy L Thompson 490*0d0321e0SJeremy L Thompson return CeedVectorGetArray_Hip(vec, mtype, array); 491*0d0321e0SJeremy L Thompson } 492*0d0321e0SJeremy L Thompson 493*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 494*0d0321e0SJeremy L Thompson // Restore an array obtained using CeedVectorGetArrayRead() 495*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 496*0d0321e0SJeremy L Thompson static int CeedVectorRestoreArrayRead_Hip(const CeedVector vec) { 497*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 498*0d0321e0SJeremy L Thompson } 499*0d0321e0SJeremy L Thompson 500*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 501*0d0321e0SJeremy L Thompson // Restore an array obtained using CeedVectorGetArray() 502*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 503*0d0321e0SJeremy L Thompson static int CeedVectorRestoreArray_Hip(const CeedVector vec) { 504*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 505*0d0321e0SJeremy L Thompson } 506*0d0321e0SJeremy L Thompson 507*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 508*0d0321e0SJeremy L Thompson // Get the norm of a CeedVector 509*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 510*0d0321e0SJeremy L Thompson static int CeedVectorNorm_Hip(CeedVector vec, CeedNormType type, 511*0d0321e0SJeremy L Thompson CeedScalar *norm) { 512*0d0321e0SJeremy L Thompson int ierr; 513*0d0321e0SJeremy L Thompson Ceed ceed; 514*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 515*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 516*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 517*0d0321e0SJeremy L Thompson CeedInt length; 518*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 519*0d0321e0SJeremy L Thompson hipblasHandle_t handle; 520*0d0321e0SJeremy L Thompson ierr = CeedHipGetHipblasHandle(ceed, &handle); CeedChkBackend(ierr); 521*0d0321e0SJeremy L Thompson 522*0d0321e0SJeremy L Thompson // Compute norm 523*0d0321e0SJeremy L Thompson const CeedScalar *d_array; 524*0d0321e0SJeremy L Thompson ierr = CeedVectorGetArrayRead(vec, CEED_MEM_DEVICE, &d_array); 525*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 526*0d0321e0SJeremy L Thompson switch (type) { 527*0d0321e0SJeremy L Thompson case CEED_NORM_1: { 528*0d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 529*0d0321e0SJeremy L Thompson ierr = hipblasSasum(handle, length, (float *) d_array, 1, (float *) norm); 530*0d0321e0SJeremy L Thompson } else { 531*0d0321e0SJeremy L Thompson ierr = hipblasDasum(handle, length, (double *) d_array, 1, (double *) norm); 532*0d0321e0SJeremy L Thompson } 533*0d0321e0SJeremy L Thompson CeedChk_Hipblas(ceed, ierr); 534*0d0321e0SJeremy L Thompson break; 535*0d0321e0SJeremy L Thompson } 536*0d0321e0SJeremy L Thompson case CEED_NORM_2: { 537*0d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 538*0d0321e0SJeremy L Thompson ierr = hipblasSnrm2(handle, length, (float *) d_array, 1, (float *) norm); 539*0d0321e0SJeremy L Thompson } else { 540*0d0321e0SJeremy L Thompson ierr = hipblasDnrm2(handle, length, (double *) d_array, 1, (double *) norm); 541*0d0321e0SJeremy L Thompson } 542*0d0321e0SJeremy L Thompson CeedChk_Hipblas(ceed, ierr); 543*0d0321e0SJeremy L Thompson break; 544*0d0321e0SJeremy L Thompson } 545*0d0321e0SJeremy L Thompson case CEED_NORM_MAX: { 546*0d0321e0SJeremy L Thompson CeedInt indx; 547*0d0321e0SJeremy L Thompson if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32) { 548*0d0321e0SJeremy L Thompson ierr = hipblasIsamax(handle, length, (float *) d_array, 1, &indx); 549*0d0321e0SJeremy L Thompson } else { 550*0d0321e0SJeremy L Thompson ierr = hipblasIdamax(handle, length, (double *) d_array, 1, &indx); 551*0d0321e0SJeremy L Thompson } 552*0d0321e0SJeremy L Thompson CeedChk_Hipblas(ceed, ierr); 553*0d0321e0SJeremy L Thompson CeedScalar normNoAbs; 554*0d0321e0SJeremy L Thompson ierr = hipMemcpy(&normNoAbs, impl->d_array+indx-1, sizeof(CeedScalar), 555*0d0321e0SJeremy L Thompson hipMemcpyDeviceToHost); CeedChk_Hip(ceed, ierr); 556*0d0321e0SJeremy L Thompson *norm = fabs(normNoAbs); 557*0d0321e0SJeremy L Thompson break; 558*0d0321e0SJeremy L Thompson } 559*0d0321e0SJeremy L Thompson } 560*0d0321e0SJeremy L Thompson ierr = CeedVectorRestoreArrayRead(vec, &d_array); CeedChkBackend(ierr); 561*0d0321e0SJeremy L Thompson 562*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 563*0d0321e0SJeremy L Thompson } 564*0d0321e0SJeremy L Thompson 565*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 566*0d0321e0SJeremy L Thompson // Take reciprocal of a vector on host 567*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 568*0d0321e0SJeremy L Thompson static int CeedHostReciprocal_Hip(CeedScalar *h_array, CeedInt length) { 569*0d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 570*0d0321e0SJeremy L Thompson if (fabs(h_array[i]) > CEED_EPSILON) 571*0d0321e0SJeremy L Thompson h_array[i] = 1./h_array[i]; 572*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 573*0d0321e0SJeremy L Thompson } 574*0d0321e0SJeremy L Thompson 575*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 576*0d0321e0SJeremy L Thompson // Take reciprocal of a vector on device (impl in .cu file) 577*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 578*0d0321e0SJeremy L Thompson int CeedDeviceReciprocal_Hip(CeedScalar *d_array, CeedInt length); 579*0d0321e0SJeremy L Thompson 580*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 581*0d0321e0SJeremy L Thompson // Take reciprocal of a vector 582*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 583*0d0321e0SJeremy L Thompson static int CeedVectorReciprocal_Hip(CeedVector vec) { 584*0d0321e0SJeremy L Thompson int ierr; 585*0d0321e0SJeremy L Thompson Ceed ceed; 586*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 587*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 588*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 589*0d0321e0SJeremy L Thompson CeedInt length; 590*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 591*0d0321e0SJeremy L Thompson 592*0d0321e0SJeremy L Thompson // Set value for synced device/host array 593*0d0321e0SJeremy L Thompson if (impl->d_array) { 594*0d0321e0SJeremy L Thompson ierr = CeedDeviceReciprocal_Hip(impl->d_array, length); CeedChkBackend(ierr); 595*0d0321e0SJeremy L Thompson } 596*0d0321e0SJeremy L Thompson if (impl->h_array) { 597*0d0321e0SJeremy L Thompson ierr = CeedHostReciprocal_Hip(impl->h_array, length); CeedChkBackend(ierr); 598*0d0321e0SJeremy L Thompson } 599*0d0321e0SJeremy L Thompson 600*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 601*0d0321e0SJeremy L Thompson } 602*0d0321e0SJeremy L Thompson 603*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 604*0d0321e0SJeremy L Thompson // Compute x = alpha x on the host 605*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 606*0d0321e0SJeremy L Thompson static int CeedHostScale_Hip(CeedScalar *x_array, CeedScalar alpha, 607*0d0321e0SJeremy L Thompson CeedInt length) { 608*0d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 609*0d0321e0SJeremy L Thompson x_array[i] *= alpha; 610*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 611*0d0321e0SJeremy L Thompson } 612*0d0321e0SJeremy L Thompson 613*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 614*0d0321e0SJeremy L Thompson // Compute x = alpha x on device (impl in .cu file) 615*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 616*0d0321e0SJeremy L Thompson int CeedDeviceScale_Hip(CeedScalar *x_array, CeedScalar alpha, 617*0d0321e0SJeremy L Thompson CeedInt length); 618*0d0321e0SJeremy L Thompson 619*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 620*0d0321e0SJeremy L Thompson // Compute x = alpha x 621*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 622*0d0321e0SJeremy L Thompson static int CeedVectorScale_Hip(CeedVector x, CeedScalar alpha) { 623*0d0321e0SJeremy L Thompson int ierr; 624*0d0321e0SJeremy L Thompson Ceed ceed; 625*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(x, &ceed); CeedChkBackend(ierr); 626*0d0321e0SJeremy L Thompson CeedVector_Hip *x_impl; 627*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(x, &x_impl); CeedChkBackend(ierr); 628*0d0321e0SJeremy L Thompson CeedInt length; 629*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(x, &length); CeedChkBackend(ierr); 630*0d0321e0SJeremy L Thompson 631*0d0321e0SJeremy L Thompson // Set value for synced device/host array 632*0d0321e0SJeremy L Thompson if (x_impl->d_array) { 633*0d0321e0SJeremy L Thompson ierr = CeedDeviceScale_Hip(x_impl->d_array, alpha, length); 634*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 635*0d0321e0SJeremy L Thompson } 636*0d0321e0SJeremy L Thompson if (x_impl->h_array) { 637*0d0321e0SJeremy L Thompson ierr = CeedHostScale_Hip(x_impl->h_array, alpha, length); CeedChkBackend(ierr); 638*0d0321e0SJeremy L Thompson } 639*0d0321e0SJeremy L Thompson 640*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 641*0d0321e0SJeremy L Thompson } 642*0d0321e0SJeremy L Thompson 643*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 644*0d0321e0SJeremy L Thompson // Compute y = alpha x + y on the host 645*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 646*0d0321e0SJeremy L Thompson static int CeedHostAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, 647*0d0321e0SJeremy L Thompson CeedScalar *x_array, CeedInt length) { 648*0d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 649*0d0321e0SJeremy L Thompson y_array[i] += alpha * x_array[i]; 650*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 651*0d0321e0SJeremy L Thompson } 652*0d0321e0SJeremy L Thompson 653*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 654*0d0321e0SJeremy L Thompson // Compute y = alpha x + y on device (impl in .cu file) 655*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 656*0d0321e0SJeremy L Thompson int CeedDeviceAXPY_Hip(CeedScalar *y_array, CeedScalar alpha, 657*0d0321e0SJeremy L Thompson CeedScalar *x_array, CeedInt length); 658*0d0321e0SJeremy L Thompson 659*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 660*0d0321e0SJeremy L Thompson // Compute y = alpha x + y 661*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 662*0d0321e0SJeremy L Thompson static int CeedVectorAXPY_Hip(CeedVector y, CeedScalar alpha, CeedVector x) { 663*0d0321e0SJeremy L Thompson int ierr; 664*0d0321e0SJeremy L Thompson Ceed ceed; 665*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(y, &ceed); CeedChkBackend(ierr); 666*0d0321e0SJeremy L Thompson CeedVector_Hip *y_impl, *x_impl; 667*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(y, &y_impl); CeedChkBackend(ierr); 668*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(x, &x_impl); CeedChkBackend(ierr); 669*0d0321e0SJeremy L Thompson CeedInt length; 670*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(y, &length); CeedChkBackend(ierr); 671*0d0321e0SJeremy L Thompson 672*0d0321e0SJeremy L Thompson // Set value for synced device/host array 673*0d0321e0SJeremy L Thompson if (y_impl->d_array) { 674*0d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_DEVICE); CeedChkBackend(ierr); 675*0d0321e0SJeremy L Thompson ierr = CeedDeviceAXPY_Hip(y_impl->d_array, alpha, x_impl->d_array, length); 676*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 677*0d0321e0SJeremy L Thompson } 678*0d0321e0SJeremy L Thompson if (y_impl->h_array) { 679*0d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_HOST); CeedChkBackend(ierr); 680*0d0321e0SJeremy L Thompson ierr = CeedHostAXPY_Hip(y_impl->h_array, alpha, x_impl->h_array, length); 681*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 682*0d0321e0SJeremy L Thompson } 683*0d0321e0SJeremy L Thompson 684*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 685*0d0321e0SJeremy L Thompson } 686*0d0321e0SJeremy L Thompson 687*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 688*0d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on the host 689*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 690*0d0321e0SJeremy L Thompson static int CeedHostPointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, 691*0d0321e0SJeremy L Thompson CeedScalar *y_array, CeedInt length) { 692*0d0321e0SJeremy L Thompson for (int i = 0; i < length; i++) 693*0d0321e0SJeremy L Thompson w_array[i] = x_array[i] * y_array[i]; 694*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 695*0d0321e0SJeremy L Thompson } 696*0d0321e0SJeremy L Thompson 697*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 698*0d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y on device (impl in .cu file) 699*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 700*0d0321e0SJeremy L Thompson int CeedDevicePointwiseMult_Hip(CeedScalar *w_array, CeedScalar *x_array, 701*0d0321e0SJeremy L Thompson CeedScalar *y_array, CeedInt length); 702*0d0321e0SJeremy L Thompson 703*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 704*0d0321e0SJeremy L Thompson // Compute the pointwise multiplication w = x .* y 705*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 706*0d0321e0SJeremy L Thompson static int CeedVectorPointwiseMult_Hip(CeedVector w, CeedVector x, 707*0d0321e0SJeremy L Thompson CeedVector y) { 708*0d0321e0SJeremy L Thompson int ierr; 709*0d0321e0SJeremy L Thompson Ceed ceed; 710*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(w, &ceed); CeedChkBackend(ierr); 711*0d0321e0SJeremy L Thompson CeedVector_Hip *w_impl, *x_impl, *y_impl; 712*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(w, &w_impl); CeedChkBackend(ierr); 713*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(x, &x_impl); CeedChkBackend(ierr); 714*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(y, &y_impl); CeedChkBackend(ierr); 715*0d0321e0SJeremy L Thompson CeedInt length; 716*0d0321e0SJeremy L Thompson ierr = CeedVectorGetLength(w, &length); CeedChkBackend(ierr); 717*0d0321e0SJeremy L Thompson 718*0d0321e0SJeremy L Thompson // Set value for synced device/host array 719*0d0321e0SJeremy L Thompson if (!w_impl->d_array && !w_impl->h_array) { 720*0d0321e0SJeremy L Thompson ierr = CeedVectorSetValue(w, 0.0); CeedChkBackend(ierr); 721*0d0321e0SJeremy L Thompson } 722*0d0321e0SJeremy L Thompson if (w_impl->d_array) { 723*0d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_DEVICE); CeedChkBackend(ierr); 724*0d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(y, CEED_MEM_DEVICE); CeedChkBackend(ierr); 725*0d0321e0SJeremy L Thompson ierr = CeedDevicePointwiseMult_Hip(w_impl->d_array, x_impl->d_array, 726*0d0321e0SJeremy L Thompson y_impl->d_array, length); 727*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 728*0d0321e0SJeremy L Thompson } 729*0d0321e0SJeremy L Thompson if (w_impl->h_array) { 730*0d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(x, CEED_MEM_HOST); CeedChkBackend(ierr); 731*0d0321e0SJeremy L Thompson ierr = CeedVectorSyncArray(y, CEED_MEM_HOST); CeedChkBackend(ierr); 732*0d0321e0SJeremy L Thompson ierr = CeedHostPointwiseMult_Hip(w_impl->h_array, x_impl->h_array, 733*0d0321e0SJeremy L Thompson y_impl->h_array, length); 734*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 735*0d0321e0SJeremy L Thompson } 736*0d0321e0SJeremy L Thompson 737*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 738*0d0321e0SJeremy L Thompson } 739*0d0321e0SJeremy L Thompson 740*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 741*0d0321e0SJeremy L Thompson // Destroy the vector 742*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 743*0d0321e0SJeremy L Thompson static int CeedVectorDestroy_Hip(const CeedVector vec) { 744*0d0321e0SJeremy L Thompson int ierr; 745*0d0321e0SJeremy L Thompson Ceed ceed; 746*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 747*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 748*0d0321e0SJeremy L Thompson ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 749*0d0321e0SJeremy L Thompson 750*0d0321e0SJeremy L Thompson ierr = hipFree(impl->d_array_owned); CeedChk_Hip(ceed, ierr); 751*0d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_array_owned); CeedChkBackend(ierr); 752*0d0321e0SJeremy L Thompson ierr = CeedFree(&impl); CeedChkBackend(ierr); 753*0d0321e0SJeremy L Thompson 754*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 755*0d0321e0SJeremy L Thompson } 756*0d0321e0SJeremy L Thompson 757*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 758*0d0321e0SJeremy L Thompson // Create a vector of the specified length (does not allocate memory) 759*0d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 760*0d0321e0SJeremy L Thompson int CeedVectorCreate_Hip(CeedInt n, CeedVector vec) { 761*0d0321e0SJeremy L Thompson CeedVector_Hip *impl; 762*0d0321e0SJeremy L Thompson int ierr; 763*0d0321e0SJeremy L Thompson Ceed ceed; 764*0d0321e0SJeremy L Thompson ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 765*0d0321e0SJeremy L Thompson 766*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", 767*0d0321e0SJeremy L Thompson CeedVectorHasValidArray_Hip); CeedChkBackend(ierr); 768*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", 769*0d0321e0SJeremy L Thompson CeedVectorHasBorrowedArrayOfType_Hip); 770*0d0321e0SJeremy L Thompson CeedChkBackend(ierr); 771*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", 772*0d0321e0SJeremy L Thompson CeedVectorSetArray_Hip); CeedChkBackend(ierr); 773*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", 774*0d0321e0SJeremy L Thompson CeedVectorTakeArray_Hip); CeedChkBackend(ierr); 775*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "SetValue", 776*0d0321e0SJeremy L Thompson (int (*)())(CeedVectorSetValue_Hip)); CeedChkBackend(ierr); 777*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", 778*0d0321e0SJeremy L Thompson CeedVectorGetArray_Hip); CeedChkBackend(ierr); 779*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", 780*0d0321e0SJeremy L Thompson CeedVectorGetArrayRead_Hip); CeedChkBackend(ierr); 781*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", 782*0d0321e0SJeremy L Thompson CeedVectorGetArrayWrite_Hip); CeedChkBackend(ierr); 783*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArray", 784*0d0321e0SJeremy L Thompson CeedVectorRestoreArray_Hip); CeedChkBackend(ierr); 785*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArrayRead", 786*0d0321e0SJeremy L Thompson CeedVectorRestoreArrayRead_Hip); CeedChkBackend(ierr); 787*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Norm", 788*0d0321e0SJeremy L Thompson CeedVectorNorm_Hip); CeedChkBackend(ierr); 789*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Reciprocal", 790*0d0321e0SJeremy L Thompson CeedVectorReciprocal_Hip); CeedChkBackend(ierr); 791*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Scale", 792*0d0321e0SJeremy L Thompson (int (*)())(CeedVectorScale_Hip)); CeedChkBackend(ierr); 793*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "AXPY", 794*0d0321e0SJeremy L Thompson (int (*)())(CeedVectorAXPY_Hip)); CeedChkBackend(ierr); 795*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "PointwiseMult", 796*0d0321e0SJeremy L Thompson CeedVectorPointwiseMult_Hip); CeedChkBackend(ierr); 797*0d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", 798*0d0321e0SJeremy L Thompson CeedVectorDestroy_Hip); CeedChkBackend(ierr); 799*0d0321e0SJeremy L Thompson 800*0d0321e0SJeremy L Thompson ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr); 801*0d0321e0SJeremy L Thompson ierr = CeedVectorSetData(vec, impl); CeedChkBackend(ierr); 802*0d0321e0SJeremy L Thompson 803*0d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 804*0d0321e0SJeremy L Thompson } 805