| @@ -14,18 +14,19 @@ | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| namespace Tensorflow.Contrib.Learn.Preprocessing | |||
| using Tensorflow.Contexts; | |||
| using Tensorflow.Framework; | |||
| namespace Tensorflow | |||
| { | |||
| public class VocabularyProcessor | |||
| public partial class tensorflow | |||
| { | |||
| private int _max_document_length; | |||
| private int _min_frequency; | |||
| public VocabularyProcessor(int max_document_length, | |||
| int min_frequency) | |||
| { | |||
| _max_document_length = max_document_length; | |||
| _min_frequency = min_frequency; | |||
| } | |||
| /// <summary> | |||
| /// Public API for tf.debugging namespace | |||
| /// https://www.tensorflow.org/api_docs/python/tf/debugging | |||
| /// More debugging instructions | |||
| /// https://developer.ibm.com/technologies/artificial-intelligence/tutorials/debug-tensorflow/ | |||
| /// </summary> | |||
| public ConfigImpl config => new ConfigImpl(); | |||
| } | |||
| } | |||
| @@ -14,41 +14,18 @@ | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using Tensorflow.Debugging; | |||
| namespace Tensorflow | |||
| { | |||
| public partial class tensorflow | |||
| { | |||
| /// <summary> | |||
| /// Assert the condition `x == y` holds element-wise. | |||
| /// Public API for tf.debugging namespace | |||
| /// https://www.tensorflow.org/api_docs/python/tf/debugging | |||
| /// More debugging instructions | |||
| /// https://developer.ibm.com/technologies/artificial-intelligence/tutorials/debug-tensorflow/ | |||
| /// </summary> | |||
| /// <typeparam name="T1"></typeparam> | |||
| /// <typeparam name="T2"></typeparam> | |||
| /// <param name="t1"></param> | |||
| /// <param name="t2"></param> | |||
| /// <param name="data"></param> | |||
| /// <param name="message"></param> | |||
| /// <param name="name"></param> | |||
| /// <returns></returns> | |||
| public Tensor assert_equal<T1, T2>(T1 t1, | |||
| T2 t2, | |||
| object[] data = null, | |||
| string message = null, | |||
| string name = null) | |||
| => check_ops.assert_equal(t1, | |||
| t2, | |||
| data: data, | |||
| message: message, | |||
| name: name); | |||
| public Tensor assert_greater_equal<T1, T2>(Tensor x, | |||
| Tensor y, | |||
| object[] data = null, | |||
| string message = null, | |||
| string name = null) | |||
| => check_ops.assert_greater_equal(x, | |||
| y, | |||
| data: data, | |||
| message: message, | |||
| name: name); | |||
| public DebugImpl debugging => new DebugImpl(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,85 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| You may obtain a copy of the License at | |||
| http://www.apache.org/licenses/LICENSE-2.0 | |||
| Unless required by applicable law or agreed to in writing, software | |||
| distributed under the License is distributed on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| See the License for the specific language governing permissions and | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using System; | |||
| using System.Diagnostics; | |||
| using System.Linq; | |||
| using Tensorflow.Eager; | |||
| using static Tensorflow.Binding; | |||
| using Google.Protobuf; | |||
| namespace Tensorflow.Contexts | |||
| { | |||
| /// <summary> | |||
| /// Environment in which eager operations execute. | |||
| /// </summary> | |||
| public sealed partial class Context | |||
| { | |||
| // [DebuggerStepThrough] | |||
| public T RunInAutoMode<T>(Func<T> graphAction, Func<T> eagerAction, params Tensor[] tensors) | |||
| { | |||
| var shouldRunInEager = executing_eagerly() | |||
| && tensors.Count(x => x.IsEagerTensor) == tensors.Length; | |||
| if (shouldRunInEager) | |||
| return eagerAction(); | |||
| else | |||
| { | |||
| if (executing_eagerly()) | |||
| { | |||
| graph_mode(); | |||
| var result = graphAction(); | |||
| restore_mode(); | |||
| return result; | |||
| } | |||
| else | |||
| { | |||
| return graphAction(); | |||
| } | |||
| } | |||
| } | |||
| // [DebuggerStepThrough] | |||
| public Tensors RunInAutoMode2(Func<Tensors> graphAction, | |||
| Func<Tensors> eagerAction, | |||
| Action<Operation> recordGradient, | |||
| Tensors tensors) | |||
| { | |||
| var shouldRunInEager = executing_eagerly() | |||
| && tensors.Count(x => x.IsEagerTensor) == tensors.Length; | |||
| if (shouldRunInEager) | |||
| return eagerAction(); | |||
| else | |||
| { | |||
| if (executing_eagerly()) | |||
| { | |||
| graph_mode(); | |||
| var result = graphAction(); | |||
| restore_mode(); | |||
| return result; | |||
| } | |||
| else | |||
| { | |||
| var result = graphAction(); | |||
| if (tf.Runner.MustRecordGradient()) | |||
| recordGradient(result[0].op); | |||
| return result; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,48 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| You may obtain a copy of the License at | |||
| http://www.apache.org/licenses/LICENSE-2.0 | |||
| Unless required by applicable law or agreed to in writing, software | |||
| distributed under the License is distributed on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| See the License for the specific language governing permissions and | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using System; | |||
| using System.Diagnostics; | |||
| namespace Tensorflow.Contexts | |||
| { | |||
| /// <summary> | |||
| /// Environment in which eager operations execute. | |||
| /// </summary> | |||
| public sealed partial class Context | |||
| { | |||
| ConfigProto _config; | |||
| ConfigProto config() | |||
| { | |||
| var config = new ConfigProto() | |||
| { | |||
| LogDevicePlacement = _log_device_placement, | |||
| GpuOptions = _compute_gpu_options() | |||
| }; | |||
| return config; | |||
| } | |||
| GPUOptions _compute_gpu_options() | |||
| { | |||
| return new GPUOptions() | |||
| { | |||
| }; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,42 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| You may obtain a copy of the License at | |||
| http://www.apache.org/licenses/LICENSE-2.0 | |||
| Unless required by applicable law or agreed to in writing, software | |||
| distributed under the License is distributed on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| See the License for the specific language governing permissions and | |||
| limitations under the License. | |||
| ******************************************************************************/ | |||
| using System; | |||
| using System.Diagnostics; | |||
| using System.Linq; | |||
| using Tensorflow.Eager; | |||
| using static Tensorflow.Binding; | |||
| using Google.Protobuf; | |||
| namespace Tensorflow.Contexts | |||
| { | |||
| /// <summary> | |||
| /// Environment in which eager operations execute. | |||
| /// </summary> | |||
| public sealed partial class Context | |||
| { | |||
| ContextDevicePlacementPolicy _device_policy; | |||
| bool _log_device_placement; | |||
| public void log_device_placement(bool enable) | |||
| { | |||
| if (_handle != null) | |||
| c_api.TFE_ContextSetLogDevicePlacement(_handle, enable, tf.Status.Handle); | |||
| _log_device_placement = enable; | |||
| // _thread_local_data.function_call_options = null; | |||
| } | |||
| } | |||
| } | |||
| @@ -19,13 +19,14 @@ using System.Diagnostics; | |||
| using System.Linq; | |||
| using Tensorflow.Eager; | |||
| using static Tensorflow.Binding; | |||
| using Google.Protobuf; | |||
| namespace Tensorflow.Contexts | |||
| { | |||
| /// <summary> | |||
| /// Environment in which eager operations execute. | |||
| /// </summary> | |||
| public sealed class Context : IDisposable | |||
| public sealed partial class Context : IDisposable | |||
| { | |||
| public const int GRAPH_MODE = 0; | |||
| public const int EAGER_MODE = 1; | |||
| @@ -37,14 +38,14 @@ namespace Tensorflow.Contexts | |||
| ContextSwitchStack context_switches; | |||
| public FunctionCallOptions FunctionCallOptions { get; } | |||
| public SafeContextHandle Handle { get; } | |||
| SafeContextHandle _handle; | |||
| public SafeContextHandle Handle => _handle; | |||
| public Context(ContextOptions opts, Status status) | |||
| public Context() | |||
| { | |||
| Handle = c_api.TFE_NewContext(opts.Handle, status.Handle); | |||
| status.Check(true); | |||
| _device_policy = ContextDevicePlacementPolicy.DEVICE_PLACEMENT_SILENT; | |||
| context_switches = new ContextSwitchStack(defaultExecutionMode == EAGER_MODE, false); | |||
| initialized = true; | |||
| initialized = false; | |||
| FunctionCallOptions = new FunctionCallOptions(); | |||
| } | |||
| @@ -55,14 +56,25 @@ namespace Tensorflow.Contexts | |||
| { | |||
| if (initialized) | |||
| return; | |||
| _config = config(); | |||
| var config_str = _config.ToByteArray(); | |||
| using var opts = new ContextOptions(); | |||
| using var status = new Status(); | |||
| c_api.TFE_ContextOptionsSetConfig(opts.Handle, config_str, (ulong)config_str.Length, status.Handle); | |||
| status.Check(true); | |||
| c_api.TFE_ContextOptionsSetDevicePlacementPolicy(opts.Handle, _device_policy); | |||
| _handle = c_api.TFE_NewContext(opts.Handle, status.Handle); | |||
| status.Check(true); | |||
| initialized = true; | |||
| } | |||
| public void start_step() | |||
| => c_api.TFE_ContextStartStep(Handle); | |||
| => c_api.TFE_ContextStartStep(_handle); | |||
| public void end_step() | |||
| => c_api.TFE_ContextEndStep(Handle); | |||
| => c_api.TFE_ContextEndStep(_handle); | |||
| /// <summary> | |||
| /// Checks whether the current thread has eager execution enabled. | |||
| @@ -91,61 +103,7 @@ namespace Tensorflow.Contexts | |||
| context_switches.Pop(); | |||
| } | |||
| // [DebuggerStepThrough] | |||
| public T RunInAutoMode<T>(Func<T> graphAction, Func<T> eagerAction, params Tensor[] tensors) | |||
| { | |||
| var shouldRunInEager = executing_eagerly() | |||
| && tensors.Count(x => x.IsEagerTensor) == tensors.Length; | |||
| if (shouldRunInEager) | |||
| return eagerAction(); | |||
| else | |||
| { | |||
| if (executing_eagerly()) | |||
| { | |||
| graph_mode(); | |||
| var result = graphAction(); | |||
| restore_mode(); | |||
| return result; | |||
| } | |||
| else | |||
| { | |||
| return graphAction(); | |||
| } | |||
| } | |||
| } | |||
| // [DebuggerStepThrough] | |||
| public Tensors RunInAutoMode2(Func<Tensors> graphAction, | |||
| Func<Tensors> eagerAction, | |||
| Action<Operation> recordGradient, | |||
| Tensors tensors) | |||
| { | |||
| var shouldRunInEager = executing_eagerly() | |||
| && tensors.Count(x => x.IsEagerTensor) == tensors.Length; | |||
| if (shouldRunInEager) | |||
| return eagerAction(); | |||
| else | |||
| { | |||
| if (executing_eagerly()) | |||
| { | |||
| graph_mode(); | |||
| var result = graphAction(); | |||
| restore_mode(); | |||
| return result; | |||
| } | |||
| else | |||
| { | |||
| var result = graphAction(); | |||
| if (tf.Runner.MustRecordGradient()) | |||
| recordGradient(result[0].op); | |||
| return result; | |||
| } | |||
| } | |||
| } | |||
| public void Dispose() | |||
| => Handle.Dispose(); | |||
| => _handle.Dispose(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Contexts | |||
| { | |||
| public enum ContextDevicePlacementPolicy | |||
| { | |||
| // Running operations with input tensors on the wrong device will fail. | |||
| DEVICE_PLACEMENT_EXPLICIT = 0, | |||
| // Copy the tensor to the right device but log a warning. | |||
| DEVICE_PLACEMENT_WARN = 1, | |||
| // Silently copy the tensor, which has a performance cost since the operation | |||
| // will be blocked till the copy completes. This is the default placement | |||
| // policy. | |||
| DEVICE_PLACEMENT_SILENT = 2, | |||
| // Placement policy which silently copies int32 tensors but not other dtypes. | |||
| DEVICE_PLACEMENT_SILENT_FOR_INT32 = 3, | |||
| } | |||
| } | |||
| @@ -1,39 +0,0 @@ | |||
| using NumSharp; | |||
| using System.Linq; | |||
| using Tensorflow.Framework; | |||
| namespace Tensorflow.Contrib.Learn.Estimators | |||
| { | |||
| public static class tensor_signature | |||
| { | |||
| public static bool is_compatible_with(this Tensor self, Tensor other) | |||
| { | |||
| bool _shape_is_compatible_0dim(Shape _this, Shape _other) | |||
| { | |||
| var __other = tensor_shape.as_shape(_other); | |||
| if (_this.Dimensions == null || __other.dims == null) | |||
| return true; | |||
| if (_this.NDim != __other.ndim) | |||
| return false; | |||
| foreach (var (x_dim, y_dim) in _this.Dimensions.Zip(__other.dims, (x_dim, y_dim) => (x_dim, y_dim))) | |||
| { | |||
| if (x_dim != y_dim) | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| if (other.is_sparse()) | |||
| { | |||
| return self.dtype.is_compatible_with(other.dtype); | |||
| } | |||
| return self.dtype.is_compatible_with(other.dtype) && | |||
| _shape_is_compatible_0dim(self.shape, other.shape) && | |||
| !self.is_sparse(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,15 +0,0 @@ | |||
| namespace Tensorflow.Contrib.Train | |||
| { | |||
| /// <summary> | |||
| /// Class to hold a set of hyperparameters as name-value pairs. | |||
| /// </summary> | |||
| public class HParams | |||
| { | |||
| public bool load_pretrained { get; set; } | |||
| public HParams(bool load_pretrained) | |||
| { | |||
| this.load_pretrained = load_pretrained; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,50 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.Debugging | |||
| { | |||
| public class DebugImpl | |||
| { | |||
| /// <summary> | |||
| /// Set if device placements should be logged. | |||
| /// </summary> | |||
| /// <param name="enabled"> Whether to enabled device placement logging.</param> | |||
| public void set_log_device_placement(bool enabled) | |||
| => tf.Context.log_device_placement(enabled); | |||
| /// <summary> | |||
| /// Assert the condition `x == y` holds element-wise. | |||
| /// </summary> | |||
| /// <typeparam name="T1"></typeparam> | |||
| /// <typeparam name="T2"></typeparam> | |||
| /// <param name="t1"></param> | |||
| /// <param name="t2"></param> | |||
| /// <param name="data"></param> | |||
| /// <param name="message"></param> | |||
| /// <param name="name"></param> | |||
| /// <returns></returns> | |||
| public Tensor assert_equal<T1, T2>(T1 t1, | |||
| T2 t2, | |||
| object[] data = null, | |||
| string message = null, | |||
| string name = null) | |||
| => check_ops.assert_equal(t1, | |||
| t2, | |||
| data: data, | |||
| message: message, | |||
| name: name); | |||
| public Tensor assert_greater_equal<T1, T2>(Tensor x, | |||
| Tensor y, | |||
| object[] data = null, | |||
| string message = null, | |||
| string name = null) | |||
| => check_ops.assert_greater_equal(x, | |||
| y, | |||
| data: data, | |||
| message: message, | |||
| name: name); | |||
| } | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| using Google.Protobuf; | |||
| using System; | |||
| using System.Runtime.InteropServices; | |||
| using Tensorflow.Contexts; | |||
| using Tensorflow.Device; | |||
| using Tensorflow.Eager; | |||
| using Tensorflow.Util; | |||
| @@ -16,6 +17,22 @@ namespace Tensorflow | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern SafeContextOptionsHandle TFE_NewContextOptions(); | |||
| /// <summary> | |||
| /// Set the config in TF_ContextOptions.options. | |||
| /// config should be a serialized tensorflow.ConfigProto proto. | |||
| /// If config was not parsed successfully as a ConfigProto, record the | |||
| /// error information in *status. | |||
| /// </summary> | |||
| /// <param name="options">TFE_ContextOptions*</param> | |||
| /// <param name="proto"></param> | |||
| /// <param name="proto_len">size_t</param> | |||
| /// <param name="status">SafeStatusHandle</param> | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern void TFE_ContextOptionsSetConfig(SafeContextOptionsHandle opts, byte[] proto, ulong proto_len, SafeStatusHandle status); | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern void TFE_ContextOptionsSetDevicePlacementPolicy(SafeContextOptionsHandle opts, ContextDevicePlacementPolicy device_policy); | |||
| /// <summary> | |||
| /// Destroy an options object. | |||
| /// </summary> | |||
| @@ -23,6 +40,16 @@ namespace Tensorflow | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern void TFE_DeleteContextOptions(IntPtr options); | |||
| /// <summary> | |||
| /// Configure device placement policy logging for the eager executor. Note this | |||
| /// policy is applied to any subsequent op executions. | |||
| /// </summary> | |||
| /// <param name="ctx"></param> | |||
| /// <param name="enable"></param> | |||
| /// <param name="status"></param> | |||
| [DllImport(TensorFlowLibName)] | |||
| public static extern void TFE_ContextSetLogDevicePlacement(SafeContextHandle ctx, bool enable, SafeStatusHandle status); | |||
| /// <summary> | |||
| /// | |||
| /// </summary> | |||
| @@ -0,0 +1,11 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Framework | |||
| { | |||
| public class ConfigImpl | |||
| { | |||
| } | |||
| } | |||
| @@ -2,7 +2,6 @@ | |||
| using System; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using Tensorflow.Contrib.Learn.Estimators; | |||
| namespace Tensorflow.Framework | |||
| { | |||
| @@ -24,6 +23,36 @@ namespace Tensorflow.Framework | |||
| } | |||
| } | |||
| public static bool is_compatible_with(this Tensor self, Tensor other) | |||
| { | |||
| bool _shape_is_compatible_0dim(Shape _this, Shape _other) | |||
| { | |||
| var __other = tensor_shape.as_shape(_other); | |||
| if (_this.Dimensions == null || __other.dims == null) | |||
| return true; | |||
| if (_this.NDim != __other.ndim) | |||
| return false; | |||
| foreach (var (x_dim, y_dim) in _this.Dimensions.Zip(__other.dims, (x_dim, y_dim) => (x_dim, y_dim))) | |||
| { | |||
| if (x_dim != y_dim) | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| if (other.is_sparse()) | |||
| { | |||
| return self.dtype.is_compatible_with(other.dtype); | |||
| } | |||
| return self.dtype.is_compatible_with(other.dtype) && | |||
| _shape_is_compatible_0dim(self.shape, other.shape) && | |||
| !self.is_sparse(); | |||
| } | |||
| public static Dimension dimension_at_index(TensorShape shape, int index) | |||
| { | |||
| return shape.rank < 0 ? | |||
| @@ -122,6 +122,7 @@ namespace Tensorflow | |||
| private static EagerTensor convert_to_eager_tensor(object value, Context ctx, TF_DataType dtype = TF_DataType.DtInvalid) | |||
| { | |||
| ctx.ensure_initialized(); | |||
| // convert data type | |||
| if (dtype != TF_DataType.DtInvalid && | |||
| value.GetType().Name != "NDArray" && | |||
| @@ -53,7 +53,7 @@ namespace Tensorflow | |||
| .CreateLogger(); | |||
| Status = new Status(); | |||
| Context = new Context(new ContextOptions(), Status); | |||
| Context = new Context(); | |||
| OpDefLib = new OpDefLibrary(); | |||
| ConstructThreadingObjects(); | |||
| InitGradientEnvironment(); | |||
| @@ -19,7 +19,7 @@ using System.Threading; | |||
| namespace Tensorflow | |||
| { | |||
| public partial class tensorflow : ITensorFlowObject | |||
| public partial class tensorflow | |||
| { | |||
| protected ThreadLocal<Session> defaultSessionFactory; | |||
| @@ -16,6 +16,12 @@ namespace Tensorflow.Benchmark.Leak | |||
| [Benchmark] | |||
| public void Run() | |||
| { | |||
| tf.debugging.set_log_device_placement(true); | |||
| var a = tf.constant(3.0); | |||
| var b = tf.constant(2.0); | |||
| var c = tf.multiply(a, b); | |||
| int num = 50, width = 64, height = 64; | |||
| // if width = 128, height = 128, the exception occurs faster | |||
| @@ -47,7 +53,7 @@ namespace Tensorflow.Benchmark.Leak | |||
| optimizer: keras.optimizers.RMSprop(), | |||
| metrics: new[] { "accuracy" }); | |||
| model.fit(inputImages, outLables, batch_size: 1, epochs: 200); | |||
| model.fit(inputImages, outLables, batch_size: 32, epochs: 200); | |||
| } | |||
| } | |||
| } | |||