diff options
author | Chris Ying <chrisying@google.com> | 2018-02-20 12:16:49 -0800 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-02-20 12:20:53 -0800 |
commit | c07a6e6568b776037f052bc0d385a509ec2647aa (patch) | |
tree | 1d6694f27b11be6707bb0b75501cd68300a113c5 | |
parent | 706089cf71af3755cc911722b596bae948d1e5b4 (diff) |
Add Timestamp Op which returns the current timestamp during graph execution
PiperOrigin-RevId: 186342760
-rw-r--r-- | tensorflow/core/api_def/base_api/api_def_Timestamp.pbtxt | 10 | ||||
-rw-r--r-- | tensorflow/core/kernels/logging_ops.cc | 19 | ||||
-rw-r--r-- | tensorflow/core/kernels/logging_ops_test.cc | 25 | ||||
-rw-r--r-- | tensorflow/core/ops/logging_ops.cc | 5 | ||||
-rw-r--r-- | tensorflow/python/ops/control_flow_ops.py | 1 | ||||
-rw-r--r-- | tensorflow/python/ops/logging_ops.py | 1 | ||||
-rw-r--r-- | tensorflow/python/ops/standard_ops.py | 5 | ||||
-rw-r--r-- | tensorflow/tools/api/golden/tensorflow.pbtxt | 4 |
8 files changed, 68 insertions, 2 deletions
diff --git a/tensorflow/core/api_def/base_api/api_def_Timestamp.pbtxt b/tensorflow/core/api_def/base_api/api_def_Timestamp.pbtxt new file mode 100644 index 0000000000..bf2d07bcf5 --- /dev/null +++ b/tensorflow/core/api_def/base_api/api_def_Timestamp.pbtxt @@ -0,0 +1,10 @@ +op { + graph_op_name: "Timestamp" + summary: "Provides the time since epoch in seconds." + description: <<END +Returns the timestamp as a `float64` for seconds since the Unix epoch. + +Note: the timestamp is computed when the op is executed, not when it is added +to the graph. +END +} diff --git a/tensorflow/core/kernels/logging_ops.cc b/tensorflow/core/kernels/logging_ops.cc index bacf3e7740..6b6a14e9a7 100644 --- a/tensorflow/core/kernels/logging_ops.cc +++ b/tensorflow/core/kernels/logging_ops.cc @@ -90,4 +90,23 @@ class PrintOp : public OpKernel { REGISTER_KERNEL_BUILDER(Name("Print").Device(DEVICE_CPU), PrintOp); +class TimestampOp : public OpKernel { + public: + explicit TimestampOp(OpKernelConstruction* context) : OpKernel(context) {} + + void Compute(OpKernelContext* context) override { + TensorShape output_shape; // Default shape is 0 dim, 1 element + Tensor* output_tensor = nullptr; + OP_REQUIRES_OK(context, + context->allocate_output(0, output_shape, &output_tensor)); + + auto output_scalar = output_tensor->scalar<double>(); + double now_us = static_cast<double>(Env::Default()->NowMicros()); + double now_s = now_us / 1000000; + output_scalar() = now_s; + } +}; + +REGISTER_KERNEL_BUILDER(Name("Timestamp").Device(DEVICE_CPU), TimestampOp); + } // end namespace tensorflow diff --git a/tensorflow/core/kernels/logging_ops_test.cc b/tensorflow/core/kernels/logging_ops_test.cc index 9cf669a7ef..5e6958f364 100644 --- a/tensorflow/core/kernels/logging_ops_test.cc +++ b/tensorflow/core/kernels/logging_ops_test.cc @@ -13,6 +13,9 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include <chrono> +#include <thread> + #include "tensorflow/core/framework/fake_input.h" #include "tensorflow/core/framework/node_def_builder.h" #include "tensorflow/core/framework/tensor.h" @@ -96,5 +99,27 @@ TEST_F(PrintingGraphTest, FirstNSuccess) { test::ExpectTensorEqual<int32>(expected, *GetOutput(0)); } +class TimestampTest : public OpsTestBase { + protected: + Status Init() { + TF_CHECK_OK(NodeDefBuilder("op", "Timestamp").Finalize(node_def())); + return InitOp(); + } +}; + +TEST_F(TimestampTest, WaitAtLeast) { + TF_ASSERT_OK(Init()); + TF_ASSERT_OK(RunOpKernel()); + double ts1 = *((*GetOutput(0)).flat<double>().data()); + + // wait 1 second + std::this_thread::sleep_for(std::chrono::seconds(1)); + + TF_ASSERT_OK(RunOpKernel()); + double ts2 = *((*GetOutput(0)).flat<double>().data()); + + EXPECT_LE(1.0, ts2 - ts1); +} + } // end namespace } // end namespace tensorflow diff --git a/tensorflow/core/ops/logging_ops.cc b/tensorflow/core/ops/logging_ops.cc index d263dc25b2..fbde692e95 100644 --- a/tensorflow/core/ops/logging_ops.cc +++ b/tensorflow/core/ops/logging_ops.cc @@ -111,4 +111,9 @@ REGISTER_OP("MergeSummary") .Attr("N : int >= 1") .SetShapeFn(shape_inference::ScalarShape); +REGISTER_OP("Timestamp") + .Output("ts: float64") + .SetIsStateful() + .SetShapeFn(shape_inference::ScalarShape); + } // end namespace tensorflow diff --git a/tensorflow/python/ops/control_flow_ops.py b/tensorflow/python/ops/control_flow_ops.py index c33f351289..f77f0050f7 100644 --- a/tensorflow/python/ops/control_flow_ops.py +++ b/tensorflow/python/ops/control_flow_ops.py @@ -44,6 +44,7 @@ See the @{$python/control_flow_ops} guide. @@add_check_numerics_ops @@Assert @@Print +@@timestamp """ # pylint: disable=g-bad-name from __future__ import absolute_import diff --git a/tensorflow/python/ops/logging_ops.py b/tensorflow/python/ops/logging_ops.py index eadbc1b7c3..3757109c95 100644 --- a/tensorflow/python/ops/logging_ops.py +++ b/tensorflow/python/ops/logging_ops.py @@ -356,3 +356,4 @@ ops.NotDifferentiable("AudioSummary") ops.NotDifferentiable("AudioSummaryV2") ops.NotDifferentiable("MergeSummary") ops.NotDifferentiable("ScalarSummary") +ops.NotDifferentiable("Timestamp") diff --git a/tensorflow/python/ops/standard_ops.py b/tensorflow/python/ops/standard_ops.py index f6d9111009..b62e556967 100644 --- a/tensorflow/python/ops/standard_ops.py +++ b/tensorflow/python/ops/standard_ops.py @@ -60,6 +60,7 @@ from tensorflow.python.ops.io_ops import * from tensorflow.python.ops.linalg_ops import * from tensorflow.python.ops.logging_ops import Print from tensorflow.python.ops.logging_ops import get_summary_op +from tensorflow.python.ops.logging_ops import timestamp from tensorflow.python.ops.lookup_ops import initialize_all_tables from tensorflow.python.ops.lookup_ops import tables_initializer from tensorflow.python.ops.manip_ops import * @@ -232,7 +233,7 @@ _allowed_symbols_clip_ops = [ "global_norm", ] -_allowed_symbols_image_ops = [ +_allowed_symbols_logging_ops = [ # Documented in training.py. # We are not importing training.py to avoid complex dependencies. "audio_summary", @@ -262,8 +263,8 @@ _allowed_symbols = (_allowed_symbols_array_ops + _allowed_symbols_clip_ops + _allowed_symbols_control_flow_ops + _allowed_symbols_functional_ops + - _allowed_symbols_image_ops + _allowed_symbols_gradients + + _allowed_symbols_logging_ops + _allowed_symbols_math_ops + _allowed_symbols_variable_scope_ops + _allowed_symbols_misc + diff --git a/tensorflow/tools/api/golden/tensorflow.pbtxt b/tensorflow/tools/api/golden/tensorflow.pbtxt index e8890e9cc0..2333736583 100644 --- a/tensorflow/tools/api/golden/tensorflow.pbtxt +++ b/tensorflow/tools/api/golden/tensorflow.pbtxt @@ -1989,6 +1989,10 @@ tf_module { argspec: "args=[\'input\', \'multiples\', \'name\'], varargs=None, keywords=None, defaults=[\'None\'], " } member_method { + name: "timestamp" + argspec: "args=[\'name\'], varargs=None, keywords=None, defaults=[\'None\'], " + } + member_method { name: "to_bfloat16" argspec: "args=[\'x\', \'name\'], varargs=None, keywords=None, defaults=[\'ToBFloat16\'], " } |