Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linalg: introduce 64-bit integer size BLAS/LAPACK implementation (ilp64) #888

Merged
merged 33 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c3a8177
add `ilp64` parameter
perazz Nov 13, 2024
65b1ec6
fypp: template `linalg` integer sizes
perazz Nov 13, 2024
1af9ea9
`blas_aux` template
perazz Nov 13, 2024
d5365ba
rollback to duplicate interface method (cannot use interfaces for `(*…
perazz Nov 13, 2024
8046997
`blas_s`: template integer type
perazz Nov 13, 2024
b9ff65b
`blas_d`: template integer type
perazz Nov 13, 2024
2cb8422
`blas_q`: template integer type
perazz Nov 13, 2024
7a35557
`blas_c`: template integer type
perazz Nov 13, 2024
9690464
`blas_z`: template integer type
perazz Nov 13, 2024
6487c23
`blas_w`: template integer type
perazz Nov 13, 2024
2c8de7b
`lapack_aux`: template integer type
perazz Nov 13, 2024
fbac7a4
`lapack_s`: template integer kind
perazz Nov 13, 2024
3028bb9
lapack_d: cleanup some loops/variables
perazz Nov 13, 2024
a6ad491
`lapack_d`: template integer kind
perazz Nov 13, 2024
4deeb9f
`lapack_q`: template integer kind
perazz Nov 13, 2024
21fac25
`lapack_c`: template integer kind
perazz Nov 13, 2024
72e8575
`lapack_z`: generalize integer kind
perazz Nov 13, 2024
93ae41e
`lapack_w`: generalize integer kind
perazz Nov 13, 2024
092d717
remove integer template from comment lines
perazz Nov 13, 2024
318ab8c
template whole BLAS interface
perazz Nov 14, 2024
eec81e6
merge interfaces with same REAL/CMPLX name
perazz Nov 14, 2024
c0f508f
generalize LAPACK interface
perazz Nov 14, 2024
4b5a6e6
`bbcsd`: generalize templated interface
perazz Nov 14, 2024
34b7a81
deployment: add `WITH_ILP64` option
perazz Nov 14, 2024
4ccfba8
Merge branch 'fortran-lang:master' into linalg_ilp64
perazz Dec 14, 2024
b782ddc
'1_${ik}$' -> '1'
perazz Dec 14, 2024
d40e088
`parameter` flags for checking external BLAS/LAPACK presence
perazz Dec 20, 2024
0a6b907
set `ilp64` to an invalid kind if not enabled
perazz Dec 20, 2024
4fc5e8b
Document linear algebra in README.md
perazz Dec 20, 2024
bef1344
deployment: add ilp64 option
perazz Dec 20, 2024
e620e9c
add 64-bit integer LAPACK deployment
perazz Dec 20, 2024
e13b612
fix deployment script
perazz Dec 20, 2024
0885394
Update config/fypp_deployment.py
perazz Dec 26, 2024
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
13 changes: 12 additions & 1 deletion .github/workflows/fpm-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ jobs:
- run: | # Just for deployment: create stdlib-fpm folder
python config/fypp_deployment.py --deploy_stdlib_fpm

- run: | # Just for deployment: create stdlib-fpm-ilp64 folder
python config/fypp_deployment.py --deploy_stdlib_fpm --with_ilp64

- run: | # Use fpm gnu ci to check xdp and qp
python config/fypp_deployment.py --with_xdp --with_qp
fpm test --profile release --flag '-DWITH_XDP -DWITH_QP'
Expand All @@ -48,4 +51,12 @@ jobs:
if: github.event_name != 'pull_request'
with:
BRANCH: stdlib-fpm
FOLDER: stdlib-fpm
FOLDER: stdlib-fpm

# Update and deploy the f90 files generated by github-ci to the `stdlib-fpm-ilp64` branch.
- name: Deploy with 64-bit integer support 🚀
uses: JamesIves/[email protected]
if: github.event_name != 'pull_request'
with:
BRANCH: stdlib-fpm-ilp64
FOLDER: stdlib-fpm-ilp64
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ list(
"-DWITH_CBOOL=$<BOOL:${WITH_CBOOL}>"
"-DWITH_QP=$<BOOL:${WITH_QP}>"
"-DWITH_XDP=$<BOOL:${WITH_XDP}>"
"-DWITH_ILP64=$<BOOL:${WITH_ILP64}>"
"-DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}"
"-DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR}"
"-DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}"
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,34 @@ as well as a specification document or ["spec"](https://stdlib.fortran-lang.org/
Some discussions and prototypes of proposed APIs along with a list of popular open source Fortran projects are available on the
[wiki](https://github.com/fortran-lang/stdlib/wiki).

## BLAS and LAPACK

`stdlib` ships full versions of BLAS and LAPACK, for all `real` and `complex` kinds, through generalized interface modules `stdlib_linalg_blas` and `stdlib_linalg_lapack`.
The 32- and 64-bit implementations may be replaced by external optimized libraries if available, which may allow for faster code.
When linking against external BLAS/LAPACK libraries, the user should define macros `STDLIB_EXTERNAL_BLAS` and `STDLIB_EXTERNAL_LAPACK`,
to ensure that the external library version is used instead of the internal implementation.

- In case of a CMake build, the necessary configuration can be added by ensuring both macros are defined:
```
add_compile_definitions(STDLIB_EXTERNAL_BLAS STDLIB_EXTERNAL_LAPACK)
```
- In case of an `fpm` build, the stdlib dependency should be set as follows:
```toml
[dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm", preprocess.cpp.macros=["STDLIB_EXTERNAL_BLAS", "STDLIB_EXTERNAL_LAPACK"] }
```

Support for 64-bit integer size interfaces of all BLAS and LAPACK procedures may also be enabled
by setting the CMake flag `-DWITH_ILP64=True`. The 64-bit integer version is always built in addition to
the 32-bit integer version, that is always available. Additional macros `STDLIB_EXTERNAL_BLAS_I64` and `STDLIB_EXTERNAL_LAPACK_I64`
may be defined to link against an external 64-bit integer library, such as Intel MKL.

- In case of an `fpm` build, 64-bit integer linear algebra support is given via branch `stdlib-fpm-ilp64`:
```toml
[dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm-ilp64", preprocess.cpp.macros=["STDLIB_EXTERNAL_BLAS_I64", "STDLIB_EXTERNAL_LAPACK"] }
```

## Contributing

* [Guidelines](CONTRIBUTING.md)
Expand Down
5 changes: 5 additions & 0 deletions config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ if (NOT DEFINED WITH_XDP)
)
set(WITH_XDP ${WITH_XDP} PARENT_SCOPE)
endif()
# Check if WITH_ILP64 is defined; if not, set it to FALSE
if (NOT DEFINED WITH_ILP64)
set(WITH_ILP64 FALSE)
set(WITH_ILP64 ${WITH_ILP64} PARENT_SCOPE)
endif()

# Export a pkg-config file
configure_file(
Expand Down
33 changes: 21 additions & 12 deletions config/fypp_deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def pre_process_fypp(args):
kwd.append("-DWITH_QP=True")
if args.with_xdp:
kwd.append("-DWITH_XDP=True")
if args.with_ilp64:
kwd.append("-DWITH_ILP64=True")

optparser = fypp.get_option_parser()
options, leftover = optparser.parse_args(args=kwd)
Expand Down Expand Up @@ -78,32 +80,38 @@ def process_f(file):
return


def deploy_stdlib_fpm():
def deploy_stdlib_fpm(with_ilp64):
"""create the stdlib-fpm folder for backwards compatibility (to be deprecated)
"""
import shutil
prune=(
"test_hash_functions.f90",
"f18estop.f90",
)
if not os.path.exists('stdlib-fpm'+os.sep+'src'):
os.makedirs('stdlib-fpm'+os.sep+'src')
if not os.path.exists('stdlib-fpm'+os.sep+'test'):
os.makedirs('stdlib-fpm'+os.sep+'test')
if not os.path.exists('stdlib-fpm'+os.sep+'example'):
os.makedirs('stdlib-fpm'+os.sep+'example')

if with_ilp64:
base_folder = 'stdlib-fpm-ilp64'
else:
base_folder = 'stdlib-fpm'

if not os.path.exists(base_folder+os.sep+'src'):
os.makedirs(base_folder+os.sep+'src')
if not os.path.exists(base_folder+os.sep+'test'):
os.makedirs(base_folder+os.sep+'test')
if not os.path.exists(base_folder+os.sep+'example'):
os.makedirs(base_folder+os.sep+'example')

def recursive_copy(folder):
for root, _, files in os.walk(folder):
for file in files:
if file not in prune:
if file.endswith(".f90") or file.endswith(".F90") or file.endswith(".dat") or file.endswith(".npy"):
shutil.copy2(os.path.join(root, file), 'stdlib-fpm'+os.sep+folder+os.sep+file)
shutil.copy2(os.path.join(root, file), base_folder+os.sep+folder+os.sep+file)
recursive_copy('src')
recursive_copy('test')
recursive_copy('example')
for file in ['.gitignore','fpm.toml','LICENSE','VERSION']:
shutil.copy2(file, 'stdlib-fpm'+os.sep+file)
shutil.copy2(file, base_folder+os.sep+file)
return

def fpm_build(args,unknown):
Expand Down Expand Up @@ -140,8 +148,9 @@ def fpm_build(args,unknown):
parser.add_argument("--maxrank",type=int, default=4, help="Set the maximum allowed rank for arrays")
parser.add_argument("--with_qp",action='store_true', help="Include WITH_QP in the command")
parser.add_argument("--with_xdp",action='store_true', help="Include WITH_XDP in the command")
parser.add_argument("--with_ilp64",action='store_true', help="Include WITH_ILP64 to build 64-bit integer BLAS/LAPACK")
parser.add_argument("--lnumbering",action='store_true', help="Add line numbering in preprocessed files")
parser.add_argument("--deploy_stdlib_fpm",action='store_true', help="create the stdlib-fpm folder")
parser.add_argument("--deploy_stdlib_fpm",action='store_true', help="create the stdlib-fpm folder")
# external libraries arguments
parser.add_argument("--build", action='store_true', help="Build the project")

Expand All @@ -158,8 +167,8 @@ def fpm_build(args,unknown):
# pre process the meta programming fypp files
pre_process_fypp(args)
if args.deploy_stdlib_fpm:
deploy_stdlib_fpm()
deploy_stdlib_fpm(args.with_ilp64)
#==========================================
# build using fpm
if args.build:
fpm_build(args,unknown)
fpm_build(args,unknown)
1 change: 1 addition & 0 deletions config/template.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set("@PROJECT_NAME@_WITH_CBOOL" @WITH_CBOOL@)
set("@PROJECT_NAME@_WITH_QP" @WITH_QP@)
set("@PROJECT_NAME@_WITH_XDP" @WITH_XDP@)
set("@PROJECT_NAME@_WITH_ILP64" @WITH_ILP64@)

if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@")
include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
Expand Down
15 changes: 15 additions & 0 deletions include/common.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#:set WITH_XDP = False
#:endif

#! Support for linear algebra with 64-bit integer sizes
#:if not defined("WITH_ILP64")
#:set WITH_ILP64 = False
#:endif

#! Real kinds to be considered during templating
#:set REAL_KINDS = ["sp", "dp"]
#:if WITH_XDP
Expand Down Expand Up @@ -74,6 +79,16 @@
$:"s" if cmplx=="c" else "d" if cmplx=="z" else "x" if cmplx=="y" else "q" if cmplx=="w" else "ERROR"
#:enddef

#! BLAS/LAPACK/Linear Algebra Integer Kinds
#:set LINALG_INT_KINDS = ["ilp"]
#:set LINALG_INT_SUFFIX = [""]
#:if WITH_ILP64
#:set LINALG_INT_KINDS = LINALG_INT_KINDS+["ilp64"]
#:set LINALG_INT_SUFFIX = LINALG_INT_SUFFIX+["_I64"]
#:endif
#:set LINALG_INT_TYPES = ["integer({})".format(k) for k in LINALG_INT_KINDS]
#:set LINALG_INT_KINDS_TYPES = list(zip(LINALG_INT_KINDS, LINALG_INT_TYPES, LINALG_INT_SUFFIX))

#! Complex types to be considered during templating
#:set CMPLX_TYPES = ["complex({})".format(k) for k in CMPLX_KINDS]
#:set CMPLX_SUFFIX = ["c{}".format(k) for k in CMPLX_KINDS]
Expand Down
Loading
Loading