+1![copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>](/assets/img/avatar_default.png)









Zijun Yu
Sigbjørn Skjæret
Xuejun Zhai
Mustafa Cavus
Mustafa Cavus
Xuejun
Wang Yang
Ravi Panchumarthy
virajwad
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Mostafa Faheem
890f1a27ed
* Add interface is_model_splitted() to check the c-graph is splited or not * Infer and propagate dynamic-dimension indices for all tensors in the GGML graph in api compute_model_outputs() * Only do this for fallback sub graph * Move dynamic dims compute in graph missmatch * ggml-openvino: fix tensor data handling for PERMUTE/VIEW ops in split models * ggml-openvino:add comments * ggml-openvino: override VIEW op_case to 0 for split model inputs * openvino backend: Handle unsupported VIEW shape-mismatch in OpenVINO backend * Enable additional mul_mat tests and add tensor data saving function (#81) * ggml-openvino: fix CONT/TRANSPOSE mapping and improve dynamic-dimension handling * OpenVINO: add NORM/TANH support and rework SOFT_MAX translation * ggml-openvino: extend VIEW handling * Enable -fa off (#118) * Enable --context-shift * Fix llm param compute error for normal softmax not the softmax in attention * OpenVINO backend: fix error for attention size compute in llm param * use tensor->extra in infer_request i/o * OpenVINO backend: refacter the compute_llm_params() func add get_attention_pattern_case to easy extand * OpenVINO backend: clean unused code * 1to1 match op update (#146) * added translate_1to1_match_1_input function and updated gelu and tanh translations * Remove unused translation function calls --------- Co-authored-by: Mustafa Cavus <mustafacavus@intel.com> * initial gemma4 support * removed hardcoded names for kv cache slicing * OpenVINO backend: Add new attention pattern for llm parameters compute * flash attn Q shape static conversion * Remove slice in permute translation when n_seq is 1 * return optional in extract_layer_from_name * OpenVINO backend: refactor VIEW related operation (#148) * OpenVINO backend: refactor VIEW related operation * Enable VIEW handling in following ops * OpenVINO backend does not support GGML_OP_NORM & GGML_OP_L2_NORM with VIEW input accuracy issue from OpenVINO * OpenVINO backend: Add ops l2_norm & pad * OpenVINO backend does not support CPY with non-contiguous data or mismatched types * add op SSM_CONV GATED_DELTA_NET * OpenVINO backend: fix error for bf16 in OV gpu plugin * reverted static Q input shape for attention layer * OpenVINO backend: remove hardcode name inp_tokens, which ignore some leaf case * Disable remote tensor due to bug in ov gpu * Disable n_token > 1 GATED_DELTA_NET on gpu * OpenVINO backend: fix the view op dynamic handling issue in gemma4 & enable view + get_row * OpenVINO backend: clean code * OpenVINO backend: enable view + norm/rms_norm * OpenVINO backend: concat op * OpenVINO backend: argsort op * OpenVINO backend: enable unary + view & GGML_UNARY_OP_SOFTPLUS * Fix issue for test-backend-ops in TOPK_MOE, which compare VIEW ops result, VIEW node in OpenVINO no need compare, the whole graph result is correct * OpenVINO backend: enable sum_rows * OpenVINO backend: enable clamp * OpenVINO backend: enable DIV * OpenVINO backend: enable GGML_OP_MUL_MAT_ID * OpenVINO backend: disable MUL_MAT_ID_FUSION case with large mem needed * OpenVINO backend: Disable GGML_OP_ARGSORT, cause test_backend-ops failed * OpenVINO backend: fix issue in mul_mat_id * OpenVINO backend: Disable DIV with broadcast on GPU * OpenVINO backend: update DIV * use ov internal op GatedDeltaNet * OpenVINO backend: enable llama erch test qwen3next * OpenVINO backend: enable RMS_NORM + VIEW & remove op_case 2 for rope * OpenVINO backend: fix error * suggested changes, need review * suggested changes, need review * OpenVINO backend: clean unused code & fix build warning * OpenVINO backend: enable minicpm3 for arch test * Disable GDN op (#177) * disable gated_delta_net * update stateful_kv_size correctly in mismatch case * OpenVINO backend: enable arch test for qwen3vl * OpenVINO backend: enable cohere2 for arch test * OpenVINO backend: enable t5 for arch test * OpenVINO backend: enable jamba for arch test * OpenVINO backend: remove warning for tmp * OpenVINO backend: enable kimi-linear for arch test * Remove unused * Fix gpt-oss accuracy issue * OpenVINO backend: enable arctic for arch test * OpenVINO backend: enable grok for arch test * Gemma4 initial npu support (#179) * Initiall gemma4 npu support * temp. fix for gemma4 accuracy bug on npu * Remove hardcoded names for npu-fold handling * revert static n tokens for cont translation as it is not needed * removed unused variable * ggml-openvino: add GGML_OPENVINO_ENABLE_CACHE env var to control decoder cache. Add environment variable GGML_OPENVINO_ENABLE_CACHE (default: YES). When set to NO, the decoder_cache is bypassed and models are rebuilt from the cgraph on every inference call in both dynamic and static compute paths. This is useful for debugging and verifying correctness without caching interference. * Revert "Gemma4 initial npu support (#179)" This reverts commit 0d29a9c4a52dc2c8aa52990f1a3854cfb01768ad. * OpenVINO backend: disable debug log print * Update TBB discovery. Delegated to OpenVINOs own config. * OpenVINO backend: GGML_OPENVINO_ENABLE_CACHE YES -> 1 * OpenVINO backend: fallback FLASH_ATTN_EXT in gemma3n to CPU backend * Add raw ov infer profiling metric * Add OV raw infer time metric to static compute path Co-authored-by: virajwad <84867530+virajwad@users.noreply.github.com> * Modify precision of static profiling * update to OV 2026.2, add OV windows CI * fix editorconfig-checks * Initiall gemma4 npu support * temp. fix for gemma4 accuracy bug on npu * Remove hardcoded names for npu-fold handling * revert static n tokens for cont translation as it is not needed * removed unused variable * test-llama-archs fix * Fix gemma4 flash_attn fallback * support im2col * fix code style * disable add_rope_sin_cos optimization * stateless boradcast and rope optimizations * Enable manual gqa attn by default for stateless gpu * manual gqa: fixed static batch * gemma4 llama-bench ctx update fix * Update OV win CI * stateful rope fusion temp. fix * OpenVINO backend: Conslolidate supported ops * Exclude unsupported GGML_OP_SUB cases * Exclude unsupported TOPK_MOE cases * OpenVINO Backend: MUL_MAT enhancements * Update OV CI * support f16 mask input for npu * Make GGML_OPENVINO_* env vars usage uniform Standardize all GGML_OPENVINO_* env flags: positive integers >0 to enable. Unset, empty, =0, or non-numeric values to disable. This fixes cases where text values or empty strings enabled features. * OpenVINO backend: Enhance envvar handling * more cleanup * move ggml_openvino_env_flag to appropriate place * OpenVINO backend: add REPEAT translator, Q5_1 weights, and GLU view-input fix * ggml-openvino: fix -Werror=cast-qual in extract_q5_1_data * Update openvino.Dockerfile Use BuildKit cache mounts for faster Docker rebuilds. Use apt instead of dpkg, remove unused .ddeb downloads, add DLLAMA_BUILD_TESTS=OFF. * ggml-openvino: centralize env var access via *getenv_str/getenv_int helpers Replace getenv and legacy flags with _str and _int helpers.Minor cleanup, doc updates. * OpenVINO backend: Enable GGML_OP_ADD_ID * Uptade openvino backend clamg-format * clang-format * Update OPENVINO.md (#211) * OpenVINO backend: fix accuracy issue for op CONCAT with i64 precision * Remove strict concurrency for gpu-openvino-low-perf * Update openvino CI keynames; add ccache-clear * Apply suggestions from code review Co-authored-by: Sigbjørn Skjæret <1629204+CISC@users.noreply.github.com> * Fix formatting --------- Co-authored-by: Xuejun Zhai <Xuejun.Zhai@intel.com> Co-authored-by: Mustafa Cavus <mustafa.cavus@intel.com> Co-authored-by: Mustafa Cavus <mustafacavus@intel.com> Co-authored-by: Xuejun <XuejunZhai@intel.com> Co-authored-by: Wang Yang <yang4.wang@intel.com> Co-authored-by: Ravi Panchumarthy <ravi.panchumarthy@intel.com> Co-authored-by: virajwad <84867530+virajwad@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Mostafa Faheem <mostafaaafaheem@gmail.com> Co-authored-by: Sigbjørn Skjæret <1629204+CISC@users.noreply.github.com>
204 lines
9.0 KiB
C++
204 lines
9.0 KiB
C++
#pragma once
|
|
|
|
#include "ggml.h"
|
|
#include "openvino/runtime/core.hpp"
|
|
|
|
#define CL_TARGET_OPENCL_VERSION 300
|
|
#include <CL/cl.h>
|
|
|
|
#include <cstdlib>
|
|
#include <memory>
|
|
#include <openvino/core/node.hpp>
|
|
#include <openvino/runtime/remote_context.hpp>
|
|
#include <openvino/runtime/tensor.hpp>
|
|
#include <optional>
|
|
#include <string>
|
|
|
|
// ExtraQuantType enum - defines requantization target formats
|
|
enum class ExtraQuantType { F16, Q4_0_C, Q8_1_C, Q4_0_128, Q8_0_C, Q8_0_32 };
|
|
|
|
ov::Core & ov_singleton_core();
|
|
|
|
// Get the remote context for the current device (returns empty optional for CPU)
|
|
std::optional<ov::RemoteContext> ggml_openvino_get_remote_context();
|
|
|
|
// Get the compile config for the current device
|
|
const ov::AnyMap & ggml_openvino_get_compile_config();
|
|
|
|
// Get the OpenCL command queue for GPU operations (returns nullptr for CPU/NPU)
|
|
cl_command_queue ggml_openvino_get_cl_queue();
|
|
|
|
// Intel USM extension function type
|
|
typedef cl_int(CL_API_CALL * clEnqueueMemFillINTEL_fn)(cl_command_queue queue,
|
|
void * dst_ptr,
|
|
const void * pattern,
|
|
size_t pattern_size,
|
|
size_t size,
|
|
cl_uint num_events_in_wait_list,
|
|
const cl_event * event_wait_list,
|
|
cl_event * event);
|
|
|
|
typedef cl_int(CL_API_CALL * clEnqueueMemcpyINTEL_fn)(cl_command_queue queue,
|
|
cl_bool blocking,
|
|
void * dst_ptr,
|
|
const void * src_ptr,
|
|
size_t size,
|
|
cl_uint num_events_in_wait_list,
|
|
const cl_event * event_wait_list,
|
|
cl_event * event);
|
|
|
|
// Get the clEnqueueMemFillINTEL function pointer (returns nullptr if not available)
|
|
clEnqueueMemFillINTEL_fn ggml_openvino_get_clEnqueueMemFillINTEL();
|
|
|
|
// Get the clEnqueueMemcpyINTEL function pointer (returns nullptr if not available)
|
|
clEnqueueMemcpyINTEL_fn ggml_openvino_get_clEnqueueMemcpyINTEL();
|
|
|
|
// =====================================================
|
|
// Global Device Configuration (singleton)
|
|
// =====================================================
|
|
// Initialized once during backend init from GGML_OPENVINO_DEVICE env var
|
|
|
|
struct ggml_openvino_device_config {
|
|
std::string device_name = "CPU";
|
|
bool is_npu = false;
|
|
bool initialized = false;
|
|
std::optional<ov::RemoteContext> remote_context;
|
|
ov::AnyMap compile_config;
|
|
std::unordered_map<std::string, std::string> environment_variables;
|
|
cl_command_queue cl_queue = nullptr;
|
|
|
|
void init();
|
|
~ggml_openvino_device_config();
|
|
};
|
|
|
|
// Get the global device config singleton
|
|
ggml_openvino_device_config & ggml_openvino_get_device_config();
|
|
|
|
// Initialize device config (call during backend init)
|
|
void ggml_openvino_init_device_config();
|
|
|
|
// Get the device name
|
|
const std::string & ggml_openvino_get_device_name();
|
|
|
|
// Environment variable accessors. All GGML_OPENVINO_* env vars are read once
|
|
// during backend init and cached on the device config; consumers must go
|
|
// through these helpers (never call ::getenv directly) so behavior stays
|
|
// consistent and centralized.
|
|
//
|
|
// Use ggml_openvino_getenv_str() for string / path values
|
|
// (e.g. GGML_OPENVINO_DEVICE, GGML_OPENVINO_CACHE_DIR). The optional
|
|
// default_value is returned when the var is unset or empty.
|
|
//
|
|
// Use ggml_openvino_getenv_int() for boolean toggles and integer settings.
|
|
// It returns std::atoi(value) when set, otherwise default_value. For
|
|
// boolean use, `if (ggml_openvino_getenv_int(name))` is true iff the value
|
|
// is a non-zero integer (so "0" disables, "1" enables).
|
|
const char * ggml_openvino_getenv_str(const char * var, const char * default_value = nullptr);
|
|
int ggml_openvino_getenv_int(const char * var, int default_value = 0);
|
|
|
|
// Check if running on NPU
|
|
bool ggml_openvino_is_npu();
|
|
|
|
// Get requantization type for a tensor type (returns nullopt if no requant needed)
|
|
std::optional<ExtraQuantType> ggml_openvino_get_requant_type(const ggml_tensor * tensor, bool no_requant = false);
|
|
|
|
// =====================================================
|
|
// OpenVINO Tensor Extra Types
|
|
// =====================================================
|
|
// These types are stored in tensor->extra by the OpenVINO backend buffer.
|
|
// They allow:
|
|
// 1. Pre-built ov::Constant nodes for weights (avoiding memcpy during graph construction)
|
|
// 2. ov::Tensor wrappers for KV cache / compute tensors (for direct use with infer_request)
|
|
|
|
// Base class for OpenVINO tensor extra data
|
|
struct ggml_openvino_extra_base {
|
|
enum class Type { WEIGHT, QUANTIZED_WEIGHT, TENSOR };
|
|
Type type;
|
|
virtual ~ggml_openvino_extra_base() = default;
|
|
protected:
|
|
explicit ggml_openvino_extra_base(Type t) : type(t) {}
|
|
};
|
|
|
|
// Extra data for F16/F32/BF16 weight tensors - stores the pre-built weight node
|
|
struct ggml_openvino_weight_extra : public ggml_openvino_extra_base {
|
|
ov::Tensor weights; // The underlying weight data tensor
|
|
std::shared_ptr<ov::Node> weight_node; // Pre-built OpenVINO weight node
|
|
|
|
ggml_openvino_weight_extra(ov::Tensor w, std::shared_ptr<ov::Node> n) :
|
|
ggml_openvino_extra_base(Type::WEIGHT),
|
|
weights(std::move(w)),
|
|
weight_node(std::move(n)) {}
|
|
};
|
|
|
|
// Extra data for quantized weight tensors - stores extracted weights/scales/zp and weight node
|
|
struct ggml_openvino_quantized_weight_extra : public ggml_openvino_extra_base {
|
|
ov::Tensor weights; // U4 or U8 extracted weights
|
|
ov::Tensor scales; // F16 scales
|
|
ov::Tensor zp; // U4 or U8 zero points (same type as weights)
|
|
std::shared_ptr<ov::Node> weight_node; // Pre-built OpenVINO weight subgraph
|
|
|
|
ggml_openvino_quantized_weight_extra(ov::Tensor w, ov::Tensor s, ov::Tensor z, std::shared_ptr<ov::Node> n) :
|
|
ggml_openvino_extra_base(Type::QUANTIZED_WEIGHT),
|
|
weights(std::move(w)),
|
|
scales(std::move(s)),
|
|
zp(std::move(z)),
|
|
weight_node(std::move(n)) {}
|
|
};
|
|
|
|
// Extra data for KV cache / compute tensors - stores ov::Tensor for infer_request
|
|
struct ggml_openvino_tensor_extra : public ggml_openvino_extra_base {
|
|
std::shared_ptr<ov::Tensor> tensor; // For direct use with infer_request
|
|
|
|
explicit ggml_openvino_tensor_extra(std::shared_ptr<ov::Tensor> t) :
|
|
ggml_openvino_extra_base(Type::TENSOR),
|
|
tensor(std::move(t)) {}
|
|
};
|
|
|
|
// =====================================================
|
|
// Extracted Size Calculation for Quantized Tensors
|
|
// =====================================================
|
|
// For quantized tensors, we need extra space to store extracted weights, scales, and zero points.
|
|
// Returns the total size needed in the buffer for extracted data.
|
|
|
|
struct ggml_openvino_extracted_layout {
|
|
size_t total_size = 0; // Total bytes needed
|
|
size_t weights_offset = 0; // Offset to weights in buffer
|
|
size_t weights_size = 0; // Size of weights in bytes
|
|
size_t scales_offset = 0; // Offset to scales in buffer
|
|
size_t scales_size = 0; // Size of scales in bytes
|
|
size_t zp_offset = 0; // Offset to zero points in buffer
|
|
size_t zp_size = 0; // Size of zero points in bytes (U4 or U8)
|
|
bool is_u4; // true for U4 weights, false for U8
|
|
int64_t weights_per_block; // weights per scale/zp block
|
|
bool is_symmetric; // true for symmetric quantization
|
|
|
|
// Requantization info
|
|
bool is_requant = false; // true if this tensor needs requantization
|
|
std::optional<ExtraQuantType> requant_type; // target requant type if is_requant
|
|
};
|
|
|
|
// Calculate the buffer layout for extracted quantized data
|
|
ggml_openvino_extracted_layout ggml_openvino_get_extracted_layout(const ggml_tensor * tensor, bool use_bias = false);
|
|
|
|
ggml_openvino_tensor_extra * ggml_openvino_create_tensor_extra(const ggml_tensor * tensor, bool is_remote);
|
|
|
|
// Check if a tensor's buffer uses remote (device) memory (e.g. GPU USM)
|
|
bool ggml_openvino_buffer_is_remote(const ggml_tensor * tensor);
|
|
|
|
// Register an extra with the tensor's OpenVINO buffer context for proper lifetime management.
|
|
// This sets tensor->extra and tracks the extra in the buffer context for cleanup.
|
|
void ggml_openvino_buffer_register_extra(ggml_tensor * tensor, ggml_openvino_extra_base * extra);
|
|
|
|
// =====================================================
|
|
// OpenVINO Backend Context and Interface
|
|
// =====================================================
|
|
struct ggml_backend_openvino_context {
|
|
int device = 0;
|
|
std::string name = "OpenVINO";
|
|
std::string description = "OpenVINO Backend Context";
|
|
|
|
std::shared_ptr<void> runtime_context = nullptr;
|
|
|
|
ggml_backend_openvino_context() = default;
|
|
};
|