@@ -111,7 +111,7 @@ namespace Tensorflow | |||||
return Enumerable.Range(start, end - start); | return Enumerable.Range(start, end - start); | ||||
} | } | ||||
public static T New<T>() where T : IObjectLife, new() | |||||
public static T New<T>() where T : ITensorFlowObject, new() | |||||
{ | { | ||||
var instance = new T(); | var instance = new T(); | ||||
instance.__init__(); | instance.__init__(); | ||||
@@ -120,7 +120,7 @@ namespace Tensorflow | |||||
[DebuggerStepThrough] | [DebuggerStepThrough] | ||||
[DebuggerNonUserCode()] // with "Just My Code" enabled this lets the debugger break at the origin of the exception | [DebuggerNonUserCode()] // with "Just My Code" enabled this lets the debugger break at the origin of the exception | ||||
public static void tf_with(IObjectLife py, Action<IObjectLife> action) | |||||
public static void tf_with(ITensorFlowObject py, Action<ITensorFlowObject> action) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -136,7 +136,7 @@ namespace Tensorflow | |||||
[DebuggerStepThrough] | [DebuggerStepThrough] | ||||
[DebuggerNonUserCode()] // with "Just My Code" enabled this lets the debugger break at the origin of the exception | [DebuggerNonUserCode()] // with "Just My Code" enabled this lets the debugger break at the origin of the exception | ||||
public static void tf_with<T>(T py, Action<T> action) where T : IObjectLife | |||||
public static void tf_with<T>(T py, Action<T> action) where T : ITensorFlowObject | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -152,7 +152,7 @@ namespace Tensorflow | |||||
[DebuggerStepThrough] | [DebuggerStepThrough] | ||||
[DebuggerNonUserCode()] // with "Just My Code" enabled this lets the debugger break at the origin of the exception | [DebuggerNonUserCode()] // with "Just My Code" enabled this lets the debugger break at the origin of the exception | ||||
public static TOut tf_with<TIn, TOut>(TIn py, Func<TIn, TOut> action) where TIn : IObjectLife | |||||
public static TOut tf_with<TIn, TOut>(TIn py, Func<TIn, TOut> action) where TIn : ITensorFlowObject | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -8,6 +8,7 @@ namespace Tensorflow.Eager | |||||
public const int EAGER_MODE = 1; | public const int EAGER_MODE = 1; | ||||
public int default_execution_mode; | public int default_execution_mode; | ||||
public string device_name = ""; | |||||
public Context(ContextOptions opts, Status status) | public Context(ContextOptions opts, Status status) | ||||
{ | { | ||||
@@ -22,7 +23,7 @@ namespace Tensorflow.Eager | |||||
=> c_api.TFE_DeleteContext(_handle); | => c_api.TFE_DeleteContext(_handle); | ||||
public bool executing_eagerly() => false; | |||||
public bool executing_eagerly() => true; | |||||
public static implicit operator IntPtr(Context ctx) | public static implicit operator IntPtr(Context ctx) | ||||
=> ctx._handle; | => ctx._handle; | ||||
@@ -0,0 +1,42 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Tensorflow.Eager | |||||
{ | |||||
public class EagerTensor : Tensor | |||||
{ | |||||
public EagerTensor(IntPtr handle) : base(handle) | |||||
{ | |||||
} | |||||
public EagerTensor(string value, string device_name) : base(value) | |||||
{ | |||||
} | |||||
public override string ToString() | |||||
{ | |||||
switch (rank) | |||||
{ | |||||
case -1: | |||||
return $"tf.Tensor: shape=<unknown>, dtype={dtype.as_numpy_name()}, numpy={GetFormattedString()}"; | |||||
case 0: | |||||
return $"tf.Tensor: shape=(), dtype={dtype.as_numpy_name()}, numpy={GetFormattedString()}"; | |||||
default: | |||||
return $"tf.Tensor: shape=({string.Join(",", shape)}), dtype={dtype.as_numpy_name()}, numpy={GetFormattedString()}"; | |||||
} | |||||
} | |||||
private string GetFormattedString() | |||||
{ | |||||
var nd = numpy(); | |||||
switch (dtype) | |||||
{ | |||||
case TF_DataType.TF_STRING: | |||||
return $"b'{(string)nd}'"; | |||||
default: | |||||
return nd.ToString(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -23,7 +23,7 @@ namespace Tensorflow | |||||
/// <summary> | /// <summary> | ||||
/// Context manager for `control_dependencies()` | /// Context manager for `control_dependencies()` | ||||
/// </summary> | /// </summary> | ||||
public class _ControlDependenciesController : IObjectLife | |||||
public class _ControlDependenciesController : ITensorFlowObject | |||||
{ | { | ||||
private Graph _graph; | private Graph _graph; | ||||
private List<ITensorOrOperation> _control_inputs_val; | private List<ITensorOrOperation> _control_inputs_val; | ||||
@@ -18,7 +18,7 @@ using System; | |||||
namespace Tensorflow | namespace Tensorflow | ||||
{ | { | ||||
public interface IObjectLife : IDisposable | |||||
public interface ITensorFlowObject : IDisposable | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Called when the instance is created. | /// Called when the instance is created. |
@@ -18,7 +18,7 @@ using Tensorflow.Keras.Layers; | |||||
namespace Tensorflow.Keras.Engine | namespace Tensorflow.Keras.Engine | ||||
{ | { | ||||
public class Sequential : Model, IObjectLife | |||||
public class Sequential : Model, ITensorFlowObject | |||||
{ | { | ||||
bool _is_graph_network; | bool _is_graph_network; | ||||
Tensor[] outputs; | Tensor[] outputs; | ||||
@@ -41,7 +41,7 @@ namespace Tensorflow.Operations | |||||
/// 4. A ControlFlowContext has _context_stack. | /// 4. A ControlFlowContext has _context_stack. | ||||
/// Pushed and popped by ctxt.Enter() and ctxt.Exit() | /// Pushed and popped by ctxt.Enter() and ctxt.Exit() | ||||
/// </summary> | /// </summary> | ||||
public abstract class ControlFlowContext : IObjectLife | |||||
public abstract class ControlFlowContext : ITensorFlowObject | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// The predicate tensor in this branch | /// The predicate tensor in this branch | ||||
@@ -22,7 +22,7 @@ using static Tensorflow.Binding; | |||||
namespace Tensorflow | namespace Tensorflow | ||||
{ | { | ||||
public class Session : BaseSession, IObjectLife | |||||
public class Session : BaseSession, ITensorFlowObject | |||||
{ | { | ||||
public Session(string target = "", Graph g = null) : base(target, g, null) | public Session(string target = "", Graph g = null) : base(target, g, null) | ||||
{ } | { } | ||||
@@ -6,6 +6,7 @@ | |||||
<RootNamespace>Tensorflow</RootNamespace> | <RootNamespace>Tensorflow</RootNamespace> | ||||
<TargetTensorFlow>1.14.1</TargetTensorFlow> | <TargetTensorFlow>1.14.1</TargetTensorFlow> | ||||
<Version>0.20.0</Version> | <Version>0.20.0</Version> | ||||
<LangVersion>8.0</LangVersion> | |||||
<Authors>Haiping Chen, Meinrad Recheis, Eli Belash</Authors> | <Authors>Haiping Chen, Meinrad Recheis, Eli Belash</Authors> | ||||
<Company>SciSharp STACK</Company> | <Company>SciSharp STACK</Company> | ||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | <GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||||
@@ -25,7 +26,6 @@ https://tensorflownet.readthedocs.io</Description> | |||||
3: Import Protobuf.Text | 3: Import Protobuf.Text | ||||
4: Support YOLOv3 object detection | 4: Support YOLOv3 object detection | ||||
5: Add implicitation for Operation to RefVariable</PackageReleaseNotes> | 5: Add implicitation for Operation to RefVariable</PackageReleaseNotes> | ||||
<LangVersion>7.3</LangVersion> | |||||
<FileVersion>0.20.0.0</FileVersion> | <FileVersion>0.20.0.0</FileVersion> | ||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | ||||
@@ -455,14 +455,14 @@ namespace Tensorflow | |||||
{ | { | ||||
var status = new Status(); | var status = new Status(); | ||||
var buffer = Encoding.UTF8.GetBytes(str); | var buffer = Encoding.UTF8.GetBytes(str); | ||||
var size = c_api.TF_StringEncodedSize((UIntPtr) buffer.Length); | |||||
var handle = TF_AllocateTensor(TF_DataType.TF_STRING, IntPtr.Zero, 0, (UIntPtr) ((ulong) size + 8)); | |||||
var size = c_api.TF_StringEncodedSize((UIntPtr)buffer.Length); | |||||
var handle = TF_AllocateTensor(TF_DataType.TF_STRING, IntPtr.Zero, 0, (UIntPtr)((ulong)size + 8)); | |||||
AllocationType = AllocationType.Tensorflow; | AllocationType = AllocationType.Tensorflow; | ||||
IntPtr tensor = c_api.TF_TensorData(handle); | IntPtr tensor = c_api.TF_TensorData(handle); | ||||
Marshal.WriteInt64(tensor, 0); | Marshal.WriteInt64(tensor, 0); | ||||
fixed (byte* src = buffer) | fixed (byte* src = buffer) | ||||
c_api.TF_StringEncode(src, (UIntPtr) buffer.Length, (sbyte*) (tensor + sizeof(Int64)), size, status); | |||||
c_api.TF_StringEncode(src, (UIntPtr)buffer.Length, (sbyte*)(tensor + sizeof(long)), size, status); | |||||
_handle = handle; | _handle = handle; | ||||
status.Check(true); | status.Check(true); | ||||
} | } | ||||
@@ -79,7 +79,7 @@ namespace Tensorflow | |||||
/// <summary> | /// <summary> | ||||
/// The string name of this tensor. | /// The string name of this tensor. | ||||
/// </summary> | /// </summary> | ||||
public string name => $"{(op == null ? "<unnamed Operation>" : $"{op.name}:{_value_index}")}"; | |||||
public string name => $"{(op == null ? "<unnamed>" : $"{op.name}:{_value_index}")}"; | |||||
/// <summary> | /// <summary> | ||||
/// The index of this tensor in the outputs of its Operation. | /// The index of this tensor in the outputs of its Operation. | ||||
@@ -381,13 +381,21 @@ namespace Tensorflow | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Copies the memory of current buffer onto newly allocated array. | |||||
/// Copy of the contents of this Tensor into a NumPy array or scalar. | |||||
/// </summary> | /// </summary> | ||||
/// <returns></returns> | |||||
[Obsolete("Please use set_shape(TensorShape shape) instead.", false)] | |||||
public byte[] Data() | |||||
/// <returns> | |||||
/// A NumPy array of the same shape and dtype or a NumPy scalar, if this | |||||
/// Tensor has rank 0. | |||||
/// </returns> | |||||
public NDArray numpy() | |||||
{ | { | ||||
return BufferToArray(); | |||||
switch (dtype) | |||||
{ | |||||
case TF_DataType.TF_STRING: | |||||
return StringData()[0]; | |||||
default: | |||||
return BufferToArray(); | |||||
} | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -399,7 +407,7 @@ namespace Tensorflow | |||||
unsafe | unsafe | ||||
{ | { | ||||
// ReSharper disable once LocalVariableHidesMember | // ReSharper disable once LocalVariableHidesMember | ||||
var bytesize = (long) this.bytesize; | |||||
var bytesize = (long)this.bytesize; | |||||
var data = new byte[bytesize]; | var data = new byte[bytesize]; | ||||
fixed (byte* dst = data) | fixed (byte* dst = data) | ||||
System.Buffer.MemoryCopy(buffer.ToPointer(), dst, bytesize, bytesize); | System.Buffer.MemoryCopy(buffer.ToPointer(), dst, bytesize, bytesize); | ||||
@@ -427,7 +435,7 @@ namespace Tensorflow | |||||
var buffer = new byte[size][]; | var buffer = new byte[size][]; | ||||
var src = c_api.TF_TensorData(_handle); | var src = c_api.TF_TensorData(_handle); | ||||
var srcLen = (IntPtr) (src.ToInt64() + (long) bytesize); | |||||
var srcLen = (IntPtr)(src.ToInt64() + (long)bytesize); | |||||
src += (int) (size * 8); | src += (int) (size * 8); | ||||
for (int i = 0; i < buffer.Length; i++) | for (int i = 0; i < buffer.Length; i++) | ||||
{ | { | ||||
@@ -435,7 +443,7 @@ namespace Tensorflow | |||||
{ | { | ||||
IntPtr dst = IntPtr.Zero; | IntPtr dst = IntPtr.Zero; | ||||
UIntPtr dstLen = UIntPtr.Zero; | UIntPtr dstLen = UIntPtr.Zero; | ||||
var read = c_api.TF_StringDecode((byte*) src, (UIntPtr) (srcLen.ToInt64() - src.ToInt64()), (byte**) &dst, &dstLen, status); | |||||
var read = c_api.TF_StringDecode((byte*)src, (UIntPtr)(srcLen.ToInt64() - src.ToInt64()), (byte**)&dst, &dstLen, status); | |||||
status.Check(true); | status.Check(true); | ||||
buffer[i] = new byte[(int) dstLen]; | buffer[i] = new byte[(int) dstLen]; | ||||
Marshal.Copy(dst, buffer[i], 0, buffer[i].Length); | Marshal.Copy(dst, buffer[i], 0, buffer[i].Length); | ||||
@@ -16,6 +16,7 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using Tensorflow.Eager; | |||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
namespace Tensorflow | namespace Tensorflow | ||||
@@ -39,11 +40,18 @@ namespace Tensorflow | |||||
return _constant_impl(value, dtype, shape, name, verify_shape: false, allow_broadcast: true); | return _constant_impl(value, dtype, shape, name, verify_shape: false, allow_broadcast: true); | ||||
} | } | ||||
public static Tensor _constant_impl(object value, TF_DataType dtype, int[] shape, string name, bool verify_shape, bool allow_broadcast) | |||||
public static Tensor _constant_impl(object value, | |||||
TF_DataType dtype, | |||||
int[] shape, | |||||
string name, | |||||
bool verify_shape, | |||||
bool allow_broadcast) | |||||
{ | { | ||||
if (tf.context.executing_eagerly()) | if (tf.context.executing_eagerly()) | ||||
{ | { | ||||
var t = convert_to_eager_tensor(value, tf.context, dtype: dtype); | |||||
if (shape == null) | |||||
return t; | |||||
} | } | ||||
Graph g = ops.get_default_graph(); | Graph g = ops.get_default_graph(); | ||||
@@ -72,6 +80,17 @@ namespace Tensorflow | |||||
return op.outputs[0]; | return op.outputs[0]; | ||||
} | } | ||||
private static EagerTensor convert_to_eager_tensor(object value, Context ctx, TF_DataType dtype = TF_DataType.DtInvalid) | |||||
{ | |||||
switch (value) | |||||
{ | |||||
case string str: | |||||
return new EagerTensor(str, ctx.device_name); | |||||
default: | |||||
throw new NotImplementedException($"convert_to_eager_tensor {value.GetType()}"); | |||||
} | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Function to convert TensorShape to Tensor. | /// Function to convert TensorShape to Tensor. | ||||
/// </summary> | /// </summary> | ||||
@@ -197,6 +197,13 @@ namespace Tensorflow | |||||
return (int)type; | return (int)type; | ||||
} | } | ||||
public static string as_numpy_name(this TF_DataType type) | |||||
=> type switch | |||||
{ | |||||
TF_DataType.TF_STRING => "string", | |||||
_ => type.ToString() | |||||
}; | |||||
public static Type as_numpy_dtype(this DataType type) | public static Type as_numpy_dtype(this DataType type) | ||||
{ | { | ||||
return type.as_tf_dtype().as_numpy_dtype(); | return type.as_tf_dtype().as_numpy_dtype(); | ||||
@@ -20,35 +20,44 @@ namespace Tensorflow | |||||
{ | { | ||||
public partial class tensorflow | public partial class tensorflow | ||||
{ | { | ||||
// public static Tensor constant(NDArray nd, string name = "Const") => constant_op.constant(nd, name: name); | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="value"></param> | |||||
/// <param name="dtype"></param> | |||||
/// <param name="shape"></param> | |||||
/// <param name="name"></param> | |||||
/// <returns></returns> | |||||
public Tensor constant(object value, | public Tensor constant(object value, | ||||
TF_DataType dtype = TF_DataType.DtInvalid, | TF_DataType dtype = TF_DataType.DtInvalid, | ||||
int[] shape = null, | |||||
string name = "Const", | |||||
bool verify_shape = false) => constant_op._constant_impl(value, | |||||
dtype, | |||||
shape, | |||||
name, | |||||
verify_shape: verify_shape, | |||||
allow_broadcast: false); | |||||
public Tensor constant(string value, | |||||
string name = "Const") => constant_op._constant_impl(value, | |||||
@string, | |||||
new int[] { 1 }, | |||||
name, | |||||
verify_shape: false, | |||||
allow_broadcast: false); | |||||
public Tensor constant(float value, | |||||
int shape, | |||||
string name = "Const") => constant_op._constant_impl(value, | |||||
float32, | |||||
new int[] { shape }, | |||||
name, | |||||
verify_shape: false, | |||||
allow_broadcast: false); | |||||
TensorShape shape = null, | |||||
string name = "Const") | |||||
{ | |||||
switch (value) | |||||
{ | |||||
case string str: | |||||
return constant_op._constant_impl(str, | |||||
@string, | |||||
null, | |||||
name, | |||||
verify_shape: false, | |||||
allow_broadcast: true); | |||||
case float val: | |||||
return constant_op._constant_impl(value, | |||||
float32, | |||||
new int[] { (int)shape }, | |||||
name, | |||||
verify_shape: false, | |||||
allow_broadcast: true); | |||||
default: | |||||
return constant_op._constant_impl(value, | |||||
dtype, | |||||
shape, | |||||
name, | |||||
verify_shape: false, | |||||
allow_broadcast: true); | |||||
} | |||||
} | |||||
public Tensor zeros(TensorShape shape, TF_DataType dtype = TF_DataType.TF_FLOAT, string name = null) | public Tensor zeros(TensorShape shape, TF_DataType dtype = TF_DataType.TF_FLOAT, string name = null) | ||||
=> array_ops.zeros(shape, dtype, name); | => array_ops.zeros(shape, dtype, name); | ||||
@@ -19,7 +19,7 @@ using System.Linq; | |||||
namespace Tensorflow | namespace Tensorflow | ||||
{ | { | ||||
public class PureVariableScope : IObjectLife | |||||
public class PureVariableScope : ITensorFlowObject | |||||
{ | { | ||||
private string _name; | private string _name; | ||||
private VariableScope _scope; | private VariableScope _scope; | ||||
@@ -23,7 +23,7 @@ namespace Tensorflow | |||||
/// <summary> | /// <summary> | ||||
/// A context manager for defining ops that creates variables (layers). | /// A context manager for defining ops that creates variables (layers). | ||||
/// </summary> | /// </summary> | ||||
public class variable_scope : IObjectLife | |||||
public class variable_scope : ITensorFlowObject | |||||
{ | { | ||||
public static string _VARSTORE_KEY = "__variable_store"; | public static string _VARSTORE_KEY = "__variable_store"; | ||||
public static string _VARSCOPESTORE_KEY = "__varscope"; | public static string _VARSCOPESTORE_KEY = "__varscope"; | ||||
@@ -23,7 +23,7 @@ namespace Tensorflow | |||||
{ | { | ||||
_DefaultStack _default_session_stack = new _DefaultStack(); | _DefaultStack _default_session_stack = new _DefaultStack(); | ||||
public class _DefaultStack : IObjectLife | |||||
public class _DefaultStack : ITensorFlowObject | |||||
{ | { | ||||
Stack<object> stack; | Stack<object> stack; | ||||
bool _enforce_nesting = true; | bool _enforce_nesting = true; | ||||
@@ -254,7 +254,7 @@ namespace Tensorflow | |||||
}); | }); | ||||
} | } | ||||
public static IObjectLife init_scope2() | |||||
public static ITensorFlowObject init_scope2() | |||||
{ | { | ||||
// Retrieve the active name scope: entering an `init_scope` preserves | // Retrieve the active name scope: entering an `init_scope` preserves | ||||
// the name scope of the current context. | // the name scope of the current context. | ||||
@@ -27,7 +27,7 @@ namespace Tensorflow | |||||
/// <summary> | /// <summary> | ||||
/// Returns a context manager that creates hierarchical names for operations. | /// Returns a context manager that creates hierarchical names for operations. | ||||
/// </summary> | /// </summary> | ||||
public class NameScope : IObjectLife | |||||
public class NameScope : ITensorFlowObject | |||||
{ | { | ||||
public string _name; | public string _name; | ||||
public string _default_name; | public string _default_name; | ||||
@@ -19,7 +19,7 @@ using Tensorflow.Eager; | |||||
namespace Tensorflow | namespace Tensorflow | ||||
{ | { | ||||
public partial class tensorflow : IObjectLife | |||||
public partial class tensorflow : ITensorFlowObject | |||||
{ | { | ||||
public TF_DataType @byte = TF_DataType.TF_UINT8; | public TF_DataType @byte = TF_DataType.TF_UINT8; | ||||
public TF_DataType @sbyte = TF_DataType.TF_INT8; | public TF_DataType @sbyte = TF_DataType.TF_INT8; | ||||
@@ -19,7 +19,7 @@ using System.Threading; | |||||
namespace Tensorflow | namespace Tensorflow | ||||
{ | { | ||||
public partial class tensorflow : IObjectLife | |||||
public partial class tensorflow : ITensorFlowObject | |||||
{ | { | ||||
protected ThreadLocal<Session> _defaultSessionFactory; | protected ThreadLocal<Session> _defaultSessionFactory; | ||||
@@ -259,7 +259,7 @@ namespace TensorFlowNET.UnitTest | |||||
return s.as_default(); | return s.as_default(); | ||||
} | } | ||||
private IObjectLife _constrain_devices_and_set_default(Session sess, bool useGpu, bool forceGpu) | |||||
private ITensorFlowObject _constrain_devices_and_set_default(Session sess, bool useGpu, bool forceGpu) | |||||
{ | { | ||||
//def _constrain_devices_and_set_default(self, sess, use_gpu, force_gpu): | //def _constrain_devices_and_set_default(self, sess, use_gpu, force_gpu): | ||||
//"""Set the session and its graph to global default and constrain devices.""" | //"""Set the session and its graph to global default and constrain devices.""" | ||||
@@ -11,7 +11,7 @@ namespace TensorFlowNET.UnitTest | |||||
public void GetVersion() | public void GetVersion() | ||||
{ | { | ||||
var ver = tf.VERSION; | var ver = tf.VERSION; | ||||
Assert.IsTrue(ver.StartsWith("1.14.")); | |||||
Assert.IsTrue(ver.StartsWith("1.15.")); | |||||
} | } | ||||
} | } | ||||
} | } |