Assumed-Size Dummy Argument Not Working in Module Procedure

Yes, exactly. You can read more here: Gfortran bug or am I missing something? - #14 by urbanjost

Regardless how small, it is a measurable overhead for small n and being called enough times (test is n=10 with repetitions on the order of millions). It looks somewhat silly, but the entire logic can be contained in a select rank subroutine for a given type and kind:

        subroutine randrng_ar(val, val_min, val_max)
        implicit none
            real(sp), intent(out) :: val(..)
            real(sp), intent(in) :: val_min, val_max
            select rank(val)
                rank(1)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(2)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(3)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(4)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(5)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(6)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(7)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(8)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(9)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(10)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(11)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(12)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(13)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(14)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
                rank(15)
                    call random_number(val)
                    val = val*(val_max - val_min) + val_min
            end select
        end subroutine randrng_ar

Maybe some day in the future I won’t have to copy/paste literally the exact same code 15 times. At least it doesn’t require any modification though, and if the algorithm ever has to change, it’s all in one place. – Looking at it I should probably add rank(0) for 16 times and rank default to just error out if the routine somehow receives something that is not rank 0-15. I believe ifort may support up to 31 ranks, but that is not standard?