Browse Source

add TFE_Executor, TFE_Context and TFE_Op.

tags/v0.20
Oceania2018 5 years ago
parent
commit
855eba9d15
21 changed files with 422 additions and 58 deletions
  1. +11
    -0
      src/TensorFlowNET.Core/APIs/tf.math.cs
  2. +11
    -0
      src/TensorFlowNET.Core/Eager/Context.cs
  3. +4
    -0
      src/TensorFlowNET.Core/Eager/ContextOptions.cs
  4. +56
    -1
      src/TensorFlowNET.Core/Eager/Execute.cs
  5. +23
    -0
      src/TensorFlowNET.Core/Eager/TFE_Context.cs
  6. +23
    -0
      src/TensorFlowNET.Core/Eager/TFE_ContextOptions.cs
  7. +23
    -0
      src/TensorFlowNET.Core/Eager/TFE_Executor.cs
  8. +23
    -0
      src/TensorFlowNET.Core/Eager/TFE_Op.cs
  9. +23
    -0
      src/TensorFlowNET.Core/Eager/TFE_TensorHandle.cs
  10. +9
    -8
      src/TensorFlowNET.Core/Eager/c_api.eager.cs
  11. +33
    -0
      src/TensorFlowNET.Core/Eager/wrap_tfe_src.RecordGradient.cs
  12. +53
    -0
      src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_Execute.cs
  13. +34
    -25
      src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs
  14. +1
    -1
      src/TensorFlowNET.Core/Operations/gen_array_ops.cs
  15. +47
    -6
      src/TensorFlowNET.Core/Operations/gen_math_ops.cs
  16. +7
    -0
      src/TensorFlowNET.Core/Operations/math_ops.cs
  17. +2
    -0
      src/TensorFlowNET.Core/Status/Status.cs
  18. +13
    -4
      src/TensorFlowNET.Core/Tensors/TF_Tensor.cs
  19. +6
    -6
      src/TensorFlowNET.Core/Tensors/Tensor.Implicit.cs
  20. +9
    -1
      src/TensorFlowNET.Core/Tensors/Tensor.Value.cs
  21. +11
    -6
      src/TensorFlowNET.Core/ops.cs

+ 11
- 0
src/TensorFlowNET.Core/APIs/tf.math.cs View File

@@ -448,6 +448,17 @@ namespace Tensorflow
public Tensor reduce_prod(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null) public Tensor reduce_prod(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_prod(input_tensor, axis: axis, keepdims: keepdims, name: name); => math_ops.reduce_prod(input_tensor, axis: axis, keepdims: keepdims, name: name);


/// <summary>
/// Computes the sum of elements across dimensions of a tensor.
/// </summary>
/// <param name="input_tensors"></param>
/// <param name="axis"></param>
/// <param name="keepdims"></param>
/// <param name="name"></param>
/// <returns></returns>
public Tensor reduce_sum(Tensor[] input_tensors, int? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_sum(input_tensors, axis: axis, keepdims: keepdims, name: name);

/// <summary> /// <summary>
/// Computes the sum of elements across dimensions of a tensor. /// Computes the sum of elements across dimensions of a tensor.
/// </summary> /// </summary>


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

@@ -9,6 +9,7 @@ namespace Tensorflow.Eager


public int default_execution_mode; public int default_execution_mode;
public string device_name = ""; public string device_name = "";
bool _initialized = false;


public Context(ContextOptions opts, Status status) public Context(ContextOptions opts, Status status)
{ {
@@ -16,6 +17,13 @@ namespace Tensorflow.Eager
status.Check(true); status.Check(true);
} }


public void ensure_initialized()
{
if (_initialized)
return;
_initialized = true;
}

/// <summary> /// <summary>
/// Dispose any unmanaged resources related to given <paramref name="handle"/>. /// Dispose any unmanaged resources related to given <paramref name="handle"/>.
/// </summary> /// </summary>
@@ -27,5 +35,8 @@ namespace Tensorflow.Eager


public static implicit operator IntPtr(Context ctx) public static implicit operator IntPtr(Context ctx)
=> ctx._handle; => ctx._handle;

public static implicit operator TFE_Context(Context ctx)
=> new TFE_Context(ctx._handle);
} }
} }

