Browse Source

fix placeholder feeds value issue.

tags/v0.60-tf.numpy
Oceania2018 4 years ago
parent
commit
2192f4d875
12 changed files with 132 additions and 507 deletions
  1. +1
    -0
      src/TensorFlowNET.Console/MemoryMonitor.cs
  2. +35
    -0
      src/TensorFlowNET.Core/Binding.Util.cs
  3. +2
    -1
      src/TensorFlowNET.Core/Numpy/NDArray.cs
  4. +1
    -1
      src/TensorFlowNET.Core/Operations/image_ops_impl.cs
  5. +24
    -3
      src/TensorFlowNET.Core/Sessions/BaseSession.cs
  6. +33
    -473
      src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs
  7. +1
    -1
      src/TensorFlowNET.Core/Tensors/TensorConverter.cs
  8. +9
    -0
      src/TensorFlowNET.Core/Tensors/c_api.tensor.cs
  9. +1
    -7
      src/TensorFlowNET.Core/Tensors/constant_op.cs
  10. +3
    -0
      src/TensorFlowNET.Core/Tensors/dtypes.cs
  11. +21
    -20
      src/TensorFlowNET.Core/Tensors/tensor_util.cs
  12. +1
    -1
      test/TensorFlowNET.Native.UnitTest/Gradients/GradientsTest.cs

+ 1
- 0
src/TensorFlowNET.Console/MemoryMonitor.cs View File

@@ -15,6 +15,7 @@ namespace Tensorflow
while (true)
{
var ones = np.ones((128, 128));
Thread.Sleep(1);
}

TensorShape shape = (1, 32, 32, 3);


+ 35
- 0
src/TensorFlowNET.Core/Binding.Util.cs View File

@@ -505,5 +505,40 @@ namespace Tensorflow

return defaultValue;
}

public static Shape GetShape(this object data)
{
if (!data.GetType().IsArray)
return Shape.Scalar;

switch (data)
{
case Array array:
var dims = range(array.Rank).Select(x => (long)array.GetLength(x)).ToArray();
return new Shape(dims);
default:
throw new NotImplementedException("");
}
}

public static unsafe byte[] ToByteArray(Array array)
{
/*var size = array.GetShape().size;
byte[]? bytes = null;
switch (array)
{
case float[] arr:
var len = new byte[size * sizeof(float)];
fixed (void* addr = &arr[0])
System.Buffer.MemoryCopy(addr, dst, bytesize, bytesize);
tensor_proto.TensorContent = Google.Protobuf.ByteString.CopyFrom(array.ToArray());
break;
default:
throw new NotImplementedException("");
}

return bytes;*/
throw new NotImplementedException("");
}
}
}

+ 2
- 1
src/TensorFlowNET.Core/Numpy/NDArray.cs View File

@@ -14,7 +14,8 @@ namespace Tensorflow.NumPy
public ulong dtypesize => _tensor.itemsize;
public int ndim => _tensor.NDims;
public long[] dims => _tensor.dims.Select(x => Convert.ToInt64(x)).ToArray();
public Shape shape => _tensor.shape;
public Shape shape => _tensor.shape;
public IntPtr data => _tensor.TensorDataPointer;

