From: Daniel Arndt Date: Sun, 11 Aug 2024 23:47:22 +0000 (-0600) Subject: Remove CUDAWrappers, related documentation and macros X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7fbd2d33640e18e4bab45207a6dfda6a99c9a2e;p=dealii.git Remove CUDAWrappers, related documentation and macros --- diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index b8998bf32a..2b946af978 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -369,7 +369,6 @@ jobs: -D CMAKE_CXX_COMPILER=${GITHUB_WORKSPACE}/kokkos/bin/nvcc_wrapper \ -D DEAL_II_CXX_FLAGS='-Werror -Wno-non-template-friend' \ -D DEAL_II_EARLY_DEPRECATIONS=ON \ - -D DEAL_II_WITH_CUDA="ON" \ -D DEAL_II_WITH_KOKKOS="ON" \ -D KOKKOS_DIR=${GITHUB_WORKSPACE}/../kokkos-install \ -D DEAL_II_WITH_MPI="ON" \ @@ -386,10 +385,8 @@ jobs: - name: build CUDA tests run: | cd build - make -j2 setup_tests_cuda setup_tests_matrix_free_kokkos - cd tests/cuda - make -j2 compile_test_executables - cd ../matrix_free_kokkos + make -j2 setup_tests_matrix_free_kokkos + cd tests/matrix_free_kokkos make -j2 compile_test_executables ############################# @@ -463,7 +460,6 @@ jobs: -D DEAL_II_FORCE_BUNDLED_BOOST=ON \ -D DEAL_II_CXX_FLAGS="-std=c++17" \ -D DEAL_II_EARLY_DEPRECATIONS=ON \ - -D DEAL_II_WITH_CUDA="ON" \ -D DEAL_II_WITH_KOKKOS="ON" \ -D KOKKOS_DIR=${GITHUB_WORKSPACE}/../kokkos-install \ -D DEAL_II_WITH_MPI="ON" \ @@ -484,8 +480,6 @@ jobs: - name: build CUDA tests run: | cd build - make -j2 setup_tests_cuda setup_tests_matrix_free_kokkos - cd tests/cuda - make -j2 compile_test_executables - cd ../matrix_free_kokkos + make -j2 setup_tests_matrix_free_kokkos + cd tests/matrix_free_kokkos make -j2 compile_test_executables diff --git a/CMakeLists.txt b/CMakeLists.txt index 89e3d3e715..8dcdbb73b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,6 @@ verbose_include(${CMAKE_SOURCE_DIR}/cmake/setup_cached_variables.cmake) # Now, set the project and set up the rest: # project(deal.II CXX C) -enable_language_optional(Fortran) verbose_include(${CMAKE_SOURCE_DIR}/cmake/setup_deal_ii.cmake) diff --git a/cmake/checks/check_01_cpu_features.cmake b/cmake/checks/check_01_cpu_features.cmake index 5626fe51cf..60afad6168 100644 --- a/cmake/checks/check_01_cpu_features.cmake +++ b/cmake/checks/check_01_cpu_features.cmake @@ -327,16 +327,6 @@ if(DEAL_II_HAVE_ARM_NEON) set(DEAL_II_VECTORIZATION_WIDTH_IN_BITS 128) endif() -# -# We need to disable SIMD vectorization for CUDA device code. -# Otherwise, nvcc compilers from version 9 on will emit an error message like: -# "[...] contains a vector, which is not supported in device code" -# - -if(DEAL_II_WITH_CUDA) - set(DEAL_II_VECTORIZATION_WIDTH_IN_BITS 0) -endif() - # # If we have OpenMP SIMD support (i.e. DEAL_II_HAVE_OPENMP_SIMD is true) # populate DEAL_II_OPENMP_SIMD_PRAGMA. diff --git a/cmake/configure/configure_10_mpi.cmake b/cmake/configure/configure_10_mpi.cmake index 1509e1c06f..bb979dc980 100644 --- a/cmake/configure/configure_10_mpi.cmake +++ b/cmake/configure/configure_10_mpi.cmake @@ -54,12 +54,7 @@ macro(feature_mpi_configure_external) # TODO: We might consider refactoring this option into an automatic check # (in Modules/FindMPI.cmake) at some point. For the time being this is an # advanced configuration option. - # - if(DEAL_II_MPI_WITH_CUDA_SUPPORT) - option(DEAL_II_MPI_WITH_DEVICE_SUPPORT "Enable MPI Device support" ON) - else() - option(DEAL_II_MPI_WITH_DEVICE_SUPPORT "Enable MPI Device support" OFF) - endif() + option(DEAL_II_MPI_WITH_DEVICE_SUPPORT "Enable MPI Device support" OFF) mark_as_advanced(DEAL_II_MPI_WITH_DEVICE_SUPPORT) endmacro() diff --git a/cmake/configure/configure_40_cuda.cmake b/cmake/configure/configure_40_cuda.cmake deleted file mode 100644 index 806bb5675a..0000000000 --- a/cmake/configure/configure_40_cuda.cmake +++ /dev/null @@ -1,126 +0,0 @@ -## ------------------------------------------------------------------------ -## -## SPDX-License-Identifier: LGPL-2.1-or-later -## Copyright (C) 2022 - 2023 by the deal.II authors -## -## This file is part of the deal.II library. -## -## Part of the source code is dual licensed under Apache-2.0 WITH -## LLVM-exception OR LGPL-2.1-or-later. Detailed license information -## governing the source code and code contributions can be found in -## LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -## -## ------------------------------------------------------------------------ - -# -# Configuration for cuda support: -# - -# -# cuda support is experimental. Therefore, disable the feature per default: -# -set(DEAL_II_WITH_CUDA FALSE CACHE BOOL "") - -macro(feature_cuda_find_external var) - if(DEAL_II_FEATURE_KOKKOS_BUNDLED_CONFIGURED) - set(CUDA_ADDITIONAL_ERROR_STRING - ${CUDA_ADDITIONAL_ERROR_STRING} - "deal.II's bundled version of Kokkos only supports the Serial backend and therefore cannot be used with Cuda." - ) - set(${var} FALSE) - elseif(NOT Kokkos_ENABLE_CUDA) - set(CUDA_ADDITIONAL_ERROR_STRING - ${CUDA_ADDITIONAL_ERROR_STRING} - "deal.II can only be compiled with Cuda support if Kokkos was built with Cuda support!" - ) - set(${var} FALSE) - else() - # FIXME We need to also find and link with cuSolver and cuSparse even though - # relying on Kokkos for linking with Cuda. That's why we keep the code below for now. - - # We need to set CUDA_USE_STATIC_CUDA_RUNTIME before find_package(CUDA) and to - # force the value otherwise it is overwritten by find_package(CUDA) - if(BUILD_SHARED_LIBS) - set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE BOOL "" FORCE) - endif() - - # - # TODO: Ultimately, this find_package call is not needed any more. We - # still use it because it is very convenient to (a) check that CUDA is - # installed, (b) get compiler path and include directories / libraries. - # - find_package(DEAL_II_CUDA) - - if(CUDA_FOUND) - # - # CUDA was found, check whether we can actually use it: - # - set(${var} TRUE) - - # - # disable CUDA support older than 10.2: - # - if(CUDA_VERSION VERSION_LESS 10.2) - message(FATAL_ERROR "\n" - "deal.II requires CUDA version 10.2 or newer." - ) - endif() - - # - # We do not support CUDA 12.0 and newer: - # - if(CUDA_VERSION VERSION_GREATER_EQUAL 12.0) - message(FATAL_ERROR "\n" - "deal.II's own CUDA backend does not support CUDA version 12.0 or newer.\n" - "Instead, configure Kokkos with CUDA enabled." - ) - endif() - - # - # CUDA Toolkit 10 is incompatible with C++17. - # Make sure that deal.II is configured appropriately - # - macro(_cuda_ensure_feature_off _version _cpp_version_bad _cpp_version_good) - if(${CUDA_VERSION_MAJOR} EQUAL ${_version}) - if(${DEAL_II_HAVE_CXX${_cpp_version_bad}}) - set(${var} FALSE) - message(STATUS "CUDA ${_version} requires ${_feature} to be set to off.") - set(CUDA_ADDITIONAL_ERROR_STRING - ${CUDA_ADDITIONAL_ERROR_STRING} - "CUDA ${_version} is not compatible with the C++${_cpp_version_bad} standard.\n" - "Please explicitly set the standard version to C++${_cpp_version_good}, e.g. by reconfiguring with\n" - " cmake -DDEAL_II_CXX_FLAGS=\"-std=c++${_cpp_version_good}\" ." - ) - endif() - endif() - endmacro() - - _cuda_ensure_feature_off(10 17 14) - - # cuSOLVER requires OpenMP - find_package(OpenMP REQUIRED) - set(DEAL_II_LINKER_FLAGS "${DEAL_II_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}") - endif() - endif() -endmacro() - - -macro(feature_cuda_configure_external) - # We cannot use -pedantic as compiler flags. nvcc generates code that - # produces a lot of warnings when pedantic is enabled. So filter out the - # flag: - # - string(REPLACE "-pedantic" "" DEAL_II_WARNING_FLAGS "${DEAL_II_WARNING_FLAGS}") -endmacro() - - -macro(feature_cuda_error_message) - message(FATAL_ERROR "\n" - "Could not find any suitable cuda library!\n" - ${CUDA_ADDITIONAL_ERROR_STRING} - "\nPlease ensure that a cuda library is installed on your computer and deal.II is configured to use an external Kokkos installation.\n" - ) -endmacro() - - -configure_feature(CUDA) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 0d545fbe89..d2857a70b8 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -28,7 +28,6 @@ RUN cd /usr/src && \ -DDEAL_II_WITH_BOOST=ON \ -DDEAL_II_WITH_CGAL=ON \ -DDEAL_II_WITH_COMPLEX_VALUES=ON \ - -DDEAL_II_WITH_CUDA=OFF \ -DDEAL_II_WITH_GINKGO=OFF \ -DDEAL_II_WITH_GMSH=ON \ -DDEAL_II_WITH_GSL=ON \ diff --git a/doc/doxygen/headers/cuda.h b/doc/doxygen/headers/cuda.h deleted file mode 100644 index 0457b9be51..0000000000 --- a/doc/doxygen/headers/cuda.h +++ /dev/null @@ -1,21 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -/** - * @defgroup CUDAWrappers CUDA Wrappers - * - * The classes in this group are concerned with the description of features - * to be run on GPUs using CUDA. - */ diff --git a/doc/doxygen/headers/glossary.h b/doc/doxygen/headers/glossary.h index aa1750a8d1..73b629ddf5 100644 --- a/doc/doxygen/headers/glossary.h +++ b/doc/doxygen/headers/glossary.h @@ -777,7 +777,7 @@ *
@anchor GlossDevice Device
* *
We commonly refer to GPUs as "devices" in deal.II. The context is - * always related to Kokkos or CUDA that motivated using this term. + * always related to Kokkos that motivated using this term. * Occasionally, we also call data corresponding to MemorySpace::Default "device data" * (even though it is allocated in CPU memory if Kokkos was configured without * a GPU backend) to distinguish between MemorySpace::Default and MemorySpace::Host. diff --git a/doc/doxygen/headers/main.h b/doc/doxygen/headers/main.h index 1d561e86e2..6d73f64d6f 100644 --- a/doc/doxygen/headers/main.h +++ b/doc/doxygen/headers/main.h @@ -74,7 +74,6 @@ rank="same"; petsc [label="PETSc", URL="\ref PETScWrappers"]; trilinos [label="Trilinos", URL="\ref TrilinosWrappers"]; - cuda [label="CUDA", URL="\ref CUDAWrappers"]; } umfpack [label="UMFPACK"]; diff --git a/doc/doxygen/headers/matrixfree.h b/doc/doxygen/headers/matrixfree.h index fbf71a97c0..7b7bf9afc6 100644 --- a/doc/doxygen/headers/matrixfree.h +++ b/doc/doxygen/headers/matrixfree.h @@ -42,7 +42,7 @@ digraph G color="gray", fontcolor="gray", fillcolor="white", style="filled"]; fevalues [label="FEEvaluation", fillcolor="deepskyblue"]; mf [label="MatrixFree loops", fillcolor="deepskyblue"]; - cuda [label="CUDA", URL="\ref CUDAWrappers", fontname="FreeSans",fontsize=12, + portable [label="Portable", URL="\ref Portable", fontname="FreeSans",fontsize=12, height=0.2,width=0.4, color="gray", fontcolor="gray", fillcolor="white", style="filled"]; tbb [label="TBB", fontname="FreeSans",fontsize=12, @@ -51,8 +51,8 @@ digraph G {rank=same simd -> fevalues [dir="none", color="transparent"]; fevalues -> mf [dir="none", color="transparent"]; - mf -> cuda [dir="none", color="transparent"]; - cuda -> tbb [dir="none", color="transparent"]; + mf -> portable [dir="none", color="transparent"]; + portable -> tbb [dir="none", color="transparent"]; } subgraph sol { rank="same"; diff --git a/doc/doxygen/options.dox.in b/doc/doxygen/options.dox.in index f1bcad8bf1..1ac505f306 100644 --- a/doc/doxygen/options.dox.in +++ b/doc/doxygen/options.dox.in @@ -204,7 +204,6 @@ PREDEFINED = DOXYGEN=1 \ DEAL_II_CGAL_VERSION_GTE=1 \ DEAL_II_WITH_TASKFLOW=1 \ DEAL_II_WITH_COMPLEX_VALUES=1 \ - DEAL_II_WITH_CUDA=1 \ DEAL_II_WITH_GINKGO=1 \ DEAL_II_WITH_GMSH=1 \ DEAL_II_GMSH_WITH_API=1 \ diff --git a/doc/external-libs/cuda.html b/doc/external-libs/cuda.html index 6e6be86b17..4bdede8462 100644 --- a/doc/external-libs/cuda.html +++ b/doc/external-libs/cuda.html @@ -15,20 +15,6 @@

To compile and run CUDA code, you need to use an external Kokkos installation that has been configured with CUDA support. - - To enable deal.II's own CUDA backend, you will need your GPU to have compute - capability 6.0 or higher. Independently from the GPU itself, you also need a - version of CUDA between 10.2 and 11.8. -

- -

- To configure deal.II's own CUDA backend use the following option: -

-
-        -DDEAL_II_WITH_CUDA=ON
-      
- CUDA versions prior to 11.0 don't support C++17 or higher. You will have - to make sure that C++17 is disabled when using earlier versions.

diff --git a/doc/news/changes/incompatibilities/20240811Arndt b/doc/news/changes/incompatibilities/20240811Arndt new file mode 100644 index 0000000000..3c61624a49 --- /dev/null +++ b/doc/news/changes/incompatibilities/20240811Arndt @@ -0,0 +1,4 @@ +Removed: All support for CUDAWrappers and CUDA-related macros have been removed. +GPU support is provided through Kokkos. +
+(Daniel Arndt, 2024/08/11) diff --git a/doc/users/cmake_dealii.html b/doc/users/cmake_dealii.html index c16240607b..ddc2f12b8e 100644 --- a/doc/users/cmake_dealii.html +++ b/doc/users/cmake_dealii.html @@ -457,7 +457,6 @@ DEAL_II_WITH_ASSIMP DEAL_II_WITH_BOOST DEAL_II_WITH_CGAL DEAL_II_WITH_COMPLEX_VALUES -DEAL_II_WITH_CUDA DEAL_II_WITH_GINKGO DEAL_II_WITH_GMSH DEAL_II_WITH_GSL diff --git a/doc/users/cmake_user.html b/doc/users/cmake_user.html index 3ad6b495c3..9be97af2c9 100644 --- a/doc/users/cmake_user.html +++ b/doc/users/cmake_user.html @@ -844,7 +844,6 @@ DEAL_II_WITH_ADOLC DEAL_II_WITH_ARPACK DEAL_II_WITH_ASSIMP DEAL_II_WITH_COMPLEX_VALUES -DEAL_II_WITH_CUDA DEAL_II_WITH_GINKGO DEAL_II_WITH_GMSH DEAL_II_WITH_GSL diff --git a/doc/users/config.sample b/doc/users/config.sample index 0e2869ca5e..4a09f4ace1 100644 --- a/doc/users/config.sample +++ b/doc/users/config.sample @@ -118,7 +118,6 @@ # set(DEAL_II_WITH_BOOST "ON" CACHE BOOL "") # set(DEAL_II_WITH_CGAL "ON" CACHE BOOL "") # set(DEAL_II_WITH_COMPLEX_VALUES "ON" CACHE BOOL "") -# set(DEAL_II_WITH_CUDA "ON" CACHE BOOL "") # set(DEAL_II_WITH_GINKGO "ON" CACHE BOOL "") # set(DEAL_II_WITH_GMSH "ON" CACHE BOOL "") # set(DEAL_II_WITH_GSL "ON" CACHE BOOL "") diff --git a/examples/step-64/doc/intro.dox b/examples/step-64/doc/intro.dox index d77a6b0d03..4bb3675738 100644 --- a/examples/step-64/doc/intro.dox +++ b/examples/step-64/doc/intro.dox @@ -67,8 +67,8 @@ The data movement in deal.II is done using LinearAlgebra::ReadWriteVector. These vectors can be seen as buffers on the host that are used to either store data received from the device or to send data to the device. There are two types of vectors that can be used on the device: -- LinearAlgebra::CUDAWrappers::Vector, which is similar to the more common -Vector, and +- LinearAlgebra::TpetraWrappers::Vector, that has a host +and device copy of the data, and - LinearAlgebra::distributed::Vector, which is a regular LinearAlgebra::distributed::Vector where we have specified which memory diff --git a/examples/step-64/step-64.cc b/examples/step-64/step-64.cc index 4ab2559049..5e3624681a 100644 --- a/examples/step-64/step-64.cc +++ b/examples/step-64/step-64.cc @@ -363,8 +363,7 @@ namespace Step64 // Since all the operations in the `solve()` function are executed on the // graphics card, it is necessary for the vectors used to store their values // on the GPU as well. LinearAlgebra::distributed::Vector can be told which - // memory space to use. There is also LinearAlgebra::CUDAWrappers::Vector - // that always uses GPU memory storage but doesn't work with MPI. It might + // memory space to use. It might // be worth noticing that the communication between different MPI processes // can be improved if the MPI implementation is GPU-aware and the configure // flag `DEAL_II_MPI_WITH_DEVICE_SUPPORT` is enabled. (The value of this diff --git a/include/deal.II/base/config.h.in b/include/deal.II/base/config.h.in index e09209db4d..95e01a2918 100644 --- a/include/deal.II/base/config.h.in +++ b/include/deal.II/base/config.h.in @@ -41,7 +41,6 @@ #cmakedefine DEAL_II_FEATURE_BOOST_BUNDLED_CONFIGURED #cmakedefine DEAL_II_WITH_CGAL #cmakedefine DEAL_II_WITH_COMPLEX_VALUES -#cmakedefine DEAL_II_WITH_CUDA #cmakedefine DEAL_II_WITH_GINKGO #cmakedefine DEAL_II_WITH_GMSH #cmakedefine DEAL_II_WITH_GSL @@ -491,9 +490,6 @@ #endif #cmakedefine DEAL_II_MPI_WITH_DEVICE_SUPPORT -#ifdef DEAL_II_MPI_WITH_DEVICE_SUPPORT -#cmakedefine DEAL_II_MPI_WITH_CUDA_SUPPORT -#endif /*********************************************************************** * Two macro names that we put at the top and bottom of all deal.II files diff --git a/include/deal.II/base/cuda.h b/include/deal.II/base/cuda.h deleted file mode 100644 index 782a47e49b..0000000000 --- a/include/deal.II/base/cuda.h +++ /dev/null @@ -1,187 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_h -#define dealii_cuda_h - -#include - -#include -#include - -#ifdef DEAL_II_WITH_CUDA -# include -# include -# include - -# include - -DEAL_II_NAMESPACE_OPEN -namespace Utilities -{ - /** - * A namespace for utility structures for CUDA. - */ - namespace CUDA - { - /** - * Various CUDA APIs need an object to store internal data. This structure - * creates, initializes, stores, and destroys these so-called handles for - * the respective CUDA libraries used inside deal.II. - */ - struct Handle - { - /** - * Constructor. Initialize the handles for the different libraries. - */ - Handle(); - - /** - * Copy constructor is deleted. - */ - Handle(const Handle &) = delete; - - /** - * Destructor. Destroy the handles. - */ - ~Handle(); - - /** - * Pointer to an opaque cuSolverDN context. - * The handle must be passed to every cuSolverDN library function. - */ - cusolverDnHandle_t cusolver_dn_handle; - - /** - * Pointer to an opaque cuSolverSP context. - * The handle must be passed to every cuSolverSP library function. - */ - cusolverSpHandle_t cusolver_sp_handle; - - /** - * Pointer to an opaque cuSPARSE context. - * The handle must be passed to every cuSPARSE library function. - */ - cusparseHandle_t cusparse_handle; - }; - - /** - * Allocate @p n_elements on the @ref GlossDevice "device". - */ - template - inline void - malloc(T *&pointer, const unsigned int n_elements) - { - cudaError_t cuda_error_code = - cudaMalloc(&pointer, n_elements * sizeof(T)); - AssertCuda(cuda_error_code); - } - - /** - * Free memory on the @ref GlossDevice "device". - */ - template - inline void - free(T *&pointer) - { - cudaError_t cuda_error_code = cudaFree(pointer); - AssertCuda(cuda_error_code); - pointer = nullptr; - } - - /** - * Allocator to be used for `std::unique_ptr` pointing to @ref GlossDevice "device" memory. - */ - template - Number * - allocate_device_data(const std::size_t size) - { - Number *device_ptr; - Utilities::CUDA::malloc(device_ptr, size); - return device_ptr; - } - - /** - * Deleter to be used for `std::unique_ptr` pointing to @ref GlossDevice "device" memory. - */ - template - void - delete_device_data(Number *device_ptr) noexcept - { - const cudaError_t error_code = cudaFree(device_ptr); - AssertNothrowCuda(error_code); - } - - /** - * Copy the @ref GlossDevice "device" ArrayView @p in to the host ArrayView @p out. - */ - template - inline void - copy_to_host(const ArrayView &in, - ArrayView &out) - { - AssertDimension(in.size(), out.size()); - cudaError_t cuda_error_code = cudaMemcpy(out.data(), - in.data(), - in.size() * sizeof(T), - cudaMemcpyDeviceToHost); - AssertCuda(cuda_error_code); - } - - /** - * Copy the host ArrayView @p in to the @ref GlossDevice "device" ArrayView @p out. - */ - template - inline void - copy_to_dev(const ArrayView &in, - ArrayView &out) - { - AssertDimension(in.size(), out.size()); - cudaError_t cuda_error_code = cudaMemcpy(out.data(), - in.data(), - in.size() * sizeof(T), - cudaMemcpyHostToDevice); - AssertCuda(cuda_error_code); - } - - /** - * Copy the elements in @p pointer_dev to the host in @p vector_host. - */ - template - inline void - copy_to_host(const T *pointer_dev, std::vector &vector_host) - { - ArrayView in(pointer_dev, vector_host.size()); - auto out = make_array_view(vector_host); - copy_to_host(in, out); - } - - /** - * Copy the elements in @p vector_host to the @ref GlossDevice "device" in @p pointer_dev. The - * memory needs to be allocate on the @ref GlossDevice "device" before this function is called. - */ - template - inline void - copy_to_dev(const std::vector &vector_host, T *pointer_dev) - { - auto in = make_array_view(vector_host); - ArrayView out(pointer_dev, vector_host.size()); - copy_to_dev(in, out); - } - } // namespace CUDA -} // namespace Utilities - -DEAL_II_NAMESPACE_CLOSE -#endif -#endif diff --git a/include/deal.II/base/cuda_size.h b/include/deal.II/base/cuda_size.h deleted file mode 100644 index bac486c1a6..0000000000 --- a/include/deal.II/base/cuda_size.h +++ /dev/null @@ -1,44 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_size_h -#define dealii_cuda_size_h - -#include - -DEAL_II_NAMESPACE_OPEN - -namespace CUDAWrappers -{ - /** - * Define the size of a block when launching a CUDA kernel. This number can be - * changed depending on the architecture the code is running on. - */ - constexpr int block_size = 512; - - /** - * Define the size of chunk of data worked on by a thread. This number can be - * changed depending on the architecture the code is running on. - */ - constexpr int chunk_size = 1; - - /** - * Define the number of threads in a warp. - */ - constexpr int warp_size = 32; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/include/deal.II/base/exceptions.h b/include/deal.II/base/exceptions.h index 95d755470a..ea4b3539bf 100644 --- a/include/deal.II/base/exceptions.h +++ b/include/deal.II/base/exceptions.h @@ -31,11 +31,6 @@ DEAL_II_ENABLE_EXTRA_DIAGNOSTICS #include #include -#ifdef DEAL_II_WITH_CUDA -# include -# include -#endif - DEAL_II_NAMESPACE_OPEN @@ -1198,21 +1193,6 @@ namespace StandardExceptions "if deal.II was configured to use Assimp, but cmake did not " "find a valid Assimp library."); -#ifdef DEAL_II_WITH_CUDA - /** - * This exception is raised if an error happened in a CUDA kernel. - * - * The constructor takes a single char*, the output of - * cudaGetErrorString. - */ - DeclException1(ExcCudaError, const char *, << arg1); - /** - * This exception is raised if an error happened in a cuSPARSE function. - */ - DeclException1(ExcCusparseError, - std::string, - << "There was an error in a cuSPARSE function: " << arg1); -#endif /** @} */ /** @@ -1518,23 +1498,6 @@ namespace deal_II_exceptions // another function: do_issue_error_nothrow(e); } -#ifdef DEAL_II_WITH_CUDA - /** - * Return a string given an error code. This is similar to the - * cudaGetErrorString function but there is no equivalent function for - * cuSPARSE. - */ - std::string - get_cusparse_error_string(const cusparseStatus_t error_code); - - /** - * Return a string given an error code. This is similar to the - * cudaGetErrorString function but there is no equivalent function for - * cuSOLVER. - */ - std::string - get_cusolver_error_string(const cusolverStatus_t error_code); -#endif } /*namespace internals*/ } /*namespace deal_II_exceptions*/ @@ -2174,201 +2137,6 @@ namespace internal while (false) #endif // DEAL_II_WITH_MPI -#ifdef DEAL_II_WITH_CUDA -/** - * An assertion that checks that the error code produced by calling a CUDA - * routine is equal to cudaSuccess. - * - * @note This and similar macro names are examples of preprocessor definitions - * in the deal.II library that are not prefixed by a string that likely makes - * them unique to deal.II. As a consequence, it is possible that other - * libraries your code interfaces with define the same name, and the result - * will be name collisions (see - * https://en.wikipedia.org/wiki/Name_collision). One can \#undef - * this macro, as well as all other macros defined by deal.II that are not - * prefixed with either DEAL or deal, by including - * the header deal.II/base/undefine_macros.h after all other - * deal.II headers have been included. - * - * @ingroup Exceptions - */ -# ifdef DEBUG -# define AssertCuda(error_code) \ - Assert(error_code == cudaSuccess, \ - dealii::ExcCudaError(cudaGetErrorString(error_code))) -# else -# define AssertCuda(error_code) \ - do \ - { \ - (void)(error_code); \ - } \ - while (false) -# endif - -/** - * The non-throwing equivalent of AssertCuda. - * - * @note This and similar macro names are examples of preprocessor definitions - * in the deal.II library that are not prefixed by a string that likely makes - * them unique to deal.II. As a consequence, it is possible that other - * libraries your code interfaces with define the same name, and the result - * will be name collisions (see - * https://en.wikipedia.org/wiki/Name_collision). One can \#undef - * this macro, as well as all other macros defined by deal.II that are not - * prefixed with either DEAL or deal, by including - * the header deal.II/base/undefine_macros.h after all other - * deal.II headers have been included. - * - * @ingroup Exceptions - */ -# ifdef DEBUG -# define AssertNothrowCuda(error_code) \ - AssertNothrow(error_code == cudaSuccess, \ - dealii::ExcCudaError(cudaGetErrorString(error_code))) -# else -# define AssertNothrowCuda(error_code) \ - do \ - { \ - (void)(error_code); \ - } \ - while (false) -# endif - -/** - * An assertion that checks that the kernel was launched and executed - * successfully. - * - * @note This and similar macro names are examples of preprocessor definitions - * in the deal.II library that are not prefixed by a string that likely makes - * them unique to deal.II. As a consequence, it is possible that other - * libraries your code interfaces with define the same name, and the result - * will be name collisions (see - * https://en.wikipedia.org/wiki/Name_collision). One can \#undef - * this macro, as well as all other macros defined by deal.II that are not - * prefixed with either DEAL or deal, by including - * the header deal.II/base/undefine_macros.h after all other - * deal.II headers have been included. - * - * @ingroup Exceptions - */ -# ifdef DEBUG -# define AssertCudaKernel() \ - do \ - { \ - cudaError_t local_error_code = cudaPeekAtLastError(); \ - AssertCuda(local_error_code); \ - local_error_code = cudaDeviceSynchronize(); \ - AssertCuda(local_error_code); \ - } \ - while (false) -# else -# define AssertCudaKernel() \ - do \ - { \ - } \ - while (false) -# endif - -/** - * An assertion that checks that the error code produced by calling a cuSPARSE - * routine is equal to CUSPARSE_STATUS_SUCCESS. - * - * @note This and similar macro names are examples of preprocessor definitions - * in the deal.II library that are not prefixed by a string that likely makes - * them unique to deal.II. As a consequence, it is possible that other - * libraries your code interfaces with define the same name, and the result - * will be name collisions (see - * https://en.wikipedia.org/wiki/Name_collision). One can \#undef - * this macro, as well as all other macros defined by deal.II that are not - * prefixed with either DEAL or deal, by including - * the header deal.II/base/undefine_macros.h after all other - * deal.II headers have been included. - * - * @ingroup Exceptions - */ -# ifdef DEBUG -# define AssertCusparse(error_code) \ - Assert( \ - error_code == CUSPARSE_STATUS_SUCCESS, \ - dealii::ExcCusparseError( \ - dealii::deal_II_exceptions::internals::get_cusparse_error_string( \ - error_code))) -# else -# define AssertCusparse(error_code) \ - do \ - { \ - (void)(error_code); \ - } \ - while (false) -# endif - -/** - * The non-throwing equivalent of AssertCusparse. - * - * @note This and similar macro names are examples of preprocessor definitions - * in the deal.II library that are not prefixed by a string that likely makes - * them unique to deal.II. As a consequence, it is possible that other - * libraries your code interfaces with define the same name, and the result - * will be name collisions (see - * https://en.wikipedia.org/wiki/Name_collision). One can \#undef - * this macro, as well as all other macros defined by deal.II that are not - * prefixed with either DEAL or deal, by including - * the header deal.II/base/undefine_macros.h after all other - * deal.II headers have been included. - * - * @ingroup Exceptions - */ -# ifdef DEBUG -# define AssertNothrowCusparse(error_code) \ - AssertNothrow( \ - error_code == CUSPARSE_STATUS_SUCCESS, \ - dealii::ExcCusparseError( \ - dealii::deal_II_exceptions::internals::get_cusparse_error_string( \ - error_code))) -# else -# define AssertNothrowCusparse(error_code) \ - do \ - { \ - (void)(error_code); \ - } \ - while (false) -# endif - -/** - * An assertion that checks that the error code produced by calling a cuSOLVER - * routine is equal to CUSOLVER_STATUS_SUCCESS. - * - * @note This and similar macro names are examples of preprocessor definitions - * in the deal.II library that are not prefixed by a string that likely makes - * them unique to deal.II. As a consequence, it is possible that other - * libraries your code interfaces with define the same name, and the result - * will be name collisions (see - * https://en.wikipedia.org/wiki/Name_collision). One can \#undef - * this macro, as well as all other macros defined by deal.II that are not - * prefixed with either DEAL or deal, by including - * the header deal.II/base/undefine_macros.h after all other - * deal.II headers have been included. - * - * @ingroup Exceptions - */ -# ifdef DEBUG -# define AssertCusolver(error_code) \ - Assert( \ - error_code == CUSOLVER_STATUS_SUCCESS, \ - dealii::ExcCusparseError( \ - dealii::deal_II_exceptions::internals::get_cusolver_error_string( \ - error_code))) -# else -# define AssertCusolver(error_code) \ - do \ - { \ - (void)(error_code); \ - } \ - while (false) -# endif - -#endif - #ifdef DEAL_II_TRILINOS_WITH_SEACAS /** * Assertion that checks that the error code produced by calling an ExodusII diff --git a/include/deal.II/base/memory_space.h b/include/deal.II/base/memory_space.h index 65346f7cb3..a4a3050d4b 100644 --- a/include/deal.II/base/memory_space.h +++ b/include/deal.II/base/memory_space.h @@ -44,13 +44,6 @@ namespace MemorySpace { using kokkos_space = ::Kokkos::DefaultExecutionSpace::memory_space; }; - -#ifdef DEAL_II_WITH_CUDA - /** - * Structure describing CUDA memory space. - */ - using CUDA = Default; -#endif } // namespace MemorySpace DEAL_II_NAMESPACE_CLOSE diff --git a/include/deal.II/base/memory_space_data.h b/include/deal.II/base/memory_space_data.h index b398087b3b..ace1182b85 100644 --- a/include/deal.II/base/memory_space_data.h +++ b/include/deal.II/base/memory_space_data.h @@ -18,7 +18,7 @@ #include -#include +#include #include #include @@ -35,9 +35,8 @@ namespace MemorySpace { /** * Structure which stores data on the host or the @ref GlossDevice "device" depending on the - * template parameter @p MemorySpace. Valid choices are MemorySpace::Host, - * MemorySpace::Default, and MemorySpace::CUDA (if CUDA was enabled in - * deal.II). The data is copied into the structure which then owns the data + * template parameter @p MemorySpace. Valid choices are MemorySpace::Host and MemorySpace::Default. + * The data is copied into the structure which then owns the data * and will release the memory when the destructor is called. */ template diff --git a/include/deal.II/base/numbers.h b/include/deal.II/base/numbers.h index a95bfd201f..245e857505 100644 --- a/include/deal.II/base/numbers.h +++ b/include/deal.II/base/numbers.h @@ -20,10 +20,6 @@ #include -#ifdef DEAL_II_WITH_CUDA -# include -#endif - #include #include @@ -32,7 +28,6 @@ #include #define DEAL_II_HOST_DEVICE KOKKOS_FUNCTION -#define DEAL_II_CUDA_HOST_DEV DEAL_II_HOST_DEVICE #define DEAL_II_HOST_DEVICE_ALWAYS_INLINE KOKKOS_FORCEINLINE_FUNCTION // clang++ assumes that all constexpr functions are __host__ __device__ when @@ -775,27 +770,6 @@ namespace internal } }; -#ifdef DEAL_II_WITH_CUDA - template <> - struct NumberType - { - static cuComplex - value(const float t) - { - return make_cuComplex(t, 0.f); - } - }; - - template <> - struct NumberType - { - static cuDoubleComplex - value(const double t) - { - return make_cuDoubleComplex(t, 0.); - } - }; -#endif } // namespace internal namespace numbers diff --git a/include/deal.II/base/undefine_macros.h b/include/deal.II/base/undefine_macros.h index df7290e53c..45cc723c65 100644 --- a/include/deal.II/base/undefine_macros.h +++ b/include/deal.II/base/undefine_macros.h @@ -25,14 +25,6 @@ # undef AssertARKode #endif // #ifdef AssertARKode -#ifdef AssertCuda -# undef AssertCuda -#endif // #ifdef AssertCuda - -#ifdef AssertCudaKernel -# undef AssertCudaKernel -#endif // #ifdef AssertCudaKernel - #ifdef AssertCusolver # undef AssertCusolver #endif // #ifdef AssertCusolver @@ -65,10 +57,6 @@ # undef AssertNothrow #endif // #ifdef AssertNothrow -#ifdef AssertNothrowCuda -# undef AssertNothrowCuda -#endif // #ifdef AssertNothrowCuda - #ifdef AssertNothrowCusparse # undef AssertNothrowCusparse #endif // #ifdef AssertNothrowCusparse diff --git a/include/deal.II/lac/cuda_atomic.h b/include/deal.II/lac/cuda_atomic.h deleted file mode 100644 index 9fff028e94..0000000000 --- a/include/deal.II/lac/cuda_atomic.h +++ /dev/null @@ -1,83 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2016 - 2022 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_atomic_h -#define dealii_cuda_atomic_h - -#include - -#ifdef DEAL_II_WITH_CUDA - -DEAL_II_NAMESPACE_OPEN - -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - /** - * Provide atomicMax for floats. - * - * @ingroup CUDAWrappers - */ - inline __device__ float - atomicMax_wrapper(float *address, float val) - { - int *address_as_int = reinterpret_cast(address); - int old = *address_as_int, assumed; - do - { - assumed = old; - old = atomicCAS(address_as_int, - assumed, - atomicMax(address_as_int, __float_as_int(val))); - } - while (assumed != old); - - return __longlong_as_double(old); - } - - - - /** - * Provide atomicMax for doubles. - * - * @ingroup CUDAWrappers - */ - inline __device__ double - atomicMax_wrapper(double *address, double val) - { - unsigned long long int *address_as_ull = - reinterpret_cast(address); - unsigned long long int old = *address_as_ull, assumed; - do - { - assumed = old; - old = atomicCAS(address_as_ull, - assumed, - atomicMax(address_as_ull, - static_cast( - __double_as_longlong(val)))); - } - while (assumed != old); - - return __longlong_as_double(old); - } - } // namespace CUDAWrappers -} // namespace LinearAlgebra - -DEAL_II_NAMESPACE_CLOSE - -#endif - -#endif diff --git a/include/deal.II/lac/cuda_kernels.h b/include/deal.II/lac/cuda_kernels.h deleted file mode 100644 index 9482670604..0000000000 --- a/include/deal.II/lac/cuda_kernels.h +++ /dev/null @@ -1,516 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_kernels_h -#define dealii_cuda_kernels_h - -#include - -#ifdef DEAL_II_WITH_CUDA - - -# include -# include - -# include - -# include - -DEAL_II_NAMESPACE_OPEN - -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - /** - * Namespace containing the CUDA kernels. - */ - namespace kernel - { - using ::dealii::CUDAWrappers::block_size; - using ::dealii::CUDAWrappers::chunk_size; - using ::dealii::CUDAWrappers::warp_size; - using size_type = types::global_dof_index; - - /** - * Multiply each entry of @p val of size @p N by @p a. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - vec_scale(Number *val, const Number a, const size_type N); - - - - /** - * Functor defining the addition of two Numbers. - * - * @ingroup CUDAWrappers - */ - template - struct Binop_Addition - { - __device__ static inline Number - operation(const Number a, const Number b) - { - return a + b; - } - }; - - template - struct Binop_Addition> - { - __device__ static inline std::complex - operation(const std::complex a, const std::complex) - { - printf("This function is not implemented for std::complex!"); - assert(false); - return a; - } - }; - - - - /** - * Functor defining the subtraction of two Numbers. - * - * @ingroup CUDAWrappers - */ - template - struct Binop_Subtraction - { - __device__ static inline Number - operation(const Number a, const Number b) - { - return a - b; - } - }; - - template - struct Binop_Subtraction> - { - __device__ static inline std::complex - operation(const std::complex a, - const std::complex /*b*/) - { - printf("This function is not implemented for std::complex!"); - assert(false); - return a; - } - }; - - - - /** - * Functor defining the maximum of two Numbers. - * - * @ingroup CUDAWrappers - */ - template - struct Binop_Max - { - __device__ static inline Number - operation(const Number a, const Number b) - { - return a > b ? a : b; - } - }; - - template - struct Binop_Max> - { - __device__ static inline std::complex - operation(const std::complex a, const std::complex) - { - printf("This function is not implemented for std::complex!"); - assert(false); - return a; - } - }; - - - - /** - * Functor defining the maximum of two Numbers. - * - * @ingroup CUDAWrappers - */ - template - struct Binop_Min - { - __device__ static inline Number - operation(const Number a, const Number b) - { - return a > b ? b : a; - } - }; - - template - struct Binop_Min> - { - __device__ static inline std::complex - operation(const std::complex a, const std::complex) - { - printf("This function is not implemented for std::complex!"); - assert(false); - return a; - } - }; - - - - /** - * Apply the functor @p Binop to each element of @p v1 and @p v2. - * - * @ingroup CUDAWrappers - */ - template class Binop> - __global__ void - vector_bin_op(Number *v1, const Number *v2, const size_type N); - - - - /** - * Apply the functor @p Binop to the elements of @p v1 that have - * indices in @p mask and @p v2. The size of @p mask should be greater - * than the size of @p v1. @p mask and @p v2 should have the same size @p - * N. - * - * @ingroup CUDAWrappers - */ - template class Binop> - __global__ void - masked_vector_bin_op(const unsigned int *mask, - Number *v1, - const Number *v2, - const size_type N); - - - - /** - * Structure implementing the functions used to add elements when - * using a reduction. - * - * @ingroup CUDAWrappers - */ - template - struct ElemSum - { - __device__ static Number - reduction_op(const Number a, const Number b); - - __device__ static Number - atomic_op(Number *dst, const Number a); - - __device__ static Number - element_wise_op(const Number a); - - __device__ static Number - null_value(); - }; - - - - /** - * Structure implementing the functions used to compute the L1 norm - * when using a reduction. - * - * @ingroup CUDAWrappers - */ - template - struct L1Norm - { - __device__ static Number - reduction_op(const Number a, const Number b); - - __device__ static Number - atomic_op(Number *dst, const Number a); - - __device__ static Number - element_wise_op(const Number a); - - __device__ static Number - null_value(); - }; - - - - /** - * Structure implementing the functions used to compute the L-infinity - * norm when using a reduction. - * - * @ingroup CUDAWrappers - */ - template - struct LInfty - { - __device__ static Number - reduction_op(const Number a, const Number b); - - __device__ static Number - atomic_op(Number *dst, const Number a); - - __device__ static Number - element_wise_op(const Number a); - - __device__ static Number - null_value(); - }; - - - - /** - * Perform a reduction on @p v using @p Operation. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - reduction(Number *result, const Number *v, const size_type N); - - - - /** - * Structure implementing the functions used to compute the dot - * product norm when using a double vector reduction. - * - * @ingroup CUDAWrappers - */ - template - struct DotProduct - { - __device__ static Number - binary_op(const Number a, const Number b); - - __device__ static Number - reduction_op(const Number a, const Number b); - - __device__ static Number - atomic_op(Number *dst, const Number a); - - __device__ static Number - null_value(); - }; - - - - /** - * Perform a binary operation on each element of @p v1 and @p v2 followed - * by reduction on the resulting array. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - double_vector_reduction(Number *result, - const Number *v1, - const Number *v2, - const size_type N); - - - - /** - * Add @p a to each element of @p val. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - vec_add(Number *val, const Number a, const size_type N); - - - - /** - * Addition of a multiple of a vector, i.e., val += a*V_val. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - add_aV(Number *val, - const Number a, - const Number *V_val, - const size_type N); - - - - /** - * Addition of multiple scaled vector, i.e., val += a*V_val + - * b*W_val. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - add_aVbW(Number *val, - const Number a, - const Number *V_val, - const Number b, - const Number *W_val, - const size_type N); - - - - /** - * Scaling and simple addition of a multiple of a vector, i.e. val - * = = s*val + a*V_val - * - * @ingroup CUDAWrappers - */ - template - __global__ void - sadd(const Number s, - Number *val, - const Number a, - const Number *V_val, - const size_type N); - - - - /** - * Scaling and multiple additions of scaled vectors, i.e. val = - * = s*val + a*V_val + b*W_val - * - * @ingroup CUDAWrappers - */ - template - __global__ void - sadd(const Number s, - Number *val, - const Number a, - const Number *V_val, - const Number b, - const Number *W_val, - const size_type N); - - - - /** - * Scale each element of this vector by the corresponding element in - * the argument. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - scale(Number *val, const Number *V_val, const size_type N); - - - - /** - * Assignment val = a*V_val. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - equ(Number *val, const Number a, const Number *V_val, const size_type N); - - - - /** - * Assignment val = a*V_val + b*W_val. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - equ(Number *val, - const Number a, - const Number *V_val, - const Number b, - const Number *W_val, - const size_type N); - - - - /** - * Perform a combined operation of a vector addition and a subsequent - * inner product, returning the value of the inner product. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - add_and_dot(Number *res, - Number *v1, - const Number *v2, - const Number *v3, - const Number a, - const size_type N); - - - - /** - * Set each element of @p val to @p s. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - set(Number *val, const Number s, const size_type N); - - - /** - * Set each element in @p val to @p v using @p indices as permutation, i.e., - * val[indices[i]] = v[i]. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - set_permutated(const IndexType *indices, - Number *val, - const Number *v, - const IndexType N); - - - - /** - * Set each element in @p val to @p v using @p indices as permutation, i.e., - * val[i] = v[indices[i]]. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - gather(Number *val, - const IndexType *indices, - const Number *v, - const IndexType N); - - - - /** - * Add each element in @p val to @p v using @p indices as permutation, i.e., - * val[indices[i]] += v[i]. - * - * @ingroup CUDAWrappers - */ - template - __global__ void - add_permutated(const size_type *indices, - Number *val, - const Number *v, - const size_type N); - } // namespace kernel - } // namespace CUDAWrappers -} // namespace LinearAlgebra - -DEAL_II_NAMESPACE_CLOSE - -#endif - -#endif diff --git a/include/deal.II/lac/cuda_kernels.templates.h b/include/deal.II/lac/cuda_kernels.templates.h deleted file mode 100644 index 6e92d9013b..0000000000 --- a/include/deal.II/lac/cuda_kernels.templates.h +++ /dev/null @@ -1,592 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_kernels_templates_h -#define dealii_cuda_kernels_templates_h - -#include - -#include - -#ifdef DEAL_II_WITH_CUDA - -DEAL_II_NAMESPACE_OPEN - -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - namespace kernel - { - template - __global__ void - vec_scale(Number *val, const Number a, const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] *= a; - } - } - - - - template class Binop> - __global__ void - vector_bin_op(Number *v1, const Number *v2, const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - v1[idx] = Binop::operation(v1[idx], v2[idx]); - } - } - - - - template class Binop> - __global__ void - masked_vector_bin_op(const unsigned int *mask, - Number *v1, - const Number *v2, - const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - v1[mask[idx]] = Binop::operation(v1[mask[idx]], v2[idx]); - } - } - - - template - __device__ Number - ElemSum::reduction_op(const Number a, const Number b) - { - return (a + b); - } - - - - template - __device__ Number - ElemSum::atomic_op(Number *dst, const Number a) - { - return atomicAdd(dst, a); - } - - - - template - __device__ Number - ElemSum::element_wise_op(const Number a) - { - return a; - } - - - - template - __device__ Number - ElemSum::null_value() - { - return Number(); - } - - - - template - __device__ Number - L1Norm::reduction_op(const Number a, const Number b) - { - return (a + b); - } - - - - template - __device__ Number - L1Norm::atomic_op(Number *dst, const Number a) - { - return atomicAdd(dst, a); - } - - - - template - __device__ Number - L1Norm::element_wise_op(const Number a) - { - return std::fabs(a); - } - - - - template - __device__ Number - L1Norm::null_value() - { - return Number(); - } - - - - template - __device__ Number - LInfty::reduction_op(const Number a, const Number b) - { - if (a > b) - return a; - else - return b; - } - - - - template - __device__ Number - LInfty::atomic_op(Number *dst, const Number a) - { - return atomicMax_wrapper(dst, a); - } - - - - template - __device__ Number - LInfty::element_wise_op(const Number a) - { - return std::fabs(a); - } - - - - template - __device__ Number - LInfty::null_value() - { - return Number(); - } - - - - template - __device__ void - reduce(Number *result, - volatile Number *result_buffer, - const size_type local_idx, - const size_type /*global_idx*/, - const size_type /*N*/) - { - for (size_type s = block_size / 2; s > warp_size; s = s >> 1) - { - if (local_idx < s) - result_buffer[local_idx] = - Operation::reduction_op(result_buffer[local_idx], - result_buffer[local_idx + s]); - __syncthreads(); - } - - if (local_idx < warp_size) - { - for (size_type s = warp_size; s > 0; s = s >> 1) - { - result_buffer[local_idx] = - Operation::reduction_op(result_buffer[local_idx], - result_buffer[local_idx + s]); - } - } - - if (local_idx == 0) - Operation::atomic_op(result, result_buffer[0]); - } - - - - template - __global__ void - reduction(Number *result, const Number *v, const size_type N) - { - __shared__ Number result_buffer[block_size]; - - const size_type global_idx = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - const size_type local_idx = threadIdx.x; - - if (global_idx < N) - result_buffer[local_idx] = Operation::element_wise_op(v[global_idx]); - else - result_buffer[local_idx] = Operation::null_value(); - - __syncthreads(); - - reduce( - result, result_buffer, local_idx, global_idx, N); - } - - - - template - __device__ Number - DotProduct::binary_op(const Number a, const Number b) - { - return a * b; - } - - - - template - __device__ Number - DotProduct::reduction_op(const Number a, const Number b) - { - return a + b; - } - - - - template - __device__ Number - DotProduct::atomic_op(Number *dst, const Number a) - { - return atomicAdd(dst, a); - } - - - - template - __device__ Number - DotProduct::null_value() - { - return Number(); - } - - - - template - __global__ void - double_vector_reduction(Number *result, - const Number *v1, - const Number *v2, - const size_type N) - { - __shared__ Number result_buffer[block_size]; - - const size_type global_idx = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - const size_type local_idx = threadIdx.x; - - if (global_idx < N) - result_buffer[local_idx] = - Operation::binary_op(v1[global_idx], v2[global_idx]); - else - result_buffer[local_idx] = Operation::null_value(); - - for (unsigned int i = 1; i < chunk_size; ++i) - { - const size_type idx = global_idx + i * block_size; - if (idx < N) - result_buffer[local_idx] = - Operation::reduction_op(result_buffer[local_idx], - Operation::binary_op(v1[idx], v2[idx])); - } - - __syncthreads(); - - reduce( - result, result_buffer, local_idx, global_idx, N); - } - - - - template - __global__ void - vec_add(Number *val, const Number a, const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] += a; - } - } - - - - template - __global__ void - add_aV(Number *val, - const Number a, - const Number *V_val, - const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] += a * V_val[idx]; - } - } - - - - template - __global__ void - add_aVbW(Number *val, - const Number a, - const Number *V_val, - const Number b, - const Number *W_val, - const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] += a * V_val[idx] + b * W_val[idx]; - } - } - - - - template - __global__ void - sadd(const Number s, - Number *val, - const Number a, - const Number *V_val, - const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] = s * val[idx] + a * V_val[idx]; - } - } - - - - template - __global__ void - sadd(const Number s, - Number *val, - const Number a, - const Number *V_val, - const Number b, - const Number *W_val, - const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] = s * val[idx] + a * V_val[idx] + b * W_val[idx]; - } - } - - - - template - __global__ void - scale(Number *val, const Number *V_val, const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] *= V_val[idx]; - } - } - - - - template - __global__ void - equ(Number *val, const Number a, const Number *V_val, const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] = a * V_val[idx]; - } - } - - - - template - __global__ void - equ(Number *val, - const Number a, - const Number *V_val, - const Number b, - const Number *W_val, - const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] = a * V_val[idx] + b * W_val[idx]; - } - } - - - - template - __global__ void - add_and_dot(Number *res, - Number *v1, - const Number *v2, - const Number *v3, - const Number a, - const size_type N) - { - __shared__ Number res_buf[block_size]; - - const unsigned int global_idx = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - const unsigned int local_idx = threadIdx.x; - if (global_idx < N) - { - v1[global_idx] += a * v2[global_idx]; - res_buf[local_idx] = - v1[global_idx] * - Number(numbers::NumberTraits::conjugate(v3[global_idx])); - } - else - res_buf[local_idx] = 0.; - - for (unsigned int i = 1; i < chunk_size; ++i) - { - const unsigned int idx = global_idx + i * block_size; - if (idx < N) - { - v1[idx] += a * v2[idx]; - res_buf[local_idx] += v1[idx] * v3[idx]; - } - } - - __syncthreads(); - - reduce>( - res, res_buf, local_idx, global_idx, N); - } - - - - template - __global__ void - set(Number *val, const Number s, const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[idx] = s; - } - } - - - - template - __global__ void - set_permutated(const IndexType *indices, - Number *val, - const Number *v, - const IndexType N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[indices[idx]] = v[idx]; - } - } - - - - template - __global__ void - gather(Number *val, - const IndexType *indices, - const Number *v, - const IndexType N) - { - const IndexType idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const IndexType idx = idx_base + i * block_size; - if (idx < N) - val[idx] = v[indices[idx]]; - } - } - - - - template - __global__ void - add_permutated(const size_type *indices, - Number *val, - const Number *v, - const size_type N) - { - const size_type idx_base = - threadIdx.x + blockIdx.x * (blockDim.x * chunk_size); - for (unsigned int i = 0; i < chunk_size; ++i) - { - const size_type idx = idx_base + i * block_size; - if (idx < N) - val[indices[idx]] += v[idx]; - } - } - } // namespace kernel - } // namespace CUDAWrappers -} // namespace LinearAlgebra - -DEAL_II_NAMESPACE_CLOSE - -#endif - -#endif diff --git a/include/deal.II/lac/cuda_precondition.h b/include/deal.II/lac/cuda_precondition.h deleted file mode 100644 index 213386ade4..0000000000 --- a/include/deal.II/lac/cuda_precondition.h +++ /dev/null @@ -1,521 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_precondition_h -#define dealii_cuda_precondition_h - -#include - -#include -#include - -#include - -#ifdef DEAL_II_WITH_CUDA - -DEAL_II_NAMESPACE_OPEN - -// forward-definition -# ifndef DOXYGEN -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - template - class Vector; - } -} // namespace LinearAlgebra -# endif - -namespace CUDAWrappers -{ - // forward definition - template - class SparseMatrix; - - /** - * This class implements an incomplete Cholesky factorization (IC) - * preconditioner for @em symmetric CUDAWrappers::SparseMatrix matrices. - * - * The implementation closely follows the one documented in the cuSPARSE - * documentation - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csric02). - * - * @note Instantiations for this template are provided for @ and - * @. - * - * @ingroup Preconditioners CUDAWrappers - */ - template - class PreconditionIC - { - public: - /** - * Declare the type for container size. - */ - using size_type = int; - - /** - * Standardized data struct to pipe additional flags to the - * preconditioner. - */ - struct AdditionalData - { - /** - * Constructor. cuSPARSE allows to compute and use level information. - * According to the documentation this might improve performance. - * It is suggested to try both options. - */ - AdditionalData(bool use_level_analysis = true); - - /** - * Flag that determines if level information is used when creating and - * applying the preconditioner. See the documentation for - * cusparseSolvePolicy_t at - * https://docs.nvidia.com/cuda/cusparse/index.html#cusparsesolvepolicy_t - * for more information. - */ - bool use_level_analysis; - }; - - /** - * Constructor. - */ - PreconditionIC(const Utilities::CUDA::Handle &handle); - - /** - * The copy constructor is deleted. - */ - PreconditionIC(const PreconditionIC &) = delete; - - /** - * The copy assignment operator is deleted. - */ - PreconditionIC & - operator=(const PreconditionIC &) = delete; - - /** - * Destructor. Free all resources that were initialized in this class. - */ - ~PreconditionIC(); - - /** - * Initialize this object. In particular, the given matrix is copied to be - * modified in-place. For the underlying sparsity pattern pointers are - * stored. Specifically, this means - * that the current object can only be used reliably as long as @p matrix is valid - * and has not been changed since calling this function. - * - * The @p additional_data determines if level information are used. - */ - void - initialize(const SparseMatrix &matrix, - const AdditionalData &additional_data = AdditionalData()); - - /** - * Apply the preconditioner. - */ - void - vmult(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Apply the preconditioner. Since the preconditioner is symmetric, this - * is the same as vmult(). - */ - void - Tvmult(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Return the dimension of the codomain (or range) space. Note that the - * matrix is square and has dimension $m \times m$. - * - * @note This function should only be called if the preconditioner has been - * initialized. - */ - size_type - m() const; - - /** - * Return the dimension of the codomain (or range) space. Note that the - * matrix is square and has dimension $n \times n$. - * - * @note This function should only be called if the preconditioner has been - * initialized. - */ - size_type - n() const; - - private: - /** - * cuSPARSE handle used to call cuSPARSE functions. - */ - cusparseHandle_t cusparse_handle; - - /** - * cuSPARSE description of the sparse matrix $M=LL^T$. - */ - cusparseMatDescr_t descr_M; - - /** - * cuSPARSE description of the lower triangular matrix $L$. - */ - cusparseMatDescr_t descr_L; - - /** - * Solve and analysis structure for $M=LL^T$. - */ - csric02Info_t info_M; - - /** - * Solve and analysis structure for the lower triangular matrix $L$. - */ - csrsv2Info_t info_L; - - /** - * Solve and analysis structure for the upper triangular matrix $L^T$. - */ - csrsv2Info_t info_Lt; - - /** - * Pointer to the matrix this object was initialized with. - */ - SmartPointer> matrix_pointer; - - /** - * Pointer to the values (on the @ref GlossDevice "device") of the computed preconditioning - * matrix. - */ - std::unique_ptr P_val_dev; - - /** - * Pointer to the row pointer (on the @ref GlossDevice "device") of the sparse matrix this - * object was initialized with. Guarded by matrix_pointer. - */ - const int *P_row_ptr_dev; - - /** - * Pointer to the column indices (on the @ref GlossDevice "device") of the sparse matrix this - * object was initialized with. Guarded by matrix_pointer. - */ - const int *P_column_index_dev; - - /** - * Pointer to the value (on the @ref GlossDevice "device") for a temporary (helper) vector - * used in vmult(). - */ - std::unique_ptr tmp_dev; - - /** - * Pointer to an internal buffer (on the @ref GlossDevice "device") that is used for - * computing the decomposition. - */ - std::unique_ptr buffer_dev; - - /** - * Determine if level information should be generated for the lower - * triangular matrix $L$. This value can be modified through an - * AdditionalData object. - */ - cusparseSolvePolicy_t policy_L; - - /** - * Determine if level information should be generated for the upper - * triangular matrix $L^T$. This value can be modified through an - * AdditionalData object. - */ - cusparseSolvePolicy_t policy_Lt; - - /** - * Determine if level information should be generated for $M=LL^T$. This - * value can be modified through an AdditionalData object. - */ - cusparseSolvePolicy_t policy_M; - - /** - * The number of rows is the same as for the matrix this object has been - * initialized with. - */ - int n_rows; - - /** - * The number of non-zero elements is the same as for the matrix this - * object has been initialized with. - */ - int n_nonzero_elements; - }; - - /** - * This class implements an incomplete LU factorization preconditioner for - * CUDAWrappers::SparseMatrix matrices. - * - * The implementation closely follows the one documented in the cuSPARSE - * documentation - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csrilu02). - * - * @note Instantiations for this template are provided for @ and - * @. - * - * @ingroup Preconditioners CUDAWrappers - */ - template - class PreconditionILU - { - public: - /** - * Declare the type for container size. - */ - using size_type = int; - - /** - * Standardized data struct to pipe additional flags to the - * preconditioner. - */ - struct AdditionalData - { - /** - * Constructor. cuSPARSE allows to compute and use level information. - * to the documentation this might improve performance. - * It is suggested to try both options. - */ - AdditionalData(bool use_level_analysis = true); - - /** - * Flag that determines if level information is used when creating and - * applying the preconditioner. See the documentation for - * cusparseSolvePolicy_t at - * https://docs.nvidia.com/cuda/cusparse/index.html#cusparsesolvepolicy_t - * for more information. - */ - bool use_level_analysis; - }; - - /** - * Constructor. - */ - PreconditionILU(const Utilities::CUDA::Handle &handle); - - /** - * The copy constructor is deleted. - */ - PreconditionILU(const PreconditionILU &) = delete; - - /** - * The copy assignment operator is deleted. - */ - PreconditionILU & - operator=(const PreconditionILU &) = delete; - - /** - * Destructor. Free all resources that were initialized in this class. - */ - ~PreconditionILU(); - - /** - * Initialize this object. In particular, the given matrix is copied to be - * modified in-place. For the underlying sparsity pattern pointers are - * stored. Specifically, this means - * that the current object can only be used reliably as long as @p matrix is valid - * and has not been changed since calling this function. - * - * The @p additional_data determines if level information are used. - */ - void - initialize(const SparseMatrix &matrix, - const AdditionalData &additional_data = AdditionalData()); - - /** - * Apply the preconditioner. - */ - void - vmult(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Apply the transposed preconditioner. Not yet implemented. - */ - void - Tvmult(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Return the dimension of the codomain (or range) space. Note that the - * matrix is square and has dimension $m \times m$. - * - * @note This function should only be called if the preconditioner has been - * initialized. - */ - size_type - m() const; - - /** - * Return the dimension of the codomain (or range) space. Note that the - * matrix is square and has dimension $n \times n$. - * - * @note This function should only be called if the preconditioner has been - * initialized. - */ - size_type - n() const; - - private: - /** - * cuSPARSE handle used to call cuSPARSE functions. - */ - cusparseHandle_t cusparse_handle; - - /** - * cuSPARSE description of the sparse matrix $M=LU$. - */ - cusparseMatDescr_t descr_M; - - /** - * cuSPARSE description of the lower triangular matrix $L$. - */ - cusparseMatDescr_t descr_L; - - /** - * cuSPARSE description of the upper triangular matrix $U$. - */ - cusparseMatDescr_t descr_U; - - /** - * Solve and analysis structure for $M=LU$. - */ - csrilu02Info_t info_M; - - /** - * Solve and analysis structure for the lower triangular matrix $L$. - */ - csrsv2Info_t info_L; - - /** - * Solve and analysis structure for the upper triangular matrix $U$. - */ - csrsv2Info_t info_U; - - /** - * Pointer to the matrix this object was initialized with. - */ - SmartPointer> matrix_pointer; - - /** - * Pointer to the values (on the @ref GlossDevice "device") of the computed preconditioning - * matrix. - */ - std::unique_ptr P_val_dev; - - /** - * Pointer to the row pointer (on the @ref GlossDevice "device") of the sparse matrix this - * object was initialized with. Guarded by matrix_pointer. - */ - const int *P_row_ptr_dev; - - /** - * Pointer to the column indices (on the @ref GlossDevice "device") of the sparse matrix this - * object was initialized with. Guarded by matrix_pointer. - */ - const int *P_column_index_dev; - - /** - * Pointer to the value (on the @ref GlossDevice "device") for a temporary (helper) vector - * used in vmult(). - */ - std::unique_ptr tmp_dev; - - /** - * Pointer to an internal buffer (on the @ref GlossDevice "device") that is used for - * computing the decomposition. - */ - std::unique_ptr buffer_dev; - - /** - * Determine if level information should be generated for the lower - * triangular matrix $L$. This value can be modified through an - * AdditionalData object. - */ - cusparseSolvePolicy_t policy_L; - - /** - * Determine if level information should be generated for the upper - * triangular matrix $U$. This value can be modified through an - * AdditionalData object. - */ - cusparseSolvePolicy_t policy_U; - - /** - * Determine if level information should be generated for $M=LU$. This - * value can be modified through an AdditionalData object. - */ - cusparseSolvePolicy_t policy_M; - - /** - * The number of rows is the same as for the matrix this object has been - * initialized with. - */ - int n_rows; - - /** - * The number of non-zero elements is the same as for the matrix this - * object has been initialized with. - */ - int n_nonzero_elements; - }; - - /*--------------------------- inline functions ----------------------------*/ - -# ifndef DOXYGEN - template - inline typename PreconditionIC::size_type - PreconditionIC::m() const - { - return n_rows; - } - - - - template - inline typename PreconditionIC::size_type - PreconditionIC::n() const - { - return n_rows; - } - - - - template - inline typename PreconditionILU::size_type - PreconditionILU::m() const - { - return n_rows; - } - - - - template - inline typename PreconditionILU::size_type - PreconditionILU::n() const - { - return n_rows; - } -# endif // DOXYGEN - -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif // DEAL_II_WITH_CUDA - -#endif // dealii_cuda_precondition_h diff --git a/include/deal.II/lac/cuda_solver_direct.h b/include/deal.II/lac/cuda_solver_direct.h deleted file mode 100644 index e5948e9392..0000000000 --- a/include/deal.II/lac/cuda_solver_direct.h +++ /dev/null @@ -1,118 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_solver_direct_h -#define dealii_cuda_solver_direct_h - -#include - -#ifdef DEAL_II_WITH_CUDA -# include - -# include -# include -# include - -DEAL_II_NAMESPACE_OPEN - -namespace CUDAWrappers -{ - /** - * Direct solvers. These solvers call cuSOLVER underneath. - * - * @note Instantiations for this template are provided for @ - * and @. - * - * @ingroup CUDAWrappers - */ - template - class SolverDirect - { - public: - /** - * Struct for additional settings for SolverDirect. - */ - struct AdditionalData - { - /** - * Set the additional data field to the desired solver. - */ - explicit AdditionalData(const std::string &solver_type = "LU_dense"); - - /** - * Set the solver type. Possibilities are: - *

- */ - std::string solver_type; - }; - - /** - * Constructor. Takes the solver control object and creates the solver. - */ - SolverDirect(const Utilities::CUDA::Handle &handle, - SolverControl &cn, - const AdditionalData &data = AdditionalData()); - - /** - * Destructor. - */ - virtual ~SolverDirect() = default; - - /** - * Solve the linear system Ax=b. - */ - void - solve(const SparseMatrix &A, - LinearAlgebra::CUDAWrappers::Vector &x, - const LinearAlgebra::CUDAWrappers::Vector &b); - - /** - * Access to object that controls convergence. - */ - SolverControl & - control() const; - - private: - /** - * Handle - */ - const Utilities::CUDA::Handle &cuda_handle; - - /** - * Reference to the object that controls convergence of the iterative - * solver. In fact, for these CUDA wrappers, cuSOLVER and cuSPARSE do so - * themselves, but we copy the data from this object before starting the - * solution process, and copy the data back into it afterwards. - */ - SolverControl &solver_control; - - /** - * Store a copy of the flags for this particular solver. - */ - const AdditionalData additional_data; - }; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif - -#endif diff --git a/include/deal.II/lac/cuda_sparse_matrix.h b/include/deal.II/lac/cuda_sparse_matrix.h deleted file mode 100644 index bda2f88066..0000000000 --- a/include/deal.II/lac/cuda_sparse_matrix.h +++ /dev/null @@ -1,531 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_sparse_matrix_h -#define dealii_cuda_sparse_matrix_h - -#include - -#include - -#include - -#ifdef DEAL_II_WITH_CUDA -# include - -# include -# include - -# include - -DEAL_II_NAMESPACE_OPEN - -namespace CUDAWrappers -{ - /** - * This class is a wrapper around cuSPARSE csr sparse matrix. Unlike deal.II's - * own SparseMatrix all elements within each row are stored in increasing - * column index order. - * - * @note Instantiations for this template are provided for @ and - * @. - * - * @ingroup Matrix1 - */ - template - class SparseMatrix : public virtual Subscriptor - { - public: - /** - * Declare type for container size. - */ - using size_type = int; - - /** - * Type of the matrix entries. - */ - using value_type = Number; - - /** - * Declare a type that holds real-valued numbers with the same precision - * as the template argument to this class. - */ - using real_type = Number; - - /** - * @name Constructors and initialization - */ - /** @{ */ - /** - * Constructor. Initialize the matrix to be empty, without any structure, - * i.e., the matrix is not usable at all. This constructor is therefore - * only useful for matrices which are members of a class. - * - * You have to initialize the matrix before usage with reinit. - */ - SparseMatrix(); - - /** - * Constructor. Takes a Utilities::CUDA::Handle and a sparse matrix on the - * host. The sparse matrix on the host is copied on the @ref GlossDevice "device" and the - * elements are reordered according to the format supported by cuSPARSE. - */ - SparseMatrix(Utilities::CUDA::Handle &handle, - const ::dealii::SparseMatrix &sparse_matrix_host); - - /** - * Move constructor. Create a new SparseMatrix by stealing the internal - * data. - */ - SparseMatrix(CUDAWrappers::SparseMatrix &&); - - /** - * Copy constructor is deleted. - */ - SparseMatrix(const CUDAWrappers::SparseMatrix &) = delete; - - /** - * Destructor. Free all memory. - */ - ~SparseMatrix(); - - /** - * Move assignment operator. - */ - SparseMatrix & - operator=(CUDAWrappers::SparseMatrix &&); - - /** - * Copy assignment is deleted. - */ - SparseMatrix & - operator=(const CUDAWrappers::SparseMatrix &) = delete; - - /** - * Reinitialize the sparse matrix. The sparse matrix on the host is copied - * to the @ref GlossDevice "device" and the elementes are reordered according to the format - * supported by cuSPARSE. - */ - void - reinit(Utilities::CUDA::Handle &handle, - const ::dealii::SparseMatrix &sparse_matrix_host); - /** @} */ - - /** - * @name Information on the matrix - */ - /** @{ */ - /** - * Return the dimension of the codomain (or range) space. Note that the - * matrix is of dimension $m \times n$. - */ - size_type - m() const; - - /** - * Return the dimension of the domain space. Note that the matrix is of - * dimension $m \times n$. - */ - size_type - n() const; - - /** - * Return the number of nonzero elements of this matrix. Actually, it - * returns the number of entries in the sparsity pattern; if any of the - * entries should happen to be zero, it is counted anyway. - */ - std::size_t - n_nonzero_elements() const; - - /** - * Print the matrix to the given stream, using the format (row,column) - * value, i.e. one nonzero entry of the matrix per line. If - * across is true, print all entries on a single line, using the - * format row,column:value. - * - * If the argument diagonal_first is true, diagonal elements of - * quadratic matrices are printed first in their row. If it is false, - * the elements in a row are written in ascending column order. - */ - template - void - print(StreamType &out, - const bool across = false, - const bool diagonal_first = true) const; - - /** - * Print the matrix in the usual format, i.e., as a matrix and not as a list - * of nonzero elements. For better readability, elements not in the matrix - * are displayed as empty space, while matrix elements which are explicitly - * set to zero are displayed as such. - * - * The parameters allow for a flexible setting of the output format: - * @p precision and @p scientific are used to determine the number format, - * where scientific = false means fixed point notation. A zero - * entry for @p width makes the function compute a width, but it may be - * changed to a positive value, if output is crude. - * - * Additionally, a character for an empty value may be specified in - * @p zero_string, and a character to separate row entries can be set in - * @p separator. - * - * Finally, the whole matrix can be multiplied with a common @p denominator - * to produce more readable output, even integers. - * - * @attention This function may produce @em large amounts of output if - * applied to a large matrix! - */ - void - print_formatted(std::ostream &out, - const unsigned int precision = 3, - const bool scientific = true, - const unsigned int width = 0, - const char *zero_string = " ", - const double denominator = 1., - const char *separator = " ") const; - /** @} */ - - /** - * @name Modifying entries - */ - /** @{ */ - /** - * Multiply the entire matrix by a fixed factor. - */ - SparseMatrix & - operator*=(const Number factor); - - /** - * Divide the entire matrix by a fixed factor. - */ - SparseMatrix & - operator/=(const Number factor); - /** @} */ - - /** - * @name Multiplications - */ - /** @{ */ - /** - * Matrix-vector multiplication: let $dst = M \cdot src$ with $M$ - * being this matrix. - */ - void - vmult(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Matrix-vector multiplication: let $dst = M^T \cdot src$ with - * $M$ being this matrix. This function does the same as vmult() but - * takes this transposed matrix. - */ - void - Tvmult(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Adding matrix-vector multiplication. Add $M \cdot src$ on $dst$ - * with $M$ being this matrix. - */ - void - vmult_add(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Adding matrix-vector multiplication. Add $M^T \cdot src$ to - * $dst$ with $M$ being this matrix. This function foes the same - * as vmult_add() but takes the transposed matrix. - */ - void - Tvmult_add(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const; - - /** - * Return the square of the norm of the vector $v$ with respect to the - * norm induced by this matrix, i.e., $\left(v,Mv\right)$. This is useful, - * e.g., in the finite context, where the $L_2$ norm of a function equals - * the matrix norm with respect to the @ref GlossMassMatrix "mass matrix" of the vector - * representing the nodal values of the finite element function. - * - * Obviously, the matrix needs to be quadratic for this operation. - */ - Number - matrix_norm_square( - const LinearAlgebra::CUDAWrappers::Vector &v) const; - - /** - * Compute the matrix scalar product $\left(u,Mv\right)$. - */ - Number - matrix_scalar_product( - const LinearAlgebra::CUDAWrappers::Vector &u, - const LinearAlgebra::CUDAWrappers::Vector &v) const; - - /** - * Compute the residual of an equation $M \cdot x=b$, where the residual is - * defined to be $r=b-M \cdot x$. Write the residual into $dst$. The - * $l_2$ norm of the residual vector is returned. - * - * Source $x$ and destination $dst$ must not be the same vector. - */ - Number - residual(LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &x, - const LinearAlgebra::CUDAWrappers::Vector &b) const; - /** @} */ - - /** - * @name Matrix norms - */ - /** @{ */ - /** - * Return the $l_1$-norm of the matrix, that is $|M|_1=\max_{\mathrm{all\ - * columns\ }j}\sum_{\mathrm{all\ rows\ }i} |M_{ij}|$, (max. sum of - * columns). This is the natural matrix norm that is compatible to the - * $l_1$-norm for vectors, i.e., $|Mv|_1\leq |M|_1 |v|_1$. - */ - Number - l1_norm() const; - - /** - * Return the $l_\infty$-norm of the matrix, that is - * $|M|_\infty=\max_{\mathrm{all\ rows\ }i}\sum_{\mathrm{all\ columns\ }j} - * |M_{ij}|$, (max. sum of rows). This is the natural norm that is - * compatible to the $l_\infty$-norm of vectors, i.e., $|Mv|_\infty \leq - * |M|_\infty |v|_\infty$. - */ - Number - linfty_norm() const; - - /** - * Return the frobenius norm of the matrix, i.e., the square root of the - * sum of squares of all entries in the matrix. - */ - Number - frobenius_norm() const; - /** @} */ - - /** - * @name Access to underlying CUDA data - */ - /** @{ */ - /** - * Return a tuple containing the pointer to the values of matrix, the - * pointer to the columns indices, the pointer to the rows pointer, - * the cuSPARSE matrix description, and the cuSPARSE SP matrix description. - */ - std::tuple - get_cusparse_matrix() const; - /** @} */ - - private: - /** - * cuSPARSE handle used to call cuSPARSE functions. - */ - cusparseHandle_t cusparse_handle; - - /** - * Number of non-zero elements in the sparse matrix. - */ - int nnz; - - /** - * Number of rows of the sparse matrix. - */ - int n_rows; - - /** - * Number of columns of the sparse matrix. - */ - int n_cols; - - /** - * Pointer to the values (on the @ref GlossDevice "device") of the sparse matrix. - */ - std::unique_ptr val_dev; - - /** - * Pointer to the column indices (on the @ref GlossDevice "device") of the sparse matrix. - */ - std::unique_ptr column_index_dev; - - /** - * Pointer to the row pointer (on the @ref GlossDevice "device") of the sparse matrix. - */ - std::unique_ptr row_ptr_dev; - - /** - * cuSPARSE description of the matrix. - */ - cusparseMatDescr_t descr; - - /** - * cuSPARSE description of the sparse matrix. - */ - cusparseSpMatDescr_t sp_descr; - }; - - - - template - inline typename SparseMatrix::size_type - SparseMatrix::m() const - { - return n_rows; - } - - - - template - inline typename SparseMatrix::size_type - SparseMatrix::n() const - { - return n_cols; - } - - - - template - inline std::size_t - SparseMatrix::n_nonzero_elements() const - { - return nnz; - } - - - - template - template - inline void - SparseMatrix::print(StreamType &out, - const bool across, - const bool diagonal_first) const - { - Assert(column_index_dev != nullptr, ExcNotInitialized()); - Assert(val_dev != nullptr, ExcNotInitialized()); - Assert(row_ptr_dev != nullptr, ExcNotInitialized()); - - std::vector rows(n_rows + 1); - std::vector cols(nnz); - std::vector val(nnz); - Utilities::CUDA::copy_to_host(row_ptr_dev.get(), rows); - Utilities::CUDA::copy_to_host(column_index_dev.get(), cols); - Utilities::CUDA::copy_to_host(val_dev.get(), val); - - bool has_diagonal = false; - Number diagonal = Number(); - - for (size_type i = 0; i < n_rows; ++i) - { - if (diagonal_first) - { - // find the diagonal and print if it exists - for (size_type j = rows[i]; j < rows[i + 1] && cols[j] <= i; ++j) - { - if (i == cols[j]) - { - diagonal = val[j]; - has_diagonal = true; - if (across) - out << ' ' << i << ',' << i << ':' << diagonal; - else - out << '(' << i << ',' << i << ") " << diagonal - << std::endl; - break; - } - } - } - for (size_type j = rows[i]; j < rows[i + 1]; ++j) - { - if (has_diagonal && i == cols[j]) - continue; - if (across) - out << ' ' << i << ',' << cols[j] << ':' << val[j]; - else - out << '(' << i << ',' << cols[j] << ") " << val[j] << std::endl; - } - } - if (across) - out << std::endl; - } - - - - template - void - SparseMatrix::print_formatted(std::ostream &out, - const unsigned int precision, - const bool scientific, - const unsigned int width_, - const char *zero_string, - const double denominator, - const char *separator) const - { - Assert(column_index_dev != nullptr, ExcNotInitialized()); - Assert(val_dev != nullptr, ExcNotInitialized()); - Assert(row_ptr_dev != nullptr, ExcNotInitialized()); - - std::vector rows(n_rows + 1); - std::vector cols(nnz); - std::vector val(nnz); - Utilities::CUDA::copy_to_host(row_ptr_dev.get(), rows); - Utilities::CUDA::copy_to_host(column_index_dev.get(), cols); - Utilities::CUDA::copy_to_host(val_dev.get(), val); - - unsigned int width = width_; - - std::ios::fmtflags old_flags = out.flags(); - unsigned int old_precision = out.precision(precision); - - if (scientific) - { - out.setf(std::ios::scientific, std::ios::floatfield); - if (!width) - width = precision + 7; - } - else - { - out.setf(std::ios::fixed, std::ios::floatfield); - if (!width) - width = precision + 2; - } - - for (size_type i = 0; i < n_rows; ++i) - { - size_type j = rows[i]; - for (size_type k = 0; k < n_cols; ++k) - { - if (k == cols[j]) - { - out << std::setw(width) << val[j] * Number(denominator) - << separator; - ++j; - } - else - out << std::setw(width) << zero_string << separator; - } - out << std::endl; - }; - AssertThrow(out.fail() == false, ExcIO()); - - // reset output format - out.precision(old_precision); - out.flags(old_flags); - } -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif -#endif diff --git a/include/deal.II/lac/cuda_vector.h b/include/deal.II/lac/cuda_vector.h deleted file mode 100644 index 820bc53020..0000000000 --- a/include/deal.II/lac/cuda_vector.h +++ /dev/null @@ -1,435 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2016 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_vector_h -#define dealii_cuda_vector_h - -#include - -#include -#include -#include - -#include - -#ifdef DEAL_II_WITH_CUDA - -DEAL_II_NAMESPACE_OPEN - -// Forward declarations -# ifndef DOXYGEN -namespace LinearAlgebra -{ - template - class ReadWriteVector; -} -# endif - -namespace LinearAlgebra -{ - /** - * A Namespace for the CUDA vectors. - */ - namespace CUDAWrappers - { - /** - * This class implements a vector using CUDA for use on Nvidia GPUs. - * - * @note Only float and double are supported. - * - *

Moving data

- * You can move data to/from the device as follows: - * @code - * unsigned int size = 10; - * LinearAlgebra::ReadWriteVector rw_vector(size); - * - * ...do something with the rw_vector... - * - * // Move the data to the device: - * LinearAlgebra::CUDAWrappers::Vector vector_dev(size); - * vector_dev.import_elements(rw_vector, VectorOperations::insert); - * - * ...do some computations on the device... - * - * // Move the data back to the host: - * rw_vector.import_elements(vector_dev, VectorOperations::insert); - * @endcode - * - * @see CUDAWrappers - * @ingroup Vectors - */ - template - class Vector - { - public: - using value_type = Number; - using size_type = types::global_dof_index; - using real_type = typename numbers::NumberTraits::real_type; - - /** - * Constructor. Create a vector of dimension zero. - */ - Vector(); - - /** - * Copy constructor. - */ - Vector(const Vector &V); - - /** - * Move constructor. - */ - Vector(Vector &&) noexcept = default; - - /** - * Constructor. Set dimension to @p n and initialize all elements with - * zero. - * - * The constructor is made explicit to avoid accident like this: - * v=0;. Presumably, the user wants to set every elements of - * the vector to zero, but instead, what happens is this call: - * v=Vector@(0);, i.e. the vector is replaced by one - * of length zero. - */ - explicit Vector(const size_type n); - - /** - * Copy assignment operator. - */ - Vector & - operator=(const Vector &v); - - /** - * Move assignment operator. - */ - Vector & - operator=(Vector &&v) noexcept = default; - - /** - * Swap the contents of this vector and the other vector @p v. One could do - * this operation with a temporary variable and copying over the data - * elements, but this function is significantly more efficient since it - * only swaps the pointers to the data of the two vectors and therefore - * does not need to allocate temporary storage and move data around. - * - * This function is analogous to the @p swap function of all C++ - * standard containers. Also, there is a global function - * swap(u,v) that simply calls u.swap(v), again in - * analogy to standard functions. - */ - void - swap(Vector &v); - - /** - * Reinit functionality. The flag omit_zeroing_entries - * determines whether the vector should be filled with zeros (`false`) or - * left in an undetermined state (`true`). - */ - void - reinit(const size_type n, const bool omit_zeroing_entries = false); - - /** - * Change the dimension to that of the vector V. The elements of V are not - * copied. - */ - void - reinit(const Vector &V, const bool omit_zeroing_entries = false); - - /** - * Import all the element from the input vector @p V. - * VectorOperation::values @p operation is used to decide if the - * elements int @p V should be added to the current vector or replace - * the current elements. The last parameter is not used. It is only used - * for distributed vectors. This is the function that should be used to - * copy a vector to the GPU. - */ - void - import_elements( - const ReadWriteVector &V, - const VectorOperation::values operation, - const std::shared_ptr - &communication_pattern = {}); - - /** - * @deprecated Use import_elements() instead. - */ - DEAL_II_DEPRECATED void - import(const ReadWriteVector &V, - VectorOperation::values operation, - std::shared_ptr - communication_pattern = {}) - { - import_elements(V, operation, communication_pattern); - } - - /** - * Sets all elements of the vector to the scalar @p s. This operation is - * only allowed if @p s is equal to zero. - */ - Vector & - operator=(const Number s); - - /** - * Multiply the entive vector by a fixed factor. - */ - Vector & - operator*=(const Number factor); - - /** - * Divide the entire vector by a fixed factor. - */ - Vector & - operator/=(const Number factor); - - /** - * Add the vector @p V to the present one. - */ - Vector & - operator+=(const Vector &V); - - /** - * Subtract the vector @p V from the present one. - */ - Vector & - operator-=(const Vector &V); - - /** - * Return the scalar product of two vectors. - */ - Number - operator*(const Vector &V) const; - - /** - * Add @p to all components. Note that @p a is a scalar not a vector. - */ - void - add(const Number a); - - /** - * Simple addition of a multiple of a vector, i.e. *this += a*V. - */ - void - add(const Number a, const Vector &V); - - /** - * Multiple additions of scaled vectors, i.e. *this += a*V+b*W. - */ - void - add(const Number a, - const Vector &V, - const Number b, - const Vector &W); - - /** - * Scaling and simple addition of a multiple of a vector, i.e. *this - * = s*(*this)+a*V - */ - void - sadd(const Number s, const Number a, const Vector &V); - - /** - * Scale each element of this vector by the corresponding element in the - * argument. This function is mostly meant to simulate multiplication - * (and immediate re-assignment) by a diagonal scaling matrix. - */ - void - scale(const Vector &scaling_factors); - - /** - * Assignment *this = a*V. - */ - void - equ(const Number a, const Vector &V); - - /** - * Return whether the vector contains only elements with value zero. - */ - bool - all_zero() const; - - /** - * Return the mean value of all the entries of this vector. - */ - value_type - mean_value() const; - - /** - * Return the l1 norm of the vector (i.e., the sum of the - * absolute values of all entries among all processors). - */ - real_type - l1_norm() const; - - /** - * Return the l2 norm of the vector (i.e., the square root of - * the sum of the square of all entries among all processors). - */ - real_type - l2_norm() const; - - /** - * Return the square of the $l_2$-norm. - */ - real_type - norm_sqr() const; - - /** - * Return the maximum norm of the vector (i.e., the maximum absolute - * value among all entries and among all processors). - */ - real_type - linfty_norm() const; - - /** - * Perform a combined operation of a vector addition and a subsequent - * inner product, returning the value of the inner product. In other - * words, the result of this function is the same as if the user called - * @code - * this->add(a, V); - * return_value = *this * W; - * @endcode - * - * The reason this function exists is that this operation involves less - * memory transfer than calling the two functions separately. This - * method only needs to load three vectors, @p this, @p V, @p W, whereas - * calling separate methods means to load the calling vector @p this - * twice. Since most vector operations are memory transfer limited, this - * reduces the time by 25\% (or 50\% if @p W equals @p this). - * - * For complex-valued vectors, the scalar product in the second step is - * implemented as $\left=\sum_i v_i \bar{w_i}$. - */ - Number - add_and_dot(const Number a, - const Vector &V, - const Vector &W); - - /** - * Return the pointer to the underlying array. Ownership still resides - * with this class. - */ - Number * - get_values() const; - - /** - * Return the size of the vector. - */ - size_type - size() const; - - /** - * Return an index set that describe which elements of this vector are - * owned by the current processor, i.e. [0, size). - */ - dealii::IndexSet - locally_owned_elements() const; - - /** - * Print the vector to the output stream @p out. - */ - void - print(std::ostream &out, - const unsigned int precision = 2, - const bool scientific = true, - const bool across = true) const; - - /** - * Return the memory consumption of this class in bytes. - */ - std::size_t - memory_consumption() const; - - /** - * Attempt to perform an operation between two incompatible vector types. - * - * @ingroup Exceptions - */ - DeclException0(ExcVectorTypeNotCompatible); - - private: - /** - * Pointer to the array of elements of this vector. - */ - std::unique_ptr val; - - /** - * Number of elements in the vector. - */ - size_type n_elements; - }; - } // namespace CUDAWrappers -} // namespace LinearAlgebra - -// ---------------------------- Inline functions -------------------------- - -/** - * Global function @p swap which overloads the default implementation of the - * C++ standard library which uses a temporary object. The function simply - * exchanges the data of the two vectors. - * - * @relatesalso Vector - */ -template -inline void -swap(LinearAlgebra::CUDAWrappers::Vector &u, - LinearAlgebra::CUDAWrappers::Vector &v) -{ - u.swap(v); -} - -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - template - inline Number * - Vector::get_values() const - { - return val.get(); - } - - - - template - inline typename Vector::size_type - Vector::size() const - { - return n_elements; - } - - - template - inline IndexSet - Vector::locally_owned_elements() const - { - return complete_index_set(n_elements); - } - - - - template - inline void - Vector::swap(Vector &v) - { - std::swap(val, v.val); - std::swap(n_elements, v.n_elements); - } - } // namespace CUDAWrappers -} // namespace LinearAlgebra - -DEAL_II_NAMESPACE_CLOSE - -#endif - -#endif diff --git a/include/deal.II/lac/precondition.h b/include/deal.II/lac/precondition.h index 7c6ae362ac..b3ab8c433a 100644 --- a/include/deal.II/lac/precondition.h +++ b/include/deal.II/lac/precondition.h @@ -17,7 +17,6 @@ #include -#include #include #include #include diff --git a/include/deal.II/lac/read_write_vector.h b/include/deal.II/lac/read_write_vector.h index 9657dd1c06..d236cf9135 100644 --- a/include/deal.II/lac/read_write_vector.h +++ b/include/deal.II/lac/read_write_vector.h @@ -81,16 +81,6 @@ namespace TrilinosWrappers } // namespace TrilinosWrappers # endif -# ifdef DEAL_II_WITH_CUDA -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - template - class Vector; - } -} // namespace LinearAlgebra -# endif #endif namespace LinearAlgebra @@ -470,35 +460,6 @@ namespace LinearAlgebra } #endif -#ifdef DEAL_II_WITH_CUDA - /** - * Import all the elements present in the vector's IndexSet from the input - * vector @p cuda_vec. VectorOperation::values @p operation is used to - * decide if the elements in @p V should be added to the current vector or - * replace the current elements. The last parameter is not used. - */ - void - import_elements( - const CUDAWrappers::Vector &cuda_vec, - VectorOperation::values operation, - const std::shared_ptr - &communication_pattern = {}); - - - /** - * @deprecated Use import_elements() instead. - */ - DEAL_II_DEPRECATED - void - import(const CUDAWrappers::Vector &V, - VectorOperation::values operation, - const std::shared_ptr - &communication_pattern = {}) - { - import_elements(V, operation, communication_pattern); - } -#endif - /** * The value returned by this function denotes the dimension of the vector * spaces that are modeled by objects of this kind. However, objects of diff --git a/include/deal.II/lac/read_write_vector.templates.h b/include/deal.II/lac/read_write_vector.templates.h index ef386c0fbf..0a6c62d9fd 100644 --- a/include/deal.II/lac/read_write_vector.templates.h +++ b/include/deal.II/lac/read_write_vector.templates.h @@ -37,10 +37,6 @@ # include #endif -#ifdef DEAL_II_WITH_CUDA -# include -#endif - #include DEAL_II_NAMESPACE_OPEN @@ -853,96 +849,6 @@ namespace LinearAlgebra -#ifdef DEAL_II_WITH_CUDA - template - void - ReadWriteVector::import_elements( - const LinearAlgebra::CUDAWrappers::Vector &cuda_vec, - VectorOperation::values operation, - const std::shared_ptr &) - { - const unsigned int n_elements = stored_elements.n_elements(); - if (operation == VectorOperation::insert) - { - cudaError_t error_code = cudaMemcpy(values.data(), - cuda_vec.get_values(), - n_elements * sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - } - else if (operation == VectorOperation::add) - { - // Copy the vector from the device to a temporary vector on the host - std::vector tmp(n_elements); - cudaError_t error_code = cudaMemcpy(tmp.data(), - cuda_vec.get_values(), - n_elements * sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - - // Add the two vectors - for (unsigned int i = 0; i < n_elements; ++i) - values[i] += tmp[i]; - } - else if (operation == VectorOperation::min) - { - // Copy the vector from the device to a temporary vector on the host - std::vector tmp(n_elements); - cudaError_t error_code = cudaMemcpy(tmp.data(), - cuda_vec.get_values(), - n_elements * sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - - // To ensure that this code also compiles with complex - // numbers, we only compare the real part of the - // variable. Note that min/max do not make sense with complex - // numbers. - for (unsigned int i = 0; i < n_elements; ++i) - { - Assert( - std::imag(tmp[i]) == 0., - ExcMessage( - "VectorOperation::min is not defined if there is an imaginary part!)")); - Assert( - std::imag(values[i]) == 0., - ExcMessage( - "VectorOperation::min is not defined if there is an imaginary part!)")); - if (std::real(tmp[i]) - std::real(values[i]) < 0.0) - values[i] = tmp[i]; - } - } - else if (operation == VectorOperation::max) - { - // Copy the vector from the device to a temporary vector on the host - std::vector tmp(n_elements); - cudaError_t error_code = cudaMemcpy(tmp.data(), - cuda_vec.get_values(), - n_elements * sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - - for (unsigned int i = 0; i < n_elements; ++i) - { - Assert( - std::imag(tmp[i]) == 0., - ExcMessage( - "VectorOperation::max is not defined if there is an imaginary part!)")); - Assert( - std::imag(values[i]) == 0., - ExcMessage( - "VectorOperation::max is not defined if there is an imaginary part!)")); - if (std::real(tmp[i]) - std::real(values[i]) > 0.0) - values[i] = tmp[i]; - } - } - else - AssertThrow(false, ExcNotImplemented()); - } -#endif - - - template void ReadWriteVector::swap(ReadWriteVector &v) noexcept diff --git a/include/deal.II/matrix_free/cuda_fe_evaluation.h b/include/deal.II/matrix_free/cuda_fe_evaluation.h deleted file mode 100644 index 9c42c9db0b..0000000000 --- a/include/deal.II/matrix_free/cuda_fe_evaluation.h +++ /dev/null @@ -1,37 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2017 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_fe_evaluation_h -#define dealii_cuda_fe_evaluation_h - -#include - -DEAL_II_NAMESPACE_OPEN - -/** - * Namespace for the CUDA wrappers - */ -// GCC 9 and before do not recognize the [[deprecated]] attribute -#if defined(__GNUC__) && (__GNUC__ < 10) -namespace CUDAWrappers -#else -namespace DEAL_II_DEPRECATED CUDAWrappers -#endif -{ - using namespace Portable; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/include/deal.II/matrix_free/cuda_hanging_nodes_internal.h b/include/deal.II/matrix_free/cuda_hanging_nodes_internal.h deleted file mode 100644 index b8a1bb773a..0000000000 --- a/include/deal.II/matrix_free/cuda_hanging_nodes_internal.h +++ /dev/null @@ -1,32 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#ifndef dealii_cuda_hanging_nodes_internal_h -#define dealii_cuda_hanging_nodes_internal_h - -#include - -DEAL_II_NAMESPACE_OPEN -// GCC 9 and before do not recognize the [[deprecated]] attribute -#if defined(__GNUC__) && (__GNUC__ < 10) -namespace CUDAWrappers -#else -namespace DEAL_II_DEPRECATED CUDAWrappers -#endif -{ - using namespace Portable; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE -#endif diff --git a/include/deal.II/matrix_free/cuda_matrix_free.h b/include/deal.II/matrix_free/cuda_matrix_free.h deleted file mode 100644 index d71de9f617..0000000000 --- a/include/deal.II/matrix_free/cuda_matrix_free.h +++ /dev/null @@ -1,35 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2017 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -#ifndef dealii_cuda_matrix_free_h -#define dealii_cuda_matrix_free_h - -#include - -DEAL_II_NAMESPACE_OPEN - -// GCC 9 and before do not recognize the [[deprecated]] attribute -#if defined(__GNUC__) && (__GNUC__ < 10) -namespace CUDAWrappers -#else -namespace DEAL_II_DEPRECATED CUDAWrappers -#endif -{ - using namespace Portable; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/include/deal.II/matrix_free/cuda_matrix_free.templates.h b/include/deal.II/matrix_free/cuda_matrix_free.templates.h deleted file mode 100644 index 30a9f1bb9b..0000000000 --- a/include/deal.II/matrix_free/cuda_matrix_free.templates.h +++ /dev/null @@ -1,35 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2017 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -#ifndef dealii_cuda_matrix_free_templates_h -#define dealii_cuda_matrix_free_templates_h - -#include - -DEAL_II_NAMESPACE_OPEN - -// GCC 9 and before do not recognize the [[deprecated]] attribute -#if defined(__GNUC__) && (__GNUC__ < 10) -namespace CUDAWrappers -#else -namespace DEAL_II_DEPRECATED CUDAWrappers -#endif -{ - using namespace Portable; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/include/deal.II/matrix_free/cuda_tensor_product_kernels.h b/include/deal.II/matrix_free/cuda_tensor_product_kernels.h deleted file mode 100644 index 7ad6f8949a..0000000000 --- a/include/deal.II/matrix_free/cuda_tensor_product_kernels.h +++ /dev/null @@ -1,37 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2017 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -#ifndef dealii_cuda_tensor_product_kernels_h -#define dealii_cuda_tensor_product_kernels_h - - -#include - -DEAL_II_NAMESPACE_OPEN - - -// GCC 9 and before do not recognize the [[deprecated]] attribute -#if defined(__GNUC__) && (__GNUC__ < 10) -namespace CUDAWrappers -#else -namespace DEAL_II_DEPRECATED CUDAWrappers -#endif -{ - using namespace Portable; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/include/deal.II/matrix_free/hanging_nodes_internal.h b/include/deal.II/matrix_free/hanging_nodes_internal.h index b6a4c96f29..fe858a08c8 100644 --- a/include/deal.II/matrix_free/hanging_nodes_internal.h +++ b/include/deal.II/matrix_free/hanging_nodes_internal.h @@ -257,7 +257,7 @@ namespace internal /** * This class creates the mask used in the treatment of hanging nodes in - * CUDAWrappers::MatrixFree. + * Portable::MatrixFree. * The implementation of this class is explained in detail in * @cite munch2022hn. */ diff --git a/include/deal.II/matrix_free/portable_fe_evaluation.h b/include/deal.II/matrix_free/portable_fe_evaluation.h index f94adf548d..3f41a31bc0 100644 --- a/include/deal.II/matrix_free/portable_fe_evaluation.h +++ b/include/deal.II/matrix_free/portable_fe_evaluation.h @@ -58,8 +58,6 @@ namespace Portable * * @tparam Number Number format, @p double or @p float. Defaults to @p * double. - * - * @ingroup CUDAWrappers */ template -#include - #include #include diff --git a/include/deal.II/matrix_free/portable_matrix_free.h b/include/deal.II/matrix_free/portable_matrix_free.h index 2b25b1ef3f..78b793a531 100644 --- a/include/deal.II/matrix_free/portable_matrix_free.h +++ b/include/deal.II/matrix_free/portable_matrix_free.h @@ -18,7 +18,6 @@ #include -#include #include #include #include @@ -34,7 +33,6 @@ #include #include -#include #include #include @@ -86,8 +84,6 @@ namespace Portable * Triangulation class in deal.II. * * @note Only float and double are supported. - * - * @ingroup CUDAWrappers */ template class MatrixFree : public Subscriptor @@ -119,7 +115,7 @@ namespace Portable AssertThrow( overlap_communication_computation == false, ExcMessage( - "Overlapping communication and computation requires CUDA-aware MPI.")); + "Overlapping communication and computation requires device-aware MPI.")); #endif if (overlap_communication_computation == true) AssertThrow( @@ -146,7 +142,7 @@ namespace Portable bool use_coloring; /** - * Overlap MPI communications with computation. This requires CUDA-aware + * Overlap MPI communications with computation. This requires device-aware * MPI and use_coloring must be false. */ bool overlap_communication_computation; @@ -374,16 +370,6 @@ namespace Portable void set_constrained_values(const Number val, VectorType &dst) const; -#ifdef DEAL_II_WITH_CUDA - /** - * Initialize a serial vector. The size corresponds to the number of degrees - * of freedom in the DoFHandler object. - */ - void - initialize_dof_vector( - LinearAlgebra::CUDAWrappers::Vector &vec) const; -#endif - /** * Initialize a distributed vector. The local elements correspond to the * locally owned degrees of freedom and the ghost elements correspond to the @@ -462,20 +448,6 @@ namespace Portable LinearAlgebra::distributed::Vector &dst) const; -#ifdef DEAL_II_WITH_CUDA - /** - * This function should never be called. Calling it results in an internal - * error. This function exists only because cell_loop needs - * distributed_cell_loop() to exist for LinearAlgebra::CUDAWrappers::Vector. - */ - template - void - distributed_cell_loop( - const Functor &func, - const LinearAlgebra::CUDAWrappers::Vector &src, - LinearAlgebra::CUDAWrappers::Vector &dst) const; -#endif - /** * Unique ID associated with the object. */ @@ -489,7 +461,7 @@ namespace Portable bool use_coloring; /** - * Overlap MPI communications with computation. This requires CUDA-aware + * Overlap MPI communications with computation. This requires device-aware * MPI and use_coloring must be false. */ bool overlap_communication_computation; diff --git a/include/deal.II/matrix_free/portable_matrix_free.templates.h b/include/deal.II/matrix_free/portable_matrix_free.templates.h index 4c8a3db6d1..aeda76ddcc 100644 --- a/include/deal.II/matrix_free/portable_matrix_free.templates.h +++ b/include/deal.II/matrix_free/portable_matrix_free.templates.h @@ -18,8 +18,6 @@ #include -#include -#include #include #include @@ -29,8 +27,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -126,7 +124,7 @@ namespace Portable void ReinitHelper::resize(const unsigned int n_colors) { - // We need at least three colors when we are using CUDA-aware MPI and + // We need at least three colors when we are using device-aware MPI and // overlapping the communication data->n_cells.resize(std::max(n_colors, 3U), 0); data->local_to_global.resize(n_colors); @@ -325,28 +323,6 @@ namespace Portable } }; -#ifdef DEAL_II_WITH_CUDA - template <> - struct VectorLocalSize> - { - static unsigned int - get(const LinearAlgebra::CUDAWrappers::Vector &vec) - { - return vec.size(); - } - }; - - template <> - struct VectorLocalSize> - { - static unsigned int - get(const LinearAlgebra::CUDAWrappers::Vector &vec) - { - return vec.size(); - } - }; -#endif - template @@ -575,17 +551,6 @@ namespace Portable } -#ifdef DEAL_II_WITH_CUDA - template - void - MatrixFree::initialize_dof_vector( - LinearAlgebra::CUDAWrappers::Vector &vec) const - { - vec.reinit(n_dofs); - } -#endif - - template void @@ -1023,7 +988,7 @@ namespace Portable apply_kernel); // We need a synchronization point because we don't want - // CUDA-aware MPI to start the MPI communication until the + // device-aware MPI to start the MPI communication until the // kernel is done. Kokkos::fence(); } @@ -1131,18 +1096,6 @@ namespace Portable } } -#ifdef DEAL_II_WITH_CUDA - template - template - void - MatrixFree::distributed_cell_loop( - const Functor &, - const LinearAlgebra::CUDAWrappers::Vector &, - LinearAlgebra::CUDAWrappers::Vector &) const - { - DEAL_II_ASSERT_UNREACHABLE(); - } -#endif } // namespace Portable DEAL_II_NAMESPACE_CLOSE diff --git a/include/deal.II/matrix_free/portable_tensor_product_kernels.h b/include/deal.II/matrix_free/portable_tensor_product_kernels.h index b340b68327..c5ebdb7442 100644 --- a/include/deal.II/matrix_free/portable_tensor_product_kernels.h +++ b/include/deal.II/matrix_free/portable_tensor_product_kernels.h @@ -20,8 +20,6 @@ #include -#include - DEAL_II_NAMESPACE_OPEN @@ -32,8 +30,6 @@ namespace Portable /** * In this namespace, the evaluator routines that evaluate the tensor * products are implemented. - * - * @ingroup CUDAWrappers */ // TODO: for now only the general variant is implemented enum EvaluatorVariant @@ -335,8 +331,6 @@ namespace Portable /** * Generic evaluator framework. - * - * @ingroup CUDAWrappers */ template struct EvaluatorTensorProduct -#include -#include - -#include -#include -#include -#include - -DEAL_II_NAMESPACE_OPEN - -namespace Utilities -{ - namespace CUDA - { - Handle::Handle() - { - cusolverStatus_t cusolver_error_code = - cusolverDnCreate(&cusolver_dn_handle); - AssertCusolver(cusolver_error_code); - - cusolver_error_code = cusolverSpCreate(&cusolver_sp_handle); - AssertCusolver(cusolver_error_code); - - cusparseStatus_t cusparse_error_code = cusparseCreate(&cusparse_handle); - AssertCusparse(cusparse_error_code); - } - - - - Handle::~Handle() - { - cusolverStatus_t cusolver_error_code = - cusolverDnDestroy(cusolver_dn_handle); - AssertCusolver(cusolver_error_code); - - cusolver_error_code = cusolverSpDestroy(cusolver_sp_handle); - AssertCusolver(cusolver_error_code); - - cusparseStatus_t cusparse_error_code = cusparseDestroy(cusparse_handle); - AssertCusparse(cusparse_error_code); - } - } // namespace CUDA -} // namespace Utilities - -DEAL_II_NAMESPACE_CLOSE diff --git a/source/base/exceptions.cc b/source/base/exceptions.cc index f20d577be1..8cab0dd491 100644 --- a/source/base/exceptions.cc +++ b/source/base/exceptions.cc @@ -551,97 +551,6 @@ namespace deal_II_exceptions } } - - -#ifdef DEAL_II_WITH_CUDA - std::string - get_cusparse_error_string(const cusparseStatus_t error_code) - { - switch (error_code) - { - case CUSPARSE_STATUS_NOT_INITIALIZED: - { - return "The cuSPARSE library was not initialized"; - } - case CUSPARSE_STATUS_ALLOC_FAILED: - { - return "Resource allocation failed inside the cuSPARSE library"; - } - case CUSPARSE_STATUS_INVALID_VALUE: - { - return "An unsupported value of parameter was passed to the function"; - } - case CUSPARSE_STATUS_ARCH_MISMATCH: - { - return "The function requires a feature absent from the device architecture"; - } - case CUSPARSE_STATUS_MAPPING_ERROR: - { - return "An access to GPU memory space failed"; - } - case CUSPARSE_STATUS_EXECUTION_FAILED: - { - return "The GPU program failed to execute"; - } - case CUSPARSE_STATUS_INTERNAL_ERROR: - { - return "An internal cuSPARSE operation failed"; - } - case CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED: - { - return "The matrix type is not supported by this function"; - } - default: - { - return "Unknown error"; - } - } - } - - - - std::string - get_cusolver_error_string(cusolverStatus_t error_code) - { - std::string message; - switch (error_code) - { - case CUSOLVER_STATUS_NOT_INITIALIZED: - { - return "The cuSolver library was not initialized"; - } - case CUSOLVER_STATUS_ALLOC_FAILED: - { - return "Resource allocation failed inside the cuSolver library"; - } - case CUSOLVER_STATUS_INVALID_VALUE: - { - return "An unsupported value of a parameter was passed to the function"; - } - case CUSOLVER_STATUS_ARCH_MISMATCH: - { - return "The function requires a feature absent from the device architecture"; - } - case CUSOLVER_STATUS_EXECUTION_FAILED: - { - return "The GPU program failed to execute"; - } - case CUSOLVER_STATUS_INTERNAL_ERROR: - { - return "An internal cuSolver operation failed"; - } - case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED: - { - return "The matrix type is not supported by this function"; - } - default: - { - return "Unknown error"; - } - } - } -#endif - } /*namespace internals*/ } /*namespace deal_II_exceptions*/ diff --git a/source/lac/CMakeLists.txt b/source/lac/CMakeLists.txt index f77a42be6a..7b9dfcd42d 100644 --- a/source/lac/CMakeLists.txt +++ b/source/lac/CMakeLists.txt @@ -57,14 +57,6 @@ set(_separate_src utilities.cc ) -# Add CUDA wrapper files -if(DEAL_II_WITH_CUDA) - set(_separate_src - ${_separate_src} - vector_memory_cuda.cc - ) -endif() - set(_inst affine_constraints.inst.in block_sparse_matrix.inst.in @@ -165,19 +157,6 @@ if(DEAL_II_WITH_TRILINOS) ) endif() -# Add CUDA wrapper files -if(DEAL_II_WITH_CUDA) - set(_separate_src - ${_separate_src} - cuda_kernels.cc - cuda_precondition.cc - cuda_solver_direct.cc - cuda_sparse_matrix.cc - cuda_vector.cc - read_write_vector_cuda.cc - ) -endif() - # determined by profiling set(_n_includes_per_unity_file 20) diff --git a/source/lac/cuda_kernels.cc b/source/lac/cuda_kernels.cc deleted file mode 100644 index 7af0bce8ab..0000000000 --- a/source/lac/cuda_kernels.cc +++ /dev/null @@ -1,250 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include - -DEAL_II_NAMESPACE_OPEN - -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - namespace kernel - { - ///////////////////////////////////////////////////////////////////////// - // Explicit instantiation // - ///////////////////////////////////////////////////////////////////////// - - template __global__ void - vec_scale(float *, const float a, const size_type); - template __global__ void - vector_bin_op(float *v1, - const float *v2, - const size_type N); - template __global__ void - vector_bin_op(float *v1, - const float *v2, - const size_type N); - template __global__ void - masked_vector_bin_op(const unsigned int *mask, - float *v1, - const float *v2, - const size_type N); - template __global__ void - masked_vector_bin_op(const unsigned int *mask, - float *v1, - const float *v2, - const size_type N); - template struct ElemSum; - template struct L1Norm; - template struct LInfty; - template __global__ void - reduction>(float *result, - const float *v, - const size_type N); - template __global__ void - reduction>(float *result, - const float *v, - const size_type N); - template __global__ void - reduction>(float *result, - const float *v, - const size_type N); - template struct DotProduct; - template __global__ void - double_vector_reduction>(float *result, - const float *v1, - const float *v2, - const size_type N); - template __global__ void - vec_add(float *val, const float, const size_type N); - template __global__ void - add_aV(float *val, - const float a, - const float *V_val, - const size_type N); - template __global__ void - add_aVbW(float *val, - const float a, - const float *V_val, - const float b, - const float *W_val, - const size_type N); - template __global__ void - sadd(const float s, - float *val, - const float a, - const float *V_val, - const size_type N); - template __global__ void - sadd(const float s, - float *val, - const float a, - const float *V_val, - const float b, - const float *W_val, - const size_type N); - template __global__ void - scale(float *val, const float *V_val, const size_type N); - template __global__ void - equ(float *val, - const float a, - const float *V_val, - const size_type N); - template __global__ void - equ(float *val, - const float a, - const float *V_val, - const float b, - const float *W_val, - const size_type N); - template __global__ void - add_and_dot(float *res, - float *v1, - const float *v2, - const float *v3, - const float a, - const size_type N); - template __global__ void - set(float *val, const float s, const size_type N); - template __global__ void - set_permutated(const size_type *indices, - float *val, - const float *v, - const size_type N); - template __global__ void - gather(float *val, - const size_type *indices, - const float *v, - const size_type N); - template __global__ void - add_permutated(const size_type *indices, - float *val, - const float *v, - const size_type N); - - - - template __global__ void - vec_scale(double *, const double a, const size_type); - template __global__ void - vector_bin_op(double *v1, - const double *v2, - const size_type N); - template __global__ void - vector_bin_op(double *v1, - const double *v2, - const size_type N); - template __global__ void - masked_vector_bin_op(const unsigned int *mask, - double *v1, - const double *v2, - const size_type N); - template __global__ void - masked_vector_bin_op(const unsigned int *mask, - double *v1, - const double *v2, - const size_type N); - template struct ElemSum; - template struct L1Norm; - template struct LInfty; - template __global__ void - reduction>(double *result, - const double *v, - const size_type N); - template __global__ void - reduction>(double *result, - const double *v, - const size_type N); - template __global__ void - reduction>(double *result, - const double *v, - const size_type N); - template struct DotProduct; - template __global__ void - double_vector_reduction>(double *result, - const double *v1, - const double *v2, - const size_type N); - template __global__ void - vec_add(double *val, const double, const size_type N); - template __global__ void - add_aV(double *val, - const double a, - const double *V_val, - const size_type N); - template __global__ void - add_aVbW(double *val, - const double a, - const double *V_val, - const double b, - const double *W_val, - const size_type N); - template __global__ void - sadd(const double s, - double *val, - const double a, - const double *V_val, - const size_type N); - template __global__ void - sadd(const double s, - double *val, - const double a, - const double *V_val, - const double b, - const double *W_val, - const size_type N); - template __global__ void - scale(double *val, const double *V_val, const size_type N); - template __global__ void - equ(double *val, - const double a, - const double *V_val, - const size_type N); - template __global__ void - equ(double *val, - const double a, - const double *V_val, - const double b, - const double *W_val, - const size_type N); - template __global__ void - add_and_dot(double *res, - double *v1, - const double *v2, - const double *v3, - const double a, - const size_type N); - template __global__ void - set(double *val, const double s, const size_type N); - template __global__ void - set_permutated(const size_type *indices, - double *val, - const double *v, - const size_type N); - template __global__ void - gather(double *val, - const size_type *indices, - const double *v, - const size_type N); - template __global__ void - add_permutated(const size_type *indices, - double *val, - const double *v, - const size_type N); - } // namespace kernel - } // namespace CUDAWrappers -} // namespace LinearAlgebra - -DEAL_II_NAMESPACE_CLOSE diff --git a/source/lac/cuda_precondition.cc b/source/lac/cuda_precondition.cc deleted file mode 100644 index df7e274400..0000000000 --- a/source/lac/cuda_precondition.cc +++ /dev/null @@ -1,1826 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2024 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include -#include - -DEAL_II_NAMESPACE_OPEN - -namespace -{ - /** - * Template wrapper for cusparsecsrilu02. - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csrilu02). - * function performs the solve phase of the incomplete-LU factorization with - * 0 fill-in and no pivoting. - */ - template - cusparseStatus_t - cusparseXcsrilu02(cusparseHandle_t /*handle*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - Number * /*csrValA_valM*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csrilu02Info_t /*info*/, - cusparseSolvePolicy_t /*policy*/, - void * /*pBuffer*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsrilu02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - float *csrValA_valM, - const int *csrRowPtrA, - const int *csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseScsrilu02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrilu02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - double *csrValA_valM, - const int *csrRowPtrA, - const int *csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseDcsrilu02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - /* - template <> - cusparseStatus_t - cusparseXcsrilu02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuComplex * csrValA_valM, - const int * csrRowPtrA, - const int * csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseCcsrilu02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrilu02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuDoubleComplex * csrValA_valM, - const int * csrRowPtrA, - const int * csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseZcsrilu02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - */ - - - - /** - * Template wrapper for cusparsecsrilu02_analysis. - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csrilu02_analysis). - * This function performs the analysis phase of the incomplete-LU - * factorization with 0 fill-in and no pivoting. - */ - template - cusparseStatus_t - cusparseXcsrilu02_analysis(cusparseHandle_t /*handle*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - const Number * /*csrValA*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csrilu02Info_t /*info*/, - cusparseSolvePolicy_t /*policy*/, - void * /*pBuffer*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsrilu02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const float *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseScsrilu02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrilu02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const double *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseDcsrilu02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - /* - template <> - cusparseStatus_t - cusparseXcsrilu02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const cuComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseCcsrilu02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrilu02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const cuDoubleComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrilu02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseZcsrilu02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } -*/ - - - - /** - * Template wrapper for cusparsecsrilu02_bufferSize. - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csrilu02_bufferSize). - * This function returns size of the buffer used in computing the - * incomplete-LU factorization with 0 fill-in and no pivoting. - */ - template - cusparseStatus_t - cusparseXcsrilu02_bufferSize(cusparseHandle_t /*handle*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - Number * /*csrValA*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csrilu02Info_t /*info*/, - int * /*pBufferSizeInBytes*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsrilu02_bufferSize(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - float *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrilu02Info_t info, - int *pBufferSizeInBytes) - { - return cusparseScsrilu02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - template <> - cusparseStatus_t - cusparseXcsrilu02_bufferSize(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - double *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrilu02Info_t info, - int *pBufferSizeInBytes) - { - return cusparseDcsrilu02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - /* - template <> - cusparseStatus_t - cusparseXcsrilu02_bufferSize(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrilu02Info_t info, - int *pBufferSizeInBytes) - { - return cusparseCcsrilu02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - template <> - cusparseStatus_t - cusparseXcsrilu02_bufferSize(cusparseHandle_t handle, int - m, int nnz, const cusparseMatDescr_t descrA, - cuDoubleComplex *csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrilu02Info_t info, - int *pBufferSizeInBytes) - { - return cusparseZcsrilu02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } -*/ - - - - /** - * Template wrapper for cusparsecsric02 - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csric02). - * This function performs the solve phase of the computing the - * incomplete-Cholesky factorization with 0 fill-in and no pivoting. - */ - template - cusparseStatus_t - cusparseXcsric02(cusparseHandle_t /*handle*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - Number * /*csrValA_valM*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csric02Info_t /*info*/, - cusparseSolvePolicy_t /*policy*/, - void * /*pBuffer*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsric02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - float *csrValA_valM, - const int *csrRowPtrA, - const int *csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseScsric02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsric02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - double *csrValA_valM, - const int *csrRowPtrA, - const int *csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseDcsric02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - /* - template <> - cusparseStatus_t - cusparseXcsric02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuComplex * csrValA_valM, - const int * csrRowPtrA, - const int * csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseCcsric02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsric02(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuDoubleComplex * csrValA_valM, - const int * csrRowPtrA, - const int * csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseZcsric02(handle, - m, - nnz, - descrA, - csrValA_valM, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - */ - - - - /** - * Template wrapper for cusparsecsrsv2_solve - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csrsv2_solve). - * This function performs the solve phase of csrsv2, a new sparse triangular - * linear system op(A)*y = alpha*x. - */ - template - cusparseStatus_t - cusparseXcsrsv2_solve(cusparseHandle_t /*handle*/, - cusparseOperation_t /*transA*/, - int /*m*/, - int /*nnz*/, - const Number * /*alpha*/, - const cusparseMatDescr_t /*descra*/, - const Number * /*csrValA*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csrsv2Info_t /*info*/, - const Number * /*x*/, - Number * /*y*/, - cusparseSolvePolicy_t /*policy*/, - void * /*pBuffer*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_solve(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const float *alpha, - const cusparseMatDescr_t descra, - const float *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrsv2Info_t info, - const float *x, - float *y, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseScsrsv2_solve(handle, - transA, - m, - nnz, - alpha, - descra, - csrValA, - csrRowPtrA, - csrColIndA, - info, - x, - y, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_solve(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const double *alpha, - const cusparseMatDescr_t descra, - const double *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrsv2Info_t info, - const double *x, - double *y, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseDcsrsv2_solve(handle, - transA, - m, - nnz, - alpha, - descra, - csrValA, - csrRowPtrA, - csrColIndA, - info, - x, - y, - policy, - pBuffer); - } - - /* - template <> - cusparseStatus_t - cusparseXcsrsv2_solve(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cuComplex * alpha, - const cusparseMatDescr_t descra, - const cuComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrsv2Info_t info, - const cuComplex * x, - cuComplex * y, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseCcsrsv2_solve(handle, - transA, - m, - nnz, - alpha, - descra, - csrValA, - csrRowPtrA, - csrColIndA, - info, - x, - y, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_solve(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cuDoubleComplex * alpha, - const cusparseMatDescr_t descra, - const cuDoubleComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrsv2Info_t info, - const cuDoubleComplex * x, - cuDoubleComplex * y, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseZcsrsv2_solve(handle, - transA, - m, - nnz, - alpha, - descra, - csrValA, - csrRowPtrA, - csrColIndA, - info, - x, - y, - policy, - pBuffer); - } -*/ - - - - /** - * Template wrapper for cusparsecsrsv2_analysis - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csrsv2_analysis). - * This function performs the analysis phase of csrsv2, a new sparse - * triangular linear system op(A)*y = alpha*x. - */ - template - cusparseStatus_t - cusparseXcsrsv2_analysis(cusparseHandle_t /*handle*/, - cusparseOperation_t /*transA*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - const Number * /*csrValA*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csrsv2Info_t /*info*/, - cusparseSolvePolicy_t /*policy*/, - void * /*pBuffer*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_analysis(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const float *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrsv2Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseScsrsv2_analysis(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_analysis(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const double *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrsv2Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseDcsrsv2_analysis(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - /* - template <> - cusparseStatus_t - cusparseXcsrsv2_analysis(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const cuComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrsv2Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseCcsrsv2_analysis(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_analysis(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const cuDoubleComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrsv2Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseZcsrsv2_analysis(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } -*/ - - - /** - * Template wrapper for cusparsecsric02_analysis - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csric02_analysis). - * This function performs the analysis phase of the incomplete-Cholesky - * factorization with 0 fill-in and no pivoting. - */ - template - cusparseStatus_t - cusparseXcsric02_analysis(cusparseHandle_t /*handle*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - const Number * /*csrValA*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csric02Info_t /*info*/, - cusparseSolvePolicy_t /*policy*/, - void * /*pBuffer*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsric02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const float *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseScsric02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsric02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const double *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void *pBuffer) - { - return cusparseDcsric02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - /* - template <> - cusparseStatus_t - cusparseXcsric02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const cuComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseCcsric02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } - - template <> - cusparseStatus_t - cusparseXcsric02_analysis(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - const cuDoubleComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csric02Info_t info, - cusparseSolvePolicy_t policy, - void * pBuffer) - { - return cusparseZcsric02_analysis(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - policy, - pBuffer); - } -*/ - - - - /** - * Template wrapper for cusparsecsrsv2_bufferSize - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csrsv2_bufferSize). - * This function returns the size of the buffer used in csrsv2, a new sparse - * triangular linear system op(A)*y = alpha*x. - */ - template - cusparseStatus_t - cusparseXcsrsv2_bufferSize(cusparseHandle_t /*handle*/, - cusparseOperation_t /*transA*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - Number * /*csrValA*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csrsv2Info_t /*info*/, - int * /*pBufferSizeInBytes*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_bufferSize(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - float *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrsv2Info_t info, - int *pBufferSizeInBytes) - { - return cusparseScsrsv2_bufferSize(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_bufferSize(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - double *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csrsv2Info_t info, - int *pBufferSizeInBytes) - { - return cusparseDcsrsv2_bufferSize(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - /* - template <> - cusparseStatus_t - cusparseXcsrsv2_bufferSize(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrsv2Info_t info, - int *pBufferSizeInBytes) - { - return cusparseCcsrsv2_bufferSize(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - template <> - cusparseStatus_t - cusparseXcsrsv2_bufferSize(cusparseHandle_t handle, - cusparseOperation_t transA, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuDoubleComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csrsv2Info_t info, - int * pBufferSizeInBytes) - { - return cusparseZcsrsv2_bufferSize(handle, - transA, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } -*/ - - - - /** - * Template wrapper for cusparsecsric02_bufferSize - * (https://docs.nvidia.com/cuda/cusparse/index.html#cusparse-lt-t-gt-csric02_bufferSize). - * This function returns size of buffer used in computing the - * incomplete-Cholesky factorization with 0 fill-in and no pivoting. - */ - template - cusparseStatus_t - cusparseXcsric02_bufferSize(cusparseHandle_t /*handle*/, - int /*m*/, - int /*nnz*/, - const cusparseMatDescr_t /*descrA*/, - Number * /*csrValA*/, - const int * /*csrRowPtrA*/, - const int * /*csrColIndA*/, - csric02Info_t /*info*/, - int * /*pBufferSizeInBytes*/) - { - AssertThrow(false, ExcNotImplemented()); - return CUSPARSE_STATUS_INVALID_VALUE; - } - - template <> - cusparseStatus_t - cusparseXcsric02_bufferSize(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - float *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csric02Info_t info, - int *pBufferSizeInBytes) - { - return cusparseScsric02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - template <> - cusparseStatus_t - cusparseXcsric02_bufferSize(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - double *csrValA, - const int *csrRowPtrA, - const int *csrColIndA, - csric02Info_t info, - int *pBufferSizeInBytes) - { - return cusparseDcsric02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - /* - template <> - cusparseStatus_t - cusparseXcsric02_bufferSize(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csric02Info_t info, - int *pBufferSizeInBytes) - { - return cusparseCcsric02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - - template <> - cusparseStatus_t - cusparseXcsric02_bufferSize(cusparseHandle_t handle, - int m, - int nnz, - const cusparseMatDescr_t descrA, - cuDoubleComplex * csrValA, - const int * csrRowPtrA, - const int * csrColIndA, - csric02Info_t info, - int * pBufferSizeInBytes) - { - return cusparseZcsric02_bufferSize(handle, - m, - nnz, - descrA, - csrValA, - csrRowPtrA, - csrColIndA, - info, - pBufferSizeInBytes); - } - */ -} // namespace - -namespace CUDAWrappers -{ - template - PreconditionIC::AdditionalData::AdditionalData( - bool use_level_analysis_) - : use_level_analysis(use_level_analysis_) - {} - - - - template - PreconditionIC::PreconditionIC(const Utilities::CUDA::Handle &handle) - : cusparse_handle(handle.cusparse_handle) - , P_val_dev(nullptr, Utilities::CUDA::delete_device_data) - , P_row_ptr_dev(nullptr) - , P_column_index_dev(nullptr) - , tmp_dev(nullptr, Utilities::CUDA::delete_device_data) - , buffer_dev(nullptr, Utilities::CUDA::delete_device_data) - , policy_L(CUSPARSE_SOLVE_POLICY_USE_LEVEL) - , policy_Lt(CUSPARSE_SOLVE_POLICY_USE_LEVEL) - , policy_M(CUSPARSE_SOLVE_POLICY_USE_LEVEL) - , n_rows(0) - , n_nonzero_elements(0) - { - // step 1: create a descriptor which contains - // - matrix M is base-0 - // - matrix L is base-0 - // - matrix L is lower triangular - // - matrix L has non-unit diagonal - cusparseStatus_t status = cusparseCreateMatDescr(&descr_M); - AssertCusparse(status); - status = cusparseSetMatIndexBase(descr_M, CUSPARSE_INDEX_BASE_ZERO); - AssertCusparse(status); - status = cusparseSetMatType(descr_M, CUSPARSE_MATRIX_TYPE_GENERAL); - AssertCusparse(status); - - status = cusparseCreateMatDescr(&descr_L); - AssertCusparse(status); - status = cusparseSetMatIndexBase(descr_L, CUSPARSE_INDEX_BASE_ZERO); - AssertCusparse(status); - status = cusparseSetMatType(descr_L, CUSPARSE_MATRIX_TYPE_GENERAL); - AssertCusparse(status); - status = cusparseSetMatFillMode(descr_L, CUSPARSE_FILL_MODE_LOWER); - AssertCusparse(status); - status = cusparseSetMatDiagType(descr_L, CUSPARSE_DIAG_TYPE_NON_UNIT); - AssertCusparse(status); - - // step 2: create a empty info structure - // we need one info for csric02 and two info's for csrsv2 - status = cusparseCreateCsric02Info(&info_M); - AssertCusparse(status); - status = cusparseCreateCsrsv2Info(&info_L); - AssertCusparse(status); - status = cusparseCreateCsrsv2Info(&info_Lt); - AssertCusparse(status); - } - - - - template - PreconditionIC::~PreconditionIC() - { - // step 8: free resources - cusparseStatus_t status = cusparseDestroyMatDescr(descr_M); - AssertNothrowCusparse(status); - - status = cusparseDestroyMatDescr(descr_L); - AssertNothrowCusparse(status); - - status = cusparseDestroyCsric02Info(info_M); - AssertNothrowCusparse(status); - - status = cusparseDestroyCsrsv2Info(info_L); - AssertNothrowCusparse(status); - - status = cusparseDestroyCsrsv2Info(info_Lt); - AssertNothrowCusparse(status); - } - - - - template - void - PreconditionIC::initialize(const SparseMatrix &A, - const AdditionalData &additional_data) - { - if (additional_data.use_level_analysis) - { - policy_L = CUSPARSE_SOLVE_POLICY_USE_LEVEL; - policy_Lt = CUSPARSE_SOLVE_POLICY_USE_LEVEL; - policy_M = CUSPARSE_SOLVE_POLICY_USE_LEVEL; - } - else - { - policy_L = CUSPARSE_SOLVE_POLICY_NO_LEVEL; - policy_Lt = CUSPARSE_SOLVE_POLICY_NO_LEVEL; - policy_M = CUSPARSE_SOLVE_POLICY_NO_LEVEL; - } - - n_rows = A.m(); - n_nonzero_elements = A.n_nonzero_elements(); - AssertDimension(A.m(), A.n()); - - matrix_pointer = &A; - const Number *A_val_dev; - std::tie(A_val_dev, - P_column_index_dev, - P_row_ptr_dev, - std::ignore, - std::ignore) = A.get_cusparse_matrix(); - - // create a copy of the matrix entries since the algorithm works in-place. - P_val_dev.reset( - Utilities::CUDA::allocate_device_data(n_nonzero_elements)); - cudaError_t cuda_status = cudaMemcpy(P_val_dev.get(), - A_val_dev, - n_nonzero_elements * sizeof(Number), - cudaMemcpyDeviceToDevice); - AssertCuda(cuda_status); - - // initialize an internal buffer we need later on - tmp_dev.reset(Utilities::CUDA::allocate_device_data(n_rows)); - - // step 3: query how much memory used in csric02 and csrsv2, and allocate - // the buffer - int BufferSize_M; - cusparseStatus_t status = cusparseXcsric02_bufferSize(cusparse_handle, - n_rows, - n_nonzero_elements, - descr_M, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_M, - &BufferSize_M); - AssertCusparse(status); - - int BufferSize_L; - status = cusparseXcsrsv2_bufferSize(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_L, - &BufferSize_L); - AssertCusparse(status); - - int BufferSize_Lt; - status = cusparseXcsrsv2_bufferSize(cusparse_handle, - CUSPARSE_OPERATION_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_Lt, - &BufferSize_Lt); - AssertCusparse(status); - - const int BufferSize = - std::max(BufferSize_M, std::max(BufferSize_L, BufferSize_Lt)); - // workaround: since allocate_device_data needs a type, we pass char - // which is required to have size 1. - buffer_dev.reset(static_cast( - Utilities::CUDA::allocate_device_data(BufferSize / sizeof(char)))); - - // step 4: perform analysis of incomplete Cholesky on M - // perform analysis of triangular solve on L - // perform analysis of triangular solve on L' - // The lower triangular part of M has the same sparsity pattern as L, so - // we can do analysis of csric02 and csrsv2 simultaneously. - - status = cusparseXcsric02_analysis(cusparse_handle, - n_rows, - n_nonzero_elements, - descr_M, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_M, - policy_M, - buffer_dev.get()); - AssertCusparse(status); - - int structural_zero; - status = - cusparseXcsric02_zeroPivot(cusparse_handle, info_M, &structural_zero); - AssertCusparse(status); - - status = cusparseXcsrsv2_analysis(cusparse_handle, - CUSPARSE_OPERATION_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_Lt, - policy_Lt, - buffer_dev.get()); - AssertCusparse(status); - - status = cusparseXcsrsv2_analysis(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_L, - policy_L, - buffer_dev.get()); - AssertCusparse(status); - - // step 5: M = L * L' - status = cusparseXcsric02(cusparse_handle, - n_rows, - n_nonzero_elements, - descr_M, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_M, - policy_M, - buffer_dev.get()); - AssertCusparse(status); - - int numerical_zero; - status = - cusparseXcsric02_zeroPivot(cusparse_handle, info_M, &numerical_zero); - AssertCusparse(status); - } - - - - template - void - PreconditionIC::vmult( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const - { - Assert(P_val_dev != nullptr, ExcNotInitialized()); - Assert(P_row_ptr_dev != nullptr, ExcNotInitialized()); - Assert(P_column_index_dev != nullptr, ExcNotInitialized()); - AssertDimension(dst.size(), static_cast(n_rows)); - AssertDimension(src.size(), static_cast(n_rows)); - Assert(tmp_dev != nullptr, ExcInternalError()); - - const Number *const src_dev = src.get_values(); - Number *const dst_dev = dst.get_values(); - // step 6: solve L*z = alpha*x - const Number alpha = internal::NumberType::value(1.); - cusparseStatus_t status = - cusparseXcsrsv2_solve(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - &alpha, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_L, - src_dev, - tmp_dev.get(), - policy_L, - buffer_dev.get()); - AssertCusparse(status); - - // step 7: solve L'*y = alpha*z - status = cusparseXcsrsv2_solve(cusparse_handle, - CUSPARSE_OPERATION_TRANSPOSE, - n_rows, - n_nonzero_elements, - &alpha, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_Lt, - tmp_dev.get(), - dst_dev, - policy_Lt, - buffer_dev.get()); - AssertCusparse(status); - } - - - - template - void - PreconditionIC::Tvmult( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const - { - // the constructed preconditioner is symmetric - vmult(dst, src); - } - - - - template - PreconditionILU::AdditionalData::AdditionalData( - bool use_level_analysis_) - : use_level_analysis(use_level_analysis_) - {} - - - - template - PreconditionILU::PreconditionILU( - const Utilities::CUDA::Handle &handle) - : cusparse_handle(handle.cusparse_handle) - , P_val_dev(nullptr, Utilities::CUDA::delete_device_data) - , P_row_ptr_dev(nullptr) - , P_column_index_dev(nullptr) - , tmp_dev(nullptr, Utilities::CUDA::delete_device_data) - , buffer_dev(nullptr, Utilities::CUDA::delete_device_data) - , policy_L(CUSPARSE_SOLVE_POLICY_USE_LEVEL) - , policy_U(CUSPARSE_SOLVE_POLICY_USE_LEVEL) - , policy_M(CUSPARSE_SOLVE_POLICY_USE_LEVEL) - , n_rows(0) - , n_nonzero_elements(0) - { - // step 1: create a descriptor which contains - // - matrix M is base-0 - // - matrix L is base-0 - // - matrix L is lower triangular - // - matrix L has unit diagonal - // - matrix U is base-0 - // - matrix U is upper triangular - // - matrix U has non-unit diagonal - cusparseStatus_t status = cusparseCreateMatDescr(&descr_M); - AssertCusparse(status); - status = cusparseSetMatIndexBase(descr_M, CUSPARSE_INDEX_BASE_ZERO); - AssertCusparse(status); - status = cusparseSetMatType(descr_M, CUSPARSE_MATRIX_TYPE_GENERAL); - AssertCusparse(status); - - status = cusparseCreateMatDescr(&descr_L); - AssertCusparse(status); - status = cusparseSetMatIndexBase(descr_L, CUSPARSE_INDEX_BASE_ZERO); - AssertCusparse(status); - status = cusparseSetMatType(descr_L, CUSPARSE_MATRIX_TYPE_GENERAL); - AssertCusparse(status); - status = cusparseSetMatFillMode(descr_L, CUSPARSE_FILL_MODE_LOWER); - AssertCusparse(status); - status = cusparseSetMatDiagType(descr_L, CUSPARSE_DIAG_TYPE_UNIT); - AssertCusparse(status); - - status = cusparseCreateMatDescr(&descr_U); - AssertCusparse(status); - status = cusparseSetMatIndexBase(descr_U, CUSPARSE_INDEX_BASE_ZERO); - AssertCusparse(status); - status = cusparseSetMatType(descr_U, CUSPARSE_MATRIX_TYPE_GENERAL); - AssertCusparse(status); - status = cusparseSetMatFillMode(descr_U, CUSPARSE_FILL_MODE_UPPER); - AssertCusparse(status); - status = cusparseSetMatDiagType(descr_U, CUSPARSE_DIAG_TYPE_NON_UNIT); - AssertCusparse(status); - - // step 2: create a empty info structure - // we need one info for csrilu02 and two info's for csrsv2 - status = cusparseCreateCsrilu02Info(&info_M); - AssertCusparse(status); - status = cusparseCreateCsrsv2Info(&info_L); - AssertCusparse(status); - status = cusparseCreateCsrsv2Info(&info_U); - AssertCusparse(status); - } - - - - template - PreconditionILU::~PreconditionILU() - { - // step 8: free resources - cusparseStatus_t status = cusparseDestroyMatDescr(descr_M); - AssertNothrowCusparse(status); - - status = cusparseDestroyMatDescr(descr_L); - AssertNothrowCusparse(status); - - status = cusparseDestroyMatDescr(descr_U); - AssertNothrowCusparse(status); - - status = cusparseDestroyCsrilu02Info(info_M); - AssertNothrowCusparse(status); - - status = cusparseDestroyCsrsv2Info(info_L); - AssertNothrowCusparse(status); - - status = cusparseDestroyCsrsv2Info(info_U); - AssertNothrowCusparse(status); - } - - - - template - void - PreconditionILU::initialize(const SparseMatrix &A, - const AdditionalData &additional_data) - { - if (additional_data.use_level_analysis) - { - policy_L = CUSPARSE_SOLVE_POLICY_USE_LEVEL; - policy_U = CUSPARSE_SOLVE_POLICY_USE_LEVEL; - policy_M = CUSPARSE_SOLVE_POLICY_USE_LEVEL; - } - else - { - policy_L = CUSPARSE_SOLVE_POLICY_NO_LEVEL; - policy_U = CUSPARSE_SOLVE_POLICY_NO_LEVEL; - policy_M = CUSPARSE_SOLVE_POLICY_NO_LEVEL; - } - - matrix_pointer = &A; - n_rows = A.m(); - n_nonzero_elements = A.n_nonzero_elements(); - AssertDimension(A.m(), A.n()); - - const Number *A_val_dev; - std::tie(A_val_dev, - P_column_index_dev, - P_row_ptr_dev, - std::ignore, - std::ignore) = A.get_cusparse_matrix(); - - // create a copy of the matrix entries since the algorithm works in-place. - P_val_dev.reset( - Utilities::CUDA::allocate_device_data(n_nonzero_elements)); - cudaError_t cuda_status = cudaMemcpy(P_val_dev.get(), - A_val_dev, - n_nonzero_elements * sizeof(Number), - cudaMemcpyDeviceToDevice); - AssertCuda(cuda_status); - - // initialize an internal buffer we need later on - tmp_dev.reset(Utilities::CUDA::allocate_device_data(n_rows)); - - // step 3: query how much memory used in csrilu02 and csrsv2, and allocate - // the buffer - int BufferSize_M; - cusparseStatus_t status = cusparseXcsrilu02_bufferSize(cusparse_handle, - n_rows, - n_nonzero_elements, - descr_M, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_M, - &BufferSize_M); - AssertCusparse(status); - - int BufferSize_L; - status = cusparseXcsrsv2_bufferSize(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_L, - &BufferSize_L); - AssertCusparse(status); - - int BufferSize_U; - status = cusparseXcsrsv2_bufferSize(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_U, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_U, - &BufferSize_U); - AssertCusparse(status); - - const int BufferSize = - std::max(BufferSize_M, std::max(BufferSize_L, BufferSize_U)); - // workaround: since allocate_device_data needs a type, we pass char - // which is required to have size 1. - buffer_dev.reset(static_cast( - Utilities::CUDA::allocate_device_data(BufferSize / sizeof(char)))); - - // step 4: perform analysis of incomplete Cholesky on M - // perform analysis of triangular solve on L - // perform analysis of triangular solve on U - // The lower(upper) triangular part of M has the same sparsity pattern as - // L(U), we can do analysis of csrilu0 and csrsv2 simultaneously. - - status = cusparseXcsrilu02_analysis(cusparse_handle, - n_rows, - n_nonzero_elements, - descr_M, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_M, - policy_M, - buffer_dev.get()); - AssertCusparse(status); - - int structural_zero; - status = - cusparseXcsrilu02_zeroPivot(cusparse_handle, info_M, &structural_zero); - AssertCusparse(status); - - status = cusparseXcsrsv2_analysis(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_L, - policy_L, - buffer_dev.get()); - AssertCusparse(status); - - status = cusparseXcsrsv2_analysis(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - descr_U, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_U, - policy_U, - buffer_dev.get()); - - // step 5: M = L * U - status = cusparseXcsrilu02(cusparse_handle, - n_rows, - n_nonzero_elements, - descr_M, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_M, - policy_M, - buffer_dev.get()); - AssertCusparse(status); - - int numerical_zero; - status = - cusparseXcsrilu02_zeroPivot(cusparse_handle, info_M, &numerical_zero); - AssertCusparse(status); - } - - - - template - void - PreconditionILU::vmult( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const - { - Assert(P_val_dev != nullptr, ExcNotInitialized()); - Assert(P_row_ptr_dev != nullptr, ExcNotInitialized()); - Assert(P_column_index_dev != nullptr, ExcNotInitialized()); - AssertDimension(dst.size(), static_cast(n_rows)); - AssertDimension(src.size(), static_cast(n_rows)); - Assert(tmp_dev != nullptr, ExcInternalError()); - - const Number *const src_dev = src.get_values(); - Number *const dst_dev = dst.get_values(); - - // step 6: solve L*z = alpha*x - const Number alpha = internal::NumberType::value(1.); - cusparseStatus_t status = - cusparseXcsrsv2_solve(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - &alpha, - descr_L, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_L, - src_dev, - tmp_dev.get(), - policy_L, - buffer_dev.get()); - AssertCusparse(status); - - // step 7: solve U*y = alpha*z - status = cusparseXcsrsv2_solve(cusparse_handle, - CUSPARSE_OPERATION_NON_TRANSPOSE, - n_rows, - n_nonzero_elements, - &alpha, - descr_U, - P_val_dev.get(), - P_row_ptr_dev, - P_column_index_dev, - info_U, - tmp_dev.get(), - dst_dev, - policy_U, - buffer_dev.get()); - AssertCusparse(status); - } - - - - template - void - PreconditionILU::Tvmult( - LinearAlgebra::CUDAWrappers::Vector & /*dst*/, - const LinearAlgebra::CUDAWrappers::Vector & /*src*/) const - { - DEAL_II_NOT_IMPLEMENTED(); - } - - - - // explicit instantiations - template class PreconditionIC; - template class PreconditionIC; - // template class PreconditionIC; - // template class PreconditionIC; - template class PreconditionILU; - template class PreconditionILU; - // template class PreconditionILU; - // template class PreconditionILU; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE diff --git a/source/lac/cuda_solver_direct.cc b/source/lac/cuda_solver_direct.cc deleted file mode 100644 index 21860dd793..0000000000 --- a/source/lac/cuda_solver_direct.cc +++ /dev/null @@ -1,488 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include - -DEAL_II_NAMESPACE_OPEN - -namespace CUDAWrappers -{ - namespace - { - void - cusparsecsr2dense(cusparseHandle_t cusparse_handle, - const SparseMatrix &matrix, - float *dense_matrix_dev) - { - auto cusparse_matrix = matrix.get_cusparse_matrix(); - - const cusparseStatus_t cusparse_error_code = - cusparseScsr2dense(cusparse_handle, - matrix.m(), - matrix.n(), - std::get<3>(cusparse_matrix), - std::get<0>(cusparse_matrix), - std::get<2>(cusparse_matrix), - std::get<1>(cusparse_matrix), - dense_matrix_dev, - matrix.m()); - AssertCusparse(cusparse_error_code); - } - - - - void - cusparsecsr2dense(cusparseHandle_t cusparse_handle, - const SparseMatrix &matrix, - double *dense_matrix_dev) - { - auto cusparse_matrix = matrix.get_cusparse_matrix(); - - const cusparseStatus_t cusparse_error_code = - cusparseDcsr2dense(cusparse_handle, - matrix.m(), - matrix.n(), - std::get<3>(cusparse_matrix), - std::get<0>(cusparse_matrix), - std::get<2>(cusparse_matrix), - std::get<1>(cusparse_matrix), - dense_matrix_dev, - matrix.m()); - AssertCusparse(cusparse_error_code); - } - - - - void - cusolverDngetrf_buffer_size(cusolverDnHandle_t cusolver_dn_handle, - int m, - int n, - float *dense_matrix_dev, - int &workspace_size) - { - const cusolverStatus_t cusolver_error_code = cusolverDnSgetrf_bufferSize( - cusolver_dn_handle, m, n, dense_matrix_dev, m, &workspace_size); - AssertCusolver(cusolver_error_code); - } - - - - void - cusolverDngetrf_buffer_size(cusolverDnHandle_t cusolver_dn_handle, - int m, - int n, - double *dense_matrix_dev, - int &workspace_size) - { - const cusolverStatus_t cusolver_error_code = cusolverDnDgetrf_bufferSize( - cusolver_dn_handle, m, n, dense_matrix_dev, m, &workspace_size); - AssertCusolver(cusolver_error_code); - } - - - - void - cusolverDngetrf(cusolverDnHandle_t cusolver_dn_handle, - int m, - int n, - float *dense_matrix_dev, - float *workspace_dev, - int *pivot_dev, - int *info_dev) - { - const cusolverStatus_t cusolver_error_code = - cusolverDnSgetrf(cusolver_dn_handle, - m, - n, - dense_matrix_dev, - m, - workspace_dev, - pivot_dev, - info_dev); - AssertCusolver(cusolver_error_code); - } - - - - void - cusolverDngetrf(cusolverDnHandle_t cusolver_dn_handle, - int m, - int n, - double *dense_matrix_dev, - double *workspace_dev, - int *pivot_dev, - int *info_dev) - { - const cusolverStatus_t cusolver_error_code = - cusolverDnDgetrf(cusolver_dn_handle, - m, - n, - dense_matrix_dev, - m, - workspace_dev, - pivot_dev, - info_dev); - AssertCusolver(cusolver_error_code); - } - - - - void - cusolverDngetrs(cusolverDnHandle_t cusolver_dn_handle, - int m, - float *dense_matrix_dev, - int *pivot_dev, - float *b, - int *info_dev) - { - const int n_rhs = 1; - const cusolverStatus_t cusolver_error_code = - cusolverDnSgetrs(cusolver_dn_handle, - CUBLAS_OP_N, - m, - n_rhs, - dense_matrix_dev, - m, - pivot_dev, - b, - m, - info_dev); - AssertCusolver(cusolver_error_code); - } - - - - void - cusolverDngetrs(cusolverDnHandle_t cusolver_dn_handle, - int m, - double *dense_matrix_dev, - int *pivot_dev, - double *b, - int *info_dev) - { - const int n_rhs = 1; - const cusolverStatus_t cusolver_error_code = - cusolverDnDgetrs(cusolver_dn_handle, - CUBLAS_OP_N, - m, - n_rhs, - dense_matrix_dev, - m, - pivot_dev, - b, - m, - info_dev); - AssertCusolver(cusolver_error_code); - } - - - - void - cusolverSpcsrlsvluHost(cusolverSpHandle_t cusolver_sp_handle, - const unsigned int n_rows, - const unsigned int nnz, - cusparseMatDescr_t descr, - const float *val_host, - const int *row_ptr_host, - const int *column_index_host, - const float *b_host, - float *x_host) - { - int singularity = 0; - const cusolverStatus_t cusolver_error_code = - cusolverSpScsrlsvluHost(cusolver_sp_handle, - n_rows, - nnz, - descr, - val_host, - row_ptr_host, - column_index_host, - b_host, - 0., - 1, - x_host, - &singularity); - AssertCusolver(cusolver_error_code); - Assert(singularity == -1, ExcMessage("Coarse matrix is singular")); - } - - - - void - cusolverSpcsrlsvluHost(cusolverSpHandle_t cusolver_sp_handle, - const unsigned int n_rows, - unsigned int nnz, - cusparseMatDescr_t descr, - const double *val_host, - const int *row_ptr_host, - const int *column_index_host, - const double *b_host, - double *x_host) - { - int singularity = 0; - const cusolverStatus_t cusolver_error_code = - cusolverSpDcsrlsvluHost(cusolver_sp_handle, - n_rows, - nnz, - descr, - val_host, - row_ptr_host, - column_index_host, - b_host, - 0., - 1, - x_host, - &singularity); - AssertCusolver(cusolver_error_code); - Assert(singularity == -1, ExcMessage("Coarse matrix is singular")); - } - - - - void - cholesky_factorization(cusolverSpHandle_t cusolver_sp_handle, - const SparseMatrix &matrix, - const float *b, - float *x) - { - auto cusparse_matrix = matrix.get_cusparse_matrix(); - int singularity = 0; - - const cusolverStatus_t cusolver_error_code = - cusolverSpScsrlsvchol(cusolver_sp_handle, - matrix.m(), - matrix.n_nonzero_elements(), - std::get<3>(cusparse_matrix), - std::get<0>(cusparse_matrix), - std::get<2>(cusparse_matrix), - std::get<1>(cusparse_matrix), - b, - 0., - 0, - x, - &singularity); - AssertCusolver(cusolver_error_code); - Assert(singularity == -1, ExcMessage("Coarse matrix is not SPD")); - } - - - - void - cholesky_factorization(cusolverSpHandle_t cusolver_sp_handle, - const SparseMatrix &matrix, - const double *b, - double *x) - { - auto cusparse_matrix = matrix.get_cusparse_matrix(); - int singularity = 0; - - const cusolverStatus_t cusolver_error_code = - cusolverSpDcsrlsvchol(cusolver_sp_handle, - matrix.m(), - matrix.n_nonzero_elements(), - std::get<3>(cusparse_matrix), - std::get<0>(cusparse_matrix), - std::get<2>(cusparse_matrix), - std::get<1>(cusparse_matrix), - b, - 0., - 0, - x, - &singularity); - AssertCusolver(cusolver_error_code); - Assert(singularity == -1, ExcMessage("Coarse matrix is not SPD")); - } - - - - template - void - lu_factorization(cusparseHandle_t cusparse_handle, - cusolverDnHandle_t cusolver_dn_handle, - const SparseMatrix &matrix, - const Number *b_dev, - Number *x_dev) - { - // Change the format of the matrix from sparse to dense - const unsigned int m = matrix.m(); - const unsigned int n = matrix.n(); - Assert(m == n, ExcMessage("The matrix is not square")); - Number *dense_matrix_dev; - Utilities::CUDA::malloc(dense_matrix_dev, m * n); - - // Change the format of matrix to dense - cusparsecsr2dense(cusparse_handle, matrix, dense_matrix_dev); - - // Create the working space - int workspace_size = 0; - cusolverDngetrf_buffer_size( - cusolver_dn_handle, m, n, dense_matrix_dev, workspace_size); - Assert(workspace_size > 0, ExcMessage("No workspace was allocated")); - Number *workspace_dev; - Utilities::CUDA::malloc(workspace_dev, workspace_size); - - // LU factorization - int *pivot_dev; - Utilities::CUDA::malloc(pivot_dev, m); - int *info_dev; - Utilities::CUDA::malloc(info_dev, 1); - - cusolverDngetrf(cusolver_dn_handle, - m, - n, - dense_matrix_dev, - workspace_dev, - pivot_dev, - info_dev); - -#ifdef DEBUG - int info = 0; - cudaError_t cuda_error_code_debug = - cudaMemcpy(&info, info_dev, sizeof(int), cudaMemcpyDeviceToHost); - AssertCuda(cuda_error_code_debug); - Assert(info == 0, - ExcMessage("There was a problem during the LU factorization")); -#endif - - // Solve Ax = b - cudaError_t cuda_error_code = - cudaMemcpy(x_dev, b_dev, m * sizeof(Number), cudaMemcpyDeviceToDevice); - AssertCuda(cuda_error_code); - cusolverDngetrs( - cusolver_dn_handle, m, dense_matrix_dev, pivot_dev, x_dev, info_dev); -#ifdef DEBUG - cuda_error_code = - cudaMemcpy(&info, info_dev, sizeof(int), cudaMemcpyDeviceToHost); - AssertCuda(cuda_error_code); - Assert(info == 0, ExcMessage("There was a problem during the LU solve")); -#endif - - // Free the memory allocated - Utilities::CUDA::free(dense_matrix_dev); - Utilities::CUDA::free(workspace_dev); - Utilities::CUDA::free(pivot_dev); - Utilities::CUDA::free(info_dev); - } - - - - template - void - lu_factorization(cusolverSpHandle_t cusolver_sp_handle, - const SparseMatrix &matrix, - const Number *b_dev, - Number *x_dev) - { - // cuSOLVER does not support LU factorization of sparse matrix on the - // device, so we need to move everything to the host first and then back - // to the host. - const unsigned int nnz = matrix.n_nonzero_elements(); - const unsigned int n_rows = matrix.m(); - std::vector val_host(nnz); - std::vector column_index_host(nnz); - std::vector row_ptr_host(n_rows + 1); - auto cusparse_matrix = matrix.get_cusparse_matrix(); - Utilities::CUDA::copy_to_host(std::get<0>(cusparse_matrix), val_host); - Utilities::CUDA::copy_to_host(std::get<1>(cusparse_matrix), - column_index_host); - Utilities::CUDA::copy_to_host(std::get<2>(cusparse_matrix), row_ptr_host); - std::vector b_host(n_rows); - Utilities::CUDA::copy_to_host(b_dev, b_host); - std::vector x_host(n_rows); - Utilities::CUDA::copy_to_host(x_dev, x_host); - - cusolverSpcsrlsvluHost(cusolver_sp_handle, - n_rows, - nnz, - std::get<3>(cusparse_matrix), - val_host.data(), - row_ptr_host.data(), - column_index_host.data(), - b_host.data(), - x_host.data()); - - // Move the solution back to the device - Utilities::CUDA::copy_to_dev(x_host, x_dev); - } - } // namespace - - - - template - SolverDirect::AdditionalData::AdditionalData( - const std::string &solver_type) - : solver_type(solver_type) - {} - - - - template - SolverDirect::SolverDirect(const Utilities::CUDA::Handle &handle, - SolverControl &cn, - const AdditionalData &data) - : cuda_handle(handle) - , solver_control(cn) - , additional_data(data.solver_type) - {} - - - - template - SolverControl & - SolverDirect::control() const - { - return solver_control; - } - - - - template - void - SolverDirect::solve( - const SparseMatrix &A, - LinearAlgebra::CUDAWrappers::Vector &x, - const LinearAlgebra::CUDAWrappers::Vector &b) - { - if (additional_data.solver_type == "Cholesky") - cholesky_factorization(cuda_handle.cusolver_sp_handle, - A, - b.get_values(), - x.get_values()); - else if (additional_data.solver_type == "LU_dense") - lu_factorization(cuda_handle.cusparse_handle, - cuda_handle.cusolver_dn_handle, - A, - b.get_values(), - x.get_values()); - else if (additional_data.solver_type == "LU_host") - lu_factorization(cuda_handle.cusolver_sp_handle, - A, - b.get_values(), - x.get_values()); - else - AssertThrow(false, - ExcMessage("The provided solver name " + - additional_data.solver_type + " is invalid.")); - - // Force the SolverControl object to report convergence - solver_control.check(0, 0); - } - - - // Explicit Instanationation - template class SolverDirect; - template class SolverDirect; -} // namespace CUDAWrappers - -DEAL_II_NAMESPACE_CLOSE diff --git a/source/lac/cuda_sparse_matrix.cc b/source/lac/cuda_sparse_matrix.cc deleted file mode 100644 index a4e156e10d..0000000000 --- a/source/lac/cuda_sparse_matrix.cc +++ /dev/null @@ -1,695 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include -#include - -#include -#include - -#ifdef DEAL_II_WITH_CUDA - -# include - -DEAL_II_NAMESPACE_OPEN - -namespace CUDAWrappers -{ - namespace internal - { - template - __global__ void - scale(Number *val, - const Number a, - const typename SparseMatrix::size_type N) - { - const typename SparseMatrix::size_type idx = - threadIdx.x + blockIdx.x * blockDim.x; - if (idx < N) - val[idx] *= a; - } - - - - void - create_sp_mat_descr(int m, - int n, - int nnz, - const float *A_val_dev, - const int *A_row_ptr_dev, - const int *A_column_index_dev, - cusparseSpMatDescr_t &sp_descr) - { - cusparseStatus_t error_code = cusparseCreateCsr( - &sp_descr, - m, - n, - nnz, - reinterpret_cast(const_cast(A_row_ptr_dev)), - reinterpret_cast(const_cast(A_column_index_dev)), - reinterpret_cast(const_cast(A_val_dev)), - CUSPARSE_INDEX_32I, - CUSPARSE_INDEX_32I, - CUSPARSE_INDEX_BASE_ZERO, - CUDA_R_32F); - AssertCusparse(error_code); - } - - - - void - create_sp_mat_descr(int m, - int n, - int nnz, - const double *A_val_dev, - const int *A_row_ptr_dev, - const int *A_column_index_dev, - cusparseSpMatDescr_t &sp_descr) - { - cusparseStatus_t error_code = cusparseCreateCsr( - &sp_descr, - m, - n, - nnz, - reinterpret_cast(const_cast(A_row_ptr_dev)), - reinterpret_cast(const_cast(A_column_index_dev)), - reinterpret_cast(const_cast(A_val_dev)), - CUSPARSE_INDEX_32I, - CUSPARSE_INDEX_32I, - CUSPARSE_INDEX_BASE_ZERO, - CUDA_R_64F); - AssertCusparse(error_code); - } - - - - void - csrmv(cusparseHandle_t handle, - bool transpose, - int m, - int n, - const cusparseSpMatDescr_t sp_descr, - const float *x, - bool add, - float *y) - { - float alpha = 1.; - float beta = add ? 1. : 0.; - cusparseOperation_t cusparse_operation = - transpose ? CUSPARSE_OPERATION_TRANSPOSE : - CUSPARSE_OPERATION_NON_TRANSPOSE; - - // Move the data to cuSPARSE data type - cusparseDnVecDescr_t x_cuvec; - cusparseStatus_t error_code = - cusparseCreateDnVec(&x_cuvec, - n, - reinterpret_cast(const_cast(x)), - CUDA_R_32F); - AssertCusparse(error_code); - - cusparseDnVecDescr_t y_cuvec; - error_code = - cusparseCreateDnVec(&y_cuvec, - m, - reinterpret_cast(const_cast(y)), - CUDA_R_32F); - AssertCusparse(error_code); - - // This function performs y = alpha*op(A)*x + beta*y - size_t buffer_size = 0; - error_code = cusparseSpMV_bufferSize(handle, - cusparse_operation, - &alpha, - sp_descr, - x_cuvec, - &beta, - y_cuvec, - CUDA_R_32F, - CUSPARSE_MV_ALG_DEFAULT, - &buffer_size); - - void *buffer = nullptr; - cudaError_t cuda_error_code = cudaMalloc(&buffer, buffer_size); - AssertCuda(cuda_error_code); - - // execute SpMV - error_code = cusparseSpMV(handle, - cusparse_operation, - &alpha, - sp_descr, - x_cuvec, - &beta, - y_cuvec, - CUDA_R_32F, - CUSPARSE_MV_ALG_DEFAULT, - buffer); - AssertCusparse(error_code); - - cuda_error_code = cudaFree(buffer); - AssertCuda(cuda_error_code); - error_code = cusparseDestroyDnVec(x_cuvec); - AssertCusparse(error_code); - error_code = cusparseDestroyDnVec(y_cuvec); - AssertCusparse(error_code); - } - - - - void - csrmv(cusparseHandle_t handle, - bool transpose, - int m, - int n, - const cusparseSpMatDescr_t sp_descr, - const double *x, - bool add, - double *y) - { - double alpha = 1.; - double beta = add ? 1. : 0.; - cusparseOperation_t cusparse_operation = - transpose ? CUSPARSE_OPERATION_TRANSPOSE : - CUSPARSE_OPERATION_NON_TRANSPOSE; - - // Move the data to cuSPARSE data type - cusparseDnVecDescr_t x_cuvec; - cusparseStatus_t error_code = - cusparseCreateDnVec(&x_cuvec, - n, - reinterpret_cast(const_cast(x)), - CUDA_R_64F); - AssertCusparse(error_code); - - cusparseDnVecDescr_t y_cuvec; - error_code = - cusparseCreateDnVec(&y_cuvec, - m, - reinterpret_cast(const_cast(y)), - CUDA_R_64F); - AssertCusparse(error_code); - - // This function performs y = alpha*op(A)*x + beta*y - size_t buffer_size = 0; - error_code = cusparseSpMV_bufferSize(handle, - cusparse_operation, - &alpha, - sp_descr, - x_cuvec, - &beta, - y_cuvec, - CUDA_R_64F, - CUSPARSE_MV_ALG_DEFAULT, - &buffer_size); - - void *buffer = nullptr; - cudaError_t cuda_error_code = cudaMalloc(&buffer, buffer_size); - AssertCuda(cuda_error_code); - - // execute SpMV - error_code = cusparseSpMV(handle, - cusparse_operation, - &alpha, - sp_descr, - x_cuvec, - &beta, - y_cuvec, - CUDA_R_64F, - CUSPARSE_MV_ALG_DEFAULT, - buffer); - AssertCusparse(error_code); - - cuda_error_code = cudaFree(buffer); - AssertCuda(cuda_error_code); - error_code = cusparseDestroyDnVec(x_cuvec); - AssertCusparse(error_code); - error_code = cusparseDestroyDnVec(y_cuvec); - AssertCusparse(error_code); - } - - - - template - __global__ void - l1_norm(const typename SparseMatrix::size_type n_rows, - const Number *val_dev, - const int *column_index_dev, - const int *row_ptr_dev, - Number *sums) - { - const typename SparseMatrix::size_type row = - threadIdx.x + blockIdx.x * blockDim.x; - - if (row < n_rows) - { - for (int j = row_ptr_dev[row]; j < row_ptr_dev[row + 1]; ++j) - atomicAdd(&sums[column_index_dev[j]], std::abs(val_dev[j])); - } - } - - - - template - __global__ void - linfty_norm(const typename SparseMatrix::size_type n_rows, - const Number *val_dev, - const int * /*column_index_dev*/, - const int *row_ptr_dev, - Number *sums) - { - const typename SparseMatrix::size_type row = - threadIdx.x + blockIdx.x * blockDim.x; - - if (row < n_rows) - { - sums[row] = (Number)0.; - for (int j = row_ptr_dev[row]; j < row_ptr_dev[row + 1]; ++j) - sums[row] += std::abs(val_dev[j]); - } - } - } // namespace internal - - - - template - SparseMatrix::SparseMatrix() - : nnz(0) - , n_rows(0) - , val_dev(nullptr, Utilities::CUDA::delete_device_data) - , column_index_dev(nullptr, Utilities::CUDA::delete_device_data) - , row_ptr_dev(nullptr, Utilities::CUDA::delete_device_data) - , descr(nullptr) - , sp_descr(nullptr) - {} - - - - template - SparseMatrix::SparseMatrix( - Utilities::CUDA::Handle &handle, - const ::dealii::SparseMatrix &sparse_matrix_host) - : val_dev(nullptr, Utilities::CUDA::delete_device_data) - , column_index_dev(nullptr, Utilities::CUDA::delete_device_data) - , row_ptr_dev(nullptr, Utilities::CUDA::delete_device_data) - , descr(nullptr) - , sp_descr(nullptr) - { - reinit(handle, sparse_matrix_host); - } - - - - template - SparseMatrix::SparseMatrix(CUDAWrappers::SparseMatrix &&other) - : cusparse_handle(other.cusparse_handle) - , nnz(other.nnz) - , n_rows(other.n_rows) - , n_cols(other.n_cols) - , val_dev(std::move(other.val_dev)) - , column_index_dev(std::move(other.column_index_dev)) - , row_ptr_dev(std::move(other.row_ptr_dev)) - , descr(other.descr) - , sp_descr(other.sp_descr) - { - other.nnz = 0; - other.n_rows = 0; - other.n_cols = 0; - other.descr = nullptr; - other.sp_descr = nullptr; - } - - - - template - SparseMatrix::~SparseMatrix() - { - if (descr != nullptr) - { - const cusparseStatus_t cusparse_error_code = - cusparseDestroyMatDescr(descr); - AssertNothrowCusparse(cusparse_error_code); - descr = nullptr; - } - - if (sp_descr != nullptr) - { - const cusparseStatus_t cusparse_error_code = - cusparseDestroySpMat(sp_descr); - AssertNothrowCusparse(cusparse_error_code); - sp_descr = nullptr; - } - - nnz = 0; - n_rows = 0; - } - - - - template - SparseMatrix & - SparseMatrix::operator=(SparseMatrix &&other) - { - cusparse_handle = other.cusparse_handle; - nnz = other.nnz; - n_rows = other.n_rows; - n_cols = other.n_cols; - val_dev = std::move(other.val_dev); - column_index_dev = std::move(other.column_index_dev); - row_ptr_dev = std::move(other.row_ptr_dev); - descr = other.descr; - sp_descr = other.sp_descr; - - other.nnz = 0; - other.n_rows = 0; - other.n_cols = 0; - other.descr = nullptr; - other.sp_descr = nullptr; - - return *this; - } - - - - template - void - SparseMatrix::reinit( - Utilities::CUDA::Handle &handle, - const ::dealii::SparseMatrix &sparse_matrix_host) - { - cusparse_handle = handle.cusparse_handle; - nnz = sparse_matrix_host.n_nonzero_elements(); - n_rows = sparse_matrix_host.m(); - n_cols = sparse_matrix_host.n(); - const unsigned int row_ptr_size = n_rows + 1; - std::vector val; - val.reserve(nnz); - std::vector column_index; - column_index.reserve(nnz); - std::vector row_ptr(row_ptr_size, 0); - - // dealii::SparseMatrix stores the diagonal first in each row so we need to - // do some reordering - for (int row = 0; row < n_rows; ++row) - { - auto p_end = sparse_matrix_host.end(row); - unsigned int counter = 0; - for (auto p = sparse_matrix_host.begin(row); p != p_end; ++p) - { - val.emplace_back(p->value()); - column_index.emplace_back(p->column()); - ++counter; - } - row_ptr[row + 1] = row_ptr[row] + counter; - - // Sort the elements in the row - const unsigned int offset = row_ptr[row]; - const int diag_index = column_index[offset]; - Number diag_elem = sparse_matrix_host.diag_element(row); - unsigned int pos = 1; - while ((column_index[offset + pos] < row) && (pos < counter)) - { - val[offset + pos - 1] = val[offset + pos]; - column_index[offset + pos - 1] = column_index[offset + pos]; - ++pos; - } - val[offset + pos - 1] = diag_elem; - column_index[offset + pos - 1] = diag_index; - } - - // Copy the elements to the gpu - val_dev.reset(Utilities::CUDA::allocate_device_data(nnz)); - cudaError_t error_code = cudaMemcpy(val_dev.get(), - val.data(), - nnz * sizeof(Number), - cudaMemcpyHostToDevice); - AssertCuda(error_code); - - // Copy the column indices to the gpu - column_index_dev.reset(Utilities::CUDA::allocate_device_data(nnz)); - AssertCuda(error_code); - error_code = cudaMemcpy(column_index_dev.get(), - column_index.data(), - nnz * sizeof(int), - cudaMemcpyHostToDevice); - AssertCuda(error_code); - - // Copy the row pointer to the gpu - row_ptr_dev.reset(Utilities::CUDA::allocate_device_data(row_ptr_size)); - AssertCuda(error_code); - error_code = cudaMemcpy(row_ptr_dev.get(), - row_ptr.data(), - row_ptr_size * sizeof(int), - cudaMemcpyHostToDevice); - AssertCuda(error_code); - - // Create the matrix descriptor - cusparseStatus_t cusparse_error_code = cusparseCreateMatDescr(&descr); - AssertCusparse(cusparse_error_code); - cusparse_error_code = - cusparseSetMatType(descr, CUSPARSE_MATRIX_TYPE_GENERAL); - AssertCusparse(cusparse_error_code); - cusparse_error_code = - cusparseSetMatIndexBase(descr, CUSPARSE_INDEX_BASE_ZERO); - AssertCusparse(cusparse_error_code); - - // Create the sparse matrix descriptor - internal::create_sp_mat_descr(n_rows, - n_cols, - nnz, - val_dev.get(), - row_ptr_dev.get(), - column_index_dev.get(), - sp_descr); - } - - - - template - SparseMatrix & - SparseMatrix::operator*=(const Number factor) - { - AssertIsFinite(factor); - const int n_blocks = 1 + (nnz - 1) / block_size; - internal::scale - <<>>(val_dev.get(), factor, nnz); - AssertCudaKernel(); - - return *this; - } - - - - template - SparseMatrix & - SparseMatrix::operator/=(const Number factor) - { - AssertIsFinite(factor); - Assert(factor != Number(0.), ExcZero()); - const int n_blocks = 1 + (nnz - 1) / block_size; - internal::scale - <<>>(val_dev.get(), 1. / factor, nnz); - AssertCudaKernel(); - - return *this; - } - - - - template - void - SparseMatrix::vmult( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const - { - internal::csrmv(cusparse_handle, - false, - n_rows, - n_cols, - sp_descr, - src.get_values(), - false, - dst.get_values()); - } - - - - template - void - SparseMatrix::Tvmult( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const - { - internal::csrmv(cusparse_handle, - true, - n_rows, - n_cols, - sp_descr, - src.get_values(), - false, - dst.get_values()); - } - - - - template - void - SparseMatrix::vmult_add( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const - { - internal::csrmv(cusparse_handle, - false, - n_rows, - n_cols, - sp_descr, - src.get_values(), - true, - dst.get_values()); - } - - - - template - void - SparseMatrix::Tvmult_add( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &src) const - { - internal::csrmv(cusparse_handle, - true, - n_rows, - n_cols, - sp_descr, - src.get_values(), - true, - dst.get_values()); - } - - - - template - Number - SparseMatrix::matrix_norm_square( - const LinearAlgebra::CUDAWrappers::Vector &v) const - { - LinearAlgebra::CUDAWrappers::Vector tmp = v; - vmult(tmp, v); - - return v * tmp; - } - - - - template - Number - SparseMatrix::matrix_scalar_product( - const LinearAlgebra::CUDAWrappers::Vector &u, - const LinearAlgebra::CUDAWrappers::Vector &v) const - { - LinearAlgebra::CUDAWrappers::Vector tmp = v; - vmult(tmp, v); - - return u * tmp; - } - - - - template - Number - SparseMatrix::residual( - LinearAlgebra::CUDAWrappers::Vector &dst, - const LinearAlgebra::CUDAWrappers::Vector &x, - const LinearAlgebra::CUDAWrappers::Vector &b) const - { - vmult(dst, x); - dst.sadd(-1., 1., b); - - return dst.l2_norm(); - } - - - - template - Number - SparseMatrix::l1_norm() const - { - LinearAlgebra::CUDAWrappers::Vector column_sums(n_cols); - const int n_blocks = 1 + (nnz - 1) / block_size; - internal::l1_norm - <<>>(n_rows, - val_dev.get(), - column_index_dev.get(), - row_ptr_dev.get(), - column_sums.get_values()); - AssertCudaKernel(); - - return column_sums.linfty_norm(); - } - - - - template - Number - SparseMatrix::linfty_norm() const - { - LinearAlgebra::CUDAWrappers::Vector row_sums(n_rows); - const int n_blocks = 1 + (nnz - 1) / block_size; - internal::linfty_norm - <<>>(n_rows, - val_dev.get(), - column_index_dev.get(), - row_ptr_dev.get(), - row_sums.get_values()); - AssertCudaKernel(); - - return row_sums.linfty_norm(); - } - - - - template - Number - SparseMatrix::frobenius_norm() const - { - LinearAlgebra::CUDAWrappers::Vector matrix_values(nnz); - cudaError_t cuda_error = cudaMemcpy(matrix_values.get_values(), - val_dev.get(), - nnz * sizeof(Number), - cudaMemcpyDeviceToDevice); - AssertCuda(cuda_error); - - return matrix_values.l2_norm(); - } - - - - template - std::tuple - SparseMatrix::get_cusparse_matrix() const - { - return std::make_tuple(val_dev.get(), - column_index_dev.get(), - row_ptr_dev.get(), - descr, - sp_descr); - } - - - - template class SparseMatrix; - template class SparseMatrix; -} // namespace CUDAWrappers -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/source/lac/cuda_vector.cc b/source/lac/cuda_vector.cc deleted file mode 100644 index 83b35ac39a..0000000000 --- a/source/lac/cuda_vector.cc +++ /dev/null @@ -1,620 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2016 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#ifdef DEAL_II_WITH_CUDA - -DEAL_II_NAMESPACE_OPEN - -namespace LinearAlgebra -{ - namespace CUDAWrappers - { - using ::dealii::CUDAWrappers::block_size; - using ::dealii::CUDAWrappers::chunk_size; - - - - template - Vector::Vector() - : val(nullptr, Utilities::CUDA::delete_device_data) - , n_elements(0) - {} - - - - template - Vector::Vector(const Vector &V) - : val(Utilities::CUDA::allocate_device_data(V.n_elements), - Utilities::CUDA::delete_device_data) - , n_elements(V.n_elements) - { - // Copy the values. - const cudaError_t error_code = cudaMemcpy(val.get(), - V.val.get(), - n_elements * sizeof(Number), - cudaMemcpyDeviceToDevice); - AssertCuda(error_code); - } - - - - template - Vector & - Vector::operator=(const Vector &V) - { - if (n_elements < V.n_elements) - reinit(V.n_elements, true); - else - n_elements = V.n_elements; - - // Copy the values. - const cudaError_t error_code = cudaMemcpy(val.get(), - V.val.get(), - n_elements * sizeof(Number), - cudaMemcpyDeviceToDevice); - AssertCuda(error_code); - - return *this; - } - - - - template - Vector::Vector(const size_type n) - : val(nullptr, Utilities::CUDA::delete_device_data) - , n_elements(0) - { - reinit(n, false); - } - - - - template - void - Vector::reinit(const size_type n, const bool omit_zeroing_entries) - { - // Resize the underlying array if necessary - if (n == 0) - val.reset(); - else if (n != n_elements) - val.reset(Utilities::CUDA::allocate_device_data(n)); - - // If necessary set the elements to zero - if (omit_zeroing_entries == false) - { - const cudaError_t error_code = - cudaMemset(val.get(), 0, n * sizeof(Number)); - AssertCuda(error_code); - } - n_elements = n; - } - - - - template - void - Vector::reinit(const Vector &V, - const bool omit_zeroing_entries) - { - reinit(V.size(), omit_zeroing_entries); - } - - - - template - void - Vector::import_elements( - const ReadWriteVector &V, - const VectorOperation::values operation, - const std::shared_ptr &) - { - if (operation == VectorOperation::insert) - { - const cudaError_t error_code = cudaMemcpy(val.get(), - V.begin(), - n_elements * sizeof(Number), - cudaMemcpyHostToDevice); - AssertCuda(error_code); - } - else if (operation == VectorOperation::add) - { - // Create a temporary vector on the device - Number *tmp; - cudaError_t error_code = - cudaMalloc(&tmp, n_elements * sizeof(Number)); - AssertCuda(error_code); - - // Copy the vector from the host to the temporary vector on the device - error_code = cudaMemcpy(tmp, - V.begin(), - n_elements * sizeof(Number), - cudaMemcpyHostToDevice); - AssertCuda(error_code); - - // Add the two vectors - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - - kernel::vector_bin_op - <<>>(val.get(), tmp, n_elements); - AssertCudaKernel(); - - // Delete the temporary vector - Utilities::CUDA::free(tmp); - } - else - AssertThrow(false, ExcNotImplemented()); - } - - - - template - Vector & - Vector::operator=(const Number s) - { - Assert(s == Number(), ExcMessage("Only 0 can be assigned to a vector.")); - (void)s; - - const cudaError_t error_code = - cudaMemset(val.get(), 0, n_elements * sizeof(Number)); - AssertCuda(error_code); - - return *this; - } - - - - template - Vector & - Vector::operator*=(const Number factor) - { - AssertIsFinite(factor); - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::vec_scale - <<>>(val.get(), factor, n_elements); - AssertCudaKernel(); - - return *this; - } - - - - template - Vector & - Vector::operator/=(const Number factor) - { - AssertIsFinite(factor); - Assert(factor != Number(0.), ExcZero()); - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::vec_scale - <<>>(val.get(), 1. / factor, n_elements); - AssertCudaKernel(); - - return *this; - } - - - - template - Vector & - Vector::operator+=(const Vector &V) - { - Assert(V.size() == this->size(), - ExcMessage( - "Cannot add two vectors with different numbers of elements")); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - - kernel::vector_bin_op - <<>>(val.get(), V.val.get(), n_elements); - AssertCudaKernel(); - - return *this; - } - - - - template - Vector & - Vector::operator-=(const Vector &V) - { - Assert(V.size() == this->size(), - ExcMessage( - "Cannot add two vectors with different numbers of elements.")); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - - kernel::vector_bin_op - <<>>(val.get(), V.val.get(), n_elements); - AssertCudaKernel(); - - return *this; - } - - - - template - Number - Vector::operator*(const Vector &V) const - { - Assert(V.size() == this->size(), - ExcMessage( - "Cannot add two vectors with different numbers of elements")); - - Number *result_device; - cudaError_t error_code = - cudaMalloc(&result_device, n_elements * sizeof(Number)); - AssertCuda(error_code); - error_code = cudaMemset(result_device, 0, sizeof(Number)); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::double_vector_reduction> - <<>>(result_device, - val.get(), - V.val.get(), - static_cast( - n_elements)); - - // Copy the result back to the host - Number result; - error_code = cudaMemcpy(&result, - result_device, - sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - // Free the memory on the device - Utilities::CUDA::free(result_device); - - return result; - } - - - - template - void - Vector::add(const Number a) - { - AssertIsFinite(a); - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::vec_add - <<>>(val.get(), a, n_elements); - AssertCudaKernel(); - } - - - - template - void - Vector::add(const Number a, const Vector &V) - { - AssertIsFinite(a); - - Assert(V.size() == this->size(), - ExcMessage( - "Cannot add two vectors with different numbers of elements.")); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::add_aV<<>>( - val.get(), a, V.val.get(), n_elements); - AssertCudaKernel(); - } - - - - template - void - Vector::add(const Number a, - const Vector &V, - const Number b, - const Vector &W) - { - AssertIsFinite(a); - AssertIsFinite(b); - - Assert(V.size() == this->size(), - ExcMessage( - "Cannot add two vectors with different numbers of elements.")); - - Assert(W.size() == this->size(), - ExcMessage( - "Cannot add two vectors with different numbers of elements.")); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::add_aVbW<<>>( - val.get(), a, V.val.get(), b, W.val.get(), n_elements); - AssertCudaKernel(); - } - - - - template - void - Vector::sadd(const Number s, - const Number a, - const Vector &V) - { - AssertIsFinite(s); - AssertIsFinite(a); - - Assert(V.size() == this->size(), - ExcMessage( - "Cannot add two vectors with different numbers of elements.")); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::sadd<<>>( - s, val.get(), a, V.val.get(), n_elements); - AssertCudaKernel(); - } - - - - template - void - Vector::scale(const Vector &scaling_factors) - { - Assert(scaling_factors.size() == this->size(), - ExcMessage( - "Cannot scale two vectors with different numbers of elements.")); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::scale - <<>>(val.get(), - scaling_factors.val.get(), - n_elements); - AssertCudaKernel(); - } - - - - template - void - Vector::equ(const Number a, const Vector &V) - { - AssertIsFinite(a); - - Assert( - V.size() == this->size(), - ExcMessage( - "Cannot assign two vectors with different numbers of elements.")); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::equ<<>>(val.get(), - a, - V.val.get(), - n_elements); - AssertCudaKernel(); - } - - - - template - bool - Vector::all_zero() const - { - return (linfty_norm() == 0) ? true : false; - } - - - - template - typename Vector::value_type - Vector::mean_value() const - { - Number *result_device; - cudaError_t error_code = cudaMalloc(&result_device, sizeof(Number)); - AssertCuda(error_code); - error_code = cudaMemset(result_device, 0, sizeof(Number)); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::reduction> - <<>>(result_device, - val.get(), - n_elements); - - // Copy the result back to the host - Number result; - error_code = cudaMemcpy(&result, - result_device, - sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - // Free the memory on the device - Utilities::CUDA::free(result_device); - - return result / - static_cast::value_type>(n_elements); - } - - - - template - typename Vector::real_type - Vector::l1_norm() const - { - Number *result_device; - cudaError_t error_code = cudaMalloc(&result_device, sizeof(Number)); - AssertCuda(error_code); - error_code = cudaMemset(result_device, 0, sizeof(Number)); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::reduction> - <<>>(result_device, - val.get(), - n_elements); - - // Copy the result back to the host - Number result; - error_code = cudaMemcpy(&result, - result_device, - sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - // Free the memory on the device - Utilities::CUDA::free(result_device); - - return result; - } - - - - template - typename Vector::real_type - Vector::l2_norm() const - { - return std::sqrt(norm_sqr()); - } - - - - template - typename Vector::real_type - Vector::norm_sqr() const - { - return (*this) * (*this); - } - - - - template - typename Vector::real_type - Vector::linfty_norm() const - { - Number *result_device; - cudaError_t error_code = cudaMalloc(&result_device, sizeof(Number)); - AssertCuda(error_code); - error_code = cudaMemset(result_device, 0, sizeof(Number)); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::reduction> - <<>>(result_device, - val.get(), - n_elements); - - // Copy the result back to the host - Number result; - error_code = cudaMemcpy(&result, - result_device, - sizeof(Number), - cudaMemcpyDeviceToHost); - AssertCuda(error_code); - // Free the memory on the device - Utilities::CUDA::free(result_device); - - return result; - } - - - - template - Number - Vector::add_and_dot(const Number a, - const Vector &V, - const Vector &W) - { - AssertIsFinite(a); - - Assert(V.size() == this->size(), - ExcMessage("Vector V has the wrong size.")); - Assert(W.size() == this->size(), - ExcMessage("Vector W has the wrong size.")); - - Number *result_device; - cudaError_t error_code = cudaMalloc(&result_device, sizeof(Number)); - AssertCuda(error_code); - error_code = cudaMemset(result_device, 0, sizeof(Number)); - AssertCuda(error_code); - - const int n_blocks = 1 + (n_elements - 1) / (chunk_size * block_size); - kernel::add_and_dot<<>>( - result_device, val.get(), V.val.get(), W.val.get(), a, n_elements); - - Number result; - error_code = cudaMemcpy(&result, - result_device, - sizeof(Number), - cudaMemcpyDeviceToHost); - Utilities::CUDA::free(result_device); - - return result; - } - - - - template - void - Vector::print(std::ostream &out, - const unsigned int precision, - const bool scientific, - const bool) const - { - AssertThrow(out.fail() == false, ExcIO()); - std::ios::fmtflags old_flags = out.flags(); - unsigned int old_precision = out.precision(precision); - - out.precision(precision); - if (scientific) - out.setf(std::ios::scientific, std::ios::floatfield); - else - out.setf(std::ios::fixed, std::ios::floatfield); - - out << "IndexSet: "; - complete_index_set(n_elements).print(out); - out << std::endl; - - // Copy the vector to the host - std::vector cpu_val(n_elements); - Utilities::CUDA::copy_to_host(val.get(), cpu_val); - for (unsigned int i = 0; i < n_elements; ++i) - out << cpu_val[i] << std::endl; - out << std::flush; - - AssertThrow(out.fail() == false, ExcIO()); - // reset output format - out.flags(old_flags); - out.precision(old_precision); - } - - - - template - std::size_t - Vector::memory_consumption() const - { - std::size_t memory = sizeof(*this); - memory += sizeof(Number) * static_cast(n_elements); - - return memory; - } - - - - // Explicit Instanationation - template class Vector; - template class Vector; - } // namespace CUDAWrappers -} // namespace LinearAlgebra - -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/source/lac/read_write_vector_cuda.cc b/source/lac/read_write_vector_cuda.cc deleted file mode 100644 index 652a163e43..0000000000 --- a/source/lac/read_write_vector_cuda.cc +++ /dev/null @@ -1,49 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include -#include - -DEAL_II_NAMESPACE_OPEN - -#ifndef DOXYGEN - -namespace LinearAlgebra -{ - template void - ReadWriteVector::import_elements( - const CUDAWrappers::Vector &, - VectorOperation::values, - const std::shared_ptr &); - template void - ReadWriteVector::import_elements( - const distributed::Vector &, - VectorOperation::values, - const std::shared_ptr &); - - template void - ReadWriteVector::import_elements( - const CUDAWrappers::Vector &, - VectorOperation::values, - const std::shared_ptr &); - template void - ReadWriteVector::import_elements( - const distributed::Vector &, - VectorOperation::values, - const std::shared_ptr &); -} // namespace LinearAlgebra - -#endif // DOXYGEN - -DEAL_II_NAMESPACE_CLOSE diff --git a/source/lac/trilinos_tpetra_block_vector.cc b/source/lac/trilinos_tpetra_block_vector.cc index c6e186422a..673c61b590 100644 --- a/source/lac/trilinos_tpetra_block_vector.cc +++ b/source/lac/trilinos_tpetra_block_vector.cc @@ -45,15 +45,15 @@ namespace LinearAlgebra # ifdef DEAL_II_WITH_COMPLEX_VALUES # ifdef HAVE_TPETRA_INST_COMPLEX_FLOAT # ifdef DEAL_II_HAVE_CXX20 - static_assert(concepts::is_vector_space_vector < - BlockVector>); + static_assert( + concepts::is_vector_space_vector>>); # endif template class BlockVector>; # endif # ifdef HAVE_TPETRA_INST_COMPLEX_DOUBLE # ifdef DEAL_II_HAVE_CXX20 - static_assert(concepts::is_vector_space_vector < - BlockVector>); + static_assert( + concepts::is_vector_space_vector>>); # endif template class BlockVector>; # endif diff --git a/source/lac/trilinos_tpetra_vector.cc b/source/lac/trilinos_tpetra_vector.cc index 5700eb84a5..f7f2755692 100644 --- a/source/lac/trilinos_tpetra_vector.cc +++ b/source/lac/trilinos_tpetra_vector.cc @@ -59,8 +59,8 @@ namespace LinearAlgebra # ifdef DEAL_II_WITH_COMPLEX_VALUES # ifdef HAVE_TPETRA_INST_COMPLEX_FLOAT # ifdef DEAL_II_HAVE_CXX20 - static_assert(concepts::is_vector_space_vector < - Vector>); + static_assert( + concepts::is_vector_space_vector>>); # endif template class Vector>; template Vector> & @@ -74,8 +74,8 @@ namespace LinearAlgebra # ifdef HAVE_TPETRA_INST_COMPLEX_DOUBLE # ifdef DEAL_II_HAVE_CXX20 - static_assert(concepts::is_vector_space_vector < - Vector>); + static_assert( + concepts::is_vector_space_vector>>); # endif template class Vector>; template Vector> & diff --git a/source/lac/vector_memory.cc b/source/lac/vector_memory.cc index ffb86321f5..c12a2b1afe 100644 --- a/source/lac/vector_memory.cc +++ b/source/lac/vector_memory.cc @@ -41,11 +41,6 @@ namespace internal { namespace GrowingVectorMemoryImplementation { -#ifdef DEAL_II_WITH_CUDA - void - release_all_unused_cuda_memory(); -#endif - void release_all_unused_memory() { @@ -56,9 +51,6 @@ namespace internal dealii::GrowingVectorMemory>::release_unused_memory(); -#ifdef DEAL_II_WITH_CUDA - release_all_unused_cuda_memory(); -#endif } } // namespace GrowingVectorMemoryImplementation } // namespace internal diff --git a/source/lac/vector_memory_cuda.cc b/source/lac/vector_memory_cuda.cc deleted file mode 100644 index 743ba77dc3..0000000000 --- a/source/lac/vector_memory_cuda.cc +++ /dev/null @@ -1,42 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2019 - 2022 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include -#include -#include - - -DEAL_II_NAMESPACE_OPEN - -template class VectorMemory>; -template class VectorMemory>; -template class GrowingVectorMemory>; -template class GrowingVectorMemory>; - -namespace internal -{ - namespace GrowingVectorMemoryImplementation - { - void - release_all_unused_cuda_memory() - { - dealii::GrowingVectorMemory>::release_unused_memory(); - dealii::GrowingVectorMemory>::release_unused_memory(); - } - } // namespace GrowingVectorMemoryImplementation -} // namespace internal - -DEAL_II_NAMESPACE_CLOSE diff --git a/tests/base/kokkos_point.cc b/tests/base/kokkos_point.cc index 4086b04a91..e1c0b4533e 100644 --- a/tests/base/kokkos_point.cc +++ b/tests/base/kokkos_point.cc @@ -12,7 +12,7 @@ // // ------------------------------------------------------------------------ -// Test that Point operations on a CUDA device can be used. +// Test that Point operations with the default Kokkos backend can be used. #include diff --git a/tests/cuda/CMakeLists.txt b/tests/cuda/CMakeLists.txt deleted file mode 100644 index 52d44f3b52..0000000000 --- a/tests/cuda/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.13.4) -include(../scripts/setup_testsubproject.cmake) -project(testsuite CXX) -if(DEAL_II_WITH_CUDA) - deal_ii_pickup_tests() -endif() diff --git a/tests/cuda/cuda_vector_01.cc b/tests/cuda/cuda_vector_01.cc deleted file mode 100644 index 9f3f41518d..0000000000 --- a/tests/cuda/cuda_vector_01.cc +++ /dev/null @@ -1,124 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2016 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -// Check LinearAlgebra::CUDAWrappers::Vector assignment and import - -#include - -#include -#include - -#include -#include - -#include "../tests.h" - -void -test() -{ - const unsigned int size = 100; - LinearAlgebra::CUDAWrappers::Vector a; - LinearAlgebra::CUDAWrappers::Vector b(size); - LinearAlgebra::CUDAWrappers::Vector c(b); - LinearAlgebra::CUDAWrappers::Vector d; - d.reinit(c); - - AssertThrow(a.size() == 0, ExcMessage("Vector has the wrong size.")); - AssertThrow(b.size() == size, ExcMessage("Vector has the wrong size.")); - AssertThrow(c.size() == size, ExcMessage("Vector has the wrong size.")); - AssertThrow(d.size() == size, ExcMessage("Vector has the wrong size.")); - - a.reinit(size); - AssertThrow(a.size() == size, ExcMessage("Vector has the wrong size.")); - - - LinearAlgebra::ReadWriteVector read_write_1(size); - LinearAlgebra::ReadWriteVector read_write_2(size); - LinearAlgebra::ReadWriteVector read_write_3(size); - for (unsigned int i = 0; i < size; ++i) - { - read_write_1[i] = i; - read_write_2[i] = 5. + i; - } - - a.import_elements(read_write_2, VectorOperation::insert); - b.import_elements(read_write_1, VectorOperation::insert); - c.import_elements(read_write_2, VectorOperation::insert); - - - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(read_write_2[i] == read_write_3[i], - ExcMessage("Vector a has been modified.")); - - read_write_3.import_elements(b, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(read_write_1[i] == read_write_3[i], - ExcMessage("Vector b has been modified.")); - - read_write_3.import_elements(c, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(read_write_2[i] == read_write_3[i], - ExcMessage("Vector c has been modified.")); - - a *= 2.; - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(2. * read_write_2[i] == read_write_3[i], - ExcMessage("Problem in operator *=.")); - - c /= 2.; - read_write_3.import_elements(c, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(0.5 * read_write_2[i] == read_write_3[i], - ExcMessage("Problem in operator /=.")); - - b += a; - read_write_3.import_elements(b, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(2. * read_write_2[i] + read_write_1[i] == read_write_3[i], - ExcMessage("Problem in operator +=.")); - - b -= c; - read_write_3.import_elements(b, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(1.5 * read_write_2[i] + read_write_1[i] == read_write_3[i], - ExcMessage("Problem in operator -=.")); - - b.import_elements(read_write_1, VectorOperation::insert); - c.import_elements(read_write_1, VectorOperation::insert); - const double val = b * c; - AssertThrow(val == 328350., ExcMessage("Problem in operator *.")); - - b = 0.; - read_write_3.import_elements(b, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(read_write_3[i] == 0., ExcMessage("Problem in operator =.")); -} - -int -main(int argc, char **argv) -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - test(); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/cuda_vector_01.output b/tests/cuda/cuda_vector_01.output deleted file mode 100644 index 0fd8fc12f0..0000000000 --- a/tests/cuda/cuda_vector_01.output +++ /dev/null @@ -1,2 +0,0 @@ - -DEAL::OK diff --git a/tests/cuda/cuda_vector_02.cc b/tests/cuda/cuda_vector_02.cc deleted file mode 100644 index 76e39dac1d..0000000000 --- a/tests/cuda/cuda_vector_02.cc +++ /dev/null @@ -1,120 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2016 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -#include - -#include -#include - -#include -#include -#include - -#include "../tests.h" - -// Check LinearAlgebra::CUDAWrappers::Vector add and sadd. - -void -test() -{ - const unsigned int size = 100; - LinearAlgebra::CUDAWrappers::Vector a(size); - LinearAlgebra::CUDAWrappers::Vector b(size); - LinearAlgebra::CUDAWrappers::Vector c(size); - - LinearAlgebra::ReadWriteVector read_write_1(size); - LinearAlgebra::ReadWriteVector read_write_2(size); - LinearAlgebra::ReadWriteVector read_write_3(size); - - for (unsigned int i = 0; i < size; ++i) - { - read_write_1[i] = i; - read_write_2[i] = 5. + i; - } - - a.import_elements(read_write_1, VectorOperation::insert); - b.import_elements(read_write_2, VectorOperation::insert); - c.import_elements(read_write_2, VectorOperation::insert); - - a.add(1.); - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(1. + read_write_1[i] == read_write_3[i], - ExcMessage("Problem in add(scalar).")); - - a.add(2., b); - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(1. + read_write_1[i] + 2. * read_write_2[i] == read_write_3[i], - ExcMessage("Problem in add(scalar,Vector).")); - - LinearAlgebra::CUDAWrappers::Vector d(a); - a.add(2., b, 3., d); - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(4. + 4. * read_write_1[i] + 10. * read_write_2[i] == - read_write_3[i], - ExcMessage("Problem in add(scalar,Vector,scalar,Vector).")); - - a.import_elements(read_write_1, VectorOperation::insert); - a.sadd(3., 2., c); - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(3. * read_write_1[i] + 2. * read_write_2[i] == read_write_3[i], - ExcMessage("Problem in sadd(scalar,scalar,Vector).")); - - a.import_elements(read_write_1, VectorOperation::insert); - a.scale(b); - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(read_write_1[i] * read_write_2[i] == read_write_3[i], - ExcMessage("Problem in scale.")); - - a.equ(2., c); - read_write_3.import_elements(a, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(2. * read_write_2[i] == read_write_3[i], - ExcMessage("Problem in equ.")); - - AssertThrow(b.mean_value() == 54.50, ExcMessage("Problem in mean_value.")); - - AssertThrow(b.l1_norm() == 5450., ExcMessage("Problem in l1_norm.")); - - const double eps = 1e-3; - AssertThrow(std::fabs(b.l2_norm() - 616.725222) < eps, - ExcMessage("Problem in l2_norm")); - - AssertThrow(b.linfty_norm() == 104., ExcMessage("Problem in linfty_norm.")); - - a.import_elements(read_write_1, VectorOperation::insert); - const double val = a.add_and_dot(2., a, b); - AssertThrow(val == 1059300., ExcMessage("Problem in add_and_dot")); -} - - -int -main(int argc, char **argv) -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - test(); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/cuda_vector_02.output b/tests/cuda/cuda_vector_02.output deleted file mode 100644 index 0fd8fc12f0..0000000000 --- a/tests/cuda/cuda_vector_02.output +++ /dev/null @@ -1,2 +0,0 @@ - -DEAL::OK diff --git a/tests/cuda/cuda_vector_03.cc b/tests/cuda/cuda_vector_03.cc deleted file mode 100644 index defd0b1c08..0000000000 --- a/tests/cuda/cuda_vector_03.cc +++ /dev/null @@ -1,50 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -#include -#include - -#include "../tests.h" - -// Check that reinit correctly set all the entries of the vector to zero - -void -test() -{ - const unsigned int size = 100; - LinearAlgebra::CUDAWrappers::Vector a(size); - LinearAlgebra::ReadWriteVector read_write(size); - for (unsigned int i = 0; i < size; ++i) - read_write[i] = i; - a.import_elements(read_write, VectorOperation::insert); - - a.reinit(size / 2); - AssertThrow(a.l1_norm() == 0., ExcMessage("reinit did not zero the entry")); -} - - -int -main(int argc, char **argv) -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - test(); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/cuda_vector_03.output b/tests/cuda/cuda_vector_03.output deleted file mode 100644 index 0fd8fc12f0..0000000000 --- a/tests/cuda/cuda_vector_03.output +++ /dev/null @@ -1,2 +0,0 @@ - -DEAL::OK diff --git a/tests/cuda/cuda_vector_04.cc b/tests/cuda/cuda_vector_04.cc deleted file mode 100644 index 9cf9c032f3..0000000000 --- a/tests/cuda/cuda_vector_04.cc +++ /dev/null @@ -1,58 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2015 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -// Check LinearAlgebra::CUDAWrappers::Vector::print() - -#include - -#include -#include - -#include -#include - -#include "../tests.h" - -void -test() -{ - const unsigned int size = 100; - LinearAlgebra::CUDAWrappers::Vector cuda_vector(size); - - LinearAlgebra::ReadWriteVector read_write_1(size); - for (unsigned int i = 0; i < size; ++i) - { - read_write_1[i] = i; - } - - cuda_vector.import_elements(read_write_1, VectorOperation::insert); - - cuda_vector.print(deallog.get_file_stream()); -} - -int -main(int argc, char **argv) -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - test(); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/cuda_vector_04.output b/tests/cuda/cuda_vector_04.output deleted file mode 100644 index 012f7efdd8..0000000000 --- a/tests/cuda/cuda_vector_04.output +++ /dev/null @@ -1,104 +0,0 @@ - -IndexSet: {[0,99]} - -0.00e+00 -1.00e+00 -2.00e+00 -3.00e+00 -4.00e+00 -5.00e+00 -6.00e+00 -7.00e+00 -8.00e+00 -9.00e+00 -1.00e+01 -1.10e+01 -1.20e+01 -1.30e+01 -1.40e+01 -1.50e+01 -1.60e+01 -1.70e+01 -1.80e+01 -1.90e+01 -2.00e+01 -2.10e+01 -2.20e+01 -2.30e+01 -2.40e+01 -2.50e+01 -2.60e+01 -2.70e+01 -2.80e+01 -2.90e+01 -3.00e+01 -3.10e+01 -3.20e+01 -3.30e+01 -3.40e+01 -3.50e+01 -3.60e+01 -3.70e+01 -3.80e+01 -3.90e+01 -4.00e+01 -4.10e+01 -4.20e+01 -4.30e+01 -4.40e+01 -4.50e+01 -4.60e+01 -4.70e+01 -4.80e+01 -4.90e+01 -5.00e+01 -5.10e+01 -5.20e+01 -5.30e+01 -5.40e+01 -5.50e+01 -5.60e+01 -5.70e+01 -5.80e+01 -5.90e+01 -6.00e+01 -6.10e+01 -6.20e+01 -6.30e+01 -6.40e+01 -6.50e+01 -6.60e+01 -6.70e+01 -6.80e+01 -6.90e+01 -7.00e+01 -7.10e+01 -7.20e+01 -7.30e+01 -7.40e+01 -7.50e+01 -7.60e+01 -7.70e+01 -7.80e+01 -7.90e+01 -8.00e+01 -8.10e+01 -8.20e+01 -8.30e+01 -8.40e+01 -8.50e+01 -8.60e+01 -8.70e+01 -8.80e+01 -8.90e+01 -9.00e+01 -9.10e+01 -9.20e+01 -9.30e+01 -9.40e+01 -9.50e+01 -9.60e+01 -9.70e+01 -9.80e+01 -9.90e+01 -DEAL::OK diff --git a/tests/cuda/cuda_vector_05.cc b/tests/cuda/cuda_vector_05.cc deleted file mode 100644 index 56931eeb2e..0000000000 --- a/tests/cuda/cuda_vector_05.cc +++ /dev/null @@ -1,71 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2019 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -#include - -#include -#include -#include - -#include -#include -#include - -#include "../tests.h" - -// There was a bug where add_and_dot would give the wrong result if the size of -// the vectors was greater than BLOCK_SIZE*CHUNK_SIZE. - -void -test() -{ - const unsigned int size = 4100; - LinearAlgebra::CUDAWrappers::Vector a(size); - LinearAlgebra::CUDAWrappers::Vector b(size); - Vector a_host(size); - Vector b_host(size); - - LinearAlgebra::ReadWriteVector read_write_1(size); - LinearAlgebra::ReadWriteVector read_write_2(size); - - for (unsigned int i = 0; i < size; ++i) - { - read_write_1[i] = i; - read_write_2[i] = 5. + i; - a_host[i] = i; - b_host[i] = 5. + i; - } - - a.import_elements(read_write_1, VectorOperation::insert); - b.import_elements(read_write_2, VectorOperation::insert); - AssertThrow(a.add_and_dot(2., a, b) == a_host.add_and_dot(2., a_host, b_host), - ExcMessage("Problem in add_and_dot")); -} - - -int -main(int argc, char **argv) -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - test(); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/cuda_vector_05.output b/tests/cuda/cuda_vector_05.output deleted file mode 100644 index 0fd8fc12f0..0000000000 --- a/tests/cuda/cuda_vector_05.output +++ /dev/null @@ -1,2 +0,0 @@ - -DEAL::OK diff --git a/tests/cuda/precondition_01.cc b/tests/cuda/precondition_01.cc deleted file mode 100644 index b1c5bcabbb..0000000000 --- a/tests/cuda/precondition_01.cc +++ /dev/null @@ -1,88 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverCG works with CUDAWrappers::SparseMatrix -// and PreconditionIC - -#include -#include - -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -template -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - const Number tolerance = 1000. * std::numeric_limits::epsilon(); - SolverControl control(100, tolerance); - SolverCG> cg_dev(control); - - CUDAWrappers::PreconditionIC prec_ic(cuda_handle); - prec_ic.initialize(A_dev); - - cg_dev.solve(A_dev, sol_dev, rhs_dev, prec_ic); - - // Check the result - LinearAlgebra::CUDAWrappers::Vector residual(size); - A_dev.residual(residual, sol_dev, rhs_dev); - Assert(residual.l2_norm() < 20 * tolerance, ExcInternalError()); - deallog << "OK" << std::endl; -} - -int -main() -{ - initlog(); - deallog << std::setprecision(10); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - deallog << "Testing float" << std::endl; - test(cuda_handle); - deallog << "Testing double" << std::endl; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/precondition_01.output b/tests/cuda/precondition_01.output deleted file mode 100644 index 27a4138a2b..0000000000 --- a/tests/cuda/precondition_01.output +++ /dev/null @@ -1,10 +0,0 @@ - -DEAL::Testing float -DEAL:cg::Starting value 416.9891968 -DEAL:cg::Convergence step 11 value 3.993874634e-05 -DEAL::OK -DEAL::Testing double -DEAL:cg::Starting value 416.9892085 -DEAL:cg::Convergence step 20 value 9.834412497e-14 -DEAL::OK -DEAL::OK diff --git a/tests/cuda/precondition_02.cc b/tests/cuda/precondition_02.cc deleted file mode 100644 index 87a904f5a1..0000000000 --- a/tests/cuda/precondition_02.cc +++ /dev/null @@ -1,88 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverCG works with CUDAWrappers::SparseMatrix -// and PreconditionILU - -#include -#include - -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -template -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - const Number tolerance = 1000. * std::numeric_limits::epsilon(); - SolverControl control(100, tolerance); - SolverCG> cg_dev(control); - - CUDAWrappers::PreconditionILU prec_ilu(cuda_handle); - prec_ilu.initialize(A_dev); - - cg_dev.solve(A_dev, sol_dev, rhs_dev, prec_ilu); - - // Check the result - LinearAlgebra::CUDAWrappers::Vector residual(size); - A_dev.residual(residual, sol_dev, rhs_dev); - Assert(residual.l2_norm() < 20 * tolerance, ExcInternalError()); - deallog << "OK" << std::endl; -} - -int -main() -{ - initlog(); - deallog << std::setprecision(10); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - deallog << "Testing float" << std::endl; - test(cuda_handle); - deallog << "Testing double" << std::endl; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/precondition_02.output b/tests/cuda/precondition_02.output deleted file mode 100644 index 1c14226e67..0000000000 --- a/tests/cuda/precondition_02.output +++ /dev/null @@ -1,10 +0,0 @@ - -DEAL::Testing float -DEAL:cg::Starting value 416.9891968 -DEAL:cg::Convergence step 11 value 3.993944847e-05 -DEAL::OK -DEAL::Testing double -DEAL:cg::Starting value 416.9892085 -DEAL:cg::Convergence step 20 value 9.834484941e-14 -DEAL::OK -DEAL::OK diff --git a/tests/cuda/solver_01.cc b/tests/cuda/solver_01.cc deleted file mode 100644 index aafee372be..0000000000 --- a/tests/cuda/solver_01.cc +++ /dev/null @@ -1,87 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverCG works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the host - PreconditionIdentity prec_no; - SolverControl control(100, 1.e-10); - SolverCG<> cg_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - cg_host.solve(A, sol_host, rhs_host, prec_no); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverCG> cg_dev(control); - cg_dev.solve(A_dev, sol_dev, rhs_dev, prec_no); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_01.output b/tests/cuda/solver_01.output deleted file mode 100644 index b0ef558ea7..0000000000 --- a/tests/cuda/solver_01.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:cg::Starting value 416.989 -DEAL:cg::Convergence step 31 value 8.71925e-12 -DEAL:cg::Starting value 416.989 -DEAL:cg::Convergence step 31 value 8.71925e-12 -DEAL::OK diff --git a/tests/cuda/solver_02.cc b/tests/cuda/solver_02.cc deleted file mode 100644 index 2f4ef25619..0000000000 --- a/tests/cuda/solver_02.cc +++ /dev/null @@ -1,117 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that CUDA direct solvers work - -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Create the matrix on the host. - dealii::SparsityPattern sparsity_pattern; - dealii::SparseMatrix matrix; - const unsigned int size = 30; - std::vector> column_indices(size); - for (unsigned int i = 0; i < size; ++i) - { - unsigned int j_max = std::min(size, i + 2); - unsigned int j_min = (i == 0) ? 0 : i - 1; - for (unsigned int j = j_min; j < j_max; ++j) - column_indices[i].emplace_back(j); - } - sparsity_pattern.copy_from(size, - size, - column_indices.begin(), - column_indices.end()); - matrix.reinit(sparsity_pattern); - for (unsigned int i = 0; i < size; ++i) - { - unsigned int j_max = std::min(size - 1, i + 1); - unsigned int j_min = (i == 0) ? 0 : i - 1; - matrix.set(i, j_min, -1.); - matrix.set(i, j_max, -1.); - matrix.set(i, i, 4.); - } - - // Generate a random solution and then compute the rhs - dealii::Vector sol_ref(size); - for (auto &val : sol_ref) - val = random_value(5., 15.); - - dealii::Vector rhs(size); - matrix.vmult(rhs, sol_ref); - - // Move the matrix and the rhs to the host - CUDAWrappers::SparseMatrix matrix_dev(cuda_handle, matrix); - - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rhs_host(size); - std::copy(rhs.begin(), rhs.end(), rhs_host.begin()); - rhs_dev.import_elements(rhs_host, VectorOperation::insert); - - LinearAlgebra::CUDAWrappers::Vector solution_dev(size); - const std::array solver_names{ - {"Cholesky", "LU_dense", "LU_host"}}; - - for (auto solver_type : solver_names) - { - // Solve on the device - CUDAWrappers::SolverDirect::AdditionalData data(solver_type); - SolverControl solver_control; - - CUDAWrappers::SolverDirect solver(cuda_handle, - solver_control, - data); - solver.solve(matrix_dev, solution_dev, rhs_dev); - - // Move the result back to the host - LinearAlgebra::ReadWriteVector solution_host(size); - solution_host.import_elements(solution_dev, VectorOperation::insert); - - // Check the result - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::abs(solution_host[i] - sol_ref[i]) < 1e-12, - ExcInternalError()); - deallog << solver_type << std::endl; - } -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_02.output b/tests/cuda/solver_02.output deleted file mode 100644 index 3db636dcc5..0000000000 --- a/tests/cuda/solver_02.output +++ /dev/null @@ -1,11 +0,0 @@ - -DEAL::Starting value 0.00000 -DEAL::Convergence step 0 value 0.00000 -DEAL::Cholesky -DEAL::Starting value 0.00000 -DEAL::Convergence step 0 value 0.00000 -DEAL::LU_dense -DEAL::Starting value 0.00000 -DEAL::Convergence step 0 value 0.00000 -DEAL::LU_host -DEAL::OK diff --git a/tests/cuda/solver_03.cc b/tests/cuda/solver_03.cc deleted file mode 100644 index 76027996fc..0000000000 --- a/tests/cuda/solver_03.cc +++ /dev/null @@ -1,87 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverGMRES works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the host - PreconditionIdentity prec_no; - SolverControl control(100, 1.e-10); - SolverGMRES<> cg_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - cg_host.solve(A, sol_host, rhs_host, prec_no); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverGMRES> cg_dev(control); - cg_dev.solve(A_dev, sol_dev, rhs_dev, prec_no); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_03.output b/tests/cuda/solver_03.output deleted file mode 100644 index b8e4a2e2fb..0000000000 --- a/tests/cuda/solver_03.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:GMRES::Starting value 416.989 -DEAL:GMRES::Convergence step 32 value 4.50651e-11 -DEAL:GMRES::Starting value 416.989 -DEAL:GMRES::Convergence step 32 value 4.50477e-11 -DEAL::OK diff --git a/tests/cuda/solver_04.cc b/tests/cuda/solver_04.cc deleted file mode 100644 index a305375741..0000000000 --- a/tests/cuda/solver_04.cc +++ /dev/null @@ -1,88 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverBicgstab works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the host - PreconditionIdentity prec_no; - SolverControl control(100, 1.e-10); - SolverBicgstab<> bicgstab_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - bicgstab_host.solve(A, sol_host, rhs_host, prec_no); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverBicgstab> bicgstab_dev( - control); - bicgstab_dev.solve(A_dev, sol_dev, rhs_dev, prec_no); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_04.output b/tests/cuda/solver_04.output deleted file mode 100644 index df448144a1..0000000000 --- a/tests/cuda/solver_04.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:Bicgstab::Starting value 416.989 -DEAL:Bicgstab::Convergence step 23 value 1.39578e-11 -DEAL:Bicgstab::Starting value 416.989 -DEAL:Bicgstab::Convergence step 23 value 1.39578e-11 -DEAL::OK diff --git a/tests/cuda/solver_05.cc b/tests/cuda/solver_05.cc deleted file mode 100644 index c016268cef..0000000000 --- a/tests/cuda/solver_05.cc +++ /dev/null @@ -1,87 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverFGMRES works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the host - PreconditionIdentity prec_no; - SolverControl control(100, 1.e-10); - SolverFGMRES<> fgmres_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - fgmres_host.solve(A, sol_host, rhs_host, prec_no); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverFGMRES> fgmres_dev(control); - fgmres_dev.solve(A_dev, sol_dev, rhs_dev, prec_no); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_05.output b/tests/cuda/solver_05.output deleted file mode 100644 index 792aee14c9..0000000000 --- a/tests/cuda/solver_05.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:FGMRES::Starting value 416.989 -DEAL:FGMRES::Convergence step 31 value 3.31663e-11 -DEAL:FGMRES::Starting value 416.989 -DEAL:FGMRES::Convergence step 31 value 3.31763e-11 -DEAL::OK diff --git a/tests/cuda/solver_06.cc b/tests/cuda/solver_06.cc deleted file mode 100644 index df0a844ad3..0000000000 --- a/tests/cuda/solver_06.cc +++ /dev/null @@ -1,87 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverFIRE works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the host - PreconditionIdentity prec_no; - SolverControl control(10000, 1.e-3); - SolverFIRE<> fire_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - fire_host.solve(A, sol_host, rhs_host, prec_no); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverFIRE> fire_dev(control); - fire_dev.solve(A_dev, sol_dev, rhs_dev, prec_no); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_06.output b/tests/cuda/solver_06.output deleted file mode 100644 index 0626e5cb42..0000000000 --- a/tests/cuda/solver_06.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:FIRE::Starting value 173880. -DEAL:FIRE::Convergence step 465 value 0.000927878 -DEAL:FIRE::Starting value 173880. -DEAL:FIRE::Convergence step 465 value 0.000927878 -DEAL::OK diff --git a/tests/cuda/solver_07.cc b/tests/cuda/solver_07.cc deleted file mode 100644 index 80b1477524..0000000000 --- a/tests/cuda/solver_07.cc +++ /dev/null @@ -1,87 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverMinRes works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the host - PreconditionIdentity prec_no; - SolverControl control(100, 1.e-10); - SolverMinRes<> minres_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - minres_host.solve(A, sol_host, rhs_host, prec_no); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverMinRes> minres_dev(control); - minres_dev.solve(A_dev, sol_dev, rhs_dev, prec_no); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_07.output b/tests/cuda/solver_07.output deleted file mode 100644 index 448f7326c7..0000000000 --- a/tests/cuda/solver_07.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:minres::Starting value 416.989 -DEAL:minres::Convergence step 31 value 8.71122e-12 -DEAL:minres::Starting value 416.989 -DEAL:minres::Convergence step 31 value 8.71119e-12 -DEAL::OK diff --git a/tests/cuda/solver_08.cc b/tests/cuda/solver_08.cc deleted file mode 100644 index 9800091ad2..0000000000 --- a/tests/cuda/solver_08.cc +++ /dev/null @@ -1,87 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverQMRS works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - - // Solve on the host - PreconditionIdentity prec_no; - SolverControl control(1000, 1.e-3); - SolverQMRS<> qmrs_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - qmrs_host.solve(A, sol_host, rhs_host, prec_no); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverQMRS> qmrs_dev(control); - qmrs_dev.solve(A_dev, sol_dev, rhs_dev, prec_no); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_08.output b/tests/cuda/solver_08.output deleted file mode 100644 index 67d21b185a..0000000000 --- a/tests/cuda/solver_08.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:SQMR::Starting value 416.989 -DEAL:SQMR::Convergence step 22 value 0.000879597 -DEAL:SQMR::Starting value 416.989 -DEAL:SQMR::Convergence step 22 value 0.000879597 -DEAL::OK diff --git a/tests/cuda/solver_09.cc b/tests/cuda/solver_09.cc deleted file mode 100644 index 6b8002198f..0000000000 --- a/tests/cuda/solver_09.cc +++ /dev/null @@ -1,116 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverRichardson works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - -template -class PreconditionOperator -{ -public: - PreconditionOperator(const MatrixType &inverse_diagonal_matrix_) - : inverse_diagonal_matrix(inverse_diagonal_matrix_) - {} - - template - void - vmult(VectorType &u, const VectorType &v) const - { - inverse_diagonal_matrix.vmult(u, v); - } - -private: - const MatrixType &inverse_diagonal_matrix; -}; - - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - SparseMatrix A_diagonal_inverse; - A_diagonal_inverse.reinit(structure); - for (unsigned int i = 0; i < size; ++i) - A_diagonal_inverse(i, i) = 1. / A(i, i); - - // Solve on the host - PreconditionOperator> preconditioner(A_diagonal_inverse); - SolverControl control(1000, 1.e-2); - SolverRichardson<> richardson_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - richardson_host.solve(A, sol_host, rhs_host, preconditioner); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - CUDAWrappers::SparseMatrix A_diagonal_inverse_dev(cuda_handle, - A_diagonal_inverse); - PreconditionOperator> preconditioner_dev( - A_diagonal_inverse_dev); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverRichardson> richardson_dev( - control); - richardson_dev.solve(A_dev, sol_dev, rhs_dev, preconditioner_dev); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_09.output b/tests/cuda/solver_09.output deleted file mode 100644 index c4357dd61c..0000000000 --- a/tests/cuda/solver_09.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:Richardson::Starting value 416.989 -DEAL:Richardson::Convergence step 207 value 0.00982595 -DEAL:Richardson::Starting value 416.989 -DEAL:Richardson::Convergence step 207 value 0.00982595 -DEAL::OK diff --git a/tests/cuda/solver_10.cc b/tests/cuda/solver_10.cc deleted file mode 100644 index 240520fb6f..0000000000 --- a/tests/cuda/solver_10.cc +++ /dev/null @@ -1,136 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check that dealii::SolverRelaxation works with CUDAWrappers::SparseMatrix - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - - -template -class RelaxationOperator -{ -public: - RelaxationOperator(const MatrixType &system_matrix_, - const MatrixType &inverse_diagonal_matrix_) - : system_matrix(system_matrix_) - , inverse_diagonal_matrix(inverse_diagonal_matrix_) - {} - - template - void - step(VectorType &u, const VectorType &v) const - { - // u = u - omega*inverse_diagonal_matrix*(system_matrix*u-v) - const double omega = 1.; - VectorType tmp_1(v.size()); - system_matrix.vmult(tmp_1, u); - tmp_1 -= v; - VectorType tmp_2(u.size()); - inverse_diagonal_matrix.vmult(tmp_2, tmp_1); - tmp_2 *= omega; - u -= tmp_2; - } - - template - void - Tstep(VectorType &u, const VectorType &v) const - { - AssertThrow(false, ExcNotImplemented()); - } - -private: - const MatrixType &system_matrix; - const MatrixType &inverse_diagonal_matrix; -}; - - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int problem_size = 10; - unsigned int size = (problem_size - 1) * (problem_size - 1); - FDMatrix testproblem(problem_size, problem_size); - SparsityPattern structure(size, size, 5); - SparseMatrix A; - testproblem.five_point_structure(structure); - structure.compress(); - A.reinit(structure); - testproblem.five_point(A); - SparseMatrix A_diagonal_inverse; - A_diagonal_inverse.reinit(structure); - for (unsigned int i = 0; i < size; ++i) - A_diagonal_inverse(i, i) = 1. / A(i, i); - - // Solve on the host - RelaxationOperator> relaxation_operator( - A, A_diagonal_inverse); - SolverControl control(1000, 1.e-3); - SolverRelaxation<> relaxation_host(control); - Vector sol_host(size); - Vector rhs_host(size); - for (unsigned int i = 0; i < size; ++i) - rhs_host[i] = static_cast(i); - relaxation_host.solve(A, sol_host, rhs_host, relaxation_operator); - - // Solve on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - CUDAWrappers::SparseMatrix A_diagonal_inverse_dev(cuda_handle, - A_diagonal_inverse); - RelaxationOperator> - relaxation_operator_dev(A_dev, A_diagonal_inverse_dev); - LinearAlgebra::CUDAWrappers::Vector sol_dev(size); - LinearAlgebra::CUDAWrappers::Vector rhs_dev(size); - LinearAlgebra::ReadWriteVector rw_vector(size); - for (unsigned int i = 0; i < size; ++i) - rw_vector[i] = static_cast(i); - rhs_dev.import_elements(rw_vector, VectorOperation::insert); - SolverRelaxation> relaxation_dev( - control); - relaxation_dev.solve(A_dev, sol_dev, rhs_dev, relaxation_operator_dev); - - // Check the result - rw_vector.import_elements(sol_dev, VectorOperation::insert); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::fabs(rw_vector[i] - sol_host[i]) < 1e-8, - ExcInternalError()); -} - -int -main() -{ - initlog(); - deallog.depth_console(10); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/solver_10.output b/tests/cuda/solver_10.output deleted file mode 100644 index d46239fd5e..0000000000 --- a/tests/cuda/solver_10.output +++ /dev/null @@ -1,6 +0,0 @@ - -DEAL:Relaxation::Starting value 416.989 -DEAL:Relaxation::Convergence step 253 value 0.000976934 -DEAL:Relaxation::Starting value 416.989 -DEAL:Relaxation::Convergence step 253 value 0.000976934 -DEAL::OK diff --git a/tests/cuda/sparse_matrix_01.cc b/tests/cuda/sparse_matrix_01.cc deleted file mode 100644 index 2d0cf68491..0000000000 --- a/tests/cuda/sparse_matrix_01.cc +++ /dev/null @@ -1,225 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check multiplications and norms - -#include -#include - -#include -#include -#include - -#include "../tests.h" - -#include "../testmatrix.h" - - -void -check_matrix(const SparseMatrix &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, 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); - - const int 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 < n_rows; ++i) - for (int j = row_ptr_host[i]; j < row_ptr_host[i + 1]; ++j) - AssertThrow(std::abs(val_host[j] - A(i, column_index_host[j])) < 1e-15, - ExcInternalError()); -} - -void -check_vector(const Vector &a, - const LinearAlgebra::ReadWriteVector &b) -{ - unsigned int size = a.size(); - for (unsigned int i = 0; i < size; ++i) - AssertThrow(std::abs(a[i] - b[i]) < 1e-15, ExcInternalError()); -} - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int size = 10; - unsigned int dim = (size - 1) * (size - 1); - FDMatrix testproblem(size, size); - SparsityPattern structure(dim, dim, 5); - SparseMatrix 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(cuda_handle, A); - check_matrix(A, A_dev); - - AssertDimension(A.m(), A_dev.m()); - AssertDimension(A.n(), A_dev.n()); - - // 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 < vector_size; ++i) - src[i] = i; - A.vmult(dst, src); - LinearAlgebra::CUDAWrappers::Vector dst_dev(vector_size); - LinearAlgebra::CUDAWrappers::Vector src_dev(vector_size); - LinearAlgebra::ReadWriteVector read_write(vector_size); - for (unsigned int i = 0; i < vector_size; ++i) - read_write[i] = i; - src_dev.import_elements(read_write, VectorOperation::insert); - A_dev.vmult(dst_dev, src_dev); - read_write.import_elements(dst_dev, VectorOperation::insert); - check_vector(dst, read_write); - - // Transpose matrix-vector multiplication - A.Tvmult(dst, src); - A_dev.Tvmult(dst_dev, src_dev); - read_write.import_elements(dst_dev, VectorOperation::insert); - check_vector(dst, read_write); - - // Matrix-vector multiplication and add - A.vmult_add(dst, src); - A_dev.vmult_add(dst_dev, src_dev); - read_write.import_elements(dst_dev, VectorOperation::insert); - check_vector(dst, read_write); - - // Transpose matrix-vector multiplication and add - A.Tvmult_add(dst, src); - A_dev.Tvmult_add(dst_dev, src_dev); - read_write.import_elements(dst_dev, VectorOperation::insert); - check_vector(dst, read_write); - - // Matrix norm square - double value = A.matrix_norm_square(src); - double value_host = A_dev.matrix_norm_square(src_dev); - AssertThrow(std::abs(value - value_host) < 1e-15, ExcInternalError()); - - // Matrix scalar product (reuse dst and src but they are both input) - value = A.matrix_scalar_product(dst, src); - value_host = A_dev.matrix_scalar_product(dst_dev, src_dev); - AssertThrow(std::abs(value - value_host) < 1e-15, ExcInternalError()); - - // Compute the residual - Vector b(src); - for (unsigned int i = 0; i < vector_size; ++i) - { - b[i] = i; - src[i] = i; - read_write[i] = i; - } - LinearAlgebra::CUDAWrappers::Vector b_dev(vector_size); - b_dev.import_elements(read_write, VectorOperation::insert); - src_dev.import_elements(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_elements(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 < vector_size; ++i) - { - sparsity_pattern.add(i, 0); - sparsity_pattern.add(i, i); - if (i < vector_size - 1) - sparsity_pattern.add(i, i + 1); - } - sparsity_pattern.compress(); - SparseMatrix B(sparsity_pattern); - for (unsigned int i = 0; i < vector_size; ++i) - { - B.set(i, 0, 1); - B.set(i, i, 1); - if (i < vector_size - 1) - B.set(i, i + 1, 1); - } - CUDAWrappers::SparseMatrix B_dev(cuda_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); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/sparse_matrix_01.output b/tests/cuda/sparse_matrix_01.output deleted file mode 100644 index 0fd8fc12f0..0000000000 --- a/tests/cuda/sparse_matrix_01.output +++ /dev/null @@ -1,2 +0,0 @@ - -DEAL::OK diff --git a/tests/cuda/sparse_matrix_02.cc b/tests/cuda/sparse_matrix_02.cc deleted file mode 100644 index c4291d0c58..0000000000 --- a/tests/cuda/sparse_matrix_02.cc +++ /dev/null @@ -1,64 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2018 - 2022 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - -// Check print and print_format - -#include -#include - -#include - -#include "../tests.h" - -#include "../testmatrix.h" - - -void -test(Utilities::CUDA::Handle &cuda_handle) -{ - // Build the sparse matrix on the host - const unsigned int size = 3; - unsigned int dim = (size - 1) * (size - 1); - - FDMatrix testproblem(size, size); - SparsityPattern structure(dim, dim, 5); - testproblem.five_point_structure(structure); - structure.compress(); - SparseMatrix A(structure); - testproblem.upwind(A, true); - A.print(deallog.get_file_stream()); - A.print_formatted(deallog.get_file_stream()); - - // Create the sparse matrix on the device - CUDAWrappers::SparseMatrix A_dev(cuda_handle, A); - A_dev.print(deallog.get_file_stream()); - A_dev.print_formatted(deallog.get_file_stream()); -} - -int -main() -{ - initlog(); - deallog.depth_console(0); - - init_cuda(); - - Utilities::CUDA::Handle cuda_handle; - - test(cuda_handle); - - deallog << "OK" << std::endl; - - return 0; -} diff --git a/tests/cuda/sparse_matrix_02.output b/tests/cuda/sparse_matrix_02.output deleted file mode 100644 index fbf0f1b3af..0000000000 --- a/tests/cuda/sparse_matrix_02.output +++ /dev/null @@ -1,34 +0,0 @@ - -(0,0) 3.00000 -(0,1) -1.00000 -(0,2) 0.00000 -(1,1) 3.00000 -(1,0) 0.00000 -(1,3) 0.00000 -(2,2) 3.00000 -(2,0) 0.00000 -(2,3) -1.00000 -(3,3) 3.00000 -(3,1) 0.00000 -(3,2) 0.00000 -3.000e+00 -1.000e+00 0.000e+00 -0.000e+00 3.000e+00 0.000e+00 -0.000e+00 3.000e+00 -1.000e+00 - 0.000e+00 0.000e+00 3.000e+00 -(0,0) 3.00000 -(0,1) -1.00000 -(0,2) 0.00000 -(1,1) 3.00000 -(1,0) 0.00000 -(1,3) 0.00000 -(2,2) 3.00000 -(2,0) 0.00000 -(2,3) -1.00000 -(3,3) 3.00000 -(3,1) 0.00000 -(3,2) 0.00000 -3.000e+00 -1.000e+00 0.000e+00 -0.000e+00 3.000e+00 0.000e+00 -0.000e+00 3.000e+00 -1.000e+00 - 0.000e+00 0.000e+00 3.000e+00 -DEAL::OK diff --git a/tests/lac/affine_constraints_set_zero.cc b/tests/lac/affine_constraints_set_zero.cc index 915fe98893..a70c345cd2 100644 --- a/tests/lac/affine_constraints_set_zero.cc +++ b/tests/lac/affine_constraints_set_zero.cc @@ -17,8 +17,6 @@ // check AffineConstraints::set_zero(Vector) for parallel distributed // vectors -#include - #include #include diff --git a/tests/lac/parallel_vector_01.cc b/tests/lac/parallel_vector_01.cc index 25eef511e1..37fd0c9389 100644 --- a/tests/lac/parallel_vector_01.cc +++ b/tests/lac/parallel_vector_01.cc @@ -15,7 +15,6 @@ // check correct initialization of parallel vector without any ghosts -#include #include #include diff --git a/tests/lac/parallel_vector_02.cc b/tests/lac/parallel_vector_02.cc index 49b1626678..c3a8934442 100644 --- a/tests/lac/parallel_vector_02.cc +++ b/tests/lac/parallel_vector_02.cc @@ -15,7 +15,6 @@ // check addition into ghosts for parallel vector -#include #include #include diff --git a/tests/lac/parallel_vector_03.cc b/tests/lac/parallel_vector_03.cc index 72a26b082c..24cfa5109c 100644 --- a/tests/lac/parallel_vector_03.cc +++ b/tests/lac/parallel_vector_03.cc @@ -15,7 +15,6 @@ // check set of ghosts for parallel vector -#include #include #include diff --git a/tests/lac/parallel_vector_03a.cc b/tests/lac/parallel_vector_03a.cc index 38ac08d6f8..516731f4fd 100644 --- a/tests/lac/parallel_vector_03a.cc +++ b/tests/lac/parallel_vector_03a.cc @@ -16,7 +16,6 @@ // similar to parallel_sparse_vector_03.cc, but make sure // compress(insert) zeroes out ghosts in Release mode -#include #include #include diff --git a/tests/lac/parallel_vector_04.cc b/tests/lac/parallel_vector_04.cc index ad0573d388..83f6aa4156 100644 --- a/tests/lac/parallel_vector_04.cc +++ b/tests/lac/parallel_vector_04.cc @@ -16,7 +16,6 @@ // check that operator= resets ghosts, both if they have been set and if they // have not been set -#include #include #include diff --git a/tests/lac/parallel_vector_05.cc b/tests/lac/parallel_vector_05.cc index 36b91857e4..a98a30c0b0 100644 --- a/tests/lac/parallel_vector_05.cc +++ b/tests/lac/parallel_vector_05.cc @@ -15,7 +15,6 @@ // check that compress(add) with zero add does not change the vector entry -#include #include #include diff --git a/tests/lac/parallel_vector_06.cc b/tests/lac/parallel_vector_06.cc index 671fc6499e..34dca9d73f 100644 --- a/tests/lac/parallel_vector_06.cc +++ b/tests/lac/parallel_vector_06.cc @@ -16,7 +16,6 @@ // check global reduction operation (norms, operator==, operator!=) on // parallel vector -#include #include #include diff --git a/tests/lac/parallel_vector_08.cc b/tests/lac/parallel_vector_08.cc index 8528597f70..01b79dd87c 100644 --- a/tests/lac/parallel_vector_08.cc +++ b/tests/lac/parallel_vector_08.cc @@ -16,7 +16,6 @@ // check parallel_vector assignment and ghost values. Same vector layout as in // parallel_vector_07.cc -#include #include #include diff --git a/tests/lac/parallel_vector_10.cc b/tests/lac/parallel_vector_10.cc index 531b3bbc19..41c9e263e5 100644 --- a/tests/lac/parallel_vector_10.cc +++ b/tests/lac/parallel_vector_10.cc @@ -15,7 +15,6 @@ // check operator= when we do some operations with ghosts -#include #include #include diff --git a/tests/lac/parallel_vector_11.cc b/tests/lac/parallel_vector_11.cc index 902b3c9370..fa9fcdf3c4 100644 --- a/tests/lac/parallel_vector_11.cc +++ b/tests/lac/parallel_vector_11.cc @@ -16,7 +16,6 @@ // check that add, sadd, equ, scale work correctly on a vector where some // processor do not own any degrees of freedom -#include #include #include diff --git a/tests/lac/parallel_vector_12.cc b/tests/lac/parallel_vector_12.cc index 2c2b3d31bb..3a682fc37e 100644 --- a/tests/lac/parallel_vector_12.cc +++ b/tests/lac/parallel_vector_12.cc @@ -15,7 +15,7 @@ // check LinearAlgebra::distributed::Vector::swap -#include +#include #include #include diff --git a/tests/lac/parallel_vector_13.cc b/tests/lac/parallel_vector_13.cc index b378d41d74..843622f58c 100644 --- a/tests/lac/parallel_vector_13.cc +++ b/tests/lac/parallel_vector_13.cc @@ -17,7 +17,6 @@ // setting where one ghost is zero and should not have an effect on vector // entries -#include #include #include diff --git a/tests/lac/parallel_vector_14.cc b/tests/lac/parallel_vector_14.cc index e371d3aa53..ad1d328640 100644 --- a/tests/lac/parallel_vector_14.cc +++ b/tests/lac/parallel_vector_14.cc @@ -16,7 +16,6 @@ // check that handling of ghost elements in parallel distributed vectors works // appropriately when assigning from ghosted to non-ghosted vectors -#include #include #include diff --git a/tests/lac/parallel_vector_15.cc b/tests/lac/parallel_vector_15.cc index e2da69cada..0fdfc90b7e 100644 --- a/tests/lac/parallel_vector_15.cc +++ b/tests/lac/parallel_vector_15.cc @@ -17,7 +17,6 @@ // appropriately when creating a vector from a non-ghosted source vector using // the assignment operator -#include #include #include diff --git a/tests/lac/parallel_vector_21.cc b/tests/lac/parallel_vector_21.cc index e9ef68eabe..8f0464e4fe 100644 --- a/tests/lac/parallel_vector_21.cc +++ b/tests/lac/parallel_vector_21.cc @@ -16,7 +16,6 @@ // when doing reinit() from another vector and manually setting the local // range -#include #include #include diff --git a/tests/lac/parallel_vector_25.cc b/tests/lac/parallel_vector_25.cc index 4dafb5fbac..0c27a19012 100644 --- a/tests/lac/parallel_vector_25.cc +++ b/tests/lac/parallel_vector_25.cc @@ -15,7 +15,6 @@ // check import from LA::d::Vector to another LA::d::Vector -#include #include #include diff --git a/tests/matrix_free_kokkos/coefficient_eval_device.cc b/tests/matrix_free_kokkos/coefficient_eval_device.cc index 3eb5f75e85..a260a5c31e 100644 --- a/tests/matrix_free_kokkos/coefficient_eval_device.cc +++ b/tests/matrix_free_kokkos/coefficient_eval_device.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include diff --git a/tests/matrix_free_kokkos/evaluate_1d_shape.cc b/tests/matrix_free_kokkos/evaluate_1d_shape.cc index 9bcb820c77..7daa538697 100644 --- a/tests/matrix_free_kokkos/evaluate_1d_shape.cc +++ b/tests/matrix_free_kokkos/evaluate_1d_shape.cc @@ -15,16 +15,15 @@ // this function tests the correctness of the 1d evaluation functions used in -// CUDAWrappers::FEEvaluation. These functions are marked 'internal' but it is +// Portable::FEEvaluation. These functions are marked 'internal' but it is // much easier to check their correctness directly rather than from the results // in dependent functions #include -#include #include -#include +#include #include #include @@ -45,8 +44,8 @@ evaluate_tensor_product( Kokkos::View dst, Kokkos::View src) { - CUDAWrappers::internal::EvaluatorTensorProduct< - CUDAWrappers::internal::evaluate_general, + Portable::internal::EvaluatorTensorProduct< + Portable::internal::evaluate_general, 1, M - 1, N, diff --git a/tests/matrix_free_kokkos/evaluate_2d_shape.cc b/tests/matrix_free_kokkos/evaluate_2d_shape.cc index ae2eec2d57..a2f51058e4 100644 --- a/tests/matrix_free_kokkos/evaluate_2d_shape.cc +++ b/tests/matrix_free_kokkos/evaluate_2d_shape.cc @@ -15,14 +15,14 @@ // this function tests the correctness of the 2d evaluation functions used in -// CUDAWrappers::FEEvaluation. These functions are marked 'internal' but it is +// Portable::FEEvaluation. These functions are marked 'internal' but it is // much easier to check their correctness directly rather than from the results // in dependent functions -#include +#include #include -#include +#include #include #include @@ -43,8 +43,8 @@ evaluate_tensor_product( Kokkos::View dst, Kokkos::View src) { - CUDAWrappers::internal::EvaluatorTensorProduct< - CUDAWrappers::internal::evaluate_general, + Portable::internal::EvaluatorTensorProduct< + Portable::internal::evaluate_general, 2, M - 1, N, diff --git a/tests/matrix_free_kokkos/matrix_free_device_initialize_vector.cc b/tests/matrix_free_kokkos/matrix_free_device_initialize_vector.cc index 12f96bd39c..f7e82faadf 100644 --- a/tests/matrix_free_kokkos/matrix_free_device_initialize_vector.cc +++ b/tests/matrix_free_kokkos/matrix_free_device_initialize_vector.cc @@ -26,7 +26,6 @@ #include #include -#include #include @@ -49,16 +48,6 @@ check(const LinearAlgebra::distributed::Vector ExcInternalError()); } -#ifdef DEAL_II_WITH_CUDA -template -void -check(const LinearAlgebra::CUDAWrappers::Vector &vector, - const Utilities::MPI::Partitioner &reference_partitioner) -{ - AssertDimension(vector.size(), reference_partitioner.size()); -} -#endif - template void test() @@ -118,9 +107,5 @@ main(int argc, char **argv) 1, LinearAlgebra::distributed::Vector>(); -#ifdef DEAL_II_WITH_CUDA - if (Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD) == 1) - test<2, 1, LinearAlgebra::CUDAWrappers::Vector>(); -#endif return 0; } diff --git a/tests/matrix_free_kokkos/matrix_free_device_matrix_vector_06a.cc b/tests/matrix_free_kokkos/matrix_free_device_matrix_vector_06a.cc index 6df7661be9..dc2be58833 100644 --- a/tests/matrix_free_kokkos/matrix_free_device_matrix_vector_06a.cc +++ b/tests/matrix_free_kokkos/matrix_free_device_matrix_vector_06a.cc @@ -14,7 +14,7 @@ // Same as matrix_free_matrix_vector_06a but uses LA::distributed::Vector -// instead of CUDAWrappers::Vector +// instead of Portable::Vector #include diff --git a/tests/matrix_free_kokkos/matrix_free_device_multiple_objects.cc b/tests/matrix_free_kokkos/matrix_free_device_multiple_objects.cc index 3c3c01beee..3875aba2e2 100644 --- a/tests/matrix_free_kokkos/matrix_free_device_multiple_objects.cc +++ b/tests/matrix_free_kokkos/matrix_free_device_multiple_objects.cc @@ -29,7 +29,6 @@ #include #include -#include #include #include #include diff --git a/tests/matrix_free_kokkos/matrix_vector_device_common.h b/tests/matrix_free_kokkos/matrix_vector_device_common.h index 50ccb2bacc..69974ed8d8 100644 --- a/tests/matrix_free_kokkos/matrix_vector_device_common.h +++ b/tests/matrix_free_kokkos/matrix_vector_device_common.h @@ -32,7 +32,6 @@ #include #include -#include #include #include #include diff --git a/tests/matrix_free_kokkos/matrix_vector_device_mf.h b/tests/matrix_free_kokkos/matrix_vector_device_mf.h index 5ffd866f2d..7ac568cab4 100644 --- a/tests/matrix_free_kokkos/matrix_vector_device_mf.h +++ b/tests/matrix_free_kokkos/matrix_vector_device_mf.h @@ -17,7 +17,6 @@ // (zero and first derivatives) on different kinds of meshes (Cartesian, // general, with and without hanging nodes). -#include #include #include diff --git a/tests/performance/timing_matrix_free_kokkos.cc b/tests/performance/timing_matrix_free_kokkos.cc index c9b0f53fbf..e985c56d22 100644 --- a/tests/performance/timing_matrix_free_kokkos.cc +++ b/tests/performance/timing_matrix_free_kokkos.cc @@ -14,13 +14,13 @@ * * Description: * - * This test compares the MatrixFree and CUDAWrapper::MatrixFree + * This test compares the MatrixFree and Portable::MatrixFree * infrastructure on the CPU. Considered are the initialization * costs and the costs for an operator evaluation. - * CUDAWrapper::MatrixFree was written with CUDA and now uses + * Portable::MatrixFree was written with CUDA and now uses * Kokkos as backend and, as consequence, favors GPU hardware. This * performance test is meant to track the improvement of - * the performance of CUDAWrapper::MatrixFree on the CPU. + * the performance of Portable::MatrixFree on the CPU. * * Status: experimental */ @@ -35,8 +35,6 @@ #include -#include -#include #include #include @@ -119,8 +117,7 @@ class LaplaceOperatorQuad public: DEAL_II_HOST_DEVICE void operator()( - CUDAWrappers::FEEvaluation - *fe_eval, + Portable::FEEvaluation *fe_eval, const int q_point) const { fe_eval->submit_gradient(fe_eval->get_gradient(q_point), q_point); @@ -132,17 +129,16 @@ class LaplaceOperatorLocal { public: DEAL_II_HOST_DEVICE void - operator()( - const unsigned int cell, - const typename CUDAWrappers::MatrixFree::Data *gpu_data, - CUDAWrappers::SharedData *shared_data, - const Number *src, - Number *dst) const + operator()(const unsigned int cell, + const typename Portable::MatrixFree::Data *gpu_data, + Portable::SharedData *shared_data, + const Number *src, + Number *dst) const { (void)cell; // TODO? - CUDAWrappers::FEEvaluation - fe_eval(/*cell,*/ gpu_data, shared_data); + Portable::FEEvaluation fe_eval( + /*cell,*/ gpu_data, shared_data); fe_eval.read_dof_values(src); fe_eval.evaluate(EvaluationFlags::gradients); fe_eval.apply_for_each_quad_point( @@ -170,8 +166,7 @@ public: const AffineConstraints &constraints, const Quadrature<1> &quadrature) { - typename CUDAWrappers::MatrixFree::AdditionalData - additional_data; + typename Portable::MatrixFree::AdditionalData additional_data; additional_data.mapping_update_flags = update_JxW_values | update_gradients; matrix_free.reinit( @@ -192,7 +187,7 @@ public: } private: - CUDAWrappers::MatrixFree matrix_free; + Portable::MatrixFree matrix_free; }; diff --git a/tests/quick_tests/cuda.cc b/tests/quick_tests/cuda.cc deleted file mode 100644 index eadffa9674..0000000000 --- a/tests/quick_tests/cuda.cc +++ /dev/null @@ -1,75 +0,0 @@ -// ------------------------------------------------------------------------ -// -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2017 - 2023 by the deal.II authors -// -// This file is part of the deal.II library. -// -// Part of the source code is dual licensed under Apache-2.0 WITH -// LLVM-exception OR LGPL-2.1-or-later. Detailed license information -// governing the source code and code contributions can be found in -// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II. -// -// ------------------------------------------------------------------------ - - -#include - -#include -#include -#include - -using namespace dealii; - -__global__ void -double_value(double *x, double *y) -{ - y[threadIdx.x] = 2. * x[threadIdx.x]; -} - -int -main() -{ - constexpr int n = 4; - - std::array host_x{}; - std::iota(host_x.begin(), host_x.end(), 1); - std::array host_y{}; - - // Copy input data to device. - double *device_x; - double *device_y; - cudaError_t cuda_error = cudaMalloc(&device_x, n * sizeof(double)); - AssertCuda(cuda_error); - cuda_error = cudaMalloc(&device_y, n * sizeof(double)); - AssertCuda(cuda_error); - cuda_error = cudaMemcpy(device_x, - host_x.data(), - n * sizeof(double), - cudaMemcpyHostToDevice); - AssertCuda(cuda_error); - - // Launch the kernel. - double_value<<<1, n>>>(device_x, device_y); - - // Copy output data to host. - cuda_error = cudaDeviceSynchronize(); - AssertCuda(cuda_error); - cuda_error = cudaMemcpy(host_y.data(), - device_y, - n * sizeof(double), - cudaMemcpyDeviceToHost); - AssertCuda(cuda_error); - - // Print the results and test - for (int i = 0; i < n; ++i) - { - std::cout << "y[" << i << "] = " << host_y[i] << "\n"; - AssertThrow(std::abs(host_y[i] - 2 * host_x[i]) < 1.e-10, - ExcInternalError()); - } - - cuda_error = cudaDeviceReset(); - AssertCuda(cuda_error); - return 0; -} diff --git a/tests/run_testsuite.cmake b/tests/run_testsuite.cmake index 85136c6f04..e6f6daccef 100644 --- a/tests/run_testsuite.cmake +++ b/tests/run_testsuite.cmake @@ -271,7 +271,7 @@ foreach(_var ${_variables}) _var MATCHES "^(DOCUMENTATION|EXAMPLES)" OR _var MATCHES "^(ADOLC|ARBORX|ARPACK|BOOST|OPENCASCADE|MUPARSER|HDF5|KOKKOS|METIS|MPI)_" OR _var MATCHES "^(GINKGO|P4EST|PETSC|SCALAPACK|SLEPC|THREADS|TBB|TRILINOS)_" OR - _var MATCHES "^(UMFPACK|ZLIB|LAPACK|MUPARSER|CUDA)_" OR + _var MATCHES "^(UMFPACK|ZLIB|LAPACK|MUPARSER)_" OR _var MATCHES "^(CMAKE|DEAL_II)_(C|CXX|Fortran|BUILD)_(COMPILER|FLAGS)" OR _var MATCHES "^CMAKE_BUILD_TYPE$" OR _var MATCHES "MAKEOPTS" OR diff --git a/tests/tests.h b/tests/tests.h index e4f69e8d14..ca4067e3e0 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -720,60 +719,6 @@ struct MPILogInitAll }; -#ifdef DEAL_II_WITH_CUDA -// By default, all the ranks will try to access the device 0. -// If we are running with MPI support it is better to address different graphic -// cards for different processes even if only one node is used. The choice below -// is based on the MPI process id. -// MPI needs to be initialized before using this function. -void -init_cuda(const bool use_mpi = false) -{ -# ifndef DEAL_II_WITH_MPI - Assert(use_mpi == false, ExcInternalError()); -# endif - const unsigned int my_id = - use_mpi ? Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) : 0; - int n_devices = 0; - cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices); - AssertCuda(cuda_error_code); - const int device_id = my_id % n_devices; - cuda_error_code = cudaSetDevice(device_id); - AssertCuda(cuda_error_code); - - // In principle, we should be able to distribute the load better by - // choosing a random graphics card. For some reason, this produces timeouts - // on the tester we use mainly for the CUDA tests so we don't use the - // following optimization by default. - - /* - # ifndef DEAL_II_WITH_MPI - Assert(use_mpi == false, ExcInternalError()); - # endif - const unsigned int my_id = - use_mpi ? Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) : 0; - int device_id = 0; - int n_devices = 0; - cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices); - AssertCuda(cuda_error_code); - if (my_id == 0) - { - Testing::srand(std::time(nullptr)); - device_id = Testing::rand() % n_devices; - } - # ifdef DEAL_II_WITH_MPI - if (use_mpi) - MPI_Bcast(&device_id, 1, MPI_INT, 0, MPI_COMM_WORLD); - # endif - device_id = (device_id + my_id) % n_devices; - cuda_error_code = cudaSetDevice(device_id); - AssertCuda(cuda_error_code); - */ -} -#endif - - - /* Override the tbb assertion handler in order to print a stacktrace:*/ #ifdef TBB_DO_ASSERT