| @@ -27,7 +27,7 @@ namespace Tensorflow | |||
| // 100K gradient 44M. | |||
| mm.Execute(10, 10 * batchSize, cases.Gradient); | |||
| // 120M | |||
| // 95M | |||
| Console.WriteLine("Finished."); | |||
| Console.ReadLine(); | |||
| } | |||
| @@ -0,0 +1,30 @@ | |||
| /***************************************************************************** | |||
| Copyright 2020 The TensorFlow.NET Authors. All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| You may obtain a copy of the License at | |||
| http://www.apache.org/licenses/LICENSE-2.0 | |||
| Unless required by applicable law or agreed to in writing, software | |||
| distributed under the License is distributed on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| See the License for the specific language governing permissions and | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using NumSharp; | |||
| namespace Tensorflow | |||
| { | |||
| public partial class tensorflow | |||
| { | |||
| public CompatApi compat { get; } = new CompatApi(); | |||
| public class CompatApi | |||
| { | |||
| public CompatV1Api v1 { get; } = new CompatV1Api(); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,30 @@ | |||
| /***************************************************************************** | |||
| Copyright 2020 The TensorFlow.NET Authors. All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| You may obtain a copy of the License at | |||
| http://www.apache.org/licenses/LICENSE-2.0 | |||
| Unless required by applicable law or agreed to in writing, software | |||
| distributed under the License is distributed on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| See the License for the specific language governing permissions and | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using System; | |||
| using Tensorflow.Eager; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow | |||
| { | |||
| public class CompatV1Api | |||
| { | |||
| public void disable_eager_execution() | |||
| { | |||
| tf.context.default_execution_mode = Context.GRAPH_MODE; | |||
| } | |||
| } | |||
| } | |||
| @@ -259,7 +259,8 @@ namespace Tensorflow | |||
| public Operation create_op(string op_type, Tensor[] inputs, TF_DataType[] dtypes, | |||
| TF_DataType[] input_types = null, string name = null, | |||
| Dictionary<string, AttrValue> attrs = null, OpDef op_def = null) | |||
| Dictionary<string, AttrValue> attrs = null, OpDef op_def = null, | |||
| bool compute_device = true) | |||
| { | |||
| if (inputs == null) | |||
| inputs = new Tensor[0]; | |||
| @@ -270,7 +271,7 @@ namespace Tensorflow | |||
| // If a names ends with a '/' it is a "name scope" and we use it as-is, | |||
| // after removing the trailing '/'. | |||
| name = name.EndsWith("/") ? ops.name_from_scope_name(name) : unique_name(name); | |||
| var node_def = ops._NodeDef(op_type, name, device: "", attrs: attrs); | |||
| var node_def = ops._NodeDef(op_type, name, attrs: attrs); | |||
| var input_ops = inputs.Select(x => x.op).ToArray(); | |||
| var control_inputs = _control_dependencies_for_inputs(input_ops); | |||
| @@ -284,7 +285,7 @@ namespace Tensorflow | |||
| original_op: null, | |||
| op_def: op_def); | |||
| _create_op_helper(op, true); | |||
| _create_op_helper(op, compute_device); | |||
| /*Console.Write($"create_op: {op_type} '{node_def.Name}'"); | |||
| Console.Write($", inputs: {(inputs.Length == 0 ? "empty" : String.Join(", ", inputs.Select(x => x.name)))}"); | |||
| @@ -40,8 +40,8 @@ namespace Tensorflow | |||
| public void _add_control_input(Operation op) | |||
| { | |||
| //c_api.TF_AddControlInput(_operDesc, op); | |||
| c_api.AddControlInput(graph, _handle, op); | |||
| c_api.TF_AddControlInput(OpDesc, op); | |||
| //c_api.AddControlInput(graph, _handle, op); | |||
| } | |||
| public void _add_control_inputs(Operation[] ops) | |||
| @@ -64,7 +64,7 @@ namespace Tensorflow | |||
| public string Device => _handle == IntPtr.Zero ? null : c_api.StringPiece(c_api.TF_OperationDevice(_handle)); | |||
| bool _is_stateful; | |||
| public OperationDescription OpDesc { get; set; } | |||
| public NodeDef node_def | |||
| { | |||
| @@ -170,7 +170,7 @@ namespace Tensorflow | |||
| op_def = g.GetOpDef(node_def.Op); | |||
| var grouped_inputs = _reconstruct_sequence_inputs(op_def, inputs, node_def.Attr); | |||
| _handle = ops._create_c_op(g, node_def, grouped_inputs, control_input_ops.ToArray()); | |||
| (_handle, OpDesc) = ops._create_c_op(g, node_def, grouped_inputs, control_input_ops.ToArray()); | |||
| _is_stateful = op_def.IsStateful; | |||
| // Initialize self._outputs. | |||
| @@ -187,9 +187,6 @@ namespace Tensorflow | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern unsafe ulong TF_StringEncode(byte* src, ulong src_len, sbyte* dst, ulong dst_len, SafeStatusHandle status); | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern unsafe ulong TF_StringEncode(IntPtr src, ulong src_len, IntPtr dst, ulong dst_len, SafeStatusHandle status); | |||
| /// <summary> | |||
| /// Decode a string encoded using TF_StringEncode. | |||
| /// </summary> | |||
| @@ -199,9 +196,6 @@ namespace Tensorflow | |||
| /// <param name="dst_len">size_t*</param> | |||
| /// <param name="status">TF_Status*</param> | |||
| /// <returns></returns> | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern ulong TF_StringDecode(IntPtr src, ulong src_len, IntPtr dst, ref ulong dst_len, SafeStatusHandle status); | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern unsafe ulong TF_StringDecode(byte* src, ulong src_len, byte** dst, ref ulong dst_len, SafeStatusHandle status); | |||
| @@ -155,7 +155,7 @@ namespace Tensorflow | |||
| /// </param> | |||
| /// <param name="control_inputs">A list of `Operation`s to set as control dependencies.</param> | |||
| /// <returns>A wrapped TF_Operation*.</returns> | |||
| public static IntPtr _create_c_op<T>(Graph graph, NodeDef node_def, T[] inputs, Operation[] control_inputs) | |||
| public static (IntPtr, OperationDescription) _create_c_op<T>(Graph graph, NodeDef node_def, T[] inputs, Operation[] control_inputs) | |||
| { | |||
| lock (Locks.ProcessWide) | |||
| { | |||
| @@ -198,7 +198,7 @@ namespace Tensorflow | |||
| status.Check(true); | |||
| return c_op; | |||
| return (c_op, op_desc); | |||
| } | |||
| } | |||
| @@ -207,7 +207,7 @@ namespace Tensorflow | |||
| return graph.GetOpDef(type); | |||
| } | |||
| public static NodeDef _NodeDef(string op_type, string name, string device = "", Dictionary<string, AttrValue> attrs = null) | |||
| public static NodeDef _NodeDef(string op_type, string name, Dictionary<string, AttrValue> attrs = null) | |||
| { | |||
| var node_def = new NodeDef(); | |||
| node_def.Op = op_type; | |||
| @@ -4,13 +4,13 @@ using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using Tensorflow.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.Basics | |||
| { | |||
| [Ignore] | |||
| [TestClass] | |||
| public class QueueTest | |||
| public class QueueTest : GraphModeTestBase | |||
| { | |||
| [TestMethod] | |||
| public void PaddingFIFOQueue() | |||
| @@ -10,7 +10,6 @@ namespace TensorFlowNET.UnitTest.Basics | |||
| [TestClass] | |||
| public class VariableTest | |||
| { | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void NewVariable() | |||
| { | |||
| @@ -34,7 +33,6 @@ namespace TensorFlowNET.UnitTest.Basics | |||
| Assert.AreEqual(4, (int)y.numpy()); | |||
| } | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void Assign1() | |||
| { | |||
| @@ -0,0 +1,24 @@ | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using TensorFlowNET.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.UnitTest | |||
| { | |||
| public class GraphModeTestBase : PythonTest | |||
| { | |||
| [TestInitialize] | |||
| public void TestInit() | |||
| { | |||
| tf.compat.v1.disable_eager_execution(); | |||
| } | |||
| [TestCleanup] | |||
| public void TestClean() | |||
| { | |||
| tf.enable_eager_execution(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,16 +1,16 @@ | |||
| using System; | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using Tensorflow; | |||
| using Tensorflow.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.Basics | |||
| { | |||
| [TestClass] | |||
| public class NameScopeTest | |||
| public class NameScopeTest : GraphModeTestBase | |||
| { | |||
| string name = ""; | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void NestedNameScope() | |||
| { | |||
| @@ -7,12 +7,12 @@ using Tensorflow; | |||
| using Tensorflow.Util; | |||
| using Buffer = Tensorflow.Buffer; | |||
| using static Tensorflow.Binding; | |||
| using Tensorflow.UnitTest; | |||
| namespace TensorFlowNET.UnitTest.Basics | |||
| { | |||
| [Ignore] | |||
| [TestClass] | |||
| public class OperationsTest | |||
| public class OperationsTest : GraphModeTestBase | |||
| { | |||
| /// <summary> | |||
| /// Port from tensorflow\c\c_api_test.cc | |||
| @@ -726,6 +726,7 @@ namespace TensorFlowNET.UnitTest.Basics | |||
| #endregion | |||
| } | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void divOpTests() | |||
| { | |||
| @@ -3,6 +3,7 @@ using NumSharp; | |||
| using System; | |||
| using System.Linq; | |||
| using System.Runtime.InteropServices; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| @@ -160,23 +161,6 @@ namespace TensorFlowNET.UnitTest.Basics | |||
| Assert.AreEqual(6.0, (double)c); | |||
| } | |||
| [TestMethod] | |||
| public void StringEncode() | |||
| { | |||
| string str = "Hello, TensorFlow.NET!"; | |||
| var handle = Marshal.StringToHGlobalAnsi(str); | |||
| var dst_len = c_api.TF_StringEncodedSize((ulong)str.Length); | |||
| Assert.AreEqual(dst_len, (ulong)23); | |||
| IntPtr dst = Marshal.AllocHGlobal((int)dst_len); | |||
| var encoded_len = c_api.TF_StringEncode(handle, (ulong)str.Length, dst, dst_len, status.Handle); | |||
| Assert.AreEqual((ulong)23, encoded_len); | |||
| Assert.AreEqual(status.Code, TF_Code.TF_OK); | |||
| string encoded_str = Marshal.PtrToStringUTF8(dst + sizeof(byte)); | |||
| Assert.AreEqual(encoded_str, str); | |||
| Assert.AreEqual(str.Length, Marshal.ReadByte(dst)); | |||
| // c_api.TF_StringDecode(dst, (ulong)str.Length, IntPtr.Zero, ref dst_len, status.Handle); | |||
| } | |||
| [TestMethod] | |||
| public void Reshape() | |||
| { | |||
| @@ -1,5 +1,6 @@ | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using Tensorflow; | |||
| using Tensorflow.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.control_flow_ops_test | |||
| @@ -7,10 +8,10 @@ namespace TensorFlowNET.UnitTest.control_flow_ops_test | |||
| /// <summary> | |||
| /// excerpt of tensorflow/python/framework/ops/control_flow_ops_test.py | |||
| /// </summary> | |||
| [Ignore] | |||
| [TestClass] | |||
| public class CondTestCases : PythonTest | |||
| public class CondTestCases : GraphModeTestBase | |||
| { | |||
| [Ignore("Dependent on UpdateEdge")] | |||
| [TestMethod] | |||
| public void testCondTrue_ConstOnly() | |||
| { | |||
| @@ -49,6 +50,7 @@ namespace TensorFlowNET.UnitTest.control_flow_ops_test | |||
| } | |||
| } | |||
| [Ignore("Dependent on UpdateEdge")] | |||
| [TestMethod] | |||
| public void testCondTrue() | |||
| { | |||
| @@ -65,6 +67,7 @@ namespace TensorFlowNET.UnitTest.control_flow_ops_test | |||
| assertEquals(result, 34); | |||
| } | |||
| [Ignore("Dependent on UpdateEdge")] | |||
| [TestMethod] | |||
| public void testCondFalse() | |||
| { | |||
| @@ -1,14 +1,14 @@ | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using Tensorflow; | |||
| using Tensorflow.UnitTest; | |||
| namespace TensorFlowNET.UnitTest.control_flow_ops_test | |||
| { | |||
| /// <summary> | |||
| /// excerpt of tensorflow/python/framework/ops/control_flow_ops_test.py | |||
| /// </summary> | |||
| [Ignore] | |||
| [TestClass] | |||
| public class ShapeTestCase : PythonTest | |||
| public class ShapeTestCase : GraphModeTestBase | |||
| { | |||
| [TestMethod] | |||
| @@ -1,24 +1,24 @@ | |||
| using System; | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using Tensorflow; | |||
| using Tensorflow.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.control_flow_ops_test | |||
| { | |||
| [TestClass] | |||
| public class WhileContextTestCase : PythonTest | |||
| public class WhileContextTestCase : GraphModeTestBase | |||
| { | |||
| /// <summary> | |||
| /// https://www.tensorflow.org/api_docs/python/tf/while_loop | |||
| /// </summary> | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void SimpleWhileLoop() | |||
| { | |||
| var i = constant_op.constant(0, name: "i"); | |||
| var c = new Func<Tensor, Tensor>(x => tf.less(x, 10, name: "c")); | |||
| var b = new Func<Tensor, Tensor>(x => tf.add(x, 1, name: "c")); | |||
| //var r = control_flow_ops.while_loop(c, b, i); | |||
| // var r = control_flow_ops.while_loop(c, b, i); | |||
| } | |||
| private void _testWhileContextHelper(int maximum_iterations) | |||
| @@ -2,15 +2,14 @@ | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using NumSharp; | |||
| using Tensorflow; | |||
| using Tensorflow.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.img_test | |||
| { | |||
| [Ignore] | |||
| [TestClass] | |||
| public class TestCrop | |||
| public class TestCrop : GraphModeTestBase | |||
| { | |||
| [TestMethod] | |||
| public void TestCropAndResize() | |||
| { | |||
| @@ -3,13 +3,13 @@ using FluentAssertions; | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using NumSharp; | |||
| using Tensorflow; | |||
| using Tensorflow.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.layers_test | |||
| { | |||
| [Ignore] | |||
| [TestClass] | |||
| public class flatten | |||
| public class flatten : GraphModeTestBase | |||
| { | |||
| [TestMethod] | |||
| public void Case1() | |||
| @@ -3,6 +3,7 @@ using System.Linq; | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using Tensorflow; | |||
| using Tensorflow.Eager; | |||
| using Tensorflow.UnitTest; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.ops_test | |||
| @@ -10,9 +11,8 @@ namespace TensorFlowNET.UnitTest.ops_test | |||
| /// <summary> | |||
| /// excerpt of tensorflow/python/framework/ops_test.py | |||
| /// </summary> | |||
| [Ignore] | |||
| [TestClass] | |||
| public class ControlDependenciesTest : PythonTest | |||
| public class ControlDependenciesTest : GraphModeTestBase | |||
| { | |||
| [TestMethod] | |||
| public void TestBasic() | |||
| @@ -35,72 +35,6 @@ namespace TensorFlowNET.UnitTest.ops_test | |||
| Assert.AreEqual(0, e.op.control_inputs.Length); | |||
| } | |||
| [Ignore("Future is not supported yet")] | |||
| [TestMethod] | |||
| public void TestEager() | |||
| { | |||
| Tensor a = null, c = null; | |||
| object b = null; | |||
| var calls = 0; | |||
| Func<Tensor> future = () => | |||
| { | |||
| calls += 1; | |||
| return constant_op.constant(2.0); | |||
| }; | |||
| using (var opts = new ContextOptions()) | |||
| using (var status = new Status()) | |||
| using (var context = new Context(opts, status)) | |||
| { | |||
| if (context.executing_eagerly()) | |||
| { | |||
| // TODO: make this compile (see original Python code below) | |||
| a = constant_op.constant(1.0); | |||
| b = future; // <--- {henon} obviously, this doesn't compile, looks like control_dependencies needs to be able to take callables as well. | |||
| tf_with(ops.control_dependencies(new object[] { a, b }), ctrl => | |||
| { | |||
| return c = constant_op.constant(3.0); | |||
| }); | |||
| Assert.AreEqual(calls, 1); | |||
| } | |||
| else | |||
| { | |||
| var g = tf.Graph().as_default(); | |||
| a = constant_op.constant(1.0); | |||
| var b1 = future(); | |||
| tf_with(g.control_dependencies(new[] { a, b }), ctrl => | |||
| { | |||
| c = constant_op.constant(3.0); | |||
| }); | |||
| Assert.IsTrue(Enumerable.SequenceEqual(c.op.control_inputs, new[] { a.op, b1.op })); | |||
| Assert.AreEqual(1, calls); | |||
| } | |||
| } | |||
| /* | |||
| def testEager(self): | |||
| def future(): | |||
| future.calls += 1 | |||
| return constant_op.constant(2.0) | |||
| future.calls = 0 | |||
| if context.executing_eagerly(): | |||
| a = constant_op.constant(1.0) | |||
| b = future | |||
| with ops.control_dependencies([a, b]): | |||
| c = constant_op.constant(3.0) | |||
| self.assertEqual(future.calls, 1) | |||
| else: | |||
| g = ops.Graph() | |||
| with g.as_default(): | |||
| a = constant_op.constant(1.0) | |||
| b = future() | |||
| with g.control_dependencies([a, b]): | |||
| c = constant_op.constant(3.0) | |||
| self.assertEqual(c.op.control_inputs, [a.op, b.op]) | |||
| self.assertEqual(future.calls, 1) | |||
| */ | |||
| } | |||
| [Ignore("How to port the ConvertibleObj?")] | |||
| [TestMethod] | |||
| public void TestBasicWithConversion() | |||
| @@ -28,7 +28,7 @@ namespace TensorFlowNET.UnitTest.ops_test | |||
| using (var g = tf.Graph().as_default()) | |||
| { | |||
| var x = constant_op.constant(new[,] {{1, 2, 3}, {4, 5, 6}}); | |||
| var c_op = ops._create_c_op(g, ops._NodeDef("Identity", "myop"), new[] {x}, new Operation[0]); | |||
| var (c_op, op_desc) = ops._create_c_op(g, ops._NodeDef("Identity", "myop"), new[] {x}, new Operation[0]); | |||
| var op = g._create_op_from_tf_operation(c_op); | |||
| Assert.AreEqual("myop", op.name); | |||