cmake_minimum_required(VERSION 3.22)

if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
  set(CMAKE_CUDA_ARCHITECTURES 75 CACHE STRING "CUDA architectures to build for")
endif()

project(spmv_sym LANGUAGES CXX CUDA)

find_package(CUDAToolkit REQUIRED)

add_executable(spmv_sym
  sym_spmv.cu
  matrix.cu
  cusparse_spmv.cu
  csr_naive_spmv.cu
  poisson_stencil.cu
  upper_atomic_spmv.cu
  upper_atomic_compensated_spmv.cu
)

add_executable(spmv_error_stats
  spmv_error_stats.cu
  matrix.cu
  upper_atomic_spmv.cu
  upper_atomic_compensated_spmv.cu
)

function(configure_spmv_target target)
  target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

  target_compile_features(${target} PRIVATE cxx_std_17)
  set_target_properties(${target} PROPERTIES
    CUDA_STANDARD 17
    CUDA_STANDARD_REQUIRED ON
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED ON
  )

  target_link_libraries(${target} PRIVATE CUDA::cusparse CUDA::cudart)

  target_compile_options(${target} PRIVATE
    $<$<COMPILE_LANGUAGE:CXX>:-Wall -Wextra -Wpedantic>
    $<$<COMPILE_LANGUAGE:CUDA>:--expt-relaxed-constexpr>
  )
endfunction()

configure_spmv_target(spmv_sym)
configure_spmv_target(spmv_error_stats)
