# Help Wanted Simple Tensor Math in Barracuda

Discussion in 'Barracuda' started by hellovivian, Jun 8, 2020.

1. ### hellovivian

Joined:
Jan 7, 2018
Posts:
5
In my last post I mentioned that when I use a texture as a tensor input ( as in Tensor(RenderTexture), I need to normalize the texture values between [-1,1] instead of [0,1]

I iterated through my inputTensor and changed every index like so, effectively sending the texture back to the CPU:

Code (CSharp):
1. for (int y = 0; y < 256; y++) {
2.             for (int x = 0; x < 256; x++) {
3.                 float r = (outputTensor[0,y,x,0] + 1.0f) / 2.0f;
4.                 float g = (outputTensor[0,y,x,1] + 1.0f) / 2.0f;
5.                 float b = (outputTensor[0,y,x,2] + 1.0f) / 2.0f;
6.                 outputTensor[0,y,x,0] =  r;
7.                 outputTensor[0,y,x,1] =  g;
8.                 outputTensor[0,y,x,2] =  b;
9.
10.             }
11.         }
To make my application faster, I am trying to use a CustomRenderTexture with a fragment shader to normalize the values, but this seemed to not have the same effect.

I am wondering two things:
1. What is the simplest efficient way to implement normalization with Barracuda? Can I do tensor math with the Tensor class?
2. Additionally, are CustomRenderTextures supported in the same way as normal render textures. If I call Tensor(CustomRenderTexture) on the CustomRenderTexture, will the values be the ones the shader has already changed?

Here is an example of how my shader has been edited for normalization:
Code (CSharp):
1. float4 frag(v2f_customrendertexture IN) : COLOR
2.             {
3.                 return (0.5 * (_Color * (tex2D(_Tex, IN.localTexcoord.xy)) + 1));
4.             }

2. ### hellovivian

Joined:
Jan 7, 2018
Posts:
5
Okay, I shall answer my own question again.

1. Yes we can do tensor math, I was looking at the older documentation for Barracuda, but 1.0 Barracuda discusses how you can initialize arrays.
2. Yes, at least for my project that is the case

I do have another question though, which is: how do we slice into our output tensors? For example if we ran a batch input tensor and get back an output tensor in the shape of (2, 256, 256, 3)--how do we separate that output tensor into (1, 256, 256, 3) and (1,256,256,3) --without explicitly reading back the srcData /source data of the tensor?

amirebrahimi_unity likes this.

### Unity Technologies

Joined:
Nov 1, 2008
Posts:
378

There are two ways to do it:
1) Use ModelBuilder and add StridedSlice node at the end of your model.

Code (CSharp):
1. var builder = new ModelBuilder(model);
2. var slice1 = builder.StridedSlice("slice1", model.outputs[0], starts:new[] { 0, 0,0,0}, ends:[] {1,256,256,3}, strides:new[]{1,1,1,1} };
3. var slice2 = builder.StridedSlice("slice2", model.outputs[0], starts:new[] { 1, 0,0,0}, ends:[] {2,256,256,3}, strides:new[]{1,1,1,1} };
4. builder.Output(slice1); // optional, if you want to use it as the final output
5. builder.Output(slice2); // optional, if you want to use it as the final output
6. model = builder.model; // take the updated model from the builder
7.
2) If you want to get the results into the RenderTexture and you have batch > 1 in the Tensor:

Code (CSharp):
1. var output = worker.Execute().PeekOutput();
2. RenderTexture texSlice1 = output.ToRenderTexture(batch:0);
3. RenderTexture texSlice2 = output.ToRenderTexture(batch:1);
Hope it helps.

unityunity