Apply checks to arrays individually (for-each fashion). Check consistency of array fields, check name.
| 1045 | // |
| 1046 | // Check consistency of array fields, check name. |
| 1047 | void CheckEachArray(const Model& model) { |
| 1048 | for (const auto& array_entry : model.GetArrayMap()) { |
| 1049 | const auto& array = array_entry.second; |
| 1050 | // It's OK to have a buffer or an alloc, but not both. |
| 1051 | // (Since allocs are for transient arrays without a buffer). |
| 1052 | CHECK(!array->buffer || !array->alloc) << "Tensor: " << array_entry.first; |
| 1053 | if (array->buffer) { |
| 1054 | // If there is a buffer, its type should be consistent with data_type. |
| 1055 | CHECK(array->buffer->type == array->data_type) |
| 1056 | << "Tensor: " << array_entry.first; |
| 1057 | // The presence of a fixed buffer should imply the presence of a fixed |
| 1058 | // shape. |
| 1059 | CHECK(array->has_shape()) << array_entry.first; |
| 1060 | // Constant buffer should has a valid shape. |
| 1061 | CheckValidShape(array->shape()); |
| 1062 | // The shape flat-size should agree with the buffer length. |
| 1063 | CHECK_EQ(array->buffer->Length(), |
| 1064 | RequiredBufferSizeForShape(array->shape())) |
| 1065 | << "Tensor: " << array_entry.first; |
| 1066 | } |
| 1067 | |
| 1068 | // Check name. Either "name_with_suffix_8", "name_with_port:3", but not |
| 1069 | // "name_with_both:3_8". |
| 1070 | const string& name = array_entry.first; |
| 1071 | auto colon_pos = name.find_first_of(":"); |
| 1072 | if (colon_pos != string::npos) { |
| 1073 | CHECK_EQ(name.substr(colon_pos + 1).find_first_not_of("0123456789"), |
| 1074 | string::npos) |
| 1075 | << "Array '" << name << "' has non-digit characters after colon."; |
| 1076 | } |
| 1077 | CHECK_GT(colon_pos, 0) << "Array '" << name |
| 1078 | << "' must not start with a colon."; |
| 1079 | } |
| 1080 | } |
| 1081 | |
| 1082 | void CheckOperatorOrdering(const Model& model) { |
| 1083 | std::unordered_set<string> arrays_behind_us; |
no test coverage detected