diff --git a/docker-build/Dockerfile b/docker-build/Dockerfile new file mode 100644 index 0000000000..e5b06c2934 --- /dev/null +++ b/docker-build/Dockerfile @@ -0,0 +1,92 @@ +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +### +# Build the image for spark-rapids-jni development environment. +# +# Arguments: CUDA_VERSION=[12.X.Y], OS_RELEASE=[8, 9], TARGETPLATFORM=[linux/amd64, linux/arm64] +# +### +ARG CUDA_VERSION=12.9.1 +ARG OS_RELEASE=9 +ARG TARGETPLATFORM=linux/amd64 + +# multi-platform build with: docker buildx build --platform linux/arm64,linux/amd64 on either amd64 or arm64 host +# check available official arm-based docker images at https://hub.docker.com/r/nvidia/cuda/tags (OS/ARCH) +FROM --platform=$TARGETPLATFORM nvidia/cuda:$CUDA_VERSION-devel-rockylinux$OS_RELEASE + +# If DEV_BUILD is ON, the gcc-toolset will be enabled by default for bash shell +ARG DEV_BUILD=OFF + +# Dependency versions +# Act as default GCC toolset in the image +ARG TOOLSET_VERSION=14 +ARG CMAKE_VERSION=3.30.4 +ARG CCACHE_VERSION=4.11.2 + +# Default x86_64 from x86 build, aarch64 cmake for arm build +ARG CMAKE_ARCH=x86_64 + +### Install basic requirements +RUN dnf --enablerepo=crb install -y scl-utils gcc-toolset-${TOOLSET_VERSION} python39 \ + zlib-devel maven tar wget patch ninja-build git zip + +# Enable the gcc-toolset by default for bash shell if DEV_BUILD is ON +RUN if [ "$DEV_BUILD" = "ON" ]; then \ + echo "source scl_source enable gcc-toolset-${TOOLSET_VERSION}" >> /etc/bashrc; \ + fi + +# Execute every time a new non-interactive bash shell is started +ENV BASH_ENV=/etc/bashrc + +## pre-create the CMAKE_INSTALL_PREFIX folder, set writable by any user for Jenkins +RUN mkdir -m 777 /usr/local/rapids /rapids + +# Fetch and install CMake. +RUN cd /usr/local && wget --quiet https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-${CMAKE_ARCH}.tar.gz && \ + tar zxf cmake-${CMAKE_VERSION}-linux-${CMAKE_ARCH}.tar.gz && \ + rm cmake-${CMAKE_VERSION}-linux-${CMAKE_ARCH}.tar.gz + +# Make version-less alias for external reference such as when cmake is called by an IDE outside of the container +RUN ln -s /usr/local/cmake-${CMAKE_VERSION}-linux-${CMAKE_ARCH}/bin/cmake /usr/local/bin/cmake + +# ccache for interactive builds +RUN cd /tmp && wget --quiet https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}.tar.gz && \ + tar zxf ccache-${CCACHE_VERSION}.tar.gz && \ + rm ccache-${CCACHE_VERSION}.tar.gz && \ + cd ccache-${CCACHE_VERSION} && \ + mkdir build && \ + cd build && \ + scl enable gcc-toolset-${TOOLSET_VERSION} \ + "cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DZSTD_FROM_INTERNET=ON \ + -DREDIS_STORAGE_BACKEND=OFF && \ + cmake --build . --parallel ${PARALLEL_LEVEL} --target install" && \ + cd ../.. && \ + rm -rf ccache-${CCACHE_VERSION} + +# Fetch and install JDK 22. +RUN cd /usr/local && wget --quiet https://download.oracle.com/java/22/archive/jdk-22.0.2_linux-x64_bin.tar.gz && \ + tar zxf jdk-22.0.2_linux-x64_bin.tar.gz && \ + rm jdk-22.0.2_linux-x64_bin.tar.gz + +# Make Java22 available in path. +RUN ln -sf /usr/local/jdk-22.0.2/bin/java /usr/local/bin/java +ENV JAVA_HOME="/usr/local/jdk-22.0.2" + +# disable cuda container constraints to allow running w/ older drivers on datacenter GPUs +ENV NVIDIA_DISABLE_REQUIRE="true" diff --git a/docker-build/build-in-docker b/docker-build/build-in-docker new file mode 100755 index 0000000000..dafc98b05d --- /dev/null +++ b/docker-build/build-in-docker @@ -0,0 +1,38 @@ +#!/bin/bash + +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Build the spark-rapids-jni artifact in a Docker container with devtoolset + +set -e + +# Base paths relative to this script's location +SCRIPTDIR=$(cd $(dirname $0); pwd) + +LOCAL_MAVEN_REPO=${LOCAL_MAVEN_REPO:-"$HOME/.m2/repository"} +export CMAKE_GENERATOR=${CMAKE_GENERATOR:-"Ninja"} +export CUDA_VERSION=${CUDA_VERSION:-12.9.1} +CUDA_CLASSIFIER=cuda${CUDA_VERSION%%.*} + +# Set env for arm64 build, The possible values of 'uname -m' : [x86_64/i386/aarch64/mips/...] +if [ "$(uname -m)" == "aarch64" ]; then + # ARM-specific settings. + echo "Set ARM Specific settings" +fi + +# TODO: Settings to build for different CUDA versions, different GPU archs, CPU archs, etc. +$SCRIPTDIR/run-in-docker "./build.sh" "$@" diff --git a/docker-build/env.sh b/docker-build/env.sh new file mode 100644 index 0000000000..1772437205 --- /dev/null +++ b/docker-build/env.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -ex +export sclCMD=${sclCMD:-"scl enable gcc-toolset-14"} diff --git a/docker-build/run-in-docker b/docker-build/run-in-docker new file mode 100755 index 0000000000..e8c143dd62 --- /dev/null +++ b/docker-build/run-in-docker @@ -0,0 +1,123 @@ +#!/bin/bash + +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Run a command in a Docker container with devtoolset + +set -e + +source env.sh + +# Set this environment variable to ON to build the docker image for local development, +# with gcc-toolset enabled by default. +# This is necessary especially if the docker container is used for local development with an IDE. +JNI_DOCKER_DEV_BUILD=${JNI_DOCKER_DEV_BUILD:-OFF} + +REPODIR_REL=$(git rev-parse --show-toplevel) +REPODIR=$(realpath "$REPODIR_REL") +GIT_COMMON_DIR_REL=$(git rev-parse --git-common-dir) +GIT_COMMON_DIR=$(realpath "$GIT_COMMON_DIR_REL") +WORKDIR=${WORKDIR:-$REPODIR} +TZ=${TZ:-UTC} + +CUDA_VERSION=${CUDA_VERSION:-12.9.1} +CUDA_CLASSIFIER=cuda${CUDA_VERSION%%.*} + +DOCKER_CMD=${DOCKER_CMD:-docker} +DOCKER_BUILD_EXTRA_ARGS=${DOCKER_BUILD_EXTRA_ARGS:-""} +if [ "$(uname -m)" == "aarch64" ]; then + DOCKER_BUILD_EXTRA_ARGS="--build-arg TARGETPLATFORM=linux/arm64 --build-arg CMAKE_ARCH=aarch64 $DOCKER_BUILD_EXTRA_ARGS" +else + DOCKER_BUILD_EXTRA_ARGS="--build-arg TARGETPLATFORM=linux/amd64 --build-arg CMAKE_ARCH=x86_64 $DOCKER_BUILD_EXTRA_ARGS" +fi +DOCKER_RUN_EXTRA_ARGS=${DOCKER_RUN_EXTRA_ARGS:-""} +LOCAL_CCACHE_DIR=${LOCAL_CCACHE_DIR:-"$HOME/.ccache"} +LOCAL_MAVEN_REPO=${LOCAL_MAVEN_REPO:-"$HOME/.m2/repository"} + +if [ "$JNI_DOCKER_DEV_BUILD" == "ON" ]; then + echo "Building docker image for local development, gcc-toolset is enabled by default..." + JNI_DOCKER_IMAGE="cuvs-jni-build:${CUDA_VERSION}-devel-rockylinux8" +else + echo "Building docker image for production, gcc-toolset is NOT enabled by default..." + JNI_DOCKER_IMAGE="cuvs-jni-build:${CUDA_VERSION}-rockylinux8" +fi + +# ensure directories exist +mkdir -p "$LOCAL_CCACHE_DIR" "$LOCAL_MAVEN_REPO" + +$DOCKER_CMD build $DOCKER_BUILD_EXTRA_ARGS -f $REPODIR/docker-build/Dockerfile \ + --build-arg CUDA_VERSION=$CUDA_VERSION \ + --build-arg DEV_BUILD=$JNI_DOCKER_DEV_BUILD \ + -t $JNI_DOCKER_IMAGE \ + $REPODIR/docker-build + +if [[ "$DOCKER_CMD" == "docker" ]]; then + DOCKER_GPU_OPTS=${DOCKER_GPU_OPTS:-"--gpus all"} +fi + +if (( $# == 0 )); then + # no arguments gets an interactive shell + DOCKER_OPTS="${DOCKER_OPTS} -it" + RUN_CMD="/bin/bash" +else + RUN_CMD="${@@Q}" +fi + +MNT_ARGS=() + +RO_SRC=( + "/etc/group" + "/etc/passwd" + "/etc/shadow" + "/etc/sudoers.d" +) +RO_DST=("${RO_SRC[@]}") +if [[ "$HOST_CUDA_PATH" != "" ]]; then + RO_SRC+=("$HOST_CUDA_PATH") + RO_DST+=("/usr/local/cuda") +fi +for (( i=0; i<${#RO_SRC[@]}; i++)); do + MNT_ARGS+=(--mount type=bind,src=${RO_SRC[$i]},dst=${RO_DST[$i]},ro) +done + +RW_SRC=( + "$GIT_COMMON_DIR" + "$WORKDIR" + "$LOCAL_CCACHE_DIR" + "$LOCAL_MAVEN_REPO" +) +for (( i=0; i<${#RW_SRC[@]}; i++)); do + MNT_ARGS+=(--mount type=bind,src=${RW_SRC[$i]},dst=${RW_SRC[$i]}) +done + +$DOCKER_CMD run $DOCKER_GPU_OPTS $DOCKER_RUN_EXTRA_ARGS -u $(id -u):$(id -g) --rm \ + ${MNT_ARGS[@]} \ + --workdir "$WORKDIR" \ + -e CCACHE_DIR="$LOCAL_CCACHE_DIR" \ + -e CMAKE_C_COMPILER_LAUNCHER="ccache" \ + -e CMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + -e CMAKE_CUDA_COMPILER_LAUNCHER="ccache" \ + -e CMAKE_CXX_LINKER_LAUNCHER="ccache" \ + -e CMAKE_PREFIX_PATH="${WORKDIR}/cpp/build/$CUDA_CLASSIFIER" \ + -e LIBCUVS_BUILD_DIR="${WORKDIR}/cpp/build/$CUDA_CLASSIFIER" \ + -e CMAKE_GENERATOR \ + -e CUDA_VISIBLE_DEVICES \ + -e PARALLEL_LEVEL \ + -e VERBOSE \ + $DOCKER_OPTS \ + $JNI_DOCKER_IMAGE \ + ${sclCMD} "$RUN_CMD"