@@ -8,7 +8,7 @@ export @cuda, cudaconvert, cufunction, dynamic_cufunction, nearest_warpsize
88# split keyword arguments to `@cuda` into ones affecting the macro itself, the compiler and
99# the code it generates, or the execution
1010function split_kwargs (kwargs)
11- macro_kws = [:dynamic ]
11+ macro_kws = [:dynamic , :init ]
1212 compiler_kws = [:minthreads , :maxthreads , :blocks_per_sm , :maxregs , :name , :malloc ]
1313 call_kws = [:cooperative , :blocks , :threads , :config , :shmem , :stream ]
1414 macro_kwargs = []
@@ -137,13 +137,14 @@ macro cuda(ex...)
137137
138138 # handle keyword arguments that influence the macro's behavior
139139 dynamic = false
140+ env_kwargs = []
140141 for kwarg in macro_kwargs
141142 key,val = kwarg. args
142143 if key == :dynamic
143144 isa (val, Bool) || throw (ArgumentError (" `dynamic` keyword argument to @cuda should be a constant value" ))
144145 dynamic = val:: Bool
145146 else
146- throw ( ArgumentError ( " Unsupported keyword argument ' $key ' " ) )
147+ push! (env_kwargs, kwarg )
147148 end
148149 end
149150
@@ -159,6 +160,7 @@ macro cuda(ex...)
159160 # we're in kernel land already, so no need to cudaconvert arguments
160161 local kernel_tt = Tuple{$ ((:(Core. Typeof ($ var)) for var in var_exprs). .. )}
161162 local kernel = dynamic_cufunction ($ (esc (f)), kernel_tt)
163+ prepare_kernel (kernel; $ (map (esc, env_kwargs)... ))
162164 kernel ($ (var_exprs... ); $ (map (esc, call_kwargs)... ))
163165 end )
164166 else
@@ -173,6 +175,7 @@ macro cuda(ex...)
173175 local kernel_tt = Tuple{Core. Typeof .(kernel_args)... }
174176 local kernel = cufunction ($ (esc (f)), kernel_tt;
175177 $ (map (esc, compiler_kwargs)... ))
178+ prepare_kernel (kernel; $ (map (esc, env_kwargs)... ))
176179 kernel (kernel_args... ; $ (map (esc, call_kwargs)... ))
177180 end
178181 end )
447450 return ex
448451end
449452
453+ """
454+ prepare_kernel(kernel::AbstractKernel{F,TT}; init::Function=nop_init_kernel)
455+
456+ Prepares a kernel for execution by setting up an environment for that kernel.
457+ This function should be invoked just prior to running the kernel. Its
458+ functionality is included in [`@cuda`](@ref).
459+
460+ The 'init' keyword argument is a function that takes a kernel as argument and
461+ sets up an environment for the kernel.
462+ """
463+ function prepare_kernel (kernel:: AbstractKernel{F,TT} ; init:: Function = nop_init_kernel) where {F,TT}
464+ # Just call the 'init' function for now.
465+ init (kernel)
466+ end
450467
451468# # device-side API
452469
470+ # There doesn't seem to be a way to access the documentation for the call-syntax,
471+ # so attach it to the type
453472"""
454473 dynamic_cufunction(f, tt=Tuple{})
455474
@@ -503,3 +522,8 @@ function nearest_warpsize(dev::CuDevice, threads::Integer)
503522 ws = CUDAdrv. warpsize (dev)
504523 return threads + (ws - threads % ws) % ws
505524end
525+
526+ function nop_init_kernel (kernel:: AbstractKernel{F,TT} ) where {F,TT}
527+ # Do nothing.
528+ return
529+ end
0 commit comments