| 579 | //sparse matrix wrapper on device: CSC format |
| 580 | template <typename T> |
| 581 | class DeviceSpMatCSR { |
| 582 | public: |
| 583 | size_s gpu_id = 0; |
| 584 | size_s row_size = 0; |
| 585 | size_s col_size = 0; |
| 586 | size_l nnz = 0; |
| 587 | int* col_ids = nullptr; |
| 588 | int* row_ptrs = nullptr; |
| 589 | T* vals = nullptr; |
| 590 | cusparseSpMatDescr_t cusparse_descr = nullptr; |
| 591 | |
| 592 | DeviceSpMatCSR(){} |
| 593 | DeviceSpMatCSR(const size_s gpu_id, const size_s row_size, const size_s col_size, const size_l nnz): |
| 594 | gpu_id(gpu_id), row_size(row_size), col_size(col_size), nnz(nnz), |
| 595 | col_ids(nullptr), row_ptrs(nullptr), vals(nullptr), cusparse_descr(NULL) { |
| 596 | this->allocate(); |
| 597 | } |
| 598 | |
| 599 | inline void allocate() { |
| 600 | if (this->vals == nullptr) { |
| 601 | CHECK_CUDA( cudaSetDevice(this->gpu_id) ); |
| 602 | CHECK_CUDA( cudaSetDevice(this->gpu_id) ); |
| 603 | CHECK_CUDA( cudaMalloc((void**) &this->row_ptrs, sizeof(int) * (this->row_size + 1)) ); |
| 604 | if (nnz > 0) { |
| 605 | CHECK_CUDA( cudaMalloc((void**) &this->col_ids, sizeof(int) * this->nnz) ); |
| 606 | CHECK_CUDA( cudaMalloc((void**) &this->vals, sizeof(T) * this->nnz) ); |
| 607 | } else { |
| 608 | this->col_ids = nullptr; |
| 609 | this->vals = nullptr; |
| 610 | } |
| 611 | CHECK_CUSPARSE( cusparseCreateCsr( |
| 612 | &this->cusparse_descr, this->row_size, this->col_size, this->nnz, |
| 613 | this->row_ptrs, this->col_ids, this->vals, |
| 614 | CUSPARSE_INDEX_32I, CUSPARSE_INDEX_32I, CUSPARSE_INDEX_BASE_ZERO, CudaTypeMapper<T>::value |
| 615 | ) ); |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | void SynchronizeHostToDevice(int* host_col_ids, int* host_row_ptrs, T* host_val){ |
| 620 | // always Synchronize to avoid read-write conflict |
| 621 | CHECK_CUDA(cudaDeviceSynchronize()); |
| 622 | CHECK_CUDA(cudaMemcpyAsync(col_ids, host_col_ids, sizeof(int) * this->nnz, cudaMemcpyHostToDevice)); |
| 623 | CHECK_CUDA(cudaMemcpyAsync(row_ptrs, host_row_ptrs, sizeof(int) * (this->row_size+1), cudaMemcpyHostToDevice)); |
| 624 | CHECK_CUDA(cudaMemcpyAsync(vals, host_val, sizeof(T) * this->nnz, cudaMemcpyHostToDevice)); |
| 625 | CHECK_CUDA(cudaDeviceSynchronize()); |
| 626 | } |
| 627 | |
| 628 | void SynchronizeDeviceToDevice(int* device_col_ids, int* device_row_ptrs, T* device_val){ |
| 629 | // always Synchronize to avoid read-write conflict |
| 630 | CHECK_CUDA(cudaDeviceSynchronize()); |
| 631 | CHECK_CUDA(cudaMemcpyAsync(col_ids, device_col_ids, sizeof(int) * this->nnz, cudaMemcpyDeviceToDevice)); |
| 632 | CHECK_CUDA(cudaMemcpyAsync(row_ptrs, device_row_ptrs, sizeof(int) * (this->row_size+1), cudaMemcpyDeviceToDevice)); |
| 633 | CHECK_CUDA(cudaMemcpyAsync(vals, device_val, sizeof(T) * this->nnz, cudaMemcpyDeviceToDevice)); |
| 634 | CHECK_CUDA(cudaDeviceSynchronize()); |
| 635 | } |
| 636 | |
| 637 | inline double get_norm(const DeviceBlasHandle& cublas_H) { |
| 638 | double norm; |
nothing calls this directly
no outgoing calls
no test coverage detected