From e5feb7a906028a8f6dc6619fce6190337d67f6df Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Sat, 3 Nov 2018 12:41:02 +0100 Subject: [PATCH] Test correct memory space --- include/deal.II/base/array_view.h | 69 ++++++++++++++++++- tests/cuda/array_view_wrong_memory.cu | 62 +++++++++++++++++ .../cuda/array_view_wrong_memory.debug.output | 25 +++++++ 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tests/cuda/array_view_wrong_memory.cu create mode 100644 tests/cuda/array_view_wrong_memory.debug.output diff --git a/include/deal.II/base/array_view.h b/include/deal.II/base/array_view.h index 92aa30e8e9..5c769608c4 100644 --- a/include/deal.II/base/array_view.h +++ b/include/deal.II/base/array_view.h @@ -264,6 +264,60 @@ private: //--------------------------------------------------------------------------- +namespace internal +{ + namespace ArrayViewHelper + { + template + inline bool + correct_memory_space(const void *const) + { + return std::is_same::value; + } + +#ifdef DEAL_II_COMPILER_CUDA_AWARE + template <> + inline bool + correct_memory_space(const void *ptr) + { + cudaPointerAttributes attributes; + const cudaError_t cuda_error = cudaPointerGetAttributes(&attributes, ptr); + if (cuda_error != cudaErrorInvalidValue) + { + AssertCuda(cuda_error); + return attributes.memoryType == cudaMemoryTypeHost; + } + else + { + // ignore and reset the error since host pointers produce an error + cudaGetLastError(); + return true; + } + } + + template <> + inline bool + correct_memory_space(const void *ptr) + { + cudaPointerAttributes attributes; + const cudaError_t cuda_error = cudaPointerGetAttributes(&attributes, ptr); + if (cuda_error != cudaErrorInvalidValue) + { + AssertCuda(cuda_error); + return attributes.memoryType == cudaMemoryTypeDevice; + } + else + { + // ignore and reset the error since host pointers produce an error + cudaGetLastError(); + return false; + } + } +#endif + } // namespace ArrayViewHelper +} // namespace internal + + template inline ArrayView::ArrayView( @@ -271,7 +325,13 @@ inline ArrayView::ArrayView( const std::size_t n_elements) : starting_element(starting_element) , n_elements(n_elements) -{} +{ + Assert(internal::ArrayViewHelper::correct_memory_space( + starting_element), + ExcMessage( + "The memory space indicated by the template parameter " + "and the one derived from the pointer value do not match!")); +} @@ -305,6 +365,11 @@ inline ArrayView::ArrayView( "object has a const value_type. In other words, you can " "only create an ArrayView to const values from a const " "std::vector."); + Assert(internal::ArrayViewHelper::correct_memory_space( + vector.data()), + ExcMessage( + "The memory space indicated by the template parameter " + "and the one derived from the pointer value do not match!")); } @@ -381,6 +446,8 @@ ArrayView::size() const return n_elements; } + + template inline typename ArrayView::iterator ArrayView::begin() const diff --git a/tests/cuda/array_view_wrong_memory.cu b/tests/cuda/array_view_wrong_memory.cu new file mode 100644 index 0000000000..66f8972317 --- /dev/null +++ b/tests/cuda/array_view_wrong_memory.cu @@ -0,0 +1,62 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// check that we detect creating ArrayView objects wit the wrong memory space. + +#include + +#include "../tests.h" + +int +main(int argc, char **argv) +{ + deal_II_exceptions::disable_abort_on_exception(); + + initlog(); + + std::vector dummy_host(2); + std::unique_ptr dummy_cuda( + Utilities::CUDA::allocate_device_data(2), + Utilities::CUDA::delete_device_data); + + deallog << "Testing host ArrayView with host memory" << std::endl; + ArrayView view_1(dummy_host); + + deallog << "Testing device ArrayView with host memory" << std::endl; + try + { + ArrayView view_2(dummy_host); + } + catch (const ExceptionBase &exc) + { + deallog << exc.what() << std::endl; + } + + deallog << "Testing host ArrayView with device memory" << std::endl; + try + { + ArrayView view_3(dummy_cuda.get(), 2); + } + catch (const ExceptionBase &exc) + { + deallog << exc.what() << std::endl; + } + + deallog << "Testing device ArrayView with device memory" << std::endl; + ArrayView view_4(dummy_cuda.get(), 2); + + return 0; +} diff --git a/tests/cuda/array_view_wrong_memory.debug.output b/tests/cuda/array_view_wrong_memory.debug.output new file mode 100644 index 0000000000..f2413eaf9c --- /dev/null +++ b/tests/cuda/array_view_wrong_memory.debug.output @@ -0,0 +1,25 @@ + +DEAL::Testing host ArrayView with host memory +DEAL::Testing device ArrayView with host memory +DEAL:: +-------------------------------------------------------- +An error occurred in file in function + dealii::ArrayView::ArrayView(dealii::ArrayView::value_type*, std::size_t) [with ElementType = unsigned int; MemorySpaceType = dealii::MemorySpace::CUDA; dealii::ArrayView::value_type = unsigned int; std::size_t = long unsigned int] +The violated condition was: + internal::ArrayViewHelper::correct_memory_space( starting_element) +Additional information: + The memory space indicated by the template parameter and the one derived from the pointer value do not match! +-------------------------------------------------------- + +DEAL::Testing host ArrayView with device memory +DEAL:: +-------------------------------------------------------- +An error occurred in file in function + dealii::ArrayView::ArrayView(dealii::ArrayView::value_type*, std::size_t) [with ElementType = unsigned int; MemorySpaceType = dealii::MemorySpace::Host; dealii::ArrayView::value_type = unsigned int; std::size_t = long unsigned int] +The violated condition was: + internal::ArrayViewHelper::correct_memory_space( starting_element) +Additional information: + The memory space indicated by the template parameter and the one derived from the pointer value do not match! +-------------------------------------------------------- + +DEAL::Testing device ArrayView with device memory -- 2.39.5