Skip to content

Commit 6c8c2e5

Browse files
NucsOceania2018
authored andcommitted
Performance optimization, refactoring and revamping. (SciSharp#362)
* Refactored DisposableObject * Added different build directory for TensorflowNET.Examples.GPU * _FetchHandler: Switched to NPTypeCode * gfile.cs, Walk(...): Handle case when directory top doesn't exist. * Tensor.Creation: Perf-opted when creating tensor from NDArray of string * Graph.cs: refactor and added docs * Tensor.Creation.cs: perf-ops * Tensor.Explicit.cs: perf-ops * Copied globals.regen from NumSharp - Added supported_numericals_TF_DataType * Tensor perf-ops and cleanup, Revamped dtypes.cs, some renames. - Cleanup and docs to all Tensor.cs files - Changed all uses of System.Convert to NumSharp.Utilities.Converts - Added all missing types in dtypes.cs - Renamed tensor.Data<T> to tensor.ToArray<T>, added obsolete message - Renamed tensor.Data() to tensor.BufferToArray(), added obsolete message - Made GraphKeys to use const string instead allocating strings at every use of GraphKeys. * Tensor: Added guards for explicit casts. * Tensor: Added explicit cast to string * Tensor.ToArray<T>(): Added support for cases when tensor is scalar. * Tensor.BufferToArray(): Fixed to use long instead of int. * TensorShape: Revamped and documented. * BaseSession: Added Session.run(ITensorOrOperation fetche, params FeedItem[] feed_dict) * Tensor: renamed _dtype to _override_dtype - Fixed all locations _dtype is used incorrectly. * Fixed unit tests * Tensor.Operations: Reverted commit * DisposableObject: sorted internal_dispose to properly handle Dispose() calls * Tensor.DisposeUnmanagedResources: Nullify _handle after delete. * TensorShape.this[...]: fixed guard check. * DisposableObject SciSharp#362
1 parent 8546b8d commit 6c8c2e5

34 files changed

Lines changed: 994 additions & 500 deletions

src/TensorFlowNET.Core/APIs/c_api.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@ public struct DeallocatorArgs
5959
}
6060

6161
[DllImport(TensorFlowLibName)]
62-
public static unsafe extern IntPtr TF_Version();
62+
public static extern IntPtr TF_Version();
6363
}
6464
}

src/TensorFlowNET.Core/Binding.Util.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,14 @@ public static __object__ getattr(object obj, string key, params Type[] ___parame
308308
public static IEnumerable TupleToEnumerable(object tuple)
309309
{
310310
Type t = tuple.GetType();
311-
if(t.IsGenericType && (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")))
311+
if (t.IsGenericType && (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")))
312312
{
313313
var flds = t.GetFields();
314-
for(int i = 0; i < flds.Length;i++)
314+
for (int i = 0; i < flds.Length; i++)
315315
{
316316
yield return flds[i].GetValue(tuple);
317317
}
318-
}
319-
else
318+
} else
320319
{
321320
throw new System.Exception("Expected Tuple.");
322321
}
@@ -329,12 +328,9 @@ public static bool isinstance(object Item1, Type Item2)
329328

330329
public static bool isinstance(object Item1, object tuple)
331330
{
332-
var tup = TupleToEnumerable(tuple);
333-
foreach(var t in tup)
334-
{
335-
if(isinstance(Item1, (Type)t))
331+
foreach (var t in TupleToEnumerable(tuple))
332+
if (isinstance(Item1, (Type) t))
336333
return true;
337-
}
338334
return false;
339335
}
340336
}

src/TensorFlowNET.Core/Buffers/Buffer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public static implicit operator byte[](Buffer buffer)
6666
return buffer.Data;
6767
}
6868

69-
protected override void DisposeUnManagedState(IntPtr handle)
69+
protected override void DisposeUnmanagedResources(IntPtr handle)
7070
=> c_api.TF_DeleteBuffer(handle);
7171
}
7272
}

src/TensorFlowNET.Core/DisposableObject.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,49 +29,54 @@ public abstract class DisposableObject : IDisposable
2929

3030
protected DisposableObject() { }
3131

32-
public DisposableObject(IntPtr handle)
33-
{
34-
_handle = handle;
35-
}
36-
37-
protected virtual void DisposeManagedState()
38-
{
39-
}
32+
protected DisposableObject(IntPtr handle)
33+
=> _handle = handle;
4034

41-
protected abstract void DisposeUnManagedState(IntPtr handle);
42-
43-
protected virtual void Dispose(bool disposing)
35+
private void internal_dispose(bool disposing)
4436
{
4537
if (disposing)
4638
{
4739
// free unmanaged resources (unmanaged objects) and override a finalizer below.
4840
if (_handle != IntPtr.Zero)
4941
{
5042
// dispose managed state (managed objects).
51-
DisposeManagedState();
43+
DisposeManagedResources();
5244

5345
// set large fields to null.
54-
DisposeUnManagedState(_handle);
46+
DisposeUnmanagedResources(_handle);
5547

5648
_handle = IntPtr.Zero;
5749
}
5850
}
5951
}
6052

53+
/// <summary>
54+
/// Dispose any managed resources.
55+
/// </summary>
56+
/// <remarks>Equivalent to what you would perform inside <see cref="Dispose()"/></remarks>
57+
protected virtual void DisposeManagedResources()
58+
{
59+
}
60+
61+
/// <summary>
62+
/// Dispose any unmanaged resources related to given <paramref name="handle"/>.
63+
/// </summary>
64+
protected abstract void DisposeUnmanagedResources(IntPtr handle);
65+
6166
// override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
6267
~DisposableObject()
6368
{
6469
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
65-
Dispose(false);
70+
internal_dispose(false);
6671
}
6772

6873
// This code added to correctly implement the disposable pattern.
6974
public void Dispose()
7075
{
7176
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
72-
Dispose(true);
77+
internal_dispose(true);
7378
// uncomment the following line if the finalizer is overridden above.
7479
GC.SuppressFinalize(this);
7580
}
7681
}
77-
}
82+
}

