Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
187 commits
Select commit Hold shift + click to select a range
2ef6045
Use the new KMM header.
isazi May 30, 2024
d1fe85a
Added CUDA architecture.
isazi May 30, 2024
a7874c0
Use new header.
isazi May 30, 2024
dcef511
Merge pull request #25 from NLeSC-COMPAS/main
isazi May 30, 2024
50e9bb6
Merge branch 'main' into tune-jacobian
stijnh Jun 11, 2024
8c67e7a
Make jacobian hermitian kernel tunable
stijnh Jun 13, 2024
d2e436a
Add shared memory support to jacobian hermitian kernel
stijnh Jul 2, 2024
091fb60
Update tuning settings for hermitian kernel
stijnh Jul 16, 2024
11318f0
Merge pull request #26 from NLeSC-COMPAS/tune-jacobian
stijnh Jul 16, 2024
b844b77
Turn coil sensitivies into complex numbers
stijnh Jul 16, 2024
b51cf17
Using the dev branch of KMM
isazi Sep 4, 2024
7158414
Merge branch 'dev' of github.com:NLeSC-COMPAS/compas-toolkit into dev
isazi Sep 4, 2024
6c6846d
Make necessary modifications to work with KMM v0.3
stijnh Nov 26, 2024
27254cc
Using latest KMM dev branch (0.3 draft).
isazi Nov 27, 2024
c4bcb8f
Adapt interface to KMM 0.3
isazi Nov 27, 2024
2a31bc7
Adapt interface to KMM 0.3
isazi Nov 27, 2024
71e7a1f
Adapt interface to KMM 0.3
isazi Nov 27, 2024
54dab35
Bug fixed in KMM.
isazi Nov 27, 2024
ef23299
Adapt interface to KMM 0.3
isazi Nov 27, 2024
50d8811
Adapt interface to KMM 0.3
isazi Nov 27, 2024
353e3f2
Adapt interface to KMM 0.3
isazi Nov 27, 2024
6a89cf2
Fix compatiblity with KMM 0.3
stijnh Dec 9, 2024
3b67aa1
Fix incorrect `simulate_magnetization_kernel` definition
stijnh Dec 10, 2024
b3dd94d
Add support for multiple GPUs in `echos.jl`
stijnh Dec 16, 2024
aa0dfe6
Changes to make compas compile with latest KMM
stijnh Jan 23, 2025
aded0b7
Add KMM support for Jacobian kernels
stijnh Jan 23, 2025
da1b53b
Add support for multi-GPU execution to several kernels
stijnh Feb 4, 2025
6e3bccc
Fix bug in `simulate_magnetization_derivative`
stijnh Feb 6, 2025
cfa0956
Remove usage of `NDRange` as it was removed from KMM
stijnh Feb 18, 2025
a61fa37
change `EPGThreadBlockState::excite` to exit early if RF is near zero
stijnh Feb 18, 2025
4d61690
Remove `spdlog::set_level` as it can now be set using an environment …
stijnh Feb 18, 2025
c96d9b0
Correctly use camelcase for view names
stijnh Feb 20, 2025
ddf82cd
Merge branch 'main' into dev
stijnh Mar 10, 2025
08465ac
Update cuda-toolkit recipe.
isazi Mar 19, 2025
2d0177e
Syncing with kmm dev.
isazi Mar 19, 2025
765db5a
Fix path to header.
isazi Mar 19, 2025
6a94809
Fixes to match kmm API.
isazi Mar 19, 2025
3e3612a
Fixes to match kmm API.
isazi Mar 19, 2025
23651db
Fixes to match kmm API.
isazi Mar 19, 2025
eb27d28
Fixes to match kmm API.
isazi Mar 19, 2025
4fef444
Fixes to match kmm API.
isazi Mar 19, 2025
6a2242f
Fixes to match kmm API.
isazi Mar 19, 2025
31d5081
Fixes to match kmm API.
isazi Mar 19, 2025
5d5d025
Fixes to match kmm API.
isazi Mar 19, 2025
387fdcf
Fixes to match kmm API.
isazi Mar 19, 2025
e961799
Fixes to match kmm API.
isazi Mar 19, 2025
38602cc
Fixes to match kmm API.
isazi Mar 19, 2025
1cbf0db
Fixes to match kmm API.
isazi Mar 19, 2025
7f997bf
Fixed a bug in kmm
isazi Mar 19, 2025
9104297
Fixes to match kmm API.
isazi Mar 19, 2025
cd6402d
Fixes to match kmm API.
isazi Mar 19, 2025
20590f9
Fixes to match kmm API.
isazi Mar 19, 2025
f9f1f70
Fixes to match kmm API.
isazi Mar 19, 2025
4155d24
Fixes to match kmm API.
isazi Mar 19, 2025
794b507
Fixes to match kmm API.
isazi Mar 19, 2025
68d9feb
Fixes to match kmm API.
isazi Mar 19, 2025
ef55d60
Fixes to match kmm API.
isazi Mar 19, 2025
8af4556
Fixes to match kmm API.
isazi Mar 19, 2025
26fc168
Fixes to match kmm API.
isazi Mar 19, 2025
12585fe
Fixes to match kmm API.
isazi Mar 19, 2025
441f762
Fixes to match kmm API.
isazi Mar 19, 2025
1928953
Fixes to match kmm API.
isazi Mar 19, 2025
c0d3974
Fixes to match kmm API.
isazi Mar 19, 2025
35c5be6
Fixed a bug in kmm
isazi Mar 19, 2025
fe03034
Fixes to match kmm API.
isazi Mar 19, 2025
d882373
Fixes to match kmm API.
isazi Mar 19, 2025
433138e
Fixes to match kmm API.
isazi Mar 19, 2025
54b7434
Merge remote-tracking branch 'origin/dev' into dev
isazi Mar 19, 2025
7d83ae2
Change how `cfloat` is defined as data type for KMM
stijnh Mar 19, 2025
d3da4ff
KMM update.
isazi Mar 20, 2025
65c6db9
Typo for the complex types.
isazi Mar 20, 2025
020195f
KMM update.
isazi Mar 20, 2025
ee7e3b6
Inconsistent naming.
isazi Mar 20, 2025
6eb071c
Using the new KMM API.
isazi Mar 20, 2025
5e2f787
Using the new KMM API.
isazi Mar 20, 2025
98c88b9
Update KMM version.
isazi Mar 20, 2025
91df9ed
Update KMM version.
isazi Mar 20, 2025
d69fa9d
Update KMM version.
isazi Mar 20, 2025
fb05a03
Using the new KMM API.
isazi Mar 20, 2025
e8c42d5
Update KMM version.
isazi Mar 20, 2025
acaaa41
Integrate `KMM_DEFINE_STRUCT_ARGUMENT` for several structs
stijnh Mar 25, 2025
3adb6df
Fix several bugs due to migration to new KMM API
stijnh Mar 25, 2025
1a6ffb8
Add support for undersampling factor in FISP simulation
stijnh Apr 8, 2025
ea19efe
Temporarily disable memory pool as it leads to segfaults in MRStat
stijnh Apr 8, 2025
c0d6cb5
Update Julia bindings with new FISP parameters
stijnh Apr 8, 2025
81eec38
Add documentation to Julia package
stijnh Apr 10, 2025
8721736
Fix issue with echos.jl example
stijnh Apr 10, 2025
e24661e
Improve `print_equals_check` in `common.jl`
stijnh Apr 10, 2025
f0d8165
Updating to latest KMM.
isazi Apr 10, 2025
285aa46
Add documentation to several functions
stijnh Apr 15, 2025
c02ce0e
Fix and optimize `magnetization_to_signal` function
stijnh Apr 15, 2025
7e0cdb4
Reenable `simulate_signal.cpp` benchmark
stijnh Apr 15, 2025
0578e8e
Add Kernel Tuner script to tune the `magnetization_to_signal` kernel
stijnh Apr 17, 2025
4c35b7e
Rename `COMPAS_PANIC` to `COMPAS_CHECK`
stijnh Apr 18, 2025
d9ab8ad
Add Kernel Tuner script to tune the `magnetization_to_signal` kernel
stijnh Apr 18, 2025
cf5633c
Tune `simulate_signal` kernel
stijnh Apr 22, 2025
1ab6cb9
Update KMM to 0.3 beta
isazi Apr 23, 2025
e280fbc
Rewrite `compute_jacobian` to use intermediate arrays
stijnh Apr 28, 2025
be2ac72
Format CUDA kernels
stijnh Apr 28, 2025
9a6b432
Rewrite Jacobian product kernel to use GEMM
stijnh Apr 28, 2025
335b60d
KMM version 0.3
isazi Apr 29, 2025
4836ef4
Merge branch 'main' into dev
isazi Apr 30, 2025
9f7ccc3
Fix julia bindings
stijnh May 8, 2025
6fde259
Rewrite Jacobian hermitian kernel to use GEMM
stijnh May 15, 2025
5547e75
Add benchmark for Jacobian hermitian kernel
stijnh May 15, 2025
38da249
Merge pull request #30 from NLeSC-COMPAS/gemm-jacobian-hermitian
stijnh May 15, 2025
04947d8
Improve performance of FISP by unrolling and using shared memory
stijnh Jun 26, 2025
a025324
Fix bug in `simulate_magnetization_derivative`
stijnh Jun 26, 2025
d794dab
Fix incorrect behavior in invert for EPG
stijnh Jun 30, 2025
de4b3ad
Remove debugging statement from `simulate_fisp_for_voxel`
stijnh Jun 30, 2025
79f05b7
Extend FISP example in Julia
stijnh Jun 30, 2025
bbc7d3d
Add initial support to switch between GPUs
stijnh Jul 10, 2025
1a72fb9
First draft of HIP support in cmake.
isazi Aug 13, 2025
e3df0cc
Fix a bug in cmake.
isazi Aug 14, 2025
b6e9681
Working on HIP compilation.
isazi Aug 14, 2025
2cae810
Refactor test and benchmark compilation.
isazi Aug 14, 2025
a892ffa
Typo.
isazi Aug 14, 2025
a3d9088
Separate CUDA and HIP includes.
isazi Aug 14, 2025
dfc01aa
Support HIP in macros.
isazi Aug 15, 2025
f793c2c
Include the backend where necessary.
isazi Aug 15, 2025
2d8e978
Fix a bug in including the backend.
isazi Aug 15, 2025
2244fe2
Missing setting in cmake.
isazi Aug 15, 2025
3b62e3b
Typo.
isazi Aug 15, 2025
c74622a
Typo.
isazi Aug 15, 2025
358e161
Minore change.
isazi Aug 15, 2025
4ea087d
Add missing include.
isazi Aug 19, 2025
5128325
Enable __shfl_*_sync versions.
isazi Aug 19, 2025
37bcfdb
Added comment.
isazi Aug 19, 2025
c41ba01
Accommodate HIP signature
isazi Aug 19, 2025
4213f78
Fix a bug and do some formatting.
isazi Aug 19, 2025
3507207
Change memory layout of EPGThreadBlockState
stijnh Aug 19, 2025
a2e6ed1
Fix the mask type.
isazi Aug 19, 2025
11d4d0c
Fix the mask type.
isazi Aug 19, 2025
6a3ee9e
Add defined.
isazi Aug 19, 2025
7cf8454
Split the shuffle for HIP.
isazi Aug 19, 2025
34ea89b
Update files to match changes made in KMM
stijnh Aug 19, 2025
8d79059
Move some CUDA specific include to backends.h
isazi Aug 19, 2025
56ad56b
Use ASM only for CUDA.
isazi Aug 19, 2025
9035fda
Fix interface difference.
isazi Aug 19, 2025
74418e7
Porting the GEMM to ROCBLAS.
isazi Aug 19, 2025
2041c18
Add support to HIP complex numbers.
isazi Aug 19, 2025
b12b04c
Fix the gemm HIP interface.
isazi Aug 19, 2025
2f240d5
The HIP gemm should compile now.
isazi Aug 19, 2025
26dcb9a
Modify cmake to compile the bindings with HIP.
isazi Aug 19, 2025
2d79a9d
Disable chunking in `compas_make_tissue_parameters`
stijnh Aug 20, 2025
504b7f7
Modify cmake to compile the bindings with HIP.
isazi Aug 20, 2025
e99a90c
Modify cmake to compile the tests with HIP.
isazi Aug 20, 2025
c2fcb77
Fix inline for HIP.
isazi Aug 20, 2025
4397035
Enable HIP benchmarks.
isazi Aug 20, 2025
37aa741
Use complex types.
isazi Aug 20, 2025
f66b392
Always use f32 with HIP.
isazi Aug 20, 2025
05ba36b
Merge pull request #31 from NLeSC-COMPAS/optimize-fisp
stijnh Aug 21, 2025
29c3179
Merge branch 'dev' into hip-support
isazi Aug 21, 2025
f469339
Formatting.
isazi Aug 21, 2025
a3aec3a
Use kmm dev branch for development
isazi Aug 21, 2025
3983c58
Fix the HIP shuffle that got messed up in the merge.
isazi Aug 21, 2025
1b4b754
Replace CUDA syncwarp with something similar in HIP.
isazi Aug 21, 2025
877bc40
Replace CUDA syncwarp with something similar in HIP.
isazi Aug 21, 2025
655b4bd
Typo.
isazi Aug 21, 2025
e5babd9
Add HIP build to the CI.
isazi Aug 22, 2025
cc3714d
Make linter optional.
isazi Aug 22, 2025
9e0c6ca
Fixing a bug in CUDA build.
isazi Aug 22, 2025
c7bf70d
Fix GitHub CI.
isazi Aug 22, 2025
9186317
Fix GitHub CI.
isazi Aug 22, 2025
80475a3
Still something wrong with cmake on the CI.
isazi Aug 22, 2025
cdeeb7c
Parameterized warp size.
isazi Aug 27, 2025
defc14d
Change the mask
isazi Aug 27, 2025
f51f419
Add `COMPAS_USE_CUDA=1` flag to README
stijnh Aug 28, 2025
06b63b7
Set CMAKE_CUDA_ARCHITECTURES if not defined
stijnh Aug 28, 2025
cc95e26
Enable CUDA backend in CMake if neither CUDA or HIP is enabled
stijnh Sep 2, 2025
57ea212
Added basic `helloworld.jl` example
stijnh Sep 2, 2025
f4b0d06
Attempt to rewrite complex matrix multiply using regular matrix multiply
stijnh Sep 2, 2025
b122b63
Use `@ccall gc_safe=true` on Julia 12.0
stijnh Sep 22, 2025
0a90244
Change `compute_gemm` to support planar complex instead of interleave…
stijnh Sep 22, 2025
471d3a0
Add support for bfloat16 GEMM
stijnh Sep 22, 2025
c3fd862
Change the options of `GemmComputeMethod` enum
stijnh Sep 23, 2025
0c34496
Add GEMM benchmark
stijnh Sep 23, 2025
3d90707
Fix compile error in Julia bindings
stijnh Sep 23, 2025
1a659b3
Fix `@ccall_gcsafe` macro in Julia
stijnh Sep 23, 2025
31533e1
Add `LOW_PRECISION_MODE` option to julia bindings
stijnh Oct 14, 2025
76b8bac
Fix bug in `simulate_signal` when using GEMM method
stijnh Oct 14, 2025
3a58d0e
Update kernel_float to c1d132f
stijnh Oct 14, 2025
49dcc5d
Update KMM to c05264f652d2
stijnh Oct 14, 2025
f0f081f
Fix `compute_gemm` on HIP
stijnh Oct 14, 2025
4a0cf04
Merge pull request #32 from NLeSC-COMPAS/low-precision
stijnh Oct 14, 2025
1166d94
Set `KERNEL_FLOAT_LANGUAGE` in CMake when using HIP
stijnh Oct 16, 2025
03b3441
KMM updated to 0.3.1
isazi Dec 3, 2025
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
5 changes: 4 additions & 1 deletion .github/workflows/cmake-cuda-multi-compiler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
cpp_compiler: [g++, clang++]

