Esempio n. 1
0
        private void setNumericAddressToValueWithAddInstruction(
            byte address, decimal value,
            SignalTable signalTable, List <CompiledInstruction> compiledInstructions)
        {
            var compiledOperand1Signal = new CompiledNumericSignal(value);
            var operand2SignalIn       = NodeSignalIn.BuildWith(
                new FieldDataType(FieldDataType.DataTypeEnum.NUMBER),
                new FieldConstant(FieldDataType.DataTypeEnum.NUMBER, 0M));
            var compiledOperand2Signal = numericSignal(operand2SignalIn, signalTable);

            var compiledResultSignal = new CompiledNumericSignal(false, address, signalTable.NumericAddressBits);
            var add = new CompiledInstruction(
                0x78, // add
                7,
                compiledOperand1Signal, compiledOperand2Signal, compiledResultSignal);

            compiledInstructions.Add(add);
            compiledInstructions.Add(new CompiledInstruction(0x03, 3)); // series instruction end (end of rung)
        }
Esempio n. 2
0
        Tensor GlobalPool2D(Tensor X)
        {
            var inputDim = new [] { X.height, X.width };

            for (var i = 0; i < m_Compiled.instructions.Length - 1; ++i)
            {
                var pool   = new[] { 8, 8 };
                var stride = pool;
                var pad    = new[] { 0, 0, 0, 0 };

                CompiledInstruction instructionPool = m_Compiled.instructions[i];
                Assert.IsNotNull(instructionPool.kernel.shader);

                var Or     = NewTensor(instructionPool.shape);
                var fnPool = instructionPool.kernel;

                fnPool.SetTensor("X", X.shape, Pin(X).buffer);
                fnPool.SetTensor("O", Or.shape, Pin(Or).buffer);

                fnPool.shader.SetInts("_Pool", pool);
                fnPool.shader.SetInts("_Stride", stride);
                fnPool.shader.SetInts("_Pad", pad);

                fnPool.Dispatch();
                X = Or;
            }

            CompiledInstruction instructionGlobalPool = m_Compiled.instructions[m_Compiled.instructions.Length - 1];

            Assert.IsNotNull(instructionGlobalPool.kernel.shader);

            var O            = NewTensor(instructionGlobalPool.shape);
            var fnGlobalPool = instructionGlobalPool.kernel;

            fnGlobalPool.SetTensor("X", X.shape, Pin(X).buffer);
            fnGlobalPool.SetTensor("O", O.shape, Pin(O).buffer);
            fnGlobalPool.shader.SetInts("_Pool", inputDim);

            fnGlobalPool.Dispatch();
            return(O);
        }
Esempio n. 3
0
        // ---------------------------------------------------------------------------------
        private Tensor ApplyUnsupportedFusedActivationIfNeeded(Layer.FusedActivation fusedActivation, Tensor O)
        {
            if (!IsFusedActivationSupported(fusedActivation))
            {
                CompiledInstruction instructionActivation = m_Compiled.instructions[m_Compiled.instructions.Length - 1];
                Assert.IsNotNull(instructionActivation.kernel.shader);

                var fnActivation = instructionActivation.kernel;
                var Oactivation  = NewTensor(O.shape);

                fnActivation.SetTensor("X", O.shape, Pin(O).buffer);
                fnActivation.SetTensor("O", Oactivation.shape, Pin(Oactivation).buffer);

                fnActivation.shader.SetFloat(_Alpha, 0.0f);
                fnActivation.shader.SetFloat(_Beta, 0.0f);

                fnActivation.Dispatch();
                return(Oactivation);
            }

            return(O);
        }
Esempio n. 4
0
        private void driveSignalWithCoilToConstantValue(
            Int16 address, bool value,
            SignalTable signalTable, List <CompiledInstruction> compiledInstructions)
        {
            if (!value) // if value is TRUE, only need the coil, otherwise need a NO contact
            {
                var compiledContactSignal = new CompiledBooleanSignal(false);
                var contact = new CompiledInstruction(
                    0x01, // NO contact
                    3,
                    compiledContactSignal);
                compiledInstructions.Add(contact);
            }

            var compiledDiscreteInputSignal = new CompiledBooleanSignal(false, address, signalTable.BooleanAddressBits);
            var coil = new CompiledInstruction(
                0x00, // coil
                3,
                compiledDiscreteInputSignal);

            compiledInstructions.Add(coil);
            compiledInstructions.Add(new CompiledInstruction(0x03, 3)); // series instruction end (end of rung)
        }
