blob: 28037927fd515327f6ad98cd802c012e2590e537 [file]
# SPDX-FileCopyrightText: The Eigen Authors
# SPDX-License-Identifier: MPL-2.0
# Benchmarks of the GPU kernels Eigen generates: the Tensor module's GpuDevice executor, its launches, and the
# hand-written and vendor baselines they are measured against. (contrib/benchmarks/GPU benchmarks the
# library-dispatch module contrib/Eigen/GPU, which maps expressions onto cuBLAS/cuSOLVER calls; nothing here
# depends on it.) Built when EIGEN_BENCH_CUDA is ON, see ../CMakeLists.txt.
# eigen_add_gpu_benchmark(name source [LIBRARIES lib ...] [DEFINITIONS def ...])
# Mirrors eigen_add_benchmark. The binary carries its own main() (gpu_bench_common.h), which prints the device it
# runs on and records it in the JSON context, so benchmark::benchmark_main is not linked. NDEBUG is defined, as for
# the CPU benchmarks; runtime failures are still caught, since GpuDevice and the harness check every call through
# EIGEN_GPU_RUNTIME_CHECK, which aborts under NDEBUG instead of asserting.
function(eigen_add_gpu_benchmark name source)
cmake_parse_arguments(BENCH "" "" "LIBRARIES;DEFINITIONS" ${ARGN})
if(NOT IS_ABSOLUTE "${source}")
set(source "${CMAKE_CURRENT_SOURCE_DIR}/${source}")
endif()
add_executable(${name} ${source})
target_include_directories(${name} PRIVATE ${EIGEN_SOURCE_DIR} ${CUDAToolkit_INCLUDE_DIRS})
target_link_libraries(${name} PRIVATE benchmark::benchmark CUDA::cudart)
if(BENCH_LIBRARIES)
target_link_libraries(${name} PRIVATE ${BENCH_LIBRARIES})
endif()
# Every source here is a .cu compiled as CUDA.
target_compile_options(${name} PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-O3>
$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:--expt-relaxed-constexpr;-lineinfo>)
target_compile_definitions(${name} PRIVATE NDEBUG EIGEN_USE_GPU)
if(BENCH_DEFINITIONS)
target_compile_definitions(${name} PRIVATE ${BENCH_DEFINITIONS})
endif()
endfunction()
# Elementwise expressions through the Tensor executor, float/half/bfloat16, aligned and unaligned maps, against a
# hand-written float4 kernel and the device-to-device copy roofline.
eigen_add_gpu_benchmark(bench_gpu_elementwise bench_gpu_elementwise.cu)
# Launch overhead: an executor launch of a tiny expression against a raw <<<>>> launch, LAUNCH_GPU_KERNEL and
# cudaLaunchKernel.
eigen_add_gpu_benchmark(bench_gpu_launch bench_gpu_launch.cu)
# Full and partial reductions against CUB, which nvcc compiles from the toolkit's own headers, so the CUDA 13
# relocation of CCCL is transparent here.
eigen_add_gpu_benchmark(bench_gpu_reduction bench_gpu_reduction.cu)
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 13.0)
# CUDA 13's CUB requires C++17, independently of Eigen's C++14 header contract.
target_compile_features(bench_gpu_reduction PRIVATE cuda_std_17)
endif()
# Contraction against cuBLAS, which is the gap a library dispatch would close.
eigen_add_gpu_benchmark(bench_gpu_contraction bench_gpu_contraction.cu LIBRARIES CUDA::cublas)
# What a temporary costs: the device's synchronous allocation against the stream-ordered one.
eigen_add_gpu_benchmark(bench_gpu_alloc bench_gpu_alloc.cu)