Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
44 namespace Tpetra {
45 namespace Details {
46 namespace Impl {
47 
48 namespace { // (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)
54 constexpr 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 
62 void* cuda_memory_ = nullptr;
63 size_t cuda_memory_size_ = 0;
64 
65 void 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 
74 void* cuda_uvm_memory_ = nullptr;
75 size_t cuda_uvm_memory_size_ = 0;
76 
77 void 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 
86 void* cuda_host_pinned_memory_ = nullptr;
87 size_t cuda_host_pinned_memory_size_ = 0;
88 
89 void 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 void* host_memory_ = nullptr;
100 size_t host_memory_size_ = 0;
101 
102 void finalize_host_memory ()
103 {
104  if (host_memory_ != nullptr) {
105  Kokkos::kokkos_free<Kokkos::HostSpace> (host_memory_);
106  host_memory_ = nullptr;
107  host_memory_size_ = 0;
108  }
109 }
110 
111 } // namespace (anonymous)
112 
113 #ifdef KOKKOS_ENABLE_CUDA
114 
115 void*
116 StaticKokkosAllocation<Kokkos::CudaSpace>::
117 resize (Kokkos::CudaSpace /* space */,
118  const size_t size)
119 {
120  using memory_space = Kokkos::CudaSpace;
121  static bool created_finalize_hook = false;
122 
123  if (size > cuda_memory_size_) {
124  if (cuda_memory_ != nullptr) {
125  Kokkos::kokkos_free<memory_space> (cuda_memory_);
126  }
127  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
128  cuda_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
129  cuda_memory_size_ = size;
130  }
131  if (! created_finalize_hook) {
132  Kokkos::push_finalize_hook (finalize_cuda_memory);
133  created_finalize_hook = true;
134  }
135 
136  return cuda_memory_;
137 }
138 
139 void*
140 StaticKokkosAllocation<Kokkos::CudaUVMSpace>::
141 resize (Kokkos::CudaUVMSpace /* space */,
142  const size_t size)
143 {
144  using memory_space = Kokkos::CudaUVMSpace;
145  static bool created_finalize_hook = false;
146 
147  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
148  if (req_size > cuda_uvm_memory_size_) {
149  if (cuda_uvm_memory_ != nullptr) {
150  Kokkos::kokkos_free<memory_space> (cuda_uvm_memory_);
151  }
152  cuda_uvm_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
153  cuda_uvm_memory_size_ = req_size;
154  }
155  if (! created_finalize_hook) {
156  Kokkos::push_finalize_hook (finalize_cuda_uvm_memory);
157  created_finalize_hook = true;
158  }
159 
160  return cuda_uvm_memory_;
161 }
162 
163 void*
164 StaticKokkosAllocation<Kokkos::CudaHostPinnedSpace>::
165 resize (Kokkos::CudaHostPinnedSpace /* space */,
166  const size_t size)
167 {
168  using memory_space = Kokkos::CudaHostPinnedSpace;
169  static bool created_finalize_hook = false;
170 
171  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
172  if (req_size > cuda_host_pinned_memory_size_) {
173  if (cuda_host_pinned_memory_ != nullptr) {
174  Kokkos::kokkos_free<memory_space> (cuda_host_pinned_memory_);
175  }
176  cuda_host_pinned_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
177  cuda_host_pinned_memory_size_ = req_size;
178  }
179  if (! created_finalize_hook) {
180  Kokkos::push_finalize_hook (finalize_cuda_host_pinned_memory);
181  created_finalize_hook = true;
182  }
183 
184  return cuda_host_pinned_memory_;
185 }
186 
187 #endif // KOKKOS_ENABLE_CUDA
188 
189 void*
190 StaticKokkosAllocation<Kokkos::HostSpace>::
191 resize (Kokkos::HostSpace /* space */,
192  const size_t size)
193 {
194  using memory_space = Kokkos::HostSpace;
195  static bool created_finalize_hook = false;
196 
197  const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size;
198  if (req_size > host_memory_size_) {
199  if (host_memory_ != nullptr) {
200  Kokkos::kokkos_free<memory_space> (host_memory_);
201  }
202  host_memory_ = Kokkos::kokkos_malloc<memory_space> (req_size);
203  host_memory_size_ = req_size;
204  }
205  if (! created_finalize_hook) {
206  Kokkos::push_finalize_hook (finalize_host_memory);
207  created_finalize_hook = true;
208  }
209 
210  return host_memory_;
211 }
212 
213 } // namespace Impl
214 } // namespace Details
215 } // namespace Tpetra