1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44
45 #include <gtest/gtest.h>
46
47 #include <Kokkos_Core.hpp>
48 #include <stdexcept>
49 #include <sstream>
50 #include <iostream>
51 #include <type_traits>
52
53 namespace Test {
54 struct SomeTag {};
55
56 template <class ExecutionSpace>
57 class TestRangePolicyConstruction {
58 public:
TestRangePolicyConstruction()59 TestRangePolicyConstruction() {
60 test_compile_time_parameters();
61 test_runtime_parameters();
62 }
63
64 private:
test_compile_time_parameters()65 void test_compile_time_parameters() {
66 {
67 using policy_t = Kokkos::RangePolicy<>;
68 using execution_space = typename policy_t::execution_space;
69 using index_type = typename policy_t::index_type;
70 using schedule_type = typename policy_t::schedule_type;
71 using work_tag = typename policy_t::work_tag;
72
73 ASSERT_TRUE((
74 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
75 ASSERT_TRUE((std::is_same<index_type,
76 typename execution_space::size_type>::value));
77 ASSERT_TRUE((std::is_same<schedule_type,
78 Kokkos::Schedule<Kokkos::Static>>::value));
79 ASSERT_TRUE((std::is_same<work_tag, void>::value));
80 }
81
82 {
83 using policy_t = Kokkos::RangePolicy<ExecutionSpace>;
84 using execution_space = typename policy_t::execution_space;
85 using index_type = typename policy_t::index_type;
86 using schedule_type = typename policy_t::schedule_type;
87 using work_tag = typename policy_t::work_tag;
88
89 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
90 ASSERT_TRUE((std::is_same<index_type,
91 typename execution_space::size_type>::value));
92 ASSERT_TRUE((std::is_same<schedule_type,
93 Kokkos::Schedule<Kokkos::Static>>::value));
94 ASSERT_TRUE((std::is_same<work_tag, void>::value));
95 }
96
97 {
98 using policy_t = Kokkos::RangePolicy<ExecutionSpace,
99 Kokkos::Schedule<Kokkos::Dynamic>>;
100 using execution_space = typename policy_t::execution_space;
101 using index_type = typename policy_t::index_type;
102 using schedule_type = typename policy_t::schedule_type;
103 using work_tag = typename policy_t::work_tag;
104
105 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
106 ASSERT_TRUE((std::is_same<index_type,
107 typename execution_space::size_type>::value));
108 ASSERT_TRUE((std::is_same<schedule_type,
109 Kokkos::Schedule<Kokkos::Dynamic>>::value));
110 ASSERT_TRUE((std::is_same<work_tag, void>::value));
111 }
112
113 {
114 using policy_t =
115 Kokkos::RangePolicy<ExecutionSpace, Kokkos::Schedule<Kokkos::Dynamic>,
116 Kokkos::IndexType<long>>;
117 using execution_space = typename policy_t::execution_space;
118 using index_type = typename policy_t::index_type;
119 using schedule_type = typename policy_t::schedule_type;
120 using work_tag = typename policy_t::work_tag;
121
122 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
123 ASSERT_TRUE((std::is_same<index_type, long>::value));
124 ASSERT_TRUE((std::is_same<schedule_type,
125 Kokkos::Schedule<Kokkos::Dynamic>>::value));
126 ASSERT_TRUE((std::is_same<work_tag, void>::value));
127 }
128
129 {
130 using policy_t =
131 Kokkos::RangePolicy<Kokkos::IndexType<long>, ExecutionSpace,
132 Kokkos::Schedule<Kokkos::Dynamic>>;
133 using execution_space = typename policy_t::execution_space;
134 using index_type = typename policy_t::index_type;
135 using schedule_type = typename policy_t::schedule_type;
136 using work_tag = typename policy_t::work_tag;
137
138 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
139 ASSERT_TRUE((std::is_same<index_type, long>::value));
140 ASSERT_TRUE((std::is_same<schedule_type,
141 Kokkos::Schedule<Kokkos::Dynamic>>::value));
142 ASSERT_TRUE((std::is_same<work_tag, void>::value));
143 }
144
145 {
146 using policy_t =
147 Kokkos::RangePolicy<ExecutionSpace, Kokkos::Schedule<Kokkos::Dynamic>,
148 Kokkos::IndexType<long>, SomeTag>;
149 using execution_space = typename policy_t::execution_space;
150 using index_type = typename policy_t::index_type;
151 using schedule_type = typename policy_t::schedule_type;
152 using work_tag = typename policy_t::work_tag;
153
154 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
155 ASSERT_TRUE((std::is_same<index_type, long>::value));
156 ASSERT_TRUE((std::is_same<schedule_type,
157 Kokkos::Schedule<Kokkos::Dynamic>>::value));
158 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
159 }
160
161 {
162 using policy_t =
163 Kokkos::RangePolicy<Kokkos::Schedule<Kokkos::Dynamic>, ExecutionSpace,
164 Kokkos::IndexType<long>, SomeTag>;
165 using execution_space = typename policy_t::execution_space;
166 using index_type = typename policy_t::index_type;
167 using schedule_type = typename policy_t::schedule_type;
168 using work_tag = typename policy_t::work_tag;
169
170 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
171 ASSERT_TRUE((std::is_same<index_type, long>::value));
172 ASSERT_TRUE((std::is_same<schedule_type,
173 Kokkos::Schedule<Kokkos::Dynamic>>::value));
174 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
175 }
176
177 {
178 using policy_t =
179 Kokkos::RangePolicy<SomeTag, Kokkos::Schedule<Kokkos::Dynamic>,
180 Kokkos::IndexType<long>, ExecutionSpace>;
181 using execution_space = typename policy_t::execution_space;
182 using index_type = typename policy_t::index_type;
183 using schedule_type = typename policy_t::schedule_type;
184 using work_tag = typename policy_t::work_tag;
185
186 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
187 ASSERT_TRUE((std::is_same<index_type, long>::value));
188 ASSERT_TRUE((std::is_same<schedule_type,
189 Kokkos::Schedule<Kokkos::Dynamic>>::value));
190 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
191 }
192
193 {
194 using policy_t = Kokkos::RangePolicy<Kokkos::Schedule<Kokkos::Dynamic>>;
195 using execution_space = typename policy_t::execution_space;
196 using index_type = typename policy_t::index_type;
197 using schedule_type = typename policy_t::schedule_type;
198 using work_tag = typename policy_t::work_tag;
199
200 ASSERT_TRUE((
201 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
202 ASSERT_TRUE((std::is_same<index_type,
203 typename execution_space::size_type>::value));
204 ASSERT_TRUE((std::is_same<schedule_type,
205 Kokkos::Schedule<Kokkos::Dynamic>>::value));
206 ASSERT_TRUE((std::is_same<work_tag, void>::value));
207 }
208
209 {
210 using policy_t = Kokkos::RangePolicy<Kokkos::Schedule<Kokkos::Dynamic>,
211 Kokkos::IndexType<long>>;
212 using execution_space = typename policy_t::execution_space;
213 using index_type = typename policy_t::index_type;
214 using schedule_type = typename policy_t::schedule_type;
215 using work_tag = typename policy_t::work_tag;
216
217 ASSERT_TRUE((
218 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
219 ASSERT_TRUE((std::is_same<index_type, long>::value));
220 ASSERT_TRUE((std::is_same<schedule_type,
221 Kokkos::Schedule<Kokkos::Dynamic>>::value));
222 ASSERT_TRUE((std::is_same<work_tag, void>::value));
223 }
224
225 {
226 using policy_t = Kokkos::RangePolicy<Kokkos::IndexType<long>,
227 Kokkos::Schedule<Kokkos::Dynamic>>;
228 using execution_space = typename policy_t::execution_space;
229 using index_type = typename policy_t::index_type;
230 using schedule_type = typename policy_t::schedule_type;
231 using work_tag = typename policy_t::work_tag;
232
233 ASSERT_TRUE((
234 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
235 ASSERT_TRUE((std::is_same<index_type, long>::value));
236 ASSERT_TRUE((std::is_same<schedule_type,
237 Kokkos::Schedule<Kokkos::Dynamic>>::value));
238 ASSERT_TRUE((std::is_same<work_tag, void>::value));
239 }
240
241 {
242 using policy_t = Kokkos::RangePolicy<Kokkos::Schedule<Kokkos::Dynamic>,
243 Kokkos::IndexType<long>, SomeTag>;
244 using execution_space = typename policy_t::execution_space;
245 using index_type = typename policy_t::index_type;
246 using schedule_type = typename policy_t::schedule_type;
247 using work_tag = typename policy_t::work_tag;
248
249 ASSERT_TRUE((
250 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
251 ASSERT_TRUE((std::is_same<index_type, long>::value));
252 ASSERT_TRUE((std::is_same<schedule_type,
253 Kokkos::Schedule<Kokkos::Dynamic>>::value));
254 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
255 }
256
257 {
258 using policy_t = Kokkos::RangePolicy<Kokkos::Schedule<Kokkos::Dynamic>,
259 Kokkos::IndexType<long>, SomeTag>;
260 using execution_space = typename policy_t::execution_space;
261 using index_type = typename policy_t::index_type;
262 using schedule_type = typename policy_t::schedule_type;
263 using work_tag = typename policy_t::work_tag;
264
265 ASSERT_TRUE((
266 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
267 ASSERT_TRUE((std::is_same<index_type, long>::value));
268 ASSERT_TRUE((std::is_same<schedule_type,
269 Kokkos::Schedule<Kokkos::Dynamic>>::value));
270 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
271 }
272
273 {
274 using policy_t =
275 Kokkos::RangePolicy<SomeTag, Kokkos::Schedule<Kokkos::Dynamic>,
276 Kokkos::IndexType<long>>;
277 using execution_space = typename policy_t::execution_space;
278 using index_type = typename policy_t::index_type;
279 using schedule_type = typename policy_t::schedule_type;
280 using work_tag = typename policy_t::work_tag;
281
282 ASSERT_TRUE((
283 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
284 ASSERT_TRUE((std::is_same<index_type, long>::value));
285 ASSERT_TRUE((std::is_same<schedule_type,
286 Kokkos::Schedule<Kokkos::Dynamic>>::value));
287 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
288 }
289 }
test_runtime_parameters()290 void test_runtime_parameters() {
291 using policy_t = Kokkos::RangePolicy<>;
292 {
293 policy_t p(5, 15);
294 ASSERT_TRUE((p.begin() == 5));
295 ASSERT_TRUE((p.end() == 15));
296 }
297 {
298 policy_t p(Kokkos::DefaultExecutionSpace(), 5, 15);
299 ASSERT_TRUE((p.begin() == 5));
300 ASSERT_TRUE((p.end() == 15));
301 }
302 {
303 policy_t p(5, 15, Kokkos::ChunkSize(10));
304 ASSERT_TRUE((p.begin() == 5));
305 ASSERT_TRUE((p.end() == 15));
306 ASSERT_TRUE((p.chunk_size() == 10));
307 }
308 {
309 policy_t p(Kokkos::DefaultExecutionSpace(), 5, 15, Kokkos::ChunkSize(10));
310 ASSERT_TRUE((p.begin() == 5));
311 ASSERT_TRUE((p.end() == 15));
312 ASSERT_TRUE((p.chunk_size() == 10));
313 }
314 {
315 policy_t p;
316 ASSERT_TRUE((p.begin() == 0));
317 ASSERT_TRUE((p.end() == 0));
318 p = policy_t(5, 15, Kokkos::ChunkSize(10));
319 ASSERT_TRUE((p.begin() == 5));
320 ASSERT_TRUE((p.end() == 15));
321 ASSERT_TRUE((p.chunk_size() == 10));
322 }
323 }
324 };
325
326 template <class ExecutionSpace>
327 class TestTeamPolicyConstruction {
328 public:
TestTeamPolicyConstruction()329 TestTeamPolicyConstruction() {
330 test_compile_time_parameters();
331 test_run_time_parameters();
332 }
333
334 private:
test_compile_time_parameters()335 void test_compile_time_parameters() {
336 {
337 using policy_t = Kokkos::TeamPolicy<>;
338 using execution_space = typename policy_t::execution_space;
339 using index_type = typename policy_t::index_type;
340 using schedule_type = typename policy_t::schedule_type;
341 using work_tag = typename policy_t::work_tag;
342
343 ASSERT_TRUE((
344 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
345 ASSERT_TRUE((std::is_same<index_type,
346 typename execution_space::size_type>::value));
347 ASSERT_TRUE((std::is_same<schedule_type,
348 Kokkos::Schedule<Kokkos::Static>>::value));
349 ASSERT_TRUE((std::is_same<work_tag, void>::value));
350 }
351
352 {
353 using policy_t = Kokkos::TeamPolicy<ExecutionSpace>;
354 using execution_space = typename policy_t::execution_space;
355 using index_type = typename policy_t::index_type;
356 using schedule_type = typename policy_t::schedule_type;
357 using work_tag = typename policy_t::work_tag;
358
359 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
360 ASSERT_TRUE((std::is_same<index_type,
361 typename execution_space::size_type>::value));
362 ASSERT_TRUE((std::is_same<schedule_type,
363 Kokkos::Schedule<Kokkos::Static>>::value));
364 ASSERT_TRUE((std::is_same<work_tag, void>::value));
365 }
366
367 {
368 using policy_t =
369 Kokkos::TeamPolicy<ExecutionSpace, Kokkos::Schedule<Kokkos::Dynamic>>;
370 using execution_space = typename policy_t::execution_space;
371 using index_type = typename policy_t::index_type;
372 using schedule_type = typename policy_t::schedule_type;
373 using work_tag = typename policy_t::work_tag;
374
375 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
376 ASSERT_TRUE((std::is_same<index_type,
377 typename execution_space::size_type>::value));
378 ASSERT_TRUE((std::is_same<schedule_type,
379 Kokkos::Schedule<Kokkos::Dynamic>>::value));
380 ASSERT_TRUE((std::is_same<work_tag, void>::value));
381 }
382
383 {
384 using policy_t =
385 Kokkos::TeamPolicy<ExecutionSpace, Kokkos::Schedule<Kokkos::Dynamic>,
386 Kokkos::IndexType<long>>;
387 using execution_space = typename policy_t::execution_space;
388 using index_type = typename policy_t::index_type;
389 using schedule_type = typename policy_t::schedule_type;
390 using work_tag = typename policy_t::work_tag;
391
392 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
393 ASSERT_TRUE((std::is_same<index_type, long>::value));
394 ASSERT_TRUE((std::is_same<schedule_type,
395 Kokkos::Schedule<Kokkos::Dynamic>>::value));
396 ASSERT_TRUE((std::is_same<work_tag, void>::value));
397 }
398
399 {
400 using policy_t =
401 Kokkos::TeamPolicy<Kokkos::IndexType<long>, ExecutionSpace,
402 Kokkos::Schedule<Kokkos::Dynamic>>;
403 using execution_space = typename policy_t::execution_space;
404 using index_type = typename policy_t::index_type;
405 using schedule_type = typename policy_t::schedule_type;
406 using work_tag = typename policy_t::work_tag;
407
408 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
409 ASSERT_TRUE((std::is_same<index_type, long>::value));
410 ASSERT_TRUE((std::is_same<schedule_type,
411 Kokkos::Schedule<Kokkos::Dynamic>>::value));
412 ASSERT_TRUE((std::is_same<work_tag, void>::value));
413 }
414
415 {
416 using policy_t =
417 Kokkos::TeamPolicy<ExecutionSpace, Kokkos::Schedule<Kokkos::Dynamic>,
418 Kokkos::IndexType<long>, SomeTag>;
419 using execution_space = typename policy_t::execution_space;
420 using index_type = typename policy_t::index_type;
421 using schedule_type = typename policy_t::schedule_type;
422 using work_tag = typename policy_t::work_tag;
423
424 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
425 ASSERT_TRUE((std::is_same<index_type, long>::value));
426 ASSERT_TRUE((std::is_same<schedule_type,
427 Kokkos::Schedule<Kokkos::Dynamic>>::value));
428 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
429 }
430
431 {
432 using policy_t =
433 Kokkos::TeamPolicy<Kokkos::Schedule<Kokkos::Dynamic>, ExecutionSpace,
434 Kokkos::IndexType<long>, SomeTag>;
435 using execution_space = typename policy_t::execution_space;
436 using index_type = typename policy_t::index_type;
437 using schedule_type = typename policy_t::schedule_type;
438 using work_tag = typename policy_t::work_tag;
439
440 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
441 ASSERT_TRUE((std::is_same<index_type, long>::value));
442 ASSERT_TRUE((std::is_same<schedule_type,
443 Kokkos::Schedule<Kokkos::Dynamic>>::value));
444 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
445 }
446
447 {
448 using policy_t =
449 Kokkos::TeamPolicy<SomeTag, Kokkos::Schedule<Kokkos::Dynamic>,
450 Kokkos::IndexType<long>, ExecutionSpace>;
451 using execution_space = typename policy_t::execution_space;
452 using index_type = typename policy_t::index_type;
453 using schedule_type = typename policy_t::schedule_type;
454 using work_tag = typename policy_t::work_tag;
455
456 ASSERT_TRUE((std::is_same<execution_space, ExecutionSpace>::value));
457 ASSERT_TRUE((std::is_same<index_type, long>::value));
458 ASSERT_TRUE((std::is_same<schedule_type,
459 Kokkos::Schedule<Kokkos::Dynamic>>::value));
460 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
461 }
462
463 {
464 using policy_t = Kokkos::TeamPolicy<Kokkos::Schedule<Kokkos::Dynamic>>;
465 using execution_space = typename policy_t::execution_space;
466 using index_type = typename policy_t::index_type;
467 using schedule_type = typename policy_t::schedule_type;
468 using work_tag = typename policy_t::work_tag;
469
470 ASSERT_TRUE((
471 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
472 ASSERT_TRUE((std::is_same<index_type,
473 typename execution_space::size_type>::value));
474 ASSERT_TRUE((std::is_same<schedule_type,
475 Kokkos::Schedule<Kokkos::Dynamic>>::value));
476 ASSERT_TRUE((std::is_same<work_tag, void>::value));
477 }
478
479 {
480 using policy_t = Kokkos::TeamPolicy<Kokkos::Schedule<Kokkos::Dynamic>,
481 Kokkos::IndexType<long>>;
482 using execution_space = typename policy_t::execution_space;
483 using index_type = typename policy_t::index_type;
484 using schedule_type = typename policy_t::schedule_type;
485 using work_tag = typename policy_t::work_tag;
486
487 ASSERT_TRUE((
488 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
489 ASSERT_TRUE((std::is_same<index_type, long>::value));
490 ASSERT_TRUE((std::is_same<schedule_type,
491 Kokkos::Schedule<Kokkos::Dynamic>>::value));
492 ASSERT_TRUE((std::is_same<work_tag, void>::value));
493 }
494
495 {
496 using policy_t = Kokkos::TeamPolicy<Kokkos::IndexType<long>,
497 Kokkos::Schedule<Kokkos::Dynamic>>;
498 using execution_space = typename policy_t::execution_space;
499 using index_type = typename policy_t::index_type;
500 using schedule_type = typename policy_t::schedule_type;
501 using work_tag = typename policy_t::work_tag;
502
503 ASSERT_TRUE((
504 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
505 ASSERT_TRUE((std::is_same<index_type, long>::value));
506 ASSERT_TRUE((std::is_same<schedule_type,
507 Kokkos::Schedule<Kokkos::Dynamic>>::value));
508 ASSERT_TRUE((std::is_same<work_tag, void>::value));
509 }
510
511 {
512 using policy_t = Kokkos::TeamPolicy<Kokkos::Schedule<Kokkos::Dynamic>,
513 Kokkos::IndexType<long>, SomeTag>;
514 using execution_space = typename policy_t::execution_space;
515 using index_type = typename policy_t::index_type;
516 using schedule_type = typename policy_t::schedule_type;
517 using work_tag = typename policy_t::work_tag;
518
519 ASSERT_TRUE((
520 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
521 ASSERT_TRUE((std::is_same<index_type, long>::value));
522 ASSERT_TRUE((std::is_same<schedule_type,
523 Kokkos::Schedule<Kokkos::Dynamic>>::value));
524 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
525 }
526
527 {
528 using policy_t = Kokkos::TeamPolicy<Kokkos::Schedule<Kokkos::Dynamic>,
529 Kokkos::IndexType<long>, SomeTag>;
530 using execution_space = typename policy_t::execution_space;
531 using index_type = typename policy_t::index_type;
532 using schedule_type = typename policy_t::schedule_type;
533 using work_tag = typename policy_t::work_tag;
534
535 ASSERT_TRUE((
536 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
537 ASSERT_TRUE((std::is_same<index_type, long>::value));
538 ASSERT_TRUE((std::is_same<schedule_type,
539 Kokkos::Schedule<Kokkos::Dynamic>>::value));
540 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
541 }
542
543 {
544 using policy_t =
545 Kokkos::TeamPolicy<SomeTag, Kokkos::Schedule<Kokkos::Dynamic>,
546 Kokkos::IndexType<long>>;
547 using execution_space = typename policy_t::execution_space;
548 using index_type = typename policy_t::index_type;
549 using schedule_type = typename policy_t::schedule_type;
550 using work_tag = typename policy_t::work_tag;
551
552 ASSERT_TRUE((
553 std::is_same<execution_space, Kokkos::DefaultExecutionSpace>::value));
554 ASSERT_TRUE((std::is_same<index_type, long>::value));
555 ASSERT_TRUE((std::is_same<schedule_type,
556 Kokkos::Schedule<Kokkos::Dynamic>>::value));
557 ASSERT_TRUE((std::is_same<work_tag, SomeTag>::value));
558 }
559 }
560
561 template <class policy_t>
test_run_time_parameters_type()562 void test_run_time_parameters_type() {
563 int league_size = 131;
564 int team_size = 4 < policy_t::execution_space::concurrency()
565 ? 4
566 : policy_t::execution_space::concurrency();
567 #ifdef KOKKOS_ENABLE_HPX
568 team_size = 1;
569 #endif
570 #ifdef KOKKOS_ENABLE_OPENMPTARGET
571 if (std::is_same<typename policy_t::execution_space,
572 Kokkos::Experimental::OpenMPTarget>::value)
573 team_size = 32;
574 #endif
575 int chunk_size = 4;
576 int per_team_scratch = 1024;
577 int per_thread_scratch = 16;
578 int scratch_size = per_team_scratch + per_thread_scratch * team_size;
579
580 policy_t p1(league_size, team_size);
581 ASSERT_EQ(p1.league_size(), league_size);
582 ASSERT_EQ(p1.team_size(), team_size);
583 // FIXME_SYCL implement chunk_size
584 #ifndef KOKKOS_ENABLE_SYCL
585 ASSERT_TRUE(p1.chunk_size() > 0);
586 #endif
587 ASSERT_EQ(p1.scratch_size(0), 0);
588
589 policy_t p2 = p1.set_chunk_size(chunk_size);
590 ASSERT_EQ(p1.league_size(), league_size);
591 ASSERT_EQ(p1.team_size(), team_size);
592 ASSERT_EQ(p1.chunk_size(), chunk_size);
593 ASSERT_EQ(p1.scratch_size(0), 0);
594
595 ASSERT_EQ(p2.league_size(), league_size);
596 ASSERT_EQ(p2.team_size(), team_size);
597 ASSERT_EQ(p2.chunk_size(), chunk_size);
598 ASSERT_EQ(p2.scratch_size(0), 0);
599
600 policy_t p3 = p2.set_scratch_size(0, Kokkos::PerTeam(per_team_scratch));
601 ASSERT_EQ(p2.league_size(), league_size);
602 ASSERT_EQ(p2.team_size(), team_size);
603 ASSERT_EQ(p2.chunk_size(), chunk_size);
604 ASSERT_EQ(p2.scratch_size(0), per_team_scratch);
605 ASSERT_EQ(p3.league_size(), league_size);
606 ASSERT_EQ(p3.team_size(), team_size);
607 ASSERT_EQ(p3.chunk_size(), chunk_size);
608 ASSERT_EQ(p3.scratch_size(0), per_team_scratch);
609
610 policy_t p4 = p2.set_scratch_size(0, Kokkos::PerThread(per_thread_scratch));
611 ASSERT_EQ(p2.league_size(), league_size);
612 ASSERT_EQ(p2.team_size(), team_size);
613 ASSERT_EQ(p2.chunk_size(), chunk_size);
614 ASSERT_EQ(p2.scratch_size(0), scratch_size);
615 ASSERT_EQ(p4.league_size(), league_size);
616 ASSERT_EQ(p4.team_size(), team_size);
617 ASSERT_EQ(p4.chunk_size(), chunk_size);
618 ASSERT_EQ(p4.scratch_size(0), scratch_size);
619
620 policy_t p5 = p2.set_scratch_size(0, Kokkos::PerThread(per_thread_scratch),
621 Kokkos::PerTeam(per_team_scratch));
622 ASSERT_EQ(p2.league_size(), league_size);
623 ASSERT_EQ(p2.team_size(), team_size);
624 ASSERT_EQ(p2.chunk_size(), chunk_size);
625 ASSERT_EQ(p2.scratch_size(0), scratch_size);
626 ASSERT_EQ(p5.league_size(), league_size);
627 ASSERT_EQ(p5.team_size(), team_size);
628 ASSERT_EQ(p5.chunk_size(), chunk_size);
629 ASSERT_EQ(p5.scratch_size(0), scratch_size);
630
631 policy_t p6 = p2.set_scratch_size(0, Kokkos::PerTeam(per_team_scratch),
632 Kokkos::PerThread(per_thread_scratch));
633 ASSERT_EQ(p2.league_size(), league_size);
634 ASSERT_EQ(p2.team_size(), team_size);
635 ASSERT_EQ(p2.chunk_size(), chunk_size);
636 ASSERT_EQ(p2.scratch_size(0), scratch_size);
637 ASSERT_EQ(p6.league_size(), league_size);
638 ASSERT_EQ(p6.team_size(), team_size);
639 ASSERT_EQ(p6.chunk_size(), chunk_size);
640 ASSERT_EQ(p6.scratch_size(0), scratch_size);
641
642 policy_t p7 = p3.set_scratch_size(0, Kokkos::PerTeam(per_team_scratch),
643 Kokkos::PerThread(per_thread_scratch));
644 ASSERT_EQ(p3.league_size(), league_size);
645 ASSERT_EQ(p3.team_size(), team_size);
646 ASSERT_EQ(p3.chunk_size(), chunk_size);
647 ASSERT_EQ(p3.scratch_size(0), scratch_size);
648 ASSERT_EQ(p7.league_size(), league_size);
649 ASSERT_EQ(p7.team_size(), team_size);
650 ASSERT_EQ(p7.chunk_size(), chunk_size);
651 ASSERT_EQ(p7.scratch_size(0), scratch_size);
652
653 policy_t p8; // default constructed
654 ASSERT_EQ(p8.league_size(), 0);
655 ASSERT_EQ(p8.scratch_size(0), 0);
656 p8 = p3; // call assignment operator
657 ASSERT_EQ(p3.league_size(), league_size);
658 ASSERT_EQ(p3.team_size(), team_size);
659 ASSERT_EQ(p3.chunk_size(), chunk_size);
660 ASSERT_EQ(p3.scratch_size(0), scratch_size);
661 ASSERT_EQ(p8.league_size(), league_size);
662 ASSERT_EQ(p8.team_size(), team_size);
663 ASSERT_EQ(p8.chunk_size(), chunk_size);
664 ASSERT_EQ(p8.scratch_size(0), scratch_size);
665 }
666
test_run_time_parameters()667 void test_run_time_parameters() {
668 test_run_time_parameters_type<Kokkos::TeamPolicy<ExecutionSpace>>();
669 test_run_time_parameters_type<
670 Kokkos::TeamPolicy<ExecutionSpace, Kokkos::Schedule<Kokkos::Dynamic>,
671 Kokkos::IndexType<long>>>();
672 test_run_time_parameters_type<
673 Kokkos::TeamPolicy<Kokkos::IndexType<long>, ExecutionSpace,
674 Kokkos::Schedule<Kokkos::Dynamic>>>();
675 test_run_time_parameters_type<
676 Kokkos::TeamPolicy<Kokkos::Schedule<Kokkos::Dynamic>,
677 Kokkos::IndexType<long>, ExecutionSpace, SomeTag>>();
678 }
679 };
680
681 // semiregular is copyable and default initializable
682 // (regular requires equality comparable)
683 template <class Policy>
check_semiregular()684 void check_semiregular() {
685 static_assert(std::is_default_constructible<Policy>::value, "");
686 static_assert(std::is_copy_constructible<Policy>::value, "");
687 static_assert(std::is_move_constructible<Policy>::value, "");
688 static_assert(std::is_copy_assignable<Policy>::value, "");
689 static_assert(std::is_move_assignable<Policy>::value, "");
690 static_assert(std::is_destructible<Policy>::value, "");
691 }
692
TEST(TEST_CATEGORY,policy_construction)693 TEST(TEST_CATEGORY, policy_construction) {
694 check_semiregular<Kokkos::RangePolicy<TEST_EXECSPACE>>();
695 check_semiregular<Kokkos::TeamPolicy<TEST_EXECSPACE>>();
696 check_semiregular<Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>>();
697
698 TestRangePolicyConstruction<TEST_EXECSPACE>();
699 TestTeamPolicyConstruction<TEST_EXECSPACE>();
700 }
701
702 template <template <class...> class Policy, class... Args>
check_converting_constructor_add_work_tag(Policy<Args...> const & policy)703 void check_converting_constructor_add_work_tag(Policy<Args...> const& policy) {
704 // Not the greatest but at least checking it compiles
705 struct WorkTag {};
706 Policy<Args..., WorkTag> policy_with_tag = policy;
707 (void)policy_with_tag;
708 }
709
TEST(TEST_CATEGORY,policy_converting_constructor_from_other_policy)710 TEST(TEST_CATEGORY, policy_converting_constructor_from_other_policy) {
711 check_converting_constructor_add_work_tag(
712 Kokkos::RangePolicy<TEST_EXECSPACE>{});
713 check_converting_constructor_add_work_tag(
714 Kokkos::TeamPolicy<TEST_EXECSPACE>{});
715 check_converting_constructor_add_work_tag(
716 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>{});
717 }
718
719 #ifndef KOKKOS_ENABLE_OPENMPTARGET // FIXME_OPENMPTARGET
TEST(TEST_CATEGORY_DEATH,policy_bounds_unsafe_narrowing_conversions)720 TEST(TEST_CATEGORY_DEATH, policy_bounds_unsafe_narrowing_conversions) {
721 using Policy = Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>,
722 Kokkos::IndexType<unsigned>>;
723
724 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
725 ASSERT_DEATH(
726 {
727 (void)Policy({-1, 0}, {2, 3});
728 },
729 "unsafe narrowing conversion");
730 }
731 #endif
732
733 template <class Policy>
test_prefer_desired_occupancy(Policy const & policy)734 void test_prefer_desired_occupancy(Policy const& policy) {
735 static_assert(!Policy::experimental_contains_desired_occupancy, "");
736
737 // MaximizeOccupancy -> MaximizeOccupancy
738 auto const policy_still_no_occ = Kokkos::Experimental::prefer(
739 policy, Kokkos::Experimental::MaximizeOccupancy{});
740 static_assert(
741 !decltype(policy_still_no_occ)::experimental_contains_desired_occupancy,
742 "");
743
744 // MaximizeOccupancy -> DesiredOccupancy
745 auto const policy_with_occ = Kokkos::Experimental::prefer(
746 policy, Kokkos::Experimental::DesiredOccupancy{33});
747 static_assert(
748 decltype(policy_with_occ)::experimental_contains_desired_occupancy, "");
749 EXPECT_EQ(policy_with_occ.impl_get_desired_occupancy().value(), 33);
750
751 // DesiredOccupancy -> DesiredOccupancy
752 auto const policy_change_occ = Kokkos::Experimental::prefer(
753 policy_with_occ, Kokkos::Experimental::DesiredOccupancy{24});
754 static_assert(
755 decltype(policy_change_occ)::experimental_contains_desired_occupancy, "");
756 EXPECT_EQ(policy_change_occ.impl_get_desired_occupancy().value(), 24);
757
758 // DesiredOccupancy -> MaximizeOccupancy
759 auto const policy_drop_occ = Kokkos::Experimental::prefer(
760 policy_with_occ, Kokkos::Experimental::MaximizeOccupancy{});
761 static_assert(
762 !decltype(policy_drop_occ)::experimental_contains_desired_occupancy, "");
763 }
764
765 template <class... Args>
766 struct DummyPolicy : Kokkos::Impl::PolicyTraits<Args...> {
767 using execution_policy = DummyPolicy;
768
769 using base_t = Kokkos::Impl::PolicyTraits<Args...>;
770 using base_t::base_t;
771 };
772
TEST(TEST_CATEGORY,desired_occupancy_prefer)773 TEST(TEST_CATEGORY, desired_occupancy_prefer) {
774 test_prefer_desired_occupancy(DummyPolicy<TEST_EXECSPACE>{});
775 test_prefer_desired_occupancy(Kokkos::RangePolicy<TEST_EXECSPACE>{});
776 test_prefer_desired_occupancy(
777 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>{});
778 test_prefer_desired_occupancy(Kokkos::TeamPolicy<TEST_EXECSPACE>{});
779 }
780
781 // For a more informative static assertion:
782 template <size_t>
783 struct static_assert_dummy_policy_must_be_size_one;
784 template <>
785 struct static_assert_dummy_policy_must_be_size_one<1> {};
786 template <size_t, size_t>
787 struct static_assert_dummy_policy_must_be_size_of_desired_occupancy;
788 template <>
789 struct static_assert_dummy_policy_must_be_size_of_desired_occupancy<
790 sizeof(Kokkos::Experimental::DesiredOccupancy),
791 sizeof(Kokkos::Experimental::DesiredOccupancy)> {};
792
TEST(TEST_CATEGORY,desired_occupancy_empty_base_optimization)793 TEST(TEST_CATEGORY, desired_occupancy_empty_base_optimization) {
794 DummyPolicy<TEST_EXECSPACE> const policy{};
795 static_assert(sizeof(decltype(policy)) == 1, "");
796 static_assert_dummy_policy_must_be_size_one<sizeof(decltype(policy))>
797 _assert1{};
798 (void)_assert1; // avoid unused variable warning
799
800 using Kokkos::Experimental::DesiredOccupancy;
801 auto policy_with_occ =
802 Kokkos::Experimental::prefer(policy, DesiredOccupancy{50});
803 static_assert(sizeof(decltype(policy_with_occ)) == sizeof(DesiredOccupancy),
804 "");
805 static_assert_dummy_policy_must_be_size_of_desired_occupancy<
806 sizeof(decltype(policy_with_occ)), sizeof(DesiredOccupancy)>
807 _assert2{};
808 (void)_assert2; // avoid unused variable warning
809 }
810
811 template <typename Policy>
test_desired_occupancy_converting_constructors(Policy const & policy)812 void test_desired_occupancy_converting_constructors(Policy const& policy) {
813 auto policy_with_occ = Kokkos::Experimental::prefer(
814 policy, Kokkos::Experimental::DesiredOccupancy{50});
815 EXPECT_EQ(policy_with_occ.impl_get_desired_occupancy().value(), 50);
816
817 auto policy_with_hint = Kokkos::Experimental::require(
818 policy_with_occ, Kokkos::Experimental::WorkItemProperty::HintLightWeight);
819 EXPECT_EQ(policy_with_hint.impl_get_desired_occupancy().value(), 50);
820 }
821
TEST(TEST_CATEGORY,desired_occupancy_converting_constructors)822 TEST(TEST_CATEGORY, desired_occupancy_converting_constructors) {
823 test_desired_occupancy_converting_constructors(
824 Kokkos::RangePolicy<TEST_EXECSPACE>{});
825 test_desired_occupancy_converting_constructors(
826 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>{});
827 test_desired_occupancy_converting_constructors(
828 Kokkos::TeamPolicy<TEST_EXECSPACE>{});
829 }
830
831 template <class T>
more_md_range_policy_construction_test()832 void more_md_range_policy_construction_test() {
833 (void)Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>{
834 Kokkos::Array<T, 2>{}, Kokkos::Array<T, 2>{}};
835
836 (void)Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>{{{T(0), T(0)}},
837 {{T(2), T(2)}}};
838
839 (void)Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>{{T(0), T(0)},
840 {T(2), T(2)}};
841 }
842
TEST(TEST_CATEGORY,md_range_policy_construction_from_arrays)843 TEST(TEST_CATEGORY, md_range_policy_construction_from_arrays) {
844 {
845 // Check that construction from Kokkos::Array of long compiles for backwards
846 // compability. This was broken in
847 // https://github.com/kokkos/kokkos/pull/3527/commits/88ea8eec6567c84739d77bdd25fdbc647fae28bb#r512323639
848 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>> p1(
849 Kokkos::Array<long, 2>{{0, 1}}, Kokkos::Array<long, 2>{{2, 3}});
850 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>> p2(
851 Kokkos::Array<long, 2>{{0, 1}}, Kokkos::Array<long, 2>{{2, 3}});
852 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>> p3(
853 Kokkos::Array<long, 2>{{0, 1}}, Kokkos::Array<long, 2>{{2, 3}},
854 Kokkos::Array<long, 1>{{4}});
855 }
856 {
857 // Check that construction from Kokkos::Array of the specified index type
858 // works.
859 using index_type = unsigned long long;
860 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>,
861 Kokkos::IndexType<index_type>>
862 p1(Kokkos::Array<index_type, 2>{{0, 1}},
863 Kokkos::Array<index_type, 2>{{2, 3}});
864 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>,
865 Kokkos::IndexType<index_type>>
866 p2(Kokkos::Array<index_type, 2>{{0, 1}},
867 Kokkos::Array<index_type, 2>{{2, 3}});
868 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>,
869 Kokkos::IndexType<index_type>>
870 p3(Kokkos::Array<index_type, 2>{{0, 1}},
871 Kokkos::Array<index_type, 2>{{2, 3}},
872 Kokkos::Array<index_type, 1>{{4}});
873 }
874 {
875 // Check that construction from double-braced initliazer list
876 // works.
877 using index_type = unsigned long long;
878 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>> p1({{0, 1}},
879 {{2, 3}});
880 Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>,
881 Kokkos::IndexType<index_type>>
882 p2({{0, 1}}, {{2, 3}});
883 }
884
885 more_md_range_policy_construction_test<char>();
886 more_md_range_policy_construction_test<int>();
887 more_md_range_policy_construction_test<unsigned long>();
888 more_md_range_policy_construction_test<std::int64_t>();
889 }
890
891 template <class WorkTag, class Policy>
set_worktag(Policy const & policy)892 constexpr auto set_worktag(Policy const& policy) {
893 static_assert(Kokkos::is_execution_policy<Policy>::value, "");
894 using PolicyWithWorkTag =
895 Kokkos::Impl::WorkTagTrait::policy_with_trait<Policy, WorkTag>;
896 return PolicyWithWorkTag{policy};
897 }
898
TEST(TEST_CATEGORY,policy_set_worktag)899 TEST(TEST_CATEGORY, policy_set_worktag) {
900 struct SomeWorkTag {};
901 struct OtherWorkTag {};
902
903 Kokkos::RangePolicy<> p1;
904 static_assert(std::is_void<decltype(p1)::work_tag>::value, "");
905
906 auto p2 = set_worktag<SomeWorkTag>(p1);
907 static_assert(std::is_same<decltype(p2)::work_tag, SomeWorkTag>::value, "");
908
909 auto p3 = set_worktag<OtherWorkTag>(p2);
910 static_assert(std::is_same<decltype(p3)::work_tag, OtherWorkTag>::value, "");
911
912 // NOTE this does not currently compile
913 // auto p4 = set_worktag<void>(p3);
914 // static_assert(std::is_void<decltype(p4)::work_tag>::value, "");
915 }
916 } // namespace Test
917