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 // 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_Random.hpp"
11 #include "Teuchos_TestForException.hpp"
12 
13 namespace Tpetra {
14 namespace Details {
15 
16 namespace { // (anonymous)
17 
18 unsigned int getSeedFromRank(int mpi_rank) {
19  // Seed the pseudorandom number generator using the calling
20  // process' rank. This helps decorrelate different process'
21  // pseudorandom streams. It's not perfect but it's effective and
22  // doesn't require MPI communication. The seed also includes bits
23  // from the standard library's rand().
24  uint64_t myRank =static_cast<uint64_t>(mpi_rank);
25  uint64_t seed64 = static_cast<uint64_t> (std::rand ()) + myRank + 17311uLL;
26  unsigned int seed = static_cast<unsigned int> (seed64&0xffffffff);
27  return seed;
28 }
29 
30 #ifdef KOKKOS_ENABLE_CUDA
31 Kokkos::Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space> * cuda_pool_=nullptr;
32 
33 void finalize_cuda_pool() {
34  if(cuda_pool_ != nullptr) {
35  delete cuda_pool_;
36  cuda_pool_ = nullptr;
37  }
38 }
39 #endif // KOKKOS_ENABLE_CUDA
40 
41 
42 #ifdef KOKKOS_ENABLE_HIP
43 Kokkos::Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space> * hip_pool_=nullptr;
44 
45 void finalize_hip_pool() {
46  if(hip_pool_ != nullptr) {
47  delete hip_pool_;
48  hip_pool_ = nullptr;
49  }
50 }
51 #endif // KOKKOS_ENABLE_HIP
52 
53 #ifdef KOKKOS_ENABLE_SYCL
54 Kokkos::Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space> * sycl_pool_=nullptr;
55 
56 void finalize_sycl_pool() {
57  if(sycl_pool_ != nullptr) {
58  delete sycl_pool_;
59  sycl_pool_ = nullptr;
60  }
61 }
62 #endif // KOKKOS_ENABLE_SYCL
63 
64 
65 #ifdef KOKKOS_ENABLE_OPENMP
66 Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP> * openmp_pool_=nullptr;
67 
68 void finalize_openmp_pool() {
69  if(openmp_pool_ != nullptr) {
70  delete openmp_pool_;
71  openmp_pool_ = nullptr;
72  }
73 }
74 #endif // KOKKOS_ENABLE_OPENMP
75 
76 
77 #ifdef KOKKOS_ENABLE_SERIAL
78 Kokkos::Random_XorShift64_Pool<Kokkos::Serial> * serial_pool_=nullptr;
79 
80 void finalize_serial_pool() {
81  if(serial_pool_ != nullptr) {
82  delete serial_pool_;
83  serial_pool_ = nullptr;
84  }
85 }
86 #endif // KOKKOS_ENABLE_SERIAL
87 
88 } // namespace (anonymous)
89 
90 
91 /********************************************************************************/
92 #ifdef KOKKOS_ENABLE_CUDA
93 void
94 Static_Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>::
95 resetPool(int mpi_rank) {
96  using pool_type = Kokkos::Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>;
97 
98  if(isSet())
99  delete cuda_pool_;
100  else
101  Kokkos::push_finalize_hook(finalize_cuda_pool);
102 
103  cuda_pool_ = new pool_type(getSeedFromRank(mpi_rank));
104 }
105 
106 bool
107 Static_Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>::
108 isSet() {
109  return cuda_pool_!=nullptr;
110 }
111 
112 Kokkos::Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space> &
113 Static_Random_XorShift64_Pool<typename Kokkos::CudaSpace::execution_space>::
114 getPool() {
115  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
116  return *cuda_pool_;
117 }
118 #endif // KOKKOS_ENABLE_CUDA
119 
120 
121 /********************************************************************************/
122 #ifdef KOKKOS_ENABLE_HIP
123 void
124 Static_Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>::
125 resetPool(int mpi_rank) {
126  using pool_type = Kokkos::Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>;
127 
128  if(isSet())
129  delete hip_pool_;
130  else
131  Kokkos::push_finalize_hook(finalize_hip_pool);
132 
133  hip_pool_ = new pool_type(getSeedFromRank(mpi_rank));
134 }
135 
136 bool
137 Static_Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>::
138 isSet() {
139  return hip_pool_!=nullptr;
140 }
141 
142 Kokkos::Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space> &
143 Static_Random_XorShift64_Pool<typename Kokkos::HIPSpace::execution_space>::
144 getPool() {
145  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
146  return *hip_pool_;
147 }
148 #endif // KOKKOS_ENABLE_HIP
149 
150 
151 /********************************************************************************/
152 #ifdef KOKKOS_ENABLE_SYCL
153 void
154 Static_Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>::
155 resetPool(int mpi_rank) {
156  using pool_type = Kokkos::Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>;
157 
158  if(isSet())
159  delete sycl_pool_;
160  else
161  Kokkos::push_finalize_hook(finalize_sycl_pool);
162 
163  sycl_pool_ = new pool_type(getSeedFromRank(mpi_rank));
164 }
165 
166 bool
167 Static_Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>::
168 isSet() {
169  return sycl_pool_!=nullptr;
170 }
171 
172 Kokkos::Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space> &
173 Static_Random_XorShift64_Pool<typename Kokkos::Experimental::SYCLDeviceUSMSpace::execution_space>::
174 getPool() {
175  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
176  return *sycl_pool_;
177 }
178 #endif // KOKKOS_ENABLE_SYCL
179 
180 
181 /********************************************************************************/
182 #ifdef KOKKOS_ENABLE_OPENMP
183 void
184 Static_Random_XorShift64_Pool<Kokkos::OpenMP>::
185 resetPool(int mpi_rank) {
186  using pool_type = Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP>;
187 
188  if(isSet())
189  delete openmp_pool_;
190  else
191  Kokkos::push_finalize_hook(finalize_openmp_pool);
192 
193  openmp_pool_ = new pool_type(getSeedFromRank(mpi_rank));
194 }
195 
196 bool
197 Static_Random_XorShift64_Pool<Kokkos::OpenMP>::
198 isSet() {
199  return openmp_pool_!=nullptr;
200 }
201 
202 Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP> &
203 Static_Random_XorShift64_Pool<Kokkos::OpenMP>::
204 getPool() {
205  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
206  return *openmp_pool_;
207 }
208 #endif // KOKKOS_ENABLE_OPENMP
209 
210 
211 /********************************************************************************/
212 #ifdef KOKKOS_ENABLE_SERIAL
213 void
214 Static_Random_XorShift64_Pool<Kokkos::Serial>::
215 resetPool(int mpi_rank) {
216  using pool_type = Kokkos::Random_XorShift64_Pool<Kokkos::Serial>;
217 
218  if(isSet())
219  delete serial_pool_;
220  else
221  Kokkos::push_finalize_hook(finalize_serial_pool);
222 
223  serial_pool_ = new pool_type(getSeedFromRank(mpi_rank));
224 }
225 
226 bool
227 Static_Random_XorShift64_Pool<Kokkos::Serial>::
228 isSet() {
229  return serial_pool_!=nullptr;
230 }
231 
232 Kokkos::Random_XorShift64_Pool<Kokkos::Serial> &
233 Static_Random_XorShift64_Pool<Kokkos::Serial>::
234 getPool() {
235  TEUCHOS_TEST_FOR_EXCEPTION(!isSet(),std::runtime_error,"Tpetra::Details::Static_Random_XorShift64_Pool: resetPool() must be called before getPool");
236  return *serial_pool_;
237 }
238 #endif // KOKKOS_ENABLE_SERIAL
239 
240 
241 } // namespace Details
242 } // namespace Tpetra