Migrating to the Fortran bindings shipped in ROCm#
Who this is for#
You build hipFORT yourself and call ROCm through it: use hipfort_rocblas,
hipMalloc, rocblas_dgemm.
In one line: the bindings move into ROCm itself (rocm-systems and
rocm-libraries), you rename your use statements and link a per-library
Fortran archive, and nothing else in your code changes.
Note
Using a ROCm library’s own Fortran module instead? If you write
use rocblas against /opt/rocm/include/rocblas/rocblas_module.f90, or
use rocsparse, or use rocrand_m, this page is not yours. Those
modules ship with the library rather than with hipFORT, and their migration
has a different deadline, different edits, and, unlike this one, call sites
that do change. See Migrating from a library’s own Fortran module.
Coming from CUDA Fortran? See Migrating from CUDA Fortran.
Why the bindings are moving#
hipFORT is a separate repository that you build and install next to ROCm. It has always lagged behind ROCm: a routine added to rocBLAS reached Fortran only when hipFORT was regenerated, which for several years did not happen at all, and a hipFORT build had to be matched by hand to the ROCm it ran against. Moving the bindings into ROCm fixes that at the root:
Always complete and current. Each binding is generated from the headers of the library it ships with, committed in the
bindings/fortran/tree of the same repository, and kept in sync by CI whenever a header changes. Every entry point the.soexports is declared, and none that it does not.Nothing extra to build. The bindings arrive precompiled with ROCm: in TheRock’s tarballs from the 10.3 tech preview, and in the
amdrocm-<family>-fortran-develpackages from 10.4. There is no separate project to clone, configure, and keep in step.Pay for what you use. One module and one archive per library, built against that library in a separate stage and shipped in the family’s Fortran package, instead of one hipFORT build for everything, so a code that only calls rocBLAS needs only rocBLAS’s binding.
One way to build and find them. The same CMake options, install layout, and
find_packagepattern across all thirteen bindings, where today each library that has a Fortran module does it differently.Easier to improve. Because the bindings are generated, a request such as a typed overload, a missing routine, or a corrected argument type becomes a generator change that reaches every library at once, instead of a hand edit that has to be repeated in each.
The price is the migration on this page: two mechanical edits, done once.
Are there breaking changes?#
Yes, but they are limited and mechanical: your code will not compile or link unchanged. Two edits are required, and the CUDA backend is dropped.
Source. The module names change:
use hipfort_rocblasbecomesuse rocblas.Build. The link target changes:
find_package(hipfort)andhipfort::rocblasbecomefind_package(rocblas-fortran)androc::rocblas_fortran.NVIDIA users. The CUDA (
nvptx) backend is not carried into the new bindings.
Everything at the call level (routine names, arguments, calling styles) is unchanged, so the two edits are find-and-replace, not a rewrite. The details are in What you change.
Timeline#
ROCm |
What happens |
|---|---|
≤ 10.2 |
Nothing changes. Keep using hipFORT as today. |
10.3 |
The new bindings ship as a tech preview, in TheRock’s tarballs and, if they are ready, in the OS packages. Their interfaces can still change. hipFORT is still maintained beside them. |
10.4 to 10.x |
The new bindings are production: they ship in the OS packages, with the full documentation and the compatibility promise below. hipFORT is still maintained, so both work and you can migrate at any point in this window. Aim for the start of it rather than the end. |
11.0 |
hipFORT is removed. You must be on the new bindings by this release. |
Do I need to do anything now? No. Today’s hipFORT keeps working until it is removed at ROCm 11.0, and old and new share the same interfaces underneath, so you migrate on your own schedule. Migrate early anyway: the edit is mechanical, but if something does behave differently you want releases to spare, and an early report gets fixed for everyone.
From 10.4, a binding is versioned with its library and stays valid across a major ROCm series in one direction: a binding built for 10.4 still links against the libraries of any later 10.x, and the CMake package accepts any version with the same major number. The 10.3 tech preview carries no such promise. A binding newer than the libraries it links against is another matter (Binding and library versions). You revisit your build at a major release, not at every point release.
Codes that build on several ROCm versions#
If one code base has to build on systems that will not reach ROCm 10.3 for a while (a production machine frozen on ROCm 6.x, for example) and on newer ones, you have two options:
Stay on hipFORT until your oldest system reaches 10.3. hipFORT keeps working through the 10.x series, so a single hipFORT-based build covers everything until then. On each system, use the hipFORT release that matches its ROCm (hipFORT tags them
rocm-<version>, for examplerocm-6.3.3): a binding declares the entry points of the ROCm it was generated from, and a newer one can reference routines an older.sodoes not export. hipFORT’sdevelopbranch is compiled with one section per procedure, so a program linked with-Wl,--gc-sectionsalso builds against an older ROCm, as long as it calls only routines that ROCm exports.Switch per system with a thin wrapper module. Both bindings export the same names, so a module of your own can pick one at compile time, and the rest of your code
uses the wrapper and never sees the difference:! my_rocblas.F90 (capital F: preprocessed) module my_rocblas #ifdef HAVE_ROCM_FORTRAN use rocblas #else use hipfort_rocblas use hipfort_rocblas_enums #endif end module my_rocblas
find_package(rocblas-fortran CONFIG QUIET) if(TARGET roc::rocblas_fortran) target_link_libraries(app PRIVATE roc::rocblas roc::rocblas_fortran) target_compile_definitions(app PRIVATE HAVE_ROCM_FORTRAN) else() find_package(hipfort REQUIRED) target_link_libraries(app PRIVATE hipfort::rocblas) endif()
Test the target rather than
rocblas-fortran_FOUND: the package can be found but have nothing installed for your compiler.
If you need the new bindings on a ROCm older than 10.3, open an issue saying which release: the bindings are generated from a release’s headers, and an older release can be generated on request.
Do I need to build anything?#
Usually not. Find your case:
Your situation |
What you build |
|---|---|
ROCm 10.3 or later, compiling with |
Nothing. The |
ROCm 10.3 or later, compiling with |
Each binding you use, once per compiler. A |
You build ROCm itself from source (Spack, EasyBuild, a distribution package) |
One more project per binding. The bindings are not built with
the libraries: each is a project of its own, in the
|
ROCm older than 10.3 |
hipFORT, as today. See Codes that build on several ROCm versions. |
Windows |
Each binding you use, from the repository. ROCm for Windows ships no Fortran compiler, so it ships neither the compiled bindings nor their sources. See Windows. |
Compile and link#
Each library you use needs two things from the bindings: its .mod file
at compile time and its lib<lib>_fortran.a archive at link time. Both are
installed under a subdirectory named after the compiler that built them:
File |
Location (stock ROCm install, |
|---|---|
|
|
|
|
|
|
No C header is involved: Fortran reads only the .mod.
With CMake#
Enable Fortran in your project and ask for the <library>-fortran package of
each library you use. The target adds the -I and -L for your compiler
and pulls in the C library:
project(app LANGUAGES Fortran)
find_package(hip-fortran REQUIRED)
find_package(rocblas-fortran REQUIRED)
add_executable(app app.f90)
target_link_libraries(app PRIVATE hip::hip_fortran roc::rocblas_fortran)
If ROCm is not in /opt/rocm, add its prefix to CMAKE_PREFIX_PATH. If
you built a binding into a prefix of your own, add that prefix too.
Without CMake#
Point -I and -L at your compiler’s subdirectory, and link the Fortran
archive of each library you use before the C libraries:
amdflang app.f90 \
-I/opt/rocm/include/fortran/amdflang \
-L/opt/rocm/lib/fortran/amdflang -lrocblas_fortran -lhip_fortran \
-L/opt/rocm/lib -lrocblas -lamdhip64 \
-o app
With another compiler, replace amdflang in both paths with that compiler’s
directory (gfortran, ftn, and so on; see Where the files install)
and use the prefix you installed your build of the bindings into.
Binding and library versions#
A binding declares the routines of the headers it was generated from. Linked
against the libraries of its own release, or of a later 10.x, every routine it
declares exists. Linked against older libraries, it can declare routines they
do not export: a binding built from a newer branch, for example, or a newer
<library>-fortran package found first on CMAKE_PREFIX_PATH. Each
library’s binding compiles to one object, and a linker takes whole objects
from an archive, so a single such routine makes every link against that
library fail, even if your program never calls it. Take a binding and its
library from the same release.
If you have to mix them, link your program with -Wl,--gc-sections. The
archives ROCm ships are compiled with one section per procedure, so the linker
then keeps only the wrappers you call: the program links as long as it calls
only routines the libraries export, and it is smaller. A binding you build
with its CMake project is compiled the same way; one you compile by hand needs
-ffunction-sections -fdata-sections (Building a binding with your
compiler).
if(NOT APPLE AND NOT WIN32)
target_link_options(app PRIVATE -Wl,--gc-sections)
endif()
Write -Wl,--gc-sections rather than LINKER:--gc-sections: CMake 3.27
passes the latter to amdflang without the -Wl, prefix, and the link
fails. Without CMake, add -Wl,--gc-sections to the command that links your
program.
If you build a shared library rather than an executable, also link it with
-Wl,--exclude-libs and the archive of each binding you use, separated by
colons, for example -Wl,--exclude-libs,librocblas_fortran.a:libhip_fortran.a.
A shared library exports its global symbols by default, including the wrappers
it links, and the linker never removes an exported symbol, so
-Wl,--gc-sections alone keeps them all. --exclude-libs keeps the wrappers
in your library, where your code calls them as before, but stops exporting them,
so the unused ones can be removed.
What you change#
Two things: the modules you use, and the Fortran library you link. Your
actual calls (routine names, arguments, calling style) do not change.
Rename your use statements#
The hipfort_ prefix is dropped, and each library collapses to a single
module named after the library. hipFFT is the exception, with a second module
for its Xt API (see below).
Old |
New |
Link (CMake target) |
CMake package |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hipFFT’s binding has two modules in one archive, as CUDA Fortran has
cufft and cufftXt. Every hipfftXt* and hipfftMp* routine is in
hipfftxt, including hipfftXtSetWorkArea, and every other hipfft*
routine is in hipfft. hipfftxt uses and re-exports hipfft, so a file
that calls the Xt API writes use hipfftxt alone. hipFORT gets the same
split, into hipfort_hipfft and hipfort_hipfftxt; code that calls the Xt
API through hipfort_hipfft moves to use hipfftxt.
The HIP memory helpers you might use directly (hipfort_hipmalloc,
hipfort_hipmemcpy, hipfort_hiphostregister) fold into use hip as
well.
The shared helper modules go away. Delete these use lines; their symbols
now come from the library module you already use:
Old |
Where the symbols are now |
|---|---|
|
In each library module ( |
|
In |
Only hipfort_cuda_errors (the CUDA-backend error enum) has no new
equivalent: it is tied to the dropped CUDA backend and retires with hipFORT at
11.0.
A rename looks like this; the calls in between are untouched:
! before
use hipfort
use hipfort_check
use hipfort_rocblas
! after
use hip ! runtime + hipCheck
use rocblas
This is a replacement, not an addition: delete the old use hipfort_rocblas
line.
Warning
Do not keep use hipfort_rocblas and use rocblas in the same
scope: both export the same public names (rocblas_dgemm,
rocblasCheck, the enums, and so on), so the compiler cannot tell which
one you mean and the file will not compile.
Different files in the same program can still migrate independently, because the clash is only within a single scope (see the FAQ).
Doing the rename automatically#
The rename is regular enough to script, so you do not have to walk a large
codebase by hand. On a Git tree, this rewrites every use line in place:
libs='roctx|rocblas|hipblas|rocsparse|hipsparse|hipfftw|hipfftxt|rocfft|hipfft|rocsolver|hipsolver|rocrand|hiprand'
sed -i -E \
-e "/^[[:space:]]*use[[:space:]]+hipfort_($libs)_(enums|types)\b/Id" \
-e "/^[[:space:]]*use[[:space:]]+hipfort_(check|auxiliary|types|enums)\b/Id" \
-e "s/^([[:space:]]*use[[:space:]]+)hipfort_($libs)\b/\1\2/I" \
-e "s/^([[:space:]]*use[[:space:]]+)hipfort_(hipmalloc|hipmemcpy|hiphostregister)\b/\1hip/I" \
-e "s/^([[:space:]]*use[[:space:]]+)hipfort\b/\1hip/I" \
$(git ls-files '*.f90' '*.F90')
The first two rules delete the modules that fold away, and the last three rename what is left.
The recipe needs GNU sed: \b and the I flag are GNU extensions, and
BSD sed -i takes a suffix argument. On macOS, install GNU sed
(brew install gnu-sed) and run the same command with gsed.
The rules cannot step on each other, because _ is a word character:
hipfort_rocblas_enums is deleted by rule 1 rather than renamed to
rocblas_enums by rule 3. The I flag covers USE HIPFORT_ROCBLAS as
well, and only: clauses survive the rename
(use hipfort_rocblas, only: rocblas_dgemm becomes
use rocblas, only: rocblas_dgemm).
Then read the diff, because a few things are deliberately left to you:
A file might end up with two
use hiplines (fromuse hipfortanduse hipfort_hipmalloc, for example). That is valid Fortran and compiles fine; collapse them if you prefer.A file that used
hipfort_check,hipfort_auxiliary,hipfort_typesorhipfort_enumswithout ever usinghipfortitself loses those symbols, because the delete rules take the whole line. Adduse hipthere.use hipfort_cuda_errorsis left untouched on purpose; it has no new equivalent (see above).A file that calls hipFFT’s Xt API through
use hipfort_hipfftbecomesuse hipfft, which does not have it. Change that line touse hipfftxt.Fixed-form sources, continuation lines, and
uselines behind preprocessor guards are not covered.grep -rniE 'use[[:space:]]+hipfort' .finds whatever the rules missed.
The recipe above is the whole of what a migration tool would do. If you would rather have the tool, open an issue.
Link the per-library Fortran archive#
Instead of one libhipfort-*.a for everything, each library ships its own
Fortran archive and CMake target. The target sits in the C library’s own
namespace (roc:: or hip::) with a _fortran suffix, and it lives in
its own config package, <lib>-fortran, which pulls the C library in for
you:
# before
find_package(hipfort REQUIRED)
target_link_libraries(app PRIVATE hipfort::rocblas)
# after
find_package(rocblas-fortran REQUIRED) # find_dependency()s rocblas itself
target_link_libraries(app PRIVATE roc::rocblas roc::rocblas_fortran)
The two spellings are deliberate: ROCm hyphenates package names
(hipblas-common) and underscores targets and archives
(librocblas_fortran.a). find_package(rocblas) alone does not define
roc::rocblas_fortran; ask for rocblas-fortran.
The package and target for each library are in the table under
Rename your use statements, and the raw archive is
lib<lib>_fortran.a (for example librocblas_fortran.a) if you link
without CMake (Without CMake).
Compiler support#
Which compiler?#
The supported compilers are amdflang (ROCm’s bundled LLVM Flang, the
recommended default), gfortran, and Cray Fortran (ftn). Each
binding’s project also carries toolchain files for Intel ifx and
ifort and NVIDIA nvfortran as a convenience, but those compilers are not
in the supported list. Any compiler with Fortran 2003 iso_c_binding should
work for the raw type(c_ptr) forms; the default array overloads need
Fortran 2008.
One catch is worth knowing: there is no portable Fortran ABI, so a .mod
(and its compiled .a) is tied to one compiler, and even one compiler
version; two compilers cannot share a .mod. ROCm therefore ships the
bindings precompiled for amdflang only, and with any other compiler you
build the bindings you use (see Do I need to build anything?).
Note
Mixing amdflang versions. A .mod is tied to the compiler version
too. From ROCm 10.1, the opt-in -fmodule-mismatch-check=warn lets
amdflang read a .mod written by another amdflang version,
warning instead of erroring. It covers version skew inside amdflang
only: nothing lets gfortran read an amdflang .mod. Rebuild when
you can, because the warning means the two artifacts were not built
together.
The C libraries you link (libamdhip64.so, librocblas.so, and so on) are
the stable, compiler-agnostic ABI; only the thin Fortran layer is
compiler-specific.
Windows#
The bindings are Linux-first. ROCm for Windows ships no Fortran compiler, so
BUILD_FORTRAN_BINDINGS defaults to OFF there, and a Windows install
contains no .mod, no lib<lib>_fortran archive, and no installed
.F90. Nothing in the bindings is Linux-specific, though: they are plain
iso_c_binding code. With a Fortran compiler of your own (Intel ifx, for
example), take the binding’s directory (bindings/fortran/<library> in
rocm-libraries, bindings/fortran in rocm-systems for HIP and ROCTx) from the repository at the tag of your ROCm and build it as in Building a binding with your compiler. This
path is not tested yet; if you try it, please
report how it went.
Where the files install#
Because the artifacts are compiler-specific, they install under a per-compiler
subdirectory: the .mod files in <includedir>/fortran/<compiler>/ and the
.a files in <libdir>/fortran/<compiler>/. Several compilers can
therefore share one prefix, and a CMake find_package picks your compiler’s
subdirectory automatically; if you link with raw flags, point -I and -L
at it.
<libdir> and <includedir> are the platform’s own: lib64 on Fedora,
RHEL and SUSE, lib/<triplet> on Debian multiarch. A stock ROCm install
gives /opt/rocm/include/fortran/amdflang/ and
/opt/rocm/lib/fortran/amdflang/. Elsewhere, check the packager’s
CMAKE_INSTALL_LIBDIR before writing a path by hand.
<compiler> is the name you would type, not the CMake compiler ID:
Compiler |
|
|---|---|
ROCm’s LLVM Flang |
|
GNU |
|
Cray |
|
Intel LLVM / Intel Classic |
|
NVIDIA HPC |
|
Anything else falls back to the basename of CMAKE_Fortran_COMPILER,
lowercased. The name ignores the compiler version, so two versions of one
compiler would share a directory; <LIB>_FORTRAN_COMPILER_DIR (for example
-DROCBLAS_FORTRAN_COMPILER_DIR=gfortran-13) gives a build its own, and the
CMake package finds it.
If nothing is installed for your compiler, the package fails and names what is, so that you can tell a rebuild from a redirect:
This project builds with gfortran, but no rocrand.mod for it is installed
under /opt/rocm/include/fortran. Available: amdflang. A Fortran .mod cannot
be shared across compilers; rebuild the bindings with gfortran, or set
ROCRAND_FORTRAN_COMPILER_DIR to the directory to use.
The installed sources#
Every binding installs, beside the compiled module, the Fortran source it was compiled from:
<datadir>/<library>/fortran/<library>.F90
which on a stock install is, for example,
/opt/rocm/share/rocblas/fortran/rocblas.F90:
Binding |
Installed source |
|---|---|
HIP |
|
ROCTx |
|
hipFFT |
|
Every other library |
|
The source is there for three reasons:
Any compiler can use ROCm. The
.modand.aonly serveamdflang; the.F90serves every compiler. Nothing to clone, no other repository to track.It cannot disagree with your libraries. It was generated from the same headers as the installed
.soand ships in the same release, so it declares exactly the entry points your ROCm exports. A copy taken from a later release or a branch can declare routines your.sodoes not have, and then fails at link time (Binding and library versions).It is the reference. It is the authoritative list of what the binding declares, with the argument types, readable without a
.modviewer. It carries no documentation comments: the C headers’ documentation applies.
It sits under share/ rather than include/ because it is
compiler-independent: everything under <includedir>/fortran/ is
partitioned by compiler, so a source file there would be read as naming one.
Building a binding with your compiler#
The .F90 is self-contained Fortran: compiling it needs only a Fortran
compiler, no C headers and no .so, since the vendor symbols resolve when
you link your application. The C libraries are not rebuilt.
By hand, compile each source you need into a .mod and an object file.
The array overloads are behind -DUSE_ASSUMED_SHAPE=1 (or
-DUSE_ASSUMED_RANK=1 for the assumed-rank variants); without either you get
no array overloads, only the raw type(c_ptr) forms and the forms with
optional arguments:
mkdir -p mods
for lib in hip rocblas; do
gfortran -c -DUSE_ASSUMED_SHAPE=1 -Jmods \
/opt/rocm/share/$lib/fortran/$lib.F90 -o mods/$lib.o
done
gfortran app.f90 -Imods mods/rocblas.o mods/hip.o \
-L/opt/rocm/lib -lrocblas -lamdhip64 -o app
To keep only the wrappers you call, add -ffunction-sections -fdata-sections
to the first command and -Wl,--gc-sections to the second
(Binding and library versions).
With CMake, which also installs the result in the per-compiler layout with
its CMake package, so that find_package(rocblas-fortran) works as for the
shipped bindings. Each binding’s directory is a self-contained
project; build it against your installed ROCm, into a prefix of your own:
cmake -S <rocm-libraries>/bindings/fortran/rocblas -B build/rocblas-fortran \
-DCMAKE_Fortran_COMPILER=gfortran \
-DCMAKE_PREFIX_PATH=/opt/rocm \
-DCMAKE_INSTALL_PREFIX=$HOME/rocm-fortran
cmake --build build/rocblas-fortran
cmake --install build/rocblas-fortran
The project compiles one section per procedure with the compilers that accept
the flags, for a program linked with -Wl,--gc-sections
(Binding and library versions).
The bindings live in their own bindings/fortran/ tree, apart from the
libraries: in rocm-libraries under
bindings/fortran/<library> for the math libraries, and in
rocm-systems under
bindings/fortran for HIP and ROCTx, which one project builds together
(cmake -S <rocm-systems>/bindings/fortran -B build/fortran with the same
options). Check out the tag of the ROCm
you have installed (both repositories tag releases as therock-<version>),
for the reason given above.
Then compile your application with -I$HOME/rocm-fortran/include/fortran/gfortran
and -L$HOME/rocm-fortran/lib/fortran/gfortran, or add
$HOME/rocm-fortran to CMAKE_PREFIX_PATH.
A binding that uses another needs the other’s .mod, built with the
same compiler, so build in dependency order. Today that is one case: rocSOLVER
uses rocBLAS, so build rocBLAS’s binding first, and put its prefix on
CMAKE_PREFIX_PATH (or the -I line) when you build rocSOLVER’s.
Build options#
Skip this section if you only use ROCm’s precompiled bindings. These
options control how the bindings are built. They matter if you build ROCm
from source, or build a binding yourself as above. They replace the
HIPFORT_* options you passed to hipFORT’s build, which you no longer run.
Each binding is a standalone CMake project, in the bindings/fortran/ tree
of rocm-systems or rocm-libraries, built against the installed library.
No library build adds it. The options below are those of these projects.
BUILD_FORTRAN_BINDINGS replaces “do I build hipFORT at all”. Each binding
project exposes it, ON by default on Linux (OFF on Windows, where ROCm
ships no Fortran compiler) but guarded: built when a Fortran compiler is
present, skipped with a STATUS message when one is not.
-DBUILD_FORTRAN_BINDINGS=OFF opts out.
Old hipFORT option |
New equivalent |
|---|---|
(build hipFORT, or do not) |
|
|
Both fold into one tri-state |
|
Gone. The per-compiler layout is unconditional (see Where the files install) |
|
Gone, with the CUDA backend |
|
Gone. Use the plain |
|
|
|
Gone, with both link-time audits it gated, which checked the bindings
themselves rather than your code. What you build is the runtime suite,
under |
<LIB>_FORTRAN_COMPILER_DIR (for example ROCBLAS_FORTRAN_COMPILER_DIR)
overrides the per-compiler subdirectory name (Where the files install).
The array tiers themselves are unchanged: raw type(c_ptr) (Fortran 2003)
always present, array overloads (2008) on, assumed-rank (2018) opt-in. One
option now selects between them instead of two, because assumed-rank
replaces the per-rank variants rather than adding to them: an assumed-rank
dummy is not distinguishable by rank from the per-rank specifics, so the two
cannot legally coexist in one generic, and two booleans could express that
illegal combination. See Fortran interface variants for the call sites side by
side. The shipped bindings use the default, assumed-shape, which is what
hipFORT gives you today.
Each binding project has its own BUILD_FORTRAN_CLIENTS, ON by default,
which builds its test/. Asking for it when the binding was not built is a
skip, not an error. The library option of the same name, in rocBLAS, hipBLAS
and rocSPARSE, is unrelated: it still builds the Fortran part of the library’s
clients/.
To test from CMake whether a binding is available, use
if(TARGET roc::rocblas_fortran) after find_package(rocblas-fortran).
Trying the bindings before ROCm 10.3#
The bindings are under review in one pull request per library. Until they ship
in a ROCm release, you can try them by building a binding from its pull request
branch against a recent ROCm, such as a TheRock nightly, with the commands in
Building a binding with your compiler. A branch can be newer than your
nightly: link with -Wl,--gc-sections (Binding and library versions), so
that a routine the nightly does not have yet fails only if you call it. Build HIP’s binding first: the other
bindings’ tests use hip. ROCTx’s binding is built with HIP’s, in
rocm-systems’ bindings/fortran/.
Library |
Pull request |
|---|---|
HIP |
|
ROCTx |
|
rocBLAS |
|
hipBLAS |
|
rocSOLVER |
|
hipSOLVER |
|
rocSPARSE |
|
hipSPARSE |
|
rocFFT |
|
hipFFT, hipFFTW |
|
rocRAND |
|
hipRAND |
Once they are merged, TheRock builds them in a separate stage after the
libraries and packages each family’s bindings in one
amdrocm-<family>-fortran-devel package. Its nightly builds are the first
place to get them precompiled. Reports from trying a real code are especially
welcome at this stage:
open an issue.
What does not change#
Your calls.
hipMalloc,rocblas_dgemm,hipblasDgemm, the enum and type names, andhipCheckkeep their names and signatures. Only the module youusechanges. The bindings come from the same generator as current hipFORT; if you are on an older hipFORT release, a few argument types have since been corrected (an output scalar typed by reference instead oftype(c_ptr), for example), and the compiler points at each one.Calling styles. Raw
type(c_ptr)still works (including for OpenMP target data), handles are stilltype(c_ptr), andconst char*results are still returned astype(c_ptr). Every routineXis still a generic around abind(C)specificX_, so the array overloads resolve under the same name andX_stays callable. Arguments that C accepts asNULLcan be omitted (they areoptional). ROCTx also accepts acharacter(kind=c_char)string; appendc_null_charyourself ('zone'//c_null_char).The vendor libraries. You still link the same
.so(libamdhip64.so,librocblas.so, and so on). Only the Fortran.aand.modchange.
Special cases#
The in-tree Fortran modules that rocBLAS, hipSPARSE, hipRAND and the others shipped themselves have collisions of their own at 10.3; those are covered in Migrating from a library’s own Fortran module, not here.
If you build for NVIDIA (CUDA), the nvptx backend is dropped from the
new bindings. It survives only in old hipFORT until 11.0.
If you port code from CUDA Fortran, the hip* modules follow the names
of NVIDIA’s CUDA Fortran modules; see Migrating from CUDA Fortran.
FAQ#
Will I be warned before old hipFORT is removed?
Yes. Configuring hipFORT prints a CMake deprecation warning that points to
this guide; -Wno-deprecated silences it. A warning when your project calls
find_package(hipfort) is planned for the last release before 11.0. Old
hipFORT keeps compiling and working through the 10.x series, and nothing is
removed before ROCm 11.0, so a build that works today keeps working until then.
Can I install both the old and new bindings at once?
Yes. Nothing collides, so you can migrate one file at a time:
Axis |
Old hipFORT |
New bindings |
Clash? |
|---|---|---|---|
Module names |
|
|
No (prefixed versus bare) |
|
|
|
No (different subpaths) |
Archives |
|
|
No (different filenames) |
Symbols in the |
Mangled |
Mangled |
No (mangled per module name) |
CMake package |
|
|
No |
Two rules: build both with the same compiler as your application, and never
use both bindings for the same library in one scope. The clash is
source-level only. The archives coexist fine, because symbols are mangled
per module name, which is why migrating one file at a time works.
Note
This answer is about hipFORT, and the first row of the table is why it
cannot extend to a library’s own in-tree module: that one is already named
rocblas, not hipfort_rocblas, so there is no prefixed-versus-bare
distinction to keep the two apart. Same module name, no coexistence, no
file-by-file window. See Migrating from a library’s own Fortran module.
My code is old fixed-form Fortran. Can I use these bindings?
Yes. Fixed form is not an old standard: a .f file with DO ...
CONTINUE, implicit typing and a 72-column layout can use hip like any
other source. The requirement is on the compiler, which must handle Fortran
2003’s iso_c_binding, not on how your code looks.
The exception is a compiler limited to Fortran 77, which has no modules and so
no use statement to write. hipFORT never had a path for that either. If you
are stuck there, open an issue
rather than hand-writing glue: a C shim with Fortran 77 linkage could be
generated from the same headers.
Will my calls break?
Your calls will not: routine names, arguments, and calling styles stay the
same. But your code will not compile or link until you make the two edits
(rename the use line, change the link target); that is the breaking part,
and it is the whole of the migration.
Where do I get the new bindings?
They ship precompiled for amdflang with ROCm: in TheRock’s tarballs from
the 10.3 tech preview (and in the OS packages if they are ready), and in the OS
packages from 10.4, where you install amdrocm-<family>-fortran-devel (for
example amdrocm-blas-fortran-devel), or amdrocm-fortran for all of
them. For another compiler, see
Building a binding with your compiler; before 10.3, see
Trying the bindings before ROCm 10.3.