@@ -31,8 +31,9 @@ namespace Tensorflow | |||||
private GraphDef _as_graph_def(bool add_shapes = false) | private GraphDef _as_graph_def(bool add_shapes = false) | ||||
{ | { | ||||
var buffer = ToGraphDef(Status); | |||||
Status.Check(); | |||||
var status = new Status(); | |||||
var buffer = ToGraphDef(status); | |||||
status.Check(); | |||||
var def = GraphDef.Parser.ParseFrom(buffer); | var def = GraphDef.Parser.ParseFrom(buffer); | ||||
buffer.Dispose(); | buffer.Dispose(); | ||||
@@ -43,16 +43,20 @@ namespace Tensorflow | |||||
var bytes = File.ReadAllBytes(file_path); | var bytes = File.ReadAllBytes(file_path); | ||||
var graph_def = new Tensorflow.Buffer(bytes); | var graph_def = new Tensorflow.Buffer(bytes); | ||||
var opts = c_api.TF_NewImportGraphDefOptions(); | var opts = c_api.TF_NewImportGraphDefOptions(); | ||||
c_api.TF_GraphImportGraphDef(_handle, graph_def, opts, Status); | |||||
return Status; | |||||
var status = new Status(); | |||||
c_api.TF_GraphImportGraphDef(_handle, graph_def, opts, status); | |||||
return status; | |||||
} | } | ||||
public Status Import(byte[] bytes) | |||||
public Status Import(byte[] bytes, string prefix = "") | |||||
{ | { | ||||
var graph_def = new Tensorflow.Buffer(bytes); | var graph_def = new Tensorflow.Buffer(bytes); | ||||
var opts = c_api.TF_NewImportGraphDefOptions(); | var opts = c_api.TF_NewImportGraphDefOptions(); | ||||
c_api.TF_GraphImportGraphDef(_handle, graph_def, opts, Status); | |||||
return Status; | |||||
c_api.TF_ImportGraphDefOptionsSetPrefix(opts, prefix); | |||||
var status = new Status(); | |||||
c_api.TF_GraphImportGraphDef(_handle, graph_def, opts, status); | |||||
c_api.TF_DeleteImportGraphDefOptions(opts); | |||||
return status; | |||||
} | } | ||||
public static Graph ImportFromPB(string file_path, string name = null) | public static Graph ImportFromPB(string file_path, string name = null) | ||||
@@ -88,8 +88,7 @@ namespace Tensorflow | |||||
private string _graph_key; | private string _graph_key; | ||||
public string graph_key => _graph_key; | public string graph_key => _graph_key; | ||||
public string _last_loss_reduction; | public string _last_loss_reduction; | ||||
public bool _is_loss_scaled_by_optimizer { get; set; } | |||||
public Status Status { get; } | |||||
public bool _is_loss_scaled_by_optimizer { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// True if the graph is considered "finalized". In that case no | /// True if the graph is considered "finalized". In that case no | ||||
@@ -107,7 +106,6 @@ namespace Tensorflow | |||||
public Graph() | public Graph() | ||||
{ | { | ||||
_handle = c_api.TF_NewGraph(); | _handle = c_api.TF_NewGraph(); | ||||
Status = new Status(); | |||||
_nodes_by_id = new Dictionary<int, ITensorOrOperation>(); | _nodes_by_id = new Dictionary<int, ITensorOrOperation>(); | ||||
_nodes_by_name = new Dictionary<string, ITensorOrOperation>(); | _nodes_by_name = new Dictionary<string, ITensorOrOperation>(); | ||||
_names_in_use = new Dictionary<string, int>(); | _names_in_use = new Dictionary<string, int>(); | ||||
@@ -117,7 +115,6 @@ namespace Tensorflow | |||||
public Graph(IntPtr handle) | public Graph(IntPtr handle) | ||||
{ | { | ||||
_handle = handle; | _handle = handle; | ||||
Status = new Status(); | |||||
_nodes_by_id = new Dictionary<int, ITensorOrOperation>(); | _nodes_by_id = new Dictionary<int, ITensorOrOperation>(); | ||||
_nodes_by_name = new Dictionary<string, ITensorOrOperation>(); | _nodes_by_name = new Dictionary<string, ITensorOrOperation>(); | ||||
_names_in_use = new Dictionary<string, int>(); | _names_in_use = new Dictionary<string, int>(); | ||||
@@ -448,7 +445,12 @@ namespace Tensorflow | |||||
public void Dispose() | public void Dispose() | ||||
{ | { | ||||
// c_api.TF_DeleteGraph(_handle); | |||||
if (_handle != IntPtr.Zero) | |||||
c_api.TF_DeleteGraph(_handle); | |||||
_handle = IntPtr.Zero; | |||||
GC.SuppressFinalize(this); | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -32,20 +32,19 @@ namespace Tensorflow | |||||
protected int _current_version; | protected int _current_version; | ||||
protected byte[] _target; | protected byte[] _target; | ||||
protected IntPtr _session; | protected IntPtr _session; | ||||
public Status Status; | |||||
public Graph graph => _graph; | public Graph graph => _graph; | ||||
public BaseSession(string target = "", Graph g = null, SessionOptions opts = null) | public BaseSession(string target = "", Graph g = null, SessionOptions opts = null) | ||||
{ | { | ||||
_graph = g is null ? ops.get_default_graph() : g; | _graph = g is null ? ops.get_default_graph() : g; | ||||
_graph.as_default(); | |||||
_target = UTF8Encoding.UTF8.GetBytes(target); | _target = UTF8Encoding.UTF8.GetBytes(target); | ||||
SessionOptions newOpts = null; | SessionOptions newOpts = null; | ||||
if (opts == null) | if (opts == null) | ||||
newOpts = c_api.TF_NewSessionOptions(); | newOpts = c_api.TF_NewSessionOptions(); | ||||
Status = new Status(); | |||||
var Status = new Status(); | |||||
_session = c_api.TF_NewSession(_graph, opts ?? newOpts, Status); | _session = c_api.TF_NewSession(_graph, opts ?? newOpts, Status); | ||||
@@ -37,7 +37,7 @@ namespace Tensorflow | |||||
: base("", g, opts) | : base("", g, opts) | ||||
{ | { | ||||
if (s == null) | if (s == null) | ||||
s = Status; | |||||
s = new Status(); | |||||
} | } | ||||
public Session as_default() | public Session as_default() | ||||
@@ -83,8 +83,19 @@ namespace Tensorflow | |||||
public void Dispose() | public void Dispose() | ||||
{ | { | ||||
c_api.TF_DeleteSession(_session, Status); | |||||
Status.Dispose(); | |||||
if (_session != IntPtr.Zero) | |||||
{ | |||||
var status = new Status(); | |||||
c_api.TF_DeleteSession(_session, status); | |||||
} | |||||
_session = IntPtr.Zero; | |||||
GC.SuppressFinalize(this); | |||||
} | |||||
~Session() | |||||
{ | |||||
Dispose(); | |||||
} | } | ||||
public void __enter__() | public void __enter__() | ||||
@@ -5,7 +5,7 @@ | |||||
<AssemblyName>TensorFlow.NET</AssemblyName> | <AssemblyName>TensorFlow.NET</AssemblyName> | ||||
<RootNamespace>Tensorflow</RootNamespace> | <RootNamespace>Tensorflow</RootNamespace> | ||||
<TargetTensorFlow>1.14.0</TargetTensorFlow> | <TargetTensorFlow>1.14.0</TargetTensorFlow> | ||||
<Version>0.10.4</Version> | |||||
<Version>0.10.7</Version> | |||||
<Authors>Haiping Chen, Meinrad Recheis</Authors> | <Authors>Haiping Chen, Meinrad Recheis</Authors> | ||||
<Company>SciSharp STACK</Company> | <Company>SciSharp STACK</Company> | ||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | <GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||||
@@ -17,7 +17,7 @@ | |||||
<PackageTags>TensorFlow, NumSharp, SciSharp, MachineLearning, TensorFlow.NET, C#</PackageTags> | <PackageTags>TensorFlow, NumSharp, SciSharp, MachineLearning, TensorFlow.NET, C#</PackageTags> | ||||
<Description>Google's TensorFlow full binding in .NET Standard. | <Description>Google's TensorFlow full binding in .NET Standard. | ||||
Docs: https://tensorflownet.readthedocs.io</Description> | Docs: https://tensorflownet.readthedocs.io</Description> | ||||
<AssemblyVersion>0.10.4.0</AssemblyVersion> | |||||
<AssemblyVersion>0.10.7.0</AssemblyVersion> | |||||
<PackageReleaseNotes>Changes since v0.9.0: | <PackageReleaseNotes>Changes since v0.9.0: | ||||
1. Added full connected Convolution Neural Network example. | 1. Added full connected Convolution Neural Network example. | ||||
@@ -31,9 +31,12 @@ Docs: https://tensorflownet.readthedocs.io</Description> | |||||
9. Fix strided_slice_grad type convention error. | 9. Fix strided_slice_grad type convention error. | ||||
10. Add AbsGrad. | 10. Add AbsGrad. | ||||
11. Fix Session.LoadFromSavedModel(string). | 11. Fix Session.LoadFromSavedModel(string). | ||||
12. Add Tensor operator overloads.</PackageReleaseNotes> | |||||
12. Add Tensor operator overloads. | |||||
13. Fix default graph and operation issue when import model. | |||||
14. Fix TF_String endcode and decode. | |||||
15. Fix Tensor memory leak.</PackageReleaseNotes> | |||||
<LangVersion>7.2</LangVersion> | <LangVersion>7.2</LangVersion> | ||||
<FileVersion>0.10.4.0</FileVersion> | |||||
<FileVersion>0.10.7.0</FileVersion> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | ||||
<SignAssembly>true</SignAssembly> | <SignAssembly>true</SignAssembly> | ||||
@@ -19,6 +19,7 @@ using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||
using System.Text; | |||||
using Tensorflow.Framework; | using Tensorflow.Framework; | ||||
using static Tensorflow.Python; | using static Tensorflow.Python; | ||||
@@ -48,8 +49,6 @@ namespace Tensorflow | |||||
private int _value_index; | private int _value_index; | ||||
public int value_index => _value_index; | public int value_index => _value_index; | ||||
private Status status = new Status(); | |||||
private TF_DataType _dtype = TF_DataType.DtInvalid; | private TF_DataType _dtype = TF_DataType.DtInvalid; | ||||
public TF_DataType dtype => _handle == IntPtr.Zero ? _dtype : c_api.TF_TensorType(_handle); | public TF_DataType dtype => _handle == IntPtr.Zero ? _dtype : c_api.TF_TensorType(_handle); | ||||
@@ -76,6 +75,7 @@ namespace Tensorflow | |||||
if (_handle == IntPtr.Zero) | if (_handle == IntPtr.Zero) | ||||
{ | { | ||||
var status = new Status(); | |||||
c_api.TF_GraphGetTensorShape(op.graph, _as_tf_output(), dims, rank, status); | c_api.TF_GraphGetTensorShape(op.graph, _as_tf_output(), dims, rank, status); | ||||
status.Check(); | status.Check(); | ||||
} | } | ||||
@@ -90,6 +90,8 @@ namespace Tensorflow | |||||
set | set | ||||
{ | { | ||||
var status = new Status(); | |||||
if (value == null) | if (value == null) | ||||
c_api.TF_GraphSetTensorShape(this.graph, this._as_tf_output(), null, -1, status); | c_api.TF_GraphSetTensorShape(this.graph, this._as_tf_output(), null, -1, status); | ||||
else | else | ||||
@@ -131,6 +133,7 @@ namespace Tensorflow | |||||
{ | { | ||||
if (_handle == IntPtr.Zero) | if (_handle == IntPtr.Zero) | ||||
{ | { | ||||
var status = new Status(); | |||||
var output = _as_tf_output(); | var output = _as_tf_output(); | ||||
return c_api.TF_GraphGetTensorNumDims(op.graph, output, status); | return c_api.TF_GraphGetTensorNumDims(op.graph, output, status); | ||||
} | } | ||||
@@ -184,6 +187,41 @@ namespace Tensorflow | |||||
return data; | return data; | ||||
} | } | ||||
public unsafe string[] StringData() | |||||
{ | |||||
// | |||||
// TF_STRING tensors are encoded with a table of 8-byte offsets followed by TF_StringEncode-encoded bytes. | |||||
// [offset1, offset2,...,offsetn, s1size, s1bytes, s2size, s2bytes,...,snsize,snbytes] | |||||
// | |||||
long size = 1; | |||||
foreach (var s in TensorShape.Dimensions) | |||||
size *= s; | |||||
var buffer = new byte[size][]; | |||||
var src = c_api.TF_TensorData(_handle); | |||||
var srcLen = (IntPtr)(src.ToInt64() + (long)bytesize); | |||||
src += (int)(size * 8); | |||||
for (int i = 0; i < buffer.Length; i++) | |||||
{ | |||||
using (var status = new Status()) | |||||
{ | |||||
IntPtr dst = IntPtr.Zero; | |||||
UIntPtr dstLen = UIntPtr.Zero; | |||||
var read = c_api.TF_StringDecode((byte*)src, (UIntPtr)(srcLen.ToInt64() - src.ToInt64()), (byte**)&dst, &dstLen, status); | |||||
status.Check(true); | |||||
buffer[i] = new byte[(int)dstLen]; | |||||
Marshal.Copy(dst, buffer[i], 0, buffer[i].Length); | |||||
src += (int)read; | |||||
} | |||||
} | |||||
var _str = new string[buffer.Length]; | |||||
for (int i = 0; i < _str.Length; i++) | |||||
_str[i] = Encoding.UTF8.GetString(buffer[i]); | |||||
return _str; | |||||
} | |||||
public Tensor MaybeMove() | public Tensor MaybeMove() | ||||
{ | { | ||||
var tensor = c_api.TF_TensorMaybeMove(_handle); | var tensor = c_api.TF_TensorMaybeMove(_handle); | ||||
@@ -364,7 +402,7 @@ namespace Tensorflow | |||||
} | } | ||||
if (h != IntPtr.Zero) | if (h != IntPtr.Zero) | ||||
c_api.TF_DeleteTensor(h); | c_api.TF_DeleteTensor(h); | ||||
status.Dispose(); | |||||
GC.SuppressFinalize(this); | GC.SuppressFinalize(this); | ||||
} | } | ||||
@@ -32,6 +32,9 @@ namespace Tensorflow | |||||
[DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
public static extern IntPtr TF_AllocateTensor(TF_DataType dtype, IntPtr dims, int num_dims, UIntPtr len); | public static extern IntPtr TF_AllocateTensor(TF_DataType dtype, IntPtr dims, int num_dims, UIntPtr len); | ||||
[DllImport(TensorFlowLibName)] | |||||
public static extern IntPtr TF_AllocateTensor(TF_DataType dtype, long[] dims, int num_dims, UIntPtr len); | |||||
/// <summary> | /// <summary> | ||||
/// returns the sizeof() for the underlying type corresponding to the given TF_DataType enum value. | /// returns the sizeof() for the underlying type corresponding to the given TF_DataType enum value. | ||||
/// </summary> | /// </summary> | ||||
@@ -150,5 +153,8 @@ namespace Tensorflow | |||||
/// <returns></returns> | /// <returns></returns> | ||||
[DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
public static extern ulong TF_StringDecode(IntPtr src, ulong src_len, IntPtr dst, ref ulong dst_len, IntPtr status); | public static extern ulong TF_StringDecode(IntPtr src, ulong src_len, IntPtr dst, ref ulong dst_len, IntPtr status); | ||||
[DllImport(TensorFlowLibName)] | |||||
public static extern unsafe UIntPtr TF_StringDecode(byte* src, UIntPtr src_len, byte** dst, UIntPtr* dst_len, IntPtr status); | |||||
} | } | ||||
} | } |