Process 3D tensors, but only enable TileWorker on 2D.
| 162 | |
| 163 | |
| 164 | class TileWorker2Dto3D: |
| 165 | """ |
| 166 | Process 3D tensors, but only enable TileWorker on 2D. |
| 167 | """ |
| 168 | def __init__(self): |
| 169 | pass |
| 170 | |
| 171 | |
| 172 | def build_mask(self, T, H, W, dtype, device, is_bound, border_width): |
| 173 | t = repeat(torch.arange(T), "T -> T H W", T=T, H=H, W=W) |
| 174 | h = repeat(torch.arange(H), "H -> T H W", T=T, H=H, W=W) |
| 175 | w = repeat(torch.arange(W), "W -> T H W", T=T, H=H, W=W) |
| 176 | border_width = (H + W) // 4 if border_width is None else border_width |
| 177 | pad = torch.ones_like(h) * border_width |
| 178 | mask = torch.stack([ |
| 179 | pad if is_bound[0] else t + 1, |
| 180 | pad if is_bound[1] else T - t, |
| 181 | pad if is_bound[2] else h + 1, |
| 182 | pad if is_bound[3] else H - h, |
| 183 | pad if is_bound[4] else w + 1, |
| 184 | pad if is_bound[5] else W - w |
| 185 | ]).min(dim=0).values |
| 186 | mask = mask.clip(1, border_width) |
| 187 | mask = (mask / border_width).to(dtype=dtype, device=device) |
| 188 | mask = rearrange(mask, "T H W -> 1 1 T H W") |
| 189 | return mask |
| 190 | |
| 191 | |
| 192 | def tiled_forward( |
| 193 | self, |
| 194 | forward_fn, |
| 195 | model_input, |
| 196 | tile_size, tile_stride, |
| 197 | tile_device="cpu", tile_dtype=torch.float32, |
| 198 | computation_device="cuda", computation_dtype=torch.float32, |
| 199 | border_width=None, scales=[1, 1, 1, 1], |
| 200 | progress_bar=lambda x:x |
| 201 | ): |
| 202 | B, C, T, H, W = model_input.shape |
| 203 | scale_C, scale_T, scale_H, scale_W = scales |
| 204 | tile_size_H, tile_size_W = tile_size |
| 205 | tile_stride_H, tile_stride_W = tile_stride |
| 206 | |
| 207 | value = torch.zeros((B, int(C*scale_C), int(T*scale_T), int(H*scale_H), int(W*scale_W)), dtype=tile_dtype, device=tile_device) |
| 208 | weight = torch.zeros((1, 1, int(T*scale_T), int(H*scale_H), int(W*scale_W)), dtype=tile_dtype, device=tile_device) |
| 209 | |
| 210 | # Split tasks |
| 211 | tasks = [] |
| 212 | for h in range(0, H, tile_stride_H): |
| 213 | for w in range(0, W, tile_stride_W): |
| 214 | if (h-tile_stride_H >= 0 and h-tile_stride_H+tile_size_H >= H) or (w-tile_stride_W >= 0 and w-tile_stride_W+tile_size_W >= W): |
| 215 | continue |
| 216 | h_, w_ = h + tile_size_H, w + tile_size_W |
| 217 | if h_ > H: h, h_ = max(H - tile_size_H, 0), H |
| 218 | if w_ > W: w, w_ = max(W - tile_size_W, 0), W |
| 219 | tasks.append((h, h_, w, w_)) |
| 220 | |
| 221 | # Run |
no outgoing calls
no test coverage detected