Browse Source

Add EagerRunner to fix memory leak and exception.

tags/v0.20
Oceania2018 5 years ago
parent
commit
6989cb1ce5
63 changed files with 1968 additions and 2613 deletions
  1. +6
    -4
      src/TensorFlowNET.Console/Program.cs
  2. +4
    -2
      src/TensorFlowNET.Core/APIs/tf.gradients.cs
  3. +11
    -2
      src/TensorFlowNET.Core/Eager/Context.cs
  4. +6
    -9
      src/TensorFlowNET.Core/Eager/EagerOperation.cs
  5. +25
    -0
      src/TensorFlowNET.Core/Eager/EagerRunner.cs
  6. +0
    -7
      src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs
  7. +5
    -6
      src/TensorFlowNET.Core/Eager/Execute.cs
  8. +18
    -0
      src/TensorFlowNET.Core/Eager/FastPathOpExecInfo.cs
  9. +29
    -0
      src/TensorFlowNET.Core/Eager/IEagerRunner.cs
  10. +6
    -0
      src/TensorFlowNET.Core/Eager/c_api.eager.cs
  11. +0
    -62
      src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_Execute.cs
  12. +0
    -305
      src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs
  13. +12
    -7
      src/TensorFlowNET.Core/Framework/op_def_registry.py.cs
  14. +18
    -0
      src/TensorFlowNET.Core/Gradients/AccumulatorCallState.cs
  15. +30
    -0
      src/TensorFlowNET.Core/Gradients/BackpropInitialState.cs
  16. +38
    -30
      src/TensorFlowNET.Core/Gradients/GradientTape.cs
  17. +33
    -0
      src/TensorFlowNET.Core/Gradients/ITape.cs
  18. +19
    -0
      src/TensorFlowNET.Core/Gradients/OpTape.cs
  19. +19
    -0
      src/TensorFlowNET.Core/Gradients/OpTapeEntry.cs
  20. +19
    -40
      src/TensorFlowNET.Core/Gradients/Tape.cs
  21. +31
    -0
      src/TensorFlowNET.Core/Gradients/TapeTensor.cs
  22. +19
    -0
      src/TensorFlowNET.Core/Gradients/TensorTape.cs
  23. +3
    -0
      src/TensorFlowNET.Core/Gradients/c_api.gradient.cs
  24. +31
    -0
      src/TensorFlowNET.Core/Gradients/gradient_exclustions.cs
  25. +3
    -3
      src/TensorFlowNET.Core/Gradients/math_grad_eager.cs
  26. +0
    -101
      src/TensorFlowNET.Core/Gradients/ops.gradient_function_mapping_eager.cs
  27. +1
    -18
      src/TensorFlowNET.Core/Graphs/Graph.Operation.cs
  28. +46
    -63
      src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs
  29. +118
    -186
      src/TensorFlowNET.Core/Operations/gen_array_ops.cs
  30. +13
    -14
      src/TensorFlowNET.Core/Operations/gen_control_flow_ops.cs
  31. +3
    -3
      src/TensorFlowNET.Core/Operations/gen_ctc_ops.cs
  32. +23
    -23
      src/TensorFlowNET.Core/Operations/gen_data_flow_ops.cs
  33. +7
    -9
      src/TensorFlowNET.Core/Operations/gen_image_ops.cs
  34. +5
    -5
      src/TensorFlowNET.Core/Operations/gen_io_ops.cs
  35. +5
    -6
      src/TensorFlowNET.Core/Operations/gen_logging_ops.cs
  36. +256
    -408
      src/TensorFlowNET.Core/Operations/gen_math_ops.cs
  37. +7
    -12
      src/TensorFlowNET.Core/Operations/gen_math_ops.eager.cs
  38. +872
    -874
      src/TensorFlowNET.Core/Operations/gen_ops.cs
  39. +21
    -37
      src/TensorFlowNET.Core/Operations/gen_random_ops.cs
  40. +35
    -55
      src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs
  41. +3
    -5
      src/TensorFlowNET.Core/Operations/gen_sparse_ops.cs
  42. +2
    -4
      src/TensorFlowNET.Core/Operations/gen_string_ops.cs
  43. +2
    -3
      src/TensorFlowNET.Core/Operations/image_ops_impl.cs
  44. +2
    -4
      src/TensorFlowNET.Core/Operations/math_ops.cs
  45. +0
    -17
      src/TensorFlowNET.Core/System/GCItemCounter.cs
  46. +0
    -13
      src/TensorFlowNET.Core/System/GCItemType.cs
  47. +0
    -97
      src/TensorFlowNET.Core/System/GarbageCollector.cs
  48. +6
    -10
      src/TensorFlowNET.Core/Tensors/EagerTensorV2.cs
  49. +1
    -3
      src/TensorFlowNET.Core/Tensors/constant_op.cs
  50. +8
    -16
      src/TensorFlowNET.Core/Training/gen_training_ops.cs
  51. +0
    -22
      src/TensorFlowNET.Core/Util/EagerTensorPass.cs
  52. +0
    -31
      src/TensorFlowNET.Core/Util/TensorManager.cs
  53. +76
    -0
      src/TensorFlowNET.Core/Util/UnorderedMap.cs
  54. +18
    -0
      src/TensorFlowNET.Core/Util/UnorderedSet.cs
  55. +4
    -3
      src/TensorFlowNET.Core/Variables/BaseResourceVariable.cs
  56. +0
    -2
      src/TensorFlowNET.Core/Variables/ResourceVariable.Operators.cs
  57. +0
    -3
      src/TensorFlowNET.Core/Variables/ResourceVariable.cs
  58. +9
    -12
      src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs
  59. +20
    -48
      src/TensorFlowNET.Core/tensorflow.cs
  60. +2
    -0
      test/TensorFlowNET.UnitTest/MultithreadingTests.cs
  61. +2
    -2
      test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpInferMixedTypeInputListAttrs.cs
  62. +16
    -2
      test/TensorFlowNET.UnitTest/NativeAPI/Eager/GradientEagerTest.cs
  63. +0
    -25
      test/TensorFlowNET.UnitTest/PlaceholderTest.cs

+ 6
- 4
src/TensorFlowNET.Console/Program.cs View File

@@ -1,4 +1,5 @@
using System;
using static Tensorflow.Binding;

namespace Tensorflow
{
@@ -14,18 +15,19 @@ namespace Tensorflow

int batchSize = 1000;

// 1 million float tensor 58.5M.
// 1 million float tensor 68M.
mm.Execute(10, 100 * batchSize, cases.Constant);

// 100K float variable 80.5M.
// 100K float variable 84M.
mm.Execute(10, 10 * batchSize, cases.Variable);

// 1 million math add 36.5M.
// 1 million math add 39M.
mm.Execute(10, 100 * batchSize, cases.MathAdd);

// 100K gradient 210M.
// 100K gradient 44M.
mm.Execute(10, 10 * batchSize, cases.Gradient);

// 120M
Console.WriteLine("Finished.");
Console.ReadLine();
}


+ 4
- 2
src/TensorFlowNET.Core/APIs/tf.gradients.cs View File

