| @@ -82,33 +82,40 @@ namespace Tensorflow | |||||
| public IDatasetV2 flat_map(Func<Tensor, IDatasetV2> map_func) | public IDatasetV2 flat_map(Func<Tensor, IDatasetV2> map_func) | ||||
| => new FlatMapDataset(this, map_func); | => new FlatMapDataset(this, map_func); | ||||
| public IDatasetV2 model(AutotuneAlgorithm algorithm, long cpu_budget) | |||||
| => new ModelDataset(this, algorithm, cpu_budget); | |||||
| public IDatasetV2 model(AutotuneAlgorithm algorithm, long cpu_budget, long ram_budget) | |||||
| => new ModelDataset(this, algorithm, cpu_budget, ram_budget); | |||||
| public IDatasetV2 with_options(DatasetOptions options) | public IDatasetV2 with_options(DatasetOptions options) | ||||
| => new OptionsDataset(this, options); | => new OptionsDataset(this, options); | ||||
| public IDatasetV2 apply_options() | public IDatasetV2 apply_options() | ||||
| { | { | ||||
| IDatasetV2 dataset = this; | |||||
| // (1) Apply threading options | // (1) Apply threading options | ||||
| // (2) Apply autotune options | |||||
| var autotune = true; | |||||
| long cpu_budget = 0; | |||||
| long ram_budget = 0; | |||||
| if (autotune) | |||||
| dataset = dataset.model(AutotuneAlgorithm.HILL_CLIMB, cpu_budget, ram_budget); | |||||
| // (3) Apply graph rewrite options | |||||
| var graph_rewrites = new[] | var graph_rewrites = new[] | ||||
| { | { | ||||
| "map_and_batch_fusion", | |||||
| "noop_elimination", | "noop_elimination", | ||||
| "map_and_batch_fusion", | |||||
| "shuffle_and_repeat_fusion" | "shuffle_and_repeat_fusion" | ||||
| }; | }; | ||||
| var graph_rewrite_configs = new string[] | |||||
| { | |||||
| "autotune_buffer_sizes:autotune:true", | |||||
| "disable_prefetch_legacy_autotune:autotune:true", | |||||
| "enable_gradient_descent:autotune:true", | |||||
| "map_parallelization:autotune:true" | |||||
| }; | |||||
| var graph_rewrite_configs = new string[0]; | |||||
| // (2) Apply graph rewrite options | |||||
| var dataset = optimize(graph_rewrites, graph_rewrite_configs); | |||||
| // (3) Apply autotune options | |||||
| var autotune = true; | |||||
| long cpu_budget = 0; | |||||
| if (autotune) | |||||
| dataset = dataset.model(AutotuneAlgorithm.HILL_CLIMB, cpu_budget); | |||||
| dataset = new OptimizeDataset(dataset, new string[0], new string[0], graph_rewrites, graph_rewrite_configs); | |||||
| // (4) Apply stats aggregator options | // (4) Apply stats aggregator options | ||||
| @@ -76,7 +76,7 @@ namespace Tensorflow | |||||
| IDatasetV2 flat_map(Func<Tensor, IDatasetV2> map_func); | IDatasetV2 flat_map(Func<Tensor, IDatasetV2> map_func); | ||||
| IDatasetV2 model(AutotuneAlgorithm algorithm, long cpu_budget); | |||||
| IDatasetV2 model(AutotuneAlgorithm algorithm, long cpu_budget, long ram_budget); | |||||
| IDatasetV2 with_options(DatasetOptions options); | IDatasetV2 with_options(DatasetOptions options); | ||||
| @@ -9,14 +9,16 @@ namespace Tensorflow | |||||
| { | { | ||||
| public ModelDataset(IDatasetV2 input_dataset, | public ModelDataset(IDatasetV2 input_dataset, | ||||
| AutotuneAlgorithm algorithm, | AutotuneAlgorithm algorithm, | ||||
| long cpu_budget) : | |||||
| long cpu_budget, | |||||
| long ram_budget) : | |||||
| base(input_dataset) | base(input_dataset) | ||||
| { | { | ||||
| variant_tensor = ops.model_dataset(input_dataset.variant_tensor, | variant_tensor = ops.model_dataset(input_dataset.variant_tensor, | ||||
| output_types, | output_types, | ||||
| output_shapes, | output_shapes, | ||||
| algorithm, | algorithm, | ||||
| cpu_budget); | |||||
| cpu_budget, | |||||
| ram_budget); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -8,19 +8,30 @@ namespace Tensorflow | |||||
| public class OptimizeDataset : UnaryUnchangedStructureDataset | public class OptimizeDataset : UnaryUnchangedStructureDataset | ||||
| { | { | ||||
| public OptimizeDataset(IDatasetV2 dataset, | public OptimizeDataset(IDatasetV2 dataset, | ||||
| string[] optimizations = null, | |||||
| string[] optimizations_enabled = null, | |||||
| string[] optimizations_disabled = null, | |||||
| string[] optimizations_default = null, | |||||
| string[] optimization_configs = null) : | string[] optimization_configs = null) : | ||||
| base(dataset) | base(dataset) | ||||
| { | { | ||||
| if (optimizations == null) | |||||
| optimizations = new string[0]; | |||||
| if (optimizations_enabled == null) | |||||
| optimizations_enabled = new string[0]; | |||||
| if (optimizations_disabled == null) | |||||
| optimizations_disabled = new string[0]; | |||||
| if (optimizations_default == null) | |||||
| optimizations_default = new string[0]; | |||||
| if (optimization_configs == null) | if (optimization_configs == null) | ||||
| optimization_configs = new string[0]; | optimization_configs = new string[0]; | ||||
| var _optimizations = tf.convert_to_tensor(optimizations, dtype: TF_DataType.TF_STRING, name: "optimizations"); | |||||
| variant_tensor = ops.optimize_dataset( | |||||
| var _optimizations_enabled = tf.convert_to_tensor(optimizations_enabled, dtype: TF_DataType.TF_STRING, name: "optimizations_enabled"); | |||||
| var _optimizations_disabled = tf.convert_to_tensor(optimizations_disabled, dtype: TF_DataType.TF_STRING, name: "optimizations_disabled"); | |||||
| var _optimizations_default = tf.convert_to_tensor(optimizations_default, dtype: TF_DataType.TF_STRING, name: "optimizations_default"); | |||||
| variant_tensor = ops.optimize_dataset_v2( | |||||
| _input_dataset.variant_tensor, | _input_dataset.variant_tensor, | ||||
| _optimizations, | |||||
| _optimizations_enabled, | |||||
| _optimizations_disabled, | |||||
| _optimizations_default, | |||||
| output_types, | output_types, | ||||
| output_shapes, | output_shapes, | ||||
| optimization_configs: optimization_configs); | optimization_configs: optimization_configs); | ||||
| @@ -295,7 +295,7 @@ namespace Tensorflow.Eager | |||||
| { | { | ||||
| if (type == TF_AttrType.TF_ATTR_STRING && values is string[] values3) | if (type == TF_AttrType.TF_ATTR_STRING && values is string[] values3) | ||||
| { | { | ||||
| c_api.TFE_OpSetAttrStringList(op, key, new IntPtr[0], values3.Select(x => x.Length).ToArray(), values3.Length); | |||||
| c_api.TFE_OpSetAttrStringList(op, key, values3, values3.Select(x => Convert.ToUInt64(x.Length)).ToArray(), values3.Length); | |||||
| attr_list_sizes[key] = values3.Length; | attr_list_sizes[key] = values3.Length; | ||||
| } | } | ||||
| else if (type == TF_AttrType.TF_ATTR_SHAPE && values is TensorShape[] values1) | else if (type == TF_AttrType.TF_ATTR_SHAPE && values is TensorShape[] values1) | ||||
| @@ -252,7 +252,7 @@ namespace Tensorflow | |||||
| public static extern void TFE_OpSetAttrShapeList(SafeOpHandle op, string attr_name, IntPtr[] dims, int[] num_dims, int num_values, SafeStatusHandle out_status); | public static extern void TFE_OpSetAttrShapeList(SafeOpHandle op, string attr_name, IntPtr[] dims, int[] num_dims, int num_values, SafeStatusHandle out_status); | ||||
| [DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
| public static extern void TFE_OpSetAttrStringList(SafeOpHandle op, string attr_name, IntPtr[] values, int[] lengths, int num_values); | |||||
| public static extern void TFE_OpSetAttrStringList(SafeOpHandle op, string attr_name, string[] values, ulong[] lengths, int num_values); | |||||
| [DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
| public static extern void TFE_OpSetAttrBool(SafeOpHandle op, string attr_name, bool value); | public static extern void TFE_OpSetAttrBool(SafeOpHandle op, string attr_name, bool value); | ||||
| @@ -67,8 +67,19 @@ namespace Tensorflow | |||||
| if (seed2 is null) | if (seed2 is null) | ||||
| _seed2 = constant_op.constant(0, dtype: TF_DataType.TF_INT64, name: "seed2"); | _seed2 = constant_op.constant(0, dtype: TF_DataType.TF_INT64, name: "seed2"); | ||||
| else | else | ||||
| _seed2 = constant_op.constant(seed2.Value, dtype: TF_DataType.TF_INT64, name: "seed2"); | |||||
| { | |||||
| _seed2 = tf_with(ops.name_scope("seed2"), scope => | |||||
| { | |||||
| _seed2 = constant_op.constant(seed2.Value, dtype: TF_DataType.TF_INT64); | |||||
| return array_ops.where_v2( | |||||
| math_ops.logical_and( | |||||
| math_ops.equal(_seed, 0l), math_ops.equal(_seed2, 0l)), | |||||
| constant_op.constant(2^31 - 1, dtype: dtypes.int64), | |||||
| _seed2, | |||||
| name: scope); | |||||
| }); | |||||
| } | |||||
| return (_seed, _seed2); | return (_seed, _seed2); | ||||
| } | } | ||||
| } | } | ||||
| @@ -168,6 +168,20 @@ namespace Tensorflow | |||||
| optimization_configs = optimization_configs ?? new string[0] | optimization_configs = optimization_configs ?? new string[0] | ||||
| })); | })); | ||||
| public Tensor optimize_dataset_v2(Tensor input_dataset, Tensor optimizations_enabled, | |||||
| Tensor optimizations_disabled, Tensor optimizations_default, | |||||
| TF_DataType[] output_types, TensorShape[] output_shapes, | |||||
| string[] optimization_configs = null, | |||||
| string name = null) | |||||
| => tf.Context.ExecuteOp("OptimizeDatasetV2", name, new ExecuteOpArgs(input_dataset, | |||||
| optimizations_enabled, optimizations_disabled, optimizations_default) | |||||
| .SetAttributes(new | |||||
| { | |||||
| output_types, | |||||
| output_shapes, | |||||
| optimization_configs = optimization_configs ?? new string[0] | |||||
| })); | |||||
| /// <summary> | /// <summary> | ||||
| /// Identity transformation that models performance. | /// Identity transformation that models performance. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -180,13 +194,14 @@ namespace Tensorflow | |||||
| /// <returns></returns> | /// <returns></returns> | ||||
| public Tensor model_dataset(Tensor input_dataset, | public Tensor model_dataset(Tensor input_dataset, | ||||
| TF_DataType[] output_types, TensorShape[] output_shapes, | TF_DataType[] output_types, TensorShape[] output_shapes, | ||||
| AutotuneAlgorithm algorithm, long cpu_budget, | |||||
| AutotuneAlgorithm algorithm, long cpu_budget, long ram_budget, | |||||
| string name = null) | string name = null) | ||||
| => tf.Context.ExecuteOp("ModelDataset", name, new ExecuteOpArgs(input_dataset) | => tf.Context.ExecuteOp("ModelDataset", name, new ExecuteOpArgs(input_dataset) | ||||
| .SetAttributes(new | .SetAttributes(new | ||||
| { | { | ||||
| algorithm, | algorithm, | ||||
| cpu_budget, | cpu_budget, | ||||
| ram_budget, | |||||
| output_types, | output_types, | ||||
| output_shapes | output_shapes | ||||
| })); | })); | ||||
| @@ -327,24 +327,16 @@ namespace Tensorflow | |||||
| => tf.Context.ExecuteOp("Log1p", name, new ExecuteOpArgs(x)); | => tf.Context.ExecuteOp("Log1p", name, new ExecuteOpArgs(x)); | ||||
| public static Tensor logical_and(Tensor x, Tensor y, string name = null) | public static Tensor logical_and(Tensor x, Tensor y, string name = null) | ||||
| => tf.OpDefLib._apply_op_helper("LogicalAnd", name, args: new { x, y }); | |||||
| => tf.Context.ExecuteOp("LogicalAnd", name, new ExecuteOpArgs(x, y)); | |||||
| public static Tensor logical_and(bool x, bool y, string name = null) | public static Tensor logical_and(bool x, bool y, string name = null) | ||||
| => tf.Context.ExecuteOp("LogicalAnd", name, new ExecuteOpArgs(x, y)); | => tf.Context.ExecuteOp("LogicalAnd", name, new ExecuteOpArgs(x, y)); | ||||
| public static Tensor logical_not(Tensor x, string name = null) | public static Tensor logical_not(Tensor x, string name = null) | ||||
| { | |||||
| var _op = tf.OpDefLib._apply_op_helper("LogicalNot", name, args: new { x }); | |||||
| return _op.outputs[0]; | |||||
| } | |||||
| => tf.Context.ExecuteOp("LogicalNot", name, new ExecuteOpArgs(x)); | |||||
| public static Tensor logical_or(Tensor x, Tensor y, string name = null) | public static Tensor logical_or(Tensor x, Tensor y, string name = null) | ||||
| { | |||||
| var _op = tf.OpDefLib._apply_op_helper("LogicalOr", name, args: new { x, y }); | |||||
| return _op.outputs[0]; | |||||
| } | |||||
| => tf.Context.ExecuteOp("LogicalOr", name, new ExecuteOpArgs(x, y)); | |||||
| public static Tensor logical_xor(Tensor x, Tensor y, string name = "LogicalXor") | public static Tensor logical_xor(Tensor x, Tensor y, string name = "LogicalXor") | ||||
| { | { | ||||
| @@ -77,10 +77,10 @@ namespace Tensorflow | |||||
| /// <param name="seed2"></param> | /// <param name="seed2"></param> | ||||
| /// <param name="name"></param> | /// <param name="name"></param> | ||||
| /// <returns></returns> | /// <returns></returns> | ||||
| public static Tensor random_shuffle(Tensor value, int seed = 0, int seed2 = 0, | |||||
| public static Tensor random_shuffle(Tensor value, int? seed = 0, int? seed2 = 0, | |||||
| string name = null) | string name = null) | ||||
| => tf.Context.ExecuteOp("RandomShuffle", name, new ExecuteOpArgs(value) | => tf.Context.ExecuteOp("RandomShuffle", name, new ExecuteOpArgs(value) | ||||
| .SetAttributes(new { seed = seed, seed2 = seed2 })); | |||||
| .SetAttributes(new { seed = seed ?? 0, seed2 = seed2 ?? 0 })); | |||||
| /// <summary> | /// <summary> | ||||
| /// Outputs random values from a truncated normal distribution. | /// Outputs random values from a truncated normal distribution. | ||||
| @@ -116,7 +116,7 @@ namespace Tensorflow | |||||
| public static Tensor random_shuffle(Tensor value, int? seed = null, string name = null) | public static Tensor random_shuffle(Tensor value, int? seed = null, string name = null) | ||||
| { | { | ||||
| var (seed1, seed2) = random_seed.get_seed(seed); | var (seed1, seed2) = random_seed.get_seed(seed); | ||||
| return gen_random_ops.random_shuffle(value, seed: seed1 ?? 0, seed2: seed2 ?? 0, name: name); | |||||
| return gen_random_ops.random_shuffle(value, seed: seed1, seed2: seed2, name: name); | |||||
| } | } | ||||
| public static Tensor truncated_normal(int[] shape, | public static Tensor truncated_normal(int[] shape, | ||||