Stokhos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
43#include "Teuchos_UnitTestHarness.hpp"
44#include "Teuchos_UnitTestRepository.hpp"
45#include "Teuchos_GlobalMPISession.hpp"
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
64using namespace KokkosKernelsUnitTest;
65
67
68// Test declarations
69#include "Stokhos_KokkosArrayKernelsUnitTestNewDecl.hpp"
70
71// Host-specific tests
72
73TEUCHOS_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
109TEUCHOS_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
158TEUCHOS_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
217template <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
247TEUCHOS_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
251TEUCHOS_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
255TEUCHOS_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
289TEUCHOS_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
334using Kokkos::Threads;
335UNIT_TEST_GROUP_SCALAR_DEVICE( double, Threads )
336UNIT_TEST_GROUP_SCALAR_HOST_DEVICE( double, Threads )
337#endif
338
339#ifdef KOKKOS_ENABLE_OPENMP
340using Kokkos::OpenMP;
341UNIT_TEST_GROUP_SCALAR_DEVICE( double, OpenMP )
343
344#ifdef HAVE_STOKHOS_MKL
345TEUCHOS_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
356using Kokkos::Serial;
357UNIT_TEST_GROUP_SCALAR_DEVICE( double, Serial )
359
360int 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::InitializationSettings init_args;
372 init_args.set_num_threads(team_count*threads_per_team);
373 init_args.set_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
381 int ret = Teuchos::UnitTestRepository::runUnitTestsFromMain(argc, argv);
382
383 // Finish up
384 Kokkos::finalize();
385
386 return ret;
387}
TEUCHOS_UNIT_TEST(tAdaptivityManager, test_interface)
#define UNIT_TEST_GROUP_SCALAR_DEVICE(SCALAR, DEVICE)
int main(int argc, char *argv[])
TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL(Kokkos_SG_SpMv, CrsProductTensorCijk, Scalar, Device)
#define UNIT_TEST_GROUP_SCALAR_HOST_DEVICE(SCALAR, DEVICE)
bool test_coo_product_tensor_cijk(const UnitTestSetup &setup, Teuchos::FancyOStream &out)
Sparse product tensor using 'COO'-like storage format.
Sparse product tensor with replicated entries to provide subsets with a given coordinate.
Sparse product tensor with replicated entries to provide subsets with a given coordinate.
Sparse product tensor with replicated entries to provide subsets with a given coordinate.