| 290 | |
| 291 | template<typename T> |
| 292 | bool llama_model_loader::get_arr(const std::string & key, std::vector<T> & result, bool required) { |
| 293 | const gguf_context * ctx = meta.get(); |
| 294 | const int kid = gguf_find_key(ctx, key.c_str()); |
| 295 | |
| 296 | if (kid < 0 || gguf_get_kv_type(ctx, kid) != GGUF_TYPE_ARRAY) { |
| 297 | if (required) { |
| 298 | throw std::runtime_error(format("array key not found in model: %s", key.c_str())); |
| 299 | } |
| 300 | return false; |
| 301 | } |
| 302 | |
| 303 | struct GGUFMeta::ArrayInfo arr_info = |
| 304 | GGUFMeta::GKV<GGUFMeta::ArrayInfo>::get_kv(ctx, kid); |
| 305 | |
| 306 | switch (arr_info.gt) { |
| 307 | case GGUF_TYPE_UINT32: |
| 308 | case GGUF_TYPE_INT32: GGML_ASSERT((std::is_same<T, int32_t>::value) || |
| 309 | (std::is_same<T, uint32_t>::value)); break; |
| 310 | case GGUF_TYPE_FLOAT32: GGML_ASSERT((std::is_same<T, float>::value)); break; |
| 311 | case GGUF_TYPE_STRING: GGML_ASSERT((std::is_same<T, std::string>::value)); break; |
| 312 | default: |
| 313 | throw std::runtime_error(format("%s is not a string/float32/uint32/int32 array", key.c_str())); |
| 314 | } |
| 315 | |
| 316 | if constexpr (std::is_same<T, std::string>::value) { |
| 317 | const size_t n_items = gguf_get_arr_n(ctx, kid); |
| 318 | result.clear(); |
| 319 | |
| 320 | for (size_t i = 0; i < n_items; i++) { |
| 321 | const T value = gguf_get_arr_str(ctx, kid, i); |
| 322 | result.emplace_back(value); |
| 323 | } |
| 324 | } else { |
| 325 | result.resize(arr_info.length); |
| 326 | result.assign((const T*)arr_info.data, (const T *)arr_info.data + arr_info.length); |
| 327 | } |
| 328 | |
| 329 | return true; |
| 330 | } |
| 331 | |
| 332 | template<typename T, size_t N_MAX> |
| 333 | bool llama_model_loader::get_arr(const std::string & key, std::array<T, N_MAX> & result, bool required) { |
no test coverage detected