steps:
- uses: Jimver/cuda-toolkit@v0.2.15
- uses: Jimver/cuda-toolkit@v0.2.22
id: cuda-toolkit
with:
method: 'network'
Expand All @@ -46,6 +46,9 @@ jobs:
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
-DSPDLOG_FMT_EXTERNAL:BOOL=ON
-DCOMPAS_USE_CUDA:BOOL=ON
-DCOMPAS_BUILD_TESTS:BOOL=ON
-DCOMPAS_BUILD_BENCHMARKS:BOOL=ON
-S ${{ github.workspace }}

- name: Build
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/cmake-hip.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: HIP build

on:
push:
branches: [ "dev" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
fail-fast: true

matrix:
os: [ubuntu-latest]
build_type: [Debug]

steps:
- uses: loostrum/rocm-installer@main
with:
version: 6.2.2
packages: hip-dev hipcc rocm-device-libs rocblas rocm-hip-runtime-dev rocrand

- uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_PREFIX_PATH=/opt/rocm
-DCMAKE_HIP_COMPILER_ROCM_ROOT:PATH=/opt/rocm
-DCMAKE_HIP_ARCHITECTURES=gfx90a
-DAMDGPU_TARGETS=gfx90a
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
-DSPDLOG_FMT_EXTERNAL:BOOL=ON
-DCOMPAS_USE_HIP:BOOL=ON
-DCOMPAS_BUILD_TESTS:BOOL=ON
-DCOMPAS_BUILD_BENCHMARKS:BOOL=ON
-S ${{ github.workspace }}

- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --parallel 4
5 changes: 4 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
[submodule "thirdparty/kernel_launcher"]
path = thirdparty/kernel_launcher
url = https://github.com/KernelTuner/kernel_launcher.git
[submodule "thirdparty/kernel_float"]
path = thirdparty/kernel_float
url = https://github.com/KernelTuner/kernel_float.git
[submodule "thirdparty/kmm"]
path = thirdparty/kmm
url = https://github.com/NLeSC-COMPAS/kmm.git
url = http://github.com/NLeSC-COMPAS/kmm.git
124 changes: 98 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)