@@ -20,8 +20,10 @@ namespace Tensorflow
{
public partial class tensorflow
{
public GradientTape GradientTape()
=> new GradientTape();
public GradientTape GradientTape(bool persistent = false,
bool watch_accessed_variables = true)
=> new GradientTape(persistent: persistent,
watch_accessed_variables: watch_accessed_variables);

public Tensor[] gradients(Tensor[] ys,
Tensor[] xs,


+ 11
- 2
src/TensorFlowNET.Core/Eager/Context.cs View File

@@ -18,6 +18,9 @@ namespace Tensorflow.Eager
status.Check(true);
}

/// <summary>
/// Initialize handle and devices if not already done so.
/// </summary>
public void ensure_initialized()
{
if (_initialized)
@@ -25,14 +28,20 @@ namespace Tensorflow.Eager
_initialized = true;
}

public void start_step()
=> c_api.TFE_ContextStartStep(_handle);

public void end_step()
=> c_api.TFE_ContextEndStep(_handle);

/// <summary>
/// Dispose any unmanaged resources related to given <paramref name="handle"/>.
/// </summary>
protected sealed override void DisposeUnmanagedResources(IntPtr handle)
=> c_api.TFE_DeleteContext(_handle);

public bool executing_eagerly() => true;
public bool executing_eagerly()
=> default_execution_mode == EAGER_MODE;

public string shared_name(string name = null)
=> !string.IsNullOrEmpty(name) || !executing_eagerly() ?


+ 6
- 9
src/TensorFlowNET.Core/Eager/EagerOperation.cs View File

@@ -8,7 +8,6 @@ namespace Tensorflow.Eager
{
public class EagerOperation : Operation
{
static Dictionary<string, OpDef> op_dict;
public string Name { get; set; }
public new int NumInputs;
public IntPtr[] InputHandles { get; set; }
@@ -16,14 +15,12 @@ namespace Tensorflow.Eager
public new int NumOutputs;
public IntPtr[] OutputHandles { get; set; }
public Tensor[] Outputs { get; set; }
public BindingArray SkipInputIndicesArray { get; set; }
public unsafe int[] SkipInputIndices => SkipInputIndicesArray.Data.Select(x => *(int*) x).ToArray();
public string[] AttrsArray { get; set; }
public long[] SkipInputIndices { get; set; }
public object[] Attrs { get; set; }

public EagerOperation() : base(IntPtr.Zero)
{
if (op_dict == null)
op_dict = op_def_registry.get_registered_ops();

}

public override InputList inputs
@@ -72,9 +69,9 @@ namespace Tensorflow.Eager

public bool get_attr_bool(string attr_name)
{
for (int i = 0; i < AttrsArray.Length; i = i + 2)
if (AttrsArray[i] == attr_name)
return AttrsArray[i + 1] == "1";
for (int i = 0; i < Attrs.Length; i = i + 2)
if (Attrs[i].Equals(attr_name))
return Attrs[i + 1].Equals("1");

throw new ValueError($"Can't find attr: {attr_name}");
}


+ 25
- 0
src/TensorFlowNET.Core/Eager/EagerRunner.cs View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Gradients;

namespace Tensorflow.Eager
{
public class EagerRunner : IEagerRunner
{
public Tensor[] TFE_Execute(Context ctx, string device_name, string op_name, Tensor[] inputs, object[] attrs, int num_outputs)
{
throw new NotImplementedException();
}

public Tensor[] TFE_FastPathExecute(Context ctx, string device_name, string opName, string name, Action callbacks, params object[] args)
{
throw new NotImplementedException();
}

public Tensor[] TFE_TapeGradient(ITape tape, Tensor[] target, Tensor[] sources, Tensor[] output_gradients)
{
throw new NotImplementedException();
}
}
}

+ 0
- 7
src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs View File

@@ -42,9 +42,6 @@ namespace Tensorflow.Eager
//print($"new Tensor {Id} {_handle.ToString("x16")}");
//print($"new TensorHandle {Id} {EagerTensorHandle.ToString("x16")}");

/*GarbageCollector.Increase(_handle, GCItemType.TensorHandle);
GarbageCollector.Increase(tfe_tensor_handle, GCItemType.LocalTensorHandle);*/

return this;
}

@@ -53,10 +50,6 @@ namespace Tensorflow.Eager

protected override void DisposeUnmanagedResources(IntPtr handle)
{
/*GarbageCollector.Decrease(_handle);
GarbageCollector.Decrease(tfe_tensor_handle);
GarbageCollector.Decrease(EagerTensorHandle);*/

//print($"deleting DeleteTensorHandle {Id} {_handle.ToString("x16")}");
c_api.TF_DeleteTensor(_handle);
//print($"deleting DeleteTensorHandle {Id} {EagerTensorHandle.ToString("x16")}");


+ 5
- 6
src/TensorFlowNET.Core/Eager/Execute.cs View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System;
using System.Linq;
using static Tensorflow.Binding;

namespace Tensorflow.Eager
{
@@ -27,20 +28,18 @@ namespace Tensorflow.Eager
/// <param name="ctx">The value of context.context().</param>
/// <param name="name">Customized name for the operation.</param>
/// <returns>List of output Tensor objects. The list is empty if there are no outputs</returns>
public EagerTensor[] execute(Context ctx, string op_name, int num_outputs,
EagerTensor[] inputs, object[] attrs,
public Tensor[] execute(Context ctx, string op_name, int num_outputs,
Tensor[] inputs, object[] attrs,
string name = null)
{
ctx.ensure_initialized();

using var status = new Status();
var results = wrap_tfe_src.TFE_Execute(ctx,
var results = tf.Runner.TFE_Execute(ctx,
ctx.device_name,
op_name,
inputs,
attrs,
num_outputs,
status);
num_outputs);

return results;
}


+ 18
- 0
src/TensorFlowNET.Core/Eager/FastPathOpExecInfo.cs View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Eager
{
public class FastPathOpExecInfo
{
public Context ctx { get; set; }
public string device_name { get; set; }
public string op_name { get; set; }
public string name { get; set; }
public object[] args { get; set; }
public bool run_gradient_callback { get; set; }
public bool run_post_exec_callbacks { get; set; }
public bool run_callbacks { get; set; }
}
}

+ 29
- 0
src/TensorFlowNET.Core/Eager/IEagerRunner.cs View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Gradients;

namespace Tensorflow.Eager
{
public interface IEagerRunner
{
public Tensor[] TFE_FastPathExecute(Context ctx,
string device_name,
string opName,
string name,
Action callbacks,
params object[] args);

public Tensor[] TFE_Execute(Context ctx,
string device_name,
string op_name,
Tensor[] inputs,
object[] attrs,
int num_outputs);

public Tensor[] TFE_TapeGradient(ITape tape,
Tensor[] target,
Tensor[] sources,
Tensor[] output_gradients);
}
}

+ 6
- 0
src/TensorFlowNET.Core/Eager/c_api.eager.cs View File

@@ -116,6 +116,12 @@ namespace Tensorflow
[DllImport(TensorFlowLibName)]
public static extern TFE_Context TFE_NewContext(IntPtr opts, IntPtr status);

[DllImport(TensorFlowLibName)]
public static extern TFE_Context TFE_ContextStartStep(IntPtr ctx);

[DllImport(TensorFlowLibName)]
public static extern TFE_Context TFE_ContextEndStep(IntPtr ctx);

/// <summary>
///
/// </summary>


+ 0
- 62
src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_Execute.cs View File

@@ -1,62 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System;
using static Tensorflow.OpDef.Types;

namespace Tensorflow.Eager
{
/// <summary>
/// python\eager\pywrap_tfe_src.cc
/// </summary>
public partial class wrap_tfe_src
{
public static EagerTensor[] TFE_Execute(Context ctx,
string device_name,
string op_name,
Tensor[] inputs,
object[] attrs,
int num_outputs,
Status status)
=> TFE_ExecuteCancelable(ctx, device_name, op_name, inputs, attrs, num_outputs, status);

public static EagerTensor[] TFE_ExecuteCancelable(Context ctx,
string device_name,
string op_name,
Tensor[] inputs,
object[] attrs,
int num_outputs,
Status status)
{
var op = GetOp(ctx, op_name, status);
status.Check(true);
c_api.TFE_OpSetDevice(op, device_name, status);
if (status.ok())
{
for (int i = 0; i < inputs.Length; ++i)
{
IntPtr tensor_handle;
switch (inputs[i])
{
case EagerTensor et:
tensor_handle = et.EagerTensorHandle;
break;
default:
tensor_handle = c_api.TFE_NewTensorHandle(inputs[i], status);
break;
}
c_api.TFE_OpAddInput(op, tensor_handle, status);
}
}
if (status.ok())
SetOpAttrs(op, attrs, status);

var outputs = new IntPtr[num_outputs];
if (status.ok())
{
c_api.TFE_Execute(op, outputs, ref num_outputs, status);
status.Check(true);
}
return outputs.Select(x => new EagerTensor(x)).ToArray();
}
}
}

+ 0
- 305
src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs View File

@@ -1,305 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System;
using static Tensorflow.OpDef.Types;
using static Tensorflow.Binding;

namespace Tensorflow.Eager
{
/// <summary>
/// python\eager\pywrap_tfe_src.cc
/// </summary>
public partial class wrap_tfe_src
{
static int kFastPathExecuteInputStartIndex = 0;

public static EagerTensor[] TFE_FastPathExecute(Context ctx,
string device_name,
string opName,
string name,
Action callbacks,
params object[] args)
{
int args_size = args.Length;
var attr_list_sizes = new Dictionary<string, long>();
using var status = new Status();
var op = GetOp(ctx, opName, status);

var op_def = Graph.TFE_GetOpDef(opName);

// Set non-inferred attrs, including setting defaults if the attr is passed in
// as None.
for (int i = kFastPathExecuteInputStartIndex + op_def.InputArg.Count; i < args_size; i += 2)
{
var attr_name = args[i].ToString();
var attr_value = args[i + 1];

foreach (var attr in op_def.Attr)
{
if (attr_name == attr.Name)
{
SetOpAttrWithDefaults(ctx, op, attr, attr_name, attr_value, attr_list_sizes, status);
status.Check(true);
break;
}
}
}

c_api.TFE_OpSetDevice(op, device_name, status);
status.Check(true);

// Add inferred attrs and inputs.
for (int i = 0; i < op_def.InputArg.Count; i++)
{
var input_arg = op_def.InputArg[i];
if (!string.IsNullOrEmpty(input_arg.NumberAttr))
{
int len = (args[kFastPathExecuteInputStartIndex + i] as object[]).Length;
c_api.TFE_OpSetAttrInt(op, input_arg.NumberAttr, len);
attr_list_sizes[input_arg.NumberAttr] = len;

if (len > 0)
{
var fast_input_array = (object[])args[i];
// First item adds the type attr.
if (!AddInputToOp(fast_input_array[i], true, input_arg, op, status))
return null;

for (var j = 1; j < len; j++)
{
// Since the list is homogeneous, we don't need to re-add the attr.
if (!AddInputToOp(fast_input_array[j], false, input_arg, op, status))
return null;
}
}
}
else if (!string.IsNullOrEmpty(input_arg.TypeListAttr))
{

}
else
{
// The item is a single item.
AddInputToOp(args[i], true, input_arg, op, status);
}
}

int num_retvals = 0;
for (int i = 0; i < op_def.OutputArg.Count; i++)
{
var output_arg = op_def.OutputArg[i];
var delta = 1L;
if (!string.IsNullOrEmpty(output_arg.NumberAttr))
delta = attr_list_sizes[output_arg.NumberAttr];
else if (!string.IsNullOrEmpty(output_arg.TypeListAttr))
delta = attr_list_sizes[output_arg.TypeListAttr];
if (delta < 0)
throw new RuntimeError("Attributes suggest that the size of an output list is less than 0");
num_retvals += (int)delta;
}

var retVals = new IntPtr[num_retvals];
c_api.TFE_Execute(op, retVals, ref num_retvals, status);
status.Check(true);

return retVals.Select(x => new EagerTensor(x)).ToArray();
}

private static TFE_Op GetOp(Context ctx, string op_or_function_name, Status status)
{
var maybe_op = ReleaseThreadLocalOp();
if (maybe_op != IntPtr.Zero)
{
c_api.TFE_OpReset(maybe_op, op_or_function_name, ctx.device_name, status);
}
else
{
maybe_op = c_api.TFE_NewOp(ctx, op_or_function_name, status);
op = maybe_op;
}

status.Check(true);
return maybe_op;
}

static TFE_Op op;
private static TFE_Op ReleaseThreadLocalOp()
{
return op;
}

/// <summary>
/// Adds input and type attr to the op, and to the list of flattened
/// inputs/attrs.
/// </summary>
/// <param name="inputs"></param>
/// <param name="add_type_attr"></param>
/// <param name="input_arg"></param>
/// <param name="op"></param>
/// <param name="status"></param>
/// <returns></returns>
private static bool AddInputToOp(object inputs,
bool add_type_attr,
ArgDef input_arg,
IntPtr op,
Status status)
{
IntPtr input_handle;

// ConvertToTensor();
switch (inputs)
{
case EagerTensor input:
input_handle = input.EagerTensorHandle;
break;
case EagerTensor[] input_list:
input_handle = input_list[0].EagerTensorHandle;
break;
default:
throw new NotImplementedException("");
}

if (add_type_attr && !string.IsNullOrEmpty(input_arg.TypeAttr))
{
var dtype = c_api.TFE_TensorHandleDataType(input_handle);
c_api.TFE_OpSetAttrType(op, input_arg.TypeAttr, dtype);
}

c_api.TFE_OpAddInput(op, input_handle, status);
status.Check(true);

return true;
}

public static void SetOpAttrs(TFE_Op op, params object[] attrs)
{
using var status = new Status();
var len = attrs.Length;
for (int i = 0; i < len; i += 2)
{
var key = attrs[i].ToString();
var value = attrs[i + 1];

byte is_list = 0;
var type = c_api.TFE_OpGetAttrType(op, key, ref is_list, status);
if (!status.ok()) return;
if (is_list != 0)
SetOpAttrList(tf.context, op, key, value, type, null, status);
else
SetOpAttrScalar(tf.context, op, key, value, type, null, status);
status.Check(true);
}
}

public static string SetOpAttrs2(params object[] attrs)
{
string attr_string = string.Empty;
for(int i = 0; i < attrs.Length; i = i + 2)
{
object key = attrs[i];
object value = attrs[i + 1];

switch (value)
{
case TF_DataType dtype:
value = (int)dtype;
break;
case bool bVal:
value = bVal ? 1 : 0;
break;
case int[] shape:
value = shape.Length == 0 ? "null" : string.Join(" ", shape);
break;
default:
break;
}

attr_string += string.IsNullOrEmpty(attr_string) ?
$"{key},{value}" :
$",{key},{value}";
}

return attr_string;
}

/// <summary>
/// This function will set the op attrs required. If an attr has the value of
/// None, then it will read the AttrDef to get the default value and set that
/// instead. Any failure in this function will simply fall back to the slow
/// path.
/// </summary>
/// <param name="ctx"></param>
/// <param name="op"></param>
/// <param name="attr"></param>
/// <param name="attr_name"></param>
/// <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,
string attr_name, object attr_value,
Dictionary<string, long> attr_list_sizes,
Status status)
{
byte is_list = 0;
var type = c_api.TFE_OpGetAttrType(op, attr_name, ref is_list, status);
if (status.Code != TF_Code.TF_OK) return;

if(attr_value == null)
{
if (is_list != 0)
;
//SetOpAttrListDefault
else
;
//SetOpAttrScalarDefault
}
else
{
if (is_list != 0)
;// SetOpAttrList
else
SetOpAttrScalar(ctx, op, attr_name, attr_value, type, attr_list_sizes, status);
}
}

private static bool SetOpAttrList(Context ctx, IntPtr op,
string key, object value, TF_AttrType type,
Dictionary<string, long> attr_list_sizes,
Status status)
{
return false;
}

private static bool SetOpAttrScalar(Context ctx, IntPtr op,
string key, object value, TF_AttrType type,
Dictionary<string, long> attr_list_sizes,
Status status)
{
switch(type)
{
case TF_AttrType.TF_ATTR_STRING:
c_api.TFE_OpSetAttrString(op, key, value.ToString(), (uint)value.ToString().Length);
break;
case TF_AttrType.TF_ATTR_TYPE:
c_api.TFE_OpSetAttrType(op, key, (TF_DataType)value);
break;
case TF_AttrType.TF_ATTR_BOOL:
c_api.TFE_OpSetAttrBool(op, key, Convert.ToBoolean(value));
break;
case TF_AttrType.TF_ATTR_INT:
c_api.TFE_OpSetAttrInt(op, key, Convert.ToInt64(value));
break;
case TF_AttrType.TF_ATTR_SHAPE:
var dims = (value as int[]).Select(x => (long)x).ToArray();
c_api.TFE_OpSetAttrShape(op, key, dims, dims.Length, status);
status.Check(true);
break;
default:
throw new NotImplementedException($"SetOpAttrScalar for {type}");
}

return true;
}
}
}

+ 12
- 7
src/TensorFlowNET.Core/Framework/op_def_registry.py.cs View File

@@ -22,22 +22,27 @@ namespace Tensorflow
{
public class op_def_registry
{
private static Dictionary<string, OpDef> _registered_ops;
static Dictionary<string, OpDef> _registered_ops;

public static Dictionary<string, OpDef> get_registered_ops()
{
if(_registered_ops == null)
{
_registered_ops = new Dictionary<string, OpDef>();
using (var buffer = new Buffer(c_api.TF_GetAllOpList()))
{
var op_list = OpList.Parser.ParseFrom(buffer.MemoryBlock.Stream());
foreach (var op_def in op_list.Op)
_registered_ops[op_def.Name] = op_def;
}
using var buffer = new Buffer(c_api.TF_GetAllOpList());
using var stream = buffer.MemoryBlock.Stream();
var op_list = OpList.Parser.ParseFrom(stream);
foreach (var op_def in op_list.Op)
_registered_ops[op_def.Name] = op_def;
}

return _registered_ops;
}

public static OpDef GetOpDef(string type)
{
var ops = get_registered_ops();
return ops[type];
}
}
}

+ 18
- 0
src/TensorFlowNET.Core/Gradients/AccumulatorCallState.cs View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Gradients
{
public class AccumulatorCallState
{
GradientTape backward_tape;
bool accumulating;

public AccumulatorCallState(GradientTape backward_tape, bool accumulating)
{
this.backward_tape = backward_tape;
this.accumulating = accumulating;
}
}
}

+ 30
- 0
src/TensorFlowNET.Core/Gradients/BackpropInitialState.cs View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Util;
using static Tensorflow.tensorflow;

namespace Tensorflow.Gradients
{
public class BackpropInitialState
{
public OpTape<BackwardFunction, TapeTensor> op_tape { get; set; }
/// <summary>
/// Map from tensor ID to how many references still exist for this tensor in
/// the tape.
/// </summary>
public UnorderedMap<long, long> tensor_usage_counts { get; set; }
/// <summary>
/// Maps from op ID to how many output tensors of this op still need to have
/// their gradients computed.
/// </summary>
public UnorderedMap<long, long> op_missing_tensor { get; set; }

public BackpropInitialState()
{
op_tape = new OpTape<BackwardFunction, TapeTensor>();
tensor_usage_counts = new UnorderedMap<long, long>();
op_missing_tensor = new UnorderedMap<long, long>();
}
}
}

+ 38
- 30
src/TensorFlowNET.Core/Gradients/GradientTape.cs View File

@@ -30,7 +30,7 @@ namespace Tensorflow.Gradients
bool _watch_accessed_variables;
ResourceVariable[] _watched_variables;
bool _created_eagerly;
Tape _tape;
ITape _tape;

public GradientTape(bool persistent = false,
bool watch_accessed_variables = true)
@@ -38,9 +38,20 @@ namespace Tensorflow.Gradients
_persistent = persistent;
_watch_accessed_variables = watch_accessed_variables;
_created_eagerly = tf.context.executing_eagerly();
_recording = false;
_created_eagerly = tf.context.executing_eagerly();
// Enters a context inside which operations are recorded on this tape.
if (_created_eagerly)
{
tf.context.ensure_initialized();
tf.context.start_step();
}
_push_tape();
}

/// <summary>
/// Pushes a new tape onto the tape stack.
/// </summary>
private void _push_tape()
{
if (_recording)
@@ -50,8 +61,8 @@ namespace Tensorflow.Gradients
if (_tape == null)
_tape = new Tape(_persistent, _watch_accessed_variables);
else
throw new NotImplementedException("");
tf.GetTapeSet().Add(_tape);
_recording = true;
}

@@ -59,7 +70,7 @@ namespace Tensorflow.Gradients
{
if (!_recording)
throw new ValueError("Tape is not recording.");
_tape.pop_tape(_tape);
_tape.PopTape(_tape);
_recording = false;
}

@@ -69,9 +80,15 @@ namespace Tensorflow.Gradients
/// <param name="x"></param>
public void watch(Tensor x)
{
_tape.watch(x as EagerTensor);
_tape.Watch(x.Id);
}

/// <summary>
/// Computes the gradient using operations recorded in context of this tape.
/// </summary>
/// <param name="target"></param>
/// <param name="source"></param>
/// <returns></returns>
public Tensor gradient(Tensor target, Tensor source)
{
if (_recording)
@@ -80,34 +97,29 @@ namespace Tensorflow.Gradients
_pop_tape();
}

var results = EagerTensorPass.Create();
var targets = EagerTensorPass.From(target);
var sources = EagerTensorPass.From(source);
var results = tf.Runner.TFE_TapeGradient(_tape,
new[] { target },
new[] { source },
null);

Status status = c_api.TFE_TapeGradient(_tape,
targets.Points, targets.Length,
sources.Points, sources.Length,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
return results[0];
}

public Tensor gradient(Tensor target, ResourceVariable source)
{
var results = gradient(target as EagerTensor, new[] { source });
var results = gradient(target, new[] { source });

return results[0];
}

public (Tensor, Tensor) gradient(Tensor target, (ResourceVariable, ResourceVariable) sources)
{
var results = gradient(target as EagerTensor, new[] { sources.Item1, sources.Item2 });
var results = gradient(target, new[] { sources.Item1, sources.Item2 });

return (results[0], results[1]);
}

public EagerTensor[] gradient(EagerTensor target, ResourceVariable[] sources)
public Tensor[] gradient(Tensor target, ResourceVariable[] sources)
{
if (_recording)
{
@@ -115,24 +127,19 @@ namespace Tensorflow.Gradients
_pop_tape();
}

var results = EagerTensorPass.Create(sources.Length);
var target_inputs = EagerTensorPass.From(target);
var source_inputs = EagerTensorPass.From(sources.Select(x => x.Handle).ToArray());

Status status = c_api.TFE_TapeGradient(_tape,
target_inputs.Points, target_inputs.Length,
source_inputs.Points, source_inputs.Length,
results.Points, results.Length);
status.Check(true);
var results = tf.Runner.TFE_TapeGradient(_tape,
new[] { target },
sources.Select(x => x.Handle).ToArray(),
null);

if (!_persistent)
{
// Keep track of watched variables before setting tape to None
_watched_variables = _tape.watched_variables();
_watched_variables = _tape.WatchedVariables();
_tape = null;
}

return results.Items.Select(x => x.Resolve()).ToArray();
return results;
}

public void Dispose()
@@ -140,7 +147,8 @@ namespace Tensorflow.Gradients
if (_recording)
_pop_tape();

tf.tensorMgr.Reset();
if (_created_eagerly)
tf.context.end_step();
}
}
}

+ 33
- 0
src/TensorFlowNET.Core/Gradients/ITape.cs View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Util;
using static Tensorflow.tensorflow;

namespace Tensorflow.Gradients
{
public interface ITape
{
void PopTape(ITape tape);

bool ShouldRecord(long[] tensor_ids, TF_DataType[] dtypes);

void RecordOperation(string op_type,
Tensor[] input_tensors,
TapeTensor[] output_tensors,
long[] input_tensor_id,
TF_DataType[] input_dtypes,
Func<BackwardFunction> backward_function_getter);

void VariableAccessed(ResourceVariable variable);

void Watch(long tensor_id);

ResourceVariable[] WatchedVariables();

Tensor[] ComputeGradient(long[] target_tensor_ids,
long[] source_tensor_ids,
UnorderedMap<long, TapeTensor> sources_that_are_targets,
Tensor[] output_gradients);
}
}

+ 19
- 0
src/TensorFlowNET.Core/Gradients/OpTape.cs View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tensorflow.Util;

namespace Tensorflow.Gradients
{
/// <summary>
/// Map from operation-id to tape entry.
/// </summary>
/// <typeparam name="BackwardFunction"></typeparam>
/// <typeparam name="TapeTensor"></typeparam>
public class OpTape<BackwardFunction, TapeTensor> :
UnorderedMap<long, OpTapeEntry<BackwardFunction, TapeTensor>>
{

}
}

+ 19
- 0
src/TensorFlowNET.Core/Gradients/OpTapeEntry.cs View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Gradients
{
/// <summary>
/// Represents an entry in the tape.
/// </summary>
/// <typeparam name="BackwardFunction"></typeparam>
/// <typeparam name="TapeTensor"></typeparam>
public class OpTapeEntry<BackwardFunction, TapeTensor>
{
public string op_type { get; set; }
public TapeTensor[] output_tensor_info { get; set; }
public long[] input_tensor_id { get; set; }
public BackwardFunction backward_function { get; set; }
}
}

+ 19
- 40
src/TensorFlowNET.Core/Gradients/Tape.cs View File

@@ -1,71 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Tensorflow.Eager;
using Tensorflow.Util;

namespace Tensorflow.Gradients
{
public class Tape : DisposableObject
public class Tape : ITape
{
public int nesting_id { get; set; }

public Tape(bool persistent, bool watch_accessed_variables)
{
_handle = c_api.TFE_TapeSetNew(persistent, watch_accessed_variables);
}

public void watch(EagerTensor x)
public Tensor[] ComputeGradient(long[] target_tensor_ids, long[] source_tensor_ids, UnorderedMap<long, TapeTensor> sources_that_are_targets, Tensor[] output_gradients)
{
c_api.TFE_TapeWatch(_handle, x.EagerTensorHandle);
throw new NotImplementedException();
}

public void pop_tape(Tape tape)
public void PopTape(ITape tape)
{
c_api.TFE_TapeSetRemove(tape);
throw new NotImplementedException();
}

public static void variable_accessed(ResourceVariable variable)
public void RecordOperation(string op_type, Tensor[] input_tensors, TapeTensor[] output_tensors, long[] input_tensor_id, TF_DataType[] input_dtypes, Func<tensorflow.BackwardFunction> backward_function_getter)
{
c_api.TFE_TapeVariableAccessed(variable);
throw new NotImplementedException();
}

public unsafe ResourceVariable[] watched_variables()
public bool ShouldRecord(long[] tensor_ids, TF_DataType[] dtypes)
{
BindingArray result = c_api.TFE_TapeWatchedVariables(_handle);
var variables = result.Data.Select(x =>
{
var tensor = c_api.ResourceVariable_Handle(x);
return new ResourceVariable(x, tensor);
}).ToArray();

return variables;
throw new NotImplementedException();
}

public static bool IsDtypeTrainable(DataType dtype)
public void VariableAccessed(ResourceVariable variable)
{
switch (dtype)
{
case DataType.DtHalf:
case DataType.DtBfloat16:
case DataType.DtFloat:
case DataType.DtDouble:
case DataType.DtComplex64:
case DataType.DtComplex128:
case DataType.DtResource:
case DataType.DtVariant:
return true;
default:
return false;
}
throw new NotImplementedException();
}

protected override void DisposeUnmanagedResources(IntPtr handle)
public void Watch(long tensor_id)
{
throw new NotImplementedException();
}

public static implicit operator IntPtr(Tape tape)
=> tape._handle;
public ResourceVariable[] WatchedVariables()
{
throw new NotImplementedException();
}
}
}

+ 31
- 0
src/TensorFlowNET.Core/Gradients/TapeTensor.cs View File

@@ -0,0 +1,31 @@
using NumSharp;
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Eager;
using static Tensorflow.Binding;

namespace Tensorflow.Gradients
{
public class TapeTensor
{
long id;
TF_DataType dtype;
TensorShape shape;

public TapeTensor(long id, TF_DataType dtype, TensorShape shape)
{
this.id = id;
this.dtype = dtype;
this.shape = shape;
}

public long GetID() => id;

public Tensor ZerosLike(int[] shape = null, TF_DataType dtype = TF_DataType.TF_FLOAT)
=> tf.zeros(shape == null ? new int[0] : shape, dtype: dtype);

public Tensor OnesLike(int[] shape = null, TF_DataType dtype = TF_DataType.TF_FLOAT)
=> tf.ones(shape == null ? new int[0] : shape, dtype: dtype);
}
}

+ 19
- 0
src/TensorFlowNET.Core/Gradients/TensorTape.cs View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using Tensorflow.Util;

namespace Tensorflow.Gradients
{
/// <summary>
/// Map from tensor_id to internally-defined operation-id of the operation which
/// produced this tensor. A value of -1 means that the tensor was directly
/// watched and not the result of any operation in the tape.
/// </summary>
public class TensorTape : UnorderedMap<long, long>
{
}
}

+ 3
- 0
src/TensorFlowNET.Core/Gradients/c_api.gradient.cs View File

@@ -15,7 +15,10 @@
******************************************************************************/

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using Tensorflow.Gradients;

namespace Tensorflow
{


+ 31
- 0
src/TensorFlowNET.Core/Gradients/gradient_exclustions.cs View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Gradients
{
public class gradient_exclustions
{
public static int[] OpGradientUnusedInputIndices(string op_name)
=> op_name switch
{
"FusedBatchNorm" => new[] { 2 },
"FusedBatchNormGradV3" => new[] { 5 },
"FusedBatchNormV2" => new[] { 2 },
"FusedBatchNormV3" => new[] { 2 },
_ => null
};

public static int[] OpGradientUnusedOutputIndices(string op_name)
=> op_name switch
{
"SoftmaxCrossEntropyWithLogits" => new[] { 0 },
"TensorArrayConcat" => new[] { 0 },
"TensorArrayConcatV2" => new[] { 0 },
"TensorArrayConcatV3" => new[] { 0 },
"Mul" => new int[0],
"Sum" => new int[0],
_ => null
};
}
}

+ 3
- 3
src/TensorFlowNET.Core/Gradients/math_grad_eager.cs View File

@@ -30,7 +30,7 @@ namespace Tensorflow.Gradients
public class math_grad_eager
{
[RegisterGradientEager("Mul")]
public static EagerTensor[] _MulGrad(EagerOperation op, IntPtr[] grads)
public static Tensor[] _MulGrad(EagerOperation op, IntPtr[] grads)
{
var x = op.InputHandles[0];
var y = op.InputHandles[1];
@@ -39,7 +39,7 @@ namespace Tensorflow.Gradients
if (op.SkipInputIndices.Contains(1) &&
EagerTensor.GetRank(grad) == 0)
{
return new EagerTensor[]
return new Tensor[]
{
null,//gen_math_ops.mul(grad, math_ops.conj(y)),
null
@@ -48,7 +48,7 @@ namespace Tensorflow.Gradients

if (_ShapesFullySpecifiedAndEqual(x, y, grad))
{
return new EagerTensor[]
return new Tensor[]
{
gen_math_ops.mul(grad, y),
gen_math_ops.mul(grad, x)


+ 0
- 101
src/TensorFlowNET.Core/Gradients/ops.gradient_function_mapping_eager.cs View File

@@ -1,101 +0,0 @@
/*****************************************************************************
Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Tensorflow.Eager;
using Tensorflow.Gradients;

namespace Tensorflow
{
public partial class ops
{
public static Dictionary<string, Func<EagerOperation, IntPtr[], EagerTensor[]>> gradientFunctionsEager = null;

public static void RegisterFromAssemblyEager()
{
if (gradientFunctionsEager == null)
{
gradientFunctionsEager = new Dictionary<string, Func<EagerOperation, IntPtr[], EagerTensor[]>>();

var gradGroups = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => x.GetCustomAttribute<RegisterGradientEager>() != null)
.ToArray();

foreach (var g in gradGroups)
{
var methods = g.GetMethods()
.Where(x => x.GetCustomAttribute<RegisterGradientEager>() != null)
.ToArray();

foreach (var m in methods)
{
RegisterGradientFunctionEager(m.GetCustomAttribute<RegisterGradientEager>().Name,
(oper, out_grads) =>
g.InvokeMember(m.Name,
BindingFlags.InvokeMethod,
null,
null,
args: new object[] { oper, out_grads }) as EagerTensor[]
);
}

// REGISTER_NO_GRADIENT_OP
methods = g.GetMethods()
.Where(x => x.GetCustomAttribute<RegisterNoGradient>() != null)
.ToArray();

foreach (var m in methods)
RegisterNoGradientFunctionEager(m.GetCustomAttribute<RegisterNoGradient>().Name);
}
}
}

/// <summary>
/// Regiter new gradient function
/// </summary>
/// <param name="name">operation type</param>
/// <param name="func">function delegate</param>
public static void RegisterGradientFunctionEager(string name, Func<EagerOperation, IntPtr[], EagerTensor[]> func)
{
RegisterFromAssemblyEager();

gradientFunctionsEager[name] = func;
}

public static void RegisterNoGradientFunctionEager(string name)
{
RegisterFromAssemblyEager();

gradientFunctionsEager[name] = null;
}

public static Func<EagerOperation, IntPtr[], EagerTensor[]> get_gradient_function_eager(EagerOperation op)
{
if (op.inputs == null) return null;

RegisterFromAssemblyEager();

if (!gradientFunctionsEager.ContainsKey(op.type))
throw new LookupError($"can't get graident function through get_gradient_function {op.type}");

return gradientFunctionsEager[op.type];
}
}
}

+ 1
- 18
src/TensorFlowNET.Core/Graphs/Graph.Operation.cs View File

@@ -26,24 +26,7 @@ namespace Tensorflow
public partial class Graph
{
public OpDef GetOpDef(string type)
{
using (var buffer = new Buffer())
using (var status = new Status())
{
c_api.TF_GraphGetOpDef(_handle, type, buffer, status);
return OpDef.Parser.ParseFrom(buffer.MemoryBlock.Stream());
}
}

public static OpDef TFE_GetOpDef(string type)
{
IntPtr handle = tf.get_default_graph();
using var buffer = new Buffer();
using var status = new Status();
c_api.TF_GraphGetOpDef(handle, type, buffer, status);
using var stream = buffer.MemoryBlock.Stream();
return OpDef.Parser.ParseFrom(stream);
}
=> op_def_registry.GetOpDef(type);

public OperationDescription NewOperation(string opType, string opName)
{


+ 46
- 63
src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs View File

@@ -16,15 +16,12 @@

using System;
using System.Linq;
using Tensorflow.Eager;
using static Tensorflow.Binding;

namespace Tensorflow.Operations
{
public class gen_nn_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

/// <summary>
/// Computes a 2-D convolution given 4-D `input` and `filter` tensors.
///
@@ -45,7 +42,7 @@ namespace Tensorflow.Operations
/// <returns></returns>
public static Tensor conv2d(Conv2dParams parameters)
{
var _op = _op_def_lib._apply_op_helper("Conv2D", name: parameters.Name, args: new
var _op = tf._op_def_lib._apply_op_helper("Conv2D", name: parameters.Name, args: new
{
input = parameters.Input,
filter = parameters.Filter,
@@ -67,7 +64,7 @@ namespace Tensorflow.Operations
/// <returns></returns>
public static Tensor conv2d_backprop_filter(Conv2dParams parameters)
{
var _op = _op_def_lib._apply_op_helper("Conv2DBackpropFilter", name: parameters.Name, args: new
var _op = tf._op_def_lib._apply_op_helper("Conv2DBackpropFilter", name: parameters.Name, args: new
{
input = parameters.Input,
filter_sizes = parameters.FilterSizes,
@@ -90,7 +87,7 @@ namespace Tensorflow.Operations
/// <returns></returns>
public static Tensor conv2d_backprop_input(Conv2dParams parameters)
{
var _op = _op_def_lib._apply_op_helper("Conv2DBackpropInput", name: parameters.Name, args: new
var _op = tf._op_def_lib._apply_op_helper("Conv2DBackpropInput", name: parameters.Name, args: new
{
input_sizes = parameters.InputSizes,
filter = parameters.Filter,
@@ -114,7 +111,7 @@ namespace Tensorflow.Operations
if (data_format == null)
data_format = "NHWC";

var _op = _op_def_lib._apply_op_helper("BiasAdd", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("BiasAdd", name: name, args: new
{
value,
bias,
@@ -131,7 +128,7 @@ namespace Tensorflow.Operations
if (data_format == null)
data_format = "NHWC";

var _op = _op_def_lib._apply_op_helper("BiasAddGrad", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("BiasAddGrad", name: name, args: new
{
out_backprop,
data_format
@@ -157,7 +154,7 @@ namespace Tensorflow.Operations
/// </remarks>
public static Tensor elu(Tensor features, string name = "Elu")
{
var op = _op_def_lib._apply_op_helper("Elu", name: name, args: new { features });
var op = tf._op_def_lib._apply_op_helper("Elu", name: name, args: new { features });
return op.output;
}

@@ -176,7 +173,7 @@ namespace Tensorflow.Operations
/// <returns></returns>
public static Tensor[] fused_batch_norm_grad(FusedBatchNormParams @params)
{
var op = _op_def_lib._apply_op_helper("FusedBatchNormGrad", name: @params.Name, args: new
var op = tf._op_def_lib._apply_op_helper("FusedBatchNormGrad", name: @params.Name, args: new
{
y_backprop = @params.YBackprop,
x = @params.X,
@@ -192,7 +189,7 @@ namespace Tensorflow.Operations

public static Tensor[] fused_batch_norm_grad_v3(FusedBatchNormParams @params)
{
var op = _op_def_lib._apply_op_helper("FusedBatchNormGradV3", name: @params.Name, args: new
var op = tf._op_def_lib._apply_op_helper("FusedBatchNormGradV3", name: @params.Name, args: new
{
y_backprop = @params.YBackprop,
x = @params.X,
@@ -217,7 +214,7 @@ namespace Tensorflow.Operations
bool is_training = true,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("FusedBatchNorm", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("FusedBatchNorm", name: name, args: new
{
x,
scale,
@@ -242,7 +239,7 @@ namespace Tensorflow.Operations
bool is_training = true,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("FusedBatchNormV3", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("FusedBatchNormV3", name: name, args: new
{
x,
scale,
@@ -270,7 +267,7 @@ namespace Tensorflow.Operations
public static Tensor local_response_normalization(Tensor input, int depth_radius = 5, int bias = 1,
int alpha = 1, float beta = 0.5f, string name = null)
{
var _op = _op_def_lib._apply_op_helper("LRN", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("LRN", name: name, args: new
{
input,
depth_radius,
@@ -284,7 +281,7 @@ namespace Tensorflow.Operations

public static Tensor log_softmax(Tensor logits, string name = null)
{
var _op = _op_def_lib._apply_op_helper("LogSoftmax", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("LogSoftmax", name: name, args: new
{
logits
});
@@ -302,7 +299,7 @@ namespace Tensorflow.Operations
/// <returns>A `Tensor` of type `bool`.</returns>
public static Tensor in_top_kv2(Tensor predictions, Tensor targets, int k, string name = null)
{
var _op = _op_def_lib._apply_op_helper("InTopKV2", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("InTopKV2", name: name, args: new
{
predictions,
targets,
@@ -314,7 +311,7 @@ namespace Tensorflow.Operations

public static Tensor leaky_relu(Tensor features, float alpha = 0.2f, string name = null)
{
var _op = _op_def_lib._apply_op_helper("LeakyRelu", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("LeakyRelu", name: name, args: new
{
features,
alpha
@@ -330,7 +327,7 @@ namespace Tensorflow.Operations
string data_format = "NHWC",
string name = null)
{
var _op = _op_def_lib._apply_op_helper("MaxPool", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("MaxPool", name: name, args: new
{
input,
ksize,
@@ -345,7 +342,7 @@ namespace Tensorflow.Operations
public static Tensor max_pool_grad(Tensor orig_input, Tensor orig_output, Tensor grad, int[] ksize, int[] strides, string padding,
string data_format= "NHWC", string name= null)
{
var _op = _op_def_lib._apply_op_helper("MaxPoolGrad", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("MaxPoolGrad", name: name, args: new
{
orig_input,
orig_output,
@@ -361,7 +358,7 @@ namespace Tensorflow.Operations

public static Tensor[] top_kv2(Tensor input, int k, bool sorted = true, string name = null)
{
var _op = _op_def_lib._apply_op_helper("TopKV2", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("TopKV2", name: name, args: new
{
input,
k,
@@ -375,18 +372,15 @@ namespace Tensorflow.Operations
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(gradients, features);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"ReluGrad", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
null,
gradients, features);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("ReluGrad", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("ReluGrad", name: name, args: new
{
gradients,
features
@@ -397,7 +391,7 @@ namespace Tensorflow.Operations

public static Tensor leaky_relu_grad(Tensor gradients, Tensor features, float alpha = 0.2f, string name = null)
{
var _op = _op_def_lib._apply_op_helper("LeakyReluGrad", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("LeakyReluGrad", name: name, args: new
{
gradients,
features,
@@ -411,18 +405,15 @@ namespace Tensorflow.Operations
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(logits);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Softmax", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
null,
logits);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("Softmax", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("Softmax", name: name, args: new
{
logits
});
@@ -439,7 +430,7 @@ namespace Tensorflow.Operations
/// <returns></returns>
public static (Tensor, Tensor) softmax_cross_entropy_with_logits(Tensor features, Tensor labels, string name = null)
{
var _op = _op_def_lib._apply_op_helper("SoftmaxCrossEntropyWithLogits", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("SoftmaxCrossEntropyWithLogits", name: name, args: new
{
features,
labels
@@ -477,7 +468,7 @@ namespace Tensorflow.Operations
/// </remarks>
public static (Tensor loss, Tensor backprop) sparse_softmax_cross_entropy_with_logits(Tensor features, Tensor labels, string name = "SparseSoftmaxCrossEntropyWithLogits")
{
var op = _op_def_lib._apply_op_helper("SparseSoftmaxCrossEntropyWithLogits", name: name, args: new { features, labels });
var op = tf._op_def_lib._apply_op_helper("SparseSoftmaxCrossEntropyWithLogits", name: name, args: new { features, labels });
int _idx = 0;
var loss = op.outputs[_idx++];
var backprop = op.outputs[_idx++];
@@ -494,19 +485,15 @@ namespace Tensorflow.Operations
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Relu", name, new IntPtr[]
{
features as EagerTensor,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Relu", name,
null,
features);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("Relu", name: name, args: new { features });
var _op = tf._op_def_lib._apply_op_helper("Relu", name: name, args: new { features });
return _op.outputs[0];
}

@@ -514,19 +501,15 @@ namespace Tensorflow.Operations
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Tanh", name, new IntPtr[]
{
x as EagerTensor,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Tanh", name,
null,
x);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("Tanh", name: name, args: new { x });
var _op = tf._op_def_lib._apply_op_helper("Tanh", name: name, args: new { x });
return _op.outputs[0];
}
}


+ 118
- 186
src/TensorFlowNET.Core/Operations/gen_array_ops.cs View File

@@ -14,32 +14,27 @@
limitations under the License.
******************************************************************************/

using NumSharp;
using System;
using System.Collections.Generic;
using static Tensorflow.Binding;
using Tensorflow.Eager;
using System.Linq;
using static Tensorflow.Binding;
using System.Security.Cryptography.X509Certificates;

namespace Tensorflow
{
public static class gen_array_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();
public static Execute _execute = new Execute();

public static Tensor batch_to_space_nd<T>(T input, int[] block_shape, int[,] crops, string name = null)
{
var _op = _op_def_lib._apply_op_helper("BatchToSpaceND", name: name, args: new { input, block_shape, crops });
var _op = tf._op_def_lib._apply_op_helper("BatchToSpaceND", name: name, args: new { input, block_shape, crops });

return _op.output;
}
public static Tensor check_numerics(Tensor tensor, string message, string name = null)
{
var _op = _op_def_lib._apply_op_helper("CheckNumerics", name: name, args: new { tensor, message });
var _op = tf._op_def_lib._apply_op_helper("CheckNumerics", name: name, args: new { tensor, message });

return _op.output;
}
@@ -55,20 +50,15 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"ConcatV2", name, new IntPtr[]
{
values as EagerTensor,
axis as EagerTensor
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"ConcatV2", name,
null,
values, axis);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("ConcatV2", name: name, args: new { values, axis });
var _op = tf._op_def_lib._apply_op_helper("ConcatV2", name: name, args: new { values, axis });
return _op.output;
}

@@ -79,24 +69,24 @@ namespace Tensorflow
return concat_v2_eager_fallback(values, axis, name, tf.context);
}

var _op = _op_def_lib._apply_op_helper("ConcatV2", name: name, args: new { values, axis });
var _op = tf._op_def_lib._apply_op_helper("ConcatV2", name: name, args: new { values, axis });
return _op.output;
}

private static Tensor concat_v2_eager_fallback<T1, T2>(T1[] values, T2 axis, string name, Context ctx)
{
var _attr_N = len(values);
var (_attr_T, input) = _execute.args_to_matching_eager(ctx, args: values.Select(x => (object)x).ToArray());
var (_attr_Tidx, axis1) = _execute.args_to_matching_eager(ctx, default_dtype: tf.int32, args: new object[] { axis });
var (_attr_T, input) = tf._execute.args_to_matching_eager(ctx, args: values.Select(x => (object)x).ToArray());
var (_attr_Tidx, axis1) = tf._execute.args_to_matching_eager(ctx, default_dtype: tf.int32, args: new object[] { axis });
var _inputs_flat = input.concat(axis1);
var _attrs = new object[] { "N", _attr_N, "T", _attr_T, "Tidx", _attr_Tidx };

return _execute.execute(ctx, "ConcatV2", 1, _inputs_flat, _attrs, name: name)[0];
return tf._execute.execute(ctx, "ConcatV2", 1, _inputs_flat, _attrs, name: name)[0];
}

public static Tensor[] concat_offset(Tensor concat_dim, Tensor[] shape, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ConcatOffset", name: name, args: new { concat_dim, shape });
var _op = tf._op_def_lib._apply_op_helper("ConcatOffset", name: name, args: new { concat_dim, shape });

return _op.outputs;
}
@@ -134,28 +124,28 @@ namespace Tensorflow
/// </remarks>
public static Tensor diag(Tensor diagonal, string name = null)
{
var op = _op_def_lib._apply_op_helper("Diag", name: name, args: new { diagonal });
var op = tf._op_def_lib._apply_op_helper("Diag", name: name, args: new { diagonal });

return op.output;
}

public static Tensor expand_dims(Tensor input, int axis, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ExpandDims", name: name, args: new { input, dim = axis });
var _op = tf._op_def_lib._apply_op_helper("ExpandDims", name: name, args: new { input, dim = axis });

return _op.outputs[0];
}

public static Tensor gather_v2<T1, T2>(T1 @params, T2 indices, int axis, string name = null)
{
var _op = _op_def_lib._apply_op_helper("GatherV2", name: name, new { @params, indices, axis });
var _op = tf._op_def_lib._apply_op_helper("GatherV2", name: name, new { @params, indices, axis });

return _op.outputs[0];
}

public static Tensor pad(Tensor input, Tensor paddings, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Pad", name: name, args: new { input, paddings });
var _op = tf._op_def_lib._apply_op_helper("Pad", name: name, args: new { input, paddings });

return _op.output;
}
@@ -164,7 +154,7 @@ namespace Tensorflow
{
if(tf.context.executing_eagerly())
{
var results = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Pack", name,
null,
values,
@@ -172,13 +162,13 @@ namespace Tensorflow
return results[0];
}

var _op = _op_def_lib._apply_op_helper("Pack", name: name, args: new { values, axis });
var _op = tf._op_def_lib._apply_op_helper("Pack", name: name, args: new { values, axis });
return _op.output;
}

public static Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Placeholder", name: name, args: new { dtype, shape });
var _op = tf._op_def_lib._apply_op_helper("Placeholder", name: name, args: new { dtype, shape });
var _result = _op.outputs;
var _inputs_flat = _op.inputs;

@@ -217,7 +207,7 @@ namespace Tensorflow
/// </remarks>
public static Tensor prevent_gradient(Tensor input, string message = "", string name = null)
{
var op = _op_def_lib._apply_op_helper("PreventGradient", name: name, args: new { input, message });
var op = tf._op_def_lib._apply_op_helper("PreventGradient", name: name, args: new { input, message });
return op.output;
}

@@ -230,40 +220,36 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Identity", name, new IntPtr[]
{
input as EagerTensor
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Identity", name,
null,
input);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("Identity", name, new { input });
var _op = tf._op_def_lib._apply_op_helper("Identity", name, new { input });

return _op.output;
}

public static Tensor invert_permutation(Tensor x, string name = null)
{
var _op = _op_def_lib._apply_op_helper("InvertPermutation", name, new { x });
var _op = tf._op_def_lib._apply_op_helper("InvertPermutation", name, new { x });

return _op.outputs[0];
}

public static Tensor log(Tensor x, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Log", name: name, args: new { x });
var _op = tf._op_def_lib._apply_op_helper("Log", name: name, args: new { x });

return _op.outputs[0];
}

public static Tensor rank(Tensor input, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Rank", name: name, args: new { input });
var _op = tf._op_def_lib._apply_op_helper("Rank", name: name, args: new { input });

return _op.outputs[0];
}
@@ -279,20 +265,15 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(dims, value);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Fill", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
null,
dims, value);

return results[0].Resolve();
return results[0];
}

var _op = _op_def_lib._apply_op_helper("Fill", name, new { dims, value });
var _op = tf._op_def_lib._apply_op_helper("Fill", name, new { dims, value });
return _op.output;
}

@@ -307,27 +288,22 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor(), new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"BroadcastGradientArgs", name, new IntPtr[]
{
s0 as EagerTensor,
s1 as EagerTensor
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return (results[0].Resolve(), results[1].Resolve());
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"BroadcastGradientArgs", name,
null,
s0,s1);
return (results[0], results[1]);
}

var _op = _op_def_lib._apply_op_helper("BroadcastGradientArgs", name, new { s0, s1 });
var _op = tf._op_def_lib._apply_op_helper("BroadcastGradientArgs", name, new { s0, s1 });

return (_op.outputs[0], _op.outputs[1]);
}

