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

[WIP] Port intel pvc #24

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
45 changes: 45 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,51 @@ jobs:
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_COMPILER=${{env.CMAKE_CXX_COMPILER}} \
-DCMAKE_CXX_STANDARD=17 -DKokkos_ENABLE_HIP=ON -DKokkos_ARCH_${{env.architecture}}=ON -DBUILD_TESTING=ON ${{matrix.backend.option}}

- name: Build
# Build your program with the given configuration
run: |
docker run -v ${{github.workspace}}:/work ${{ env.container }} cmake --build build_${{matrix.backend.name}} --config ${{env.BUILD_TYPE}} -j 2

build_intel:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest

env:
#backends: HIP HIP_HOST_DEVICE
architecture: INTEL_PVC
CMAKE_CXX_COMPILER: icpx
container: intel_env

strategy:
matrix:
backend: [ {name: INTEL, option: ""}, {name: INTEL_HOST_DEVICE, option: "-DKokkosFFT_ENABLE_HOST_AND_DEVICE=ON"} ]

steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/[email protected]
with: { tool-cache: true, large-packages: false }

- name: Checkout built branch
uses: actions/checkout@v3
with:
submodules: recursive

- name: Update submodules
run: git submodule update --remote --recursive

- name: Build docker
run: docker build -t ${{ env.container }} docker/intel

- name: Configure CMake for SYCL backend
# 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: |
docker run -v ${{github.workspace}}:/work ${{ env.container }} cmake -B build_${{matrix.backend.name}} \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_COMPILER=${{env.CMAKE_CXX_COMPILER}} \
-DCMAKE_CXX_STANDARD=17 -DKokkos_ENABLE_SYCL=ON -DKokkos_ARCH_${{env.architecture}}=ON -DBUILD_TESTING=ON ${{matrix.backend.option}}

- name: Build
# Build your program with the given configuration
run: |
Expand Down
8 changes: 8 additions & 0 deletions common/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ elseif(Kokkos_ENABLE_HIP)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double FFTW::FloatOpenMP FFTW::DoubleOpenMP)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE)
endif()
elseif(Kokkos_ENABLE_SYCL)
find_package(MKL REQUIRED COMPONENTS SYCL)
target_link_libraries(common INTERFACE MKL::MKL_SYCL)
if(KokkosFFT_ENABLE_HOST_AND_DEVICE)
find_package(FFTW MODULE REQUIRED)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double FFTW::FloatOpenMP FFTW::DoubleOpenMP)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE)
endif()
elseif(Kokkos_ENABLE_OPENMP)
find_package(FFTW MODULE REQUIRED)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double FFTW::FloatOpenMP FFTW::DoubleOpenMP)
Expand Down
10 changes: 5 additions & 5 deletions common/src/KokkosFFT_Cuda_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ struct FFTDataType {
cufftDoubleComplex, fftw_complex>;
};

template <typename ExecutionSpace, typename T>
template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType {
using fftwHandle =
std::conditional_t<std::is_same_v<KokkosFFT::Impl::real_type_t<T>, float>,
fftwf_plan, fftw_plan>;
using fftwHandle = std::conditional_t<
std::is_same_v<KokkosFFT::Impl::real_type_t<T1>, float>, fftwf_plan,
fftw_plan>;
using type = std::conditional_t<std::is_same_v<ExecutionSpace, Kokkos::Cuda>,
cufftHandle, fftwHandle>;
};
Expand Down Expand Up @@ -151,7 +151,7 @@ struct FFTDataType {
using complex128 = cufftDoubleComplex;
};

template <typename ExecutionSpace, typename T>
template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType {
using type = cufftHandle;
};
Expand Down
10 changes: 5 additions & 5 deletions common/src/KokkosFFT_HIP_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ struct FFTDataType {
hipfftDoubleComplex, fftw_complex>;
};

template <typename ExecutionSpace, typename T>
template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType {
using fftwHandle =
std::conditional_t<std::is_same_v<KokkosFFT::Impl::real_type_t<T>, float>,
fftwf_plan, fftw_plan>;
using fftwHandle = std::conditional_t<
std::is_same_v<KokkosFFT::Impl::real_type_t<T1>, float>, fftwf_plan,
fftw_plan>;
using type = std::conditional_t<std::is_same_v<ExecutionSpace, Kokkos::HIP>,
hipfftHandle, fftwHandle>;
};
Expand Down Expand Up @@ -151,7 +151,7 @@ struct FFTDataType {
using complex128 = hipfftDoubleComplex;
};

template <typename ExecutionSpace, typename T>
template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType {
using type = hipfftHandle;
};
Expand Down
8 changes: 4 additions & 4 deletions common/src/KokkosFFT_OpenMP_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ struct FFTDataType {
using complex128 = fftw_complex;
};

template <typename ExecutionSpace, typename T>
template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType {
using type =
std::conditional_t<std::is_same_v<KokkosFFT::Impl::real_type_t<T>, float>,
fftwf_plan, fftw_plan>;
using type = std::conditional_t<
std::is_same_v<KokkosFFT::Impl::real_type_t<T1>, float>, fftwf_plan,
fftw_plan>;
};

