# Transpose issue

**URL:** https://discussions.unity.com/t/transpose-issue/351657
**Category:** AI Inference Engine
**Tags:** Inference-Engine, Question
**Created:** [April 12, 2024, 2:45pm UTC](https://discussions.unity.com/t/transpose-issue/351657 "2024-04-12T14:45:43Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![MS-Fove](https://avatars.discourse-cdn.com/v4/letter/m/e9c0ed/32.png) [@MS-Fove](https://discussions.unity.com/u/MS-Fove)
#### Post date: [April 12, 2024, 2:45pm UTC](https://discussions.unity.com/t/transpose-issue/351657/1 "2024-04-12T14:45:43Z")

</div>

I’ve been running into an issue with `Transpose`.

I used to use Ops.Transpose on a Tensor to permutate the dimensions.  
For example, I had a tensor of shape (1, 256, 256, 3) and but my model only takes into input a tensor of shape (1, 3, 256, 256). Thus in Sentis 1.3.0, I was doing this:

```auto
TensorFloat output = ops.Transpose(inputTensor, new int[] {0, 3, 1, 2})

```

and it would modify the data as well as the shape properly into the output tensor.

But now, I’m currently using IBackend.Transpose which is the same thing but we need to add the output tensor in the parameters. But it doesn’t update the shape of the output tensor.  
I did a test:

```auto
        IBackend backend = WorkerFactory.CreateBackend(BackendType.CPU);
        TensorShape shape = new TensorShape(2, 3);
        float[] srcData = { 1, 2, 3, 4, 5, 6};
        TensorFloat tens = new TensorFloat(shape, srcData);
        tens.PrintDataPart(6);
        TensorFloat transposedTens = TensorFloat.AllocNoData(shape);
        Debug.Log($"Before transpose: tens.shape=" + tens.shape + " transposedTens.shape=" + transposedTens.shape);
        backend.Transpose(tens, transposedTens, new int[] { 1, 0 });
        Debug.Log($"After transpose: tens.shape=" + tens.shape + " transposedTens.shape=" + transposedTens.shape);
        transposedTens.PrintDataPart(6);
        backend.Dispose();
        tens.Dispose();
        transposedTens.Dispose();

```

And this is the output:

```auto
 1 2 3 4 5 6
Before transpose: tens.shape=(2, 3) transposedTens.shape=(2, 3)
After transpose: tens.shape=(2, 3) transposedTens.shape=(2, 3)
1 4 2 5 3 6 

```

The issue I have with the output is that the transposedTens’ shape is unchanged. Shouldn’t it be (3, 2) now ?  
I may be completely wrong so please feel free to correct me.

---

<div class="post-metadata">

### Author: ![PaulBUnity](https://avatars.discourse-cdn.com/v4/letter/p/59ef9b/32.png) [@PaulBUnity](https://discussions.unity.com/u/PaulBUnity)
#### Post date: [April 12, 2024, 2:59pm UTC](https://discussions.unity.com/t/transpose-issue/351657/2 "2024-04-12T14:59:55Z")

</div>

Hi, unfotunately the backend API does not automatically do shape checking. You have to specify the output shape yourself.

On the line:

```auto
 TensorFloat transposedTens = TensorFloat.AllocNoData(shape);

```

you can replace with

```auto
 TensorFloat transposedTens = TensorFloat.AllocNoData(new TensorShape(3,2));

```

BTW you can also use the [Functional API](https://docs.unity3d.com/Packages/com.unity.sentis@1.4/manual/edit-a-model.html) for manipulating tensors within models which has shape checking.

---

<div class="post-metadata">

### Author: ![MS-Fove](https://avatars.discourse-cdn.com/v4/letter/m/e9c0ed/32.png) [@MS-Fove](https://discussions.unity.com/u/MS-Fove)
#### Post date: [April 12, 2024, 3:14pm UTC](https://discussions.unity.com/t/transpose-issue/351657/3 "2024-04-12T15:14:10Z")

</div>

Thank you very much, that was quick 🙂

Well I was actually checking the Functional API since I am preprocessing and postprocessing tensors so that might makes things even easier

---

<div class="post-metadata">

### Author: ![PaulBUnity](https://avatars.discourse-cdn.com/v4/letter/p/59ef9b/32.png) [@PaulBUnity](https://discussions.unity.com/u/PaulBUnity)
#### Post date: [April 12, 2024, 5:38pm UTC](https://discussions.unity.com/t/transpose-issue/351657/4 "2024-04-12T17:38:44Z")

</div>

Hi @MS-Fove .  
Did you also know, if you are using `TextureConverter.ToTensor(texture)` to get the tensor from a texture, you can also specify the ordering without needing to use a permute operation:

```auto
TextureTransform settings = new TextureTransform().SetDimensions(256, 256, 3).SetTensorLayout(TensorLayout.NCHW)
var tensor = TextureConverter.ToTensor(texture,settings);

```

---

<div class="post-metadata">

### Author: ![PaulBUnity](https://avatars.discourse-cdn.com/v4/letter/p/59ef9b/32.png) [@PaulBUnity](https://discussions.unity.com/u/PaulBUnity)
#### Post date: [April 12, 2024, 5:55pm UTC](https://discussions.unity.com/t/transpose-issue/351657/5 "2024-04-12T17:55:41Z")

</div>

Here is also the functional code which will do the same thing. Let’s assume you want to permute the first input of two inputs:

```auto
         var newModel = Functional.Compile(
            (input1, input2) =>model.Forward ( Functional.Permute(input1, new[] { 0, 3, 1, 2 } ), input2)[0],
            (model.inputs[0],model.inputs[1])
        );

```

You can use the newModel now in place of the old model which will automatically permute the input1. The newModel inputs are now renamed as “input\_0”, “input\_1” and the outputs as “output\_0”,… etc.