Esempio n. 5
0
        public override Tensor Normalization(Tensor X, Tensor S, Tensor B, int pool, int axis, float epsilon, Layer.FusedActivation fusedActivation)
        {
            if (axis != 3 && axis != -1)
            {
                throw new NotImplementedException();
            }

            if (pool <= 0)
            {
                pool = X.batch;
            }

            if (pool > 1)
            {
                throw new NotImplementedException(); // @TODO: support other types of Normalization at test time
            }
            // Currently supported only pool=1 (InstanceNormalization)

            // [0,N] : AvgVariancePool2DReduce
            // N+1 : GlobalAvgVariancePool2D
            // N+2: Normalize
            // N+3 Activation

            var inputDim = new[] { X.height, X.width };

            var  Xr              = X;
            var  X2r             = X;
            bool isFirstDispatch = true;

            for (var i = 0; i < m_Compiled.instructions.Length - 3; ++i)
            {
                var poolReduce = new[] { 8, 8 };
                var stride     = poolReduce;
                var pad        = new[] { 0, 0, 0, 0 };

                CompiledInstruction instructionPool = m_Compiled.instructions[i];
                Assert.IsNotNull(instructionPool.kernel.shader);

                var Or     = NewTensor(instructionPool.shape);
                var O2r    = NewTensor(instructionPool.shape);
                var fnPool = instructionPool.kernel;

                fnPool.SetTensor("X", Xr.shape, Pin(Xr).buffer);
                fnPool.SetTensor("X2", X2r.shape, Pin(X2r).buffer);
                fnPool.SetTensor("O", Or.shape, Pin(Or).buffer);
                fnPool.SetTensor("O2", O2r.shape, Pin(O2r).buffer);

                fnPool.shader.SetInts("_Pool", poolReduce);
                fnPool.shader.SetInts("_Stride", stride);
                fnPool.shader.SetInts("_Pad", pad);
                fnPool.shader.SetInt("_IsFirstDispatch", isFirstDispatch ? 1 : 0);

                fnPool.Dispatch();

                Xr              = Or;
                X2r             = O2r;
                isFirstDispatch = false;
            }

            CompiledInstruction instructionGlobalPool = m_Compiled.instructions[m_Compiled.instructions.Length - 3];

            Assert.IsNotNull(instructionGlobalPool.kernel.shader);

            var meanVariance = NewTensor(instructionGlobalPool.shape);
            var fnGlobalPool = instructionGlobalPool.kernel;

            fnGlobalPool.SetTensor("X", Xr.shape, Pin(Xr).buffer);
            fnGlobalPool.SetTensor("X2", X2r.shape, Pin(X2r).buffer);
            fnGlobalPool.SetTensor("O", meanVariance.shape, Pin(meanVariance).buffer);
            fnGlobalPool.shader.SetInts("_Pool", inputDim);
            fnGlobalPool.shader.SetInt("_IsFirstDispatch", isFirstDispatch ? 1 : 0);

            fnGlobalPool.Dispatch();

            CompiledInstruction instructionNormalize = m_Compiled.instructions[m_Compiled.instructions.Length - 2];

            Assert.IsNotNull(instructionNormalize.kernel.shader);
            Assert.AreEqual(X.channels, B.channels); Assert.AreEqual(X.channels, S.channels);
            Assert.AreEqual(B.length, B.channels); Assert.AreEqual(S.length, S.channels);

            var O           = NewTensor(X.shape);
            var fnNormalize = instructionNormalize.kernel;

            fnNormalize.SetTensor("X", X.shape, Pin(X).buffer);
            fnNormalize.SetTensor("O", O.shape, Pin(O).buffer);
            fnNormalize.SetTensor("W", meanVariance.shape, Pin(meanVariance).buffer);
            fnNormalize.SetTensorDecl("S", S.shape, Pin(S).offset);
            fnNormalize.SetTensorDecl("B", B.shape, Pin(B).offset);
            Assert.AreEqual(Pin(S).buffer, Pin(B).buffer);
            fnNormalize.SetTensorBuffer("WBK", Pin(S).buffer);
            fnNormalize.shader.SetFloat("_Epsilon", epsilon);
            fnNormalize.shader.SetInt("_ActivationMode", (int)fusedActivation);

            fnNormalize.Dispatch();

            return(ApplyUnsupportedFusedActivationIfNeeded(fusedActivation, O));
        }