template <typename ExecutionSpace>
Expand Down
256 changes: 256 additions & 0 deletions common/src/KokkosFFT_SYCL_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
#ifndef KOKKOSFFT_SYCL_TYPES_HPP
#define KOKKOSFFT_SYCL_TYPES_HPP

#include <complex>
#include <sycl/sycl.hpp>
#include <mkl.h>
#include <oneapi/mkl/dfti.hpp>
#include "KokkosFFT_utils.hpp"

// Check the size of complex type
// [TO DO] I guess this kind of test is already made by Kokkos itself
static_assert(sizeof(std::complex<float>) == sizeof(Kokkos::complex<float>));
static_assert(alignof(std::complex<float>) <= alignof(Kokkos::complex<float>));

static_assert(sizeof(std::complex<double>) == sizeof(Kokkos::complex<double>));
static_assert(alignof(std::complex<double>) <=
alignof(Kokkos::complex<double>));

#ifdef ENABLE_HOST_AND_DEVICE
#include <fftw3.h>
static_assert(sizeof(fftwf_complex) == sizeof(Kokkos::complex<float>));
static_assert(alignof(fftwf_complex) <= alignof(Kokkos::complex<float>));

static_assert(sizeof(fftw_complex) == sizeof(Kokkos::complex<double>));
static_assert(alignof(fftw_complex) <= alignof(Kokkos::complex<double>));
#endif