public NDArray(bool value)
{


+ 1
- 1
src/TensorFlowNET.Core/Operations/image_ops_impl.cs View File

@@ -923,7 +923,7 @@ new_height, new_width");
int p_height = (int)max_(0, math_ops.cast(f_padding_height, dtype: dtypes.int32));
int p_width = (int)max_(0, math_ops.cast(f_padding_width, dtype: dtypes.int32));

var resized = resize_fn(image, new Tensor(new[] { resized_height, resized_width }));
var resized = resize_fn(image, array_ops.concat(new[] { resized_height, resized_width }, 0));

var padded = pad_to_bounding_box(resized, p_height, p_width, target_height,
target_width);


+ 24
- 3
src/TensorFlowNET.Core/Sessions/BaseSession.cs View File

@@ -176,14 +176,35 @@ namespace Tensorflow
var tensor = new Tensor(v);
if (tensor.dtype != key.dtype)
throw new ValueError($"Tensor {v} does not match the expected dtype {key.dtype}, actual dtype: {tensor.dtype}");

feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), tensor);
break;
default:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), constant_op.constant(x.Value));
case bool v:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), new Tensor(v));
break;
case byte v:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), new Tensor(v));
break;
case int v:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), new Tensor(v));
break;
case long v:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), new Tensor(v));
break;
case float v:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), new Tensor(v));
break;
case double v:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), new Tensor(v));
break;
case Array v:
feeds[i++] = new KeyValuePair<TF_Output, Tensor>(key._as_tf_output(), new Tensor(v, v.GetShape()));
break;
default:
throw new NotImplementedException("");
}
}
else
throw new NotImplementedException("");
}

var fetches = fetch_list.Select(x => x._as_tf_output()).ToArray();


+ 33
- 473
src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs View File

@@ -22,7 +22,6 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using static Tensorflow.Binding;
using static Tensorflow.c_api;

namespace Tensorflow
@@ -65,11 +64,12 @@ namespace Tensorflow
#endif
}

internal Tensor(Array array, Shape shape)
internal Tensor(Array array, Shape? shape = null)
=> InitTensor(array, shape);

unsafe void InitTensor(Array array, Shape shape)
unsafe void InitTensor(Array array, Shape? shape = null)
{
shape = shape ?? array.GetShape();
var dtype = array.GetType().GetElementType().as_tf_dtype();
var length = (ulong)(array.Length * dtype.get_datatype_size());

@@ -112,14 +112,6 @@ namespace Tensorflow
}
}

public Tensor(int value)
{
unsafe
{
_handle = TF_NewTensor(tf.int32, dims: null, num_dims: 0, data: &value, len: sizeof(int));
}
}

/// <summary>
/// Create a new Tensor from the given unmanaged memory pointer (which must be allocated, fixed or pinned by the caller)
/// Note: the caller is responsible for freeing the memory. Calling Dispose on this object will dispose the TensorFlow tensor
@@ -138,329 +130,36 @@ namespace Tensorflow
}
}

/// <summary>
/// Create a new Tensor from the given unmanaged memory pointer (which must be allocated, fixed or pinned by the caller)
/// Note: the caller is responsible for freeing the memory. Calling Dispose on this object will dispose the TensorFlow tensor
/// but not the memory itself!
/// </summary>
/// <param name="data_ptr">Pointer to unmanaged, fixed or pinned memory which the caller owns</param>
/// <param name="shape">Tensor shape</param>
/// <param name="dType">TF data type</param>
/// <param name="num_bytes">Size of the tensor in memory</param>
public unsafe Tensor(void* data_ptr, long[] shape, TF_DataType dType, int num_bytes)
{
_handle = TF_NewTensor(dType, dims: shape, num_dims: shape.Length, data: data_ptr, len: (ulong)num_bytes);
AllocationType = TF_TensorData(_handle).ToPointer() == data_ptr ? AllocationType.FromPointer : AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(sbyte[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(sbyte)), new long[] { data.Length }, data, sizeof(sbyte));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(sbyte[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(sbyte)), shape, data, sizeof(sbyte));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(sbyte value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(sbyte)), dims: new long[0], num_dims: 0, len: sizeof(sbyte));
*(sbyte*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(bool[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(bool)), new long[] { data.Length }, data, sizeof(bool));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(bool[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(bool)), shape, data, sizeof(bool));
}

