Compare commits

...
Author SHA1 Message Date
Aaron Teo 85056e094a vendor: attempt to ignore warnings from vendored files
Signed-off-by: Aaron Teo <[email protected]>
2026-09-28 03:22:59 +08:00
Aaron Teo cda4023517 ggml-zdnn: fix compiler errors
Signed-off-by: Aaron Teo <[email protected]>
2026-09-28 02:57:13 +08:00
Aaron Teo 1c87213937 ci: clean up comments
Signed-off-by: Aaron Teo <[email protected]>
2026-09-28 02:56:50 +08:00
Aaron Teo 69022c2af8 ci: set shell to bash
Signed-off-by: Aaron Teo <[email protected]>
2026-09-28 02:39:23 +08:00
Aaron Teo 1c7986a776 ci: attempt to run a ubuntu 26.04 container
Signed-off-by: Aaron Teo <[email protected]>
2026-09-28 02:36:07 +08:00
Aaron Teo 6b5a83d97b ci: add zdnn backend build but not test
Signed-off-by: Aaron Teo <[email protected]>
2026-09-28 02:24:18 +08:00
Georgi Gerganov a97cce86a8 common : avoid side effects around params parsing (#29537)
- register --rpc unconditionally and call llama_supports_rpc() only from its handler
- print server "initialization ..." log after args are parsed

Assisted-by: pi:llama.cpp/MiMo-V2.6-Flash-RL
2026-09-27 20:18:56 +03:00
Adrien Gallouët 136887b665 common : make string_split<T> throw on invalid values (#29518)
Signed-off-by: Adrien Gallouët <[email protected]>
2026-09-27 18:04:11 +02:00
Toki Nasin 9adc7f420c convert : export YaRN scaling parameters for PLaMo-3 (#29528)
Recent PLaMo-3 models use YaRN, while some earlier PLaMo-3 models do not.
The recent PLaMo-3 store their YaRN settings as flat config keys
(rope_scaling_factor, initial_context_length) and build the dict at runtime
in Plamo3Config.rope_parameters. The current converter misses these settings
and writes plain RoPE metadata to GGUF. Mirror the runtime settings into
rope_parameters so the corresponding rope.scaling.* is written to GGUF.
2026-09-27 13:45:47 +02:00
Sigbjørn Skjæret 6fd50a4094 ci : bump ty to 0.0.84 (#29529)
* bump ty to 0.0.84

* fix assertion bug caught by ty
2026-09-27 13:43:08 +02:00
Sigbjørn Skjæret 33c923db1b jinja : add support for dict builtin (#29477)
* add support for dict builtin

* add tests
2026-09-27 13:41:50 +02:00
lhez c9064dded7 opencl: refine bin kernel loading condition (#29503) 2026-09-27 13:08:39 +03:00
bri-prism c829670992 sycl: FWHT kernels for block widths above 512 (#29243)
The SYCL FWHT covers 64 to 512 via the standard butterfly network, plus
384/640/768/1280 via the Kronecker/Paley construction added separately in
Hadamard hint can produce (1024, 2048, 4096, 8192); those still fall through
to the default case and run as a dense GEMM against the materialized
rotation tensor, correct but O(n^2) instead of O(n log n).

fwht_kernel_wide runs one row per work-group instead of per sub-group, so
each work-item keeps N/NT values rather than N/WARP_SIZE. Butterflies below
the sub-group width still shuffle; those up to the work-group width go
through work-group local memory; the rest stay in registers. Same butterfly
and sign convention as the existing narrow kernel.

ggml's SYCL backend registration (dpct::dev_mgr) unconditionally requires a
GPU-labeled platform to exist and throws before any op-level test can run,
so test-backend-ops could not be exercised on this box (a GPU-less pod) even
via the CPU device. Verified instead with a standalone harness: the same
kernel body run through a real SYCL CPU device (Intel oneAPI DPC++ 2026.1,
OpenCL CPU backend), checked against an independent recursive-doubling
Hadamard reference, cross-validated by first running the existing unmodified
narrow kernel through the identical harness and confirming it passes (rules
out a reference-convention bug before trusting a pass on the new code).
Random-input results for all four widths, single- and multi-row:

  N=1024 NT=256 rows=1  max_abs_err=1.7e-07  max_rel_err=4.9e-04  PASS
  N=2048 NT=256 rows=1  max_abs_err=1.9e-07  max_rel_err=2.0e-04  PASS
  N=4096 NT=256 rows=1  max_abs_err=2.0e-07  max_rel_err=1.4e-04  PASS
  N=8192 NT=256 rows=1  max_abs_err=2.5e-07  max_rel_err=3.8e-03  PASS
  N=1024 NT=256 rows=7  max_abs_err=2.4e-07  max_rel_err=1.0e-03  PASS
  N=2048 NT=256 rows=5  max_abs_err=3.0e-07  max_rel_err=9.4e-04  PASS
  N=4096 NT=256 rows=3  max_abs_err=2.7e-07  max_rel_err=1.7e-03  PASS
  N=8192 NT=256 rows=2  max_abs_err=2.5e-07  max_rel_err=1.9e-03  PASS

This covers the kernel algorithm itself; it does not exercise the ggml
dispatch/supports_op integration end to end, which needs a real GPU (or a
SYCL GPU plugin) to get past backend registration. test-backend-ops build
is verified: fwht.cpp recompiles with zero warnings as part of ggml-sycl.
2026-09-27 13:08:19 +03:00
Animesh 36d7b08340 CUDA: tune fp16 tile FlashAttention configs for head sizes 40-112 (#26289) 2026-09-27 13:07:37 +03:00
uvos 2ebd9ae621 HIP: Enable fattn-mma kernel on cdna for dkq > 256 for large batch sizes (#28907)
* HIP: Enable fattn-mma kernel on cdna for dkq > 256 for large batch sizes

* CI: hip-quality-check: ignore spills for very large mfma mma kernels
2026-09-27 13:06:56 +03:00
Ruben Ortlam cea74625fa vulkan: fix argsort kernel selection for Adreno (#29469) 2026-09-27 13:06:06 +03:00
Adrien Gallouët da6c28eb13 common : throw instead of abort on grammar without llguidance (#29516)
Signed-off-by: Adrien Gallouët <[email protected]>
2026-09-27 13:05:50 +03:00
Aman Gupta d7fb90e8e2 RPC: use RDMA completion channel to not spin (#29440)
* RPC: use RDMA completion queue to not spin

* add TODO for apple RDMA
2026-09-27 17:28:32 +08:00
Georgi Gerganov 7fb2b082ce ci : enable GGML_SCHED_DEBUG_REALLOC=1 for ctest workflows (#29514)
* ci : enable GGML_SCHED_DEBUG_REALLOC=1 for ctest workflows

* cont : metal paravirtual device is not compatible
2026-09-27 12:16:47 +03:00
Adrien Gallouët 187664b537 llama-bench : fix OOB access of hf_file (#29515)
Signed-off-by: Adrien Gallouët <[email protected]>
2026-09-27 10:24:54 +02:00
26 changed files with 372 additions and 69 deletions
+3 -1
View File
@@ -33,6 +33,7 @@ concurrency:
env:
GGML_NLOOP: 3
GGML_N_THREADS: 1
GGML_SCHED_DEBUG_REALLOC: 1
LLAMA_ARG_LOG_COLORS: 1
LLAMA_ARG_LOG_PREFIX: 1
LLAMA_ARG_LOG_TIMESTAMPS: 1
@@ -98,7 +99,8 @@ jobs:
id: cmake_test
run: |
cd build
ctest -L main -E "test-llama-archs" --verbose --timeout 900
# ref: https://github.com/ggml-org/llama.cpp/pull/19802#issuecomment-4013704023
ctest -L main -E "test-llama-archs|test-save-load-state" --verbose --timeout 900
macos-latest-x64:
runs-on: macos-15-intel
+1
View File
@@ -37,6 +37,7 @@ concurrency:
env:
GGML_NLOOP: 3
GGML_N_THREADS: 1
GGML_SCHED_DEBUG_REALLOC: 1
LLAMA_ARG_LOG_COLORS: 1
LLAMA_ARG_LOG_PREFIX: 1
LLAMA_ARG_LOG_TIMESTAMPS: 1
+40
View File
@@ -100,6 +100,46 @@ jobs:
wget https://huggingface.co/ggml-org/models/resolve/main/tinyllamas/stories260K-be.gguf
./bin/llama-completion -m stories260K-be.gguf -p "One day, Lily met a Shoggoth" -n 500 -c 256
ubuntu-26-zdnn-s390x:
name: ubuntu-26-zdnn-s390x
runs-on: ubuntu-24.04-s390x
container: ubuntu:26.04 # required to get GCC 15.1 and binutils 2.44
defaults:
run:
shell: bash
steps:
- name: Build Dependencies
id: build_depends
run: |
apt-get update
apt-get install -y --no-install-recommends \
build-essential cmake git ca-certificates \
libssl-dev libzdnn-dev
- name: Clone
id: checkout
uses: actions/checkout@v6
- name: Toolchain workaround (GCC 15)
run: |
apt-get install -y gcc-15 g++-15
echo "CC=gcc-15" >> "$GITHUB_ENV"
echo "CXX=g++-15" >> "$GITHUB_ENV"
- name: Build with zDNN Backend
id: cmake_build
run: |
cmake -B build \
-DLLAMA_FATAL_WARNINGS=ON \
-DGGML_NATIVE=OFF \
-DGGML_VXE=ON \
-DGGML_ZDNN=ON \
-DGGML_RPC=ON \
-DCMAKE_C_FLAGS="-march=arch15" \
-DCMAKE_CXX_FLAGS="-march=arch15"
time cmake --build build --config Release -j $(nproc)
ubuntu-24-ppc64le:
runs-on: ubuntu-24.04-ppc64le
+1
View File
@@ -31,6 +31,7 @@ concurrency:
env:
GGML_NLOOP: 3
GGML_N_THREADS: 1
GGML_SCHED_DEBUG_REALLOC: 1
LLAMA_ARG_LOG_COLORS: 1
LLAMA_ARG_LOG_PREFIX: 1
LLAMA_ARG_LOG_TIMESTAMPS: 1
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "3.11"
pip-install: -r requirements/requirements-all.txt ty==0.0.78
pip-install: -r requirements/requirements-all.txt ty==0.0.84
# - name: Type-check with Pyright
# uses: jakebailey/pyright-action@v2
# with:
+10 -9
View File
@@ -2673,16 +2673,17 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
params.video_ffmpeg_bin_dir = value;
}
).set_examples(mmproj_examples).set_env("LLAMA_ARG_VIDEO_FFMPEG_DIR"));
if (params.is_gen_docs || llama_supports_rpc()) {
add_opt(common_arg(
{"--rpc"}, "SERVERS",
"comma-separated list of RPC servers (host:port)",
[](common_params & params, const std::string & value) {
add_rpc_devices(value);
GGML_UNUSED(params);
add_opt(common_arg(
{"--rpc"}, "SERVERS",
"comma-separated list of RPC servers (host:port)",
[](common_params & params, const std::string & value) {
if (!llama_supports_rpc()) {
throw std::invalid_argument("RPC not supported in this build");
}
).set_env("LLAMA_ARG_RPC"));
}
add_rpc_devices(value);
GGML_UNUSED(params);
}
).set_env("LLAMA_ARG_RPC"));
add_opt(common_arg(
{"-lm", "--load-mode"}, "MODE",
"model loading mode (default: auto)\n"
+3 -1
View File
@@ -809,7 +809,9 @@ static std::vector<T> string_split(const std::string & str, char delim) {
while (std::getline(str_stream, token, delim)) {
T value;
std::istringstream token_stream(token);
token_stream >> value;
if (!(token_stream >> value)) {
throw std::invalid_argument("invalid value: \"" + token + "\"");
}
values.push_back(value);
}
return values;
+39 -12
View File
@@ -348,6 +348,43 @@ static value default_value(const func_args & args) {
return no_value ? args.get_pos(1) : args.get_pos(0);
}
static value toobject(const func_args & args) {
auto out = mk_val<value_object>();
value iter = args.get_pos(0, mk_val<value_undefined>());
bool iter_first = false;
if (is_val<value_array>(iter)) {
iter_first = true;
for (const auto & it : iter->as_array()) {
if (is_val<value_array>(it) && it->as_array().size() == 2) {
auto tuple = it->as_array();
auto key = tuple[0];
auto val = tuple[1];
JJ_DEBUG("namespace/dict: adding key '%s'", key->as_string().str().c_str());
out->insert(key, val);
} else {
throw raised_exception("namespace/dict() iterable argument must consist of tuples, not " + it->type());
}
}
} else if (is_val<value_object>(iter)) {
iter_first = true;
for (const auto & pair : iter->as_ordered_object()) {
JJ_DEBUG("namespace/dict: adding key '%s'", pair.first->as_string().str().c_str());
out->insert(pair.first, pair.second);
}
}
for (const auto & arg : args.get_args()) {
if (is_val<value_kwarg>(arg)) {
auto kwarg = cast_val<value_kwarg>(arg);
JJ_DEBUG("namespace/dict: adding key '%s'", kwarg->key.c_str());
out->insert(kwarg->key, kwarg->val);
} else if (!iter_first) {
throw raised_exception("namespace/dict() arguments must be kwargs, dict and/or iterable of tuples, not " + arg->type());
}
iter_first = false;
}
return out;
}
const func_builtins & global_builtins() {
static const func_builtins builtins = {
{"raise_exception", [](const func_args & args) -> value {
@@ -355,18 +392,8 @@ const func_builtins & global_builtins() {
std::string msg = args.get_pos(0)->as_string().str();
throw raised_exception("Jinja Exception: " + msg);
}},
{"namespace", [](const func_args & args) -> value {
auto out = mk_val<value_object>();
for (const auto & arg : args.get_args()) {
if (!is_val<value_kwarg>(arg)) {
throw raised_exception("namespace() arguments must be kwargs");
}
auto kwarg = cast_val<value_kwarg>(arg);
JJ_DEBUG("namespace: adding key '%s'", kwarg->key.c_str());
out->insert(kwarg->key, kwarg->val);
}
return out;
}},
{"dict", toobject},
{"namespace", toobject},
{"strftime_now", [](const func_args & args) -> value {
args.ensure_vals<value_string>();
std::string format = args.get_pos(0)->as_string().str();
+1 -1
View File
@@ -214,7 +214,7 @@ struct common_sampler * common_sampler_init(
#ifdef LLAMA_USE_LLGUIDANCE
grmr = llama_sampler_init_llg(vocab, "lark", grammar_str.c_str());
#else
GGML_ABORT("llguidance (cmake -DLLAMA_LLGUIDANCE=ON) is not enabled");
throw std::runtime_error("failed to parse grammar: llguidance is not enabled");
#endif // LLAMA_USE_LLGUIDANCE
} else {
std::vector<std::string> trigger_patterns;
+1 -1
View File
@@ -341,7 +341,7 @@ class NomicBertModel(BertModel):
else:
raise ValueError(f"unrecognized parameters: n_positions={npos}, max_trained_positions={mtp}")
assert self.hparams["activation_function"] == "gelu" if self.is_moe else "swiglu"
assert self.hparams["activation_function"] == ("gelu" if self.is_moe else "swiglu")
# this doesn't do anything in the HF version
assert self.hparams["causal"] is False
+15
View File
@@ -154,6 +154,21 @@ class Plamo2Model(TextModel):
class Plamo3Model(TextModel):
model_arch = gguf.MODEL_ARCH.PLAMO3
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# PLaMo-3 builds rope_parameters from flat config keys at runtime; mirror the YaRN settings for GGUF.
rope_scaling_factor = self.hparams.get("rope_scaling_factor", 1)
if rope_scaling_factor != 1 and "rope_type" not in self.rope_parameters:
self.rope_parameters.update({
"rope_type": "yarn",
"factor": float(rope_scaling_factor),
"original_max_position_embeddings": int(self.hparams["initial_context_length"]),
"beta_fast": 32.0,
"beta_slow": 1.0,
"truncate": False,
})
def set_vocab(self):
self._set_vocab_plamo()
+2
View File
@@ -10,6 +10,8 @@ extern "C" {
// device buffer
GGML_BACKEND_API ggml_backend_buffer_type_t ggml_backend_zdnn_buffer_type(void);
GGML_BACKEND_API bool ggml_backend_is_zdnn(ggml_backend_t backend);
GGML_BACKEND_API ggml_backend_reg_t ggml_backend_zdnn_reg(void);
#ifdef __cplusplus
+1 -1
View File
@@ -1875,7 +1875,7 @@ static __global__ void flash_attn_ext_f16(
#endif // defined(AMD_WMMA_AVAILABLE)
#if defined(AMD_MFMA_AVAILABLE)
if (ncols1*ncols2 < 16 || DKQ > 256) {
if (ncols1*ncols2 < 16 || (DKQ > 256 && ncols1*ncols2 < 64)) {
NO_DEVICE_CODE;
return;
}
+13 -13
View File
@@ -19,41 +19,41 @@
} \
static constexpr __host__ __device__ uint32_t ggml_cuda_fattn_tile_get_config_nvidia_fp16(const int DKQ, const int DV, const int ncols) {
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 2, 64, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 4, 128, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 8, 256, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 2, 128, 3, 128, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 4, 128, 2, 128, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 8, 128, 3, 128, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 16, 256, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 40, 40, 32, 256, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 64, 64, 2, 64, 2, 64, 64)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 64, 64, 4, 128, 2, 64, 64)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 64, 64, 8, 256, 2, 64, 64)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 64, 64, 8, 256, 3, 128, 64)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 64, 64, 16, 256, 2, 64, 64)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 64, 64, 32, 256, 2, 64, 64)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 72, 72, 2, 64, 2, 64, 72)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 72, 72, 4, 128, 2, 64, 72)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 72, 72, 2, 128, 2, 64, 72)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 72, 72, 4, 128, 3, 128, 72)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 72, 72, 8, 256, 2, 64, 72)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 72, 72, 16, 256, 2, 64, 72)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 72, 72, 32, 256, 2, 64, 72)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 80, 80, 2, 64, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 80, 80, 2, 128, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 80, 80, 4, 128, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 80, 80, 8, 256, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 80, 80, 16, 256, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 80, 80, 32, 256, 2, 64, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 80, 80, 32, 256, 2, 128, 40)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 96, 96, 2, 64, 2, 64, 48)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 96, 96, 4, 128, 2, 64, 48)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 96, 96, 8, 256, 2, 64, 48)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 96, 96, 16, 256, 2, 64, 48)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 96, 96, 32, 256, 2, 64, 48)
GGML_CUDA_FATTN_TILE_CONFIG_CASE( 96, 96, 32, 256, 2, 128, 24)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 2, 64, 2, 64, 56)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 2, 128, 3, 64, 56)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 4, 128, 2, 64, 56)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 8, 256, 2, 64, 56)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 16, 256, 2, 64, 56)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 32, 256, 2, 64, 56)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 8, 256, 3, 64, 112)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 16, 256, 2, 32, 112)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(112, 112, 32, 256, 2, 128, 56)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(128, 128, 2, 64, 2, 64, 64)
GGML_CUDA_FATTN_TILE_CONFIG_CASE(128, 128, 4, 128, 2, 64, 64)
+4 -1
View File
@@ -681,7 +681,7 @@ static best_fattn_kernel ggml_cuda_get_best_fattn_kernel(const int device, const
}
// AMD MFMA needs a certain minimum batch size to outscale the tile kernel for large head sizes.
if ((amd_mfma_available(cc) && Q->ne[0] <= 256) && Q->ne[0] != 40 && Q->ne[0] != 72) {
if (amd_mfma_available(cc) && Q->ne[0] != 40 && Q->ne[0] != 72) {
if ((Q->ne[0] <= 64 && Q->ne[1] * gqa_ratio_eff > 8)) {
return BEST_FATTN_KERNEL_MMA_F16;
}
@@ -691,6 +691,9 @@ static best_fattn_kernel ggml_cuda_get_best_fattn_kernel(const int device, const
if ((Q->ne[0] <= 256 && Q->ne[1] * gqa_ratio_eff > 64)) {
return BEST_FATTN_KERNEL_MMA_F16;
}
if (Q->ne[0] > 256 && gqa_opt_applies && Q->ne[1] * gqa_ratio_eff > 128) {
return BEST_FATTN_KERNEL_MMA_F16;
}
}
// AMD WMMA is faster than the tile kernel if the wide tiles with high arithmetic intensity can be utilized.
+8 -8
View File
@@ -1186,7 +1186,7 @@ struct ggml_backend_opencl_context {
return nullptr;
}
size_t sz;
size_t sz = 0;
const void * kernel_bin = get_adreno_bin_kernel_func(
kernel_name.c_str(), device_name.c_str(), driver_version.c_str(), &sz);
if (bin_size) {
@@ -3881,7 +3881,7 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
backend_ctx->kernel_gemv_noshuffle_q4_0_f32_32b_trans = nullptr;
backend_ctx->kernel_gemm_noshuffle_q4_0_f32_32b_trans_ila_a8_bin = nullptr;
backend_ctx->kernel_gemm_noshuffle_q4_0_q8_1_dp4a_ila_a8_bin = nullptr;
if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::X2E) {
{
{
std::string opts = std::string("-cl-std=") + opencl_c_std +
" -cl-mad-enable "
@@ -4381,8 +4381,8 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
backend_ctx->kernel_gemv_noshuffle_q4_k_f32_32b_trans = nullptr;
backend_ctx->kernel_gemm_noshuffle_q4_k_f32_32b_trans_ila_a8_bin = nullptr;
backend_ctx->kernel_gemm_noshuffle_q4_k_q8_1_dp4a_ila_a8_bin = nullptr;
if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::X2E) {
{
{
if (backend_ctx->has_vector_subgroup_broadcast) {
std::string opts = std::string("-cl-std=") + opencl_c_std +
" -cl-mad-enable "
" -DSIMDGROUP_WIDTH=" +
@@ -4430,8 +4430,8 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
backend_ctx->kernel_gemv_noshuffle_q6_k_f32_32b_trans = nullptr;
backend_ctx->kernel_gemm_noshuffle_q6_k_f32_32b_trans_ila_a8_bin = nullptr;
backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin = nullptr;
if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::X2E) {
{
{
if (backend_ctx->has_vector_subgroup_broadcast) {
std::string opts = std::string("-cl-std=") + opencl_c_std +
" -cl-mad-enable "
" -DSIMDGROUP_WIDTH=" +
@@ -4479,8 +4479,8 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
backend_ctx->kernel_gemv_noshuffle_q5_k_f32_32b_trans = nullptr;
backend_ctx->kernel_gemm_noshuffle_q5_k_f32_32b_trans_ila_a8_bin = nullptr;
backend_ctx->kernel_gemm_noshuffle_q5_k_q8_1_dp4a_ila_a8_bin = nullptr;
if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::X2E) {
{
{
if (backend_ctx->has_vector_subgroup_broadcast) {
std::string opts = std::string("-cl-std=") + opencl_c_std +
" -cl-mad-enable "
" -DSIMDGROUP_WIDTH=" +
+1
View File
@@ -26,6 +26,7 @@
// so every SEND posts a whole 128KiB stride over the wire, even when partially filled.
// (In testing 128KiB was the best performing among 32, 64, 128, 256)
//TODO: add mechanism similar to https://github.com/ggml-org/llama.cpp/pull/29440 to prevent idle CPU from spinning
static constexpr uint32_t RDMA_SEG_MAGIC = 0x52534547u; // "RSEG"
static constexpr int RDMA_NBUF = 16; // ring depth (frames per direction)
static constexpr size_t RDMA_FRAME = 4096; // Thunderbolt frame (fixed on Apple)
+63 -4
View File
@@ -25,6 +25,8 @@
#ifdef GGML_RPC_RDMA
# include <infiniband/verbs.h>
# include <array>
# include <cerrno>
# include <chrono>
# include <time.h>
# ifndef _WIN32
# include <poll.h>
@@ -54,6 +56,8 @@ using rdma_gid_t = std::array<uint8_t, RDMA_GID_SIZE>;
#if defined(GGML_RPC_RDMA) && !defined(GGML_RPC_RDMA_APPLE)
static constexpr size_t RDMA_CHUNK = 256 * 1024; // 256 KiB per send/recv (fits default 8 MiB memlock)
static constexpr int RDMA_RX_DEPTH = 24; // pre-posted recv ring: 24 × 256 KiB = 6 MiB
// keep polling the CQ for this long after the last activity, then sleep until the next completion
static constexpr auto RDMA_SPIN_TIME = std::chrono::milliseconds(100);
struct rdma_conn {
struct ibv_context * ctx = nullptr;
@@ -61,6 +65,9 @@ struct rdma_conn {
struct ibv_cq * scq = nullptr; // send completions
struct ibv_cq * rcq = nullptr; // recv completions
struct ibv_qp * qp = nullptr;
struct ibv_comp_channel * ch = nullptr; // CQ events, so an idle connection can sleep instead of spinning
std::chrono::steady_clock::time_point last_active; // last completion or posted send
void * tx_buf = nullptr;
struct ibv_mr * tx_mr = nullptr;
@@ -95,6 +102,7 @@ struct rdma_conn {
if (qp) ibv_destroy_qp(qp);
if (scq) ibv_destroy_cq(scq);
if (rcq) ibv_destroy_cq(rcq);
if (ch) ibv_destroy_comp_channel(ch);
if (pd) ibv_dealloc_pd(pd);
if (ctx) ibv_close_device(ctx);
}
@@ -142,6 +150,7 @@ struct socket_t::impl {
bool tcp_peer_closed();
bool rdma_activate(uint32_t remote_qpn, uint32_t remote_psn, const uint8_t * remote_gid);
bool rdma_poll(struct ibv_cq * cq, struct ibv_wc * wc);
bool rdma_wait_event();
std::unique_ptr<rdma_conn> rdma;
rdma_local_info rdma_local = {};
@@ -291,8 +300,10 @@ bool socket_t::impl::rdma_probe() {
rdma->pd = ibv_alloc_pd(ibctx);
if (!rdma->pd) return false;
rdma->scq = ibv_create_cq(ibctx, 16, nullptr, nullptr, 0);
rdma->rcq = ibv_create_cq(ibctx, RDMA_RX_DEPTH + 4, nullptr, nullptr, 0);
// without a completion channel rdma_poll() spins all the time, as before
rdma->ch = ibv_create_comp_channel(ibctx);
rdma->scq = ibv_create_cq(ibctx, 16, nullptr, rdma->ch, 0);
rdma->rcq = ibv_create_cq(ibctx, RDMA_RX_DEPTH + 4, nullptr, rdma->ch, 0);
if (!rdma->scq || !rdma->rcq) return false;
ibv_qp_init_attr qia = {};
@@ -394,15 +405,45 @@ bool socket_t::impl::rdma_activate(uint32_t remote_qpn, uint32_t remote_psn, con
}
}
rdma->last_active = std::chrono::steady_clock::now();
GGML_LOG_INFO("RDMA activated: qpn=%u->%u mtu=%d rx_depth=%d\n",
rdma_local.qpn, remote_qpn, 128 << rdma_local.path_mtu, RDMA_RX_DEPTH);
return true;
}
// Sleep until the completion channel has an event or the TCP peer closes.
bool socket_t::impl::rdma_wait_event() {
rdma_conn * c = rdma.get();
// POLLHUP and POLLERR are always reported, the TCP socket carries no data after the RDMA upgrade
struct pollfd pfds[2] = {
{ c->ch->fd, POLLIN, 0 },
{ fd, POLLRDHUP, 0 },
};
if (poll(pfds, 2, -1) < 0) {
return errno == EINTR;
}
if (pfds[1].revents & (POLLHUP | POLLERR | POLLRDHUP)) {
return false;
}
if (pfds[0].revents & POLLIN) {
struct ibv_cq * ev_cq = nullptr;
void * ev_ctx = nullptr;
if (ibv_get_cq_event(c->ch, &ev_cq, &ev_ctx) != 0) {
return false;
}
ibv_ack_cq_events(ev_cq, 1);
}
return true;
}
bool socket_t::impl::rdma_poll(struct ibv_cq * cq, struct ibv_wc * wc) {
for (uint64_t s = 0; ; s++) {
rdma_conn * c = rdma.get();
bool armed = false;
for (uint64_t s = 1; ; s++) {
int n = ibv_poll_cq(cq, 1, wc);
if (n > 0) {
c->last_active = std::chrono::steady_clock::now();
if (wc->status != IBV_WC_SUCCESS) {
GGML_LOG_ERROR("RDMA CQ wc error: status=%d (%s) vendor_err=0x%x\n",
wc->status, ibv_wc_status_str(wc->status), wc->vendor_err);
@@ -410,7 +451,24 @@ bool socket_t::impl::rdma_poll(struct ibv_cq * cq, struct ibv_wc * wc) {
return wc->status == IBV_WC_SUCCESS;
}
if (n < 0) return false;
if ((s & 0xFFFFF) == 0 && s > 0) {
if (armed) {
// armed and still empty: sleep until the next completion
if (!rdma_wait_event()) {
return false;
}
armed = false;
continue;
}
// spin while the connection is busy, arm the CQ once it has been idle for RDMA_SPIN_TIME
// a completion that arrives before arming raises no event, so poll once more after arming
if (c->ch && (s & 0x3FF) == 0 && std::chrono::steady_clock::now() - c->last_active > RDMA_SPIN_TIME) {
if (ibv_req_notify_cq(cq, 0) != 0) {
return false;
}
armed = true;
continue;
}
if ((s & 0xFFFFF) == 0) {
if (tcp_peer_closed()) {
return false;
}
@@ -444,6 +502,7 @@ bool socket_t::impl::rdma_send(const void * data, size_t size) {
}
if (ibv_post_send(c->qp, &wr, &bad) != 0) return false;
c->last_active = std::chrono::steady_clock::now();
struct ibv_wc wc;
if (!rdma_poll(c->scq, &wc)) return false;
+113
View File
@@ -124,6 +124,107 @@ static void launch_fwht(const float * src, float * dst, const int64_t n_rows, co
});
}
// Wide blocks: one row per work-group instead of per sub-group, so each work-item
// keeps N/NT values rather than N/WARP_SIZE. Butterflies below the sub-group width
// still shuffle; those up to NT go through work-group local memory; the rest stay
// in registers.
template <int N, int NT>
static void fwht_kernel_wide(const float * __restrict__ src,
float * __restrict__ dst,
const int64_t n_rows,
const float scale,
const sycl::nd_item<2> & item,
float * smem) {
const int64_t r = item.get_global_id(0);
if (r >= n_rows) {
return;
}
src += r * N;
dst += r * N;
constexpr int el_w = N / NT;
static_assert(el_w >= 1 && N % NT == 0, "row must be a whole number of work-group widths");
const int tid = item.get_local_id(1);
float reg[el_w];
#pragma unroll
for (int i = 0; i < el_w; ++i) {
reg[i] = src[i * NT + tid] * scale;
}
const sycl::sub_group sg = item.get_sub_group();
const int lane = sg.get_local_linear_id();
// Butterflies inside the sub-group, same pattern as the narrow kernel.
#pragma unroll
for (int h = 1; h < WARP_SIZE; h *= 2) {
#pragma unroll
for (int j = 0; j < el_w; ++j) {
const float val = reg[j];
const float val2 = dpct::permute_sub_group_by_xor(sg, val, h, WARP_SIZE);
reg[j] = (lane & h) == 0 ? val + val2 : val2 - val;
}
}
// Butterflies from the sub-group width up to NT: the partner lane is outside
// this sub-group, so it goes through work-group local memory instead of a shuffle.
for (int h = WARP_SIZE; h < NT; h *= 2) {
#pragma unroll
for (int j = 0; j < el_w; ++j) {
smem[j * NT + tid] = reg[j];
}
item.barrier(sycl::access::fence_space::local_space);
#pragma unroll
for (int j = 0; j < el_w; ++j) {
const float val = reg[j];
const float val2 = smem[j * NT + (tid ^ h)];
reg[j] = (tid & h) == 0 ? val + val2 : val2 - val;
}
item.barrier(sycl::access::fence_space::local_space);
}
// Butterflies across registers: h is a multiple of NT, so the partner of element
// i*NT + tid lives in reg[i + h/NT] on the same work-item.
for (int h = NT; h < N; h *= 2) {
const int step = h / NT;
for (int j = 0; j < el_w; j += 2 * step) {
for (int k = 0; k < step; ++k) {
const float x = reg[j + k];
const float y = reg[j + k + step];
reg[j + k] = x + y;
reg[j + k + step] = x - y;
}
}
}
#pragma unroll
for (int i = 0; i < el_w; ++i) {
dst[i * NT + tid] = reg[i];
}
}
template <int N, int NT>
static void launch_fwht_wide(const float * src,
float * dst,
const int64_t n_rows,
const float scale,
dpct::queue_ptr stream) {
const sycl::range<2> global(n_rows, NT);
const sycl::range<2> local(1, NT);
stream->submit([&](sycl::handler & cgh) {
sycl::local_accessor<float, 1> smem(sycl::range<1>(N), cgh);
cgh.parallel_for(sycl::nd_range<2>(global, local),
[=](sycl::nd_item<2> item) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
fwht_kernel_wide<N, NT>(src, dst, n_rows, scale, item, get_pointer(smem));
});
});
}
template <int N, int m>
static void kronecker_kernel(const float * __restrict__ src,
float * __restrict__ dst,
@@ -285,6 +386,18 @@ bool ggml_sycl_op_fwht(ggml_backend_sycl_context & ctx, const ggml_tensor * src,
case 1280:
launch_kronecker<1280, 20>(src_d, dst_d, rows, scale, stream);
return true;
case 1024:
launch_fwht_wide<1024, 256>(src_d, dst_d, rows, scale, stream);
return true;
case 2048:
launch_fwht_wide<2048, 256>(src_d, dst_d, rows, scale, stream);
return true;
case 4096:
launch_fwht_wide<4096, 256>(src_d, dst_d, rows, scale, stream);
return true;
case 8192:
launch_fwht_wide<8192, 256>(src_d, dst_d, rows, scale, stream);
return true;
default:
return false;
}
+6 -4
View File
@@ -11172,8 +11172,10 @@ void ggml_vk_argsort(ggml_backend_vk_context * ctx, vk_context& subctx, const gg
// Pick the largest workgroup size <= ncolsp2
uint32_t pipeline_idx = std::min(ncols_pad_log2, num_argsort_pipelines - 1);
uint32_t max_wg_log2 = std::min(ctx->device->max_workgroup_size_log2, num_argsort_pipelines - 1);
// Use the "small" argsort shader if the whole sort can be done by a single workgroup.
bool use_small = ncols_pad_log2 <= ctx->device->max_workgroup_size_log2 &&
bool use_small = ncols_pad_log2 <= max_wg_log2 &&
ctx->device->pipeline_argsort_f32[pipeline_idx] != nullptr;
vk_pipeline pipeline = use_small ? ctx->device->pipeline_argsort_f32[pipeline_idx]
@@ -11208,7 +11210,7 @@ void ggml_vk_argsort(ggml_backend_vk_context * ctx, vk_context& subctx, const gg
{
vk_op_argsort_push_constants pc2 = pc;
pc2.outer_start = 0;
pc2.outer_end = std::min(ncols_pad_log2, ctx->device->max_workgroup_size_log2);
pc2.outer_end = std::min(ncols_pad_log2, max_wg_log2);
pc2.inner_start = 0;
pc2.inner_end = 100;
ggml_pipeline_request_descriptor_sets(ctx, pipeline, 1);
@@ -11217,7 +11219,7 @@ void ggml_vk_argsort(ggml_backend_vk_context * ctx, vk_context& subctx, const gg
if (!use_small) {
ggml_vk_sync_buffers(ctx, subctx);
// Loop over outer/inner passes, synchronizing between each pass.
for (uint32_t outer = ctx->device->max_workgroup_size_log2; outer < ncols_pad_log2; ++outer) {
for (uint32_t outer = max_wg_log2; outer < ncols_pad_log2; ++outer) {
for (uint32_t inner = 0; inner < outer + 1; ++inner) {
vk_op_argsort_push_constants pc2 = pc;
pc2.outer_start = outer;
@@ -15612,7 +15614,7 @@ static bool ggml_backend_vk_device_supports_op(ggml_backend_dev_t dev, const ggm
if (device->vulkan_memory_model) {
return true;
} else {
return op->ne[0] <= (1 << device->max_workgroup_size_log2);
return op->ne[0] <= (1 << std::min(device->max_workgroup_size_log2, num_argsort_pipelines - 1));
}
}
case GGML_OP_TOP_K:
+6 -8
View File
@@ -438,15 +438,13 @@ static ggml_backend_i ggml_backend_zdnn_i = {
};
static ggml_guid_t ggml_backend_zdnn_guid(void) {
static const char * guid_str = "IBM-ZDNN-ACCELER";
return reinterpret_cast<ggml_guid_t>((void *)guid_str);
static char guid_str[] = "IBM-ZDNN-ACCELER";
return reinterpret_cast<ggml_guid_t>(guid_str);
}
bool ggml_backend_is_zdnn(ggml_backend_t backend) {
return backend != NULL &&
ggml_guid_matches(backend->guid, ggml_backend_zdnn_guid());
GGML_UNUSED(backend);
}
//
@@ -483,7 +481,7 @@ static void ggml_backend_zdnn_device_get_props(ggml_backend_dev_t dev, ggml_back
props->description = ggml_backend_zdnn_device_get_description(dev);
props->type = ggml_backend_zdnn_device_get_type(dev);
ggml_backend_zdnn_device_get_memory(dev, &props->memory_free, &props->memory_total);
props->caps = (ggml_backend_dev_caps) {
props->caps = {
/* .async = */ false,
/* .host_buffer = */ false,
/* .buffer_from_host_ptr = */ false,
@@ -500,7 +498,7 @@ static ggml_backend_t ggml_backend_zdnn_device_init(ggml_backend_dev_t dev, cons
}
ggml_backend_t backend = (ggml_backend *)malloc(sizeof(ggml_backend));
*backend = (ggml_backend) {
*backend = {
/* .guid = */ ggml_backend_zdnn_guid(),
/* .iface = */ ggml_backend_zdnn_i,
/* .device = */ dev,
@@ -619,13 +617,13 @@ ggml_backend_reg_t ggml_backend_zdnn_reg(void) {
atexit(ggml_zdnn_cleanup);
{
g_ggml_backend_zdnn_reg = (ggml_backend_reg) {
g_ggml_backend_zdnn_reg = {
/* .api_version = */ GGML_ZDNN_VERSION,
/* .iface = */ ggml_backend_zdnn_reg_i,
/* .context = */ NULL
};
g_ggml_backend_zdnn_device = (ggml_backend_device) {
g_ggml_backend_zdnn_device = {
/* .iface = */ ggml_backend_zdnn_device_i,
/* .reg = */ &g_ggml_backend_zdnn_reg,
/* .context = */ &g_ggml_ctx_dev_main
+9 -1
View File
@@ -64,7 +64,15 @@ def main():
'_ZL12rwkv_wkv_f32ILi128EEviiiiPKfS1_S1_S1_S1_S1_Pf',
'_ZL9mul_mat_qIL9ggml_type10ELi64ELb1EEvPKcPKiS4_S4_PfS5_PKf15HIP_vector_typeIjLj3EEiiiiiS9_S9_iiiS9_S9_iiiS9_',
'_ZL9mul_mat_qIL9ggml_type42ELi128ELb1EEvPKcPKiS4_S4_PfS5_PKf15HIP_vector_typeIjLj3EEiiiiiS9_S9_iiiS9_S9_iiiS9_',
'_ZL18flash_attn_ext_f16ILi576ELi512ELi2ELi32ELb0ELb1ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil'
'_ZL18flash_attn_ext_f16ILi576ELi512ELi2ELi32ELb0ELb1ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi512ELi512ELi16ELi4ELb0ELb0ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi512ELi512ELi16ELi4ELb1ELb0ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi512ELi512ELi32ELi2ELb0ELb0ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi512ELi512ELi32ELi2ELb1ELb0ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi512ELi512ELi8ELi8ELb0ELb0ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi512ELi512ELi8ELi8ELb1ELb0ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi576ELi512ELi16ELi4ELb0ELb1ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
'_ZL18flash_attn_ext_f16ILi576ELi512ELi4ELi16ELb0ELb1ELb0EEvPKcS1_S1_S1_S1_PKiPfP15HIP_vector_typeIfLj2EEffffjfiS5_IjLj3EEiiiiiiiiiiiliiliiiiil',
}
functions = parse_log_file(log_file)
+24
View File
@@ -1976,6 +1976,30 @@ static void test_object_methods(testing & t) {
json::object(),
""
);
test_template(t, "dict from dict",
"{% set o = dict({'a': 3, 'b': 1, 'c': 2}) %}{{ o|tojson }}",
json::object(),
"{\"a\": 3, \"b\": 1, \"c\": 2}"
);
test_template(t, "dict from kwargs",
"{% set o = dict(a=3, b=1, c=2) %}{{ o|tojson }}",
json::object(),
"{\"a\": 3, \"b\": 1, \"c\": 2}"
);
test_template(t, "dict from tuples",
"{% set o = dict((obj | items | list)) %}{{ o|tojson }}",
{{"obj", {{"a", 3}, {"b", 1}, {"c", 2}}}},
"{\"a\": 3, \"b\": 1, \"c\": 2}"
);
test_template(t, "dict from tuples and kwargs",
"{% set o = dict((obj | items | list), c=2) %}{{ o|tojson }}",
{{"obj", {{"a", 3}, {"b", 1}}}},
"{\"a\": 3, \"b\": 1, \"c\": 2}"
);
}
static void test_hasher(testing & t) {
+1 -1
View File
@@ -1097,7 +1097,7 @@ static cmd_params parse_cmd_params(int argc, char ** argv) {
p.hf_token = params.hf_token;
p.offline = params.offline;
p.model.hf_repo = params.hf_repo[i];
if (!params.hf_file.empty() && !params.hf_file[i].empty()) {
if (i < params.hf_file.size() && !params.hf_file[i].empty()) {
p.model.hf_file = params.hf_file[i];
}
+2 -2
View File
@@ -102,12 +102,12 @@ int llama_server(int argc, char ** argv) {
// touch it. lifecycle is symmetric, stop_gc() runs in clean_up() before backend free
server_stream_session_manager_start();
SRV_INF("%s", "initializing ...\n");
if (!common_params_parse(argc, argv, params, LLAMA_EXAMPLE_SERVER)) {
return 1;
}
SRV_INF("%s", "initializing ...\n");
llama_backend_init();
llama_numa_init(params.numa);
+4
View File
@@ -4,3 +4,7 @@ add_library(stb INTERFACE)
add_library(vendor::stb ALIAS stb)
target_include_directories(stb INTERFACE ..)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(stb INTERFACE -Wno-maybe-uninitialized)
endif()