Val{N} + LinearIndices Causes Massive Compile-Time Unrolling

0samuraiE
Sun, 20 Apr 2025 13:27:55 +0000
GPU

I’m seeing strange behavior when using @code_warntype on a function that takes a Val{N} parameter and creates a LinearIndices object with size (N, N, N). Here’s a minimal example:

function test(::Val{N}) where {N}
    LinearIndices((1:N, 1:N, 1:N))
end
@code_warntype test(Val(100))

The output includes a massive list of literal integers:

996900 997000 997100 997200 ... 1000000])
└──      return %9

This was surprising and prompted me to investigate further, because I encountered a serious performance issue when using similar code in a GPU kernel via KernelAbstractions.jl. Specifically, compiling the kernel resulted in:

588.306677 seconds (13.85 M CPU allocations: 2.513 GiB, 0.05% gc time), 0.00% GPU memmgmt time

It seems that passing a large N as a type parameter (Val{N}) causes excessive unrolling or compile-time expansion of index structures. My questions are:

Is this behavior expected when using Val{N} with large N in combination with LinearIndices?

Is there a recommended way to avoid this kind of compile-time explosion while maintaining type stability?

Are there best practices for using Val-based parameters safely in GPU kernels with KernelAbstractions?

Any insight would be appreciated.

3 posts - 2 participants