Browse Source

add EagerTensorPass and TensorManager.

tags/v0.20
Oceania2018 5 years ago
parent
commit
c078ef6a9f
32 changed files with 646 additions and 184 deletions
  1. +1
    -1
      src/TensorFlowNET.Core/APIs/tf.array.cs
  2. +8
    -1
      src/TensorFlowNET.Core/APIs/tf.math.cs
  3. +8
    -1
      src/TensorFlowNET.Core/APIs/tf.nn.cs
  4. +5
    -8
      src/TensorFlowNET.Core/Eager/EagerOperation.cs
  5. +8
    -0
      src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs
  6. +1
    -1
      src/TensorFlowNET.Core/Eager/EagerTensor.cs
  7. +2
    -1
      src/TensorFlowNET.Core/Eager/c_api.eager.cs
  8. +31
    -0
      src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs
  9. +26
    -12
      src/TensorFlowNET.Core/Gradients/GradientTape.cs
  10. +17
    -11
      src/TensorFlowNET.Core/Gradients/math_grad.cs
  11. +4
    -0
      src/TensorFlowNET.Core/Graphs/Graph.Control.cs
  12. +34
    -0
      src/TensorFlowNET.Core/Graphs/NullContextmanager.cs
  13. +30
    -2
      src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs
  14. +1
    -1
      src/TensorFlowNET.Core/Operations/array_ops.cs
  15. +1
    -1
      src/TensorFlowNET.Core/Operations/clip_ops.cs
  16. +82
    -23
      src/TensorFlowNET.Core/Operations/gen_array_ops.cs
  17. +196
    -57
      src/TensorFlowNET.Core/Operations/gen_math_ops.cs
  18. +4
    -3
      src/TensorFlowNET.Core/Operations/gen_math_ops.eager.cs
  19. +26
    -20
      src/TensorFlowNET.Core/Operations/gen_random_ops.cs
  20. +25
    -25
      src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs
  21. +10
    -1
      src/TensorFlowNET.Core/Operations/math_ops.cs
  22. +9
    -6
      src/TensorFlowNET.Core/System/GarbageCollector.cs
  23. +6
    -1
      src/TensorFlowNET.Core/Tensors/Tensor.cs
  24. +1
    -0
      src/TensorFlowNET.Core/Tensors/dtypes.cs
  25. +1
    -0
      src/TensorFlowNET.Core/Training/gen_training_ops.cs
  26. +22
    -0
      src/TensorFlowNET.Core/Util/EagerTensorPass.cs
  27. +11
    -0
      src/TensorFlowNET.Core/Util/IPointerInputs.cs
  28. +30
    -0
      src/TensorFlowNET.Core/Util/PointerInputs.cs
  29. +31
    -0
      src/TensorFlowNET.Core/Util/TensorManager.cs
  30. +1
    -1
      src/TensorFlowNET.Core/Variables/BaseResourceVariable.cs
  31. +4
    -0
      src/TensorFlowNET.Core/ops.name_scope.cs
  32. +10
    -7
      src/TensorFlowNET.Core/tensorflow.cs

+ 1
- 1
src/TensorFlowNET.Core/APIs/tf.array.cs View File

@@ -217,7 +217,7 @@ namespace Tensorflow
Tensor off_value = null,
TF_DataType dtype = TF_DataType.DtInvalid,
int axis = -1,
string name = null) => array_ops.one_hot(indices, depth, dtype: dtype, axis: axis, name: name);
string name = null) => array_ops.one_hot(indices, ops.convert_to_tensor(depth), dtype: dtype, axis: axis, name: name);

/// <summary>
/// Pads a tensor


+ 8
- 1
src/TensorFlowNET.Core/APIs/tf.math.cs View File

