| 668 | //sparse matrix wrapper on device: COO format |
| 669 | template <typename T> |
| 670 | class DeviceSpMatCOO { |
| 671 | public: |
| 672 | size_s gpu_id = 0; |
| 673 | size_s row_size = 0; |
| 674 | size_s col_size = 0; |
| 675 | size_l nnz = 0; |
| 676 | int* col_ids = nullptr; |
| 677 | int* row_ids = nullptr; |
| 678 | T* vals = nullptr; |
| 679 | cusparseSpMatDescr_t cusparse_descr = nullptr; |
| 680 | |
| 681 | DeviceSpMatCOO(){} |
| 682 | DeviceSpMatCOO(const size_s gpu_id, const size_s row_size, const size_s col_size, const size_l nnz): |
| 683 | gpu_id(gpu_id), row_size(row_size), col_size(col_size), nnz(nnz), |
| 684 | col_ids(nullptr), row_ids(nullptr), vals(nullptr), cusparse_descr(NULL) { |
| 685 | this->allocate(); |
| 686 | } |
| 687 | |
| 688 | inline void allocate() { |
| 689 | if (this->vals == nullptr) { |
| 690 | CHECK_CUDA( cudaSetDevice(this->gpu_id) ); |
| 691 | CHECK_CUDA( cudaSetDevice(this->gpu_id) ); |
| 692 | |
| 693 | if (nnz > 0) { |
| 694 | CHECK_CUDA( cudaMalloc((void**) &this->row_ids, sizeof(int) * this->nnz) ); |
| 695 | CHECK_CUDA( cudaMalloc((void**) &this->col_ids, sizeof(int) * this->nnz) ); |
| 696 | CHECK_CUDA( cudaMalloc((void**) &this->vals, sizeof(T) * this->nnz) ); |
| 697 | } else { |
| 698 | this->row_ids = nullptr; |
| 699 | this->col_ids = nullptr; |
| 700 | this->vals = nullptr; |
| 701 | } |
| 702 | CHECK_CUSPARSE( cusparseCreateCoo( |
| 703 | &this->cusparse_descr, this->row_size, this->col_size, this->nnz, |
| 704 | this->row_ids, this->col_ids, this->vals, |
| 705 | CUSPARSE_INDEX_32I, CUSPARSE_INDEX_BASE_ZERO, CudaTypeMapper<T>::value |
| 706 | ) ); |
| 707 | } |
| 708 | } |
| 709 | |
| 710 | void SynchronizeHostToDevice(int* host_col_ids, int* host_row_ids, T* host_val){ |
| 711 | // always Synchronize to avoid read-write conflict |
| 712 | CHECK_CUDA(cudaDeviceSynchronize()); |
| 713 | CHECK_CUDA(cudaMemcpyAsync(col_ids, host_col_ids, sizeof(int) * this->nnz, cudaMemcpyHostToDevice)); |
| 714 | CHECK_CUDA(cudaMemcpyAsync(row_ids, host_row_ids, sizeof(int) * this->nnz, cudaMemcpyHostToDevice)); |
| 715 | CHECK_CUDA(cudaMemcpyAsync(vals, host_val, sizeof(T) * nnz, cudaMemcpyHostToDevice)); |
| 716 | CHECK_CUDA(cudaDeviceSynchronize()); |
| 717 | } |
| 718 | |
| 719 | inline double get_norm(const DeviceBlasHandle& cublas_H) { |
| 720 | double norm; |
| 721 | CHECK_CUDA( cudaSetDevice(this->gpu_id) ); |
| 722 | CHECK_CUBLAS( cublasDnrm2_v2( |
| 723 | cublas_H.cublas_handle, this->nnz, this->vals, 1, &norm |
| 724 | ) ); |
| 725 | return norm; |
| 726 | } |
| 727 |
nothing calls this directly
no outgoing calls
no test coverage detected