Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Details_StaticView.cpp
1// @HEADER
2// ***********************************************************************
3//
4// Tpetra: Templated Linear Algebra Services Package
5// Copyright (2008) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ************************************************************************
40// @HEADER
41
42#include "Tpetra_Details_StaticView.hpp"
43
44namespace Tpetra {
45namespace Details {
46namespace Impl {
47
48namespace { // (anonymous)
49
50// Motivating use cases for the initial size:
51//
52// 1. GMRES (need restart length (default 30) number of rows)
53// 2. Single reduce CG (need 2 x 2)
54constexpr size_t minimum_initial_size = sizeof (double) * 30 * 2;
55
56// Intel 17 seems a bit buggy with respect to initialization of
57// templated static classes, so let's make the compiler's job really
58// easy by having nontemplated static raw pointers.
59
60#ifdef KOKKOS_ENABLE_CUDA
61
62void* cuda_memory_ = nullptr;
63size_t cuda_memory_size_ = 0;
64
65void finalize_cuda_memory ()
66{
67 if (cuda_memory_ != nullptr) {
68 Kokkos::kokkos_free<Kokkos::CudaSpace> (cuda_memory_);
69 cuda_memory_ = nullptr;
70 cuda_memory_size_ = 0;
71 }
72}
73
74void* cuda_uvm_memory_ = nullptr;
75size_t cuda_uvm_memory_size_ = 0;
76
77void finalize_cuda_uvm_memory ()
78{
79 if (cuda_uvm_memory_ != nullptr) {
80 Kokkos::kokkos_free<Kokkos::CudaUVMSpace> (cuda_uvm_memory_);
81 cuda_uvm_memory_ = nullptr;
82 cuda_uvm_memory_size_ = 0;
83 }
84}
85
86void* cuda_host_pinned_memory_ = nullptr;
87size_t cuda_host_pinned_memory_size_ = 0;
88
89void finalize_cuda_host_pinned_memory ()
90{
91 if (cuda_host_pinned_memory_ != nullptr) {
92 Kokkos::kokkos_free<Kokkos::CudaHostPinnedSpace> (cuda_host_pinned_memory_);
93 cuda_host_pinned_memory_ = nullptr;
94 cuda_host_pinned_memory_size_ = 0;
95 }
96}
97#endif // KOKKOS_ENABLE_CUDA
98
99#ifdef KOKKOS_ENABLE_HIP
100
101void* hip_memory_ = nullptr;
102size_t hip_memory_size_ = 0;
103
104void finalize_hip_memory ()
105{
106 if (hip_memory_ != nullptr) {
107 Kokkos::kokkos_free<Kokkos::Experimental::HIPSpace> (hip_memory_);
108 hip_memory_ = nullptr;
109 hip_memory_size_ = 0;
110 }
111}
112
113void* hip_host_pinned_memory_ = nullptr;
114size_t hip_host_pinned_memory_size_ = 0;
115
116void finalize_hip_host_pinned_memory ()
117{
118 if (hip_host_pinned_memory_ != nullptr) {
119 Kokkos::kokkos_free<Kokkos::Experimental::HIPHostPinnedSpace> (hip_host_pinned_memory_);
120 hip_host_pinned_memory_ = nullptr;
121 hip_host_pinned_memory_size_ = 0;
122 }
123}
124#endif // KOKKOS_ENABLE_HIP
125
126#ifdef KOKKOS_ENABLE_SYCL
127
128void* sycl_memory_ = nullptr;
129size_t sycl_memory_size_ = 0;
130
131void finalize_sycl_memory ()
132{
133 if (sycl_memory_ != nullptr) {
134 Kokkos::kokkos_free<Kokkos::Experimental::SYCLDeviceUSMSpace> (sycl_memory_);
135 sycl_memory_ = nullptr;
136 sycl_memory_size_ = 0;
137 }
138}
139
140void* sycl_shared_memory_ = nullptr;
141size_t sycl_shared_memory_size_ = 0;
142
143void finalize_sycl_shared_memory ()
144{
145 if (sycl_shared_memory_ != nullptr) {
146 Kokkos::kokkos_free<Kokkos::Experimental::SYCLSharedUSMSpace> (sycl_shared_memory_);
147 sycl_shared_memory_ = nullptr;
148 sycl_shared_memory_size_ = 0;
149 }
150}
151#endif // KOKKOS_ENABLE_SYCL
152
153void* host_memory_ = nullptr;
154size_t host_memory_size_ = 0;
155
156void finalize_host_memory ()
157{
158 if (host_memory_ != nullptr) {
159 Kokkos::kokkos_free<Kokkos::HostSpace> (host_memory_);
160 host_memory_ = nullptr;
161 host_memory_size_ = 0;
162 }
163}
164
165} // namespace (anonymous)
166
167#ifdef KOKKOS_ENABLE_CUDA
168
169void*
170StaticKokkosAllocation<Kokkos::CudaSpace>::
171resize (Kokkos::CudaSpace /* space */,
172 const size_t size)
173{
174 using memory_space = Kokkos::CudaSpace;
175 static bool created_finalize_hook = false;
176
177 if (size > cuda_memory_size_) {
178 if (cuda_memory_ != nullptr) {
179 Kokkos::kokkos_free<memory_space> (cuda_memory_);
180 }
181 const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
182 cuda_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
183 cuda_memory_size_ = size;
184 }
185 if (! created_finalize_hook) {
186 Kokkos::push_finalize_hook (finalize_cuda_memory);
187 created_finalize_hook = true;
188 }
189
190 return cuda_memory_;
191}
192
193void*
194StaticKokkosAllocation<Kokkos::CudaUVMSpace>::
195resize (Kokkos::CudaUVMSpace /* space */,
196 const size_t size)
197{
198 using memory_space = Kokkos::CudaUVMSpace;
199 static bool created_finalize_hook = false;
200
201 const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
202 if (req_size > cuda_uvm_memory_size_) {
203 if (cuda_uvm_memory_ != nullptr) {
204 Kokkos::kokkos_free<memory_space> (cuda_uvm_memory_);
205 }
206 cuda_uvm_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
207 cuda_uvm_memory_size_ = req_size;
208 }
209 if (! created_finalize_hook) {
210 Kokkos::push_finalize_hook (finalize_cuda_uvm_memory);
211 created_finalize_hook = true;
212 }
213
214 return cuda_uvm_memory_;
215}
216
217void*
218StaticKokkosAllocation<Kokkos::CudaHostPinnedSpace>::
219resize (Kokkos::CudaHostPinnedSpace /* space */,
220 const size_t size)
221{
222 using memory_space = Kokkos::CudaHostPinnedSpace;
223 static bool created_finalize_hook = false;
224
225 const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
226 if (req_size > cuda_host_pinned_memory_size_) {
227 if (cuda_host_pinned_memory_ != nullptr) {
228 Kokkos::kokkos_free<memory_space> (cuda_host_pinned_memory_);
229 }
230 cuda_host_pinned_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
231 cuda_host_pinned_memory_size_ = req_size;
232 }
233 if (! created_finalize_hook) {
234 Kokkos::push_finalize_hook (finalize_cuda_host_pinned_memory);
235 created_finalize_hook = true;
236 }
237
238 return cuda_host_pinned_memory_;
239}
240
241#endif // KOKKOS_ENABLE_CUDA
242
243#ifdef KOKKOS_ENABLE_HIP
244
245void*
246StaticKokkosAllocation<Kokkos::Experimental::HIPSpace>::
247resize (Kokkos::Experimental::HIPSpace /* space */,
248 const size_t size)
249{
250 using memory_space = Kokkos::Experimental::HIPSpace;
251 static bool created_finalize_hook = false;
252
253 if (size > hip_memory_size_) {
254 if (hip_memory_ != nullptr) {
255 Kokkos::kokkos_free<memory_space> (hip_memory_);
256 }
257 const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
258 hip_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
259 hip_memory_size_ = size;
260 }
261 if (! created_finalize_hook) {
262 Kokkos::push_finalize_hook (finalize_hip_memory);
263 created_finalize_hook = true;
264 }
265
266 return hip_memory_;
267}
268
269void*
270StaticKokkosAllocation<Kokkos::Experimental::HIPHostPinnedSpace>::
271resize (Kokkos::Experimental::HIPHostPinnedSpace /* space */,
272 const size_t size)
273{
274 using memory_space = Kokkos::Experimental::HIPHostPinnedSpace;
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 > hip_host_pinned_memory_size_) {
279 if (hip_host_pinned_memory_ != nullptr) {
280 Kokkos::kokkos_free<memory_space> (hip_host_pinned_memory_);
281 }
282 hip_host_pinned_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
283 hip_host_pinned_memory_size_ = req_size;
284 }
285 if (! created_finalize_hook) {
286 Kokkos::push_finalize_hook (finalize_hip_host_pinned_memory);
287 created_finalize_hook = true;
288 }
289
290 return hip_host_pinned_memory_;
291}
292
293#endif // KOKKOS_ENABLE_HIP
294
295#ifdef KOKKOS_ENABLE_SYCL
296
297template <>
298void*
299StaticKokkosAllocation<Kokkos::Experimental::SYCLDeviceUSMSpace>::
300resize (Kokkos::Experimental::SYCLDeviceUSMSpace /* space */,
301 const size_t size)
302{
303 using memory_space = Kokkos::Experimental::SYCLDeviceUSMSpace;
304 static bool created_finalize_hook = false;
305
306 if (size > sycl_memory_size_) {
307 if (sycl_memory_ != nullptr) {
308 Kokkos::kokkos_free<memory_space> (sycl_memory_);
309 }
310 const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
311 sycl_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
312 sycl_memory_size_ = size;
313 }
314 if (! created_finalize_hook) {
315 Kokkos::push_finalize_hook (finalize_sycl_memory);
316 created_finalize_hook = true;
317 }
318
319 return sycl_memory_;
320}
321
322template <>
323void*
324StaticKokkosAllocation<Kokkos::Experimental::SYCLSharedUSMSpace>::
325resize (Kokkos::Experimental::SYCLSharedUSMSpace /* space */,
326 const size_t size)
327{
328 using memory_space = Kokkos::Experimental::SYCLSharedUSMSpace;
329 static bool created_finalize_hook = false;
330
331 const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
332 if (req_size > sycl_shared_memory_size_) {
333 if (sycl_shared_memory_ != nullptr) {
334 Kokkos::kokkos_free<memory_space> (sycl_shared_memory_);
335 }
336 sycl_shared_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
337 sycl_shared_memory_size_ = req_size;
338 }
339 if (! created_finalize_hook) {
340 Kokkos::push_finalize_hook (finalize_sycl_shared_memory);
341 created_finalize_hook = true;
342 }
343
344 return sycl_shared_memory_;
345}
346
347#endif // KOKKOS_ENABLE_SYCL
348
349void*
350StaticKokkosAllocation<Kokkos::HostSpace>::
351resize (Kokkos::HostSpace /* space */,
352 const size_t size)
353{
354 using memory_space = Kokkos::HostSpace;
355 static bool created_finalize_hook = false;
356
357 const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
358 if (req_size > host_memory_size_) {
359 if (host_memory_ != nullptr) {
360 Kokkos::kokkos_free<memory_space> (host_memory_);
361 }
362 host_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
363 host_memory_size_ = req_size;
364 }
365 if (! created_finalize_hook) {
366 Kokkos::push_finalize_hook (finalize_host_memory);
367 created_finalize_hook = true;
368 }
369
370 return host_memory_;
371}
372
373} // namespace Impl
374} // namespace Details
375} // namespace Tpetra
Implementation details of Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.