| 260 | } |
| 261 | |
| 262 | int YALMData::update_from_file(const std::string& filename, bool read_metadata, bool lock_model_weights) { |
| 263 | std::cout << "loading data from file: " << filename << std::endl; |
| 264 | int fd = open(filename.c_str(), O_RDONLY); |
| 265 | if (fd == -1) { |
| 266 | return -1; |
| 267 | } |
| 268 | |
| 269 | struct stat st; |
| 270 | if (fstat(fd, &st) != 0) { |
| 271 | close(fd); |
| 272 | return -1; |
| 273 | } |
| 274 | |
| 275 | size_t size = st.st_size; |
| 276 | int mmap_flags = MAP_PRIVATE; |
| 277 | if (lock_model_weights) { |
| 278 | // Eagerly load memory-mapped file into memory. |
| 279 | // This ensures the mlock call later is locking memory already in RAM. |
| 280 | mmap_flags |= MAP_POPULATE; |
| 281 | } |
| 282 | void* data = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, fd, 0); |
| 283 | if (data == MAP_FAILED) { |
| 284 | close(fd); |
| 285 | return -1; |
| 286 | } |
| 287 | if (lock_model_weights && mlock(data, size) != 0) { |
| 288 | std::cerr << "Warning: mlock failed for model data. Performance may be suboptimal. Are you running as sudo?" << std::endl; |
| 289 | } |
| 290 | |
| 291 | #ifdef __linux__ |
| 292 | // increases readahead buffer size, resulting in faster cold loads |
| 293 | posix_fadvise(fd, 0, size, POSIX_FADV_SEQUENTIAL); |
| 294 | #endif |
| 295 | |
| 296 | close(fd); |
| 297 | |
| 298 | // Parse the metadata JSON and the tensors |
| 299 | if (size < sizeof(uint64_t)) { |
| 300 | munmap(data, size); |
| 301 | return -1; |
| 302 | } |
| 303 | |
| 304 | uint64_t json_size = *(uint64_t*)data; |
| 305 | if (json_size == 0 || json_size > size - sizeof(uint64_t)) { |
| 306 | munmap(data, size); |
| 307 | return -1; |
| 308 | } |
| 309 | |
| 310 | char* json_ptr = (char*)data + sizeof(uint64_t); |
| 311 | void* bytes_ptr = (char*)data + sizeof(uint64_t) + json_size; |
| 312 | size_t bytes_size = size - sizeof(uint64_t) - json_size; |
| 313 | |
| 314 | std::string json_str(json_ptr, json_size); |
| 315 | json header = json::parse(json_str); |
| 316 | |
| 317 | for (auto& [key, val] : header.items()) { |
| 318 | if (key == "__metadata__" && read_metadata) { |
| 319 | metadata = val; |