Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
891346e
Refactored DisposableObject
Nucs Aug 21, 2019
35295f8
Added different build directory for TensorflowNET.Examples.GPU
Nucs Aug 21, 2019
c876be4
_FetchHandler: Switched to NPTypeCode
Nucs Aug 21, 2019
1992bb0
gfile.cs, Walk(...): Handle case when directory top doesn't exist.
Nucs Aug 21, 2019
d60c36f
Tensor.Creation: Perf-opted when creating tensor from NDArray of string
Nucs Aug 21, 2019
4be99ec
Graph.cs: refactor and added docs
Nucs Aug 21, 2019
533f8fd
Tensor.Creation.cs: perf-ops
Nucs Aug 21, 2019
4ba71e2
Tensor.Explicit.cs: perf-ops
Nucs Aug 21, 2019
cfc3926
Copied globals.regen from NumSharp
Nucs Aug 21, 2019
2129dbd
Tensor perf-ops and cleanup, Revamped dtypes.cs, some renames.
Nucs Aug 21, 2019
766fa6f
Tensor: Added guards for explicit casts.
Nucs Aug 21, 2019
4cf817e
Tensor: Added explicit cast to string
Nucs Aug 21, 2019
52955b3
Tensor.ToArray<T>(): Added support for cases when tensor is scalar.
Nucs Aug 21, 2019
f375e1c
Tensor.BufferToArray(): Fixed to use long instead of int.
Nucs Aug 21, 2019
290d0dd
TensorShape: Revamped and documented.
Nucs Aug 21, 2019
35360e9
BaseSession: Added Session.run(ITensorOrOperation fetche, params Feed…
Nucs Aug 21, 2019
38f27f1
Tensor: renamed _dtype to _override_dtype
Nucs Aug 21, 2019
605a05e
Fixed unit tests
Nucs Aug 21, 2019
667a566
Tensor.Operations: Reverted commit
Nucs Aug 21, 2019
a5bdd99
DisposableObject: sorted internal_dispose to properly handle Dispose(…
Nucs Aug 21, 2019
2c01153
Tensor.DisposeUnmanagedResources: Nullify _handle after delete.
Nucs Aug 21, 2019
44adad6
TensorShape.this[...]: fixed guard check.
Nucs Aug 21, 2019
672c923
DisposableObject #362
Oceania2018 Aug 22, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Core/APIs/c_api.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ public struct DeallocatorArgs
}

[DllImport(TensorFlowLibName)]
public static unsafe extern IntPtr TF_Version();
public static extern IntPtr TF_Version();
}
}
14 changes: 5 additions & 9 deletions src/TensorFlowNET.Core/Binding.Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,15 +308,14 @@ public static __object__ getattr(object obj, string key, params Type[] ___parame
public static IEnumerable TupleToEnumerable(object tuple)
{
Type t = tuple.GetType();
if(t.IsGenericType && (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")))
if (t.IsGenericType && (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")))
{
var flds = t.GetFields();
for(int i = 0; i < flds.Length;i++)
for (int i = 0; i < flds.Length; i++)
{
yield return flds[i].GetValue(tuple);
}
}
else
} else
{
throw new System.Exception("Expected Tuple.");
}
Expand All @@ -329,12 +328,9 @@ public static bool isinstance(object Item1, Type Item2)

public static bool isinstance(object Item1, object tuple)
{
var tup = TupleToEnumerable(tuple);
foreach(var t in tup)
{
if(isinstance(Item1, (Type)t))
foreach (var t in TupleToEnumerable(tuple))
if (isinstance(Item1, (Type) t))
return true;
}
return false;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Core/Buffers/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static implicit operator byte[](Buffer buffer)
return buffer.Data;
}

protected override void DisposeUnManagedState(IntPtr handle)
protected override void DisposeUnmanagedResources(IntPtr handle)
=> c_api.TF_DeleteBuffer(handle);
}
}
37 changes: 21 additions & 16 deletions src/TensorFlowNET.Core/DisposableObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,49 +29,54 @@ public abstract class DisposableObject : IDisposable

protected DisposableObject() { }

public DisposableObject(IntPtr handle)
{
_handle = handle;
}

protected virtual void DisposeManagedState()
{
}
protected DisposableObject(IntPtr handle)
=> _handle = handle;

protected abstract void DisposeUnManagedState(IntPtr handle);

protected virtual void Dispose(bool disposing)
private void internal_dispose(bool disposing)
{
if (disposing)
{
// free unmanaged resources (unmanaged objects) and override a finalizer below.
if (_handle != IntPtr.Zero)
{
// dispose managed state (managed objects).
DisposeManagedState();
DisposeManagedResources();

// set large fields to null.
DisposeUnManagedState(_handle);
DisposeUnmanagedResources(_handle);

_handle = IntPtr.Zero;
}
}
}

/// <summary>
/// Dispose any managed resources.
/// </summary>
/// <remarks>Equivalent to what you would perform inside <see cref="Dispose()"/></remarks>
protected virtual void DisposeManagedResources()
{
}

/// <summary>
/// Dispose any unmanaged resources related to given <paramref name="handle"/>.
/// </summary>
protected abstract void DisposeUnmanagedResources(IntPtr handle);

// override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
~DisposableObject()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(false);
internal_dispose(false);
}

// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
internal_dispose(true);
// uncomment the following line if the finalizer is overridden above.
GC.SuppressFinalize(this);
}
}
}
}
3 changes: 2 additions & 1 deletion src/TensorFlowNET.Core/Eager/ContextOptions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System;
using System.IO;