+ 4
- 0
src/TensorFlowNET.Core/Eager/ContextOptions.cs View File

@@ -17,6 +17,10 @@ namespace Tensorflow.Eager


public static implicit operator IntPtr(ContextOptions opts) public static implicit operator IntPtr(ContextOptions opts)
=> opts._handle; => opts._handle;

public static implicit operator TFE_ContextOptions(ContextOptions opts)
=> new TFE_ContextOptions(opts._handle);
} }


} }

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

@@ -1,12 +1,67 @@
using System.Collections.Generic; using System.Collections.Generic;
using System;
using System.Linq;


namespace Tensorflow.Eager namespace Tensorflow.Eager
{ {
public class Execute public class Execute
{ {
/// <summary>
/// Execute a TensorFlow operation.
/// </summary>
/// <param name="op_name">
/// Name of the TensorFlow operation (see REGISTER_OP in C++ code) to
/// execute.
/// </param>
/// <param name="num_outputs">
/// The number of outputs of the operation to fetch.
/// </param>
/// <param name="inputs">
/// A list of inputs to the operation. Each entry should be a Tensor, or
/// a value which can be passed to the Tensor constructor to create one.
/// </param>
/// <param name="attrs">
/// A tuple with alternating string attr names and attr values for this
/// operation.
/// </param>
/// <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 Tensor execute(Context ctx, string op_name, Tensor[] inputs, object[] attrs, string name = null)
{
ctx.ensure_initialized();
using (var status = new Status())
{
var retVals = wrap_tfe_src.TFE_Py_Execute(ctx, ctx.device_name, op_name, inputs, attrs, 1, status);

var t = c_api.TFE_TensorHandleResolve(retVals[0], status);
status.Check(true);

return new EagerTensor(t);
}
}

public (TF_DataType, Tensor) args_to_matching_eager(Tensor[] l, Context ctx, TF_DataType default_dtype = TF_DataType.DtInvalid)
{
var dtype = default_dtype;
if(dtype == TF_DataType.DtInvalid)
{
var tensor = ops.convert_to_tensor(l, dtype, preferred_dtype: default_dtype, ctx: ctx);

if (dtype == TF_DataType.DtInvalid)
dtype = tensor.dtype;

return (dtype, tensor);
}
else
{
return (dtype, l[0]);
}
}

public void record_gradient(string op_name, InputList inputs, Dictionary<string, object> attrs, Tensor[] results, string name = null) public void record_gradient(string op_name, InputList inputs, Dictionary<string, object> attrs, Tensor[] results, string name = null)
{ {
pywrap_tfe_src.RecordGradient(op_name, inputs._inputs, attrs, results, name);
wrap_tfe_src.RecordGradient(op_name, inputs._inputs, attrs, results, name);
} }
} }
} }

+ 23
- 0
src/TensorFlowNET.Core/Eager/TFE_Context.cs View File

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

namespace Tensorflow.Eager
{
public struct TFE_Context
{
IntPtr _handle;

public TFE_Context(IntPtr handle)
=> _handle = handle;

public static implicit operator TFE_Context(IntPtr handle)
=> new TFE_Context(handle);

public static implicit operator IntPtr(TFE_Context tensor)
=> tensor._handle;

public override string ToString()
=> $"TFE_Context {_handle}";
}
}

+ 23
- 0
src/TensorFlowNET.Core/Eager/TFE_ContextOptions.cs View File

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