@@ -21,6 +21,13 @@ namespace Tensorflow
{
public partial class tensorflow
{
public MathApi math { get; } = new MathApi();
public class MathApi
{
public Tensor log(Tensor x, string name = null)
=> gen_math_ops.log(x, name);
}

public Tensor abs(Tensor x, string name = null)
=> math_ops.abs(x, name);

@@ -254,7 +261,7 @@ namespace Tensorflow
/// Any values less than <c>clip_value_min</c> are set to <c>clip_value_min</c>. Any values
/// greater than <c>clip_value_max</c> are set to <c>clip_value_max</c>.
/// </remarks>
public Tensor clip_by_value (Tensor t, Tensor clip_value_min, Tensor clip_value_max, string name = "ClipByValue")
public Tensor clip_by_value<T1, T2>(Tensor t, T1 clip_value_min, T2 clip_value_max, string name = "ClipByValue")
=> clip_ops.clip_by_value(t, clip_value_min, clip_value_max, name);
public Tensor sub<Tx, Ty>(Tx a, Ty b, string name = null)


+ 8
- 1
src/TensorFlowNET.Core/APIs/tf.nn.cs View File

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

using System;
using Tensorflow.Operations;
using Tensorflow.Operations.Activation;
using static Tensorflow.Binding;
@@ -182,7 +183,13 @@ namespace Tensorflow
=> nn_impl.sigmoid_cross_entropy_with_logits(labels: labels, logits: logits, name: name);

public Tensor softmax(Tensor logits, int axis = -1, string name = null)
=> gen_nn_ops.softmax(logits, name);
{
if (axis == -1)
return gen_nn_ops.softmax(logits, name);
else
throw new NotImplementedException("");
}

/// <summary>
/// Computes sparse softmax cross entropy between `logits` and `labels`.


+ 5
- 8
src/TensorFlowNET.Core/Eager/EagerOperation.cs View File

@@ -18,7 +18,7 @@ namespace Tensorflow.Eager
public Tensor[] Outputs { get; set; }
public BindingArray SkipInputIndicesArray { get; set; }
public unsafe int[] SkipInputIndices => SkipInputIndicesArray.Data.Select(x => *(int*) x).ToArray();
public BindingArray AttrsArray { get; set; }
public string[] AttrsArray { get; set; }

public EagerOperation() : base(IntPtr.Zero)
{
@@ -70,14 +70,11 @@ namespace Tensorflow.Eager
return value;
}

public bool get_attr_bool(string attr_name)
public bool get_attr_bool(string attr_name)
{
for (int i = 0; i < AttrsArray.Data.Length; i = i + 2)
{
// var a = *(char*)AttrsArray.Data[i];
if (op_dict[Name].Attr[i].Name == attr_name)
return (int)AttrsArray.Data[i + 1] == 1;
}
for (int i = 0; i < AttrsArray.Length; i = i + 2)
if (AttrsArray[i] == attr_name)
return AttrsArray[i + 1] == "1";

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


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

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using static Tensorflow.Binding;

namespace Tensorflow.Eager
@@ -49,6 +50,10 @@ namespace Tensorflow.Eager
print($"new TensorHandle {Id} {tfe_tensor_handle.ToString("x16")}");
print($"new EagerTensor {Id} {EagerTensorHandle.ToString("x16")}");*/

if (tfe_tensor_handle == IntPtr.Zero && _id == 0)
{
}

GarbageCollector.Increase(_handle, GCItemType.TensorHandle);
GarbageCollector.Increase(tfe_tensor_handle, GCItemType.LocalTensorHandle);
GarbageCollector.Increase(EagerTensorHandle, GCItemType.EagerTensorHandle);
@@ -56,6 +61,9 @@ namespace Tensorflow.Eager
return this;
}

public override IntPtr ToPointer()
=> EagerTensorHandle;

protected override void DisposeUnmanagedResources(IntPtr handle)
{
GarbageCollector.Decrease(_handle);


+ 1
- 1
src/TensorFlowNET.Core/Eager/EagerTensor.cs View File

@@ -13,7 +13,7 @@ namespace Tensorflow.Eager
public IntPtr EagerTensorHandle { get; set; }
public override string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(tfe_tensor_handle, status));

// public override int rank => c_api.TFE_TensorHandleNumDims(tfe_tensor_handle, status);
public override int rank => c_api.TFE_TensorHandleNumDims(tfe_tensor_handle, status);

public static int GetRank(IntPtr handle)
{


+ 2
- 1
src/TensorFlowNET.Core/Eager/c_api.eager.cs View File

@@ -25,7 +25,7 @@ namespace Tensorflow
public delegate IntPtr gradient_function_callback(string op_name,
IntPtr op_inputs,
IntPtr op_outputs,
IntPtr attrs_handle,
string attrs_string,
IntPtr output_grads,
IntPtr skip_input_indices);

@@ -402,6 +402,7 @@ namespace Tensorflow
string name,
IntPtr[] inputs,
int input_size,
string attrs_string,
TFE_FastPathExecute_SetOpAttrs set_op_attrs,
IntPtr[] outputs,
int output_size);


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

@@ -31,6 +31,37 @@ namespace Tensorflow.Eager
}
}

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


+ 26
- 12
src/TensorFlowNET.Core/Gradients/GradientTape.cs View File

