@@ -1,5 +1,4 @@ | |||||
using Tensorflow.Util; | using Tensorflow.Util; | ||||
using static Tensorflow.tensorflow; | |||||
namespace Tensorflow.Gradients | namespace Tensorflow.Gradients | ||||
{ | { | ||||
@@ -15,13 +14,13 @@ namespace Tensorflow.Gradients | |||||
/// Maps from op ID to how many output tensors of this op still need to have | /// Maps from op ID to how many output tensors of this op still need to have | ||||
/// their gradients computed. | /// their gradients computed. | ||||
/// </summary> | /// </summary> | ||||
public UnorderedMap<Tensor, long> op_missing_tensor { get; set; } | |||||
public UnorderedMap<long, long> op_missing_tensor { get; set; } | |||||
public BackpropInitialState() | public BackpropInitialState() | ||||
{ | { | ||||
op_tape = new OpTape(); | op_tape = new OpTape(); | ||||
tensor_usage_counts = new UnorderedMap<Tensor, long>(); | tensor_usage_counts = new UnorderedMap<Tensor, long>(); | ||||
op_missing_tensor = new UnorderedMap<Tensor, long>(); | |||||
op_missing_tensor = new UnorderedMap<long, long>(); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -5,7 +5,7 @@ namespace Tensorflow.Gradients | |||||
/// <summary> | /// <summary> | ||||
/// Map from operation-id to tape entry. | /// Map from operation-id to tape entry. | ||||
/// </summary> | /// </summary> | ||||
public class OpTape : UnorderedMap<Tensor, OpTapeEntry> | |||||
public class OpTape : UnorderedMap<long, OpTapeEntry> | |||||
{ | { | ||||
} | } | ||||
@@ -144,7 +144,7 @@ namespace Tensorflow.Gradients | |||||
} | } | ||||
var op_id = tape_it; | var op_id = tape_it; | ||||
if (op_id == null) | |||||
if (op_id == -1) | |||||
continue; | continue; | ||||
if (state.op_missing_tensor.find(op_id, out var missing_it)) | if (state.op_missing_tensor.find(op_id, out var missing_it)) | ||||
@@ -235,10 +235,10 @@ namespace Tensorflow.Gradients | |||||
return result; | return result; | ||||
} | } | ||||
Queue<Tensor> InitialStack(OpTape op_tape, | |||||
UnorderedMap<Tensor, long> op_missing_tensor) | |||||
Queue<long> InitialStack(OpTape op_tape, | |||||
UnorderedMap<long, long> op_missing_tensor) | |||||
{ | { | ||||
var result = new Queue<Tensor>(); | |||||
var result = new Queue<long>(); | |||||
foreach (var op_entry in op_tape) | foreach (var op_entry in op_tape) | ||||
{ | { | ||||
if (!op_missing_tensor.find(op_entry.Key)) | if (!op_missing_tensor.find(op_entry.Key)) | ||||
@@ -1,6 +1,5 @@ | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using Tensorflow.Util; | using Tensorflow.Util; | ||||
using static Tensorflow.tensorflow; | |||||
namespace Tensorflow.Gradients | namespace Tensorflow.Gradients | ||||
{ | { | ||||
@@ -21,7 +20,7 @@ namespace Tensorflow.Gradients | |||||
if (!tensor_tape.find(tensor_id, out var op_id)) | if (!tensor_tape.find(tensor_id, out var op_id)) | ||||
continue; | continue; | ||||
if (op_id == null || | |||||
if (op_id == -1 || | |||||
!op_tape.find(op_id, out var op_it) || | !op_tape.find(op_id, out var op_it) || | ||||
result.op_tape.find(op_id, out var result_op_it)) | result.op_tape.find(op_id, out var result_op_it)) | ||||
continue; | continue; | ||||
@@ -46,7 +45,7 @@ namespace Tensorflow.Gradients | |||||
foreach (var pair in result.tensor_usage_counts) | foreach (var pair in result.tensor_usage_counts) | ||||
{ | { | ||||
if (tensor_tape.find(pair.Key, out var it) && it != null) | |||||
if (tensor_tape.find(pair.Key, out var it) && it != -1) | |||||
result.op_missing_tensor[it] += 1; | result.op_missing_tensor[it] += 1; | ||||
} | } | ||||
@@ -1,10 +1,7 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using Tensorflow.Util; | using Tensorflow.Util; | ||||
using static Tensorflow.tensorflow; | |||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
using System.Linq; | |||||
using Tensorflow.Eager; | |||||
namespace Tensorflow.Gradients | namespace Tensorflow.Gradients | ||||
{ | { | ||||
@@ -21,7 +18,7 @@ namespace Tensorflow.Gradients | |||||
if (!ShouldRecord(input_tensors)) | if (!ShouldRecord(input_tensors)) | ||||
return; | return; | ||||
var op_id = new EagerTensor(next_op_id_++); | |||||
var op_id = next_op_id_++; | |||||
foreach (var i in input_tensors) | foreach (var i in input_tensors) | ||||
tensor_usage_[i]++; | tensor_usage_[i]++; | ||||
@@ -42,7 +42,7 @@ namespace Tensorflow.Gradients | |||||
public void Watch(Tensor x) | public void Watch(Tensor x) | ||||
{ | { | ||||
tf.Logger.Debug($"Watch tensor id={x.Id}, name={x.name}"); | tf.Logger.Debug($"Watch tensor id={x.Id}, name={x.name}"); | ||||
tensor_tape_.emplace(x, null); | |||||
tensor_tape_.emplace(x, -1); | |||||
} | } | ||||
public bool ShouldRecord(Tensor[] tensors) | public bool ShouldRecord(Tensor[] tensors) | ||||
@@ -7,7 +7,7 @@ namespace Tensorflow.Gradients | |||||
/// produced this tensor. A value of -1 means that the tensor was directly | /// produced this tensor. A value of -1 means that the tensor was directly | ||||
/// watched and not the result of any operation in the tape. | /// watched and not the result of any operation in the tape. | ||||
/// </summary> | /// </summary> | ||||
public class TensorTape : UnorderedMap<Tensor, Tensor> | |||||
public class TensorTape : UnorderedMap<Tensor, long> | |||||
{ | { | ||||
} | } | ||||
@@ -656,9 +656,6 @@ namespace Tensorflow | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (x.rank > -1 && tf.executing_eagerly()) | |||||
return constant_op.constant(np.arange(x.rank)); | |||||
var rank = array_ops.rank(x); | var rank = array_ops.rank(x); | ||||
return range(0, rank, 1); | return range(0, rank, 1); | ||||
} | } | ||||
@@ -678,11 +675,6 @@ namespace Tensorflow | |||||
// we rely on Range and Rank to do the right thing at run-time. | // we rely on Range and Rank to do the right thing at run-time. | ||||
if (rank == -1) return range(0, array_ops.rank(x)); | if (rank == -1) return range(0, array_ops.rank(x)); | ||||
if (rank.HasValue && rank.Value > -1) | |||||
{ | |||||
return constant_op.constant(np.arange(rank.Value), TF_DataType.TF_INT32); | |||||
} | |||||
return range(0, rank, 1); | return range(0, rank, 1); | ||||
} | } | ||||
} | } | ||||
@@ -6,7 +6,7 @@ | |||||
<RootNamespace>Tensorflow</RootNamespace> | <RootNamespace>Tensorflow</RootNamespace> | ||||
<TargetTensorFlow>2.2.0</TargetTensorFlow> | <TargetTensorFlow>2.2.0</TargetTensorFlow> | ||||
<Version>0.60.5</Version> | <Version>0.60.5</Version> | ||||
<LangVersion>9.0</LangVersion> | |||||
<LangVersion>10.0</LangVersion> | |||||
<Nullable>enable</Nullable> | <Nullable>enable</Nullable> | ||||
<Authors>Haiping Chen, Meinrad Recheis, Eli Belash</Authors> | <Authors>Haiping Chen, Meinrad Recheis, Eli Belash</Authors> | ||||
<Company>SciSharp STACK</Company> | <Company>SciSharp STACK</Company> | ||||
@@ -71,38 +71,7 @@ namespace Tensorflow | |||||
/// <param name="deallocator_arg"></param> | /// <param name="deallocator_arg"></param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
[DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
public static extern IntPtr TF_NewTensor(TF_DataType dataType, long[] dims, int num_dims, IntPtr data, UIntPtr len, Deallocator deallocator, ref DeallocatorArgs deallocator_arg); | |||||
[DllImport(TensorFlowLibName)] | |||||
public static extern TF_Tensor TF_NewTensor(TF_DataType dataType, long[] dims, int num_dims, IntPtr data, long len, DeallocatorV2 deallocator, IntPtr args); | |||||
/// <summary> | |||||
/// Return a new tensor that holds the bytes data[0,len-1] | |||||
/// </summary> | |||||
/// <param name="dataType"></param> | |||||
/// <param name="dims"></param> | |||||
/// <param name="num_dims"></param> | |||||
/// <param name="data"></param> | |||||
/// <param name="len">num_bytes, ex: 6 * sizeof(float)</param> | |||||
/// <param name="deallocator"></param> | |||||
/// <param name="deallocator_arg"></param> | |||||
/// <returns></returns> | |||||
[DllImport(TensorFlowLibName)] | |||||
public static extern IntPtr TF_NewTensor(TF_DataType dataType, long[] dims, int num_dims, IntPtr data, ulong len, Deallocator deallocator, IntPtr deallocator_arg); | |||||
/// <summary> | |||||
/// Return a new tensor that holds the bytes data[0,len-1] | |||||
/// </summary> | |||||
/// <param name="dataType"></param> | |||||
/// <param name="dims"></param> | |||||
/// <param name="num_dims"></param> | |||||
/// <param name="data"></param> | |||||
/// <param name="len">num_bytes, ex: 6 * sizeof(float)</param> | |||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||||
public static unsafe IntPtr TF_NewTensor(TF_DataType dataType, long[] dims, int num_dims, IntPtr data, ulong len) | |||||
{ | |||||
return TF_NewTensor(dataType, dims, num_dims, data, len, EmptyDeallocator, DeallocatorArgs.Empty); | |||||
} | |||||
public static extern SafeTensorHandle TF_NewTensor(TF_DataType dataType, long[] dims, int num_dims, IntPtr data, ulong len, Deallocator deallocator, IntPtr deallocator_arg); | |||||
public static unsafe SafeTensorHandle TF_NewTensor(byte[] data, Shape shape, TF_DataType dtype) | public static unsafe SafeTensorHandle TF_NewTensor(byte[] data, Shape shape, TF_DataType dtype) | ||||
{ | { | ||||
@@ -137,20 +106,6 @@ namespace Tensorflow | |||||
return handle; | return handle; | ||||
} | } | ||||
/// <summary> | |||||
/// Return a new tensor that holds the bytes data[0,len-1] | |||||
/// </summary> | |||||
/// <param name="dataType"></param> | |||||
/// <param name="dims"></param> | |||||
/// <param name="num_dims"></param> | |||||
/// <param name="data"></param> | |||||
/// <param name="len">num_bytes, ex: 6 * sizeof(float)</param> | |||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||||
public static unsafe IntPtr TF_NewTensor(TF_DataType dataType, long[] dims, int num_dims, void* data, ulong len) | |||||
{ | |||||
return TF_NewTensor(dataType, dims, num_dims, new IntPtr(data), len); | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Return the number of dimensions that the tensor has. | /// Return the number of dimensions that the tensor has. | ||||
/// </summary> | /// </summary> | ||||
@@ -3,7 +3,7 @@ | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<TargetFramework>netstandard2.0</TargetFramework> | <TargetFramework>netstandard2.0</TargetFramework> | ||||
<AssemblyName>Tensorflow.Keras</AssemblyName> | <AssemblyName>Tensorflow.Keras</AssemblyName> | ||||
<LangVersion>9.0</LangVersion> | |||||
<LangVersion>10.0</LangVersion> | |||||
<Nullable>enable</Nullable> | <Nullable>enable</Nullable> | ||||
<RootNamespace>Tensorflow.Keras</RootNamespace> | <RootNamespace>Tensorflow.Keras</RootNamespace> | ||||
<Platforms>AnyCPU;x64</Platforms> | <Platforms>AnyCPU;x64</Platforms> | ||||