set(PROJECT_NAME "compas-toolkit")
project(${PROJECT_NAME} LANGUAGES CXX CUDA)
project(${PROJECT_NAME} LANGUAGES CXX VERSION 0.2)

# User options (features)
option(COMPAS_USE_CUDA "Use the CUDA backend (default)" OFF)
option(COMPAS_USE_HIP "Use the HIP backend" OFF)
option(COMPAS_BUILD_TEST "Build tests" OFF)
option(COMPAS_BUILD_BENCHMARK "Build benchmarks" OFF)
option(COMPAS_ENABLE_LINTER "Enable clang-tidy linter" OFF)

# If neither backend is enabled, default to CUDA
if(NOT COMPAS_USE_CUDA AND NOT COMPAS_USE_HIP)
set(COMPAS_USE_CUDA ON CACHE BOOL "Use the CUDA backend (default)" FORCE)
message(STATUS "No GPU backend was enabled. Compiling for CUDA.")
endif()

# Check for mutual exclusivity
if(COMPAS_USE_CUDA AND COMPAS_USE_HIP)
message(FATAL_ERROR "Exactly one backend between CUDA and HIP must be enabled.")
endif()

# Set CMAKE_CUDA_ARCHITECTURES if not defined. This needs to happen before calling `add_library`
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES all-major)
endif()

