ARG BASE=nvidia/cuda:11.7.1-devel-ubuntu22.04
FROM $BASE

ARG NPROCS=4

RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -yq \
        bc \
        ca-certificates \
        ccache \
        git \
        jq \
        libopenmpi-dev \
        ninja-build \
        vim \
        wget \
        && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN KEYDUMP_URL=https://cloud1.cees.ornl.gov/download && \
    KEYDUMP_FILE=keydump && \
    wget --quiet ${KEYDUMP_URL}/${KEYDUMP_FILE} && \
    wget --quiet ${KEYDUMP_URL}/${KEYDUMP_FILE}.sig && \
    gpg --import ${KEYDUMP_FILE} && \
    gpg --verify ${KEYDUMP_FILE}.sig ${KEYDUMP_FILE} && \
    rm ${KEYDUMP_FILE}*

ARG CMAKE_VERSION=3.26.3
ENV CMAKE_DIR=/opt/cmake
RUN CMAKE_KEY=2D2CEF1034921684 && \
    CMAKE_URL=https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION} && \
    CMAKE_SCRIPT=cmake-${CMAKE_VERSION}-Linux-x86_64.sh && \
    CMAKE_SHA256=cmake-${CMAKE_VERSION}-SHA-256.txt && \
    wget --quiet ${CMAKE_URL}/${CMAKE_SHA256} && \
    wget --quiet ${CMAKE_URL}/${CMAKE_SHA256}.asc && \
    wget --quiet ${CMAKE_URL}/${CMAKE_SCRIPT} && \
    gpg --verify ${CMAKE_SHA256}.asc ${CMAKE_SHA256} && \
    grep -i ${CMAKE_SCRIPT} ${CMAKE_SHA256} | sed -e s/linux/Linux/ | sha256sum --check && \
    mkdir -p ${CMAKE_DIR} && \
    sh ${CMAKE_SCRIPT} --skip-license --prefix=${CMAKE_DIR} && \
    rm cmake*
ENV PATH=${CMAKE_DIR}/bin:$PATH

# Install the dpcpp compiler, see
# https://www.intel.com/content/www/us/en/docs/vtune-profiler/installation-guide/2023-1/package-managers.html
ARG DPCPP_VERSION=2023.0.0
RUN wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB && \
    apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB && \
    echo "deb https://apt.repos.intel.com/oneapi all main" | tee /etc/apt/sources.list.d/oneAPI.list && \
    apt-get update -o Dir::Etc::sourcelist="sources.list.d/oneAPI.list" -o APT::Get::List-Cleanup="0" && \
    apt-get install -y intel-oneapi-compiler-dpcpp-cpp-${DPCPP_VERSION} && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
ENV DPCPP=/opt/intel/oneapi/compiler/${DPCPP_VERSION}/linux/bin-llvm/clang++

# Install Codeplay's oneAPI for NVIDIA GPUs, see
# https://developer.codeplay.com/products/oneapi/nvidia/2023.0.0/guides/get-started-guide-nvidia
RUN wget https://cloud1.cees.ornl.gov/download/oneapi-for-nvidia-gpus-${DPCPP_VERSION}-linux.sh && \
    chmod +x oneapi-for-nvidia-gpus-${DPCPP_VERSION}-linux.sh && \
    ./oneapi-for-nvidia-gpus-${DPCPP_VERSION}-linux.sh -y && \
    rm oneapi-for-nvidia-gpus-${DPCPP_VERSION}-linux.sh

# Install oneDPL
ENV ONE_DPL_DIR=/opt/onedpl
RUN . /opt/intel/oneapi/setvars.sh --include-intel-llvm && \
    ONE_DPL_VERSION=oneDPL-2022.2.0 && \
    ONE_DPL_URL=https://github.com/oneapi-src/oneDPL/archive && \
    ONE_DPL_ARCHIVE=${ONE_DPL_VERSION}-rc1.tar.gz && \
    SCRATCH_DIR=/scratch && mkdir -p ${SCRATCH_DIR} && cd ${SCRATCH_DIR} && \
    wget --quiet ${ONE_DPL_URL}/${ONE_DPL_ARCHIVE} && \
    mkdir onedpl && \
    tar -xf ${ONE_DPL_ARCHIVE} -C onedpl --strip-components=1 && cd onedpl && \
    mkdir build && cd build && \
    cmake -DCMAKE_CXX_COMPILER=icpx -DCMAKE_CXX_FLAGS="-w" -DCMAKE_INSTALL_PREFIX=${ONE_DPL_DIR} -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=TRUE -DONEDPL_BACKEND="dpcpp_only" .. && \
    make -j${NPROCS} install && \
    rm -rf ${SCRATCH_DIR}

