Kernels
Grid
cuTile.bid — Function
bid(axis) -> Int32Get the block ID along the given axis (1=x, 2=y, 3=z). Returns 1-indexed block ID.
cuTile.num_blocks — Function
num_blocks(axis) -> Int32Get the grid size along the given axis (1=x, 2=y, 3=z).
cuTile.num_tiles — Function
num_tiles(arr::TileArray, axis::Integer, shape::NTuple{M, Int}) -> Int32Get the number of tiles along a specific axis of an array, given the tile shape. Axis is 1-indexed. Equivalent to cld(size(arr, axis), shape[axis]).
Example
# For a 1024x768 matrix with 32x32 tiles:
# num_tiles(arr, 1, (32, 32)) returns cld(1024, 32) = 32
# num_tiles(arr, 2, (32, 32)) returns cld(768, 32) = 24Compiling and launching
cuTile.launch — Function
launch(f, grid, args...; sm_arch=nothing, opt_level=nothing,
num_ctas=nothing, occupancy=nothing, num_worker_warps=nothing, name=nothing)Compile and launch a Tile IR kernel. args are converted via cuTileconvert (CuArray → TileArray, Type → Constant). Equivalent to @cuda backend=cuTile blocks=grid f(args...) modulo slight kwarg naming.
Example
using CUDA, cuTile
a = CUDA.zeros(Float32, 1024); b = CUDA.ones(Float32, 1024); c = similar(a)
function vadd_kernel(a::cuTile.TileArray{Float32,1}, b::cuTile.TileArray{Float32,1},
c::cuTile.TileArray{Float32,1})
pid = cuTile.bid(1)
ta = cuTile.load(a, (pid,), (16,))
tb = cuTile.load(b, (pid,), (16,))
cuTile.store(c, (pid,), ta + tb)
return
end
cuTile.launch(vadd_kernel, 64, a, b, c)cuTile.cufunction — Function
cuTile.cufunction(f, tt=Tuple{}; sm_arch=nothing, opt_level=nothing,
num_ctas=nothing, occupancy=nothing, num_worker_warps=nothing,
name=nothing) -> TileKernelCompile f for the cuTile backend. tt is the tuple of converted argument types (i.e. after cuTileconvert/Adapt.adapt(KernelAdaptor(), …)). Compilation is cached; calling cufunction repeatedly with the same (f, tt, opts) is O(1) after the first compile.
Mirrors CUDACore.cufunction but produces a TileKernel. Caching is delegated to CompilerCaching: the resulting TileKernel is stored in the CuTileResults attached to the underlying Julia CodeInstance, so invalidation rides on Julia's normal CI lifecycle.
cuTile.TileKernel — Type
TileKernel{F, TT}A compiled cuTile kernel. Returned by cuTile.cufunction and the target of (::TileKernel)(args...; blocks, …) calls. Concrete subtype of CUDACore.AbstractKernel.
cuTile.TileBackend — Type
TileBackend()cuTile backend for @cuda backend=.... Routes the call through cuTile.cufunction (Tile IR bytecode → tileiras → CUBIN) and returns a TileKernel for launch.
@cuda backend=cuTile blocks=N my_kernel(a, b, c) # via DefaultBackend()
@cuda backend=cuTile.TileBackend() blocks=N my_kernel(a, b, c)cuTile.DefaultBackend — Function
DefaultBackend() -> TileBackendThe default cuTile backend, looked up by @cuda backend=cuTile. Returns a TileBackend. Provided as the module-level resolution hook for CUDACore's @cuda dispatch.
Compiler options
cuTile.@compiler_options — Macro
@compiler_options key=val...Specify per-architecture optimization hints inside a kernel function body. Hints are embedded as :meta nodes and resolved at compile time based on the target sm_arch.
Supported options: num_ctas, occupancy, opt_level, num_worker_warps.
Values can be plain scalars or ByTarget(...) for per-architecture dispatch.
Examples
function my_kernel(A, B)
ct.@compiler_options num_ctas=2
...
end
function my_kernel(A, B)
ct.@compiler_options num_ctas=ByTarget(v"10.0" => 2, v"12.0" => 4) occupancy=8
...
endcuTile.ByTarget — Type
ByTarget{T}Per-architecture value that resolves to a concrete T based on the target GPU's compute capability. Use with @compiler_options to specify architecture-specific optimization hints.
Example
function my_kernel(...)
ct.@compiler_options num_ctas=ByTarget(v"10.0" => 2, v"12.0" => 4)
...
endcuTile.@fpmode — Macro
@fpmode [rounding_mode=Rounding.X] [flush_to_zero=bool] begin ... endSet the floating-point mode for all FP operations in the block. Operations that support rounding mode and/or flush-to-zero will use the specified values. The mode applies to all operations in the block, including those inside inlined function calls.
Nested @fpmode blocks inherit unspecified fields from the outer scope.
Examples
ct.@fpmode rounding_mode=ct.Rounding.Approx flush_to_zero=true begin
acc = acc ./ l_i # uses Approx rounding + FTZ
p = exp2.(qk) # uses FTZ
end
# Nesting: inner inherits FTZ from outer
ct.@fpmode rounding_mode=ct.Rounding.Approx flush_to_zero=true begin
x = a + b # Approx + FTZ
ct.@fpmode rounding_mode=ct.Rounding.NearestEven begin
y = c + d # NearestEven + FTZ (inherited)
end
endcuTile.Rounding — Module
Rounding mode for floating-point operations. Use with @fpmode to set the rounding mode for a block of code.
Assertions and assumptions
cuTile.@assert — Macro
@assert cond [message]Assert that cond is true, aborting the kernel with message on failure. If no message is given, the stringified condition is used.
Works like Base.@assert but compiles to a Tile IR assert op. Failed assertions are fatal — they crash the kernel and corrupt the CUDA context (not a catchable exception).
Examples
ct.@assert bid > Int32(0)
ct.@assert bid > Int32(0) "bid must be positive"cuTile.assume_divisible_by — Function
assume_divisible_by(x::Integer, divisor::Integer) -> typeof(x)Declare that x is divisible by divisor, a compiler hint that propagates through arithmetic and can e.g. prove alignment for derived indices and pointer offsets, enabling wider memory operations.
The caller is responsible for the correctness of the claim; behavior is undefined if x is not actually divisible by divisor at runtime.
divisor must be a positive integer constant.
Examples
n = ct.assume_divisible_by(n, 128)
ptr_offset = base + n # compiler knows this is 128-divisible