Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify use of OpenCL extensions #257

Open
VarLad opened this issue Oct 14, 2024 · 5 comments
Open

Simplify use of OpenCL extensions #257

VarLad opened this issue Oct 14, 2024 · 5 comments

Comments

@VarLad
Copy link

VarLad commented Oct 14, 2024

could not load symbol "clHostMemAllocINTEL":

~/.julia/artifacts/c99d19d2f6dd75af3e997c4ecc4ac85e410cb7a7/lib/libOpenCL.so: undefined symbol: clHostMemAllocINTEL

To reproduce:

using OpenCL
error = Ref{Int32}()
al = cl.clHostMemAllocINTEL(cl.context(), C_NULL, 10000, 1, error)

Could this be an issue in using the function itself (wrong parameters or something)? 🤔

@maleadt maleadt changed the title Packaged JLL might not include USM functions ICD JLL does not include USM functions Oct 14, 2024
@maleadt
Copy link
Member

maleadt commented Oct 14, 2024

I think this is intended. The ICD we use only provides entry-points for functions from the spec, and for extensions one needs to use clGetExtensionFunctionAddressForPlatform to fetch the entrypoint address:

julia> using OpenCL, pocl_jll

julia> ptr = cl.clGetExtensionFunctionAddressForPlatform(cl.platform(), "clHostMemAllocINTEL")
Ptr{Nothing} @0x000000013131f000

julia> error = Ref{Int32}()
Base.RefValue{Int32}(219365504)

julia> ccall(ptr, Ptr{Cvoid}, (cl.cl_context, Ptr{cl.cl_mem_properties_intel}, Csize_t, cl.cl_uint, Ptr{cl.cl_int}), cl.context(), C_NULL, 1000, 1, error)
Ptr{Nothing} @0x0000000121016e00

julia> error[]
0

It's a bit annoying that we can't re-use the existing Clang.jl-generated headers for this, although for the handful of USM functions you need it's probably fine duplicating those ccalls.

@VarLad
Copy link
Author

VarLad commented Nov 19, 2024

@maleadt Would you have an example of how to pass the properties flags properly? I'm not sure how this works...
It seems to work differently from the svm flags in the current implementation
Unable to figure out how to use these from the docs:
Image
Image

@maleadt
Copy link
Member

maleadt commented Nov 19, 2024

AFAIU it behaves like context properties, so you pass a list of properties starting with CL_MEM_ALLOC_FLAGS_INTEL, then a flags bitmask, and terminate with NULL.

julia> using OpenCL, pocl_jll

julia> fun = cl.clGetExtensionFunctionAddressForPlatform(cl.platform(), "clHostMemAllocINTEL")
Ptr{Nothing} @0x0000000135a78178

julia> error = Ref{Int32}();

julia> flags = cl.CL_MEM_ALLOC_WRITE_COMBINED_INTEL;

julia> properties = cl.cl_mem_properties_intel[cl.CL_MEM_ALLOC_FLAGS_INTEL, flags, 0];

julia> buf = ccall(fun, Ptr{Cvoid},
                   (cl.cl_context, Ptr{cl.cl_mem_properties_intel}, Csize_t, cl.cl_uint, Ptr{cl.cl_int}),
                   cl.context(), properties, 1000, 1, error)
Ptr{Nothing} @0x00000001322cee00

julia> @assert error[] == cl.CL_SUCCESS

You can also look at how PoCL implements this:

@VarLad
Copy link
Author

VarLad commented Nov 26, 2024

@maleadt I've been trying to use clGetMemAllocInfoINTEL, but so far, all my efforts to try and get any info out of that function are not working as I get CL_INVALID_VALUE (-30)

Here's an MWE for that:

    using OpenCL, pocl_jll

    ocl_extension(s) = cl.clGetExtensionFunctionAddressForPlatform(cl.platform(), s)

    function clDeviceMemAllocINTEL(context, device, properties, size, alignment, errcode_ret)
	ocl_intel = ocl_extension("clDeviceMemAllocINTEL")
	
        @ccall $ocl_intel(context::cl.cl_context, device::cl.cl_device_id, properties::Ptr{cl.cl_mem_properties_intel}, size::Csize_t, alignment::cl.cl_uint, errcode_ret::Ptr{cl.cl_int})::Ptr{Cvoid}
    end

    function clGetMemAllocInfoINTEL(context, ptr, param_name, param_value_size, param_value, param_value_size_ret)
	ocl_intel = ocl_extension("clGetMemAllocInfoINTEL")
	
        @ccall $ocl_intel(context::cl.cl_context, ptr::Ptr{Cvoid}, param_name::cl.cl_mem_info_intel, param_value_size::Csize_t, param_value::Ptr{Cvoid}, param_value_size_ret::Ptr{Csize_t})::cl.cl_int
    end     
    begin    
        ctx = cl.context()
        dev = cl.device()
        bytesize = 1000
        alignment = 1
        error_code = Ref{Int32}()
        flags = cl.CL_MEM_ALLOC_WRITE_COMBINED_INTEL

	ptr = clDeviceMemAllocINTEL(ctx, dev,cl.cl_mem_properties_intel[cl.CL_MEM_ALLOC_FLAGS_INTEL, flags, 0], bytesize, alignment, error_code)
	
	@assert error_code[] == cl.CL_SUCCESS

	result = Ref{Cvoid}()

	success = clGetMemAllocInfoINTEL(ctx, ptr, cl.CL_MEM_ALLOC_BASE_PTR_INTEL, 
        sizeof(cl.cl_mem_info_intel), result, C_NULL)

        @assert success == cl.CL_SUCCESS
    end

The last assertion fails...
I've also tried defining result as:

result = Ref{cl.cl_mem_info_intel}()

but that gives me the same error...

Finally, it works if I instead define result as:

result = Ptr{Cvoid}()

But I don't think setting a NULL pointer is a valid solution...

@maleadt
Copy link
Member

maleadt commented Nov 26, 2024

Run with POCL_DEBUG=all:

[2024-11-26 14:32:46.175664000] PoCL: in fn clGetMemAllocInfoINTEL at line 53:
 |     ERROR | CL_INVALID_VALUE param_value_size (4) smaller than actual size (8)

@maleadt maleadt changed the title ICD JLL does not include USM functions Simplify use of OpenCL extensions Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants