lammps-sys 0.6.0

Generates bindings to LAMMPS' C interface (with optional builds from source)
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
//@HEADER
// ************************************************************************
//
//                        Kokkos v. 2.0
//              Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER

#ifndef KOKKOS_TEST_DUALVIEW_HPP
#define KOKKOS_TEST_DUALVIEW_HPP

#include <gtest/gtest.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <impl/Kokkos_Timer.hpp>
#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include <cmath>
#include <chrono>

namespace Test {

namespace Impl{

// This test runs the random number generators and uses some statistic tests to
// check the 'goodness' of the random numbers:
//    (i)   mean:         the mean is expected to be 0.5*RAND_MAX
//    (ii)  variance:     the variance is 1/3*mean*mean
//    (iii) covariance:   the covariance is 0
//    (iv)  1-tupledistr: the mean, variance and covariance of a 1D Histrogram of random numbers
//    (v)   3-tupledistr: the mean, variance and covariance of a 3D Histrogram of random numbers

#define HIST_DIM3D 24
#define HIST_DIM1D (HIST_DIM3D*HIST_DIM3D*HIST_DIM3D)

struct RandomProperties {
  uint64_t count;
  double mean;
  double variance;
  double covariance;
  double min;
  double max;

  KOKKOS_INLINE_FUNCTION
  RandomProperties() {
    count = 0;
    mean = 0.0;
    variance = 0.0;
    covariance = 0.0;
    min = 1e64;
    max = -1e64;
  }

  KOKKOS_INLINE_FUNCTION
  RandomProperties& operator+=(const RandomProperties& add) {
    count      += add.count;
    mean       += add.mean;
    variance   += add.variance;
    covariance += add.covariance;
    min         = add.min<min?add.min:min;
    max         = add.max>max?add.max:max;
    return *this;
  }

  KOKKOS_INLINE_FUNCTION
  void operator+=(const volatile RandomProperties& add) volatile {
    count      += add.count;
    mean       += add.mean;
    variance   += add.variance;
    covariance += add.covariance;
    min         = add.min<min?add.min:min;
    max         = add.max>max?add.max:max;
  }
};

template<class GeneratorPool, class Scalar>
struct test_random_functor {
  typedef typename GeneratorPool::generator_type rnd_type;

  typedef RandomProperties value_type;
  typedef typename GeneratorPool::device_type device_type;

  GeneratorPool rand_pool;
  const double mean;

  // NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to define
  // an exclusive upper bound on the range of random numbers that
  // draw() can generate.  However, for the float specialization, some
  // implementations might violate this upper bound, due to rounding
  // error.  Just in case, we leave an extra space at the end of each
  // dimension, in the View types below.
  typedef Kokkos::View<int[HIST_DIM1D+1],typename GeneratorPool::device_type> type_1d;
  type_1d density_1d;
  typedef Kokkos::View<int[HIST_DIM3D+1][HIST_DIM3D+1][HIST_DIM3D+1],typename GeneratorPool::device_type> type_3d;
  type_3d density_3d;

  test_random_functor (GeneratorPool rand_pool_, type_1d d1d, type_3d d3d) :
    rand_pool (rand_pool_),
    mean (0.5*Kokkos::rand<rnd_type,Scalar>::max ()),
    density_1d (d1d),
    density_3d (d3d)
  {}