public static Tensor reverse<T>(Tensor tensor, T axis, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ReverseV2", name, new { tensor, axis });
var _op = tf._op_def_lib._apply_op_helper("ReverseV2", name, new { tensor, axis });
return _op.output;
}

@@ -335,26 +311,21 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Reshape", name, new IntPtr[]
{
tensor as EagerTensor,
shape as EagerTensor
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Reshape", name,
null,
tensor, shape);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("Reshape", name, new { tensor, shape });
var _op = tf._op_def_lib._apply_op_helper("Reshape", name, new { tensor, shape });
return _op.output;
}

public static Tensor reshape(Tensor tensor, int[] shape, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Reshape", name, new { tensor, shape });
var _op = tf._op_def_lib._apply_op_helper("Reshape", name, new { tensor, shape });
return _op.outputs[0];
}

@@ -367,7 +338,7 @@ namespace Tensorflow
/// <returns></returns>
public static (Tensor, Tensor) unique(Tensor x, TF_DataType out_idx = TF_DataType.TF_INT32, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Unique", name, new { x, out_idx });
var _op = tf._op_def_lib._apply_op_helper("Unique", name, new { x, out_idx });
// TODO
//var _result = _UniqueOutput._make(_op.outputs);
return (_op.outputs[0], _op.outputs[1]);
@@ -375,13 +346,13 @@ namespace Tensorflow

public static Tensor[] unpack(Tensor value, int num, int axis = 0, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Unpack", name, new { value, num, axis });
var _op = tf._op_def_lib._apply_op_helper("Unpack", name, new { value, num, axis });
return _op.outputs;
}

public static Tensor where(Tensor condition, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Where", name, new { input = condition });
var _op = tf._op_def_lib._apply_op_helper("Where", name, new { input = condition });
return _op.output;
}

@@ -394,22 +365,16 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(indices, depth, on_value, off_value);
var attrs = new object[] { "axis", axis };

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"OneHot", name,
inputs.Points, inputs.Length,
wrap_tfe_src.SetOpAttrs2(attrs),
op => wrap_tfe_src.SetOpAttrs(op, attrs),
results.Points, results.Length);
status.Check(true);
null,
indices, depth, on_value, off_value,
"axis", axis);