@@ -3,6 +3,7 @@ using NumSharp.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Tensorflow.Eager;
@@ -79,15 +80,26 @@ namespace Tensorflow.Gradients
_pop_tape();
}

var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var targets = EagerTensorPass.From(target);
var sources = EagerTensorPass.From(source);

Status status = c_api.TFE_TapeGradient(_tape,
new[] { (target as EagerTensor).EagerTensorHandle }, 1,
new[] { (source as EagerTensor).EagerTensorHandle }, 1,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
targets.Points, targets.Length,
sources.Points, sources.Length,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

public Tensor gradient(Tensor target, ResourceVariable source)
{
var results = gradient(target as EagerTensor, 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 });
@@ -103,14 +115,14 @@ namespace Tensorflow.Gradients
_pop_tape();
}

var results = sources.Select(x => new EagerTensor()).ToArray();
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,
new IntPtr[]
{
target.EagerTensorHandle
}, 1,
sources.Select(x => (x.Handle as EagerTensor).EagerTensorHandle).ToArray(), sources.Length,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
target_inputs.Points, target_inputs.Length,
source_inputs.Points, source_inputs.Length,
results.Points, results.Length);
status.Check(true);

if (!_persistent)
@@ -120,13 +132,15 @@ namespace Tensorflow.Gradients
_tape = null;
}

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

public void Dispose()
{
if (_recording)
_pop_tape();

tf.tensorMgr.Reset();
}
}
}

+ 17
- 11
src/TensorFlowNET.Core/Gradients/math_grad.cs View File

@@ -310,23 +310,26 @@ namespace Tensorflow.Gradients
var input_shape = op.inputs[0]._shape_tuple();
var output_shape = op.outputs[0]._shape_tuple();

Tensor result, factor_tensor;
if(input_shape != null &&
output_shape != null)
{
var input_size = np.prod(input_shape);
var output_size = np.prod(output_shape);
var factor = (int)input_size / Math.Max((int)output_size, 1);
var factor_tensor = constant_op.constant((int)input_size, dtype: sum_grad.dtype);
return new Tensor[] { math_ops.truediv(sum_grad, math_ops.cast(factor_tensor, sum_grad.dtype)), null };
factor_tensor = constant_op.constant(factor, dtype: sum_grad.dtype);
}
else
{
var input_shape_tensor = array_ops.shape(op.inputs[0]);
var output_shape_tensor = array_ops.shape(op.outputs[0]);
var factor = _safe_shape_div(math_ops.reduce_prod(input_shape_tensor), math_ops.reduce_prod(output_shape_tensor));
return new Tensor[] { math_ops.truediv(sum_grad, math_ops.cast(factor, sum_grad.dtype)), null };
throw new NotImplementedException("");
factor_tensor = null;
}

result = math_ops.truediv(sum_grad, math_ops.cast(factor_tensor, sum_grad.dtype));
return new Tensor[] { result, null };
}

/// <summary>
@@ -513,20 +516,23 @@ namespace Tensorflow.Gradients
input_shape = array_ops.shape(op.inputs[0]);
return new Tensor[] { gen_array_ops.tile(grad, input_shape), null };
}
else
else if (!input_0_shape.Contains(-1) && !tf.context.executing_eagerly())
{
throw new NotImplementedException("");
}
}
}

input_shape = array_ops.shape(op.inputs[0]);
ops.colocate_with(input_shape);
var output_shape_kept_dims = math_ops.reduced_shape(input_shape, op.inputs[1]);
var tile_scaling = _safe_shape_div(input_shape, output_shape_kept_dims);
grad = gen_array_ops.reshape(grad, output_shape_kept_dims);
if (!op.get_attr<bool>("keep_dims"))
{
ops.colocate_with(input_shape);
var output_shape_kept_dims = math_ops.reduced_shape(input_shape, op.inputs[1]);
// var tile_scaling = _safe_shape_div(input_shape, output_shape_kept_dims);
grad = gen_array_ops.reshape(grad, output_shape_kept_dims);
}

return new Tensor[] { gen_array_ops.tile(grad, tile_scaling), null };
return new Tensor[] { gen_array_ops.broadcast_to(grad, input_shape), null };
}

[RegisterGradient("RealDiv")]


+ 4
- 0
src/TensorFlowNET.Core/Graphs/Graph.Control.cs View File

@@ -17,6 +17,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Tensorflow.Eager;
using Tensorflow.Operations;
using static Tensorflow.Binding;