  KOKKOS_INLINE_FUNCTION
  void operator() (int i, RandomProperties& prop) const {
    using Kokkos::atomic_fetch_add;

    rnd_type rand_gen = rand_pool.get_state();
    for (int k = 0; k < 1024; ++k) {
      const Scalar tmp = Kokkos::rand<rnd_type,Scalar>::draw(rand_gen);
      prop.count++;
      prop.mean += tmp;
      prop.variance += (tmp-mean)*(tmp-mean);
      const Scalar tmp2 = Kokkos::rand<rnd_type,Scalar>::draw(rand_gen);
      prop.count++;
      prop.mean += tmp2;
      prop.variance += (tmp2-mean)*(tmp2-mean);
      prop.covariance += (tmp-mean)*(tmp2-mean);
      const Scalar tmp3 = Kokkos::rand<rnd_type,Scalar>::draw(rand_gen);
      prop.count++;
      prop.mean += tmp3;
      prop.variance += (tmp3-mean)*(tmp3-mean);
      prop.covariance += (tmp2-mean)*(tmp3-mean);

      // NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to
      // define an exclusive upper bound on the range of random
      // numbers that draw() can generate.  However, for the float
      // specialization, some implementations might violate this upper
      // bound, due to rounding error.  Just in case, we have left an
      // extra space at the end of each dimension of density_1d and
      // density_3d.
      //
      // Please note that those extra entries might not get counted in
      // the histograms.  However, if Kokkos::rand is broken and only
      // returns values of max(), the histograms will still catch this
      // indirectly, since none of the other values will be filled in.

      const Scalar theMax = Kokkos::rand<rnd_type, Scalar>::max ();

      const uint64_t ind1_1d = static_cast<uint64_t> (1.0 * HIST_DIM1D * tmp / theMax);
      const uint64_t ind2_1d = static_cast<uint64_t> (1.0 * HIST_DIM1D * tmp2 / theMax);
      const uint64_t ind3_1d = static_cast<uint64_t> (1.0 * HIST_DIM1D * tmp3 / theMax);

      const uint64_t ind1_3d = static_cast<uint64_t> (1.0 * HIST_DIM3D * tmp / theMax);
      const uint64_t ind2_3d = static_cast<uint64_t> (1.0 * HIST_DIM3D * tmp2 / theMax);
      const uint64_t ind3_3d = static_cast<uint64_t> (1.0 * HIST_DIM3D * tmp3 / theMax);

      atomic_fetch_add (&density_1d(ind1_1d), 1);
      atomic_fetch_add (&density_1d(ind2_1d), 1);
      atomic_fetch_add (&density_1d(ind3_1d), 1);
      atomic_fetch_add (&density_3d(ind1_3d, ind2_3d, ind3_3d), 1);
    }
    rand_pool.free_state(rand_gen);
  }
};

template<class DeviceType>
struct test_histogram1d_functor {
  typedef RandomProperties value_type;
  typedef typename DeviceType::execution_space execution_space;
  typedef typename DeviceType::memory_space memory_space;

  // NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to define
  // an exclusive upper bound on the range of random numbers that
  // draw() can generate.  However, for the float specialization, some
  // implementations might violate this upper bound, due to rounding
  // error.  Just in case, we leave an extra space at the end of each
  // dimension, in the View type below.
  typedef Kokkos::View<int[HIST_DIM1D+1], memory_space> type_1d;
  type_1d density_1d;
  double mean;

  test_histogram1d_functor (type_1d d1d, int num_draws) :
    density_1d (d1d),
    mean (1.0*num_draws/HIST_DIM1D*3)
  {
  }

  KOKKOS_INLINE_FUNCTION void
  operator() (const typename memory_space::size_type i,
              RandomProperties& prop) const
  {
    typedef typename memory_space::size_type size_type;
    const double count = density_1d(i);
    prop.mean += count;
    prop.variance += 1.0 * (count - mean) * (count - mean);
    //prop.covariance += 1.0*count*count;
    prop.min = count < prop.min ? count : prop.min;
    prop.max = count > prop.max ? count : prop.max;
    if (i < static_cast<size_type> (HIST_DIM1D-1)) {
      prop.covariance += (count - mean) * (density_1d(i+1) - mean);
    }
  }
};

template<class DeviceType>
struct test_histogram3d_functor {
  typedef RandomProperties value_type;
  typedef typename DeviceType::execution_space execution_space;
  typedef typename DeviceType::memory_space memory_space;

  // NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to define
  // an exclusive upper bound on the range of random numbers that
  // draw() can generate.  However, for the float specialization, some
  // implementations might violate this upper bound, due to rounding
  // error.  Just in case, we leave an extra space at the end of each
  // dimension, in the View type below.
  typedef Kokkos::View<int[HIST_DIM3D+1][HIST_DIM3D+1][HIST_DIM3D+1], memory_space> type_3d;
  type_3d density_3d;
  double mean;

  test_histogram3d_functor (type_3d d3d, int num_draws) :
    density_3d (d3d),
    mean (1.0*num_draws/HIST_DIM1D)
  {}

