Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
/projects/rocrand/**/.readthedocs.yaml @ROCm/prims-rands-reviewers @ROCm/rands-docs-reviewers
/projects/rocrand/docs/ @ROCm/prims-rands-reviewers @ROCm/rands-docs-reviewers
/projects/rocrand/library/include/ @ROCm/prims-rands-reviewers @ROCm/rands-docs-reviewers
/bindings/fortran/rocrand/ @ROCm/rocm-fortran-maintainers @ROCm/prims-rands-reviewers

/projects/rocsolver/**/*.md @ROCm/solvers-reviewers @ROCm/solvers-docs-reviewers
/projects/rocsolver/**/*.rst @ROCm/solvers-reviewers @ROCm/solvers-docs-reviewers
Expand Down
9 changes: 9 additions & 0 deletions .github/repos-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,15 @@
"auto_subtree_pull": false,
"auto_subtree_push": false,
"monorepo_source_of_truth": true
},
{
"name": "rocrand",
"url": "ROCm/rocm-libraries",
"branch": "develop",
"category": "bindings/fortran",
"auto_subtree_pull": false,
"auto_subtree_push": false,
"monorepo_source_of_truth": true
}
]
}
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ repos:
(?x)
projects/hipblaslt/.*|
projects/hipsparse/.*|
# Vendored FRUIT unit-test harness (third party, own LICENSE.txt):
# kept byte-identical to upstream so that re-vendoring is a plain copy.
bindings/fortran/rocrand/test/fruit/.*|
shared/tensile/.*
- id: end-of-file-fixer
exclude: *opted_out_but_scanned
Expand Down
2 changes: 2 additions & 0 deletions bindings/fortran/rocrand/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Generated by the rocm-fortran generator
/rocrand.F90 linguist-generated=true
14 changes: 14 additions & 0 deletions bindings/fortran/rocrand/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Changelog for the rocRAND Fortran binding

## Unreleased

### Added

* Generated Fortran bindings, as a single `rocrand` module: `use rocrand`, link
`roc::rocrand_fortran`. Controlled by `BUILD_FORTRAN_BINDINGS` (`ON` on Linux, `OFF` on Windows,
where ROCm ships no Fortran compiler), `BUILD_FORTRAN_CLIENTS` and `FORTRAN_ARRAY_INTERFACES`
(`assumed-shape` by default; `none` or `assumed-rank`). Found with
`find_package(rocrand-fortran)`; the archive and the `.mod` files install per compiler, under
`<libdir>/fortran/<compiler>` and `<includedir>/fortran/<compiler>`.
The archive has one section per procedure: link with `-Wl,--gc-sections` to keep only the wrappers
you call.
200 changes: 200 additions & 0 deletions bindings/fortran/rocrand/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# MIT License
#
# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# Fortran bindings for rocRAND. rocrand.F90 is GENERATED by the rocm-fortran
# generator: regenerate it, do not edit it.

cmake_minimum_required(VERSION 3.19)

project(rocrand-fortran LANGUAGES NONE)

# Not ON: ROCm ships no Fortran compiler on Windows.
option(BUILD_FORTRAN_BINDINGS "Build the rocRAND Fortran bindings" "${UNIX}")
option(BUILD_FORTRAN_CLIENTS "Build the rocRAND Fortran binding tests" ON)

set(FORTRAN_ARRAY_INTERFACES "assumed-shape" CACHE STRING
"Array-argument overloads to expose: none, assumed-shape, or assumed-rank")
set_property(CACHE FORTRAN_ARRAY_INTERFACES PROPERTY STRINGS
none assumed-shape assumed-rank)

if(NOT BUILD_FORTRAN_BINDINGS)
return()
endif()

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/ROCmFortranCompiler.cmake")
if(NOT CMAKE_Fortran_COMPILER)
message(STATUS "rocRAND: no Fortran compiler found, skipping the Fortran bindings")
return()
endif()

enable_language(Fortran)

include(GNUInstallDirs)

if(NOT FORTRAN_ARRAY_INTERFACES MATCHES "^(none|assumed-shape|assumed-rank)$")
message(FATAL_ERROR
"FORTRAN_ARRAY_INTERFACES must be none, assumed-shape or assumed-rank, "
"not '${FORTRAN_ARRAY_INTERFACES}'.")
endif()

add_library(rocrand_fortran STATIC rocrand.F90)

add_library(roc::rocrand_fortran ALIAS rocrand_fortran)

# Each module compiles to one object, and a linker extracts whole objects from
# an archive, so a program that calls one wrapper links all of them. One section
# per procedure lets a program linked with -Wl,--gc-sections keep only the
# wrappers it calls, and still link when another wrapper names a C function the
# installed library does not export. Only these compilers split the sections
# (the Intel ones accept the flags but do not).
target_compile_options(rocrand_fortran PRIVATE
"$<$<COMPILE_LANG_AND_ID:Fortran,GNU,LLVMFlang,Flang,NVHPC>:-ffunction-sections;-fdata-sections>")