# Set up environment variables to avoid using setvars.sh in CI
# clang++
ENV PATH=/opt/intel/oneapi/compiler/latest/linux/bin-llvm/:$PATH
# sycl-ls, icpx
ENV PATH=/opt/intel/oneapi/compiler/latest/linux/bin/:$PATH
# libsycl
ENV LD_LIBRARY_PATH=/opt/intel/oneapi/compiler/latest/linux/lib:$LD_LIBRARY_PATH
# libsvml
ENV LD_LIBRARY_PATH=/opt/intel/oneapi/compiler/latest/linux/compiler/lib/intel64_lin:$LD_LIBRARY_PATH

# Install Boost and patch it, see
# intel.com/content/www/us/en/developer/articles/technical/building-boost-with-oneapi.html
ENV BOOST_DIR=/opt/boost
RUN . /opt/intel/oneapi/setvars.sh --include-intel-llvm && \
    BOOST_VERSION=1.81.0 && \
    BOOST_VERSION_UNDERSCORE=$(echo "$BOOST_VERSION" | sed -e "s/\./_/g") && \
    BOOST_KEY=379CE192D401AB61 && \
    BOOST_URL=https://archives.boost.io/release/${BOOST_VERSION}/source && \
    BOOST_ARCHIVE=boost_${BOOST_VERSION_UNDERSCORE}.tar.bz2 && \
    SCRATCH_DIR=/scratch && mkdir -p ${SCRATCH_DIR} && cd ${SCRATCH_DIR} && \
    wget --quiet ${BOOST_URL}/${BOOST_ARCHIVE} && \
    wget --quiet ${BOOST_URL}/${BOOST_ARCHIVE}.json && \
    cat ${BOOST_ARCHIVE}.json | jq -r '. | .sha256 + "  " + .file' | sha256sum --check && \
    mkdir -p boost && \
    tar -xf ${BOOST_ARCHIVE} -C boost --strip-components=1 && \
    cd boost && \
    sed -i "s/-pch-create/-Xclang -emit-pch -o/g" tools/build/src/tools/intel-linux.jam && \
    cat tools/build/src/tools/intel-linux.jam && \
    CXXFLAGS="-w" ./bootstrap.sh --with-toolset=intel-linux --prefix=${BOOST_DIR} && \
    ./b2 -j${NPROCS} \
        hardcode-dll-paths=true dll-path=${BOOST_DIR}/lib \
        toolset=intel-linux \
        link=shared \
        variant=release \
        cxxflags=-w \
        install \
        && \
    rm -rf ${SCRATCH_DIR}

# Install Google Benchmark support library
ENV BENCHMARK_DIR=/opt/benchmark
RUN SCRATCH_DIR=/scratch && mkdir -p ${SCRATCH_DIR} && cd ${SCRATCH_DIR} && \
    git clone https://github.com/google/benchmark.git -b v1.5.4 && \
    cd benchmark && \
    mkdir build && cd build && \
    cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=${BENCHMARK_DIR} -D BENCHMARK_ENABLE_TESTING=OFF .. && \
    make -j${NPROCS} && make install && \
    rm -rf ${SCRATCH_DIR}

# Install Kokkos
ARG KOKKOS_VERSION=4.5.00
ARG KOKKOS_OPTIONS="-DCMAKE_CXX_STANDARD=20 -DKokkos_ENABLE_SYCL=ON -DCMAKE_CXX_FLAGS=-Wno-unknown-cuda-version -DKokkos_ENABLE_UNSUPPORTED_ARCHS=ON -DKokkos_ARCH_VOLTA70=ON -DKOKKOS_IMPL_SYCL_DEVICE_GLOBAL_SUPPORTED=0 -DCMAKE_CXX_FLAGS=-w"
ENV KOKKOS_DIR=/opt/kokkos
RUN . /opt/intel/oneapi/setvars.sh --include-intel-llvm && \
    KOKKOS_URL=https://github.com/kokkos/kokkos/archive/${KOKKOS_VERSION}.tar.gz && \
    KOKKOS_ARCHIVE=kokkos-${KOKKOS_VERSION}.tar.gz && \
    SCRATCH_DIR=/scratch && mkdir -p ${SCRATCH_DIR} && cd ${SCRATCH_DIR} && \
    wget --quiet ${KOKKOS_URL} --output-document=${KOKKOS_ARCHIVE} && \
    mkdir -p kokkos && \
    tar -xf ${KOKKOS_ARCHIVE} -C kokkos --strip-components=1 && \
    cd kokkos && \
    mkdir -p build && cd build && \
    cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=${KOKKOS_DIR} -D CMAKE_CXX_COMPILER=${DPCPP} ${KOKKOS_OPTIONS} .. && \
    make -j${NPROCS} install && \
    rm -rf ${SCRATCH_DIR}