return results[0].Resolve();
return results[0];
}

var _op = _op_def_lib._apply_op_helper("OneHot", name, new { indices, depth, on_value, off_value, axis });
var _op = tf._op_def_lib._apply_op_helper("OneHot", name, new { indices, depth, on_value, off_value, axis });
return _op.outputs[0];
}

@@ -422,7 +387,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor placeholder_with_default<T>(T input, int[] shape, string name = null)
{
var _op = _op_def_lib._apply_op_helper("PlaceholderWithDefault", name, new { input, shape, name });
var _op = tf._op_def_lib._apply_op_helper("PlaceholderWithDefault", name, new { input, shape, name });
return _op.outputs[0];
}

@@ -430,26 +395,21 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(condition, t, e);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"SelectV2", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"SelectV2", name,
null,
condition, t, e);

return results[0].Resolve();
return results[0];
}

var _op = _op_def_lib._apply_op_helper("Select", name, new { condition, t, e });
var _op = tf._op_def_lib._apply_op_helper("Select", name, new { condition, t, e });
return _op.outputs[0];
}

public static Tensor scatter_nd(Tensor indices, Tensor updates, Tensor[] shape, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ScatterNd", name, new { indices, updates, shape });
var _op = tf._op_def_lib._apply_op_helper("ScatterNd", name, new { indices, updates, shape });
return _op.outputs[0];
}

