Repository: root-project/genvectorx
Pull request #5: Implement alpaka backend for vector operations
Author: login: sbaldu
Created: 2025-02-26T15:28:14Z | Merged: 2025-03-14T12:53:44Z

This PR implements an extra backend for the vector operations, providing host functions calling alpaka kernels.




Diff:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a994c40..055b0c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ project(genvectorx)
 cmake_minimum_required(VERSION 3.9)
 
 find_package(ROOT COMPONENTS MathCore ROOTVecOps GenVector)
-if (ROOT_FOUND)
+if(ROOT_FOUND)
   message(STATUS "ROOT library found")
   message(DEBUG "ROOT_INCLUDE_DIRS: ${ROOT_INCLUDE_DIRS}")
   message(DEBUG "ROOT_LIBRARIES: ${ROOT_LIBRARIES}")
@@ -17,72 +17,84 @@ include_directories(${CMAKE_SOURCE_DIR}/inc)
 
 string(TOUPPER "${CMAKE_BUILD_TYPE}" _BUILD_TYPE_UPPER)
 
-if (oneapi)
-   SET(_sycl_search_dirs ${SYCL_ROOT_DIR} /usr/lib /usr/local/lib /opt/intel/oneapi/compiler/latest/linux)
-   find_program(SYCL_COMPILER
-                NAMES icpx clang++
-                HINTS ${_sycl_search_dirs}
-                PATH_SUFFIXES bin)
-   find_path(SYCL_INCLUDE_DIR
-             NAMES sycl/sycl.hpp
-             HINTS ${_sycl_search_dirs}
-             PATH_SUFFIXES include)
-    find_path(SYCL_LIB_DIR
-             NAMES libsycl.so
-             HINTS ${_sycl_search_dirs}
-             PATH_SUFFIXES lib)
-    message(DEBUG "_sycl_search_dirs: ${_sycl_search_dirs}")
-    message(DEBUG "SYCL_COMPILER: ${SYCL_COMPILER}")
-    message(DEBUG "SYCL_INCLUDE_DIR: ${SYCL_INCLUDE_DIR}")
-    message(DEBUG "SYCL_LIB_DIR: ${SYCL_LIB_DIR}")
-
-    if (syclcuda)
-      set(_fsycl_targets "-fsycl-targets=nvptx64-nvidia-cuda,spir64_x86_64,spir64 -Xsycl-target-backend=nvptx64-nvidia-cuda --cuda-gpu-arch=sm_${CMAKE_CUDA_ARCHITECTURES} --cuda-path=${CUDA_TOOLKIT_ROOT_DIR} ")
-    elseif (syclamd)
-      set(_fsycl_targets "-fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=${CMAKE_OFFLOAD_ARCHITECTURES} ")
-    else()
-        set(_fsycl_targets "-fsycl-targets=spir64_x86_64,spir64")
-    endif()
+if(oneapi)
+  set(_sycl_search_dirs ${SYCL_ROOT_DIR} /usr/lib /usr/local/lib
+                        /opt/intel/oneapi/compiler/latest/linux)
+  find_program(
+    SYCL_COMPILER
+    NAMES icpx clang++
+    HINTS ${_sycl_search_dirs}
+    PATH_SUFFIXES bin)
+  find_path(
+    SYCL_INCLUDE_DIR
+    NAMES sycl/sycl.hpp
+    HINTS ${_sycl_search_dirs}
+    PATH_SUFFIXES include)
+  find_path(
+    SYCL_LIB_DIR
+    NAMES libsycl.so
+    HINTS ${_sycl_search_dirs}
+    PATH_SUFFIXES lib)
+  message(DEBUG "_sycl_search_dirs: ${_sycl_search_dirs}")
+  message(DEBUG "SYCL_COMPILER: ${SYCL_COMPILER}")
+  message(DEBUG "SYCL_INCLUDE_DIR: ${SYCL_INCLUDE_DIR}")
+  message(DEBUG "SYCL_LIB_DIR: ${SYCL_LIB_DIR}")
+
+  if(syclcuda)
+    set(_fsycl_targets
+        "-fsycl-targets=nvptx64-nvidia-cuda,spir64_x86_64,spir64 -Xsycl-target-backend=nvptx64-nvidia-cuda --cuda-gpu-arch=sm_${CMAKE_CUDA_ARCHITECTURES} --cuda-path=${CUDA_TOOLKIT_ROOT_DIR} "
+    )
+  elseif(syclamd)
+    set(_fsycl_targets
+        "-fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=${CMAKE_OFFLOAD_ARCHITECTURES} "
+    )
+  else()
+    set(_fsycl_targets "-fsycl-targets=spir64_x86_64,spir64")
+  endif()
 
-    set(SYCL_COMPILER_FLAGS "-fPIC -fsycl -fsycl-unnamed-lambda -sycl-std=2020 ${_fsycl_targets} ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_BUILD_TYPE_UPPER}}")
-    message(DEBUG "SYCL compiler flags: ${SYCL_COMPILER_FLAGS}")
-    separate_arguments(SYCL_COMPILER_FLAGS NATIVE_COMMAND ${SYCL_COMPILER_FLAGS})
+  set(SYCL_COMPILER_FLAGS
+      "-fPIC -fsycl -fsycl-unnamed-lambda -sycl-std=2020 ${_fsycl_targets} ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_BUILD_TYPE_UPPER}}"
+  )
+  message(DEBUG "SYCL compiler flags: ${SYCL_COMPILER_FLAGS}")
+  separate_arguments(SYCL_COMPILER_FLAGS NATIVE_COMMAND ${SYCL_COMPILER_FLAGS})
 
-    if (SYCL_COMPILER)
-      set(sycl ON)
+  if(SYCL_COMPILER)
+    set(sycl ON)
 
     function(add_sycl_to_root_target_exe)
-      CMAKE_PARSE_ARGUMENTS(ARG "" "TARGET" "SOURCES;HEADERS;DEPENDENCIES;INCLUDE_DIRECTORIES;COMPILE_DEFINITIONS" ${ARGN})
+      cmake_parse_arguments(
+        ARG "" "TARGET"
+        "SOURCES;HEADERS;DEPENDENCIES;INCLUDE_DIRECTORIES;COMPILE_DEFINITIONS"
+        ${ARGN})
 
-      
       # Get include directories for the SYCL target
       set(_inc_dirs ${ARG_INCLUDE_DIRECTORIES})
       list(APPEND _inc_dirs ${SYCL_INCLUDE_DIR})
-      if (_inc_dirs)
+      if(_inc_dirs)
         list(REMOVE_DUPLICATES _inc_dirs)
         list(TRANSFORM _inc_dirs PREPEND -I)
       endif()
-      
+
       foreach(comp_def ${ARG_COMPILE_DEFINITIONS})
         list(APPEND _COMPILE_DEFINITIONS -D${comp_def})
       endforeach()
 
       # Compile the sycl source files with the found sycl compiler
       foreach(src ${ARG_SOURCES})
-        set(_output_path ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${ARG_TARGET}.dir/${src}${CMAKE_CXX_OUTPUT_EXTENSION})
+        set(_output_path
+            ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${ARG_TARGET}.dir/${src}${CMAKE_CXX_OUTPUT_EXTENSION}
+        )
         list(APPEND _outputs ${_output_path})
 
-        add_custom_command(OUTPUT ${_output_path}
-                            COMMAND ${SYCL_COMPILER}
-                                    ${SYCL_COMPILER_FLAGS} -c
-                                    ${_inc_dirs}
-                                    ${_COMPILE_DEFINITIONS}
-                                    -o ${_output_path}
-                                    ${CMAKE_CURRENT_SOURCE_DIR}/${src}
-                            DEPENDS ${ARG_DEPENDENCIES}
-                            COMMENT "Building SYCL object ${_output_path}"
-                            MAIN_DEPENDENCY ${src}
-                            )
+        add_custom_command(
+          OUTPUT ${_output_path}
+          COMMAND
+            ${SYCL_COMPILER} ${SYCL_COMPILER_FLAGS} -c ${_inc_dirs}
+            ${_COMPILE_DEFINITIONS} -o ${_output_path}
+            ${CMAKE_CURRENT_SOURCE_DIR}/${src}
+          DEPENDS ${ARG_DEPENDENCIES}
+          COMMENT "Building SYCL object ${_output_path}"
+          MAIN_DEPENDENCY ${src})
       endforeach()
 
       set(SYCL_LINKER_FLAGS "-L${SYCL_LIB_DIR}  -Wl,-rpath,${SYCL_LIB_DIR}")
@@ -91,35 +103,36 @@ if (oneapi)
         list(APPEND SYCL_LINKER_FLAGS ":$<TARGET_FILE_DIR:${lib}>")
       endforeach()
       string(REPLACE ";" "" SYCL_LINKER_FLAGS ${SYCL_LINKER_FLAGS})
-    
+
       separate_arguments(SYCL_LINKER_FLAGS NATIVE_COMMAND ${SYCL_LINKER_FLAGS})
       set_target_properties(${ARG_TARGET} PROPERTIES LINKER_LANGUAGE CXX)
 
