diff --git a/mcpp.toml b/mcpp.toml index dd1897c..5971983 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -42,6 +42,8 @@ members = [ "tests/examples/freetype", "tests/examples/glad", "tests/examples/libpng", + "tests/examples/llamacpp", + "tests/examples/llamacpp-metal", "tests/examples/md4c", "tests/examples/spdlog-compiled", "tests/examples/tinyhttps", diff --git a/pkgs/l/llamacpp.lua b/pkgs/l/llamacpp.lua new file mode 100644 index 0000000..dba97ef --- /dev/null +++ b/pkgs/l/llamacpp.lua @@ -0,0 +1,36 @@ +-- Form A descriptor: llama.cpp-m ships its own mcpp.toml and a vendored, +-- pinned llama.cpp checkpoint. The default lookup finds that manifest inside +-- the GitHub tag archive. CPU is the default backend; Metal is an additive +-- package feature for macOS ARM64 consumers. +package = { + spec = "1", + name = "llamacpp", + namespace = "mcpplibs", + description = "C++23 module package for llama.cpp (import llamacpp)", + licenses = {"MIT"}, + repo = "https://github.com/mcpplibs/llama.cpp-m", + type = "package", + + xpm = { + linux = { + ["0.1.0"] = { + url = "https://github.com/mcpplibs/llama.cpp-m/archive/refs/tags/v0.1.0.tar.gz", + sha256 = "9af34d44349e520f2f9bd2eace29eb6a634ab4633a7f3bafa225f77be178ca84", + }, + }, + macosx = { + ["0.1.0"] = { + url = "https://github.com/mcpplibs/llama.cpp-m/archive/refs/tags/v0.1.0.tar.gz", + sha256 = "9af34d44349e520f2f9bd2eace29eb6a634ab4633a7f3bafa225f77be178ca84", + }, + }, + windows = { + ["0.1.0"] = { + url = "https://github.com/mcpplibs/llama.cpp-m/archive/refs/tags/v0.1.0.tar.gz", + sha256 = "9af34d44349e520f2f9bd2eace29eb6a634ab4633a7f3bafa225f77be178ca84", + }, + }, + }, + + -- No `mcpp` field: default lookup finds /*/mcpp.toml. +} diff --git a/tests/examples/llamacpp-metal/mcpp.toml b/tests/examples/llamacpp-metal/mcpp.toml new file mode 100644 index 0000000..c0cbebf --- /dev/null +++ b/tests/examples/llamacpp-metal/mcpp.toml @@ -0,0 +1,10 @@ +# Metal is supported only by the macOS ARM64 leg of the workspace matrix. +[indices] +default = { path = "../../.." } + +[package] +name = "llamacpp-metal-tests" +version = "0.1.0" + +[target.'cfg(macos)'.dependencies] +llamacpp = { version = "0.1.0", features = ["backend-metal"] } diff --git a/tests/examples/llamacpp-metal/tests/backend.cpp b/tests/examples/llamacpp-metal/tests/backend.cpp new file mode 100644 index 0000000..16905d2 --- /dev/null +++ b/tests/examples/llamacpp-metal/tests/backend.cpp @@ -0,0 +1,23 @@ +import std; + +#if defined(__APPLE__) && defined(__aarch64__) +import llamacpp; + +int main() { + llama_backend_init(); + const bool metal_available = llama_supports_gpu_offload(); + llama_backend_free(); + + if (!metal_available) { + std::cerr << "Metal backend is not available\n"; + return 1; + } + + std::cout << "LLAMACPP_METAL_INDEX_TEST=PASS\n"; + return 0; +} +#else +int main() { + return 0; +} +#endif diff --git a/tests/examples/llamacpp/mcpp.toml b/tests/examples/llamacpp/mcpp.toml new file mode 100644 index 0000000..fc7191c --- /dev/null +++ b/tests/examples/llamacpp/mcpp.toml @@ -0,0 +1,16 @@ +# Resolve the public default-namespace package from this checkout. +[indices] +default = { path = "../../.." } + +[package] +name = "llamacpp-tests" +version = "0.1.0" + +[target.'cfg(linux)'.dependencies] +llamacpp = "0.1.0" + +[target.'cfg(macos)'.dependencies] +llamacpp = "0.1.0" + +[target.'cfg(windows)'.dependencies] +llamacpp = "0.1.0" diff --git a/tests/examples/llamacpp/tests/api.cpp b/tests/examples/llamacpp/tests/api.cpp new file mode 100644 index 0000000..559cc8a --- /dev/null +++ b/tests/examples/llamacpp/tests/api.cpp @@ -0,0 +1,35 @@ +import std; +import llamacpp; + +int main() { + static_assert(LLAMA_DEFAULT_SEED == 0xFFFFFFFFu); + static_assert(LLAMA_TOKEN_NULL == llama_token{-1}); + + llama_backend_init(); + + const auto model_params = llama_model_default_params(); + const bool gpu_offload_available = llama_supports_gpu_offload(); + llama_sampler * chain = llama_sampler_chain_init( + llama_sampler_chain_default_params() + ); + llama_sampler * greedy = llama_sampler_init_greedy(); + + if (!chain || !greedy) { + if (chain) { + llama_sampler_free(chain); + } else if (greedy) { + llama_sampler_free(greedy); + } + llama_backend_free(); + return 1; + } + + llama_sampler_chain_add(chain, greedy); + llama_sampler_free(chain); + llama_backend_free(); + + std::cout << "gpu_offload_available=" << gpu_offload_available + << " default_gpu_layers=" << model_params.n_gpu_layers << '\n' + << "LLAMACPP_INDEX_TEST=PASS\n"; + return 0; +}