# Enable C++17 support
set(CXX_STANDARD 17)
Expand All @@ -21,29 +45,71 @@ install(TARGETS ${PROJECT_NAME}
target_include_directories(${PROJECT_NAME} PUBLIC "${PROJECT_SOURCE_DIR}/include")
target_include_directories(${PROJECT_NAME} PUBLIC "${PROJECT_SOURCE_DIR}/src")

# The CUDA compiler struggles with the "Werror" options, so we need to explicitly forward it to the host compiler
# using `-Xcompiler=-Werror` if we are compiling CUDA code.
set(CXXFLAGS
$<$<COMPILE_LANGUAGE:CUDA>:-forward-unknown-to-host-compiler>
$<$<COMPILE_LANGUAGE:CUDA>:--generate-line-info>
-Wall -Wextra -Wconversion -Wno-unused-parameter
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-Werror>
$<$<COMPILE_LANGUAGE:CUDA>:--use_fast_math>
$<$<COMPILE_LANGUAGE:CUDA>:-Xptxas="-v">
)
target_compile_options(${PROJECT_NAME} PRIVATE ${CXXFLAGS})

# Enable PIC
set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON)

set(PROJECT_CLANG_TIDY clang-tidy)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_CLANG_TIDY "${PROJECT_CLANG_TIDY}")
if(COMPAS_ENABLE_LINTER)
set(PROJECT_CLANG_TIDY clang-tidy)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_CLANG_TIDY "${PROJECT_CLANG_TIDY}")
endif()