-      set_property(TARGET ${ARG_TARGET} PROPERTY SOURCES ${_outputs})  
-      set_property(TARGET ${ARG_TARGET} PROPERTY LINK_DEPENDS ${ARG_DEPENDENCIES})
-
-      add_custom_command(TARGET ${ARG_TARGET}
-                            COMMAND ${SYCL_COMPILER} 
-                                    ${SYCL_COMPILER_FLAGS}
-                                    ${SYCL_LINKER_FLAGS}
-                                    ${_lib_dep_paths}
-                                    ${_COMPILE_DEFINITIONS}
-                                    -o ${ARG_TARGET} ${_outputs} 
-                            DEPENDS ${ARG_DEPENDENCIES}
-                            COMMENT "Building SYCL executable ${ARG_TARGET}"
-                            MAIN_DEPENDENCY ${ARG_TARGET}
-                            )
-    
+      set_property(TARGET ${ARG_TARGET} PROPERTY SOURCES ${_outputs})
+      set_property(TARGET ${ARG_TARGET} PROPERTY LINK_DEPENDS
+                                                 ${ARG_DEPENDENCIES})
+
+      add_custom_command(
+        TARGET ${ARG_TARGET}
+        COMMAND
+          ${SYCL_COMPILER} ${SYCL_COMPILER_FLAGS} ${SYCL_LINKER_FLAGS}
+          ${_lib_dep_paths} ${_COMPILE_DEFINITIONS} -o ${ARG_TARGET} ${_outputs}
+          DEPENDS ${ARG_DEPENDENCIES}
+        COMMENT "Building SYCL executable ${ARG_TARGET}" MAIN_DEPENDENCY
+                ${ARG_TARGET})
+
     endfunction()
 
     function(add_sycl_to_root_target)
-      CMAKE_PARSE_ARGUMENTS(ARG "" "TARGET" "SOURCES;HEADERS;DEPENDENCIES;INCLUDE_DIRECTORIES;COMPILE_DEFINITIONS" ${ARGN})
+      cmake_parse_arguments(
+        ARG "" "TARGET"
+        "SOURCES;HEADERS;DEPENDENCIES;INCLUDE_DIRECTORIES;COMPILE_DEFINITIONS"
+        ${ARGN})
 
       set(_library_name ${ARG_TARGET})
 
       # Get include directories for the SYCL target
       set(_inc_dirs ${ARG_INCLUDE_DIRECTORIES})
-      if (_inc_dirs)
+      if(_inc_dirs)
         list(REMOVE_DUPLICATES _inc_dirs)
         list(TRANSFORM _inc_dirs PREPEND -I)
       endif()
@@ -137,70 +150,81 @@ if (oneapi)
 
       # Compile the sycl source files with the found sycl compiler
       foreach(src ${ARG_SOURCES})
-        set(_output_path ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${ARG_TARGET}.dir/${src}${CMAKE_CXX_OUTPUT_EXTENSION})
+        set(_output_path
+            ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${ARG_TARGET}.dir/${src}${CMAKE_CXX_OUTPUT_EXTENSION}
+        )
         list(APPEND _outputs ${_output_path})
 
-        add_custom_command(OUTPUT ${_output_path}
-                            COMMAND ${SYCL_COMPILER}  
-                                    ${SYCL_COMPILER_FLAGS} -c
-                                    ${_inc_dirs} 
-                                    ${_COMPILE_DEFINITIONS}
-                                    -o ${_output_path}
-                                    ${CMAKE_CURRENT_SOURCE_DIR}/${src}
-                            DEPENDS ${ARG_DEPENDENCIES}
-                            COMMENT "Building SYCL object ${_output_path}"
-                            MAIN_DEPENDENCY ${src}
-                            )
+        add_custom_command(
+          OUTPUT ${_output_path}
+          COMMAND
+            ${SYCL_COMPILER} ${SYCL_COMPILER_FLAGS} -c ${_inc_dirs}
+            ${_COMPILE_DEFINITIONS} -o ${_output_path}
+            ${CMAKE_CURRENT_SOURCE_DIR}/${src}
+          DEPENDS ${ARG_DEPENDENCIES}
+          COMMENT "Building SYCL object ${_output_path}"
+          MAIN_DEPENDENCY ${src})
       endforeach()
 
-      set(SYCL_LINKER_FLAGS "-shared -Wl,-soname,$<TARGET_FILE:${_library_name}> -L${SYCL_LIB_DIR} ${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,${SYCL_LIB_DIR}:$<TARGET_FILE_DIR:${_library_name}>")
+      set(SYCL_LINKER_FLAGS
+          "-shared -Wl,-soname,$<TARGET_FILE:${_library_name}> -L${SYCL_LIB_DIR} ${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,${SYCL_LIB_DIR}:$<TARGET_FILE_DIR:${_library_name}>"
+      )
       separate_arguments(SYCL_LINKER_FLAGS NATIVE_COMMAND ${SYCL_LINKER_FLAGS})
       message(DEBUG "SYCL linker flags: ${SYCL_LINKER_FLAGS}")
       set_property(TARGET ${ARG_TARGET} PROPERTY LINK_DEPENDS ${_outputs})
-      set_property(TARGET ${ARG_TARGET} PROPERTY LINK_DEPENDS ${ARG_DEPENDENCIES})
-
-      add_custom_command(OUTPUT ${ARG_TARGET}
-                          COMMAND ${SYCL_COMPILER}
-                                  ${SYCL_LINKER_FLAGS}
-                                  ${_lib_dep_paths} ${_inc_dirs}
-                                  ${_COMPILE_DEFINITIONS} 
-                                  -o  $<TARGET_FILE:${_library_name}>
-                                  ${_outputs}
-                          DEPENDS ${ARG_DEPENDENCIES} ${_outputs} 
-                          COMMENT "Linking shared library ${_library_name}"
-                          MAIN_DEPENDENCY ${_outputs}
-                          )
-
-
-   endfunction()
+      set_property(TARGET ${ARG_TARGET} PROPERTY LINK_DEPENDS
+                                                 ${ARG_DEPENDENCIES})
+
+      add_custom_command(
+        OUTPUT ${ARG_TARGET}
+        COMMAND
+          ${SYCL_COMPILER} ${SYCL_LINKER_FLAGS} ${_lib_dep_paths} ${_inc_dirs}
+          ${_COMPILE_DEFINITIONS} -o $<TARGET_FILE:${_library_name}> ${_outputs}
+        DEPENDS ${ARG_DEPENDENCIES} ${_outputs}
+        COMMENT "Linking shared library ${_library_name}"
+        MAIN_DEPENDENCY ${_outputs})
 
+    endfunction()
 
-     message(STATUS "Found Intel OneAPI SYCL: ${SYCL_INCLUDE_DIR}  (modify with: SYCL_ROOT_DIR)")
-     message(STATUS "Using SYCL Host Compiler: ${SYCL_COMPILER}")
-else()
+    message(
+      STATUS
+        "Found Intel OneAPI SYCL: ${SYCL_INCLUDE_DIR}  (modify with: SYCL_ROOT_DIR)"
+    )
+    message(STATUS "Using SYCL Host Compiler: ${SYCL_COMPILER}")
+  else()
     if(fail-on-missing)
-       message(FATAL_ERROR "OpenAPI SYCL library not found")
-     else()
-       message(STATUS "OpenAPI SYCL library not found")
-       set(sycl OFF CACHE BOOL "Disabled because no SYCL implementation is not found" FORCE)
-     endif()
-   endif()
- endif()
-
-if (adaptivecpp)
-  if (oneapi)
+      message(FATAL_ERROR "OpenAPI SYCL library not found")
+    else()
+      message(STATUS "OpenAPI SYCL library not found")
+      set(sycl
+          OFF
+          CACHE BOOL "Disabled because no SYCL implementation is not found"
+                FORCE)
+    endif()
+  endif()
+endif()
+
+if(adaptivecpp)
+  if(oneapi)
     message(WARNING "Disable OneAPI to load AdaptiveCpp")
-    set(sycl OFF CACHE BOOL "Disabled because AdaptiveCpp is enabled" FORCE)
+    set(sycl
+        OFF
+        CACHE BOOL "Disabled because AdaptiveCpp is enabled" FORCE)
   else()
     find_package(AdaptiveCpp)
-    #add_definitions(-DHIPSYCL_DEBUG_LEVEL=4)
-    if (AdaptiveCpp_FOUND)
+    # add_definitions(-DHIPSYCL_DEBUG_LEVEL=4)
+    if(AdaptiveCpp_FOUND)
       set(sycl ON)
       function(add_sycl_to_root_target)
-        CMAKE_PARSE_ARGUMENTS(ARG "" "TARGET" "SOURCES;HEADERS;DEPENDENCIES;INCLUDE_DIRECTORIES;COMPILE_DEFINITIONS" ${ARGN})
-        target_compile_definitions(${ARG_TARGET} PUBLIC ${ARG_COMPILE_DEFINITIONS})
+        cmake_parse_arguments(
+          ARG "" "TARGET"
+          "SOURCES;HEADERS;DEPENDENCIES;INCLUDE_DIRECTORIES;COMPILE_DEFINITIONS"
+          ${ARGN})
+        target_compile_definitions(${ARG_TARGET}
+                                   PUBLIC ${ARG_COMPILE_DEFINITIONS})
         target_link_libraries(${ARG_TARGET} PUBLIC ${ARG_DEPENDENCIES})