# A .mod is compiler-specific, so artifacts install per compiler. This mapping
# MUST match the one in rocrand-fortran-config.cmake.in.
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
set(_fc_name "gfortran")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Flang") # Flang, LLVMFlang
set(_fc_name "amdflang")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Cray")
set(_fc_name "ftn")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM")
set(_fc_name "ifx")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
set(_fc_name "ifort")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "NVHPC")
set(_fc_name "nvfortran")
else()
get_filename_component(_fc_name "${CMAKE_Fortran_COMPILER}" NAME_WE)
string(TOLOWER "${_fc_name}" _fc_name)
endif()

set(ROCRAND_FORTRAN_COMPILER_DIR "${_fc_name}" CACHE STRING
"Per-compiler subdirectory the .mod and the archive install under")

set(_moddir "${CMAKE_CURRENT_BINARY_DIR}/include")
set_target_properties(rocrand_fortran PROPERTIES
Fortran_MODULE_DIRECTORY "${_moddir}"
Fortran_PREPROCESS ON
Fortran_FORMAT FREE
POSITION_INDEPENDENT_CODE ON)

if(FORTRAN_ARRAY_INTERFACES STREQUAL "assumed-shape")
target_compile_definitions(rocrand_fortran PRIVATE USE_ASSUMED_SHAPE=1)
elseif(FORTRAN_ARRAY_INTERFACES STREQUAL "assumed-rank")
target_compile_definitions(rocrand_fortran PRIVATE USE_ASSUMED_RANK=1)
endif()

target_include_directories(rocrand_fortran PUBLIC
"$<BUILD_INTERFACE:${_moddir}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/fortran/${ROCRAND_FORTRAN_COMPILER_DIR}>")

# Link interface only. C is enabled because hip-config.cmake reaches FindThreads.
enable_language(C)
find_package(rocrand QUIET)

# Always TRUE or FALSE: the config template substitutes it into a bare if().
if(TARGET roc::rocrand)
target_link_libraries(rocrand_fortran INTERFACE roc::rocrand)
set(ROCRAND_FORTRAN_NEEDS_C_PACKAGE TRUE)
else()
set(ROCRAND_FORTRAN_NEEDS_C_PACKAGE FALSE)
message(STATUS
"rocRAND: the C library was not found, so the Fortran bindings carry no "
"link interface; a consumer will have to link it (-lrocrand) itself.")
endif()

# The uninstrumented Fortran executables cannot link an ASan librocrand.
if(BUILD_FORTRAN_CLIENTS AND BUILD_ADDRESS_SANITIZER)
message(STATUS
"rocRAND: address sanitizer is enabled, skipping the Fortran binding tests.")
set(BUILD_FORTRAN_CLIENTS OFF)
endif()

if(BUILD_FORTRAN_CLIENTS)
enable_testing()
add_subdirectory(test)
endif()

include(CMakePackageConfigHelpers)

set(_fortran_pkgdir "${CMAKE_INSTALL_LIBDIR}/cmake/rocrand-fortran")

install(TARGETS rocrand_fortran
EXPORT rocrand-fortran-targets
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}/fortran/${ROCRAND_FORTRAN_COMPILER_DIR}"
COMPONENT devel)
install(DIRECTORY "${_moddir}/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/fortran/${ROCRAND_FORTRAN_COMPILER_DIR}"
COMPONENT devel
FILES_MATCHING PATTERN "*.mod")

# Under share/: the config reads every entry of include/fortran/ as a compiler.
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/rocrand.F90"
DESTINATION "${CMAKE_INSTALL_DATADIR}/rocrand/fortran"
COMPONENT devel)
install(EXPORT rocrand-fortran-targets
FILE rocrand-fortran-targets.cmake
NAMESPACE roc::
DESTINATION "${_fortran_pkgdir}"
COMPONENT devel)

set(ROCRAND_FORTRAN_LIBDIR "${CMAKE_INSTALL_LIBDIR}/fortran")
set(ROCRAND_FORTRAN_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/fortran")

configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/rocrand-fortran-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/rocrand-fortran-config.cmake"
INSTALL_DESTINATION "${_fortran_pkgdir}"
PATH_VARS ROCRAND_FORTRAN_LIBDIR ROCRAND_FORTRAN_INCLUDEDIR)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rocrand-fortran-config.cmake"
DESTINATION "${_fortran_pkgdir}"
COMPONENT devel)

# Read from this tree, not rocrand_VERSION, which is the INSTALLED rocRAND's.
set(_fortran_version "")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../../projects/rocrand/CMakeLists.txt")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/../../../projects/rocrand/CMakeLists.txt" _rocrand_root)
string(REGEX MATCH "rocm_setup_version\\([ \t]*VERSION[ \t]+\"?([0-9]+\\.[0-9]+\\.[0-9]+)"
_m "${_rocrand_root}")
if(CMAKE_MATCH_1)
set(_fortran_version "${CMAKE_MATCH_1}")
endif()
unset(_rocrand_root)
endif()

