/* ----------------------------------------------------------------------- Copyright (2010) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the Simplified BSD License. ----------------------------------------------------------------------- */ #ifndef HIP_MEMORY_H #define HIP_MEMORY_H #include #include #include #include #include "hip_macros.h" #include "hip_device.h" #include "ucl_types.h" namespace ucl_hip { // -------------------------------------------------------------------------- // - API Specific Types // -------------------------------------------------------------------------- //typedef dim3 ucl_kernel_dim; #ifdef __HIP_PLATFORM_NVCC__ typedef enum hipArray_Format { HIP_AD_FORMAT_UNSIGNED_INT8 = 0x01, HIP_AD_FORMAT_UNSIGNED_INT16 = 0x02, HIP_AD_FORMAT_UNSIGNED_INT32 = 0x03, HIP_AD_FORMAT_SIGNED_INT8 = 0x08, HIP_AD_FORMAT_SIGNED_INT16 = 0x09, HIP_AD_FORMAT_SIGNED_INT32 = 0x0a, HIP_AD_FORMAT_HALF = 0x10, HIP_AD_FORMAT_FLOAT = 0x20 }hipArray_Format; #endif // -------------------------------------------------------------------------- // - API SPECIFIC DEVICE POINTERS // -------------------------------------------------------------------------- typedef hipDeviceptr_t device_ptr; // -------------------------------------------------------------------------- // - HOST MEMORY ALLOCATION ROUTINES // -------------------------------------------------------------------------- template inline int _host_alloc(mat_type &mat, copy_type &cm, const size_t n, const enum UCL_MEMOPT kind, const enum UCL_MEMOPT kind2){ hipError_t err=hipSuccess; if (kind==UCL_NOT_PINNED) *(mat.host_ptr())=(typename mat_type::data_type*)malloc(n); else if (kind==UCL_WRITE_ONLY) err=hipHostMalloc((void **)mat.host_ptr(),n,hipHostMallocWriteCombined); else err=hipHostMalloc((void **)mat.host_ptr(),n,hipHostMallocDefault); if (err!=hipSuccess || *(mat.host_ptr())==nullptr) return UCL_MEMORY_ERROR; mat.cq()=cm.cq(); return UCL_SUCCESS; } template inline int _host_alloc(mat_type &mat, UCL_Device &dev, const size_t n, const enum UCL_MEMOPT kind, const enum UCL_MEMOPT kind2){ hipError_t err=hipSuccess; if (kind==UCL_NOT_PINNED) *(mat.host_ptr())=(typename mat_type::data_type*)malloc(n); else if (kind==UCL_WRITE_ONLY) err=hipHostMalloc((void **)mat.host_ptr(),n,hipHostMallocWriteCombined); else err=hipHostMalloc((void **)mat.host_ptr(),n,hipHostMallocDefault); if (err!=hipSuccess || *(mat.host_ptr())==nullptr) return UCL_MEMORY_ERROR; mat.cq()=dev.cq(); return UCL_SUCCESS; } template inline void _host_free(mat_type &mat) { if (mat.kind()==UCL_VIEW) return; else if (mat.kind()!=UCL_NOT_PINNED) CU_DESTRUCT_CALL(hipHostFree(mat.begin())); else free(mat.begin()); } template inline int _host_resize(mat_type &mat, const size_t n) { _host_free(mat); hipError_t err=hipSuccess; if (mat.kind()==UCL_NOT_PINNED) *(mat.host_ptr())=(typename mat_type::data_type*)malloc(n); else if (mat.kind()==UCL_WRITE_ONLY) err=hipHostMalloc((void **)mat.host_ptr(),n,hipHostMallocWriteCombined); else err=hipHostMalloc((void **)mat.host_ptr(),n,hipHostMallocDefault); if (err!=hipSuccess || *(mat.host_ptr())==nullptr) return UCL_MEMORY_ERROR; return UCL_SUCCESS; } // -------------------------------------------------------------------------- // - DEVICE MEMORY ALLOCATION ROUTINES // -------------------------------------------------------------------------- template inline int _device_alloc(mat_type &mat, copy_type &cm, const size_t n, const enum UCL_MEMOPT kind) { hipError_t err=hipMalloc((void**)&mat.cbegin(),n); if (err!=hipSuccess) return UCL_MEMORY_ERROR; mat.cq()=cm.cq(); return UCL_SUCCESS; } template inline int _device_alloc(mat_type &mat, UCL_Device &dev, const size_t n, const enum UCL_MEMOPT kind) { hipError_t err=hipMalloc((void**)&mat.cbegin(),n); if (err!=hipSuccess) return UCL_MEMORY_ERROR; mat.cq()=dev.cq(); return UCL_SUCCESS; } template inline int _device_alloc(mat_type &mat, copy_type &cm, const size_t rows, const size_t cols, size_t &pitch, const enum UCL_MEMOPT kind) { hipError_t err; size_t upitch; err=hipMallocPitch((void**)&mat.cbegin(),&upitch, cols*sizeof(typename mat_type::data_type),rows); pitch=static_cast(upitch); if (err!=hipSuccess) return UCL_MEMORY_ERROR; mat.cq()=cm.cq(); return UCL_SUCCESS; } template inline int _device_alloc(mat_type &mat, UCL_Device &d, const size_t rows, const size_t cols, size_t &pitch, const enum UCL_MEMOPT kind) { hipError_t err; size_t upitch; err=hipMallocPitch((void**)&mat.cbegin(),&upitch, cols*sizeof(typename mat_type::data_type),rows); pitch=static_cast(upitch); if (err!=hipSuccess) return UCL_MEMORY_ERROR; mat.cq()=d.cq(); return UCL_SUCCESS; } template inline void _device_free(mat_type &mat) { if (mat.kind()!=UCL_VIEW){ CU_DESTRUCT_CALL(hipFree((void*)mat.cbegin())); } } template inline int _device_resize(mat_type &mat, const size_t n) { _device_free(mat); hipError_t err=hipMalloc((void**)&mat.cbegin(),n); if (err!=hipSuccess) return UCL_MEMORY_ERROR; return UCL_SUCCESS; } template inline int _device_resize(mat_type &mat, const size_t rows, const size_t cols, size_t &pitch) { _device_free(mat); hipError_t err; size_t upitch; err=hipMallocPitch((void**)&mat.cbegin(),&upitch, cols*sizeof(typename mat_type::data_type),rows); pitch=static_cast(upitch); if (err!=hipSuccess) return UCL_MEMORY_ERROR; return UCL_SUCCESS; } inline void _device_view(hipDeviceptr_t *ptr, hipDeviceptr_t &in) { *ptr=in; } template inline void _device_view(hipDeviceptr_t *ptr, numtyp *in) { *ptr=0; } inline void _device_view(hipDeviceptr_t *ptr, hipDeviceptr_t &in, const size_t offset, const size_t numsize) { *ptr=(hipDeviceptr_t)(((char*)in)+offset*numsize); } template inline void _device_view(hipDeviceptr_t *ptr, numtyp *in, const size_t offset, const size_t numsize) { *ptr=0; } // -------------------------------------------------------------------------- // - DEVICE IMAGE ALLOCATION ROUTINES // -------------------------------------------------------------------------- template inline void _device_image_alloc(mat_type &mat, copy_type &cm, const size_t rows, const size_t cols) { assert(0==1); } template inline void _device_image_alloc(mat_type &mat, UCL_Device &d, const size_t rows, const size_t cols) { assert(0==1); } template inline void _device_image_free(mat_type &mat) { assert(0==1); } // -------------------------------------------------------------------------- // - ZERO ROUTINES // -------------------------------------------------------------------------- inline void _host_zero(void *ptr, const size_t n) { memset(ptr,0,n); } template inline void _device_zero(mat_type &mat, const size_t n, command_queue &cq) { CU_SAFE_CALL(hipMemsetAsync((void*)mat.cbegin(),0,n,cq)); } // -------------------------------------------------------------------------- // - MEMCPY ROUTINES // -------------------------------------------------------------------------- template hipMemcpyKind _memcpy_kind(mat1 &dst, const mat2 &src){ assert(mat1::MEM_TYPE < 2 && mat2::MEM_TYPE < 2); return (hipMemcpyKind)((1 - mat2::MEM_TYPE)*2 + (1 - mat1::MEM_TYPE)); } template inline void ucl_mv_cpy(mat1 &dst, const mat2 &src, const size_t n) { CU_SAFE_CALL(hipMemcpy((void*)dst.begin(), (void*)src.begin(), n, _memcpy_kind(dst, src))); } template inline void ucl_mv_cpy(mat1 &dst, const mat2 &src, const size_t n, hipStream_t &cq) { CU_SAFE_CALL(hipMemcpyAsync((void*)dst.begin(), (void*)src.begin(), n, _memcpy_kind(dst, src), cq)); } template inline void ucl_mv_cpy(mat1 &dst, const size_t dpitch, const mat2 &src, const size_t spitch, const size_t cols, const size_t rows) { CU_SAFE_CALL(hipMemcpy2D((void*)dst.begin(), dpitch, (void*)src.begin(), spitch, cols, rows, _memcpy_kind(dst, src))); } template inline void ucl_mv_cpy(mat1 &dst, const size_t dpitch, const mat2 &src, const size_t spitch, const size_t cols, const size_t rows,hipStream_t &cq) { CU_SAFE_CALL(hipMemcpy2DAsync((void*)dst.begin(), dpitch, (void*)src.begin(), spitch, cols, rows, _memcpy_kind(dst, src), cq)); } } // namespace ucl_cudart #endif