@@ -9,6 +9,7 @@ function clear_task_local_storage!()
99 delete! (task_local_storage (), :CLPlatform )
1010 delete! (task_local_storage (), :CLQueue )
1111 delete! (task_local_storage (), :CLMemoryBackend )
12+ delete! (task_local_storage (), :CLUnifiedMemoryBackend )
1213end
1314
1415
@@ -163,21 +164,23 @@ struct SVMBackend <: AbstractMemoryBackend end
163164struct USMBackend <: AbstractMemoryBackend end
164165struct BufferBackend <: AbstractMemoryBackend end
165166
166- function supported_memory_backends (dev:: Device )
167+ function supported_memory_backends (dev:: Device ; unified = false )
167168 backends = AbstractMemoryBackend[]
168169
169170 # unified shared memory is the first choice, as it gives us separate host and device
170171 # memory spaces that can be directly referenced by raw pointers.
171172 if usm_supported (dev)
172173 usm_caps = usm_capabilities (dev)
173- if usm_caps. host. access && usm_caps. device. access
174+ if unified
175+ usm_caps. shared. access && push! (backends, USMBackend ())
176+ elseif usm_caps. host. access && usm_caps. device. access
174177 push! (backends, USMBackend ())
175178 end
176179 end
177180
178181 # plain old buffers are always supported, but we only want to use them if we have the
179182 # buffer device address extension, which allows us to reference them by raw pointers.
180- if bda_supported (dev)
183+ if ! unified && bda_supported (dev)
181184 push! (backends, BufferBackend ())
182185 end
183186
@@ -187,7 +190,7 @@ function supported_memory_backends(dev::Device)
187190 push! (backends, SVMBackend ())
188191 end
189192
190- if isempty (backends)
193+ if ! unified && isempty (backends)
191194 # as a last resort, use plain buffers without the ability to reference by pointer.
192195 # this severely limits compatibility, but it's better than nothing.
193196 push! (backends, BufferBackend ())
@@ -196,8 +199,9 @@ function supported_memory_backends(dev::Device)
196199 return backends
197200end
198201
199- function default_memory_backend (dev:: Device )
200- supported_backends = supported_memory_backends (dev)
202+ function default_memory_backend (dev:: Device ; unified= false )
203+ supported_backends = supported_memory_backends (dev; unified)
204+ isempty (supported_backends) && return nothing
201205
202206 backend_str = load_preference (OpenCL, " default_memory_backend" )
203207 backend_str === nothing && return first (supported_backends)
@@ -211,8 +215,7 @@ function default_memory_backend(dev::Device)
211215 else
212216 error (" Unknown memory backend '$backend_str ' requested" )
213217 end
214- in (backend, supported_backends) ? backend : nothing
215- backend
218+ return in (backend, supported_backends) ? backend : nothing
216219end
217220
218221function memory_backend ()
@@ -230,6 +233,17 @@ function memory_backend()
230233 end
231234end
232235
236+ function unified_memory_backend ()
237+ return get! (task_local_storage (), :CLUnifiedMemoryBackend ) do
238+ dev = device ()
239+ backend = default_memory_backend (dev; unified= true )
240+ if backend === nothing
241+ error (" Device $(dev) does not support any of the available unified memory backends" )
242+ end
243+ backend
244+ end
245+ end
246+
233247
234248# # per-task queues
235249
0 commit comments