-        target_include_directories(${ARG_TARGET} INTERFACE ${AdaptiveCpp_INCLUDE_DIRS})
+        target_include_directories(${ARG_TARGET}
+                                   INTERFACE ${AdaptiveCpp_INCLUDE_DIRS})
         target_link_libraries(${ARG_TARGET} INTERFACE AdaptiveCpp::acpp-rt)
         add_sycl_to_target(TARGET ${ARG_TARGET} SOURCES ${ARG_SOURCES})
       endfunction()
@@ -210,7 +234,10 @@ if (adaptivecpp)
         message(FATAL_ERROR "AdaptiveCpp library not found")
       else()
         message(STATUS "AdaptiveCpp library not found")
-        set(sycl OFF CACHE BOOL "Disabled because no SYCL implementation is not found" FORCE)
+        set(sycl
+            OFF
+            CACHE BOOL "Disabled because no SYCL implementation is not found"
+                  FORCE)
       endif()
     endif()
   endif()
@@ -222,152 +249,239 @@ endif()
 
 if(NOT ACPP_DEBUG_LEVEL)
   if(CMAKE_BUILD_TYPE MATCHES "Debug")
-    set(ACPP_DEBUG_LEVEL 3 CACHE STRING
-      "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
-FORCE)
+    set(ACPP_DEBUG_LEVEL
+        3
+        CACHE
+          STRING
+          "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
+          FORCE)
   else()
-    set(ACPP_DEBUG_LEVEL 2 CACHE STRING
-      "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
-FORCE)
+    set(ACPP_DEBUG_LEVEL
+        2
+        CACHE
+          STRING
+          "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
+          FORCE)
   endif()
 endif()
 
-if (cuda)
+if((cuda) OR ((alpaka) AND (alpakacuda)))
   include(CheckLanguage)
   check_language(CUDA)
-  if (CMAKE_CUDA_COMPILER)
+  if(CMAKE_CUDA_COMPILER)
     enable_language(CUDA)
   else()
     message(FATAL_ERROR "CUDA library not found")
   endif()
 endif()
 
-if (cuda)
-  add_library(SYCLMath SHARED
-  src/MathUtil.cxx
-  )
+if((hip) OR ((alpaka) AND (alpakahip)))
+  include(CheckLanguage)
+  check_language(HIP)
+  if(CMAKE_HIP_COMPILER)
+    enable_language(HIP)
+  else()
+    message(FATAL_ERROR "HIP library not found")
+  endif()
+endif()
+
+if(cuda)
+  add_library(SYCLMath SHARED src/MathUtil.cxx)
   set_source_files_properties(src/MathUtil.cxx PROPERTIES LANGUAGE CUDA)
