| @@ -43,7 +43,7 @@ namespace Tensorflow | |||
| /// </summary> | |||
| 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) | |||
| { | |||
| @@ -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); | |||
| @@ -27,15 +27,30 @@ namespace Tensorflow.Eager | |||
| /// <param name="ctx">The value of context.context().</param> | |||
| /// <param name="name">Customized name for the operation.</param> | |||
| /// <returns>List of output Tensor objects. The list is empty if there are no outputs</returns> | |||
| public 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) | |||
| @@ -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); | |||
| @@ -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()) | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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, 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 _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); | |||
| } | |||
| /// <summary> | |||
| @@ -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); | |||
| @@ -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; | |||
| } | |||