extern "C" magma_int_t magma_cmtransposeconjugate( magma_c_matrix A, magma_c_matrix *B, magma_queue_t queue ) { // for symmetric matrices: convert to csc using cusparse magma_int_t info = 0; cusparseHandle_t handle=NULL; cusparseMatDescr_t descrA=NULL; cusparseMatDescr_t descrB=NULL; magma_c_matrix ACSR={Magma_CSR}, BCSR={Magma_CSR}; magma_c_matrix A_d={Magma_CSR}, B_d={Magma_CSR}; if( A.storage_type == Magma_CSR && A.memory_location == Magma_DEV ) { // fill in information for B B->storage_type = A.storage_type; B->diagorder_type = A.diagorder_type; B->memory_location = Magma_DEV; B->num_rows = A.num_cols; // transposed B->num_cols = A.num_rows; // transposed B->nnz = A.nnz; B->true_nnz = A.true_nnz; if ( A.fill_mode == MagmaFull ) { B->fill_mode = MagmaFull; } else if ( A.fill_mode == MagmaLower ) { B->fill_mode = MagmaUpper; } else if ( A.fill_mode == MagmaUpper ) { B->fill_mode = MagmaLower; } B->dval = NULL; B->drow = NULL; B->dcol = NULL; // memory allocation CHECK( magma_cmalloc( &B->dval, B->nnz )); CHECK( magma_index_malloc( &B->drow, B->num_rows + 1 )); CHECK( magma_index_malloc( &B->dcol, B->nnz )); // CUSPARSE context // CHECK_CUSPARSE( cusparseCreate( &handle )); CHECK_CUSPARSE( cusparseSetStream( handle, queue->cuda_stream() )); CHECK_CUSPARSE( cusparseCreateMatDescr( &descrA )); CHECK_CUSPARSE( cusparseCreateMatDescr( &descrB )); CHECK_CUSPARSE( cusparseSetMatType( descrA, CUSPARSE_MATRIX_TYPE_GENERAL )); CHECK_CUSPARSE( cusparseSetMatType( descrB, CUSPARSE_MATRIX_TYPE_GENERAL )); CHECK_CUSPARSE( cusparseSetMatIndexBase( descrA, CUSPARSE_INDEX_BASE_ZERO )); CHECK_CUSPARSE( cusparseSetMatIndexBase( descrB, CUSPARSE_INDEX_BASE_ZERO )); CHECK_CUSPARSE( cusparseCcsr2csc( handle, A.num_rows, A.num_cols, A.nnz, A.dval, A.drow, A.dcol, B->dval, B->dcol, B->drow, CUSPARSE_ACTION_NUMERIC, CUSPARSE_INDEX_BASE_ZERO) ); CHECK( magma_cmconjugate( B, queue )); } else if ( A.memory_location == Magma_CPU ){ CHECK( magma_cmtransfer( A, &A_d, A.memory_location, Magma_DEV, queue )); CHECK( magma_cmtransposeconjugate( A_d, &B_d, queue )); CHECK( magma_cmtransfer( B_d, B, Magma_DEV, A.memory_location, queue )); } else { CHECK( magma_cmconvert( A, &ACSR, A.storage_type, Magma_CSR, queue )); CHECK( magma_cmtransposeconjugate( ACSR, &BCSR, queue )); CHECK( magma_cmconvert( BCSR, B, Magma_CSR, A.storage_type, queue )); } cleanup: cusparseDestroyMatDescr( descrA ); cusparseDestroyMatDescr( descrB ); cusparseDestroy( handle ); magma_cmfree( &A_d, queue ); magma_cmfree( &B_d, queue ); magma_cmfree( &ACSR, queue ); magma_cmfree( &BCSR, queue ); if( info != 0 ){ magma_cmfree( B, queue ); } return info; }
extern "C" magma_int_t magma_c_cucsrtranspose( magma_c_sparse_matrix A, magma_c_sparse_matrix *B, magma_queue_t queue ) { // for symmetric matrices: convert to csc using cusparse if( A.storage_type == Magma_CSR && A.memory_location == Magma_DEV ) { magma_c_sparse_matrix C; magma_c_mtransfer( A, &C, Magma_DEV, Magma_DEV, queue ); // CUSPARSE context // cusparseHandle_t handle; cusparseStatus_t cusparseStatus; cusparseStatus = cusparseCreate(&handle); cusparseSetStream( handle, queue ); if (cusparseStatus != 0) printf("error in Handle.\n"); cusparseMatDescr_t descrA; cusparseMatDescr_t descrB; cusparseStatus = cusparseCreateMatDescr(&descrA); cusparseStatus = cusparseCreateMatDescr(&descrB); if (cusparseStatus != 0) printf("error in MatrDescr.\n"); cusparseStatus = cusparseSetMatType(descrA,CUSPARSE_MATRIX_TYPE_GENERAL); cusparseSetMatType(descrB,CUSPARSE_MATRIX_TYPE_GENERAL); if (cusparseStatus != 0) printf("error in MatrType.\n"); cusparseStatus = cusparseSetMatIndexBase(descrA,CUSPARSE_INDEX_BASE_ZERO); cusparseSetMatIndexBase(descrB,CUSPARSE_INDEX_BASE_ZERO); if (cusparseStatus != 0) printf("error in IndexBase.\n"); cusparseStatus = cusparseCcsr2csc( handle, A.num_rows, A.num_rows, A.nnz, A.dval, A.drow, A.dcol, C.dval, C.dcol, C.drow, CUSPARSE_ACTION_NUMERIC, CUSPARSE_INDEX_BASE_ZERO); if (cusparseStatus != 0) printf("error in transpose: %d.\n", cusparseStatus); cusparseDestroyMatDescr( descrA ); cusparseDestroyMatDescr( descrB ); cusparseDestroy( handle ); magma_c_mtransfer( C, B, Magma_DEV, Magma_DEV, queue ); if( A.fill_mode == Magma_FULL ){ B->fill_mode = Magma_FULL; } else if( A.fill_mode == Magma_LOWER ){ B->fill_mode = Magma_UPPER; } else if ( A.fill_mode == Magma_UPPER ){ B->fill_mode = Magma_LOWER; } // end CUSPARSE context // return MAGMA_SUCCESS; }else if( A.storage_type == Magma_CSR && A.memory_location == Magma_CPU ){ magma_c_sparse_matrix A_d, B_d; magma_c_mtransfer( A, &A_d, A.memory_location, Magma_DEV, queue ); magma_c_cucsrtranspose( A_d, &B_d, queue ); magma_c_mtransfer( B_d, B, Magma_DEV, A.memory_location, queue ); magma_c_mfree( &A_d, queue ); magma_c_mfree( &B_d, queue ); return MAGMA_SUCCESS; }else { magma_c_sparse_matrix ACSR, BCSR; magma_c_mconvert( A, &ACSR, A.storage_type, Magma_CSR, queue ); magma_c_cucsrtranspose( ACSR, &BCSR, queue ); magma_c_mconvert( BCSR, B, Magma_CSR, A.storage_type, queue ); magma_c_mfree( &ACSR, queue ); magma_c_mfree( &BCSR, queue ); return MAGMA_SUCCESS; } }