Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Details_Random.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_Random.hpp"
43 #include "Teuchos_TestForException.hpp"
44 
45 namespace Tpetra {
46 namespace Details {
47 
48 namespace { // (anonymous)
49 
50 unsigned int getSeedFromRank(int mpi_rank) {
51  // Seed the pseudorandom number generator using the calling
52  // process' rank. This helps decorrelate different process'
53  // pseudorandom streams. It's not perfect but it's effective and
54  // doesn't require MPI communication. The seed also includes bits
55  // from the standard library's rand().
56  uint64_t myRank =static_cast<uint64_t>(mpi_rank);
57  uint64_t seed64 = static_cast<uint64_t> (std::rand ()) + myRank + 17311uLL;
58  unsigned int seed = static_cast<unsigned int> (seed64&0xffffffff);
59  return seed;
60 }
61 
62 #ifdef KOKKOS_ENABLE_CUDA
63 Kokkos::Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space> * cuda_pool_=nullptr;
64 
65 void finalize_cuda_pool() {
66  if(cuda_pool_ != nullptr) {
67  delete cuda_pool_;
68  cuda_pool_ = nullptr;
69  }
70 }
71 #endif // KOKKOS_ENABLE_CUDA
72 
73 
74 #ifdef KOKKOS_ENABLE_HIP
75 Kokkos::Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space> * hip_pool_=nullptr;
76 
77 void finalize_hip_pool() {
78  if(hip_pool_ != nullptr) {
79  delete hip_pool_;
80  hip_pool_ = nullptr;
81  }
82 }
83 #endif // KOKKOS_ENABLE_HIP
84 
85 #ifdef KOKKOS_ENABLE_SYCL
86 Kokkos::Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space> * sycl_pool_=nullptr;
87 
88 void finalize_sycl_pool() {
89  if(sycl_pool_ != nullptr) {
90  delete sycl_pool_;
91  sycl_pool_ = nullptr;
92  }
93 }
94 #endif // KOKKOS_ENABLE_SYCL
95 
96 
97 #ifdef KOKKOS_ENABLE_OPENMP
98 Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP> * openmp_pool_=nullptr;
99 
100 void finalize_openmp_pool() {
101  if(openmp_pool_ != nullptr) {
102  delete openmp_pool_;
103  openmp_pool_ = nullptr;
104  }
105 }
106 #endif // KOKKOS_ENABLE_OPENMP
107 
108 
109 #ifdef KOKKOS_ENABLE_SERIAL
110 Kokkos::Random_XorShift64_Pool<Kokkos::Serial> * serial_pool_=nullptr;
111 
112 void finalize_serial_pool() {
113  if(serial_pool_ != nullptr) {
114  delete serial_pool_;
115  serial_pool_ = nullptr;
116  }
117 }
118 #endif // KOKKOS_ENABLE_SERIAL
119 
120 } // namespace (anonymous)
121 
122 
123 /********************************************************************************/
124 #ifdef KOKKOS_ENABLE_CUDA
125 void
126 Static_Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>::
127 resetPool(int mpi_rank) {
128  using pool_type = Kokkos::Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>;
129 
130  if(isSet())
131  delete cuda_pool_;
132  else
133  Kokkos::push_finalize_hook(finalize_cuda_pool);
134 
135  cuda_pool_ = new pool_type(getSeedFromRank(mpi_rank));
136 }
137 
138 bool
139 Static_Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>::
140 isSet() {
141  return cuda_pool_!=nullptr;
142 }
143 
144 Kokkos::Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space> &
145 Static_Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>::
146 getPool() {
147  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
148  return *cuda_pool_;
149 }
150 #endif // KOKKOS_ENABLE_CUDA
151 
152 
153 /********************************************************************************/
154 #ifdef KOKKOS_ENABLE_HIP
155 void
156 Static_Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>::
157 resetPool(int mpi_rank) {
158  using pool_type = Kokkos::Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>;
159 
160  if(isSet())
161  delete hip_pool_;
162  else
163  Kokkos::push_finalize_hook(finalize_hip_pool);
164 
165  hip_pool_ = new pool_type(getSeedFromRank(mpi_rank));
166 }
167 
168 bool
169 Static_Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>::
170 isSet() {
171  return hip_pool_!=nullptr;
172 }
173 
174 Kokkos::Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space> &
175 Static_Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>::
176 getPool() {
177  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
178  return *hip_pool_;
179 }
180 #endif // KOKKOS_ENABLE_HIP
181 
182 
183 /********************************************************************************/
184 #ifdef KOKKOS_ENABLE_SYCL
185 void
186 Static_Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>::
187 resetPool(int mpi_rank) {
188  using pool_type = Kokkos::Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>;
189 
190  if(isSet())
191  delete sycl_pool_;
192  else
193  Kokkos::push_finalize_hook(finalize_sycl_pool);
194 
195  sycl_pool_ = new pool_type(getSeedFromRank(mpi_rank));
196 }
197 
198 bool
199 Static_Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>::
200 isSet() {
201  return sycl_pool_!=nullptr;
202 }
203 
204 Kokkos::Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space> &
205 Static_Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>::
206 getPool() {
207  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
208  return *sycl_pool_;
209 }
210 #endif // KOKKOS_ENABLE_SYCL
211 
212 
213 /********************************************************************************/
214 #ifdef KOKKOS_ENABLE_OPENMP
215 void
216 Static_Random_XorShift64_Pool<Kokkos::OpenMP>::
217 resetPool(int mpi_rank) {
218  using pool_type = Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP>;
219 
220  if(isSet())
221  delete openmp_pool_;
222  else
223  Kokkos::push_finalize_hook(finalize_openmp_pool);
224 
225  openmp_pool_ = new pool_type(getSeedFromRank(mpi_rank));
226 }
227 
228 bool
229 Static_Random_XorShift64_Pool<Kokkos::OpenMP>::
230 isSet() {
231  return openmp_pool_!=nullptr;
232 }
233 
234 Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP> &
235 Static_Random_XorShift64_Pool<Kokkos::OpenMP>::
236 getPool() {
237  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
238  return *openmp_pool_;
239 }
240 #endif // KOKKOS_ENABLE_OPENMP
241 
242 
243 /********************************************************************************/
244 #ifdef KOKKOS_ENABLE_SERIAL
245 void
246 Static_Random_XorShift64_Pool<Kokkos::Serial>::
247 resetPool(int mpi_rank) {
248  using pool_type = Kokkos::Random_XorShift64_Pool<Kokkos::Serial>;
249 
250  if(isSet())
251  delete serial_pool_;
252  else
253  Kokkos::push_finalize_hook(finalize_serial_pool);
254 
255  serial_pool_ = new pool_type(getSeedFromRank(mpi_rank));
256 }
257 
258 bool
259 Static_Random_XorShift64_Pool<Kokkos::Serial>::
260 isSet() {
261  return serial_pool_!=nullptr;
262 }
263 
264 Kokkos::Random_XorShift64_Pool<Kokkos::Serial> &
265 Static_Random_XorShift64_Pool<Kokkos::Serial>::
266 getPool() {
267  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
268  return *serial_pool_;
269 }
270 #endif // KOKKOS_ENABLE_SERIAL
271 
272 
273 } // namespace Details
274 } // namespace Tpetra