diff --git a/src/TensorFlowNET.Core/APIs/c_api.cs b/src/TensorFlowNET.Core/APIs/c_api.cs index bdf2785f..56672173 100644 --- a/src/TensorFlowNET.Core/APIs/c_api.cs +++ b/src/TensorFlowNET.Core/APIs/c_api.cs @@ -43,7 +43,7 @@ namespace Tensorflow /// public partial class c_api { - public const string TensorFlowLibName = @"D:\SciSharp\tensorflow-google\bazel-bin\tensorflow\tensorflow.dll"; + public const string TensorFlowLibName = "tensorflow"; public static string StringPiece(IntPtr handle) { diff --git a/src/TensorFlowNET.Core/Eager/EagerTensor.cs b/src/TensorFlowNET.Core/Eager/EagerTensor.cs index bfe3a9e1..b0fed5a5 100644 --- a/src/TensorFlowNET.Core/Eager/EagerTensor.cs +++ b/src/TensorFlowNET.Core/Eager/EagerTensor.cs @@ -19,6 +19,13 @@ namespace Tensorflow.Eager _handle = c_api.TFE_TensorHandleResolve(tfe_tensor_handle, status); } + public EagerTensor(TFE_TensorHandle handle) : base(handle) + { + tfe_tensor_handle = handle; + _handle = c_api.TFE_TensorHandleResolve(tfe_tensor_handle, status); + EagerTensorHandle = c_api.TFE_EagerTensorFromHandle(tf.context, tfe_tensor_handle); + } + public EagerTensor(string value, string device_name) : base(value) { tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); diff --git a/src/TensorFlowNET.Core/Eager/Execute.cs b/src/TensorFlowNET.Core/Eager/Execute.cs index 92460a0d..9aa9a3ee 100644 --- a/src/TensorFlowNET.Core/Eager/Execute.cs +++ b/src/TensorFlowNET.Core/Eager/Execute.cs @@ -27,15 +27,30 @@ namespace Tensorflow.Eager /// The value of context.context(). /// Customized name for the operation. /// List of output Tensor objects. The list is empty if there are no outputs - public Tensor execute(Context ctx, string op_name, Tensor[] inputs, object[] attrs, string name = null) + 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 retVals = wrap_tfe_src.TFE_Execute(ctx, ctx.device_name, op_name, inputs, attrs, 1, status); - return new EagerTensor(retVals[0]); - } + // TFE_TensorHandle + using var status = new Status(); + var retVals = wrap_tfe_src.TFE_Execute(ctx, ctx.device_name, op_name, inputs, attrs, num_outputs, status); + + return new EagerTensor((TFE_TensorHandle)retVals[0]); + + /*IntPtr[] outputs = new IntPtr[num_outputs]; + c_api.TFE_QuickExecute(ctx, ctx.device_name, + "Sum", + inputs.Select(x => (IntPtr)(TFE_TensorHandle)(x as EagerTensor)).ToArray(), inputs.Length, + op => wrap_tfe_src.SetOpAttrs(ctx, op, attrs, 0, status), + outputs, num_outputs, + status); + status.Check(true); + + var tfe_tensor_handle = outputs[0]; + var eager_tensor_handle = c_api.TFE_EagerTensorFromHandle(ctx, tfe_tensor_handle); + return new EagerTensor(eager_tensor_handle);*/ } public (TF_DataType, Tensor[]) args_to_matching_eager(Context ctx, TF_DataType default_dtype = TF_DataType.DtInvalid, object[] args = null) diff --git a/src/TensorFlowNET.Core/Eager/c_api.eager.cs b/src/TensorFlowNET.Core/Eager/c_api.eager.cs index 6b542382..a92d5bda 100644 --- a/src/TensorFlowNET.Core/Eager/c_api.eager.cs +++ b/src/TensorFlowNET.Core/Eager/c_api.eager.cs @@ -357,6 +357,15 @@ namespace Tensorflow [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void TFE_FastPathExecute_SetOpAttrs(IntPtr op); + [DllImport(TensorFlowLibName)] + public static extern IntPtr TFE_QuickExecute(IntPtr ctx, + string device_name, + string op_name, + IntPtr[] inputs, int input_size, + TFE_FastPathExecute_SetOpAttrs set_op_attrs, + IntPtr[] outputs, int output_size, + IntPtr status); + [DllImport(TensorFlowLibName)] public static extern IntPtr TFE_TapeSetNew(bool persistent, bool watch_accessed_variables); diff --git a/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_Execute.cs b/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_Execute.cs index 591290d9..6dfbf035 100644 --- a/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_Execute.cs +++ b/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_Execute.cs @@ -48,7 +48,7 @@ namespace Tensorflow.Eager } } if (status.ok()) - SetOpAttrs(ctx, op, attrs, 0, status); + SetOpAttrs(ctx, op, attrs, status); var outputs = new IntPtr[num_outputs]; if (status.ok()) diff --git a/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs b/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs index 297a7a83..6f225a47 100644 --- a/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs +++ b/src/TensorFlowNET.Core/Eager/wrap_tfe_src.TFE_FastPathExecute.cs @@ -173,13 +173,13 @@ namespace Tensorflow.Eager return true; } - public static void SetOpAttrs(Context ctx, TFE_Op op, object[] attrs, int start_index, Status out_status) + public static void SetOpAttrs(Context ctx, TFE_Op op, object[] attrs, 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]; + 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, out_status); diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs index 00483e2e..3c5a6954 100644 --- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs @@ -79,7 +79,7 @@ namespace Tensorflow var _inputs_flat = input.concat(axis1); var _attrs = new object[] { "N", _attr_N, "T", _attr_T, "Tidx", _attr_Tidx }; - return _execute.execute(ctx, "ConcatV2", _inputs_flat, _attrs, name: name); + return _execute.execute(ctx, "ConcatV2", 1, _inputs_flat, _attrs, name: name); } public static Tensor[] concat_offset(Tensor concat_dim, Tensor[] shape, string name = null) @@ -155,8 +155,8 @@ namespace Tensorflow using var status = new Status(); var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, "Pack", name, - values.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), 1, - op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "axis", axis }, 0 , status), + values.Select(x => (x as EagerTensor).EagerTensorHandle).ToArray(), values.Length, + op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "axis", axis } , status), status); status.Check(true); return new EagerTensor(tensor); diff --git a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs index 6f481f31..0607817c 100644 --- a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs @@ -141,16 +141,13 @@ namespace Tensorflow input as EagerTensor, axis as EagerTensor }, 2, - op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "keep_dims", keep_dims }, 0, status), + op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "keep_dims", keep_dims }, status), status); status.Check(true); return new EagerTensor(tensor); } catch (Exception) { - /*tensors = c_api.TFE_Execute(tf.context, tf.context.device_name, op_name, - inputs, attrs, num_outputs);*/ - return mean_eager_fallback(input as Tensor[], axis as Tensor, keep_dims: keep_dims, name: name, ctx: tf.context); } } @@ -167,7 +164,7 @@ namespace Tensorflow var _inputs_flat = input.concat(axis1); var _attrs = new object[] { "keep_dims", keep_dims, "T", _attr_T, "Tidx", _attr_Tidx }; - return _execute.execute(ctx, "Mean", _inputs_flat, _attrs, name: name); + return _execute.execute(ctx, "Mean", 1, _inputs_flat, _attrs, name: name); } public static Tensor prod(T1 input, T2 axis, bool keep_dims = false, string name = null) @@ -198,7 +195,7 @@ namespace Tensorflow var _inputs_flat = input.concat(axis1); var _attrs = new object[] { "keep_dims", keep_dims, "T", _attr_T, "Tidx", _attr_Tidx }; - return _execute.execute(ctx, "Prod", _inputs_flat, _attrs, name: name); + return _execute.execute(ctx, "Prod", 1, _inputs_flat, _attrs, name: name); } public static Tensor acos(Tensor x, string name = null) @@ -599,7 +596,7 @@ namespace Tensorflow var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, "Cast", name, new IntPtr[] { x as EagerTensor }, 1, - op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "DstT", DstT, "Truncate", Truncate }, 0, status), + op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "DstT", DstT, "Truncate", Truncate }, status), status); status.Check(true); return new EagerTensor(tensor); @@ -836,10 +833,24 @@ namespace Tensorflow { if (tf.context.executing_eagerly()) { - var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, - "MatMul", name, null, - a, b, "transpose_a", transpose_a, "transpose_b", transpose_b); - return _result; + using var status = new Status(); + var tensor = 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(tf.context, op, new object[] + { + "transpose_a", + transpose_a, + "transpose_b", + transpose_b + }, status), + status); + status.Check(true); + return new EagerTensor(tensor); } var _op = _op_def_lib._apply_op_helper("MatMul", name, args: new { a, b, transpose_a, transpose_b }); @@ -944,10 +955,18 @@ namespace Tensorflow { try { - var _result = wrap_tfe_src.TFE_FastPathExecute(tf.context, tf.context.device_name, - "Sum", name, null, - input, axis, "keep_dims", keep_dims); - return _result; + using var status = new Status(); + var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, + "Sum", name, + new IntPtr[] + { + input as EagerTensor, + axis as EagerTensor + }, 2, + op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "keep_dims", keep_dims }, status), + status); + status.Check(true); + return new EagerTensor(tensor); } catch (Exception) { @@ -968,7 +987,7 @@ namespace Tensorflow var _inputs_flat = input.concat(axis1); var _attrs = new object[] { "keep_dims", keep_dims, "T", _attr_T, "Tidx", _attr_Tidx }; - return _execute.execute(ctx, "Sum", _inputs_flat, _attrs, name: name); + return _execute.execute(ctx, "Sum", 1, _inputs_flat, _attrs, name: name); } /// diff --git a/src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs b/src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs index e33bb66c..8ce319eb 100644 --- a/src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs @@ -87,7 +87,7 @@ namespace Tensorflow "shared_name", shared_name, "dtype", dtype, "shape", shape.dims - }, 0, status), + }, status), status); status.Check(true); return new EagerTensor(tensor); @@ -118,7 +118,7 @@ namespace Tensorflow var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, "ReadVariableOp", name, new IntPtr[] { resource as EagerTensor }, 1, - op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "dtype", dtype }, 0, status), + op => wrap_tfe_src.SetOpAttrs(tf.context, op, new object[] { "dtype", dtype }, status), status); status.Check(true); return new EagerTensor(tensor); diff --git a/src/TensorFlowNET.Core/Tensors/constant_op.cs b/src/TensorFlowNET.Core/Tensors/constant_op.cs index 15f61072..73e3365a 100644 --- a/src/TensorFlowNET.Core/Tensors/constant_op.cs +++ b/src/TensorFlowNET.Core/Tensors/constant_op.cs @@ -107,7 +107,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", inputs_flat, attrs); + var result = _execute.execute(ctx, "Fill", 1, inputs_flat, attrs); return result; }