| @@ -16,95 +16,51 @@ EndProject | |||
| Global | |||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
| Debug|Any CPU = Debug|Any CPU | |||
| Debug|x64 = Debug|x64 | |||
| Debug-Minimal|Any CPU = Debug-Minimal|Any CPU | |||
| Debug-Minimal|x64 = Debug-Minimal|x64 | |||
| Publish|Any CPU = Publish|Any CPU | |||
| Publish|x64 = Publish|x64 | |||
| Release|Any CPU = Release|Any CPU | |||
| Release|x64 = Release|x64 | |||
| EndGlobalSection | |||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|x64.ActiveCfg = Debug|x64 | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|x64.Build.0 = Debug|x64 | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|x64.ActiveCfg = Debug|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|x64.Build.0 = Debug|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|Any CPU.ActiveCfg = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|Any CPU.Build.0 = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|x64.ActiveCfg = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|x64.Build.0 = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|x64.ActiveCfg = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|x64.Build.0 = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|x64.Build.0 = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|x64.ActiveCfg = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|x64.Build.0 = Debug|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|Any CPU.ActiveCfg = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|Any CPU.Build.0 = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|x64.ActiveCfg = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|x64.Build.0 = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|x64.ActiveCfg = Release|Any CPU | |||
| {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|x64.Build.0 = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|x64.Build.0 = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|x64.ActiveCfg = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|x64.Build.0 = Debug|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|Any CPU.ActiveCfg = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|Any CPU.Build.0 = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|x64.ActiveCfg = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|x64.Build.0 = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x64.ActiveCfg = Release|Any CPU | |||
| {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x64.Build.0 = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|x64.Build.0 = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|x64.ActiveCfg = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|x64.Build.0 = Debug|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|Any CPU.ActiveCfg = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|Any CPU.Build.0 = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|x64.ActiveCfg = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|x64.Build.0 = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|x64.ActiveCfg = Release|Any CPU | |||
| {6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|x64.Build.0 = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|x64.Build.0 = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|x64.ActiveCfg = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|x64.Build.0 = Debug|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|Any CPU.ActiveCfg = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|Any CPU.Build.0 = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|x64.ActiveCfg = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|x64.Build.0 = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x64.ActiveCfg = Release|Any CPU | |||
| {EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x64.Build.0 = Release|Any CPU | |||
| EndGlobalSection | |||
| GlobalSection(SolutionProperties) = preSolution | |||
| HideSolutionNode = FALSE | |||
| @@ -43,7 +43,7 @@ namespace Tensorflow | |||
| /// </summary> | |||
| public partial class c_api | |||
| { | |||
| public const string TensorFlowLibName = "tensorflow"; | |||
| public const string TensorFlowLibName = @"D:\SciSharp\tensorflow-google\bazel-bin\tensorflow\tensorflow.dll"; | |||
| public static string StringPiece(IntPtr handle) | |||
| { | |||
| @@ -0,0 +1,34 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Eager | |||
| { | |||
| public class EagerOperation : Operation | |||
| { | |||
| public int NumInputs; | |||
| public Tensor[] Inputs { get; set; } | |||
| public EagerOperation() : base(IntPtr.Zero) { } | |||
| public override InputList inputs | |||
| { | |||
| get | |||
| { | |||
| if (_inputs_val == null) | |||
| { | |||
| var retval = new Tensor[NumInputs]; | |||
| for (int i = 0; i < NumInputs; i++) | |||
| { | |||
| } | |||
| _inputs_val = new InputList(Inputs); | |||
| } | |||
| return _inputs_val; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -10,5 +10,8 @@ namespace Tensorflow.Eager | |||
| { | |||
| public static explicit operator TFE_TensorHandle(EagerTensor tensor) | |||
| => tensor.tfe_tensor_handle; | |||
| public static implicit operator IntPtr(EagerTensor tensor) | |||
| => tensor.EagerTensorHandle; | |||
| } | |||
| } | |||
| @@ -24,31 +24,10 @@ namespace Tensorflow.Eager | |||
| tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | |||
| } | |||
| public EagerTensor(int value, string device_name) : base(value) | |||
| { | |||
| tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | |||
| EagerTensorHandle = c_api.TFE_EagerTensorFromHandle(tf.context, tfe_tensor_handle); | |||
| } | |||
| public EagerTensor(float value, string device_name) : base(value) | |||
| { | |||
| tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | |||
| EagerTensorHandle = c_api.TFE_EagerTensorFromHandle(tf.context, tfe_tensor_handle); | |||
| } | |||
| public EagerTensor(float[] value, string device_name) : base(value) | |||
| { | |||
| tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | |||
| } | |||
| public EagerTensor(double[] value, string device_name) : base(value) | |||
| { | |||
| tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | |||
| } | |||
| public EagerTensor(NDArray value, string device_name) : base(value) | |||
| { | |||
| tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | |||
| EagerTensorHandle = c_api.TFE_EagerTensorFromHandle(tf.context, tfe_tensor_handle); | |||
| } | |||
| public override string ToString() | |||
| @@ -56,23 +35,24 @@ namespace Tensorflow.Eager | |||
| switch (rank) | |||
| { | |||
| case -1: | |||
| return $"tf.Tensor: shape=<unknown>, dtype={dtype.as_numpy_name()}, numpy={GetFormattedString()}"; | |||
| return $"tf.Tensor: shape=<unknown>, dtype={dtype.as_numpy_name()}, numpy={GetFormattedString(dtype, numpy())}"; | |||
| case 0: | |||
| return $"tf.Tensor: shape=(), dtype={dtype.as_numpy_name()}, numpy={GetFormattedString()}"; | |||
| return $"tf.Tensor: shape=(), dtype={dtype.as_numpy_name()}, numpy={GetFormattedString(dtype, numpy())}"; | |||
| default: | |||
| return $"tf.Tensor: shape=({string.Join(",", shape)}), dtype={dtype.as_numpy_name()}, numpy={GetFormattedString()}"; | |||
| return $"tf.Tensor: shape=({string.Join(",", shape)}), dtype={dtype.as_numpy_name()}, numpy={GetFormattedString(dtype, numpy())}"; | |||
| } | |||
| } | |||
| private string GetFormattedString() | |||
| public static string GetFormattedString(TF_DataType dtype, NDArray nd) | |||
| { | |||
| var nd = numpy(); | |||
| switch (dtype) | |||
| { | |||
| case TF_DataType.TF_STRING: | |||
| return $"b'{(string)nd}'"; | |||
| case TF_DataType.TF_BOOL: | |||
| return (nd.GetByte(0) > 0).ToString(); | |||
| case TF_DataType.TF_RESOURCE: | |||
| return "<unprintable>"; | |||
| default: | |||
| return nd.ToString(); | |||
| } | |||
| @@ -11,8 +11,18 @@ namespace Tensorflow | |||
| public static extern void TFE_RegisterGradientFunction(_gradient_function_callback callbackPointer); | |||
| [UnmanagedFunctionPointer(CallingConvention.StdCall)] | |||
| public delegate void _gradient_function_callback(string op_name, int num_inputs, IntPtr attrs, int num_attrs); | |||
| public delegate IntPtr _gradient_function_callback(string op_name, int num_inputs, IntPtr[] op_inputs, int num_attrs, IntPtr[] output_grads); | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern IntPtr VSpace_Handle(VSpace_callback_Ones ones, VSpace_callback_AggregateGrads aggregate_grads); | |||
| [UnmanagedFunctionPointer(CallingConvention.StdCall)] | |||
| public delegate IntPtr VSpace_callback_Ones(long[] shape, int dims, TF_DataType dtype); | |||
| [UnmanagedFunctionPointer(CallingConvention.StdCall)] | |||
| public delegate IntPtr VSpace_callback_AggregateGrads(IntPtr gradients, int num_grads); | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern void TFE_RegisterVSpace(IntPtr vspace); | |||
| /// <summary> | |||
| /// Return a new options object. | |||
| /// </summary> | |||
| @@ -330,7 +340,10 @@ namespace Tensorflow | |||
| string name, | |||
| IntPtr[] args, | |||
| int input_size, | |||
| TFE_FastPathExecute_SetOpAttrs set_op_attrs, | |||
| IntPtr status); | |||
| [UnmanagedFunctionPointer(CallingConvention.StdCall)] | |||
| public delegate void TFE_FastPathExecute_SetOpAttrs(IntPtr op); | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern IntPtr TFE_TapeSetNew(bool persistent, bool watch_accessed_variables); | |||
| @@ -342,7 +355,8 @@ namespace Tensorflow | |||
| public static extern void TFE_TapeWatch(IntPtr tape, IntPtr tensor); | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern IntPtr TFE_TapeGradient(IntPtr tape, IntPtr[] target, int target_size, | |||
| public static extern IntPtr TFE_TapeGradient(IntPtr tape, | |||
| IntPtr[] target, int target_size, | |||
| IntPtr[] sources, int source_size, | |||
| IntPtr status); | |||
| } | |||
| @@ -11,6 +11,8 @@ namespace Tensorflow.Eager | |||
| public partial class wrap_tfe_src | |||
| { | |||
| static int kFastPathExecuteInputStartIndex = 0; | |||
| [Obsolete] | |||
| public static EagerTensor TFE_FastPathExecute(Context ctx, | |||
| string device_name, | |||
| string opName, | |||
| @@ -203,7 +205,7 @@ namespace Tensorflow.Eager | |||
| /// <param name="attr_value"></param> | |||
| /// <param name="attr_list_sizes"></param> | |||
| /// <param name="status"></param> | |||
| private static void SetOpAttrWithDefaults(Context ctx, IntPtr op, AttrDef attr, | |||
| public static void SetOpAttrWithDefaults(Context ctx, IntPtr op, AttrDef attr, | |||
| string attr_name, object attr_value, | |||
| Dictionary<string, long> attr_list_sizes, | |||
| Status status) | |||
| @@ -74,12 +74,12 @@ namespace Tensorflow.Gradients | |||
| } | |||
| using var status = new Status(); | |||
| var et = c_api.TFE_TapeGradient(_tape, | |||
| new IntPtr[] { (target as EagerTensor).EagerTensorHandle }, 1, | |||
| new IntPtr[] { (sources as EagerTensor).EagerTensorHandle }, 1, | |||
| var et = c_api.TFE_TapeGradient(_tape, | |||
| new [] { (target as EagerTensor).EagerTensorHandle }, 1, | |||
| new [] { (sources as EagerTensor).EagerTensorHandle }, 1, | |||
| status); | |||
| status.Check(true); | |||
| return et; | |||
| return new EagerTensor(et); | |||
| } | |||
| public void Dispose() | |||
| @@ -24,9 +24,9 @@ namespace Tensorflow | |||
| { | |||
| public partial class ops | |||
| { | |||
| static Dictionary<string, Func<Operation, Tensor[], Tensor[]>> gradientFunctions = null; | |||
| public static Dictionary<string, Func<Operation, Tensor[], Tensor[]>> gradientFunctions = null; | |||
| private static void RegisterFromAssembly() | |||
| public static void RegisterFromAssembly() | |||
| { | |||
| if (gradientFunctions == null) | |||
| { | |||
| @@ -40,9 +40,9 @@ namespace Tensorflow | |||
| public int NumInputs => c_api.TF_OperationNumInputs(_handle); | |||
| private TF_DataType[] _input_types => _inputs_val._inputs.Select(x => x.dtype).ToArray(); | |||
| private InputList _inputs_val; | |||
| protected InputList _inputs_val; | |||
| public InputList inputs | |||
| public virtual InputList inputs | |||
| { | |||
| get | |||
| { | |||
| @@ -152,8 +152,14 @@ namespace Tensorflow | |||
| { | |||
| if(tf.context.executing_eagerly()) | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, "Pack", name, null, values, "axis", axis); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Pack", name, | |||
| values.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), 1, | |||
| (op) => wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "axis", axis, null, status), | |||
| status); | |||
| status.Check(true); | |||
| return new EagerTensor(tensor); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("Pack", name: name, args: new { values, axis }); | |||
| @@ -41,6 +41,18 @@ namespace Tensorflow | |||
| /// <returns></returns> | |||
| public static Tensor add_n(Tensor[] inputs, string name = null) | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| using var status = new Status(); | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "AddN", name, | |||
| inputs.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), inputs.Length, | |||
| null, | |||
| status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("AddN", name, args: new { inputs }); | |||
| return _op.outputs[0]; | |||
| @@ -121,10 +133,18 @@ namespace Tensorflow | |||
| { | |||
| try | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Mean", name, null, | |||
| input, axis, "keep_dims", keep_dims); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Mean", name, | |||
| new IntPtr[] | |||
| { | |||
| (input as EagerTensor).EagerTensorHandle, | |||
| (axis as EagerTensor).EagerTensorHandle | |||
| }, 2, | |||
| (op) => wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "keep_dims", keep_dims, null, status), | |||
| status); | |||
| status.Check(true); | |||
| return new EagerTensor(tensor); | |||
| } | |||
| catch (Exception) | |||
| { | |||
| @@ -196,17 +216,15 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| using (var status = new Status()) | |||
| { | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Add", name, new IntPtr[] | |||
| { | |||
| (x as EagerTensor).EagerTensorHandle, | |||
| (y as EagerTensor).EagerTensorHandle | |||
| }, 2, status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| using var status = new Status(); | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Add", name, new IntPtr[] | |||
| { | |||
| (x as EagerTensor).EagerTensorHandle, | |||
| (y as EagerTensor).EagerTensorHandle | |||
| }, 2, null, status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("Add", name, args: new { x, y }); | |||
| @@ -574,10 +592,18 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Cast", name, null, | |||
| x, "DstT", DstT, "Truncate", Truncate); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Cast", name, | |||
| new IntPtr[] { (x as EagerTensor).EagerTensorHandle }, 1, | |||
| (op) => | |||
| { | |||
| wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "DstT", DstT, null, status); | |||
| wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "Truncate", Truncate, null, status); | |||
| }, | |||
| status); | |||
| status.Check(true); | |||
| return new EagerTensor(tensor); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("Cast", name, args: new { x, DstT, Truncate }); | |||
| @@ -619,17 +645,15 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| using (var status = new Status()) | |||
| { | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Sub", name, new IntPtr[] | |||
| { | |||
| (x as EagerTensor).EagerTensorHandle, | |||
| (y as EagerTensor).EagerTensorHandle | |||
| }, 2, status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| using var status = new Status(); | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Sub", name, new IntPtr[] | |||
| { | |||
| (x as EagerTensor).EagerTensorHandle, | |||
| (y as EagerTensor).EagerTensorHandle | |||
| }, 2, null, status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("Sub", name, args: new { x, y }); | |||
| @@ -717,11 +741,11 @@ namespace Tensorflow | |||
| { | |||
| using var status = new Status(); | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Mul", name, new IntPtr[] | |||
| { | |||
| (x as EagerTensor).EagerTensorHandle, | |||
| (y as EagerTensor).EagerTensorHandle | |||
| }, 2, status); | |||
| "Mul", name, new IntPtr[] | |||
| { | |||
| (x as EagerTensor).EagerTensorHandle, | |||
| (y as EagerTensor).EagerTensorHandle | |||
| }, 2, null, status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| @@ -757,17 +781,15 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| using (var status = new Status()) | |||
| { | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| using var status = new Status(); | |||
| var _result = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "RealDiv", name, new IntPtr[] | |||
| { | |||
| (x as EagerTensor).EagerTensorHandle, | |||
| (y as EagerTensor).EagerTensorHandle | |||
| }, 2, status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| }, 2, null, status); | |||
| status.Check(true); | |||
| return new EagerTensor(_result); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("RealDiv", name, args: new { x, y }); | |||
| @@ -962,8 +984,16 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, "Range", name, null, start, limit, delta); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "Range", name, new IntPtr[] | |||
| { | |||
| (start as EagerTensor).EagerTensorHandle, | |||
| (limit as EagerTensor).EagerTensorHandle, | |||
| (delta as EagerTensor).EagerTensorHandle | |||
| }, 3, null, status); | |||
| status.Check(true); | |||
| return new EagerTensor(tensor); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("Range", name, new { start, limit, delta }); | |||
| @@ -14,6 +14,8 @@ | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using System; | |||
| using System.Linq; | |||
| using Tensorflow.Eager; | |||
| using static Tensorflow.Binding; | |||
| @@ -27,10 +29,16 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "AssignVariableOp", name, null, | |||
| resource, value); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "AssignVariableOp", name, | |||
| new[] | |||
| { | |||
| (resource as EagerTensor).EagerTensorHandle, | |||
| (value as EagerTensor).EagerTensorHandle | |||
| }, 2, null, status); | |||
| status.Check(true); | |||
| return tensor; | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("AssignVariableOp", name, new { resource, value }); | |||
| @@ -42,10 +50,13 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "VarIsInitializedOp", name, null, | |||
| resource); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "VarIsInitializedOp", name, | |||
| new[] { (resource as EagerTensor).EagerTensorHandle }, | |||
| 1, null, status); | |||
| status.Check(true); | |||
| return new EagerTensor(tensor); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("VarIsInitializedOp", name, new { resource }); | |||
| @@ -67,10 +78,17 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "VarHandleOp", name, null, | |||
| "container", container, "shared_name", shared_name, "dtype", dtype, "shape", shape.dims); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "VarHandleOp", name, null, 0, op => | |||
| { | |||
| wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "container", container, null, status); | |||
| wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "shared_name", shared_name, null, status); | |||
| wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "dtype", dtype, null, status); | |||
| wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "shape", shape.dims, null, status); | |||
| }, status); | |||
| status.Check(true); | |||
| return new EagerTensor(tensor); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("VarHandleOp", name, new { | |||
| @@ -94,10 +112,13 @@ namespace Tensorflow | |||
| { | |||
| if (tf.context.executing_eagerly()) | |||
| { | |||
| var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "ReadVariableOp", name, null, | |||
| resource, "dtype", dtype); | |||
| return _result; | |||
| using var status = new Status(); | |||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | |||
| "ReadVariableOp", name, new IntPtr[] { (resource as EagerTensor).EagerTensorHandle }, 1, | |||
| (op) => wrap_tfe_src.SetOpAttrWithDefaults(tf.context, op, null, "dtype", dtype, null, status), | |||
| status); | |||
| status.Check(true); | |||
| return new EagerTensor(tensor); | |||
| } | |||
| var _op = _op_def_lib._apply_op_helper("ReadVariableOp", name, new | |||
| @@ -31,7 +31,7 @@ https://tensorflownet.readthedocs.io</Description> | |||
| <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||
| <SignAssembly>true</SignAssembly> | |||
| <AssemblyOriginatorKeyFile>Open.snk</AssemblyOriginatorKeyFile> | |||
| <Platforms>AnyCPU;x64</Platforms> | |||
| <Platforms>AnyCPU</Platforms> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | |||
| @@ -40,20 +40,10 @@ https://tensorflownet.readthedocs.io</Description> | |||
| <PlatformTarget>x64</PlatformTarget> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
| <DefineConstants>TRACE;DEBUG;SERIALIZABLE_</DefineConstants> | |||
| <PlatformTarget>x64</PlatformTarget> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | |||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Compile Remove="Distribute\**" /> | |||
| <Compile Remove="Models\**" /> | |||
| @@ -127,6 +127,8 @@ namespace Tensorflow | |||
| return new EagerTensor(val, ctx.device_name); | |||
| case float val: | |||
| return new EagerTensor(val, ctx.device_name); | |||
| case float[,] val: | |||
| return new EagerTensor(val, ctx.device_name); | |||
| case double val: | |||
| return new EagerTensor(val, ctx.device_name); | |||
| case float[] val: | |||
| @@ -202,6 +202,7 @@ namespace Tensorflow | |||
| TF_DataType.TF_INT32 => "int32", | |||
| TF_DataType.TF_FLOAT => "float32", | |||
| TF_DataType.TF_BOOL => "bool", | |||
| TF_DataType.TF_RESOURCE => "resource", | |||
| _ => type.ToString() | |||
| }; | |||
| @@ -18,6 +18,7 @@ using Google.Protobuf; | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using Tensorflow.Eager; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow | |||
| @@ -221,5 +222,10 @@ namespace Tensorflow | |||
| return array_ops.identity(value); | |||
| }); | |||
| } | |||
| public override string ToString() | |||
| { | |||
| return $"tf.Variable: '{name}' shape={string.Join(",", shape)}, dtype={dtype.as_numpy_name()}, numpy={EagerTensor.GetFormattedString(dtype, numpy())}"; | |||
| } | |||
| } | |||
| } | |||
| @@ -14,6 +14,9 @@ | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using System; | |||
| using System.Linq; | |||
| using System.Runtime.InteropServices; | |||
| using System.Threading; | |||
| using Tensorflow.Eager; | |||
| @@ -39,6 +42,45 @@ namespace Tensorflow | |||
| public tensorflow() | |||
| { | |||
| _constructThreadingObjects(); | |||
| InitGradientEnvironment(); | |||
| } | |||
| private unsafe void InitGradientEnvironment() | |||
| { | |||
| var vspace = c_api.VSpace_Handle((shape, dims, dtype) => | |||
| { | |||
| var ones = constant_op.constant(1.0f, dtype: dtype) as EagerTensor; | |||
| return ones.EagerTensorHandle; | |||
| }, (gradients, num_grads) => | |||
| { | |||
| var input_grads = new EagerTensor[num_grads]; | |||
| for (int i = 0; i < num_grads; i++) | |||
| input_grads[i] = new EagerTensor(*((IntPtr*)gradients + i)); | |||
| var add_n = gen_math_ops.add_n(input_grads); | |||
| return (add_n as EagerTensor).EagerTensorHandle; | |||
| }); | |||
| ops.RegisterFromAssembly(); | |||
| c_api.TFE_RegisterGradientFunction((op_name, num_inputs, op_inputs, num_attrs, output_grads) => | |||
| { | |||
| var output_grad_tensors = output_grads.Select(x => new EagerTensor(x)).ToArray(); | |||
| var input_tensors = new EagerTensor[num_inputs]; | |||
| for (int i = 0; i < num_inputs; i++) | |||
| input_tensors[i] = new EagerTensor(op_inputs[op_inputs.Length == 1 ? 0 : i]); | |||
| var gradients = ops.gradientFunctions[op_name](new EagerOperation | |||
| { | |||
| NumInputs = num_inputs, | |||
| Inputs = input_tensors | |||
| }, output_grad_tensors); | |||
| var ret_tensors = Marshal.AllocHGlobal(sizeof(IntPtr) * num_inputs); | |||
| Marshal.Copy(gradients.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), 0, ret_tensors, 2); | |||
| // Marshal.FreeHGlobal(ret_tensors); | |||
| return ret_tensors; | |||
| }); | |||
| } | |||
| public ResourceVariable Variable<T>(T data, | |||
| @@ -0,0 +1,27 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.UnitTest.Gradient | |||
| { | |||
| [TestClass] | |||
| public class GradientEagerTest : PythonTest | |||
| { | |||
| [TestMethod] | |||
| public void ConstantSq() | |||
| { | |||
| // Calcute the gradient of w * w | |||
| // by Automatic Differentiation in Eager mode | |||
| // in tensorflow.net 2.x that is in development intensively | |||
| var w = tf.constant(1.5f); | |||
| using var tape = tf.GradientTape(); | |||
| tape.watch(w); | |||
| var loss = w * w; | |||
| var grad = tape.gradient(loss, w); | |||
| print(grad); | |||
| } | |||
| } | |||
| } | |||
| @@ -30,11 +30,10 @@ | |||
| <ItemGroup> | |||
| <PackageReference Include="FluentAssertions" Version="5.10.3" /> | |||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | |||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> | |||
| <PackageReference Include="MSTest.TestAdapter" Version="2.1.1" /> | |||
| <PackageReference Include="MSTest.TestFramework" Version="2.1.1" /> | |||
| <PackageReference Include="NumSharp.Lite" Version="0.1.7" /> | |||
| <PackageReference Include="SciSharp.TensorFlow.Redist" Version="2.1.0" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| @@ -7,7 +7,7 @@ | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | |||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> | |||
| <PackageReference Include="MSTest.TestAdapter" Version="2.1.1" /> | |||
| <PackageReference Include="MSTest.TestFramework" Version="2.1.1" /> | |||
| <PackageReference Include="coverlet.collector" Version="1.2.1"> | |||