/// <summary>
 /// Given an element dimensions indices [N,H,W,C] return this element offset in memory.
 /// </summary>
 public int Index(int b, int h, int w, int ch)
 {
     return(shape.Index(b, h, w, ch));
 }
Beispiel #2
0
        Tensor[] PrepareConv2dWinograd(Model model, Layer l)
        {
            var K      = l.datasets[0];
            var Kshape = new TensorShape(K.shape.batch + 1, K.shape.height + 1, K.shape.width, K.shape.channels);

            var B      = l.datasets[1];
            var Bshape = B.shape;

            var weights = new float[Kshape.length + Bshape.length];

            for (int c = 0; c < Kshape.kernelDepth; ++c)
            {
                for (int k = 0; k < Kshape.kernelCount; ++k)
                {
                    float g00 = l.weights[K.offset + K.shape.Index(0, 0, c, k)];
                    float g01 = l.weights[K.offset + K.shape.Index(0, 1, c, k)];
                    float g02 = l.weights[K.offset + K.shape.Index(0, 2, c, k)];
                    float g10 = l.weights[K.offset + K.shape.Index(1, 0, c, k)];
                    float g11 = l.weights[K.offset + K.shape.Index(1, 1, c, k)];
                    float g12 = l.weights[K.offset + K.shape.Index(1, 2, c, k)];
                    float g20 = l.weights[K.offset + K.shape.Index(2, 0, c, k)];
                    float g21 = l.weights[K.offset + K.shape.Index(2, 1, c, k)];
                    float g22 = l.weights[K.offset + K.shape.Index(2, 2, c, k)];

                    // float4x3 Winograd_G = float4x3(float3(1, 0, 0), float3(0.5, 0.5, 0.5), float3(0.5, -0.5, 0.5), float3(0, 0, 1));
                    // float3x4 Winograd_GT = transpose(Winograd_G);
                    // float4x4 v = mul(Winograd_G, mul(g, Winograd_GT));
                    float w00 = g00;
                    float w01 = 0.5f * g00 + 0.5f * g01 + 0.5f * g02;
                    float w02 = 0.5f * g00 - 0.5f * g01 + 0.5f * g02;
                    float w03 = g02;

                    float w10 = g10;
                    float w11 = 0.5f * g10 + 0.5f * g11 + 0.5f * g12;
                    float w12 = 0.5f * g10 - 0.5f * g11 + 0.5f * g12;
                    float w13 = g12;

                    float w20 = g20;
                    float w21 = 0.5f * g20 + 0.5f * g21 + 0.5f * g22;
                    float w22 = 0.5f * g20 - 0.5f * g21 + 0.5f * g22;
                    float w23 = g22;

                    float v00 = w00;
                    float v01 = w01;
                    float v02 = w02;
                    float v03 = w03;

                    float v10 = 0.5f * w00 + 0.5f * w10 + 0.5f * w20;
                    float v11 = 0.5f * w01 + 0.5f * w11 + 0.5f * w21;
                    float v12 = 0.5f * w02 + 0.5f * w12 + 0.5f * w22;
                    float v13 = 0.5f * w03 + 0.5f * w13 + 0.5f * w23;

                    float v20 = 0.5f * w00 - 0.5f * w10 + 0.5f * w20;
                    float v21 = 0.5f * w01 - 0.5f * w11 + 0.5f * w21;
                    float v22 = 0.5f * w02 - 0.5f * w12 + 0.5f * w22;
                    float v23 = 0.5f * w03 - 0.5f * w13 + 0.5f * w23;

                    float v30 = w20;
                    float v31 = w21;
                    float v32 = w22;
                    float v33 = w23;

                    weights[Kshape.Index(0, 0, c, k)] = v00;
                    weights[Kshape.Index(1, 0, c, k)] = v10;
                    weights[Kshape.Index(2, 0, c, k)] = v20;
                    weights[Kshape.Index(3, 0, c, k)] = v30;
                    weights[Kshape.Index(0, 1, c, k)] = v01;
                    weights[Kshape.Index(1, 1, c, k)] = v11;
                    weights[Kshape.Index(2, 1, c, k)] = v21;
                    weights[Kshape.Index(3, 1, c, k)] = v31;
                    weights[Kshape.Index(0, 2, c, k)] = v02;
                    weights[Kshape.Index(1, 2, c, k)] = v12;
                    weights[Kshape.Index(2, 2, c, k)] = v22;
                    weights[Kshape.Index(3, 2, c, k)] = v32;
                    weights[Kshape.Index(0, 3, c, k)] = v03;
                    weights[Kshape.Index(1, 3, c, k)] = v13;
                    weights[Kshape.Index(2, 3, c, k)] = v23;
                    weights[Kshape.Index(3, 3, c, k)] = v33;
                }
            }

            Buffer.BlockCopy(weights, Kshape.length, l.weights, (int)B.offset, B.length);

            ComputeBuffer buffer = new ComputeBuffer(Kshape.length + Bshape.length, sizeof(float));

            buffer.SetData(weights);
            var Kw = new Tensor(Kshape, new SharedComputeTensorData(buffer, Kshape, 0));
            var Bw = new Tensor(Bshape, new SharedComputeTensorData(buffer, Bshape, Kshape.length));

            return(new Tensor[] { Kw, Bw });
        }