namespace KokkosFFT {
namespace Impl {
enum class Direction {
Forward,
Backward,
};

using FFTDirectionType = int;
constexpr FFTDirectionType MKL_FFT_FORWARD = 1;
constexpr FFTDirectionType MKL_FFT_BACKWARD = -1;

enum class FFTWTransformType { R2C, D2Z, C2R, Z2D, C2C, Z2Z };

template <typename ExecutionSpace>
using TransformType = FFTWTransformType;

// Define fft transform types
template <typename ExecutionSpace, typename T1, typename T2>
struct transform_type {
static_assert(std::is_same_v<T1, T2>,
"Real to real transform is unavailable");
};

template <typename ExecutionSpace, typename T1, typename T2>
struct transform_type<ExecutionSpace, T1, Kokkos::complex<T2>> {
static_assert(std::is_same_v<T1, T2>,
"T1 and T2 should have the same precision");
using _TransformType = TransformType<ExecutionSpace>;

static constexpr _TransformType m_type = std::is_same_v<T1, float>
? FFTWTransformType::R2C
: FFTWTransformType::D2Z;
static constexpr _TransformType type() { return m_type; };
};

template <typename ExecutionSpace, typename T1, typename T2>
struct transform_type<ExecutionSpace, Kokkos::complex<T1>, T2> {
static_assert(std::is_same_v<T1, T2>,
"T1 and T2 should have the same precision");
using _TransformType = TransformType<ExecutionSpace>;

static constexpr _TransformType m_type = std::is_same_v<T2, float>
? FFTWTransformType::C2R
: FFTWTransformType::Z2D;
static constexpr _TransformType type() { return m_type; };
};

template <typename ExecutionSpace, typename T1, typename T2>
struct transform_type<ExecutionSpace, Kokkos::complex<T1>,
Kokkos::complex<T2>> {
static_assert(std::is_same_v<T1, T2>,
"T1 and T2 should have the same precision");
using _TransformType = TransformType<ExecutionSpace>;

static constexpr _TransformType m_type = std::is_same_v<T1, float>
? FFTWTransformType::C2C
: FFTWTransformType::Z2Z;
static constexpr _TransformType type() { return m_type; };
};

#ifdef ENABLE_HOST_AND_DEVICE

template <typename ExecutionSpace>
struct FFTDataType {
using float32 = float;
using float64 = double;

using complex64 = std::conditional_t<
std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>,
std::complex<float>, fftwf_complex>;
using complex128 = std::conditional_t<
std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>,
std::complex<double>, fftw_complex>;
};

template <typename ExecutionSpace, typename T>
struct FFTPlanType {
using fftwHandle =
std::conditional_t<std::is_same_v<KokkosFFT::Impl::real_type_t<T>, float>,
fftwf_plan, fftw_plan>;
using precision =
std::conditional_t<std::is_same_v<KokkosFFT::Impl::real_type_t<T>, float>,
oneapi::mkl::dft::precision::SINGLE,
oneapi::mkl::dft::precision::DOUBLE>;
using type = std::conditional_t<std::is_same_v<ExecutionSpace, Kokkos::Cuda>,
cufftHandle, fftwHandle>;
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType {
static_assert(std::is_same_v<T1, T2>,
"Real to real transform is unavailable");
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType<ExecutionSpace, T1, Kokkos::complex<T2>> {
using float_type = T1;
static constexpr oneapi::mkl::dft::precision prec =
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>
? oneapi::mkl::dft::precision::SINGLE
: oneapi::mkl::dft::precision::DOUBLE;
static constexpr oneapi::mkl::dft::domain dom =
oneapi::mkl::dft::domain::REAL;

using fftwHandle = std::conditional_t<
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>,
fftwf_plan, fftw_plan>;

using onemklHandle = oneapi::mkl::dft::descriptor<prec, dom>;
using type = std::conditional_t<
std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>, onemklHandle,
fftwHandle>;
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType<ExecutionSpace, Kokkos::complex<T1>, T2> {
using float_type = T2;
static constexpr oneapi::mkl::dft::precision prec =
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>
? oneapi::mkl::dft::precision::SINGLE
: oneapi::mkl::dft::precision::DOUBLE;
static constexpr oneapi::mkl::dft::domain dom =
oneapi::mkl::dft::domain::REAL;

using fftwHandle = std::conditional_t<
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>,
fftwf_plan, fftw_plan>;

using onemklHandle = oneapi::mkl::dft::descriptor<prec, dom>;
using type = std::conditional_t<
std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>, onemklHandle,
fftwHandle>;
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType<ExecutionSpace, Kokkos::complex<T1>, Kokkos::complex<T2>> {
using float_type = KokkosFFT::Impl::real_type_t<T1>;
static constexpr oneapi::mkl::dft::precision prec =
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>
? oneapi::mkl::dft::precision::SINGLE
: oneapi::mkl::dft::precision::DOUBLE;
static constexpr oneapi::mkl::dft::domain dom =
oneapi::mkl::dft::domain::COMPLEX;

using fftwHandle = std::conditional_t<
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>,
fftwf_plan, fftw_plan>;

using onemklHandle = oneapi::mkl::dft::descriptor<prec, dom>;
using type = std::conditional_t<
std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>, onemklHandle,
fftwHandle>;
};

template <typename ExecutionSpace>
auto direction_type(Direction direction) {
static constexpr FFTDirectionType _FORWARD =
std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>
? MKL_FFT_FORWARD
: FFTW_FORWARD;
static constexpr FFTDirectionType _BACKWARD =
std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>
? MKL_FFT_BACKWARD
: FFTW_BACKWARD;
return direction == Direction::Forward ? _FORWARD : _BACKWARD;
}
#else
template <typename ExecutionSpace>
struct FFTDataType {
using float32 = float;
using float64 = double;
using complex64 = std::complex<float>;
using complex128 = std::complex<double>;
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType {
static_assert(std::is_same_v<T1, T2>,
"Real to real transform is unavailable");
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType<ExecutionSpace, T1, Kokkos::complex<T2>> {
using float_type = T1;
static constexpr oneapi::mkl::dft::precision prec =
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>
? oneapi::mkl::dft::precision::SINGLE
: oneapi::mkl::dft::precision::DOUBLE;
static constexpr oneapi::mkl::dft::domain dom =
oneapi::mkl::dft::domain::REAL;

using type = oneapi::mkl::dft::descriptor<prec, dom>;
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType<ExecutionSpace, Kokkos::complex<T1>, T2> {
using float_type = T2;
static constexpr oneapi::mkl::dft::precision prec =
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>
? oneapi::mkl::dft::precision::SINGLE
: oneapi::mkl::dft::precision::DOUBLE;
static constexpr oneapi::mkl::dft::domain dom =
oneapi::mkl::dft::domain::REAL;

using type = oneapi::mkl::dft::descriptor<prec, dom>;
};

template <typename ExecutionSpace, typename T1, typename T2>
struct FFTPlanType<ExecutionSpace, Kokkos::complex<T1>, Kokkos::complex<T2>> {
using float_type = KokkosFFT::Impl::real_type_t<T1>;
static constexpr oneapi::mkl::dft::precision prec =
std::is_same_v<KokkosFFT::Impl::real_type_t<float_type>, float>
? oneapi::mkl::dft::precision::SINGLE
: oneapi::mkl::dft::precision::DOUBLE;
static constexpr oneapi::mkl::dft::domain dom =
oneapi::mkl::dft::domain::COMPLEX;

using type = oneapi::mkl::dft::descriptor<prec, dom>;
};

template <typename ExecutionSpace>
auto direction_type(Direction direction) {
return direction == Direction::Forward ? MKL_FFT_FORWARD : MKL_FFT_BACKWARD;
}
#endif
} // namespace Impl
} // namespace KokkosFFT

#endif
2 changes: 2 additions & 0 deletions common/src/KokkosFFT_default_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using default_device = Kokkos::Cuda;
#elif defined(KOKKOS_ENABLE_HIP)
using default_device = Kokkos::HIP;
#include "KokkosFFT_HIP_types.hpp"
#elif defined(KOKKOS_ENABLE_SYCL)
#include "KokkosFFT_SYCL_types.hpp"
#elif defined(KOKKOS_ENABLE_OPENMP)
using default_device = Kokkos::OpenMP;
#include "KokkosFFT_OpenMP_types.hpp"
Expand Down
Loading
Loading