if(COMPAS_USE_CUDA)
enable_language(CUDA)
set(CUDA_SEPARABLE_COMPILATION ON)
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
set(CUDA_RESOLVE_DEVICE_SYMBOLS ON)
set_property(TARGET ${PROJECT_NAME} PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON)

find_package(CUDAToolkit REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::cudart_static)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::cuda_driver)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::cublas)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::nvrtc)
set_target_properties(${PROJECT_NAME} PROPERTIES CUDA_ARCHITECTURES ${CMAKE_CUDA_ARCHITECTURES})

# The CUDA compiler struggles with the "Werror" options, so we need to explicitly forward it to the host compiler
# using `-Xcompiler=-Werror` if we are compiling CUDA code.
set(CXXFLAGS
$<$<COMPILE_LANGUAGE:CUDA>:-forward-unknown-to-host-compiler>
$<$<COMPILE_LANGUAGE:CUDA>:--generate-line-info>
-Wall -Wextra -Wconversion -Wno-unused-parameter
#$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-Werror>
$<$<COMPILE_LANGUAGE:CUDA>:--use_fast_math>
$<$<COMPILE_LANGUAGE:CUDA>:-Xptxas="-v">
)
target_compile_options(${PROJECT_NAME} PRIVATE ${CXXFLAGS})

