@@ -1,27 +0,0 @@ | |||
namespace Tensorflow | |||
{ | |||
/// <summary> | |||
/// Used internally to | |||
/// </summary> | |||
public enum AllocationType | |||
{ | |||
None = 0, | |||
/// <summary> | |||
/// Allocation was done by passing in a pointer, might be also holding reference to a C# object. | |||
/// </summary> | |||
FromPointer = 1, | |||
/// <summary> | |||
/// Allocation was done by calling c_api.TF_AllocateTensor or TF decided it has to copy data during c_api.TF_NewTensor. <br></br> | |||
/// Deallocation is handled solely by Tensorflow. | |||
/// </summary> | |||
Tensorflow = 2, | |||
/// <summary> | |||
/// Allocation was done by Marshal.AllocateHGlobal | |||
/// </summary> | |||
Marshal = 3, | |||
/// <summary> | |||
/// Allocation was done by GCHandle.Alloc | |||
/// </summary> | |||
GCHandle = 4, | |||
} | |||
} |
@@ -19,8 +19,6 @@ using System; | |||
using System.Diagnostics.CodeAnalysis; | |||
using System.Linq; | |||
using System.Numerics; | |||
using System.Runtime.CompilerServices; | |||
using System.Runtime.InteropServices; | |||
using System.Text; | |||
using static Tensorflow.c_api; | |||
@@ -29,21 +27,6 @@ namespace Tensorflow | |||
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")] | |||
public partial class Tensor | |||
{ | |||
/// <summary> | |||
/// The handle that was used to allocate this tensor, dependent on <see cref="AllocationType"/>. | |||
/// </summary> | |||
protected object AllocationHandle; | |||
/// <summary> | |||
/// True if this Tensor holds data allocated by C#. | |||
/// </summary> | |||
public bool IsMemoryOwner => AllocationType >= AllocationType.Marshal; | |||
/// <summary> | |||
/// The allocation method used to create this Tensor. | |||
/// </summary> | |||
public AllocationType AllocationType { get; protected set; } | |||
public IntPtr TensorDataPointer => _handle == IntPtr.Zero ? IntPtr.Zero : TF_TensorData(_handle); | |||
public Tensor() | |||
@@ -125,11 +108,7 @@ namespace Tensorflow | |||
/// <param name="num_bytes">Size of the tensor in memory</param> | |||
public Tensor(IntPtr data_ptr, long[] shape, TF_DataType dType, int num_bytes) | |||
{ | |||
unsafe | |||
{ | |||
_handle = TF_NewTensor(dType, dims: shape, num_dims: shape.Length, data: data_ptr, len: (ulong)num_bytes); | |||
AllocationType = TF_TensorData(_handle) == data_ptr ? AllocationType.FromPointer : AllocationType.Tensorflow; | |||
} | |||
_handle = TF_NewTensor(dType, dims: shape, num_dims: shape.Length, data: data_ptr, len: (ulong)num_bytes); | |||
} | |||
public unsafe Tensor(NDArray nd) | |||
@@ -93,7 +93,8 @@ namespace Tensorflow | |||
/// TFE_TensorHandle | |||
/// </summary> | |||
public SafeTensorHandleHandle EagerTensorHandle { get; set; } | |||
protected bool _createdInGraphMode; | |||
public bool CreatedInGraphMode => _createdInGraphMode; | |||
public bool IsEagerTensor => this is EagerTensor; | |||
public bool IsSparseTensor => this is SparseTensor; | |||
@@ -262,29 +263,6 @@ namespace Tensorflow | |||
#if TRACK_TENSOR_LIFE | |||
print($"Delete Tensor 0x{handle.ToString("x16")} {AllocationType} Data: 0x{TensorDataPointer.ToString("x16")}"); | |||
#endif | |||
if (AllocationHandle != null) | |||
{ | |||
if (AllocationType == AllocationType.GCHandle) | |||
{ | |||
((GCHandle)AllocationHandle).Free(); | |||
AllocationHandle = null; | |||
AllocationType = AllocationType.None; | |||
} | |||
else if (AllocationType == AllocationType.Marshal) | |||
{ | |||
Marshal.FreeHGlobal((IntPtr)AllocationHandle); | |||
AllocationHandle = null; | |||
AllocationType = AllocationType.None; | |||
} | |||
else if (AllocationType == AllocationType.FromPointer) | |||
{ | |||
AllocationHandle = null; | |||
AllocationType = AllocationType.None; | |||
} | |||
else | |||
throw new InvalidOperationException($"Tensor.AllocationHandle is not null ({AllocationHandle}) but AllocationType is not matched to a C# allocation type ({AllocationType})."); | |||
} | |||
if (dtype == TF_DataType.TF_STRING) | |||
{ | |||
long size = 1; | |||