Commit fd8f8451a for llama.cpp
commit fd8f8451a2c067a296d03c77292a322b155f1280
Author: Georgi Gerganov <ggerganov@gmail.com>
Date: Mon Oct 26 12:16:02 2026 +0200
tests : refactor test-llama-archs to not link internal libllama symbols (#30880)
test-llama-archs included src/llama-arch.h and src/llama-model-saver.h,
which prevented building on Windows with shared libraries since the
used symbols are not exported from the DLL.
- declare llama_arch_* wrappers around the internal llm_ arch query
functions in the llama-ext.h staging header, together with
llama_arch_kv_name() and llama_arch_supports_save()
- slim llama_model_saver down to the private implementation of
llama_model_save_to_file(): the fixture-writer half used by the test
moves into tests/test-llama-archs.cpp as a local kv_writer
- replace the roundtrip saver usage with the public
llama_model_save_to_file() writing to a temp path (also removes the
tmpfile() fd leak and its Windows workaround)
- move test-llama-archs, test-generate-models, test-llama-context and
test-fusion out of the NOT WIN32 OR NOT BUILD_SHARED_LIBS guard
Assisted-by: pi:llama.cpp/ggml-org/GLM-5.3-Flash-GGUF (2x DGX Spark (RDMA, TP=2))
diff --git a/src/llama-arch.cpp b/src/llama-arch.cpp
index ea13e9c3f..06fc56bb2 100644
--- a/src/llama-arch.cpp
+++ b/src/llama-arch.cpp
@@ -1,5 +1,6 @@
#include "llama-arch.h"
+#include "llama-ext.h"
#include "llama-impl.h"
#include <map>
@@ -1356,3 +1357,43 @@ bool llm_arch_supports_sm_tensor(const llm_arch & arch) {
return true;
}
}
+
+bool llama_arch_supports_save(llm_arch arch) {
+ switch (arch) {
+ case LLM_ARCH_SENSENOVA_U1:
+ case LLM_ARCH_GEMMA3N:
+ case LLM_ARCH_BITNET:
+ case LLM_ARCH_T5:
+ case LLM_ARCH_APERTUS:
+ case LLM_ARCH_STEP35:
+ case LLM_ARCH_CLEF: // the head tensors are not saved
+ case LLM_ARCH_VLLM_DECISION2:
+ return false;
+ default:
+ return true;
+ }
+}
+
+std::vector<llm_arch> llama_arch_all() {
+ return llm_arch_all();
+}
+
+const char * llama_arch_name(llm_arch arch) {
+ return llm_arch_name(arch);
+}
+
+llm_arch llama_arch_from_string(const std::string & name) {
+ return llm_arch_from_string(name);
+}
+
+std::string llama_arch_kv_name(llm_arch arch, llm_kv key) {
+ return LLM_KV(arch)(key);
+}
+
+bool llama_arch_supports_sm_tensor(llm_arch arch) {
+ return llm_arch_supports_sm_tensor(arch);
+}
+
+bool llama_arch_supports_mixed_batch(llm_arch arch) {
+ return llm_arch_supports_mixed_batch(arch);
+}
diff --git a/src/llama-ext.h b/src/llama-ext.h
index 933cb8013..fcd91e912 100644
--- a/src/llama-ext.h
+++ b/src/llama-ext.h
@@ -5,11 +5,36 @@
// try as much as possible to not include this header in the rest of the codebase
#include "llama.h"
+#include "llama-arch.h"
#include <cstdint>
#include <map>
+#include <string>
#include <vector>
+//
+// llama architecture queries
+//
+
+// all the LLM architectures known to the library
+LLAMA_API std::vector<llm_arch> llama_arch_all();
+
+// the canonical name of an architecture (e.g. "llama"), or "unknown"
+LLAMA_API const char * llama_arch_name(llm_arch arch);
+
+// the architecture with the given canonical name, or LLM_ARCH_UNKNOWN
+LLAMA_API llm_arch llama_arch_from_string(const std::string & name);
+
+// the arch-resolved GGUF key of a KV id, e.g. LLM_KV_CONTEXT_LENGTH -> "llama.context_length"
+LLAMA_API std::string llama_arch_kv_name(llm_arch arch, llm_kv key);
+
+LLAMA_API bool llama_arch_supports_sm_tensor(llm_arch arch);
+
+LLAMA_API bool llama_arch_supports_mixed_batch(llm_arch arch);
+
+// FIXME temporary function for better error messages
+LLAMA_API bool llama_arch_supports_save(llm_arch arch);
+
// Reserve a new compute graph. It is valid until the next call to llama_graph_reserve.
LLAMA_API struct ggml_cgraph * llama_graph_reserve(
struct llama_context * ctx,
diff --git a/src/llama-model-saver.cpp b/src/llama-model-saver.cpp
index 56a42c756..1160e88a2 100644
--- a/src/llama-model-saver.cpp
+++ b/src/llama-model-saver.cpp
@@ -4,6 +4,7 @@
#include "gguf.h"
#include "llama-arch.h"
+#include "llama-ext.h"
#include "llama.h"
#include "llama-hparams.h"
#include "llama-model.h"
@@ -13,34 +14,13 @@
#include <string>
#include <unordered_set>
-bool llama_model_saver_supports_arch(llm_arch arch) {
- switch (arch) {
- case LLM_ARCH_SENSENOVA_U1:
- case LLM_ARCH_GEMMA3N:
- case LLM_ARCH_BITNET:
- case LLM_ARCH_T5:
- case LLM_ARCH_APERTUS:
- case LLM_ARCH_STEP35:
- case LLM_ARCH_CLEF: // the head tensors are not saved
- case LLM_ARCH_VLLM_DECISION2:
- return false;
- default:
- return true;
- }
-}
-
llama_model_saver::llama_model_saver(const struct llama_model * model) :
- gguf_ctx(gguf_init_empty()), gguf_ctx_owned(true), model(model), llm_kv(model->arch) {
- GGML_ASSERT(llama_model_saver_supports_arch(model->arch));
+ gguf_ctx(gguf_init_empty()), model(model), llm_kv(model->arch) {
+ GGML_ASSERT(llama_arch_supports_save(model->arch));
}
-llama_model_saver::llama_model_saver(enum llm_arch arch, struct gguf_context * gguf_ctx) :
- gguf_ctx(gguf_ctx == nullptr ? gguf_init_empty() : gguf_ctx), gguf_ctx_owned(gguf_ctx == nullptr), model(nullptr), llm_kv(arch) {}
-
llama_model_saver::~llama_model_saver() {
- if (gguf_ctx_owned) {
- gguf_free(gguf_ctx);
- }
+ gguf_free(gguf_ctx);
}
void llama_model_saver::add_kv(const enum llm_kv key, const uint32_t value) {
@@ -118,11 +98,6 @@ void llama_model_saver::add_kv(const enum llm_kv key, const Container & value, c
GGML_ABORT("fatal error");
}
}
-// instantiate for external usage:
-template void llama_model_saver::add_kv<std::vector<uint32_t>>(const enum llm_kv, const std::vector<uint32_t> &, const bool);
-template void llama_model_saver::add_kv<std::vector<float>>(const enum llm_kv, const std::vector<float> &, const bool);
-template void llama_model_saver::add_kv<std::vector<uint64_t>>(const enum llm_kv, const std::vector<uint64_t> &, const bool);
-template void llama_model_saver::add_kv<std::vector<int32_t>>(const enum llm_kv, const std::vector<int32_t> &, const bool);
void llama_model_saver::add_kv(const enum llm_kv key, const std::vector<std::string> & value) {
std::vector<const char *> tmp(value.size());
@@ -548,7 +523,3 @@ void llama_model_saver::add_tensors_from_model() {
void llama_model_saver::save(const std::string & path_model) {
gguf_write_to_file(gguf_ctx, path_model.c_str(), false);
}
-
-void llama_model_saver::save(FILE * file) {
- gguf_write_to_file_ptr(gguf_ctx, file, false);
-}
diff --git a/src/llama-model-saver.h b/src/llama-model-saver.h
index 95e19e666..5829abac6 100644
--- a/src/llama-model-saver.h
+++ b/src/llama-model-saver.h
@@ -6,17 +6,12 @@
#include <vector>
-// FIXME temporary function for better error messages
-bool llama_model_saver_supports_arch(llm_arch arch);
-
struct llama_model_saver {
struct gguf_context * gguf_ctx = nullptr;
- const bool gguf_ctx_owned;
const struct llama_model * model;
const struct LLM_KV llm_kv;
llama_model_saver(const struct llama_model * model);
- llama_model_saver(enum llm_arch arch, struct gguf_context * gguf_ctx);
~llama_model_saver();
void add_kv(enum llm_kv key, uint32_t value);
@@ -41,5 +36,4 @@ struct llama_model_saver {
void add_tensors_from_model();
void save(const std::string & path_model);
- void save(FILE * file);
};
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 36703127a..2e768cb38 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -223,57 +223,56 @@ if (NOT WIN32 OR NOT BUILD_SHARED_LIBS)
# llama_build_and_test(test-double-float.cpp) # SLOW
- # TODO: after `test-llama-archs` is refactored to not link internal symbols, we can move all related tests out of
- # this branch and run them on all platforms
- llama_build(test-llama-archs.cpp)
-
- set(MODEL_DIR "${CMAKE_CURRENT_BINARY_DIR}/test-models/")
- file(MAKE_DIRECTORY "${MODEL_DIR}")
-
- llama_test(
- test-llama-archs
- NAME test-generate-models
- LABEL "main behavior backend"
- ARGS -o "${MODEL_DIR}"
- )
- set_tests_properties(test-generate-models PROPERTIES
- FIXTURES_SETUP generate-models
- )
+endif()
- # Target model for test-speculative-rejection-sampling
- set(SPEC_TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/test-speculative-models/target")
- file(MAKE_DIRECTORY "${SPEC_TARGET_DIR}")
- llama_test(
- test-llama-archs
- NAME test-generate-speculative-target
- LABEL main
- ARGS -a llama -s 999 -o "${SPEC_TARGET_DIR}"
- )
- set_tests_properties(
- test-generate-speculative-target
- PROPERTIES FIXTURES_SETUP speculative-model
- )
+llama_build(test-llama-archs.cpp)
- # To avoid recreating the model use the fixture exclude any option:
- # -FA "^speculative-model$"
- llama_build_and_test(test-speculative-rejection-sampling.cpp ARGS
- -m "${SPEC_TARGET_DIR}/llama-dense.gguf")
- set_tests_properties(test-speculative-rejection-sampling PROPERTIES FIXTURES_REQUIRED speculative-model)
-
- # Test context state handling across all architectures, using the generated dummy models
- llama_test(
- test-llama-context
- LABEL "main behavior backend"
- ARGS --models "${MODEL_DIR}"
- )
- # abort on graph reallocations that the initial reserve should have covered
- set_tests_properties(test-llama-context PROPERTIES
- FIXTURES_REQUIRED generate-models
- ENVIRONMENT "GGML_SCHED_DEBUG_REALLOC=1"
- )
+set(MODEL_DIR "${CMAKE_CURRENT_BINARY_DIR}/test-models/")
+file(MAKE_DIRECTORY "${MODEL_DIR}")
- llama_build(test-fusion.cpp)
-endif()
+llama_test(
+ test-llama-archs
+ NAME test-generate-models
+ LABEL "main behavior backend"
+ ARGS -o "${MODEL_DIR}"
+)
+set_tests_properties(test-generate-models PROPERTIES
+ FIXTURES_SETUP generate-models
+)
+
+# Target model for test-speculative-rejection-sampling
+set(SPEC_TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/test-speculative-models/target")
+file(MAKE_DIRECTORY "${SPEC_TARGET_DIR}")
+llama_test(
+ test-llama-archs
+ NAME test-generate-speculative-target
+ LABEL main
+ ARGS -a llama -s 999 -o "${SPEC_TARGET_DIR}"
+)
+set_tests_properties(
+ test-generate-speculative-target
+ PROPERTIES FIXTURES_SETUP speculative-model
+)
+
+# To avoid recreating the model use the fixture exclude any option:
+# -FA "^speculative-model$"
+llama_build_and_test(test-speculative-rejection-sampling.cpp ARGS
+ -m "${SPEC_TARGET_DIR}/llama-dense.gguf")
+set_tests_properties(test-speculative-rejection-sampling PROPERTIES FIXTURES_REQUIRED speculative-model)
+
+# Test context state handling across all architectures, using the generated dummy models
+llama_test(
+ test-llama-context
+ LABEL "main behavior backend"
+ ARGS --models "${MODEL_DIR}"
+)
+# abort on graph reallocations that the initial reserve should have covered
+set_tests_properties(test-llama-context PROPERTIES
+ FIXTURES_REQUIRED generate-models
+ ENVIRONMENT "GGML_SCHED_DEBUG_REALLOC=1"
+)
+
+llama_build(test-fusion.cpp)
llama_build_and_test(test-chat-peg-parser.cpp peg-parser/simple-tokenize.cpp LABEL behavior)
llama_build_and_test(test-jinja.cpp LABEL behavior)
diff --git a/tests/test-llama-archs.cpp b/tests/test-llama-archs.cpp
index 00267716d..8b8ab6e5d 100644
--- a/tests/test-llama-archs.cpp
+++ b/tests/test-llama-archs.cpp
@@ -6,10 +6,7 @@
#include "ggml-cpp.h"
#include "llama.h"
#include "llama-cpp.h"
-
-// TODO: replace with #include "llama-ext.h" in the future
-#include "../src/llama-arch.h"
-#include "../src/llama-model-saver.h"
+#include "../src/llama-ext.h"
#include <cinttypes>
#include <cmath>
@@ -17,6 +14,7 @@
#include <cstdio>
#include <cstring>
#include <cstdint>
+#include <filesystem>
#include <random>
#include <regex>
#include <stdexcept>
@@ -28,7 +26,7 @@ static bool arch_matches(const std::string & filter, llm_arch arch) {
if (filter.empty()) {
return true;
}
- return std::regex_search(llm_arch_name(arch), std::regex(filter));
+ return std::regex_search(llama_arch_name(arch), std::regex(filter));
}
// normalized mean squared error = mse(a, b) / mse(a, 0)
@@ -164,9 +162,50 @@ static bool host_experts_test(const llm_arch arch) {
}
}
+// writes arch-resolved GGUF keys into the fixture context, the test-side equivalent of llama_model_saver
+struct kv_writer {
+ struct gguf_context * gguf_ctx;
+ const llm_arch arch;
+
+ kv_writer(enum llm_arch arch, struct gguf_context * gguf_ctx) : gguf_ctx(gguf_ctx), arch(arch) {}
+
+ void add_kv(enum llm_kv key, uint32_t value) { gguf_set_val_u32 (gguf_ctx, llama_arch_kv_name(arch, key).c_str(), value); }
+ void add_kv(enum llm_kv key, int32_t value) { gguf_set_val_i32 (gguf_ctx, llama_arch_kv_name(arch, key).c_str(), value); }
+ void add_kv(enum llm_kv key, uint64_t value) { gguf_set_val_u64 (gguf_ctx, llama_arch_kv_name(arch, key).c_str(), value); }
+ void add_kv(enum llm_kv key, float value) { gguf_set_val_f32 (gguf_ctx, llama_arch_kv_name(arch, key).c_str(), value); }
+ void add_kv(enum llm_kv key, bool value) { gguf_set_val_bool(gguf_ctx, llama_arch_kv_name(arch, key).c_str(), value); }
+ void add_kv(enum llm_kv key, const char * value) { gguf_set_val_str (gguf_ctx, llama_arch_kv_name(arch, key).c_str(), value); }
+
+ template <typename T>
+ void add_kv(enum llm_kv key, const std::vector<T> & value) {
+ if (value.empty()) {
+ return;
+ }
+ if (std::is_same<T, uint32_t>::value) {
+ gguf_set_arr_data(gguf_ctx, llama_arch_kv_name(arch, key).c_str(), GGUF_TYPE_UINT32, value.data(), value.size());
+ } else if (std::is_same<T, int32_t>::value) {
+ gguf_set_arr_data(gguf_ctx, llama_arch_kv_name(arch, key).c_str(), GGUF_TYPE_INT32, value.data(), value.size());
+ } else if (std::is_same<T, uint64_t>::value) {
+ gguf_set_arr_data(gguf_ctx, llama_arch_kv_name(arch, key).c_str(), GGUF_TYPE_UINT64, value.data(), value.size());
+ } else if (std::is_same<T, float>::value) {
+ gguf_set_arr_data(gguf_ctx, llama_arch_kv_name(arch, key).c_str(), GGUF_TYPE_FLOAT32, value.data(), value.size());
+ } else {
+ GGML_ABORT("fatal error");
+ }
+ }
+
+ void add_kv(enum llm_kv key, const std::vector<std::string> & value) {
+ std::vector<const char *> tmp(value.size());
+ for (size_t i = 0; i < value.size(); ++i) {
+ tmp[i] = value[i].c_str();
+ }
+ gguf_set_arr_str(gguf_ctx, llama_arch_kv_name(arch, key).c_str(), tmp.data(), tmp.size());
+ }
+};
+
static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
gguf_context_ptr ret(gguf_init_empty());
- llama_model_saver ms(arch, ret.get());
+ kv_writer ms(arch, ret.get());
const uint32_t n_ctx = 256;
uint32_t n_vocab = 128;
@@ -243,7 +282,7 @@ static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
}
const uint32_t n_embd_head = n_embd / n_head;
- ms.add_kv(LLM_KV_GENERAL_ARCHITECTURE, llm_arch_name(arch));
+ ms.add_kv(LLM_KV_GENERAL_ARCHITECTURE, llama_arch_name(arch));
ms.add_kv(LLM_KV_VOCAB_SIZE, n_vocab);
ms.add_kv(LLM_KV_CONTEXT_LENGTH, n_ctx);
ms.add_kv(LLM_KV_EMBEDDING_LENGTH, n_embd);
@@ -638,6 +677,11 @@ static bool silent_model_load_progress(float /*progress*/, void * /*user_data*/)
return true;
}
+static std::string get_tmp_gguf_path() {
+ static size_t id = 0;
+ return (std::filesystem::temp_directory_path() / ("test-llama-archs-" + std::to_string(++id) + ".gguf")).string();
+}
+
static std::pair<llama_model_ptr, llama_context_ptr> get_model_and_ctx(
struct gguf_context * gguf_ctx, FILE * file, const size_t seed, const float stdev,
const std::vector<ggml_backend_dev_t> & devs,
@@ -958,7 +1002,7 @@ static int save_models(const std::string & arch_filter, const size_t seed, const
}
}, &ud);
- for (const llm_arch & arch : llm_arch_all()) {
+ for (const llm_arch & arch : llama_arch_all()) {
if (arch == LLM_ARCH_UNKNOWN) {
continue;
}
@@ -978,14 +1022,14 @@ static int save_models(const std::string & arch_filter, const size_t seed, const
if (!moe && moe_mandatory(arch)) {
continue;
}
- if (!llama_model_saver_supports_arch(arch) || !arch_supported(arch)) {
- LOG_INF("%s: %s model (%s) is unsupported, skipping\n", __func__, llm_arch_name(arch), moe ? "MoE" : "dense");
+ if (!llama_arch_supports_save(arch) || !arch_supported(arch)) {
+ LOG_INF("%s: %s model (%s) is unsupported, skipping\n", __func__, llama_arch_name(arch), moe ? "MoE" : "dense");
continue;
}
gguf_context_ptr gguf_ctx = get_gguf_ctx(arch, moe);
auto model_and_ctx = get_model_and_ctx(gguf_ctx.get(), nullptr, seed, stdev, {});
- const std::string path = dir + "/" + llm_arch_name(arch) + (moe ? "-moe.gguf" : "-dense.gguf");
- LOG_INF("%s: Saving %s model (%s) to %s...\n", __func__, llm_arch_name(arch), moe ? "MoE" : "dense", path.c_str());
+ const std::string path = dir + "/" + llama_arch_name(arch) + (moe ? "-moe.gguf" : "-dense.gguf");
+ LOG_INF("%s: Saving %s model (%s) to %s...\n", __func__, llama_arch_name(arch), moe ? "MoE" : "dense", path.c_str());
llama_model_save_to_file(model_and_ctx.first.get(), path.c_str());
}
}
@@ -1094,8 +1138,8 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
}
size_t max_arch_name_length = 0;
- for (const llm_arch & arch : llm_arch_all()) {
- max_arch_name_length = std::max(max_arch_name_length, strlen(llm_arch_name(arch)));
+ for (const llm_arch & arch : llama_arch_all()) {
+ max_arch_name_length = std::max(max_arch_name_length, strlen(llama_arch_name(arch)));
}
const std::string template_header = std::string("|%" + std::to_string(max_arch_name_length) + "s|%") + std::to_string(max_device_label_length) + "s|%6s|%15s|%9s|%15s|\n";
@@ -1116,7 +1160,7 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
LOG("-");
}
LOG("|------|---------------|---------|---------------|\n");
- for (const llm_arch & arch : llm_arch_all()) {
+ for (const llm_arch & arch : llama_arch_all()) {
if (arch == LLM_ARCH_UNKNOWN) {
continue;
}
@@ -1152,7 +1196,7 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
const llama_model_tensor_buft_override * overrides = dc.host_experts ? host_experts_overrides : nullptr;
// print test config first; should anything fail during model loading or inference, at least we know which test case caused it
- LOG(template_row_cfg.c_str(), llm_arch_name(arch), dc.label.c_str(), config_name.c_str());
+ LOG(template_row_cfg.c_str(), llama_arch_name(arch), dc.label.c_str(), config_name.c_str());
fflush(stdout);
std::pair<llama_model_ptr, llama_context_ptr> model_and_ctx_dev;
@@ -1171,7 +1215,7 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
model_and_ctx_cpu = get_model_and_ctx(gguf_ctx.get(), nullptr, seed, stdev, {}, LLAMA_SPLIT_MODE_LAYER, encode);
logits_cpu = get_logits(model_and_ctx_cpu.first.get(), model_and_ctx_cpu.second.get(), tokens, encode);
}
- if (dc.split_mode != LLAMA_SPLIT_MODE_TENSOR || llm_arch_supports_sm_tensor(arch)) {
+ if (dc.split_mode != LLAMA_SPLIT_MODE_TENSOR || llama_arch_supports_sm_tensor(arch)) {
test_executed = true;
model_and_ctx_dev = get_model_and_ctx(gguf_ctx.get(), nullptr, seed, stdev, dc.devs, dc.split_mode, encode, overrides, dc.moe_cache_size);
logits_dev = get_logits(model_and_ctx_dev.first.get(), model_and_ctx_dev.second.get(), tokens, encode);
@@ -1194,7 +1238,7 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
}
std::vector<float> logits_mixed;
std::vector<float> logits_chunks;
- if (llm_arch_supports_mixed_batch(arch)) {
+ if (llama_arch_supports_mixed_batch(arch)) {
if (get_logits_mixed(model_and_ctx_dev.first.get(), lctx_dev, tokens, embd_mixed, false, logits_chunks) != 0 ||
get_logits_mixed(model_and_ctx_dev.first.get(), lctx_dev, tokens, embd_mixed, true, logits_mixed) != 0) {
throw std::runtime_error("failed to decode mixed batch");
@@ -1227,30 +1271,33 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
}
}
- FILE * file = tmpfile(); // Can be null on Windows without administrator privileges.
- // FIXME: when adding a tensor to a gguf_context a copy is made, this changes the pointer which the meta backend
- // in turn uses to map the tensors to their simple equivalents - this is fundamentally incompatible
- if (file != nullptr && llama_model_saver_supports_arch(arch) && dc.split_mode != LLAMA_SPLIT_MODE_TENSOR) {
+ if (llama_arch_supports_save(arch) && dc.split_mode != LLAMA_SPLIT_MODE_TENSOR) {
test_executed = true;
GGML_ASSERT(model_and_ctx_dev.first && model_and_ctx_dev.second);
- llama_model_saver ms = llama_model_saver(model_and_ctx_dev.first.get());
- ms.add_kv_from_model();
- ms.add_tensors_from_model();
- ms.save(file);
- rewind(file);
-
- auto model_and_ctx_roundtrip = get_model_and_ctx(nullptr, file, seed, stdev, dc.devs, dc.split_mode, encode, overrides, dc.moe_cache_size);
- const std::vector<float> logits_roundtrip = get_logits(
- model_and_ctx_roundtrip.first.get(), model_and_ctx_roundtrip.second.get(), tokens, encode);
- status_roundtrip = "\033[1;32mOK\033[0m";
- GGML_ASSERT(logits_roundtrip.size() == logits_dev.size());
- for (size_t i = 0; i < logits_roundtrip.size(); i++) {
- if (logits_roundtrip[i] != logits_dev[i]) {
- test_ok = false;
- status_roundtrip = "\033[1;31mFAIL\033[0m";
- break;
+ // FIXME: when adding a tensor to a gguf_context a copy is made, this changes the pointer which the meta backend
+ // in turn uses to map the tensors to their simple equivalents - this is fundamentally incompatible
+ const std::string path = get_tmp_gguf_path();
+ llama_model_save_to_file(model_and_ctx_dev.first.get(), path.c_str());
+ FILE * file = fopen(path.c_str(), "rb");
+ GGML_ASSERT(file != nullptr);
+
+ {
+ auto model_and_ctx_roundtrip = get_model_and_ctx(nullptr, file, seed, stdev, dc.devs, dc.split_mode, encode, overrides, dc.moe_cache_size);
+ const std::vector<float> logits_roundtrip = get_logits(
+ model_and_ctx_roundtrip.first.get(), model_and_ctx_roundtrip.second.get(), tokens, encode);
+ status_roundtrip = "\033[1;32mOK\033[0m";
+ GGML_ASSERT(logits_roundtrip.size() == logits_dev.size());
+ for (size_t i = 0; i < logits_roundtrip.size(); i++) {
+ if (logits_roundtrip[i] != logits_dev[i]) {
+ test_ok = false;
+ status_roundtrip = "\033[1;31mFAIL\033[0m";
+ break;
+ }
}
}
+
+ fclose(file);
+ std::filesystem::remove(path);
}
}
@@ -1303,7 +1350,7 @@ int main(int argc, char ** argv) {
} else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--arch") == 0) {
if (i + 1 < argc) {
const std::string arch_name = argv[++i];
- if (llm_arch_from_string(arch_name) != LLM_ARCH_UNKNOWN) {
+ if (llama_arch_from_string(arch_name) != LLM_ARCH_UNKNOWN) {
// exact architecture name
arch_filter = "^" + arch_name + "$";
} else {