@@ -30,5 +30,62 @@ namespace Tensorflow.NumPy | |||||
TypeCode.Single => (T)Convert.ChangeType(input, TypeCode.Single), | TypeCode.Single => (T)Convert.ChangeType(input, TypeCode.Single), | ||||
_ => throw new NotImplementedException("") | _ => throw new NotImplementedException("") | ||||
}; | }; | ||||
public static unsafe Array ToMultiDimArray<T>(NDArray nd) where T : unmanaged | |||||
{ | |||||
var ret = Array.CreateInstance(typeof(T), nd.shape.as_int_list()); | |||||
var addr = ret switch | |||||
{ | |||||
T[] array => Addr(array), | |||||
T[,] array => Addr(array), | |||||
T[,,] array => Addr(array), | |||||
T[,,,] array => Addr(array), | |||||
T[,,,,] array => Addr(array), | |||||
T[,,,,,] array => Addr(array), | |||||
_ => throw new NotImplementedException("") | |||||
}; | |||||
System.Buffer.MemoryCopy(nd.data.ToPointer(), addr, nd.bytesize, nd.bytesize); | |||||
return ret; | |||||
} | |||||
#region multiple array | |||||
static unsafe T* Addr<T>(T[] array) where T : unmanaged | |||||
{ | |||||
fixed (T* a = &array[0]) | |||||
return a; | |||||
} | |||||
static unsafe T* Addr<T>(T[,] array) where T : unmanaged | |||||
{ | |||||
fixed (T* a = &array[0, 0]) | |||||
return a; | |||||
} | |||||
static unsafe T* Addr<T>(T[,,] array) where T : unmanaged | |||||
{ | |||||
fixed (T* a = &array[0, 0, 0]) | |||||
return a; | |||||
} | |||||
static unsafe T* Addr<T>(T[,,,] array) where T : unmanaged | |||||
{ | |||||
fixed (T* a = &array[0, 0, 0, 0]) | |||||
return a; | |||||
} | |||||
static unsafe T* Addr<T>(T[,,,,] array) where T : unmanaged | |||||
{ | |||||
fixed (T* a = &array[0, 0, 0, 0, 0]) | |||||
return a; | |||||
} | |||||
static unsafe T* Addr<T>(T[,,,,,] array) where T : unmanaged | |||||
{ | |||||
fixed (T* a = &array[0, 0, 0, 0, 0, 0]) | |||||
return a; | |||||
} | |||||
#endregion | |||||
} | } | ||||
} | } |
@@ -8,28 +8,28 @@ namespace Tensorflow.NumPy | |||||
{ | { | ||||
public partial class NDArray | public partial class NDArray | ||||
{ | { | ||||
public NDArray(bool value) : base(value) { NewEagerTensorHandle(); } | |||||
public NDArray(byte value) : base(value) { NewEagerTensorHandle(); } | |||||
public NDArray(short value) : base(value) { NewEagerTensorHandle(); } | |||||
public NDArray(int value) : base(value) { NewEagerTensorHandle(); } | |||||
public NDArray(long value) : base(value) { NewEagerTensorHandle(); } | |||||
public NDArray(float value) : base(value) { NewEagerTensorHandle(); } | |||||
public NDArray(double value) : base(value) { NewEagerTensorHandle(); } | |||||
public NDArray(bool value) : base(value) => NewEagerTensorHandle(); | |||||
public NDArray(byte value) : base(value) => NewEagerTensorHandle(); | |||||
public NDArray(short value) : base(value) => NewEagerTensorHandle(); | |||||
public NDArray(int value) : base(value) => NewEagerTensorHandle(); | |||||
public NDArray(long value) : base(value) => NewEagerTensorHandle(); | |||||
public NDArray(float value) : base(value) => NewEagerTensorHandle(); | |||||
public NDArray(double value) : base(value) => NewEagerTensorHandle(); | |||||
public NDArray(Array value, Shape? shape = null) | |||||
: base(value, shape) { NewEagerTensorHandle(); } | |||||
public NDArray(Array value, Shape? shape = null) : base(value, shape) | |||||
=> NewEagerTensorHandle(); | |||||
public NDArray(Shape shape, TF_DataType dtype = TF_DataType.TF_DOUBLE) | |||||
: base(shape, dtype: dtype) { NewEagerTensorHandle(); } | |||||
public NDArray(Shape shape, TF_DataType dtype = TF_DataType.TF_DOUBLE) : base(shape, dtype: dtype) | |||||
=> NewEagerTensorHandle(); | |||||
public NDArray(byte[] bytes, Shape shape, TF_DataType dtype) | |||||
: base(bytes, shape, dtype) { NewEagerTensorHandle(); } | |||||
public NDArray(byte[] bytes, Shape shape, TF_DataType dtype) : base(bytes, shape, dtype) | |||||
=> NewEagerTensorHandle(); | |||||
public NDArray(long[] value, Shape? shape = null) | |||||
: base(value, shape) { NewEagerTensorHandle(); } | |||||
public NDArray(long[] value, Shape? shape = null) : base(value, shape) | |||||
=> NewEagerTensorHandle(); | |||||
public NDArray(IntPtr address, Shape shape, TF_DataType dtype) | |||||
: base(address, shape, dtype) { NewEagerTensorHandle(); } | |||||
public NDArray(IntPtr address, Shape shape, TF_DataType dtype) : base(address, shape, dtype) | |||||
=> NewEagerTensorHandle(); | |||||
public NDArray(Tensor tensor, bool clone = false) : base(tensor.Handle, clone: clone) | public NDArray(Tensor tensor, bool clone = false) : base(tensor.Handle, clone: clone) | ||||
{ | { | ||||
@@ -19,6 +19,7 @@ using System.Collections; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Text; | using System.Text; | ||||
using Tensorflow.Util; | |||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
namespace Tensorflow.NumPy | namespace Tensorflow.NumPy | ||||
@@ -35,7 +36,10 @@ namespace Tensorflow.NumPy | |||||
public NDArray astype(TF_DataType dtype) => new NDArray(math_ops.cast(this, dtype)); | public NDArray astype(TF_DataType dtype) => new NDArray(math_ops.cast(this, dtype)); | ||||
public NDArray ravel() => throw new NotImplementedException(""); | public NDArray ravel() => throw new NotImplementedException(""); | ||||
public void shuffle(NDArray nd) => np.random.shuffle(nd); | public void shuffle(NDArray nd) => np.random.shuffle(nd); | ||||
public Array ToMuliDimArray<T>() => throw new NotImplementedException(""); | |||||
public unsafe Array ToMultiDimArray<T>() where T : unmanaged | |||||
=> NDArrayConverter.ToMultiDimArray<T>(this); | |||||
public byte[] ToByteArray() => BufferToArray(); | public byte[] ToByteArray() => BufferToArray(); | ||||
public override string ToString() => NDArrayRender.ToString(this); | public override string ToString() => NDArrayRender.ToString(this); | ||||
@@ -273,19 +273,19 @@ namespace Tensorflow.Keras.Saving | |||||
switch (data.dtype) | switch (data.dtype) | ||||
{ | { | ||||
case TF_DataType.TF_FLOAT: | case TF_DataType.TF_FLOAT: | ||||
Hdf5.WriteDatasetFromArray<float>(f, name, data.numpy().ToMuliDimArray<float>()); | |||||
Hdf5.WriteDatasetFromArray<float>(f, name, data.numpy().ToMultiDimArray<float>()); | |||||
break; | break; | ||||
case TF_DataType.TF_DOUBLE: | case TF_DataType.TF_DOUBLE: | ||||
Hdf5.WriteDatasetFromArray<double>(f, name, data.numpy().ToMuliDimArray<double>()); | |||||
Hdf5.WriteDatasetFromArray<double>(f, name, data.numpy().ToMultiDimArray<double>()); | |||||
break; | break; | ||||
case TF_DataType.TF_INT32: | case TF_DataType.TF_INT32: | ||||
Hdf5.WriteDatasetFromArray<int>(f, name, data.numpy().ToMuliDimArray<int>()); | |||||
Hdf5.WriteDatasetFromArray<int>(f, name, data.numpy().ToMultiDimArray<int>()); | |||||
break; | break; | ||||
case TF_DataType.TF_INT64: | case TF_DataType.TF_INT64: | ||||
Hdf5.WriteDatasetFromArray<long>(f, name, data.numpy().ToMuliDimArray<long>()); | |||||
Hdf5.WriteDatasetFromArray<long>(f, name, data.numpy().ToMultiDimArray<long>()); | |||||
break; | break; | ||||
default: | default: | ||||
Hdf5.WriteDatasetFromArray<float>(f, name, data.numpy().ToMuliDimArray<float>()); | |||||
Hdf5.WriteDatasetFromArray<float>(f, name, data.numpy().ToMultiDimArray<float>()); | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -50,6 +50,22 @@ namespace TensorFlowNET.UnitTest.NumPy | |||||
AssetSequenceEqual(new[] { 1, 2, 3, 4, 5, 6 }, x.ToArray<int>()); | AssetSequenceEqual(new[] { 1, 2, 3, 4, 5, 6 }, x.ToArray<int>()); | ||||
} | } | ||||
[TestMethod] | |||||
public void to_multi_dim_array() | |||||
{ | |||||
var x1 = np.arange(12); | |||||
var y1 = x1.ToMultiDimArray<int>(); | |||||
AssetSequenceEqual((int[])y1, x1.ToArray<int>()); | |||||
var x2 = np.arange(12).reshape((2, 6)); | |||||
var y2 = (int[,])x2.ToMultiDimArray<int>(); | |||||
Assert.AreEqual(x2[0, 5], y2[0, 5]); | |||||
var x3 = np.arange(12).reshape((2, 2, 3)); | |||||
var y3 = (int[,,])x3.ToMultiDimArray<int>(); | |||||
Assert.AreEqual(x3[0, 1, 2], y3[0, 1, 2]); | |||||
} | |||||
[TestMethod] | [TestMethod] | ||||
public void eye() | public void eye() | ||||
{ | { | ||||