diff --git a/test/TensorFlowNET.UnitTest/EagerModeTestBase.cs b/test/TensorFlowNET.UnitTest/EagerModeTestBase.cs index 1b49c3b4..9ca58ab0 100644 --- a/test/TensorFlowNET.UnitTest/EagerModeTestBase.cs +++ b/test/TensorFlowNET.UnitTest/EagerModeTestBase.cs @@ -2,10 +2,9 @@ using System; using System.Collections.Generic; using System.Text; -using TensorFlowNET.UnitTest; using static Tensorflow.Binding; -namespace Tensorflow.UnitTest +namespace TensorFlowNET.UnitTest { public class EagerModeTestBase : PythonTest { diff --git a/test/TensorFlowNET.UnitTest/ImageTest.cs b/test/TensorFlowNET.UnitTest/ImageTest.cs index f9b3ec10..395f5fe4 100644 --- a/test/TensorFlowNET.UnitTest/ImageTest.cs +++ b/test/TensorFlowNET.UnitTest/ImageTest.cs @@ -14,7 +14,7 @@ namespace TensorFlowNET.UnitTest.Basics /// Find more examples in https://www.programcreek.com/python/example/90444/tensorflow.read_file /// [TestClass] - public class ImageTest + public class ImageTest : GraphModeTestBase { string imgPath = "shasta-daisy.jpg"; Tensor contents; diff --git a/test/TensorFlowNET.UnitTest/ManagedAPI/ControlFlowApiTest.cs b/test/TensorFlowNET.UnitTest/ManagedAPI/ControlFlowApiTest.cs new file mode 100644 index 00000000..56eeddf9 --- /dev/null +++ b/test/TensorFlowNET.UnitTest/ManagedAPI/ControlFlowApiTest.cs @@ -0,0 +1,54 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using Tensorflow; +using static Tensorflow.Binding; + +namespace TensorFlowNET.UnitTest.ManagedAPI +{ + [TestClass] + public class ControlFlowApiTest + { + [TestMethod] + public void WhileLoopOneInputEagerMode() + { + tf.enable_eager_execution(); + + var i = tf.constant(2); + Func c = (x) => tf.less(x, 10); + Func b = (x) => tf.add(x, 1); + var r = tf.while_loop(c, b, i); + Assert.AreEqual(10, (int)r); + } + + [TestMethod] + public void WhileLoopTwoInputsEagerMode() + { + tf.enable_eager_execution(); + + var i = tf.constant(2); + var j = tf.constant(3); + Func c = (x) => tf.less(x[0] + x[1], 10); + Func b = (x) => new[] { tf.add(x[0], 1), tf.add(x[1], 1) }; + var r = tf.while_loop(c, b, new[] { i, j }); + Assert.AreEqual(5, (int)r[0]); + Assert.AreEqual(6, (int)r[1]); + } + + [TestMethod, Ignore] + public void WhileLoopGraphMode() + { + tf.compat.v1.disable_eager_execution(); + + var i = tf.constant(2); + Func c = (x) => tf.less(x, 10); + Func b = (x) => tf.add(x, 1); + var r = tf.while_loop(c, b, i); + Assert.AreEqual(10, (int)r); + } + } +} diff --git a/test/TensorFlowNET.UnitTest/ManagedAPI/FunctionApiTest.cs b/test/TensorFlowNET.UnitTest/ManagedAPI/FunctionApiTest.cs new file mode 100644 index 00000000..cfc234e7 --- /dev/null +++ b/test/TensorFlowNET.UnitTest/ManagedAPI/FunctionApiTest.cs @@ -0,0 +1,70 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Tensorflow; +using Tensorflow.Graphs; +using static Tensorflow.Binding; + +namespace TensorFlowNET.UnitTest.ManagedAPI +{ + [TestClass] + public class FunctionApiTest : TFNetApiTest + { + [TestMethod] + public void TwoInputs_OneOutput() + { + var func = tf.autograph.to_graph(Add); + var a = tf.constant(1); + var b = tf.constant(2); + var output = func(a, b); + Assert.AreEqual(3, (int)output); + } + + Tensor Add(Tensor a, Tensor b) + { + return a + b; + } + + [TestMethod] + public void TwoInputs_OneOutput_Condition() + { + var func = tf.autograph.to_graph(Condition); + var a = tf.constant(3); + var b = tf.constant(2); + var output = func(a, b); + Assert.AreEqual(2, (int)output); + } + + Tensor Condition(Tensor a, Tensor b) + { + return tf.cond(a < b, a, b); + } + + [TestMethod] + public void TwoInputs_OneOutput_Lambda() + { + var func = tf.autograph.to_graph((x, y) => x * y); + var output = func(tf.constant(3), tf.constant(2)); + Assert.AreEqual(6, (int)output); + } + + [TestMethod] + public void TwoInputs_OneOutput_WhileLoop() + { + var func = tf.autograph.to_graph((x, y) => x * y); + var output = func(tf.constant(3), tf.constant(2)); + Assert.AreEqual(6, (int)output); + } + + Tensor WhileLoop() + { + var i = tf.constant(0); + Func c = i => tf.less(i, 10); + Func b = i => tf.add(i, 1); + //var r = tf.(c, b, [i]) + throw new NotImplementedException(""); + } + } +} diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/CApiFunctionTest.cs b/test/TensorFlowNET.UnitTest/NativeAPI/CApiFunctionTest.cs index edeea743..75be3a49 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/CApiFunctionTest.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/CApiFunctionTest.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Runtime.InteropServices; using Tensorflow; using Tensorflow.Functions; @@ -41,7 +42,351 @@ namespace TensorFlowNET.UnitTest.NativeAPI // Use, run, and verify var func_op = Use(new Operation[0]); Run(new KeyValuePair[0], func_op, 10); - VerifyFDef(new[] { "scalar10_0" }); + VerifyFDef(new[] { "scalar10_0" }, + new List(), + new List { new IOSpec("scalar10", DataType.DtInt32) }, + new List { new EdgeSpec("scalar10_0:output:0", "scalar10") }, + new List()); + } + + [TestMethod] + public void OneOp_OneInput_OneOutput() + { + // Define + var feed = Placeholder(func_graph_, s_); + var neg = Neg(feed, func_graph_, s_); + Define(-1, new Operation[0], new[] { feed }, new[] { neg }, new string[0]); + + // Use, run, and verify + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, func_op, -3); + VerifyFDef(new string[] { "neg_0" }, + new List { new IOSpec("feed", DataType.DtInt32) }, + new List { new IOSpec("neg", DataType.DtInt32) }, + new List { new EdgeSpec("feed", "neg_0:0"), new EdgeSpec("neg_0:y:0", "neg") }, + new List()); + } + + [TestMethod] + public void OneOutput_OutputNames() + { + // Define + var feed = Placeholder(func_graph_, s_); + var neg = Neg(feed, func_graph_, s_); + Define(-1, + new Operation[0], + new[] { feed }, + new[] { neg }, + new[] { "negated_num" }); + + // Use, run, and verify + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, func_op, -3); + VerifyFDef(new string[] { "neg" }, + new List { new IOSpec("feed", DataType.DtInt32) }, + new List { new IOSpec("negated_num", DataType.DtInt32) }, + new List { new EdgeSpec("feed", "neg:0"), new EdgeSpec("neg:y:0", "negated_num") }, + new List()); + } + + [TestMethod] + public void OutputNames_SameNameAsInput() + { + // Define + var feed = Placeholder(func_graph_, s_, "negation"); + var neg = Neg(feed, func_graph_, s_, "neg"); + Define(-1, + new Operation[0], + new[] { feed }, + new[] { neg }, + new[] { "negation" }); + + // Use, run, and verify + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, func_op, -3); + VerifyFDef(new string[] { "neg" }, + new List { new IOSpec("negation_0", DataType.DtInt32) }, + new List { new IOSpec("negation", DataType.DtInt32) }, + new List { new EdgeSpec("negation_0", "neg:0"), new EdgeSpec("neg:y:0", "negation") }, + new List()); + } + + [TestMethod] + public void ZeroOps_Identity() + { + // Define + var feed = Placeholder(func_graph_, s_); + Define(-1, + new Operation[0], + new[] { feed }, + new[] { feed }, + new string[0]); + + // Use, run, and verify + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, func_op, 3); + VerifyFDef(new string[0], + new List { new IOSpec("feed_0", DataType.DtInt32) }, + new List { new IOSpec("feed", DataType.DtInt32) }, + new List { new EdgeSpec("feed_0", "feed") }, + new List()); + } + + [TestMethod] + public void ZeroOps_Permutation() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + Define(-1, + null, + new[] { feed1, feed2 }, + new[] { feed2, feed1 }, + null); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, + new[] { new TF_Output(func_op, 0), new TF_Output(func_op, 1) }, + new[] { 3, 2 }); + VerifyFDef(new string[0], + new List { new IOSpec("feed1_0"), new IOSpec("feed2_0") }, + new List { new IOSpec("feed2"), new IOSpec("feed1") }, + new List { new EdgeSpec("feed1_0", "feed1"), new EdgeSpec("feed2_0", "feed2") }, + new List()); + } + + [TestMethod] + public void ZeroOps_Permutation_OutputNames() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + Define(-1, + null, + new[] { feed1, feed2 }, + new[] { feed2, feed1 }, + new[] { "first", "second" }); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, + new[] { new TF_Output(func_op, 0), new TF_Output(func_op, 1) }, + new[] { 3, 2 }); + VerifyFDef(new string[0], + new List { new IOSpec("feed1"), new IOSpec("feed2") }, + new List { new IOSpec("first"), new IOSpec("second") }, + new List { new EdgeSpec("feed1", "second"), new EdgeSpec("feed2", "first") }, + new List()); + } + + [TestMethod] + public void OneOp_TwoInputs_OneOutput() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + var add = Add(feed1, feed2, func_graph_, s_); + Define(-1, + null, + new[] { feed1, feed2 }, + new[] { add }, + null); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, + func_op, + 2 + 3); + VerifyFDef(new string[] { "add_0" }, + new List { new IOSpec("feed1"), new IOSpec("feed2") }, + new List { new IOSpec("add") }, + new List + { + new EdgeSpec("feed1", "add_0:0"), + new EdgeSpec("feed2", "add_0:1"), + new EdgeSpec("add_0:sum:0", "add") + }, + new List()); + } + + [TestMethod] + public void OneOp_TwoInputs_ZeroOutputs() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + var add = Add(feed1, feed2, func_graph_, s_); + Define(-1, + null, + new[] { feed1, feed2 }, + new Operation[0], + null); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, func_feed }); + VerifyFDef(new string[] { "add" }, + new List { new IOSpec("feed1"), new IOSpec("feed2") }, + new List(), + new List + { + new EdgeSpec("feed1", "add:0"), + new EdgeSpec("feed2", "add:1") + }, + new List()); + } + + [TestMethod] + public void TwoOps_ThreeInputs_OneOutput() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + var feed3 = Placeholder(func_graph_, s_, "feed3"); + var add1 = Add(feed1, feed2, func_graph_, s_, "add1"); + var add2 = Add(add1, feed3, func_graph_, s_, "add2"); + Define(-1, + null, + new[] { feed1, feed2, feed3 }, + new[] { add2 }, + null); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_, "two"); + var ten = ScalarConst(10, host_graph_, s_, "ten"); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, ten, func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, + func_op, + 2 + 10 + 3); + VerifyFDef(new string[] { "add1", "add2_0" }, + new List { new IOSpec("feed1"), new IOSpec("feed2"), new IOSpec("feed3") }, + new List { new IOSpec("add2") }, + new List + { + new EdgeSpec("feed1", "add1:0"), + new EdgeSpec("feed2", "add1:1"), + new EdgeSpec("add1:sum:0", "add2_0:0"), + new EdgeSpec("feed3", "add2_0:1"), + new EdgeSpec("add2_0:sum:0", "add2"), + }, + new List()); + } + + [TestMethod] + public void OneOp_TwoInputs_TwoDuplicateOutputs() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + var add = Add(feed1, feed2, func_graph_, s_); + Define(-1, + null, + new[] { feed1, feed2 }, + new[] { add, add }, + null); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, + new[] { new TF_Output(func_op, 0), new TF_Output(func_op, 1) }, + new[] { 5, 5 }); + VerifyFDef(new string[] { "add_1" }, + new List { new IOSpec("feed1"), new IOSpec("feed2") }, + new List { new IOSpec("add"), new IOSpec("add_0") }, + new List + { + new EdgeSpec("feed1", "add_1:0"), + new EdgeSpec("feed2", "add_1:1"), + new EdgeSpec("add_1:sum:0", "add"), + new EdgeSpec("add_1:sum:0", "add_0") + }, + new List()); + } + + [TestMethod] + public void TwoDuplicateOutputs_OutputNames() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + var add = Add(feed1, feed2, func_graph_, s_); + Define(-1, + null, + new[] { feed1, feed2 }, + new[] { add, add }, + new[] { "out1", "out2" }); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, + new[] { new TF_Output(func_op, 0), new TF_Output(func_op, 1) }, + new[] { 5, 5 }); + VerifyFDef(new string[] { "add" }, + new List { new IOSpec("feed1"), new IOSpec("feed2") }, + new List { new IOSpec("out1"), new IOSpec("out2") }, + new List + { + new EdgeSpec("feed1", "add:0"), + new EdgeSpec("feed2", "add:1"), + new EdgeSpec("add:sum:0", "out1"), + new EdgeSpec("add:sum:0", "out2") + }, + new List()); + } + + [TestMethod] + public void TwoOps_ThreeInputs_TwoOutputs() + { + // Define + var feed1 = Placeholder(func_graph_, s_, "feed1"); + var feed2 = Placeholder(func_graph_, s_, "feed2"); + var feed3 = Placeholder(func_graph_, s_, "feed3"); + var add1 = Add(feed1, feed2, func_graph_, s_, "add1"); + var add2 = Add(add1, feed3, func_graph_, s_, "add2"); + Define(-1, + null, + new[] { feed1, feed2, feed3 }, + new[] { add1, add2 }, + null); + + // Use, run, and verify + var two = ScalarConst(2, host_graph_, s_, "two"); + var ten = ScalarConst(10, host_graph_, s_, "ten"); + var func_feed = Placeholder(host_graph_, s_); + var func_op = Use(new[] { two, ten, func_feed }); + Run(new[] { new KeyValuePair(func_feed, Int32Tensor(3)) }, + new[] { new TF_Output(func_op, 0), new TF_Output(func_op, 1) }, + new[] { 12, 15 }); + VerifyFDef(new string[] { "add1_0", "add2_0" }, + new List { new IOSpec("feed1"), new IOSpec("feed2"), new IOSpec("feed3") }, + new List { new IOSpec("add1"), new IOSpec("add2") }, + new List + { + new EdgeSpec("feed1", "add1_0:0"), + new EdgeSpec("feed2", "add1_0:1"), + new EdgeSpec("add1_0:sum:0", "add2_0:0"), + new EdgeSpec("feed3", "add2_0:1"), + new EdgeSpec("add1_0:sum:0", "add1"), + new EdgeSpec("add2_0:sum:0", "add2") + }, + new List()); } void Define(int num_opers, Operation[] opers, @@ -56,15 +401,12 @@ namespace TensorFlowNET.UnitTest.NativeAPI TF_Output[] inputs, TF_Output[] outputs, string[] output_names, bool expect_failure = false) { - IntPtr output_names_ptr = IntPtr.Zero; - func_ = c_api.TF_GraphToFunction(func_graph_, func_name_, false, - num_opers, num_opers == -1 ? new IntPtr[0] : opers.Select(x => (IntPtr)x).ToArray(), + num_opers, num_opers == -1 ? null : opers.Select(x => (IntPtr)x).ToArray(), inputs.Length, inputs.ToArray(), outputs.Length, outputs.ToArray(), - output_names_ptr, IntPtr.Zero, null, s_.Handle); - - // delete output_names_ptr + output_names == null || output_names.Length == 0 ? null : output_names, + IntPtr.Zero, null, s_.Handle); if (expect_failure) { @@ -73,6 +415,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI } ASSERT_EQ(TF_OK, s_.Code, s_.Message); + ASSERT_NE(func_, IntPtr.Zero); ASSERT_EQ(func_name_, c_api.StringPiece(c_api.TF_FunctionName(func_))); c_api.TF_GraphCopyFunction(host_graph_, func_, IntPtr.Zero, s_.Handle); ASSERT_EQ(TF_OK, s_.Code, s_.Message); @@ -113,7 +456,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI for (int i = 0; i < expected_results.Length; ++i) { var output = csession.output_tensor(i); - ASSERT_NE(output, IntPtr.Zero); + ASSERT_TRUE(output != IntPtr.Zero); EXPECT_EQ(TF_DataType.TF_INT32, c_api.TF_TensorType(output)); EXPECT_EQ(0, c_api.TF_NumDims(output)); ASSERT_EQ(sizeof(int), (int)c_api.TF_TensorByteSize(output)); @@ -122,21 +465,125 @@ namespace TensorFlowNET.UnitTest.NativeAPI } } - void VerifyFDef(string[] nodes) + void VerifyFDef(string[] nodes, List inputs, List outputs, + List e_edges, List c_edges, + bool is_exact_edges = true) { var fdef = GetFunctionDef(func_); EXPECT_NE(fdef, IntPtr.Zero); VerifyFDefNodes(fdef, nodes); + VerifyFDefInputs(fdef, inputs); + VerifyFDefOutputs(fdef, outputs); + VerifyFDefEdges(fdef, e_edges, c_edges, is_exact_edges); } void VerifyFDefNodes(FunctionDef fdef, string[] nodes) { ASSERT_EQ(nodes.Length, fdef.NodeDef.Count); + foreach(var node in fdef.NodeDef) + { + ASSERT_TRUE(nodes.Contains(node.Name), $"Got unexpected node: {node.Name} in fdef: {fdef}"); + } + } + + void VerifyFDefInputs(FunctionDef fdef, List inputs) + { + var signature = fdef.Signature; + ASSERT_EQ(inputs.Count, signature.InputArg.Count); + for (int i = 0; i < inputs.Count; ++i) + { + var arg = signature.InputArg[i]; + var input = inputs[i]; + if (input.Value != DataType.DtInvalid) + ASSERT_EQ(arg.Type, input.Value, $""); + ASSERT_EQ(arg.Name, input.Key, $"Got unexpected name for input {i}. fdef: {fdef}"); + } + } + + void VerifyFDefOutputs(FunctionDef fdef, List outputs) + { + var signature = fdef.Signature; + ASSERT_EQ(outputs.Count, signature.OutputArg.Count); + for (int i = 0; i < outputs.Count; ++i) + { + var arg = signature.OutputArg[i]; + var output = outputs[i]; + if (output.Value != DataType.DtInvalid) + ASSERT_EQ(arg.Type, output.Value, $""); + ASSERT_EQ(arg.Name, output.Key, $"Got unexpected name for input {i}. fdef: {fdef}"); + } + } + + void VerifyFDefEdges(FunctionDef fdef, List e_edges, List c_edges, bool is_exact_edges = true) + { + // Build a set of edges from fdef + var a_edges = new List(); // actual edges + // Get edges from inputs to body nodes and between body nodes + foreach(var node in fdef.NodeDef) + { + for (int i = 0; i < node.Input.Count; ++i) + { + var input = node.Input[i]; + a_edges.Add(new EdgeSpec(input, $"{node.Name}:{i}")); + } + } + // Get edges from body nodes to outputs and from inputs to outputs + foreach(var arg in fdef.Signature.OutputArg) + { + var iter = fdef.Ret.FirstOrDefault(x => x.Key == arg.Name); + if(iter.Key != null) + { + a_edges.Add(new EdgeSpec(iter.Value, arg.Name)); + } + else + { + a_edges.Add(new EdgeSpec(arg.Name, arg.Name)); + } + } + // Verify edges + foreach(var edge in e_edges) + { + ASSERT_TRUE(a_edges.Contains(edge)); + } + foreach (var edge in c_edges) + { + ASSERT_TRUE(a_edges.Contains(edge)); + } + // If caller specified all edges, check that we have seen all + if (is_exact_edges) + { + ASSERT_EQ(e_edges.Count + c_edges.Count, a_edges.Count, + $"Expected edges: {e_edges}, Expected Control edges: {c_edges}, Actual edges: {a_edges}"); + } } public void Dispose() { } + + public struct IOSpec + { + KeyValuePair pair; + public string Key => pair.Key; + public DataType Value => pair.Value; + + public IOSpec(string key, DataType value = DataType.DtInvalid) + { + pair = new KeyValuePair(key, value); + } + } + + public struct EdgeSpec + { + KeyValuePair pair; + public string Key => pair.Key; + public string Value => pair.Value; + + public EdgeSpec(string key, string value) + { + pair = new KeyValuePair(key, value); + } + } } } diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs b/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs index 9711e76b..8d1f85ad 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs @@ -90,7 +90,8 @@ namespace TensorFlowNET.UnitTest s.Check(); - output_values_[0] = output_values_ptr[0]; + for (var i = 0; i < outputs_.Count; i++) + output_values_[i] = output_values_ptr[i]; } public IntPtr output_tensor(int i) diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs b/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs index dc8af9a6..24766453 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using Tensorflow; using Tensorflow.Util; using Buffer = Tensorflow.Buffer; @@ -230,5 +231,10 @@ namespace TensorFlowNET.UnitTest { return Const(new Tensor(v), graph, s, name); } + + public static Tensor Int32Tensor(int v) + { + return new Tensor(v); + } } } \ No newline at end of file diff --git a/test/TensorFlowNET.UnitTest/Tensorflow.UnitTest.csproj b/test/TensorFlowNET.UnitTest/Tensorflow.UnitTest.csproj index 1b9cae28..ca4f7e21 100644 --- a/test/TensorFlowNET.UnitTest/Tensorflow.UnitTest.csproj +++ b/test/TensorFlowNET.UnitTest/Tensorflow.UnitTest.csproj @@ -41,6 +41,10 @@ + + + +