| 134 | explicit SummaryMergeOp(OpKernelConstruction* context) : OpKernel(context) {} |
| 135 | |
| 136 | void Compute(OpKernelContext* c) override { |
| 137 | Summary s; |
| 138 | std::unordered_set<string> tags; |
| 139 | for (int input_num = 0; input_num < c->num_inputs(); input_num++) { |
| 140 | const Tensor& in = c->input(input_num); |
| 141 | auto in_vec = in.flat<tstring>(); |
| 142 | for (int i = 0; i < in_vec.dimension(0); i++) { |
| 143 | const string& s_in = in_vec(i); |
| 144 | Summary summary_in; |
| 145 | if (!ParseProtoUnlimited(&summary_in, s_in)) { |
| 146 | c->SetStatus(errors::InvalidArgument( |
| 147 | "Could not parse one of the summary inputs")); |
| 148 | return; |
| 149 | } |
| 150 | |
| 151 | for (int v = 0; v < summary_in.value_size(); v++) { |
| 152 | const string& tag = summary_in.value(v).tag(); |
| 153 | // The tag is unused by the TensorSummary op, so no need to check |
| 154 | // for duplicates. |
| 155 | if ((!tag.empty()) && !tags.insert(tag).second) { |
| 156 | c->SetStatus(errors::InvalidArgument(strings::StrCat( |
| 157 | "Duplicate tag ", tag, " found in summary inputs"))); |
| 158 | return; |
| 159 | } |
| 160 | *s.add_value() = summary_in.value(v); |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | Tensor* summary_tensor = nullptr; |
| 166 | OP_REQUIRES_OK(c, c->allocate_output(0, TensorShape({}), &summary_tensor)); |
| 167 | CHECK(SerializeToTString(s, &summary_tensor->scalar<tstring>()())); |
| 168 | } |
| 169 | }; |
| 170 | |
| 171 | REGISTER_KERNEL_BUILDER(Name("MergeSummary").Device(DEVICE_CPU), |
nothing calls this directly
no test coverage detected