| 
1 |  | -# OpenCL Memory Object  | 
2 |  | - | 
3 |  | -abstract type AbstractMemoryObject <: CLObject end  | 
4 |  | - | 
5 |  | -#This should be implemented by all subtypes  | 
6 |  | -# type MemoryType <: AbstractMemoryObject  | 
7 |  | -#     id::cl_mem  | 
8 |  | -#     ...  | 
9 |  | -# end  | 
10 |  | - | 
11 |  | -# for passing buffers to OpenCL APIs: use the underlying handle  | 
12 |  | -Base.unsafe_convert(::Type{cl_mem}, mem::AbstractMemoryObject) = mem.id  | 
13 |  | - | 
14 |  | -# for passing buffers to kernels: keep the buffer, it's handled by `cl.set_arg!`  | 
15 |  | -Base.unsafe_convert(::Type{<:Ptr}, mem::AbstractMemoryObject) = mem  | 
16 |  | - | 
17 |  | -Base.sizeof(mem::AbstractMemoryObject) = mem.size  | 
18 |  | - | 
19 |  | -release(mem::AbstractMemoryObject) = clReleaseMemObject(mem)  | 
20 |  | - | 
21 |  | -function Base.getproperty(mem::AbstractMemoryObject, s::Symbol)  | 
22 |  | -    if s == :context  | 
23 |  | -        param = Ref{cl_context}()  | 
24 |  | -        clGetMemObjectInfo(mem, CL_MEM_CONTEXT, sizeof(cl_context), param, C_NULL)  | 
25 |  | -        return Context(param[], retain = true)  | 
26 |  | -    elseif s == :mem_type  | 
27 |  | -        result = Ref{cl_mem_object_type}()  | 
28 |  | -        clGetMemObjectInfo(mem, CL_MEM_TYPE, sizeof(cl_mem_object_type), result, C_NULL)  | 
29 |  | -        return result[]  | 
30 |  | -    elseif s == :mem_flags  | 
31 |  | -        result = Ref{cl_mem_flags}()  | 
32 |  | -        clGetMemObjectInfo(mem, CL_MEM_FLAGS, sizeof(cl_mem_flags), result, C_NULL)  | 
33 |  | -        mf = result[]  | 
34 |  | -        flags = Symbol[]  | 
35 |  | -        if (mf & CL_MEM_READ_WRITE) != 0  | 
36 |  | -            push!(flags, :rw)  | 
37 |  | -        end  | 
38 |  | -        if (mf & CL_MEM_WRITE_ONLY) != 0  | 
39 |  | -            push!(flags, :w)  | 
40 |  | -        end  | 
41 |  | -        if (mf & CL_MEM_READ_ONLY) != 0  | 
42 |  | -            push!(flags, :r)  | 
43 |  | -        end  | 
44 |  | -        if (mf & CL_MEM_USE_HOST_PTR) != 0  | 
45 |  | -            push!(flags, :use)  | 
46 |  | -        end  | 
47 |  | -        if (mf & CL_MEM_ALLOC_HOST_PTR) != 0  | 
48 |  | -            push!(flags, :alloc)  | 
49 |  | -        end  | 
50 |  | -        if (mf & CL_MEM_COPY_HOST_PTR) != 0  | 
51 |  | -            push!(flags, :copy)  | 
52 |  | -        end  | 
53 |  | -        return tuple(flags...)  | 
54 |  | -    elseif s == :size  | 
55 |  | -        result = Ref{Csize_t}()  | 
56 |  | -        clGetMemObjectInfo(mem, CL_MEM_SIZE, sizeof(Csize_t), result, C_NULL)  | 
57 |  | -        return result[]  | 
58 |  | -    elseif s == :reference_count  | 
59 |  | -        result = Ref{Cuint}()  | 
60 |  | -        clGetMemObjectInfo(mem, CL_MEM_REFERENCE_COUNT, sizeof(Cuint), result, C_NULL)  | 
61 |  | -        return Int(result[])  | 
62 |  | -    elseif s == :map_count  | 
63 |  | -        result = Ref{Cuint}()  | 
64 |  | -        clGetMemObjectInfo(mem, CL_MEM_MAP_COUNT, sizeof(Cuint), result, C_NULL)  | 
65 |  | -        return Int(result[])  | 
66 |  | -    elseif s == :device_address  | 
67 |  | -        result = Ref{cl_mem_device_address_ext}()  | 
68 |  | -        clGetMemObjectInfo(mem, CL_MEM_DEVICE_ADDRESS_EXT, sizeof(cl_mem_device_address_ext), result, C_NULL)  | 
69 |  | -        return CLPtr{Cvoid}(result[])  | 
70 |  | -    else  | 
71 |  | -        return getfield(mem, s)  | 
72 |  | -    end  | 
73 |  | -end  | 
74 |  | - | 
75 |  | -# convenience functions  | 
76 |  | -context(mem::AbstractMemoryObject) = mem.context  | 
77 |  | -Base.pointer(mem::AbstractMemoryObject) = mem.pointer  | 
78 |  | - | 
79 |  | -#TODO: enqueue_migrate_mem_objects(queue, mem_objects, flags=0, wait_for=None)  | 
80 |  | -#TODO: enqueue_migrate_mem_objects_ext(queue, mem_objects, flags=0, wait_for=None)  | 
81 |  | - | 
82 | 1 | # OpenCL.Buffer  | 
83 | 2 | 
 
  | 
84 | 3 | struct Buffer <: AbstractMemoryObject  | 
85 | 4 |     id::cl_mem  | 
 | 5 | +    ptr::Union{Nothing,CLPtr{Cvoid}}  | 
86 | 6 |     bytesize::Int  | 
 | 7 | +    context::Context  | 
87 | 8 | end  | 
88 | 9 | 
 
  | 
 | 10 | +Buffer() = Buffer(C_NULL, nothing, 0, context())  | 
 | 11 | + | 
 | 12 | +Base.pointer(buf::Buffer) = @something buf.ptr error("Buffer does not have a device private address")  | 
89 | 13 | Base.sizeof(buf::Buffer) = buf.bytesize  | 
 | 14 | +context(buf::Buffer) = buf.context  | 
90 | 15 | 
 
  | 
91 | 16 | 
 
  | 
92 | 17 | ## constructors  | 
@@ -130,7 +55,16 @@ function Buffer(sz::Int, flags::Integer, hostbuf=nothing;  | 
130 | 55 |     if err_code[] != CL_SUCCESS  | 
131 | 56 |         throw(CLError(err_code[]))  | 
132 | 57 |     end  | 
133 |  | -    return Buffer(mem_id, sz)  | 
 | 58 | + | 
 | 59 | +    ptr = if device_private_address  | 
 | 60 | +        ptr_ref = Ref{cl_mem_device_address_ext}()  | 
 | 61 | +        clGetMemObjectInfo(mem_id, CL_MEM_DEVICE_ADDRESS_EXT, sizeof(cl_mem_device_address_ext), ptr_ref, C_NULL)  | 
 | 62 | +        CLPtr{Cvoid}(ptr_ref[])  | 
 | 63 | +    else  | 
 | 64 | +        nothing  | 
 | 65 | +    end  | 
 | 66 | + | 
 | 67 | +    return Buffer(mem_id, ptr, sz, context())  | 
134 | 68 | end  | 
135 | 69 | 
 
  | 
136 | 70 | # allocated buffer  | 
 | 
0 commit comments