| @@ -25,9 +25,11 @@ https://tensorflownet.readthedocs.io</Description> | |||||
| * Eager Mode is added finally. | * Eager Mode is added finally. | ||||
| * tf.keras is partially working. | * tf.keras is partially working. | ||||
| * tf.data is added. | * tf.data is added. | ||||
| * autograph works partially. | |||||
| * Autograph works partially. | |||||
| * Improve memory usage. | |||||
| TensorFlow .NET v0.3x is focused on making more Keras API works</PackageReleaseNotes> | |||||
| TensorFlow .NET v0.3x is focused on making more Keras API works. | |||||
| Keras API is a separate package released as TensorFlow.Keras.</PackageReleaseNotes> | |||||
| <FileVersion>0.33.0.0</FileVersion> | <FileVersion>0.33.0.0</FileVersion> | ||||
| <PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
| <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | ||||
| @@ -83,7 +85,7 @@ TensorFlow .NET v0.3x is focused on making more Keras API works</PackageReleaseN | |||||
| <PackageReference Include="MethodBoundaryAspect.Fody" Version="2.0.138" /> | <PackageReference Include="MethodBoundaryAspect.Fody" Version="2.0.138" /> | ||||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" /> | <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" /> | ||||
| <PackageReference Include="NumSharp.Lite" Version="0.1.12" /> | <PackageReference Include="NumSharp.Lite" Version="0.1.12" /> | ||||
| <PackageReference Include="Protobuf.Text" Version="0.4.0" /> | |||||
| <PackageReference Include="Protobuf.Text" Version="0.5.0" /> | |||||
| <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> | <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | </Project> | ||||
| @@ -0,0 +1,14 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| namespace Tensorflow | |||||
| { | |||||
| public enum TF_TString_Type | |||||
| { | |||||
| TF_TSTR_SMALL = 0, | |||||
| TF_TSTR_LARGE = 1, | |||||
| TF_TSTR_OFFSET = 2, | |||||
| TF_TSTR_VIEW = 3 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| using Tensorflow.Util; | |||||
| namespace Tensorflow | |||||
| { | |||||
| public class TStringHandle : SafeTensorflowHandle | |||||
| { | |||||
| protected override bool ReleaseHandle() | |||||
| { | |||||
| c_api.TF_StringDealloc(handle); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -8,7 +8,29 @@ namespace Tensorflow | |||||
| { | { | ||||
| public partial class Tensor | public partial class Tensor | ||||
| { | { | ||||
| public unsafe IntPtr StringTensor(string[] strings, TensorShape shape) | |||||
| const ulong TF_TSRING_SIZE = 24; | |||||
| public IntPtr StringTensor25(string[] strings, TensorShape shape) | |||||
| { | |||||
| var handle = c_api.TF_AllocateTensor(TF_DataType.TF_STRING, | |||||
| shape.dims.Select(x => (long)x).ToArray(), | |||||
| shape.ndim, | |||||
| (ulong)shape.size * TF_TSRING_SIZE); | |||||
| var data = c_api.TF_TensorData(handle); | |||||
| var tstr = c_api.TF_StringInit(handle); | |||||
| // AllocationHandle = tstr; | |||||
| // AllocationType = AllocationType.Tensorflow; | |||||
| for (int i = 0; i< strings.Length; i++) | |||||
| { | |||||
| c_api.TF_StringCopy(tstr, strings[i], strings[i].Length); | |||||
| tstr += (int)TF_TSRING_SIZE; | |||||
| } | |||||
| // c_api.TF_StringDealloc(tstr); | |||||
| return handle; | |||||
| } | |||||
| public IntPtr StringTensor(string[] strings, TensorShape shape) | |||||
| { | { | ||||
| // convert string array to byte[][] | // convert string array to byte[][] | ||||
| var buffer = new byte[strings.Length][]; | var buffer = new byte[strings.Length][]; | ||||
| @@ -61,11 +83,27 @@ namespace Tensorflow | |||||
| return handle; | return handle; | ||||
| } | } | ||||
| public string[] StringData25() | |||||
| { | |||||
| string[] strings = new string[c_api.TF_Dim(_handle, 0)]; | |||||
| var tstrings = TensorDataPointer; | |||||
| for (int i = 0; i< strings.Length; i++) | |||||
| { | |||||
| var tstringData = c_api.TF_StringGetDataPointer(tstrings); | |||||
| /*var size = c_api.TF_StringGetSize(tstrings); | |||||
| var capacity = c_api.TF_StringGetCapacity(tstrings); | |||||
| var type = c_api.TF_StringGetType(tstrings);*/ | |||||
| strings[i] = c_api.StringPiece(tstringData); | |||||
| tstrings += (int)TF_TSRING_SIZE; | |||||
| } | |||||
| return strings; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Extracts string array from current Tensor. | /// Extracts string array from current Tensor. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="InvalidOperationException">When <see cref="dtype"/> != TF_DataType.TF_STRING</exception> | /// <exception cref="InvalidOperationException">When <see cref="dtype"/> != TF_DataType.TF_STRING</exception> | ||||
| public unsafe string[] StringData() | |||||
| public string[] StringData() | |||||
| { | { | ||||
| var buffer = StringBytes(); | var buffer = StringBytes(); | ||||
| @@ -181,6 +181,30 @@ namespace Tensorflow | |||||
| [DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
| public static extern unsafe ulong TF_StringEncode(byte* src, ulong src_len, byte* dst, ulong dst_len, SafeStatusHandle status); | public static extern unsafe ulong TF_StringEncode(byte* src, ulong src_len, byte* dst, ulong dst_len, SafeStatusHandle status); | ||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern IntPtr TF_StringInit(IntPtr t); | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern void TF_StringCopy(IntPtr dst, string text, long size); | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern void TF_StringAssignView(IntPtr dst, IntPtr text, long size); | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern IntPtr TF_StringGetDataPointer(IntPtr tst); | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern TF_TString_Type TF_StringGetType(IntPtr tst); | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern ulong TF_StringGetSize(IntPtr tst); | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern ulong TF_StringGetCapacity(IntPtr tst); | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern void TF_StringDealloc(IntPtr tst); | |||||
| /// <summary> | /// <summary> | ||||
| /// Decode a string encoded using TF_StringEncode. | /// Decode a string encoded using TF_StringEncode. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -107,6 +107,32 @@ namespace Tensorflow.Native.UnitTest.Tensors | |||||
| Assert.IsTrue(Enumerable.SequenceEqual(nd.Data<float>(), new float[] { 1, 2, 3, 4, 5, 6 })); | Assert.IsTrue(Enumerable.SequenceEqual(nd.Data<float>(), new float[] { 1, 2, 3, 4, 5, 6 })); | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Port from c_api_test.cc | |||||
| /// `TEST_F(CApiAttributesTest, StringTensor)` | |||||
| /// </summary> | |||||
| [TestMethod, Ignore("Waiting for PR https://github.com/tensorflow/tensorflow/pull/46804")] | |||||
| public void StringTensor() | |||||
| { | |||||
| string text = "Hello world!."; | |||||
| var tensor = c_api.TF_AllocateTensor(TF_DataType.TF_STRING, | |||||
| null, | |||||
| 0, | |||||
| 1 * 24); | |||||
| var tstr = c_api.TF_StringInit(tensor); | |||||
| var data = c_api.TF_StringGetDataPointer(tstr); | |||||
| c_api.TF_StringCopy(tstr, text, text.Length); | |||||
| Assert.AreEqual((ulong)text.Length, c_api.TF_StringGetSize(tstr)); | |||||
| Assert.AreEqual(text, c_api.StringPiece(data)); | |||||
| Assert.AreEqual((ulong)text.Length, c_api.TF_TensorByteSize(tensor)); | |||||
| Assert.AreEqual(0, c_api.TF_NumDims(tensor)); | |||||
| TF_DeleteTensor(tensor); | |||||
| c_api.TF_StringDealloc(tstr); | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Port from tensorflow\c\c_api_test.cc | /// Port from tensorflow\c\c_api_test.cc | ||||
| /// `TEST(CAPI, SetShape)` | /// `TEST(CAPI, SetShape)` | ||||