Esempio n. 6
0
        public override Tensor Conv2DTrans(Tensor X, Tensor K, Tensor B, int[] stride, int[] pad, int[] outputAdjustment)
        {
            Assert.AreEqual(m_Compiled.instructions.Length, 3); // pad, kernel flip, conv

            Assert.AreEqual(X.channels, K.kernelDepth);
            Assert.AreEqual(K.kernelCount, B.flatWidth);
            Assert.AreEqual(B.flatWidth, B.length);
            Assert.AreEqual(stride.Length, 2);
            Assert.AreEqual(pad.Length, 4);

            // refer to BarracudaCompute.cs for details
            // 0-pad X
            CompiledInstruction instruction0PadX = m_Compiled.instructions[0];

            Assert.IsNotNull(instruction0PadX.kernel.shader);

            var XpaddedShape = instruction0PadX.shape;
            var Xpadded      = NewTensor(XpaddedShape);
            var fn0PadX      = instruction0PadX.kernel;

            fn0PadX.shader.SetInts("_Stride", stride);
            fn0PadX.SetTensor("X", X.shape, Pin(X).buffer);
            fn0PadX.SetTensor("O", Xpadded.shape, Pin(Xpadded).buffer);
            fn0PadX.Dispatch();

            // kernel flip
            CompiledInstruction instructionKernelFlip = m_Compiled.instructions[1];

            Assert.IsTrue(instructionKernelFlip.tensors.Length >= 2);
            var Kflipped = instructionKernelFlip.tensors[0];
            var Bpacked  = instructionKernelFlip.tensors[1];

            // convolution
            CompiledInstruction instructionConv = m_Compiled.instructions[2];

            Assert.IsNotNull(instructionConv.kernel.shader);
            var fnConv = instructionConv.kernel;

            var padTrans = new int[]
            {
                K.kernelWidth - pad[0] - 1, K.kernelHeight - pad[1] - 1,
                K.kernelWidth - pad[2] - 1, K.kernelHeight - pad[3] - 1
            };
            var strideTrans = new int[] { 1, 1 };

            if (fnConv.shader == null)
            {
                return(base.Conv2D(Xpadded, Kflipped, Bpacked, strideTrans, padTrans, Layer.FusedActivation.None));
            }

            Assert.IsNotNull(fnConv.shader);

            var O = NewTensor(instructionConv.shape);

            fnConv.SetTensor("X", Xpadded.shape, Pin(Xpadded).buffer);
            fnConv.SetTensor(_DeclO, _DataO, O.shape, Pin(O).buffer);

            if (instructionConv.tensors?.Length == 2)
            {
                Kflipped = instructionConv.tensors[0];
                Bpacked  = instructionConv.tensors[1];
            }

            fnConv.SetTensorDecl(_DeclK, Kflipped.shape, Pin(Kflipped).offset);
            fnConv.SetTensorDecl(_DeclB, Bpacked.shape, Pin(Bpacked).offset);
            Assert.AreEqual(Pin(Kflipped).buffer, Pin(Bpacked).buffer);
            fnConv.SetTensorBuffer(_DataWBK, Pin(Kflipped).buffer);

            fnConv.shader.SetInts(_Pad, padTrans);
            fnConv.shader.SetInts(_Stride, strideTrans);

            fnConv.Dispatch();

            Xpadded.Dispose();
            return(O);
        }