find_package(CUDAToolkit REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::cudart_static)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::cuda_driver)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::cublas)
target_link_libraries(${PROJECT_NAME} PUBLIC CUDA::nvrtc)
# Define `COMPAS_USE_CUDA` macro so that headers can detect CUDA usage
target_compile_definitions(${PROJECT_NAME} PUBLIC COMPAS_USE_CUDA=1)
set(KMM_USE_CUDA ON)
elseif(COMPAS_USE_HIP)
if(NOT DEFINED HIP_PATH)
if(NOT DEFINED ENV{HIP_PATH})
set(HIP_PATH "/opt/rocm/hip" CACHE PATH "Path to which HIP has been installed")
else()
set(HIP_PATH $ENV{HIP_PATH} CACHE PATH "Path to which HIP has been installed")
endif()
endif()
set(CMAKE_MODULE_PATH "${HIP_PATH}/cmake" ${CMAKE_MODULE_PATH})
enable_language(HIP)
set_source_files_properties(${sources} PROPERTIES LANGUAGE HIP)

find_package(HIP REQUIRED)
find_package(ROCBLAS REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC hip::host)
target_link_libraries(${PROJECT_NAME} PUBLIC hip::device)
target_link_libraries(${PROJECT_NAME} PUBLIC roc::rocblas)

# Enable HIP in KMM and kernel float
set(KMM_USE_HIP ON)
set(KERNEL_FLOAT_LANGUAGE "HIP")

