Files
rocm-systems/tests/hipify-clang/unit_tests/libraries/cuSPARSE/cuSPARSE_02.cu
T
Evgeny Mankov fbfe005e4e [HIPIFY] Introduce CUDA installation path option '-cuda-path'
Repeats clang's '--cuda-path' option.

[Reason]
In case of absence of any other clang's options setting '-cuda-path' allows not to specify separator '--' before clang's '--cuda-path'.

+ Tests and scripts are updated accordingly.
2019-01-09 20:18:36 +03:00

285 строки
12 KiB
Plaintext

// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// CHECK: #include <hip/hip_runtime.h>
#include <cuda_runtime.h>
// CHECK: #include <hipblas.h>
#include <cublas_v2.h>
// CHECK: #include "hipsparse.h"
#include "cusparse.h"
void printMatrix(int m, int n, const double*A, int lda, const char* name)
{
for(int row = 0 ; row < m ; row++){
for(int col = 0 ; col < n ; col++){
double Areg = A[row + col*lda];
printf("%s(%d,%d) = %f\n", name, row+1, col+1, Areg);
}
}
}
int main(int argc, char*argv[])
{
// CHECK: hipblasHandle_t cublasH = NULL;
cublasHandle_t cublasH = NULL;
// CHECK: hipsparseHandle_t cusparseH = NULL;
cusparseHandle_t cusparseH = NULL;
// CHECK: hipStream_t stream = NULL;
cudaStream_t stream = NULL;
// CHECK: hipsparseMatDescr_t descrA = NULL;
cusparseMatDescr_t descrA = NULL;
// CHECK: hipblasStatus_t cublasStat = HIPBLAS_STATUS_SUCCESS;
cublasStatus_t cublasStat = CUBLAS_STATUS_SUCCESS;
// CHECK: hipsparseStatus_t cusparseStat = HIPSPARSE_STATUS_SUCCESS;
cusparseStatus_t cusparseStat = CUSPARSE_STATUS_SUCCESS;
// CHECK: hipError_t cudaStat1 = hipSuccess;
// CHECK: hipError_t cudaStat2 = hipSuccess;
// CHECK: hipError_t cudaStat3 = hipSuccess;
// CHECK: hipError_t cudaStat4 = hipSuccess;
// CHECK: hipError_t cudaStat5 = hipSuccess;
cudaError_t cudaStat1 = cudaSuccess;
cudaError_t cudaStat2 = cudaSuccess;
cudaError_t cudaStat3 = cudaSuccess;
cudaError_t cudaStat4 = cudaSuccess;
cudaError_t cudaStat5 = cudaSuccess;
const int n = 4;
const int nnzA = 9;
/*
* | 1 0 2 3 |
* | 0 4 0 0 |
* A = | 5 0 6 7 |
* | 0 8 0 9 |
*
* eigevales are { -0.5311, 7.5311, 9.0000, 4.0000 }
*
* The largest eigenvaluse is 9 and corresponding eigenvector is
*
* | 0.3029 |
* v = | 0 |
* | 0.9350 |
* | 0.1844 |
*/
const int csrRowPtrA[n+1] = { 0, 3, 4, 7, 9 };
const int csrColIndA[nnzA] = {0, 2, 3, 1, 0, 2, 3, 1, 3 };
const double csrValA[nnzA] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
const double lambda_exact[n] = { 9.0000, 7.5311, 4.0000, -0.5311 };
const double x0[n] = {1.0, 2.0, 3.0, 4.0 }; /* initial guess */
double x[n]; /* numerical eigenvector */
int *d_csrRowPtrA = NULL;
int *d_csrColIndA = NULL;
double *d_csrValA = NULL;
double *d_x = NULL; /* eigenvector */
double *d_y = NULL; /* workspace */
const double tol = 1.e-6;
const int max_ites = 30;
const double h_one = 1.0;
const double h_zero = 0.0;
printf("example of csrmv_mp \n");
printf("tol = %E \n", tol);
printf("max. iterations = %d \n", max_ites);
printf("1st eigenvaluse is %f\n", lambda_exact[0] );
printf("2nd eigenvaluse is %f\n", lambda_exact[1] );
double alpha = lambda_exact[1]/lambda_exact[0] ;
printf("convergence rate is %f\n", alpha );
double est_iterations = log(tol)/log(alpha);
printf("# of iterations required is %d\n", (int)ceil(est_iterations));
// step 1: create cublas/cusparse handle, bind a stream
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
// CHECK: assert(hipSuccess == cudaStat1);
assert(cudaSuccess == cudaStat1);
// CHECK: cublasStat = hipblasCreate(&cublasH);
cublasStat = cublasCreate(&cublasH);
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
// CHECK: cublasStat = hipblasSetStream(cublasH, stream);
cublasStat = cublasSetStream(cublasH, stream);
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
// CHECK: cusparseStat = hipsparseCreate(&cusparseH);
cusparseStat = cusparseCreate(&cusparseH);
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
// CHECK: cusparseStat = hipsparseSetStream(cusparseH, stream);
cusparseStat = cusparseSetStream(cusparseH, stream);
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
// step 2: configuration of matrix A
// CHECK: cusparseStat = hipsparseCreateMatDescr(&descrA);
cusparseStat = cusparseCreateMatDescr(&descrA);
// assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
// CHECK: hipsparseSetMatIndexBase(descrA,HIPSPARSE_INDEX_BASE_ZERO);
cusparseSetMatIndexBase(descrA,CUSPARSE_INDEX_BASE_ZERO);
// CHECK: hipsparseSetMatType(descrA, HIPSPARSE_MATRIX_TYPE_GENERAL );
cusparseSetMatType(descrA, CUSPARSE_MATRIX_TYPE_GENERAL );
// step 3: copy A and x0 to device
// CHECK: cudaStat1 = hipMalloc ((void**)&d_csrRowPtrA, sizeof(int) * (n+1) );
cudaStat1 = cudaMalloc ((void**)&d_csrRowPtrA, sizeof(int) * (n+1) );
// CHECK: cudaStat2 = hipMalloc ((void**)&d_csrColIndA, sizeof(int) * nnzA );
cudaStat2 = cudaMalloc ((void**)&d_csrColIndA, sizeof(int) * nnzA );
// CHECK: cudaStat3 = hipMalloc ((void**)&d_csrValA , sizeof(double) * nnzA );
cudaStat3 = cudaMalloc ((void**)&d_csrValA , sizeof(double) * nnzA );
// CHECK: cudaStat4 = hipMalloc ((void**)&d_x , sizeof(double) * n );
cudaStat4 = cudaMalloc ((void**)&d_x , sizeof(double) * n );
// CHECK: cudaStat5 = hipMalloc ((void**)&d_y , sizeof(double) * n );
cudaStat5 = cudaMalloc ((void**)&d_y , sizeof(double) * n );
// CHECK: assert(hipSuccess == cudaStat1);
// CHECK: assert(hipSuccess == cudaStat2);
// CHECK: assert(hipSuccess == cudaStat3);
// CHECK: assert(hipSuccess == cudaStat4);
// CHECK: assert(hipSuccess == cudaStat5);
assert(cudaSuccess == cudaStat1);
assert(cudaSuccess == cudaStat2);
assert(cudaSuccess == cudaStat3);
assert(cudaSuccess == cudaStat4);
assert(cudaSuccess == cudaStat5);
// CHECK: cudaStat1 = hipMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int) * (n+1) , hipMemcpyHostToDevice);
cudaStat1 = cudaMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int) * (n+1) , cudaMemcpyHostToDevice);
// CHECK: cudaStat2 = hipMemcpy(d_csrColIndA, csrColIndA, sizeof(int) * nnzA , hipMemcpyHostToDevice);
cudaStat2 = cudaMemcpy(d_csrColIndA, csrColIndA, sizeof(int) * nnzA , cudaMemcpyHostToDevice);
// CHECK: cudaStat3 = hipMemcpy(d_csrValA , csrValA , sizeof(double) * nnzA , hipMemcpyHostToDevice);
cudaStat3 = cudaMemcpy(d_csrValA , csrValA , sizeof(double) * nnzA , cudaMemcpyHostToDevice);
// CHECK: assert(hipSuccess == cudaStat1);
assert(cudaSuccess == cudaStat1);
// CHECK: assert(hipSuccess == cudaStat2);
assert(cudaSuccess == cudaStat2);
// CHECK: assert(hipSuccess == cudaStat3);
assert(cudaSuccess == cudaStat3);
// step 4: power method
double lambda = 0.0;
double lambda_next = 0.0;
// 4.1: initial guess x0
cudaStat1 = cudaMemcpy(d_x, x0, sizeof(double) * n, cudaMemcpyHostToDevice);
// CHECK: assert(hipSuccess == cudaStat1);
assert(cudaSuccess == cudaStat1);
for(int ite = 0 ; ite < max_ites ; ite++ ){
// 4.2: normalize vector x
// x = x / |x|
double nrm2_x;
// TODO: cublasStat = hipblasDnrm2_v2(cublasH,
cublasStat = cublasDnrm2_v2(cublasH,
n,
d_x,
1, // incx,
&nrm2_x /* host pointer */
);
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
double one_over_nrm2_x = 1.0 / nrm2_x;
// TODO: cublasStat = hipblasDscal_v2( cublasH,
cublasStat = cublasDscal_v2( cublasH,
n,
&one_over_nrm2_x, /* host pointer */
d_x,
1 // incx
);
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
// 4.3: y = A*x
// TODO: hipsparseStat = cusparseDcsrmv_mp(cusparseH,
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE
cusparseStat = cusparseDcsrmv_mp(cusparseH,
CUSPARSE_OPERATION_NON_TRANSPOSE,
n,
n,
nnzA,
&h_one,
descrA,
d_csrValA,
d_csrRowPtrA,
d_csrColIndA,
d_x,
&h_zero,
d_y);
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
// 4.4: lambda = y**T*x
// TODO: cublasStat = hipblasDdot_v2 ( cublasH,
cublasStat = cublasDdot_v2 ( cublasH,
n,
d_x,
1, // incx,
d_y,
1, // incy,
&lambda_next /* host pointer */
);
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
double lambda_err = fabs( lambda_next - lambda_exact[0] );
printf("ite %d: lambda = %f, error = %E\n", ite, lambda_next, lambda_err );
// 4.5: check if converges
if ( (ite > 0) &&
fabs( lambda - lambda_next ) < tol
){
break; // converges
}
/*
* 4.6: x := y
* lambda = lambda_next
*
* so new approximation is (lambda, x), x is not normalized.
*/
// CHECK: cudaStat1 = hipMemcpy(d_x, d_y, sizeof(double) * n , hipMemcpyDeviceToDevice);
cudaStat1 = cudaMemcpy(d_x, d_y, sizeof(double) * n , cudaMemcpyDeviceToDevice);
// CHECK: assert(hipSuccess == cudaStat1);
assert(cudaSuccess == cudaStat1);
lambda = lambda_next;
}
// step 5: report eigen-pair
// CHECK: cudaStat1 = hipMemcpy(x, d_x, sizeof(double) * n, hipMemcpyDeviceToHost);
cudaStat1 = cudaMemcpy(x, d_x, sizeof(double) * n, cudaMemcpyDeviceToHost);
// CHECK: assert(hipSuccess == cudaStat1);
assert(cudaSuccess == cudaStat1);
printf("largest eigenvalue is %E\n", lambda );
printf("eigenvector = (matlab base-1)\n");
printMatrix(n, 1, x, n, "V0");
printf("=====\n");
// free resources
// CHECK: if (d_csrRowPtrA ) hipFree(d_csrRowPtrA);
if (d_csrRowPtrA ) cudaFree(d_csrRowPtrA);
// CHECK: if (d_csrColIndA ) hipFree(d_csrColIndA);
if (d_csrColIndA ) cudaFree(d_csrColIndA);
// CHECK: if (d_csrValA ) hipFree(d_csrValA);
if (d_csrValA ) cudaFree(d_csrValA);
// CHECK: if (d_x ) hipFree(d_x);
if (d_x ) cudaFree(d_x);
// CHeCK: if (d_y ) hipFree(d_y);
if (d_y ) cudaFree(d_y);
// CHECK: if (cublasH ) hipblasDestroy(cublasH);
if (cublasH ) cublasDestroy(cublasH);
// CHECK: if (cusparseH ) hipsparseDestroy(cusparseH);
if (cusparseH ) cusparseDestroy(cusparseH);
// CHECK: if (stream ) hipStreamDestroy(stream);
if (stream ) cudaStreamDestroy(stream);
// CHECK: if (descrA ) hipsparseDestroyMatDescr(descrA);
if (descrA ) cusparseDestroyMatDescr(descrA);
// CHECK: hipDeviceReset();
cudaDeviceReset();
return 0;
}