Information about a TIR block.
| 169 | |
| 170 | |
| 171 | class SBlockInfo: |
| 172 | """Information about a TIR block.""" |
| 173 | |
| 174 | name: str |
| 175 | iters: list[IterInfo] |
| 176 | block_rv: s_tir.schedule.SBlockRV |
| 177 | _reduction_block: bool |
| 178 | |
| 179 | def __init__( |
| 180 | self, |
| 181 | name: str, |
| 182 | iters: list[IterInfo], |
| 183 | block_rv: s_tir.schedule.SBlockRV, |
| 184 | reduction_block: bool = False, |
| 185 | ): |
| 186 | """Construct a SBlockInfo object.""" |
| 187 | self.name = name |
| 188 | self.block_rv = block_rv |
| 189 | self.iters = iters |
| 190 | self._reduction_block = reduction_block |
| 191 | |
| 192 | def dom(self) -> list[int | tirx.PrimExpr]: |
| 193 | """The iteration domain of the block.""" |
| 194 | return [i.dom for i in self.iters] |
| 195 | |
| 196 | def read_bufs(self, sch: s_tir.Schedule) -> list[BufferInfo]: |
| 197 | block_stmt = sch.get(self.block_rv) |
| 198 | lps = sch.get_loops(self.block_rv) |
| 199 | return [BufferInfo(sch, self.block_rv, buf, lps) for buf in block_stmt.reads] |
| 200 | |
| 201 | def write_bufs(self, sch: s_tir.Schedule) -> list[BufferInfo]: |
| 202 | block_stmt = sch.get(self.block_rv) |
| 203 | lps = sch.get_loops(self.block_rv) |
| 204 | return [BufferInfo(sch, self.block_rv, buf, lps) for buf in block_stmt.writes] |
| 205 | |
| 206 | def dom_kind(self) -> str: |
| 207 | """The iteration domain kind of the block, for example, SSSS, SSSR.""" |
| 208 | return "".join(i.kind for i in self.iters) |
| 209 | |
| 210 | def is_injective(self) -> bool: |
| 211 | """Whether the SBlock is injective, i.e. all its iteration domains are injective.""" |
| 212 | return all(k == "S" for k in self.dom_kind()) |
| 213 | |
| 214 | def is_elementwise(self, sch: s_tir.Schedule) -> bool: |
| 215 | """Whether the SBlock is elementwise, i.e. trivial mapping between read/write region""" |
| 216 | |
| 217 | def _check_unit_var_range(dom: ir.Range, var: tirx.Var) -> bool: |
| 218 | return dom.min.same_as(var) and dom.extent == 1 |
| 219 | |
| 220 | if not self.is_injective(): |
| 221 | return False |
| 222 | block = sch.get(self.block_rv) |
| 223 | if len(block.reads) != 1 or len(block.writes) != 1: |
| 224 | return False |
| 225 | r_region = block.reads[0].region |
| 226 | w_region = block.writes[0].region |
| 227 | if len(r_region) != len(w_region): |
| 228 | return False |
no outgoing calls
no test coverage detected
searching dependent graphs…