| 896 | } |
| 897 | |
| 898 | bool llama_model_loader::load_all_data( |
| 899 | struct ggml_context * ctx, |
| 900 | llama_buf_map & bufs, |
| 901 | llama_mlocks * lmlocks, |
| 902 | llama_progress_callback progress_callback, |
| 903 | void * progress_callback_user_data) { |
| 904 | GGML_ASSERT(size_data != 0 && "call init_mappings() first"); |
| 905 | |
| 906 | std::vector<no_init<uint8_t>> read_buf; |
| 907 | std::vector<std::future<std::pair<ggml_tensor *, bool>>> validation_result; |
| 908 | |
| 909 | // 4 staging buffers for async uploads, each sized 1MB seems to be a good default for single NVMe drives. |
| 910 | // NVMe raid configurations might require more / larger buffers. |
| 911 | constexpr size_t n_buffers = 4; |
| 912 | constexpr size_t buffer_size = 1 * 1024 * 1024; // 1MB |
| 913 | |
| 914 | std::vector<ggml_backend_buffer_t> host_buffers; |
| 915 | std::vector<ggml_backend_event_t> events; |
| 916 | std::vector<void *> host_ptrs; |
| 917 | size_t buffer_idx = 0; // buffer to use for async loads |
| 918 | ggml_backend_t upload_backend = [&](const char * func) -> ggml_backend_t { |
| 919 | if (use_mmap || check_tensors) { |
| 920 | return nullptr; |
| 921 | } |
| 922 | // When not using mmaped io use async uploads from pinned memory to GPU memory. |
| 923 | // First determine if the backend supports the necessary features for async uploads. |
| 924 | auto * buf = bufs.count(0) ? bufs.at(0) : nullptr; |
| 925 | if (!buf) { |
| 926 | LLAMA_LOG_DEBUG("%s: no buffer found for async uploads\n", func); |
| 927 | return nullptr; |
| 928 | } |
| 929 | |
| 930 | auto * buft = ggml_backend_buffer_get_type(buf); |
| 931 | auto * dev = ggml_backend_buft_get_device(buft); |
| 932 | if (!dev) { |
| 933 | LLAMA_LOG_DEBUG("%s: no device found for buffer type %s for async uploads\n", func, |
| 934 | ggml_backend_buft_name(buft)); |
| 935 | return nullptr; |
| 936 | } |
| 937 | |
| 938 | if (buft != ggml_backend_dev_buffer_type(dev)) { |
| 939 | LLAMA_LOG_DEBUG("%s: buffer type %s is not the default buffer type for device %s for async uploads\n", func, |
| 940 | ggml_backend_buft_name(buft), ggml_backend_dev_name(dev)); |
| 941 | return nullptr; |
| 942 | } |
| 943 | |
| 944 | ggml_backend_dev_props props; |
| 945 | ggml_backend_dev_get_props(dev, &props); |
| 946 | if (!props.caps.async || !props.caps.host_buffer || !props.caps.events) { |
| 947 | LLAMA_LOG_DEBUG("%s: device %s does not support async, host buffers or events\n", func, |
| 948 | ggml_backend_dev_name(dev)); |
| 949 | return nullptr; |
| 950 | } |
| 951 | |
| 952 | auto * host_buft = ggml_backend_dev_host_buffer_type(dev); |
| 953 | if (!host_buft) { |
| 954 | LLAMA_LOG_DEBUG("%s: no host buffer type found for device %s\n", func, |
| 955 | ggml_backend_dev_name(dev)); |
no test coverage detected