| 121 | } |
| 122 | |
| 123 | void ParseHeaderContents(HeaderData& target, const std::string_view header) { |
| 124 | target.shape = {}; |
| 125 | const char* hdr = header.data(); |
| 126 | SkipSpaces(hdr); |
| 127 | Skip(hdr, "{"); |
| 128 | SkipFieldName(hdr, "descr"); |
| 129 | auto typestr = ParseStringValue(hdr); |
| 130 | // < means LE, | means N/A, = means native. In all those cases, we can read |
| 131 | bool little_endian = (typestr[0] == '<' || typestr[0] == '|' || typestr[0] == '='); |
| 132 | DALI_ENFORCE(little_endian, "Big Endian files are not supported."); |
| 133 | target.type_info = &TypeFromNumpyStr(typestr.substr(1)); |
| 134 | |
| 135 | SkipSpaces(hdr); |
| 136 | Skip(hdr, ","); |
| 137 | SkipFieldName(hdr, "fortran_order"); |
| 138 | if (TrySkip(hdr, "True")) { |
| 139 | target.fortran_order = true; |
| 140 | } else if (TrySkip(hdr, "False")) { |
| 141 | target.fortran_order = false; |
| 142 | } else { |
| 143 | DALI_FAIL("Failed to parse fortran_order field."); |
| 144 | } |
| 145 | SkipSpaces(hdr); |
| 146 | Skip(hdr, ","); |
| 147 | SkipFieldName(hdr, "shape"); |
| 148 | Skip(hdr, "("); |
| 149 | SkipSpaces(hdr); |
| 150 | while (*hdr != ')') { |
| 151 | // ParseInteger already skips the leading spaces (strtol does). |
| 152 | target.shape.shape.push_back(ParseInteger<int64_t>(hdr)); |
| 153 | SkipSpaces(hdr); |
| 154 | DALI_ENFORCE(TrySkip(hdr, ",") || target.shape.size() > 1, |
| 155 | "The first number in a tuple must be followed by a comma."); |
| 156 | } |
| 157 | if (target.fortran_order) { |
| 158 | // cheapest thing to do is to define the tensor in an reversed way |
| 159 | std::reverse(target.shape.begin(), target.shape.end()); |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | void CheckNpyVersion(char *token) { |
| 164 | int api_version = token[6]; |