@@ -457,20 +417,16 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Shape", name, new IntPtr[]
{
input as EagerTensor,
}, 1,
wrap_tfe_src.SetOpAttrs2("out_type", out_type),
op => wrap_tfe_src.SetOpAttrs(op, "out_type", out_type),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Shape", name,
null,
input,
"out_type", out_type);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("Shape", name, new { input, out_type });
var _op = tf._op_def_lib._apply_op_helper("Shape", name, new { input, out_type });
return _op.outputs[0];
}

@@ -483,13 +439,13 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor[] shape_n(Tensor[] input, TF_DataType out_type = TF_DataType.TF_INT32, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ShapeN", name, new { input, out_type });
var _op = tf._op_def_lib._apply_op_helper("ShapeN", name, new { input, out_type });
return _op.outputs;
}

public static Tensor size(Tensor input, TF_DataType out_type = TF_DataType.TF_INT32, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Size", name, new { input, out_type });
var _op = tf._op_def_lib._apply_op_helper("Size", name, new { input, out_type });
return _op.outputs[0];
}

@@ -503,13 +459,13 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor slice(Tensor input, Tensor begin, Tensor size, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Slice", name, new { input, begin, size });
var _op = tf._op_def_lib._apply_op_helper("Slice", name, new { input, begin, size });
return _op.outputs[0];
}

public static Tensor[] split(Tensor axis, Tensor value, int num_split, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Split", name, new { split_dim = axis, value, num_split });
var _op = tf._op_def_lib._apply_op_helper("Split", name, new { split_dim = axis, value, num_split });
return _op.outputs;
}

@@ -517,38 +473,33 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Tile", name, new IntPtr[]
{
input as EagerTensor,
multiples as EagerTensor
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Tile", name,
null,
input, multiples);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("Tile", name, new { input, multiples });
var _op = tf._op_def_lib._apply_op_helper("Tile", name, new { input, multiples });
return _op.outputs[0];
}

public static Tensor transpose<T1, T2>(T1 x, T2 perm, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Transpose", name, new { x, perm });
var _op = tf._op_def_lib._apply_op_helper("Transpose", name, new { x, perm });
return _op.outputs[0];
}

public static Tensor zeros_like(Tensor x, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ZerosLike", name, new { x });
var _op = tf._op_def_lib._apply_op_helper("ZerosLike", name, new { x });
return _op.outputs[0];
}

public static Tensor stop_gradient(Tensor x, string name = null)
{
var _op = _op_def_lib._apply_op_helper("StopGradient", name, args: new { input = x, name });
var _op = tf._op_def_lib._apply_op_helper("StopGradient", name, args: new { input = x, name });

return _op.output;
}
@@ -563,31 +514,20 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var attrs = new object[]
{
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"StridedSlice", name,
null,
input, begin, end, strides,
"begin_mask", begin_mask,
"end_mask", end_mask,
"ellipsis_mask", ellipsis_mask,
"new_axis_mask", new_axis_mask,
"shrink_axis_mask", shrink_axis_mask
};
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"StridedSlice", name, new IntPtr[]
{
input as EagerTensor,
begin as EagerTensor,
end as EagerTensor,
strides as EagerTensor,
}, 4,
wrap_tfe_src.SetOpAttrs2(attrs),
op => wrap_tfe_src.SetOpAttrs(op, attrs),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
"shrink_axis_mask", shrink_axis_mask);
return results[0];
}

