| /* Copyright 2020 The TensorFlow 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. |
| ==============================================================================*/ |
| |
| #include "tensorflow/c/kernels.h" |
| #include "tensorflow/core/framework/allocator.h" |
| #include "tensorflow/core/framework/device_base.h" |
| #include "tensorflow/core/framework/attr_value.pb.h" |
| #include "tensorflow/core/framework/attr_value_util.h" |
| #include "tensorflow/core/framework/node_def.pb.h" |
| #include "tensorflow/core/framework/op_kernel.h" |
| #include "tensorflow/core/framework/types.h" |
| #include "tensorflow/core/framework/op.h" |
| #include "tensorflow/core/framework/op_def_builder.h" |
| #include "tensorflow/core/framework/summary.pb.h" |
| #include "tensorflow/core/framework/tensor.h" |
| #include "tensorflow/core/platform/env.h" |
| #include "tensorflow/core/platform/status.h" |
| #include "tensorflow/core/platform/strcat.h" |
| #include "tensorflow/core/platform/test.h" |
| #include "tensorflow/core/platform/protobuf.h" |
| #include "tensorflow/core/protobuf/error_codes.pb.h" |
| #include "tensorflow/core/lib/gtl/inlined_vector.h" |
| |
| |
| namespace tensorflow { |
| namespace { |
| |
| class DummyDevice : public DeviceBase { |
| public: |
| explicit DummyDevice(Env* env) : DeviceBase(env) {} |
| Allocator* GetAllocator(AllocatorAttributes /*attr*/) override { |
| return cpu_allocator(); |
| } |
| }; |
| |
| // Helper for comparing ouput and expected output |
| void ExpectSummaryMatches(const Summary& actual, const string& expected_str) { |
| Summary expected; |
| ASSERT_TRUE(protobuf::TextFormat::ParseFromString(expected_str, &expected)); |
| EXPECT_EQ(expected.DebugString(), actual.DebugString()); |
| } |
| |
| |
| void TestScalarSummaryOp(Tensor* tags, Tensor* values, string expected_summary, |
| error::Code expected_code) { |
| // Initialize node used to fetch OpKernel |
| Status status; |
| NodeDef def; |
| def.set_op("ScalarSummary"); |
| |
| def.set_device(DEVICE_CPU); |
| |
| AttrValue valuesTypeAttr; |
| SetAttrValue(values->dtype(), &valuesTypeAttr); |
| (*def.mutable_attr())["T"] = valuesTypeAttr; |
| |
| def.add_input( |
| strings::StrCat("input1: ", DataTypeString(tags->dtype()))); |
| def.add_input( |
| strings::StrCat("input2: ", DataTypeString(values->dtype()))); |
| |
| std::unique_ptr<OpKernel> kernel = |
| CreateOpKernel(DeviceType(DEVICE_CPU), nullptr, |
| nullptr, def, 1, &status); |
| ASSERT_TRUE(status.ok()) << status.ToString(); |
| OpKernelContext::Params params; |
| DummyDevice dummy_device(nullptr); |
| params.device = &dummy_device; |
| params.op_kernel = kernel.get(); |
| AllocatorAttributes alloc_attrs; |
| params.output_attr_array = &alloc_attrs; |
| gtl::InlinedVector<TensorValue, 4> inputs; |
| inputs.emplace_back(tags); |
| inputs.emplace_back(values); |
| params.inputs = &inputs; |
| OpKernelContext ctx(¶ms, 1); |
| kernel->Compute(&ctx); |
| ASSERT_EQ(expected_code, ctx.status().code()); |
| if (expected_code == error::OK){ |
| Summary summary; |
| ASSERT_TRUE(ParseProtoUnlimited(&summary, ctx.mutable_output(0)-> |
| scalar<tstring>()())); |
| ExpectSummaryMatches(summary, expected_summary); |
| |
| } |
| } |
| |
| TEST(ScalarSummaryOpTest, SimpleFloat) { |
| int vectorSize = 3; |
| Tensor tags(DT_STRING, {vectorSize}); |
| Tensor values(DT_FLOAT, {vectorSize}); |
| tags.vec<tstring>()(0) = "tag1"; |
| tags.vec<tstring>()(1) = "tag2"; |
| tags.vec<tstring>()(2) = "tag3"; |
| values.vec<float>()(0) = 1.0f; |
| values.vec<float>()(1) = -0.73f; |
| values.vec<float>()(2) = 10000.0f; |
| TestScalarSummaryOp(&tags, &values, R"( |
| value { tag: 'tag1' simple_value: 1.0 } |
| value { tag: 'tag2' simple_value: -0.73} |
| value { tag: 'tag3' simple_value: 10000.0})", error::OK); |
| } |
| |
| TEST(ScalarSummaryOpTest, SimpleDouble) { |
| int vectorSize = 3; |
| Tensor tags(DT_STRING, {vectorSize}); |
| Tensor values(DT_DOUBLE, {vectorSize}); |
| tags.vec<tstring>()(0) = "tag1"; |
| tags.vec<tstring>()(1) = "tag2"; |
| tags.vec<tstring>()(2) = "tag3"; |
| values.vec<double>()(0) = 1.0; |
| values.vec<double>()(1) = -0.73; |
| values.vec<double>()(2) = 10000.0; |
| TestScalarSummaryOp(&tags, &values, R"( |
| value { tag: 'tag1' simple_value: 1.0 } |
| value { tag: 'tag2' simple_value: -0.73} |
| value { tag: 'tag3' simple_value: 10000.0})", error::OK); |
| } |
| |
| |
| TEST(ScalarSummaryOpTest, SimpleHalf) { |
| int vectorSize = 3; |
| Tensor tags(DT_STRING, {vectorSize}); |
| Tensor values(DT_HALF, {vectorSize}); |
| tags.vec<tstring>()(0) = "tag1"; |
| tags.vec<tstring>()(1) = "tag2"; |
| tags.vec<tstring>()(2) = "tag3"; |
| values.vec<Eigen::half>()(0) = Eigen::half(1.0); |
| values.vec<Eigen::half>()(1) = Eigen::half(-2.0); |
| values.vec<Eigen::half>()(2) = Eigen::half(10000.0); |
| TestScalarSummaryOp(&tags, &values, R"( |
| value { tag: 'tag1' simple_value: 1.0 } |
| value { tag: 'tag2' simple_value: -2.0} |
| value { tag: 'tag3' simple_value: 10000.0})", error::OK); |
| } |
| |
| TEST(ScalarSummaryOpTest, Error_WrongDimsTags) { |
| Tensor tags(DT_STRING, {2, 1}); |
| Tensor values(DT_FLOAT, {2}); |
| tags.matrix<tstring>()(0, 0) = "tag1"; |
| tags.matrix<tstring>()(1, 0) = "tag2"; |
| values.vec<float>()(0) = 1.0f; |
| values.vec<float>()(1) = -2.0f; |
| TestScalarSummaryOp(&tags, &values, R"()", error::INVALID_ARGUMENT); |
| } |
| |
| TEST(ScalarSummaryOpTest, Error_WrongValuesTags) { |
| Tensor tags(DT_STRING, {2}); |
| Tensor values(DT_FLOAT, {2, 1}); |
| tags.vec<tstring>()(0) = "tag1"; |
| tags.vec<tstring>()(1) = "tag2"; |
| values.matrix<float>()(0, 0) = 1.0f; |
| values.matrix<float>()(1, 0) = -2.0f; |
| TestScalarSummaryOp(&tags, &values, R"()", error::INVALID_ARGUMENT); |
| } |
| |
| TEST(ScalarSummaryOpTest, Error_WrongWithSingleTag) { |
| Tensor tags(DT_STRING, {1}); |
| Tensor values(DT_FLOAT, {2, 1}); |
| tags.vec<tstring>()(0) = "tag1"; |
| values.matrix<float>()(0, 0) = 1.0f; |
| values.matrix<float>()(1, 0) = -2.0f; |
| TestScalarSummaryOp(&tags, &values, R"()", error::INVALID_ARGUMENT); |
| } |
| |
| |
| TEST(ScalarSummaryOpTest, IsRegistered){ |
| const OpRegistrationData* reg; |
| TF_CHECK_OK(OpRegistry::Global()->LookUp("ScalarSummary", ®)); |
| } |
| |
| } // namespace |
| } // namespace tensorflow |