From b78e91364f01868f048204e363dde9be9812541b Mon Sep 17 00:00:00 2001 From: Bruno Turcksin Date: Sun, 18 Feb 2018 20:58:53 -0500 Subject: [PATCH] Add test for CUDAWrappers::SparseMatrix --- tests/cuda/sparse_matrix_01.cu | 216 +++++++++++++++++++++++++++++ tests/cuda/sparse_matrix_01.output | 2 + 2 files changed, 218 insertions(+) create mode 100644 tests/cuda/sparse_matrix_01.cu create mode 100644 tests/cuda/sparse_matrix_01.output diff --git a/tests/cuda/sparse_matrix_01.cu b/tests/cuda/sparse_matrix_01.cu new file mode 100644 index 0000000000..e1bc483cc7 --- /dev/null +++ b/tests/cuda/sparse_matrix_01.cu @@ -0,0 +1,216 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +// Check multiplications and norms + +#include "../tests.h" +#include "../testmatrix.h" + +#include +#include +#include +#include + + +void check_matrix(SparseMatrix const &A, + CUDAWrappers::SparseMatrix &A_dev) +{ + cudaError_t cuda_error_code; + double *val_dev = nullptr; + int *column_index_dev = nullptr; + int *row_ptr_dev = nullptr; + std::tie(val_dev, column_index_dev, row_ptr_dev, std::ignore) = + A_dev.get_cusparse_matrix(); + + int nnz = A_dev.n_nonzero_elements(); + std::vector val_host(nnz); + cuda_error_code = cudaMemcpy(&val_host[0], val_dev, nnz*sizeof(double), + cudaMemcpyDeviceToHost); + AssertCuda(cuda_error_code); + + std::vector column_index_host(nnz); + cuda_error_code = cudaMemcpy(&column_index_host[0], column_index_dev, + nnz*sizeof(int), cudaMemcpyDeviceToHost); + AssertCuda(cuda_error_code); + + int const n_rows = A_dev.m() + 1; + std::vector row_ptr_host(n_rows+1); + cuda_error_code = cudaMemcpy(&row_ptr_host[0], row_ptr_dev, + (A_dev.m()+1)*sizeof(int), cudaMemcpyDeviceToHost); + AssertCuda(cuda_error_code); + + for (int i=0; i const &a, + LinearAlgebra::ReadWriteVector const &b) +{ + unsigned int size = a.size(); + for (unsigned int i=0; i A; + testproblem.five_point_structure(structure); + structure.compress(); + A.reinit(structure); + testproblem.five_point(A, true); + + // Create the sparse matrix on the device + CUDAWrappers::SparseMatrix A_dev(cusparse_handle, A); + check_matrix(A, A_dev); + + AssertThrow(A.m() == A_dev.m(), ExcInternalError()); + AssertThrow(A.n() == A_dev.n(), ExcInternalError()); + + // Multiply by a constant + A *= 2.; + A_dev *= 2.; + check_matrix(A, A_dev); + + // Divide by a constant + A /= 2.; + A_dev /= 2.; + check_matrix(A, A_dev); + + // Matrix-vector multiplication + const unsigned int vector_size = A.n(); + Vector dst(vector_size); + Vector src(vector_size); + for (unsigned int i=0; i dst_dev(vector_size); + LinearAlgebra::CUDAWrappers::Vector src_dev(vector_size); + LinearAlgebra::ReadWriteVector read_write(vector_size); + for (unsigned int i=0; i b(src); + for (unsigned int i=0; i b_dev(vector_size); + b_dev.import(read_write, VectorOperation::insert); + src_dev.import(read_write, VectorOperation::insert); + value = A.residual(dst, src, b); + value_host = A_dev.residual(dst_dev, src_dev, b_dev); + AssertThrow(std::abs(value-value_host) < 1e-15, ExcInternalError()); + read_write.import(dst_dev, VectorOperation::insert); + check_vector(dst, read_write); + + // Compute L1 norm + value = A.l1_norm(); + value_host = A_dev.l1_norm(); + AssertThrow(std::abs(value-value_host) < 1e-15, ExcInternalError()); + + // Compute Linfty norm + value = A.linfty_norm(); + value_host = A_dev.linfty_norm(); + AssertThrow(std::abs(value-value_host) < 1e-15, ExcInternalError()); + + // Compute Frobenius norm + value = A.frobenius_norm(); + value_host = A_dev.frobenius_norm(); + AssertThrow(std::abs(value-value_host) < 1e-15, ExcInternalError()); + + // Compute L1 norm second test + SparsityPattern sparsity_pattern(vector_size, vector_size, 3); + for (unsigned int i=0; i B(sparsity_pattern); + for (unsigned int i=0; i B_dev(cusparse_handle, B); + value = B.l1_norm(); + value_host = B_dev.l1_norm(); + AssertThrow(std::abs(value-value_host) < 1e-15, ExcInternalError()); +} + +int main() +{ + initlog(); + deallog.depth_console(0); + + cusparseHandle_t cusparse_handle; + cusparseStatus_t cusparse_error_code = cusparseCreate(&cusparse_handle); + AssertCusparse(cusparse_error_code); + + test(cusparse_handle); + + cusparse_error_code = cusparseDestroy(cusparse_handle); + AssertCusparse(cusparse_error_code); + + deallog << "OK" <