clr/hipamd/include/hip/amd_detail/amd_hip_cooperative_groups.h Source File

clr/hipamd/include/hip/amd_detail/amd_hip_cooperative_groups.h Source File#

HIP Runtime API Reference: clr/hipamd/include/hip/amd_detail/amd_hip_cooperative_groups.h Source File
amd_hip_cooperative_groups.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
16#ifndef HIP_INCLUDE_HIP_AMD_DETAIL_HIP_COOPERATIVE_GROUPS_H
17#define HIP_INCLUDE_HIP_AMD_DETAIL_HIP_COOPERATIVE_GROUPS_H
18
19#if __cplusplus
20#if !defined(__HIPCC_RTC__)
21#include <hip/amd_detail/hip_cooperative_groups_helper.h>
22#endif
23
25 class thread_group;
26namespace impl {
27 template <typename TyGroup>
28__CG_QUALIFIER__ unsigned long long groupMask(const TyGroup&);
29}
30
40 template <typename TyGroup>
41 friend __CG_QUALIFIER__ unsigned long long cooperative_groups::impl::groupMask(const TyGroup&);
42 protected:
43 __hip_uint32_t _type;
44 __hip_uint32_t _num_threads;
45 __hip_uint64_t _mask;
52 __CG_QUALIFIER__ thread_group(internal::group_type type,
53 __hip_uint32_t num_threads = static_cast<__hip_uint64_t>(0),
54 __hip_uint64_t mask = static_cast<__hip_uint64_t>(0)) {
55 _type = type;
57 _mask = mask;
58 }
59
60 struct _tiled_info {
62 unsigned int num_threads;
63 unsigned int meta_group_rank;
64 unsigned int meta_group_size;
65 };
66
72
73 friend __CG_QUALIFIER__ thread_group this_thread();
74 friend __CG_QUALIFIER__ thread_group tiled_partition(const thread_group& parent,
75 unsigned int tile_size);
76 friend class thread_block;
77
78 public:
82 __CG_QUALIFIER__ __hip_uint32_t num_threads() const { return _num_threads; }
84 __CG_QUALIFIER__ __hip_uint32_t size() const { return num_threads(); }
86 __CG_QUALIFIER__ unsigned int cg_type() const { return _type; }
88 __CG_QUALIFIER__ __hip_uint32_t thread_rank() const;
90 __CG_QUALIFIER__ __hip_uint32_t block_rank() const;
92 __CG_QUALIFIER__ bool is_valid() const;
93
106 __CG_QUALIFIER__ void sync() const;
107};
133 friend __CG_QUALIFIER__ multi_grid_group this_multi_grid();
134
135 protected:
137 explicit __CG_QUALIFIER__ multi_grid_group(__hip_uint32_t size)
138 : thread_group(internal::cg_multi_grid, size) {}
139
140 public:
143 __CG_QUALIFIER__ __hip_uint32_t num_grids() { return internal::multi_grid::num_grids(); }
144
147 __CG_QUALIFIER__ __hip_uint32_t grid_rank() { return internal::multi_grid::grid_rank(); }
149 __CG_QUALIFIER__ __hip_uint32_t thread_rank() const {
150 return internal::multi_grid::thread_rank();
151 }
153 __CG_QUALIFIER__ bool is_valid() const { return internal::multi_grid::is_valid(); }
155 __CG_QUALIFIER__ void sync() const { internal::multi_grid::sync(); }
156};
157
172 return multi_grid_group(internal::multi_grid::num_threads());
173}
174// Doxygen end group CooperativeGConstruct
185class grid_group : public thread_group {
188 friend __CG_QUALIFIER__ grid_group this_grid();
189
190 protected:
192 explicit __CG_QUALIFIER__ grid_group(__hip_uint32_t size)
193 : thread_group(internal::cg_grid, size) {}
194
195 public:
197 __CG_QUALIFIER__ __hip_uint32_t thread_rank() const { return internal::grid::thread_rank(); }
199 __CG_QUALIFIER__ __hip_uint32_t block_rank() const { return internal::grid::block_rank(); }
201 __CG_QUALIFIER__ bool is_valid() const { return internal::grid::is_valid(); }
203 __CG_QUALIFIER__ void sync() const { internal::grid::sync(); }
204 __CG_QUALIFIER__ dim3 group_dim() const { return internal::grid::grid_dim(); }
206 unsigned int signal;
207 };
209 __CG_QUALIFIER__ arrival_token barrier_arrive() const {
211 t.signal = internal::grid::barrier_signal();
212 return t;
213 }
215 __CG_QUALIFIER__ void barrier_wait(arrival_token&& t) const {
216 internal::grid::barrier_wait(t.signal);
217 }
218};
219
230__CG_QUALIFIER__ grid_group this_grid() { return grid_group(internal::grid::num_threads()); }
231
244 friend __CG_QUALIFIER__ thread_block this_thread_block();
245 friend __CG_QUALIFIER__ thread_group tiled_partition(const thread_group& parent,
246 unsigned int tile_size);
247 friend __CG_QUALIFIER__ thread_group tiled_partition(const thread_block& parent,
248 unsigned int tile_size);
249
250 protected:
251 // Construct a workgroup thread group (through the API this_thread_block())
252 explicit __CG_QUALIFIER__ thread_block(__hip_uint32_t size)
253 : thread_group(internal::cg_workgroup, size) {}
254
255 __CG_QUALIFIER__ thread_group new_tiled_group(unsigned int tile_size) const {
256 const bool pow2 = ((tile_size & (tile_size - 1)) == 0);
257 // Invalid tile size, assert
258 if (!tile_size || (tile_size > warpSize) || !pow2) {
259 __hip_assert(false && "invalid tile size");
260 }
261
262 auto block_size = num_threads();
263 auto rank = thread_rank();
264 auto partitions = (block_size + tile_size - 1) / tile_size;
265 auto tail = (partitions * tile_size) - block_size;
266 auto partition_size = tile_size - tail * (rank >= (partitions - 1) * tile_size);
267 thread_group tiledGroup = thread_group(internal::cg_tiled_group, partition_size);
268
269 tiledGroup.coalesced_info.tiled_info.num_threads = tile_size;
270 tiledGroup.coalesced_info.tiled_info.is_tiled = true;
271 tiledGroup.coalesced_info.tiled_info.meta_group_rank = rank / tile_size;
272 tiledGroup.coalesced_info.tiled_info.meta_group_size = partitions;
273 return tiledGroup;
274 }
275
276 public:
278 __CG_STATIC_QUALIFIER__ dim3 group_index() { return internal::workgroup::group_index(); }
280 __CG_STATIC_QUALIFIER__ dim3 thread_index() { return internal::workgroup::thread_index(); }
282 __CG_STATIC_QUALIFIER__ __hip_uint32_t thread_rank() {
283 return internal::workgroup::thread_rank();
284 }
286 __CG_STATIC_QUALIFIER__ __hip_uint32_t block_rank() {
287 return internal::workgroup::block_rank();
288 }
290 __CG_STATIC_QUALIFIER__ __hip_uint32_t num_threads() {
291 return internal::workgroup::num_threads();
292 }
294 __CG_STATIC_QUALIFIER__ __hip_uint32_t size() { return num_threads(); }
296 __CG_STATIC_QUALIFIER__ bool is_valid() { return internal::workgroup::is_valid(); }
298 __CG_STATIC_QUALIFIER__ void sync() { internal::workgroup::sync(); }
300 __CG_QUALIFIER__ dim3 group_dim() { return internal::workgroup::block_dim(); }
301 struct arrival_token {};
303 __CG_QUALIFIER__ arrival_token barrier_arrive() const {
304 internal::workgroup::barrier_arrive();
305 return arrival_token{};
306 }
308 __CG_QUALIFIER__ void barrier_wait(arrival_token&&) const { internal::workgroup::barrier_wait(); }
309};
310
321__CG_QUALIFIER__ thread_block this_thread_block() {
322 return thread_block(internal::workgroup::num_threads());
323}
324
332class tiled_group : public thread_group {
333 private:
334 friend __CG_QUALIFIER__ thread_group tiled_partition(const thread_group& parent,
335 unsigned int tile_size);
336 friend __CG_QUALIFIER__ tiled_group tiled_partition(const tiled_group& parent,
337 unsigned int tile_size);
338
339 __CG_QUALIFIER__ tiled_group new_tiled_group(unsigned int tile_size) const {
340 const bool pow2 = ((tile_size & (tile_size - 1)) == 0);
341
342 if (!tile_size || (tile_size > warpSize) || !pow2) {
343 __hip_assert(false && "invalid tile size");
344 }
345
346 if (num_threads() <= tile_size) {
347 return *this;
348 }
349
350 tiled_group tiledGroup = tiled_group(tile_size);
351 tiledGroup.coalesced_info.tiled_info.is_tiled = true;
352 return tiledGroup;
353 }
354
355 protected:
356 explicit __CG_QUALIFIER__ tiled_group(unsigned int tileSize)
357 : thread_group(internal::cg_tiled_group, tileSize) {
360 }
361
362 public:
364 __CG_QUALIFIER__ unsigned int num_threads() const {
366 }
367
369 __CG_QUALIFIER__ unsigned int size() const { return num_threads(); }
370
372 __CG_QUALIFIER__ unsigned int thread_rank() const {
373 return (internal::workgroup::thread_rank() & (coalesced_info.tiled_info.num_threads - 1));
374 }
376 __CG_QUALIFIER__ void sync() const { internal::tiled_group::sync(); }
377};
378
379template <unsigned int size, class ParentCGTy> class thread_block_tile;
380
389 private:
390 friend __CG_QUALIFIER__ coalesced_group coalesced_threads();
391 friend __CG_QUALIFIER__ thread_group tiled_partition(const thread_group& parent,
392 unsigned int tile_size);
393 friend __CG_QUALIFIER__ coalesced_group tiled_partition(const coalesced_group& parent,
394 unsigned int tile_size);
395 friend __CG_QUALIFIER__ coalesced_group binary_partition(const coalesced_group& cgrp, bool pred);
396
397 template <unsigned int fsize, class fparent> friend __CG_QUALIFIER__ coalesced_group
399
400 __CG_QUALIFIER__ coalesced_group new_tiled_group(unsigned int tile_size) const {
401 const bool pow2 = ((tile_size & (tile_size - 1)) == 0);
402
403 if (!tile_size || !pow2) {
404 return coalesced_group(0);
405 }
406
407 // If a tiled group is passed to be partitioned further into a coalesced_group.
408 // prepare a mask for further partitioning it so that it stays coalesced.
410 unsigned int base_offset = (thread_rank() & (~(tile_size - 1)));
411 unsigned int masklength =
412 min(static_cast<unsigned int>(num_threads()) - base_offset, tile_size);
413 lane_mask full_mask = (static_cast<int>(warpSize) == 32)
414 ? static_cast<lane_mask>((1u << 32) - 1)
415 : static_cast<lane_mask>(-1ull);
416 lane_mask member_mask = full_mask >> (warpSize - masklength);
417
418 member_mask <<= (__lane_id() & ~(tile_size - 1));
419 coalesced_group coalesced_tile = coalesced_group(member_mask);
420 coalesced_tile.coalesced_info.tiled_info.is_tiled = true;
421 coalesced_tile.coalesced_info.tiled_info.meta_group_rank = thread_rank() / tile_size;
422 coalesced_tile.coalesced_info.tiled_info.meta_group_size = num_threads() / tile_size;
423 return coalesced_tile;
424 }
425 // Here the parent coalesced_group is not partitioned.
426 else {
427 lane_mask member_mask = 0;
428 unsigned int tile_rank = 0;
429 int lanes_to_skip = ((thread_rank()) / tile_size) * tile_size;
430
431 for (unsigned int i = 0; i < warpSize; i++) {
432 lane_mask active = coalesced_info.member_mask & (static_cast<lane_mask>(1) << i);
433 // Make sure the lane is active
434 if (active) {
435 if (lanes_to_skip <= 0 && tile_rank < tile_size) {
436 // Prepare a member_mask that is appropriate for a tile
437 member_mask |= active;
438 tile_rank++;
439 }
440 lanes_to_skip--;
441 }
442 }
443 coalesced_group coalesced_tile = coalesced_group(member_mask);
444 coalesced_tile.coalesced_info.tiled_info.meta_group_rank = thread_rank() / tile_size;
445 coalesced_tile.coalesced_info.tiled_info.meta_group_size =
446 (num_threads() + tile_size - 1) / tile_size;
447 return coalesced_tile;
448 }
449 return coalesced_group(0);
450 }
451
452 protected:
453 // Constructor
454 explicit __CG_QUALIFIER__ coalesced_group(lane_mask member_mask)
455 : thread_group(internal::cg_coalesced_group) {
456 coalesced_info.member_mask = member_mask; // Which threads are active
458 __popcll(coalesced_info.member_mask); // How many threads are active
459 coalesced_info.tiled_info.is_tiled = false; // Not a partitioned group
462 }
463
464 public:
466 __CG_QUALIFIER__ unsigned int num_threads() const { return coalesced_info.num_threads; }
467
469 __CG_QUALIFIER__ unsigned int size() const { return num_threads(); }
470
472 __CG_QUALIFIER__ unsigned int thread_rank() const {
473 return internal::coalesced_group::masked_bit_count(coalesced_info.member_mask);
474 }
475
477 __CG_QUALIFIER__ void sync() const { internal::coalesced_group::sync(); }
478
481 __CG_QUALIFIER__ unsigned int meta_group_rank() const {
483 }
484
486 __CG_QUALIFIER__ unsigned int meta_group_size() const {
488 }
489
502 template <class T> __CG_QUALIFIER__ T shfl(T var, int srcRank) const {
503 srcRank = srcRank % static_cast<int>(num_threads());
504
505 int lane = (num_threads() == warpSize) ? srcRank
506 : (static_cast<int>(warpSize) == 64)
507 ? __fns64(coalesced_info.member_mask, 0, (srcRank + 1))
508 : __fns32(coalesced_info.member_mask, 0, (srcRank + 1));
509
510 return __shfl(var, lane, warpSize);
511 }
512
527 template <class T> __CG_QUALIFIER__ T shfl_down(T var, unsigned int lane_delta) const {
528 // Note: The cuda implementation appears to use the remainder of lane_delta
529 // and WARP_SIZE as the shift value rather than lane_delta itself.
530 // This is not described in the documentation and is not done here.
531
532 if (num_threads() == warpSize) {
533 return __shfl_down(var, lane_delta, warpSize);
534 }
535
536 int lane;
537 if (static_cast<int>(warpSize) == 64) {
538 lane = __fns64(coalesced_info.member_mask, __lane_id(), lane_delta + 1);
539 } else {
540 lane = __fns32(coalesced_info.member_mask, __lane_id(), lane_delta + 1);
541 }
542
543 if (lane == -1) {
544 lane = __lane_id();
545 }
546
547 return __shfl(var, lane, warpSize);
548 }
549
564 template <class T> __CG_QUALIFIER__ T shfl_up(T var, unsigned int lane_delta) const {
565 // Note: The cuda implementation appears to use the remainder of lane_delta
566 // and WARP_SIZE as the shift value rather than lane_delta itself.
567 // This is not described in the documentation and is not done here.
568
569 if (num_threads() == warpSize) {
570 return __shfl_up(var, lane_delta, warpSize);
571 }
572
573 int lane;
574 if (static_cast<int>(warpSize) == 64) {
575 lane = __fns64(coalesced_info.member_mask, __lane_id(), -(lane_delta + 1));
576 } else if (static_cast<int>(warpSize) == 32) {
577 lane = __fns32(coalesced_info.member_mask, __lane_id(), -(lane_delta + 1));
578 }
579
580 if (lane == -1) {
581 lane = __lane_id();
582 }
583
584 return __shfl(var, lane, warpSize);
585 }
586#if !defined(HIP_DISABLE_WARP_SYNC_BUILTINS)
587
595 __CG_QUALIFIER__ unsigned long long ballot(int pred) const {
596 return internal::helper::adjust_mask(
598 __ballot_sync<unsigned long long>(coalesced_info.member_mask, pred));
599 }
600
607 __CG_QUALIFIER__ int any(int pred) const {
608 return __any_sync(static_cast<unsigned long long>(coalesced_info.member_mask), pred);
609 }
610
617 __CG_QUALIFIER__ int all(int pred) const {
618 return __all_sync(static_cast<unsigned long long>(coalesced_info.member_mask), pred);
619 }
620
629 template <typename T> __CG_QUALIFIER__ unsigned long long match_any(T value) const {
630 return internal::helper::adjust_mask(
632 __match_any_sync(static_cast<unsigned long long>(coalesced_info.member_mask), value));
633 }
634
646 template <typename T> __CG_QUALIFIER__ unsigned long long match_all(T value, int& pred) const {
647 return internal::helper::adjust_mask(
649 __match_all_sync(static_cast<unsigned long long>(coalesced_info.member_mask), value,
650 &pred));
651 }
652#endif // HIP_DISABLE_WARP_SYNC_BUILTINS
653};
654
665 __builtin_amdgcn_is_invocable(__builtin_amdgcn_read_exec)
666 ? __builtin_amdgcn_read_exec()
667 : 0);
668}
669
670#ifndef DOXYGEN_SHOULD_SKIP_THIS
671
677__CG_QUALIFIER__ __hip_uint32_t thread_group::thread_rank() const {
678 switch (this->_type) {
679 case internal::cg_multi_grid: {
680 return (static_cast<const multi_grid_group*>(this)->thread_rank());
681 }
682 case internal::cg_grid: {
683 return (static_cast<const grid_group*>(this)->thread_rank());
684 }
685 case internal::cg_workgroup: {
686 return (static_cast<const thread_block*>(this)->thread_rank());
687 }
688 case internal::cg_tiled_group: {
689 return (static_cast<const tiled_group*>(this)->thread_rank());
690 }
691 case internal::cg_coalesced_group: {
692 return (static_cast<const coalesced_group*>(this)->thread_rank());
693 }
694 default: {
695 __hip_assert(false && "invalid cooperative group type");
696 return -1;
697 }
698 }
699}
700
706__CG_QUALIFIER__ bool thread_group::is_valid() const {
707 switch (this->_type) {
708 case internal::cg_multi_grid: {
709 return (static_cast<const multi_grid_group*>(this)->is_valid());
710 }
711 case internal::cg_grid: {
712 return (static_cast<const grid_group*>(this)->is_valid());
713 }
714 case internal::cg_workgroup: {
715 return (static_cast<const thread_block*>(this)->is_valid());
716 }
717 case internal::cg_tiled_group: {
718 return (static_cast<const tiled_group*>(this)->is_valid());
719 }
720 case internal::cg_coalesced_group: {
721 return (static_cast<const coalesced_group*>(this)->is_valid());
722 }
723 default: {
724 __hip_assert(false && "invalid cooperative group type");
725 return false;
726 }
727 }
728}
729
735__CG_QUALIFIER__ void thread_group::sync() const {
736 switch (this->_type) {
737 case internal::cg_multi_grid: {
738 static_cast<const multi_grid_group*>(this)->sync();
739 break;
740 }
741 case internal::cg_grid: {
742 static_cast<const grid_group*>(this)->sync();
743 break;
744 }
745 case internal::cg_workgroup: {
746 static_cast<const thread_block*>(this)->sync();
747 break;
748 }
749 case internal::cg_tiled_group: {
750 static_cast<const tiled_group*>(this)->sync();
751 break;
752 }
753 case internal::cg_coalesced_group: {
754 static_cast<const coalesced_group*>(this)->sync();
755 break;
756 }
757 default: {
758 __hip_assert(false && "invalid cooperative group type");
759 }
760 }
761}
762
763#endif
764
782template <class CGTy> __CG_QUALIFIER__ __hip_uint32_t group_size(CGTy const& g) {
783 return g.num_threads();
784}
785
797template <class CGTy> __CG_QUALIFIER__ __hip_uint32_t thread_rank(CGTy const& g) {
798 return g.thread_rank();
799}
800
810template <class CGTy> __CG_QUALIFIER__ bool is_valid(CGTy const& g) { return g.is_valid(); }
811
821template <class CGTy> __CG_QUALIFIER__ void sync(CGTy const& g) { g.sync(); }
822
823// Doxygen end group CooperativeGAPI
831template <unsigned int tileSize> class tile_base {
832 protected:
833 _CG_STATIC_CONST_DECL_ unsigned int numThreads = tileSize;
834
835 public:
837 _CG_STATIC_CONST_DECL_ unsigned int thread_rank() {
838 return (internal::workgroup::thread_rank() & (numThreads - 1));
839 }
840
842 __CG_STATIC_QUALIFIER__ unsigned int num_threads() { return numThreads; }
843
846 __CG_STATIC_QUALIFIER__ unsigned int size() { return num_threads(); }
847};
848
854template <unsigned int size> class thread_block_tile_base : public tile_base<size> {
855 static_assert(is_valid_tile_size<size>::value,
856 "Tile size is either not a power of 2 or greater than the wavefront size");
858
859 template <unsigned int fsize, class fparent> friend __CG_QUALIFIER__ coalesced_group
861
862#if !defined(HIP_DISABLE_WARP_SYNC_BUILTINS)
863 __CG_QUALIFIER__ unsigned long long build_mask() const {
864 unsigned long long mask = ~0ull >> (64 - numThreads);
865 // thread_rank() gives thread id from 0..thread launch size.
866 return mask << (((internal::workgroup::thread_rank() % warpSize) / numThreads) * numThreads);
867 }
868#endif // HIP_DISABLE_WARP_SYNC_BUILTINS
869
870 public:
871 __CG_STATIC_QUALIFIER__ void sync() { internal::tiled_group::sync(); }
872
873 template <class T> __CG_QUALIFIER__ T shfl(T var, int srcRank) const {
874 return (__shfl(var, srcRank, numThreads));
875 }
876
877 template <class T> __CG_QUALIFIER__ T shfl_down(T var, unsigned int lane_delta) const {
878 return (__shfl_down(var, lane_delta, numThreads));
879 }
880
881 template <class T> __CG_QUALIFIER__ T shfl_up(T var, unsigned int lane_delta) const {
882 return (__shfl_up(var, lane_delta, numThreads));
883 }
884
885 template <class T> __CG_QUALIFIER__ T shfl_xor(T var, unsigned int laneMask) const {
886 return (__shfl_xor(var, laneMask, numThreads));
887 }
888
889#if !defined(HIP_DISABLE_WARP_SYNC_BUILTINS)
890 __CG_QUALIFIER__ unsigned long long ballot(int pred) const {
891 const auto mask = build_mask();
892 return internal::helper::adjust_mask(mask, __ballot_sync(mask, pred));
893 }
894
895 __CG_QUALIFIER__ int any(int pred) const { return __any_sync(build_mask(), pred); }
896
897 __CG_QUALIFIER__ int all(int pred) const { return __all_sync(build_mask(), pred); }
898
899 template <typename T> __CG_QUALIFIER__ unsigned long long match_any(T value) const {
900 const auto mask = build_mask();
901 return internal::helper::adjust_mask(mask, __match_any_sync(mask, value));
902 }
903
904 template <typename T> __CG_QUALIFIER__ unsigned long long match_all(T value, int& pred) const {
905 const auto mask = build_mask();
906 return internal::helper::adjust_mask(mask, __match_all_sync(mask, value, &pred));
907 }
908#endif // HIP_DISABLE_WARP_SYNC_BUILTINS
909};
910
913template <unsigned int tileSize, typename ParentCGTy> class parent_group_info {
914 public:
917 __CG_STATIC_QUALIFIER__ unsigned int meta_group_rank() {
918 return ParentCGTy::thread_rank() / tileSize;
919 }
920
922 __CG_STATIC_QUALIFIER__ unsigned int meta_group_size() {
923 return (ParentCGTy::num_threads() + tileSize - 1) / tileSize;
924 }
925};
926
933template <unsigned int tileSize, class ParentCGTy> class thread_block_tile_type
934 : public thread_block_tile_base<tileSize>,
935 public tiled_group,
936 public parent_group_info<tileSize, ParentCGTy> {
937 _CG_STATIC_CONST_DECL_ unsigned int numThreads = tileSize;
939
940 protected:
941 __CG_QUALIFIER__ thread_block_tile_type() : tiled_group(numThreads) {
944 }
945
954
955 public:
957 using tbtBase::size;
960};
961
962// Partial template specialization
963template <unsigned int tileSize> class thread_block_tile_type<tileSize, void>
964 : public thread_block_tile_base<tileSize>, public tiled_group {
965 _CG_STATIC_CONST_DECL_ unsigned int numThreads = tileSize;
966
968
969 protected:
978
979 public:
981 using tbtBase::size;
982 using tbtBase::sync;
984
987 __CG_QUALIFIER__ unsigned int meta_group_rank() const {
989 }
990
992 __CG_QUALIFIER__ unsigned int meta_group_size() const {
994 }
995 // Doxygen end group CooperativeG
999};
1000
1001__CG_QUALIFIER__ thread_group this_thread() {
1002 thread_group g(internal::group_type::cg_coalesced_group, 1, __ockl_activelane_u32());
1003 return g;
1004}
1005
1013__CG_QUALIFIER__ thread_group tiled_partition(const thread_group& parent, unsigned int tile_size) {
1014 if (parent.cg_type() == internal::cg_tiled_group) {
1015 const tiled_group* cg = static_cast<const tiled_group*>(&parent);
1016 return cg->new_tiled_group(tile_size);
1017 } else if (parent.cg_type() == internal::cg_coalesced_group) {
1018 const coalesced_group* cg = static_cast<const coalesced_group*>(&parent);
1019 return cg->new_tiled_group(tile_size);
1020 } else {
1021 const thread_block* tb = static_cast<const thread_block*>(&parent);
1022 return tb->new_tiled_group(tile_size);
1023 }
1024}
1025
1026// Thread block type overload
1027__CG_QUALIFIER__ thread_group tiled_partition(const thread_block& parent, unsigned int tile_size) {
1028 return (parent.new_tiled_group(tile_size));
1029}
1030
1031__CG_QUALIFIER__ tiled_group tiled_partition(const tiled_group& parent, unsigned int tile_size) {
1032 return (parent.new_tiled_group(tile_size));
1033}
1034
1035// If a coalesced group is passed to be partitioned, it should remain coalesced
1036__CG_QUALIFIER__ coalesced_group tiled_partition(const coalesced_group& parent,
1037 unsigned int tile_size) {
1038 return (parent.new_tiled_group(tile_size));
1039}
1040
1041namespace impl {
1042template <unsigned int size, class ParentCGTy> class thread_block_tile_internal;
1043
1044template <unsigned int size, class ParentCGTy> class thread_block_tile_internal
1045 : public thread_block_tile_type<size, ParentCGTy> {
1046 protected:
1047 template <unsigned int tbtSize, class tbtParentT> __CG_QUALIFIER__ thread_block_tile_internal(
1050
1051 __CG_QUALIFIER__ thread_block_tile_internal(const thread_block& g)
1052 : thread_block_tile_type<size, ParentCGTy>() {}
1053};
1054
1055// becomes to std::true_type if the group is tiled and has a size known at compile time
1056template <class TyGroup>
1057struct isTiledGroup : __hip_internal::false_type {
1058};
1059
1060template <unsigned int N, class ParentCGTy>
1062 : __hip_internal::integral_constant<bool,
1063 (N == 1 || N == 2 || N == 4 || N == 8 ||
1064 N == 16 || N == 32 || N == 64)> {
1065};
1066
1067// returns the size of tile_group provided it is known at compile time
1068template <class TyGroup>
1069struct tiledGroupSize : __hip_internal::integral_constant<int, 0> {
1070
1071};
1072template <unsigned int N, class ParentCGTy>
1074 : __hip_internal::integral_constant<int, N> {
1075};
1076
1077template <class TyGroup>
1078struct isCoalescedGroup : __hip_internal::false_type {
1079};
1080
1081template <>
1082struct isCoalescedGroup<cooperative_groups::coalesced_group> : __hip_internal::true_type {
1083};
1084} // namespace impl
1085
1094template <unsigned int size, class ParentCGTy> class thread_block_tile
1095 : public impl::thread_block_tile_internal<size, ParentCGTy> {
1096 protected:
1097 __CG_QUALIFIER__ thread_block_tile(const ParentCGTy& g)
1098 : impl::thread_block_tile_internal<size, ParentCGTy>(g) {}
1099
1100 public:
1101 __CG_QUALIFIER__ operator thread_block_tile<size, void>() const {
1102 return thread_block_tile<size, void>(*this);
1103 }
1104
1105#ifdef DOXYGEN_SHOULD_INCLUDE_THIS
1106
1108 __CG_QUALIFIER__ unsigned int thread_rank() const;
1109
1111 __CG_QUALIFIER__ void sync();
1112
1115 __CG_QUALIFIER__ unsigned int meta_group_rank() const;
1116
1118 __CG_QUALIFIER__ unsigned int meta_group_size() const;
1119
1132 template <class T> __CG_QUALIFIER__ T shfl(T var, int srcRank) const;
1133
1148 template <class T> __CG_QUALIFIER__ T shfl_down(T var, unsigned int lane_delta) const;
1149
1164 template <class T> __CG_QUALIFIER__ T shfl_up(T var, unsigned int lane_delta) const;
1165
1178 template <class T> __CG_QUALIFIER__ T shfl_xor(T var, unsigned int laneMask) const;
1179
1187 __CG_QUALIFIER__ unsigned long long ballot(int pred) const;
1188
1195 __CG_QUALIFIER__ int any(int pred) const;
1196
1203 __CG_QUALIFIER__ int all(int pred) const;
1204
1213 template <typename T> __CG_QUALIFIER__ unsigned long long match_any(T value) const;
1214
1226 template <typename T> __CG_QUALIFIER__ unsigned long long match_all(T value, int& pred) const;
1227
1228#endif
1229};
1230
1231template <unsigned int size> class thread_block_tile<size, void>
1232 : public impl::thread_block_tile_internal<size, void> {
1233 template <unsigned int, class ParentCGTy> friend class thread_block_tile;
1234
1235 protected:
1236 public:
1237 template <class ParentCGTy>
1239 : impl::thread_block_tile_internal<size, void>(g) {}
1240};
1241
1242template <unsigned int size, class ParentCGTy = void> class thread_block_tile;
1243
1244namespace impl {
1245template <unsigned int size, class ParentCGTy> struct tiled_partition_internal;
1246
1247template <unsigned int size> struct tiled_partition_internal<size, thread_block>
1248 : public thread_block_tile<size, thread_block> {
1251};
1252
1253// ParentCGTy = thread_block_tile<ParentSize, GrandParentCGTy> specialization
1254template <unsigned int size, unsigned int ParentSize, class GrandParentCGTy>
1255struct tiled_partition_internal<size, thread_block_tile<ParentSize, GrandParentCGTy> >
1256 : public thread_block_tile<size, thread_block_tile<ParentSize, GrandParentCGTy> > {
1257 static_assert(size < ParentSize, "Sub tile size must be < parent tile size in tiled_partition");
1258
1260 : thread_block_tile<size, thread_block_tile<ParentSize, GrandParentCGTy> >(g) {}
1261};
1262
1263} // namespace impl
1264
1277template <unsigned int size, class ParentCGTy>
1278__CG_QUALIFIER__ thread_block_tile<size, ParentCGTy> tiled_partition(const ParentCGTy& g) {
1279 static_assert(is_valid_tile_size<size>::value,
1280 "Tiled partition with size > wavefront size. Currently not supported ");
1282}
1283
1284#if !defined(HIP_DISABLE_WARP_SYNC_BUILTINS)
1285
1294__CG_QUALIFIER__ coalesced_group binary_partition(const coalesced_group& cgrp, bool pred) {
1295 auto mask = __ballot_sync<unsigned long long>(cgrp.coalesced_info.member_mask, pred);
1296
1297 if (pred) {
1298 return coalesced_group(mask);
1299 } else {
1300 return coalesced_group(cgrp.coalesced_info.member_mask ^ mask);
1301 }
1302}
1303
1315template <unsigned int size, class parent>
1317 bool pred) {
1318 auto mask = __ballot_sync<unsigned long long>(tgrp.build_mask(), pred);
1319
1320 if (pred) {
1321 return coalesced_group(mask);
1322 } else {
1323 return coalesced_group(tgrp.build_mask() ^ mask);
1324 }
1325}
1326
1327
1328template <class T>
1329struct plus {
1330 __CG_QUALIFIER__ T operator()(T lhs, T rhs) const
1331 {
1332 return lhs + rhs;
1333 }
1334};
1335
1336template <class T>
1337struct less {
1338 __CG_QUALIFIER__ T operator()(T lhs, T rhs) const
1339 {
1340 return lhs < rhs? lhs : rhs;
1341 }
1342};
1343
1344template <class T>
1345struct greater {
1346 __CG_QUALIFIER__ T operator()(T lhs, T rhs) const
1347 {
1348 return lhs < rhs? rhs : lhs;
1349 }
1350};
1351
1352template <class T>
1353struct bit_and {
1354 __CG_QUALIFIER__ T operator()(T lhs, T rhs) const
1355 {
1356 return lhs & rhs;
1357 }
1358};
1359
1360template <class T>
1361struct bit_xor {
1362 __CG_QUALIFIER__ T operator()(T lhs, T rhs) const
1363 {
1364 return lhs ^ rhs;
1365 }
1366};
1367
1368template <class T>
1369struct bit_or {
1370 __CG_QUALIFIER__ T operator()(T lhs, T rhs) const
1371 {
1372 return lhs | rhs;
1373 }
1374};
1375
1376namespace impl {
1377// when instantiated with two parameter types, allows to know if there are the same, regardless
1378// of const/volatile qualifiers
1379template <typename T, typename U>
1380using is_param_type_same = __hip_internal::is_same<typename __hip_internal::remove_cvref<T>,
1381 typename __hip_internal::remove_cvref<U>>;
1382
1383template <class T, class Op>
1384struct isArithmeticFunc : __hip_internal::false_type {
1385};
1386
1387template <class T>
1388struct isArithmeticFunc<T, cooperative_groups::plus<T>> : __hip_internal::true_type {
1389};
1390
1391template <class T>
1392struct isArithmeticFunc<T, cooperative_groups::less<T>> : __hip_internal::true_type {
1393};
1394
1395template <class T>
1396struct isArithmeticFunc<T, cooperative_groups::greater<T>> : __hip_internal::true_type {
1397};
1398
1399template <class T, class Op>
1400struct isBooleanFunc : __hip_internal::false_type {
1401};
1402
1403template <class T>
1404struct isBooleanFunc<T, cooperative_groups::bit_and<T>> : __hip_internal::true_type {
1405};
1406
1407template <class T>
1408struct isBooleanFunc<T, cooperative_groups::bit_or<T>> : __hip_internal::true_type {
1409};
1410
1411template <class T>
1412struct isBooleanFunc<T, cooperative_groups::bit_xor<T>> : __hip_internal::true_type {
1413};
1414
1415// this is the value to return in exclusive_scan, for lane 0
1416template <class T, class Op>
1419 {
1420 T result = {};
1421 return result;
1422 }
1423};
1424
1425template <class T>
1428 {
1429 T result {};
1430 return ~result;
1431 }
1432};
1433
1434template <class T>
1437 {
1438 // CUDA would return 0 in this case. But in our case we mimic what __ockl_wfscan_*
1439 // would do
1440 return __hip_internal::NumericLimits<T>::maximum();
1441 }
1442};
1443
1444template <class T>
1447 {
1448 return __hip_internal::NumericLimits<T>::minimum();
1449 }
1450};
1451
1452// calculates the necessary warp mask for cooperative groups that support reduce(), or
1453// inclusive/exlcusive_scan()
1454template <typename TyGroup>
1455__CG_QUALIFIER__ unsigned long long groupMask(const TyGroup& group)
1456{
1457 unsigned long long mask = ~0ull;
1458
1460 mask = group.coalesced_info.member_mask;
1461 } else {
1462 // we cannot simply just use the __activemask() here, because more than one tile could have active
1463 // threads at a time; we need to mask away the threads that not part of this tile first
1464 mask >>= (64 - group.num_threads());
1465 mask <<= (((internal::workgroup::thread_rank() % warpSize) / group.num_threads()) * group.num_threads());
1466 }
1467
1468 return mask;
1469}
1470
1471// backward permute implementation for cooperative group operations, i.e.
1472// for up to 32 bytes (__hip_ds_bpermute() can only do 4 bytes at a time,
1473// this function calls it (or the floating point version) multiple times to
1474// implement it for bigger sizes
1475template <bool isPrimitiveType, class T, size_t NumPermutes, typename __hip_internal::enable_if<NumPermutes == 0, int>::type = 0>
1477{
1478}
1479
1480// trivial case: the type fits within the permute size
1481template <bool IsPrimitiveType, class T, size_t NumPermutes, typename __hip_internal::enable_if<IsPrimitiveType && NumPermutes == 1, int>::type = 0>
1482__CG_QUALIFIER__ void bPermute(T& permuteResult, T result, int from)
1483{
1484 auto backwardPermute = [](int index, T arg) {
1485 if constexpr (__hip_internal::is_floating_point<T>::value &&
1486 sizeof(T) <= 4) {
1487 return __hip_ds_bpermutef(index, arg);
1488 } else {
1489 return __hip_ds_bpermute(index, arg);
1490 }
1491 };
1492
1493 if constexpr (sizeof(T) == 2) {
1494 union {
1495 int i;
1496 T f;
1497 } tmp;
1498
1499 tmp.f = result;
1500 tmp.i = __hip_ds_bpermute(from << 2, tmp.i);
1501 permuteResult = tmp.f;
1502 } else if constexpr (sizeof(T) == 4) {
1503 auto bPermuteResult = backwardPermute(from << 2, result);
1504 __builtin_memcpy(&permuteResult, &bPermuteResult, sizeof(result));
1505 } else {
1506 static_assert(__hip_internal::is_void<T>::value, "Unexpected type");
1507 }
1508}
1509
1510// Overload when we need multiple ds_permute, because one is not enough
1511template <bool IsPrimitiveType, class T, size_t NumPermutes>
1513{
1514 // ds_bpermute only deals with 32-bit sizes, so for other sizes
1515 // we need to call the permute multiple times
1516 for (int i = 0; i < NumPermutes; i++) {
1518 }
1519}
1520
1521} // namespace impl
1522#endif
1523
1531 friend __CG_QUALIFIER__ cluster_group this_cluster();
1532
1533 // Default constructor, hidden
1534 __CG_QUALIFIER__ cluster_group() {}
1535
1536 public:
1537 using arrival_token = struct {};
1538
1539 // Sync the cluster, equivalent to c.barrier_wait(c.barrier_arrive());
1540 __CG_STATIC_QUALIFIER__ void sync() { internal::cluster::sync(); }
1541
1542 // Arrive on a cluster barrier, returns token that needs to be passed to barrier_wait
1543 __CG_STATIC_QUALIFIER__ arrival_token barrier_arrive() {
1544 // signal user cluster barrier
1545 internal::cluster::barrier_arrive();
1546 return arrival_token();
1547 }
1548
1549 // Wait on arrival_token
1550 __CG_STATIC_QUALIFIER__ void barrier_wait(arrival_token&&) { internal::cluster::barrier_wait(); }
1551
1552 // TODO: implement this when compiler work is done
1553 // block rank to which shared memory address belongs to
1554 // __CG_STATIC_QUALIFIER__ unsigned int query_shared_rank(const void* addr) {}
1555 // Obtain the address of shared memory variable of another block in the cluster
1556 // template <typename T> __CG_STATIC_QUALIFIER__ T* map_shared_rank(T* addr, int rank) {}
1557
1558 // index of the calling block within cluster
1559 __CG_STATIC_QUALIFIER__ dim3 block_index() { return internal::cluster::block_index(); }
1560
1561 // Rank of calling block within [0, num_blocks)
1562 __CG_STATIC_QUALIFIER__ unsigned int block_rank() { return internal::cluster::block_rank(); }
1563
1564 // index of the calling thread within cluster
1565 __CG_STATIC_QUALIFIER__ dim3 thread_index() { return internal::cluster::thread_index(); }
1566
1567 // Rank of calling thread within [0, num_threads)
1568 __CG_STATIC_QUALIFIER__ unsigned int thread_rank() { return internal::cluster::thread_rank(); }
1569
1570 // Dimensions of launched cluster in unit of blocks
1571 __CG_STATIC_QUALIFIER__ dim3 dim_blocks() { return internal::cluster::dim_blocks(); }
1572
1573 // total number of blocks in the group
1574 __CG_STATIC_QUALIFIER__ unsigned int num_blocks() { return internal::cluster::num_blocks(); }
1575
1576 // Dimensions of launched cluster in unit of threads
1577 __CG_STATIC_QUALIFIER__ dim3 dim_threads() { return internal::cluster::dim_threads(); }
1578
1579 // Total number of threads in the group
1580 __CG_STATIC_QUALIFIER__ unsigned int num_threads() { return internal::cluster::num_threads(); }
1581
1582 // Get address of shared memory variable in another cluster
1583 template <typename T> __CG_STATIC_QUALIFIER__ T* map_shared_rank(T* in, int rank) {
1584 return internal::cluster::map_shared_rank<T>(in, rank);
1585 }
1586
1587 // Return block rank of shared memory address
1588 __CG_STATIC_QUALIFIER__ unsigned int query_shared_rank(const void* in) {
1589 return internal::cluster::query_shared_rank(in);
1590 }
1591
1592 // Alias of num_threads
1593 __CG_STATIC_QUALIFIER__ unsigned int size() { return num_threads(); }
1594};
1595
1601__CG_QUALIFIER__ cluster_group this_cluster() {
1602 cluster_group cg;
1603 return cg;
1604}
1605} // namespace cooperative_groups
1606
1607#endif // __cplusplus
1608#endif // HIP_INCLUDE_HIP_AMD_DETAIL_HIP_COOPERATIVE_GROUPS_H
Cluster group.
Definition amd_hip_cooperative_groups.h:1530
static unsigned int query_shared_rank(const void *in)
Definition amd_hip_cooperative_groups.h:1588
static unsigned int thread_rank()
Definition amd_hip_cooperative_groups.h:1568
static dim3 thread_index()
Definition amd_hip_cooperative_groups.h:1565
static T * map_shared_rank(T *in, int rank)
Definition amd_hip_cooperative_groups.h:1583
static void sync()
Definition amd_hip_cooperative_groups.h:1540
{} arrival_token
Definition amd_hip_cooperative_groups.h:1537
static dim3 block_index()
Definition amd_hip_cooperative_groups.h:1559
static void barrier_wait(arrival_token &&)
Definition amd_hip_cooperative_groups.h:1550
static unsigned int block_rank()
Definition amd_hip_cooperative_groups.h:1562
static unsigned int num_threads()
Definition amd_hip_cooperative_groups.h:1580
static unsigned int size()
Definition amd_hip_cooperative_groups.h:1593
static arrival_token barrier_arrive()
Definition amd_hip_cooperative_groups.h:1543
static unsigned int num_blocks()
Definition amd_hip_cooperative_groups.h:1574
friend cluster_group this_cluster()
get cluster group
Definition amd_hip_cooperative_groups.h:1601
static dim3 dim_threads()
Definition amd_hip_cooperative_groups.h:1577
static dim3 dim_blocks()
Definition amd_hip_cooperative_groups.h:1571
The coalesced_group cooperative group type.
Definition amd_hip_cooperative_groups.h:388
The grid cooperative group type.
Definition amd_hip_cooperative_groups.h:185
Definition amd_hip_cooperative_groups.h:1045
thread_block_tile_internal(const thread_block &g)
Definition amd_hip_cooperative_groups.h:1051
thread_block_tile_internal(const thread_block_tile_internal< tbtSize, tbtParentT > &g)
Definition amd_hip_cooperative_groups.h:1047
The multi-grid cooperative group type.
Definition amd_hip_cooperative_groups.h:130
User exposed API that captures the state of the parent group pre-partition.
Definition amd_hip_cooperative_groups.h:913
thread_block_tile(const thread_block_tile< size, ParentCGTy > &g)
Definition amd_hip_cooperative_groups.h:1238
Definition amd_hip_cooperative_groups.h:854
Group type - thread_block_tile.
Definition amd_hip_cooperative_groups.h:936
Group type - thread_block_tile.
Definition amd_hip_cooperative_groups.h:1095
T shfl_down(T var, unsigned int lane_delta) const
Shuffle down operation on group level.
int any(int pred) const
Any function on group level.
unsigned long long ballot(int pred) const
Ballot function on group level.
thread_block_tile(const ParentCGTy &g)
Definition amd_hip_cooperative_groups.h:1097
unsigned int meta_group_rank() const
unsigned int thread_rank() const
Rank of the calling thread within [0, num_threads() ).
T shfl_xor(T var, unsigned int laneMask) const
Shuffle xor operation on group level.
int all(int pred) const
All function on group level.
unsigned long long match_any(T value) const
Match any function on group level.
unsigned long long match_all(T value, int &pred) const
Match all function on group level.
unsigned int meta_group_size() const
Returns the number of groups created when the parent group was partitioned.
T shfl_up(T var, unsigned int lane_delta) const
Shuffle up operation on group level.
void sync()
Synchronizes the threads in the group.
T shfl(T var, int srcRank) const
Shuffle operation on group level.
The workgroup (thread-block in CUDA terminology) cooperative group type.
Definition amd_hip_cooperative_groups.h:241
The base type of all cooperative group types.
Definition amd_hip_cooperative_groups.h:39
Definition amd_hip_cooperative_groups.h:831
The tiled_group cooperative group type.
Definition amd_hip_cooperative_groups.h:332
const struct texture< T, dim, readMode > const void size_t size
Definition hip_runtime_api.h:10829
bool is_valid(CGTy const &g)
Returns true if the group has not violated any API constraints.
Definition amd_hip_cooperative_groups.h:810
void sync(CGTy const &g)
Synchronizes the threads in the group.
Definition amd_hip_cooperative_groups.h:821
__hip_uint32_t group_size(CGTy const &g)
Returns the size of the group.
Definition amd_hip_cooperative_groups.h:782
__hip_uint32_t thread_rank(CGTy const &g)
Returns the rank of thread of the group.
Definition amd_hip_cooperative_groups.h:797
thread_block this_thread_block()
User-exposed API interface to construct workgroup cooperative group type object - thread_block.
Definition amd_hip_cooperative_groups.h:321
coalesced_group binary_partition(const coalesced_group &cgrp, bool pred)
Binary partition.
Definition amd_hip_cooperative_groups.h:1294
thread_group tiled_partition(const thread_group &parent, unsigned int tile_size)
User-exposed API to partition groups.
Definition amd_hip_cooperative_groups.h:1013
multi_grid_group this_multi_grid()
User-exposed API interface to construct grid cooperative group type object - multi_grid_group.
Definition amd_hip_cooperative_groups.h:171
coalesced_group coalesced_threads()
User-exposed API to create coalesced groups.
Definition amd_hip_cooperative_groups.h:663
grid_group this_grid()
User-exposed API interface to construct grid cooperative group type object - grid_group.
Definition amd_hip_cooperative_groups.h:230
void sync() const
Synchronizes the threads in the group.
Definition amd_hip_cooperative_groups.h:376
T shfl_xor(T var, unsigned int laneMask) const
Definition amd_hip_cooperative_groups.h:885
static constexpr unsigned int numThreads
Definition amd_hip_cooperative_groups.h:833
friend multi_grid_group this_multi_grid()
User-exposed API interface to construct grid cooperative group type object - multi_grid_group.
Definition amd_hip_cooperative_groups.h:171
void sync() const
Synchronizes the threads in the group.
Definition amd_hip_cooperative_groups.h:477
static void sync()
Definition amd_hip_cooperative_groups.h:871
void barrier_wait(arrival_token &&t) const
Arrive at a barrier.
Definition amd_hip_cooperative_groups.h:215
unsigned int num_threads
Definition amd_hip_cooperative_groups.h:62
__hip_uint32_t thread_rank() const
Rank of the calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:197
arrival_token barrier_arrive() const
Arrive at a barrier.
Definition amd_hip_cooperative_groups.h:209
void sync() const
Synchronizes the threads in the group.
Definition amd_hip_cooperative_groups.h:203
__hip_uint32_t size() const
Total number of threads in the group (alias of num_threads())
Definition amd_hip_cooperative_groups.h:84
unsigned int size() const
Total number of threads in the group (alias of num_threads())
Definition amd_hip_cooperative_groups.h:469
__hip_uint32_t num_grids()
Definition amd_hip_cooperative_groups.h:143
unsigned long long match_all(T value, int &pred) const
Definition amd_hip_cooperative_groups.h:904
unsigned long long match_any(T value) const
Match any function on group level.
Definition amd_hip_cooperative_groups.h:629
friend thread_block this_thread_block()
User-exposed API interface to construct workgroup cooperative group type object - thread_block.
Definition amd_hip_cooperative_groups.h:321
static unsigned int meta_group_size()
Returns the number of groups created when the parent group was partitioned.
Definition amd_hip_cooperative_groups.h:922
unsigned int signal
Definition amd_hip_cooperative_groups.h:206
unsigned int meta_group_rank() const
Definition amd_hip_cooperative_groups.h:481
dim3 group_dim() const
Definition amd_hip_cooperative_groups.h:204
unsigned int meta_group_rank() const
Definition amd_hip_cooperative_groups.h:987
__hip_uint32_t _num_threads
Type of the thread_group.
Definition amd_hip_cooperative_groups.h:44
__hip_uint32_t block_rank() const
Rank of the block in calling thread within [0, num_threads() ).
static unsigned int num_threads()
Number of threads within this tile.
Definition amd_hip_cooperative_groups.h:842
thread_group(internal::group_type type, __hip_uint32_t num_threads=static_cast< __hip_uint64_t >(0), __hip_uint64_t mask=static_cast< __hip_uint64_t >(0))
Definition amd_hip_cooperative_groups.h:52
unsigned int meta_group_size() const
Returns the number of groups created when the parent group was partitioned.
Definition amd_hip_cooperative_groups.h:486
unsigned int thread_rank() const
Rank of the calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:372
unsigned int thread_rank() const
Rank of the calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:472
unsigned int meta_group_size() const
Returns the number of groups created when the parent group was partitioned.
Definition amd_hip_cooperative_groups.h:992
int all(int pred) const
All function on group level.
Definition amd_hip_cooperative_groups.h:617
unsigned int cg_type() const
Returns the type of the group.
Definition amd_hip_cooperative_groups.h:86
T shfl(T var, int srcRank) const
Definition amd_hip_cooperative_groups.h:873
thread_group new_tiled_group(unsigned int tile_size) const
Definition amd_hip_cooperative_groups.h:255
static __hip_uint32_t size()
Total number of threads in the group (alias of num_threads())
Definition amd_hip_cooperative_groups.h:294
unsigned int num_threads() const
Definition amd_hip_cooperative_groups.h:364
unsigned int num_threads() const
Definition amd_hip_cooperative_groups.h:466
void barrier_wait(arrival_token &&) const
Arrive at a barrier.
Definition amd_hip_cooperative_groups.h:308
tiled_group(unsigned int tileSize)
Definition amd_hip_cooperative_groups.h:356
unsigned int meta_group_rank
Definition amd_hip_cooperative_groups.h:63
void sync() const
Synchronizes the threads in the group.
unsigned long long match_all(T value, int &pred) const
Match all function on group level.
Definition amd_hip_cooperative_groups.h:646
thread_block_tile_type()
Definition amd_hip_cooperative_groups.h:941
__hip_uint32_t block_rank() const
Rank of the block in calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:199
grid_group(__hip_uint32_t size)
Construct grid thread group (through the API this_grid())
Definition amd_hip_cooperative_groups.h:192
__hip_uint32_t grid_rank()
Definition amd_hip_cooperative_groups.h:147
static constexpr unsigned int thread_rank()
Rank of the thread within this tile.
Definition amd_hip_cooperative_groups.h:837
bool is_tiled
Definition amd_hip_cooperative_groups.h:61
unsigned long long ballot(int pred) const
Ballot function on group level.
Definition amd_hip_cooperative_groups.h:595
void sync() const
Synchronizes the threads in the group.
Definition amd_hip_cooperative_groups.h:155
T shfl_up(T var, unsigned int lane_delta) const
Definition amd_hip_cooperative_groups.h:881
static __hip_uint32_t block_rank()
Rank of the block in calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:286
static dim3 group_index()
Returns 3-dimensional block index within the grid.
Definition amd_hip_cooperative_groups.h:278
unsigned long long groupMask(const TyGroup &)
Definition amd_hip_cooperative_groups.h:1455
unsigned int num_threads
Definition amd_hip_cooperative_groups.h:69
static void sync()
Synchronizes the threads in the group.
Definition amd_hip_cooperative_groups.h:298
friend coalesced_group binary_partition(const thread_block_tile< fsize, fparent > &tgrp, bool pred)
__hip_uint32_t thread_rank() const
Rank of the calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:149
bool is_valid() const
Returns true if the group has not violated any API constraints.
static unsigned int size()
Definition amd_hip_cooperative_groups.h:846
friend thread_group tiled_partition(const thread_group &parent, unsigned int tile_size)
User-exposed API to partition groups.
Definition amd_hip_cooperative_groups.h:1013
int any(int pred) const
Definition amd_hip_cooperative_groups.h:895
int all(int pred) const
Definition amd_hip_cooperative_groups.h:897
__hip_uint64_t _mask
Total number of threads in the thread_group.
Definition amd_hip_cooperative_groups.h:45
friend thread_group this_thread()
Definition amd_hip_cooperative_groups.h:1001
bool is_valid() const
Returns true if the group has not violated any API constraints.
Definition amd_hip_cooperative_groups.h:201
__hip_uint32_t _type
Definition amd_hip_cooperative_groups.h:43
unsigned long long match_any(T value) const
Definition amd_hip_cooperative_groups.h:899
unsigned int size() const
Total number of threads in the group (alias of num_threads())
Definition amd_hip_cooperative_groups.h:369
struct cooperative_groups::thread_group::_coalesced_info coalesced_info
lane_mask member_mask
Definition amd_hip_cooperative_groups.h:68
thread_block(__hip_uint32_t size)
Definition amd_hip_cooperative_groups.h:252
unsigned int meta_group_size
Definition amd_hip_cooperative_groups.h:64
multi_grid_group(__hip_uint32_t size)
Construct multi-grid thread group (through the API this_multi_grid())
Definition amd_hip_cooperative_groups.h:137
int any(int pred) const
Any function on group level.
Definition amd_hip_cooperative_groups.h:607
thread_group this_thread()
Definition amd_hip_cooperative_groups.h:1001
cluster_group this_cluster()
get cluster group
Definition amd_hip_cooperative_groups.h:1601
static unsigned int meta_group_rank()
Definition amd_hip_cooperative_groups.h:917
__hip_uint32_t num_threads() const
Definition amd_hip_cooperative_groups.h:82
struct _tiled_info tiled_info
Definition amd_hip_cooperative_groups.h:70
friend coalesced_group coalesced_threads()
User-exposed API to create coalesced groups.
Definition amd_hip_cooperative_groups.h:663
friend coalesced_group binary_partition(const coalesced_group &cgrp, bool pred)
Binary partition.
Definition amd_hip_cooperative_groups.h:1294
static dim3 thread_index()
Returns 3-dimensional thread index within the block.
Definition amd_hip_cooperative_groups.h:280
friend class thread_block
Definition amd_hip_cooperative_groups.h:76
coalesced_group(lane_mask member_mask)
Definition amd_hip_cooperative_groups.h:454
T shfl_down(T var, unsigned int lane_delta) const
Shuffle down operation on group level.
Definition amd_hip_cooperative_groups.h:527
static bool is_valid()
Returns true if the group has not violated any API constraints.
Definition amd_hip_cooperative_groups.h:296
dim3 group_dim()
Returns the group dimensions.
Definition amd_hip_cooperative_groups.h:300
thread_block_tile_type(unsigned int meta_group_rank, unsigned int meta_group_size)
Definition amd_hip_cooperative_groups.h:970
static __hip_uint32_t num_threads()
Definition amd_hip_cooperative_groups.h:290
unsigned long long ballot(int pred) const
Definition amd_hip_cooperative_groups.h:890
T shfl(T var, int srcRank) const
Shuffle operation on group level.
Definition amd_hip_cooperative_groups.h:502
arrival_token barrier_arrive() const
Arrive at a barrier.
Definition amd_hip_cooperative_groups.h:303
bool is_valid() const
Returns true if the group has not violated any API constraints.
Definition amd_hip_cooperative_groups.h:153
static __hip_uint32_t thread_rank()
Rank of the calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:282
friend grid_group this_grid()
User-exposed API interface to construct grid cooperative group type object - grid_group.
Definition amd_hip_cooperative_groups.h:230
T shfl_down(T var, unsigned int lane_delta) const
Definition amd_hip_cooperative_groups.h:877
T shfl_up(T var, unsigned int lane_delta) const
Shuffle up operation on group level.
Definition amd_hip_cooperative_groups.h:564
thread_block_tile_type(unsigned int meta_group_rank, unsigned int meta_group_size)
Definition amd_hip_cooperative_groups.h:946
__hip_uint32_t thread_rank() const
Rank of the calling thread within [0, num_threads() ).
Definition amd_hip_cooperative_groups.h:205
Definition amd_hip_cooperative_groups.h:301
Definition amd_hip_cooperative_groups.h:67
Definition amd_hip_cooperative_groups.h:60
void bPermute(T &, T, int from)
Definition amd_hip_cooperative_groups.h:1476
__hip_internal::is_same< typename __hip_internal::remove_cvref< T >, typename __hip_internal::remove_cvref< U > > is_param_type_same
Definition amd_hip_cooperative_groups.h:1381
Definition amd_hip_cooperative_groups.h:1245
Definition amd_hip_cooperative_groups.h:24
Definition amd_hip_cooperative_groups.h:1353
T operator()(T lhs, T rhs) const
Definition amd_hip_cooperative_groups.h:1354
Definition amd_hip_cooperative_groups.h:1369
T operator()(T lhs, T rhs) const
Definition amd_hip_cooperative_groups.h:1370
Definition amd_hip_cooperative_groups.h:1361
T operator()(T lhs, T rhs) const
Definition amd_hip_cooperative_groups.h:1362
Definition amd_hip_cooperative_groups.h:1345
T operator()(T lhs, T rhs) const
Definition amd_hip_cooperative_groups.h:1346
T operator()()
Definition amd_hip_cooperative_groups.h:1427
T operator()()
Definition amd_hip_cooperative_groups.h:1446
T operator()()
Definition amd_hip_cooperative_groups.h:1436
Definition amd_hip_cooperative_groups.h:1417
T operator()()
Definition amd_hip_cooperative_groups.h:1418
Definition amd_hip_cooperative_groups.h:1384
Definition amd_hip_cooperative_groups.h:1400
Definition amd_hip_cooperative_groups.h:1078
Definition amd_hip_cooperative_groups.h:1057
tiled_partition_internal(const thread_block &g)
Definition amd_hip_cooperative_groups.h:1249
tiled_partition_internal(const thread_block_tile< ParentSize, GrandParentCGTy > &g)
Definition amd_hip_cooperative_groups.h:1259
Definition amd_hip_cooperative_groups.h:1069
Definition amd_hip_cooperative_groups.h:1337
T operator()(T lhs, T rhs) const
Definition amd_hip_cooperative_groups.h:1338
Definition amd_hip_cooperative_groups.h:1329
T operator()(T lhs, T rhs) const
Definition amd_hip_cooperative_groups.h:1330
Definition hip_runtime_api.h:1405