std::ofstream logfile("output");
deallog.attach(logfile);
+ init_cuda();
+
deallog.push("values");
test<4, 4, 0, false>();
test<3, 3, 0, false>();
std::ofstream logfile("output");
deallog.attach(logfile);
+ init_cuda();
+
deallog.push("values");
test<4, 4, 0, false>();
test<3, 3, 0, false>();
deallog << std::setprecision(5);
deallog.attach(logfile);
+ init_cuda();
+
test_cpu();
test_gpu();
initlog();
deallog.depth_console(0);
+ init_cuda();
+
test();
deallog << "OK" << std::endl;
initlog();
deallog.depth_console(0);
+ init_cuda();
+
test();
deallog << "OK" << std::endl;
initlog();
deallog.depth_console(0);
+ init_cuda();
+
test();
deallog << "OK" << std::endl;
initlog();
deallog.depth_console(0);
+ init_cuda();
+
test();
deallog << "OK" << std::endl;
deallog << std::setprecision(3);
+ init_cuda();
+
{
deallog.push("2d");
test<2, 1>();
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
-
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
Utilities::MPI::MPI_InitFinalize mpi_initialization(
argc, argv, testing_max_num_threads());
+ init_cuda(true);
+
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
-
-
if (myid == 0)
{
initlog();
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
-
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda();
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
-
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
-
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
deallog.push(Utilities::int_to_string(myid));
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = myid % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
if (myid == 0)
{
Utilities::MPI::MPI_InitFinalize mpi_initialization(
argc, argv, testing_max_num_threads());
- unsigned int my_id = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
- Utilities::CUDA::Handle cuda_handle;
- // By default, all the ranks will try to access the device 0. This is fine if
- // we have one rank per node _and_ one gpu per node. If we have multiple GPUs
- // on one node, we need each process to access a different GPU. We assume that
- // each node has the same number of GPUs.
- int n_devices = 0;
- cudaError_t cuda_error_code = cudaGetDeviceCount(&n_devices);
- AssertCuda(cuda_error_code);
- int device_id = my_id % n_devices;
- cuda_error_code = cudaSetDevice(device_id);
- AssertCuda(cuda_error_code);
+ init_cuda(true);
MPILogInitAll log;
test();
deallog << std::setprecision(10);
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
deallog << "Testing float" << std::endl;
test<float>(cuda_handle);
deallog << std::setprecision(10);
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
deallog << "Testing float" << std::endl;
test<float>(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(10);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
initlog();
deallog.depth_console(0);
+ init_cuda();
+
Utilities::CUDA::Handle cuda_handle;
test(cuda_handle);
{
Utilities::MPI::MPI_InitFinalize mpi_initialization(
argc, argv, testing_max_num_threads());
- Utilities::CUDA::Handle cuda_handle;
initlog();
+ init_cuda();
do_test<
LinearAlgebra::distributed::Vector<double, dealii::MemorySpace::CUDA>>();
#include <deal.II/base/config.h>
+#include <deal.II/base/cuda.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/job_identifier.h>
#include <deal.II/base/logstream.h>
};
+#ifdef DEAL_II_COMPILER_CUDA_AWARE
+// By default, all the ranks will try to access the device 0. We can distribute
+// the load better by using a random device which is done in this function. In
+// case tests use MPI, we make sure to set subsequent devices. MPI needs to be
+// initialized before using this function.
+// Also initialize a dummy handle that makes sure that unused memory is released
+// before the device shuts down.
+void
+init_cuda(bool use_mpi = false)
+{
+ static Utilities::CUDA::Handle cuda_handle;
+# 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);
+ if (my_id == 0)
+ {
+ Testing::srand(std::time(nullptr));
+ AssertCuda(cuda_error_code);
+ 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:*/