| 1398 | } |
| 1399 | |
| 1400 | bool llama_model_loader::load_all_data( |
| 1401 | struct ggml_context * ctx, |
| 1402 | llama_buf_map & bufs, |
| 1403 | llama_mlocks * lmlocks, |
| 1404 | llama_progress_callback progress_callback, |
| 1405 | void * progress_callback_user_data) { |
| 1406 | if (files.empty()) { |
| 1407 | for (ggml_tensor * t = ggml_get_first_tensor(ctx); t != nullptr; t = ggml_get_next_tensor(ctx, t)) { |
| 1408 | set_tensor_data(t, set_tensor_data_ud); |
| 1409 | } |
| 1410 | return true; |
| 1411 | } |
| 1412 | GGML_ASSERT(size_data != 0 && "call init_mappings() first"); |
| 1413 | |
| 1414 | std::vector<no_init<uint8_t>> read_buf; |
| 1415 | std::vector<std::future<std::pair<ggml_tensor *, bool>>> validation_result; |
| 1416 | |
| 1417 | // 4 staging buffers for async uploads, each sized 1MB seems to be a good default for single NVMe drives. |
| 1418 | // NVMe raid configurations might require more / larger buffers. |
| 1419 | constexpr size_t n_buffers = 4; |
| 1420 | |
| 1421 | size_t alignment = 1; |
| 1422 | for (const auto & file : files) { |
| 1423 | alignment = std::max(file->read_alignment(), alignment); |
| 1424 | } |
| 1425 | |
| 1426 | // Buffer size: balance between memory usage and I/O efficiency |
| 1427 | // 64MB works well for NVMe drives |
| 1428 | const size_t buffer_size = alignment != 1 ? 64 * 1024 * 1024 + 2 * alignment : 1 * 1024 * 1024; |
| 1429 | |
| 1430 | std::vector<ggml_backend_buffer_t> host_buffers; |
| 1431 | std::vector<ggml_backend_event_t> events; |
| 1432 | std::vector<void *> host_ptrs; |
| 1433 | size_t buffer_idx = 0; // buffer to use for async loads |
| 1434 | ggml_backend_t upload_backend = [&](const char * func) -> ggml_backend_t { |
| 1435 | if (use_mmap || check_tensors) { |
| 1436 | return nullptr; |
| 1437 | } |
| 1438 | // When not using mmaped io use async uploads from pinned memory to GPU memory. |
| 1439 | // First determine if the backend supports the necessary features for async uploads. |
| 1440 | auto * buf = bufs.count(0) ? bufs.at(0) : nullptr; |
| 1441 | if (!buf) { |
| 1442 | LLAMA_LOG_DEBUG("%s: no buffer found for async uploads\n", func); |
| 1443 | return nullptr; |
| 1444 | } |
| 1445 | |
| 1446 | auto * buft = ggml_backend_buffer_get_type(buf); |
| 1447 | auto * dev = ggml_backend_buft_get_device(buft); |
| 1448 | if (!dev) { |
| 1449 | LLAMA_LOG_DEBUG("%s: no device found for buffer type %s for async uploads\n", func, |
| 1450 | ggml_backend_buft_name(buft)); |
| 1451 | return nullptr; |
| 1452 | } |
| 1453 | |
| 1454 | if (buft != ggml_backend_dev_buffer_type(dev)) { |
| 1455 | LLAMA_LOG_DEBUG("%s: buffer type %s is not the default buffer type for device %s for async uploads\n", func, |
| 1456 | ggml_backend_buft_name(buft), ggml_backend_dev_name(dev)); |
| 1457 | return nullptr; |
no test coverage detected