@@ -243,6 +243,43 @@ def unwrap_to_dense(t: Tensor):
243243 return t
244244
245245
246+ def get_full_source (source : list [int ], destination : list [int ], ndim : int ) -> list [int ]:
247+ """
248+ Doing a movedim with source and destination is always equivalent to doing a movedim with
249+ [0, 1, ..., ndim-1] (aka "full_destination") as destination, and the "full_source" as source.
250+
251+ This function computes the full_source based on a source and destination.
252+
253+ Example:
254+ source=[2, 4]
255+ destination=[0, 3]
256+ ndim=5
257+
258+ full_source = [2, 0, 1, 4, 3]
259+ full_destination = [0, 1, 2, 3, 4]
260+ """
261+
262+ idx = torch .full ((ndim ,), - 1 , dtype = torch .int64 )
263+ idx [destination ] = tensor (source )
264+ source_set = set (source )
265+ idx [idx .eq (- 1 )] = tensor ([i for i in range (ndim ) if i not in source_set ])
266+
267+ # source_mask = torch.zeros(ndim, dtype=torch.bool)
268+ # destination_mask = torch.zeros(ndim, dtype=torch.bool)
269+ # source_mask[source] = True
270+ # destination_mask[destination] = True
271+ #
272+ # destination_cumsum = torch.cumsum(destination_mask, dim=0)
273+ # source_cumsum = torch.cumsum(source_mask, dim=0)
274+ # base = arange(ndim, dtype=torch.int64)
275+ #
276+ # idx = torch.empty((ndim,), dtype=torch.int64)
277+ # idx[destination_mask] = tensor(source)
278+ # idx[~destination_mask] = base[~destination_mask] - destination_cumsum[~destination_mask] + source_cumsum[:ndim - len(source)]
279+
280+ return idx .tolist ()
281+
282+
246283def fix_dim_of_size_1 (physical : Tensor , strides : Tensor ) -> tuple [Tensor , Tensor ]:
247284 is_of_size_1 = torch .tensor ([s == 1 for s in physical .shape ])
248285 return physical .squeeze (), strides [:, ~ is_of_size_1 ]
0 commit comments