namespace Tensorflow.Eager
{
public struct TFE_ContextOptions
{
IntPtr _handle;

public TFE_ContextOptions(IntPtr handle)
=> _handle = handle;

public static implicit operator TFE_ContextOptions(IntPtr handle)
=> new TFE_ContextOptions(handle);

public static implicit operator IntPtr(TFE_ContextOptions tensor)
=> tensor._handle;

public override string ToString()
=> $"TFE_ContextOptions {_handle}";
}
}

+ 23
- 0
src/TensorFlowNET.Core/Eager/TFE_Executor.cs View File

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

namespace Tensorflow.Eager
{
public struct TFE_Executor
{
IntPtr _handle;

public TFE_Executor(IntPtr handle)
=> _handle = handle;

public static implicit operator TFE_Executor(IntPtr handle)
=> new TFE_Executor(handle);

public static implicit operator IntPtr(TFE_Executor tensor)
=> tensor._handle;

public override string ToString()
=> $"TFE_Executor {_handle}";
}
}

+ 23
- 0
src/TensorFlowNET.Core/Eager/TFE_Op.cs View File

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

namespace Tensorflow.Eager
{
public struct TFE_Op
{
IntPtr _handle;

public TFE_Op(IntPtr handle)
=> _handle = handle;

public static implicit operator TFE_Op(IntPtr handle)
=> new TFE_Op(handle);

public static implicit operator IntPtr(TFE_Op tensor)
=> tensor._handle;

public override string ToString()
=> $"TFE_Op {_handle}";
}
}

+ 23
- 0
src/TensorFlowNET.Core/Eager/TFE_TensorHandle.cs View File

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

namespace Tensorflow.Eager
{
public struct TFE_TensorHandle
{
IntPtr _handle;

public TFE_TensorHandle(IntPtr handle)
=> _handle = handle;

public static implicit operator TFE_TensorHandle(IntPtr handle)
=> new TFE_TensorHandle(handle);

public static implicit operator IntPtr(TFE_TensorHandle tensor)
=> tensor._handle;

public override string ToString()
=> $"TFE_TensorHandle {_handle}";
}
}

+ 9
- 8
src/TensorFlowNET.Core/Eager/c_api.eager.cs View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Tensorflow.Eager;
using TFE_Executor = System.IntPtr; using TFE_Executor = System.IntPtr;


namespace Tensorflow namespace Tensorflow
@@ -11,7 +12,7 @@ namespace Tensorflow
/// </summary> /// </summary>
/// <returns>TFE_ContextOptions*</returns> /// <returns>TFE_ContextOptions*</returns>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_NewContextOptions();
public static extern TFE_ContextOptions TFE_NewContextOptions();


/// <summary> /// <summary>
/// Destroy an options object. /// Destroy an options object.
@@ -70,7 +71,7 @@ namespace Tensorflow
/// <param name="status">TF_Status*</param> /// <param name="status">TF_Status*</param>
/// <returns>TFE_Context*</returns> /// <returns>TFE_Context*</returns>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_NewContext(IntPtr opts, IntPtr status);
public static extern TFE_Context TFE_NewContext(IntPtr opts, IntPtr status);


/// <summary> /// <summary>
/// ///
@@ -88,7 +89,7 @@ namespace Tensorflow
/// <param name="num_retvals">int*</param> /// <param name="num_retvals">int*</param>
/// <param name="status">TF_Status*</param> /// <param name="status">TF_Status*</param>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern void TFE_Execute(IntPtr op, IntPtr[] retvals, ref int num_retvals, IntPtr status);
public static extern void TFE_Execute(TFE_Op op, IntPtr[] retvals, ref int num_retvals, IntPtr status);


/// <summary> /// <summary>
/// ///
@@ -98,7 +99,7 @@ namespace Tensorflow
/// <param name="status">TF_Status*</param> /// <param name="status">TF_Status*</param>
/// <returns></returns> /// <returns></returns>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_NewOp(IntPtr ctx, string op_or_function_name, IntPtr status);
public static extern TFE_Op TFE_NewOp(IntPtr ctx, string op_or_function_name, IntPtr status);