Beispiel #3
0
        private static void FillCacheFromTexture(float[] output, Texture tex,
                                                 int batchOffset, int channelOffset, int[] channelWriteMask, int[] channelReadMap,
                                                 bool flipY, Vector4 scale4, Vector4 bias4, TensorShape texDataShape)
        {
            var tex2D  = tex as Texture2D;
            var texArr = tex as Texture2DArray;
            var tex3D  = tex as Texture3D;
            var rt     = tex as RenderTexture;

            Color[] colors   = null;
            var     texDepth = 1;

            if (tex2D)
            {
                colors   = tex2D.GetPixels(0);
                texDepth = 1;
            }
            else if (texArr)
            {
                colors   = texArr.GetPixels(0, 0);
                texDepth = texArr.depth;
            }
            else if (tex3D)
            {
                colors   = tex3D.GetPixels(0);
                texDepth = tex3D.depth;
            }
            else if (rt)
            {
                var currentRT = RenderTexture.active;
                RenderTexture.active = rt;
                Texture2D tmpTexture = new Texture2D(rt.width, rt.height, tex.graphicsFormat, TextureCreationFlags.None);
                tmpTexture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
                tmpTexture.Apply();
                colors = tmpTexture.GetPixels(0);
                RenderTexture.active = currentRT;
                texDepth             = rt.volumeDepth;
                if (rt.format == RenderTextureFormat.RHalf)
                {
                    Debug.LogError(
                        "Texture to Tensor does not support RHalf format for source rendertarget when Compute shader are not available on platform.");
                }
            }

            if (texDepth != 1)
            {
                Debug.LogError(
                    "Texture to Tensor only support texture resource with one slice when Compute shader are not available on platform!");
            }

            Assert.IsNotNull(colors);

            for (int x = 0; x < texDataShape.width; ++x)
            {
                for (int yTex = 0; yTex < texDataShape.height; ++yTex)
                {
                    int c = channelOffset;
                    int y = flipY ? texDataShape.height - yTex - 1 : yTex;

                    var     pixelIndex = yTex * texDataShape.width + x;
                    Vector4 v          = colors[pixelIndex];
                    bool    specialCaseWhenChannelMaskIsEmptyStoresAverage = true;
                    for (int i = 0; i < 4; ++i)
                    {
                        if (channelWriteMask[i] == 1)
                        {
                            int   readFrom = channelReadMap[i];
                            float value    = i < 3 ? 0 : 1; // default values for channels R,G,B=0 and A=1
                            float scale    = 1.0f;
                            float bias     = 0.0f;
                            if (readFrom >= 0)
                            {
                                value = v[readFrom];
                                scale = scale4[readFrom];
                                bias  = bias4[readFrom];
                            }

                            output[texDataShape.Index(batchOffset, y, x, c)] = scale * value + bias;
                            specialCaseWhenChannelMaskIsEmptyStoresAverage   = false;
                            c += 1;
                        }
                    }

                    if (specialCaseWhenChannelMaskIsEmptyStoresAverage)
                    {
                        v = Vector4.Scale(v, scale4) + bias4;
                        float avg = (v.x + v.y + v.z) / 3.0f;
                        output[texDataShape.Index(batchOffset, y, x, c)] = avg;
                    }
                }
            }
        }