internal Tensor(float[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(bool)), shape, data, sizeof(bool));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(bool value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(bool)), dims: new long[0], num_dims: 0, len: sizeof(bool));
*(bool*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(byte[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(byte)), new long[] { data.Length }, data, sizeof(byte));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(byte[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(byte)), shape, data, sizeof(byte));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(byte value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(byte)), dims: new long[0], num_dims: 0, len: sizeof(byte));
*(byte*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(short[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(short)), new long[] { data.Length }, data, sizeof(short));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(short[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(short)), shape, data, sizeof(short));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(short value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(short)), dims: new long[0], num_dims: 0, len: sizeof(short));
*(short*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(ushort[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(ushort)), new long[] { data.Length }, data, sizeof(ushort));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(ushort[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(ushort)), shape, data, sizeof(ushort));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(ushort value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(ushort)), dims: new long[0], num_dims: 0, len: sizeof(ushort));
*(ushort*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(int[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(int)), new long[] { data.Length }, data, sizeof(int));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(int[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(int)), shape, data, sizeof(int));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(int value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(int)), dims: new long[0], num_dims: 0, len: sizeof(int));
*(int*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(uint[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(uint)), new long[] { data.Length }, data, sizeof(uint));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(uint[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(uint)), shape, data, sizeof(uint));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(uint value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(uint)), dims: new long[0], num_dims: 0, len: sizeof(uint));
*(uint*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(long[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(long)), new long[] { data.Length }, data, sizeof(long));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(long[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(long)), shape, data, sizeof(long));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(long value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(long)), dims: new long[0], num_dims: 0, len: sizeof(long));
*(long*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(ulong[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(ulong)), new long[] { data.Length }, data, sizeof(ulong));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(ulong[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(ulong)), shape, data, sizeof(ulong));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(ulong value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(ulong)), dims: new long[0], num_dims: 0, len: sizeof(ulong));
*(ulong*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(float[] data)
{
_handle = CreateTensorFromArray(TF_DataType.TF_FLOAT, new long[] { data.Length }, data, sizeof(float));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(float value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(float)), dims: new long[0], num_dims: 0, len: sizeof(float));
*(float*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(double[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(double)), new long[] { data.Length }, data, sizeof(double));
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(double[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(double)), shape, data, sizeof(double));
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(double value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(double)), dims: new long[0], num_dims: 0, len: sizeof(double));
*(double*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}

/// <summary>
/// Create a 1d Tensor from the given linear array and shape
/// </summary>
public Tensor(Complex[] data, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(Complex)), new long[] { data.Length }, data, Marshal.SizeOf<Complex>());
}

/// <summary>
/// Create a N-dimensional Tensor from the given array
/// </summary>
public Tensor(Complex[] data, long[] shape, TF_DataType? dType = null)
{
_handle = CreateTensorFromArray(dType ?? dtypes.as_tf_dtype(typeof(Complex)), shape, data, Marshal.SizeOf<Complex>());
}

/// <summary>
/// Create a scalar Tensor from the given value
/// </summary>
public unsafe Tensor(Complex value, TF_DataType? dType = null)
{
_handle = TF_AllocateTensor(dType ?? dtypes.as_tf_dtype(typeof(Complex)), dims: new long[0], num_dims: 0, len: (ulong)sizeof(Complex));
*(Complex*)TF_TensorData(_handle) = value;
AllocationType = AllocationType.Tensorflow;
}
public unsafe Tensor(NDArray nd)
=> _handle = TF_NewTensor(nd.shape, nd.dtype.as_tf_dtype(), nd.data.ToPointer(), nd.size * nd.dtypesize);

#region scala
public Tensor(bool value) => _handle = TF_NewTensor(value);
public Tensor(byte value) => _handle = TF_NewTensor(value);
public Tensor(sbyte value) => _handle = TF_NewTensor(value);
public Tensor(short value) => _handle = TF_NewTensor(value);
public Tensor(int value) => _handle = TF_NewTensor(value);
public Tensor(uint value) => _handle = TF_NewTensor(value);
public Tensor(long value) => _handle = TF_NewTensor(value);
public Tensor(ulong value) => _handle = TF_NewTensor(value);
public Tensor(float value) => _handle = TF_NewTensor(value);
public Tensor(double value) => _handle = TF_NewTensor(value);
#endregion