  KOKKOS_INLINE_FUNCTION void
  operator() (const typename memory_space::size_type i,
              RandomProperties& prop) const
  {
    typedef typename memory_space::size_type size_type;
    const double count = density_3d(i/(HIST_DIM3D*HIST_DIM3D),
                                    (i % (HIST_DIM3D*HIST_DIM3D))/HIST_DIM3D,
                                    i % HIST_DIM3D);
    prop.mean += count;
    prop.variance += (count - mean) * (count - mean);
    if (i < static_cast<size_type> (HIST_DIM1D-1)) {
      const double count_next = density_3d((i+1)/(HIST_DIM3D*HIST_DIM3D),
                                           ((i+1)%(HIST_DIM3D*HIST_DIM3D))/HIST_DIM3D,
                                           (i+1)%HIST_DIM3D);
      prop.covariance += (count - mean) * (count_next - mean);
    }
  }
};

//
// Templated test that uses the above functors.
//
template <class RandomGenerator,class Scalar>
struct test_random_scalar {
  typedef typename RandomGenerator::generator_type rnd_type;

  int pass_mean,pass_var,pass_covar;
  int pass_hist1d_mean,pass_hist1d_var,pass_hist1d_covar;
  int pass_hist3d_mean,pass_hist3d_var,pass_hist3d_covar;

