26
26
namespace tc {
27
27
namespace polyhedral {
28
28
namespace {
29
- // This returns the (inclusive) range of the mapping parameter "mappingId"
30
- // within the context "mappingContext".
31
- // This range corresponds to the blocks/threads active at the particular
32
- // location in the tree where this mapping is active.
33
- //
34
- // This is used to tighten the kernel to only launch on the necessary amount
35
- // of resources.
36
- //
37
- // When the range is unbounded on the right, we return the maximal positive
38
- // range (0, max_size_t). This needs to be intersected with launch bounds to
39
- // obtain the proper finite range.
40
- // Otherwise, the range is asserted bounded on the left and to lie in the
41
- // positive half of the integer axis.
42
- std::pair<size_t , size_t > rangeOfMappingParameter (
43
- isl::set mappingContext,
44
- mapping::MappingId mappingId) {
45
- if (!mappingContext.involves_param (mappingId)) {
46
- return std::make_pair (0 , std::numeric_limits<size_t >::max ());
47
- }
48
- auto space = mappingContext.get_space ();
49
- isl::aff a (isl::aff::param_on_domain_space (space, mappingId));
50
- auto max = mappingContext.max_val (a);
51
- if (max.is_nan () || max.is_infty ()) {
52
- return std::make_pair (0 , std::numeric_limits<size_t >::max ());
53
- }
54
- TC_CHECK (max.is_int ()) << max.to_str ();
55
- TC_CHECK (max.is_nonneg ()) << max.to_str ();
56
- auto min = mappingContext.min_val (a);
57
- TC_CHECK (min.is_int ()) << max.to_str ();
58
- TC_CHECK (min.is_nonneg ()) << max.to_str ();
59
-
60
- return std::make_pair (
61
- static_cast <size_t >(min.get_num_si ()),
62
- static_cast <size_t >(max.get_num_si ()));
63
- }
64
-
65
- /*
66
- * Compute the maximal value attained by the mapping parameter "id".
67
- */
68
- template <typename MappingIdType>
69
- size_t maxValue (const Scop& scop, const MappingIdType& id) {
70
- using namespace polyhedral ::detail;
71
-
72
- auto root = scop.scheduleRoot ();
73
- auto params = scop.context ();
74
- size_t sizetMax = std::numeric_limits<size_t >::max ();
75
- size_t max = 0 ;
76
- size_t min = sizetMax;
77
- auto filters = root->collect (root, ScheduleTreeType::Mapping);
78
- filters = functional::Filter (isMappingTo<MappingIdType>, filters);
79
- for (auto p : filters) {
80
- auto mappingNode = p->elemAs <ScheduleTreeElemMapping>();
81
- auto active = activeDomainPoints (root, p).intersect_params (params);
82
- active = active.intersect (mappingNode->filter_ );
83
- auto range = rangeOfMappingParameter (active.params (), id);
84
- min = std::min (min, range.first );
85
- max = std::max (max, range.second );
86
- }
87
- TC_CHECK (max < sizetMax) << " missing mapping to " << id << " \n " << *root;
88
- TC_CHECK (min < sizetMax) << " missing mapping to " << id << " type\n " << *root;
89
- // Inclusive range needs + 1 to translate to sizes
90
- return max + 1 ;
91
- }
92
-
93
29
/*
94
30
* Take grid or block launch bounds "size" and replace them
95
31
* by the tightened, actual, launch bounds used in practice.
@@ -98,8 +34,17 @@ template <typename MappingIdType, typename Size>
98
34
Size launchBounds (const MappedScop& mscop, Size size) {
99
35
Size tightened;
100
36
37
+ auto params = mscop.scop ().context ();
38
+ auto mapping = mscop.mappingSchedule <MappingIdType>(mscop.schedule ());
39
+ mapping = mapping.intersect_params (params);
40
+ auto max = mapping.max_multi_val ();
41
+
101
42
for (size_t i = 0 ; i < size.view .size (); ++i) {
102
- tightened.view [i] = maxValue (mscop.scop (), MappingIdType::makeId (i));
43
+ auto maxVal = max.get_val (i);
44
+ TC_CHECK (maxVal.is_int ()) << maxVal.to_str ();
45
+ TC_CHECK (maxVal.is_nonneg ()) << maxVal.to_str ();
46
+ // Inclusive range needs + 1 to translate to sizes
47
+ tightened.view [i] = maxVal.get_num_si () + 1 ;
103
48
}
104
49
105
50
return tightened;
0 commit comments