| @@ -43,7 +43,7 @@ namespace Tensorflow | |||||
| /// </summary> | /// </summary> | ||||
| public partial class c_api | 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) | public static string StringPiece(IntPtr handle) | ||||
| { | { | ||||
| @@ -19,6 +19,13 @@ namespace Tensorflow.Eager | |||||
| _handle = c_api.TFE_TensorHandleResolve(tfe_tensor_handle, status); | _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) | public EagerTensor(string value, string device_name) : base(value) | ||||
| { | { | ||||
| tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | tfe_tensor_handle = c_api.TFE_NewTensorHandle(_handle, status); | ||||
| @@ -27,15 +27,30 @@ namespace Tensorflow.Eager | |||||
| /// <param name="ctx">The value of context.context().</param> | /// <param name="ctx">The value of context.context().</param> | ||||
| /// <param name="name">Customized name for the operation.</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> | /// <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) | |||||
| public Tensor execute(Context ctx, string op_name, int num_outputs, | |||||
| Tensor[] inputs, object[] attrs, | |||||
| string name = null) | |||||
| { | { | ||||
| ctx.ensure_initialized(); | 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) | public (TF_DataType, Tensor[]) args_to_matching_eager(Context ctx, TF_DataType default_dtype = TF_DataType.DtInvalid, object[] args = null) | ||||
| @@ -357,6 +357,15 @@ namespace Tensorflow | |||||
| [UnmanagedFunctionPointer(CallingConvention.StdCall)] | [UnmanagedFunctionPointer(CallingConvention.StdCall)] | ||||
| public delegate void TFE_FastPathExecute_SetOpAttrs(IntPtr op); | 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)] | [DllImport(TensorFlowLibName)] | ||||
| public static extern IntPtr TFE_TapeSetNew(bool persistent, bool watch_accessed_variables); | public static extern IntPtr TFE_TapeSetNew(bool persistent, bool watch_accessed_variables); | ||||
| @@ -48,7 +48,7 @@ namespace Tensorflow.Eager | |||||
| } | } | ||||
| } | } | ||||
| if (status.ok()) | if (status.ok()) | ||||
| SetOpAttrs(ctx, op, attrs, 0, status); | |||||
| SetOpAttrs(ctx, op, attrs, status); | |||||
| var outputs = new IntPtr[num_outputs]; | var outputs = new IntPtr[num_outputs]; | ||||
| if (status.ok()) | if (status.ok()) | ||||
| @@ -173,13 +173,13 @@ namespace Tensorflow.Eager | |||||
| return true; | 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; | var len = attrs.Length; | ||||
| for (int i = 0; i < len; i += 2) | 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; | byte is_list = 0; | ||||
| var type = c_api.TFE_OpGetAttrType(op, key, ref is_list, out_status); | var type = c_api.TFE_OpGetAttrType(op, key, ref is_list, out_status); | ||||
| @@ -79,7 +79,7 @@ namespace Tensorflow | |||||
| var _inputs_flat = input.concat(axis1); | var _inputs_flat = input.concat(axis1); | ||||
| var _attrs = new object[] { "N", _attr_N, "T", _attr_T, "Tidx", _attr_Tidx }; | 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) | public static Tensor[] concat_offset(Tensor concat_dim, Tensor[] shape, string name = null) | ||||
| @@ -155,8 +155,8 @@ namespace Tensorflow | |||||
| using var status = new Status(); | using var status = new Status(); | ||||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | ||||
| "Pack", 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); | ||||
| status.Check(true); | status.Check(true); | ||||
| return new EagerTensor(tensor); | return new EagerTensor(tensor); | ||||
| @@ -141,16 +141,13 @@ namespace Tensorflow | |||||
| input as EagerTensor, | input as EagerTensor, | ||||
| axis as EagerTensor | axis as EagerTensor | ||||
| }, 2, | }, 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); | ||||
| status.Check(true); | status.Check(true); | ||||
| return new EagerTensor(tensor); | return new EagerTensor(tensor); | ||||
| } | } | ||||
| catch (Exception) | 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); | 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 _inputs_flat = input.concat(axis1); | ||||
| var _attrs = new object[] { "keep_dims", keep_dims, "T", _attr_T, "Tidx", _attr_Tidx }; | 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, 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) | ||||
| @@ -198,7 +195,7 @@ namespace Tensorflow | |||||
| var _inputs_flat = input.concat(axis1); | var _inputs_flat = input.concat(axis1); | ||||
| var _attrs = new object[] { "keep_dims", keep_dims, "T", _attr_T, "Tidx", _attr_Tidx }; | 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) | 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, | var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | ||||
| "Cast", name, | "Cast", name, | ||||
| new IntPtr[] { x as EagerTensor }, 1, | 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); | ||||
| status.Check(true); | status.Check(true); | ||||
| return new EagerTensor(tensor); | return new EagerTensor(tensor); | ||||
| @@ -836,10 +833,24 @@ namespace Tensorflow | |||||
| { | { | ||||
| if (tf.context.executing_eagerly()) | 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 }); | 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 | 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) | catch (Exception) | ||||
| { | { | ||||
| @@ -968,7 +987,7 @@ namespace Tensorflow | |||||
| var _inputs_flat = input.concat(axis1); | var _inputs_flat = input.concat(axis1); | ||||
| var _attrs = new object[] { "keep_dims", keep_dims, "T", _attr_T, "Tidx", _attr_Tidx }; | 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); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -87,7 +87,7 @@ namespace Tensorflow | |||||
| "shared_name", shared_name, | "shared_name", shared_name, | ||||
| "dtype", dtype, | "dtype", dtype, | ||||
| "shape", shape.dims | "shape", shape.dims | ||||
| }, 0, status), | |||||
| }, status), | |||||
| status); | status); | ||||
| status.Check(true); | status.Check(true); | ||||
| return new EagerTensor(tensor); | return new EagerTensor(tensor); | ||||
| @@ -118,7 +118,7 @@ namespace Tensorflow | |||||
| var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | var tensor = c_api.TFE_FastPathExecute(tf.context, tf.context.device_name, | ||||
| "ReadVariableOp", name, | "ReadVariableOp", name, | ||||
| new IntPtr[] { resource as EagerTensor }, 1, | 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); | ||||
| status.Check(true); | status.Check(true); | ||||
| return new EagerTensor(tensor); | return new EagerTensor(tensor); | ||||
| @@ -107,7 +107,7 @@ namespace Tensorflow | |||||
| var dims_t = convert_to_eager_tensor(dims, ctx, dtypes.int32); | var dims_t = convert_to_eager_tensor(dims, ctx, dtypes.int32); | ||||
| var inputs_flat = new[] { dims_t, value }; | var inputs_flat = new[] { dims_t, value }; | ||||
| var attrs = new object[] { "T", attr_t, "index_type", TF_DataType.TF_INT32 }; | 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; | return result; | ||||
| } | } | ||||