1 /* Copyright 2018 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include "tensorflow/c/c_api_experimental.h"
17
18 #include "absl/strings/substitute.h"
19 #include "tensorflow/c/c_api.h"
20 #include "tensorflow/c/c_api_internal.h"
21 #include "tensorflow/c/eager/c_api.h"
22 #include "tensorflow/c/eager/c_api_internal.h"
23 #include "tensorflow/compiler/jit/flags.h"
24 #include "tensorflow/core/common_runtime/eager/attr_builder.h"
25 #include "tensorflow/core/framework/tensor.pb.h"
26 #include "tensorflow/core/graph/graph.h"
27 #include "tensorflow/core/graph/node_builder.h"
28 #include "tensorflow/core/lib/strings/strcat.h"
29 #include "tensorflow/core/platform/init_main.h"
30 #include "tensorflow/core/platform/net.h"
31 #include "tensorflow/core/platform/platform.h"
32 #include "tensorflow/core/protobuf/config.pb.h"
33 #include "tensorflow/core/protobuf/tensorflow_server.pb.h"
34
35 using tensorflow::FunctionDef;
36 using tensorflow::Node;
37 using tensorflow::NodeBuilder;
38 using tensorflow::Status;
39
40 namespace {
41 typedef std::unique_ptr<TF_Function, decltype(&TF_DeleteFunction)>
42 UniqueFuncPtr;
43 }
44
45 // struct TF_Operation { tensorflow::Node node; };
ToTF_Operation(Node * node)46 static TF_Operation* ToTF_Operation(Node* node) {
47 return static_cast<TF_Operation*>(static_cast<void*>(node));
48 }
49
TF_EnableXLACompilation(TF_SessionOptions * options,unsigned char enable)50 void TF_EnableXLACompilation(TF_SessionOptions* options, unsigned char enable) {
51 tensorflow::ConfigProto& config = options->options.config;
52 auto* optimizer_options =
53 config.mutable_graph_options()->mutable_optimizer_options();
54 if (enable) {
55 optimizer_options->set_global_jit_level(tensorflow::OptimizerOptions::ON_1);
56
57 // These XLA flags are needed to trigger XLA properly from C (more generally
58 // non-Python) clients. If this API is called again with `enable` set to
59 // false, it is safe to keep these flag values as is.
60 tensorflow::MarkForCompilationPassFlags* flags =
61 tensorflow::GetMarkForCompilationPassFlags();
62 flags->tf_xla_cpu_global_jit = true;
63 flags->tf_xla_min_cluster_size = 1;
64 } else {
65 optimizer_options->set_global_jit_level(tensorflow::OptimizerOptions::OFF);
66 }
67 }
68
TF_CreateConfig(unsigned char enable_xla_compilation,unsigned char gpu_memory_allow_growth,unsigned int num_cpu_devices)69 TF_Buffer* TF_CreateConfig(unsigned char enable_xla_compilation,
70 unsigned char gpu_memory_allow_growth,
71 unsigned int num_cpu_devices) {
72 tensorflow::ConfigProto config;
73 auto* optimizer_options =
74 config.mutable_graph_options()->mutable_optimizer_options();
75 if (enable_xla_compilation) {
76 optimizer_options->set_global_jit_level(tensorflow::OptimizerOptions::ON_1);
77
78 // These XLA flags are needed to trigger XLA properly from C (more generally
79 // non-Python) clients. If this API is called again with `enable` set to
80 // false, it is safe to keep these flag values as is.
81 tensorflow::MarkForCompilationPassFlags* flags =
82 tensorflow::GetMarkForCompilationPassFlags();
83 flags->tf_xla_cpu_global_jit = true;
84 flags->tf_xla_min_cluster_size = 1;
85 } else {
86 optimizer_options->set_global_jit_level(tensorflow::OptimizerOptions::OFF);
87 }
88
89 auto* gpu_options = config.mutable_gpu_options();
90 gpu_options->set_allow_growth(gpu_memory_allow_growth);
91
92 (*config.mutable_device_count())["CPU"] = num_cpu_devices;
93
94 // TODO(b/113217601): This is needed for EagerContext::runner_ to use a
95 // threadpool, so that we avoid the possibility of running the runner_ in the
96 // threadpool of GPU event mgr, as that can trigger more callbacks to be
97 // scheduled on that same threadpool, causing a deadlock in cases where the
98 // caller of event_mgr->ThenExecute() blocks on the completion of the callback
99 // (as in the case of ConstOp kernel creation on GPU, which involves copying a
100 // CPU tensor to GPU).
101 // Setting a larger thread pool does not help with the Swift caller, as we use
102 // a different TFE context for each thread of execution (for running graph
103 // functions, and their send/recvs corountines).
104 config.set_inter_op_parallelism_threads(1);
105
106 TF_Buffer* ret = TF_NewBuffer();
107 TF_CHECK_OK(MessageToBuffer(config, ret));
108 return ret;
109 }
110
TF_CreateRunOptions(unsigned char enable_full_trace)111 TF_Buffer* TF_CreateRunOptions(unsigned char enable_full_trace) {
112 tensorflow::RunOptions options;
113 if (enable_full_trace) {
114 options.set_trace_level(tensorflow::RunOptions::FULL_TRACE);
115 } else {
116 options.set_trace_level(tensorflow::RunOptions::NO_TRACE);
117 }
118 TF_Buffer* ret = TF_NewBuffer();
119 TF_CHECK_OK(MessageToBuffer(options, ret));
120 return ret;
121 }
122
TF_GraphDebugString(TF_Graph * graph,size_t * len)123 const char* TF_GraphDebugString(TF_Graph* graph, size_t* len) {
124 tensorflow::mutex_lock c(graph->mu);
125 const auto& debug_str = graph->graph.ToGraphDefDebug().DebugString();
126 *len = debug_str.size();
127 char* ret = static_cast<char*>(malloc(*len + 1));
128 memcpy(ret, debug_str.c_str(), *len + 1);
129 return ret;
130 }
131
TF_FunctionDebugString(TF_Function * func,size_t * len)132 char* TF_FunctionDebugString(TF_Function* func, size_t* len) {
133 const auto& debug_str = func->fdef.DebugString();
134 *len = debug_str.size();
135 char* ret = static_cast<char*>(malloc(*len + 1));
136 memcpy(ret, debug_str.c_str(), *len + 1);
137 return ret;
138 }
139
140 // On success, returns a set of TF_Function instances from `text_proto` of
141 // GraphDef type. These functions must be deleted by calling TF_DeleteFunction.
142 //
143 // If `mutate_proto_func` is non-NULL, run it over each FunctionDef proto,
144 // before creating a TF_Function out of the possibly mutated proto.
CreateFunctionsFromTextProto(const char * text_proto,std::function<void (FunctionDef *)> * mutate_proto_func,TF_Status * status)145 static std::vector<UniqueFuncPtr> CreateFunctionsFromTextProto(
146 const char* text_proto,
147 std::function<void(FunctionDef*)>* mutate_proto_func, TF_Status* status) {
148 tensorflow::GraphDef gdef;
149 if (!tensorflow::protobuf::TextFormat::ParseFromString(text_proto, &gdef)) {
150 status->status = tensorflow::errors::Internal(
151 "Invalid text proto for GraphDef: ", text_proto);
152 return {};
153 }
154 const auto& fdef_lib = gdef.library();
155 if (fdef_lib.gradient_size() > 0) {
156 status->status = tensorflow::errors::Internal(
157 "GradientDef is not supported in reading Dataset related functions: ",
158 text_proto);
159 return {};
160 }
161 std::vector<UniqueFuncPtr> ret;
162 for (const FunctionDef& fdef : fdef_lib.function()) {
163 // Make a copy so that we can mutate it.
164 FunctionDef fdef_to_load = fdef;
165 if (mutate_proto_func) {
166 (*mutate_proto_func)(&fdef_to_load);
167 }
168 VLOG(1) << "Adding func to graph: " << fdef_to_load.DebugString();
169 std::vector<char> binary_proto_buf(fdef_to_load.ByteSizeLong());
170 fdef_to_load.SerializeToArray(binary_proto_buf.data(),
171 binary_proto_buf.size());
172 TF_Function* func = TF_FunctionImportFunctionDef(
173 binary_proto_buf.data(), binary_proto_buf.size(), status);
174 if (!status->status.ok()) return {};
175 ret.push_back(UniqueFuncPtr(func, TF_DeleteFunction));
176 }
177 return ret;
178 }
179
180 // On success, returns a newly created TF_Function instance encoding a dataset
181 // node stack that returns a sequence of 3 floats, and sets `dataset_name` to
182 // the created dataset name. The returned function must be deleted by calling
183 // TF_DeleteFunction.
CreateFakeDatasetFunction(std::string * dataset_name,TF_Status * status)184 static UniqueFuncPtr CreateFakeDatasetFunction(std::string* dataset_name,
185 TF_Status* status) {
186 const char* func_def = R"PREFIX(
187 library {
188 function {
189 signature {
190 name: "_make_dataset_d8de2712"
191 output_arg {
192 name: "TensorSliceDataset"
193 type: DT_VARIANT
194 }
195 is_stateful: true
196 }
197 node_def {
198 name: "TensorSliceDataset/tensors/component_0"
199 op: "Const"
200 attr {
201 key: "dtype"
202 value {
203 type: DT_FLOAT
204 }
205 }
206 attr {
207 key: "value"
208 value {
209 tensor {
210 dtype: DT_FLOAT
211 tensor_shape {
212 dim {
213 size: 3
214 }
215 }
216 tensor_content: "\000\000(B\000\000,B\000\0000B"
217 }
218 }
219 }
220 }
221 node_def {
222 name: "TensorSliceDataset"
223 op: "TensorSliceDataset"
224 input: "TensorSliceDataset/tensors/component_0:output:0"
225 attr {
226 key: "Toutput_types"
227 value {
228 list {
229 type: DT_FLOAT
230 }
231 }
232 }
233 attr {
234 key: "output_shapes"
235 value {
236 list {
237 shape {
238 }
239 }
240 }
241 }
242 }
243 ret {
244 key: "TensorSliceDataset"
245 value: "TensorSliceDataset:handle:0"
246 }
247 }
248 }
249 )PREFIX";
250
251 *dataset_name = "_make_dataset_d8de2712";
252 auto functions = CreateFunctionsFromTextProto(
253 func_def, /*mutate_proto_func*/ nullptr, status);
254 DCHECK_EQ(functions.size(), 1);
255 return std::move(functions[0]);
256 }
257
258 #if not defined(PLATFORM_WINDOWS)
259 // On success, returns a set of TF_Function instances encoding a dataset
260 // node stack that reads a Imagenet TFRecordFile dataset from `file_path`, and
261 // sets `dataset_name` to the created dataset name. The returned functions must
262 // be deleted by calling TF_DeleteFunction.
CreateImagenetDatasetFunctions(const char * file_path,std::string * dataset_name,TF_Status * status)263 static std::vector<UniqueFuncPtr> CreateImagenetDatasetFunctions(
264 const char* file_path, std::string* dataset_name, TF_Status* status) {
265 #if defined(PLATFORM_WINDOWS)
266 status->status = tensorflow::errors::Unimplemented(
267 "TF_MakeFileBasedIteratorGetNextWithDatasets in the experimental C API "
268 "is not implemented for Windows");
269 return std::vector<UniqueFuncPtr>();
270 #else
271 const char* func_def = R"PREFIX(
272 library {
273 function {
274 signature {
275 name: "tf_map_func_91295dea"
276 input_arg {
277 name: "arg0"
278 type: DT_STRING
279 }
280 output_arg {
281 name: "FlatMapDataset"
282 type: DT_VARIANT
283 }
284 description: "A wrapper for Defun that facilitates shape inference."
285 is_stateful: true
286 }
287 node_def {
288 name: "flat_filenames/shape"
289 op: "Const"
290 attr {
291 key: "dtype"
292 value {
293 type: DT_INT32
294 }
295 }
296 attr {
297 key: "value"
298 value {
299 tensor {
300 dtype: DT_INT32
301 tensor_shape {
302 dim {
303 size: 1
304 }
305 }
306 int_val: -1
307 }
308 }
309 }
310 }
311 node_def {
312 name: "flat_filenames"
313 op: "Reshape"
314 input: "arg0"
315 input: "flat_filenames/shape:output:0"
316 attr {
317 key: "T"
318 value {
319 type: DT_STRING
320 }
321 }
322 attr {
323 key: "Tshape"
324 value {
325 type: DT_INT32
326 }
327 }
328 }
329 node_def {
330 name: "TensorSliceDataset"
331 op: "TensorSliceDataset"
332 input: "flat_filenames:output:0"
333 attr {
334 key: "Toutput_types"
335 value {
336 list {
337 type: DT_STRING
338 }
339 }
340 }
341 attr {
342 key: "output_shapes"
343 value {
344 list {
345 shape {
346 }
347 }
348 }
349 }
350 }
351 node_def {
352 name: "FlatMapDataset"
353 op: "FlatMapDataset"
354 input: "TensorSliceDataset:handle:0"
355 attr {
356 key: "Targuments"
357 value {
358 list {
359 }
360 }
361 }
362 attr {
363 key: "f"
364 value {
365 func {
366 name: "tf_map_func_0cc8c35b"
367 }
368 }
369 }
370 attr {
371 key: "output_shapes"
372 value {
373 list {
374 shape {
375 }
376 }
377 }
378 }
379 attr {
380 key: "output_types"
381 value {
382 list {
383 type: DT_STRING
384 }
385 }
386 }
387 }
388 ret {
389 key: "FlatMapDataset"
390 value: "FlatMapDataset:handle:0"
391 }
392 }
393 function {
394 signature {
395 name: "tf_map_func_0cc8c35b"
396 input_arg {
397 name: "arg0"
398 type: DT_STRING
399 }
400 output_arg {
401 name: "TFRecordDataset"
402 type: DT_VARIANT
403 }
404 description: "A wrapper for Defun that facilitates shape inference."
405 is_stateful: true
406 }
407 node_def {
408 name: "compression_type"
409 op: "Const"
410 attr {
411 key: "dtype"
412 value {
413 type: DT_STRING
414 }
415 }
416 attr {
417 key: "value"
418 value {
419 tensor {
420 dtype: DT_STRING
421 tensor_shape {
422 }
423 string_val: ""
424 }
425 }
426 }
427 }
428 node_def {
429 name: "buffer_size"
430 op: "Const"
431 attr {
432 key: "dtype"
433 value {
434 type: DT_INT64
435 }
436 }
437 attr {
438 key: "value"
439 value {
440 tensor {
441 dtype: DT_INT64
442 tensor_shape {
443 }
444 int64_val: 8388608
445 }
446 }
447 }
448 }
449 node_def {
450 name: "TFRecordDataset"
451 op: "TFRecordDataset"
452 input: "arg0"
453 input: "compression_type:output:0"
454 input: "buffer_size:output:0"
455 }
456 ret {
457 key: "TFRecordDataset"
458 value: "TFRecordDataset:handle:0"
459 }
460 }
461 function {
462 signature {
463 name: "tf_map_func_74b6b15c"
464 input_arg {
465 name: "arg0"
466 type: DT_STRING
467 }
468 output_arg {
469 name: "Reshape_1"
470 type: DT_FLOAT
471 }
472 output_arg {
473 name: "sub_1"
474 type: DT_INT32
475 }
476 description: "A wrapper for Defun that facilitates shape inference."
477 is_stateful: true
478 }
479 node_def {
480 name: "ParseSingleExample/key_image/class/label"
481 op: "Const"
482 attr {
483 key: "dtype"
484 value {
485 type: DT_INT64
486 }
487 }
488 attr {
489 key: "value"
490 value {
491 tensor {
492 dtype: DT_INT64
493 tensor_shape {
494 }
495 int64_val: -1
496 }
497 }
498 }
499 }
500 node_def {
501 name: "ParseSingleExample/Reshape/shape"
502 op: "Const"
503 attr {
504 key: "dtype"
505 value {
506 type: DT_INT32
507 }
508 }
509 attr {
510 key: "value"
511 value {
512 tensor {
513 dtype: DT_INT32
514 tensor_shape {
515 dim {
516 }
517 }
518 }
519 }
520 }
521 }
522 node_def {
523 name: "ParseSingleExample/Reshape"
524 op: "Reshape"
525 input: "ParseSingleExample/key_image/class/label:output:0"
526 input: "ParseSingleExample/Reshape/shape:output:0"
527 attr {
528 key: "T"
529 value {
530 type: DT_INT64
531 }
532 }
533 attr {
534 key: "Tshape"
535 value {
536 type: DT_INT32
537 }
538 }
539 }
540 node_def {
541 name: "ParseSingleExample/key_image/class/text"
542 op: "Const"
543 attr {
544 key: "dtype"
545 value {
546 type: DT_STRING
547 }
548 }
549 attr {
550 key: "value"
551 value {
552 tensor {
553 dtype: DT_STRING
554 tensor_shape {
555 }
556 string_val: ""
557 }
558 }
559 }
560 }
561 node_def {
562 name: "ParseSingleExample/Reshape_1/shape"
563 op: "Const"
564 attr {
565 key: "dtype"
566 value {
567 type: DT_INT32
568 }
569 }
570 attr {
571 key: "value"
572 value {
573 tensor {
574 dtype: DT_INT32
575 tensor_shape {
576 dim {
577 }
578 }
579 }
580 }
581 }
582 }
583 node_def {
584 name: "ParseSingleExample/Reshape_1"
585 op: "Reshape"
586 input: "ParseSingleExample/key_image/class/text:output:0"
587 input: "ParseSingleExample/Reshape_1/shape:output:0"
588 attr {
589 key: "T"
590 value {
591 type: DT_STRING
592 }
593 }
594 attr {
595 key: "Tshape"
596 value {
597 type: DT_INT32
598 }
599 }
600 }
601 node_def {
602 name: "ParseSingleExample/key_image/encoded"
603 op: "Const"
604 attr {
605 key: "dtype"
606 value {
607 type: DT_STRING
608 }
609 }
610 attr {
611 key: "value"
612 value {
613 tensor {
614 dtype: DT_STRING
615 tensor_shape {
616 }
617 string_val: ""
618 }
619 }
620 }
621 }
622 node_def {
623 name: "ParseSingleExample/Reshape_2/shape"
624 op: "Const"
625 attr {
626 key: "dtype"
627 value {
628 type: DT_INT32
629 }
630 }
631 attr {
632 key: "value"
633 value {
634 tensor {
635 dtype: DT_INT32
636 tensor_shape {
637 dim {
638 }
639 }
640 }
641 }
642 }
643 }
644 node_def {
645 name: "ParseSingleExample/Reshape_2"
646 op: "Reshape"
647 input: "ParseSingleExample/key_image/encoded:output:0"
648 input: "ParseSingleExample/Reshape_2/shape:output:0"
649 attr {
650 key: "T"
651 value {
652 type: DT_STRING
653 }
654 }
655 attr {
656 key: "Tshape"
657 value {
658 type: DT_INT32
659 }
660 }
661 }
662 node_def {
663 name: "ParseSingleExample/key_image/format"
664 op: "Const"
665 attr {
666 key: "dtype"
667 value {
668 type: DT_STRING
669 }
670 }
671 attr {
672 key: "value"
673 value {
674 tensor {
675 dtype: DT_STRING
676 tensor_shape {
677 }
678 string_val: "jpeg"
679 }
680 }
681 }
682 }
683 node_def {
684 name: "ParseSingleExample/Reshape_3/shape"
685 op: "Const"
686 attr {
687 key: "dtype"
688 value {
689 type: DT_INT32
690 }
691 }
692 attr {
693 key: "value"
694 value {
695 tensor {
696 dtype: DT_INT32
697 tensor_shape {
698 dim {
699 }
700 }
701 }
702 }
703 }
704 }
705 node_def {
706 name: "ParseSingleExample/Reshape_3"
707 op: "Reshape"
708 input: "ParseSingleExample/key_image/format:output:0"
709 input: "ParseSingleExample/Reshape_3/shape:output:0"
710 attr {
711 key: "T"
712 value {
713 type: DT_STRING
714 }
715 }
716 attr {
717 key: "Tshape"
718 value {
719 type: DT_INT32
720 }
721 }
722 }
723 node_def {
724 name: "ParseSingleExample/ParseSingleExample"
725 op: "ParseSingleExample"
726 input: "arg0"
727 input: "ParseSingleExample/Reshape:output:0"
728 input: "ParseSingleExample/Reshape_1:output:0"
729 input: "ParseSingleExample/Reshape_2:output:0"
730 input: "ParseSingleExample/Reshape_3:output:0"
731 attr {
732 key: "Tdense"
733 value {
734 list {
735 type: DT_INT64
736 type: DT_STRING
737 type: DT_STRING
738 type: DT_STRING
739 }
740 }
741 }
742 attr {
743 key: "dense_keys"
744 value {
745 list {
746 s: "image/class/label"
747 s: "image/class/text"
748 s: "image/encoded"
749 s: "image/format"
750 }
751 }
752 }
753 attr {
754 key: "dense_shapes"
755 value {
756 list {
757 shape {
758 }
759 shape {
760 }
761 shape {
762 }
763 shape {
764 }
765 }
766 }
767 }
768 attr {
769 key: "num_sparse"
770 value {
771 i: 5
772 }
773 }
774 attr {
775 key: "sparse_keys"
776 value {
777 list {
778 s: "image/object/bbox/xmax"
779 s: "image/object/bbox/xmin"
780 s: "image/object/bbox/ymax"
781 s: "image/object/bbox/ymin"
782 s: "image/object/class/label"
783 }
784 }
785 }
786 attr {
787 key: "sparse_types"
788 value {
789 list {
790 type: DT_FLOAT
791 type: DT_FLOAT
792 type: DT_FLOAT
793 type: DT_FLOAT
794 type: DT_INT64
795 }
796 }
797 }
798 }
799 node_def {
800 name: "Reshape/shape"
801 op: "Const"
802 attr {
803 key: "dtype"
804 value {
805 type: DT_INT32
806 }
807 }
808 attr {
809 key: "value"
810 value {
811 tensor {
812 dtype: DT_INT32
813 tensor_shape {
814 dim {
815 }
816 }
817 }
818 }
819 }
820 }
821 node_def {
822 name: "Reshape"
823 op: "Reshape"
824 input: "ParseSingleExample/ParseSingleExample:dense_values:2"
825 input: "Reshape/shape:output:0"
826 attr {
827 key: "T"
828 value {
829 type: DT_STRING
830 }
831 }
832 attr {
833 key: "Tshape"
834 value {
835 type: DT_INT32
836 }
837 }
838 }
839 node_def {
840 name: "decode_image/Substr/pos"
841 op: "Const"
842 attr {
843 key: "dtype"
844 value {
845 type: DT_INT32
846 }
847 }
848 attr {
849 key: "value"
850 value {
851 tensor {
852 dtype: DT_INT32
853 tensor_shape {
854 }
855 int_val: 0
856 }
857 }
858 }
859 }
860 node_def {
861 name: "decode_image/Substr/len"
862 op: "Const"
863 attr {
864 key: "dtype"
865 value {
866 type: DT_INT32
867 }
868 }
869 attr {
870 key: "value"
871 value {
872 tensor {
873 dtype: DT_INT32
874 tensor_shape {
875 }
876 int_val: 3
877 }
878 }
879 }
880 }
881 node_def {
882 name: "decode_image/Substr"
883 op: "Substr"
884 input: "Reshape:output:0"
885 input: "decode_image/Substr/pos:output:0"
886 input: "decode_image/Substr/len:output:0"
887 attr {
888 key: "T"
889 value {
890 type: DT_INT32
891 }
892 }
893 }
894 node_def {
895 name: "decode_image/is_jpeg/Substr/pos"
896 op: "Const"
897 attr {
898 key: "dtype"
899 value {
900 type: DT_INT32
901 }
902 }
903 attr {
904 key: "value"
905 value {
906 tensor {
907 dtype: DT_INT32
908 tensor_shape {
909 }
910 int_val: 0
911 }
912 }
913 }
914 }
915 node_def {
916 name: "decode_image/is_jpeg/Substr/len"
917 op: "Const"
918 attr {
919 key: "dtype"
920 value {
921 type: DT_INT32
922 }
923 }
924 attr {
925 key: "value"
926 value {
927 tensor {
928 dtype: DT_INT32
929 tensor_shape {
930 }
931 int_val: 3
932 }
933 }
934 }
935 }
936 node_def {
937 name: "decode_image/is_jpeg/Substr"
938 op: "Substr"
939 input: "Reshape:output:0"
940 input: "decode_image/is_jpeg/Substr/pos:output:0"
941 input: "decode_image/is_jpeg/Substr/len:output:0"
942 attr {
943 key: "T"
944 value {
945 type: DT_INT32
946 }
947 }
948 }
949 node_def {
950 name: "decode_image/is_jpeg/Equal/y"
951 op: "Const"
952 attr {
953 key: "dtype"
954 value {
955 type: DT_STRING
956 }
957 }
958 attr {
959 key: "value"
960 value {
961 tensor {
962 dtype: DT_STRING
963 tensor_shape {
964 }
965 string_val: "\377\330\377"
966 }
967 }
968 }
969 }
970 node_def {
971 name: "decode_image/is_jpeg/Equal"
972 op: "Equal"
973 input: "decode_image/is_jpeg/Substr:output:0"
974 input: "decode_image/is_jpeg/Equal/y:output:0"
975 attr {
976 key: "T"
977 value {
978 type: DT_STRING
979 }
980 }
981 }
982 node_def {
983 name: "decode_image/cond_jpeg/Switch"
984 op: "Switch"
985 input: "decode_image/is_jpeg/Equal:z:0"
986 input: "decode_image/is_jpeg/Equal:z:0"
987 attr {
988 key: "T"
989 value {
990 type: DT_BOOL
991 }
992 }
993 }
994 node_def {
995 name: "decode_image/cond_jpeg/switch_t"
996 op: "Identity"
997 input: "decode_image/cond_jpeg/Switch:output_true:0"
998 attr {
999 key: "T"
1000 value {
1001 type: DT_BOOL
1002 }
1003 }
1004 }
1005 node_def {
1006 name: "decode_image/cond_jpeg/switch_f"
1007 op: "Identity"
1008 input: "decode_image/cond_jpeg/Switch:output_false:0"
1009 attr {
1010 key: "T"
1011 value {
1012 type: DT_BOOL
1013 }
1014 }
1015 }
1016 node_def {
1017 name: "decode_image/cond_jpeg/pred_id"
1018 op: "Identity"
1019 input: "decode_image/is_jpeg/Equal:z:0"
1020 attr {
1021 key: "T"
1022 value {
1023 type: DT_BOOL
1024 }
1025 }
1026 }
1027 node_def {
1028 name: "decode_image/cond_jpeg/check_jpeg_channels/x"
1029 op: "Const"
1030 input: "^decode_image/cond_jpeg/switch_t"
1031 attr {
1032 key: "dtype"
1033 value {
1034 type: DT_INT32
1035 }
1036 }
1037 attr {
1038 key: "value"
1039 value {
1040 tensor {
1041 dtype: DT_INT32
1042 tensor_shape {
1043 }
1044 int_val: 3
1045 }
1046 }
1047 }
1048 }
1049 node_def {
1050 name: "decode_image/cond_jpeg/check_jpeg_channels/y"
1051 op: "Const"
1052 input: "^decode_image/cond_jpeg/switch_t"
1053 attr {
1054 key: "dtype"
1055 value {
1056 type: DT_INT32
1057 }
1058 }
1059 attr {
1060 key: "value"
1061 value {
1062 tensor {
1063 dtype: DT_INT32
1064 tensor_shape {
1065 }
1066 int_val: 4
1067 }
1068 }
1069 }
1070 }
1071 node_def {
1072 name: "decode_image/cond_jpeg/check_jpeg_channels"
1073 op: "NotEqual"
1074 input: "decode_image/cond_jpeg/check_jpeg_channels/x:output:0"
1075 input: "decode_image/cond_jpeg/check_jpeg_channels/y:output:0"
1076 attr {
1077 key: "T"
1078 value {
1079 type: DT_INT32
1080 }
1081 }
1082 }
1083 node_def {
1084 name: "decode_image/cond_jpeg/Assert/Const"
1085 op: "Const"
1086 input: "^decode_image/cond_jpeg/switch_t"
1087 attr {
1088 key: "dtype"
1089 value {
1090 type: DT_STRING
1091 }
1092 }
1093 attr {
1094 key: "value"
1095 value {
1096 tensor {
1097 dtype: DT_STRING
1098 tensor_shape {
1099 }
1100 string_val: "Channels must be in (None, 0, 1, 3) when decoding JPEG images"
1101 }
1102 }
1103 }
1104 }
1105 node_def {
1106 name: "decode_image/cond_jpeg/Assert/Assert/data_0"
1107 op: "Const"
1108 input: "^decode_image/cond_jpeg/switch_t"
1109 attr {
1110 key: "dtype"
1111 value {
1112 type: DT_STRING
1113 }
1114 }
1115 attr {
1116 key: "value"
1117 value {
1118 tensor {
1119 dtype: DT_STRING
1120 tensor_shape {
1121 }
1122 string_val: "Channels must be in (None, 0, 1, 3) when decoding JPEG images"
1123 }
1124 }
1125 }
1126 }
1127 node_def {
1128 name: "decode_image/cond_jpeg/Assert/Assert"
1129 op: "Assert"
1130 input: "decode_image/cond_jpeg/check_jpeg_channels:z:0"
1131 input: "decode_image/cond_jpeg/Assert/Assert/data_0:output:0"
1132 attr {
1133 key: "T"
1134 value {
1135 list {
1136 type: DT_STRING
1137 }
1138 }
1139 }
1140 attr {
1141 key: "summarize"
1142 value {
1143 i: 3
1144 }
1145 }
1146 }
1147 node_def {
1148 name: "decode_image/cond_jpeg/DecodeJpeg"
1149 op: "DecodeJpeg"
1150 input: "decode_image/cond_jpeg/DecodeJpeg/Switch:output_true:0"
1151 input: "^decode_image/cond_jpeg/Assert/Assert"
1152 attr {
1153 key: "acceptable_fraction"
1154 value {
1155 f: 1.0
1156 }
1157 }
1158 attr {
1159 key: "channels"
1160 value {
1161 i: 3
1162 }
1163 }
1164 attr {
1165 key: "dct_method"
1166 value {
1167 s: ""
1168 }
1169 }
1170 attr {
1171 key: "fancy_upscaling"
1172 value {
1173 b: true
1174 }
1175 }
1176 attr {
1177 key: "ratio"
1178 value {
1179 i: 1
1180 }
1181 }
1182 attr {
1183 key: "try_recover_truncated"
1184 value {
1185 b: false
1186 }
1187 }
1188 }
1189 node_def {
1190 name: "decode_image/cond_jpeg/DecodeJpeg/Switch"
1191 op: "Switch"
1192 input: "Reshape:output:0"
1193 input: "decode_image/cond_jpeg/pred_id:output:0"
1194 attr {
1195 key: "T"
1196 value {
1197 type: DT_STRING
1198 }
1199 }
1200 attr {
1201 key: "_class"
1202 value {
1203 list {
1204 s: "loc:@Reshape"
1205 }
1206 }
1207 }
1208 }
1209 node_def {
1210 name: "decode_image/cond_jpeg/is_png/y"
1211 op: "Const"
1212 input: "^decode_image/cond_jpeg/switch_f"
1213 attr {
1214 key: "dtype"
1215 value {
1216 type: DT_STRING
1217 }
1218 }
1219 attr {
1220 key: "value"
1221 value {
1222 tensor {
1223 dtype: DT_STRING
1224 tensor_shape {
1225 }
1226 string_val: "\211PN"
1227 }
1228 }
1229 }
1230 }
1231 node_def {
1232 name: "decode_image/cond_jpeg/is_png"
1233 op: "Equal"
1234 input: "decode_image/cond_jpeg/is_png/Switch:output_false:0"
1235 input: "decode_image/cond_jpeg/is_png/y:output:0"
1236 attr {
1237 key: "T"
1238 value {
1239 type: DT_STRING
1240 }
1241 }
1242 }
1243 node_def {
1244 name: "decode_image/cond_jpeg/is_png/Switch"
1245 op: "Switch"
1246 input: "decode_image/Substr:output:0"
1247 input: "decode_image/cond_jpeg/pred_id:output:0"
1248 attr {
1249 key: "T"
1250 value {
1251 type: DT_STRING
1252 }
1253 }
1254 attr {
1255 key: "_class"
1256 value {
1257 list {
1258 s: "loc:@decode_image/Substr"
1259 }
1260 }
1261 }
1262 }
1263 node_def {
1264 name: "decode_image/cond_jpeg/cond_png/Switch"
1265 op: "Switch"
1266 input: "decode_image/cond_jpeg/is_png:z:0"
1267 input: "decode_image/cond_jpeg/is_png:z:0"
1268 attr {
1269 key: "T"
1270 value {
1271 type: DT_BOOL
1272 }
1273 }
1274 }
1275 node_def {
1276 name: "decode_image/cond_jpeg/cond_png/switch_t"
1277 op: "Identity"
1278 input: "decode_image/cond_jpeg/cond_png/Switch:output_true:0"
1279 attr {
1280 key: "T"
1281 value {
1282 type: DT_BOOL
1283 }
1284 }
1285 }
1286 node_def {
1287 name: "decode_image/cond_jpeg/cond_png/switch_f"
1288 op: "Identity"
1289 input: "decode_image/cond_jpeg/cond_png/Switch:output_false:0"
1290 attr {
1291 key: "T"
1292 value {
1293 type: DT_BOOL
1294 }
1295 }
1296 }
1297 node_def {
1298 name: "decode_image/cond_jpeg/cond_png/pred_id"
1299 op: "Identity"
1300 input: "decode_image/cond_jpeg/is_png:z:0"
1301 attr {
1302 key: "T"
1303 value {
1304 type: DT_BOOL
1305 }
1306 }
1307 }
1308 node_def {
1309 name: "decode_image/cond_jpeg/cond_png/DecodePng"
1310 op: "DecodePng"
1311 input: "decode_image/cond_jpeg/cond_png/DecodePng/Switch_1:output_true:0"
1312 attr {
1313 key: "channels"
1314 value {
1315 i: 3
1316 }
1317 }
1318 attr {
1319 key: "dtype"
1320 value {
1321 type: DT_UINT8
1322 }
1323 }
1324 }
1325 node_def {
1326 name: "decode_image/cond_jpeg/cond_png/DecodePng/Switch"
1327 op: "Switch"
1328 input: "Reshape:output:0"
1329 input: "decode_image/cond_jpeg/pred_id:output:0"
1330 attr {
1331 key: "T"
1332 value {
1333 type: DT_STRING
1334 }
1335 }
1336 attr {
1337 key: "_class"
1338 value {
1339 list {
1340 s: "loc:@Reshape"
1341 }
1342 }
1343 }
1344 }
1345 node_def {
1346 name: "decode_image/cond_jpeg/cond_png/DecodePng/Switch_1"
1347 op: "Switch"
1348 input: "decode_image/cond_jpeg/cond_png/DecodePng/Switch:output_false:0"
1349 input: "decode_image/cond_jpeg/cond_png/pred_id:output:0"
1350 attr {
1351 key: "T"
1352 value {
1353 type: DT_STRING
1354 }
1355 }
1356 attr {
1357 key: "_class"
1358 value {
1359 list {
1360 s: "loc:@Reshape"
1361 }
1362 }
1363 }
1364 }
1365 node_def {
1366 name: "decode_image/cond_jpeg/cond_png/is_gif/y"
1367 op: "Const"
1368 input: "^decode_image/cond_jpeg/cond_png/switch_f"
1369 attr {
1370 key: "dtype"
1371 value {
1372 type: DT_STRING
1373 }
1374 }
1375 attr {
1376 key: "value"
1377 value {
1378 tensor {
1379 dtype: DT_STRING
1380 tensor_shape {
1381 }
1382 string_val: "GIF"
1383 }
1384 }
1385 }
1386 }
1387 node_def {
1388 name: "decode_image/cond_jpeg/cond_png/is_gif"
1389 op: "Equal"
1390 input: "decode_image/cond_jpeg/cond_png/is_gif/Switch:output_false:0"
1391 input: "decode_image/cond_jpeg/cond_png/is_gif/y:output:0"
1392 attr {
1393 key: "T"
1394 value {
1395 type: DT_STRING
1396 }
1397 }
1398 }
1399 node_def {
1400 name: "decode_image/cond_jpeg/cond_png/is_gif/Switch"
1401 op: "Switch"
1402 input: "decode_image/cond_jpeg/is_png/Switch:output_false:0"
1403 input: "decode_image/cond_jpeg/cond_png/pred_id:output:0"
1404 attr {
1405 key: "T"
1406 value {
1407 type: DT_STRING
1408 }
1409 }
1410 attr {
1411 key: "_class"
1412 value {
1413 list {
1414 s: "loc:@decode_image/Substr"
1415 }
1416 }
1417 }
1418 }
1419 node_def {
1420 name: "decode_image/cond_jpeg/cond_png/cond_gif/Switch"
1421 op: "Switch"
1422 input: "decode_image/cond_jpeg/cond_png/is_gif:z:0"
1423 input: "decode_image/cond_jpeg/cond_png/is_gif:z:0"
1424 attr {
1425 key: "T"
1426 value {
1427 type: DT_BOOL
1428 }
1429 }
1430 }
1431 node_def {
1432 name: "decode_image/cond_jpeg/cond_png/cond_gif/switch_t"
1433 op: "Identity"
1434 input: "decode_image/cond_jpeg/cond_png/cond_gif/Switch:output_true:0"
1435 attr {
1436 key: "T"
1437 value {
1438 type: DT_BOOL
1439 }
1440 }
1441 }
1442 node_def {
1443 name: "decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1444 op: "Identity"
1445 input: "decode_image/cond_jpeg/cond_png/cond_gif/Switch:output_false:0"
1446 attr {
1447 key: "T"
1448 value {
1449 type: DT_BOOL
1450 }
1451 }
1452 }
1453 node_def {
1454 name: "decode_image/cond_jpeg/cond_png/cond_gif/pred_id"
1455 op: "Identity"
1456 input: "decode_image/cond_jpeg/cond_png/is_gif:z:0"
1457 attr {
1458 key: "T"
1459 value {
1460 type: DT_BOOL
1461 }
1462 }
1463 }
1464 node_def {
1465 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels/x"
1466 op: "Const"
1467 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_t"
1468 attr {
1469 key: "dtype"
1470 value {
1471 type: DT_INT32
1472 }
1473 }
1474 attr {
1475 key: "value"
1476 value {
1477 tensor {
1478 dtype: DT_INT32
1479 tensor_shape {
1480 }
1481 int_val: 3
1482 }
1483 }
1484 }
1485 }
1486 node_def {
1487 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels/y"
1488 op: "Const"
1489 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_t"
1490 attr {
1491 key: "dtype"
1492 value {
1493 type: DT_INT32
1494 }
1495 }
1496 attr {
1497 key: "value"
1498 value {
1499 tensor {
1500 dtype: DT_INT32
1501 tensor_shape {
1502 }
1503 int_val: 1
1504 }
1505 }
1506 }
1507 }
1508 node_def {
1509 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels"
1510 op: "NotEqual"
1511 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels/x:output:0"
1512 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels/y:output:0"
1513 attr {
1514 key: "T"
1515 value {
1516 type: DT_INT32
1517 }
1518 }
1519 }
1520 node_def {
1521 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels_1/x"
1522 op: "Const"
1523 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_t"
1524 attr {
1525 key: "dtype"
1526 value {
1527 type: DT_INT32
1528 }
1529 }
1530 attr {
1531 key: "value"
1532 value {
1533 tensor {
1534 dtype: DT_INT32
1535 tensor_shape {
1536 }
1537 int_val: 3
1538 }
1539 }
1540 }
1541 }
1542 node_def {
1543 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels_1/y"
1544 op: "Const"
1545 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_t"
1546 attr {
1547 key: "dtype"
1548 value {
1549 type: DT_INT32
1550 }
1551 }
1552 attr {
1553 key: "value"
1554 value {
1555 tensor {
1556 dtype: DT_INT32
1557 tensor_shape {
1558 }
1559 int_val: 4
1560 }
1561 }
1562 }
1563 }
1564 node_def {
1565 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels_1"
1566 op: "NotEqual"
1567 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels_1/x:output:0"
1568 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels_1/y:output:0"
1569 attr {
1570 key: "T"
1571 value {
1572 type: DT_INT32
1573 }
1574 }
1575 }
1576 node_def {
1577 name: "decode_image/cond_jpeg/cond_png/cond_gif/LogicalAnd"
1578 op: "LogicalAnd"
1579 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels:z:0"
1580 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_gif_channels_1:z:0"
1581 }
1582 node_def {
1583 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert/Const"
1584 op: "Const"
1585 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_t"
1586 attr {
1587 key: "dtype"
1588 value {
1589 type: DT_STRING
1590 }
1591 }
1592 attr {
1593 key: "value"
1594 value {
1595 tensor {
1596 dtype: DT_STRING
1597 tensor_shape {
1598 }
1599 string_val: "Channels must be in (None, 0, 3) when decoding GIF images"
1600 }
1601 }
1602 }
1603 }
1604 node_def {
1605 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert/Assert/data_0"
1606 op: "Const"
1607 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_t"
1608 attr {
1609 key: "dtype"
1610 value {
1611 type: DT_STRING
1612 }
1613 }
1614 attr {
1615 key: "value"
1616 value {
1617 tensor {
1618 dtype: DT_STRING
1619 tensor_shape {
1620 }
1621 string_val: "Channels must be in (None, 0, 3) when decoding GIF images"
1622 }
1623 }
1624 }
1625 }
1626 node_def {
1627 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert/Assert"
1628 op: "Assert"
1629 input: "decode_image/cond_jpeg/cond_png/cond_gif/LogicalAnd:z:0"
1630 input: "decode_image/cond_jpeg/cond_png/cond_gif/Assert/Assert/data_0:output:0"
1631 attr {
1632 key: "T"
1633 value {
1634 list {
1635 type: DT_STRING
1636 }
1637 }
1638 }
1639 attr {
1640 key: "summarize"
1641 value {
1642 i: 3
1643 }
1644 }
1645 }
1646 node_def {
1647 name: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif"
1648 op: "DecodeGif"
1649 input: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif/Switch_1:output_true:0"
1650 input: "^decode_image/cond_jpeg/cond_png/cond_gif/Assert/Assert"
1651 }
1652 node_def {
1653 name: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif/Switch"
1654 op: "Switch"
1655 input: "decode_image/cond_jpeg/cond_png/DecodePng/Switch:output_false:0"
1656 input: "decode_image/cond_jpeg/cond_png/pred_id:output:0"
1657 attr {
1658 key: "T"
1659 value {
1660 type: DT_STRING
1661 }
1662 }
1663 attr {
1664 key: "_class"
1665 value {
1666 list {
1667 s: "loc:@Reshape"
1668 }
1669 }
1670 }
1671 }
1672 node_def {
1673 name: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif/Switch_1"
1674 op: "Switch"
1675 input: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif/Switch:output_false:0"
1676 input: "decode_image/cond_jpeg/cond_png/cond_gif/pred_id:output:0"
1677 attr {
1678 key: "T"
1679 value {
1680 type: DT_STRING
1681 }
1682 }
1683 attr {
1684 key: "_class"
1685 value {
1686 list {
1687 s: "loc:@Reshape"
1688 }
1689 }
1690 }
1691 }
1692 node_def {
1693 name: "decode_image/cond_jpeg/cond_png/cond_gif/Substr/pos"
1694 op: "Const"
1695 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1696 attr {
1697 key: "dtype"
1698 value {
1699 type: DT_INT32
1700 }
1701 }
1702 attr {
1703 key: "value"
1704 value {
1705 tensor {
1706 dtype: DT_INT32
1707 tensor_shape {
1708 }
1709 int_val: 0
1710 }
1711 }
1712 }
1713 }
1714 node_def {
1715 name: "decode_image/cond_jpeg/cond_png/cond_gif/Substr/len"
1716 op: "Const"
1717 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1718 attr {
1719 key: "dtype"
1720 value {
1721 type: DT_INT32
1722 }
1723 }
1724 attr {
1725 key: "value"
1726 value {
1727 tensor {
1728 dtype: DT_INT32
1729 tensor_shape {
1730 }
1731 int_val: 2
1732 }
1733 }
1734 }
1735 }
1736 node_def {
1737 name: "decode_image/cond_jpeg/cond_png/cond_gif/Substr"
1738 op: "Substr"
1739 input: "decode_image/cond_jpeg/cond_png/cond_gif/Substr/Switch:output_false:0"
1740 input: "decode_image/cond_jpeg/cond_png/cond_gif/Substr/pos:output:0"
1741 input: "decode_image/cond_jpeg/cond_png/cond_gif/Substr/len:output:0"
1742 attr {
1743 key: "T"
1744 value {
1745 type: DT_INT32
1746 }
1747 }
1748 }
1749 node_def {
1750 name: "decode_image/cond_jpeg/cond_png/cond_gif/Substr/Switch"
1751 op: "Switch"
1752 input: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif/Switch:output_false:0"
1753 input: "decode_image/cond_jpeg/cond_png/cond_gif/pred_id:output:0"
1754 attr {
1755 key: "T"
1756 value {
1757 type: DT_STRING
1758 }
1759 }
1760 attr {
1761 key: "_class"
1762 value {
1763 list {
1764 s: "loc:@Reshape"
1765 }
1766 }
1767 }
1768 }
1769 node_def {
1770 name: "decode_image/cond_jpeg/cond_png/cond_gif/is_bmp/y"
1771 op: "Const"
1772 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1773 attr {
1774 key: "dtype"
1775 value {
1776 type: DT_STRING
1777 }
1778 }
1779 attr {
1780 key: "value"
1781 value {
1782 tensor {
1783 dtype: DT_STRING
1784 tensor_shape {
1785 }
1786 string_val: "BM"
1787 }
1788 }
1789 }
1790 }
1791 node_def {
1792 name: "decode_image/cond_jpeg/cond_png/cond_gif/is_bmp"
1793 op: "Equal"
1794 input: "decode_image/cond_jpeg/cond_png/cond_gif/Substr:output:0"
1795 input: "decode_image/cond_jpeg/cond_png/cond_gif/is_bmp/y:output:0"
1796 attr {
1797 key: "T"
1798 value {
1799 type: DT_STRING
1800 }
1801 }
1802 }
1803 node_def {
1804 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Const"
1805 op: "Const"
1806 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1807 attr {
1808 key: "dtype"
1809 value {
1810 type: DT_STRING
1811 }
1812 }
1813 attr {
1814 key: "value"
1815 value {
1816 tensor {
1817 dtype: DT_STRING
1818 tensor_shape {
1819 }
1820 string_val: "Unable to decode bytes as JPEG, PNG, GIF, or BMP"
1821 }
1822 }
1823 }
1824 }
1825 node_def {
1826 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert/data_0"
1827 op: "Const"
1828 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1829 attr {
1830 key: "dtype"
1831 value {
1832 type: DT_STRING
1833 }
1834 }
1835 attr {
1836 key: "value"
1837 value {
1838 tensor {
1839 dtype: DT_STRING
1840 tensor_shape {
1841 }
1842 string_val: "Unable to decode bytes as JPEG, PNG, GIF, or BMP"
1843 }
1844 }
1845 }
1846 }
1847 node_def {
1848 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert"
1849 op: "Assert"
1850 input: "decode_image/cond_jpeg/cond_png/cond_gif/is_bmp:z:0"
1851 input: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert/data_0:output:0"
1852 attr {
1853 key: "T"
1854 value {
1855 list {
1856 type: DT_STRING
1857 }
1858 }
1859 }
1860 attr {
1861 key: "summarize"
1862 value {
1863 i: 3
1864 }
1865 }
1866 }
1867 node_def {
1868 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_channels/x"
1869 op: "Const"
1870 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1871 attr {
1872 key: "dtype"
1873 value {
1874 type: DT_INT32
1875 }
1876 }
1877 attr {
1878 key: "value"
1879 value {
1880 tensor {
1881 dtype: DT_INT32
1882 tensor_shape {
1883 }
1884 int_val: 3
1885 }
1886 }
1887 }
1888 }
1889 node_def {
1890 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_channels/y"
1891 op: "Const"
1892 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1893 attr {
1894 key: "dtype"
1895 value {
1896 type: DT_INT32
1897 }
1898 }
1899 attr {
1900 key: "value"
1901 value {
1902 tensor {
1903 dtype: DT_INT32
1904 tensor_shape {
1905 }
1906 int_val: 1
1907 }
1908 }
1909 }
1910 }
1911 node_def {
1912 name: "decode_image/cond_jpeg/cond_png/cond_gif/check_channels"
1913 op: "NotEqual"
1914 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_channels/x:output:0"
1915 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_channels/y:output:0"
1916 attr {
1917 key: "T"
1918 value {
1919 type: DT_INT32
1920 }
1921 }
1922 }
1923 node_def {
1924 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_2/Const"
1925 op: "Const"
1926 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1927 attr {
1928 key: "dtype"
1929 value {
1930 type: DT_STRING
1931 }
1932 }
1933 attr {
1934 key: "value"
1935 value {
1936 tensor {
1937 dtype: DT_STRING
1938 tensor_shape {
1939 }
1940 string_val: "Channels must be in (None, 0, 3) when decoding BMP images"
1941 }
1942 }
1943 }
1944 }
1945 node_def {
1946 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_2/Assert/data_0"
1947 op: "Const"
1948 input: "^decode_image/cond_jpeg/cond_png/cond_gif/switch_f"
1949 attr {
1950 key: "dtype"
1951 value {
1952 type: DT_STRING
1953 }
1954 }
1955 attr {
1956 key: "value"
1957 value {
1958 tensor {
1959 dtype: DT_STRING
1960 tensor_shape {
1961 }
1962 string_val: "Channels must be in (None, 0, 3) when decoding BMP images"
1963 }
1964 }
1965 }
1966 }
1967 node_def {
1968 name: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_2/Assert"
1969 op: "Assert"
1970 input: "decode_image/cond_jpeg/cond_png/cond_gif/check_channels:z:0"
1971 input: "decode_image/cond_jpeg/cond_png/cond_gif/Assert_2/Assert/data_0:output:0"
1972 attr {
1973 key: "T"
1974 value {
1975 list {
1976 type: DT_STRING
1977 }
1978 }
1979 }
1980 attr {
1981 key: "summarize"
1982 value {
1983 i: 3
1984 }
1985 }
1986 }
1987 node_def {
1988 name: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeBmp"
1989 op: "DecodeBmp"
1990 input: "decode_image/cond_jpeg/cond_png/cond_gif/Substr/Switch:output_false:0"
1991 input: "^decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert"
1992 input: "^decode_image/cond_jpeg/cond_png/cond_gif/Assert_2/Assert"
1993 attr {
1994 key: "channels"
1995 value {
1996 i: 0
1997 }
1998 }
1999 }
2000 node_def {
2001 name: "decode_image/cond_jpeg/cond_png/cond_gif/Merge"
2002 op: "Merge"
2003 input: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeBmp:image:0"
2004 input: "decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif:image:0"
2005 attr {
2006 key: "N"
2007 value {
2008 i: 2
2009 }
2010 }
2011 attr {
2012 key: "T"
2013 value {
2014 type: DT_UINT8
2015 }
2016 }
2017 }
2018 node_def {
2019 name: "decode_image/cond_jpeg/cond_png/Merge"
2020 op: "Merge"
2021 input: "decode_image/cond_jpeg/cond_png/cond_gif/Merge:output:0"
2022 input: "decode_image/cond_jpeg/cond_png/DecodePng:image:0"
2023 attr {
2024 key: "N"
2025 value {
2026 i: 2
2027 }
2028 }
2029 attr {
2030 key: "T"
2031 value {
2032 type: DT_UINT8
2033 }
2034 }
2035 }
2036 node_def {
2037 name: "decode_image/cond_jpeg/Merge"
2038 op: "Merge"
2039 input: "decode_image/cond_jpeg/cond_png/Merge:output:0"
2040 input: "decode_image/cond_jpeg/DecodeJpeg:image:0"
2041 attr {
2042 key: "N"
2043 value {
2044 i: 2
2045 }
2046 }
2047 attr {
2048 key: "T"
2049 value {
2050 type: DT_UINT8
2051 }
2052 }
2053 }
2054 node_def {
2055 name: "convert_image/Cast"
2056 op: "Cast"
2057 input: "decode_image/cond_jpeg/Merge:output:0"
2058 attr {
2059 key: "DstT"
2060 value {
2061 type: DT_FLOAT
2062 }
2063 }
2064 attr {
2065 key: "SrcT"
2066 value {
2067 type: DT_UINT8
2068 }
2069 }
2070 }
2071 node_def {
2072 name: "convert_image/y"
2073 op: "Const"
2074 attr {
2075 key: "dtype"
2076 value {
2077 type: DT_FLOAT
2078 }
2079 }
2080 attr {
2081 key: "value"
2082 value {
2083 tensor {
2084 dtype: DT_FLOAT
2085 tensor_shape {
2086 }
2087 float_val: 0.00392156885937
2088 }
2089 }
2090 }
2091 }
2092 node_def {
2093 name: "convert_image"
2094 op: "Mul"
2095 input: "convert_image/Cast:y:0"
2096 input: "convert_image/y:output:0"
2097 attr {
2098 key: "T"
2099 value {
2100 type: DT_FLOAT
2101 }
2102 }
2103 }
2104 node_def {
2105 name: "Const"
2106 op: "Const"
2107 attr {
2108 key: "dtype"
2109 value {
2110 type: DT_FLOAT
2111 }
2112 }
2113 attr {
2114 key: "value"
2115 value {
2116 tensor {
2117 dtype: DT_FLOAT
2118 tensor_shape {
2119 dim {
2120 size: 1
2121 }
2122 dim {
2123 size: 1
2124 }
2125 dim {
2126 size: 4
2127 }
2128 }
2129 tensor_content: "\000\000\000\000\000\000\000\000\000\000\200?\000\000\200?"
2130 }
2131 }
2132 }
2133 }
2134 node_def {
2135 name: "distorted_bounding_box_crop/Shape"
2136 op: "Shape"
2137 input: "convert_image:z:0"
2138 attr {
2139 key: "T"
2140 value {
2141 type: DT_FLOAT
2142 }
2143 }
2144 attr {
2145 key: "out_type"
2146 value {
2147 type: DT_INT32
2148 }
2149 }
2150 }
2151 node_def {
2152 name: "distorted_bounding_box_crop/sample_distorted_bounding_box/SampleDistortedBoundingBoxV2/min_object_covered"
2153 op: "Const"
2154 attr {
2155 key: "dtype"
2156 value {
2157 type: DT_FLOAT
2158 }
2159 }
2160 attr {
2161 key: "value"
2162 value {
2163 tensor {
2164 dtype: DT_FLOAT
2165 tensor_shape {
2166 }
2167 float_val: 0.10000000149
2168 }
2169 }
2170 }
2171 }
2172 node_def {
2173 name: "distorted_bounding_box_crop/sample_distorted_bounding_box/SampleDistortedBoundingBoxV2"
2174 op: "SampleDistortedBoundingBoxV2"
2175 input: "distorted_bounding_box_crop/Shape:output:0"
2176 input: "Const:output:0"
2177 input: "distorted_bounding_box_crop/sample_distorted_bounding_box/SampleDistortedBoundingBoxV2/min_object_covered:output:0"
2178 attr {
2179 key: "T"
2180 value {
2181 type: DT_INT32
2182 }
2183 }
2184 attr {
2185 key: "area_range"
2186 value {
2187 list {
2188 f: 0.0799999982119
2189 f: 1.0
2190 }
2191 }
2192 }
2193 attr {
2194 key: "aspect_ratio_range"
2195 value {
2196 list {
2197 f: 0.75
2198 f: 1.33333337307
2199 }
2200 }
2201 }
2202 attr {
2203 key: "max_attempts"
2204 value {
2205 i: 1
2206 }
2207 }
2208 attr {
2209 key: "seed"
2210 value {
2211 i: 0
2212 }
2213 }
2214 attr {
2215 key: "seed2"
2216 value {
2217 i: 0
2218 }
2219 }
2220 attr {
2221 key: "use_image_if_no_bounding_boxes"
2222 value {
2223 b: true
2224 }
2225 }
2226 }
2227 node_def {
2228 name: "distorted_bounding_box_crop/Slice"
2229 op: "Slice"
2230 input: "convert_image:z:0"
2231 input: "distorted_bounding_box_crop/sample_distorted_bounding_box/SampleDistortedBoundingBoxV2:begin:0"
2232 input: "distorted_bounding_box_crop/sample_distorted_bounding_box/SampleDistortedBoundingBoxV2:size:0"
2233 attr {
2234 key: "Index"
2235 value {
2236 type: DT_INT32
2237 }
2238 }
2239 attr {
2240 key: "T"
2241 value {
2242 type: DT_FLOAT
2243 }
2244 }
2245 }
2246 node_def {
2247 name: "Shape"
2248 op: "Shape"
2249 input: "convert_image:z:0"
2250 attr {
2251 key: "T"
2252 value {
2253 type: DT_FLOAT
2254 }
2255 }
2256 attr {
2257 key: "out_type"
2258 value {
2259 type: DT_INT32
2260 }
2261 }
2262 }
2263 node_def {
2264 name: "Shape_1"
2265 op: "Shape"
2266 input: "distorted_bounding_box_crop/Slice:output:0"
2267 attr {
2268 key: "T"
2269 value {
2270 type: DT_FLOAT
2271 }
2272 }
2273 attr {
2274 key: "out_type"
2275 value {
2276 type: DT_INT32
2277 }
2278 }
2279 }
2280 node_def {
2281 name: "Equal"
2282 op: "Equal"
2283 input: "Shape:output:0"
2284 input: "Shape_1:output:0"
2285 attr {
2286 key: "T"
2287 value {
2288 type: DT_INT32
2289 }
2290 }
2291 }
2292 node_def {
2293 name: "Cast"
2294 op: "Cast"
2295 input: "Equal:z:0"
2296 attr {
2297 key: "DstT"
2298 value {
2299 type: DT_INT32
2300 }
2301 }
2302 attr {
2303 key: "SrcT"
2304 value {
2305 type: DT_BOOL
2306 }
2307 }
2308 }
2309 node_def {
2310 name: "Const_1"
2311 op: "Const"
2312 attr {
2313 key: "dtype"
2314 value {
2315 type: DT_INT32
2316 }
2317 }
2318 attr {
2319 key: "value"
2320 value {
2321 tensor {
2322 dtype: DT_INT32
2323 tensor_shape {
2324 dim {
2325 size: 1
2326 }
2327 }
2328 int_val: 0
2329 }
2330 }
2331 }
2332 }
2333 node_def {
2334 name: "Sum"
2335 op: "Sum"
2336 input: "Cast:y:0"
2337 input: "Const_1:output:0"
2338 attr {
2339 key: "T"
2340 value {
2341 type: DT_INT32
2342 }
2343 }
2344 attr {
2345 key: "Tidx"
2346 value {
2347 type: DT_INT32
2348 }
2349 }
2350 attr {
2351 key: "keep_dims"
2352 value {
2353 b: false
2354 }
2355 }
2356 }
2357 node_def {
2358 name: "GreaterEqual/y"
2359 op: "Const"
2360 attr {
2361 key: "dtype"
2362 value {
2363 type: DT_INT32
2364 }
2365 }
2366 attr {
2367 key: "value"
2368 value {
2369 tensor {
2370 dtype: DT_INT32
2371 tensor_shape {
2372 }
2373 int_val: 3
2374 }
2375 }
2376 }
2377 }
2378 node_def {
2379 name: "GreaterEqual"
2380 op: "GreaterEqual"
2381 input: "Sum:output:0"
2382 input: "GreaterEqual/y:output:0"
2383 attr {
2384 key: "T"
2385 value {
2386 type: DT_INT32
2387 }
2388 }
2389 }
2390 node_def {
2391 name: "cond/Switch"
2392 op: "Switch"
2393 input: "GreaterEqual:z:0"
2394 input: "GreaterEqual:z:0"
2395 attr {
2396 key: "T"
2397 value {
2398 type: DT_BOOL
2399 }
2400 }
2401 }
2402 node_def {
2403 name: "cond/switch_t"
2404 op: "Identity"
2405 input: "cond/Switch:output_true:0"
2406 attr {
2407 key: "T"
2408 value {
2409 type: DT_BOOL
2410 }
2411 }
2412 }
2413 node_def {
2414 name: "cond/switch_f"
2415 op: "Identity"
2416 input: "cond/Switch:output_false:0"
2417 attr {
2418 key: "T"
2419 value {
2420 type: DT_BOOL
2421 }
2422 }
2423 }
2424 node_def {
2425 name: "cond/pred_id"
2426 op: "Identity"
2427 input: "GreaterEqual:z:0"
2428 attr {
2429 key: "T"
2430 value {
2431 type: DT_BOOL
2432 }
2433 }
2434 }
2435 node_def {
2436 name: "cond/Shape"
2437 op: "Shape"
2438 input: "cond/Shape/Switch:output_true:0"
2439 attr {
2440 key: "T"
2441 value {
2442 type: DT_FLOAT
2443 }
2444 }
2445 attr {
2446 key: "out_type"
2447 value {
2448 type: DT_INT32
2449 }
2450 }
2451 }
2452 node_def {
2453 name: "cond/Shape/Switch"
2454 op: "Switch"
2455 input: "convert_image:z:0"
2456 input: "cond/pred_id:output:0"
2457 attr {
2458 key: "T"
2459 value {
2460 type: DT_FLOAT
2461 }
2462 }
2463 attr {
2464 key: "_class"
2465 value {
2466 list {
2467 s: "loc:@convert_image"
2468 }
2469 }
2470 }
2471 }
2472 node_def {
2473 name: "cond/Cast"
2474 op: "Cast"
2475 input: "cond/Shape:output:0"
2476 attr {
2477 key: "DstT"
2478 value {
2479 type: DT_FLOAT
2480 }
2481 }
2482 attr {
2483 key: "SrcT"
2484 value {
2485 type: DT_INT32
2486 }
2487 }
2488 }
2489 node_def {
2490 name: "cond/strided_slice/stack"
2491 op: "Const"
2492 input: "^cond/switch_t"
2493 attr {
2494 key: "dtype"
2495 value {
2496 type: DT_INT32
2497 }
2498 }
2499 attr {
2500 key: "value"
2501 value {
2502 tensor {
2503 dtype: DT_INT32
2504 tensor_shape {
2505 dim {
2506 size: 1
2507 }
2508 }
2509 int_val: 0
2510 }
2511 }
2512 }
2513 }
2514 node_def {
2515 name: "cond/strided_slice/stack_1"
2516 op: "Const"
2517 input: "^cond/switch_t"
2518 attr {
2519 key: "dtype"
2520 value {
2521 type: DT_INT32
2522 }
2523 }
2524 attr {
2525 key: "value"
2526 value {
2527 tensor {
2528 dtype: DT_INT32
2529 tensor_shape {
2530 dim {
2531 size: 1
2532 }
2533 }
2534 int_val: 1
2535 }
2536 }
2537 }
2538 }
2539 node_def {
2540 name: "cond/strided_slice/stack_2"
2541 op: "Const"
2542 input: "^cond/switch_t"
2543 attr {
2544 key: "dtype"
2545 value {
2546 type: DT_INT32
2547 }
2548 }
2549 attr {
2550 key: "value"
2551 value {
2552 tensor {
2553 dtype: DT_INT32
2554 tensor_shape {
2555 dim {
2556 size: 1
2557 }
2558 }
2559 int_val: 1
2560 }
2561 }
2562 }
2563 }
2564 node_def {
2565 name: "cond/strided_slice"
2566 op: "StridedSlice"
2567 input: "cond/Cast:y:0"
2568 input: "cond/strided_slice/stack:output:0"
2569 input: "cond/strided_slice/stack_1:output:0"
2570 input: "cond/strided_slice/stack_2:output:0"
2571 attr {
2572 key: "Index"
2573 value {
2574 type: DT_INT32
2575 }
2576 }
2577 attr {
2578 key: "T"
2579 value {
2580 type: DT_FLOAT
2581 }
2582 }
2583 attr {
2584 key: "begin_mask"
2585 value {
2586 i: 0
2587 }
2588 }
2589 attr {
2590 key: "ellipsis_mask"
2591 value {
2592 i: 0
2593 }
2594 }
2595 attr {
2596 key: "end_mask"
2597 value {
2598 i: 0
2599 }
2600 }
2601 attr {
2602 key: "new_axis_mask"
2603 value {
2604 i: 0
2605 }
2606 }
2607 attr {
2608 key: "shrink_axis_mask"
2609 value {
2610 i: 1
2611 }
2612 }
2613 }
2614 node_def {
2615 name: "cond/strided_slice_1/stack"
2616 op: "Const"
2617 input: "^cond/switch_t"
2618 attr {
2619 key: "dtype"
2620 value {
2621 type: DT_INT32
2622 }
2623 }
2624 attr {
2625 key: "value"
2626 value {
2627 tensor {
2628 dtype: DT_INT32
2629 tensor_shape {
2630 dim {
2631 size: 1
2632 }
2633 }
2634 int_val: 1
2635 }
2636 }
2637 }
2638 }
2639 node_def {
2640 name: "cond/strided_slice_1/stack_1"
2641 op: "Const"
2642 input: "^cond/switch_t"
2643 attr {
2644 key: "dtype"
2645 value {
2646 type: DT_INT32
2647 }
2648 }
2649 attr {
2650 key: "value"
2651 value {
2652 tensor {
2653 dtype: DT_INT32
2654 tensor_shape {
2655 dim {
2656 size: 1
2657 }
2658 }
2659 int_val: 2
2660 }
2661 }
2662 }
2663 }
2664 node_def {
2665 name: "cond/strided_slice_1/stack_2"
2666 op: "Const"
2667 input: "^cond/switch_t"
2668 attr {
2669 key: "dtype"
2670 value {
2671 type: DT_INT32
2672 }
2673 }
2674 attr {
2675 key: "value"
2676 value {
2677 tensor {
2678 dtype: DT_INT32
2679 tensor_shape {
2680 dim {
2681 size: 1
2682 }
2683 }
2684 int_val: 1
2685 }
2686 }
2687 }
2688 }
2689 node_def {
2690 name: "cond/strided_slice_1"
2691 op: "StridedSlice"
2692 input: "cond/Cast:y:0"
2693 input: "cond/strided_slice_1/stack:output:0"
2694 input: "cond/strided_slice_1/stack_1:output:0"
2695 input: "cond/strided_slice_1/stack_2:output:0"
2696 attr {
2697 key: "Index"
2698 value {
2699 type: DT_INT32
2700 }
2701 }
2702 attr {
2703 key: "T"
2704 value {
2705 type: DT_FLOAT
2706 }
2707 }
2708 attr {
2709 key: "begin_mask"
2710 value {
2711 i: 0
2712 }
2713 }
2714 attr {
2715 key: "ellipsis_mask"
2716 value {
2717 i: 0
2718 }
2719 }
2720 attr {
2721 key: "end_mask"
2722 value {
2723 i: 0
2724 }
2725 }
2726 attr {
2727 key: "new_axis_mask"
2728 value {
2729 i: 0
2730 }
2731 }
2732 attr {
2733 key: "shrink_axis_mask"
2734 value {
2735 i: 1
2736 }
2737 }
2738 }
2739 node_def {
2740 name: "cond/Greater"
2741 op: "Greater"
2742 input: "cond/strided_slice:output:0"
2743 input: "cond/strided_slice_1:output:0"
2744 attr {
2745 key: "T"
2746 value {
2747 type: DT_FLOAT
2748 }
2749 }
2750 }
2751 node_def {
2752 name: "cond/cond/Switch"
2753 op: "Switch"
2754 input: "cond/Greater:z:0"
2755 input: "cond/Greater:z:0"
2756 attr {
2757 key: "T"
2758 value {
2759 type: DT_BOOL
2760 }
2761 }
2762 }
2763 node_def {
2764 name: "cond/cond/switch_t"
2765 op: "Identity"
2766 input: "cond/cond/Switch:output_true:0"
2767 attr {
2768 key: "T"
2769 value {
2770 type: DT_BOOL
2771 }
2772 }
2773 }
2774 node_def {
2775 name: "cond/cond/switch_f"
2776 op: "Identity"
2777 input: "cond/cond/Switch:output_false:0"
2778 attr {
2779 key: "T"
2780 value {
2781 type: DT_BOOL
2782 }
2783 }
2784 }
2785 node_def {
2786 name: "cond/cond/pred_id"
2787 op: "Identity"
2788 input: "cond/Greater:z:0"
2789 attr {
2790 key: "T"
2791 value {
2792 type: DT_BOOL
2793 }
2794 }
2795 }
2796 node_def {
2797 name: "cond/cond/strided_slice/stack"
2798 op: "Const"
2799 input: "^cond/cond/switch_t"
2800 attr {
2801 key: "dtype"
2802 value {
2803 type: DT_INT32
2804 }
2805 }
2806 attr {
2807 key: "value"
2808 value {
2809 tensor {
2810 dtype: DT_INT32
2811 tensor_shape {
2812 dim {
2813 size: 1
2814 }
2815 }
2816 int_val: 0
2817 }
2818 }
2819 }
2820 }
2821 node_def {
2822 name: "cond/cond/strided_slice/stack_1"
2823 op: "Const"
2824 input: "^cond/cond/switch_t"
2825 attr {
2826 key: "dtype"
2827 value {
2828 type: DT_INT32
2829 }
2830 }
2831 attr {
2832 key: "value"
2833 value {
2834 tensor {
2835 dtype: DT_INT32
2836 tensor_shape {
2837 dim {
2838 size: 1
2839 }
2840 }
2841 int_val: 1
2842 }
2843 }
2844 }
2845 }
2846 node_def {
2847 name: "cond/cond/strided_slice/stack_2"
2848 op: "Const"
2849 input: "^cond/cond/switch_t"
2850 attr {
2851 key: "dtype"
2852 value {
2853 type: DT_INT32
2854 }
2855 }
2856 attr {
2857 key: "value"
2858 value {
2859 tensor {
2860 dtype: DT_INT32
2861 tensor_shape {
2862 dim {
2863 size: 1
2864 }
2865 }
2866 int_val: 1
2867 }
2868 }
2869 }
2870 }
2871 node_def {
2872 name: "cond/cond/strided_slice"
2873 op: "StridedSlice"
2874 input: "cond/cond/strided_slice/Switch:output_true:0"
2875 input: "cond/cond/strided_slice/stack:output:0"
2876 input: "cond/cond/strided_slice/stack_1:output:0"
2877 input: "cond/cond/strided_slice/stack_2:output:0"
2878 attr {
2879 key: "Index"
2880 value {
2881 type: DT_INT32
2882 }
2883 }
2884 attr {
2885 key: "T"
2886 value {
2887 type: DT_FLOAT
2888 }
2889 }
2890 attr {
2891 key: "begin_mask"
2892 value {
2893 i: 0
2894 }
2895 }
2896 attr {
2897 key: "ellipsis_mask"
2898 value {
2899 i: 0
2900 }
2901 }
2902 attr {
2903 key: "end_mask"
2904 value {
2905 i: 0
2906 }
2907 }
2908 attr {
2909 key: "new_axis_mask"
2910 value {
2911 i: 0
2912 }
2913 }
2914 attr {
2915 key: "shrink_axis_mask"
2916 value {
2917 i: 1
2918 }
2919 }
2920 }
2921 node_def {
2922 name: "cond/cond/strided_slice/Switch"
2923 op: "Switch"
2924 input: "cond/Cast:y:0"
2925 input: "cond/cond/pred_id:output:0"
2926 attr {
2927 key: "T"
2928 value {
2929 type: DT_FLOAT
2930 }
2931 }
2932 attr {
2933 key: "_class"
2934 value {
2935 list {
2936 s: "loc:@cond/Cast"
2937 }
2938 }
2939 }
2940 }
2941 node_def {
2942 name: "cond/cond/strided_slice_1/stack"
2943 op: "Const"
2944 input: "^cond/cond/switch_t"
2945 attr {
2946 key: "dtype"
2947 value {
2948 type: DT_INT32
2949 }
2950 }
2951 attr {
2952 key: "value"
2953 value {
2954 tensor {
2955 dtype: DT_INT32
2956 tensor_shape {
2957 dim {
2958 size: 1
2959 }
2960 }
2961 int_val: 1
2962 }
2963 }
2964 }
2965 }
2966 node_def {
2967 name: "cond/cond/strided_slice_1/stack_1"
2968 op: "Const"
2969 input: "^cond/cond/switch_t"
2970 attr {
2971 key: "dtype"
2972 value {
2973 type: DT_INT32
2974 }
2975 }
2976 attr {
2977 key: "value"
2978 value {
2979 tensor {
2980 dtype: DT_INT32
2981 tensor_shape {
2982 dim {
2983 size: 1
2984 }
2985 }
2986 int_val: 2
2987 }
2988 }
2989 }
2990 }
2991 node_def {
2992 name: "cond/cond/strided_slice_1/stack_2"
2993 op: "Const"
2994 input: "^cond/cond/switch_t"
2995 attr {
2996 key: "dtype"
2997 value {
2998 type: DT_INT32
2999 }
3000 }
3001 attr {
3002 key: "value"
3003 value {
3004 tensor {
3005 dtype: DT_INT32
3006 tensor_shape {
3007 dim {
3008 size: 1
3009 }
3010 }
3011 int_val: 1
3012 }
3013 }
3014 }
3015 }
3016 node_def {
3017 name: "cond/cond/strided_slice_1"
3018 op: "StridedSlice"
3019 input: "cond/cond/strided_slice/Switch:output_true:0"
3020 input: "cond/cond/strided_slice_1/stack:output:0"
3021 input: "cond/cond/strided_slice_1/stack_1:output:0"
3022 input: "cond/cond/strided_slice_1/stack_2:output:0"
3023 attr {
3024 key: "Index"
3025 value {
3026 type: DT_INT32
3027 }
3028 }
3029 attr {
3030 key: "T"
3031 value {
3032 type: DT_FLOAT
3033 }
3034 }
3035 attr {
3036 key: "begin_mask"
3037 value {
3038 i: 0
3039 }
3040 }
3041 attr {
3042 key: "ellipsis_mask"
3043 value {
3044 i: 0
3045 }
3046 }
3047 attr {
3048 key: "end_mask"
3049 value {
3050 i: 0
3051 }
3052 }
3053 attr {
3054 key: "new_axis_mask"
3055 value {
3056 i: 0
3057 }
3058 }
3059 attr {
3060 key: "shrink_axis_mask"
3061 value {
3062 i: 1
3063 }
3064 }
3065 }
3066 node_def {
3067 name: "cond/cond/truediv"
3068 op: "RealDiv"
3069 input: "cond/cond/strided_slice:output:0"
3070 input: "cond/cond/strided_slice_1:output:0"
3071 attr {
3072 key: "T"
3073 value {
3074 type: DT_FLOAT
3075 }
3076 }
3077 }
3078 node_def {
3079 name: "cond/cond/mul/y"
3080 op: "Const"
3081 input: "^cond/cond/switch_t"
3082 attr {
3083 key: "dtype"
3084 value {
3085 type: DT_FLOAT
3086 }
3087 }
3088 attr {
3089 key: "value"
3090 value {
3091 tensor {
3092 dtype: DT_FLOAT
3093 tensor_shape {
3094 }
3095 float_val: 224.0
3096 }
3097 }
3098 }
3099 }
3100 node_def {
3101 name: "cond/cond/mul"
3102 op: "Mul"
3103 input: "cond/cond/truediv:z:0"
3104 input: "cond/cond/mul/y:output:0"
3105 attr {
3106 key: "T"
3107 value {
3108 type: DT_FLOAT
3109 }
3110 }
3111 }
3112 node_def {
3113 name: "cond/cond/Cast/x/1"
3114 op: "Const"
3115 input: "^cond/cond/switch_t"
3116 attr {
3117 key: "dtype"
3118 value {
3119 type: DT_FLOAT
3120 }
3121 }
3122 attr {
3123 key: "value"
3124 value {
3125 tensor {
3126 dtype: DT_FLOAT
3127 tensor_shape {
3128 }
3129 float_val: 224.0
3130 }
3131 }
3132 }
3133 }
3134 node_def {
3135 name: "cond/cond/Cast/x"
3136 op: "Pack"
3137 input: "cond/cond/mul:z:0"
3138 input: "cond/cond/Cast/x/1:output:0"
3139 attr {
3140 key: "N"
3141 value {
3142 i: 2
3143 }
3144 }
3145 attr {
3146 key: "T"
3147 value {
3148 type: DT_FLOAT
3149 }
3150 }
3151 attr {
3152 key: "axis"
3153 value {
3154 i: 0
3155 }
3156 }
3157 }
3158 node_def {
3159 name: "cond/cond/Cast"
3160 op: "Cast"
3161 input: "cond/cond/Cast/x:output:0"
3162 attr {
3163 key: "DstT"
3164 value {
3165 type: DT_INT32
3166 }
3167 }
3168 attr {
3169 key: "SrcT"
3170 value {
3171 type: DT_FLOAT
3172 }
3173 }
3174 }
3175 node_def {
3176 name: "cond/cond/strided_slice_2/stack"
3177 op: "Const"
3178 input: "^cond/cond/switch_f"
3179 attr {
3180 key: "dtype"
3181 value {
3182 type: DT_INT32
3183 }
3184 }
3185 attr {
3186 key: "value"
3187 value {
3188 tensor {
3189 dtype: DT_INT32
3190 tensor_shape {
3191 dim {
3192 size: 1
3193 }
3194 }
3195 int_val: 1
3196 }
3197 }
3198 }
3199 }
3200 node_def {
3201 name: "cond/cond/strided_slice_2/stack_1"
3202 op: "Const"
3203 input: "^cond/cond/switch_f"
3204 attr {
3205 key: "dtype"
3206 value {
3207 type: DT_INT32
3208 }
3209 }
3210 attr {
3211 key: "value"
3212 value {
3213 tensor {
3214 dtype: DT_INT32
3215 tensor_shape {
3216 dim {
3217 size: 1
3218 }
3219 }
3220 int_val: 2
3221 }
3222 }
3223 }
3224 }
3225 node_def {
3226 name: "cond/cond/strided_slice_2/stack_2"
3227 op: "Const"
3228 input: "^cond/cond/switch_f"
3229 attr {
3230 key: "dtype"
3231 value {
3232 type: DT_INT32
3233 }
3234 }
3235 attr {
3236 key: "value"
3237 value {
3238 tensor {
3239 dtype: DT_INT32
3240 tensor_shape {
3241 dim {
3242 size: 1
3243 }
3244 }
3245 int_val: 1
3246 }
3247 }
3248 }
3249 }
3250 node_def {
3251 name: "cond/cond/strided_slice_2"
3252 op: "StridedSlice"
3253 input: "cond/cond/strided_slice_2/Switch:output_false:0"
3254 input: "cond/cond/strided_slice_2/stack:output:0"
3255 input: "cond/cond/strided_slice_2/stack_1:output:0"
3256 input: "cond/cond/strided_slice_2/stack_2:output:0"
3257 attr {
3258 key: "Index"
3259 value {
3260 type: DT_INT32
3261 }
3262 }
3263 attr {
3264 key: "T"
3265 value {
3266 type: DT_FLOAT
3267 }
3268 }
3269 attr {
3270 key: "begin_mask"
3271 value {
3272 i: 0
3273 }
3274 }
3275 attr {
3276 key: "ellipsis_mask"
3277 value {
3278 i: 0
3279 }
3280 }
3281 attr {
3282 key: "end_mask"
3283 value {
3284 i: 0
3285 }
3286 }
3287 attr {
3288 key: "new_axis_mask"
3289 value {
3290 i: 0
3291 }
3292 }
3293 attr {
3294 key: "shrink_axis_mask"
3295 value {
3296 i: 1
3297 }
3298 }
3299 }
3300 node_def {
3301 name: "cond/cond/strided_slice_2/Switch"
3302 op: "Switch"
3303 input: "cond/Cast:y:0"
3304 input: "cond/cond/pred_id:output:0"
3305 attr {
3306 key: "T"
3307 value {
3308 type: DT_FLOAT
3309 }
3310 }
3311 attr {
3312 key: "_class"
3313 value {
3314 list {
3315 s: "loc:@cond/Cast"
3316 }
3317 }
3318 }
3319 }
3320 node_def {
3321 name: "cond/cond/strided_slice_3/stack"
3322 op: "Const"
3323 input: "^cond/cond/switch_f"
3324 attr {
3325 key: "dtype"
3326 value {
3327 type: DT_INT32
3328 }
3329 }
3330 attr {
3331 key: "value"
3332 value {
3333 tensor {
3334 dtype: DT_INT32
3335 tensor_shape {
3336 dim {
3337 size: 1
3338 }
3339 }
3340 int_val: 0
3341 }
3342 }
3343 }
3344 }
3345 node_def {
3346 name: "cond/cond/strided_slice_3/stack_1"
3347 op: "Const"
3348 input: "^cond/cond/switch_f"
3349 attr {
3350 key: "dtype"
3351 value {
3352 type: DT_INT32
3353 }
3354 }
3355 attr {
3356 key: "value"
3357 value {
3358 tensor {
3359 dtype: DT_INT32
3360 tensor_shape {
3361 dim {
3362 size: 1
3363 }
3364 }
3365 int_val: 1
3366 }
3367 }
3368 }
3369 }
3370 node_def {
3371 name: "cond/cond/strided_slice_3/stack_2"
3372 op: "Const"
3373 input: "^cond/cond/switch_f"
3374 attr {
3375 key: "dtype"
3376 value {
3377 type: DT_INT32
3378 }
3379 }
3380 attr {
3381 key: "value"
3382 value {
3383 tensor {
3384 dtype: DT_INT32
3385 tensor_shape {
3386 dim {
3387 size: 1
3388 }
3389 }
3390 int_val: 1
3391 }
3392 }
3393 }
3394 }
3395 node_def {
3396 name: "cond/cond/strided_slice_3"
3397 op: "StridedSlice"
3398 input: "cond/cond/strided_slice_2/Switch:output_false:0"
3399 input: "cond/cond/strided_slice_3/stack:output:0"
3400 input: "cond/cond/strided_slice_3/stack_1:output:0"
3401 input: "cond/cond/strided_slice_3/stack_2:output:0"
3402 attr {
3403 key: "Index"
3404 value {
3405 type: DT_INT32
3406 }
3407 }
3408 attr {
3409 key: "T"
3410 value {
3411 type: DT_FLOAT
3412 }
3413 }
3414 attr {
3415 key: "begin_mask"
3416 value {
3417 i: 0
3418 }
3419 }
3420 attr {
3421 key: "ellipsis_mask"
3422 value {
3423 i: 0
3424 }
3425 }
3426 attr {
3427 key: "end_mask"
3428 value {
3429 i: 0
3430 }
3431 }
3432 attr {
3433 key: "new_axis_mask"
3434 value {
3435 i: 0
3436 }
3437 }
3438 attr {
3439 key: "shrink_axis_mask"
3440 value {
3441 i: 1
3442 }
3443 }
3444 }
3445 node_def {
3446 name: "cond/cond/truediv_1"
3447 op: "RealDiv"
3448 input: "cond/cond/strided_slice_2:output:0"
3449 input: "cond/cond/strided_slice_3:output:0"
3450 attr {
3451 key: "T"
3452 value {
3453 type: DT_FLOAT
3454 }
3455 }
3456 }
3457 node_def {
3458 name: "cond/cond/mul_1/y"
3459 op: "Const"
3460 input: "^cond/cond/switch_f"
3461 attr {
3462 key: "dtype"
3463 value {
3464 type: DT_FLOAT
3465 }
3466 }
3467 attr {
3468 key: "value"
3469 value {
3470 tensor {
3471 dtype: DT_FLOAT
3472 tensor_shape {
3473 }
3474 float_val: 224.0
3475 }
3476 }
3477 }
3478 }
3479 node_def {
3480 name: "cond/cond/mul_1"
3481 op: "Mul"
3482 input: "cond/cond/truediv_1:z:0"
3483 input: "cond/cond/mul_1/y:output:0"
3484 attr {
3485 key: "T"
3486 value {
3487 type: DT_FLOAT
3488 }
3489 }
3490 }
3491 node_def {
3492 name: "cond/cond/Cast_1/x/0"
3493 op: "Const"
3494 input: "^cond/cond/switch_f"
3495 attr {
3496 key: "dtype"
3497 value {
3498 type: DT_FLOAT
3499 }
3500 }
3501 attr {
3502 key: "value"
3503 value {
3504 tensor {
3505 dtype: DT_FLOAT
3506 tensor_shape {
3507 }
3508 float_val: 224.0
3509 }
3510 }
3511 }
3512 }
3513 node_def {
3514 name: "cond/cond/Cast_1/x"
3515 op: "Pack"
3516 input: "cond/cond/Cast_1/x/0:output:0"
3517 input: "cond/cond/mul_1:z:0"
3518 attr {
3519 key: "N"
3520 value {
3521 i: 2
3522 }
3523 }
3524 attr {
3525 key: "T"
3526 value {
3527 type: DT_FLOAT
3528 }
3529 }
3530 attr {
3531 key: "axis"
3532 value {
3533 i: 0
3534 }
3535 }
3536 }
3537 node_def {
3538 name: "cond/cond/Cast_1"
3539 op: "Cast"
3540 input: "cond/cond/Cast_1/x:output:0"
3541 attr {
3542 key: "DstT"
3543 value {
3544 type: DT_INT32
3545 }
3546 }
3547 attr {
3548 key: "SrcT"
3549 value {
3550 type: DT_FLOAT
3551 }
3552 }
3553 }
3554 node_def {
3555 name: "cond/cond/Merge"
3556 op: "Merge"
3557 input: "cond/cond/Cast_1:y:0"
3558 input: "cond/cond/Cast:y:0"
3559 attr {
3560 key: "N"
3561 value {
3562 i: 2
3563 }
3564 }
3565 attr {
3566 key: "T"
3567 value {
3568 type: DT_INT32
3569 }
3570 }
3571 }
3572 node_def {
3573 name: "cond/ResizeBicubic/images"
3574 op: "Pack"
3575 input: "cond/Shape/Switch:output_true:0"
3576 attr {
3577 key: "N"
3578 value {
3579 i: 1
3580 }
3581 }
3582 attr {
3583 key: "T"
3584 value {
3585 type: DT_FLOAT
3586 }
3587 }
3588 attr {
3589 key: "axis"
3590 value {
3591 i: 0
3592 }
3593 }
3594 }
3595 node_def {
3596 name: "cond/ResizeBicubic"
3597 op: "ResizeBicubic"
3598 input: "cond/ResizeBicubic/images:output:0"
3599 input: "cond/cond/Merge:output:0"
3600 attr {
3601 key: "T"
3602 value {
3603 type: DT_FLOAT
3604 }
3605 }
3606 attr {
3607 key: "align_corners"
3608 value {
3609 b: false
3610 }
3611 }
3612 }
3613 node_def {
3614 name: "cond/strided_slice_2/stack"
3615 op: "Const"
3616 input: "^cond/switch_t"
3617 attr {
3618 key: "dtype"
3619 value {
3620 type: DT_INT32
3621 }
3622 }
3623 attr {
3624 key: "value"
3625 value {
3626 tensor {
3627 dtype: DT_INT32
3628 tensor_shape {
3629 dim {
3630 size: 1
3631 }
3632 }
3633 int_val: 0
3634 }
3635 }
3636 }
3637 }
3638 node_def {
3639 name: "cond/strided_slice_2/stack_1"
3640 op: "Const"
3641 input: "^cond/switch_t"
3642 attr {
3643 key: "dtype"
3644 value {
3645 type: DT_INT32
3646 }
3647 }
3648 attr {
3649 key: "value"
3650 value {
3651 tensor {
3652 dtype: DT_INT32
3653 tensor_shape {
3654 dim {
3655 size: 1
3656 }
3657 }
3658 int_val: 1
3659 }
3660 }
3661 }
3662 }
3663 node_def {
3664 name: "cond/strided_slice_2/stack_2"
3665 op: "Const"
3666 input: "^cond/switch_t"
3667 attr {
3668 key: "dtype"
3669 value {
3670 type: DT_INT32
3671 }
3672 }
3673 attr {
3674 key: "value"
3675 value {
3676 tensor {
3677 dtype: DT_INT32
3678 tensor_shape {
3679 dim {
3680 size: 1
3681 }
3682 }
3683 int_val: 1
3684 }
3685 }
3686 }
3687 }
3688 node_def {
3689 name: "cond/strided_slice_2"
3690 op: "StridedSlice"
3691 input: "cond/ResizeBicubic:resized_images:0"
3692 input: "cond/strided_slice_2/stack:output:0"
3693 input: "cond/strided_slice_2/stack_1:output:0"
3694 input: "cond/strided_slice_2/stack_2:output:0"
3695 attr {
3696 key: "Index"
3697 value {
3698 type: DT_INT32
3699 }
3700 }
3701 attr {
3702 key: "T"
3703 value {
3704 type: DT_FLOAT
3705 }
3706 }
3707 attr {
3708 key: "begin_mask"
3709 value {
3710 i: 0
3711 }
3712 }
3713 attr {
3714 key: "ellipsis_mask"
3715 value {
3716 i: 0
3717 }
3718 }
3719 attr {
3720 key: "end_mask"
3721 value {
3722 i: 0
3723 }
3724 }
3725 attr {
3726 key: "new_axis_mask"
3727 value {
3728 i: 0
3729 }
3730 }
3731 attr {
3732 key: "shrink_axis_mask"
3733 value {
3734 i: 1
3735 }
3736 }
3737 }
3738 node_def {
3739 name: "cond/Shape_1"
3740 op: "Shape"
3741 input: "cond/strided_slice_2:output:0"
3742 attr {
3743 key: "T"
3744 value {
3745 type: DT_FLOAT
3746 }
3747 }
3748 attr {
3749 key: "out_type"
3750 value {
3751 type: DT_INT32
3752 }
3753 }
3754 }
3755 node_def {
3756 name: "cond/strided_slice_3/stack"
3757 op: "Const"
3758 input: "^cond/switch_t"
3759 attr {
3760 key: "dtype"
3761 value {
3762 type: DT_INT32
3763 }
3764 }
3765 attr {
3766 key: "value"
3767 value {
3768 tensor {
3769 dtype: DT_INT32
3770 tensor_shape {
3771 dim {
3772 size: 1
3773 }
3774 }
3775 int_val: 0
3776 }
3777 }
3778 }
3779 }
3780 node_def {
3781 name: "cond/strided_slice_3/stack_1"
3782 op: "Const"
3783 input: "^cond/switch_t"
3784 attr {
3785 key: "dtype"
3786 value {
3787 type: DT_INT32
3788 }
3789 }
3790 attr {
3791 key: "value"
3792 value {
3793 tensor {
3794 dtype: DT_INT32
3795 tensor_shape {
3796 dim {
3797 size: 1
3798 }
3799 }
3800 int_val: 1
3801 }
3802 }
3803 }
3804 }
3805 node_def {
3806 name: "cond/strided_slice_3/stack_2"
3807 op: "Const"
3808 input: "^cond/switch_t"
3809 attr {
3810 key: "dtype"
3811 value {
3812 type: DT_INT32
3813 }
3814 }
3815 attr {
3816 key: "value"
3817 value {
3818 tensor {
3819 dtype: DT_INT32
3820 tensor_shape {
3821 dim {
3822 size: 1
3823 }
3824 }
3825 int_val: 1
3826 }
3827 }
3828 }
3829 }
3830 node_def {
3831 name: "cond/strided_slice_3"
3832 op: "StridedSlice"
3833 input: "cond/Shape_1:output:0"
3834 input: "cond/strided_slice_3/stack:output:0"
3835 input: "cond/strided_slice_3/stack_1:output:0"
3836 input: "cond/strided_slice_3/stack_2:output:0"
3837 attr {
3838 key: "Index"
3839 value {
3840 type: DT_INT32
3841 }
3842 }
3843 attr {
3844 key: "T"
3845 value {
3846 type: DT_INT32
3847 }
3848 }
3849 attr {
3850 key: "begin_mask"
3851 value {
3852 i: 0
3853 }
3854 }
3855 attr {
3856 key: "ellipsis_mask"
3857 value {
3858 i: 0
3859 }
3860 }
3861 attr {
3862 key: "end_mask"
3863 value {
3864 i: 0
3865 }
3866 }
3867 attr {
3868 key: "new_axis_mask"
3869 value {
3870 i: 0
3871 }
3872 }
3873 attr {
3874 key: "shrink_axis_mask"
3875 value {
3876 i: 1
3877 }
3878 }
3879 }
3880 node_def {
3881 name: "cond/Shape_2"
3882 op: "Shape"
3883 input: "cond/strided_slice_2:output:0"
3884 attr {
3885 key: "T"
3886 value {
3887 type: DT_FLOAT
3888 }
3889 }
3890 attr {
3891 key: "out_type"
3892 value {
3893 type: DT_INT32
3894 }
3895 }
3896 }
3897 node_def {
3898 name: "cond/strided_slice_4/stack"
3899 op: "Const"
3900 input: "^cond/switch_t"
3901 attr {
3902 key: "dtype"
3903 value {
3904 type: DT_INT32
3905 }
3906 }
3907 attr {
3908 key: "value"
3909 value {
3910 tensor {
3911 dtype: DT_INT32
3912 tensor_shape {
3913 dim {
3914 size: 1
3915 }
3916 }
3917 int_val: 1
3918 }
3919 }
3920 }
3921 }
3922 node_def {
3923 name: "cond/strided_slice_4/stack_1"
3924 op: "Const"
3925 input: "^cond/switch_t"
3926 attr {
3927 key: "dtype"
3928 value {
3929 type: DT_INT32
3930 }
3931 }
3932 attr {
3933 key: "value"
3934 value {
3935 tensor {
3936 dtype: DT_INT32
3937 tensor_shape {
3938 dim {
3939 size: 1
3940 }
3941 }
3942 int_val: 2
3943 }
3944 }
3945 }
3946 }
3947 node_def {
3948 name: "cond/strided_slice_4/stack_2"
3949 op: "Const"
3950 input: "^cond/switch_t"
3951 attr {
3952 key: "dtype"
3953 value {
3954 type: DT_INT32
3955 }
3956 }
3957 attr {
3958 key: "value"
3959 value {
3960 tensor {
3961 dtype: DT_INT32
3962 tensor_shape {
3963 dim {
3964 size: 1
3965 }
3966 }
3967 int_val: 1
3968 }
3969 }
3970 }
3971 }
3972 node_def {
3973 name: "cond/strided_slice_4"
3974 op: "StridedSlice"
3975 input: "cond/Shape_2:output:0"
3976 input: "cond/strided_slice_4/stack:output:0"
3977 input: "cond/strided_slice_4/stack_1:output:0"
3978 input: "cond/strided_slice_4/stack_2:output:0"
3979 attr {
3980 key: "Index"
3981 value {
3982 type: DT_INT32
3983 }
3984 }
3985 attr {
3986 key: "T"
3987 value {
3988 type: DT_INT32
3989 }
3990 }
3991 attr {
3992 key: "begin_mask"
3993 value {
3994 i: 0
3995 }
3996 }
3997 attr {
3998 key: "ellipsis_mask"
3999 value {
4000 i: 0
4001 }
4002 }
4003 attr {
4004 key: "end_mask"
4005 value {
4006 i: 0
4007 }
4008 }
4009 attr {
4010 key: "new_axis_mask"
4011 value {
4012 i: 0
4013 }
4014 }
4015 attr {
4016 key: "shrink_axis_mask"
4017 value {
4018 i: 1
4019 }
4020 }
4021 }
4022 node_def {
4023 name: "cond/sub/y"
4024 op: "Const"
4025 input: "^cond/switch_t"
4026 attr {
4027 key: "dtype"
4028 value {
4029 type: DT_INT32
4030 }
4031 }
4032 attr {
4033 key: "value"
4034 value {
4035 tensor {
4036 dtype: DT_INT32
4037 tensor_shape {
4038 }
4039 int_val: 224
4040 }
4041 }
4042 }
4043 }
4044 node_def {
4045 name: "cond/sub"
4046 op: "Sub"
4047 input: "cond/strided_slice_3:output:0"
4048 input: "cond/sub/y:output:0"
4049 attr {
4050 key: "T"
4051 value {
4052 type: DT_INT32
4053 }
4054 }
4055 }
4056 node_def {
4057 name: "cond/add/y"
4058 op: "Const"
4059 input: "^cond/switch_t"
4060 attr {
4061 key: "dtype"
4062 value {
4063 type: DT_INT32
4064 }
4065 }
4066 attr {
4067 key: "value"
4068 value {
4069 tensor {
4070 dtype: DT_INT32
4071 tensor_shape {
4072 }
4073 int_val: 1
4074 }
4075 }
4076 }
4077 }
4078 node_def {
4079 name: "cond/add"
4080 op: "Add"
4081 input: "cond/sub:z:0"
4082 input: "cond/add/y:output:0"
4083 attr {
4084 key: "T"
4085 value {
4086 type: DT_INT32
4087 }
4088 }
4089 }
4090 node_def {
4091 name: "cond/truediv/y"
4092 op: "Const"
4093 input: "^cond/switch_t"
4094 attr {
4095 key: "dtype"
4096 value {
4097 type: DT_INT32
4098 }
4099 }
4100 attr {
4101 key: "value"
4102 value {
4103 tensor {
4104 dtype: DT_INT32
4105 tensor_shape {
4106 }
4107 int_val: 2
4108 }
4109 }
4110 }
4111 }
4112 node_def {
4113 name: "cond/truediv/Cast"
4114 op: "Cast"
4115 input: "cond/add:z:0"
4116 attr {
4117 key: "DstT"
4118 value {
4119 type: DT_DOUBLE
4120 }
4121 }
4122 attr {
4123 key: "SrcT"
4124 value {
4125 type: DT_INT32
4126 }
4127 }
4128 }
4129 node_def {
4130 name: "cond/truediv/Cast_1"
4131 op: "Cast"
4132 input: "cond/truediv/y:output:0"
4133 attr {
4134 key: "DstT"
4135 value {
4136 type: DT_DOUBLE
4137 }
4138 }
4139 attr {
4140 key: "SrcT"
4141 value {
4142 type: DT_INT32
4143 }
4144 }
4145 }
4146 node_def {
4147 name: "cond/truediv"
4148 op: "RealDiv"
4149 input: "cond/truediv/Cast:y:0"
4150 input: "cond/truediv/Cast_1:y:0"
4151 attr {
4152 key: "T"
4153 value {
4154 type: DT_DOUBLE
4155 }
4156 }
4157 }
4158 node_def {
4159 name: "cond/sub_1/y"
4160 op: "Const"
4161 input: "^cond/switch_t"
4162 attr {
4163 key: "dtype"
4164 value {
4165 type: DT_INT32
4166 }
4167 }
4168 attr {
4169 key: "value"
4170 value {
4171 tensor {
4172 dtype: DT_INT32
4173 tensor_shape {
4174 }
4175 int_val: 224
4176 }
4177 }
4178 }
4179 }
4180 node_def {
4181 name: "cond/sub_1"
4182 op: "Sub"
4183 input: "cond/strided_slice_4:output:0"
4184 input: "cond/sub_1/y:output:0"
4185 attr {
4186 key: "T"
4187 value {
4188 type: DT_INT32
4189 }
4190 }
4191 }
4192 node_def {
4193 name: "cond/add_1/y"
4194 op: "Const"
4195 input: "^cond/switch_t"
4196 attr {
4197 key: "dtype"
4198 value {
4199 type: DT_INT32
4200 }
4201 }
4202 attr {
4203 key: "value"
4204 value {
4205 tensor {
4206 dtype: DT_INT32
4207 tensor_shape {
4208 }
4209 int_val: 1
4210 }
4211 }
4212 }
4213 }
4214 node_def {
4215 name: "cond/add_1"
4216 op: "Add"
4217 input: "cond/sub_1:z:0"
4218 input: "cond/add_1/y:output:0"
4219 attr {
4220 key: "T"
4221 value {
4222 type: DT_INT32
4223 }
4224 }
4225 }
4226 node_def {
4227 name: "cond/truediv_1/y"
4228 op: "Const"
4229 input: "^cond/switch_t"
4230 attr {
4231 key: "dtype"
4232 value {
4233 type: DT_INT32
4234 }
4235 }
4236 attr {
4237 key: "value"
4238 value {
4239 tensor {
4240 dtype: DT_INT32
4241 tensor_shape {
4242 }
4243 int_val: 2
4244 }
4245 }
4246 }
4247 }
4248 node_def {
4249 name: "cond/truediv_1/Cast"
4250 op: "Cast"
4251 input: "cond/add_1:z:0"
4252 attr {
4253 key: "DstT"
4254 value {
4255 type: DT_DOUBLE
4256 }
4257 }
4258 attr {
4259 key: "SrcT"
4260 value {
4261 type: DT_INT32
4262 }
4263 }
4264 }
4265 node_def {
4266 name: "cond/truediv_1/Cast_1"
4267 op: "Cast"
4268 input: "cond/truediv_1/y:output:0"
4269 attr {
4270 key: "DstT"
4271 value {
4272 type: DT_DOUBLE
4273 }
4274 }
4275 attr {
4276 key: "SrcT"
4277 value {
4278 type: DT_INT32
4279 }
4280 }
4281 }
4282 node_def {
4283 name: "cond/truediv_1"
4284 op: "RealDiv"
4285 input: "cond/truediv_1/Cast:y:0"
4286 input: "cond/truediv_1/Cast_1:y:0"
4287 attr {
4288 key: "T"
4289 value {
4290 type: DT_DOUBLE
4291 }
4292 }
4293 }
4294 node_def {
4295 name: "cond/Shape_3"
4296 op: "Shape"
4297 input: "cond/strided_slice_2:output:0"
4298 attr {
4299 key: "T"
4300 value {
4301 type: DT_FLOAT
4302 }
4303 }
4304 attr {
4305 key: "out_type"
4306 value {
4307 type: DT_INT32
4308 }
4309 }
4310 }
4311 node_def {
4312 name: "cond/Rank"
4313 op: "Const"
4314 input: "^cond/switch_t"
4315 attr {
4316 key: "dtype"
4317 value {
4318 type: DT_INT32
4319 }
4320 }
4321 attr {
4322 key: "value"
4323 value {
4324 tensor {
4325 dtype: DT_INT32
4326 tensor_shape {
4327 }
4328 int_val: 3
4329 }
4330 }
4331 }
4332 }
4333 node_def {
4334 name: "cond/Equal/y"
4335 op: "Const"
4336 input: "^cond/switch_t"
4337 attr {
4338 key: "dtype"
4339 value {
4340 type: DT_INT32
4341 }
4342 }
4343 attr {
4344 key: "value"
4345 value {
4346 tensor {
4347 dtype: DT_INT32
4348 tensor_shape {
4349 }
4350 int_val: 3
4351 }
4352 }
4353 }
4354 }
4355 node_def {
4356 name: "cond/Equal"
4357 op: "Equal"
4358 input: "cond/Rank:output:0"
4359 input: "cond/Equal/y:output:0"
4360 attr {
4361 key: "T"
4362 value {
4363 type: DT_INT32
4364 }
4365 }
4366 }
4367 node_def {
4368 name: "cond/Assert/Const"
4369 op: "Const"
4370 input: "^cond/switch_t"
4371 attr {
4372 key: "dtype"
4373 value {
4374 type: DT_STRING
4375 }
4376 }
4377 attr {
4378 key: "value"
4379 value {
4380 tensor {
4381 dtype: DT_STRING
4382 tensor_shape {
4383 }
4384 string_val: "Rank of image must be equal to 3."
4385 }
4386 }
4387 }
4388 }
4389 node_def {
4390 name: "cond/Assert/Assert/data_0"
4391 op: "Const"
4392 input: "^cond/switch_t"
4393 attr {
4394 key: "dtype"
4395 value {
4396 type: DT_STRING
4397 }
4398 }
4399 attr {
4400 key: "value"
4401 value {
4402 tensor {
4403 dtype: DT_STRING
4404 tensor_shape {
4405 }
4406 string_val: "Rank of image must be equal to 3."
4407 }
4408 }
4409 }
4410 }
4411 node_def {
4412 name: "cond/Assert/Assert"
4413 op: "Assert"
4414 input: "cond/Equal:z:0"
4415 input: "cond/Assert/Assert/data_0:output:0"
4416 attr {
4417 key: "T"
4418 value {
4419 list {
4420 type: DT_STRING
4421 }
4422 }
4423 }
4424 attr {
4425 key: "summarize"
4426 value {
4427 i: 3
4428 }
4429 }
4430 }
4431 node_def {
4432 name: "cond/strided_slice_5/stack"
4433 op: "Const"
4434 input: "^cond/Assert/Assert"
4435 input: "^cond/switch_t"
4436 attr {
4437 key: "dtype"
4438 value {
4439 type: DT_INT32
4440 }
4441 }
4442 attr {
4443 key: "value"
4444 value {
4445 tensor {
4446 dtype: DT_INT32
4447 tensor_shape {
4448 dim {
4449 size: 1
4450 }
4451 }
4452 int_val: 2
4453 }
4454 }
4455 }
4456 }
4457 node_def {
4458 name: "cond/strided_slice_5/stack_1"
4459 op: "Const"
4460 input: "^cond/Assert/Assert"
4461 input: "^cond/switch_t"
4462 attr {
4463 key: "dtype"
4464 value {
4465 type: DT_INT32
4466 }
4467 }
4468 attr {
4469 key: "value"
4470 value {
4471 tensor {
4472 dtype: DT_INT32
4473 tensor_shape {
4474 dim {
4475 size: 1
4476 }
4477 }
4478 int_val: 3
4479 }
4480 }
4481 }
4482 }
4483 node_def {
4484 name: "cond/strided_slice_5/stack_2"
4485 op: "Const"
4486 input: "^cond/Assert/Assert"
4487 input: "^cond/switch_t"
4488 attr {
4489 key: "dtype"
4490 value {
4491 type: DT_INT32
4492 }
4493 }
4494 attr {
4495 key: "value"
4496 value {
4497 tensor {
4498 dtype: DT_INT32
4499 tensor_shape {
4500 dim {
4501 size: 1
4502 }
4503 }
4504 int_val: 1
4505 }
4506 }
4507 }
4508 }
4509 node_def {
4510 name: "cond/strided_slice_5"
4511 op: "StridedSlice"
4512 input: "cond/Shape_3:output:0"
4513 input: "cond/strided_slice_5/stack:output:0"
4514 input: "cond/strided_slice_5/stack_1:output:0"
4515 input: "cond/strided_slice_5/stack_2:output:0"
4516 attr {
4517 key: "Index"
4518 value {
4519 type: DT_INT32
4520 }
4521 }
4522 attr {
4523 key: "T"
4524 value {
4525 type: DT_INT32
4526 }
4527 }
4528 attr {
4529 key: "begin_mask"
4530 value {
4531 i: 0
4532 }
4533 }
4534 attr {
4535 key: "ellipsis_mask"
4536 value {
4537 i: 0
4538 }
4539 }
4540 attr {
4541 key: "end_mask"
4542 value {
4543 i: 0
4544 }
4545 }
4546 attr {
4547 key: "new_axis_mask"
4548 value {
4549 i: 0
4550 }
4551 }
4552 attr {
4553 key: "shrink_axis_mask"
4554 value {
4555 i: 1
4556 }
4557 }
4558 }
4559 node_def {
4560 name: "cond/stack/0"
4561 op: "Const"
4562 input: "^cond/Assert/Assert"
4563 input: "^cond/switch_t"
4564 attr {
4565 key: "dtype"
4566 value {
4567 type: DT_INT32
4568 }
4569 }
4570 attr {
4571 key: "value"
4572 value {
4573 tensor {
4574 dtype: DT_INT32
4575 tensor_shape {
4576 }
4577 int_val: 224
4578 }
4579 }
4580 }
4581 }
4582 node_def {
4583 name: "cond/stack/1"
4584 op: "Const"
4585 input: "^cond/Assert/Assert"
4586 input: "^cond/switch_t"
4587 attr {
4588 key: "dtype"
4589 value {
4590 type: DT_INT32
4591 }
4592 }
4593 attr {
4594 key: "value"
4595 value {
4596 tensor {
4597 dtype: DT_INT32
4598 tensor_shape {
4599 }
4600 int_val: 224
4601 }
4602 }
4603 }
4604 }
4605 node_def {
4606 name: "cond/stack"
4607 op: "Pack"
4608 input: "cond/stack/0:output:0"
4609 input: "cond/stack/1:output:0"
4610 input: "cond/strided_slice_5:output:0"
4611 attr {
4612 key: "N"
4613 value {
4614 i: 3
4615 }
4616 }
4617 attr {
4618 key: "T"
4619 value {
4620 type: DT_INT32
4621 }
4622 }
4623 attr {
4624 key: "axis"
4625 value {
4626 i: 0
4627 }
4628 }
4629 }
4630 node_def {
4631 name: "cond/strided_slice_6/stack"
4632 op: "Const"
4633 input: "^cond/switch_t"
4634 attr {
4635 key: "dtype"
4636 value {
4637 type: DT_INT32
4638 }
4639 }
4640 attr {
4641 key: "value"
4642 value {
4643 tensor {
4644 dtype: DT_INT32
4645 tensor_shape {
4646 dim {
4647 size: 1
4648 }
4649 }
4650 int_val: 0
4651 }
4652 }
4653 }
4654 }
4655 node_def {
4656 name: "cond/strided_slice_6/stack_1"
4657 op: "Const"
4658 input: "^cond/switch_t"
4659 attr {
4660 key: "dtype"
4661 value {
4662 type: DT_INT32
4663 }
4664 }
4665 attr {
4666 key: "value"
4667 value {
4668 tensor {
4669 dtype: DT_INT32
4670 tensor_shape {
4671 dim {
4672 size: 1
4673 }
4674 }
4675 int_val: 1
4676 }
4677 }
4678 }
4679 }
4680 node_def {
4681 name: "cond/strided_slice_6/stack_2"
4682 op: "Const"
4683 input: "^cond/switch_t"
4684 attr {
4685 key: "dtype"
4686 value {
4687 type: DT_INT32
4688 }
4689 }
4690 attr {
4691 key: "value"
4692 value {
4693 tensor {
4694 dtype: DT_INT32
4695 tensor_shape {
4696 dim {
4697 size: 1
4698 }
4699 }
4700 int_val: 1
4701 }
4702 }
4703 }
4704 }
4705 node_def {
4706 name: "cond/strided_slice_6"
4707 op: "StridedSlice"
4708 input: "cond/Shape_3:output:0"
4709 input: "cond/strided_slice_6/stack:output:0"
4710 input: "cond/strided_slice_6/stack_1:output:0"
4711 input: "cond/strided_slice_6/stack_2:output:0"
4712 attr {
4713 key: "Index"
4714 value {
4715 type: DT_INT32
4716 }
4717 }
4718 attr {
4719 key: "T"
4720 value {
4721 type: DT_INT32
4722 }
4723 }
4724 attr {
4725 key: "begin_mask"
4726 value {
4727 i: 0
4728 }
4729 }
4730 attr {
4731 key: "ellipsis_mask"
4732 value {
4733 i: 0
4734 }
4735 }
4736 attr {
4737 key: "end_mask"
4738 value {
4739 i: 0
4740 }
4741 }
4742 attr {
4743 key: "new_axis_mask"
4744 value {
4745 i: 0
4746 }
4747 }
4748 attr {
4749 key: "shrink_axis_mask"
4750 value {
4751 i: 1
4752 }
4753 }
4754 }
4755 node_def {
4756 name: "cond/GreaterEqual/y"
4757 op: "Const"
4758 input: "^cond/switch_t"
4759 attr {
4760 key: "dtype"
4761 value {
4762 type: DT_INT32
4763 }
4764 }
4765 attr {
4766 key: "value"
4767 value {
4768 tensor {
4769 dtype: DT_INT32
4770 tensor_shape {
4771 }
4772 int_val: 224
4773 }
4774 }
4775 }
4776 }
4777 node_def {
4778 name: "cond/GreaterEqual"
4779 op: "GreaterEqual"
4780 input: "cond/strided_slice_6:output:0"
4781 input: "cond/GreaterEqual/y:output:0"
4782 attr {
4783 key: "T"
4784 value {
4785 type: DT_INT32
4786 }
4787 }
4788 }
4789 node_def {
4790 name: "cond/strided_slice_7/stack"
4791 op: "Const"
4792 input: "^cond/switch_t"
4793 attr {
4794 key: "dtype"
4795 value {
4796 type: DT_INT32
4797 }
4798 }
4799 attr {
4800 key: "value"
4801 value {
4802 tensor {
4803 dtype: DT_INT32
4804 tensor_shape {
4805 dim {
4806 size: 1
4807 }
4808 }
4809 int_val: 1
4810 }
4811 }
4812 }
4813 }
4814 node_def {
4815 name: "cond/strided_slice_7/stack_1"
4816 op: "Const"
4817 input: "^cond/switch_t"
4818 attr {
4819 key: "dtype"
4820 value {
4821 type: DT_INT32
4822 }
4823 }
4824 attr {
4825 key: "value"
4826 value {
4827 tensor {
4828 dtype: DT_INT32
4829 tensor_shape {
4830 dim {
4831 size: 1
4832 }
4833 }
4834 int_val: 2
4835 }
4836 }
4837 }
4838 }
4839 node_def {
4840 name: "cond/strided_slice_7/stack_2"
4841 op: "Const"
4842 input: "^cond/switch_t"
4843 attr {
4844 key: "dtype"
4845 value {
4846 type: DT_INT32
4847 }
4848 }
4849 attr {
4850 key: "value"
4851 value {
4852 tensor {
4853 dtype: DT_INT32
4854 tensor_shape {
4855 dim {
4856 size: 1
4857 }
4858 }
4859 int_val: 1
4860 }
4861 }
4862 }
4863 }
4864 node_def {
4865 name: "cond/strided_slice_7"
4866 op: "StridedSlice"
4867 input: "cond/Shape_3:output:0"
4868 input: "cond/strided_slice_7/stack:output:0"
4869 input: "cond/strided_slice_7/stack_1:output:0"
4870 input: "cond/strided_slice_7/stack_2:output:0"
4871 attr {
4872 key: "Index"
4873 value {
4874 type: DT_INT32
4875 }
4876 }
4877 attr {
4878 key: "T"
4879 value {
4880 type: DT_INT32
4881 }
4882 }
4883 attr {
4884 key: "begin_mask"
4885 value {
4886 i: 0
4887 }
4888 }
4889 attr {
4890 key: "ellipsis_mask"
4891 value {
4892 i: 0
4893 }
4894 }
4895 attr {
4896 key: "end_mask"
4897 value {
4898 i: 0
4899 }
4900 }
4901 attr {
4902 key: "new_axis_mask"
4903 value {
4904 i: 0
4905 }
4906 }
4907 attr {
4908 key: "shrink_axis_mask"
4909 value {
4910 i: 1
4911 }
4912 }
4913 }
4914 node_def {
4915 name: "cond/GreaterEqual_1/y"
4916 op: "Const"
4917 input: "^cond/switch_t"
4918 attr {
4919 key: "dtype"
4920 value {
4921 type: DT_INT32
4922 }
4923 }
4924 attr {
4925 key: "value"
4926 value {
4927 tensor {
4928 dtype: DT_INT32
4929 tensor_shape {
4930 }
4931 int_val: 224
4932 }
4933 }
4934 }
4935 }
4936 node_def {
4937 name: "cond/GreaterEqual_1"
4938 op: "GreaterEqual"
4939 input: "cond/strided_slice_7:output:0"
4940 input: "cond/GreaterEqual_1/y:output:0"
4941 attr {
4942 key: "T"
4943 value {
4944 type: DT_INT32
4945 }
4946 }
4947 }
4948 node_def {
4949 name: "cond/LogicalAnd"
4950 op: "LogicalAnd"
4951 input: "cond/GreaterEqual:z:0"
4952 input: "cond/GreaterEqual_1:z:0"
4953 }
4954 node_def {
4955 name: "cond/Assert_1/Const"
4956 op: "Const"
4957 input: "^cond/switch_t"
4958 attr {
4959 key: "dtype"
4960 value {
4961 type: DT_STRING
4962 }
4963 }
4964 attr {
4965 key: "value"
4966 value {
4967 tensor {
4968 dtype: DT_STRING
4969 tensor_shape {
4970 }
4971 string_val: "Crop size greater than the image size."
4972 }
4973 }
4974 }
4975 }
4976 node_def {
4977 name: "cond/Assert_1/Assert/data_0"
4978 op: "Const"
4979 input: "^cond/switch_t"
4980 attr {
4981 key: "dtype"
4982 value {
4983 type: DT_STRING
4984 }
4985 }
4986 attr {
4987 key: "value"
4988 value {
4989 tensor {
4990 dtype: DT_STRING
4991 tensor_shape {
4992 }
4993 string_val: "Crop size greater than the image size."
4994 }
4995 }
4996 }
4997 }
4998 node_def {
4999 name: "cond/Assert_1/Assert"
5000 op: "Assert"
5001 input: "cond/LogicalAnd:z:0"
5002 input: "cond/Assert_1/Assert/data_0:output:0"
5003 attr {
5004 key: "T"
5005 value {
5006 list {
5007 type: DT_STRING
5008 }
5009 }
5010 }
5011 attr {
5012 key: "summarize"
5013 value {
5014 i: 3
5015 }
5016 }
5017 }
5018 node_def {
5019 name: "cond/stack_1/2"
5020 op: "Const"
5021 input: "^cond/switch_t"
5022 attr {
5023 key: "dtype"
5024 value {
5025 type: DT_DOUBLE
5026 }
5027 }
5028 attr {
5029 key: "value"
5030 value {
5031 tensor {
5032 dtype: DT_DOUBLE
5033 tensor_shape {
5034 }
5035 double_val: 0.0
5036 }
5037 }
5038 }
5039 }
5040 node_def {
5041 name: "cond/stack_1"
5042 op: "Pack"
5043 input: "cond/truediv:z:0"
5044 input: "cond/truediv_1:z:0"
5045 input: "cond/stack_1/2:output:0"
5046 attr {
5047 key: "N"
5048 value {
5049 i: 3
5050 }
5051 }
5052 attr {
5053 key: "T"
5054 value {
5055 type: DT_DOUBLE
5056 }
5057 }
5058 attr {
5059 key: "axis"
5060 value {
5061 i: 0
5062 }
5063 }
5064 }
5065 node_def {
5066 name: "cond/ToInt32"
5067 op: "Cast"
5068 input: "cond/stack_1:output:0"
5069 attr {
5070 key: "DstT"
5071 value {
5072 type: DT_INT32
5073 }
5074 }
5075 attr {
5076 key: "SrcT"
5077 value {
5078 type: DT_DOUBLE
5079 }
5080 }
5081 }
5082 node_def {
5083 name: "cond/Slice"
5084 op: "Slice"
5085 input: "cond/strided_slice_2:output:0"
5086 input: "cond/ToInt32:y:0"
5087 input: "cond/stack:output:0"
5088 input: "^cond/Assert_1/Assert"
5089 attr {
5090 key: "Index"
5091 value {
5092 type: DT_INT32
5093 }
5094 }
5095 attr {
5096 key: "T"
5097 value {
5098 type: DT_FLOAT
5099 }
5100 }
5101 }
5102 node_def {
5103 name: "cond/Reshape"
5104 op: "Reshape"
5105 input: "cond/Slice:output:0"
5106 input: "cond/stack:output:0"
5107 attr {
5108 key: "T"
5109 value {
5110 type: DT_FLOAT
5111 }
5112 }
5113 attr {
5114 key: "Tshape"
5115 value {
5116 type: DT_INT32
5117 }
5118 }
5119 }
5120 node_def {
5121 name: "cond/ResizeBicubic_1/images"
5122 op: "Pack"
5123 input: "cond/ResizeBicubic_1/images/Switch:output_false:0"
5124 attr {
5125 key: "N"
5126 value {
5127 i: 1
5128 }
5129 }
5130 attr {
5131 key: "T"
5132 value {
5133 type: DT_FLOAT
5134 }
5135 }
5136 attr {
5137 key: "axis"
5138 value {
5139 i: 0
5140 }
5141 }
5142 }
5143 node_def {
5144 name: "cond/ResizeBicubic_1/images/Switch"
5145 op: "Switch"
5146 input: "distorted_bounding_box_crop/Slice:output:0"
5147 input: "cond/pred_id:output:0"
5148 attr {
5149 key: "T"
5150 value {
5151 type: DT_FLOAT
5152 }
5153 }
5154 attr {
5155 key: "_class"
5156 value {
5157 list {
5158 s: "loc:@distorted_bounding_box_crop/Slice"
5159 }
5160 }
5161 }
5162 }
5163 node_def {
5164 name: "cond/ResizeBicubic_1/size"
5165 op: "Const"
5166 input: "^cond/switch_f"
5167 attr {
5168 key: "dtype"
5169 value {
5170 type: DT_INT32
5171 }
5172 }
5173 attr {
5174 key: "value"
5175 value {
5176 tensor {
5177 dtype: DT_INT32
5178 tensor_shape {
5179 dim {
5180 size: 2
5181 }
5182 }
5183 tensor_content: "\340\000\000\000\340\000\000\000"
5184 }
5185 }
5186 }
5187 }
5188 node_def {
5189 name: "cond/ResizeBicubic_1"
5190 op: "ResizeBicubic"
5191 input: "cond/ResizeBicubic_1/images:output:0"
5192 input: "cond/ResizeBicubic_1/size:output:0"
5193 attr {
5194 key: "T"
5195 value {
5196 type: DT_FLOAT
5197 }
5198 }
5199 attr {
5200 key: "align_corners"
5201 value {
5202 b: false
5203 }
5204 }
5205 }
5206 node_def {
5207 name: "cond/strided_slice_8/stack"
5208 op: "Const"
5209 input: "^cond/switch_f"
5210 attr {
5211 key: "dtype"
5212 value {
5213 type: DT_INT32
5214 }
5215 }
5216 attr {
5217 key: "value"
5218 value {
5219 tensor {
5220 dtype: DT_INT32
5221 tensor_shape {
5222 dim {
5223 size: 1
5224 }
5225 }
5226 int_val: 0
5227 }
5228 }
5229 }
5230 }
5231 node_def {
5232 name: "cond/strided_slice_8/stack_1"
5233 op: "Const"
5234 input: "^cond/switch_f"
5235 attr {
5236 key: "dtype"
5237 value {
5238 type: DT_INT32
5239 }
5240 }
5241 attr {
5242 key: "value"
5243 value {
5244 tensor {
5245 dtype: DT_INT32
5246 tensor_shape {
5247 dim {
5248 size: 1
5249 }
5250 }
5251 int_val: 1
5252 }
5253 }
5254 }
5255 }
5256 node_def {
5257 name: "cond/strided_slice_8/stack_2"
5258 op: "Const"
5259 input: "^cond/switch_f"
5260 attr {
5261 key: "dtype"
5262 value {
5263 type: DT_INT32
5264 }
5265 }
5266 attr {
5267 key: "value"
5268 value {
5269 tensor {
5270 dtype: DT_INT32
5271 tensor_shape {
5272 dim {
5273 size: 1
5274 }
5275 }
5276 int_val: 1
5277 }
5278 }
5279 }
5280 }
5281 node_def {
5282 name: "cond/strided_slice_8"
5283 op: "StridedSlice"
5284 input: "cond/ResizeBicubic_1:resized_images:0"
5285 input: "cond/strided_slice_8/stack:output:0"
5286 input: "cond/strided_slice_8/stack_1:output:0"
5287 input: "cond/strided_slice_8/stack_2:output:0"
5288 attr {
5289 key: "Index"
5290 value {
5291 type: DT_INT32
5292 }
5293 }
5294 attr {
5295 key: "T"
5296 value {
5297 type: DT_FLOAT
5298 }
5299 }
5300 attr {
5301 key: "begin_mask"
5302 value {
5303 i: 0
5304 }
5305 }
5306 attr {
5307 key: "ellipsis_mask"
5308 value {
5309 i: 0
5310 }
5311 }
5312 attr {
5313 key: "end_mask"
5314 value {
5315 i: 0
5316 }
5317 }
5318 attr {
5319 key: "new_axis_mask"
5320 value {
5321 i: 0
5322 }
5323 }
5324 attr {
5325 key: "shrink_axis_mask"
5326 value {
5327 i: 1
5328 }
5329 }
5330 }
5331 node_def {
5332 name: "cond/Merge"
5333 op: "Merge"
5334 input: "cond/strided_slice_8:output:0"
5335 input: "cond/Reshape:output:0"
5336 attr {
5337 key: "N"
5338 value {
5339 i: 2
5340 }
5341 }
5342 attr {
5343 key: "T"
5344 value {
5345 type: DT_FLOAT
5346 }
5347 }
5348 }
5349 node_def {
5350 name: "Const_2"
5351 op: "Const"
5352 attr {
5353 key: "dtype"
5354 value {
5355 type: DT_FLOAT
5356 }
5357 }
5358 attr {
5359 key: "value"
5360 value {
5361 tensor {
5362 dtype: DT_FLOAT
5363 tensor_shape {
5364 dim {
5365 size: 1
5366 }
5367 dim {
5368 size: 1
5369 }
5370 dim {
5371 size: 3
5372 }
5373 }
5374 tensor_content: "\354Q\370>\325x\351>;\337\317>"
5375 }
5376 }
5377 }
5378 }
5379 node_def {
5380 name: "sub"
5381 op: "Sub"
5382 input: "cond/Merge:output:0"
5383 input: "Const_2:output:0"
5384 attr {
5385 key: "T"
5386 value {
5387 type: DT_FLOAT
5388 }
5389 }
5390 }
5391 node_def {
5392 name: "Const_3"
5393 op: "Const"
5394 attr {
5395 key: "dtype"
5396 value {
5397 type: DT_FLOAT
5398 }
5399 }
5400 attr {
5401 key: "value"
5402 value {
5403 tensor {
5404 dtype: DT_FLOAT
5405 tensor_shape {
5406 dim {
5407 size: 1
5408 }
5409 dim {
5410 size: 1
5411 }
5412 dim {
5413 size: 3
5414 }
5415 }
5416 tensor_content: "\372~j>B`e>fff>"
5417 }
5418 }
5419 }
5420 }
5421 node_def {
5422 name: "truediv"
5423 op: "RealDiv"
5424 input: "sub:z:0"
5425 input: "Const_3:output:0"
5426 attr {
5427 key: "T"
5428 value {
5429 type: DT_FLOAT
5430 }
5431 }
5432 }
5433 node_def {
5434 name: "random_flip_left_right/control_dependency"
5435 op: "Identity"
5436 input: "truediv:z:0"
5437 attr {
5438 key: "T"
5439 value {
5440 type: DT_FLOAT
5441 }
5442 }
5443 attr {
5444 key: "_class"
5445 value {
5446 list {
5447 s: "loc:@truediv"
5448 }
5449 }
5450 }
5451 }
5452 node_def {
5453 name: "random_flip_left_right/random_uniform/shape"
5454 op: "Const"
5455 attr {
5456 key: "dtype"
5457 value {
5458 type: DT_INT32
5459 }
5460 }
5461 attr {
5462 key: "value"
5463 value {
5464 tensor {
5465 dtype: DT_INT32
5466 tensor_shape {
5467 dim {
5468 }
5469 }
5470 }
5471 }
5472 }
5473 }
5474 node_def {
5475 name: "random_flip_left_right/random_uniform/min"
5476 op: "Const"
5477 attr {
5478 key: "dtype"
5479 value {
5480 type: DT_FLOAT
5481 }
5482 }
5483 attr {
5484 key: "value"
5485 value {
5486 tensor {
5487 dtype: DT_FLOAT
5488 tensor_shape {
5489 }
5490 float_val: 0.0
5491 }
5492 }
5493 }
5494 }
5495 node_def {
5496 name: "random_flip_left_right/random_uniform/max"
5497 op: "Const"
5498 attr {
5499 key: "dtype"
5500 value {
5501 type: DT_FLOAT
5502 }
5503 }
5504 attr {
5505 key: "value"
5506 value {
5507 tensor {
5508 dtype: DT_FLOAT
5509 tensor_shape {
5510 }
5511 float_val: 1.0
5512 }
5513 }
5514 }
5515 }
5516 node_def {
5517 name: "random_flip_left_right/random_uniform/RandomUniform"
5518 op: "RandomUniform"
5519 input: "random_flip_left_right/random_uniform/shape:output:0"
5520 attr {
5521 key: "T"
5522 value {
5523 type: DT_INT32
5524 }
5525 }
5526 attr {
5527 key: "dtype"
5528 value {
5529 type: DT_FLOAT
5530 }
5531 }
5532 attr {
5533 key: "seed"
5534 value {
5535 i: 0
5536 }
5537 }
5538 attr {
5539 key: "seed2"
5540 value {
5541 i: 0
5542 }
5543 }
5544 }
5545 node_def {
5546 name: "random_flip_left_right/random_uniform/sub"
5547 op: "Sub"
5548 input: "random_flip_left_right/random_uniform/max:output:0"
5549 input: "random_flip_left_right/random_uniform/min:output:0"
5550 attr {
5551 key: "T"
5552 value {
5553 type: DT_FLOAT
5554 }
5555 }
5556 }
5557 node_def {
5558 name: "random_flip_left_right/random_uniform/mul"
5559 op: "Mul"
5560 input: "random_flip_left_right/random_uniform/RandomUniform:output:0"
5561 input: "random_flip_left_right/random_uniform/sub:z:0"
5562 attr {
5563 key: "T"
5564 value {
5565 type: DT_FLOAT
5566 }
5567 }
5568 }
5569 node_def {
5570 name: "random_flip_left_right/random_uniform"
5571 op: "Add"
5572 input: "random_flip_left_right/random_uniform/mul:z:0"
5573 input: "random_flip_left_right/random_uniform/min:output:0"
5574 attr {
5575 key: "T"
5576 value {
5577 type: DT_FLOAT
5578 }
5579 }
5580 }
5581 node_def {
5582 name: "random_flip_left_right/Less/y"
5583 op: "Const"
5584 attr {
5585 key: "dtype"
5586 value {
5587 type: DT_FLOAT
5588 }
5589 }
5590 attr {
5591 key: "value"
5592 value {
5593 tensor {
5594 dtype: DT_FLOAT
5595 tensor_shape {
5596 }
5597 float_val: 0.5
5598 }
5599 }
5600 }
5601 }
5602 node_def {
5603 name: "random_flip_left_right/Less"
5604 op: "Less"
5605 input: "random_flip_left_right/random_uniform:z:0"
5606 input: "random_flip_left_right/Less/y:output:0"
5607 attr {
5608 key: "T"
5609 value {
5610 type: DT_FLOAT
5611 }
5612 }
5613 }
5614 node_def {
5615 name: "random_flip_left_right/Switch"
5616 op: "Switch"
5617 input: "random_flip_left_right/Less:z:0"
5618 input: "random_flip_left_right/Less:z:0"
5619 attr {
5620 key: "T"
5621 value {
5622 type: DT_BOOL
5623 }
5624 }
5625 }
5626 node_def {
5627 name: "random_flip_left_right/switch_t"
5628 op: "Identity"
5629 input: "random_flip_left_right/Switch:output_true:0"
5630 attr {
5631 key: "T"
5632 value {
5633 type: DT_BOOL
5634 }
5635 }
5636 }
5637 node_def {
5638 name: "random_flip_left_right/switch_f"
5639 op: "Identity"
5640 input: "random_flip_left_right/Switch:output_false:0"
5641 attr {
5642 key: "T"
5643 value {
5644 type: DT_BOOL
5645 }
5646 }
5647 }
5648 node_def {
5649 name: "random_flip_left_right/pred_id"
5650 op: "Identity"
5651 input: "random_flip_left_right/Less:z:0"
5652 attr {
5653 key: "T"
5654 value {
5655 type: DT_BOOL
5656 }
5657 }
5658 }
5659 node_def {
5660 name: "random_flip_left_right/ReverseV2/axis"
5661 op: "Const"
5662 input: "^random_flip_left_right/switch_t"
5663 attr {
5664 key: "dtype"
5665 value {
5666 type: DT_INT32
5667 }
5668 }
5669 attr {
5670 key: "value"
5671 value {
5672 tensor {
5673 dtype: DT_INT32
5674 tensor_shape {
5675 dim {
5676 size: 1
5677 }
5678 }
5679 int_val: 1
5680 }
5681 }
5682 }
5683 }
5684 node_def {
5685 name: "random_flip_left_right/ReverseV2"
5686 op: "ReverseV2"
5687 input: "random_flip_left_right/ReverseV2/Switch:output_true:0"
5688 input: "random_flip_left_right/ReverseV2/axis:output:0"
5689 attr {
5690 key: "T"
5691 value {
5692 type: DT_FLOAT
5693 }
5694 }
5695 attr {
5696 key: "Tidx"
5697 value {
5698 type: DT_INT32
5699 }
5700 }
5701 }
5702 node_def {
5703 name: "random_flip_left_right/ReverseV2/Switch"
5704 op: "Switch"
5705 input: "random_flip_left_right/control_dependency:output:0"
5706 input: "random_flip_left_right/pred_id:output:0"
5707 attr {
5708 key: "T"
5709 value {
5710 type: DT_FLOAT
5711 }
5712 }
5713 attr {
5714 key: "_class"
5715 value {
5716 list {
5717 s: "loc:@truediv"
5718 }
5719 }
5720 }
5721 }
5722 node_def {
5723 name: "random_flip_left_right/Switch_1"
5724 op: "Switch"
5725 input: "random_flip_left_right/control_dependency:output:0"
5726 input: "random_flip_left_right/pred_id:output:0"
5727 attr {
5728 key: "T"
5729 value {
5730 type: DT_FLOAT
5731 }
5732 }
5733 attr {
5734 key: "_class"
5735 value {
5736 list {
5737 s: "loc:@truediv"
5738 }
5739 }
5740 }
5741 }
5742 node_def {
5743 name: "random_flip_left_right/Merge"
5744 op: "Merge"
5745 input: "random_flip_left_right/Switch_1:output_false:0"
5746 input: "random_flip_left_right/ReverseV2:output:0"
5747 attr {
5748 key: "N"
5749 value {
5750 i: 2
5751 }
5752 }
5753 attr {
5754 key: "T"
5755 value {
5756 type: DT_FLOAT
5757 }
5758 }
5759 }
5760 node_def {
5761 name: "Reshape_1/shape"
5762 op: "Const"
5763 attr {
5764 key: "dtype"
5765 value {
5766 type: DT_INT32
5767 }
5768 }
5769 attr {
5770 key: "value"
5771 value {
5772 tensor {
5773 dtype: DT_INT32
5774 tensor_shape {
5775 dim {
5776 size: 3
5777 }
5778 }
5779 tensor_content: "\340\000\000\000\340\000\000\000\003\000\000\000"
5780 }
5781 }
5782 }
5783 }
5784 node_def {
5785 name: "Reshape_1"
5786 op: "Reshape"
5787 input: "random_flip_left_right/Merge:output:0"
5788 input: "Reshape_1/shape:output:0"
5789 attr {
5790 key: "T"
5791 value {
5792 type: DT_FLOAT
5793 }
5794 }
5795 attr {
5796 key: "Tshape"
5797 value {
5798 type: DT_INT32
5799 }
5800 }
5801 }
5802 node_def {
5803 name: "Reshape_2/shape"
5804 op: "Const"
5805 attr {
5806 key: "dtype"
5807 value {
5808 type: DT_INT32
5809 }
5810 }
5811 attr {
5812 key: "value"
5813 value {
5814 tensor {
5815 dtype: DT_INT32
5816 tensor_shape {
5817 dim {
5818 }
5819 }
5820 }
5821 }
5822 }
5823 }
5824 node_def {
5825 name: "Reshape_2"
5826 op: "Reshape"
5827 input: "ParseSingleExample/ParseSingleExample:dense_values:0"
5828 input: "Reshape_2/shape:output:0"
5829 attr {
5830 key: "T"
5831 value {
5832 type: DT_INT64
5833 }
5834 }
5835 attr {
5836 key: "Tshape"
5837 value {
5838 type: DT_INT32
5839 }
5840 }
5841 }
5842 node_def {
5843 name: "Cast_1"
5844 op: "Cast"
5845 input: "Reshape_2:output:0"
5846 attr {
5847 key: "DstT"
5848 value {
5849 type: DT_INT32
5850 }
5851 }
5852 attr {
5853 key: "SrcT"
5854 value {
5855 type: DT_INT64
5856 }
5857 }
5858 }
5859 node_def {
5860 name: "sub_1/y"
5861 op: "Const"
5862 attr {
5863 key: "dtype"
5864 value {
5865 type: DT_INT32
5866 }
5867 }
5868 attr {
5869 key: "value"
5870 value {
5871 tensor {
5872 dtype: DT_INT32
5873 tensor_shape {
5874 }
5875 int_val: 1
5876 }
5877 }
5878 }
5879 }
5880 node_def {
5881 name: "sub_1"
5882 op: "Sub"
5883 input: "Cast_1:y:0"
5884 input: "sub_1/y:output:0"
5885 attr {
5886 key: "T"
5887 value {
5888 type: DT_INT32
5889 }
5890 }
5891 }
5892 ret {
5893 key: "Reshape_1"
5894 value: "Reshape_1:output:0"
5895 }
5896 ret {
5897 key: "sub_1"
5898 value: "sub_1:z:0"
5899 }
5900 }
5901 function {
5902 signature {
5903 name: "tf_predicate_7089b845"
5904 input_arg {
5905 name: "arg0"
5906 type: DT_FLOAT
5907 }
5908 input_arg {
5909 name: "arg1"
5910 type: DT_INT32
5911 }
5912 input_arg {
5913 name: "Equal/Placeholder"
5914 type: DT_INT64
5915 }
5916 output_arg {
5917 name: "Equal"
5918 type: DT_BOOL
5919 }
5920 description: "A wrapper for Defun that facilitates shape inference."
5921 }
5922 node_def {
5923 name: "Shape"
5924 op: "Shape"
5925 input: "arg0"
5926 attr {
5927 key: "T"
5928 value {
5929 type: DT_FLOAT
5930 }
5931 }
5932 attr {
5933 key: "out_type"
5934 value {
5935 type: DT_INT64
5936 }
5937 }
5938 }
5939 node_def {
5940 name: "strided_slice/stack"
5941 op: "Const"
5942 attr {
5943 key: "dtype"
5944 value {
5945 type: DT_INT32
5946 }
5947 }
5948 attr {
5949 key: "value"
5950 value {
5951 tensor {
5952 dtype: DT_INT32
5953 tensor_shape {
5954 dim {
5955 size: 1
5956 }
5957 }
5958 int_val: 0
5959 }
5960 }
5961 }
5962 }
5963 node_def {
5964 name: "strided_slice/stack_1"
5965 op: "Const"
5966 attr {
5967 key: "dtype"
5968 value {
5969 type: DT_INT32
5970 }
5971 }
5972 attr {
5973 key: "value"
5974 value {
5975 tensor {
5976 dtype: DT_INT32
5977 tensor_shape {
5978 dim {
5979 size: 1
5980 }
5981 }
5982 int_val: 1
5983 }
5984 }
5985 }
5986 }
5987 node_def {
5988 name: "strided_slice/stack_2"
5989 op: "Const"
5990 attr {
5991 key: "dtype"
5992 value {
5993 type: DT_INT32
5994 }
5995 }
5996 attr {
5997 key: "value"
5998 value {
5999 tensor {
6000 dtype: DT_INT32
6001 tensor_shape {
6002 dim {
6003 size: 1
6004 }
6005 }
6006 int_val: 1
6007 }
6008 }
6009 }
6010 }
6011 node_def {
6012 name: "strided_slice"
6013 op: "StridedSlice"
6014 input: "Shape:output:0"
6015 input: "strided_slice/stack:output:0"
6016 input: "strided_slice/stack_1:output:0"
6017 input: "strided_slice/stack_2:output:0"
6018 attr {
6019 key: "Index"
6020 value {
6021 type: DT_INT32
6022 }
6023 }
6024 attr {
6025 key: "T"
6026 value {
6027 type: DT_INT64
6028 }
6029 }
6030 attr {
6031 key: "begin_mask"
6032 value {
6033 i: 0
6034 }
6035 }
6036 attr {
6037 key: "ellipsis_mask"
6038 value {
6039 i: 0
6040 }
6041 }
6042 attr {
6043 key: "end_mask"
6044 value {
6045 i: 0
6046 }
6047 }
6048 attr {
6049 key: "new_axis_mask"
6050 value {
6051 i: 0
6052 }
6053 }
6054 attr {
6055 key: "shrink_axis_mask"
6056 value {
6057 i: 1
6058 }
6059 }
6060 }
6061 node_def {
6062 name: "Equal"
6063 op: "Equal"
6064 input: "strided_slice:output:0"
6065 input: "Equal/Placeholder"
6066 attr {
6067 key: "T"
6068 value {
6069 type: DT_INT64
6070 }
6071 }
6072 }
6073 ret {
6074 key: "Equal"
6075 value: "Equal:z:0"
6076 }
6077 }
6078 function {
6079 signature {
6080 name: "_make_dataset_5fa5e1f4"
6081 output_arg {
6082 name: "PrefetchDataset_1"
6083 type: DT_VARIANT
6084 }
6085 is_stateful: true
6086 }
6087 node_def {
6088 name: "TensorSliceDataset/MatchingFiles/pattern"
6089 op: "Const"
6090 attr {
6091 key: "dtype"
6092 value {
6093 type: DT_STRING
6094 }
6095 }
6096 attr {
6097 key: "value"
6098 value {
6099 tensor {
6100 dtype: DT_STRING
6101 tensor_shape {
6102 }
6103 string_val: "$(DATA_DIR)"
6104 }
6105 }
6106 }
6107 }
6108 node_def {
6109 name: "TensorSliceDataset/MatchingFiles"
6110 op: "MatchingFiles"
6111 input: "TensorSliceDataset/MatchingFiles/pattern:output:0"
6112 }
6113 node_def {
6114 name: "TensorSliceDataset"
6115 op: "TensorSliceDataset"
6116 input: "TensorSliceDataset/MatchingFiles:filenames:0"
6117 attr {
6118 key: "Toutput_types"
6119 value {
6120 list {
6121 type: DT_STRING
6122 }
6123 }
6124 }
6125 attr {
6126 key: "output_shapes"
6127 value {
6128 list {
6129 shape {
6130 }
6131 }
6132 }
6133 }
6134 }
6135 node_def {
6136 name: "ShuffleDataset/MatchingFiles/pattern"
6137 op: "Const"
6138 attr {
6139 key: "dtype"
6140 value {
6141 type: DT_STRING
6142 }
6143 }
6144 attr {
6145 key: "value"
6146 value {
6147 tensor {
6148 dtype: DT_STRING
6149 tensor_shape {
6150 }
6151 string_val: "$(DATA_DIR)"
6152 }
6153 }
6154 }
6155 }
6156 node_def {
6157 name: "ShuffleDataset/MatchingFiles"
6158 op: "MatchingFiles"
6159 input: "ShuffleDataset/MatchingFiles/pattern:output:0"
6160 }
6161 node_def {
6162 name: "ShuffleDataset/Shape"
6163 op: "Shape"
6164 input: "ShuffleDataset/MatchingFiles:filenames:0"
6165 attr {
6166 key: "T"
6167 value {
6168 type: DT_STRING
6169 }
6170 }
6171 attr {
6172 key: "out_type"
6173 value {
6174 type: DT_INT64
6175 }
6176 }
6177 }
6178 node_def {
6179 name: "ShuffleDataset/strided_slice/stack"
6180 op: "Const"
6181 attr {
6182 key: "dtype"
6183 value {
6184 type: DT_INT32
6185 }
6186 }
6187 attr {
6188 key: "value"
6189 value {
6190 tensor {
6191 dtype: DT_INT32
6192 tensor_shape {
6193 dim {
6194 size: 1
6195 }
6196 }
6197 int_val: 0
6198 }
6199 }
6200 }
6201 }
6202 node_def {
6203 name: "ShuffleDataset/strided_slice/stack_1"
6204 op: "Const"
6205 attr {
6206 key: "dtype"
6207 value {
6208 type: DT_INT32
6209 }
6210 }
6211 attr {
6212 key: "value"
6213 value {
6214 tensor {
6215 dtype: DT_INT32
6216 tensor_shape {
6217 dim {
6218 size: 1
6219 }
6220 }
6221 int_val: 1
6222 }
6223 }
6224 }
6225 }
6226 node_def {
6227 name: "ShuffleDataset/strided_slice/stack_2"
6228 op: "Const"
6229 attr {
6230 key: "dtype"
6231 value {
6232 type: DT_INT32
6233 }
6234 }
6235 attr {
6236 key: "value"
6237 value {
6238 tensor {
6239 dtype: DT_INT32
6240 tensor_shape {
6241 dim {
6242 size: 1
6243 }
6244 }
6245 int_val: 1
6246 }
6247 }
6248 }
6249 }
6250 node_def {
6251 name: "ShuffleDataset/strided_slice"
6252 op: "StridedSlice"
6253 input: "ShuffleDataset/Shape:output:0"
6254 input: "ShuffleDataset/strided_slice/stack:output:0"
6255 input: "ShuffleDataset/strided_slice/stack_1:output:0"
6256 input: "ShuffleDataset/strided_slice/stack_2:output:0"
6257 attr {
6258 key: "Index"
6259 value {
6260 type: DT_INT32
6261 }
6262 }
6263 attr {
6264 key: "T"
6265 value {
6266 type: DT_INT64
6267 }
6268 }
6269 attr {
6270 key: "begin_mask"
6271 value {
6272 i: 0
6273 }
6274 }
6275 attr {
6276 key: "ellipsis_mask"
6277 value {
6278 i: 0
6279 }
6280 }
6281 attr {
6282 key: "end_mask"
6283 value {
6284 i: 0
6285 }
6286 }
6287 attr {
6288 key: "new_axis_mask"
6289 value {
6290 i: 0
6291 }
6292 }
6293 attr {
6294 key: "shrink_axis_mask"
6295 value {
6296 i: 1
6297 }
6298 }
6299 }
6300 node_def {
6301 name: "ShuffleDataset/Maximum/y"
6302 op: "Const"
6303 attr {
6304 key: "dtype"
6305 value {
6306 type: DT_INT64
6307 }
6308 }
6309 attr {
6310 key: "value"
6311 value {
6312 tensor {
6313 dtype: DT_INT64
6314 tensor_shape {
6315 }
6316 int64_val: 1
6317 }
6318 }
6319 }
6320 }
6321 node_def {
6322 name: "ShuffleDataset/Maximum"
6323 op: "Maximum"
6324 input: "ShuffleDataset/strided_slice:output:0"
6325 input: "ShuffleDataset/Maximum/y:output:0"
6326 attr {
6327 key: "T"
6328 value {
6329 type: DT_INT64
6330 }
6331 }
6332 }
6333 node_def {
6334 name: "ShuffleDataset/seed"
6335 op: "Const"
6336 attr {
6337 key: "dtype"
6338 value {
6339 type: DT_INT64
6340 }
6341 }
6342 attr {
6343 key: "value"
6344 value {
6345 tensor {
6346 dtype: DT_INT64
6347 tensor_shape {
6348 }
6349 int64_val: 0
6350 }
6351 }
6352 }
6353 }
6354 node_def {
6355 name: "ShuffleDataset/seed2"
6356 op: "Const"
6357 attr {
6358 key: "dtype"
6359 value {
6360 type: DT_INT64
6361 }
6362 }
6363 attr {
6364 key: "value"
6365 value {
6366 tensor {
6367 dtype: DT_INT64
6368 tensor_shape {
6369 }
6370 int64_val: 0
6371 }
6372 }
6373 }
6374 }
6375 node_def {
6376 name: "ShuffleDataset"
6377 op: "ShuffleDataset"
6378 input: "TensorSliceDataset:handle:0"
6379 input: "ShuffleDataset/Maximum:z:0"
6380 input: "ShuffleDataset/seed:output:0"
6381 input: "ShuffleDataset/seed2:output:0"
6382 attr {
6383 key: "output_shapes"
6384 value {
6385 list {
6386 shape {
6387 }
6388 }
6389 }
6390 }
6391 attr {
6392 key: "output_types"
6393 value {
6394 list {
6395 type: DT_STRING
6396 }
6397 }
6398 }
6399 attr {
6400 key: "reshuffle_each_iteration"
6401 value {
6402 b: true
6403 }
6404 }
6405 }
6406 node_def {
6407 name: "ShuffleDataset_1/buffer_size"
6408 op: "Const"
6409 attr {
6410 key: "dtype"
6411 value {
6412 type: DT_INT64
6413 }
6414 }
6415 attr {
6416 key: "value"
6417 value {
6418 tensor {
6419 dtype: DT_INT64
6420 tensor_shape {
6421 }
6422 int64_val: 1024
6423 }
6424 }
6425 }
6426 }
6427 node_def {
6428 name: "ShuffleDataset_1/seed_1"
6429 op: "Const"
6430 attr {
6431 key: "dtype"
6432 value {
6433 type: DT_INT64
6434 }
6435 }
6436 attr {
6437 key: "value"
6438 value {
6439 tensor {
6440 dtype: DT_INT64
6441 tensor_shape {
6442 }
6443 int64_val: 0
6444 }
6445 }
6446 }
6447 }
6448 node_def {
6449 name: "ShuffleDataset_1/seed2_1"
6450 op: "Const"
6451 attr {
6452 key: "dtype"
6453 value {
6454 type: DT_INT64
6455 }
6456 }
6457 attr {
6458 key: "value"
6459 value {
6460 tensor {
6461 dtype: DT_INT64
6462 tensor_shape {
6463 }
6464 int64_val: 0
6465 }
6466 }
6467 }
6468 }
6469 node_def {
6470 name: "ShuffleDataset_1"
6471 op: "ShuffleDataset"
6472 input: "ShuffleDataset:handle:0"
6473 input: "ShuffleDataset_1/buffer_size:output:0"
6474 input: "ShuffleDataset_1/seed_1:output:0"
6475 input: "ShuffleDataset_1/seed2_1:output:0"
6476 attr {
6477 key: "output_shapes"
6478 value {
6479 list {
6480 shape {
6481 }
6482 }
6483 }
6484 }
6485 attr {
6486 key: "output_types"
6487 value {
6488 list {
6489 type: DT_STRING
6490 }
6491 }
6492 }
6493 attr {
6494 key: "reshuffle_each_iteration"
6495 value {
6496 b: true
6497 }
6498 }
6499 }
6500 node_def {
6501 name: "RepeatDataset/count"
6502 op: "Const"
6503 attr {
6504 key: "dtype"
6505 value {
6506 type: DT_INT64
6507 }
6508 }
6509 attr {
6510 key: "value"
6511 value {
6512 tensor {
6513 dtype: DT_INT64
6514 tensor_shape {
6515 }
6516 int64_val: -1
6517 }
6518 }
6519 }
6520 }
6521 node_def {
6522 name: "RepeatDataset"
6523 op: "RepeatDataset"
6524 input: "ShuffleDataset_1:handle:0"
6525 input: "RepeatDataset/count:output:0"
6526 attr {
6527 key: "output_shapes"
6528 value {
6529 list {
6530 shape {
6531 }
6532 }
6533 }
6534 }
6535 attr {
6536 key: "output_types"
6537 value {
6538 list {
6539 type: DT_STRING
6540 }
6541 }
6542 }
6543 }
6544 node_def {
6545 name: "ExperimentalParallelInterleaveDataset/cycle_length"
6546 op: "Const"
6547 attr {
6548 key: "dtype"
6549 value {
6550 type: DT_INT64
6551 }
6552 }
6553 attr {
6554 key: "value"
6555 value {
6556 tensor {
6557 dtype: DT_INT64
6558 tensor_shape {
6559 }
6560 int64_val: 8
6561 }
6562 }
6563 }
6564 }
6565 node_def {
6566 name: "ExperimentalParallelInterleaveDataset/block_length"
6567 op: "Const"
6568 attr {
6569 key: "dtype"
6570 value {
6571 type: DT_INT64
6572 }
6573 }
6574 attr {
6575 key: "value"
6576 value {
6577 tensor {
6578 dtype: DT_INT64
6579 tensor_shape {
6580 }
6581 int64_val: 1
6582 }
6583 }
6584 }
6585 }
6586 node_def {
6587 name: "ExperimentalParallelInterleaveDataset/sloppy"
6588 op: "Const"
6589 attr {
6590 key: "dtype"
6591 value {
6592 type: DT_BOOL
6593 }
6594 }
6595 attr {
6596 key: "value"
6597 value {
6598 tensor {
6599 dtype: DT_BOOL
6600 tensor_shape {
6601 }
6602 bool_val: true
6603 }
6604 }
6605 }
6606 }
6607 node_def {
6608 name: "ExperimentalParallelInterleaveDataset/buffer_output_elements"
6609 op: "Const"
6610 attr {
6611 key: "dtype"
6612 value {
6613 type: DT_INT64
6614 }
6615 }
6616 attr {
6617 key: "value"
6618 value {
6619 tensor {
6620 dtype: DT_INT64
6621 tensor_shape {
6622 }
6623 int64_val: 2
6624 }
6625 }
6626 }
6627 }
6628 node_def {
6629 name: "ExperimentalParallelInterleaveDataset/prefetch_input_elements"
6630 op: "Const"
6631 attr {
6632 key: "dtype"
6633 value {
6634 type: DT_INT64
6635 }
6636 }
6637 attr {
6638 key: "value"
6639 value {
6640 tensor {
6641 dtype: DT_INT64
6642 tensor_shape {
6643 }
6644 int64_val: 16
6645 }
6646 }
6647 }
6648 }
6649 node_def {
6650 name: "ExperimentalParallelInterleaveDataset"
6651 op: "ExperimentalParallelInterleaveDataset"
6652 input: "RepeatDataset:handle:0"
6653 input: "ExperimentalParallelInterleaveDataset/cycle_length:output:0"
6654 input: "ExperimentalParallelInterleaveDataset/block_length:output:0"
6655 input: "ExperimentalParallelInterleaveDataset/sloppy:output:0"
6656 input: "ExperimentalParallelInterleaveDataset/buffer_output_elements:output:0"
6657 input: "ExperimentalParallelInterleaveDataset/prefetch_input_elements:output:0"
6658 attr {
6659 key: "Targuments"
6660 value {
6661 list {
6662 }
6663 }
6664 }
6665 attr {
6666 key: "f"
6667 value {
6668 func {
6669 name: "tf_map_func_91295dea"
6670 }
6671 }
6672 }
6673 attr {
6674 key: "output_shapes"
6675 value {
6676 list {
6677 shape {
6678 }
6679 }
6680 }
6681 }
6682 attr {
6683 key: "output_types"
6684 value {
6685 list {
6686 type: DT_STRING
6687 }
6688 }
6689 }
6690 }
6691 node_def {
6692 name: "ShuffleDataset_2/buffer_size_1"
6693 op: "Const"
6694 attr {
6695 key: "dtype"
6696 value {
6697 type: DT_INT64
6698 }
6699 }
6700 attr {
6701 key: "value"
6702 value {
6703 tensor {
6704 dtype: DT_INT64
6705 tensor_shape {
6706 }
6707 int64_val: 1024
6708 }
6709 }
6710 }
6711 }
6712 node_def {
6713 name: "ShuffleDataset_2/seed_2"
6714 op: "Const"
6715 attr {
6716 key: "dtype"
6717 value {
6718 type: DT_INT64
6719 }
6720 }
6721 attr {
6722 key: "value"
6723 value {
6724 tensor {
6725 dtype: DT_INT64
6726 tensor_shape {
6727 }
6728 int64_val: 0
6729 }
6730 }
6731 }
6732 }
6733 node_def {
6734 name: "ShuffleDataset_2/seed2_2"
6735 op: "Const"
6736 attr {
6737 key: "dtype"
6738 value {
6739 type: DT_INT64
6740 }
6741 }
6742 attr {
6743 key: "value"
6744 value {
6745 tensor {
6746 dtype: DT_INT64
6747 tensor_shape {
6748 }
6749 int64_val: 0
6750 }
6751 }
6752 }
6753 }
6754 node_def {
6755 name: "ShuffleDataset_2"
6756 op: "ShuffleDataset"
6757 input: "ExperimentalParallelInterleaveDataset:handle:0"
6758 input: "ShuffleDataset_2/buffer_size_1:output:0"
6759 input: "ShuffleDataset_2/seed_2:output:0"
6760 input: "ShuffleDataset_2/seed2_2:output:0"
6761 attr {
6762 key: "output_shapes"
6763 value {
6764 list {
6765 shape {
6766 }
6767 }
6768 }
6769 }
6770 attr {
6771 key: "output_types"
6772 value {
6773 list {
6774 type: DT_STRING
6775 }
6776 }
6777 }
6778 attr {
6779 key: "reshuffle_each_iteration"
6780 value {
6781 b: true
6782 }
6783 }
6784 }
6785 node_def {
6786 name: "ParallelMapDataset/num_parallel_calls"
6787 op: "Const"
6788 attr {
6789 key: "dtype"
6790 value {
6791 type: DT_INT32
6792 }
6793 }
6794 attr {
6795 key: "value"
6796 value {
6797 tensor {
6798 dtype: DT_INT32
6799 tensor_shape {
6800 }
6801 int_val: 64
6802 }
6803 }
6804 }
6805 }
6806 node_def {
6807 name: "ParallelMapDataset"
6808 op: "ParallelMapDataset"
6809 input: "ShuffleDataset_2:handle:0"
6810 input: "ParallelMapDataset/num_parallel_calls:output:0"
6811 attr {
6812 key: "Targuments"
6813 value {
6814 list {
6815 }
6816 }
6817 }
6818 attr {
6819 key: "f"
6820 value {
6821 func {
6822 name: "tf_map_func_74b6b15c"
6823 }
6824 }
6825 }
6826 attr {
6827 key: "output_shapes"
6828 value {
6829 list {
6830 shape {
6831 dim {
6832 size: 224
6833 }
6834 dim {
6835 size: 224
6836 }
6837 dim {
6838 size: 3
6839 }
6840 }
6841 shape {
6842 }
6843 }
6844 }
6845 }
6846 attr {
6847 key: "output_types"
6848 value {
6849 list {
6850 type: DT_FLOAT
6851 type: DT_INT32
6852 }
6853 }
6854 }
6855 }
6856 node_def {
6857 name: "PrefetchDataset/buffer_size_2"
6858 op: "Const"
6859 attr {
6860 key: "dtype"
6861 value {
6862 type: DT_INT64
6863 }
6864 }
6865 attr {
6866 key: "value"
6867 value {
6868 tensor {
6869 dtype: DT_INT64
6870 tensor_shape {
6871 }
6872 int64_val: 64
6873 }
6874 }
6875 }
6876 }
6877 node_def {
6878 name: "PrefetchDataset"
6879 op: "PrefetchDataset"
6880 input: "ParallelMapDataset:handle:0"
6881 input: "PrefetchDataset/buffer_size_2:output:0"
6882 attr {
6883 key: "output_shapes"
6884 value {
6885 list {
6886 shape {
6887 dim {
6888 size: 224
6889 }
6890 dim {
6891 size: 224
6892 }
6893 dim {
6894 size: 3
6895 }
6896 }
6897 shape {
6898 }
6899 }
6900 }
6901 }
6902 attr {
6903 key: "output_types"
6904 value {
6905 list {
6906 type: DT_FLOAT
6907 type: DT_INT32
6908 }
6909 }
6910 }
6911 }
6912 node_def {
6913 name: "BatchDataset/batch_size"
6914 op: "Const"
6915 attr {
6916 key: "dtype"
6917 value {
6918 type: DT_INT64
6919 }
6920 }
6921 attr {
6922 key: "value"
6923 value {
6924 tensor {
6925 dtype: DT_INT64
6926 tensor_shape {
6927 }
6928 int64_val: 64
6929 }
6930 }
6931 }
6932 }
6933 node_def {
6934 name: "BatchDataset"
6935 op: "BatchDataset"
6936 input: "PrefetchDataset:handle:0"
6937 input: "BatchDataset/batch_size:output:0"
6938 attr {
6939 key: "output_shapes"
6940 value {
6941 list {
6942 shape {
6943 dim {
6944 size: -1
6945 }
6946 dim {
6947 size: 224
6948 }
6949 dim {
6950 size: 224
6951 }
6952 dim {
6953 size: 3
6954 }
6955 }
6956 shape {
6957 dim {
6958 size: -1
6959 }
6960 }
6961 }
6962 }
6963 }
6964 attr {
6965 key: "output_types"
6966 value {
6967 list {
6968 type: DT_FLOAT
6969 type: DT_INT32
6970 }
6971 }
6972 }
6973 }
6974 node_def {
6975 name: "FilterDataset/batch_size_1"
6976 op: "Const"
6977 attr {
6978 key: "dtype"
6979 value {
6980 type: DT_INT64
6981 }
6982 }
6983 attr {
6984 key: "value"
6985 value {
6986 tensor {
6987 dtype: DT_INT64
6988 tensor_shape {
6989 }
6990 int64_val: 64
6991 }
6992 }
6993 }
6994 }
6995 node_def {
6996 name: "FilterDataset"
6997 op: "FilterDataset"
6998 input: "BatchDataset:handle:0"
6999 input: "FilterDataset/batch_size_1:output:0"
7000 attr {
7001 key: "Targuments"
7002 value {
7003 list {
7004 type: DT_INT64
7005 }
7006 }
7007 }
7008 attr {
7009 key: "output_shapes"
7010 value {
7011 list {
7012 shape {
7013 dim {
7014 size: -1
7015 }
7016 dim {
7017 size: 224
7018 }
7019 dim {
7020 size: 224
7021 }
7022 dim {
7023 size: 3
7024 }
7025 }
7026 shape {
7027 dim {
7028 size: -1
7029 }
7030 }
7031 }
7032 }
7033 }
7034 attr {
7035 key: "output_types"
7036 value {
7037 list {
7038 type: DT_FLOAT
7039 type: DT_INT32
7040 }
7041 }
7042 }
7043 attr {
7044 key: "predicate"
7045 value {
7046 func {
7047 name: "tf_predicate_7089b845"
7048 }
7049 }
7050 }
7051 }
7052 node_def {
7053 name: "PrefetchDataset_1/buffer_size_3"
7054 op: "Const"
7055 attr {
7056 key: "dtype"
7057 value {
7058 type: DT_INT64
7059 }
7060 }
7061 attr {
7062 key: "value"
7063 value {
7064 tensor {
7065 dtype: DT_INT64
7066 tensor_shape {
7067 }
7068 int64_val: 2
7069 }
7070 }
7071 }
7072 }
7073 node_def {
7074 name: "PrefetchDataset_1"
7075 op: "PrefetchDataset"
7076 input: "FilterDataset:handle:0"
7077 input: "PrefetchDataset_1/buffer_size_3:output:0"
7078 attr {
7079 key: "output_shapes"
7080 value {
7081 list {
7082 shape {
7083 dim {
7084 size: 64
7085 }
7086 dim {
7087 size: 224
7088 }
7089 dim {
7090 size: 224
7091 }
7092 dim {
7093 size: 3
7094 }
7095 }
7096 shape {
7097 dim {
7098 size: 64
7099 }
7100 }
7101 }
7102 }
7103 }
7104 attr {
7105 key: "output_types"
7106 value {
7107 list {
7108 type: DT_FLOAT
7109 type: DT_INT32
7110 }
7111 }
7112 }
7113 }
7114 ret {
7115 key: "PrefetchDataset_1"
7116 value: "PrefetchDataset_1:handle:0"
7117 }
7118 }
7119 }
7120 )PREFIX";
7121
7122 *dataset_name = "_make_dataset_5fa5e1f4";
7123 std::function<void(FunctionDef*)> mutate_proto_func =
7124 [dataset_name, file_path](FunctionDef* fdef) {
7125 VLOG(1) << "Processsing function " << fdef->DebugString();
7126 if (std::string(fdef->signature().name()) != *dataset_name) return;
7127 // Change the input file pattern to `file_path`.
7128 bool found = false;
7129 for (auto& node_def : *fdef->mutable_node_def()) {
7130 if (node_def.name() != "TensorSliceDataset/MatchingFiles/pattern" &&
7131 node_def.name() != "ShuffleDataset/MatchingFiles/pattern")
7132 continue;
7133 DCHECK_EQ(node_def.op(), "Const");
7134 DCHECK_GT(node_def.attr().count("value"), 0);
7135 found = true;
7136 DCHECK_EQ(node_def.attr().at("value").tensor().string_val(0),
7137 "$(DATA_DIR)");
7138 VLOG(1) << "Setting the value of node_def "
7139 "TensorSliceDataset/MatchingFiles/pattern to "
7140 << file_path;
7141 auto* tensor = (*node_def.mutable_attr())["value"].mutable_tensor();
7142 tensor->clear_string_val();
7143 tensor->add_string_val(file_path);
7144 }
7145 VLOG(1) << "Rewrote function to " << fdef->DebugString();
7146 DCHECK(found);
7147 };
7148 return CreateFunctionsFromTextProto(func_def, &mutate_proto_func, status);
7149 #endif
7150 }
7151 #endif
7152
7153 #if not defined(PLATFORM_WINDOWS)
7154 // On success, returns a set of TF_Function instances encoding a dataset
7155 // node stack that reads an MNIST file dataset from `file_path`, and
7156 // sets `dataset_name` to the created dataset name. The returned functions must
7157 // be deleted by calling TF_DeleteFunction.
CreateMNISTDatasetFunctions(const char * file_path,int batch_size,std::string * dataset_name,TF_Status * status)7158 static std::vector<UniqueFuncPtr> CreateMNISTDatasetFunctions(
7159 const char* file_path, int batch_size, std::string* dataset_name,
7160 TF_Status* status) {
7161 #if defined(PLATFORM_WINDOWS)
7162 status->status = tensorflow::errors::Unimplemented(
7163 "TF_MakeFileBasedIteratorGetNextWithDatasets in the experimental C API "
7164 "is not implemented for Windows");
7165 return nullptr;
7166 #else
7167 const char* func_def = R"PREFIX(
7168 library {
7169 function {
7170 signature {
7171 name: "tf_map_func_521bfd08"
7172 input_arg {
7173 name: "arg0"
7174 type: DT_STRING
7175 }
7176 output_arg {
7177 name: "truediv"
7178 type: DT_FLOAT
7179 }
7180 description: "A wrapper for Defun that facilitates shape inference."
7181 }
7182 node_def {
7183 name: "DecodeRaw"
7184 op: "DecodeRaw"
7185 input: "arg0"
7186 attr {
7187 key: "little_endian"
7188 value {
7189 b: true
7190 }
7191 }
7192 attr {
7193 key: "out_type"
7194 value {
7195 type: DT_UINT8
7196 }
7197 }
7198 }
7199 node_def {
7200 name: "Cast"
7201 op: "Cast"
7202 input: "DecodeRaw:output:0"
7203 attr {
7204 key: "DstT"
7205 value {
7206 type: DT_FLOAT
7207 }
7208 }
7209 attr {
7210 key: "SrcT"
7211 value {
7212 type: DT_UINT8
7213 }
7214 }
7215 }
7216 node_def {
7217 name: "Reshape/shape"
7218 op: "Const"
7219 attr {
7220 key: "dtype"
7221 value {
7222 type: DT_INT32
7223 }
7224 }
7225 attr {
7226 key: "value"
7227 value {
7228 tensor {
7229 dtype: DT_INT32
7230 tensor_shape {
7231 dim {
7232 size: 1
7233 }
7234 }
7235 int_val: 784
7236 }
7237 }
7238 }
7239 }
7240 node_def {
7241 name: "Reshape"
7242 op: "Reshape"
7243 input: "Cast:y:0"
7244 input: "Reshape/shape:output:0"
7245 attr {
7246 key: "T"
7247 value {
7248 type: DT_FLOAT
7249 }
7250 }
7251 attr {
7252 key: "Tshape"
7253 value {
7254 type: DT_INT32
7255 }
7256 }
7257 }
7258 node_def {
7259 name: "truediv/y"
7260 op: "Const"
7261 attr {
7262 key: "dtype"
7263 value {
7264 type: DT_FLOAT
7265 }
7266 }
7267 attr {
7268 key: "value"
7269 value {
7270 tensor {
7271 dtype: DT_FLOAT
7272 tensor_shape {
7273 }
7274 float_val: 255.0
7275 }
7276 }
7277 }
7278 }
7279 node_def {
7280 name: "truediv"
7281 op: "RealDiv"
7282 input: "Reshape:output:0"
7283 input: "truediv/y:output:0"
7284 attr {
7285 key: "T"
7286 value {
7287 type: DT_FLOAT
7288 }
7289 }
7290 }
7291 ret {
7292 key: "truediv"
7293 value: "truediv:z:0"
7294 }
7295 }
7296 function {
7297 signature {
7298 name: "tf_map_func_9a08860d"
7299 input_arg {
7300 name: "arg0"
7301 type: DT_STRING
7302 }
7303 output_arg {
7304 name: "ToInt32"
7305 type: DT_INT32
7306 }
7307 description: "A wrapper for Defun that facilitates shape inference."
7308 }
7309 node_def {
7310 name: "DecodeRaw"
7311 op: "DecodeRaw"
7312 input: "arg0"
7313 attr {
7314 key: "little_endian"
7315 value {
7316 b: true
7317 }
7318 }
7319 attr {
7320 key: "out_type"
7321 value {
7322 type: DT_UINT8
7323 }
7324 }
7325 }
7326 node_def {
7327 name: "Reshape/shape"
7328 op: "Const"
7329 attr {
7330 key: "dtype"
7331 value {
7332 type: DT_INT32
7333 }
7334 }
7335 attr {
7336 key: "value"
7337 value {
7338 tensor {
7339 dtype: DT_INT32
7340 tensor_shape {
7341 dim {
7342 }
7343 }
7344 }
7345 }
7346 }
7347 }
7348 node_def {
7349 name: "Reshape"
7350 op: "Reshape"
7351 input: "DecodeRaw:output:0"
7352 input: "Reshape/shape:output:0"
7353 attr {
7354 key: "T"
7355 value {
7356 type: DT_UINT8
7357 }
7358 }
7359 attr {
7360 key: "Tshape"
7361 value {
7362 type: DT_INT32
7363 }
7364 }
7365 }
7366 node_def {
7367 name: "ToInt32"
7368 op: "Cast"
7369 input: "Reshape:output:0"
7370 attr {
7371 key: "DstT"
7372 value {
7373 type: DT_INT32
7374 }
7375 }
7376 attr {
7377 key: "SrcT"
7378 value {
7379 type: DT_UINT8
7380 }
7381 }
7382 }
7383 ret {
7384 key: "ToInt32"
7385 value: "ToInt32:y:0"
7386 }
7387 }
7388 function {
7389 signature {
7390 name: "tf_predicate_7089b845"
7391 input_arg {
7392 name: "arg0"
7393 type: DT_FLOAT
7394 }
7395 input_arg {
7396 name: "arg1"
7397 type: DT_INT32
7398 }
7399 input_arg {
7400 name: "Equal/Placeholder"
7401 type: DT_INT64
7402 }
7403 output_arg {
7404 name: "Equal"
7405 type: DT_BOOL
7406 }
7407 description: "A wrapper for Defun that facilitates shape inference."
7408 }
7409 node_def {
7410 name: "Shape"
7411 op: "Shape"
7412 input: "arg0"
7413 attr {
7414 key: "T"
7415 value {
7416 type: DT_FLOAT
7417 }
7418 }
7419 attr {
7420 key: "out_type"
7421 value {
7422 type: DT_INT64
7423 }
7424 }
7425 }
7426 node_def {
7427 name: "strided_slice/stack"
7428 op: "Const"
7429 attr {
7430 key: "dtype"
7431 value {
7432 type: DT_INT32
7433 }
7434 }
7435 attr {
7436 key: "value"
7437 value {
7438 tensor {
7439 dtype: DT_INT32
7440 tensor_shape {
7441 dim {
7442 size: 1
7443 }
7444 }
7445 int_val: 0
7446 }
7447 }
7448 }
7449 }
7450 node_def {
7451 name: "strided_slice/stack_1"
7452 op: "Const"
7453 attr {
7454 key: "dtype"
7455 value {
7456 type: DT_INT32
7457 }
7458 }
7459 attr {
7460 key: "value"
7461 value {
7462 tensor {
7463 dtype: DT_INT32
7464 tensor_shape {
7465 dim {
7466 size: 1
7467 }
7468 }
7469 int_val: 1
7470 }
7471 }
7472 }
7473 }
7474 node_def {
7475 name: "strided_slice/stack_2"
7476 op: "Const"
7477 attr {
7478 key: "dtype"
7479 value {
7480 type: DT_INT32
7481 }
7482 }
7483 attr {
7484 key: "value"
7485 value {
7486 tensor {
7487 dtype: DT_INT32
7488 tensor_shape {
7489 dim {
7490 size: 1
7491 }
7492 }
7493 int_val: 1
7494 }
7495 }
7496 }
7497 }
7498 node_def {
7499 name: "strided_slice"
7500 op: "StridedSlice"
7501 input: "Shape:output:0"
7502 input: "strided_slice/stack:output:0"
7503 input: "strided_slice/stack_1:output:0"
7504 input: "strided_slice/stack_2:output:0"
7505 attr {
7506 key: "Index"
7507 value {
7508 type: DT_INT32
7509 }
7510 }
7511 attr {
7512 key: "T"
7513 value {
7514 type: DT_INT64
7515 }
7516 }
7517 attr {
7518 key: "begin_mask"
7519 value {
7520 i: 0
7521 }
7522 }
7523 attr {
7524 key: "ellipsis_mask"
7525 value {
7526 i: 0
7527 }
7528 }
7529 attr {
7530 key: "end_mask"
7531 value {
7532 i: 0
7533 }
7534 }
7535 attr {
7536 key: "new_axis_mask"
7537 value {
7538 i: 0
7539 }
7540 }
7541 attr {
7542 key: "shrink_axis_mask"
7543 value {
7544 i: 1
7545 }
7546 }
7547 }
7548 node_def {
7549 name: "Equal"
7550 op: "Equal"
7551 input: "strided_slice:output:0"
7552 input: "Equal/Placeholder"
7553 attr {
7554 key: "T"
7555 value {
7556 type: DT_INT64
7557 }
7558 }
7559 }
7560 ret {
7561 key: "Equal"
7562 value: "Equal:z:0"
7563 }
7564 }
7565 function {
7566 signature {
7567 name: "_make_dataset_2451e43a"
7568 output_arg {
7569 name: "FilterDataset"
7570 type: DT_VARIANT
7571 }
7572 is_stateful: true
7573 }
7574 node_def {
7575 name: "FixedLengthRecordDataset/filenames"
7576 op: "Const"
7577 attr {
7578 key: "dtype"
7579 value {
7580 type: DT_STRING
7581 }
7582 }
7583 attr {
7584 key: "value"
7585 value {
7586 tensor {
7587 dtype: DT_STRING
7588 tensor_shape {
7589 }
7590 string_val: "$(DATA_DIR)/train-images-idx3-ubyte"
7591 }
7592 }
7593 }
7594 }
7595 node_def {
7596 name: "FixedLengthRecordDataset/header_bytes"
7597 op: "Const"
7598 attr {
7599 key: "dtype"
7600 value {
7601 type: DT_INT64
7602 }
7603 }
7604 attr {
7605 key: "value"
7606 value {
7607 tensor {
7608 dtype: DT_INT64
7609 tensor_shape {
7610 }
7611 int64_val: 16
7612 }
7613 }
7614 }
7615 }
7616 node_def {
7617 name: "FixedLengthRecordDataset/record_bytes"
7618 op: "Const"
7619 attr {
7620 key: "dtype"
7621 value {
7622 type: DT_INT64
7623 }
7624 }
7625 attr {
7626 key: "value"
7627 value {
7628 tensor {
7629 dtype: DT_INT64
7630 tensor_shape {
7631 }
7632 int64_val: 784
7633 }
7634 }
7635 }
7636 }
7637 node_def {
7638 name: "FixedLengthRecordDataset/footer_bytes"
7639 op: "Const"
7640 attr {
7641 key: "dtype"
7642 value {
7643 type: DT_INT64
7644 }
7645 }
7646 attr {
7647 key: "value"
7648 value {
7649 tensor {
7650 dtype: DT_INT64
7651 tensor_shape {
7652 }
7653 int64_val: 0
7654 }
7655 }
7656 }
7657 }
7658 node_def {
7659 name: "FixedLengthRecordDataset/buffer_size"
7660 op: "Const"
7661 attr {
7662 key: "dtype"
7663 value {
7664 type: DT_INT64
7665 }
7666 }
7667 attr {
7668 key: "value"
7669 value {
7670 tensor {
7671 dtype: DT_INT64
7672 tensor_shape {
7673 }
7674 int64_val: 262144
7675 }
7676 }
7677 }
7678 }
7679 node_def {
7680 name: "FixedLengthRecordDataset"
7681 op: "FixedLengthRecordDataset"
7682 input: "FixedLengthRecordDataset/filenames:output:0"
7683 input: "FixedLengthRecordDataset/header_bytes:output:0"
7684 input: "FixedLengthRecordDataset/record_bytes:output:0"
7685 input: "FixedLengthRecordDataset/footer_bytes:output:0"
7686 input: "FixedLengthRecordDataset/buffer_size:output:0"
7687 }
7688 node_def {
7689 name: "MapDataset"
7690 op: "MapDataset"
7691 input: "FixedLengthRecordDataset:handle:0"
7692 attr {
7693 key: "Targuments"
7694 value {
7695 list {
7696 }
7697 }
7698 }
7699 attr {
7700 key: "f"
7701 value {
7702 func {
7703 name: "tf_map_func_521bfd08"
7704 }
7705 }
7706 }
7707 attr {
7708 key: "output_shapes"
7709 value {
7710 list {
7711 shape {
7712 dim {
7713 size: 784
7714 }
7715 }
7716 }
7717 }
7718 }
7719 attr {
7720 key: "output_types"
7721 value {
7722 list {
7723 type: DT_FLOAT
7724 }
7725 }
7726 }
7727 }
7728 node_def {
7729 name: "FixedLengthRecordDataset_1/filenames_1"
7730 op: "Const"
7731 attr {
7732 key: "dtype"
7733 value {
7734 type: DT_STRING
7735 }
7736 }
7737 attr {
7738 key: "value"
7739 value {
7740 tensor {
7741 dtype: DT_STRING
7742 tensor_shape {
7743 }
7744 string_val: "$(DATA_DIR)/train-labels-idx1-ubyte"
7745 }
7746 }
7747 }
7748 }
7749 node_def {
7750 name: "FixedLengthRecordDataset_1/header_bytes_1"
7751 op: "Const"
7752 attr {
7753 key: "dtype"
7754 value {
7755 type: DT_INT64
7756 }
7757 }
7758 attr {
7759 key: "value"
7760 value {
7761 tensor {
7762 dtype: DT_INT64
7763 tensor_shape {
7764 }
7765 int64_val: 8
7766 }
7767 }
7768 }
7769 }
7770 node_def {
7771 name: "FixedLengthRecordDataset_1/record_bytes_1"
7772 op: "Const"
7773 attr {
7774 key: "dtype"
7775 value {
7776 type: DT_INT64
7777 }
7778 }
7779 attr {
7780 key: "value"
7781 value {
7782 tensor {
7783 dtype: DT_INT64
7784 tensor_shape {
7785 }
7786 int64_val: 1
7787 }
7788 }
7789 }
7790 }
7791 node_def {
7792 name: "FixedLengthRecordDataset_1/footer_bytes_1"
7793 op: "Const"
7794 attr {
7795 key: "dtype"
7796 value {
7797 type: DT_INT64
7798 }
7799 }
7800 attr {
7801 key: "value"
7802 value {
7803 tensor {
7804 dtype: DT_INT64
7805 tensor_shape {
7806 }
7807 int64_val: 0
7808 }
7809 }
7810 }
7811 }
7812 node_def {
7813 name: "FixedLengthRecordDataset_1/buffer_size_1"
7814 op: "Const"
7815 attr {
7816 key: "dtype"
7817 value {
7818 type: DT_INT64
7819 }
7820 }
7821 attr {
7822 key: "value"
7823 value {
7824 tensor {
7825 dtype: DT_INT64
7826 tensor_shape {
7827 }
7828 int64_val: 262144
7829 }
7830 }
7831 }
7832 }
7833 node_def {
7834 name: "FixedLengthRecordDataset_1"
7835 op: "FixedLengthRecordDataset"
7836 input: "FixedLengthRecordDataset_1/filenames_1:output:0"
7837 input: "FixedLengthRecordDataset_1/header_bytes_1:output:0"
7838 input: "FixedLengthRecordDataset_1/record_bytes_1:output:0"
7839 input: "FixedLengthRecordDataset_1/footer_bytes_1:output:0"
7840 input: "FixedLengthRecordDataset_1/buffer_size_1:output:0"
7841 }
7842 node_def {
7843 name: "MapDataset_1"
7844 op: "MapDataset"
7845 input: "FixedLengthRecordDataset_1:handle:0"
7846 attr {
7847 key: "Targuments"
7848 value {
7849 list {
7850 }
7851 }
7852 }
7853 attr {
7854 key: "f"
7855 value {
7856 func {
7857 name: "tf_map_func_9a08860d"
7858 }
7859 }
7860 }
7861 attr {
7862 key: "output_shapes"
7863 value {
7864 list {
7865 shape {
7866 }
7867 }
7868 }
7869 }
7870 attr {
7871 key: "output_types"
7872 value {
7873 list {
7874 type: DT_INT32
7875 }
7876 }
7877 }
7878 }
7879 node_def {
7880 name: "ZipDataset"
7881 op: "ZipDataset"
7882 input: "MapDataset:handle:0"
7883 input: "MapDataset_1:handle:0"
7884 attr {
7885 key: "N"
7886 value {
7887 i: 2
7888 }
7889 }
7890 attr {
7891 key: "output_shapes"
7892 value {
7893 list {
7894 shape {
7895 dim {
7896 size: 784
7897 }
7898 }
7899 shape {
7900 }
7901 }
7902 }
7903 }
7904 attr {
7905 key: "output_types"
7906 value {
7907 list {
7908 type: DT_FLOAT
7909 type: DT_INT32
7910 }
7911 }
7912 }
7913 }
7914 node_def {
7915 name: "CacheDataset/filename"
7916 op: "Const"
7917 attr {
7918 key: "dtype"
7919 value {
7920 type: DT_STRING
7921 }
7922 }
7923 attr {
7924 key: "value"
7925 value {
7926 tensor {
7927 dtype: DT_STRING
7928 tensor_shape {
7929 }
7930 string_val: ""
7931 }
7932 }
7933 }
7934 }
7935 node_def {
7936 name: "CacheDataset"
7937 op: "CacheDataset"
7938 input: "ZipDataset:handle:0"
7939 input: "CacheDataset/filename:output:0"
7940 attr {
7941 key: "output_shapes"
7942 value {
7943 list {
7944 shape {
7945 dim {
7946 size: 784
7947 }
7948 }
7949 shape {
7950 }
7951 }
7952 }
7953 }
7954 attr {
7955 key: "output_types"
7956 value {
7957 list {
7958 type: DT_FLOAT
7959 type: DT_INT32
7960 }
7961 }
7962 }
7963 }
7964 node_def {
7965 name: "RepeatDataset/count"
7966 op: "Const"
7967 attr {
7968 key: "dtype"
7969 value {
7970 type: DT_INT64
7971 }
7972 }
7973 attr {
7974 key: "value"
7975 value {
7976 tensor {
7977 dtype: DT_INT64
7978 tensor_shape {
7979 }
7980 int64_val: -1
7981 }
7982 }
7983 }
7984 }
7985 node_def {
7986 name: "RepeatDataset"
7987 op: "RepeatDataset"
7988 input: "CacheDataset:handle:0"
7989 input: "RepeatDataset/count:output:0"
7990 attr {
7991 key: "output_shapes"
7992 value {
7993 list {
7994 shape {
7995 dim {
7996 size: 784
7997 }
7998 }
7999 shape {
8000 }
8001 }
8002 }
8003 }
8004 attr {
8005 key: "output_types"
8006 value {
8007 list {
8008 type: DT_FLOAT
8009 type: DT_INT32
8010 }
8011 }
8012 }
8013 }
8014 node_def {
8015 name: "ShuffleDataset/buffer_size_2"
8016 op: "Const"
8017 attr {
8018 key: "dtype"
8019 value {
8020 type: DT_INT64
8021 }
8022 }
8023 attr {
8024 key: "value"
8025 value {
8026 tensor {
8027 dtype: DT_INT64
8028 tensor_shape {
8029 }
8030 int64_val: 50000
8031 }
8032 }
8033 }
8034 }
8035 node_def {
8036 name: "ShuffleDataset/seed"
8037 op: "Const"
8038 attr {
8039 key: "dtype"
8040 value {
8041 type: DT_INT64
8042 }
8043 }
8044 attr {
8045 key: "value"
8046 value {
8047 tensor {
8048 dtype: DT_INT64
8049 tensor_shape {
8050 }
8051 int64_val: 0
8052 }
8053 }
8054 }
8055 }
8056 node_def {
8057 name: "ShuffleDataset/seed2"
8058 op: "Const"
8059 attr {
8060 key: "dtype"
8061 value {
8062 type: DT_INT64
8063 }
8064 }
8065 attr {
8066 key: "value"
8067 value {
8068 tensor {
8069 dtype: DT_INT64
8070 tensor_shape {
8071 }
8072 int64_val: 0
8073 }
8074 }
8075 }
8076 }
8077 node_def {
8078 name: "ShuffleDataset"
8079 op: "ShuffleDataset"
8080 input: "RepeatDataset:handle:0"
8081 input: "ShuffleDataset/buffer_size_2:output:0"
8082 input: "ShuffleDataset/seed:output:0"
8083 input: "ShuffleDataset/seed2:output:0"
8084 attr {
8085 key: "output_shapes"
8086 value {
8087 list {
8088 shape {
8089 dim {
8090 size: 784
8091 }
8092 }
8093 shape {
8094 }
8095 }
8096 }
8097 }
8098 attr {
8099 key: "output_types"
8100 value {
8101 list {
8102 type: DT_FLOAT
8103 type: DT_INT32
8104 }
8105 }
8106 }
8107 attr {
8108 key: "reshuffle_each_iteration"
8109 value {
8110 b: true
8111 }
8112 }
8113 }
8114 node_def {
8115 name: "BatchDataset/batch_size"
8116 op: "Const"
8117 attr {
8118 key: "dtype"
8119 value {
8120 type: DT_INT64
8121 }
8122 }
8123 attr {
8124 key: "value"
8125 value {
8126 tensor {
8127 dtype: DT_INT64
8128 tensor_shape {
8129 }
8130 int64_val: -123
8131 }
8132 }
8133 }
8134 }
8135 node_def {
8136 name: "BatchDataset"
8137 op: "BatchDataset"
8138 input: "ShuffleDataset:handle:0"
8139 input: "BatchDataset/batch_size:output:0"
8140 attr {
8141 key: "output_shapes"
8142 value {
8143 list {
8144 shape {
8145 dim {
8146 size: -1
8147 }
8148 dim {
8149 size: 784
8150 }
8151 }
8152 shape {
8153 dim {
8154 size: -1
8155 }
8156 }
8157 }
8158 }
8159 }
8160 attr {
8161 key: "output_types"
8162 value {
8163 list {
8164 type: DT_FLOAT
8165 type: DT_INT32
8166 }
8167 }
8168 }
8169 }
8170 node_def {
8171 name: "FilterDataset/batch_size_1"
8172 op: "Const"
8173 attr {
8174 key: "dtype"
8175 value {
8176 type: DT_INT64
8177 }
8178 }
8179 attr {
8180 key: "value"
8181 value {
8182 tensor {
8183 dtype: DT_INT64
8184 tensor_shape {
8185 }
8186 int64_val: -123
8187 }
8188 }
8189 }
8190 }
8191 node_def {
8192 name: "FilterDataset"
8193 op: "FilterDataset"
8194 input: "BatchDataset:handle:0"
8195 input: "FilterDataset/batch_size_1:output:0"
8196 attr {
8197 key: "Targuments"
8198 value {
8199 list {
8200 type: DT_INT64
8201 }
8202 }
8203 }
8204 attr {
8205 key: "output_shapes"
8206 value {
8207 list {
8208 shape {
8209 dim {
8210 size: -1
8211 }
8212 dim {
8213 size: 784
8214 }
8215 }
8216 shape {
8217 dim {
8218 size: -1
8219 }
8220 }
8221 }
8222 }
8223 }
8224 attr {
8225 key: "output_types"
8226 value {
8227 list {
8228 type: DT_FLOAT
8229 type: DT_INT32
8230 }
8231 }
8232 }
8233 attr {
8234 key: "predicate"
8235 value {
8236 func {
8237 name: "tf_predicate_7089b845"
8238 }
8239 }
8240 }
8241 }
8242 ret {
8243 key: "FilterDataset"
8244 value: "FilterDataset:handle:0"
8245 }
8246 }
8247 }
8248 )PREFIX";
8249
8250 *dataset_name = "_make_dataset_2451e43a";
8251 std::function<void(FunctionDef*)> mutate_proto_func =
8252 [dataset_name, file_path, batch_size](FunctionDef* fdef) {
8253 VLOG(1) << "Processsing function " << fdef->DebugString();
8254 if (std::string(fdef->signature().name()) != *dataset_name) return;
8255 // Change the input file pattern to `file_path`.
8256 bool found_file_path = false, found_batch_size = false;
8257 // `node_def` may be mutated.
8258 for (auto& node_def : *fdef->mutable_node_def()) {
8259 if (node_def.name() == "FixedLengthRecordDataset/filenames" ||
8260 node_def.name() == "FixedLengthRecordDataset_1/filenames_1") {
8261 DCHECK_EQ(node_def.op(), "Const");
8262 DCHECK_GT(node_def.attr().count("value"), 0);
8263 found_file_path = true;
8264 // Replace $(DATA_DIR)/foo with <file_path>/foo
8265 // TODO(hongm): Use StringPiece manipulation for better efficiency.
8266 const std::string cur_value =
8267 node_def.attr().at("value").tensor().string_val(0);
8268 const std::string pattern = "$(DATA_DIR)";
8269 DCHECK_EQ(cur_value.compare(0, pattern.length(), pattern), 0);
8270 const std::string new_value =
8271 file_path + cur_value.substr(pattern.length());
8272 VLOG(1) << "Setting the value of node_def " << node_def.name()
8273 << " to " << new_value;
8274 auto* tensor = (*node_def.mutable_attr())["value"].mutable_tensor();
8275 tensor->clear_string_val();
8276 tensor->add_string_val(new_value);
8277 } else if (node_def.name() == "BatchDataset/batch_size" ||
8278 node_def.name() == "FilterDataset/batch_size_1") {
8279 DCHECK_EQ(node_def.op(), "Const");
8280 DCHECK_GT(node_def.attr().count("value"), 0);
8281 found_batch_size = true;
8282 // Replace $(BATCH_SIZE) with `batch_size`
8283 DCHECK_EQ(node_def.attr().at("value").tensor().int64_val(0), -123);
8284 VLOG(1) << "Setting the batch size attr value of node_def "
8285 << node_def.name() << " to " << batch_size;
8286 auto* tensor = (*node_def.mutable_attr())["value"].mutable_tensor();
8287 tensor->clear_int64_val();
8288 tensor->add_int64_val(batch_size);
8289 }
8290 }
8291 VLOG(1) << "Rewrote function to " << fdef->DebugString();
8292 DCHECK(found_file_path);
8293 DCHECK(found_batch_size);
8294 };
8295 return CreateFunctionsFromTextProto(func_def, &mutate_proto_func, status);
8296 #endif
8297 }
8298 #endif
8299
8300 // Adds the input functions to `graph`. On success, returns the created
8301 // IteratorGetNext node.
AddDatasetFunctionAndIteratorNodesToGraph(const std::vector<UniqueFuncPtr> & funcs,const std::string & dataset_name,const std::vector<tensorflow::DataType> & output_types,const std::vector<tensorflow::TensorShapeProto> & output_shapes,TF_Graph * graph,TF_Status * status)8302 static TF_Operation* AddDatasetFunctionAndIteratorNodesToGraph(
8303 const std::vector<UniqueFuncPtr>& funcs, const std::string& dataset_name,
8304 const std::vector<tensorflow::DataType>& output_types,
8305 const std::vector<tensorflow::TensorShapeProto>& output_shapes,
8306 TF_Graph* graph, TF_Status* status) {
8307 DCHECK(!dataset_name.empty());
8308 for (auto& func : funcs) {
8309 TF_GraphCopyFunction(graph, func.get(), /*gradient*/ nullptr, status);
8310 if (!status->status.ok()) {
8311 return nullptr;
8312 }
8313 }
8314
8315 tensorflow::mutex_lock c(graph->mu);
8316
8317 tensorflow::NameAttrList func;
8318 func.set_name(dataset_name);
8319 // Run the iterator node on CPU.
8320 Node* oneshot_iterator_node;
8321 tensorflow::Status s = NodeBuilder("OneShotIterator", "OneShotIterator")
8322 .Device("/device:CPU:0")
8323 .Attr("container", "")
8324 .Attr("dataset_factory", func)
8325 .Attr("output_types", output_types)
8326 .Attr("output_shapes", output_shapes)
8327 .Attr("shared_name", "")
8328 .Finalize(&graph->graph, &oneshot_iterator_node);
8329 if (!s.ok()) {
8330 status->status = s;
8331 return nullptr;
8332 }
8333 // Run shape inference function for each newly added node, so that more
8334 // subsequent nodes can be added to the graph via C API (TF_NewOperation()).
8335 s = graph->refiner.AddNode(oneshot_iterator_node);
8336 if (!s.ok()) {
8337 status->status = s;
8338 return nullptr;
8339 }
8340
8341 // Run the iterator node on CPU.
8342 Node* getnext_node;
8343 s = NodeBuilder("IteratorGetNext", "IteratorGetNext")
8344 .Input(oneshot_iterator_node)
8345 .Device("/device:CPU:0")
8346 .Attr("output_types", output_types)
8347 .Attr("output_shapes", output_shapes)
8348 .Finalize(&graph->graph, &getnext_node);
8349 if (!s.ok()) {
8350 status->status = s;
8351 return nullptr;
8352 }
8353 // Run shape inference function for each newly added node, so that more
8354 // subsequent nodes can be added to the graph via C API (TF_NewOperation()).
8355 s = graph->refiner.AddNode(getnext_node);
8356 if (!s.ok()) {
8357 status->status = s;
8358 return nullptr;
8359 }
8360
8361 VLOG(1) << "Output graph: " << graph->graph.ToGraphDefDebug().DebugString();
8362 return ToTF_Operation(getnext_node);
8363 }
8364
TF_MakeFakeIteratorGetNextWithDatasets(TF_Graph * graph,TF_Status * status)8365 TF_Operation* TF_MakeFakeIteratorGetNextWithDatasets(TF_Graph* graph,
8366 TF_Status* status) {
8367 tensorflow::Status s;
8368
8369 std::string dataset_name;
8370 UniqueFuncPtr result_func = CreateFakeDatasetFunction(&dataset_name, status);
8371 if (!status->status.ok()) {
8372 return nullptr;
8373 }
8374
8375 std::vector<UniqueFuncPtr> funcs;
8376 funcs.push_back(std::move(result_func));
8377 std::vector<tensorflow::TensorShapeProto> output_shape_list;
8378 output_shape_list.push_back(tensorflow::TensorShapeProto());
8379 auto* getnext_node = AddDatasetFunctionAndIteratorNodesToGraph(
8380 funcs, dataset_name, {tensorflow::DT_FLOAT}, output_shape_list, graph,
8381 status);
8382 if (!status->status.ok()) {
8383 return nullptr;
8384 }
8385
8386 return getnext_node;
8387 }
8388
TF_MakeFileBasedIteratorGetNextWithDatasets(TF_Graph * graph,const char * file_path,int batch_size,unsigned char is_mnist,TF_Status * status)8389 TF_Operation* TF_MakeFileBasedIteratorGetNextWithDatasets(
8390 TF_Graph* graph, const char* file_path, int batch_size,
8391 unsigned char is_mnist, TF_Status* status) {
8392 #if defined(PLATFORM_WINDOWS)
8393 // TODO(ashankar): get these functions working on Windows.
8394 status->status = tensorflow::errors::Unimplemented(
8395 "TF_MakeFileBasedIteratorGetNextWithDatasets in the experimental C API "
8396 "is not implemented for Windows");
8397 return nullptr;
8398 #else
8399 tensorflow::Status s;
8400
8401 std::string dataset_name;
8402 const auto& funcs =
8403 is_mnist
8404 ? CreateMNISTDatasetFunctions(file_path, batch_size, &dataset_name,
8405 status)
8406 : CreateImagenetDatasetFunctions(file_path, &dataset_name, status);
8407 if (!status->status.ok()) {
8408 return nullptr;
8409 }
8410
8411 std::vector<tensorflow::TensorShapeProto> output_shape_list;
8412 // batch_size X 224 X 224 X 3
8413 auto image_shape = tensorflow::TensorShapeProto();
8414 image_shape.add_dim()->set_size(batch_size);
8415 if (is_mnist) {
8416 image_shape.add_dim()->set_size(784);
8417 } else {
8418 image_shape.add_dim()->set_size(224);
8419 image_shape.add_dim()->set_size(224);
8420 image_shape.add_dim()->set_size(3);
8421 }
8422 output_shape_list.push_back(image_shape);
8423
8424 // batch_size
8425 auto label_shape = tensorflow::TensorShapeProto();
8426 label_shape.add_dim()->set_size(batch_size);
8427 output_shape_list.push_back(label_shape);
8428 auto* getnext_node = AddDatasetFunctionAndIteratorNodesToGraph(
8429 funcs, dataset_name, {tensorflow::DT_FLOAT, tensorflow::DT_INT32},
8430 output_shape_list, graph, status);
8431 if (!status->status.ok()) {
8432 return nullptr;
8433 }
8434
8435 tensorflow::mutex_lock c(graph->mu);
8436 VLOG(1) << "The extended graph: "
8437 << graph->graph.ToGraphDefDebug().DebugString();
8438
8439 return getnext_node;
8440 #endif
8441 }
8442
TF_DequeueNamedTensor(TF_Session * session,int tensor_id,TF_Status * status)8443 TF_Tensor* TF_DequeueNamedTensor(TF_Session* session, int tensor_id,
8444 TF_Status* status) {
8445 assert(session);
8446 {
8447 tensorflow::mutex_lock c(session->graph->mu);
8448 VLOG(1) << "Dequeuing named tensor with id " << tensor_id
8449 << ", with input graph: "
8450 << session->graph->graph.ToGraphDefDebug().DebugString();
8451 }
8452
8453 TF_Operation* dequeue_op = TF_GraphOperationByName(
8454 session->graph,
8455 tensorflow::strings::StrCat("fifo_queue_dequeue_", tensor_id).c_str());
8456 if (dequeue_op == nullptr) {
8457 status->status = tensorflow::errors::Internal(
8458 "Unable to find the dequeue node in the TF graph.");
8459 return nullptr;
8460 }
8461
8462 VLOG(1) << "Running the dequeue op";
8463 TF_Output output{dequeue_op, 0};
8464 TF_Tensor* ret;
8465 TF_SessionRun(session, /*run_options*/ nullptr,
8466 // input related parameters
8467 /*inputs*/ nullptr, /*input_values*/ nullptr, /*ninputs*/ 0,
8468 // output related parameters
8469 /*outputs*/ &output, /*output_values*/ &ret,
8470 /*noutputs*/ 1,
8471 /*targets*/ nullptr, /*ntargets*/ 0,
8472 /*run_metadata*/ nullptr, status);
8473 if (VLOG_IS_ON(1) && status->status.ok()) {
8474 tensorflow::Tensor tensor;
8475 if (tensorflow::TF_TensorToTensor(ret, &tensor).ok()) {
8476 VLOG(1) << "Dequeued tensor content: " << tensor.DebugString();
8477 }
8478 }
8479 return ret;
8480 }
8481
TF_EnqueueNamedTensor(TF_Session * session,int tensor_id,TF_Tensor * tensor,TF_Status * status)8482 void TF_EnqueueNamedTensor(TF_Session* session, int tensor_id,
8483 TF_Tensor* tensor, TF_Status* status) {
8484 assert(session);
8485 {
8486 tensorflow::mutex_lock c(session->graph->mu);
8487 if (VLOG_IS_ON(1)) {
8488 VLOG(1) << "Enqueuing named tensor with id " << tensor_id
8489 << ", with input graph: "
8490 << session->graph->graph.ToGraphDefDebug().DebugString();
8491 tensorflow::Tensor internal_tensor;
8492 if (tensorflow::TF_TensorToTensor(tensor, &internal_tensor).ok()) {
8493 VLOG(1) << "Enqueu'ing tensor content: "
8494 << internal_tensor.DebugString();
8495 }
8496 }
8497 }
8498
8499 TF_Operation* enqueue_op = TF_GraphOperationByName(
8500 session->graph,
8501 tensorflow::strings::StrCat("fifo_queue_enqueue_", tensor_id).c_str());
8502 if (enqueue_op == nullptr) {
8503 status->status = tensorflow::errors::Internal(
8504 "Unable to find the enqueue node in the TF graph.");
8505 return;
8506 }
8507
8508 TF_Operation* placeholder_op = TF_GraphOperationByName(
8509 session->graph,
8510 tensorflow::strings::StrCat("arg_tensor_enqueue_", tensor_id).c_str());
8511 if (placeholder_op == nullptr) {
8512 status->status = tensorflow::errors::Internal(
8513 "Unable to find the placeholder node as input to enqueue in the TF "
8514 "graph.");
8515 return;
8516 }
8517
8518 VLOG(1) << "Running the enqueue op";
8519 TF_Output input{placeholder_op, 0};
8520 TF_SessionRun(session, /*run_options*/ nullptr,
8521 // input related parameters
8522 /*inputs*/ &input, /*input_values*/ &tensor, /*ninputs*/ 1,
8523 // output related parameters
8524 /*outputs*/ nullptr, /*output_values*/ nullptr, /*noutputs*/ 0,
8525 /*targets*/ &enqueue_op, /*ntargets*/ 1,
8526 /*run_metadata*/ nullptr, status);
8527 VLOG(1) << "Enqueuing is done.";
8528 }
8529
TFE_GetServerDef(const char * text_proto,TF_Status * status)8530 TF_Buffer* TFE_GetServerDef(const char* text_proto, TF_Status* status) {
8531 tensorflow::ServerDef server_def;
8532 if (!tensorflow::protobuf::TextFormat::ParseFromString(text_proto,
8533 &server_def)) {
8534 status->status = tensorflow::errors::Internal(
8535 "Invalid text proto for ServerDef: ", text_proto);
8536 return nullptr;
8537 }
8538 status->status = tensorflow::Status();
8539 TF_Buffer* ret = TF_NewBuffer();
8540 TF_CHECK_OK(MessageToBuffer(server_def, ret));
8541 return ret;
8542 }
8543
TFE_CreateContextFromSession(TF_Session * session,TF_Status * status)8544 TFE_Context* TFE_CreateContextFromSession(TF_Session* session,
8545 TF_Status* status) {
8546 auto* opts = TFE_NewContextOptions();
8547
8548 // Reduce GPU memory allocation, and set appropriate config options for TFE
8549 // context.
8550 auto* config = TF_CreateConfig(
8551 /*xla*/ false, /* gpu_memory_allow_growth */ true, /* num_cpu_devices */
8552 10);
8553 TFE_ContextOptionsSetConfig(opts, config->data, config->length, status);
8554 if (!status->status.ok()) {
8555 CHECK(!config);
8556 TFE_DeleteContextOptions(opts);
8557 return nullptr;
8558 }
8559
8560 auto* ctx = TFE_NewContextFromSession(opts, session, status);
8561 TF_DeleteBuffer(config);
8562 TFE_DeleteContextOptions(opts);
8563 return ctx;
8564 }
8565
8566 // TODO: retrieve the device string via TFE_ContextListDevices()
8567 static const char DEFAULT_CPU_DEVICE[] =
8568 "/job:localhost/replica:0/task:0/device:CPU:0";
8569
createTFEQueue(TFE_Context * ctx,TF_DataType inputType,int tensor_id,TF_Status * status)8570 static TFE_TensorHandle* createTFEQueue(TFE_Context* ctx, TF_DataType inputType,
8571 int tensor_id, TF_Status* status) {
8572 std::unique_ptr<TFE_Op, decltype(&TFE_DeleteOp)> queueOp(
8573 TFE_NewOp(ctx, "FIFOQueueV2", status), TFE_DeleteOp);
8574 TFE_OpSetDevice(queueOp.get(), DEFAULT_CPU_DEVICE, status);
8575 if (!status->status.ok()) return nullptr;
8576 // TODO: use NAMED_TENSOR_QUEUE_CAPACITY in S4TF compiler.
8577 TFE_OpSetAttrInt(queueOp.get(), "capacity", 1);
8578 TFE_OpSetAttrTypeList(queueOp.get(), "component_types", &inputType, 1);
8579 auto shared_name = tensorflow::strings::StrCat("fifo_queue_", tensor_id);
8580 TFE_OpSetAttrString(queueOp.get(), "shared_name", shared_name.data(),
8581 shared_name.size());
8582 TFE_OpSetAttrString(queueOp.get(), "container", "", 0);
8583
8584 // TODO: consider making this an unknown shape.
8585 const int64_t* dims_ptr = nullptr;
8586 int num_dims = 0;
8587 TFE_OpSetAttrShapeList(queueOp.get(), "shapes", &dims_ptr, &num_dims,
8588 /*num_values*/ 0, status);
8589 if (!status->status.ok()) return nullptr;
8590
8591 int num_retvals = 1;
8592 TFE_TensorHandle* queue = nullptr;
8593 TFE_Execute(queueOp.get(), &queue, &num_retvals, status);
8594 if (!status->status.ok()) return nullptr;
8595 CHECK_EQ(num_retvals, 1);
8596
8597 return queue;
8598 }
8599
createTFEEnqueue(TFE_Context * ctx,TF_DataType inputType,TFE_TensorHandle * queue,TFE_TensorHandle * tensor,TF_Status * status)8600 static void createTFEEnqueue(TFE_Context* ctx, TF_DataType inputType,
8601 TFE_TensorHandle* queue, TFE_TensorHandle* tensor,
8602 TF_Status* status) {
8603 TFE_Op* op = TFE_NewOp(ctx, "QueueEnqueueV2", status);
8604 if (!status->status.ok()) return;
8605 std::unique_ptr<TFE_Op, decltype(&TFE_DeleteOp)> op_deleter(op, TFE_DeleteOp);
8606 TFE_OpSetDevice(op, DEFAULT_CPU_DEVICE, status);
8607 if (!status->status.ok()) return;
8608 TFE_OpAddInput(op, queue, status);
8609 if (!status->status.ok()) return;
8610 TFE_OpAddInput(op, tensor, status);
8611 if (!status->status.ok()) return;
8612 TFE_OpSetAttrTypeList(op, "Tcomponents", &inputType, 1);
8613 TFE_OpSetAttrInt(op, "timeout_ms", -1);
8614
8615 int num_retvals = 0;
8616 TFE_Execute(op, nullptr /*retvals*/, &num_retvals, status);
8617 if (!status->status.ok()) return;
8618 CHECK_EQ(num_retvals, 0);
8619 }
8620
createTFEDequeue(TFE_Context * ctx,TF_DataType inputType,TFE_TensorHandle * queue,TF_Status * status)8621 static TFE_TensorHandle* createTFEDequeue(TFE_Context* ctx,
8622 TF_DataType inputType,
8623 TFE_TensorHandle* queue,
8624 TF_Status* status) {
8625 TFE_Op* op = TFE_NewOp(ctx, "QueueDequeueV2", status);
8626 if (!status->status.ok()) return nullptr;
8627 std::unique_ptr<TFE_Op, decltype(&TFE_DeleteOp)> op_deleter(op, TFE_DeleteOp);
8628 TFE_OpSetDevice(op, DEFAULT_CPU_DEVICE, status);
8629 if (!status->status.ok()) return nullptr;
8630
8631 TFE_OpAddInput(op, queue, status);
8632 if (!status->status.ok()) return nullptr;
8633 TFE_OpSetAttrTypeList(op, "component_types", &inputType, 1);
8634 TFE_OpSetAttrInt(op, "timeout_ms", -1);
8635 TFE_TensorHandle* ret;
8636 int num_retvals = 1;
8637 TFE_Execute(op, &ret, &num_retvals, status);
8638 if (!status->status.ok()) return nullptr;
8639 CHECK_EQ(num_retvals, 1);
8640 return ret;
8641 }
8642
TFE_DequeueNamedTensor(TF_Session * session,int tensor_id,TF_DataType inputType,TF_Status * status)8643 TFE_TensorHandle* TFE_DequeueNamedTensor(TF_Session* session, int tensor_id,
8644 TF_DataType inputType,
8645 TF_Status* status) {
8646 assert(session);
8647 VLOG(1) << "Dequeuing data tensor with id " << tensor_id;
8648
8649 auto ctx = TFE_CreateContextFromSession(session, status);
8650 if (!status->status.ok()) return nullptr;
8651 std::unique_ptr<TFE_Context, decltype(&TFE_DeleteContext)> ctx_deleter(
8652 ctx, TFE_DeleteContext);
8653
8654 TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
8655 if (!status->status.ok()) return nullptr;
8656 std::unique_ptr<TFE_TensorHandle, decltype(&TFE_DeleteTensorHandle)>
8657 queue_deleter(queue, TFE_DeleteTensorHandle);
8658
8659 auto* ret = createTFEDequeue(ctx, inputType, queue, status);
8660 return ret;
8661 }
8662
TFE_DequeueNamedTensorFromCtx(TFE_Context * ctx,int tensor_id,TF_DataType inputType,TF_Status * status)8663 TFE_TensorHandle* TFE_DequeueNamedTensorFromCtx(TFE_Context* ctx, int tensor_id,
8664 TF_DataType inputType,
8665 TF_Status* status) {
8666 TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
8667 if (!status->status.ok()) return nullptr;
8668 std::unique_ptr<TFE_TensorHandle, decltype(&TFE_DeleteTensorHandle)>
8669 queue_deleter(queue, TFE_DeleteTensorHandle);
8670
8671 auto* ret = createTFEDequeue(ctx, inputType, queue, status);
8672
8673 return ret;
8674 }
8675
TFE_EnqueueNamedTensor(TF_Session * session,int tensor_id,TFE_TensorHandle * tensor,TF_Status * status)8676 void TFE_EnqueueNamedTensor(TF_Session* session, int tensor_id,
8677 TFE_TensorHandle* tensor, TF_Status* status) {
8678 assert(session);
8679 VLOG(1) << "Enqueuing data tensor with id " << tensor_id;
8680
8681 auto ctx = TFE_CreateContextFromSession(session, status);
8682 if (!status->status.ok()) return;
8683 std::unique_ptr<TFE_Context, decltype(&TFE_DeleteContext)> ctx_deleter(
8684 ctx, TFE_DeleteContext);
8685
8686 TF_DataType inputType = TFE_TensorHandleDataType(tensor);
8687 TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
8688 if (!status->status.ok()) return;
8689 std::unique_ptr<TFE_TensorHandle, decltype(&TFE_DeleteTensorHandle)>
8690 queue_deleter(queue, TFE_DeleteTensorHandle);
8691
8692 createTFEEnqueue(ctx, inputType, queue, tensor, status);
8693 }
8694
TFE_EnqueueNamedTensorFromCtx(TFE_Context * ctx,int tensor_id,TFE_TensorHandle * tensor,TF_Status * status)8695 void TFE_EnqueueNamedTensorFromCtx(TFE_Context* ctx, int tensor_id,
8696 TFE_TensorHandle* tensor,
8697 TF_Status* status) {
8698 VLOG(1) << "Enqueuing data tensor with id " << tensor_id;
8699
8700 TF_DataType inputType = TFE_TensorHandleDataType(tensor);
8701 TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
8702 if (!status->status.ok()) return;
8703 std::unique_ptr<TFE_TensorHandle, decltype(&TFE_DeleteTensorHandle)>
8704 queue_deleter(queue, TFE_DeleteTensorHandle);
8705
8706 createTFEEnqueue(ctx, inputType, queue, tensor, status);
8707 }
8708
TFE_EnqueueVariantTensor(TF_Session * session,int tensor_id,TFE_TensorHandle * tensor,TF_Status * status)8709 void TFE_EnqueueVariantTensor(TF_Session* session, int tensor_id,
8710 TFE_TensorHandle* tensor, TF_Status* status) {
8711 VLOG(1) << "Enqueuing variant tensor with id " << tensor_id;
8712
8713 auto ctx = TFE_CreateContextFromSession(session, status);
8714 if (!status->status.ok()) return;
8715 std::unique_ptr<TFE_Context, decltype(&TFE_DeleteContext)> ctx_deleter(
8716 ctx, TFE_DeleteContext);
8717
8718 TFE_TensorHandle* queue = createTFEQueue(ctx, TF_VARIANT, tensor_id, status);
8719 if (!status->status.ok()) return;
8720 std::unique_ptr<TFE_TensorHandle, decltype(&TFE_DeleteTensorHandle)>
8721 queue_deleter(queue, TFE_DeleteTensorHandle);
8722
8723 createTFEEnqueue(ctx, TF_VARIANT, queue, tensor, status);
8724 }
8725
TFE_DequeueVariantTensor(TF_Session * session,int tensor_id,TF_Status * status)8726 TFE_TensorHandle* TFE_DequeueVariantTensor(TF_Session* session, int tensor_id,
8727 TF_Status* status) {
8728 VLOG(1) << "Dequeuing variant tensor with id " << tensor_id;
8729
8730 auto ctx = TFE_CreateContextFromSession(session, status);
8731 if (!status->status.ok()) return nullptr;
8732 std::unique_ptr<TFE_Context, decltype(&TFE_DeleteContext)> ctx_deleter(
8733 ctx, TFE_DeleteContext);
8734
8735 TFE_TensorHandle* queue = createTFEQueue(ctx, TF_VARIANT, tensor_id, status);
8736 if (!status->status.ok()) return nullptr;
8737 std::unique_ptr<TFE_TensorHandle, decltype(&TFE_DeleteTensorHandle)>
8738 queue_deleter(queue, TFE_DeleteTensorHandle);
8739
8740 return createTFEDequeue(ctx, TF_VARIANT, queue, status);
8741 }
8742
CheckOk(TF_Status * status)8743 static void CheckOk(TF_Status* status) {
8744 CHECK_EQ(TF_GetCode(status), TF_OK) << TF_Message(status);
8745 }
8746
TFE_TensorHandlePrintDebugString(TFE_TensorHandle * handle)8747 void TFE_TensorHandlePrintDebugString(TFE_TensorHandle* handle) {
8748 auto* status = TF_NewStatus();
8749 if (!TFE_TensorHandleIsConcrete(handle)) {
8750 VLOG(1) << "Symbolic tensor: " << handle;
8751 TF_DeleteStatus(status);
8752 return;
8753 }
8754
8755 TF_Tensor* t = TFE_TensorHandleResolve(handle, status);
8756 CHECK_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status);
8757
8758 tensorflow::Tensor dst;
8759 TF_CHECK_OK(TF_TensorToTensor(t, &dst));
8760 LOG(INFO) << dst.DebugString();
8761
8762 TF_DeleteTensor(t);
8763 TF_DeleteStatus(status);
8764 }
8765
TFE_OpPrintDebugString(TFE_Op * op)8766 void TFE_OpPrintDebugString(TFE_Op* op) {
8767 VLOG(1) << "TFE_OpPrintDebugString() over " << op;
8768 LOG(INFO) << op->operation.DebugString();
8769 }
8770
8771 struct TFE_ExecuteOpNotification {
TFE_ExecuteOpNotificationTFE_ExecuteOpNotification8772 TFE_ExecuteOpNotification() : status(TF_NewStatus(), TF_DeleteStatus) {}
8773 tensorflow::Notification n;
8774 std::unique_ptr<tensorflow::Thread> thread;
8775 std::unique_ptr<TF_Status, decltype(&TF_DeleteStatus)> status;
8776 };
8777
TFE_ExecuteOpInNewThread(TFE_Op * op,TFE_TensorHandle ** retvals,int * num_retvals,TF_Status * status)8778 TFE_ExecuteOpNotification* TFE_ExecuteOpInNewThread(TFE_Op* op,
8779 TFE_TensorHandle** retvals,
8780 int* num_retvals,
8781 TF_Status* status) {
8782 TFE_ExecuteOpNotification* n = new TFE_ExecuteOpNotification;
8783
8784 n->thread.reset(op->operation.EagerContext()->TFEnv()->StartThread(
8785 tensorflow::ThreadOptions(), "ExecuteOpThread",
8786 [op, retvals, num_retvals, n]() {
8787 TFE_Execute(op, retvals, num_retvals, n->status.get());
8788 n->n.Notify();
8789 }));
8790
8791 return n;
8792 }
8793
TFE_ExecuteOpNotificationWaitAndDelete(TFE_ExecuteOpNotification * notification,TF_Status * status)8794 void TFE_ExecuteOpNotificationWaitAndDelete(
8795 TFE_ExecuteOpNotification* notification, TF_Status* status) {
8796 if (notification == nullptr) {
8797 status->status = tensorflow::errors::InvalidArgument(
8798 "Passed in notification is a nullptr.");
8799
8800 return;
8801 }
8802 if (notification->thread == nullptr) {
8803 status->status = tensorflow::errors::InvalidArgument(
8804 "Passed in notification didn't start a thread correctly. Cleaning up "
8805 "this notification. Please re-execute the operation to get a new "
8806 "notification.");
8807
8808 delete notification;
8809 return;
8810 }
8811
8812 notification->n.WaitForNotification();
8813
8814 status->status = notification->status->status;
8815
8816 delete notification;
8817 }
8818
TF_MakeInternalErrorStatus(TF_Status * status,const char * errMsg)8819 void TF_MakeInternalErrorStatus(TF_Status* status, const char* errMsg) {
8820 status->status = tensorflow::errors::Internal(errMsg);
8821 }
8822
8823 // This builder is used in the eager API to build a NodeDef.
8824 struct TF_AttrBuilder : public tensorflow::AttrBuilder {
8825 using tensorflow::AttrBuilder::AttrBuilder;
8826 // The string buffers to make sure that any `attr_name` we pass into
8827 // `builder->Set()` will outlive the subsequent
8828 // `TF_AttrBuilderCheckCanRunOnDevice()` call(s) on the same `builder`.
8829 std::set<std::string> attr_names;
8830 };
8831
TF_NewAttrBuilder(const char * op_name)8832 TF_AttrBuilder* TF_NewAttrBuilder(const char* op_name) {
8833 return new TF_AttrBuilder(op_name);
8834 }
8835
TF_DeleteAttrBuilder(TF_AttrBuilder * builder)8836 void TF_DeleteAttrBuilder(TF_AttrBuilder* builder) { delete builder; }
8837
TF_AttrBuilderSetType(TF_AttrBuilder * builder,const char * attr_name,TF_DataType value)8838 void TF_AttrBuilderSetType(TF_AttrBuilder* builder, const char* attr_name,
8839 TF_DataType value) {
8840 auto iter = builder->attr_names.insert(attr_name).first;
8841 builder->Set((*iter).c_str(), static_cast<tensorflow::DataType>(value));
8842 }
8843
TF_AttrBuilderSetTypeList(TF_AttrBuilder * builder,const char * attr_name,const TF_DataType * values,int num_values)8844 void TF_AttrBuilderSetTypeList(TF_AttrBuilder* builder, const char* attr_name,
8845 const TF_DataType* values, int num_values) {
8846 auto iter = builder->attr_names.insert(attr_name).first;
8847 builder->Set(
8848 (*iter).c_str(),
8849 tensorflow::gtl::ArraySlice<const tensorflow::DataType>(
8850 reinterpret_cast<const tensorflow::DataType*>(values), num_values));
8851 }
8852
TF_AttrBuilderCheckCanRunOnDevice(TF_AttrBuilder * builder,const char * device_type,TF_Status * status)8853 void TF_AttrBuilderCheckCanRunOnDevice(TF_AttrBuilder* builder,
8854 const char* device_type,
8855 TF_Status* status) {
8856 status->status = tensorflow::FindKernelDef(
8857 tensorflow::DeviceType(device_type), builder->BuildNodeDef(),
8858 /* def = */ nullptr, /* kernel_class_name = */ nullptr);
8859 }
8860
TF_GetNumberAttrForOpListInput(const char * op_name,int input_index,TF_Status * status)8861 const char* TF_GetNumberAttrForOpListInput(const char* op_name, int input_index,
8862 TF_Status* status) {
8863 const tensorflow::OpDef* op_def = nullptr;
8864 status->status =
8865 tensorflow::OpRegistry::Global()->LookUpOpDef(op_name, &op_def);
8866 if (!status->status.ok()) return nullptr;
8867
8868 if (input_index >= op_def->input_arg_size() || input_index < 0) {
8869 status->status = tensorflow::errors::InvalidArgument(
8870 input_index, " out of range for ", op_name);
8871 return nullptr;
8872 }
8873
8874 const tensorflow::OpDef_ArgDef& input_arg = op_def->input_arg()[input_index];
8875
8876 if (input_arg.number_attr().empty()) {
8877 status->status = tensorflow::errors::NotFound(
8878 op_name, " does not have number_attr() defined.");
8879 return nullptr;
8880 }
8881
8882 // The returned string is owned by OpRegistry, so liveness is not a concern.
8883 return input_arg.number_attr().c_str();
8884 }
8885
TF_OpIsStateful(const char * op_type,TF_Status * status)8886 int TF_OpIsStateful(const char* op_type, TF_Status* status) {
8887 const tensorflow::OpRegistrationData* op_reg_data;
8888 status->status =
8889 tensorflow::OpRegistry::Global()->LookUp(op_type, &op_reg_data);
8890 if (!status->status.ok()) {
8891 return 0;
8892 }
8893 return op_reg_data->op_def.is_stateful();
8894 }
8895
TF_InitMain(const char * usage,int * argc,char *** argv)8896 void TF_InitMain(const char* usage, int* argc, char*** argv) {
8897 tensorflow::port::InitMain(usage, argc, argv);
8898 }
8899
TF_PickUnusedPortOrDie()8900 int TF_PickUnusedPortOrDie() {
8901 return tensorflow::internal::PickUnusedPortOrDie();
8902 }
8903
TFE_NewTensorHandleFromScalar(TF_DataType dtype_arg,void * data,size_t len)8904 TFE_TensorHandle* TFE_NewTensorHandleFromScalar(TF_DataType dtype_arg,
8905 void* data, size_t len) {
8906 auto dtype = static_cast<tensorflow::DataType>(dtype_arg);
8907 DCHECK(tensorflow::DataTypeCanUseMemcpy(dtype));
8908
8909 tensorflow::Tensor tensor(dtype, tensorflow::TensorShape({}));
8910 std::memcpy(tensorflow::TensorCApi::Buffer(tensor)->data(), data, len);
8911 return new TFE_TensorHandle(tensor, nullptr, nullptr);
8912 }
8913
8914 namespace {
EnableCollectiveOps(const tensorflow::ServerDef & server_def,TFE_Context * ctx)8915 tensorflow::Status EnableCollectiveOps(const tensorflow::ServerDef& server_def,
8916 TFE_Context* ctx) {
8917 // We don't use the TF_RETURN_IF_ERROR macro directly since that destroys the
8918 // server object (which currently CHECK-fails) and we miss the error, instead,
8919 // we log the error, and then return to allow the user to see the error
8920 // message.
8921 #define LOG_AND_RETURN_IF_ERROR(...) \
8922 do { \
8923 const ::tensorflow::Status _status = (__VA_ARGS__); \
8924 if (TF_PREDICT_FALSE(!_status.ok())) { \
8925 LOG(ERROR) << _status.error_message(); \
8926 return _status; \
8927 } \
8928 } while (0);
8929
8930 std::unique_ptr<tensorflow::ServerInterface> server;
8931 LOG_AND_RETURN_IF_ERROR(tensorflow::NewServer(server_def, &server));
8932
8933 tensorflow::GrpcServer* grpc_server =
8934 dynamic_cast<tensorflow::GrpcServer*>(server.get());
8935 if (grpc_server == nullptr) {
8936 LOG_AND_RETURN_IF_ERROR(tensorflow::errors::Internal(
8937 "Currently, TFE_NewContext only supports tensorflow::GrpcServer."));
8938 }
8939
8940 LOG_AND_RETURN_IF_ERROR(grpc_server->Start());
8941
8942 LOG_AND_RETURN_IF_ERROR(ctx->context.StoreCollectiveOpsServer(
8943 std::move(server), grpc_server->worker_env()->device_mgr,
8944 grpc_server->worker_env()->collective_executor_mgr));
8945
8946 return tensorflow::Status::OK();
8947 #undef LOG_AND_RETURN_IF_ERROR
8948 }
8949 } // namespace
8950
8951 // Set server_def on the context, possibly updating it.
TFE_EnableCollectiveOps(TFE_Context * ctx,const void * proto,size_t proto_len,TF_Status * status)8952 TF_CAPI_EXPORT extern void TFE_EnableCollectiveOps(TFE_Context* ctx,
8953 const void* proto,
8954 size_t proto_len,
8955 TF_Status* status) {
8956 tensorflow::ServerDef server_def;
8957 if (!server_def.ParseFromArray(proto, proto_len)) {
8958 status->status = tensorflow::errors::InvalidArgument(
8959 "Invalid tensorflow.ServerDef protocol buffer");
8960 return;
8961 }
8962 status->status = EnableCollectiveOps(server_def, ctx);
8963 }
8964
getTF_OutputDebugString(TF_Output node)8965 std::string tensorflow::getTF_OutputDebugString(TF_Output node) {
8966 return absl::Substitute("TF_Output($0, $1)", node.oper, node.index);
8967 }
8968
8969 using tensorflow::getTF_OutputDebugString;
8970
TFE_NewTensorHandleFromTFOutput(TF_Output t,TF_DataType dtype)8971 TFE_TensorHandle* TFE_NewTensorHandleFromTFOutput(TF_Output t,
8972 TF_DataType dtype) {
8973 auto ret = new TFE_TensorHandle(t, dtype);
8974 VLOG(1) << "Storing TFOutput " << getTF_OutputDebugString(t)
8975 << " into tensor handle " << ret << " with internal handle "
8976 << ret->handle;
8977 return ret;
8978 }
8979
TFE_TensorHandleIsConcrete(TFE_TensorHandle * handle)8980 unsigned char TFE_TensorHandleIsConcrete(TFE_TensorHandle* handle) {
8981 assert(handle->handle != nullptr);
8982 return handle->handle->getSymbolicTensor() == nullptr;
8983 }
8984
TFE_GetTFOutputFromTensorHandle(TFE_TensorHandle * handle,TF_Status * status)8985 TF_Output TFE_GetTFOutputFromTensorHandle(TFE_TensorHandle* handle,
8986 TF_Status* status) {
8987 if (TFE_TensorHandleIsConcrete(handle)) {
8988 status->status =
8989 tensorflow::errors::Internal("Not a symbolic tensor: ", handle);
8990 return TF_Output{nullptr, -1};
8991 }
8992
8993 auto* sym_tensor = handle->handle->getSymbolicTensor();
8994 CHECK(sym_tensor != nullptr);
8995 auto ret = TF_Output{sym_tensor->oper, sym_tensor->index};
8996 VLOG(1) << "Retrieving " << getTF_OutputDebugString(ret)
8997 << " from tensor handle " << handle;
8998 CHECK_GE(sym_tensor->index, 0);
8999 return ret;
9000 }
9001
TFE_NewTraceContext(TF_Graph * graph)9002 TFE_TraceContext* TFE_NewTraceContext(TF_Graph* graph) {
9003 return new TFE_TraceContext(graph);
9004 }
9005
TFE_DeleteTraceContext(TFE_TraceContext * trace_ctx)9006 void TFE_DeleteTraceContext(TFE_TraceContext* trace_ctx) { delete trace_ctx; }
9007
9008 // If `handle` is already symbolic, return it. Otherwise map it to a new
9009 // symbolic tensor (a PlaceHolder op) and return that.
getOrCreateSymbolicTensor(TFE_TraceContext * trace_ctx,tensorflow::TensorHandle * handle,TF_Status * status)9010 static TF_Output getOrCreateSymbolicTensor(TFE_TraceContext* trace_ctx,
9011 tensorflow::TensorHandle* handle,
9012 TF_Status* status) {
9013 VLOG(1) << "Getting symbolic tensor for input tensor handle " << handle
9014 << ": " << handle->DebugString();
9015
9016 auto* sym_tensor = handle->getSymbolicTensor();
9017 if (sym_tensor != nullptr) {
9018 auto ret = TF_Output{sym_tensor->oper, sym_tensor->index};
9019 VLOG(1) << "This handle is a symbolic tensor " << sym_tensor << ": "
9020 << getTF_OutputDebugString(ret);
9021 return ret;
9022 }
9023
9024 auto find_it = trace_ctx->input_tensor_map.find(handle);
9025 if (find_it != trace_ctx->input_tensor_map.end()) {
9026 VLOG(1) << "There exists a map entry from this concrete tensor to: "
9027 << getTF_OutputDebugString(find_it->second);
9028 return find_it->second;
9029 }
9030
9031 auto node_name = tensorflow::strings::StrCat("additional_input_",
9032 trace_ctx->node_counter++);
9033 VLOG(1) << "Adding a place holder node named " << node_name;
9034 auto* desc =
9035 TF_NewOperation(trace_ctx->graph, "Placeholder", node_name.c_str());
9036 TF_SetAttrType(desc, "dtype",
9037 static_cast<TF_DataType>(handle->dtype) /*TF_FLOAT*/);
9038 auto* result = TF_FinishOperation(desc, status);
9039 if (!status->status.ok()) {
9040 return TF_Output{nullptr, -1};
9041 }
9042
9043 auto ret = TF_Output{result, 0};
9044 VLOG(1) << "Creating a new map entry to map to: "
9045 << getTF_OutputDebugString(ret);
9046 trace_ctx->input_tensor_map[handle] = ret;
9047 // `handle` could be destroyed before it's read from `input_tensor_map` (say
9048 // during a subsequent TFE_FinalizeInputTensorsFromTraceContext() call), so we
9049 // increment its ref count to extend its life span to that of `trace_ctx`.
9050 handle->Ref();
9051 VLOG(1) << "Ref count for handle " << handle
9052 << " is 1?: " << handle->RefCountIsOne();
9053 return ret;
9054 }
9055
TFE_AddEagerOpToGraph(TFE_Op * op,TFE_TraceContext * trace_ctx,TFE_TensorHandle ** retvals,int * num_retvals,TF_Status * status)9056 TF_Operation* TFE_AddEagerOpToGraph(TFE_Op* op, TFE_TraceContext* trace_ctx,
9057 TFE_TensorHandle** retvals,
9058 int* num_retvals, TF_Status* status) {
9059 VLOG(1) << "Calling TFE_AddEagerOpToGraph() with op " << op << ": "
9060 << op->operation.DebugString();
9061
9062 const auto& op_type = op->operation.Name();
9063 auto op_name =
9064 tensorflow::strings::StrCat(op_type, "_", trace_ctx->node_counter++);
9065 auto* desc =
9066 TF_NewOperation(trace_ctx->graph, op_type.c_str(), op_name.c_str());
9067
9068 VLOG(1) << "Adding attrs.";
9069 tensorflow::AttrValueMap attrs;
9070 op->operation.Attrs().FillAttrValueMap(&attrs);
9071 for (const auto& attr : attrs) {
9072 desc->node_builder.Attr(attr.first, attr.second);
9073 }
9074
9075 VLOG(1) << "Adding inputs.";
9076 const auto& inputs = op->operation.Inputs();
9077 size_t inputIndex = 0;
9078 const tensorflow::OpDef& op_def = desc->node_builder.op_def();
9079 for (const tensorflow::OpDef::ArgDef& input_arg : op_def.input_arg()) {
9080 // TODO(bgogul): Add support for number attributes.
9081 DCHECK(input_arg.number_attr().empty())
9082 << "Number attributes is not implemented yet.";
9083 if (input_arg.type_list_attr().empty()) {
9084 auto symbolic_input =
9085 getOrCreateSymbolicTensor(trace_ctx, inputs[inputIndex++], status);
9086 if (!status->status.ok()) return nullptr;
9087 TF_AddInput(desc, symbolic_input);
9088 continue;
9089 }
9090 const std::string& type_list_attr = input_arg.type_list_attr();
9091 const auto& attr_value = attrs[type_list_attr];
9092 DCHECK(attr_value.value_case() == tensorflow::AttrValue::kList)
9093 << "Type list attribute should be a list!";
9094 std::vector<TF_Output> list_inputs(attr_value.list().type_size());
9095 for (TF_Output& list_input : list_inputs) {
9096 list_input =
9097 getOrCreateSymbolicTensor(trace_ctx, inputs[inputIndex++], status);
9098 if (!status->status.ok()) return nullptr;
9099 }
9100 TF_AddInputList(desc, list_inputs.data(), list_inputs.size());
9101 }
9102
9103 auto* graph_op = TF_FinishOperation(desc, status);
9104 if (!status->status.ok()) return nullptr;
9105
9106 VLOG(1) << "Op finalized; setting return tensors.";
9107 *num_retvals = TF_OperationNumOutputs(graph_op);
9108 VLOG(1) << "This op has " << *num_retvals << " outputs.";
9109 for (int i = 0; i < *num_retvals; ++i) {
9110 auto output = TF_Output{graph_op, i};
9111 auto dtype = TF_OperationOutputType(output);
9112 retvals[i] = TFE_NewTensorHandleFromTFOutput(output, dtype);
9113 }
9114 return graph_op;
9115 }
9116
TFE_FinalizeInputTensorsFromTraceContext(TFE_TraceContext * trace_ctx)9117 int TFE_FinalizeInputTensorsFromTraceContext(TFE_TraceContext* trace_ctx) {
9118 if (trace_ctx->input_tensors == nullptr) {
9119 trace_ctx->input_tensors =
9120 new std::vector<std::pair<tensorflow::TensorHandle*, TF_Output>>();
9121 trace_ctx->input_tensors->reserve(trace_ctx->input_tensor_map.size());
9122
9123 for (auto input : trace_ctx->input_tensor_map) {
9124 trace_ctx->input_tensors->emplace_back(input.first, input.second);
9125 }
9126 }
9127 return trace_ctx->input_tensor_map.size();
9128 }
9129
TFE_GetInputGraphNodeFromTraceContext(TFE_TraceContext * trace_ctx,unsigned int idx)9130 TF_Output TFE_GetInputGraphNodeFromTraceContext(TFE_TraceContext* trace_ctx,
9131 unsigned int idx) {
9132 CHECK(trace_ctx->input_tensors != nullptr);
9133 CHECK(trace_ctx->input_tensors->size() > idx);
9134 return trace_ctx->input_tensors->at(idx).second;
9135 }
9136
TFE_ConsumeInputConcreteTensorFromTraceContext(TFE_TraceContext * trace_ctx,unsigned int idx)9137 TFE_TensorHandle* TFE_ConsumeInputConcreteTensorFromTraceContext(
9138 TFE_TraceContext* trace_ctx, unsigned int idx) {
9139 CHECK(trace_ctx->input_tensors != nullptr);
9140 CHECK(trace_ctx->input_tensors->size() > idx);
9141 auto* handle = trace_ctx->input_tensors->at(idx).first;
9142 VLOG(1) << "Ref count for internal handle " << handle
9143 << " is 1?: " << handle->RefCountIsOne();
9144 handle->Ref();
9145 auto* ret = new TFE_TensorHandle(handle);
9146 VLOG(1) << "Returning a new tensor handle " << ret << ": "
9147 << handle->DebugString();
9148 return ret;
9149 }
9150