| 111 | } |
| 112 | |
| 113 | Status OpCompatibilityLib::ValidateCompatible(Env* env, int* changed_ops, |
| 114 | int* added_ops, |
| 115 | OpHistory* out_op_history) { |
| 116 | *changed_ops = 0; |
| 117 | *added_ops = 0; |
| 118 | |
| 119 | // Strip docs out of op_list_. |
| 120 | RemoveDescriptionsFromOpList(&op_list_); |
| 121 | |
| 122 | if (stable_ops_ != nullptr) { |
| 123 | printf("Verifying no stable ops have been removed...\n"); |
| 124 | std::vector<string> removed; |
| 125 | // We rely on stable_ops_ and op_list_ being in sorted order. |
| 126 | auto iter = stable_ops_->begin(); |
| 127 | for (int cur = 0; iter != stable_ops_->end() && cur < op_list_.op_size(); |
| 128 | ++cur) { |
| 129 | const string& op_name = op_list_.op(cur).name(); |
| 130 | while (op_name > *iter) { |
| 131 | removed.push_back(*iter); |
| 132 | ++iter; |
| 133 | } |
| 134 | if (op_name == *iter) { |
| 135 | ++iter; |
| 136 | } |
| 137 | } |
| 138 | for (; iter != stable_ops_->end(); ++iter) { |
| 139 | removed.push_back(*iter); |
| 140 | } |
| 141 | if (!removed.empty()) { |
| 142 | return errors::InvalidArgument("Error, stable op(s) removed: ", |
| 143 | absl::StrJoin(removed, ", ")); |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | OpHistory in_op_history; |
| 148 | TF_RETURN_IF_ERROR(ReadOpHistory(env, op_history_file_, op_history_directory_, |
| 149 | &in_op_history)); |
| 150 | |
| 151 | int cur = 0; |
| 152 | int hist = 0; |
| 153 | |
| 154 | printf("Verifying updates are compatible...\n"); |
| 155 | // Note: Op history is one OpList per unique op name in alphabetical order. |
| 156 | // Within the OplList it has versions in oldest-first order. |
| 157 | while (cur < op_list_.op_size() && hist < in_op_history.size()) { |
| 158 | const OpDef& cur_op = op_list_.op(cur); |
| 159 | const string& cur_op_name = cur_op.name(); |
| 160 | const OpList& history_op_list = in_op_history[hist].second; |
| 161 | const string& history_op_name = history_op_list.op(0).name(); |
| 162 | if (stable_ops_ != nullptr && stable_ops_->count(cur_op_name) == 0) { |
| 163 | // Ignore unstable op. |
| 164 | for (++cur; cur < op_list_.op_size(); ++cur) { |
| 165 | if (op_list_.op(cur).name() != cur_op_name) break; |
| 166 | } |
| 167 | } else if (cur_op_name < history_op_name) { |
| 168 | // New op: add it. |
| 169 | AddNewOpToHistory(cur_op, out_op_history); |
| 170 | ++*added_ops; |