/// <summary> /// <summary>
/// ///
@@ -150,7 +151,7 @@ namespace Tensorflow
/// <param name="device_name"></param> /// <param name="device_name"></param>
/// <param name="status"></param> /// <param name="status"></param>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern void TFE_OpSetDevice(IntPtr op, string device_name, IntPtr status);
public static extern void TFE_OpSetDevice(TFE_Op op, string device_name, IntPtr status);


/// <summary> /// <summary>
/// ///
@@ -167,7 +168,7 @@ namespace Tensorflow
/// <param name="t">const tensorflow::Tensor&</param> /// <param name="t">const tensorflow::Tensor&</param>
/// <returns>TFE_TensorHandle*</returns> /// <returns>TFE_TensorHandle*</returns>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_NewTensorHandle(IntPtr t, IntPtr status);
public static extern TFE_TensorHandle TFE_NewTensorHandle(IntPtr t, IntPtr status);


/// <summary> /// <summary>
/// Sets the default execution mode (sync/async). Note that this can be /// Sets the default execution mode (sync/async). Note that this can be
@@ -195,7 +196,7 @@ namespace Tensorflow
/// <param name="status">TF_Status*</param> /// <param name="status">TF_Status*</param>
/// <returns></returns> /// <returns></returns>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_TensorHandleResolve(IntPtr h, IntPtr status);
public static extern TF_Tensor TFE_TensorHandleResolve(IntPtr h, IntPtr status);


/// <summary> /// <summary>
/// This function will block till the operation that produces `h` has completed. /// This function will block till the operation that produces `h` has completed.
@@ -252,7 +253,7 @@ namespace Tensorflow
/// <param name="is_async"></param> /// <param name="is_async"></param>
/// <returns>TFE_Executor*</returns> /// <returns>TFE_Executor*</returns>
[DllImport(TensorFlowLibName)] [DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_NewExecutor(bool is_async);
public static extern TFE_Executor TFE_NewExecutor(bool is_async);


/// <summary> /// <summary>
/// Deletes the eager Executor without waiting for enqueued nodes. Please call /// Deletes the eager Executor without waiting for enqueued nodes. Please call


+ 33
- 0
src/TensorFlowNET.Core/Eager/wrap_tfe_src.RecordGradient.cs View File

@@ -0,0 +1,33 @@
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 void RecordGradient(string op_name, Tensor[] inputs, Dictionary<string, object> attrs, Tensor[] results, string name = null)
{
var input_ids = inputs.Select(x => x.Id).ToArray();
var input_dtypes = inputs.Select(x => x.dtype).ToArray();

bool should_record = false;
foreach (var input_dtype in input_dtypes)
{
if (Tape.IsDtypeTrainable(input_dtype.as_datatype_enum()))
{
should_record = true;
break;
}
}
if (!should_record) return;

var op_outputs = results;
var op_inputs = inputs;
}
}
}

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

@@ -0,0 +1,53 @@
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 IntPtr[] TFE_Py_Execute(Context ctx,
string device_name,
string op_name,
Tensor[] inputs,
object[] attrs,
int num_outputs,
Status status)
=> TFE_Py_ExecuteCancelable(ctx, device_name, op_name, inputs, attrs, num_outputs, status);

public static IntPtr[] TFE_Py_ExecuteCancelable(Context ctx,
string device_name,
string op_name,
Tensor[] inputs,
object[] attrs,
int num_outputs,
Status status)
{
var op = c_api.TFE_NewOp(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)
{
var tensor_handle = c_api.TFE_NewTensorHandle(inputs[i], status);
c_api.TFE_OpAddInput(op, tensor_handle, status);
}
}
if (status.ok())
SetOpAttrs(ctx, op, attrs, 0, 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;
}
}
}