var _op = _op_def_lib._apply_op_helper("StridedSlice", name, new
var _op = tf._op_def_lib._apply_op_helper("StridedSlice", name, new
{
input,
begin,
@@ -611,7 +551,7 @@ namespace Tensorflow
int shrink_axis_mask = 0,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("StridedSlice", name, new
var _op = tf._op_def_lib._apply_op_helper("StridedSlice", name, new
{
input,
begin,
@@ -651,7 +591,7 @@ namespace Tensorflow
int begin_mask = 0, int end_mask = 0, int ellipsis_mask = 0, int new_axis_mask = 0,
int shrink_axis_mask = 0, string name = null)
{
var op = _op_def_lib._apply_op_helper("StridedSliceGrad", name: name, args: new
var op = tf._op_def_lib._apply_op_helper("StridedSliceGrad", name: name, args: new
{
shape,
begin,
@@ -670,7 +610,7 @@ namespace Tensorflow

public static Tensor slice<Tb, Ts>(Tensor input, Tb begin, Ts size, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Slice", name, new { input, begin, size });
var _op = tf._op_def_lib._apply_op_helper("Slice", name, new { input, begin, size });
return _op.outputs[0];
}

@@ -689,21 +629,17 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Squeeze", name, new IntPtr[]
{
input as EagerTensor
}, 1,
wrap_tfe_src.SetOpAttrs2("squeeze_dims", axis),
op => wrap_tfe_src.SetOpAttrs(op, "squeeze_dims", axis),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Squeeze", name,
null,
input,
"squeeze_dims", axis);

return results[0];
}

if (axis == null) axis = new int[0];
var _op = _op_def_lib._apply_op_helper("Squeeze", name, args: new { input, squeeze_dims = axis });
var _op = tf._op_def_lib._apply_op_helper("Squeeze", name, args: new { input, squeeze_dims = axis });

return _op.outputs[0];
}
@@ -719,7 +655,7 @@ namespace Tensorflow
/// <returns> `Tensor`. Has the same type as `s0`.</returns>
public static Tensor broadcast_args(Tensor s0, Tensor s1, string name = null)
{
var _op = _op_def_lib._apply_op_helper("BroadcastArgs", name, args: new { s0, s1, name });
var _op = tf._op_def_lib._apply_op_helper("BroadcastArgs", name, args: new { s0, s1, name });

return _op.outputs[0];
}
@@ -735,19 +671,15 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(input, shape);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"BroadcastTo", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
null,
input, shape);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("BroadcastTo", name, args: new { input, shape, name });
var _op = tf._op_def_lib._apply_op_helper("BroadcastTo", name, args: new { input, shape, name });

return _op.outputs[0];
}


+ 13
- 14
src/TensorFlowNET.Core/Operations/gen_control_flow_ops.cs View File

@@ -15,16 +15,15 @@
******************************************************************************/

using Tensorflow.Operations;
using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_control_flow_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Operation control_trigger(string name = null)
{
var _op = _op_def_lib._apply_op_helper("ControlTrigger", name, new
var _op = tf._op_def_lib._apply_op_helper("ControlTrigger", name, new
{
});

@@ -42,7 +41,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor enter(Tensor data, string frame_name = "frame_name", bool is_constant = false, int parallel_iterations = 10, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Enter", name, new
var _op = tf._op_def_lib._apply_op_helper("Enter", name, new
{
data,
frame_name,
@@ -61,7 +60,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor loop_cond(Tensor input, string name = null)
{
var _op = _op_def_lib._apply_op_helper("LoopCond", name, new { input });
var _op = tf._op_def_lib._apply_op_helper("LoopCond", name, new { input });

return _op.output;
}
@@ -74,7 +73,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor ref_next_iteration(Tensor data, string name = null)
{
var _op = _op_def_lib._apply_op_helper("RefNextIteration", name, new { data });
var _op = tf._op_def_lib._apply_op_helper("RefNextIteration", name, new { data });

return _op;
}
@@ -87,7 +86,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor next_iteration(Tensor data, string name = null)
{
var _op = _op_def_lib._apply_op_helper("NextIteration", name, new { data });
var _op = tf._op_def_lib._apply_op_helper("NextIteration", name, new { data });

return _op;
}
@@ -100,7 +99,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor ref_exit(Tensor data, string name = null)
{
var _op = _op_def_lib._apply_op_helper("RefExit", name, new { data });
var _op = tf._op_def_lib._apply_op_helper("RefExit", name, new { data });

return _op;
}
@@ -113,21 +112,21 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor _exit(Tensor data, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Exit", name, new { data });
var _op = tf._op_def_lib._apply_op_helper("Exit", name, new { data });

return _op;
}

public static Operation no_op(string name = null)
{
var _op = _op_def_lib._apply_op_helper("NoOp", name, null);
var _op = tf._op_def_lib._apply_op_helper("NoOp", name, null);

return _op;
}

public static Tensor[] ref_switch(Tensor data, Tensor pred, string name = null)
{
var _op = _op_def_lib._apply_op_helper("RefSwitch", name, new { data, pred });
var _op = tf._op_def_lib._apply_op_helper("RefSwitch", name, new { data, pred });
return _op.outputs;
}

@@ -151,7 +150,7 @@ namespace Tensorflow
/// </returns>
public static Tensor[] @switch(Tensor data, Tensor pred, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Switch", name, new { data, pred });
var _op = tf._op_def_lib._apply_op_helper("Switch", name, new { data, pred });
var _inputs_flat = _op.inputs;
var _attrs = ("T", _op.get_attr("T"));
// TODO: missing original code
@@ -161,14 +160,14 @@ namespace Tensorflow

public static MergeOutput ref_merge(Tensor[] inputs, string name = null)
{
var _op = _op_def_lib._apply_op_helper("RefMerge", name, new { inputs });
var _op = tf._op_def_lib._apply_op_helper("RefMerge", name, new { inputs });

return new MergeOutput(_op.outputs);
}

public static MergeOutput merge(Tensor[] inputs, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Merge", name, new { inputs });
var _op = tf._op_def_lib._apply_op_helper("Merge", name, new { inputs });

return new MergeOutput(_op.outputs);
}


+ 3
- 3
src/TensorFlowNET.Core/Operations/gen_ctc_ops.cs View File

@@ -14,15 +14,15 @@
limitations under the License.
******************************************************************************/

using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_ctc_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Tensor[] ctc_greedy_decoder(Tensor inputs, Tensor sequence_length, bool merge_repeated = true, string name = "CTCGreedyDecoder")
{
var op = _op_def_lib._apply_op_helper("CTCGreedyDecoder", name: name, args: new
var op = tf._op_def_lib._apply_op_helper("CTCGreedyDecoder", name: name, args: new
{
inputs,
sequence_length,


+ 23
- 23
src/TensorFlowNET.Core/Operations/gen_data_flow_ops.cs View File

@@ -14,15 +14,15 @@
limitations under the License.
******************************************************************************/

using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_data_flow_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Tensor dynamic_stitch(Tensor[] indices, Tensor[] data, string name = null)
{
var _op = _op_def_lib._apply_op_helper("DynamicStitch", name, new { indices, data });
var _op = tf._op_def_lib._apply_op_helper("DynamicStitch", name, new { indices, data });

return _op.output;
}
@@ -30,7 +30,7 @@ namespace Tensorflow
public static Tensor[] dynamic_partition(Tensor data, Tensor partitions, int num_partitions,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("DynamicPartition", name, new
var _op = tf._op_def_lib._apply_op_helper("DynamicPartition", name, new
{
data,
partitions,
@@ -44,7 +44,7 @@ namespace Tensorflow
TensorShape element_shape = null, bool dynamic_size = false, bool clear_after_read = true,
bool identical_element_shapes = false, string tensor_array_name = "", string name = null)
{
var _op = _op_def_lib._apply_op_helper("TensorArrayV3", name, new
var _op = tf._op_def_lib._apply_op_helper("TensorArrayV3", name, new
{
size,
dtype,
@@ -61,7 +61,7 @@ namespace Tensorflow
public static Tensor tensor_array_scatter_v3(Tensor handle, Tensor indices, Tensor value,
Tensor flow_in, string name = null)
{
var _op = _op_def_lib._apply_op_helper("TensorArrayScatterV3", name, new
var _op = tf._op_def_lib._apply_op_helper("TensorArrayScatterV3", name, new
{
handle,
indices,
@@ -76,7 +76,7 @@ namespace Tensorflow
int capacity = -1, string container = "", string shared_name = "",
string name = null)
{
var _op = _op_def_lib._apply_op_helper("PaddingFIFOQueueV2", name, new
var _op = tf._op_def_lib._apply_op_helper("PaddingFIFOQueueV2", name, new
{
component_types,
shapes,
@@ -92,7 +92,7 @@ namespace Tensorflow
int capacity = -1, string container = "", string shared_name = "",
string name = null)
{
var _op = _op_def_lib._apply_op_helper("FIFOQueueV2", name, new
var _op = tf._op_def_lib._apply_op_helper("FIFOQueueV2", name, new
{
component_types,
shapes,
@@ -108,7 +108,7 @@ namespace Tensorflow
int capacity = -1, string container = "", string shared_name = "",
string name = null)
{
var _op = _op_def_lib._apply_op_helper("PriorityQueueV2", name, new
var _op = tf._op_def_lib._apply_op_helper("PriorityQueueV2", name, new
{
component_types,
shapes,
@@ -124,7 +124,7 @@ namespace Tensorflow
int capacity = -1, int min_after_dequeue = 0, int seed = 0, int seed2 = 0,
string container = "", string shared_name = "", string name = null)
{
var _op = _op_def_lib._apply_op_helper("RandomShuffleQueueV2", name, new
var _op = tf._op_def_lib._apply_op_helper("RandomShuffleQueueV2", name, new
{
component_types,
shapes,
@@ -141,7 +141,7 @@ namespace Tensorflow

public static Operation queue_enqueue(Tensor handle, Tensor[] components, int timeout_ms = -1, string name = null)
{
var _op = _op_def_lib._apply_op_helper("QueueEnqueue", name, new
var _op = tf._op_def_lib._apply_op_helper("QueueEnqueue", name, new
{
handle,
components,
@@ -153,7 +153,7 @@ namespace Tensorflow

public static Operation queue_enqueue_v2(Tensor handle, Tensor[] components, int timeout_ms = -1, string name = null)
{
var _op = _op_def_lib._apply_op_helper("QueueEnqueueV2", name, new
var _op = tf._op_def_lib._apply_op_helper("QueueEnqueueV2", name, new
{
handle,
components,
@@ -165,7 +165,7 @@ namespace Tensorflow

public static Tensor[] queue_dequeue_v2(Tensor handle, TF_DataType[] component_types, int timeout_ms = -1, string name = null)
{
var _op = _op_def_lib._apply_op_helper("QueueDequeueV2", name, new
var _op = tf._op_def_lib._apply_op_helper("QueueDequeueV2", name, new
{
handle,
component_types,
@@ -177,7 +177,7 @@ namespace Tensorflow

public static Tensor[] queue_dequeue(Tensor handle, TF_DataType[] component_types, int timeout_ms = -1, string name = null)
{
var _op = _op_def_lib._apply_op_helper("QueueDequeue", name, new
var _op = tf._op_def_lib._apply_op_helper("QueueDequeue", name, new
{
handle,
component_types,
@@ -189,7 +189,7 @@ namespace Tensorflow

public static Operation queue_enqueue_many_v2(Tensor handle, Tensor[] components, int timeout_ms = -1, string name = null)
{
var _op = _op_def_lib._apply_op_helper("QueueEnqueueManyV2", name, new
var _op = tf._op_def_lib._apply_op_helper("QueueEnqueueManyV2", name, new
{
handle,
components,
@@ -201,7 +201,7 @@ namespace Tensorflow

public static Tensor[] queue_dequeue_many_v2(Tensor handle, int n, TF_DataType[] component_types, int timeout_ms = -1, string name = null)
{
var _op = _op_def_lib._apply_op_helper("QueueDequeueManyV2", name, new
var _op = tf._op_def_lib._apply_op_helper("QueueDequeueManyV2", name, new
{
handle,
n,
@@ -223,7 +223,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor tensor_array_read_v3(Tensor handle, Tensor index, Tensor flow_in, TF_DataType dtype, string name = null)
{
var _op = _op_def_lib._apply_op_helper("TensorArrayReadV3", name, new
var _op = tf._op_def_lib._apply_op_helper("TensorArrayReadV3", name, new
{
handle,
index,
@@ -236,7 +236,7 @@ namespace Tensorflow

public static Tensor tensor_array_write_v3(Tensor handle, Tensor index, Tensor value, Tensor flow_in, string name = null)
{
var _op = _op_def_lib._apply_op_helper("TensorArrayWriteV3", name, new
var _op = tf._op_def_lib._apply_op_helper("TensorArrayWriteV3", name, new
{
handle,
index,
@@ -249,7 +249,7 @@ namespace Tensorflow

public static Tensor tensor_array_size_v3(Tensor handle, Tensor flow_in, string name = null)
{
var _op = _op_def_lib._apply_op_helper("TensorArraySizeV3", name, new
var _op = tf._op_def_lib._apply_op_helper("TensorArraySizeV3", name, new
{
handle,
flow_in
@@ -261,7 +261,7 @@ namespace Tensorflow
public static Tensor tensor_array_gather_v3(Tensor handle, Tensor indices, Tensor flow_in,
TF_DataType dtype, TensorShape element_shape = null, string name = null)
{
var _op = _op_def_lib._apply_op_helper("TensorArrayGatherV3", name, new
var _op = tf._op_def_lib._apply_op_helper("TensorArrayGatherV3", name, new
{
handle,
indices,
@@ -276,7 +276,7 @@ namespace Tensorflow
public static Tensor stack_v2(Tensor max_size, TF_DataType elem_type, string stack_name = "",
string name = null)
{
var _op = _op_def_lib._apply_op_helper("StackV2", name, new
var _op = tf._op_def_lib._apply_op_helper("StackV2", name, new
{
max_size,
elem_type,
@@ -289,7 +289,7 @@ namespace Tensorflow
public static Tensor stack_push_v2(Tensor handle, Tensor elem, bool swap_memory = false,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("StackPushV2", name, new
var _op = tf._op_def_lib._apply_op_helper("StackPushV2", name, new
{
handle,
elem,
@@ -301,7 +301,7 @@ namespace Tensorflow

public static Tensor stack_pop_v2(Tensor handle, TF_DataType elem_type, string name = null)
{
var _op = _op_def_lib._apply_op_helper("StackPopV2", name, new
var _op = tf._op_def_lib._apply_op_helper("StackPopV2", name, new
{
handle,
elem_type


+ 7
- 9
src/TensorFlowNET.Core/Operations/gen_image_ops.cs View File

@@ -21,8 +21,6 @@ namespace Tensorflow
{
public class gen_image_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Tensor convert_image_dtype(Tensor image, TF_DataType dtype, bool saturate = false, string name= null)
{
if (dtype == image.dtype)
@@ -73,7 +71,7 @@ namespace Tensorflow
}
else
{
var _op = _op_def_lib._apply_op_helper("DecodeJpeg", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("DecodeJpeg", name: name, args: new
{
contents,
channels,
@@ -98,7 +96,7 @@ namespace Tensorflow
}
else
{
var _op = _op_def_lib._apply_op_helper("DecodeGif", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("DecodeGif", name: name, args: new
{
contents
});
@@ -119,7 +117,7 @@ namespace Tensorflow
}
else
{
var _op = _op_def_lib._apply_op_helper("DecodePng", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("DecodePng", name: name, args: new
{
contents,
channels,
@@ -141,7 +139,7 @@ namespace Tensorflow
}
else
{
var _op = _op_def_lib._apply_op_helper("DecodeBmp", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("DecodeBmp", name: name, args: new
{
contents,
channels
@@ -159,7 +157,7 @@ namespace Tensorflow
}
else
{
var _op = _op_def_lib._apply_op_helper("ResizeBilinear", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("ResizeBilinear", name: name, args: new
{
images,
size,
@@ -173,7 +171,7 @@ namespace Tensorflow
public static Tensor resize_nearest_neighbor<Tsize>(Tensor images, Tsize size, bool align_corners = false,
bool half_pixel_centers = false, string name = null)
{
var op = _op_def_lib._apply_op_helper("ResizeNearestNeighbor", name: name, args: new
var op = tf._op_def_lib._apply_op_helper("ResizeNearestNeighbor", name: name, args: new
{
images,
size,
@@ -187,7 +185,7 @@ namespace Tensorflow
public static Tensor resize_nearest_neighbor_grad<Tsize>(Tensor grads, Tsize size, bool align_corners = false,
bool half_pixel_centers = false, string name = null)
{
var op = _op_def_lib._apply_op_helper("ResizeNearestNeighborGrad", name: name, args: new
var op = tf._op_def_lib._apply_op_helper("ResizeNearestNeighborGrad", name: name, args: new
{
grads,
size,


+ 5
- 5
src/TensorFlowNET.Core/Operations/gen_io_ops.cs View File

@@ -14,29 +14,29 @@
limitations under the License.
******************************************************************************/

using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_io_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Operation save_v2(Tensor prefix, string[] tensor_names, string[] shape_and_slices, Tensor[] tensors, string name = null)
{
var _op = _op_def_lib._apply_op_helper("SaveV2", name: name, args: new { prefix, tensor_names, shape_and_slices, tensors });
var _op = tf._op_def_lib._apply_op_helper("SaveV2", name: name, args: new { prefix, tensor_names, shape_and_slices, tensors });

return _op;
}

public static Tensor[] restore_v2(Tensor prefix, string[] tensor_names, string[] shape_and_slices, TF_DataType[] dtypes, string name = null)
{
var _op = _op_def_lib._apply_op_helper("RestoreV2", name: name, args: new { prefix, tensor_names, shape_and_slices, dtypes });
var _op = tf._op_def_lib._apply_op_helper("RestoreV2", name: name, args: new { prefix, tensor_names, shape_and_slices, dtypes });

return _op.outputs;
}

public static Tensor read_file<T>(T filename, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ReadFile", name: name, args: new { filename });
var _op = tf._op_def_lib._apply_op_helper("ReadFile", name: name, args: new { filename });

return _op.outputs[0];
}


+ 5
- 6
src/TensorFlowNET.Core/Operations/gen_logging_ops.cs View File

@@ -15,19 +15,18 @@
******************************************************************************/

using System.Collections.Generic;
using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_logging_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Operation _assert(Tensor condition, object[] data, int? summarize = 3, string name = null)
{
if (!summarize.HasValue)
summarize = 3;

var _op = _op_def_lib._apply_op_helper("Assert", name, args: new { condition, data, summarize });
var _op = tf._op_def_lib._apply_op_helper("Assert", name, args: new { condition, data, summarize });

return _op;
}
@@ -35,7 +34,7 @@ namespace Tensorflow
public static Tensor histogram_summary(string tag, Tensor values, string name = null)
{
var dict = new Dictionary<string, object>();
var op = _op_def_lib._apply_op_helper("HistogramSummary", name: name, args: new { tag, values });
var op = tf._op_def_lib._apply_op_helper("HistogramSummary", name: name, args: new { tag, values });
return op.output;
}

@@ -64,7 +63,7 @@ namespace Tensorflow
var dict = new Dictionary<string, object>();
dict["tags"] = tags;
dict["values"] = values;
var op = _op_def_lib._apply_op_helper("ScalarSummary", name: name, keywords: dict);
var op = tf._op_def_lib._apply_op_helper("ScalarSummary", name: name, keywords: dict);
return op.output;
}

@@ -95,7 +94,7 @@ namespace Tensorflow
{
var dict = new Dictionary<string, object>();
dict["inputs"] = inputs;
var op = _op_def_lib._apply_op_helper("MergeSummary", name: name, keywords: dict);
var op = tf._op_def_lib._apply_op_helper("MergeSummary", name: name, keywords: dict);
return op.output;
}
}


+ 256
- 408
src/TensorFlowNET.Core/Operations/gen_math_ops.cs
File diff suppressed because it is too large
View File


+ 7
- 12
src/TensorFlowNET.Core/Operations/gen_math_ops.eager.cs View File

@@ -9,19 +9,14 @@ namespace Tensorflow
{
public static partial class gen_math_ops
{
public static EagerTensor mul(IntPtr x, IntPtr y, string name = null)
public static Tensor mul(IntPtr x, IntPtr y, string name = null)
{
var results = EagerTensorPass.Create();
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Mul", name, new IntPtr[]
{
x,
y,
}, 2,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Mul", name,
null,
x, y);

return results[0];
}
}
}

+ 872
- 874
src/TensorFlowNET.Core/Operations/gen_ops.cs
File diff suppressed because it is too large
View File


+ 21
- 37
src/TensorFlowNET.Core/Operations/gen_random_ops.cs View File

@@ -22,8 +22,6 @@ namespace Tensorflow
{
public class gen_random_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

/// <summary>
/// Outputs random values from a normal distribution.
/// </summary>
@@ -42,25 +40,18 @@ namespace Tensorflow

if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var attrs = new object[]
{
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"RandomStandardNormal", name,
null,
shape,
"seed", seed,
"seed2", seed2,
"dtype", dtype
};
var inputs = EagerTensorPass.From(shape);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"RandomStandardNormal", name,
inputs.Points, inputs.Length,
wrap_tfe_src.SetOpAttrs2(attrs),
op => wrap_tfe_src.SetOpAttrs(op, attrs),
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
"dtype", dtype);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("RandomStandardNormal",
var _op = tf._op_def_lib._apply_op_helper("RandomStandardNormal",
name: name,
args: new { shape, dtype, seed, seed2 });

@@ -84,7 +75,7 @@ namespace Tensorflow
if (!seed2.HasValue)
seed2 = 0;

var _op = _op_def_lib._apply_op_helper("RandomUniformInt",
var _op = tf._op_def_lib._apply_op_helper("RandomUniformInt",
name: name,
args: new { shape, minval, maxval, seed, seed2 });

@@ -107,7 +98,7 @@ namespace Tensorflow
if (!seed2.HasValue)
seed2 = 0;

var _op = _op_def_lib._apply_op_helper("RandomUniform",
var _op = tf._op_def_lib._apply_op_helper("RandomUniform",
name: name,
args: new { shape, dtype, seed, seed2});

@@ -125,7 +116,7 @@ namespace Tensorflow
public static Tensor random_shuffle(Tensor value, int seed = 0, int seed2 = 0,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("RandomShuffle",
var _op = tf._op_def_lib._apply_op_helper("RandomShuffle",
name: name,
args: new { value, seed, seed2 });

@@ -151,25 +142,18 @@ namespace Tensorflow

if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(shape);
var attrs = new object[]
{
"seed", seed,
"seed2", seed2,
"dtype", dtype
};
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"TruncatedNormal", name,
inputs.Points, inputs.Length,
wrap_tfe_src.SetOpAttrs2(attrs),
op => wrap_tfe_src.SetOpAttrs(op, attrs),
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
null,
shape,
"seed", seed,
"seed2", seed2,
"dtype", dtype);
return results[0];
}

var _op = _op_def_lib._apply_op_helper("TruncatedNormal",
var _op = tf._op_def_lib._apply_op_helper("TruncatedNormal",
name: name,
args: new { shape, dtype, seed, seed2 });

@@ -186,7 +170,7 @@ namespace Tensorflow
if (output_dtype == TF_DataType.DtInvalid)
output_dtype = TF_DataType.TF_INT64;

var _op = _op_def_lib._apply_op_helper("Multinomial",
var _op = tf._op_def_lib._apply_op_helper("Multinomial",
name: name,
args: new { logits, num_samples, seed, seed2, output_dtype });



+ 35
- 55
src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs View File

@@ -23,21 +23,16 @@ namespace Tensorflow
{
public static class gen_resource_variable_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Operation assign_sub_variable_op(Tensor resource, Tensor value, string name = null)
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(resource, value);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"AssignSubVariableOp", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
null,
resource, value);

return null;
}

return null;
@@ -54,13 +49,11 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var inputs = EagerTensorPass.From(resource, value);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"AssignAddVariableOp", name,
inputs.Points, inputs.Length,
null, null,
null, 0);
status.Check(true);
null,
resource, value);

return null;
}

@@ -71,17 +64,15 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var inputs = EagerTensorPass.From(resource, value);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"AssignVariableOp", name,
inputs.Points, inputs.Length,
null, null,
null, 0);
status.Check(true);
null,
resource, value);

return null;
}

var _op = _op_def_lib._apply_op_helper("AssignVariableOp", name, new { resource, value });
var _op = tf._op_def_lib._apply_op_helper("AssignVariableOp", name, new { resource, value });

return _op;
}
@@ -90,18 +81,15 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"VarIsInitializedOp", name,
new IntPtr[] { resource as EagerTensor },
1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
null,
resource);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("VarIsInitializedOp", name, new { resource });
var _op = tf._op_def_lib._apply_op_helper("VarIsInitializedOp", name, new { resource });

return _op.output;
}
@@ -120,24 +108,18 @@ namespace Tensorflow
{
if(tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var attrs = new object[]
{
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"VarHandleOp", name,
null,
"container", container,
"shared_name", shared_name,
"dtype", dtype,
"shape", shape.dims
};
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"VarHandleOp", name, null, 0,
wrap_tfe_src.SetOpAttrs2(attrs),
op => wrap_tfe_src.SetOpAttrs(op, attrs),
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
"shape", shape.dims);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("VarHandleOp", name, new {
var _op = tf._op_def_lib._apply_op_helper("VarHandleOp", name, new {
dtype,
shape,
container,
@@ -158,18 +140,16 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
var results = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"ReadVariableOp", name,
new IntPtr[] { resource as EagerTensor }, 1,
wrap_tfe_src.SetOpAttrs2("dtype", dtype),
op => wrap_tfe_src.SetOpAttrs(op, "dtype", dtype),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
null,
resource,
"dtype", dtype);

return results[0];
}

var _op = _op_def_lib._apply_op_helper("ReadVariableOp", name, new
var _op = tf._op_def_lib._apply_op_helper("ReadVariableOp", name, new
{
resource,
dtype
@@ -181,7 +161,7 @@ namespace Tensorflow
public static Tensor resource_gather(Tensor resource, Tensor indices, TF_DataType dtype,
int batch_dims = 0, bool validate_indices = true, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ResourceGather", name, new
var _op = tf._op_def_lib._apply_op_helper("ResourceGather", name, new
{
resource,
indices,


+ 3
- 5
src/TensorFlowNET.Core/Operations/gen_sparse_ops.cs View File

@@ -15,14 +15,12 @@
******************************************************************************/

using System.Collections.Generic;
using Tensorflow.Framework;
using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_sparse_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

/// <summary>
/// Converts a sparse representation into a dense tensor.
/// </summary>
@@ -40,7 +38,7 @@ namespace Tensorflow
bool validate_indices = true,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("SparseToDense", name, args: new
var _op = tf._op_def_lib._apply_op_helper("SparseToDense", name, args: new
{
sparse_indices,
output_shape,
@@ -59,7 +57,7 @@ namespace Tensorflow
bool validate_indices = true,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("SparseToDense", name, args: new
var _op = tf._op_def_lib._apply_op_helper("SparseToDense", name, args: new
{
sparse_indices,
output_shape,


+ 2
- 4
src/TensorFlowNET.Core/Operations/gen_string_ops.cs View File

@@ -17,18 +17,16 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_string_ops
{
static readonly OpDefLibrary _op_def_lib;
static gen_string_ops() { _op_def_lib = new OpDefLibrary(); }

public static Tensor substr(Tensor input, int pos, int len,
string name = null, string @uint = "BYTE")
{
var _op = _op_def_lib._apply_op_helper("Substr", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("Substr", name: name, args: new
{
input,
pos,


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

@@ -1,5 +1,5 @@
/*****************************************************************************
Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved.
Copyright 2020 Haiping Chen. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
limitations under the License.
******************************************************************************/

using NumSharp;
using System;
using System.Collections.Generic;
using System.Text;
@@ -112,7 +111,7 @@ namespace Tensorflow
public static Tensor crop_and_resize(Tensor image, Tensor boxes, Tensor box_ind, Tensor crop_size, string method, float extrapolation_value, string name)
{
var _op = gen_nn_ops._op_def_lib._apply_op_helper("CropAndResize", name: name, args: new
var _op = tf._op_def_lib._apply_op_helper("CropAndResize", name: name, args: new
{
image,
boxes,


+ 2
- 4
src/TensorFlowNET.Core/Operations/math_ops.cs View File

@@ -567,10 +567,8 @@ namespace Tensorflow
}
else
{
if(x is EagerTensor)
{
return constant_op.constant(np.arange(x.shape.Rank));
}
if(x is Tensor)
return constant_op.constant(np.arange(x.rank));

var rank = array_ops.rank(x);
return range(0, rank, 1);


+ 0
- 17
src/TensorFlowNET.Core/System/GCItemCounter.cs View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow
{
public class GCItemCounter
{
public GCItemType ItemType { get; set; }
public int RefCounter { get; set; }
public DateTime LastUpdateTime { get; set; }
public IntPtr Handle { get; set; }

public override string ToString()
=> $"{ItemType} {RefCounter} {LastUpdateTime}";
}
}

+ 0
- 13
src/TensorFlowNET.Core/System/GCItemType.cs View File

@@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow
{
public enum GCItemType
{
TensorHandle = 0,
LocalTensorHandle = 1,
EagerTensorHandle = 2
}
}

+ 0
- 97
src/TensorFlowNET.Core/System/GarbageCollector.cs View File

@@ -1,97 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using static Tensorflow.Binding;

namespace Tensorflow
{
public class GarbageCollector
{
static Dictionary<IntPtr, GCItemCounter> container = new Dictionary<IntPtr, GCItemCounter>();

static object locker = new object();
public static void Init()
{
/*Task.Run(() =>
{
while (true)
{
Thread.Sleep(100);
Recycle();
}
});*/
}

public static void Increase(IntPtr handle, GCItemType type)
{
if (handle == IntPtr.Zero)
return;

if (container.ContainsKey(handle))
{
container[handle].RefCounter++;
container[handle].LastUpdateTime = DateTime.Now;
}
else
{
lock (locker)
{
container[handle] = new GCItemCounter
{
ItemType = type,
RefCounter = 1,
Handle = handle,
LastUpdateTime = DateTime.Now
};
}
}
}

public static void Decrease(IntPtr handle)
{
lock (locker)
{
if (handle != IntPtr.Zero && container.ContainsKey(handle))
container[handle].RefCounter--;
}
}

private static void Recycle()
{
// dispose before 1 sec
lock (locker)
{
var items = container.Values
.Where(x => x.RefCounter <= 0 && (DateTime.Now - x.LastUpdateTime).TotalMilliseconds > 300)
.ToArray();

foreach (var item in items)
{
item.RefCounter = 0;
container.Remove(item.Handle);
switch (item.ItemType)
{
case GCItemType.TensorHandle:
//print($"c_api.TF_DeleteTensor({item.Handle.ToString("x16")})");
c_api.TF_DeleteTensor(item.Handle);
break;
case GCItemType.LocalTensorHandle:
//print($"c_api.TFE_DeleteTensorHandle({item.Handle.ToString("x16")})");
c_api.TFE_DeleteTensorHandle(item.Handle);
break;
case GCItemType.EagerTensorHandle:
//print($"c_api.TFE_DeleteEagerTensor({item.Handle.ToString("x16")})");
c_api.TFE_DeleteEagerTensor(item.Handle);
break;
default:
break;
}
}
}
}
}
}

+ 6
- 10
src/TensorFlowNET.Core/Tensors/EagerTensorV2.cs View File

@@ -12,17 +12,15 @@ namespace Tensorflow
{
public class EagerTensorV2 : DisposableObject, ITensor
{
IntPtr tfe_tensor_handle;
public IntPtr EagerTensorHandle { get; set; }
public string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(tfe_tensor_handle, status));
IntPtr EagerTensorHandle;
public string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(EagerTensorHandle, status));

static Status status = new Status();

public EagerTensorV2(IntPtr handle)
{
EagerTensorHandle = handle;
tfe_tensor_handle = c_api.TFE_EagerTensorHandle(handle);
_handle = c_api.TFE_TensorHandleResolve(tfe_tensor_handle, status);
EagerTensorHandle = c_api.TFE_EagerTensorHandle(handle);
_handle = c_api.TFE_TensorHandleResolve(EagerTensorHandle, status);
}

public unsafe EagerTensorV2(NDArray nd, string device_name = "")
@@ -42,8 +40,7 @@ namespace Tensorflow

}, IntPtr.Zero);

tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status);
EagerTensorHandle = c_api.TFE_NewEagerTensor();
EagerTensorHandle = c_api.TFE_NewTensorHandle(_handle, status);
}

/*public unsafe EagerTensorV2(float[,] value)
@@ -72,8 +69,7 @@ namespace Tensorflow
protected override void DisposeUnmanagedResources(IntPtr handle)
{
c_api.TF_DeleteTensor(_handle);
c_api.TFE_DeleteTensorHandle(tfe_tensor_handle);
c_api.TFE_DeleteEagerTensor(EagerTensorHandle);
c_api.TFE_DeleteTensorHandle(EagerTensorHandle);
}
}
}

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

@@ -25,8 +25,6 @@ namespace Tensorflow
{
public class constant_op
{
public static Execute _execute = new Execute();

/// <summary>
/// Creates a constant tensor.
///
@@ -107,7 +105,7 @@ namespace Tensorflow
var dims_t = convert_to_eager_tensor(dims, ctx, dtypes.int32);
var inputs_flat = new[] { dims_t, value };
var attrs = new object[] { "T", attr_t, "index_type", TF_DataType.TF_INT32 };
var result = _execute.execute(ctx, "Fill", 1, inputs_flat, attrs);
var result = tf._execute.execute(ctx, "Fill", 1, inputs_flat, attrs);
return result[0];
}



+ 8
- 16
src/TensorFlowNET.Core/Training/gen_training_ops.cs View File

@@ -23,13 +23,11 @@ namespace Tensorflow
{
public class gen_training_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Tensor apply_adam(RefVariable var, RefVariable m, RefVariable v, Tensor beta1_power, Tensor beta2_power,
Tensor lr, Tensor beta1, Tensor beta2, Tensor epsilon, Tensor grad,
bool use_locking = false, bool use_nesterov = false, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ApplyAdam", name, new
var _op = tf._op_def_lib._apply_op_helper("ApplyAdam", name, new
{
var,
m,
@@ -50,7 +48,7 @@ namespace Tensorflow

public static Tensor apply_gradient_descent(RefVariable var, Tensor alpha, Tensor delta, bool use_locking = false, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ApplyGradientDescent", name, new
var _op = tf._op_def_lib._apply_op_helper("ApplyGradientDescent", name, new
{
var,
alpha,
@@ -65,21 +63,15 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"ResourceApplyGradientDescent", name, new IntPtr[]
{
var,
alpha,
delta
}, 3,
wrap_tfe_src.SetOpAttrs2("use_locking", use_locking),
op => wrap_tfe_src.SetOpAttrs(op, "use_locking", use_locking),
null, 0);
status.Check(true);
var result = tf.Runner.TFE_FastPathExecute(tf.context, tf.context.device_name,
"ResourceApplyGradientDescent", name,
null,
var, alpha, delta,
"use_locking", use_locking);
return null;
}

var _op = _op_def_lib._apply_op_helper("ResourceApplyGradientDescent", name, new
var _op = tf._op_def_lib._apply_op_helper("ResourceApplyGradientDescent", name, new
{
var,
alpha,


+ 0
- 22
src/TensorFlowNET.Core/Util/EagerTensorPass.cs View File

@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tensorflow.Eager;

namespace Tensorflow
{
public class EagerTensorPass : PointerInputs<EagerTensor>
{
public EagerTensorPass(params EagerTensor[] tensors)
{
data = tensors;
}

public static EagerTensorPass Create(int count = 1)
=> new EagerTensorPass(Enumerable.Range(0, count).Select(x => new EagerTensor()).ToArray());

public static EagerTensorPass From(params object[] objects)
=> new EagerTensorPass(objects.Select(x => ops.convert_to_tensor(x) as EagerTensor).ToArray());
}
}

+ 0
- 31
src/TensorFlowNET.Core/Util/TensorManager.cs View File

@@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Eager;

namespace Tensorflow
{
public class TensorManager
{
Dictionary<IntPtr, EagerTensor> tensors;
public TensorManager()
{
tensors = new Dictionary<IntPtr, EagerTensor>();
}

public EagerTensor GetTensor(IntPtr handle)
{
if (tensors.ContainsKey(handle))
return tensors[handle];

//return new EagerTensor(handle);
tensors[handle] = new EagerTensor(handle);
return tensors[handle];
}

public void Reset()
{
tensors.Clear();
}
}
}

+ 76
- 0
src/TensorFlowNET.Core/Util/UnorderedMap.cs View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Util
{
public class UnorderedMap<Tk, Tv> : Dictionary<Tk, Tv>
{
/// <summary>
/// Avoid null when accessing not existed element
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public new Tv this[Tk key]
{
get
{
if (!ContainsKey(key))
Add(key, default);

return base[key];
}

set
{
base[key] = value;
}
}

public void push_back(Tk key, Tv value)
=> Add(key, value);

public void emplace(Tk key, Tv value)
=> Add(key, value);

public bool find(Tk key)
=> ContainsKey(key);

public void erase(Tk key)
=> Remove(key);

public bool find(Tk key, out Tv value)
{
if (ContainsKey(key))
{
value = this[key];
return true;
}
else
{
value = default(Tv);
return false;
}
}
}

public class UnorderedMapEnumerable<Tk, Tv> : UnorderedMap<Tk, Tv>
where Tv : new()
{
public new Tv this[Tk key]
{
get
{
if (!ContainsKey(key))
Add(key, new Tv());

return base[key];
}

set
{
base[key] = value;
}
}
}
}

+ 18
- 0
src/TensorFlowNET.Core/Util/UnorderedSet.cs View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Util
{
public class UnorderedSet<T> : HashSet<T>
{
public UnorderedSet(T[] elements)
{
foreach (var el in elements)
Add(el);
}

public bool find(T value)
=> Contains(value);
}
}

+ 4
- 3
src/TensorFlowNET.Core/Variables/BaseResourceVariable.cs View File

@@ -48,13 +48,11 @@ namespace Tensorflow

public BaseResourceVariable()
{
_handle = c_api.TFE_NewResourceVariable();
}

public BaseResourceVariable(IntPtr handle, IntPtr tensor)
{
_handle = handle;
this.handle = tf.tensorMgr.GetTensor(tensor);
}

public void __init__(bool trainable = true,
@@ -104,7 +102,10 @@ namespace Tensorflow
void variable_accessed(BaseResourceVariable variable)
{
if (variable.trainable)
Tape.variable_accessed(variable as ResourceVariable);
{
foreach (var tape in tf.GetTapeSet())
tape.VariableAccessed(variable as ResourceVariable);
}
}

/// <summary>


+ 0
- 2
src/TensorFlowNET.Core/Variables/ResourceVariable.Operators.cs View File

@@ -22,8 +22,6 @@ namespace Tensorflow
{
public partial class ResourceVariable
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();

public static Tensor operator +(ResourceVariable x, int y) => op_helper("add", x, y);
public static Tensor operator +(ResourceVariable x, float y) => op_helper("add", x, y);
public static Tensor operator +(ResourceVariable x, double y) => op_helper("add", x, y);


+ 0
- 3
src/TensorFlowNET.Core/Variables/ResourceVariable.cs View File

@@ -160,9 +160,6 @@ namespace Tensorflow
initializer_op = null;
_graph_element = null;
initial_value = _in_graph_mode ? initial_value : null;

c_api.TFE_SetResourceVariableHandle(_handle, handle as EagerTensor);
c_api.TFE_SetResourceVariableName(_handle, handle_name + ":0");
}

base.__init__(trainable: trainable,


+ 9
- 12
src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs View File

@@ -16,15 +16,12 @@

using System;
using System.Collections.Generic;
using Tensorflow.Eager;
using static Tensorflow.Binding;

namespace Tensorflow
{
public class gen_state_ops
{
public static OpDefLibrary _op_def_lib = new OpDefLibrary();
public static Execute _execute = new Execute();

/// <summary>
/// Holds state in the form of a tensor that persists across steps.
/// Outputs a ref to the tensor state so it may be read or modified.
@@ -37,7 +34,7 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor variable_v2(int[] shape, TF_DataType dtype, string name = null, string container = "", string shared_name = "")
{
var _op = _op_def_lib._apply_op_helper("VariableV2", name: name, args: new { dtype, shape, container, shared_name });
var _op = tf._op_def_lib._apply_op_helper("VariableV2", name: name, args: new { dtype, shape, container, shared_name });

var _result = _op.outputs;
var _inputs_flat = _op.inputs;
@@ -64,7 +61,7 @@ namespace Tensorflow
bool use_locking = true,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking });
var _op = tf._op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking });

var _result = _op.outputs;
var _inputs_flat = _op.inputs;
@@ -82,7 +79,7 @@ namespace Tensorflow
bool use_locking = true,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking });
var _op = tf._op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking });

var _result = _op.outputs;
var _inputs_flat = _op.inputs;
@@ -100,7 +97,7 @@ namespace Tensorflow
bool use_locking = true,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking });
var _op = tf._op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking });

var _result = _op.outputs;
var _inputs_flat = _op.inputs;
@@ -118,7 +115,7 @@ namespace Tensorflow
bool use_locking = false,
string name = null)
{
var _op = _op_def_lib._apply_op_helper("AssignSub", name: name, args: new { @ref, value, use_locking });
var _op = tf._op_def_lib._apply_op_helper("AssignSub", name: name, args: new { @ref, value, use_locking });

return _op.outputs[0];
}
@@ -140,7 +137,7 @@ namespace Tensorflow
// A mutable `Tensor`. Has the same type as `ref`.
public static Tensor assign_add<T>(RefVariable @ref, T value, bool use_locking = false, string name = null)
{
var _op = _op_def_lib._apply_op_helper("AssignAdd", name: name, args: new { @ref, value, use_locking });
var _op = tf._op_def_lib._apply_op_helper("AssignAdd", name: name, args: new { @ref, value, use_locking });
return _op.outputs[0];
}

@@ -155,13 +152,13 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor scatter_add(RefVariable @ref, Tensor indices, Tensor updates, bool use_locking = false, string name = null)
{
var _op = _op_def_lib._apply_op_helper("ScatterAdd", name: name, args: new { @ref, indices, updates, use_locking });
var _op = tf._op_def_lib._apply_op_helper("ScatterAdd", name: name, args: new { @ref, indices, updates, use_locking });
return _op.outputs[0];
}

public static Tensor is_variable_initialized(RefVariable @ref, string name = null)
{
var _op = _op_def_lib._apply_op_helper("IsVariableInitialized", name: name, args: new { @ref });
var _op = tf._op_def_lib._apply_op_helper("IsVariableInitialized", name: name, args: new { @ref });
return _op.output;
}
}


+ 20
- 48
src/TensorFlowNET.Core/tensorflow.cs View File

@@ -21,6 +21,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using Tensorflow.Eager;
using Tensorflow.Gradients;
using static Tensorflow.Binding;

namespace Tensorflow
@@ -39,63 +40,23 @@ namespace Tensorflow
public TF_DataType chars = TF_DataType.TF_STRING;
public TF_DataType @string = TF_DataType.TF_STRING;

public delegate Tensor[] BackwardFunction(Tensor[] grads, long[] unneeded_gradients);

public OpDefLibrary _op_def_lib = new OpDefLibrary();
public Execute _execute = new Execute();
public IEagerRunner Runner = new EagerRunner();
public Context context = new Context(new ContextOptions(), new Status());
public TensorManager tensorMgr;
public tensorflow()
{
enable_eager_execution();
_constructThreadingObjects();
InitGradientEnvironment();
tensorMgr = new TensorManager();
}

private void InitGradientEnvironment()
{
GarbageCollector.Init();

/*var vspace = c_api.VSpace_Handle((shape, dims, dtype) =>
{
var ones = constant_op.constant(1.0f, dtype: dtype) as EagerTensor;
return ones.EagerTensorHandle;
}, (gradients) =>
{
var add_n = gen_math_ops.add_n(gradients.Data);
return add_n;
});*/

ops.RegisterFromAssembly();
// ops.RegisterFromAssemblyEager();

/*c_api.TFE_RegisterGradientFunction((op_name, op_inputs, op_outputs, attrs_string, output_grads, skip_input_indices) =>
{
var input_tensors = new BindingTensorArray(op_inputs)
.Data.Select(x => tf.tensorMgr.GetTensor(x)).ToArray();
var output_tensors = new BindingTensorArray(op_outputs)
.Data.Select(x => tf.tensorMgr.GetTensor(x)).ToArray();
var output_grad_tensors = new BindingTensorArray(output_grads)
.Data.Select(x => tf.tensorMgr.GetTensor(x)).ToArray();
var skip_input_indices_param = new BindingArray(skip_input_indices);

var gradients = ops.gradientFunctions[op_name](new EagerOperation
{
Name = op_name,
NumInputs = input_tensors.Length,
Inputs = input_tensors,
// InputHandles = input_tensors.Data,
NumOutputs = output_tensors.Length,
Outputs = output_tensors,
// OutputHandles = output_tensors.Data,
SkipInputIndicesArray = skip_input_indices_param,
AttrsArray = attrs_string.Split(',')
}, output_grad_tensors);

var gradients_handles = gradients.Select(x => x == null ? IntPtr.Zero : (x as EagerTensor).EagerTensorHandle).ToArray();
var wrap_handle = c_api.TFE_WrapGradientResult(gradients_handles, gradients.Length);

return wrap_handle;
}, (op_name, op_inputs, op_outputs) =>
{

});*/
}

public ResourceVariable Variable<T>(T data,
@@ -111,7 +72,7 @@ namespace Tensorflow
dtype: dtype,
shape: shape);

public unsafe Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = null)
public Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = null)
=> gen_array_ops.placeholder(dtype, shape, name);

public void enable_eager_execution()
@@ -140,6 +101,17 @@ namespace Tensorflow
return new Session(null, config).as_default();
}

List<ITape> tape_set;
public List<ITape> GetTapeSet()
{
if (tape_set == null)
{
tape_set = new List<ITape>();
}
return tape_set;
}

public void __init__()
{


+ 2
- 0
test/TensorFlowNET.UnitTest/MultithreadingTests.cs View File

@@ -229,6 +229,7 @@ namespace TensorFlowNET.UnitTest
}
}

[Ignore]
[TestMethod]
public void SessionRun_Initialization()
{
@@ -248,6 +249,7 @@ namespace TensorFlowNET.UnitTest
}
}

[Ignore]
[TestMethod]
public void SessionRun_Initialization_OutsideSession()
{


+ 2
- 2
test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpInferMixedTypeInputListAttrs.cs View File

@@ -33,9 +33,9 @@ namespace TensorFlowNET.UnitTest.NativeAPI
TFE_OpAddInputList(assertOp, data, 3, status);
CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status));

var attr_values = Graph.TFE_GetOpDef("Assert").Attr;
/*var attr_values = Graph.TFE_GetOpDef("Assert").Attr;
var attr_found = attr_values.First(x => x.Name == "T");
EXPECT_NE(attr_found, attr_values.Last());
EXPECT_NE(attr_found, attr_values.Last());*/
// EXPECT_EQ(attr_found.Type[0], "DT_BOOL");
//EXPECT_EQ(attr_found->second.list().type(1), tensorflow::DataType::DT_FLOAT);
//EXPECT_EQ(attr_found->second.list().type(2), tensorflow::DataType::DT_INT32);


+ 16
- 2
test/TensorFlowNET.UnitTest/NativeAPI/Eager/GradientEagerTest.cs View File

@@ -11,7 +11,7 @@ namespace TensorFlowNET.UnitTest.Gradient
public class GradientEagerTest : PythonTest
{
[TestMethod]
public void ConstantSq()
public void ConstantSquare()
{
// Calcute the gradient of w * w
// by Automatic Differentiation in Eager mode
@@ -21,7 +21,21 @@ namespace TensorFlowNET.UnitTest.Gradient
tape.watch(w);
var loss = w * w;
var grad = tape.gradient(loss, w);
print(grad);
Assert.AreEqual((float)grad, 3.0f);
}

[TestMethod]
public void ConstantMultiply()
{
var x = tf.ones((2, 2));
using var tape = tf.GradientTape();
tape.watch(x);
var y = tf.reduce_sum(x);
var z = tf.multiply(y, y);
var dz_dx = tape.gradient(z, x);

var expected = new float[] { 8.0f, 8.0f, 8.0f, 8.0f };
Assert.IsTrue(Enumerable.SequenceEqual(dz_dx.numpy().ToArray<float>(), expected));
}
}
}

+ 0
- 25
test/TensorFlowNET.UnitTest/PlaceholderTest.cs View File

@@ -1,25 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Tensorflow;
using static Tensorflow.Binding;

namespace TensorFlowNET.UnitTest
{
[TestClass]
public class PlaceholderTest
{
[Ignore]
[TestMethod]
public void placeholder()
{
var x = tf.placeholder(tf.int32);
var y = x * 3;

using (var sess = tf.Session())
{
var result = sess.run(y,
new FeedItem(x, 2));
Assert.AreEqual((int)result, 6);
}
}
}
}

Loading…
Cancel
Save