diff --git a/src/TensorFlowNET.Core/Graphs/Graph.Control.cs b/src/TensorFlowNET.Core/Graphs/Graph.Control.cs
index a1977968..d6fda591 100644
--- a/src/TensorFlowNET.Core/Graphs/Graph.Control.cs
+++ b/src/TensorFlowNET.Core/Graphs/Graph.Control.cs
@@ -54,6 +54,13 @@ namespace Tensorflow
return ret;
}
+ ///
+ /// Returns a context manager that specifies control dependencies.
+ ///
+ /// Use with the `with` keyword to specify that all operations constructed
+ /// within the context should have control dependencies on
+ /// `control_inputs`.
+ ///
public _ControlDependenciesController control_dependencies(ITensorOrOperation[] control_inputs)
{
if (control_inputs == null)
diff --git a/src/TensorFlowNET.Core/Operations/Operation.cs b/src/TensorFlowNET.Core/Operations/Operation.cs
index b6952540..e4bccea1 100644
--- a/src/TensorFlowNET.Core/Operations/Operation.cs
+++ b/src/TensorFlowNET.Core/Operations/Operation.cs
@@ -7,7 +7,26 @@ using System.Runtime.InteropServices;
using System.Text;
namespace Tensorflow
-{
+{
+
+ ///
+ /// Represents a graph node that performs computation on tensors.
+ ///
+ /// An `Operation` is a node in a TensorFlow `Graph` that takes zero or
+ /// more `Tensor` objects as input, and produces zero or more `Tensor`
+ /// objects as output. Objects of type `Operation` are created by
+ /// calling an op constructor(such as `tf.matmul`)
+ /// or `tf.Graph.create_op`.
+ ///
+ /// For example `c = tf.matmul(a, b)` creates an `Operation` of type
+ /// "MatMul" that takes tensors `a` and `b` as input, and produces `c`
+ /// as output.
+ ///
+ /// After the graph has been launched in a session, an `Operation` can
+ /// be executed by passing it to
+ /// `tf.Session.run`.
+ /// `op.run()` is a shortcut for calling `tf.get_default_session().run(op)`.
+ ///
public partial class Operation : ITensorOrOperation
{
private readonly IntPtr _handle; // _c_op in python
@@ -98,6 +117,13 @@ namespace Tensorflow
case Operation c1:
control_input_ops.Add(c1);
break;
+ case Tensor tensor:
+ control_input_ops.Add(tensor.op);
+ break;
+ // TODO: IndexedSlices don't yet exist, but once they do, this needs to be uncommented
+ //case IndexedSlices islices:
+ // control_input_ops.Add(islices.op);
+ // break;
default:
throw new NotImplementedException($"Control input must be an Operation, a Tensor, or IndexedSlices: {c}");
}
diff --git a/src/TensorFlowNET.Core/Train/GradientDescentOptimizer.cs b/src/TensorFlowNET.Core/Train/GradientDescentOptimizer.cs
index ecdb22f6..f545d859 100644
--- a/src/TensorFlowNET.Core/Train/GradientDescentOptimizer.cs
+++ b/src/TensorFlowNET.Core/Train/GradientDescentOptimizer.cs
@@ -4,8 +4,25 @@ using System.Text;
namespace Tensorflow.Train
{
+ ///
+ /// Optimizer that implements the gradient descent algorithm.
+ ///
public class GradientDescentOptimizer : Optimizer
- {
+ {
+ ///
+ /// Construct a new gradient descent optimizer.
+ ///
+ /// A Tensor or a floating point value. The learning
+ /// rate to use.
+ /// If true use locks for update operations.
+ /// Optional name prefix for the operations created when applying
+ /// gradients.Defaults to "GradientDescent".
+ ///
+ /// When eager execution is enabled, `learning_rate` can be a callable that
+ /// takes no arguments and returns the actual value to use.This can be useful
+ /// for changing these values across different invocations of optimizer
+ /// functions.
+ ///
public GradientDescentOptimizer(float learning_rate, bool use_locking = false, string name = "GradientDescent")
: base(learning_rate, use_locking, name)
{
diff --git a/src/TensorFlowNET.Core/ops.py.cs b/src/TensorFlowNET.Core/ops.py.cs
index 43a3c9ba..514530f3 100644
--- a/src/TensorFlowNET.Core/ops.py.cs
+++ b/src/TensorFlowNET.Core/ops.py.cs
@@ -98,12 +98,27 @@ namespace Tensorflow
public static Tensor internal_convert_to_tensor_or_composite(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool as_ref = false)
{
return internal_convert_to_tensor(value, dtype: dtype, name: name, as_ref: as_ref);
- }
-
+ }
+
///
/// Wrapper for `Graph.control_dependencies()` using the default graph.
+ ///
+ /// See `tf.Graph.control_dependencies` for more details.
+
+ /// When eager execution is enabled, any callable object in the `control_inputs`
+ /// list will be called.
///
- ///
+ ///
+ /// A list of `Operation` or `Tensor` objects which
+ /// must be executed or computed before running the operations
+ /// defined in the context.Can also be `None` to clear the control
+ /// dependencies.If eager execution is enabled, any callable object in the
+ /// `control_inputs` list will be called.
+ ///
+ ///
+ /// A context manager that specifies control dependencies for all
+ /// operations constructed within the context.
+ ///
public static _ControlDependenciesController control_dependencies(Operation[] control_inputs)
{
return get_default_graph().control_dependencies(control_inputs);
diff --git a/src/TensorFlowNET.Visualization/TensorFlowNET.Visualization.csproj b/src/TensorFlowNET.Visualization/TensorFlowNET.Visualization.csproj
index 827932d7..81860dad 100644
--- a/src/TensorFlowNET.Visualization/TensorFlowNET.Visualization.csproj
+++ b/src/TensorFlowNET.Visualization/TensorFlowNET.Visualization.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.2
+ netcoreapp2.1
InProcess
diff --git a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj
index 0259fc4e..ba342e5f 100644
--- a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj
+++ b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp2.2
+ netcoreapp2.1
false
diff --git a/test/TensorFlowNET.UnitTest/ControlDependenciesTest.cs b/test/TensorFlowNET.UnitTest/ControlDependenciesTest.cs
new file mode 100644
index 00000000..c2c40337
--- /dev/null
+++ b/test/TensorFlowNET.UnitTest/ControlDependenciesTest.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Tensorflow;
+
+namespace TensorFlowNET.UnitTest
+{
+ ///
+ /// tensorflow/python/framework/ops_test.py
+ ///
+ [TestClass]
+ public class ControlDependenciesTest : Python
+ {
+ [TestMethod]
+ public void TestBasic()
+ {
+ var graph = tf.Graph().as_default();
+ Tensor a=null, b = null, c = null, d = null, e = null;
+ with(graph, g =>
+ {
+ a = constant_op.constant(1.0);
+ b = constant_op.constant(1.0);
+ with(g.control_dependencies(new ITensorOrOperation[] {a}), x =>
+ {
+ c = constant_op.constant(1.0);
+ d = array_ops.identity(b);
+ e = array_ops.identity(c);
+ });
+ });
+ Assert.IsTrue(Enumerable.SequenceEqual(c.op.control_inputs, new[] {a.op}));
+ Assert.IsTrue(Enumerable.SequenceEqual(d.op.control_inputs, new[] {a.op}));
+ // e should be dominated by c.
+ Assert.AreEqual(0, e.op.control_inputs.Length);
+ }
+ }
+}
diff --git a/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj b/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj
index 04aebf0d..a3dd23ec 100644
--- a/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj
+++ b/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.2
+ netcoreapp2.1
false