#region 1d array
public Tensor(bool[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(sbyte[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(byte[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(short[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(ushort[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(int[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(uint[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(long[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(ulong[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(float[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(double[] data, Shape? shape = null) => InitTensor(data, shape);
public Tensor(Complex[] data, Shape? shape = null) => InitTensor(data, shape);
#endregion

/// <summary>
/// Create a string Tensor from the given string
@@ -481,77 +180,6 @@ namespace Tensorflow
#endif
}

public unsafe Tensor(NDArray nd, TF_DataType? tensorDType = null)
{
if (tensorDType == null)
tensorDType = nd.dtype.as_tf_dtype();

// todo: handle nd of type "String" here too
/*if (tensorDType == TF_DataType.TF_STRING && nd.typecode == NPTypeCode.Byte)
{
if (nd.Unsafe.Storage.Shape.IsContiguous)
{
var bytesLength = (ulong)nd.size;
var size = bytesLength + 1;
var handle = TF_AllocateTensor(TF_DataType.TF_STRING, null, 0, size + 8);
AllocationType = AllocationType.Tensorflow;

IntPtr tensor = c_api.TF_TensorData(handle);
Marshal.WriteInt64(tensor, 0);

c_api.TF_StringEncode((byte*)nd.Unsafe.Address, bytesLength, (byte*)(tensor + sizeof(long)), size, tf.Status.Handle);
tf.Status.Check(true);
_handle = handle;
}
else
{
var buffer = nd.ToArray<byte>();
var size = (ulong)buffer.Length + 1;
var handle = TF_AllocateTensor(TF_DataType.TF_STRING, null, 0, size + 8);
AllocationType = AllocationType.Tensorflow;

IntPtr tensor = c_api.TF_TensorData(handle);
Marshal.WriteInt64(tensor, 0);

fixed (byte* src = buffer)
c_api.TF_StringEncode(src, (ulong)buffer.Length, (byte*)(tensor + sizeof(Int64)), size, tf.Status.Handle);

tf.Status.Check(true);
_handle = handle;
}

return;
}*/

CreateTensorFromNDArray(nd, tensorDType);
#if TRACK_TENSOR_LIFE
print($"New Tensor 0x{_handle.ToString("x16")} {AllocationType} Data: 0x{TensorDataPointer.ToString("x16")}");
#endif
}

private unsafe void CreateTensorFromNDArray(NDArray nd, TF_DataType? given_dtype)
{
if (nd.dtype == NumpyDType.String)
throw new NotImplementedException("Support for NDArray of type string not implemented yet");

throw new NotImplementedException("");
/*_handle = TF_NewTensor(
given_dtype ?? nd.dtype.as_tf_dtype(),
dims: nd.dims.Select(i => (long)i).ToArray(),
num_dims: nd.ndim,
data: nd.Address,
len: nd.size * nd.dtypesize);

// if TF decided not to perform copy, hold reference for given NDArray.
if (TensorDataPointer == nd.Address)
{
AllocationType = AllocationType.FromPointer;
AllocationHandle = nd;
}
else
AllocationType = AllocationType.Tensorflow;*/
}

public Tensor(Operation op, int value_index, TF_DataType dtype)
{
_op = op;
@@ -559,73 +187,5 @@ namespace Tensorflow
_override_dtype = dtype;
_id = ops.uid();
}


/// <summary>
/// Creates a new tensor from the given array without copying memory. The array is pinned down and the pointer passed on.
/// </summary>
/// <param name="shape">Represents the tensor shape.</param>
/// <param name="data">The linear array of data, the data must fit in the tensor with the specified dimensions.</param>
/// <param name="element_size">The number of bytes in memory of a single array element</param>
/// <remarks>
/// Use the FromBuffer method to create a tensor that has the specified dimensions
/// and is initialized with data from the data array. The data is copied starting
/// at the start offset, for count bytes and is laid out into the tensor following the
/// specified dimensions.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[SuppressMessage("ReSharper", "LocalVariableHidesMember")]
protected IntPtr CreateTensorFromArray(TF_DataType dt, long[] shape, Array data, int element_size)
{
if (dt == TF_DataType.TF_STRING && data is byte[] buffer)
return StringTensor(new byte[][] { buffer }, TensorShape.Scalar);
return CreateTensorFromArray(dt, shape, data, 0, data.Length, element_size);
}

/// <summary>
/// Creates a new tensor from a subsection of the given array without copying memory. The array is pinned down and the pointer passed on.
/// </summary>
/// <param name="shape">Represents the tensor shape.</param>
/// <param name="data">The linear array of data, the data must fit in the tensor with the specified dimensions.</param>
/// <param name="start">The offset into the provided data array where the data resides.</param>
/// <param name="count">The number of elements to copy from data.</param>
/// <param name="element_size">The number of bytes in memory of a single array element</param>
/// <remarks>
/// Use the FromBuffer method to create a tensor that has the specified dimensions
/// and is initialized with data from the data array. The data is copied starting
/// at the start offset, for count bytes and is laid out into the tensor following the
/// specified dimensions.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected IntPtr CreateTensorFromArray(TF_DataType dt, long[] shape, Array data, int start, int count, int element_size)
{
if (start < 0 || start > data.Length - count)
throw new ArgumentException($"Array length {data.Length} does not match the given shape {new Shape(shape.ToArray())}");

// get a handle to the pinned array which we will pass on to the tensor computation engine to use
var gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
var pinnedAddr = gcHandle.AddrOfPinnedObject();

//call NewTensor
IntPtr handle;
if (shape == null || shape.Length == 0)
handle = TF_NewTensor(dt, new long[0], 0, pinnedAddr + start * element_size, (ulong)(count * element_size));
else
handle = TF_NewTensor(dt, shape, shape.Length, pinnedAddr + start * element_size, (ulong)(count * element_size));

//Figure if TF decided to clone or not.
if (c_api.TF_TensorData(handle) == pinnedAddr)
{
AllocationType = AllocationType.GCHandle;
AllocationHandle = gcHandle;
}
else
{
AllocationType = AllocationType.Tensorflow;
gcHandle.Free();
}

return handle;
}
}
}

+ 1
- 1
src/TensorFlowNET.Core/Tensors/TensorConverter.cs View File

@@ -64,7 +64,7 @@ namespace Tensorflow

//is multidim or jagged, if so - use NDArrays constructor as it records shape.
if (array.Rank != 1 || array.GetType().GetElementType().IsArray)
return new Tensor(new NDArray(array));
return new Tensor(array, array.GetShape());

switch (arrtype.GetTypeCode())
{


+ 9
- 0
src/TensorFlowNET.Core/Tensors/c_api.tensor.cs View File

@@ -112,6 +112,15 @@ namespace Tensorflow
return handle;
}

public static unsafe IntPtr TF_NewTensor<T>(T value)
where T : unmanaged
{
var dtype = value.GetType().as_tf_dtype();
var handle = TF_AllocateTensor(dtype, new long[0], 0, (ulong)dtype.get_datatype_size());
*(T*)TF_TensorData(handle) = value;
return handle;
}

/// <summary>
/// Return a new tensor that holds the bytes data[0,len-1]
/// </summary>


+ 1
- 7
src/TensorFlowNET.Core/Tensors/constant_op.cs View File

@@ -182,18 +182,12 @@ namespace Tensorflow
case double val:
return new EagerTensor(new[] { val }, Shape.Scalar);
case Array val:
return new EagerTensor(val, GetArrayDims(val));
return new EagerTensor(val, val.GetShape());
default:
throw new NotImplementedException($"convert_to_eager_tensor {value.GetType()}");
}
}

static Shape GetArrayDims(Array array)
{
var dims = range(array.Rank).Select(x => (long)array.GetLength(x)).ToArray();
return new Shape(dims);
}

/// <summary>
/// Function to convert TensorShape to Tensor.
/// </summary>


+ 3
- 0
src/TensorFlowNET.Core/Tensors/dtypes.cs View File

@@ -128,6 +128,9 @@ namespace Tensorflow
/// <exception cref="ArgumentException">When <paramref name="type"/> has no equivalent <see cref="TF_DataType"/></exception>
public static TF_DataType as_tf_dtype(this Type type, TF_DataType? dtype = null)
{
while (type.IsArray)
type = type.GetElementType();

switch (type.Name)
{
case "Char":


+ 21
- 20
src/TensorFlowNET.Core/Tensors/tensor_util.cs View File

@@ -27,13 +27,6 @@ namespace Tensorflow
{
public static class tensor_util
{
public static TF_DataType[] _TENSOR_CONTENT_TYPES =
{
TF_DataType.TF_FLOAT, TF_DataType.TF_DOUBLE, TF_DataType.TF_INT32, TF_DataType.TF_UINT8, TF_DataType.TF_INT16,
TF_DataType.TF_INT8, TF_DataType.TF_INT64, TF_DataType.TF_QINT8, TF_DataType.TF_QUINT8, TF_DataType.TF_QINT16,
TF_DataType.TF_QUINT16, TF_DataType.TF_QINT32, TF_DataType.TF_UINT32, TF_DataType.TF_UINT64
};

/// <summary>
/// Returns the constant value of the given tensor, if efficiently calculable.
/// </summary>
@@ -119,13 +112,12 @@ namespace Tensorflow
var tensor_proto = new TensorProto
{
Dtype = dtype.as_datatype_enum(),
TensorShape = values.GetShape().as_shape_proto()
};

// scalar
if (!values.GetType().IsArray)
{
tensor_proto.TensorShape = tensor_util.as_shape(new int[0]);

switch (values)
{
case bool val:
@@ -157,7 +149,6 @@ namespace Tensorflow
if (values is string str)
{
tensor_proto.StringVal.Add(Google.Protobuf.ByteString.CopyFromUtf8(str));
tensor_proto.TensorShape = tensor_util.as_shape(new int[0]);
}
else if (values is string[] str_values)
tensor_proto.StringVal.AddRange(str_values.Select(x => Google.Protobuf.ByteString.CopyFromUtf8(x)));
@@ -166,18 +157,12 @@ namespace Tensorflow

return tensor_proto;
}
else
else if(values is Array array)
{
tensor_proto.TensorShape = tensor_util.as_shape(shape);

// array
if (_TENSOR_CONTENT_TYPES.Contains(dtype))
{
throw new NotImplementedException("");
/*byte[] bytes = nparray.ToByteArray();
tensor_proto.TensorContent = Google.Protobuf.ByteString.CopyFrom(bytes.ToArray());
return tensor_proto;*/
}
/*byte[] bytes = array.ToByteArray();
tensor_proto.TensorContent = Google.Protobuf.ByteString.CopyFrom(bytes.ToArray());
return tensor_proto;*/
}

return tensor_proto;
@@ -417,6 +402,22 @@ would not be rank 1.", tensor.op.get_attr("axis")));
return new TensorShape(shape.dims);
}

public static TensorShapeProto as_shape_proto(this Shape tshape)
{
TensorShapeProto shape = new TensorShapeProto();

for (int i = 0; i < tshape.ndim; i++)
{
var dim = new TensorShapeProto.Types.Dim();
dim.Size = tshape.dims[i];
//dim.Name = $"dim_{i}";

shape.Dim.Add(dim);
}

return shape;
}

public static TensorShape reshape(this Shape shape, int[] dims)
{
return new TensorShape(dims);


+ 1
- 1
test/TensorFlowNET.Native.UnitTest/Gradients/GradientsTest.cs View File

@@ -226,7 +226,7 @@ namespace Tensorflow.Native.UnitTest
//long[] dims = { 2, 2 };
//Tensor t = c_api.TF_AllocateTensor(TF_FLOAT, dims, 2, sizeof(float) * 4);
//Marshal.Copy(values, 0, t, 4);
Tensor t = new Tensor(new NDArray(values).reshape((2, 2)));
Tensor t = np.array(values).reshape((2, 2));
return t;
}



Loading…
Cancel
Save