From 1291aa5dacebae686a0f28552b38398f4c848bfa Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Wed, 12 Dec 2018 20:13:21 -0600 Subject: [PATCH] add ops._create_c_op --- TensorFlow.NET.sln | 12 ++--- src/TensorFlowNET.Core/Graph.cs | 17 +++++-- .../MonoPInvokeCallbackAttribute.cs | 16 +++++++ src/TensorFlowNET.Core/Operation.cs | 5 ++- src/TensorFlowNET.Core/TF_DataType.cs | 38 ++++++++++++++++ src/TensorFlowNET.Core/Tensor.cs | 10 +++++ src/TensorFlowNET.Core/Tensorflow.cs | 31 +++++++------ src/TensorFlowNET.Core/c_api.cs | 45 +++++++++++++++++++ src/TensorFlowNET.Core/ops.cs | 41 +++++++++++++++++ test/TensorFlowNET.Examples/HelloWorld.cs | 3 +- test/TensorFlowNET.Examples/Program.cs | 9 +++- .../TensorFlowNET.Examples.csproj | 1 - .../TensorFlowNET.UnitTest.csproj | 1 - 13 files changed, 199 insertions(+), 30 deletions(-) create mode 100644 src/TensorFlowNET.Core/MonoPInvokeCallbackAttribute.cs create mode 100644 src/TensorFlowNET.Core/TF_DataType.cs create mode 100644 src/TensorFlowNET.Core/Tensor.cs create mode 100644 src/TensorFlowNET.Core/c_api.cs create mode 100644 src/TensorFlowNET.Core/ops.cs diff --git a/TensorFlow.NET.sln b/TensorFlow.NET.sln index 9b9875c1..09cbb256 100644 --- a/TensorFlow.NET.sln +++ b/TensorFlow.NET.sln @@ -7,9 +7,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.UnitTest", "t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{1B1BC950-2CB0-48E2-B4CD-8172AFF67A10}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NumSharp.Core", "..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj", "{D314AE83-D586-4589-B653-1937F1138A5A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Examples", "test\TensorFlowNET.Examples\TensorFlowNET.Examples.csproj", "{1FE60088-157C-4140-91AB-E96B915E4BAE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TensorFlowNET.Examples", "test\TensorFlowNET.Examples\TensorFlowNET.Examples.csproj", "{1FE60088-157C-4140-91AB-E96B915E4BAE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NumSharp.Core", "..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj", "{1D4158AC-0ED2-46D3-9532-E92232A10743}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -25,14 +25,14 @@ Global {1B1BC950-2CB0-48E2-B4CD-8172AFF67A10}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B1BC950-2CB0-48E2-B4CD-8172AFF67A10}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B1BC950-2CB0-48E2-B4CD-8172AFF67A10}.Release|Any CPU.Build.0 = Release|Any CPU - {D314AE83-D586-4589-B653-1937F1138A5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D314AE83-D586-4589-B653-1937F1138A5A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D314AE83-D586-4589-B653-1937F1138A5A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D314AE83-D586-4589-B653-1937F1138A5A}.Release|Any CPU.Build.0 = Release|Any CPU {1FE60088-157C-4140-91AB-E96B915E4BAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1FE60088-157C-4140-91AB-E96B915E4BAE}.Debug|Any CPU.Build.0 = Debug|Any CPU {1FE60088-157C-4140-91AB-E96B915E4BAE}.Release|Any CPU.ActiveCfg = Release|Any CPU {1FE60088-157C-4140-91AB-E96B915E4BAE}.Release|Any CPU.Build.0 = Release|Any CPU + {1D4158AC-0ED2-46D3-9532-E92232A10743}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D4158AC-0ED2-46D3-9532-E92232A10743}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D4158AC-0ED2-46D3-9532-E92232A10743}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D4158AC-0ED2-46D3-9532-E92232A10743}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/TensorFlowNET.Core/Graph.cs b/src/TensorFlowNET.Core/Graph.cs index 66b947ef..67c98366 100644 --- a/src/TensorFlowNET.Core/Graph.cs +++ b/src/TensorFlowNET.Core/Graph.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Text; namespace TensorFlowNET.Core @@ -12,11 +13,21 @@ namespace TensorFlowNET.Core /// public class Graph { - public IntPtr TFGraph { get; set; } + public IntPtr handle; - public Operation create_op() + public Graph(IntPtr graph) { - var op = new Operation(this); + this.handle = graph; + } + + public unsafe Operation create_op(object inputs, string op_type = "", string name = "") + { + if (String.IsNullOrEmpty(name)) + { + op_type = name; + } + + var op = new Operation(this, inputs); return op; } diff --git a/src/TensorFlowNET.Core/MonoPInvokeCallbackAttribute.cs b/src/TensorFlowNET.Core/MonoPInvokeCallbackAttribute.cs new file mode 100644 index 00000000..a2c579a6 --- /dev/null +++ b/src/TensorFlowNET.Core/MonoPInvokeCallbackAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TensorFlowNET.Core +{ + public sealed class MonoPInvokeCallbackAttribute : Attribute + { + /// + /// Use this constructor to annotate the type of the callback function that + /// will be invoked from unmanaged code. + /// + /// T. + public MonoPInvokeCallbackAttribute(Type t) { } + } +} diff --git a/src/TensorFlowNET.Core/Operation.cs b/src/TensorFlowNET.Core/Operation.cs index 9128234a..78da3d47 100644 --- a/src/TensorFlowNET.Core/Operation.cs +++ b/src/TensorFlowNET.Core/Operation.cs @@ -7,10 +7,13 @@ namespace TensorFlowNET.Core public class Operation { private Graph _graph; + private IntPtr _c_op; - public Operation(Graph g) + public Operation(Graph g, object inputs) { _graph = g; + + _c_op = ops._create_c_op(g, inputs); } } } diff --git a/src/TensorFlowNET.Core/TF_DataType.cs b/src/TensorFlowNET.Core/TF_DataType.cs new file mode 100644 index 00000000..912fba82 --- /dev/null +++ b/src/TensorFlowNET.Core/TF_DataType.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TensorFlowNET.Core +{ + /// + /// TF_DataType holds the type for a scalar value. E.g., one slot in a tensor. + /// The enum values here are identical to corresponding values in types.proto. + /// + public enum TF_DataType + { + TF_FLOAT = 1, + TF_DOUBLE = 2, + TF_INT32 = 3, // Int32 tensors are always in 'host' memory. + TF_UINT8 = 4, + TF_INT16 = 5, + TF_INT8 = 6, + TF_STRING = 7, + TF_COMPLEX64 = 8, // Single-precision complex + TF_COMPLEX = 8, // Old identifier kept for API backwards compatibility + TF_INT64 = 9, + TF_BOOL = 10, + TF_QINT8 = 11, // Quantized int8 + TF_QUINT8 = 12, // Quantized uint8 + TF_QINT32 = 13, // Quantized int32 + TF_BFLOAT16 = 14, // Float32 truncated to 16 bits. Only for cast ops. + TF_QINT16 = 15, // Quantized int16 + TF_QUINT16 = 16, // Quantized uint16 + TF_UINT16 = 17, + TF_COMPLEX128 = 18, // Double-precision complex + TF_HALF = 19, + TF_RESOURCE = 20, + TF_VARIANT = 21, + TF_UINT32 = 22, + TF_UINT64 = 23, + } +} diff --git a/src/TensorFlowNET.Core/Tensor.cs b/src/TensorFlowNET.Core/Tensor.cs new file mode 100644 index 00000000..c8c3b7f0 --- /dev/null +++ b/src/TensorFlowNET.Core/Tensor.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TensorFlowNET.Core +{ + public class Tensor + { + } +} diff --git a/src/TensorFlowNET.Core/Tensorflow.cs b/src/TensorFlowNET.Core/Tensorflow.cs index 471fafae..1fc847c0 100644 --- a/src/TensorFlowNET.Core/Tensorflow.cs +++ b/src/TensorFlowNET.Core/Tensorflow.cs @@ -3,36 +3,35 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; + + namespace TensorFlowNET.Core { public static class Tensorflow { - public const string TensorFlowLibName = "libtensorflow"; - - [DllImport(TensorFlowLibName)] - public static extern unsafe IntPtr TF_Version(); + public delegate void Deallocator(IntPtr data, IntPtr size, IntPtr deallocatorData); - public static string VERSION => Marshal.PtrToStringAnsi(TF_Version()); + public static unsafe Tensor constant(object value) + { + var g = ops.get_default_graph(); + g.create_op(value, "Const"); - [DllImport(TensorFlowLibName)] - static extern unsafe IntPtr TF_NewOperation(IntPtr graph, string opType, string oper_name); + return new Tensor(); + } - [DllImport(TensorFlowLibName)] - static extern unsafe IntPtr TF_FinishOperation(IntPtr desc, IntPtr status); + public static Deallocator FreeTensorDataDelegate = FreeTensorData; - public static IntPtr constant(T value) + [MonoPInvokeCallback(typeof(Deallocator))] + internal static void FreeTensorData(IntPtr data, IntPtr len, IntPtr closure) { - var g = Graph(); - return TF_NewOperation(g.TFGraph, "Const", "Const"); + Marshal.FreeHGlobal(data); } - [DllImport(TensorFlowLibName)] - static extern unsafe IntPtr TF_NewGraph(); + public static string VERSION => Marshal.PtrToStringAnsi(c_api.TF_Version()); public static Graph Graph() { - Graph g = new Graph(); - g.TFGraph = TF_NewGraph(); + Graph g = new Graph(c_api.TF_NewGraph()); return g; } } diff --git a/src/TensorFlowNET.Core/c_api.cs b/src/TensorFlowNET.Core/c_api.cs new file mode 100644 index 00000000..e00c5bb7 --- /dev/null +++ b/src/TensorFlowNET.Core/c_api.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +using size_t = System.UIntPtr; +using TF_Graph = System.IntPtr; +using TF_OperationDescription = System.IntPtr; +using TF_Operation = System.IntPtr; +using TF_Status = System.IntPtr; +using TF_Tensor = System.IntPtr; + +using static TensorFlowNET.Core.Tensorflow; + +namespace TensorFlowNET.Core +{ + public static class c_api + { + public const string TensorFlowLibName = "libtensorflow"; + + [DllImport(TensorFlowLibName)] + public static unsafe extern TF_Operation TF_FinishOperation(TF_OperationDescription desc, TF_Status status); + + [DllImport(TensorFlowLibName)] + public static unsafe extern IntPtr TF_NewGraph(); + + [DllImport(TensorFlowLibName)] + public static unsafe extern TF_OperationDescription TF_NewOperation(TF_Graph graph, string opType, string oper_name); + + [DllImport(TensorFlowLibName)] + public static unsafe extern TF_Status TF_NewStatus(); + + [DllImport(TensorFlowLibName)] + public static extern unsafe TF_Tensor TF_NewTensor(TF_DataType dataType, IntPtr zeroDims, int num_dims, IntPtr data, size_t len, Deallocator deallocator, IntPtr deallocator_arg); + + [DllImport(TensorFlowLibName)] + public static extern unsafe void TF_SetAttrTensor(TF_OperationDescription desc, string attr_name, TF_Tensor value, TF_Status status); + + [DllImport(TensorFlowLibName)] + public static extern unsafe void TF_SetAttrType(TF_OperationDescription desc, string attr_name, TF_DataType value); + + [DllImport(TensorFlowLibName)] + public static unsafe extern IntPtr TF_Version(); + } +} diff --git a/src/TensorFlowNET.Core/ops.cs b/src/TensorFlowNET.Core/ops.cs new file mode 100644 index 00000000..7e96f365 --- /dev/null +++ b/src/TensorFlowNET.Core/ops.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using tf = TensorFlowNET.Core.Tensorflow; + +namespace TensorFlowNET.Core +{ + public static class ops + { + public static Graph get_default_graph() + { + return tf.Graph(); + } + + public static unsafe IntPtr _create_c_op(Graph graph, object inputs) + { + var op_desc = c_api.TF_NewOperation(graph.handle, "Const", "Const0"); + var status = c_api.TF_NewStatus(); + + IntPtr tensor = IntPtr.Zero; + + switch (inputs) + { + case double value: + var v = (double*)Marshal.AllocHGlobal(sizeof(double)); + *v = value; + tensor = c_api.TF_NewTensor(TF_DataType.TF_DOUBLE, IntPtr.Zero, 0, data: (IntPtr)v, len: (UIntPtr)sizeof(double), deallocator: Tensorflow.FreeTensorDataDelegate, deallocator_arg: IntPtr.Zero); + c_api.TF_SetAttrType(op_desc, "dtype", TF_DataType.TF_DOUBLE); + break; + } + + c_api.TF_SetAttrTensor(op_desc, "value", tensor, status); + + var c_op = c_api.TF_FinishOperation(op_desc, status); + + return c_op; + } + } +} diff --git a/test/TensorFlowNET.Examples/HelloWorld.cs b/test/TensorFlowNET.Examples/HelloWorld.cs index 3a14e2da..dedcff7f 100644 --- a/test/TensorFlowNET.Examples/HelloWorld.cs +++ b/test/TensorFlowNET.Examples/HelloWorld.cs @@ -18,7 +18,8 @@ namespace TensorFlowNET.Examples The value returned by the constructor represents the output of the Constant op.*/ - var hello = tf.constant("Hello, TensorFlow!"); + var hello = tf.constant(4.0); + //var hello = tf.constant("Hello, TensorFlow!"); // Start tf session // var sess = tf.Session(); diff --git a/test/TensorFlowNET.Examples/Program.cs b/test/TensorFlowNET.Examples/Program.cs index 8bc8b25a..fdb0c2bb 100644 --- a/test/TensorFlowNET.Examples/Program.cs +++ b/test/TensorFlowNET.Examples/Program.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Reflection; namespace TensorFlowNET.Examples { @@ -6,7 +8,12 @@ namespace TensorFlowNET.Examples { static void Main(string[] args) { - Console.WriteLine("Hello World!"); + var assembly = Assembly.GetEntryAssembly(); + foreach(Type type in assembly.GetTypes().Where(x => x.GetInterfaces().Contains(typeof(IExample)))) + { + var example = (IExample)Activator.CreateInstance(type); + example.Run(); + } } } } diff --git a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj index 8081a6b7..627d1088 100644 --- a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj +++ b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj @@ -6,7 +6,6 @@ - diff --git a/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj b/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj index d7a5f65e..ad9f34a6 100644 --- a/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj +++ b/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj @@ -13,7 +13,6 @@ -