namespace Tensorflow.Eager
{
public class ContextOptions : IDisposable
public class ContextOptions : IDisposable //TODO! Eli: Shouldn't this inherieting DisposableObject?
{
private IntPtr _handle;

Expand Down
103 changes: 52 additions & 51 deletions src/TensorFlowNET.Core/Graphs/Graph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,57 +23,58 @@ limitations under the License.

namespace Tensorflow
{
/*
A TensorFlow computation, represented as a dataflow graph.

A `Graph` contains a set of
`tf.Operation` objects,
which represent units of computation; and
`tf.Tensor` objects, which represent
the units of data that flow between operations.

A default `Graph` is always registered, and accessible by calling
`tf.get_default_graph`.
To add an operation to the default graph, simply call one of the functions
that defines a new `Operation`:

```python
c = tf.constant(4.0)
assert c.graph is tf.get_default_graph()
```

Another typical usage involves the
`tf.Graph.as_default`
context manager, which overrides the current default graph for the
lifetime of the context:

```python
g = tf.Graph()
with g.as_default():
# Define operations and tensors in `g`.
c = tf.constant(30.0)
assert c.graph is g
```

Important note: This class *is not* thread-safe for graph construction. All
operations should be created from a single thread, or external
synchronization must be provided. Unless otherwise specified, all methods
are not thread-safe.

A `Graph` instance supports an arbitrary number of "collections"
that are identified by name. For convenience when building a large
graph, collections can store groups of related objects: for
example, the `tf.Variable` uses a collection (named
`tf.GraphKeys.GLOBAL_VARIABLES`) for
all variables that are created during the construction of a graph. The caller
may define additional collections by specifying a new name.
*/

/// <summary>
/// TensorFlow uses a dataflow graph to represent your computation in terms of the dependencies between individual operations.
/// This leads to a low-level programming model in which you first define the dataflow graph,
/// then create a TensorFlow session to run parts of the graph across a set of local and remote devices.
/// https://www.tensorflow.org/guide/graphs
/// TensorFlow uses a dataflow graph to represent your computation in terms of the dependencies between individual operations.
/// This leads to a low-level programming model in which you first define the dataflow graph,
/// then create a TensorFlow session to run parts of the graph across a set of local and remote devices.
/// </summary>
/*
A TensorFlow computation, represented as a dataflow graph.

A `Graph` contains a set of
`tf.Operation` objects,
which represent units of computation; and
`tf.Tensor` objects, which represent
the units of data that flow between operations.

A default `Graph` is always registered, and accessible by calling
`tf.get_default_graph`.
To add an operation to the default graph, simply call one of the functions
that defines a new `Operation`:

```python
c = tf.constant(4.0)
assert c.graph is tf.get_default_graph()
```

Another typical usage involves the
`tf.Graph.as_default`
context manager, which overrides the current default graph for the
lifetime of the context:

```python
g = tf.Graph()
with g.as_default():
# Define operations and tensors in `g`.
c = tf.constant(30.0)
assert c.graph is g
```

Important note: This class *is not* thread-safe for graph construction. All
operations should be created from a single thread, or external
synchronization must be provided. Unless otherwise specified, all methods
are not thread-safe.

A `Graph` instance supports an arbitrary number of "collections"
that are identified by name. For convenience when building a large
graph, collections can store groups of related objects: for
example, the `tf.Variable` uses a collection (named
`tf.GraphKeys.GLOBAL_VARIABLES`) for
all variables that are created during the construction of a graph. The caller
may define additional collections by specifying a new name.
*/
/// <remarks>https://www.tensorflow.org/guide/graphs <br></br>https://www.tensorflow.org/api_docs/python/tf/Graph</remarks>
public partial class Graph : DisposableObject, IEnumerable<Operation>
{
private Dictionary<int, ITensorOrOperation> _nodes_by_id;
Expand Down Expand Up @@ -439,12 +440,12 @@ public void prevent_fetching(Operation op)
_unfetchable_ops.Add(op);
}

protected override void DisposeManagedState()
protected override void DisposeManagedResources()
{
ops.default_graph_stack.remove(this);
}

protected override void DisposeUnManagedState(IntPtr handle)
protected override void DisposeUnmanagedResources(IntPtr handle)
{
c_api.TF_DeleteGraph(handle);
}
Expand Down
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Core/Graphs/ImportGraphDefOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void AddReturnOutput(string name, int index)
c_api.TF_ImportGraphDefOptionsAddReturnOutput(_handle, name, index);
}

protected override void DisposeUnManagedState(IntPtr handle)
protected override void DisposeUnmanagedResources(IntPtr handle)
=> c_api.TF_DeleteImportGraphDefOptions(handle);

public static implicit operator IntPtr(ImportGraphDefOptions opts) => opts._handle;
Expand Down
4 changes: 4 additions & 0 deletions src/TensorFlowNET.Core/IO/gfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Tensorflow.IO
{
Expand All @@ -28,6 +29,9 @@ public class GFile
/// <param name="in_order">Traverse in order if True, post order if False.</param>
public IEnumerable<(string, string[], string[])> Walk(string top, bool in_order = true)
{
if (!Directory.Exists(top))
return Enumerable.Empty<(string, string[], string[])>();

return walk_v2(top, in_order);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ protected virtual Tensor _Enter(Tensor data, string frame_name,
data, frame_name, is_constant, parallel_iterations, name: name);

if (use_input_shape)
result.SetShape(data.TensorShape);
result.set_shape(data.TensorShape);

return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Core/Operations/NnOps/rnn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public static Tensor _transpose_batch_time(Tensor x)
dims.AddRange(x_static_shape.dims.Skip(2));
var shape = new TensorShape(dims.ToArray());

x_t.SetShape(shape);
x_t.set_shape(shape);

return x_t;
}
Expand Down
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Core/Operations/array_ops.py.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ private static Tensor shape_internal(Tensor input, string name = null, bool opti
var input_shape = tensor_util.to_shape(input_tensor.shape);
if (optimize && input_tensor.NDims > -1 && input_shape.is_fully_defined())
{
var nd = np.array(input_tensor.shape).astype(out_type.as_numpy_datatype());
var nd = np.array(input_tensor.shape).astype(out_type.as_numpy_dtype());
return constant_op.constant(nd, name: name);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Core/Operations/nn_ops.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static Tensor dropout_v2(Tensor x, Tensor rate, Tensor noise_shape = null
// float to be selected, hence we use a >= comparison.
var keep_mask = random_tensor >= rate;
var ret = x * scale * math_ops.cast(keep_mask, x.dtype);
ret.SetShape(x.TensorShape);
ret.set_shape(x.TensorShape);
return ret;
});
}
Expand Down
15 changes: 10 additions & 5 deletions src/TensorFlowNET.Core/Sessions/BaseSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public BaseSession(string target = "", Graph g = null, SessionOptions opts = nul

// dispose newOpts
if (opts == null)
c_api.TF_DeleteSessionOptions(newOpts);
newOpts.Dispose();

status.Check(true);
}
Expand All @@ -64,6 +64,11 @@ public virtual NDArray run(Tensor fetche, params FeedItem[] feed_dict)
return _run(fetche, feed_dict)[0];
}

public virtual NDArray run(ITensorOrOperation fetche, params FeedItem[] feed_dict)
{
return _run(fetche, feed_dict)[0];
}

public virtual (NDArray, NDArray, NDArray, NDArray) run((ITensorOrOperation, ITensorOrOperation, ITensorOrOperation, ITensorOrOperation) fetches, params FeedItem[] feed_dict)
{
var results = _run(new object[] { fetches.Item1, fetches.Item2, fetches.Item3, fetches.Item4 }, feed_dict);
Expand Down Expand Up @@ -273,7 +278,7 @@ private unsafe NDArray fetchValue(IntPtr output)
{
var tensor = new Tensor(output);
NDArray nd = null;
Type type = tensor.dtype.as_numpy_datatype();
Type type = tensor.dtype.as_numpy_dtype();
var ndims = tensor.shape;
var offset = c_api.TF_TensorData(output);

Expand All @@ -285,7 +290,7 @@ private unsafe NDArray fetchValue(IntPtr output)
nd = NDArray.Scalar(*(bool*)offset);
break;
case TF_DataType.TF_STRING:
var bytes = tensor.Data();
var bytes = tensor.BufferToArray();
// wired, don't know why we have to start from offset 9.
// length in the begin
var str = UTF8Encoding.Default.GetString(bytes, 9, bytes[8]);
Expand Down Expand Up @@ -324,7 +329,7 @@ private unsafe NDArray fetchValue(IntPtr output)
nd = np.array(bools).reshape(ndims);
break;
case TF_DataType.TF_STRING:
var bytes = tensor.Data();
var bytes = tensor.BufferToArray();
// wired, don't know why we have to start from offset 9.
// length in the begin
var str = UTF8Encoding.Default.GetString(bytes, 9, bytes[8]);
Expand Down Expand Up @@ -396,7 +401,7 @@ public void close()
Dispose();
}

protected override void DisposeUnManagedState(IntPtr handle)
protected override void DisposeUnmanagedResources(IntPtr handle)
{
using (var status = new Status())
{
Expand Down
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Core/Sessions/SessionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public SessionOptions(IntPtr handle)
_handle = handle;
}

protected override void DisposeUnManagedState(IntPtr handle)
protected override void DisposeUnmanagedResources(IntPtr handle)
=> c_api.TF_DeleteSessionOptions(handle);

public void SetConfig(ConfigProto config)
Expand Down
Loading