Skip to content

Commit 88cf781

Browse files
authored
ggml-zendnn: update code for latest ZenDNN API (ggml-org#19923)
- adapt ggml-zendnn.cpp to the new lowoha::matmul interface - update the ZenDNN git tag in CMake to the latest release (ZenDNN‑2026‑WW08) - add static lib support in CMake
1 parent 4e76d24 commit 88cf781

3 files changed

Lines changed: 52 additions & 92 deletions

File tree

docs/backend/ZenDNN.md

Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
**Llama.cpp + ZenDNN**
2424

25-
The llama.cpp ZenDNN backend leverages AMD's optimized matrix multiplication primitives to accelerate inference on AMD CPUs. It utilizes ZenDNN's **LowOHA (Low Overhead Hardware Accelerated)** MatMul operator for efficient GEMM operations with minimal execution overhead, built-in weight caching, and direct access to backend libraries (AOCL BLIS, LibXSMM, OneDNN).
25+
The llama.cpp ZenDNN backend leverages AMD's optimized matrix multiplication primitives to accelerate inference on AMD CPUs. It utilizes ZenDNN's **LowOHA (Low Overhead Hardware Accelerated)** MatMul operator for efficient GEMM operations with minimal execution overhead, built-in weight caching, and direct access to backend libraries (AOCL DLP, LibXSMM, OneDNN).
2626

2727
For more information about ZenDNN, visit: https://www.amd.com/en/developer/zendnn.html
2828

@@ -32,7 +32,7 @@ For more information about ZenDNN, visit: https://www.amd.com/en/developer/zendn
3232
|:-------:|:-------:|:----------------------------------------------:|
3333
| Linux | Support | Ubuntu 20.04, 22.04, 24.04 |
3434

35-
For the latest list of supported operating systems, see the [ZenDNN Supported OS](https://github.com/amd/ZenDNN/blob/zendnnl/README.md#15-supported-os).
35+
For the latest list of supported operating systems, see the [ZenDNN Supported OS](https://github.com/amd/ZenDNN/blob/a18adf8c605fb5f5e52cefd7eda08a7b18febbaf/README.md#15-supported-os).
3636

3737
## Hardware
3838

@@ -44,9 +44,9 @@ ZenDNN is optimized for AMD EPYC™ processors and AMD Ryzen™ processors based
4444

4545
| CPU Family | Status | Notes |
4646
|:-----------------------------:|:-------:|:----------------------------------:|
47-
| AMD EPYC™ 9005 Series (Turin)| Support | 5th Gen - Zen 5 architecture |
48-
| AMD EPYC™ 9004 Series (Genoa)| Support | 4th Gen - Zen 4 architecture |
49-
| AMD EPYC™ 7003 Series (Milan)| Support | 3rd Gen - Zen 3 architecture |
47+
| AMD EPYC™ 9005 Series (Turin) | Support | 5th Gen - Zen 5 architecture |
48+
| AMD EPYC™ 9004 Series (Genoa) | Support | 4th Gen - Zen 4 architecture |
49+
| AMD EPYC™ 7003 Series (Milan) | Support | 3rd Gen - Zen 3 architecture |
5050
| AMD Ryzen™ AI MAX (Strix Halo)| Support | High-performance mobile processors |
5151

5252
*Notes:*
@@ -61,7 +61,7 @@ The ZenDNN backend currently accelerates **matrix multiplication (MUL_MAT)** ope
6161

6262
| Operation | Status | Notes |
6363
|:-------------|:-------:|:----------------------------------------------:|
64-
| MUL_MAT | | Accelerated via ZenDNN LowOHA MatMul |
64+
| MUL_MAT | Support | Accelerated via ZenDNN LowOHA MatMul |
6565

6666
*Note:* Since only MUL_MAT is accelerated, models will benefit most from ZenDNN when matrix multiplications dominate the computational workload (which is typical for transformer-based LLMs).
6767

@@ -104,7 +104,6 @@ If you want to build ZenDNN yourself or use a specific version:
104104
# Clone ZenDNN repository
105105
git clone https://github.com/amd/ZenDNN.git
106106
cd ZenDNN
107-
git checkout zendnnl
108107

109108
# Build and install (requires CMake >= 3.25)
110109
mkdir build && cd build
@@ -114,7 +113,7 @@ cmake --build . --target all
114113

115114
Default installation path: `ZenDNN/build/install`
116115

117-
**For detailed build instructions**, refer to the [ZenDNN README](https://github.com/amd/ZenDNN/blob/zendnnl/README.md).
116+
**For detailed build instructions**, refer to the [ZenDNN README](https://github.com/amd/ZenDNN/blob/a18adf8c605fb5f5e52cefd7eda08a7b18febbaf/README.md).
118117

119118
**Step 2: Build llama.cpp with custom ZenDNN path**
120119

@@ -146,8 +145,7 @@ Run llama.cpp server with ZenDNN acceleration:
146145

147146
```sh
148147
# Set optimal configuration
149-
export OMP_NUM_THREADS=64 # Adjust to your CPU core count
150-
export ZENDNNL_MATMUL_ALGO=2 # Blocked AOCL BLIS for best performance
148+
export ZENDNNL_MATMUL_ALGO=1 # Blocked AOCL DLP algo for best performance
151149

152150
# Start server
153151
./build/bin/llama-server \
@@ -160,62 +158,26 @@ export ZENDNNL_MATMUL_ALGO=2 # Blocked AOCL BLIS for best performance
160158
Access the server at `http://localhost:8080`.
161159

162160
**Performance tips**:
163-
- Set `OMP_NUM_THREADS` to match your physical core count
164-
- Use `ZENDNNL_MATMUL_ALGO=2` for optimal performance
161+
- Use `ZENDNNL_MATMUL_ALGO=1` for optimal performance
165162
- For NUMA systems: `numactl --cpunodebind=0 --membind=0 ./build/bin/llama-server ...`
166163

167164
## Environment Variable
168165

169-
### Build Time
166+
For environment variables related to ZenDNN, refer to the [ZenDNN Environment Variables Documentation](https://github.com/amd/ZenDNN/blob/a18adf8c605fb5f5e52cefd7eda08a7b18febbaf/docs/runtime_env.md).
170167

171-
| Name | Value | Function |
172-
|--------------------|---------------------------------------|---------------------------------------------|
173-
| GGML_ZENDNN | ON/OFF | Enable ZenDNN backend support |
174-
| ZENDNN_ROOT | Path to ZenDNN installation | Set ZenDNN installation directory |
175-
| GGML_OPENMP | ON/OFF (recommended: ON) | Enable OpenMP for multi-threading |
168+
### Performance Optimization
176169

177-
### Runtime
178-
179-
| Name | Value | Function |
180-
|-------------------------|--------------------------|-------------------------------------------------------------------|
181-
| OMP_NUM_THREADS | Number (e.g., 64) | Set number of OpenMP threads (recommended: physical core count) |
182-
| ZENDNNL_MATMUL_ALGO | 0-5 | Select MatMul backend algorithm (see Performance Optimization) |
183-
| ZENDNNL_PROFILE_LOG_LEVEL | 0-4 | Profiling log level (0=disabled, 4=verbose) |
184-
| ZENDNNL_ENABLE_PROFILER | 0 or 1 | Enable detailed profiling (1=enabled) |
185-
| ZENDNNL_API_LOG_LEVEL | 0-4 | API log level (0=disabled, 4=verbose) |
186-
187-
**Example**:
170+
ZenDNN's LowOHA MatMul supports multiple backend algorithms. For **best performance**, use the **Blocked AOCL DLP** algorithm:
188171

189172
```sh
190-
export OMP_NUM_THREADS=64
191-
export ZENDNNL_MATMUL_ALGO=2 # Use Blocked AOCL BLIS for best performance
192-
./build/bin/llama-cli -m models/llama-2-7b.Q4_0.gguf -p "Test" -n 100
173+
export ZENDNNL_MATMUL_ALGO=1 # Blocked AOCL DLP algo (recommended)
193174
```
194175

195-
## Performance Optimization
196-
197-
### MatMul Algorithm Selection
198-
199-
ZenDNN's LowOHA MatMul supports multiple backend algorithms. For **best performance**, use the **Blocked AOCL BLIS** algorithm:
200-
201-
```sh
202-
export ZENDNNL_MATMUL_ALGO=2 # Blocked AOCL BLIS (recommended)
203-
```
204-
205-
**Available algorithms**:
206-
207-
| Value | Algorithm | Description |
208-
|:-----:|:-----------------------|:----------------------------------------------|
209-
| 0 | Dynamic Dispatch | Automatic backend selection (default) |
210-
| 1 | AOCL BLIS | AOCL BLIS backend |
211-
| 2 | AOCL BLIS Blocked | **Blocked AOCL BLIS (recommended)** |
212-
| 3 | OneDNN | OneDNN backend |
213-
| 4 | OneDNN Blocked | Blocked OneDNN |
214-
| 5 | LibXSMM | LibXSMM backend |
176+
For more details on available algorithms, see the [ZenDNN MatMul Algorithm Documentation](https://github.com/amd/ZenDNN/blob/a18adf8c605fb5f5e52cefd7eda08a7b18febbaf/docs/runtime_env.md#algorithm-details).
215177

216178
### Profiling and Debugging
217179

218-
For detailed profiling and logging options, refer to the [ZenDNN Logging Documentation](https://github.com/amd/ZenDNN/blob/zendnnl/docs/logging.md).
180+
For detailed profiling and logging options, refer to the [ZenDNN Logging Documentation](https://github.com/amd/ZenDNN/blob/a18adf8c605fb5f5e52cefd7eda08a7b18febbaf/docs/logging.md).
219181

220182
## Known Issues
221183

@@ -245,10 +207,9 @@ A: Currently, ZenDNN primarily supports FP32 and BF16 data types. Quantized mode
245207

246208
A: Ensure:
247209
1. You're using an AMD EPYC or Ryzen processor (Zen 2 or newer)
248-
2. `OMP_NUM_THREADS` is set appropriately (physical core count)
249-
3. `ZENDNNL_MATMUL_ALGO=2` is set for best performance (Blocked AOCL BLIS)
250-
4. You're using a sufficiently large model (small models may not benefit as much)
251-
5. Enable profiling to verify ZenDNN MatMul is being called
210+
2. `ZENDNNL_MATMUL_ALGO=1` is set for best performance (Blocked AOCL DLP)
211+
3. You're using a sufficiently large model (small models may not benefit as much)
212+
4. Enable profiling to verify ZenDNN MatMul is being called
252213

253214
### **GitHub Contribution**:
254215
Please add the **[ZenDNN]** prefix/tag in issues/PRs titles to help the ZenDNN-team check/address them without delay.

ggml/src/ggml-zendnn/CMakeLists.txt

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
ggml_add_backend_library(ggml-zendnn
22
ggml-zendnn.cpp)
33

4-
# Get ZenDNN path
54
if (NOT DEFINED ZENDNN_ROOT OR ZENDNN_ROOT STREQUAL "")
65
set(ZENDNN_ROOT "$ENV{ZENDNN_ROOT}")
76
endif()
87

9-
# Check if path is still empty or OFF
8+
if (BUILD_SHARED_LIBS)
9+
set(ZENDNN_SHARED_LIB ON)
10+
set(ZENDNN_ARCHIVE_LIB OFF)
11+
else()
12+
set(ZENDNN_SHARED_LIB OFF)
13+
set(ZENDNN_ARCHIVE_LIB ON)
14+
endif()
15+
16+
# Download and build ZenDNN if not provided
1017
if (NOT ZENDNN_ROOT OR ZENDNN_ROOT STREQUAL "" OR ZENDNN_ROOT STREQUAL "OFF")
1118
message(STATUS "ZENDNN_ROOT not set. Automatically downloading and building ZenDNN...")
1219
message(STATUS "This will take several minutes on first build...")
@@ -21,7 +28,7 @@ if (NOT ZENDNN_ROOT OR ZENDNN_ROOT STREQUAL "" OR ZENDNN_ROOT STREQUAL "OFF")
2128
ExternalProject_Add(
2229
zendnn
2330
GIT_REPOSITORY https://github.com/amd/ZenDNN.git
24-
GIT_TAG 21ce8f7879c86bf3637f707fae6f29e0951db5fe
31+
GIT_TAG a18adf8c605fb5f5e52cefd7eda08a7b18febbaf # ZenDNN-2026-WW08
2532
PREFIX ${ZENDNN_PREFIX}
2633
SOURCE_DIR ${ZENDNN_SOURCE_DIR}
2734
BINARY_DIR ${ZENDNN_BUILD_DIR}
@@ -32,7 +39,9 @@ if (NOT ZENDNN_ROOT OR ZENDNN_ROOT STREQUAL "" OR ZENDNN_ROOT STREQUAL "OFF")
3239
-DZENDNNL_BUILD_DOXYGEN=OFF
3340
-DZENDNNL_BUILD_GTEST=OFF
3441
-DZENDNNL_BUILD_BENCHDNN=OFF
35-
# Enable ALL matmul algorithm backends
42+
-DZENDNNL_DEPENDS_FBGEMM=OFF
43+
-DZENDNNL_LIB_BUILD_ARCHIVE=${ZENDNN_ARCHIVE_LIB}
44+
-DZENDNNL_LIB_BUILD_SHARED=${ZENDNN_SHARED_LIB}
3645
-DZENDNNL_DEPENDS_AOCLDLP=ON
3746
-DZENDNNL_DEPENDS_ONEDNN=ON
3847
-DZENDNNL_DEPENDS_LIBXSMM=ON
@@ -45,47 +54,37 @@ if (NOT ZENDNN_ROOT OR ZENDNN_ROOT STREQUAL "" OR ZENDNN_ROOT STREQUAL "OFF")
4554
LOG_INSTALL ON
4655
)
4756

48-
# Add dependency so ZenDNN builds before our library
4957
add_dependencies(ggml-zendnn zendnn)
50-
51-
# Set ZENDNN_ROOT to the installation directory
5258
set(ZENDNN_ROOT ${ZENDNN_INSTALL_DIR})
53-
5459
message(STATUS "ZenDNN will be built to: ${ZENDNN_ROOT}")
5560
else()
5661
message(STATUS "Using custom ZenDNN installation at: ${ZENDNN_ROOT}")
5762
endif()
5863

59-
# ZenDNN headers + libs
6064
target_include_directories(ggml-zendnn PRIVATE
6165
${ZENDNN_ROOT}/zendnnl/include
62-
${ZENDNN_ROOT}/deps/aocldlp/include
63-
${ZENDNN_ROOT}/deps/aoclutils/include
6466
${ZENDNN_ROOT}/deps/json/include
65-
${ZENDNN_ROOT}/deps/libxsmm/include
67+
${ZENDNN_ROOT}/deps/aoclutils/include
68+
${ZENDNN_ROOT}/deps/aocldlp/include
6669
${ZENDNN_ROOT}/deps/onednn/include
67-
)
70+
${ZENDNN_ROOT}/deps/libxsmm/include)
6871

69-
target_link_directories(ggml-zendnn PRIVATE
70-
${ZENDNN_ROOT}/zendnnl/lib
71-
${ZENDNN_ROOT}/deps/aocldlp/lib
72-
${ZENDNN_ROOT}/deps/aoclutils/lib
73-
${ZENDNN_ROOT}/deps/libxsmm/lib
74-
${ZENDNN_ROOT}/deps/onednn/lib
75-
)
72+
if (ZENDNN_SHARED_LIB)
73+
target_link_directories(ggml-zendnn PRIVATE ${ZENDNN_ROOT}/zendnnl/lib)
74+
target_link_libraries(ggml-zendnn PRIVATE zendnnl)
75+
elseif (ZENDNN_ARCHIVE_LIB)
76+
target_link_libraries(ggml-zendnn PRIVATE
77+
${ZENDNN_ROOT}/zendnnl/lib/libzendnnl_archive.a
78+
${ZENDNN_ROOT}/deps/aoclutils/${CMAKE_INSTALL_LIBDIR}/libaoclutils.a
79+
${ZENDNN_ROOT}/deps/aoclutils/${CMAKE_INSTALL_LIBDIR}/libau_cpuid.a
80+
${ZENDNN_ROOT}/deps/aocldlp/lib/libaocl-dlp.a
81+
${ZENDNN_ROOT}/deps/onednn/${CMAKE_INSTALL_LIBDIR}/libdnnl.a
82+
${ZENDNN_ROOT}/deps/libxsmm/lib/libxsmm.a
83+
${ZENDNN_ROOT}/deps/libxsmm/lib/libxsmmext.a
84+
${ZENDNN_ROOT}/deps/libxsmm/lib/libxsmmnoblas.a)
85+
endif()
7686

77-
target_link_libraries(ggml-zendnn PRIVATE
78-
zendnnl_archive # ZenDNN main
79-
aocl-dlp # AOCL libraries
80-
aoclutils
81-
au_cpuid
82-
dnnl # OneDNN
83-
xsmm # libxsmm small matrix math
84-
xsmmext
85-
xsmmnoblas
86-
m
87-
pthread
88-
)
87+
target_link_libraries(ggml-zendnn PRIVATE m pthread)
8988

9089
if (GGML_OPENMP)
9190
target_link_libraries(ggml-zendnn PRIVATE OpenMP::OpenMP_CXX)

ggml/src/ggml-zendnn/ggml-zendnn.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ static bool ggml_zendnn_matmul(ggml_backend_zendnn_context * ctx, int64_t m, int
4141
const TA * A, int64_t lda, const TB * B, int64_t ldb, TC * C,
4242
int64_t ldc) {
4343

44-
zendnnl::lowoha::lowoha_params params;
44+
zendnnl::lowoha::matmul::matmul_params params;
4545
params.dtypes.src = ggml_to_zendnn_type<TB>();
4646
params.dtypes.wei = ggml_to_zendnn_type<TA>();
4747
params.dtypes.dst = ggml_to_zendnn_type<TC>();
4848
params.num_threads = ctx->n_threads;
4949

50-
zendnnl::lowoha::status_t status = zendnnl::lowoha::matmul_direct(
50+
zendnnl::error_handling::status_t status = zendnnl::lowoha::matmul::matmul_direct(
5151
'r', false, true, // row-major, don't transpose B, transpose A (because it's column-major)
5252
n, // M: rows of B and C
5353
m, // N: cols of A^T and C
@@ -63,7 +63,7 @@ static bool ggml_zendnn_matmul(ggml_backend_zendnn_context * ctx, int64_t m, int
6363
params // params
6464
);
6565

66-
if (status != zendnnl::lowoha::status_t::success) {
66+
if (status != zendnnl::error_handling::status_t::success) {
6767
GGML_LOG_ERROR("%s, ZenDNN matmul failed: status=%d\n", __func__, static_cast<int>(status));
6868
return false;
6969
}

0 commit comments

Comments
 (0)