diff --git a/src/TensorFlowNET.Core/APIs/tf.debugging.cs b/src/TensorFlowNET.Core/APIs/tf.debugging.cs index 9d129b20..b3b3529e 100644 --- a/src/TensorFlowNET.Core/APIs/tf.debugging.cs +++ b/src/TensorFlowNET.Core/APIs/tf.debugging.cs @@ -15,6 +15,7 @@ ******************************************************************************/ using Tensorflow.Debugging; +using static Tensorflow.Binding; namespace Tensorflow { @@ -27,5 +28,8 @@ namespace Tensorflow /// https://developer.ibm.com/technologies/artificial-intelligence/tutorials/debug-tensorflow/ /// public DebugImpl debugging => new DebugImpl(); + + public void print(Tensor input) + => tf.logging.print_v2(input); } } diff --git a/src/TensorFlowNET.Core/APIs/tf.logging.cs b/src/TensorFlowNET.Core/APIs/tf.logging.cs new file mode 100644 index 00000000..0e10c161 --- /dev/null +++ b/src/TensorFlowNET.Core/APIs/tf.logging.cs @@ -0,0 +1,23 @@ +/***************************************************************************** + Copyright 2021 Haiping Chen. 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. +******************************************************************************/ + +namespace Tensorflow +{ + public partial class tensorflow + { + public logging_ops logging => new logging_ops(); + } +} diff --git a/src/TensorFlowNET.Core/APIs/tf.strings.cs b/src/TensorFlowNET.Core/APIs/tf.strings.cs index 38a40eb4..52cd96b4 100644 --- a/src/TensorFlowNET.Core/APIs/tf.strings.cs +++ b/src/TensorFlowNET.Core/APIs/tf.strings.cs @@ -14,7 +14,7 @@ limitations under the License. ******************************************************************************/ -using Tensorflow.Framework; +using static Tensorflow.Binding; namespace Tensorflow { @@ -77,6 +77,9 @@ namespace Tensorflow public Tensor string_length(Tensor input, string name = null, string unit = "BYTE") => ops.string_length(input, name: name, unit: unit); + public Tensor format(string template, Tensor[] inputs, string placeholder = "{}", int summarize = 3, string name = null) + => ops.string_format(inputs, template: template, placeholder: placeholder, summarize: summarize, name: name); + public RaggedTensor split(Tensor input, string sep = "", int maxsplit = -1, string name = null) => ops.string_split_v2(input, sep: sep, maxsplit : maxsplit, name : name); diff --git a/src/TensorFlowNET.Core/Contexts/Context.ExecuteOp.cs b/src/TensorFlowNET.Core/Contexts/Context.ExecuteOp.cs index def787a9..d6eedd47 100644 --- a/src/TensorFlowNET.Core/Contexts/Context.ExecuteOp.cs +++ b/src/TensorFlowNET.Core/Contexts/Context.ExecuteOp.cs @@ -52,10 +52,11 @@ namespace Tensorflow.Contexts Func eagerAction = () => { - return tf.Runner.TFE_FastPathExecute(new FastPathOpExecInfo(OpType, Name, args.OpInputArgs) + var opExecInfo = new FastPathOpExecInfo(OpType, Name, args.OpInputArgs) { attrs = args.OpAttrs - }); + }; + return tf.Runner.TFE_FastPathExecute(opExecInfo); }; if (tf.Context.has_graph_arg(args.OpInputArgs)) diff --git a/src/TensorFlowNET.Core/Operations/logging_ops.cs b/src/TensorFlowNET.Core/Operations/logging_ops.cs new file mode 100644 index 00000000..e38e60b5 --- /dev/null +++ b/src/TensorFlowNET.Core/Operations/logging_ops.cs @@ -0,0 +1,36 @@ +/***************************************************************************** + Copyright 2021 Haiping Chen. 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 Tensorflow.Contexts; +using static Tensorflow.Binding; + +namespace Tensorflow +{ + public class logging_ops + { + public Tensor print_v2(Tensor input, string output_stream = "stderr", string end = "\n", string name = null) + { + var formatted_string = tf.strings.format("{}", + new[] { input }, + placeholder: "{}", + summarize: 3, + name: name); + + return tf.Context.ExecuteOp("PrintV2", name, new ExecuteOpArgs(formatted_string) + .SetAttributes(new { output_stream, end })); + } + } +} diff --git a/src/TensorFlowNET.Core/Operations/string_ops.cs b/src/TensorFlowNET.Core/Operations/string_ops.cs index 2d7c54c7..59e99960 100644 --- a/src/TensorFlowNET.Core/Operations/string_ops.cs +++ b/src/TensorFlowNET.Core/Operations/string_ops.cs @@ -60,6 +60,19 @@ namespace Tensorflow } }.SetAttributes(new { unit })); + public Tensor string_format(Tensor[] inputs, string template = "%s", string placeholder = "%s", int summarize = 3, string name = null) + => tf.Context.ExecuteOp("StringFormat", name, new ExecuteOpArgs() + { + OpInputArgs = new object[] { inputs }, + GetGradientAttrs = op => new + { + T = op.get_attr("T"), + template = op.get_attr("template"), + placeholder = op.get_attr("placeholder"), + summarize = op.get_attr("summarize") + } + }.SetAttributes(new { template, placeholder, summarize })); + public RaggedTensor string_split_v2(Tensor input, string sep = "", int maxsplit = -1, string name = null) { return tf_with(ops.name_scope(name, "StringSplit"), scope => diff --git a/test/TensorFlowNET.UnitTest/ManagedAPI/LoggingTest.cs b/test/TensorFlowNET.UnitTest/ManagedAPI/LoggingTest.cs new file mode 100644 index 00000000..3fa0d018 --- /dev/null +++ b/test/TensorFlowNET.UnitTest/ManagedAPI/LoggingTest.cs @@ -0,0 +1,16 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using static Tensorflow.Binding; + +namespace TensorFlowNET.UnitTest.ManagedAPI +{ + [TestClass] + public class LoggingTest + { + [TestMethod] + public void PrintTest() + { + var tensor = tf.range(10); + tf.print(tensor); + } + } +}