# Define `COMPAS_USE_HIP` macro so that headers can detect HIP usage
target_compile_definitions(${PROJECT_NAME} PUBLIC COMPAS_USE_HIP=1)

# Needed for ROCM < 6.3
target_compile_definitions(${PROJECT_NAME} PUBLIC HIP_ENABLE_WARP_SYNC_BUILTINS=1)
endif()

# Installation of library files
set(COMPAS_LIB_PATH "${CMAKE_INSTALL_PREFIX}/lib")
Expand All @@ -59,14 +125,20 @@ configure_file(
${PROJECT_SOURCE_DIR}/julia-bindings/src/constants.h.input
${PROJECT_SOURCE_DIR}/julia-bindings/src/constants.h)

set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
add_subdirectory(thirdparty/Catch2)
set(KMM_USE_CUDA ON)
set(KMM_STATIC ON)
add_subdirectory(thirdparty/kmm)
target_link_libraries(${PROJECT_NAME} PUBLIC kmm)
add_subdirectory(thirdparty/kernel_float)

target_link_libraries(${PROJECT_NAME} PUBLIC kmm)
target_link_libraries(${PROJECT_NAME} PRIVATE kernel_float)

add_subdirectory(julia-bindings)
add_subdirectory(tests)
add_subdirectory(benchmarks)

if(COMPAS_BUILD_TEST)
add_subdirectory(thirdparty/Catch2)
add_subdirectory(tests)
endif()

if(COMPAS_BUILD_BENCHMARK)
add_subdirectory(benchmarks)
endif()
49 changes: 39 additions & 10 deletions CompasToolkit.jl/examples/common.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using BlochSimulators
using StaticArrays
using Statistics
using ComputationalResources
using ImagePhantoms
using LinearAlgebra
using Random
using Printf

Random.seed!(1337)

Expand All @@ -28,7 +30,7 @@ function generate_parameters(N)
ρ = ComplexF32.(ImagePhantoms.shepp_logan(N, ImagePhantoms.SheppLoganEmis())') |> vec;
T₁ = fill(0.85f0, N, N) |> vec;
T₂ = fill(0.05f0, N, N) |> vec;
B₀ = repeat(1:N,1,N) .|> Float32 |> vec;
B₀ = zeros(Float32, N, N) |> vec; #repeat(1:N,1,N) .|> Float32 |> vec;
B₁ = ones(Float32, N, N) |> vec;

FOVˣ, FOVʸ = 25.6, 25.6;
Expand Down Expand Up @@ -58,6 +60,7 @@ end

function generate_cartesian_trajectory(N)
FOVˣ, FOVʸ = 25.6, 25.6;
FOVˣ, FOVʸ = 30.0, 28.0;

nr = N # nr of readouts
ns = N # nr of samples per readout
Expand All @@ -77,7 +80,8 @@ function generate_coils(N, ncoils)
coil₃ = coil₁;
coil₄ = coil₂;

return hcat(coil₁ |> vec, coil₂ |> vec, coil₃ |> vec, coil₄ |> vec) .|> Float32
coils = hcat(coil₁ |> vec, coil₂ |> vec, coil₃ |> vec, coil₄ |> vec) .|> ComplexF32
return coils[:, 1:ncoils]
end

function generate_echos(N, sequence)
Expand Down Expand Up @@ -113,20 +117,45 @@ function generate_delta_echos(N, sequence)
)
end

function print_equals_check(expected, answer)
atol = 1e-9
function print_equals_check(expected, answer; atol = 1e-9)
answer = collect(answer)

println("=== Statistics ===")
# Shape and length are the same, so print once
@printf(" Shape: %s\n", string(size(expected)))
@printf(" Min: %s vs %s\n", expected[argmin(real.(expected))], answer[argmin(real.(answer))])
@printf(" Max: %s vs %s\n", expected[argmax(real.(expected))], answer[argmax(real.(answer))])
@printf(" Mean: %s vs %s\n", mean(expected), mean(answer))
@printf(" Std.: %s vs %s\n", std(expected), std(answer))
@printf(" Zeros: %s vs %s\n", mean(expected .== 0), mean(answer .== 0))
println()