@@ -81,6 +82,9 @@ namespace Tensorflow
/// </summary>
public _ControlDependenciesController control_dependencies(object[] control_inputs)
{
if (tf.context.executing_eagerly())
return new _ControlDependenciesController(this, null);

if (control_inputs == null)
return new _ControlDependenciesController(this, null);



+ 34
- 0
src/TensorFlowNET.Core/Graphs/NullContextmanager.cs View File

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

namespace Tensorflow
{
public class NullContextmanager : ITensorFlowObject
{
public void __init__()
{
throw new NotImplementedException();
}

public void __enter__()
{
throw new NotImplementedException();
}

public void __del__()
{
throw new NotImplementedException();
}

public void __exit__()
{
throw new NotImplementedException();
}

public void Dispose()
{
throw new NotImplementedException();
}
}
}

+ 30
- 2
src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs View File

@@ -373,6 +373,19 @@ namespace Tensorflow.Operations

public static Tensor relu_grad(Tensor gradients, Tensor features, string name = null)
{
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,
"ReluGrad", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("ReluGrad", name: name, args: new
{
gradients,
@@ -396,6 +409,19 @@ namespace Tensorflow.Operations

public static Tensor softmax(Tensor logits, string name = null)
{
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,
"Softmax", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("Softmax", name: name, args: new
{
logits
@@ -473,7 +499,8 @@ namespace Tensorflow.Operations
"Relu", name, new IntPtr[]
{
features as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -492,7 +519,8 @@ namespace Tensorflow.Operations
"Tanh", name, new IntPtr[]
{
x as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();


+ 1
- 1
src/TensorFlowNET.Core/Operations/array_ops.cs View File

@@ -349,7 +349,7 @@ namespace Tensorflow
return fill(shape_tensor, ones, name: name);
});

public static Tensor one_hot(Tensor indices, int depth,
public static Tensor one_hot(Tensor indices, Tensor depth,
Tensor on_value = null,
Tensor off_value = null,
TF_DataType dtype = TF_DataType.DtInvalid,


+ 1
- 1
src/TensorFlowNET.Core/Operations/clip_ops.cs View File

@@ -25,7 +25,7 @@ namespace Tensorflow
{
public class clip_ops
{
public static Tensor clip_by_value(Tensor t, Tensor clip_value_min, Tensor clip_value_max, string name = null)
public static Tensor clip_by_value<T1, T2>(Tensor t, T1 clip_value_min, T2 clip_value_max, string name = null)
{
return tf_with(ops.name_scope(name, "clip_by_value", new { t, clip_value_min, clip_value_max }), delegate
{


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

@@ -21,6 +21,7 @@ using static Tensorflow.Binding;
using Tensorflow.Eager;
using System.Linq;
using static Tensorflow.Binding;
using System.Security.Cryptography.X509Certificates;

namespace Tensorflow
{
@@ -60,7 +61,8 @@ namespace Tensorflow
{
values as EagerTensor,
axis as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -165,7 +167,8 @@ namespace Tensorflow
var results = new[] { new EagerTensor() };
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Pack", name,
values.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), values.Length,
values.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), values.Length,
wrap_tfe_src.SetOpAttrs2("axis", axis),
op => wrap_tfe_src.SetOpAttrs(op, "axis", axis),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
@@ -235,7 +238,8 @@ namespace Tensorflow
"Identity", name, new IntPtr[]
{
input as EagerTensor
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -278,15 +282,16 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(dims, value);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Fill", name, new IntPtr[]
{
dims as EagerTensor,
value as EagerTensor
}, 2, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
"Fill", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

@@ -311,7 +316,8 @@ namespace Tensorflow
{
s0 as EagerTensor,
s1 as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return (results[0].Resolve(), results[1].Resolve());
@@ -338,7 +344,8 @@ namespace Tensorflow
{
tensor as EagerTensor,
shape as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -381,13 +388,30 @@ namespace Tensorflow
return _op.output;
}

public static Tensor one_hot(Tensor indices, int depth,
public static Tensor one_hot(Tensor indices, Tensor depth,
Tensor on_value = null,
Tensor off_value = null,
TF_DataType dtype = TF_DataType.DtInvalid,
int axis = -1,
string name = null)
{
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,
"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);

return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("OneHot", name, new { indices, depth, on_value, off_value, axis });
return _op.outputs[0];
}
@@ -407,6 +431,21 @@ namespace Tensorflow

public static Tensor select<Tx, Ty>(Tensor condition, Tx t, Ty e, string name = null)
{
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);

return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("Select", name, new { condition, t, e });
return _op.outputs[0];
}
@@ -427,6 +466,7 @@ namespace Tensorflow
{
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);
@@ -486,7 +526,8 @@ namespace Tensorflow
{
input as EagerTensor,
multiples as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -526,6 +567,14 @@ namespace Tensorflow
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var attrs = new object[]
{
"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[]
{
@@ -534,12 +583,8 @@ namespace Tensorflow
end as EagerTensor,
strides as EagerTensor,
}, 4,
op => wrap_tfe_src.SetOpAttrs(op,
"begin_mask", begin_mask,
"end_mask", end_mask,
"ellipsis_mask", ellipsis_mask,
"new_axis_mask", new_axis_mask,
"shrink_axis_mask", shrink_axis_mask),
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();
@@ -653,8 +698,8 @@ namespace Tensorflow
{
input as EagerTensor
}, 1,
op => wrap_tfe_src.SetOpAttrs(op,
"squeeze_dims", axis),
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();
@@ -689,8 +734,22 @@ namespace Tensorflow
/// <param name="shape"></param>
/// <param name="name"></param>
/// <returns></returns>
public static Tensor broadcast_to(Tensor input, int[] shape, string name = null)
public static Tensor broadcast_to<T>(Tensor input, T shape, string name = null)
{
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,
"BroadcastTo", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}

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

return _op.outputs[0];


+ 196
- 57
src/TensorFlowNET.Core/Operations/gen_math_ops.cs View File

@@ -48,7 +48,7 @@ namespace Tensorflow
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"AddN", name,
inputs.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), inputs.Length,
null,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -65,7 +65,7 @@ namespace Tensorflow
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"AddN", name,
inputs, inputs.Length,
null,
null, null,
results, results.Length);
status.Check(true);
return results[0];
@@ -80,7 +80,23 @@ namespace Tensorflow
/// <param name="name"></param>
/// <returns></returns>
public static Tensor arg_max(Tensor input, int dimension, TF_DataType output_type = TF_DataType.TF_INT64, string name = null)
=> _op_def_lib._apply_op_helper("ArgMax", name, args: new { input, dimension, output_type }).outputs[0];
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(input, dimension);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"ArgMax", name,
inputs.Points, inputs.Length,
wrap_tfe_src.SetOpAttrs2("output_type", output_type),
op => wrap_tfe_src.SetOpAttrs(op, "output_type", output_type),
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}

return _op_def_lib._apply_op_helper("ArgMax", name, args: new { input, dimension, output_type }).output;
}

/// <summary>
/// Returns the index with the smallest value across dimensions of a tensor.
@@ -152,6 +168,7 @@ namespace Tensorflow
input as EagerTensor,
axis as EagerTensor
}, 2,
wrap_tfe_src.SetOpAttrs2("keep_dims", keep_dims),
op => wrap_tfe_src.SetOpAttrs(op, "keep_dims", keep_dims),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
@@ -198,6 +215,7 @@ namespace Tensorflow
input as EagerTensor,
axis as EagerTensor
}, 2,
wrap_tfe_src.SetOpAttrs2("keep_dims", keep_dims),
op => wrap_tfe_src.SetOpAttrs(op, "keep_dims", keep_dims),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
@@ -247,7 +265,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -268,7 +287,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -290,7 +310,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -324,7 +345,8 @@ namespace Tensorflow
"Sin", name, new IntPtr[]
{
x as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -358,7 +380,8 @@ namespace Tensorflow
"Sigmoid", name, new IntPtr[]
{
x as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -451,7 +474,8 @@ namespace Tensorflow
"Tan", name, new IntPtr[]
{
x as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -471,7 +495,8 @@ namespace Tensorflow
"Tanh", name, new IntPtr[]
{
x as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -499,7 +524,8 @@ namespace Tensorflow
{
y as EagerTensor,
dy as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -550,6 +576,21 @@ namespace Tensorflow

public static Tensor greater_equal<Tx, Ty>(Tx x, Ty y, string name = null)
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x, y);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"GreaterEqual", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("GreaterEqual", name: name, args: new { x, y });

return _op.outputs[0];
@@ -559,14 +600,13 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x, y);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Less", name, new IntPtr[]
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
"Less", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}
@@ -578,6 +618,19 @@ namespace Tensorflow

public static Tensor less_equal<Tx, Ty>(Tx x, Ty y, string name = null)
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x, y);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"LessEqual", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("LessEqual", name: name, args: new { x, y });

return _op.outputs[0];
@@ -641,7 +694,8 @@ namespace Tensorflow
"Square", name, new IntPtr[]
{
x as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -693,6 +747,21 @@ namespace Tensorflow
/// <returns> A `Tensor`. Has the same type as `x`.</returns>
public static Tensor log(Tensor x, string name = null)
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Log", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("Log", name, args: new { x });

return _op.outputs[0];
@@ -703,12 +772,20 @@ namespace Tensorflow
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var attrs = new object[]
{
"DstT", DstT,
"Truncate", Truncate
};

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Cast", name,
new IntPtr[] { x as EagerTensor }, 1,
op => wrap_tfe_src.SetOpAttrs(op, "DstT", DstT, "Truncate", Truncate),
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();
}

@@ -721,14 +798,16 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Neg", name, new IntPtr[]
{
x as EagerTensor
}, 2, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
"Neg", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

@@ -746,7 +825,8 @@ namespace Tensorflow
"Sqrt", name, new IntPtr[]
{
x as EagerTensor,
}, 1, null,
}, 1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -767,7 +847,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -788,7 +869,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -816,7 +898,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -845,7 +928,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -866,7 +950,8 @@ namespace Tensorflow
{
y as EagerTensor,
x as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -886,7 +971,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -907,7 +993,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor,
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -935,7 +1022,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -948,6 +1036,21 @@ namespace Tensorflow

public static Tensor reciprocal(Tensor x, string name = null)
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Reciprocal", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("Reciprocal", name, args: new { x });

return _op.outputs[0];
@@ -963,7 +1066,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -984,7 +1088,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -1008,18 +1113,19 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(a, b);
var attrs = new object[]
{
"transpose_a", transpose_a,
"transpose_b", transpose_b
};
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"MatMul", name,
new IntPtr[]
{
a as EagerTensor,
b as EagerTensor
}, 2,
op => wrap_tfe_src.SetOpAttrs(op,
"transpose_a", transpose_a,
"transpose_b", transpose_b),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
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();
}
@@ -1073,6 +1179,21 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor maximum<T1, T2>(T1 x, T2 y, string name = null)
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x, y);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Maximum", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("Maximum", name, args: new { x, y });

return _op.outputs[0];
@@ -1080,6 +1201,21 @@ namespace Tensorflow

public static Tensor minimum<T1, T2>(T1 x, T2 y, string name = null)
{
if (tf.context.executing_eagerly())
{
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(x, y);

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Minimum", name,
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);

return results[0].Resolve();
}

var _op = _op_def_lib._apply_op_helper("Minimum", name, args: new { x, y });

return _op.outputs[0];
@@ -1123,7 +1259,8 @@ namespace Tensorflow
{
x as EagerTensor,
y as EagerTensor
}, 2, null,
}, 2,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -1138,17 +1275,18 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(input, axis);
var attrs = new object[] { "keep_dims", keep_dims };

Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Sum", name,
new IntPtr[]
{
input as EagerTensor,
axis as EagerTensor
}, 2,
op => wrap_tfe_src.SetOpAttrs(op, "keep_dims", keep_dims),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
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();
}

@@ -1199,7 +1337,8 @@ namespace Tensorflow
start as EagerTensor,
limit as EagerTensor,
delta as EagerTensor
}, 3, null,
}, 3,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();


+ 4
- 3
src/TensorFlowNET.Core/Operations/gen_math_ops.eager.cs View File

@@ -11,14 +11,15 @@ namespace Tensorflow
{
public static EagerTensor mul(IntPtr x, IntPtr y, string name = null)
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"Mul", name, new IntPtr[]
{
x,
y,
}, 2, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
}, 2,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}


+ 26
- 20
src/TensorFlowNET.Core/Operations/gen_random_ops.cs View File

@@ -42,17 +42,20 @@ namespace Tensorflow

if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var attrs = new object[]
{
"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, new IntPtr[]
{
shape as EagerTensor,
}, 1,
op => wrap_tfe_src.SetOpAttrs(op,
"seed", seed,
"seed2", seed2,
"dtype", dtype),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
"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();
}
@@ -148,17 +151,20 @@ namespace Tensorflow

if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
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,
"TruncatedNormal", name, new IntPtr[]
{
shape as EagerTensor,
}, 1,
op => wrap_tfe_src.SetOpAttrs(op,
"seed", seed,
"seed2", seed2,
"dtype", dtype),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
"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();
}


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

@@ -29,15 +29,13 @@ namespace Tensorflow
{
if (tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var inputs = EagerTensorPass.From(resource, value);
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"AssignSubVariableOp", name,
new IntPtr[]
{
resource as EagerTensor,
value as EagerTensor
}, 2, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
inputs.Points, inputs.Length,
null, null,
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}
@@ -56,13 +54,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,
"AssignAddVariableOp", name,
new IntPtr[]
{
resource as EagerTensor,
value as EagerTensor
}, 2, null,
inputs.Points, inputs.Length,
null, null,
null, 0);
status.Check(true);
return null;
@@ -75,13 +71,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,
"AssignVariableOp", name,
new IntPtr[]
{
resource as EagerTensor,
value as EagerTensor
}, 2, null,
inputs.Points, inputs.Length,
null, null,
null, 0);
status.Check(true);
return null;
@@ -100,7 +94,8 @@ namespace Tensorflow
Status status = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name,
"VarIsInitializedOp", name,
new IntPtr[] { resource as EagerTensor },
1, null,
1,
null, null,
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
status.Check(true);
return results[0].Resolve();
@@ -125,15 +120,19 @@ namespace Tensorflow
{
if(tf.context.executing_eagerly())
{
var results = new[] { new EagerTensor() };
var results = EagerTensorPass.Create();
var attrs = new object[]
{
"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,
op => wrap_tfe_src.SetOpAttrs(op,
"container", container,
"shared_name", shared_name,
"dtype", dtype,
"shape", shape.dims),
results.Select(x => x.EagerTensorHandle).ToArray(), results.Length);
wrap_tfe_src.SetOpAttrs2(attrs),
op => wrap_tfe_src.SetOpAttrs(op, attrs),
results.Points, results.Length);
status.Check(true);
return results[0].Resolve();
}
@@ -163,6 +162,7 @@ namespace Tensorflow
Status status = c_api.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);


+ 10
- 1
src/TensorFlowNET.Core/Operations/math_ops.cs View File

@@ -348,6 +348,14 @@ namespace Tensorflow
/// <returns>A 1-D Tensor, the output shape as if keepdims were set to True.</returns>
public static Tensor reduced_shape(Tensor input_shape, Tensor axes)
{
if(tf.context.executing_eagerly())
{
var input_shape_val = input_shape.numpy();
var axes_val = (int)axes.numpy();
input_shape_val[axes_val] = 1;
return tf.constant(input_shape_val);
}

input_shape = to_int32(input_shape);
axes = to_int32(axes);

@@ -522,7 +530,8 @@ namespace Tensorflow

public static Tensor reduce_sum(Tensor input_tensor, int axis, bool keepdims = false, string name = null)
{
var m = gen_math_ops._sum(input_tensor, axis, keep_dims: keepdims, name: name);
var dims = _ReductionDims(input_tensor, axis);
var m = gen_math_ops._sum(input_tensor, dims, keep_dims: keepdims, name: name);
return _may_reduce_to_scalar(keepdims, axis, m);
}



+ 9
- 6
src/TensorFlowNET.Core/System/GarbageCollector.cs View File

@@ -54,8 +54,11 @@ namespace Tensorflow

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

private static void Recycle()
@@ -64,7 +67,7 @@ namespace Tensorflow
lock (locker)
{
var items = container.Values
.Where(x => x.RefCounter <= 0 && (DateTime.Now - x.LastUpdateTime).TotalMilliseconds > 100)
.Where(x => x.RefCounter <= 0 && (DateTime.Now - x.LastUpdateTime).TotalMilliseconds > 300)
.ToArray();

foreach (var item in items)
@@ -74,15 +77,15 @@ namespace Tensorflow
switch (item.ItemType)
{
case GCItemType.TensorHandle:
// print($"c_api.TF_DeleteTensor({item.Handle.ToString("x16")})");
//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")})");
//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")})");
//print($"c_api.TFE_DeleteEagerTensor({item.Handle.ToString("x16")})");
c_api.TFE_DeleteEagerTensor(item.Handle);
break;
default:


+ 6
- 1
src/TensorFlowNET.Core/Tensors/Tensor.cs View File

@@ -38,7 +38,8 @@ namespace Tensorflow
_TensorLike,
ITensorOrTensorArray,
IPackable<Tensor>,
ICanBeFlattened
ICanBeFlattened,
IPointerInputs
{
protected int _id;
private readonly Operation _op;
@@ -280,6 +281,10 @@ namespace Tensorflow
} else
throw new InvalidOperationException($"Tensor.AllocationHandle is not null ({AllocationHandle}) but AllocationType is not matched to a C# allocation type ({AllocationType}).");
}

public virtual IntPtr ToPointer()
=> _handle;

public bool IsDisposed => _disposed;

// public int tensor_int_val { get; set; }


+ 1
- 0
src/TensorFlowNET.Core/Tensors/dtypes.cs View File

@@ -199,6 +199,7 @@ namespace Tensorflow
=> type switch
{
TF_DataType.TF_STRING => "string",
TF_DataType.TF_UINT8 => "uint8",
TF_DataType.TF_INT32 => "int32",
TF_DataType.TF_FLOAT => "float32",
TF_DataType.TF_BOOL => "bool",


+ 1
- 0
src/TensorFlowNET.Core/Training/gen_training_ops.cs View File

@@ -72,6 +72,7 @@ namespace Tensorflow
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);


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

@@ -0,0 +1,22 @@
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());
}
}

+ 11
- 0
src/TensorFlowNET.Core/Util/IPointerInputs.cs View File

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

namespace Tensorflow
{
public interface IPointerInputs
{
public IntPtr ToPointer();
}
}

+ 30
- 0
src/TensorFlowNET.Core/Util/PointerInputs.cs View File

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

namespace Tensorflow
{
public abstract class PointerInputs<T>
where T : IPointerInputs, new()
{
protected T[] data;
public int Length
=> data.Length;

public IntPtr[] Points
=> data.Select(x => x.ToPointer()).ToArray();

public PointerInputs(params T[] data)
=> this.data = data;

public T this[int idx]
=> data[idx];

public T[] Items
=> data;

public static implicit operator IntPtr[](PointerInputs<T> inputs)
=> inputs.data.Select(x => x.ToPointer()).ToArray();
}
}

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

@@ -0,0 +1,31 @@
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();
}
}
}

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

