Reference documentation for deal.II version Git 040c6ad7d4 2020-09-26 18:01:03 +0200
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
memory_space.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2018 - 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #ifndef dealii_memory_space_h
18 #define dealii_memory_space_h
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/base/cuda.h>
24 
25 #include <functional>
26 #include <memory>
27 
29 
32 namespace MemorySpace
33 {
37  struct Host
38  {};
39 
40 
41 
45  struct CUDA
46  {};
47 
48 
49 
53  template <typename Number, typename MemorySpace>
55  {
57  {
58  static_assert(std::is_same<MemorySpace, Host>::value ||
59  std::is_same<MemorySpace, CUDA>::value,
60  "MemorySpace should be Host or CUDA");
61  }
62 
67  virtual void
68  copy_to(Number *begin, std::size_t n_elements)
69  {
70  (void)begin;
71  (void)n_elements;
72  }
73 
78  virtual void
79  copy_from(Number *begin, std::size_t n_elements)
80  {
81  (void)begin;
82  (void)n_elements;
83  }
84 
88  std::unique_ptr<Number[], std::function<void(Number *)>> values;
89 
93  std::unique_ptr<Number[]> values_dev;
94  };
95 
96 
97 
101  template <typename Number, typename MemorySpace>
102  inline void
105  {
106  static_assert(std::is_same<MemorySpace, Host>::value ||
107  std::is_same<MemorySpace, CUDA>::value,
108  "MemorySpace should be Host or CUDA");
109  }
110 
111 #ifndef DOXYGEN
112 
113  template <typename Number>
114  struct MemorySpaceData<Number, Host>
115  {
117  : values(nullptr, &std::free)
118  {}
119 
120  virtual ~MemorySpaceData() = default;
121 
122  MemorySpaceData(MemorySpaceData &&) noexcept = default;
123 
124  MemorySpaceData &
125  operator=(MemorySpaceData &&) noexcept = default;
126 
127  virtual void
128  copy_to(Number *begin, std::size_t n_elements)
129  {
130  std::copy(values.get(), values.get() + n_elements, begin);
131  }
132 
133  virtual void
134  copy_from(Number *begin, std::size_t n_elements)
135  {
136  std::copy(begin, begin + n_elements, values.get());
137  }
138 
139  std::unique_ptr<Number[], std::function<void(Number *)>> values;
140 
141  // This is not used but it allows to simplify the code until we start using
142  // CUDA-aware MPI.
143  std::unique_ptr<Number[]> values_dev;
144  };
145 
146 
147 
148  template <typename Number>
149  inline void
151  {
152  std::swap(u.values, v.values);
153  }
154 
155 
156 
157 # ifdef DEAL_II_COMPILER_CUDA_AWARE
158 
159  template <typename Number>
160  struct MemorySpaceData<Number, CUDA>
161  {
163  : values(nullptr, &std::free)
164  , values_dev(nullptr, Utilities::CUDA::delete_device_data<Number>)
165  {}
166 
167  virtual ~MemorySpaceData() = default;
168 
169  MemorySpaceData(MemorySpaceData &&) noexcept = default;
170 
171  MemorySpaceData &
172  operator=(MemorySpaceData &&) noexcept = default;
173 
174  virtual void
175  copy_to(Number *begin, std::size_t n_elements)
176  {
177  const cudaError_t cuda_error_code =
178  cudaMemcpy(begin,
179  values_dev.get(),
180  n_elements * sizeof(Number),
181  cudaMemcpyDeviceToHost);
182  AssertCuda(cuda_error_code);
183  }
184 
185  virtual void
186  copy_from(Number *begin, std::size_t n_elements)
187  {
188  const cudaError_t cuda_error_code =
189  cudaMemcpy(values_dev.get(),
190  begin,
191  n_elements * sizeof(Number),
192  cudaMemcpyHostToDevice);
193  AssertCuda(cuda_error_code);
194  }
195 
196  std::unique_ptr<Number[], std::function<void(Number *)>> values;
197  std::unique_ptr<Number[], void (*)(Number *)> values_dev;
198  };
199 
200 
201 
202  template <typename Number>
203  inline void
205  {
206  std::swap(u.values, v.values);
208  }
209 
210 # endif
211 
212 #endif
213 
214 } // namespace MemorySpace
215 
217 
218 #endif
virtual void copy_to(Number *begin, std::size_t n_elements)
Definition: memory_space.h:68
#define AssertCuda(error_code)
Definition: exceptions.h:1718
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:363
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
Definition: memory_space.h:103
std::unique_ptr< Number[], std::function< void(Number *)> > values
Definition: memory_space.h:88
virtual void copy_from(Number *begin, std::size_t n_elements)
Definition: memory_space.h:79
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:362
VectorType::value_type * begin(VectorType &V)
void free(T *&pointer)
Definition: cuda.h:96
void copy(const T *begin, const T *end, U *dest)
std::unique_ptr< Number[]> values_dev
Definition: memory_space.h:93