Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Details_StaticView.cpp
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Tpetra_Details_StaticView.hpp"
11 
12 namespace Tpetra {
13 namespace Details {
14 namespace Impl {
15 
16 namespace { // (anonymous)
17 
18 // Motivating use cases for the initial size:
19 //
20 // 1. GMRES (need restart length (default 30) number of rows)
21 // 2. Single reduce CG (need 2 x 2)
22 constexpr size_t minimum_initial_size = sizeof (double) * 30 * 2;
23 
24 // Intel 17 seems a bit buggy with respect to initialization of
25 // templated static classes, so let's make the compiler's job really
26 // easy by having nontemplated static raw pointers.
27 
28 #ifdef KOKKOS_ENABLE_CUDA
29 
30 void* cuda_memory_ = nullptr;
31 size_t cuda_memory_size_ = 0;
32 
33 void finalize_cuda_memory ()
34 {
35  if (cuda_memory_ != nullptr) {
36  Kokkos::kokkos_free<Kokkos::CudaSpace> (cuda_memory_);
37  cuda_memory_ = nullptr;
38  cuda_memory_size_ = 0;
39  }
40 }
41 
42 void* cuda_uvm_memory_ = nullptr;
43 size_t cuda_uvm_memory_size_ = 0;
44 
45 void finalize_cuda_uvm_memory ()
46 {
47  if (cuda_uvm_memory_ != nullptr) {
48  Kokkos::kokkos_free<Kokkos::CudaUVMSpace> (cuda_uvm_memory_);
49  cuda_uvm_memory_ = nullptr;
50  cuda_uvm_memory_size_ = 0;
51  }
52 }
53 
54 void* cuda_host_pinned_memory_ = nullptr;
55 size_t cuda_host_pinned_memory_size_ = 0;
56 
57 void finalize_cuda_host_pinned_memory ()
58 {
59  if (cuda_host_pinned_memory_ != nullptr) {
60  Kokkos::kokkos_free<Kokkos::CudaHostPinnedSpace> (cuda_host_pinned_memory_);
61  cuda_host_pinned_memory_ = nullptr;
62  cuda_host_pinned_memory_size_ = 0;
63  }
64 }
65 #endif // KOKKOS_ENABLE_CUDA
66 
67 #ifdef KOKKOS_ENABLE_HIP
68 
69 void* hip_memory_ = nullptr;
70 size_t hip_memory_size_ = 0;
71 
72 void finalize_hip_memory ()
73 {
74  if (hip_memory_ != nullptr) {
75  Kokkos::kokkos_free<Kokkos::HIPSpace> (hip_memory_);
76  hip_memory_ = nullptr;
77  hip_memory_size_ = 0;
78  }
79 }
80 
81 void* hip_host_pinned_memory_ = nullptr;
82 size_t hip_host_pinned_memory_size_ = 0;
83 
84 void finalize_hip_host_pinned_memory ()
85 {
86  if (hip_host_pinned_memory_ != nullptr) {
87  Kokkos::kokkos_free<Kokkos::HIPHostPinnedSpace> (hip_host_pinned_memory_);
88  hip_host_pinned_memory_ = nullptr;
89  hip_host_pinned_memory_size_ = 0;
90  }
91 }
92 #endif // KOKKOS_ENABLE_HIP
93 
94 #ifdef KOKKOS_ENABLE_SYCL
95 
96 void* sycl_memory_ = nullptr;
97 size_t sycl_memory_size_ = 0;
98 
99 void finalize_sycl_memory ()
100 {
101  if (sycl_memory_ != nullptr) {
102  Kokkos::kokkos_free<Kokkos::Experimental::SYCLDeviceUSMSpace> (sycl_memory_);
103  sycl_memory_ = nullptr;
104  sycl_memory_size_ = 0;
105  }
106 }
107 
108 void* sycl_shared_memory_ = nullptr;
109 size_t sycl_shared_memory_size_ = 0;
110 
111 void finalize_sycl_shared_memory ()
112 {
113  if (sycl_shared_memory_ != nullptr) {
114  Kokkos::kokkos_free<Kokkos::Experimental::SYCLSharedUSMSpace> (sycl_shared_memory_);
115  sycl_shared_memory_ = nullptr;
116  sycl_shared_memory_size_ = 0;
117  }
118 }
119 #endif // KOKKOS_ENABLE_SYCL
120 
121 void* host_memory_ = nullptr;
122 size_t host_memory_size_ = 0;
123 
124 void finalize_host_memory ()
125 {
126  if (host_memory_ != nullptr) {
127  Kokkos::kokkos_free<Kokkos::HostSpace> (host_memory_);
128  host_memory_ = nullptr;
129  host_memory_size_ = 0;
130  }
131 }
132 
133 } // namespace (anonymous)
134 
135 #ifdef KOKKOS_ENABLE_CUDA
136 
137 void*
138 StaticKokkosAllocation<Kokkos::CudaSpace>::
139 resize (Kokkos::CudaSpace /* space */,
140  const size_t size)
141 {
142  using memory_space = Kokkos::CudaSpace;
143  static bool created_finalize_hook = false;
144 
145  if (size > cuda_memory_size_) {
146  if (cuda_memory_ != nullptr) {
147  Kokkos::kokkos_free<memory_space> (cuda_memory_);
148  }
149  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
150  cuda_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
151  cuda_memory_size_ = size;
152  }
153  if (! created_finalize_hook) {
154  Kokkos::push_finalize_hook (finalize_cuda_memory);
155  created_finalize_hook = true;
156  }
157 
158  return cuda_memory_;
159 }
160 
161 void*
162 StaticKokkosAllocation<Kokkos::CudaUVMSpace>::
163 resize (Kokkos::CudaUVMSpace /* space */,
164  const size_t size)
165 {
166  using memory_space = Kokkos::CudaUVMSpace;
167  static bool created_finalize_hook = false;
168 
169  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
170  if (req_size > cuda_uvm_memory_size_) {
171  if (cuda_uvm_memory_ != nullptr) {
172  Kokkos::kokkos_free<memory_space> (cuda_uvm_memory_);
173  }
174  cuda_uvm_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
175  cuda_uvm_memory_size_ = req_size;
176  }
177  if (! created_finalize_hook) {
178  Kokkos::push_finalize_hook (finalize_cuda_uvm_memory);
179  created_finalize_hook = true;
180  }
181 
182  return cuda_uvm_memory_;
183 }
184 
185 void*
186 StaticKokkosAllocation<Kokkos::CudaHostPinnedSpace>::
187 resize (Kokkos::CudaHostPinnedSpace /* space */,
188  const size_t size)
189 {
190  using memory_space = Kokkos::CudaHostPinnedSpace;
191  static bool created_finalize_hook = false;
192 
193  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
194  if (req_size > cuda_host_pinned_memory_size_) {
195  if (cuda_host_pinned_memory_ != nullptr) {
196  Kokkos::kokkos_free<memory_space> (cuda_host_pinned_memory_);
197  }
198  cuda_host_pinned_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
199  cuda_host_pinned_memory_size_ = req_size;
200  }
201  if (! created_finalize_hook) {
202  Kokkos::push_finalize_hook (finalize_cuda_host_pinned_memory);
203  created_finalize_hook = true;
204  }
205 
206  return cuda_host_pinned_memory_;
207 }
208 
209 #endif // KOKKOS_ENABLE_CUDA
210 
211 #ifdef KOKKOS_ENABLE_HIP
212 
213 void*
214 StaticKokkosAllocation<Kokkos::HIPSpace>::
215 resize (Kokkos::HIPSpace /* space */,
216  const size_t size)
217 {
218  using memory_space = Kokkos::HIPSpace;
219  static bool created_finalize_hook = false;
220 
221  if (size > hip_memory_size_) {
222  if (hip_memory_ != nullptr) {
223  Kokkos::kokkos_free<memory_space> (hip_memory_);
224  }
225  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
226  hip_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
227  hip_memory_size_ = size;
228  }
229  if (! created_finalize_hook) {
230  Kokkos::push_finalize_hook (finalize_hip_memory);
231  created_finalize_hook = true;
232  }
233 
234  return hip_memory_;
235 }
236 
237 void*
238 StaticKokkosAllocation<Kokkos::HIPHostPinnedSpace>::
239 resize (Kokkos::HIPHostPinnedSpace /* space */,
240  const size_t size)
241 {
242  using memory_space = Kokkos::HIPHostPinnedSpace;
243  static bool created_finalize_hook = false;
244 
245  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
246  if (req_size > hip_host_pinned_memory_size_) {
247  if (hip_host_pinned_memory_ != nullptr) {
248  Kokkos::kokkos_free<memory_space> (hip_host_pinned_memory_);
249  }
250  hip_host_pinned_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
251  hip_host_pinned_memory_size_ = req_size;
252  }
253  if (! created_finalize_hook) {
254  Kokkos::push_finalize_hook (finalize_hip_host_pinned_memory);
255  created_finalize_hook = true;
256  }
257 
258  return hip_host_pinned_memory_;
259 }
260 
261 #endif // KOKKOS_ENABLE_HIP
262 
263 #ifdef KOKKOS_ENABLE_SYCL
264 
265 template <>
266 void*
267 StaticKokkosAllocation<Kokkos::Experimental::SYCLDeviceUSMSpace>::
268 resize (Kokkos::Experimental::SYCLDeviceUSMSpace /* space */,
269  const size_t size)
270 {
271  using memory_space = Kokkos::Experimental::SYCLDeviceUSMSpace;
272  static bool created_finalize_hook = false;
273 
274  if (size > sycl_memory_size_) {
275  if (sycl_memory_ != nullptr) {
276  Kokkos::kokkos_free<memory_space> (sycl_memory_);
277  }
278  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
279  sycl_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
280  sycl_memory_size_ = size;
281  }
282  if (! created_finalize_hook) {
283  Kokkos::push_finalize_hook (finalize_sycl_memory);
284  created_finalize_hook = true;
285  }
286 
287  return sycl_memory_;
288 }
289 
290 template <>
291 void*
292 StaticKokkosAllocation<Kokkos::Experimental::SYCLSharedUSMSpace>::
293 resize (Kokkos::Experimental::SYCLSharedUSMSpace /* space */,
294  const size_t size)
295 {
296  using memory_space = Kokkos::Experimental::SYCLSharedUSMSpace;
297  static bool created_finalize_hook = false;
298 
299  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
300  if (req_size > sycl_shared_memory_size_) {
301  if (sycl_shared_memory_ != nullptr) {
302  Kokkos::kokkos_free<memory_space> (sycl_shared_memory_);
303  }
304  sycl_shared_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
305  sycl_shared_memory_size_ = req_size;
306  }
307  if (! created_finalize_hook) {
308  Kokkos::push_finalize_hook (finalize_sycl_shared_memory);
309  created_finalize_hook = true;
310  }
311 
312  return sycl_shared_memory_;
313 }
314 
315 #endif // KOKKOS_ENABLE_SYCL
316 
317 void*
318 StaticKokkosAllocation<Kokkos::HostSpace>::
319 resize (Kokkos::HostSpace /* space */,
320  const size_t size)
321 {
322  using memory_space = Kokkos::HostSpace;
323  static bool created_finalize_hook = false;
324 
325  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
326  if (req_size > host_memory_size_) {
327  if (host_memory_ != nullptr) {
328  Kokkos::kokkos_free<memory_space> (host_memory_);
329  }
330  host_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
331  host_memory_size_ = req_size;
332  }
333  if (! created_finalize_hook) {
334  Kokkos::push_finalize_hook (finalize_host_memory);
335  created_finalize_hook = true;
336  }
337 
338  return host_memory_;
339 }
340 
341 } // namespace Impl
342 } // namespace Details
343 } // namespace Tpetra