Home | History | Annotate | Download | only in c
      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; };
     46 static TF_Operation* ToTF_Operation(Node* node) {
     47   return static_cast<TF_Operation*>(static_cast<void*>(node));
     48 }
     49 
     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 
     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 
    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 
    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 
    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.
    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.
    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.
    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.
   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.
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   8743 static void CheckOk(TF_Status* status) {
   8744   CHECK_EQ(TF_GetCode(status), TF_OK) << TF_Message(status);
   8745 }
   8746 
   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 
   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 {
   8772   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 
   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 
   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 
   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 
   8832 TF_AttrBuilder* TF_NewAttrBuilder(const char* op_name) {
   8833   return new TF_AttrBuilder(op_name);
   8834 }
   8835 
   8836 void TF_DeleteAttrBuilder(TF_AttrBuilder* builder) { delete builder; }
   8837 
   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 
   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 
   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 
   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 
   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 
   8896 void TF_InitMain(const char* usage, int* argc, char*** argv) {
   8897   tensorflow::port::InitMain(usage, argc, argv);
   8898 }
   8899 
   8900 int TF_PickUnusedPortOrDie() {
   8901   return tensorflow::internal::PickUnusedPortOrDie();
   8902 }
   8903 
   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 {
   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.
   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 
   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 
   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 
   8980 unsigned char TFE_TensorHandleIsConcrete(TFE_TensorHandle* handle) {
   8981   assert(handle->handle != nullptr);
   8982   return handle->handle->getSymbolicTensor() == nullptr;
   8983 }
   8984 
   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 
   9002 TFE_TraceContext* TFE_NewTraceContext(TF_Graph* graph) {
   9003   return new TFE_TraceContext(graph);
   9004 }
   9005 
   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.
   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 
   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 
   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 
   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 
   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