/* Parallel Sparse BLAS GPU plugin */ /* (C) Copyright 2013 */ /* Salvatore Filippone */ /* Alessandro Fanfarillo */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* 1. Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* 2. Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions, and the following disclaimer in the */ /* documentation and/or other materials provided with the distribution. */ /* 3. The name of the PSBLAS group or the names of its contributors may */ /* not be used to endorse or promote products derived from this */ /* software without specific written permission. */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */ /* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ /* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS */ /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */ /* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ /* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ /* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN */ /* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) */ /* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ /* POSSIBILITY OF SUCH DAMAGE. */ typedef struct T_CSRGDeviceMat { #if CUDA_SHORT_VERSION <= 10 cusparseMatDescr_t descr; cusparseSolveAnalysisInfo_t triang; #elif CUDA_VERSION < 11030 cusparseMatDescr_t descr; csrsv2Info_t triang; size_t mvbsize, svbsize; void *mvbuffer, *svbuffer; #else cusparseSpMatDescr_t descr; cusparseSpSVDescr_t *spsvDescr; size_t mvbsize, svbsize; void *mvbuffer, *svbuffer; #endif int m, n, nz; TYPE *val; int *irp; int *ja; } T_CSRGDeviceMat; /* Interoperability: type coming from Fortran side to distinguish D/S/C/Z. */ typedef struct T_Cmat { T_CSRGDeviceMat *mat; } T_Cmat; #if CUDA_SHORT_VERSION <= 10 typedef struct T_HYBGDeviceMat { cusparseMatDescr_t descr; cusparseSolveAnalysisInfo_t triang; cusparseHybMat_t hybA; int m, n, nz; TYPE *val; int *irp; int *ja; } T_HYBGDeviceMat; /* Interoperability: type coming from Fortran side to distinguish D/S/C/Z. */ typedef struct T_Hmat { T_HYBGDeviceMat *mat; } T_Hmat; #endif int T_spmvCSRGDevice(T_Cmat *Mat, TYPE alpha, void *deviceX, TYPE beta, void *deviceY); int T_spsvCSRGDevice(T_Cmat *Mat, TYPE alpha, void *deviceX, TYPE beta, void *deviceY); int T_CSRGDeviceAlloc(T_Cmat *Mat,int nr, int nc, int nz); int T_CSRGDeviceFree(T_Cmat *Mat); int T_CSRGHost2Device(T_Cmat *Mat, int m, int n, int nz, int *irp, int *ja, TYPE *val); int T_CSRGDevice2Host(T_Cmat *Mat, int m, int n, int nz, int *irp, int *ja, TYPE *val); int T_CSRGDeviceGetParms(T_Cmat *Mat,int *nr, int *nc, int *nz); #if CUDA_SHORT_VERSION <= 10 int T_CSRGDeviceSetMatType(T_Cmat *Mat, int type); int T_CSRGDeviceSetMatFillMode(T_Cmat *Mat, int type); int T_CSRGDeviceSetMatDiagType(T_Cmat *Mat, int type); int T_CSRGDeviceSetMatIndexBase(T_Cmat *Mat, int type); int T_CSRGDeviceCsrsmAnalysis(T_Cmat *Mat); #elif CUDA_VERSION < 11030 int T_CSRGDeviceSetMatType(T_Cmat *Mat, int type); int T_CSRGDeviceSetMatFillMode(T_Cmat *Mat, int type); int T_CSRGDeviceSetMatDiagType(T_Cmat *Mat, int type); int T_CSRGDeviceSetMatIndexBase(T_Cmat *Mat, int type); #endif #if CUDA_SHORT_VERSION <= 10 int T_HYBGDeviceFree(T_Hmat *Matrix); int T_spmvHYBGDevice(T_Hmat *Matrix, TYPE alpha, void *deviceX, TYPE beta, void *deviceY); int T_HYBGDeviceAlloc(T_Hmat *Matrix,int nr, int nc, int nz); int T_HYBGDeviceSetMatDiagType(T_Hmat *Matrix, int type); int T_HYBGDeviceSetMatIndexBase(T_Hmat *Matrix, int type); int T_HYBGDeviceSetMatType(T_Hmat *Matrix, int type); int T_HYBGDeviceSetMatFillMode(T_Hmat *Matrix, int type); int T_HYBGDeviceHybsmAnalysis(T_Hmat *Matrix); int T_spsvHYBGDevice(T_Hmat *Matrix, TYPE alpha, void *deviceX, TYPE beta, void *deviceY); int T_HYBGHost2Device(T_Hmat *Matrix, int m, int n, int nz, int *irp, int *ja, TYPE *val); #endif int T_spmvCSRGDevice(T_Cmat *Matrix, TYPE alpha, void *deviceX, TYPE beta, void *deviceY) { T_CSRGDeviceMat *cMat=Matrix->mat; struct MultiVectDevice *x = (struct MultiVectDevice *) deviceX; struct MultiVectDevice *y = (struct MultiVectDevice *) deviceY; void *vX, *vY; int r,n; cusparseHandle_t *my_handle=getHandle(); TYPE ealpha=alpha, ebeta=beta; #if CUDA_SHORT_VERSION <= 10 /*getAddrMultiVecDevice(deviceX, &vX); getAddrMultiVecDevice(deviceY, &vY); */ vX=x->v_; vY=y->v_; return cusparseTcsrmv(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,cMat->n,cMat->nz,(const TYPE *) &alpha,cMat->descr, cMat->val, cMat->irp, cMat->ja, (const TYPE *) vX, (const TYPE *) &beta, (TYPE *) vY); #elif CUDA_VERSION < 11030 size_t bfsz; vX=x->v_; vY=y->v_; #if 1 CHECK_CUSPARSE(cusparseCsrmvEx_bufferSize(*my_handle,CUSPARSE_ALG_MERGE_PATH, CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,cMat->n,cMat->nz, (const void *) &ealpha,CUSPARSE_BASE_TYPE, cMat->descr, (const void *) cMat->val, CUSPARSE_BASE_TYPE, (const int *) cMat->irp, (const int *) cMat->ja, (const void *) vX, CUSPARSE_BASE_TYPE, (const void *) &ebeta, CUSPARSE_BASE_TYPE, (void *) vY, CUSPARSE_BASE_TYPE, CUSPARSE_BASE_TYPE, &bfsz)); #else bfsz=cMat->nz; #endif if (bfsz > cMat->mvbsize) { if (cMat->mvbuffer != NULL) { CHECK_CUDA(cudaFree(cMat->mvbuffer)); cMat->mvbuffer = NULL; } CHECK_CUDA(cudaMalloc((void **) &(cMat->mvbuffer), bfsz)); cMat->mvbsize = bfsz; } CHECK_CUSPARSE(cusparseCsrmvEx(*my_handle, CUSPARSE_ALG_MERGE_PATH, CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,cMat->n,cMat->nz, (const void *) &ealpha,CUSPARSE_BASE_TYPE, cMat->descr, (const void *) cMat->val, CUSPARSE_BASE_TYPE, (const int *) cMat->irp, (const int *) cMat->ja, (const void *) vX, CUSPARSE_BASE_TYPE, (const void *) &ebeta, CUSPARSE_BASE_TYPE, (void *) vY, CUSPARSE_BASE_TYPE, CUSPARSE_BASE_TYPE, (void *) cMat->mvbuffer)); #else cusparseDnVecDescr_t vecX, vecY; size_t bfsz; vX=x->v_; vY=y->v_; CHECK_CUSPARSE( cusparseCreateDnVec(&vecY, cMat->m, vY, CUSPARSE_BASE_TYPE) ); CHECK_CUSPARSE( cusparseCreateDnVec(&vecX, cMat->n, vX, CUSPARSE_BASE_TYPE) ); CHECK_CUSPARSE(cusparseSpMV_bufferSize(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, &alpha,cMat->descr,vecX,&beta,vecY, CUSPARSE_BASE_TYPE,CUSPARSE_SPMV_ALG_DEFAULT, &bfsz)); if (bfsz > cMat->mvbsize) { if (cMat->mvbuffer != NULL) { CHECK_CUDA(cudaFree(cMat->mvbuffer)); cMat->mvbuffer = NULL; } CHECK_CUDA(cudaMalloc((void **) &(cMat->mvbuffer), bfsz)); cMat->mvbsize = bfsz; } CHECK_CUSPARSE(cusparseSpMV(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, &alpha,cMat->descr,vecX,&beta,vecY, CUSPARSE_BASE_TYPE,CUSPARSE_SPMV_ALG_DEFAULT, cMat->mvbuffer)); CHECK_CUSPARSE(cusparseDestroyDnVec(vecX) ); CHECK_CUSPARSE(cusparseDestroyDnVec(vecY) ); #endif } int T_spsvCSRGDevice(T_Cmat *Matrix, TYPE alpha, void *deviceX, TYPE beta, void *deviceY) { T_CSRGDeviceMat *cMat=Matrix->mat; struct MultiVectDevice *x = (struct MultiVectDevice *) deviceX; struct MultiVectDevice *y = (struct MultiVectDevice *) deviceY; void *vX, *vY; int r,n; cusparseHandle_t *my_handle=getHandle(); #if CUDA_SHORT_VERSION <= 10 vX=x->v_; vY=y->v_; return cusparseTcsrsv_solve(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,(const TYPE *) &alpha,cMat->descr, cMat->val, cMat->irp, cMat->ja, cMat->triang, (const TYPE *) vX, (TYPE *) vY); #elif CUDA_VERSION < 11030 vX=x->v_; vY=y->v_; CHECK_CUSPARSE(cusparseTcsrsv2_solve(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,cMat->nz, (const TYPE *) &alpha, cMat->descr, cMat->val, cMat->irp, cMat->ja, cMat->triang, (const TYPE *) vX, (TYPE *) vY, CUSPARSE_SOLVE_POLICY_USE_LEVEL, (void *) cMat->svbuffer)); #else cusparseDnVecDescr_t vecX, vecY; size_t bfsz; vX=x->v_; vY=y->v_; cMat->spsvDescr=(cusparseSpSVDescr_t *) malloc(sizeof(cusparseSpSVDescr_t *)); CHECK_CUSPARSE( cusparseCreateDnVec(&vecY, cMat->m, vY, CUSPARSE_BASE_TYPE) ); CHECK_CUSPARSE( cusparseCreateDnVec(&vecX, cMat->n, vX, CUSPARSE_BASE_TYPE) ); CHECK_CUSPARSE(cusparseSpSV_bufferSize(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, &alpha,cMat->descr,vecX,vecY, CUSPARSE_BASE_TYPE, CUSPARSE_SPSV_ALG_DEFAULT, *(cMat->spsvDescr), &bfsz)); if (bfsz > cMat->svbsize) { if (cMat->svbuffer != NULL) { CHECK_CUDA(cudaFree(cMat->svbuffer)); cMat->svbuffer = NULL; } CHECK_CUDA(cudaMalloc((void **) &(cMat->svbuffer), bfsz)); cMat->svbsize=bfsz; } if (cMat->spsvDescr==NULL) { CHECK_CUSPARSE(cusparseSpSV_analysis(*my_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, &alpha, cMat->descr, vecX, vecY, CUSPARSE_BASE_TYPE, CUSPARSE_SPSV_ALG_DEFAULT, *(cMat->spsvDescr), cMat->svbuffer)); } CHECK_CUSPARSE(cusparseSpSV_solve(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, &alpha,cMat->descr,vecX,vecY, CUSPARSE_BASE_TYPE, CUSPARSE_SPSV_ALG_DEFAULT, *(cMat->spsvDescr))); CHECK_CUSPARSE(cusparseDestroyDnVec(vecX) ); CHECK_CUSPARSE(cusparseDestroyDnVec(vecY) ); #endif } int T_CSRGDeviceAlloc(T_Cmat *Matrix,int nr, int nc, int nz) { T_CSRGDeviceMat *cMat; int nr1=nr, nz1=nz, rc; cusparseHandle_t *my_handle=getHandle(); int bfsz; if ((nr<0)||(nc<0)||(nz<0)) return((int) CUSPARSE_STATUS_INVALID_VALUE); if ((cMat=(T_CSRGDeviceMat *) malloc(sizeof(T_CSRGDeviceMat)))==NULL) return((int) CUSPARSE_STATUS_ALLOC_FAILED); cMat->m = nr; cMat->n = nc; cMat->nz = nz; if (nr1 == 0) nr1 = 1; if (nz1 == 0) nz1 = 1; if ((rc= allocRemoteBuffer(((void **) &(cMat->irp)), ((nr1+1)*sizeof(int)))) != 0) return(rc); if ((rc= allocRemoteBuffer(((void **) &(cMat->ja)), ((nz1)*sizeof(int)))) != 0) return(rc); if ((rc= allocRemoteBuffer(((void **) &(cMat->val)), ((nz1)*sizeof(TYPE)))) != 0) return(rc); #if CUDA_SHORT_VERSION <= 10 if ((rc= cusparseCreateMatDescr(&(cMat->descr))) !=0) return(rc); if ((rc= cusparseCreateSolveAnalysisInfo(&(cMat->triang))) !=0) return(rc); #elif CUDA_VERSION < 11030 if ((rc= cusparseCreateMatDescr(&(cMat->descr))) !=0) return(rc); CHECK_CUSPARSE(cusparseSetMatType(cMat->descr,CUSPARSE_MATRIX_TYPE_GENERAL)); CHECK_CUSPARSE(cusparseSetMatDiagType(cMat->descr,CUSPARSE_DIAG_TYPE_NON_UNIT)); CHECK_CUSPARSE(cusparseSetMatIndexBase(cMat->descr,CUSPARSE_INDEX_BASE_ONE)); CHECK_CUSPARSE(cusparseCreateCsrsv2Info(&(cMat->triang))); if (cMat->nz > 0) { CHECK_CUSPARSE(cusparseTcsrsv2_bufferSize(*my_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,cMat->nz, cMat->descr, cMat->val, cMat->irp, cMat->ja, cMat->triang, &bfsz)); } else { bfsz = 0; } /* if (cMat->svbuffer != NULL) { */ /* fprintf(stderr,"Calling cudaFree\n"); */ /* CHECK_CUDA(cudaFree(cMat->svbuffer)); */ /* cMat->svbuffer = NULL; */ /* } */ if (bfsz > 0) { CHECK_CUDA(cudaMalloc((void **) &(cMat->svbuffer), bfsz)); } else { cMat->svbuffer=NULL; } cMat->svbsize=bfsz; cMat->mvbuffer=NULL; cMat->mvbsize = 0; #else int64_t rows=nr, cols=nc, nnz=nz; CHECK_CUSPARSE(cusparseCreateCsr(&(cMat->descr), rows, cols, nnz, (void *) cMat->irp, (void *) cMat->ja, (void *) cMat->val, CUSPARSE_INDEX_32I, CUSPARSE_INDEX_32I, CUSPARSE_INDEX_BASE_ONE, CUSPARSE_BASE_TYPE) ); cMat->spsvDescr=NULL; cMat->mvbuffer=NULL; cMat->svbuffer=NULL; cMat->mvbsize=0; cMat->svbsize=0; #endif Matrix->mat = cMat; return(CUSPARSE_STATUS_SUCCESS); } int T_CSRGDeviceFree(T_Cmat *Matrix) { T_CSRGDeviceMat *cMat= Matrix->mat; if (cMat!=NULL) { freeRemoteBuffer(cMat->irp); freeRemoteBuffer(cMat->ja); freeRemoteBuffer(cMat->val); #if CUDA_SHORT_VERSION <= 10 cusparseDestroyMatDescr(cMat->descr); cusparseDestroySolveAnalysisInfo(cMat->triang); #elif CUDA_VERSION < 11030 cusparseDestroyMatDescr(cMat->descr); cusparseDestroyCsrsv2Info(cMat->triang); #else cusparseDestroySpMat(cMat->descr); if (cMat->spsvDescr!=NULL) { CHECK_CUSPARSE( cusparseSpSV_destroyDescr(*(cMat->spsvDescr))); free(cMat->spsvDescr); cMat->spsvDescr=NULL; } if (cMat->mvbuffer!=NULL) CHECK_CUDA( cudaFree(cMat->mvbuffer)); if (cMat->svbuffer!=NULL) CHECK_CUDA( cudaFree(cMat->svbuffer)); cMat->spsvDescr=NULL; cMat->mvbuffer=NULL; cMat->svbuffer=NULL; cMat->mvbsize=0; cMat->svbsize=0; #endif free(cMat); Matrix->mat = NULL; } return(CUSPARSE_STATUS_SUCCESS); } int T_CSRGDeviceGetParms(T_Cmat *Matrix,int *nr, int *nc, int *nz) { T_CSRGDeviceMat *cMat= Matrix->mat; if (cMat!=NULL) { *nr = cMat->m ; *nc = cMat->n ; *nz = cMat->nz ; return(CUSPARSE_STATUS_SUCCESS); } else { return((int) CUSPARSE_STATUS_ALLOC_FAILED); } } #if CUDA_SHORT_VERSION <= 10 int T_CSRGDeviceSetMatType(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatType(cMat->descr,type)); } int T_CSRGDeviceSetMatFillMode(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatFillMode(cMat->descr,type)); } int T_CSRGDeviceSetMatDiagType(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatDiagType(cMat->descr,type)); } int T_CSRGDeviceSetMatIndexBase(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatIndexBase(cMat->descr,type)); } int T_CSRGDeviceCsrsmAnalysis(T_Cmat *Matrix) { T_CSRGDeviceMat *cMat= Matrix->mat; int rc, buffersize; cusparseHandle_t *my_handle=getHandle(); cusparseSolveAnalysisInfo_t info; rc= (int) cusparseTcsrsv_analysis(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,cMat->nz,cMat->descr, cMat->val, cMat->irp, cMat->ja, cMat->triang); if (rc !=0) { fprintf(stderr,"From csrsv_analysis: %d\n",rc); } return(rc); } #elif CUDA_VERSION < 11030 int T_CSRGDeviceSetMatType(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatType(cMat->descr,type)); } int T_CSRGDeviceSetMatFillMode(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatFillMode(cMat->descr,type)); } int T_CSRGDeviceSetMatDiagType(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatDiagType(cMat->descr,type)); } int T_CSRGDeviceSetMatIndexBase(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; return ((int) cusparseSetMatIndexBase(cMat->descr,type)); } #else int T_CSRGDeviceSetMatFillMode(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; cusparseFillMode_t mode=type; CHECK_CUSPARSE(cusparseSpMatSetAttribute(cMat->descr, CUSPARSE_SPMAT_FILL_MODE, (const void*) &mode, sizeof(cusparseFillMode_t))); return(0); } int T_CSRGDeviceSetMatDiagType(T_Cmat *Matrix, int type) { T_CSRGDeviceMat *cMat= Matrix->mat; cusparseDiagType_t cutype=type; CHECK_CUSPARSE(cusparseSpMatSetAttribute(cMat->descr, CUSPARSE_SPMAT_DIAG_TYPE, (const void*) &cutype, sizeof(cusparseDiagType_t))); return(0); } #endif int T_CSRGHost2Device(T_Cmat *Matrix, int m, int n, int nz, int *irp, int *ja, TYPE *val) { int rc; T_CSRGDeviceMat *cMat= Matrix->mat; cusparseHandle_t *my_handle=getHandle(); if ((rc=writeRemoteBuffer((void *) irp, (void *) cMat->irp, (m+1)*sizeof(int))) != SPGPU_SUCCESS) return(rc); if ((rc=writeRemoteBuffer((void *) ja,(void *) cMat->ja, (nz)*sizeof(int))) != SPGPU_SUCCESS) return(rc); if ((rc=writeRemoteBuffer((void *) val, (void *) cMat->val, (nz)*sizeof(TYPE))) != SPGPU_SUCCESS) return(rc); #if (CUDA_SHORT_VERSION > 10 ) && (CUDA_VERSION < 11030) if (cusparseGetMatType(cMat->descr)== CUSPARSE_MATRIX_TYPE_TRIANGULAR) { // Why do we need to set TYPE_GENERAL??? cuSPARSE can be misterious sometimes. cusparseSetMatType(cMat->descr,CUSPARSE_MATRIX_TYPE_GENERAL); CHECK_CUSPARSE(cusparseTcsrsv2_analysis(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, cMat->m,cMat->nz, cMat->descr, cMat->val, cMat->irp, cMat->ja, cMat->triang, CUSPARSE_SOLVE_POLICY_USE_LEVEL, cMat->svbuffer)); } #endif return(CUSPARSE_STATUS_SUCCESS); } int T_CSRGDevice2Host(T_Cmat *Matrix, int m, int n, int nz, int *irp, int *ja, TYPE *val) { int rc; T_CSRGDeviceMat *cMat = Matrix->mat; if ((rc=readRemoteBuffer((void *) irp, (void *) cMat->irp, (m+1)*sizeof(int))) != SPGPU_SUCCESS) return(rc); if ((rc=readRemoteBuffer((void *) ja, (void *) cMat->ja, (nz)*sizeof(int))) != SPGPU_SUCCESS) return(rc); if ((rc=readRemoteBuffer((void *) val, (void *) cMat->val, (nz)*sizeof(TYPE))) != SPGPU_SUCCESS) return(rc); return(CUSPARSE_STATUS_SUCCESS); } #if CUDA_SHORT_VERSION <= 10 int T_HYBGDeviceFree(T_Hmat *Matrix) { T_HYBGDeviceMat *hMat= Matrix->mat; if (hMat != NULL) { cusparseDestroyMatDescr(hMat->descr); cusparseDestroySolveAnalysisInfo(hMat->triang); cusparseDestroyHybMat(hMat->hybA); free(hMat); } Matrix->mat = NULL; return(CUSPARSE_STATUS_SUCCESS); } int T_spmvHYBGDevice(T_Hmat *Matrix, TYPE alpha, void *deviceX, TYPE beta, void *deviceY) { T_HYBGDeviceMat *hMat=Matrix->mat; struct MultiVectDevice *x = (struct MultiVectDevice *) deviceX; struct MultiVectDevice *y = (struct MultiVectDevice *) deviceY; void *vX, *vY; int r,n,rc; cusparseMatrixType_t type; cusparseHandle_t *my_handle=getHandle(); /*getAddrMultiVecDevice(deviceX, &vX); getAddrMultiVecDevice(deviceY, &vY); */ vX=x->v_; vY=y->v_; /* rc = (int) cusparseGetMatType(hMat->descr); */ /* fprintf(stderr,"Spmv MatType: %d\n",rc); */ /* rc = (int) cusparseGetMatDiagType(hMat->descr); */ /* fprintf(stderr,"Spmv DiagType: %d\n",rc); */ /* rc = (int) cusparseGetMatFillMode(hMat->descr); */ /* fprintf(stderr,"Spmv FillMode: %d\n",rc); */ /* Dirty trick: apparently hybmv does not accept a triangular matrix even though it should not make a difference. So we claim it's general anyway */ type = cusparseGetMatType(hMat->descr); rc = cusparseSetMatType(hMat->descr,CUSPARSE_MATRIX_TYPE_GENERAL); if (rc == 0) rc = (int) cusparseThybmv(*my_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, (const TYPE *) &alpha, hMat->descr, hMat->hybA, (const TYPE *) vX, (const TYPE *) &beta, (TYPE *) vY); if (rc == 0) rc = cusparseSetMatType(hMat->descr,type); return(rc); } int T_HYBGDeviceAlloc(T_Hmat *Matrix,int nr, int nc, int nz) { T_HYBGDeviceMat *hMat; int nr1=nr, nz1=nz, rc; if ((nr<0)||(nc<0)||(nz<0)) return((int) CUSPARSE_STATUS_INVALID_VALUE); if ((hMat=(T_HYBGDeviceMat *) malloc(sizeof(T_HYBGDeviceMat)))==NULL) return((int) CUSPARSE_STATUS_ALLOC_FAILED); hMat->m = nr; hMat->n = nc; hMat->nz = nz; if ((rc= cusparseCreateMatDescr(&(hMat->descr))) !=0) return(rc); if ((rc= cusparseCreateSolveAnalysisInfo(&(hMat->triang))) !=0) return(rc); if((rc = cusparseCreateHybMat(&(hMat->hybA))) != 0) return(rc); Matrix->mat = hMat; return(CUSPARSE_STATUS_SUCCESS); } int T_HYBGDeviceSetMatDiagType(T_Hmat *Matrix, int type) { T_HYBGDeviceMat *hMat= Matrix->mat; return ((int) cusparseSetMatDiagType(hMat->descr,type)); } int T_HYBGDeviceSetMatIndexBase(T_Hmat *Matrix, int type) { T_HYBGDeviceMat *hMat= Matrix->mat; return ((int) cusparseSetMatIndexBase(hMat->descr,type)); } int T_HYBGDeviceSetMatType(T_Hmat *Matrix, int type) { T_HYBGDeviceMat *hMat= Matrix->mat; return ((int) cusparseSetMatType(hMat->descr,type)); } int T_HYBGDeviceSetMatFillMode(T_Hmat *Matrix, int type) { T_HYBGDeviceMat *hMat= Matrix->mat; return ((int) cusparseSetMatFillMode(hMat->descr,type)); } int T_spsvHYBGDevice(T_Hmat *Matrix, TYPE alpha, void *deviceX, TYPE beta, void *deviceY) { //beta?? T_HYBGDeviceMat *hMat=Matrix->mat; struct MultiVectDevice *x = (struct MultiVectDevice *) deviceX; struct MultiVectDevice *y = (struct MultiVectDevice *) deviceY; void *vX, *vY; int r,n; cusparseHandle_t *my_handle=getHandle(); /*getAddrMultiVecDevice(deviceX, &vX); getAddrMultiVecDevice(deviceY, &vY); */ vX=x->v_; vY=y->v_; return cusparseThybsv_solve(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, (const TYPE *) &alpha, hMat->descr, hMat->hybA, hMat->triang, (const TYPE *) vX, (TYPE *) vY); } int T_HYBGDeviceHybsmAnalysis(T_Hmat *Matrix) { T_HYBGDeviceMat *hMat= Matrix->mat; cusparseSolveAnalysisInfo_t info; int rc; cusparseHandle_t *my_handle=getHandle(); /* rc = (int) cusparseGetMatType(hMat->descr); */ /* fprintf(stderr,"Analysis MatType: %d\n",rc); */ /* rc = (int) cusparseGetMatDiagType(hMat->descr); */ /* fprintf(stderr,"Analysis DiagType: %d\n",rc); */ /* rc = (int) cusparseGetMatFillMode(hMat->descr); */ /* fprintf(stderr,"Analysis FillMode: %d\n",rc); */ rc = (int) cusparseThybsv_analysis(*my_handle,CUSPARSE_OPERATION_NON_TRANSPOSE, hMat->descr, hMat->hybA, hMat->triang); if (rc !=0) { fprintf(stderr,"From csrsv_analysis: %d\n",rc); } return(rc); } int T_HYBGHost2Device(T_Hmat *Matrix, int m, int n, int nz, int *irp, int *ja, TYPE *val) { int rc; double t1,t2; int nr1=m, nz1=nz; T_HYBGDeviceMat *hMat= Matrix->mat; cusparseHandle_t *my_handle=getHandle(); if (nr1 == 0) nr1 = 1; if (nz1 == 0) nz1 = 1; if ((rc= allocRemoteBuffer(((void **) &(hMat->irp)), ((nr1+1)*sizeof(int)))) != 0) return(rc); if ((rc= allocRemoteBuffer(((void **) &(hMat->ja)), ((nz1)*sizeof(int)))) != 0) return(rc); if ((rc= allocRemoteBuffer(((void **) &(hMat->val)), ((nz1)*sizeof(TYPE)))) != 0) return(rc); if ((rc=writeRemoteBuffer((void *) irp, (void *) hMat->irp, (m+1)*sizeof(int))) != SPGPU_SUCCESS) return(rc); if ((rc=writeRemoteBuffer((void *) ja,(void *) hMat->ja, (nz)*sizeof(int))) != SPGPU_SUCCESS) return(rc); if ((rc=writeRemoteBuffer((void *) val, (void *) hMat->val, (nz)*sizeof(TYPE))) != SPGPU_SUCCESS) return(rc); /* rc = (int) cusparseGetMatType(hMat->descr); */ /* fprintf(stderr,"Conversion MatType: %d\n",rc); */ /* rc = (int) cusparseGetMatDiagType(hMat->descr); */ /* fprintf(stderr,"Conversion DiagType: %d\n",rc); */ /* rc = (int) cusparseGetMatFillMode(hMat->descr); */ /* fprintf(stderr,"Conversion FillMode: %d\n",rc); */ //t1=etime(); rc = (int) cusparseTcsr2hyb(*my_handle, m, n, hMat->descr, (const TYPE *)hMat->val, (const int *)hMat->irp, (const int *)hMat->ja, hMat->hybA,0, CUSPARSE_HYB_PARTITION_AUTO); freeRemoteBuffer(hMat->irp); hMat->irp = NULL; freeRemoteBuffer(hMat->ja); hMat->ja = NULL; freeRemoteBuffer(hMat->val); hMat->val = NULL; //cudaSync(); //t2 = etime(); //fprintf(stderr,"Inner call to cusparseTcsr2hyb: %lf\n",(t2-t1)); if (rc != 0) { fprintf(stderr,"From csr2hyb: %d\n",rc); } return(rc); } #endif