if(_fortran_version)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/rocrand-fortran-config-version.cmake"
VERSION "${_fortran_version}"
COMPATIBILITY SameMajorVersion)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rocrand-fortran-config-version.cmake"
DESTINATION "${_fortran_pkgdir}"
COMPONENT devel)
else()
message(STATUS
"rocRAND: could not determine the version for the Fortran package, so no "
"rocrand-fortran-config-version.cmake is installed; "
"find_package(rocrand-fortran <version>) will not match.")
endif()
59 changes: 59 additions & 0 deletions bindings/fortran/rocrand/cmake/ROCmFortranCompiler.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT

# Runs check_language(Fortran), preferring ROCm's amdflang over the first
# Fortran compiler on PATH (often gfortran). An explicit CMAKE_Fortran_COMPILER
# or FC wins. CMAKE_Fortran_COMPILER is left false when none is found.

include(CheckLanguage)

# rocm-cmake's ROCMChecks watches CMAKE_Fortran_COMPILER and fails under
# ROCM_ERROR_TOOLCHAIN_VAR=ON; silence it across the writes.
set(_rocm_fc_warn_toolchain_var "${ROCM_WARN_TOOLCHAIN_VAR}")
set(_rocm_fc_error_toolchain_var "${ROCM_ERROR_TOOLCHAIN_VAR}")
set(ROCM_WARN_TOOLCHAIN_VAR OFF)
set(ROCM_ERROR_TOOLCHAIN_VAR OFF)

if(NOT CMAKE_Fortran_COMPILER AND NOT DEFINED ENV{FC})
set(_rocm_fc_hints)
foreach(_rocm_fc_cc "${CMAKE_CXX_COMPILER}" "${CMAKE_C_COMPILER}"
"${CMAKE_HIP_COMPILER}")
if(_rocm_fc_cc)
get_filename_component(_rocm_fc_dir "${_rocm_fc_cc}" DIRECTORY)
list(APPEND _rocm_fc_hints "${_rocm_fc_dir}")
endif()
endforeach()
foreach(_rocm_fc_root "${ROCM_PATH}" "$ENV{ROCM_PATH}" "/opt/rocm")
if(_rocm_fc_root)
list(APPEND _rocm_fc_hints "${_rocm_fc_root}/bin"
"${_rocm_fc_root}/lib/llvm/bin")
endif()
endforeach()
# Uncached, so a changed ROCM_PATH is honoured on reconfigure.
unset(_rocm_amdflang CACHE)
find_program(_rocm_amdflang NAMES amdflang HINTS ${_rocm_fc_hints}
NO_DEFAULT_PATH)
# A ROCm tree can carry a dangling amdflang symlink.
if(_rocm_amdflang)
execute_process(COMMAND "${_rocm_amdflang}" --version
RESULT_VARIABLE _rocm_fc_rc
OUTPUT_QUIET ERROR_QUIET)
if(_rocm_fc_rc EQUAL 0)
set(CMAKE_Fortran_COMPILER "${_rocm_amdflang}" CACHE FILEPATH
"Fortran compiler used for the ROCm Fortran bindings" FORCE)
endif()
endif()
unset(_rocm_amdflang CACHE)
endif()

check_language(Fortran)

set(ROCM_WARN_TOOLCHAIN_VAR "${_rocm_fc_warn_toolchain_var}")
set(ROCM_ERROR_TOOLCHAIN_VAR "${_rocm_fc_error_toolchain_var}")
unset(_rocm_fc_warn_toolchain_var)
unset(_rocm_fc_error_toolchain_var)
unset(_rocm_fc_hints)
unset(_rocm_fc_cc)
unset(_rocm_fc_dir)
unset(_rocm_fc_root)
unset(_rocm_fc_rc)
30 changes: 30 additions & 0 deletions bindings/fortran/rocrand/cmake/toolchains/amdflang.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# MIT License
#
# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# AMD ROCm toolchain (amdflang). The recommended default: amdflang is the LLVM-based Fortran compiler shipped with ROCm.
# Usage, from bindings/fortran/rocrand:
# cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/amdflang.cmake

set(CMAKE_Fortran_COMPILER amdflang CACHE FILEPATH "Fortran compiler")
set(CMAKE_C_COMPILER amdclang CACHE FILEPATH "C compiler")
30 changes: 30 additions & 0 deletions bindings/fortran/rocrand/cmake/toolchains/cray.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# MIT License
#
# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# Cray toolchain. ftn and cc are the Cray compiler wrappers, which select the underlying compiler from the loaded PrgEnv module.
# Usage, from bindings/fortran/rocrand:
# cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/cray.cmake

set(CMAKE_Fortran_COMPILER ftn CACHE FILEPATH "Fortran compiler")
set(CMAKE_C_COMPILER cc CACHE FILEPATH "C compiler")
Loading
Loading