| 249 | } |
| 250 | |
| 251 | Status ValidateOpDef(const OpDef& op_def) { |
| 252 | using ::tensorflow::strings::Scanner; |
| 253 | |
| 254 | if (!absl::StartsWith(op_def.name(), "_")) { |
| 255 | VALIDATE(Scanner(op_def.name()) |
| 256 | .One(Scanner::UPPERLETTER) |
| 257 | .Any(Scanner::LETTER_DIGIT_UNDERSCORE) |
| 258 | .Eos() |
| 259 | .GetResult(), |
| 260 | "Invalid name: ", op_def.name(), " (Did you use CamelCase?)"); |
| 261 | } |
| 262 | |
| 263 | std::set<string> names; // for detecting duplicate names |
| 264 | for (const auto& attr : op_def.attr()) { |
| 265 | // Validate name |
| 266 | VALIDATE(gtl::InsertIfNotPresent(&names, attr.name()), |
| 267 | "Duplicate name: ", attr.name()); |
| 268 | DataType dt; |
| 269 | VALIDATE(!DataTypeFromString(attr.name(), &dt), "Attr can't have name ", |
| 270 | attr.name(), " that matches a data type"); |
| 271 | |
| 272 | // Validate type |
| 273 | StringPiece type(attr.type()); |
| 274 | bool is_list = absl::ConsumePrefix(&type, "list("); |
| 275 | bool found = false; |
| 276 | for (StringPiece valid : {"string", "int", "float", "bool", "type", "shape", |
| 277 | "tensor", "func"}) { |
| 278 | if (absl::ConsumePrefix(&type, valid)) { |
| 279 | found = true; |
| 280 | break; |
| 281 | } |
| 282 | } |
| 283 | VALIDATE(found, "Unrecognized type '", type, "' in attr '", attr.name(), |
| 284 | "'"); |
| 285 | if (is_list) { |
| 286 | VALIDATE(absl::ConsumePrefix(&type, ")"), |
| 287 | "'list(' is missing ')' in attr ", attr.name(), "'s type ", |
| 288 | attr.type()); |
| 289 | } |
| 290 | VALIDATE(type.empty(), "Extra '", type, "' at the end of attr ", |
| 291 | attr.name(), "'s type ", attr.type()); |
| 292 | |
| 293 | // Validate minimum |
| 294 | if (attr.has_minimum()) { |
| 295 | VALIDATE(attr.type() == "int" || is_list, "Attr '", attr.name(), |
| 296 | "' has minimum for unsupported type ", attr.type()); |
| 297 | if (is_list) { |
| 298 | VALIDATE(attr.minimum() >= 0, "Attr '", attr.name(), |
| 299 | "' with list type must have a non-negative minimum, not ", |
| 300 | attr.minimum()); |
| 301 | } |
| 302 | } else { |
| 303 | VALIDATE(attr.minimum() == 0, "Attr '", attr.name(), |
| 304 | "' with has_minimum = false but minimum ", attr.minimum(), |
| 305 | " not equal to default of 0"); |
| 306 | } |
| 307 | |
| 308 | // Validate allowed_values |