Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_KokkosArrayKernelsUnitTestNew.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
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 Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 // Utilities
46 
47 #include "Stokhos_ConfigDefs.h"
48 
49 #include "Kokkos_Core.hpp"
50 
51 // Threads kernels
52 #ifdef KOKKOS_ENABLE_THREADS
54 #endif
55 
56 // OpenMP kernels
57 #if defined(KOKKOS_ENABLE_OPENMP) && defined(HAVE_STOKHOS_MKL)
59 #endif
60 
61 // Tests
62 #include "Stokhos_KokkosArrayKernelsUnitTestNew.hpp"
63 
64 using namespace KokkosKernelsUnitTest;
65 
67 
68 // Test declarations
69 #include "Stokhos_KokkosArrayKernelsUnitTestNewDecl.hpp"
70 
71 // Host-specific tests
72 
73 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( Kokkos_SG_SpMv, CrsProductTensorCijk, Scalar, Device ) {
74  success = true;
75 
76  typedef Scalar value_type;
77  typedef int size_type;
79 
80  tensor_type tensor =
81  Stokhos::create_product_tensor<Device>( *setup.basis, *setup.Cijk );
82 
83  for (int i=0; i<setup.stoch_length; ++i) {
84  const int iEntryBeg = tensor.entry_begin(i);
85  const int iEntryEnd = tensor.entry_end(i);
86  for (int iEntry = iEntryBeg ; iEntry < iEntryEnd ; ++iEntry ) {
87  const int kj = tensor.coord( iEntry );
88  const int j = kj & 0x0ffff;
89  const int k = kj >> 16;
90  // const int j = tensor.coord(iEntry,0);
91  // const int k = tensor.coord(iEntry,1);
92  value_type c2 = tensor.value(iEntry);
93  if (j == k) c2 *= 2.0;
94 
95  int ii = setup.inv_perm[i];
96  int jj = setup.inv_perm[j];
97  int kk = setup.inv_perm[k];
98  value_type c = setup.Cijk->getValue(ii,jj,kk);
99 
100  if (std::abs(c-c2) > std::abs(c)*setup.rel_tol + setup.abs_tol) {
101  out << "(" << ii << "," << jj << "," << kk << "): " << c
102  << " == " << c2 << " failed!" << std::endl;
103  success = false;
104  }
105  }
106  }
107 }
108 
109 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( Kokkos_SG_SpMv, TiledCrsProductTensorCijk, Scalar, Device ) {
110  success = true;
111 
112  typedef Scalar value_type;
114 
115  Teuchos::ParameterList params;
116  params.set("Tile Size",10);
117  params.set("Max Tiles",10000);
118 
119  tensor_type tensor =
120  Stokhos::create_tiled_product_tensor<Device>( *setup.basis, *setup.Cijk,
121  params );
122 
123  // This is a valid test only with no symmetry
124  // TEUCHOS_TEST_EQUALITY( tensor.entry_count(), setup.Cijk->num_entries(),
125  // out, success );
126 
127  const size_t n_tile = tensor.num_tiles();
128  for ( size_t tile = 0 ; tile < n_tile ; ++tile ) {
129  const size_t i_offset = tensor.offset(tile, 0);
130  const size_t j_offset = tensor.offset(tile, 1);
131  const size_t k_offset = tensor.offset(tile, 2);
132  const size_t n_row = tensor.num_rows(tile);
133 
134  for (size_t i=0; i<n_row; ++i) {
135  const size_t iEntryBeg = tensor.entry_begin(tile,i);
136  const size_t iEntryEnd = tensor.entry_end(tile,i);
137  for (size_t iEntry = iEntryBeg ; iEntry < iEntryEnd ; ++iEntry ) {
138  const size_t j = tensor.coord(iEntry,0);
139  const size_t k = tensor.coord(iEntry,1);
140  value_type c2 = tensor.value(iEntry);
141  int ii = i + i_offset;
142  int jj = j + j_offset;
143  int kk = k + k_offset;
144  if (jj == kk)
145  c2 *= 2.0;
146  value_type c = setup.Cijk->getValue(ii,jj,kk);
147 
148  if (std::abs(c-c2) > std::abs(c)*setup.rel_tol + setup.abs_tol) {
149  out << "(" << ii << "," << jj << "," << kk << "): " << c
150  << " == " << c2 << " failed!" << std::endl;
151  success = false;
152  }
153  }
154  }
155  }
156 }
157 
158 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( Kokkos_SG_SpMv, SimpleTiledCrsProductTensorCijk, Scalar, Device ) {
159  success = true;
160 
161  typedef Scalar value_type;
163 
164  Teuchos::ParameterList params;
165  params.set("Tile Size",10);
166 
167  tensor_type tensor =
168  Stokhos::create_simple_tiled_product_tensor<Device>(
169  *setup.basis, *setup.Cijk, params);
170 
171  int num_entry = 0;
172  const size_t n_i_tile = tensor.num_i_tiles();
173  for (size_t i_tile = 0; i_tile<n_i_tile; ++i_tile) {
174  const size_t i_begin = tensor.i_begin(i_tile);
175  const size_t i_size = tensor.i_size(i_tile);
176 
177  const size_t n_j_tile = tensor.num_j_tiles(i_tile);
178  for (size_t j_tile = 0; j_tile<n_j_tile; ++j_tile) {
179  const size_t j_begin = tensor.j_begin(i_tile, j_tile);
180  //const size_t j_size = tensor.j_size(i_tile, j_tile);
181 
182  const size_t n_k_tile = tensor.num_k_tiles(i_tile, j_tile);
183  for (size_t k_tile = 0; k_tile<n_k_tile; ++k_tile) {
184  const size_t k_begin = tensor.k_begin(i_tile, j_tile, k_tile);
185  //const size_t k_size = tensor.k_size(i_tile, j_tile, k_tile);
186 
187  for (size_t i=0; i<i_size; ++i) {
188  const size_t iEntryBeg = tensor.entry_begin(i_tile,j_tile,k_tile,i);
189  const size_t iEntryEnd = tensor.entry_end(i_tile,j_tile,k_tile,i);
190  for (size_t iEntry = iEntryBeg ; iEntry < iEntryEnd ; ++iEntry ) {
191  const size_t j = tensor.coord(iEntry,0);
192  const size_t k = tensor.coord(iEntry,1);
193  value_type c2 = tensor.value(iEntry);
194  int ii = i + i_begin;
195  int jj = j + j_begin;
196  int kk = k + k_begin;
197  ++num_entry;
198  if (jj == kk)
199  c2 *= 2.0;
200  else
201  ++num_entry;
202  value_type c = setup.Cijk->getValue(ii,jj,kk);
203 
204  if (std::abs(c-c2) > std::abs(c)*setup.rel_tol + setup.abs_tol) {
205  out << "(" << ii << "," << jj << "," << kk << "): " << c
206  << " == " << c2 << " failed!" << std::endl;
207  success = false;
208  }
209  }
210  }
211  }
212  }
213  }
214  TEUCHOS_TEST_EQUALITY( num_entry, setup.Cijk->num_entries(), out, success );
215 }
216 
217 template <typename Scalar, typename Device, bool Pack>
219  Teuchos::FancyOStream& out) {
220  bool success = true;
221 
222  typedef Scalar value_type;
224 
225  tensor_type tensor =
226  Stokhos::create_coo_product_tensor<Device, Pack>(
227  *setup.basis, *setup.Cijk );
228 
229  const size_t nEntry = tensor.entry_count();
230  size_t i, j, k;
231  for ( size_t entry = 0 ; entry < nEntry ; ++entry ) {
232  tensor.coord(entry, i, j, k);
233  value_type c2 = tensor.value(entry);
234  if (j == k) c2 *= 2.0;
235  value_type c = setup.Cijk->getValue(i,j,k);
236 
237  if (std::abs(c-c2) > std::abs(c)*setup.rel_tol + setup.abs_tol) {
238  out << "(" << i << "," << j << "," << k << "): " << c
239  << " == " << c2 << " failed!" << std::endl;
240  success = false;
241  }
242  }
243 
244  return success;
245 }
246 
247 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( Kokkos_SG_SpMv, CooProductTensorCijk_Packed, Scalar, Device ) {
248  success = test_coo_product_tensor_cijk<Scalar,Device,true>(setup, out);
249 }
250 
251 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( Kokkos_SG_SpMv, CooProductTensorCijk_Unpacked, Scalar, Device ) {
252  success = test_coo_product_tensor_cijk<Scalar,Device,false>(setup, out);
253 }
254 
255 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( Kokkos_SG_SpMv, FlatSparseCijk, Scalar, Device ) {
256  success = true;
257 
258  typedef Scalar value_type;
260  typedef size_t size_type;
261 
262  tensor_type tensor =
263  Stokhos::create_flat_sparse_3_tensor<Device>( *setup.basis, *setup.Cijk );
264 
265  for (int i=0; i<setup.stoch_length; ++i) {
266  const size_type nk = tensor.num_k(i);
267  const size_type kBeg = tensor.k_begin(i);
268  const size_type kEnd = kBeg + nk;
269  for (size_type kEntry = kBeg; kEntry < kEnd; ++kEntry) {
270  const size_type k = tensor.k_coord(kEntry);
271  const size_type nj = tensor.num_j(kEntry);
272  const size_type jBeg = tensor.j_begin(kEntry);
273  const size_type jEnd = jBeg + nj;
274  for (size_type jEntry = jBeg; jEntry < jEnd; ++jEntry) {
275  const size_type j = tensor.j_coord(jEntry);
276  value_type c2 = tensor.value(jEntry);
277  if (j == k) c2 *= 2.0;
278  value_type c = setup.Cijk->getValue(i,j,k);
279  if (std::abs(c-c2) > std::abs(c)*setup.rel_tol + setup.abs_tol) {
280  out << "(" << i << "," << j << "," << k << "): " << c
281  << " == " << c2 << " failed!" << std::endl;
282  success = false;
283  }
284  }
285  }
286  }
287 }
288 
289 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( Kokkos_SG_SpMv, FlatSparseCijk_kji, Scalar, Device ) {
290  success = true;
291 
292  typedef Scalar value_type;
294  typedef size_t size_type;
295 
296  tensor_type tensor =
297  Stokhos::create_flat_sparse_3_tensor_kji<Device>(*setup.basis, *setup.Cijk);
298  const size_type nk = tensor.num_k();
299 
300  for ( size_type k = 0; k < nk; ++k) {
301  const size_type nj = tensor.num_j(k);
302  const size_type jBeg = tensor.j_begin(k);
303  const size_type jEnd = jBeg + nj;
304  for (size_type jEntry = jBeg; jEntry < jEnd; ++jEntry) {
305  const size_type j = tensor.j_coord(jEntry);
306  const size_type ni = tensor.num_i(jEntry);
307  const size_type iBeg = tensor.i_begin(jEntry);
308  const size_type iEnd = iBeg + ni;
309  for (size_type iEntry = iBeg; iEntry < iEnd; ++iEntry) {
310  const size_type i = tensor.i_coord(iEntry);
311  value_type c2 = tensor.value(iEntry);
312  if (j == k) c2 *= 2.0;
313  value_type c = setup.Cijk->getValue(i,j,k);
314  if (std::abs(c-c2) > std::abs(c)*setup.rel_tol + setup.abs_tol) {
315  out << "(" << i << "," << j << "," << k << "): " << c
316  << " == " << c2 << " failed!" << std::endl;
317  success = false;
318  }
319  }
320  }
321  }
322 }
323 
324 #define UNIT_TEST_GROUP_SCALAR_HOST_DEVICE( SCALAR, DEVICE ) \
325  TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( Kokkos_SG_SpMv, CrsProductTensorCijk, SCALAR, DEVICE ) \
326  TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( Kokkos_SG_SpMv, TiledCrsProductTensorCijk, SCALAR, DEVICE ) \
327  TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( Kokkos_SG_SpMv, SimpleTiledCrsProductTensorCijk, SCALAR, DEVICE ) \
328  TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( Kokkos_SG_SpMv, CooProductTensorCijk_Packed, SCALAR, DEVICE ) \
329  TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( Kokkos_SG_SpMv, CooProductTensorCijk_Unpacked, SCALAR, DEVICE ) \
330  TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( Kokkos_SG_SpMv, FlatSparseCijk, SCALAR, DEVICE ) \
331  TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( Kokkos_SG_SpMv, FlatSparseCijk_kji, SCALAR, DEVICE )
332 
333 #ifdef KOKKOS_ENABLE_THREADS
334 using Kokkos::Threads;
335 UNIT_TEST_GROUP_SCALAR_DEVICE( double, Threads )
336 UNIT_TEST_GROUP_SCALAR_HOST_DEVICE( double, Threads )
337 #endif
338 
339 #ifdef KOKKOS_ENABLE_OPENMP
340 using Kokkos::OpenMP;
341 UNIT_TEST_GROUP_SCALAR_DEVICE( double, OpenMP )
342 UNIT_TEST_GROUP_SCALAR_HOST_DEVICE( double, OpenMP )
343 
344 #ifdef HAVE_STOKHOS_MKL
345 TEUCHOS_UNIT_TEST( Kokkos_SG_SpMv, double_OpenMP_CrsMatrixFree_MKL ) {
346  typedef double Scalar;
347  typedef Kokkos::OpenMP Device;
348  typedef Stokhos::MKLMultiply SparseMatOps;
349  success = test_crs_matrix_free<Scalar,Device,SparseMatOps>(
350  setup, out);
351 }
352 #endif
353 
354 #endif
355 
356 using Kokkos::Serial;
357 UNIT_TEST_GROUP_SCALAR_DEVICE( double, Serial )
358 UNIT_TEST_GROUP_SCALAR_HOST_DEVICE( double, Serial )
359 
360 int main( int argc, char* argv[] ) {
361  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
362 
363  const size_t team_count =
364  Kokkos::hwloc::get_available_numa_count() *
365  Kokkos::hwloc::get_available_cores_per_numa();
366  const size_t threads_per_team =
367  Kokkos::hwloc::get_available_threads_per_core();
368  // const size_t team_count = 1 ;
369  // const size_t threads_per_team = 1 ;
370 
371  Kokkos::InitArguments init_args;
372  init_args.num_threads = team_count*threads_per_team;
373  init_args.device_id = 0;
374  Kokkos::initialize( init_args );
375  Kokkos::print_configuration( std::cout );
376 
377  // Setup (has to happen after initialization)
378  setup.setup();
379 
380  // Run tests
382 
383  // Finish up
384  Kokkos::finalize();
385 
386  return ret;
387 }
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
bool test_coo_product_tensor_cijk(const KokkosKernelsUnitTest::UnitTestSetup< Device > &setup, Teuchos::FancyOStream &out)
Sparse product tensor with replicated entries to provide subsets with a given coordinate.
#define UNIT_TEST_GROUP_SCALAR_HOST_DEVICE(SCALAR, DEVICE)
Sparse product tensor with replicated entries to provide subsets with a given coordinate.
static int runUnitTestsFromMain(int argc, char *argv[])
TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL(Kokkos_SG_SpMv, CrsProductTensorCijk, Scalar, Device)
KOKKOS_INLINE_FUNCTION size_type num_k() const
Number of k entries.
KOKKOS_INLINE_FUNCTION size_type entry_begin(size_type i) const
Begin entries with a coordinate &#39;i&#39;.
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION size_type num_k(size_type i) const
Number of k entries with a coordinate &#39;i&#39;.
int main(int argc, char **argv)
#define TEUCHOS_TEST_EQUALITY(v1, v2, out, success)
#define UNIT_TEST_GROUP_SCALAR_DEVICE(SCALAR, DEVICE)
TEUCHOS_UNIT_TEST(tAdaptivityManager, test_interface)
Sparse product tensor with replicated entries to provide subsets with a given coordinate.
Sparse product tensor using &#39;COO&#39;-like storage format.