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  if (cuda_memory_ != nullptr) {
35  Kokkos::kokkos_free<Kokkos::CudaSpace>(cuda_memory_);
36  cuda_memory_ = nullptr;
37  cuda_memory_size_ = 0;
38  }
39 }
40 
41 void* cuda_uvm_memory_ = nullptr;
42 size_t cuda_uvm_memory_size_ = 0;
43 
44 void finalize_cuda_uvm_memory() {
45  if (cuda_uvm_memory_ != nullptr) {
46  Kokkos::kokkos_free<Kokkos::CudaUVMSpace>(cuda_uvm_memory_);
47  cuda_uvm_memory_ = nullptr;
48  cuda_uvm_memory_size_ = 0;
49  }
50 }
51 
52 void* cuda_host_pinned_memory_ = nullptr;
53 size_t cuda_host_pinned_memory_size_ = 0;
54 
55 void finalize_cuda_host_pinned_memory() {
56  if (cuda_host_pinned_memory_ != nullptr) {
57  Kokkos::kokkos_free<Kokkos::CudaHostPinnedSpace>(cuda_host_pinned_memory_);
58  cuda_host_pinned_memory_ = nullptr;
59  cuda_host_pinned_memory_size_ = 0;
60  }
61 }
62 #endif // KOKKOS_ENABLE_CUDA
63 
64 #ifdef KOKKOS_ENABLE_HIP
65 
66 void* hip_memory_ = nullptr;
67 size_t hip_memory_size_ = 0;
68 
69 void finalize_hip_memory() {
70  if (hip_memory_ != nullptr) {
71  Kokkos::kokkos_free<Kokkos::HIPSpace>(hip_memory_);
72  hip_memory_ = nullptr;
73  hip_memory_size_ = 0;
74  }
75 }
76 
77 void* hip_host_pinned_memory_ = nullptr;
78 size_t hip_host_pinned_memory_size_ = 0;
79 
80 void finalize_hip_host_pinned_memory() {
81  if (hip_host_pinned_memory_ != nullptr) {
82  Kokkos::kokkos_free<Kokkos::HIPHostPinnedSpace>(hip_host_pinned_memory_);
83  hip_host_pinned_memory_ = nullptr;
84  hip_host_pinned_memory_size_ = 0;
85  }
86 }
87 #endif // KOKKOS_ENABLE_HIP
88 
89 #ifdef KOKKOS_ENABLE_SYCL
90 
91 void* sycl_memory_ = nullptr;
92 size_t sycl_memory_size_ = 0;
93 
94 void finalize_sycl_memory() {
95  if (sycl_memory_ != nullptr) {
96  Kokkos::kokkos_free<Kokkos::Experimental::SYCLDeviceUSMSpace>(sycl_memory_);
97  sycl_memory_ = nullptr;
98  sycl_memory_size_ = 0;
99  }
100 }
101 
102 void* sycl_shared_memory_ = nullptr;
103 size_t sycl_shared_memory_size_ = 0;
104 
105 void finalize_sycl_shared_memory() {
106  if (sycl_shared_memory_ != nullptr) {
107  Kokkos::kokkos_free<Kokkos::Experimental::SYCLSharedUSMSpace>(sycl_shared_memory_);
108  sycl_shared_memory_ = nullptr;
109  sycl_shared_memory_size_ = 0;
110  }
111 }
112 #endif // KOKKOS_ENABLE_SYCL
113 
114 void* host_memory_ = nullptr;
115 size_t host_memory_size_ = 0;
116 
117 void finalize_host_memory() {
118  if (host_memory_ != nullptr) {
119  Kokkos::kokkos_free<Kokkos::HostSpace>(host_memory_);
120  host_memory_ = nullptr;
121  host_memory_size_ = 0;
122  }
123 }
124 
125 } // namespace
126 
127 #ifdef KOKKOS_ENABLE_CUDA
128 
129 void* StaticKokkosAllocation<Kokkos::CudaSpace>::
130  resize(Kokkos::CudaSpace /* space */,
131  const size_t size) {
132  using memory_space = Kokkos::CudaSpace;
133  static bool created_finalize_hook = false;
134 
135  if (size > cuda_memory_size_) {
136  if (cuda_memory_ != nullptr) {
137  Kokkos::kokkos_free<memory_space>(cuda_memory_);
138  }
139  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
140  cuda_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
141  cuda_memory_size_ = size;
142  }
143  if (!created_finalize_hook) {
144  Kokkos::push_finalize_hook(finalize_cuda_memory);
145  created_finalize_hook = true;
146  }
147 
148  return cuda_memory_;
149 }
150 
151 void* StaticKokkosAllocation<Kokkos::CudaUVMSpace>::
152  resize(Kokkos::CudaUVMSpace /* space */,
153  const size_t size) {
154  using memory_space = Kokkos::CudaUVMSpace;
155  static bool created_finalize_hook = false;
156 
157  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
158  if (req_size > cuda_uvm_memory_size_) {
159  if (cuda_uvm_memory_ != nullptr) {
160  Kokkos::kokkos_free<memory_space>(cuda_uvm_memory_);
161  }
162  cuda_uvm_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
163  cuda_uvm_memory_size_ = req_size;
164  }
165  if (!created_finalize_hook) {
166  Kokkos::push_finalize_hook(finalize_cuda_uvm_memory);
167  created_finalize_hook = true;
168  }
169 
170  return cuda_uvm_memory_;
171 }
172 
173 void* StaticKokkosAllocation<Kokkos::CudaHostPinnedSpace>::
174  resize(Kokkos::CudaHostPinnedSpace /* space */,
175  const size_t size) {
176  using memory_space = Kokkos::CudaHostPinnedSpace;
177  static bool created_finalize_hook = false;
178 
179  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
180  if (req_size > cuda_host_pinned_memory_size_) {
181  if (cuda_host_pinned_memory_ != nullptr) {
182  Kokkos::kokkos_free<memory_space>(cuda_host_pinned_memory_);
183  }
184  cuda_host_pinned_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
185  cuda_host_pinned_memory_size_ = req_size;
186  }
187  if (!created_finalize_hook) {
188  Kokkos::push_finalize_hook(finalize_cuda_host_pinned_memory);
189  created_finalize_hook = true;
190  }
191 
192  return cuda_host_pinned_memory_;
193 }
194 
195 #endif // KOKKOS_ENABLE_CUDA
196 
197 #ifdef KOKKOS_ENABLE_HIP
198 
199 void* StaticKokkosAllocation<Kokkos::HIPSpace>::
200  resize(Kokkos::HIPSpace /* space */,
201  const size_t size) {
202  using memory_space = Kokkos::HIPSpace;
203  static bool created_finalize_hook = false;
204 
205  if (size > hip_memory_size_) {
206  if (hip_memory_ != nullptr) {
207  Kokkos::kokkos_free<memory_space>(hip_memory_);
208  }
209  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
210  hip_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
211  hip_memory_size_ = size;
212  }
213  if (!created_finalize_hook) {
214  Kokkos::push_finalize_hook(finalize_hip_memory);
215  created_finalize_hook = true;
216  }
217 
218  return hip_memory_;
219 }
220 
221 void* StaticKokkosAllocation<Kokkos::HIPHostPinnedSpace>::
222  resize(Kokkos::HIPHostPinnedSpace /* space */,
223  const size_t size) {
224  using memory_space = Kokkos::HIPHostPinnedSpace;
225  static bool created_finalize_hook = false;
226 
227  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
228  if (req_size > hip_host_pinned_memory_size_) {
229  if (hip_host_pinned_memory_ != nullptr) {
230  Kokkos::kokkos_free<memory_space>(hip_host_pinned_memory_);
231  }
232  hip_host_pinned_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
233  hip_host_pinned_memory_size_ = req_size;
234  }
235  if (!created_finalize_hook) {
236  Kokkos::push_finalize_hook(finalize_hip_host_pinned_memory);
237  created_finalize_hook = true;
238  }
239 
240  return hip_host_pinned_memory_;
241 }
242 
243 #endif // KOKKOS_ENABLE_HIP
244 
245 #ifdef KOKKOS_ENABLE_SYCL
246 
247 template <>
248 void* StaticKokkosAllocation<Kokkos::Experimental::SYCLDeviceUSMSpace>::
249  resize(Kokkos::Experimental::SYCLDeviceUSMSpace /* space */,
250  const size_t size) {
251  using memory_space = Kokkos::Experimental::SYCLDeviceUSMSpace;
252  static bool created_finalize_hook = false;
253 
254  if (size > sycl_memory_size_) {
255  if (sycl_memory_ != nullptr) {
256  Kokkos::kokkos_free<memory_space>(sycl_memory_);
257  }
258  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
259  sycl_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
260  sycl_memory_size_ = size;
261  }
262  if (!created_finalize_hook) {
263  Kokkos::push_finalize_hook(finalize_sycl_memory);
264  created_finalize_hook = true;
265  }
266 
267  return sycl_memory_;
268 }
269 
270 template <>
271 void* StaticKokkosAllocation<Kokkos::Experimental::SYCLSharedUSMSpace>::
272  resize(Kokkos::Experimental::SYCLSharedUSMSpace /* space */,
273  const size_t size) {
274  using memory_space = Kokkos::Experimental::SYCLSharedUSMSpace;
275  static bool created_finalize_hook = false;
276 
277  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
278  if (req_size > sycl_shared_memory_size_) {
279  if (sycl_shared_memory_ != nullptr) {
280  Kokkos::kokkos_free<memory_space>(sycl_shared_memory_);
281  }
282  sycl_shared_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
283  sycl_shared_memory_size_ = req_size;
284  }
285  if (!created_finalize_hook) {
286  Kokkos::push_finalize_hook(finalize_sycl_shared_memory);
287  created_finalize_hook = true;
288  }
289 
290  return sycl_shared_memory_;
291 }
292 
293 #endif // KOKKOS_ENABLE_SYCL
294 
295 void* StaticKokkosAllocation<Kokkos::HostSpace>::
296  resize(Kokkos::HostSpace /* space */,
297  const size_t size) {
298  using memory_space = Kokkos::HostSpace;
299  static bool created_finalize_hook = false;
300 
301  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
302  if (req_size > host_memory_size_) {
303  if (host_memory_ != nullptr) {
304  Kokkos::kokkos_free<memory_space>(host_memory_);
305  }
306  host_memory_ = Kokkos::kokkos_malloc<memory_space>(req_size);
307  host_memory_size_ = req_size;
308  }
309  if (!created_finalize_hook) {
310  Kokkos::push_finalize_hook(finalize_host_memory);
311  created_finalize_hook = true;
312  }
313 
314  return host_memory_;
315 }
316 
317 } // namespace Impl
318 } // namespace Details
319 } // namespace Tpetra