println("=== Fraction of equal values ===")
for rtol in [0.001, 0.005, 0.01, 0.05, 0.1]
is_equal = isapprox.(answer, expected, atol=atol, rtol=rtol)
println("fraction equal (atol=$(atol), rtol=$(rtol)): ", sum(is_equal) / length(answer))
println(" atol=$(atol), rtol=$(rtol): ", sum(is_equal) / length(answer))
end

err = abs.(answer - expected)
index = argmax(err)
println("maximum abs error ($(index)): ", err[index], "($(answer[index]) vs $(expected[index]))")
err = abs.(answer .- expected)
idx_abs = argmax(err)
max_abs_err = err[idx_abs]

println("\n=== Maximum absolute error ===")
println(" Index: $(Tuple(idx_abs))")
println(" Answer: $(answer[idx_abs])")
println(" Expected: $(expected[idx_abs])")
println(" Absolute Error: $(max_abs_err)")
println()

rel_err = err ./ max.(abs.(expected), atol)
index = argmax(rel_err)
println("maximum rel error ($(index)): ", rel_err[index], "($(answer[index]) vs $(expected[index]))")
idx_rel = argmax(rel_err)
max_rel_err = rel_err[idx_rel]

println("\n=== Maximum relative error ===")
println(" Index: $(Tuple(idx_rel))")
println(" Answer: $(answer[idx_rel])")
println(" Expected: $(expected[idx_rel])")
println(" Relative Error: $max_rel_err")
println()
println()
end
9 changes: 6 additions & 3 deletions CompasToolkit.jl/examples/echos.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using CompasToolkit
using ImagePhantoms
using StructArrays

include("common.jl")

function make_phantom(N, coordinates)
Expand Down Expand Up @@ -48,6 +50,7 @@ x = LinRange(-FOVˣ/2, FOVˣ/2, N) # cm
y = LinRange(-FOVʸ/2, FOVʸ/2, N) # cm

coordinates = tuple.(x,y');
coordinates_ref = StructArray(Coordinates(x, y, zero(x)) for (x, y) in coordinates)

# Make trajectory
# dwell time between samples within readout
Expand Down Expand Up @@ -77,7 +80,7 @@ parameters = vec(make_phantom(N, coordinates));

# Make coil sensitivities
ncoils = 2
coil_sensitivities = rand((0.75:0.01:1.25), ncoils,N^2) .|> Float32
coil_sensitivities = rand((0.75:0.01:1.25), ncoils,N^2) .|> ComplexF32
coil_sensitivities .= 1
coil_sensitivities = map(SVector{ncoils}, eachcol(coil_sensitivities))

Expand Down Expand Up @@ -109,14 +112,14 @@ compas_trajectory = CompasToolkit.CartesianTrajectory(
trajectory.k_start_readout,
trajectory.Δk_adc[1]);

compas_coils = CompasToolkit.make_array(compas_context, Float32.(hcat(vec(coil₁), vec(coil₂))))
echos = CompasToolkit.simulate_magnetization(compas_parameters, compas_sequence)

# Set precision and send to gpu
parameters = gpu(f32(vec(parameters)))
sequence = gpu(f32(sequence))
coil_sensitivities = gpu(f32(coil_sensitivities))
trajectory = gpu(f32(trajectory))
coordinates_ref = gpu(coordinates_ref)

# Simulate data
echos_ref = simulate_magnetization(CUDALibs(), sequence, parameters)
Expand All @@ -126,6 +129,6 @@ print_equals_check(transpose(collect(echos_ref)), collect(echos))

# Phase encoding
echos = CompasToolkit.phase_encoding(echos, compas_parameters, compas_trajectory)
phase_encoding!(echos_ref, trajectory, parameters)
phase_encoding!(echos_ref, trajectory, coordinates_ref)

print_equals_check(transpose(collect(echos_ref)), collect(echos))
Loading