char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Zijun YuOpenVINO: Qwen3.5, memory optimization, and test-recurrent-state-rollback (#26952)aee56b3ab

char/aliceai-t5-moe
9.7 KiB216 linesraw
1#pragma once
2
3#include "ggml.h"
4#include "openvino/runtime/core.hpp"
5
6#define CL_TARGET_OPENCL_VERSION 300
7#include <CL/cl.h>
8
9#include <cstdlib>
10#include <memory>
11#include <openvino/core/node.hpp>
12#include <openvino/runtime/remote_context.hpp>
13#include <openvino/runtime/tensor.hpp>
14#include <optional>
15#include <string>
16
17// ExtraQuantType enum - defines requantization target formats
18enum class ExtraQuantType { F16, Q4_0_C, Q8_1_C, Q4_0_128, Q8_0_C, Q8_0_32 };
19
20ov::Core & ov_singleton_core();
21
22// Get the remote context for the current device (returns empty optional for CPU)
23std::optional<ov::RemoteContext> ggml_openvino_get_remote_context();
24
25// Get the compile config for the current device
26const ov::AnyMap & ggml_openvino_get_compile_config();
27
28// Get the OpenCL command queue for GPU operations (returns nullptr for CPU/NPU)
29cl_command_queue ggml_openvino_get_cl_queue();
30
31// Intel USM extension function type
32typedef cl_int(CL_API_CALL * clEnqueueMemFillINTEL_fn)(cl_command_queue queue,
33                                                       void * dst_ptr,
34                                                       const void * pattern,
35                                                       size_t pattern_size,
36                                                       size_t size,
37                                                       cl_uint num_events_in_wait_list,
38                                                       const cl_event * event_wait_list,
39                                                       cl_event * event);
40
41typedef cl_int(CL_API_CALL * clEnqueueMemcpyINTEL_fn)(cl_command_queue queue,
42                                                      cl_bool blocking,
43                                                      void * dst_ptr,
44                                                      const void * src_ptr,
45                                                      size_t size,
46                                                      cl_uint num_events_in_wait_list,
47                                                      const cl_event * event_wait_list,
48                                                      cl_event * event);
49
50// Get the clEnqueueMemFillINTEL function pointer (returns nullptr if not available)
51clEnqueueMemFillINTEL_fn ggml_openvino_get_clEnqueueMemFillINTEL();
52
53// Get the clEnqueueMemcpyINTEL function pointer (returns nullptr if not available)
54clEnqueueMemcpyINTEL_fn ggml_openvino_get_clEnqueueMemcpyINTEL();
55
56// =====================================================
57// Global Device Configuration (singleton)
58// =====================================================
59// Initialized once during backend init from GGML_OPENVINO_DEVICE env var
60
61struct ggml_openvino_device_config {
62    std::string device_name = "CPU";
63    bool is_npu = false;
64    bool initialized = false;
65    std::optional<ov::RemoteContext> remote_context;
66    ov::AnyMap compile_config;
67    std::unordered_map<std::string, std::string> environment_variables;
68    cl_command_queue cl_queue = nullptr;
69
70    void init();
71    ~ggml_openvino_device_config();
72};
73
74// Get the global device config singleton
75ggml_openvino_device_config & ggml_openvino_get_device_config();
76
77// Initialize device config (call during backend init)
78void ggml_openvino_init_device_config();
79
80// Get the device name
81const std::string & ggml_openvino_get_device_name();
82
83// Environment variable accessors. All GGML_OPENVINO_* env vars are read once
84// during backend init and cached on the device config; consumers must go
85// through these helpers (never call ::getenv directly) so behavior stays
86// consistent and centralized.
87//
88// Use ggml_openvino_getenv_str() for string / path values
89// (e.g. GGML_OPENVINO_DEVICE, GGML_OPENVINO_CACHE_DIR). The optional
90// default_value is returned when the var is unset or empty.
91//
92// Use ggml_openvino_getenv_int() for boolean toggles and integer settings.
93// It returns std::atoi(value) when set, otherwise default_value. For
94// boolean use, `if (ggml_openvino_getenv_int(name))` is true iff the value
95// is a non-zero integer (so "0" disables, "1" enables).
96const char * ggml_openvino_getenv_str(const char * var, const char * default_value = nullptr);
97int ggml_openvino_getenv_int(const char * var, int default_value = 0);
98
99// Memory optimization toggles. GGML_OPENVINO_MEMORY_OPTIMIZE is an umbrella
100// switch; the fine-grained env vars still override it when explicitly set.
101bool ggml_openvino_reduce_compile_mem_enabled();
102bool ggml_openvino_release_weights_enabled(const std::string & device);
103
104// Check if running on NPU
105bool ggml_openvino_is_npu();
106
107// Host weight-buffer release (GGML_OPENVINO_RELEASE_WEIGHTS, GPU only).
108// register: record a host weight buffer (idempotent per data pointer).
109// release:  madvise(MADV_DONTNEED) all registered buffers, dropping their RSS.
110// released: true once release has run (used to fail-fast on post-release recompile).
111void ggml_openvino_register_weight_buffer(void * data, size_t size);
112void ggml_openvino_release_weight_buffers();
113bool ggml_openvino_weight_buffers_released();
114
115// Get requantization type for a tensor type (returns nullopt if no requant needed)
116std::optional<ExtraQuantType> ggml_openvino_get_requant_type(const ggml_tensor * tensor, bool no_requant = false);
117
118// =====================================================
119// OpenVINO Tensor Extra Types
120// =====================================================
121// These types are stored in tensor->extra by the OpenVINO backend buffer.
122// They allow:
123// 1. Pre-built ov::Constant nodes for weights (avoiding memcpy during graph construction)
124// 2. ov::Tensor wrappers for KV cache / compute tensors (for direct use with infer_request)
125
126// Base class for OpenVINO tensor extra data
127struct ggml_openvino_extra_base {
128    enum class Type { WEIGHT, QUANTIZED_WEIGHT, TENSOR };
129    Type type;
130    virtual ~ggml_openvino_extra_base() = default;
131protected:
132    explicit ggml_openvino_extra_base(Type t) : type(t) {}
133};
134
135// Extra data for F16/F32/BF16 weight tensors - stores the pre-built weight node
136struct ggml_openvino_weight_extra : public ggml_openvino_extra_base {
137    ov::Tensor weights;                     // The underlying weight data tensor
138    std::shared_ptr<ov::Node> weight_node;  // Pre-built OpenVINO weight node
139
140    ggml_openvino_weight_extra(ov::Tensor w, std::shared_ptr<ov::Node> n) :
141        ggml_openvino_extra_base(Type::WEIGHT),
142        weights(std::move(w)),
143        weight_node(std::move(n)) {}
144};
145
146// Extra data for quantized weight tensors - stores extracted weights/scales/zp and weight node
147struct ggml_openvino_quantized_weight_extra : public ggml_openvino_extra_base {
148    ov::Tensor weights;                     // U4 or U8 extracted weights
149    ov::Tensor scales;                      // F16 scales
150    ov::Tensor zp;                          // U4 or U8 zero points (same type as weights)
151    std::shared_ptr<ov::Node> weight_node;  // Pre-built OpenVINO weight subgraph
152
153    ggml_openvino_quantized_weight_extra(ov::Tensor w, ov::Tensor s, ov::Tensor z, std::shared_ptr<ov::Node> n) :
154        ggml_openvino_extra_base(Type::QUANTIZED_WEIGHT),
155        weights(std::move(w)),
156        scales(std::move(s)),
157        zp(std::move(z)),
158        weight_node(std::move(n)) {}
159};
160
161// Extra data for KV cache / compute tensors - stores ov::Tensor for infer_request
162struct ggml_openvino_tensor_extra : public ggml_openvino_extra_base {
163    std::shared_ptr<ov::Tensor> tensor;  // For direct use with infer_request
164
165    explicit ggml_openvino_tensor_extra(std::shared_ptr<ov::Tensor> t) :
166        ggml_openvino_extra_base(Type::TENSOR),
167        tensor(std::move(t)) {}
168};
169
170// =====================================================
171// Extracted Size Calculation for Quantized Tensors
172// =====================================================
173// For quantized tensors, we need extra space to store extracted weights, scales, and zero points.
174// Returns the total size needed in the buffer for extracted data.
175
176struct ggml_openvino_extracted_layout {
177    size_t total_size = 0;      // Total bytes needed
178    size_t weights_offset = 0;  // Offset to weights in buffer
179    size_t weights_size = 0;    // Size of weights in bytes
180    size_t scales_offset = 0;   // Offset to scales in buffer
181    size_t scales_size = 0;     // Size of scales in bytes
182    size_t zp_offset = 0;       // Offset to zero points in buffer
183    size_t zp_size = 0;         // Size of zero points in bytes (U4 or U8)
184    bool is_u4;                 // true for U4 weights, false for U8
185    int64_t weights_per_block;  // weights per scale/zp block
186    bool is_symmetric;          // true for symmetric quantization
187
188    // Requantization info
189    bool is_requant = false;                     // true if this tensor needs requantization
190    std::optional<ExtraQuantType> requant_type;  // target requant type if is_requant
191};
192
193// Calculate the buffer layout for extracted quantized data
194ggml_openvino_extracted_layout ggml_openvino_get_extracted_layout(const ggml_tensor * tensor, bool use_bias = false);
195
196ggml_openvino_tensor_extra * ggml_openvino_create_tensor_extra(const ggml_tensor * tensor, bool is_remote);
197
198// Check if a tensor's buffer uses remote (device) memory (e.g. GPU USM)
199bool ggml_openvino_buffer_is_remote(const ggml_tensor * tensor);
200
201// Register an extra with the tensor's OpenVINO buffer context for proper lifetime management.
202// This sets tensor->extra and tracks the extra in the buffer context for cleanup.
203void ggml_openvino_buffer_register_extra(ggml_tensor * tensor, ggml_openvino_extra_base * extra);
204
205// =====================================================
206// OpenVINO Backend Context and Interface
207// =====================================================
208struct ggml_backend_openvino_context {
209    int device = 0;
210    std::string name = "OpenVINO";
211    std::string description = "OpenVINO Backend Context";
212
213    std::shared_ptr<void> runtime_context = nullptr;
214
215    ggml_backend_openvino_context() = default;
216};