-  target_compile_options(SYCLMath PRIVATE -rdc=true -lineinfo --expt-relaxed-constexpr)
+  target_compile_options(SYCLMath PRIVATE -rdc=true -lineinfo
+                                          --expt-relaxed-constexpr)
   set_target_properties(SYCLMath PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
   target_compile_definitions(SYCLMath INTERFACE ROOT_MATH_CUDA)
   list(APPEND cuda_compile_list ROOT_MATH_CUDA)
-  if (timing)
+  if(timing)
     list(APPEND cuda_compile_list ROOT_MEAS_TIMING)
   endif()
+elseif(alpaka)
+  set(CMAKE_CXX_STANDARD 20)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
+  set(CMAKE_CXX_EXTENSIONS OFF)
+
+  find_package(Boost 1.74.0 REQUIRED)
+  find_package(alpaka 1.2.0 REQUIRED)
+
+  add_library(SYCLMath SHARED src/MathUtil.cxx)
+  target_include_directories(SYCLMath PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                              ${Boost_INCLUDE_DIR})
+  target_link_libraries(SYCLMath PUBLIC alpaka::alpaka)
+  if (alpakacuda)
+    set_source_files_properties(src/MathUtil.cxx PROPERTIES LANGUAGE CUDA)
+    target_compile_definitions(SYCLMath PRIVATE ALPAKA_ACC_GPU_CUDA_ENABLED)
+  elseif (alpakahip)
+    set_source_files_properties(src/MathUtil.cxx PROPERTIES LANGUAGE HIP)
+    target_compile_definitions(SYCLMath PRIVATE ALPAKA_ACC_GPU_CUDA_ENABLED)
+    else()
+    set_source_files_properties(src/MathUtil.cxx PROPERTIES LANGUAGE CXX)
+    target_compile_definitions(SYCLMath PRIVATE ALPAKA_HOST_ONLY
+                          ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+  endif()
+  list(APPEND alpaka_compile_list ROOT_MATH_ALPAKA)
+  if(timing)
+    list(APPEND alpaka_compile_list ROOT_MEAS_TIMING)
+  endif()
 else()
-  add_library(SYCLMath SHARED
-  src/MathUtil.cxx
-  )
+  add_library(SYCLMath SHARED src/MathUtil.cxx)
   set_target_properties(SYCLMath PROPERTIES LINKER_LANGUAGE CXX)
 endif()
 
-if (sycl)
-    #set_target_properties(GenVector PROPERTIES LINKER_LANGUAGE CXX)
-    target_compile_definitions(SYCLMath PUBLIC ROOT_MATH_SYCL)
-    list(APPEND sycl_compile_list ROOT_MATH_SYCL)
-    if (timing)
-      list(APPEND sycl_compile_list ROOT_MEAS_TIMING)
-    endif()
-    if (sycl_buffer)
-      list(APPEND sycl_compile_list SYCL_BUFFER)
-    endif()
-    message(DEBUG "sycl_buffer: ${sycl_buffer}")
-    message(DEBUG "sycl_compile_list: ${sycl_compile_list}")
-    add_sycl_to_root_target(TARGET SYCLMath SOURCES src/MathUtil.cxx 
-                            HEADERS inc/SYCLMath/GenVector/MathUtil.h 
-                            INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/inc/ 
-                            COMPILE_DEFINITIONS ${sycl_compile_list} )
+if(sycl)
+  # set_target_properties(GenVector PROPERTIES LINKER_LANGUAGE CXX)
+  target_compile_definitions(SYCLMath PUBLIC ROOT_MATH_SYCL)
+  list(APPEND sycl_compile_list ROOT_MATH_SYCL)
+  if(timing)
+    list(APPEND sycl_compile_list ROOT_MEAS_TIMING)
+  endif()
+  if(sycl_buffer)
+    list(APPEND sycl_compile_list SYCL_BUFFER)
+  endif()
+  message(DEBUG "sycl_buffer: ${sycl_buffer}")
+  message(DEBUG "sycl_compile_list: ${sycl_compile_list}")
+  add_sycl_to_root_target(
+    TARGET
+    SYCLMath
+    SOURCES
+    src/MathUtil.cxx
+    HEADERS
+    inc/SYCLMath/GenVector/MathUtil.h
+    INCLUDE_DIRECTORIES
+    ${CMAKE_SOURCE_DIR}/inc/
+    COMPILE_DEFINITIONS
+    ${sycl_compile_list})
 endif()
 
-if (timing)
+if(timing)
   list(APPEND compile_list ROOT_MEAS_TIMING)
 endif()
 
-add_library(GenVectorX SHARED
+add_library(
+  GenVectorX SHARED
   src/3DConversions.cxx
-  src/BitReproducible.cxx  
-  src/BoostZ.cxx           
-  src/Quaternion.cxx        
+  src/BitReproducible.cxx
+  src/BoostZ.cxx
+  src/Quaternion.cxx
   src/RotationZYX.cxx
-  src/3DDistances.cxx      
-  src/Boost.cxx            
-  src/EulerAngles.cxx      
-  src/QuaternionXaxial.cxx  
-  #src/VecOps.cxx
-  src/AxisAngle.cxx        
-  src/BoostX.cxx           
-  src/LorentzRotation.cxx  
-  src/Rotation3D.cxx        
+  src/3DDistances.cxx
+  src/Boost.cxx
+  src/EulerAngles.cxx
+  src/QuaternionXaxial.cxx
+  # src/VecOps.cxx
+  src/AxisAngle.cxx
+  src/BoostX.cxx
+  src/LorentzRotation.cxx
+  src/Rotation3D.cxx
   src/VectorUtil.cxx
-  src/AxisAngleXother.cxx  
-  src/BoostY.cxx           
-  src/MathUtil.cxx         
-  src/Rotation3DxAxial.cxx
-)
+  src/AxisAngleXother.cxx
+  src/BoostY.cxx
+  src/MathUtil.cxx
+  src/Rotation3DxAxial.cxx)
 
 target_include_directories(GenVectorX INTERFACE inc)
 set_target_properties(GenVectorX PROPERTIES LINKER_LANGUAGE CXX)
 target_link_libraries(GenVectorX PUBLIC SYCLMath)
 target_compile_definitions(GenVectorX PUBLIC ${compile_list})
 
-
-if ((cuda) OR (sycl))
-  add_library(VecOps SHARED
-   src/VecOps.cxx
-   )
+if((cuda)
+   OR (sycl)
+   OR (alpaka))
+  add_library(VecOps SHARED src/VecOps.cxx)
   target_link_libraries(VecOps PUBLIC GenVectorX SYCLMath)
 
-  if (cuda)
+  if(cuda)
     set_source_files_properties(src/VecOps.cxx PROPERTIES LANGUAGE CUDA)
-    target_compile_options(VecOps PRIVATE -rdc=true -lineinfo --expt-relaxed-constexpr)
+    target_compile_options(VecOps PRIVATE -rdc=true -lineinfo
+                                          --expt-relaxed-constexpr)
     set_target_properties(VecOps PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
     target_compile_definitions(VecOps PUBLIC ${cuda_compile_list})
   endif()
-  if (sycl)
-     set_target_properties(VecOps PROPERTIES LINKER_LANGUAGE CXX)
-
-     add_sycl_to_root_target(TARGET VecOps SOURCES src/VecOps.cxx HEADERS inc/SYCLMath/VecOps.h 
-                            INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/inc/ DEPENDENCIES GenVectorX SYCLMath 
-                            COMPILE_DEFINITIONS ${sycl_compile_list} )
 
-      set_target_properties(GenVectorX PROPERTIES LINKER_LANGUAGE CXX)
-
-      add_sycl_to_root_target(TARGET GenVectorX SOURCES 
+  if(alpaka)
+    target_include_directories(VecOps PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                              ${Boost_INCLUDE_DIR})
+    if(alpakacuda)
+      set_source_files_properties(src/VecOps.cxx PROPERTIES LANGUAGE CUDA)
+      set_target_properties(VecOps PROPERTIES LINKER_LANGUAGE CUDA)
+      target_compile_definitions(VecOps PUBLIC ${alpaka_compile_list}
+                                               ALPAKA_ACC_GPU_CUDA_ENABLED)
+    elseif(alpakahip)
+      set_source_files_properties(src/VecOps.cxx PROPERTIES LANGUAGE HIP)
+      set_target_properties(VecOps PROPERTIES LINKER_LANGUAGE HIP)
+      target_compile_definitions(VecOps PUBLIC ${alpaka_compile_list}
+                                               ALPAKA_ACC_GPU_HIP_ENABLED)
+    else()
+      set_source_files_properties(src/VecOps.cxx PROPERTIES LANGUAGE CXX)
+      target_compile_definitions(
+        VecOps PUBLIC ${alpaka_compile_list} ALPAKA_HOST_ONLY
+                      ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+    endif()
+  endif()
+  
+  if(sycl)
+    set_target_properties(VecOps PROPERTIES LINKER_LANGUAGE CXX)
+
+    add_sycl_to_root_target(
+      TARGET
+      VecOps
+      SOURCES
+      src/VecOps.cxx
+      HEADERS
+      inc/SYCLMath/VecOps.h
+      INCLUDE_DIRECTORIES
+      ${CMAKE_SOURCE_DIR}/inc/
+      DEPENDENCIES
+      GenVectorX
+      SYCLMath
+      COMPILE_DEFINITIONS
+      ${sycl_compile_list})
+
+    set_target_properties(GenVectorX PROPERTIES LINKER_LANGUAGE CXX)
+
+    add_sycl_to_root_target(
+      TARGET
+      GenVectorX
+      SOURCES
       src/3DConversions.cxx
-      src/BitReproducible.cxx  
-      src/BoostZ.cxx           
-      src/Quaternion.cxx        
+      src/BitReproducible.cxx
+      src/BoostZ.cxx
+      src/Quaternion.cxx
       src/RotationZYX.cxx
-      src/3DDistances.cxx      
-      src/Boost.cxx            
-      src/EulerAngles.cxx      
-      src/QuaternionXaxial.cxx  
-      #src/VecOps.cxx
-      src/AxisAngle.cxx        
-      src/BoostX.cxx           
-      src/LorentzRotation.cxx  
-      src/Rotation3D.cxx        
+      src/3DDistances.cxx
+      src/Boost.cxx
+      src/EulerAngles.cxx
+      src/QuaternionXaxial.cxx
+      # src/VecOps.cxx
+      src/AxisAngle.cxx
+      src/BoostX.cxx
+      src/LorentzRotation.cxx
+      src/Rotation3D.cxx
       src/VectorUtil.cxx
-      src/AxisAngleXother.cxx  
-      src/BoostY.cxx           
-      src/MathUtil.cxx         
+      src/AxisAngleXother.cxx
+      src/BoostY.cxx
+      src/MathUtil.cxx
       src/Rotation3DxAxial.cxx
-      INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/inc/ 
-      DEPENDENCIES SYCLMath 
-      COMPILE_DEFINITIONS ${sycl_compile_list} )
+      INCLUDE_DIRECTORIES
+      ${CMAKE_SOURCE_DIR}/inc/
+      DEPENDENCIES
+      SYCLMath
+      COMPILE_DEFINITIONS
+      ${sycl_compile_list})
 
   endif()
-      
 
-  install(TARGETS GenVectorX SYCLMath VecOps
-      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}   )
+  install(
+    TARGETS GenVectorX SYCLMath VecOps
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 else()
-  install(TARGETS GenVectorX SYCLMath 
-      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}   )
+  install(
+    TARGETS GenVectorX SYCLMath
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 endif()
 
-if (testing)
- add_subdirectory(testx)
-endif()
\ No newline at end of file
+if(testing)
+  add_subdirectory(testx)
+endif()
diff --git a/inc/SYCLMath/GenVector/MathUtil.h b/inc/SYCLMath/GenVector/MathUtil.h
index 06c03d2..b1fbf9b 100644
--- a/inc/SYCLMath/GenVector/MathUtil.h
+++ b/inc/SYCLMath/GenVector/MathUtil.h
@@ -48,6 +48,14 @@
 #define __roohost__ __host__
 #define __rooglobal__ __global__
 
+#elif defined(ROOT_MATH_ALPAKA)
+
+#include <alpaka/alpaka.hpp>
+
+#define __roodevice__ ALPAKA_FN_ACC
+#define __roohost__ ALPAKA_FN_HOST
+#define __rooglobal__
+
 #else
 
 #define __roodevice__ 
@@ -326,4 +334,4 @@ template <typename Scalar> inline Scalar Eta_FromTheta(Scalar theta, Scalar r) {
 
 } // end namespace ROOT
 
-#endif
\ No newline at end of file
+#endif
diff --git a/inc/SYCLMath/GenVector/VecOps.h b/inc/SYCLMath/GenVector/VecOps.h
index 12dad4c..a3ed5b9 100644
--- a/inc/SYCLMath/GenVector/VecOps.h
+++ b/inc/SYCLMath/GenVector/VecOps.h
@@ -21,6 +21,11 @@ inline static void __checkCudaErrors(cudaError_t code, const char *file, int lin
   }
 }
 
+#elif defined(ROOT_MATH_ALPAKA)
+
+#include "alpaka/alpakaVecOps.h"
+#include "alpaka/config.h"
+
 #endif
 
 namespace ROOT
diff --git a/inc/SYCLMath/GenVector/alpaka/alpakaVecOps.h b/inc/SYCLMath/GenVector/alpaka/alpakaVecOps.h
new file mode 100644
index 0000000..fbefaf6
--- /dev/null
+++ b/inc/SYCLMath/GenVector/alpaka/alpakaVecOps.h
@@ -0,0 +1,240 @@
+#include "SYCLMath/GenVector/MathUtil.h"
+#include <cstdio>
+#include <chrono>
+#include <iostream>
+#include <type_traits>
+#include <alpaka/alpaka.hpp>
+#include "config.h"
+
+template <typename TAcc,
+          typename TDim,
+          typename TIdx,
+          typename = std::enable_if_t<alpaka::isAccelerator<TAcc>>>
+ALPAKA_FN_HOST auto getWorkDiv(TIdx gridSize, TIdx elementsOrThreads) {
+  using WorkDiv = alpaka::WorkDivMembers<TDim, TIdx>;
+  if constexpr (std::is_same_v<TAcc, alpaka::AccGpuCudaRt<TDim, TIdx>> ||
+                std::is_same_v<TAcc, alpaka::AccGpuHipRt<TDim, TIdx>>) {
+    const TIdx elementsPerThread = 1;
+    return WorkDiv{gridSize, elementsOrThreads, elementsPerThread};
+  } else {
+    const TIdx threadsPerBlock = 1;
+    return WorkDiv{gridSize, threadsPerBlock, elementsOrThreads};
+  }
+}
+
+namespace ROOT {
+
+  namespace Experimental {
+
+    template <typename TVector, typename TBoost>
+    struct ApplyBoostKernel {
+      template <typename TAcc>
+      ALPAKA_FN_ACC void operator()(const TAcc& acc,
+                                    const TVector* lv,
+                                    TVector* lvb,
+                                    const TBoost* bst,
+                                    size_t N) const {
+        for (auto i : alpaka::uniformElements(acc, N)) {
+          TBoost bst_loc = bst[0];
+          lvb[i] = bst_loc(lv[i]);
+        }
+      }
+    };
+
+    template <typename TAcc,
+              typename TVector,
+              typename TBoost,
+              typename TQueue,
+              typename = std::enable_if_t<alpaka::isAccelerator<TAcc>>,
+              typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
+    ALPAKA_FN_HOST TVector* ApplyBoost(
+        TVector* lv, const TBoost& bst, TQueue& queue, size_t N, size_t blocksize) {
+      using Dim = alpaka::DimInt<1u>;
+      using Idx = uint32_t;
+      using Vec = alpaka::Vec<Dim, Idx>;
+      using WorkDiv = alpaka::WorkDivMembers<Dim, Idx>;
+      const auto devHost = alpaka::getDevByIdx(alpaka::PlatformCpu{}, 0);
+
+      TVector* lvb = new TVector[N];
+
+#ifdef ROOT_MEAS_TIMING
+      auto start = std::chrono::system_clock::now();
+#endif
+
+      // allocate device buffers
+      auto d_lv = alpaka::allocAsyncBuf<TVector, Idx>(queue, static_cast<Idx>(N));
+      auto d_lvb = alpaka::allocAsyncBuf<TVector, Idx>(queue, static_cast<Idx>(N));
+      auto d_bst = alpaka::allocAsyncBuf<TBoost, Idx>(queue, 1u);
+
+      // memcpy
+      alpaka::memcpy(queue, d_lv, alpaka::createView(devHost, lv, Vec{N}));
+      alpaka::memcpy(queue, d_bst, alpaka::createView(devHost, &bst, Vec{1}));
+
+      const Idx gridsize = (N + blocksize - 1) / blocksize;
+      const auto workdiv = getWorkDiv<TAcc, Dim>(gridsize, static_cast<Idx>(blocksize));
+
+      // launch kernel
+      alpaka::exec<TAcc>(queue,
+                         workdiv,
+                         ApplyBoostKernel<TVector, TBoost>{},
+                         d_lv.data(),
+                         d_lvb.data(),
+                         d_bst.data(),
+                         static_cast<Idx>(N));
+
+      // memcpy
+      alpaka::memcpy(queue, alpaka::createView(devHost, lvb, Vec{N}), d_lvb);
+
+#ifdef ROOT_MEAS_TIMING
+      auto end = std::chrono::system_clock::now();
+      auto duration =
+          std::chrono::duration_cast<std::chrono::microseconds>(end - start)
+              .count() *
+          1e-6;
+      std::cout << "alpaka time " << duration << " (s)" << std::endl;
+#endif
+
+      return lvb;
+    }
+
+    template <typename TVector, typename TScalar>
+    struct InvariantMassKernel {
+      template <typename TAcc>
+      ALPAKA_FN_ACC void operator()(const TAcc& acc,
+                                    const TVector* v1,
+                                    TScalar* m,
+                                    size_t N) const {
+        for (auto i : alpaka::uniformElements(acc, N)) {
+          m[i] = v1[i].mass();
+        }
+      }
+    };
+
+    template <typename TVector, typename TScalar>
+    struct InvariantMassesKernel {
+      template <typename TAcc>
+      ALPAKA_FN_ACC void operator()(const TAcc& acc,
+                                    const TVector* v1,
+                                    const TVector* v2,
+                                    TScalar* m,
+                                    size_t N) const {
+        for (auto i : alpaka::uniformElements(acc, N)) {
+          const auto w = v1[i] + v2[i];
+          m[i] = w.mass();
+        }
+      }
+    };
+
+    template <typename TAcc,
+              typename TScalar,
+              typename TVector,
+              typename TQueue,
+              typename = std::enable_if_t<alpaka::isAccelerator<TAcc>>,
+              typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
+    ALPAKA_FN_HOST TScalar* InvariantMass(const TVector* v1,
+                                          size_t N,
+                                          TQueue& queue,
+                                          size_t blocksize) {
+      using Dim = alpaka::DimInt<1>;
+      using Idx = uint32_t;
+      using Vec = alpaka::Vec<Dim, Idx>;
+      using WorkDiv = alpaka::WorkDivMembers<Dim, Idx>;
+      auto const devHost = alpaka::getDevByIdx(alpaka::PlatformCpu{}, 0);
+
+      TScalar* invMasses = new TScalar[N];
+
+#ifdef ROOT_MEAS_TIMING
+      auto start = std::chrono::system_clock::now();
+#endif
+
+      // allocate device buffers
+      auto d_lv = alpaka::allocAsyncBuf<TVector, Idx>(queue, static_cast<Idx>(N));
+      auto d_m = alpaka::allocAsyncBuf<TScalar, Idx>(queue, static_cast<Idx>(N));
+
+      // memcpy
+      alpaka::memcpy(queue, d_lv, alpaka::createView(devHost, v1, Vec{N}));
+
+      const Idx gridsize = (N + blocksize - 1) / blocksize;
+      const auto workdiv = getWorkDiv<TAcc, Dim>(gridsize, static_cast<Idx>(blocksize));
+
+      // launch kernel
+      alpaka::exec<TAcc>(queue,
+                         workdiv,
+                         InvariantMassKernel<TVector, TScalar>{},
+                         d_lv.data(),
+                         d_m.data(),
+                         static_cast<Idx>(N));
+
+      // memcpy
+      alpaka::memcpy(queue, alpaka::createView(devHost, invMasses, Vec{N}), d_m);
+
+#ifdef ROOT_MEAS_TIMING
+      auto end = std::chrono::system_clock::now();
+      auto duration =
+          std::chrono::duration_cast<std::chrono::microseconds>(end - start)
+              .count() *
+          1e-6;
+      std::cout << "alpaka time " << duration << " (s)" << std::endl;
+#endif
+
+      return invMasses;
+    }
+
+    template <typename TAcc,
+              typename TScalar,
+              typename TVector,
+              typename TQueue,
+              typename = std::enable_if_t<alpaka::isAccelerator<TAcc>>,
+              typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
+    ALPAKA_FN_HOST TScalar* InvariantMasses(
+        const TVector* v1, TVector* v2, size_t N, TQueue& queue, size_t blocksize) {
+      using Dim = alpaka::DimInt<1>;
+      using Idx = uint32_t;
+      using Vec = alpaka::Vec<Dim, Idx>;
+      using WorkDiv = alpaka::WorkDivMembers<Dim, Idx>;
+      auto const devHost = alpaka::getDevByIdx(alpaka::PlatformCpu{}, 0);
+
+      TScalar* invMasses = new TScalar[N];
+
+#ifdef ROOT_MEAS_TIMING
+      auto start = std::chrono::system_clock::now();
+#endif
+
+      // allocate device buffers
+      auto d_v1 = alpaka::allocAsyncBuf<TVector, Idx>(queue, static_cast<Idx>(N));
+      auto d_v2 = alpaka::allocAsyncBuf<TVector, Idx>(queue, static_cast<Idx>(N));
+      auto d_m = alpaka::allocAsyncBuf<TScalar, Idx>(queue, static_cast<Idx>(N));
+
+      // memcpy
+      alpaka::memcpy(queue, d_v1, alpaka::createView(devHost, v1, Vec{N}));
+      alpaka::memcpy(queue, d_v2, alpaka::createView(devHost, v2, Vec{N}));
+
+      const Idx gridsize = (N + blocksize - 1) / blocksize;
+      const auto workdiv = getWorkDiv<TAcc, Dim>(gridsize, static_cast<Idx>(blocksize));
+
+      // launch kernel
+      alpaka::exec<TAcc>(queue,
+                         workdiv,
+                         InvariantMassesKernel<TVector, TScalar>{},
+                         d_v1.data(),
+                         d_v2.data(),
+                         d_m.data(),
+                         static_cast<Idx>(N));
+
+      // memcpy
+      alpaka::memcpy(queue, alpaka::createView(devHost, invMasses, Vec{N}), d_m);
+
+#ifdef ROOT_MEAS_TIMING
+      auto end = std::chrono::system_clock::now();
+      auto duration =
+          std::chrono::duration_cast<std::chrono::microseconds>(end - start)
+              .count() *
+          1e-6;
+      std::cout << "alpaka time " << duration << " (s)" << std::endl;
+#endif
+
+      return invMasses;
+    }
+
+  }  // namespace Experimental
+}  // namespace ROOT
diff --git a/inc/SYCLMath/GenVector/alpaka/config.h b/inc/SYCLMath/GenVector/alpaka/config.h
new file mode 100644
index 0000000..3bdddf8
--- /dev/null
+++ b/inc/SYCLMath/GenVector/alpaka/config.h
@@ -0,0 +1,177 @@
+
+#pragma once
+
+#include <alpaka/alpaka.hpp>
+
+namespace alpaka {
+
+  // miscellanea
+  template <std::size_t N>
+  using DimInt = std::integral_constant<std::size_t, N>;
+
+  template <typename TDim, typename TVal>
+  class Vec;
+
+  template <typename TDim, typename TIdx>
+  class WorkDivMembers;
+
+  // API
+  struct ApiCudaRt;
+  struct ApiHipRt;
+
+  // Platforms
+  class PltfCpu;
+  template <typename TApi>
+  class PltfUniformCudaHipRt;
+  using PltfCudaRt = PltfUniformCudaHipRt<ApiCudaRt>;
+  using PltfHipRt = PltfUniformCudaHipRt<ApiHipRt>;
+
+  // Devices
+  class DevCpu;
+  template <typename TApi>
+  class DevUniformCudaHipRt;
+  using DevCudaRt = DevUniformCudaHipRt<ApiCudaRt>;
+  using DevHipRt = DevUniformCudaHipRt<ApiHipRt>;
+
+  // Queues
+  template <typename TDev>
+  class QueueGenericThreadsBlocking;
+  using QueueCpuBlocking = QueueGenericThreadsBlocking<DevCpu>;
+
+  template <typename TDev>
+  class QueueGenericThreadsNonBlocking;
+  using QueueCpuNonBlocking = QueueGenericThreadsNonBlocking<DevCpu>;
+
+  namespace uniform_cuda_hip::detail {
+    template <typename TApi, bool TBlocking>
+    class QueueUniformCudaHipRt;
+  }
+  using QueueCudaRtBlocking =
+      uniform_cuda_hip::detail::QueueUniformCudaHipRt<ApiCudaRt, true>;
+  using QueueCudaRtNonBlocking =
+      uniform_cuda_hip::detail::QueueUniformCudaHipRt<ApiCudaRt, false>;
+  using QueueHipRtBlocking =
+      uniform_cuda_hip::detail::QueueUniformCudaHipRt<ApiHipRt, true>;
+  using QueueHipRtNonBlocking =
+      uniform_cuda_hip::detail::QueueUniformCudaHipRt<ApiHipRt, false>;
+
+  // Events
+  template <typename TDev>
+  class EventGenericThreads;
+  using EventCpu = EventGenericThreads<DevCpu>;
+
+  template <typename TApi>
+  class EventUniformCudaHipRt;
+  using EventCudaRt = EventUniformCudaHipRt<ApiCudaRt>;
+  using EventHipRt = EventUniformCudaHipRt<ApiHipRt>;
+
+  // Accelerators
+  template <typename TApi, typename TDim, typename TIdx>
+  class AccGpuUniformCudaHipRt;
+
+  template <typename TDim, typename TIdx>
+  using AccGpuCudaRt = AccGpuUniformCudaHipRt<ApiCudaRt, TDim, TIdx>;
+
+  template <typename TDim, typename TIdx>
+  using AccGpuHipRt = AccGpuUniformCudaHipRt<ApiHipRt, TDim, TIdx>;
+
+  template <typename TDim, typename TIdx>
+  class AccCpuSerial;
+
+  template <typename TDim, typename TIdx>
+  class AccCpuTbbBlocks;
+
+  template <typename TDim, typename TIdx>
+  class AccCpuOmp2Blocks;
+
+}  // namespace alpaka
+
+namespace alpaka_common {
+
+  // common types and dimensions
+  using Idx = uint32_t;
+  using Extent = uint32_t;
+  using Offsets = Extent;
+
+  using Dim0D = alpaka::DimInt<0u>;
+  using Dim1D = alpaka::DimInt<1u>;
+  using Dim2D = alpaka::DimInt<2u>;
+  using Dim3D = alpaka::DimInt<3u>;
+
+  template <typename TDim>
+  using Vec = alpaka::Vec<TDim, Idx>;
+  using Vec1D = Vec<Dim1D>;
+  using Vec2D = Vec<Dim2D>;
+  using Vec3D = Vec<Dim3D>;
+
+  template <typename TDim>
+  using WorkDiv = alpaka::WorkDivMembers<TDim, Idx>;
+  using WorkDiv1D = WorkDiv<Dim1D>;
+  using WorkDiv2D = WorkDiv<Dim2D>;
+  using WorkDiv3D = WorkDiv<Dim3D>;
+
+  // host types
+  using DevHost = alpaka::DevCpu;
+  using PlatformHost = alpaka::PlatformCpu;
+
+}  // namespace alpaka_common
+
+#ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
+namespace alpaka_cuda_async {
+  using namespace alpaka_common;
+
+  using Platform = alpaka::PlatformCudaRt;
+  using Device = alpaka::DevCudaRt;
+  using Queue = alpaka::QueueCudaRtNonBlocking;
+  using Event = alpaka::EventCudaRt;
+
+  template <typename TDim>
+  using Acc = alpaka::AccGpuCudaRt<TDim, Idx>;
+  using Acc1D = Acc<Dim1D>;
+  using Acc2D = Acc<Dim2D>;
+  using Acc3D = Acc<Dim3D>;
+
+#define ALPAKA_ACCELERATOR_NAMESPACE alpaka_cuda_async
+}  // namespace alpaka_cuda_async
+
+#endif  // ALPAKA_ACC_GPU_CUDA_ASYNC_BACKEND
+
+#ifdef ALPAKA_ACC_GPU_HIP_ENABLED
+namespace alpaka_rocm_async {
+  using namespace alpaka_common;
+
+  using Platform = alpaka::PlatformHipRt;
+  using Device = alpaka::DevHipRt;
+  using Queue = alpaka::QueueHipRtNonBlocking;
+  using Event = alpaka::EventHipRt;
+
+  template <typename TDim>
+  using Acc = alpaka::AccGpuHipRt<TDim, Idx>;
+  using Acc1D = Acc<Dim1D>;
+  using Acc2D = Acc<Dim2D>;
+  using Acc3D = Acc<Dim3D>;
+
+#define ALPAKA_ACCELERATOR_NAMESPACE alpaka_rocm_async
+}  // namespace alpaka_rocm_async
+#endif
+
+#ifdef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED
+namespace alpaka_serial_sync {
+  using namespace alpaka_common;
+
+  using Platform = alpaka::PlatformCpu;
+  using Device = alpaka::DevCpu;
+  using Queue = alpaka::QueueCpuBlocking;
+  using Event = alpaka::EventCpu;
+
+  template <typename TDim>
+  using Acc = alpaka::AccCpuSerial<TDim, Idx>;
+  using Acc1D = Acc<Dim1D>;
+  using Acc2D = Acc<Dim2D>;
+  using Acc3D = Acc<Dim3D>;
+
+#define ALPAKA_ACCELERATOR_NAMESPACE alpaka_serial_sync
+}  // namespace alpaka_serial_sync
+
+#endif  // ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED
+
diff --git a/testx/BoostAlpaka.cxx b/testx/BoostAlpaka.cxx
new file mode 100644
index 0000000..6dda724
--- /dev/null
+++ b/testx/BoostAlpaka.cxx
@@ -0,0 +1,70 @@
+#include "SYCLMath/Boost.h"
+#include "SYCLMath/Vector4D.h"
+#include "SYCLMath/VecOps.h"
+#include <chrono>
+
+#include <alpaka/alpaka.hpp>
+#include "SYCLMath/GenVector/alpaka/config.h"
+
+#ifdef SINGLE_PRECISION
+using Scalar = float;
+#else
+using Scalar = double;
+#endif
+
+using LVector =
+    ROOT::Experimental::LorentzVector<ROOT::Experimental::PtEtaPhiM4D<Scalar>>;
+using Boost = ROOT::Experimental::Boost;
+
+LVector* GenVectors(int n) {
+  LVector* vectors = new LVector[n];
+
+  // generate n -4 momentum quantities
+  for (int i = 0; i < n; ++i) {
+    // fill vectors
+    vectors[i] = {1., 1., 1., 1.};
+  }
+
+  return vectors;
+}
+
+bool print_if_false(const bool assertion, size_t i) {
+  if (!assertion) {
+    std::cout << "Assertion failed at index " << i << std::endl;
+  }
+  return assertion;
+}
+
+int main(int argc, char** argv) {
+  using namespace ALPAKA_ACCELERATOR_NAMESPACE;
+
+  std::string arg1 = argv[1];
+  std::size_t pos;
+  std::size_t N = std::stoi(arg1, &pos);
+  std::string arg2 = argv[2];
+  std::size_t nruns = std::stoi(arg2, &pos);
+
+  // setup alpaka
+  const auto device = alpaka::getDevByIdx(alpaka::Platform<Acc1D>{}, 0u);
+  Queue queue(device);
+
+  LVector* lv = GenVectors(N);
+  LVector* lvb = new LVector[N];
+
+  Boost bst(0.3, 0.4, 0.5);
+
+  const size_t blocksize = 256;
+  for (size_t i = 0; i < nruns; i++)
+    lvb = ROOT::Experimental::ApplyBoost<Acc1D>(lv, bst, queue, N, blocksize);
+
+  for (size_t i = 0; i < N; i++) {
+    assert(print_if_false((std::abs(lvb[i].Pt() - 1.7225) <= 1e-5), i));
+    assert(print_if_false((std::abs(lvb[i].Eta() - 1.96333) <= 1e-5), i));
+    assert(print_if_false((std::abs(lvb[i].Phi() - 2.20416) <= 1e-5), i));
+    assert(print_if_false((std::abs(lvb[i].M() - 3.11127) <= 1e-5), i));
+  }
+
+  delete[] lv;
+  delete[] lvb;
+  return 0;
+}
diff --git a/testx/CMakeLists.txt b/testx/CMakeLists.txt
index 74b1ceb..8519ee4 100644
--- a/testx/CMakeLists.txt
+++ b/testx/CMakeLists.txt
@@ -1,12 +1,146 @@
 set(sycl_compile_list_single "${sycl_compile_list}")
 list(APPEND sycl_compile_list_single SINGLE_PRECISION)
 
+set(alpaka_compile_list_single "${alpaka_compile_list}")
+list(APPEND alpaka_compile_list_single SINGLE_PRECISION)
+
 set(cuda_compile_list_single "${cuda_compile_list}")
 list(APPEND cuda_compile_list_single SINGLE_PRECISION)
 
 set(compile_list_single "${compile_list}")
 list(APPEND compile_list_single SINGLE_PRECISION)
 
+if(alpaka)
+
+  if(alpakacpu)
+    add_executable(BoostAlpakaCpu BoostAlpaka.cxx)
+    target_link_libraries(BoostAlpakaCpu PUBLIC alpaka::alpaka)
+    target_compile_options(
+      BoostAlpakaCpu PRIVATE -DALPAKA_HOST_ONLY
+                             -DALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+    target_include_directories(
+      BoostAlpakaCpu PRIVATE ${Alpaka_SOURCE_DIR}/include ${Boost_INCLUDE_DIR})
+    target_compile_definitions(
+      BoostAlpakaCpu PRIVATE ${alpaka_compile_list} ALPAKA_HOST_ONLY
+                             ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+
+    add_executable(InvariantMassesAlpakaCpu InvariantMassesAlpaka.cxx)
+    target_link_libraries(InvariantMassesAlpakaCpu PUBLIC alpaka::alpaka)
+    target_include_directories(
+      InvariantMassesAlpakaCpu PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                       ${Boost_INCLUDE_DIR})
+    target_compile_definitions(
+      InvariantMassesAlpakaCpu PRIVATE ${alpaka_compile_list} ALPAKA_HOST_ONLY
+                                       ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+    if(single_precision)
+      add_executable(SBoostAlpakaCpu BoostAlpaka.cxx)
+      target_link_libraries(SBoostAlpakaCpu PUBLIC alpaka::alpaka)
+      target_compile_options(
+        SBoostAlpakaCpu PRIVATE -DALPAKA_HOST_ONLY
+                              -DALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+      target_include_directories(
+        SBoostAlpakaCpu PRIVATE ${Alpaka_SOURCE_DIR}/include ${Boost_INCLUDE_DIR})
+      target_compile_definitions(
+        SBoostAlpakaCpu PRIVATE ${alpaka_compile_list_single} ALPAKA_HOST_ONLY
+                              ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+
+      add_executable(SInvariantMassesAlpakaCpu InvariantMassesAlpaka.cxx)
+      target_link_libraries(SInvariantMassesAlpakaCpu PUBLIC alpaka::alpaka)
+      target_include_directories(
+        SInvariantMassesAlpakaCpu PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                        ${Boost_INCLUDE_DIR})
+      target_compile_definitions(
+        SInvariantMassesAlpakaCpu PRIVATE ${alpaka_compile_list_single} ALPAKA_HOST_ONLY
+                                        ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED)
+    endif()
+  endif()
+
+  if(alpakacuda)
+	  set_source_files_properties(BoostAlpaka.cxx PROPERTIES LANGUAGE CUDA)
+    add_executable(BoostAlpakaCuda BoostAlpaka.cxx)
+    target_link_libraries(BoostAlpakaCuda PUBLIC alpaka::alpaka)
+    target_compile_options(BoostAlpakaCuda
+                           PRIVATE -DALPAKA_ACC_GPU_CUDA_ENABLED)
+    target_include_directories(
+      BoostAlpakaCuda PRIVATE ${Alpaka_SOURCE_DIR}/include ${Boost_INCLUDE_DIR})
+    target_compile_definitions(
+      BoostAlpakaCuda PRIVATE ${alpaka_compile_list}
+                              ALPAKA_ACC_GPU_CUDA_ENABLED)
+
+	  set_source_files_properties(InvariantMassesAlpaka.cxx PROPERTIES LANGUAGE CUDA)
+    add_executable(InvariantMassesAlpakaCuda InvariantMassesAlpaka.cxx)
+    target_link_libraries(InvariantMassesAlpakaCuda PUBLIC alpaka::alpaka)
+    target_include_directories(
+      InvariantMassesAlpakaCuda PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                        ${Boost_INCLUDE_DIR})
+    target_compile_definitions(
+      InvariantMassesAlpakaCuda PRIVATE ${alpaka_compile_list}
+                                        ALPAKA_ACC_GPU_CUDA_ENABLED)
+    if(single_precision)
+      set_source_files_properties(SBoostAlpaka.cxx PROPERTIES LANGUAGE CUDA)
+      add_executable(SBoostAlpakaCuda BoostAlpaka.cxx)
+      target_link_libraries(SBoostAlpakaCuda PUBLIC alpaka::alpaka)
+      target_compile_options(SBoostAlpakaCuda
+                            PRIVATE -DALPAKA_ACC_GPU_CUDA_ENABLED)
+      target_include_directories(
+        SBoostAlpakaCuda PRIVATE ${Alpaka_SOURCE_DIR}/include ${Boost_INCLUDE_DIR})
+      target_compile_definitions(
+        SBoostAlpakaCuda PRIVATE ${alpaka_compile_list_single}
+                                ALPAKA_ACC_GPU_CUDA_ENABLED)
+
+      set_source_files_properties(SInvariantMassesAlpaka.cxx PROPERTIES LANGUAGE CUDA)
+      add_executable(SInvariantMassesAlpakaCuda InvariantMassesAlpaka.cxx)
+      target_link_libraries(SInvariantMassesAlpakaCuda PUBLIC alpaka::alpaka)
+      target_include_directories(
+        SInvariantMassesAlpakaCuda PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                          ${Boost_INCLUDE_DIR})
+      target_compile_definitions(
+        SInvariantMassesAlpakaCuda PRIVATE ${alpaka_compile_list_single}
+                                          ALPAKA_ACC_GPU_CUDA_ENABLED)
+    endif()
+  endif()
+
+  if(alpakahip)
+	  set_source_files_properties(BoostAlpaka.cxx PROPERTIES LANGUAGE HIP)
+    add_executable(BoostAlpakaHip BoostAlpaka.cxx)
+    target_link_libraries(BoostAlpakaHip PUBLIC alpaka::alpaka)
+    target_include_directories(
+      BoostAlpakaHip PRIVATE ${Alpaka_SOURCE_DIR}/include ${Boost_INCLUDE_DIR})
+    target_compile_definitions(
+      BoostAlpakaHip PRIVATE ${alpaka_compile_list} ALPAKA_ACC_GPU_HIP_ENABLED)
+
+	  set_source_files_properties(InvariantMassesAlpaka.cxx PROPERTIES LANGUAGE HIP)
+    add_executable(InvariantMassesAlpakaHip InvariantMassesAlpaka.cxx)
+    target_link_libraries(InvariantMassesAlpakaHip PUBLIC alpaka::alpaka)
+    target_include_directories(
+      InvariantMassesAlpakaHip PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                       ${Boost_INCLUDE_DIR})
+    target_compile_definitions(
+      InvariantMassesAlpakaHip PRIVATE ${alpaka_compile_list}
+                                       ALPAKA_ACC_GPU_HIP_ENABLED)
+    if(single_precision)
+      set_source_files_properties(SBoostAlpaka.cxx PROPERTIES LANGUAGE HIP)
+      add_executable(SBoostAlpakaHip BoostAlpaka.cxx)
+      target_link_libraries(SBoostAlpakaHip PUBLIC alpaka::alpaka)
+      target_include_directories(
+        SBoostAlpakaHip PRIVATE ${Alpaka_SOURCE_DIR}/include ${Boost_INCLUDE_DIR})
+      target_compile_definitions(
+        SBoostAlpakaHip PRIVATE ${alpaka_compile_list_single} ALPAKA_ACC_GPU_HIP_ENABLED)
+
+      set_source_files_properties(SInvariantMassesAlpaka.cxx PROPERTIES LANGUAGE HIP)
+      add_executable(SInvariantMassesAlpakaHip InvariantMassesAlpaka.cxx)
+      target_link_libraries(SInvariantMassesAlpakaHip PUBLIC alpaka::alpaka)
+      target_include_directories(
+        SInvariantMassesAlpakaHip PRIVATE ${Alpaka_SOURCE_DIR}/include
+                                        ${Boost_INCLUDE_DIR})
+      target_compile_definitions(
+        SInvariantMassesAlpakaHip PRIVATE ${alpaka_compile_list_single}
+                                        ALPAKA_ACC_GPU_HIP_ENABLED)
+    endif()
+  endif()
+
+endif()
+
 if(oneapi)
   add_executable(InvariantMassesSYCL InvariantMassesSYCL.cxx)
   target_link_options(InvariantMassesSYCL PUBLIC -E)
@@ -72,6 +206,7 @@ if(oneapi)
       ${CMAKE_SOURCE_DIR}/inc
       COMPILE_DEFINITIONS
       ${sycl_compile_list_single})
+
   endif()
 
 endif()
@@ -137,6 +272,7 @@ if(adaptivecpp)
       ${CMAKE_SOURCE_DIR}/inc
       COMPILE_DEFINITIONS
       ${sycl_compile_list_single})
+
   endif()
 
 endif()
diff --git a/testx/InvariantMassesAlpaka.cxx b/testx/InvariantMassesAlpaka.cxx
new file mode 100644
index 0000000..2436fb0
--- /dev/null
+++ b/testx/InvariantMassesAlpaka.cxx
@@ -0,0 +1,63 @@
+#include "SYCLMath/PtEtaPhiM4D.h"
+#include "SYCLMath/Vector4D.h"
+#include "SYCLMath/VecOps.h"
+#include <assert.h>
+#include <chrono>
+#include <vector>
+
+#include <alpaka/alpaka.hpp>
+#include "SYCLMath/GenVector/alpaka/config.h"
+
+#ifdef SINGLE_PRECISION
+using Scalar = float;
+#else
+using Scalar = double;
+#endif
+
+using LVector =
+    ROOT::Experimental::LorentzVector<ROOT::Experimental::PtEtaPhiM4D<Scalar>>;
+
+
+LVector* GenVectors(int n)
+{
+  LVector  *vectors = new LVector[n];
+
+  // generate n -4 momentum quantities
+  for (int i = 0; i < n; ++i)
+  {
+    // fill vectors
+    vectors[i] = {1., 1., 1., 1.};
+  }
+
+  return vectors;
+}
+
+int main(int argc, char **argv)
+{
+  using namespace ALPAKA_ACCELERATOR_NAMESPACE;
+
+  std::string arg1 = argv[1];
+  std::size_t pos;
+  std::size_t N = std::stoi(arg1, &pos);
+  std::string arg2 = argv[2];
+  std::size_t nruns = std::stoi(arg2, &pos);
+  size_t local_size = 128;
+
+  // setup alpaka
+  const auto device = alpaka::getDevByIdx(alpaka::Platform<Acc1D>{}, 0u);
+  Queue queue(device);
+
+  auto u_vectors = GenVectors(N);
+  auto v_vectors = GenVectors(N);
+
+  Scalar *masses = new Scalar(N);
+
+  const size_t blocksize = 256;
+  for (size_t i = 0; i < nruns; i++)
+  {
+    masses = ROOT::Experimental::InvariantMasses<Acc1D, Scalar>(u_vectors, v_vectors, N, queue, blocksize);
+  }
+  assert((std::abs(masses[0] - 2.) <= 1e-5));
+
+  return 0;
+}


Reviews:
user: login: mdessole
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T15:28:07Z
user: login: sbaldu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T15:29:14Z

Review comments:
diff_hunk: @@ -222,152 +249,226 @@ endif()
 
 if(NOT ACPP_DEBUG_LEVEL)
   if(CMAKE_BUILD_TYPE MATCHES "Debug")
-    set(ACPP_DEBUG_LEVEL 3 CACHE STRING
-      "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
-FORCE)
+    set(ACPP_DEBUG_LEVEL
+        3
+        CACHE
+          STRING
+          "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
+          FORCE)
   else()
-    set(ACPP_DEBUG_LEVEL 2 CACHE STRING
-      "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
-FORCE)
+    set(ACPP_DEBUG_LEVEL
+        2
+        CACHE
+          STRING
+          "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
+          FORCE)
   endif()
 endif()
 
-if (cuda)
+if((cuda) OR ((alpaka) AND (alpakacuda)))
   include(CheckLanguage)
   check_language(CUDA)
-  if (CMAKE_CUDA_COMPILER)
+  if(CMAKE_CUDA_COMPILER)
     enable_language(CUDA)
   else()
     message(FATAL_ERROR "CUDA library not found")
   endif()
 endif()
 
-if (cuda)
-  add_library(SYCLMath SHARED
-  src/MathUtil.cxx
-  )
+if((hip) OR ((alpaka) AND (alpakahip)))
+  include(CheckLanguage)
+  check_language(HIP)
+  if(CMAKE_HIP_COMPILER)
+	enable_language(HIP)
+  else()
+	message(FATAL_ERROR "HIP library not found")
+  endif()
+endif()
+
+if(cuda)
+  add_library(SYCLMath SHARED src/MathUtil.cxx)
   set_source_files_properties(src/MathUtil.cxx PROPERTIES LANGUAGE CUDA)
-  target_compile_options(SYCLMath PRIVATE -rdc=true -lineinfo --expt-relaxed-constexpr)
+  target_compile_options(SYCLMath PRIVATE -rdc=true -lineinfo
+                                          --expt-relaxed-constexpr)
   set_target_properties(SYCLMath PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
   target_compile_definitions(SYCLMath INTERFACE ROOT_MATH_CUDA)
   list(APPEND cuda_compile_list ROOT_MATH_CUDA)
-  if (timing)
+  if(timing)
     list(APPEND cuda_compile_list ROOT_MEAS_TIMING)
   endif()
+elseif(alpaka)
+  set(CMAKE_CXX_STANDARD 20)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
+  set(CMAKE_CXX_EXTENSIONS OFF)
+
+  find_package(Boost 1.74.0 REQUIRED)
+  find_package(alpaka 2.0.0 REQUIRED)
path: CMakeLists.txt
user: login: mdessole
body: isn't the latest stable version 1.2.0?
created_at: 2025-03-07T15:26:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -222,152 +249,226 @@ endif()
 
 if(NOT ACPP_DEBUG_LEVEL)
   if(CMAKE_BUILD_TYPE MATCHES "Debug")
-    set(ACPP_DEBUG_LEVEL 3 CACHE STRING
-      "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
-FORCE)
+    set(ACPP_DEBUG_LEVEL
+        3
+        CACHE
+          STRING
+          "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
+          FORCE)
   else()
-    set(ACPP_DEBUG_LEVEL 2 CACHE STRING
-      "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
-FORCE)
+    set(ACPP_DEBUG_LEVEL
+        2
+        CACHE
+          STRING
+          "Choose the debug level, options are: 0 (no debug), 1 (print errors), 2 (also print warnings), 3 (also print general information)"
+          FORCE)
   endif()
 endif()
 
-if (cuda)
+if((cuda) OR ((alpaka) AND (alpakacuda)))
   include(CheckLanguage)
   check_language(CUDA)
-  if (CMAKE_CUDA_COMPILER)
+  if(CMAKE_CUDA_COMPILER)
     enable_language(CUDA)
   else()
     message(FATAL_ERROR "CUDA library not found")
   endif()
 endif()
 
-if (cuda)
-  add_library(SYCLMath SHARED
-  src/MathUtil.cxx
-  )
+if((hip) OR ((alpaka) AND (alpakahip)))
+  include(CheckLanguage)
+  check_language(HIP)
+  if(CMAKE_HIP_COMPILER)
+	enable_language(HIP)
+  else()
+	message(FATAL_ERROR "HIP library not found")
+  endif()
+endif()
+
+if(cuda)
+  add_library(SYCLMath SHARED src/MathUtil.cxx)
   set_source_files_properties(src/MathUtil.cxx PROPERTIES LANGUAGE CUDA)
-  target_compile_options(SYCLMath PRIVATE -rdc=true -lineinfo --expt-relaxed-constexpr)
+  target_compile_options(SYCLMath PRIVATE -rdc=true -lineinfo
+                                          --expt-relaxed-constexpr)
   set_target_properties(SYCLMath PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
   target_compile_definitions(SYCLMath INTERFACE ROOT_MATH_CUDA)
   list(APPEND cuda_compile_list ROOT_MATH_CUDA)
-  if (timing)
+  if(timing)
     list(APPEND cuda_compile_list ROOT_MEAS_TIMING)
   endif()
+elseif(alpaka)
+  set(CMAKE_CXX_STANDARD 20)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
+  set(CMAKE_CXX_EXTENSIONS OFF)
+
+  find_package(Boost 1.74.0 REQUIRED)
+  find_package(alpaka 2.0.0 REQUIRED)
path: CMakeLists.txt
user: login: sbaldu
body: Yep sorry I fixed it but forgot to push
created_at: 2025-03-07T15:29:14Z
author_association: CONTRIBUTOR

PR comments:
user: login: sbaldu
created_at: 2025-03-03T09:10:03Z
body: I think this is now ready for review
author_association: CONTRIBUTOR
user: login: mdessole
created_at: 2025-03-08T13:50:13Z
body: Thank you Simone for this PR!

I believe that here and there in the cmake files you're missing a few linking statements (i.e. add line such as `target_link_libraries(SYCLMath PUBLIC alpaka::alpaka)` and similars). If I don't do that I get an error at project compilation.
author_association: CONTRIBUTOR
user: login: mdessole
created_at: 2025-03-08T13:57:57Z
body: Also, could you squash your commits before I merge your PR? Thanks!
author_association: CONTRIBUTOR