Commit 52c9bad94 for llama.cpp
commit 52c9bad94678485e82362331cb62b4f71fd3f0e6
Author: lhez <lih@qti.qualcomm.com>
Date: Fri Nov 6 01:36:27 2026 -0800
opencl: support repeat for f16, i32, i16, bf16 (#31782)
* opencl: add f16 repeat
Assisted-by: Codex
* opencl: support repeat for i32, i16, bf16
Assisted-by: Codex
* opencl: update ops
Assisted-by: Codex
diff --git a/docs/ops.md b/docs/ops.md
index 351093cfa..e9f4e8adb 100644
--- a/docs/ops.md
+++ b/docs/ops.md
@@ -91,7 +91,7 @@ Legend:
| POOL_2D | ❌ | 🟡 | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
| REGLU | ❌ | ✅ | ✅ | ✅ | 🟡 | 🟡 | 🟡 | 🟡 | ✅ | ✅ | ✅ | ❌ | ❌ |
| RELU | ❌ | ✅ | ✅ | 🟡 | 🟡 | 🟡 | ✅ | 🟡 | ✅ | ✅ | ✅ | ❌ | ❌ |
-| REPEAT | ❌ | ✅ | ✅ | 🟡 | 🟡 | 🟡 | ✅ | 🟡 | ✅ | ✅ | 🟡 | ❌ | ❌ |
+| REPEAT | ❌ | ✅ | ✅ | 🟡 | 🟡 | 🟡 | ✅ | ✅ | ✅ | ✅ | 🟡 | ❌ | ❌ |
| REPEAT_BACK | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
| RMS_NORM | ❌ | ✅ | ✅ | ✅ | 🟡 | ✅ | ✅ | 🟡 | ✅ | ✅ | ✅ | ❌ | ❌ |
| RMS_NORM_BACK | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
diff --git a/docs/ops/OpenCL.csv b/docs/ops/OpenCL.csv
index db66c5655..4a6e90456 100644
--- a/docs/ops/OpenCL.csv
+++ b/docs/ops/OpenCL.csv
@@ -7682,19 +7682,19 @@
"OpenCL","REPEAT","type=f32,ne=[10,5,4,1],nr=[1,2,1,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT","type=f32,ne=[10,5,4,1],nr=[1,1,2,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT","type=f32,ne=[10,5,4,1],nr=[1,1,1,2]","support","1","yes","OpenCL"
-"OpenCL","REPEAT","type=f16,ne=[10,5,4,1],nr=[2,1,1,1]","support","0","no","OpenCL"
-"OpenCL","REPEAT","type=i32,ne=[10,5,4,1],nr=[2,1,1,1]","support","0","no","OpenCL"
-"OpenCL","REPEAT","type=i16,ne=[10,5,4,1],nr=[1,1,1,2]","support","0","no","OpenCL"
-"OpenCL","REPEAT","type=bf16,ne=[10,5,4,1],nr=[2,1,1,1]","support","0","no","OpenCL"
+"OpenCL","REPEAT","type=f16,ne=[10,5,4,1],nr=[2,1,1,1]","support","1","yes","OpenCL"
+"OpenCL","REPEAT","type=i32,ne=[10,5,4,1],nr=[2,1,1,1]","support","1","yes","OpenCL"
+"OpenCL","REPEAT","type=i16,ne=[10,5,4,1],nr=[1,1,1,2]","support","1","yes","OpenCL"
+"OpenCL","REPEAT","type=bf16,ne=[10,5,4,1],nr=[2,1,1,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT","type=f32,ne=[10,5,4,3],nr=[1,1,1,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT","type=f32,ne=[10,5,4,3],nr=[2,1,1,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT","type=f32,ne=[10,5,4,3],nr=[1,2,1,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT","type=f32,ne=[10,5,4,3],nr=[1,1,2,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT","type=f32,ne=[10,5,4,3],nr=[1,1,1,2]","support","1","yes","OpenCL"
-"OpenCL","REPEAT","type=f16,ne=[10,5,4,3],nr=[2,1,1,1]","support","0","no","OpenCL"
-"OpenCL","REPEAT","type=i32,ne=[10,5,4,3],nr=[2,1,1,1]","support","0","no","OpenCL"
-"OpenCL","REPEAT","type=i16,ne=[10,5,4,3],nr=[1,1,1,2]","support","0","no","OpenCL"
-"OpenCL","REPEAT","type=bf16,ne=[10,5,4,3],nr=[2,1,1,1]","support","0","no","OpenCL"
+"OpenCL","REPEAT","type=f16,ne=[10,5,4,3],nr=[2,1,1,1]","support","1","yes","OpenCL"
+"OpenCL","REPEAT","type=i32,ne=[10,5,4,3],nr=[2,1,1,1]","support","1","yes","OpenCL"
+"OpenCL","REPEAT","type=i16,ne=[10,5,4,3],nr=[1,1,1,2]","support","1","yes","OpenCL"
+"OpenCL","REPEAT","type=bf16,ne=[10,5,4,3],nr=[2,1,1,1]","support","1","yes","OpenCL"
"OpenCL","REPEAT_BACK","type=f32,ne=[8,6,4,2],nr=[1,1,1,1],v=0","support","0","no","OpenCL"
"OpenCL","REPEAT_BACK","type=f32,ne=[8,6,4,2],nr=[2,1,1,1],v=0","support","0","no","OpenCL"
"OpenCL","REPEAT_BACK","type=f32,ne=[8,6,4,2],nr=[1,2,1,1],v=0","support","0","no","OpenCL"
diff --git a/ggml/src/ggml-opencl/ggml-opencl.cpp b/ggml/src/ggml-opencl/ggml-opencl.cpp
index 33457f990..e0ee5518b 100644
--- a/ggml/src/ggml-opencl/ggml-opencl.cpp
+++ b/ggml/src/ggml-opencl/ggml-opencl.cpp
@@ -1110,7 +1110,7 @@ struct ggml_backend_opencl_context {
size_t local_dsv4_hc_pre = 0;
size_t local_dsv4_hc_post[2] = {};
cl_kernel kernel_cumsum_blk, kernel_cumsum_add;
- cl_kernel kernel_repeat_f32;
+ cl_kernel kernel_repeat_f32, kernel_repeat_f16, kernel_repeat_i32;
cl_kernel kernel_pad;
cl_kernel kernel_tanh_f32, kernel_tanh_f32_4, kernel_tanh_f32_nc;
cl_kernel kernel_tanh_f16, kernel_tanh_f16_4, kernel_tanh_f16_nc;
@@ -4345,6 +4345,8 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
cl_program prog =
build_program_from_source(backend_ctx, kernel_src.c_str(), compile_opts);
CL_CHECK((backend_ctx->kernel_repeat_f32 = clCreateKernel(prog, "kernel_repeat_f32", &err), err));
+ CL_CHECK((backend_ctx->kernel_repeat_f16 = clCreateKernel(prog, "kernel_repeat_f16", &err), err));
+ CL_CHECK((backend_ctx->kernel_repeat_i32 = clCreateKernel(prog, "kernel_repeat_i32", &err), err));
CL_CHECK(clReleaseProgram(prog));
GGML_LOG_CONT(".");
}
@@ -11800,7 +11802,16 @@ static bool ggml_opencl_supports_op(ggml_backend_dev_t dev, const struct ggml_te
case GGML_OP_L2_NORM:
return ggml_is_contiguous_rows(op->src[0]);
case GGML_OP_REPEAT:
- return op->src[0]->type == GGML_TYPE_F32 && op->type == GGML_TYPE_F32; // Assuming F32 for now, can be expanded
+ switch (op->type) {
+ case GGML_TYPE_F32:
+ case GGML_TYPE_F16:
+ case GGML_TYPE_I32:
+ case GGML_TYPE_I16:
+ case GGML_TYPE_BF16:
+ return op->src[0]->type == op->type;
+ default:
+ return false;
+ }
case GGML_OP_PAD:
// TODO: add circular padding support for opencl, see https://github.com/ggml-org/llama.cpp/pull/16985
if (ggml_get_op_params_i32(op, 8) != 0) {
@@ -20819,7 +20830,22 @@ static void ggml_cl_repeat(ggml_backend_t backend, const ggml_tensor * src0, con
const cl_ulong nb2 = dst->nb[2];
const cl_ulong nb3 = dst->nb[3];
- cl_kernel kernel = backend_ctx->kernel_repeat_f32;
+ cl_kernel kernel;
+ switch (src0->type) {
+ case GGML_TYPE_F32:
+ kernel = backend_ctx->kernel_repeat_f32;
+ break;
+ case GGML_TYPE_F16:
+ case GGML_TYPE_I16:
+ case GGML_TYPE_BF16:
+ kernel = backend_ctx->kernel_repeat_f16;
+ break;
+ case GGML_TYPE_I32:
+ kernel = backend_ctx->kernel_repeat_i32;
+ break;
+ default:
+ GGML_ABORT("unsupported type");
+ }
CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
diff --git a/ggml/src/ggml-opencl/kernels/repeat.cl b/ggml/src/ggml-opencl/kernels/repeat.cl
index 53951a554..88dee31cc 100644
--- a/ggml/src/ggml-opencl/kernels/repeat.cl
+++ b/ggml/src/ggml-opencl/kernels/repeat.cl
@@ -1,38 +1,43 @@
-kernel void kernel_repeat_f32(
- global const char * src0,
- ulong offset0,
- global char * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3
-) {
- src0 = src0 + offset0;
- dst = dst + offsetd;
-
- const int i3 = get_group_id(2);
- const int i2 = get_group_id(1);
- const int i1 = get_group_id(0);
-
- const int i03 = i3%ne03;
- const int i02 = i2%ne02;
- const int i01 = i1%ne01;
-
- global const char * src0_ptr = src0 + i03*nb03 + i02*nb02 + i01*nb01;
- global char * dst_ptr = dst + i3*nb3 + i2*nb2 + i1*nb1;
-
- for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) {
- const int i00 = i0%ne00;
- *((global float *)(dst_ptr + i0*nb0)) = *((global float *)(src0_ptr + i00*nb00));
- }
+#define KERNEL_REPEAT(SUFFIX, T) \
+kernel void kernel_repeat_##SUFFIX( \
+ global const char * src0, \
+ ulong offset0, \
+ global char * dst, \
+ ulong offsetd, \
+ int ne00, \
+ int ne01, \
+ int ne02, \
+ int ne03, \
+ ulong nb00, \
+ ulong nb01, \
+ ulong nb02, \
+ ulong nb03, \
+ int ne0, \
+ ulong nb0, \
+ ulong nb1, \
+ ulong nb2, \
+ ulong nb3 \
+) { \
+ src0 = src0 + offset0; \
+ dst = dst + offsetd; \
+ \
+ const int i3 = get_group_id(2); \
+ const int i2 = get_group_id(1); \
+ const int i1 = get_group_id(0); \
+ \
+ const int i03 = i3%ne03; \
+ const int i02 = i2%ne02; \
+ const int i01 = i1%ne01; \
+ \
+ global const char * src0_ptr = src0 + i03*nb03 + i02*nb02 + i01*nb01; \
+ global char * dst_ptr = dst + i3*nb3 + i2*nb2 + i1*nb1; \
+ \
+ for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) { \
+ const int i00 = i0%ne00; \
+ *((global T *)(dst_ptr + i0*nb0)) = *((global T *)(src0_ptr + i00*nb00)); \
+ } \
}
+
+KERNEL_REPEAT(f32, float)
+KERNEL_REPEAT(f16, ushort)
+KERNEL_REPEAT(i32, int)