src/TensorFlowNET.Core/Eager/pywrap_tfe_src.cs → src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs View File

@@ -8,7 +8,7 @@ namespace Tensorflow.Eager
/// <summary> /// <summary>
/// python\eager\pywrap_tfe_src.cc /// python\eager\pywrap_tfe_src.cc
/// </summary> /// </summary>
public class pywrap_tfe_src
public partial class wrap_tfe_src
{ {
static int kFastPathExecuteInputStartIndex = 0; static int kFastPathExecuteInputStartIndex = 0;
public static EagerTensor TFE_Py_FastPathExecute(Context ctx, public static EagerTensor TFE_Py_FastPathExecute(Context ctx,
@@ -19,11 +19,10 @@ namespace Tensorflow.Eager
params object[] args) params object[] args)
{ {
int args_size = args.Length; int args_size = args.Length;
IntPtr op = IntPtr.Zero;
var attr_list_sizes = new Dictionary<string, long>(); var attr_list_sizes = new Dictionary<string, long>();
using (var status = new Status()) using (var status = new Status())
{ {
op = c_api.TFE_NewOp(ctx, opName, status);
var op = c_api.TFE_NewOp(ctx, opName, status);


var op_def = Graph.TFE_GetOpDef(opName); var op_def = Graph.TFE_GetOpDef(opName);


@@ -52,9 +51,9 @@ namespace Tensorflow.Eager
for (int i = 0; i < op_def.InputArg.Count; i++) for (int i = 0; i < op_def.InputArg.Count; i++)
{ {
var input_arg = op_def.InputArg[i]; var input_arg = op_def.InputArg[i];
int len = (args[kFastPathExecuteInputStartIndex + i] as object[]).Length;
if (!string.IsNullOrEmpty(input_arg.NumberAttr)) if (!string.IsNullOrEmpty(input_arg.NumberAttr))
{ {
int len = (args[kFastPathExecuteInputStartIndex + i] as object[]).Length;
c_api.TFE_OpSetAttrInt(op, input_arg.NumberAttr, len); c_api.TFE_OpSetAttrInt(op, input_arg.NumberAttr, len);
attr_list_sizes[input_arg.NumberAttr] = len; attr_list_sizes[input_arg.NumberAttr] = len;


@@ -125,13 +124,16 @@ namespace Tensorflow.Eager
IntPtr op, IntPtr op,
Status status) Status status)
{ {
IntPtr input_handle = IntPtr.Zero;
TFE_TensorHandle input_handle;


switch (inputs) switch (inputs)
{ {
case Tensor input: case Tensor input:
input_handle = c_api.TFE_NewTensorHandle(input, status); input_handle = c_api.TFE_NewTensorHandle(input, status);
break; break;
case Tensor[] input_list:
input_handle = c_api.TFE_NewTensorHandle(input_list[0], status);
break;
default: default:
throw new NotImplementedException(""); throw new NotImplementedException("");
} }
@@ -148,6 +150,25 @@ namespace Tensorflow.Eager
return true; return true;
} }


private static void SetOpAttrs(Context ctx, TFE_Op op, object[] attrs, int start_index, Status out_status)
{
var len = attrs.Length;
for (int i = 0; i < len; i += 2)
{
var key = attrs[start_index + i].ToString();
var value = attrs[start_index + i + 1];

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

/// <summary> /// <summary>
/// This function will set the op attrs required. If an attr has the value of /// 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 /// None, then it will read the AttrDef to get the default value and set that
@@ -188,6 +209,14 @@ namespace Tensorflow.Eager
} }
} }


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, private static bool SetOpAttrScalar(Context ctx, IntPtr op,
string key, object value, TF_AttrType type, string key, object value, TF_AttrType type,
Dictionary<string, long> attr_list_sizes, Dictionary<string, long> attr_list_sizes,
@@ -213,25 +242,5 @@ namespace Tensorflow.Eager


return true; return true;
} }

public static void RecordGradient(string op_name, Tensor[] inputs, Dictionary<string, object> attrs, Tensor[] results, string name = null)
{
var input_ids = inputs.Select(x => x.Id).ToArray();
var input_dtypes = inputs.Select(x => x.dtype).ToArray();

bool should_record = false;
foreach (var input_dtype in input_dtypes)
{
if (Tape.IsDtypeTrainable(input_dtype.as_datatype_enum()))
{
should_record = true;
break;
}
}
if (!should_record) return;

var op_outputs = results;
var op_inputs = inputs;
}
} }
} }

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

@@ -125,7 +125,7 @@ namespace Tensorflow
{ {
if(tf.context.executing_eagerly()) if(tf.context.executing_eagerly())
{ {
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, tf.context.device_name, "Pack", name, null, values, "axis", axis);
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, tf.context.device_name, "Pack", name, null, values, "axis", axis);
return _result; return _result;
} }




+ 47
- 6
src/TensorFlowNET.Core/Operations/gen_math_ops.cs View File

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


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


@@ -22,6 +23,7 @@ namespace Tensorflow
public static class gen_math_ops public static class gen_math_ops
{ {
public static OpDefLibrary _op_def_lib = new OpDefLibrary(); public static OpDefLibrary _op_def_lib = new OpDefLibrary();
public static Execute _execute = new Execute();


public static Tensor _all(Tensor input, Tensor axis, bool keep_dims = false, string name = null) public static Tensor _all(Tensor input, Tensor axis, bool keep_dims = false, string name = null)
{ {
@@ -114,11 +116,36 @@ namespace Tensorflow
/// <returns> A `Tensor`. Has the same type as `input`.</returns> /// <returns> A `Tensor`. Has the same type as `input`.</returns>
public static Tensor mean<T1, T2>(T1 input, T2 axis, bool keep_dims= false, string name = null) public static Tensor mean<T1, T2>(T1 input, T2 axis, bool keep_dims= false, string name = null)
{ {
if (tf.context.executing_eagerly())
{
try
{
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, tf.context.device_name, "Mean", name, null, input, axis, "keep_dims", keep_dims);
return _result;
}
catch (Exception ex)
{
return mean_eager_fallback(input as Tensor[], axis as Tensor, keep_dims: keep_dims, name: name, ctx: tf.context);
}
}

var _op = _op_def_lib._apply_op_helper("Mean", name, args: new { input, reduction_indices = axis, keep_dims = keep_dims }); var _op = _op_def_lib._apply_op_helper("Mean", name, args: new { input, reduction_indices = axis, keep_dims = keep_dims });


return _op.output; return _op.output;
} }


private static Tensor mean_eager_fallback(Tensor[] inputs, Tensor axis, bool keep_dims = false, string name = null, Context ctx = null)
{
var (_attr_T, input) = _execute.args_to_matching_eager(inputs, ctx);
var (_attr_Tidx, axis1) = _execute.args_to_matching_eager(new[] { axis }, ctx, TF_DataType.TF_INT32);
var _inputs_flat = new Tensor[] { input, axis1 };
var _attrs = new object[] { "keep_dims", keep_dims, "T", _attr_T, "Tidx", _attr_Tidx };
var _result = _execute.execute(ctx, "Mean", _inputs_flat, _attrs, name: name);
return _result;
}

public static Tensor prod<T1, T2>(T1 input, T2 axis, bool keep_dims = false, string name = null) public static Tensor prod<T1, T2>(T1 input, T2 axis, bool keep_dims = false, string name = null)
{ {
var _op = _op_def_lib._apply_op_helper("Prod", name, args: new { input, reduction_indices = axis, keep_dims }); var _op = _op_def_lib._apply_op_helper("Prod", name, args: new { input, reduction_indices = axis, keep_dims });
@@ -144,7 +171,7 @@ namespace Tensorflow
{ {
if (tf.context.executing_eagerly()) if (tf.context.executing_eagerly())
{ {
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Add", name, null, x, y);
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Add", name, null, x, y);
return _result; return _result;
} }


@@ -466,7 +493,7 @@ namespace Tensorflow
{ {
if (tf.context.executing_eagerly()) if (tf.context.executing_eagerly())
{ {
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Cast", name, null, x, "DstT", DstT, "Truncate", Truncate);
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Cast", name, null, x, "DstT", DstT, "Truncate", Truncate);
return _result; return _result;
} }


@@ -493,7 +520,7 @@ namespace Tensorflow
{ {
if (tf.context.executing_eagerly()) if (tf.context.executing_eagerly())
{ {
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Sub", name, null, x, y);
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Sub", name, null, x, y);
return _result; return _result;
} }


@@ -544,7 +571,7 @@ namespace Tensorflow
{ {
if (tf.context.executing_eagerly()) if (tf.context.executing_eagerly())
{ {
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Mul", name, null, x, y);
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Mul", name, null, x, y);
return _result; return _result;
} }


@@ -564,7 +591,7 @@ namespace Tensorflow
{ {
if (tf.context.executing_eagerly()) if (tf.context.executing_eagerly())
{ {
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "RealDiv", name, null, x, y);
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "RealDiv", name, null, x, y);
return _result; return _result;
} }


@@ -591,7 +618,7 @@ namespace Tensorflow
{ {
if (tf.context.executing_eagerly()) if (tf.context.executing_eagerly())
{ {
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "FloorDiv", name, null, x, y);
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "FloorDiv", name, null, x, y);
return _result; return _result;
} }


@@ -709,6 +736,14 @@ namespace Tensorflow


public static Tensor _sum<Tx, Ty>(Tx input, Ty axis = default, bool keep_dims = false, string name = null) public static Tensor _sum<Tx, Ty>(Tx input, Ty axis = default, bool keep_dims = false, string name = null)
{ {
if (tf.context.executing_eagerly())
{
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, tf.context.device_name,
"Sum", name, null,
input, axis, "keep_dims", keep_dims);
return _result;
}

var _op = _op_def_lib._apply_op_helper("Sum", name, args: new { input, reduction_indices = axis, keep_dims }); var _op = _op_def_lib._apply_op_helper("Sum", name, args: new { input, reduction_indices = axis, keep_dims });


return _op.outputs[0]; return _op.outputs[0];
@@ -724,6 +759,12 @@ namespace Tensorflow
/// <returns></returns> /// <returns></returns>
public static Tensor range(Tensor start, Tensor limit, Tensor delta, string name = null) public static Tensor range(Tensor start, Tensor limit, Tensor delta, string name = null)
{ {
if (tf.context.executing_eagerly())
{
var _result = wrap_tfe_src.TFE_Py_FastPathExecute(tf.context, tf.context.device_name, "Range", name, null, start, limit, delta);
return _result;
}

var _op = _op_def_lib._apply_op_helper("Range", name, new { start, limit, delta }); var _op = _op_def_lib._apply_op_helper("Range", name, new { start, limit, delta });


return _op.outputs[0]; return _op.outputs[0];


+ 7
- 0
src/TensorFlowNET.Core/Operations/math_ops.cs View File

@@ -480,6 +480,13 @@ namespace Tensorflow
throw new NotImplementedException(); throw new NotImplementedException();
} }


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

public static Tensor reduce_sum(Tensor input_tensor, Tensor axis = null, bool keepdims = false, string name = null) public static Tensor reduce_sum(Tensor input_tensor, Tensor axis = null, bool keepdims = false, string name = null)
{ {
var r = _ReductionDims(input_tensor, axis); var r = _ReductionDims(input_tensor, axis);


+ 2
- 0
src/TensorFlowNET.Core/Status/Status.cs View File

@@ -47,6 +47,8 @@ namespace Tensorflow
TF_SetStatus(_handle, code, msg); TF_SetStatus(_handle, code, msg);
} }


public bool ok() => Code == TF_Code.TF_OK;

/// <summary> /// <summary>
/// Check status /// Check status
/// Throw exception with error message if code != TF_OK /// Throw exception with error message if code != TF_OK


+ 13
- 4
src/TensorFlowNET.Core/Tensors/TF_Tensor.cs View File

@@ -3,11 +3,20 @@ using System.Runtime.InteropServices;


namespace Tensorflow namespace Tensorflow
{ {
[StructLayout(LayoutKind.Sequential)]
public struct TF_Tensor public struct TF_Tensor
{ {
public TF_DataType dtype;
public IntPtr shape;
public IntPtr buffer;
IntPtr _handle;

public TF_Tensor(IntPtr handle)
=> _handle = handle;

public static implicit operator TF_Tensor(IntPtr handle)
=> new TF_Tensor(handle);

public static implicit operator IntPtr(TF_Tensor tensor)
=> tensor._handle;

public override string ToString()
=> $"TF_Tensor {_handle}";
} }
} }

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

@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Tensorflow.Eager;


namespace Tensorflow namespace Tensorflow
{ {
@@ -15,13 +16,12 @@ namespace Tensorflow
} }


public static implicit operator Operation(Tensor tensor) public static implicit operator Operation(Tensor tensor)
{
return tensor.op;
}
=> tensor.op;

public static implicit operator TF_Tensor(Tensor tensor)
=> new TF_Tensor(tensor._handle);


public static implicit operator Tensor(IntPtr handle) public static implicit operator Tensor(IntPtr handle)
{
return new Tensor(handle);
}
=> new Tensor(handle);
} }
} }

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

@@ -157,7 +157,15 @@ namespace Tensorflow
} }
else else
{ {
throw new NotImplementedException("numpy not implemented when ndim > 0");
switch (dtype)
{
case TF_DataType.TF_STRING:
return StringData();
case TF_DataType.TF_INT32:
return ToArray<int>();
default:
return BufferToArray();
}
} }
} }




+ 11
- 6
src/TensorFlowNET.Core/ops.cs View File

@@ -23,6 +23,7 @@ using System.Threading;
using NumSharp; using NumSharp;
using Tensorflow.Util; using Tensorflow.Util;
using static Tensorflow.Binding; using static Tensorflow.Binding;
using Tensorflow.Eager;


namespace Tensorflow namespace Tensorflow
{ {
@@ -95,15 +96,19 @@ namespace Tensorflow
/// <param name="dtype"></param> /// <param name="dtype"></param>
/// <param name="name"></param> /// <param name="name"></param>
/// <returns></returns> /// <returns></returns>
public static Tensor convert_to_tensor(object value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, TF_DataType preferred_dtype = TF_DataType.DtInvalid)
public static Tensor convert_to_tensor(object value,
TF_DataType dtype = TF_DataType.DtInvalid,
string name = null,
TF_DataType preferred_dtype = TF_DataType.DtInvalid,
Context ctx = null)
{ {
return convert_to_tensor_v2(value, dtype, preferred_dtype, name);
return internal_convert_to_tensor(value,
dtype: dtype,
name: name,
preferred_dtype: preferred_dtype,
as_ref: false);
} }


public static Tensor convert_to_tensor_v2(object value, TF_DataType dtype = TF_DataType.DtInvalid, TF_DataType dtype_hint = TF_DataType.DtInvalid, string name = null)
{
return internal_convert_to_tensor(value, dtype: dtype, name: name, preferred_dtype: dtype_hint, as_ref: false);
}


public static Tensor convert_to_tensor_or_composite(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) public static Tensor convert_to_tensor_or_composite(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null)
{ {


Loading…
Cancel
Save