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) }
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); }
// --------------------------------------------------------------------------------- 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); }
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) }
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)); }
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); }
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)); }
public CodeBlock(IList <byte> v1, CompiledInstruction instr) : this(v1) { Instructions = new CompiledInstruction[] { instr }; }