Compiler: nvfortran 26.3-0 (NVHPC 26.3), Linux x86_64
Summary
The Fortran modulo intrinsic applied to integer(int64) operands fails to compile when used inside
an OpenMP target or OpenACC compute region. The compiler emits:
NVFORTRAN-S-1058-Call to Compiler runtime function not supported - pgf90_i8modulov_i8
The same call compiles and runs fine on the host, and mod(int64,int64) works inside the target
region — only modulo is affected.
Reproducer (OpenMP)
program mre_omp_modulo_int64
use iso_fortran_env, only: int64
implicit none
integer(int64) :: a = 10_int64, b = 3_int64, r = 0_int64
!$omp target map(tofrom: r) map(to: a, b)
r = modulo(a, b)
!$omp end target
print *, 'r = ', r
end program
$ nvfortran -mp=gpu -gpu=mem:separate mre_omp.F90
NVFORTRAN-S-1058-Call to Compiler runtime function not supported - pgf90_i8modulov_i8
Reproducer (OpenACC) — same body, replacing the directives with:
!$acc serial copy(r) copyin(a, b)
r = modulo(a, b)
!$acc end serial
$ nvfortran -acc=gpu -gpu=mem:separate mre_acc.F90
NVFORTRAN-S-1058-Call to Compiler runtime function not supported - pgf90_i8modulov_i8
Trigger boundaries
The bug requires all three of: the modulo intrinsic (not mod), int64 operands, and a target/compute
region. int32 is correctly lowered to a device-supported routine; the int64 variant apparently
expects a host-only pgf90_i8modulov_i8 runtime helper that has no device implementation.
Expected
modulo(int64, int64) should be supported on the device, like mod(int64, int64) and modulo(int32,
int32) already are.
Workaround
Open-code it in terms of mod:
r = mod(a, b)
if (r /= 0_int64 .and. (r < 0_int64) .neqv. (b < 0_int64)) r = r + b
See here for the full code: fortran-bugs/modulo_int64_target at main · JorgeG94/fortran-bugs · GitHub