From 76b27fb5f1b08562d0db3735a6a358d7703f98e7 Mon Sep 17 00:00:00 2001 From: homksei Date: Mon, 11 Mar 2024 18:41:40 +0100 Subject: [PATCH] feat(samples): add CMakeLists.txt for mpi/ccl samples --- .ci/pipeline/ci.yml | 4 +- .ci/scripts/test.sh | 37 ++++-- makefile | 9 +- samples/cmake/FindCCL.cmake | 46 ++++++++ samples/cmake/setup_samples.cmake | 161 ++++++++++++++++++++++++++ samples/daal/cpp/mpi/CMakeLists.txt | 49 ++++++++ samples/oneapi/dpc/ccl/CMakeLists.txt | 54 +++++++++ samples/oneapi/dpc/mpi/CMakeLists.txt | 53 +++++++++ 8 files changed, 398 insertions(+), 15 deletions(-) create mode 100644 samples/cmake/FindCCL.cmake create mode 100644 samples/cmake/setup_samples.cmake create mode 100644 samples/daal/cpp/mpi/CMakeLists.txt create mode 100644 samples/oneapi/dpc/ccl/CMakeLists.txt create mode 100644 samples/oneapi/dpc/mpi/CMakeLists.txt diff --git a/.ci/pipeline/ci.yml b/.ci/pipeline/ci.yml index be3d1c55311..403b5c9cbdc 100755 --- a/.ci/pipeline/ci.yml +++ b/.ci/pipeline/ci.yml @@ -68,7 +68,7 @@ jobs: .ci/scripts/test.sh --test-kind examples --build-dir $(release.dir) --compiler gnu --interface oneapi/cpp --build_system cmake displayName: 'oneapi/cpp examples' - script: | - .ci/scripts/test.sh --test-kind samples --build-dir $(release.dir) --compiler gnu --interface daal/cpp/mpi --conda-env ci-env --build_system make + .ci/scripts/test.sh --test-kind samples --build-dir $(release.dir) --compiler gnu --interface daal/cpp/mpi --conda-env ci-env --build_system cmake displayName: 'daal/cpp/mpi samples' - script: | deploy/nuget/prepare_dal_nuget.sh --release-dir $(release.dir) --build-nupkg yes @@ -165,7 +165,7 @@ jobs: displayName: 'oneapi/cpp examples' - script: | source /opt/intel/oneapi/compiler/latest/env/vars.sh - .ci/scripts/test.sh --test-kind samples --build-dir $(release.dir) --compiler gnu --interface daal/cpp/mpi --conda-env ci-env --build_system make + .ci/scripts/test.sh --test-kind samples --build-dir $(release.dir) --compiler gnu --interface daal/cpp/mpi --conda-env ci-env --build_system cmake displayName: 'daal/cpp/mpi samples' - task: PublishPipelineArtifact@1 inputs: diff --git a/.ci/scripts/test.sh b/.ci/scripts/test.sh index b9856cf8554..e00bff66739 100755 --- a/.ci/scripts/test.sh +++ b/.ci/scripts/test.sh @@ -129,15 +129,19 @@ for link_mode in ${link_modes}; do fi if [ "$build_system" == "cmake" ]; then if [[ ${compiler} == gnu ]]; then - export CC=gcc - export CXX=g++ + CC=gcc + CXX=g++ elif [[ ${compiler} == clang ]]; then - export CC=clang - export CXX=clang++ + CC=clang + CXX=clang++ elif [[ ${compiler} == icx ]]; then - export CC=icx - export CXX=icpx + CC=icx + CXX=icpx fi + + export CC + export CXX + echo "============== Configuration: ==============" echo Compiler: ${compiler} echo Link mode: ${link_mode} @@ -173,11 +177,24 @@ for link_mode in ${link_modes}; do output_result= err= cmake_results_dir="_cmake_results/${arch_dir}_${lib_ext}" - for p in ${cmake_results_dir}/*; do + + if [ "$TEST_KIND" = "samples" ]; then + cd Build; + cmake_results_dir="../_cmake_results/${arch_dir}_${lib_ext}" + fi + + for p in "${cmake_results_dir}"/*; do e=$(basename "$p") - ${p} 2>&1 > ${e}.res + + if [ "$TEST_KIND" = "samples" ]; then + run_command="make run_${e}" + else + run_command="$p" + fi + + ${run_command} > "${e}.res" 2>&1 err=$? - output_result=$(cat ${e}.res) + output_result=$(cat "${e}.res") mv -f ${e}.res ${cmake_results_dir}/ status_ex= if [ ${err} -ne 0 ]; then @@ -191,6 +208,8 @@ for link_mode in ${link_modes}; do fi echo -e $status_ex done + # Go back from "Build" directory in case of samples testing + [ "$TEST_KIND" = "samples" ] && cd .. else build_command="make ${make_op} ${l}${full_arch} mode=build compiler=${compiler}" echo "Building ${TEST_KIND} ${build_command}" diff --git a/makefile b/makefile index 18211bbe973..db6716a862c 100644 --- a/makefile +++ b/makefile @@ -362,7 +362,7 @@ release.HEADERS.COMMON := $(filter-out $(subst _$(_OS),,$(release.HEADERS.OSSPEC # List examples files to populate release/examples. expat = %.cpp %.h %.hpp %.txt %.csv %.cmake expat += $(if $(OS_is_win),%.bat,%_$(_OS).lst %_$(_OS).sh) -release.CMAKE := $(filter $(expat),$(shell find examples/cmake -type f)) +release.EXAMPLES.CMAKE := $(filter $(expat),$(shell find examples/cmake -type f)) release.EXAMPLES.CPP := $(filter $(expat),$(shell find examples/daal/cpp -type f)) release.EXAMPLES.DATA := $(filter $(expat),$(shell find examples/daal/data -type f)) release.ONEAPI.EXAMPLES.CPP := $(filter $(expat),$(shell find examples/oneapi/cpp -type f)) @@ -380,8 +380,9 @@ release.CONF = deploy/local/config.txt # List samples files to populate release/examples. SAMPLES.srcdir:= $(DIR)/samples -spat = %.scala %.cpp %.h %.hpp %.txt %.csv %.html %.png %.parquet %.blob +spat = %.scala %.cpp %.h %.hpp %.txt %.csv %.html %.png %.parquet %.blob %.cmake spat += $(if $(OS_is_win),%.bat,%_$(_OS).lst %makefile_$(_OS) %.sh) +release.SAMPLES.CMAKE := $(filter $(spat),$(shell find $(SAMPLES.srcdir)/cmake -type f)) release.SAMPLES.CPP := $(if $(wildcard $(SAMPLES.srcdir)/daal/cpp/*), \ $(if $(OS_is_mac), \ $(filter $(spat),$(shell find $(SAMPLES.srcdir)/daal/cpp -not -wholename '*mpi*' -type f)) \ @@ -1005,8 +1006,7 @@ $(foreach x,$(release.EXAMPLES.CPP),$(eval $(call .release.x,$x,$(RELEASEDIR.daa $(foreach x,$(release.ONEAPI.EXAMPLES.CPP),$(eval $(call .release.x,$x,$(RELEASEDIR.daal),_release_oneapi_c))) $(foreach x,$(release.ONEAPI.EXAMPLES.DPC),$(eval $(call .release.x,$x,$(RELEASEDIR.daal),_release_oneapi_dpc))) $(foreach x,$(release.ONEAPI.EXAMPLES.DATA),$(eval $(call .release.x,$x,$(RELEASEDIR.daal),_release_oneapi_common))) -$(foreach x,$(release.EXAMPLES.COMMON_CMAKE),$(eval $(call .release.x,$x,$(RELEASEDIR.daal),_release_common))) -$(foreach x,$(release.CMAKE),$(eval $(call .release.x,$x,$(RELEASEDIR.daal),_release_common))) +$(foreach x,$(release.EXAMPLES.CMAKE),$(eval $(call .release.x,$x,$(RELEASEDIR.daal),_release_common))) #----- releasing environment scripts define .release.x @@ -1039,6 +1039,7 @@ $2: $1 | $(dir $2)/. ; $(value cpy) endef $(foreach d,$(release.SAMPLES.CPP), $(eval $(call .release.d,$d,$(subst $(SAMPLES.srcdir),$(RELEASEDIR.samples),$(subst _$(_OS),,$d)),_release_c))) $(foreach d,$(release.SAMPLES.ONEDAL.DPC), $(eval $(call .release.d,$d,$(subst $(SAMPLES.srcdir),$(RELEASEDIR.samples),$(subst _$(_OS),,$d)),_release_oneapi_dpc))) +$(foreach d,$(release.SAMPLES.CMAKE), $(eval $(call .release.d,$d,$(subst $(SAMPLES.srcdir),$(RELEASEDIR.samples),$d),_release_common))) $(CORE.incdirs): _release_c_h diff --git a/samples/cmake/FindCCL.cmake b/samples/cmake/FindCCL.cmake new file mode 100644 index 00000000000..34739f009b2 --- /dev/null +++ b/samples/cmake/FindCCL.cmake @@ -0,0 +1,46 @@ +#=============================================================================== +# Copyright contributors to the oneDAL project +# +# 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. +#=============================================================================== + +find_package(oneCCL REQUIRED) +set(CCL_ROOT $ENV{CCL_ROOT}) + +find_path(CCL_INCLUDE_DIR + NAMES "ccl.hpp" + NO_DEFAULT_PATH + PATH_SUFFIXES include/oneapi/ + PATHS ${CCL_ROOT}) + +find_library(CCL_LIBRARY + NAMES "ccl" + PATHS ${CCL_ROOT} + PATH_SUFFIXES lib + NO_DEFAULT_PATH) + +if(NOT CCL_INCLUDE_DIR MATCHES NOTFOUND AND CCL_LIBRARY) + set(CCL_FOUND TRUE) +endif() + +if(NOT DEFINED CCL_FOUND) + message( + FATAL_ERROR + "CCL was not found in ${CCL_ROOT}! Set/check CCL_ROOT environment variable!" + ) +else() + message(STATUS "Found CCL: " ${CCL_FOUND}) + message(STATUS "CCL_ROOT: .......................... " ${CCL_ROOT}) + message(STATUS "CCL_LIBRARY: ....................... " ${CCL_LIBRARY}) + message(STATUS "CCL_INCLUDE_DIR: ................... " ${CCL_INCLUDE_DIR}) +endif() diff --git a/samples/cmake/setup_samples.cmake b/samples/cmake/setup_samples.cmake new file mode 100644 index 00000000000..afaf9042417 --- /dev/null +++ b/samples/cmake/setup_samples.cmake @@ -0,0 +1,161 @@ +#=============================================================================== +# Copyright contributors to the oneDAL project +# +# 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. +#=============================================================================== + +include_guard() + +# Defines mapping between link mode and filenames +function(set_link_type) + if("${ONEDAL_LINK}" STREQUAL "static") + set(LINK_TYPE "a" PARENT_SCOPE) + else() + set(LINK_TYPE "so" PARENT_SCOPE) + endif() +endfunction() + +# Define dependencies for MPI/CCL samples +function(find_dependencies) + if(ONEDAL_DISTRIBUTED STREQUAL "yes") + find_package(MPI REQUIRED) + set(MPI_DEPENDENCIES MPI::MPI_C MPI::MPI_CXX PARENT_SCOPE) + if(ONEDAL_USE_CCL STREQUAL "yes") + # This policy allows finding modules using _ROOT variables + cmake_policy(SET CMP0074 NEW) + find_package(CCL REQUIRED) + set(MPI_DEPENDENCIES MPI::MPI_C MPI::MPI_CXX ${CCL_LIBRARY} PARENT_SCOPE) + endif() + endif() +endfunction() + +function(set_common_compiler_options) + # Setting base common set of params for samples compilation + if(WIN32) + add_compile_options(/W3 /EHsc) + elseif(UNIX) + add_compile_options(-pedantic -Wall -Wextra -Wno-unused-parameter) + endif() + + if(ONEDAL_USE_CCL STREQUAL "no") + add_compile_options(-Werror) + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM" AND WIN32 OR ONEDAL_INTERFACE STREQUAL "no") + add_compile_options(-Wall -w) + endif() + # Disable icc depreacation warnings + if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + if(WIN32) + set(DIAG_DISABLE "/Qdiag-disable:10441") + else() + set(DIAG_DISABLE "-diag-disable=10441") + endif() + add_compile_options(${DIAG_DISABLE}) + add_link_options(${DIAG_DISABLE}) + endif() + if(ONEDAL_USE_DPCPP STREQUAL "yes" AND CMAKE_BUILD_TYPE STREQUAL "Debug") + # link huge device code for DPCPP + # without this flag build fails with relocation errors + if(WIN32) + add_link_options("/flink-huge-device-code") + else() + add_link_options("-flink-huge-device-code") + endif() + endif() + message(STATUS "Common compiler params set") + message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") + message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") + message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") +endfunction() + +# Function for adding new samples to CMAKE configuration based on list of samples paths +function(add_samples samples_paths) + foreach(sample_file_path ${samples_paths}) + get_filename_component(sample ${sample_file_path} NAME_WE) + + # Detect CPU architecture + if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64") + set(CPU_ARCHITECTURE "intel_intel64") + elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") + set(CPU_ARCHITECTURE "arm_aarch64") + else() + message(FATAL_ERROR "Unkown architecture ${CMAKE_HOST_SYSTEM_PROCESSOR}") + endif() + + add_executable(${sample} ${sample_file_path}) + target_include_directories(${sample} PRIVATE ${oneDAL_INCLUDE_DIRS}) + + if(ONEDAL_USE_CCL STREQUAL "yes") + target_include_directories(${sample} PRIVATE ${CCL_INCLUDE_DIR}) + endif() + + if(UNIX AND NOT APPLE) + target_link_libraries(${sample} PRIVATE -Wl,--start-group ${oneDAL_IMPORTED_TARGETS} ${MPI_DEPENDENCIES} -Wl,--end-group) + else() + target_link_libraries(${sample} PRIVATE ${oneDAL_IMPORTED_TARGETS} ${MPI_DEPENDENCIES}) + endif() + + target_compile_options(${sample} PRIVATE ${ONEDAL_CUSTOM_COMPILE_OPTIONS}) + target_link_options(${sample} PRIVATE ${ONEDAL_CUSTOM_LINK_OPTIONS}) + set_target_properties(${sample} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/_cmake_results/${CPU_ARCHITECTURE}_${LINK_TYPE}") + + add_custom_target(run_${sample} + COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} \\ + ${MPIEXEC_MAX_NUMPROCS} -ppn ${MPIEXEC_NUMPROCS_PER_NODE} $ + DEPENDS ${sample} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + endforeach() + set_common_compiler_options() +endfunction() + +#Function generate list of sample paths based in user selection and exlude paths +function(generate_samples EXCLUDE_PATHS SAMPLES_INPUT) + if(SAMPLES_INPUT) + # Split the SAMPLES_INPUT option into a list of patterns + string(REPLACE "," ";" SAMPLES_LIST ${SAMPLES_INPUT}) + message(STATUS "Executing samples override: ${SAMPLES_LIST}") + else() + set(SAMPLES_LIST "") + endif() + + # Initialize the SAMPLES variable with an empty list + set(SAMPLES "") + + # Recursively find all the sample files in the source directory, using the + # EXCLUDE_PATHS exclude samples or directories + file(GLOB_RECURSE SAMPLE_FILES sources/*.cpp) + foreach(EXCLUDE_RULE ${EXCLUDE_PATHS}) + list(FILTER SAMPLE_FILES EXCLUDE REGEX ${EXCLUDE_RULE}) + endforeach() + + # Convert the file names to executable names + foreach(SAMPLE_FILE ${SAMPLE_FILES}) + get_filename_component(SAMPLE_NAME ${SAMPLE_FILE} NAME_WE) + if(SAMPLES_LIST) + # Otherwise, check if the sample is in the SAMPLES_LIST + foreach(SAMPLE_PATTERN ${SAMPLES_LIST}) + if("${SAMPLE_NAME}" MATCHES "${SAMPLE_PATTERN}") + list(APPEND SAMPLES ${SAMPLE_FILE}) + endif() + endforeach() + else() + # If SAMPLES_LIST is empty, add all samples to the SAMPLES variable + list(APPEND SAMPLES ${SAMPLE_FILE}) + endif() + endforeach() + + # Add the samples to the build + add_samples("${SAMPLES}") +endfunction() diff --git a/samples/daal/cpp/mpi/CMakeLists.txt b/samples/daal/cpp/mpi/CMakeLists.txt new file mode 100644 index 00000000000..6467daa0004 --- /dev/null +++ b/samples/daal/cpp/mpi/CMakeLists.txt @@ -0,0 +1,49 @@ +#=============================================================================== +# Copyright contributors to the oneDAL project +# +# 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. +#=============================================================================== + +cmake_minimum_required(VERSION 3.16) + +set(ONEDAL_USE_DPCPP no) +set(ONEDAL_INTERFACE no) +set(ONEDAL_DISTRIBUTED yes) +set(ONEDAL_USE_CCL no) +set(MPIEXEC_MAX_NUMPROCS "4" CACHE STRING "Number of processes") +set(MPIEXEC_NUMPROCS_PER_NODE "1" CACHE STRING "Number of processes per node") + + +# Add cmake scripts and modules to CMake search path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/") +include(setup_samples) + +project(oneapi_dpc_samples) + +find_package(oneDAL REQUIRED) + +find_dependencies() +set_link_type() +set_common_compiler_options() + +include_directories(sources) + +option(REF_BACKEND "Exclude not supported files for non-MKL backend" OFF) + +# Initialize the EXCLUDE_LIST variable +set(EXCLUDE_LIST "sources/*.h") + +# Define variable to specify the samples or directories to include or exclude +option(SAMPLES_LIST "") + +generate_samples("${EXCLUDE_LIST}" "${SAMPLEtupSamoS_LIST}") diff --git a/samples/oneapi/dpc/ccl/CMakeLists.txt b/samples/oneapi/dpc/ccl/CMakeLists.txt new file mode 100644 index 00000000000..8836a9cc69e --- /dev/null +++ b/samples/oneapi/dpc/ccl/CMakeLists.txt @@ -0,0 +1,54 @@ +#=============================================================================== +# Copyright contributors to the oneDAL project +# +# 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. +#=============================================================================== + +cmake_minimum_required(VERSION 3.16) + +set(ONEDAL_USE_DPCPP yes) +set(ONEDAL_INTERFACE yes) +set(ONEDAL_DISTRIBUTED yes) +set(ONEDAL_USE_CCL yes) +set(MPIEXEC_MAX_NUMPROCS "1" CACHE STRING "Number of processes") +set(MPIEXEC_NUMPROCS_PER_NODE "1" CACHE STRING "Number of processes per node") + + +set(CMAKE_C_COMPILER "mpiicx") +if(WIN32) + set(CMAKE_CXX_COMPILER "mpiicx") +elseif(UNIX) + set(CMAKE_CXX_COMPILER "mpiicpx") +endif() + +# Add cmake scripts and modules to CMake search path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/") +include(setup_samples) + +project(oneapi_dpc_samples) + +find_package(oneDAL REQUIRED) + +find_dependencies() +set_link_type() +set_common_compiler_options() + +include_directories(sources) + +# Initialize the EXCLUDE_LIST variable +set(EXCLUDE_LIST "sources/*.hpp") + +# Define variable to specify the samples or directories to include or exclude +option(SAMPLES_LIST "") + +generate_samples("${EXCLUDE_LIST}" "${SAMPLES_LIST}") diff --git a/samples/oneapi/dpc/mpi/CMakeLists.txt b/samples/oneapi/dpc/mpi/CMakeLists.txt new file mode 100644 index 00000000000..3846bda92f6 --- /dev/null +++ b/samples/oneapi/dpc/mpi/CMakeLists.txt @@ -0,0 +1,53 @@ +#=============================================================================== +# Copyright contributors to the oneDAL project +# +# 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. +#=============================================================================== + +cmake_minimum_required(VERSION 3.16) + +set(ONEDAL_USE_DPCPP yes) +set(ONEDAL_INTERFACE yes) +set(ONEDAL_DISTRIBUTED yes) +set(ONEDAL_USE_CCL no) +set(MPIEXEC_MAX_NUMPROCS "4" CACHE STRING "Number of processes") +set(MPIEXEC_NUMPROCS_PER_NODE "4" CACHE STRING "Number of processes per node") + +set(CMAKE_C_COMPILER "mpiicx") +if(WIN32) + set(CMAKE_CXX_COMPILER "mpiicx") +elseif(UNIX) + set(CMAKE_CXX_COMPILER "mpiicpx") +endif() + +# Add cmake scripts and modules to CMake search path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/") +include(setup_samples) + +project(oneapi_dpc_samples) + +find_package(oneDAL REQUIRED) + +find_dependencies() +set_link_type() +set_common_compiler_options() + +include_directories(sources) + +# Initialize the EXCLUDE_LIST variable +set(EXCLUDE_LIST "sources/*.hpp") + +# Define variable to specify the samples or directories to include or exclude +option(SAMPLES_LIST "") + +generate_samples("${EXCLUDE_LIST}" "${SAMPLES_LIST}")