oracle_argsort Subroutine

public subroutine oracle_argsort(keys, nrows, nthreads, proc, perm)

Relays onto the oracle's procedure pointers, and they exist for a COMPILER reason rather than a design one -- do not inline them back into the callers.

gfortran 15.2 ICEs (in write_symbol, at lto-streamer-out.cc:3086, during IPA pass: modref) when a SUBMODULE calls a module-level procedure pointer under -flto, which is what --profile release builds with. Every ingredient was bisected: the optimisation level is irrelevant, so are save, => null() and accessibility, copying the pointer to a local first does NOT help, and a submodule of a DIFFERENT module that use-associates the pointer fails identically. Calling from the owning module's own contains -- which is what these do -- is clean.

So no submodule may name a p_* pointer at all: even passing associated(p_argsort) as an actual argument reproduces it, though the bare test alone does not. check_oracle is folded in here for that reason, not for brevity. check_source_conventions.py's check_no_submodule_oracle_pointer_call enforces it, because nothing in CI or a plain fpm test builds with -flto -- a reintroduced call would sit in the tree until someone next asked for a release build. See CLAUDE.md, "Compiler & language gotchas".

Arguments

Type IntentOptional Attributes Name
type(sort_key_buf), intent(in), target :: keys(:)

the keys, primary first.

integer(kind=int64), intent(in) :: nrows

rows each key describes.

integer(kind=int64), intent(in) :: nthreads

resolved thread count.

character(len=*), intent(in) :: proc

calling procedure, for messages.

integer(kind=int64), intent(inout) :: perm(:)

the permutation to fill.


Source Code

    subroutine oracle_argsort(keys, nrows, nthreads, proc, perm)
        type(sort_key_buf), intent(in), target :: keys(:)  !! the keys, primary first.
        integer(int64), intent(in) :: nrows                !! rows each key describes.
        integer(int64), intent(in) :: nthreads             !! resolved thread count.
        character(len=*), intent(in) :: proc               !! calling procedure, for messages.
        integer(int64), intent(inout) :: perm(:)           !! the permutation to fill.
        !
        call check_oracle(associated(p_argsort), proc)
        call p_argsort(keys, nrows, nthreads, proc, perm)
    end subroutine oracle_argsort