src/TensorFlowNET.Core/Eager/ContextOptions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using System;
2+
using System.IO;
23

34
namespace Tensorflow.Eager
45
{
5-
public class ContextOptions : IDisposable
6+
public class ContextOptions : IDisposable //TODO! Eli: Shouldn't this inherieting DisposableObject?
67
{
78
private IntPtr _handle;
89

src/TensorFlowNET.Core/Graphs/Graph.cs

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,57 +23,58 @@ limitations under the License.
2323

2424
namespace Tensorflow
2525
{
26+
/*
27+
A TensorFlow computation, represented as a dataflow graph.
28+
29+
A `Graph` contains a set of
30+
`tf.Operation` objects,
31+
which represent units of computation; and
32+
`tf.Tensor` objects, which represent
33+
the units of data that flow between operations.
34+
35+
A default `Graph` is always registered, and accessible by calling
36+
`tf.get_default_graph`.
37+
To add an operation to the default graph, simply call one of the functions
38+
that defines a new `Operation`:
39+
40+
```python
41+
c = tf.constant(4.0)
42+
assert c.graph is tf.get_default_graph()
43+
```
44+
45+
Another typical usage involves the
46+
`tf.Graph.as_default`
47+
context manager, which overrides the current default graph for the
48+
lifetime of the context:
49+
50+
```python
51+
g = tf.Graph()
52+
with g.as_default():
53+
# Define operations and tensors in `g`.
54+
c = tf.constant(30.0)
55+
assert c.graph is g
56+
```
57+
58+
Important note: This class *is not* thread-safe for graph construction. All
59+
operations should be created from a single thread, or external
60+
synchronization must be provided. Unless otherwise specified, all methods
61+
are not thread-safe.
62+
63+
A `Graph` instance supports an arbitrary number of "collections"
64+
that are identified by name. For convenience when building a large
65+
graph, collections can store groups of related objects: for
66+
example, the `tf.Variable` uses a collection (named
67+
`tf.GraphKeys.GLOBAL_VARIABLES`) for
68+
all variables that are created during the construction of a graph. The caller
69+
may define additional collections by specifying a new name.
70+
*/
71+
2672
/// <summary>
27-
/// TensorFlow uses a dataflow graph to represent your computation in terms of the dependencies between individual operations.
28-
/// This leads to a low-level programming model in which you first define the dataflow graph,
29-
/// then create a TensorFlow session to run parts of the graph across a set of local and remote devices.
30-
/// https://www.tensorflow.org/guide/graphs
73+
/// TensorFlow uses a dataflow graph to represent your computation in terms of the dependencies between individual operations.
74+
/// This leads to a low-level programming model in which you first define the dataflow graph,
75+
/// then create a TensorFlow session to run parts of the graph across a set of local and remote devices.
3176
/// </summary>
32-
/*
33-
A TensorFlow computation, represented as a dataflow graph.
34-
35-
A `Graph` contains a set of
36-
`tf.Operation` objects,
37-
which represent units of computation; and
38-
`tf.Tensor` objects, which represent
39-
the units of data that flow between operations.
40-
41-
A default `Graph` is always registered, and accessible by calling
42-
`tf.get_default_graph`.
43-
To add an operation to the default graph, simply call one of the functions
44-
that defines a new `Operation`:
45-
46-
```python
47-
c = tf.constant(4.0)
48-
assert c.graph is tf.get_default_graph()
49-
```
50-
51-
Another typical usage involves the
52-
`tf.Graph.as_default`
53-
context manager, which overrides the current default graph for the
54-
lifetime of the context:
55-
56-
```python
57-
g = tf.Graph()
58-
with g.as_default():
59-
# Define operations and tensors in `g`.
60-
c = tf.constant(30.0)
61-
assert c.graph is g
62-
```
63-
64-
Important note: This class *is not* thread-safe for graph construction. All
65-
operations should be created from a single thread, or external
66-
synchronization must be provided. Unless otherwise specified, all methods
67-
are not thread-safe.
68-
69-
A `Graph` instance supports an arbitrary number of "collections"
70-
that are identified by name. For convenience when building a large
71-
graph, collections can store groups of related objects: for
72-
example, the `tf.Variable` uses a collection (named
73-
`tf.GraphKeys.GLOBAL_VARIABLES`) for
74-
all variables that are created during the construction of a graph. The caller
75-
may define additional collections by specifying a new name.
76-
*/
77+
/// <remarks>https://www.tensorflow.org/guide/graphs <br></br>https://www.tensorflow.org/api_docs/python/tf/Graph</remarks>
7778
public partial class Graph : DisposableObject, IEnumerable<Operation>
7879
{
7980
private Dictionary<int, ITensorOrOperation> _nodes_by_id;
@@ -439,12 +440,12 @@ public void prevent_fetching(Operation op)
439440
_unfetchable_ops.Add(op);
440441
}
441442

442-
protected override void DisposeManagedState()
443+
protected override void DisposeManagedResources()
443444
{
444445
ops.default_graph_stack.remove(this);
445446
}
446447

447-
protected override void DisposeUnManagedState(IntPtr handle)
448+
protected override void DisposeUnmanagedResources(IntPtr handle)
448449
{
449450
c_api.TF_DeleteGraph(handle);
450451
}

src/TensorFlowNET.Core/Graphs/ImportGraphDefOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void AddReturnOutput(string name, int index)
3737
c_api.TF_ImportGraphDefOptionsAddReturnOutput(_handle, name, index);
3838
}
3939

40-
protected override void DisposeUnManagedState(IntPtr handle)
40+
protected override void DisposeUnmanagedResources(IntPtr handle)
4141
=> c_api.TF_DeleteImportGraphDefOptions(handle);
4242

4343
public static implicit operator IntPtr(ImportGraphDefOptions opts) => opts._handle;

src/TensorFlowNET.Core/IO/gfile.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ limitations under the License.
1616

1717
using System.Collections.Generic;
1818
using System.IO;
19+
using System.Linq;
1920

2021
namespace Tensorflow.IO
2122
{
@@ -28,6 +29,9 @@ public class GFile
2829
/// <param name="in_order">Traverse in order if True, post order if False.</param>
2930
public IEnumerable<(string, string[], string[])> Walk(string top, bool in_order = true)
3031
{
32+
if (!Directory.Exists(top))
33+
return Enumerable.Empty<(string, string[], string[])>();
34+
3135
return walk_v2(top, in_order);
3236
}
3337

src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ protected virtual Tensor _Enter(Tensor data, string frame_name,
141141
data, frame_name, is_constant, parallel_iterations, name: name);
142142

143143
if (use_input_shape)
144-
result.SetShape(data.TensorShape);
144+
result.set_shape(data.TensorShape);
145145

146146
return result;
147147
}

src/TensorFlowNET.Core/Operations/NnOps/rnn.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public static Tensor _transpose_batch_time(Tensor x)
233233
dims.AddRange(x_static_shape.dims.Skip(2));
234234
var shape = new TensorShape(dims.ToArray());
235235

236-
x_t.SetShape(shape);
236+
x_t.set_shape(shape);
237237

238238
return x_t;
239239
}

0 commit comments

Comments
 (0)