예제 #1
0
        public RunStatus Run(IVariable <T> output, ref IVariable <T> gradient, params IVariable <T>[] input)
        {
            RunStatus s = Run(output, input);

            if (s != RunStatus.Success)
            {
                gradient = null;
                return(s);
            }

            var gc = new Gradient(Context, OutputValue);
            var c  = new Composer(_context);

            GradientTensors = new Dictionary <DeviceTensor, DeviceTensor>();
            for (int i = 0; i < InputTensors.Count; i++)
            {
                var t    = InputTensors[i];
                var grad = gc.ComputeWrt(t);
                if (!grad.IsAllocated)
                {
                    continue;
                }
                c.AddInputPlaceholder(InputTensors[i].Name, InputTensors[i].DimensionCount);
                var gt = new DeviceTensor(t.Device, t.Shape, grad.Name);
                c.AddOutputValue(gt);
                c.AddUpdate(gt, grad);
                GradientTensors.Add(t, gt);
            }

            var gf    = c.BuildFunction();
            var ginv  = new Invoker <int>(_context, gf, InputTensors.ToArray(), GradientTensors.Values.ToArray());
            var ginvc = ginv.Invoke();

            if (!ginvc.IsAllocated)
            {
                gradient = null;
                return(RunStatus.ErrorComputingGradient);
            }

            var gv = GradientTensors.First().Value.CreateView <T>(MemoryMapType.Retain);

            if (!gv.CopyToAndFree(gradient.Span))
            {
                gv.Free();
                gradient = null;
                return(RunStatus.ErrorComputingGradient);
            }

            return(RunStatus.Success);
        }
예제 #2
0
        public void CanComputeGradient()
        {
            Device   device = new Device(testContext);
            string   code   = @"function (I) -> (O) {
                                O = I * I;
                            }";
            Function f      = new Function(testContext, code);

            Assert.True(f.IsAllocated);
            DeviceTensor i = new DeviceTensor(device, new Compiler.PlaidML.Shape(testContext, PlaidmlDatatype.PLAIDML_DATA_INT32, 6),
                                              "I");
            DeviceTensor o = new DeviceTensor(device, new Compiler.PlaidML.Shape(testContext, PlaidmlDatatype.PLAIDML_DATA_INT32, 6),
                                              "O");

            Int32[] input_data = { 0, 1, 3, 4, 5, 6 };
            i.CreateView <Int32>(MemoryMapType.Discard).CopyFromAndFree(input_data);
            var v = i.CreateView <Int32>(MemoryMapType.Retain);

            Assert.Equal(3, v[2]);
            Invoker <int> inv1 = new Invoker <int>(testContext, f, o, i);

            Assert.True(inv1.IsAllocated);
            Invocation <int> k = inv1.Invoke();

            Assert.True(k.IsAllocated);
            DeviceTensorView <Int32> R = o.CreateView <Int32>(MemoryMapType.Retain);

            Assert.Equal(6, R.ElementCount);
            Assert.Equal(9, R[2]);

            var gradients = new Dictionary <DeviceTensor, Value>();

            for (int n = 0; n < inv1.InputTensors.Count; n++)
            {
                Gradient gc = new Gradient(testContext, inv1.OutputValue);
                if (!gc.IsAllocated)
                {
                    continue;
                }
                Value grad = gc.ComputeWrt(inv1.InputTensors[n]);
                if (!grad.IsAllocated)
                {
                    continue;
                }
                gradients.Add(inv1.InputTensors[n], grad);
            }

            Composer c = new Composer(testContext);


            foreach (DeviceTensor t in inv1.InputTensors)
            {
                Assert.True(c.AddInputPlaceholder(t.Name, t.DimensionCount));
            }
            List <DeviceTensor> gradTensors = new List <DeviceTensor>();

            foreach (var g in gradients)
            {
                var gt = new DeviceTensor(g.Key.Device, g.Key.Shape, g.Value.Name);
                c.AddOutputValue(gt);
                c.AddUpdate(gt, g.Value);
                gradTensors.Add(gt);
            }
            Function gf = c.BuildFunction();

            Assert.True(gf.IsAllocated);
            Invoker <int> ginv = new Invoker <int>(testContext, gf, inv1.InputTensors.ToArray(), gradTensors.ToArray());

            Assert.True(ginv.IsAllocated);
            var k2 = ginv.Invoke();

            Assert.True(k2.IsAllocated);

            DeviceTensorView <Int32> RG = gradTensors.First().CreateView <Int32>(MemoryMapType.Retain);
        }