From 2753e8efa9d2cdff7d1d07cce4c57d7ca1680c63 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Sat, 3 Nov 2018 13:52:23 +0100 Subject: [PATCH] Restrict access to ArrayView::operator[] to CPU memory --- include/deal.II/base/array_view.h | 19 +++++--- tests/cuda/array_view_access_data.cu | 46 +++++++++++++++++++ .../cuda/array_view_access_data.debug.output | 11 +++++ 3 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 tests/cuda/array_view_access_data.cu create mode 100644 tests/cuda/array_view_access_data.debug.output diff --git a/include/deal.II/base/array_view.h b/include/deal.II/base/array_view.h index 5c769608c4..19f0d9bd6a 100644 --- a/include/deal.II/base/array_view.h +++ b/include/deal.II/base/array_view.h @@ -34,15 +34,15 @@ DEAL_II_NAMESPACE_OPEN /** * A class that represents a window of memory locations of type @p ElementType - * and presents it as if it was an array that can be accessed via an - * operator[]. In essence, this class is nothing more than just a - * pointer to the first location and an integer that represents the length of - * the array in elements. The memory remains owned by whoever allocated it, as - * this class does not take over ownership. + * and presents it as if it was an array. In essence, this class is nothing more + * than just a pointer to the first location and an integer that represents the + * length of the array in elements. The memory remains owned by whoever + * allocated it, as this class does not take over ownership. * * The advantage of using this class is that you don't have to pass around * pairs of pointers and that operator[] checks for the validity - * of the index with which you subscript this array view. + * of the index with which you subscript this array view. Note that accessing + * elements is only allowed if the underlying data is stored in CPU memory. * * This class can handle views to both non-constant and constant memory * locations. If you want to represent a view of a constant array, then the @@ -241,6 +241,9 @@ public: * view object. It may however return a reference to a non-@p const * memory location depending on whether the template type of the class is @p * const or not. + * + * This function is only allowed to be called if the underlying data is indeed + * stored in CPU memory. */ value_type &operator[](const std::size_t i) const; @@ -488,6 +491,10 @@ template inline typename ArrayView::value_type & ArrayView::operator[](const std::size_t i) const { + Assert( + (std::is_same::value), + ExcMessage( + "Accessing elements is only allowed if the data is stored in CPU memory!")); Assert(i < n_elements, ExcIndexRange(i, 0, n_elements)); return *(starting_element + i); diff --git a/tests/cuda/array_view_access_data.cu b/tests/cuda/array_view_access_data.cu new file mode 100644 index 0000000000..5165c22b5f --- /dev/null +++ b/tests/cuda/array_view_access_data.cu @@ -0,0 +1,46 @@ +// --------------------------------------------------------------------- +// +// 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 that accessing CUDA memory in an ArrayView object +// is not allowed. + +#include + +#include "../tests.h" + +int +main(int argc, char **argv) +{ + deal_II_exceptions::disable_abort_on_exception(); + + initlog(); + + std::unique_ptr dummy_cuda( + Utilities::CUDA::allocate_device_data(2), + Utilities::CUDA::delete_device_data); + + try + { + ArrayView view(dummy_cuda.get(), 2); + const auto dummy = view[0]; + } + catch (const ExceptionBase &exc) + { + deallog << exc.what() << std::endl; + } + + return 0; +} diff --git a/tests/cuda/array_view_access_data.debug.output b/tests/cuda/array_view_access_data.debug.output new file mode 100644 index 0000000000..b50cbe5806 --- /dev/null +++ b/tests/cuda/array_view_access_data.debug.output @@ -0,0 +1,11 @@ + +DEAL:: +-------------------------------------------------------- +An error occurred in file in function + dealii::ArrayView::value_type& dealii::ArrayView::operator[](std::size_t) const [with ElementType = unsigned int; MemorySpaceType = dealii::MemorySpace::CUDA; dealii::ArrayView::value_type = unsigned int; std::size_t = long unsigned int] +The violated condition was: + (std::is_same::value) +Additional information: + Accessing elements is only allowed if the data is stored in CPU memory! +-------------------------------------------------------- + -- 2.39.5