Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Question Simple Tensor Math in Barracuda

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

  1. hellovivian

    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.             }
    Thank you for reading!
     
    M4R5 likes this.
  2. hellovivian

    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.
  3. ReJ

    ReJ

    Unity Technologies

    Joined:
    Nov 1, 2008
    Posts:
    378
    Sorry for late reply, just found your post.

    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.
     
    M4R5 likes this.