Esempio n. 7
0
        public CompiledProgram Compile(NodeRuntimeApplication rta, SignalTable signalTable)
        {
            if (rta == null)
            {
                throw new ArgumentNullException("rta");
            }
            if (signalTable == null)
            {
                throw new ArgumentNullException("signalTable");
            }
            var runtimeId = Guid.Parse(rta.RuntimeId.ToString());
            var versionId = Guid.Parse(rta.ID.ToString());

            var logic = rta.Logic;
            var compiledInstructions = new List <CompiledInstruction>();

            var discreteInputs = rta.DeviceConfiguration.GetChildrenRecursive()
                                 .Select(x => x.Value)
                                 .OfType <NodeDiscreteInput>();

            foreach (var discreteInput in discreteInputs)
            {
                if (discreteInput.Forced.BoolValue)
                {
                    var address = Int16.Parse(discreteInput.Address.ToString());
                    this.driveSignalWithCoilToConstantValue(
                        address, discreteInput.ForcedValue.BoolValue,
                        signalTable, compiledInstructions);
                }
            }

            var analogInputs = rta.DeviceConfiguration.GetChildrenRecursive()
                               .Select(x => x.Value)
                               .OfType <NodeAnalogInput>();

            foreach (var analogInput in analogInputs)
            {
                if (analogInput.Forced.BoolValue)
                {
                    if (analogInput.ForcedValue.DataType != FieldDataType.DataTypeEnum.NUMBER)
                    {
                        throw new Exception("Data type of forced value must be NUMBER.");
                    }
                    var address = byte.Parse(analogInput.Address.ToString());
                    this.setNumericAddressToValueWithAddInstruction(
                        address, (decimal)(analogInput.ForcedValue.Value),
                        signalTable, compiledInstructions);
                }
            }

            compiledInstructions.AddRange(compilePageCollection(logic, signalTable));

            // discrete output literals
            var discreteOutputs = rta.DeviceConfiguration.GetChildrenRecursive()
                                  .Select(x => x.Value)
                                  .OfType <NodeDiscreteOutput>();

            foreach (var discreteOutput in discreteOutputs)
            {
                var literal = discreteOutput.SignalIn.Literal;
                var address = Int16.Parse(discreteOutput.Address.ToString());
                if (literal != null)
                {
                    // insert a new rung to set the literal value
                    if (literal.DataType != FieldDataType.DataTypeEnum.BOOL)
                    {
                        throw new Exception("Data type must be BOOL.");
                    }
                    var literalValue = (bool)(literal.Value);

                    this.driveSignalWithCoilToConstantValue(
                        address, literalValue,
                        signalTable, compiledInstructions);
                }
            }

            // boolean jumpers (from internal signals to outputs)
            foreach (var booleanJumper in signalTable.BooleanJumpers)
            {
                var compiledContactSignal = new CompiledBooleanSignal(true, booleanJumper.Item1, signalTable.BooleanAddressBits);
                var contact = new CompiledInstruction(
                    0x01, // NO contact
                    3,
                    compiledContactSignal);
                compiledInstructions.Add(contact);

                var compiledDiscreteOutputSignal = new CompiledBooleanSignal(false, booleanJumper.Item2, signalTable.BooleanAddressBits);
                var coil = new CompiledInstruction(
                    0x00, // coil
                    3,
                    compiledDiscreteOutputSignal);
                compiledInstructions.Add(coil);
                compiledInstructions.Add(new CompiledInstruction(0x03, 3)); // series instruction end (end of rung)
            }

            // boolean forces
            foreach (var discreteOutput in discreteOutputs)
            {
                var address = Int16.Parse(discreteOutput.Address.ToString());
                if (discreteOutput.Forced.BoolValue)
                {
                    this.driveSignalWithCoilToConstantValue(
                        address, discreteOutput.ForcedValue.BoolValue,
                        signalTable, compiledInstructions);
                }
            }

            // analog output literals
            var analogOutputs = rta.DeviceConfiguration.GetChildrenRecursive()
                                .Select(x => x.Value)
                                .OfType <NodeAnalogOutput>();

            foreach (var analogOutput in analogOutputs)
            {
                var literal = analogOutput.SignalIn.Literal;
                var address = Byte.Parse(analogOutput.Address.ToString());
                if (literal != null)
                {
                    // insert a new rung to set the literal value
                    if (literal.DataType != FieldDataType.DataTypeEnum.NUMBER)
                    {
                        throw new Exception("Data type of literal must be NUMBER.");
                    }
                    this.setNumericAddressToValueWithAddInstruction(
                        address, (decimal)(literal.Value),
                        signalTable, compiledInstructions);
                }
            }

            // analog jumpers (from internal signals to outputs)
            foreach (var numericJumper in signalTable.NumericJumpers)
            {
                var sourceAddress      = numericJumper.Item1;
                var destinationAddress = numericJumper.Item2;

                var compiledOperand1Signal = new CompiledNumericSignal(true, sourceAddress, signalTable.NumericAddressBits);
                var operand2SignalIn       = NodeSignalIn.BuildWith(
                    new FieldDataType(FieldDataType.DataTypeEnum.NUMBER),
                    new FieldConstant(FieldDataType.DataTypeEnum.NUMBER, 0M));
                var compiledOperand2Signal = numericSignal(operand2SignalIn, signalTable);

                var compiledResultSignal = new CompiledNumericSignal(false, destinationAddress, signalTable.NumericAddressBits);
                var add = new CompiledInstruction(
                    0x78, // add
                    7,
                    compiledOperand1Signal, compiledOperand2Signal, compiledResultSignal);
                compiledInstructions.Add(add);
                compiledInstructions.Add(new CompiledInstruction(0x03, 3)); // series instruction end (end of rung)
            }

            // analog forces
            foreach (var analogOutput in analogOutputs)
            {
                var address = Byte.Parse(analogOutput.Address.ToString());
                if (analogOutput.Forced.BoolValue)
                {
                    if (analogOutput.ForcedValue.DataType != FieldDataType.DataTypeEnum.NUMBER)
                    {
                        throw new Exception("Data type of forced value must be NUMBER.");
                    }
                    this.setNumericAddressToValueWithAddInstruction(
                        address, (decimal)(analogOutput.ForcedValue.Value),
                        signalTable, compiledInstructions);
                }
            }

            // end of program
            compiledInstructions.Add(new CompiledInstruction(PROGRAM_END, 8));

            var packedInstructions = bitPackInstructions(compiledInstructions);

            return(new CompiledProgram(
                       runtimeId,
                       versionId,
                       signalTable.BooleanAddressBits,
                       signalTable.NumericAddressBits,
                       packedInstructions));
        }
Esempio n. 8
0
 public CodeBlock(IList <byte> v1, CompiledInstruction instr) : this(v1) { Instructions = new CompiledInstruction[] { instr }; }