@@ -54,7 +54,7 @@ namespace Tensorflow
public BaseResourceVariable(IntPtr handle, IntPtr tensor)
{
_handle = handle;
this.handle = new EagerTensor(tensor);
this.handle = tf.tensorMgr.GetTensor(tensor);
}

public void __init__(bool trainable = true,


+ 4
- 0
src/TensorFlowNET.Core/ops.name_scope.cs View File

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

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

@@ -96,15 +97,18 @@ namespace Tensorflow
get_default_graph()._name_stack = old_scope_name;
}
[DebuggerNonUserCode]
public void __exit__()
{
}

[DebuggerNonUserCode]
public void __init__()
{
}

[DebuggerNonUserCode]
public void __del__()
{


+ 10
- 7
src/TensorFlowNET.Core/tensorflow.cs View File

@@ -40,11 +40,12 @@ namespace Tensorflow
public TF_DataType @string = TF_DataType.TF_STRING;

public Context context = new Context(new ContextOptions(), new Status());
public TensorManager tensorMgr;
public tensorflow()
{
_constructThreadingObjects();
InitGradientEnvironment();
tensorMgr = new TensorManager();
}

private void InitGradientEnvironment()
@@ -64,16 +65,18 @@ namespace Tensorflow
ops.RegisterFromAssembly();
// ops.RegisterFromAssemblyEager();

c_api.TFE_RegisterGradientFunction((op_name, op_inputs, op_outputs, attrs_handle, output_grads, skip_input_indices) =>
c_api.TFE_RegisterGradientFunction((op_name, op_inputs, op_outputs, attrs_string, output_grads, skip_input_indices) =>
{
/*var input_tensors = new BindingArray(op_inputs);
var output_tensors = new BindingArray(op_outputs);
var output_grad_tensors = new BindingArray(output_grads);*/
var input_tensors = new BindingTensorArray(op_inputs).Data.Select(x => new EagerTensor(x)).ToArray();
var output_tensors = new BindingTensorArray(op_outputs).Data.Select(x => new EagerTensor(x)).ToArray();
var output_grad_tensors = new BindingTensorArray(output_grads).Data.Select(x => new EagerTensor(x)).ToArray();
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 attrs = new BindingArray(attrs_handle);//.Data.Select(x => *(int*)x).ToArray();

var gradients = ops.gradientFunctions[op_name](new EagerOperation
{
@@ -85,7 +88,7 @@ namespace Tensorflow
Outputs = output_tensors,
// OutputHandles = output_tensors.Data,
SkipInputIndicesArray = skip_input_indices_param,
AttrsArray = attrs
AttrsArray = attrs_string.Split(',')
}, output_grad_tensors);

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


Loading…
Cancel
Save