  test_random_scalar (typename test_random_functor<RandomGenerator,int>::type_1d& density_1d,
                      typename test_random_functor<RandomGenerator,int>::type_3d& density_3d,
                      RandomGenerator& pool,
                      unsigned int num_draws)
  {
    using std::cout;
    using std::endl;
    using Kokkos::parallel_reduce;

    {
      cout << " -- Testing randomness properties" << endl;

      RandomProperties result;
      typedef test_random_functor<RandomGenerator, Scalar> functor_type;
      parallel_reduce (num_draws/1024, functor_type (pool, density_1d, density_3d), result);

      //printf("Result: %lf %lf %lf\n",result.mean/num_draws/3,result.variance/num_draws/3,result.covariance/num_draws/2);
      double tolerance = 1.6*std::sqrt(1.0/num_draws);
      double mean_expect = 0.5*Kokkos::rand<rnd_type,Scalar>::max();
      double variance_expect = 1.0/3.0*mean_expect*mean_expect;
      double mean_eps = mean_expect/(result.mean/num_draws/3)-1.0;
      double variance_eps = variance_expect/(result.variance/num_draws/3)-1.0;
      double covariance_eps = result.covariance/num_draws/2/variance_expect;
      pass_mean  = ((-tolerance < mean_eps) &&
                    ( tolerance > mean_eps)) ? 1:0;
      pass_var   = ((-1.5*tolerance < variance_eps) &&
                    ( 1.5*tolerance > variance_eps)) ? 1:0;
      pass_covar = ((-2.0*tolerance < covariance_eps) &&
                    ( 2.0*tolerance > covariance_eps)) ? 1:0;
      cout << "Pass: " << pass_mean
           << " " << pass_var
           << " " << mean_eps
           << " " << variance_eps
           << " " << covariance_eps
           << " || " << tolerance << endl;
    }
    {
      cout << " -- Testing 1-D histogram" << endl;

      RandomProperties result;
      typedef test_histogram1d_functor<typename RandomGenerator::device_type> functor_type;
      parallel_reduce (HIST_DIM1D, functor_type (density_1d, num_draws), result);

      double tolerance = 6*std::sqrt(1.0/HIST_DIM1D);
      double mean_expect = 1.0*num_draws*3/HIST_DIM1D;
      double variance_expect = 1.0*num_draws*3/HIST_DIM1D*(1.0-1.0/HIST_DIM1D);
      double covariance_expect = -1.0*num_draws*3/HIST_DIM1D/HIST_DIM1D;
      double mean_eps = mean_expect/(result.mean/HIST_DIM1D)-1.0;
      double variance_eps = variance_expect/(result.variance/HIST_DIM1D)-1.0;
      double covariance_eps = (result.covariance/HIST_DIM1D - covariance_expect)/mean_expect;
      pass_hist1d_mean  = ((-0.0001 < mean_eps) &&
                           ( 0.0001 > mean_eps)) ? 1:0;
      pass_hist1d_var   = ((-0.07 < variance_eps) &&
                           ( 0.07 > variance_eps)) ? 1:0;
      pass_hist1d_covar = ((-0.06 < covariance_eps) &&
                           ( 0.06 > covariance_eps)) ? 1:0;

      cout << "Density 1D: " << mean_eps
           << " " << variance_eps
           << " " << (result.covariance/HIST_DIM1D/HIST_DIM1D)
           << " || " << tolerance
           << " " << result.min
           << " " << result.max
           << " || " << result.variance/HIST_DIM1D
           << " " << 1.0*num_draws*3/HIST_DIM1D*(1.0-1.0/HIST_DIM1D)
           << " || " << result.covariance/HIST_DIM1D
           << " " << -1.0*num_draws*3/HIST_DIM1D/HIST_DIM1D
           << endl;
    }
    {
      cout << " -- Testing 3-D histogram" << endl;

      RandomProperties result;
      typedef test_histogram3d_functor<typename RandomGenerator::device_type> functor_type;
      parallel_reduce (HIST_DIM1D, functor_type (density_3d, num_draws), result);

      double tolerance = 6*std::sqrt(1.0/HIST_DIM1D);
      double mean_expect = 1.0*num_draws/HIST_DIM1D;
      double variance_expect = 1.0*num_draws/HIST_DIM1D*(1.0-1.0/HIST_DIM1D);
      double covariance_expect = -1.0*num_draws/HIST_DIM1D/HIST_DIM1D;
      double mean_eps = mean_expect/(result.mean/HIST_DIM1D)-1.0;
      double variance_eps = variance_expect/(result.variance/HIST_DIM1D)-1.0;
      double covariance_eps = (result.covariance/HIST_DIM1D - covariance_expect)/mean_expect;
      pass_hist3d_mean  = ((-tolerance < mean_eps) &&
                           ( tolerance > mean_eps)) ? 1:0;
      pass_hist3d_var   = ((-1.2*tolerance < variance_eps) &&
                           ( 1.2*tolerance > variance_eps)) ? 1:0;
      pass_hist3d_covar = ((-tolerance < covariance_eps) &&
                           ( tolerance > covariance_eps)) ? 1:0;

      cout << "Density 3D: " << mean_eps
           << " " << variance_eps
           << " " << result.covariance/HIST_DIM1D/HIST_DIM1D
           << " || " << tolerance
           << " " << result.min
           << " " << result.max << endl;
    }
  }
};

template <class RandomGenerator>
void test_random(unsigned int num_draws)
{
  using std::cout;
  using std::endl;
  typename test_random_functor<RandomGenerator,int>::type_1d density_1d("D1d");
  typename test_random_functor<RandomGenerator,int>::type_3d density_3d("D3d");


  uint64_t ticks = std::chrono::high_resolution_clock::now().time_since_epoch().count();
  cout << "Test Seed:" << ticks << endl;

  RandomGenerator pool(ticks);

  cout << "Test Scalar=int" << endl;
  test_random_scalar<RandomGenerator,int> test_int(density_1d,density_3d,pool,num_draws);
  ASSERT_EQ( test_int.pass_mean,1);
  ASSERT_EQ( test_int.pass_var,1);
  ASSERT_EQ( test_int.pass_covar,1);
  ASSERT_EQ( test_int.pass_hist1d_mean,1);
  ASSERT_EQ( test_int.pass_hist1d_var,1);
  ASSERT_EQ( test_int.pass_hist1d_covar,1);
  ASSERT_EQ( test_int.pass_hist3d_mean,1);
  ASSERT_EQ( test_int.pass_hist3d_var,1);
  ASSERT_EQ( test_int.pass_hist3d_covar,1);
  deep_copy(density_1d,0);
  deep_copy(density_3d,0);

  cout << "Test Scalar=unsigned int" << endl;
  test_random_scalar<RandomGenerator,unsigned int> test_uint(density_1d,density_3d,pool,num_draws);
  ASSERT_EQ( test_uint.pass_mean,1);
  ASSERT_EQ( test_uint.pass_var,1);
  ASSERT_EQ( test_uint.pass_covar,1);
  ASSERT_EQ( test_uint.pass_hist1d_mean,1);
  ASSERT_EQ( test_uint.pass_hist1d_var,1);
  ASSERT_EQ( test_uint.pass_hist1d_covar,1);
  ASSERT_EQ( test_uint.pass_hist3d_mean,1);
  ASSERT_EQ( test_uint.pass_hist3d_var,1);
  ASSERT_EQ( test_uint.pass_hist3d_covar,1);
  deep_copy(density_1d,0);
  deep_copy(density_3d,0);

  cout << "Test Scalar=int64_t" << endl;
  test_random_scalar<RandomGenerator,int64_t> test_int64(density_1d,density_3d,pool,num_draws);
  ASSERT_EQ( test_int64.pass_mean,1);
  ASSERT_EQ( test_int64.pass_var,1);
  ASSERT_EQ( test_int64.pass_covar,1);
  ASSERT_EQ( test_int64.pass_hist1d_mean,1);
  ASSERT_EQ( test_int64.pass_hist1d_var,1);
  ASSERT_EQ( test_int64.pass_hist1d_covar,1);
  ASSERT_EQ( test_int64.pass_hist3d_mean,1);
  ASSERT_EQ( test_int64.pass_hist3d_var,1);
  ASSERT_EQ( test_int64.pass_hist3d_covar,1);
  deep_copy(density_1d,0);
  deep_copy(density_3d,0);

  cout << "Test Scalar=uint64_t" << endl;
  test_random_scalar<RandomGenerator,uint64_t> test_uint64(density_1d,density_3d,pool,num_draws);
  ASSERT_EQ( test_uint64.pass_mean,1);
  ASSERT_EQ( test_uint64.pass_var,1);
  ASSERT_EQ( test_uint64.pass_covar,1);
  ASSERT_EQ( test_uint64.pass_hist1d_mean,1);
  ASSERT_EQ( test_uint64.pass_hist1d_var,1);
  ASSERT_EQ( test_uint64.pass_hist1d_covar,1);
  ASSERT_EQ( test_uint64.pass_hist3d_mean,1);
  ASSERT_EQ( test_uint64.pass_hist3d_var,1);
  ASSERT_EQ( test_uint64.pass_hist3d_covar,1);
  deep_copy(density_1d,0);
  deep_copy(density_3d,0);

  cout << "Test Scalar=float" << endl;
  test_random_scalar<RandomGenerator,float> test_float(density_1d,density_3d,pool,num_draws);
  ASSERT_EQ( test_float.pass_mean,1);
  ASSERT_EQ( test_float.pass_var,1);
  ASSERT_EQ( test_float.pass_covar,1);
  ASSERT_EQ( test_float.pass_hist1d_mean,1);
  ASSERT_EQ( test_float.pass_hist1d_var,1);
  ASSERT_EQ( test_float.pass_hist1d_covar,1);
  ASSERT_EQ( test_float.pass_hist3d_mean,1);
  ASSERT_EQ( test_float.pass_hist3d_var,1);
  ASSERT_EQ( test_float.pass_hist3d_covar,1);
  deep_copy(density_1d,0);
  deep_copy(density_3d,0);

  cout << "Test Scalar=double" << endl;
  test_random_scalar<RandomGenerator,double> test_double(density_1d,density_3d,pool,num_draws);
  ASSERT_EQ( test_double.pass_mean,1);
  ASSERT_EQ( test_double.pass_var,1);
  ASSERT_EQ( test_double.pass_covar,1);
  ASSERT_EQ( test_double.pass_hist1d_mean,1);
  ASSERT_EQ( test_double.pass_hist1d_var,1);
  ASSERT_EQ( test_double.pass_hist1d_covar,1);
  ASSERT_EQ( test_double.pass_hist3d_mean,1);
  ASSERT_EQ( test_double.pass_hist3d_var,1);
  ASSERT_EQ( test_double.pass_hist3d_covar,1);
}
}

} // namespace Test

#endif //KOKKOS_TEST_UNORDERED_MAP_HPP