tc/core/polyhedral/cuda/memory_promotion_heuristic.cc
/*
 * Check if a reference group is accessed in a coalesced way.
 *
 * In particular, check if incrementing the schedule dimension mapped to
 * Thread::x results in the last tensor index being incremented as well.
 * Since accesses in the group may belong to different statements, which are
 * have different loops mapped to Thread::x, perform the check for each basic
 * map in the union of access maps taking into account which dimension is
 * mapped for a particular statement (domain of the basic map).  The group is
 * accessed in a coalesced way if all references in this group are accessed in
 * a coalesced way.
 */
Check if a reference group is accessed in a coalesced way.
In particular, check if incrementing the schedule dimension mapped to
Thread::x results in the last tensor index being incremented as well.
Since accesses in the group may belong to different statements, which are
have different loops mapped to Thread::x, perform the check for each basic
map in the union of access maps taking into account which dimension is
mapped for a particular statement (domain of the basic map).  The group is
accessed in a coalesced way if all references in this group are accessed in
a coalesced way.
Check if a reference group is accessed in a coalesced way . In particular check if incrementing the schedule dimension mapped to Thread :: x results in the last tensor index being incremented as well . Since accesses in the group may belong to different statements which are have different loops mapped to Thread :: x perform the check for each basic map in the union of access maps taking into account which dimension is mapped for a particular statement ( domain of the basic map ) . The group is accessed in a coalesced way if all references in this group are accessed in a coalesced way .
bool isCoalesced(
    const ThreadIdxXScheduleDepthState& threadIdxXScheduleDepthState,
    const TensorReferenceGroup& group,
    isl::union_map schedule,
    isl::union_set activePoints) {
  auto originalAccesses = group.originalAccesses();
  for (auto accessMap : isl::UnionAsVector<isl::union_map>(originalAccesses)) {
    for (auto access : accessMap.get_basic_map_list()) {
      auto tensorSpace = access.get_space().range();
      auto elementToNext = makeNextElementMap(
          tensorSpace, tensorSpace.dim(isl::dim_type::set) - 1);
      auto domainUMap = isl::union_set(isl::set(access.domain()));
      int threadIdxXDepth = computeThreadIdxXScheduleDepth(
          threadIdxXScheduleDepthState, domainUMap.intersect(activePoints));
      auto partialScheduleUMap =
          schedule.intersect_domain(domainUMap.universe());
      if (partialScheduleUMap.n_map() != 1) {
        throw promotion::PromotionLogicError("expected single schedule space");
      }
      auto partialSchedule = isl::map::from_union_map(partialScheduleUMap);
      auto scheduleToNextX = makeNextElementMap(
          partialSchedule.get_space().range(), threadIdxXDepth);
      auto scheduledAccess = isl::map(access).apply_domain(partialSchedule);
      auto accessedByAdjacentX = scheduleToNextX.apply_domain(scheduledAccess)
                                     .apply_range(scheduledAccess);
      if (not accessedByAdjacentX.is_subset(elementToNext)) {
        return false;
      }
    }
  }
  return true;
}
bool isCoalesced ( const ThreadIdxXScheduleDepthState & threadIdxXScheduleDepthState , const TensorReferenceGroup & group , isl :: union_map schedule , isl :: union_set activePoints ) { auto originalAccesses = group . originalAccesses ( ) ; for ( auto accessMap : isl :: UnionAsVector < isl :: union_map > ( originalAccesses ) ) { for ( auto access : accessMap . get_basic_map_list ( ) ) { auto tensorSpace = access . get_space ( ) . range ( ) ; auto elementToNext = makeNextElementMap ( tensorSpace , tensorSpace . dim ( isl :: dim_type :: set ) - 1 ) ; auto domainUMap = isl :: union_set ( isl :: set ( access . domain ( ) ) ) ; int threadIdxXDepth = computeThreadIdxXScheduleDepth ( threadIdxXScheduleDepthState , domainUMap . intersect ( activePoints ) ) ; auto partialScheduleUMap = schedule . intersect_domain ( domainUMap . universe ( ) ) ; if ( partialScheduleUMap . n_map ( ) != 1 ) { throw promotion :: PromotionLogicError ( " " ) ; } auto partialSchedule = isl :: map :: from_union_map ( partialScheduleUMap ) ; auto scheduleToNextX = makeNextElementMap ( partialSchedule . get_space ( ) . range ( ) , threadIdxXDepth ) ; auto scheduledAccess = isl :: map ( access ) . apply_domain ( partialSchedule ) ; auto accessedByAdjacentX = scheduleToNextX . apply_domain ( scheduledAccess ) . apply_range ( scheduledAccess ) ; if ( not accessedByAdjacentX . is_subset ( elementToNext ) ) { return false ; } } } return true ; }
Check if a reference group is accessed in a coalesced way.
Check if a reference group is accessed in a coalesced way .