@@ -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.Diagnostics.CodeAnalysis; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Numerics; | using System.Numerics; | ||||
using System.Runtime.CompilerServices; | |||||
using System.Runtime.InteropServices; | |||||
using System.Text; | using System.Text; | ||||
using static Tensorflow.c_api; | using static Tensorflow.c_api; | ||||
@@ -29,21 +27,6 @@ namespace Tensorflow | |||||
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")] | [SuppressMessage("ReSharper", "InvokeAsExtensionMethod")] | ||||
public partial class Tensor | 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 IntPtr TensorDataPointer => _handle == IntPtr.Zero ? IntPtr.Zero : TF_TensorData(_handle); | ||||
public Tensor() | public Tensor() | ||||
@@ -125,11 +108,7 @@ namespace Tensorflow | |||||
/// <param name="num_bytes">Size of the tensor in memory</param> | /// <param name="num_bytes">Size of the tensor in memory</param> | ||||
public Tensor(IntPtr data_ptr, long[] shape, TF_DataType dType, int num_bytes) | 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) | public unsafe Tensor(NDArray nd) | ||||
@@ -93,7 +93,8 @@ namespace Tensorflow | |||||
/// TFE_TensorHandle | /// TFE_TensorHandle | ||||
/// </summary> | /// </summary> | ||||
public SafeTensorHandleHandle EagerTensorHandle { get; set; } | public SafeTensorHandleHandle EagerTensorHandle { get; set; } | ||||
protected bool _createdInGraphMode; | |||||
public bool CreatedInGraphMode => _createdInGraphMode; | |||||
public bool IsEagerTensor => this is EagerTensor; | public bool IsEagerTensor => this is EagerTensor; | ||||
public bool IsSparseTensor => this is SparseTensor; | public bool IsSparseTensor => this is SparseTensor; | ||||
@@ -262,29 +263,6 @@ namespace Tensorflow | |||||
#if TRACK_TENSOR_LIFE | #if TRACK_TENSOR_LIFE | ||||
print($"Delete Tensor 0x{handle.ToString("x16")} {AllocationType} Data: 0x{TensorDataPointer.ToString("x16")}"); | print($"Delete Tensor 0x{handle.ToString("x16")} {AllocationType} Data: 0x{TensorDataPointer.ToString("x16")}"); | ||||
#endif | #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) | if (dtype == TF_DataType.TF_STRING) | ||||
{ | { | ||||
long size = 1; | long size = 1; | ||||