Skip to content

Commit 56c3672

Browse files
committed
opencl: check that the compiler accepts the Adreno large-buffer option
Advertising cl_qcom_large_buffer and being able to build for it are different questions. The Adreno 850 (compiler E17.51) reports the extension and then rejects -qcom-enable-large-buffer with "invalid option", so every kernel build fails and the process exits. Setting GGML_OPENCL_ADRENO_USE_LARGE_BUFFER=1 there does not cost throughput, it stops the backend working at all. Build a trivial program once with the option and keep large-buffer mode only if that succeeds, logging the downgrade so the fallback is visible. This sits beside the existing check for whether the driver advertises the extension at all, which has the same shape. Costs one small program build, and only when the variable is set. On the 850, test-backend-ops -o CPY with the variable set goes from a compile error and exit 1 to 138/138 passing.
1 parent 3f545be commit 56c3672

1 file changed

Lines changed: 19 additions & 0 deletions

File tree

ggml/src/ggml-opencl/ggml-opencl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5752,6 +5752,21 @@ static std::vector<ggml_backend_device> ggml_opencl_probe_devices(ggml_backend_r
57525752
return found_devices;
57535753
}
57545754

5755+
// Advertising an extension and being able to build for it are different questions: a driver can
5756+
// report cl_qcom_large_buffer and then reject -qcom-enable-large-buffer as an invalid option,
5757+
// which fails every kernel build and takes the process down. Build a trivial program and ask.
5758+
static bool ggml_opencl_compiler_accepts(cl_context context, cl_device_id device, const char * opt) {
5759+
const char * src = "__kernel void ggml_cl_probe(void) {}\n";
5760+
cl_int err = CL_SUCCESS;
5761+
cl_program p = clCreateProgramWithSource(context, 1, &src, NULL, &err);
5762+
if (err != CL_SUCCESS || p == NULL) {
5763+
return false;
5764+
}
5765+
err = clBuildProgram(p, 1, &device, opt, NULL, NULL);
5766+
clReleaseProgram(p);
5767+
return err == CL_SUCCESS;
5768+
}
5769+
57555770
static void ggml_opencl_print_backend_info(ggml_backend_opencl_device_context * dev_ctx) {
57565771
GGML_ASSERT(dev_ctx);
57575772
GGML_ASSERT(dev_ctx->backend_ctx);
@@ -5807,6 +5822,10 @@ static void ggml_opencl_print_backend_info(ggml_backend_opencl_device_context *
58075822
if (!backend_ctx->adreno_has_large_buffer) {
58085823
GGML_LOG_INFO("ggml_opencl: Adreno large buffer requested but not supported by driver, will use regular buffer\n");
58095824
backend_ctx->adreno_use_large_buffer = false;
5825+
} else if (!ggml_opencl_compiler_accepts(backend_ctx->context, backend_ctx->device,
5826+
" -qcom-enable-large-buffer ")) {
5827+
GGML_LOG_INFO("ggml_opencl: Adreno large buffer advertised but rejected by the compiler, will use regular buffer\n");
5828+
backend_ctx->adreno_use_large_buffer = false;
58105829
} else {
58115830
GGML_LOG_INFO("ggml_opencl: Adreno large buffer enabled\n");
58125831
}

0 commit comments

Comments
 (0)