...
 
Commits (8)
......@@ -4,3 +4,9 @@
[submodule "inastemp"]
path = inastemp
url = https://gitlab.inria.fr/coulaud/inastemp.git
[submodule "experimental/modules/morse_cmake"]
path = experimental/modules/morse_cmake
url = https://gitlab.inria.fr/solverstack/morse_cmake.git
[submodule "experimental/modules/xsimd"]
path = experimental/modules/xsimd
url = https://github.com/QuantStack/xsimd.git
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 3
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 2
UseTab: Never
cmake_minimum_required (VERSION 3.13.0 FATAL_ERROR)
#
# Project Declaration
#--------------------
project(scalfmm CXX)
# check if compiling into source directories
string(COMPARE EQUAL "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" insource)
if(insource)
message(FATAL_ERROR "${PROJECT_NAME} requires an out of source build. Goto ./Build and tapes cmake ../")
endif(insource)
#
# Version Number
# --------------
# SCALFMM version number. An even minor number corresponds to releases.
set(${CMAKE_PROJECT_NAME}_MAJOR_VERSION 3)
set(${CMAKE_PROJECT_NAME}_MINOR_VERSION 0)
set(${CMAKE_PROJECT_NAME}_PATCH_VERSION 0-pre-alpha)
set(${CMAKE_PROJECT_NAME}_VERSION "${${CMAKE_PROJECT_NAME}_MAJOR_VERSION}.${${CMAKE_PROJECT_NAME}_MINOR_VERSION}.${${CMAKE_PROJECT_NAME}_PATCH_VERSION}" )
#
# Update cmake path
# -----------------
#list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
#
# Creating main lib
# -----------------
add_library(${CMAKE_PROJECT_NAME} INTERFACE)
target_compile_features(${CMAKE_PROJECT_NAME} INTERFACE cxx_std_20)
# Set library includes
# --------------------
target_include_directories(${CMAKE_PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
if(MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/morse_cmake")
# Add extra cmake module path and initialize morse cmake modules
# --------------------------------------------------------------
if(MORSE_DISTRIB_DIR)
list(APPEND CMAKE_MODULE_PATH ${MORSE_DISTRIB_DIR}/modules)
set(MORSE_CMAKE_MODULE_PATH ${MORSE_DISTRIB_DIR}/modules )
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/morse_cmake")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules/morse_cmake/modules)
set(MORSE_CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules/morse_cmake/modules )
endif()
include(MorseInit)
# Set the RPATH config
# These options allow all installed executables to run correctly
# when installed to the install diretory
# --------------------
# use, i.e. don't skip the full RPATH for the build tree
set(CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH already
# (but later on when installing)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
# the RPATH to be used when installing
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# Build ScalFmm as static or dynamic lib
# --------------------------------------
# option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
#
# Options
#
# Cmake options for dependencies
option( SCALFMM_USE_MPI "Set to ON to build ScaFMM with MPI" OFF )
option( SCALFMM_USE_BLAS "Set to ON to build ScaFMM with BLAS" ON )
option( SCALFMM_USE_FFT "Set to ON to build ScaFMM with FFTW" OFF )
option( SCALFMM_USE_STARPU "Set to ON to build SCALFMM with StarPU" OFF )
# Cmake options that impact the build tree
option( SCALFMM_BUILD_EXAMPLES "Set to ON to build examples" ON )
option( SCALFMM_BUILD_UNITS "Set to ON to build unit tests" OFF )
option( SCALFMM_BUILD_DOC "Set to ON to build the Doxygen documentation" OFF )
# Cmake options related to trace, logging and statistics
option( SCALFMM_USE_LOG "Set to ON to print output debug information" OFF )
option( SCALFMM_USE_MEM_STATS "Set to ON to profile memory" OFF )
option( SCALFMM_ONLY_DEVEL "Set to ON to compile Development tools (only scalfmm team)" ON )
set(SCALFMM_COMPILE_DEFINITIONS "${SCALFMM_COMPILE_DEFINITIONS}" CACHE STRING "Global compile definitions for ScalFMM")
#
# Set scalfmm dev flags
# ------------------------
if(SCALFMM_ONLY_DEVEL)
list(APPEND SCALFMM_CXX_FLAGS -Wall -pedantic )
endif(SCALFMM_ONLY_DEVEL)
# TODO: Find new way to resolve dependencies...
# Set FUSE LIST
# -------------
set(FUSE_LIST "") # Construct during configure
set(FUSE_DEP_AVAILABLE "MPI;CUDA;STARPU;OMP4;BLAS;FFT;OPENCL") # List to compare against when compiling tests, etc...
#
# Boost
# -----
find_package(Boost 1.69.0 COMPONENTS serialization REQUIRED)
message(STATUS "${Boost_LIBRARIES}")
#
# OpenMP
# ------
if(NOT OpenMP_CXX_FOUND)
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE OpenMP::OpenMP_CXX)
list(APPEND SCALFMM_LIBRARIES OpenMP)
if(OpenMP_CXX_VERSION_MAJOR GREATER_EQUAL 4)
list(APPEND FUSE_LIST OMP4)
endif()
else(OpenMP_CXX_FOUND)
message(WARNING "OPENMP NOT FOUND")
endif(OpenMP_CXX_FOUND)
endif(NOT OpenMP_CXX_FOUND)
#
# XTL, XSIMD & XTENSOR
# --------------------
#if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/xsimd")
# set(xsimd_DIR "${CMAKE_CURRENT_BINARY_DIR}/modules/xsimd")
# # Find XSIMD properly
# add_subdirectory(modules/xsimd)
find_package(xsimd CONFIG REQUIRED)
if(xsimd_FOUND)
message(STATUS "XSIMD found")
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE xsimd)
else(xsimd_FOUND)
message(FATAL_ERROR "Can't find XSIMD !")
endif(xsimd_FOUND)
#endif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/xsimd")
find_package(xtl CONFIG REQUIRED)
if(xtl_FOUND)
message(STATUS "XTL found")
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE xtl)
else(xtl_FOUND)
message(FATAL_ERROR "Can't find XTL !")
endif(xtl_FOUND)
find_package(xtensor CONFIG REQUIRED)
if(xtensor_FOUND)
if(xsimd_FOUND)
list(APPEND SCALFMM_COMPILE_DEFINITIONS XTENSOR_USE_XSIMD)
endif(xsimd_FOUND)
message(STATUS "XTENSOR found")
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE xtensor)
else(xtensor_FOUND)
message(FATAL_ERROR "Can't find XTENSOR !")
endif(xtensor_FOUND)
#set(xtensor-blas_DIR $ENV{xtensor_blas_DIR})
#find_package(xtensor-blas CONFIG REQUIRED)
#if(xtensor-blas_FOUND)
# message(STATUS "XTENSOR-BLAS found")
# target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE xtensor-blas)
#else(xtensor-blas_FOUND)
# message(FATAL_ERROR "Can't find XTENSOR-BLAS !")
#endif(xtensor-blas_FOUND)
#
# Module inria
# ------------
target_include_directories(${CMAKE_PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/modules/inria>
$<INSTALL_INTERFACE:include>
)
#
# Module rangev3
# ------------
target_include_directories(${CMAKE_PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/modules/rangev3>
$<INSTALL_INTERFACE:include>
)
#
# Specific Debug flags
# --------------------
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND SCALFMM_CXX_FLAGS -funroll-loops)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
list(APPEND SCALFMM_CXX_FLAGS -fp-model\ strict)
endif()
endif()
#
# Specific Release flags
# ----------------------
if(CMAKE_BUILD_TYPE STREQUAL "Release")
list(APPEND SCALFMM_CXX_FLAGS -funroll-loops)
if(NOT APPLE)
list(APPEND -ftree-vectorize)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
list(APPEND SCALFMM_CXX_FLAGS -ipo -fstrict-aliasing)
endif()
list(APPEND SCALFMM_CXX_FLAGS -ffast-math -ftree-vectorize)
endif(NOT APPLE)
endif()
#
# MPI
# ---
if(SCALFMM_USE_MPI)
if(NOT MPI_FOUND)
find_package(MPI REQUIRED)
if(MPI_CXX_FOUND)
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE MPI::MPI_CXX)
list(APPEND SCALFMM_LIBRARIES MPI)
list(APPEND FUSE_LIST MPI)
else(MPI_CXX_FOUND)
message(FATAL_ERROR "MPI_CXX is required but was not found. "
"Please provide an MPI compiler in your environment."
"Note that you can give the path to your MPI installation "
"by setting MPI_DIR cmake variable.")
endif(MPI_CXX_FOUND)
endif(NOT MPI_FOUND)
endif(SCALFMM_USE_MPI)
#
# Blas options
# ------------
if(SCALFMM_USE_BLAS)
option( SCALFMM_USE_MKL_AS_BLAS "Set to ON to use MKL BLAS/LAPACK" OFF )
option( SCALFMM_USE_ESSL_AS_BLAS "Set to ON to use ESSL BLAS/LAPACK" OFF )
option( SCALFMM_USE_EXTERNAL_BLAS "Set to ON to use external BLAS. Please, set BLAS_LIBRARIES variable." OFF )
if( SCALFMM_USE_MKL_AS_BLAS )
set(BLA_VENDOR "Intel10_64lp_seq")
find_package(BLAS ) # not REQUIRED
elseif(SCALFMM_USE_ESSL_AS_BLAS)
set(BLA_VENDOR "IBMESSL")
find_package(BLAS QUIET) # not REQUIRED
find_package(LAPACK QUIET) # not REQUIRED
elseif(SCALFMM_USE_EXTERNAL_BLAS)
message(STATUS "BLAS SET BY EXTERNAL PROGRAM = ${BLAS_LIBRARIES}")
list(APPEND BLASLAPACK_LIBRARIES "${BLAS_LIBRARIES}")
else()
find_package(BLAS) # not REQUIRED
find_package(LAPACK) # not REQUIRED
endif()
if(BLAS_FOUND)
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE blas::blas)
list(APPEND SCALFMM_LIBRARIES BLAS)
list(APPEND FUSE_LIST BLAS)
if(LAPACK_FOUND)
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE lapack::lapack)
list(APPEND SCALFMM_LIBRARIES LAPACK)
endif()
message (STATUS "Check BLAS Fortran mangling")
# add options to let the user be able to force a behavior
option( SCALFMM_BLAS_ADD_ "Set to ON to force calls to BLAS Fortran symbols with _ (ex: dgemm_)" ON )
option( SCALFMM_BLAS_UPCASE "Set to ON to force calls to BLAS Fortran symbols in capital (ex: DGEMM)" OFF )
option( SCALFMM_BLAS_NOCHANGE "Set to ON to force calls to BLAS Fortran symbols with no change (ex: dgemm)" OFF )
# if options not changed by user then auto-detection
if (NOT SCALFMM_BLAS_ADD_ AND NOT SCALFMM_BLAS_UPCASE AND NOT SCALFMM_BLAS_NOCHANGE)
# give blas libraries and check dgemm symbol
set(CMAKE_REQUIRED_LIBRARIES "${BLAS_LIBRARIES}")
check_function_exists(dgemv_ DGEMV_ADD_)
check_function_exists(DGEMV DGEMV_UPCASE)
check_function_exists(dgemv DGEMV_NOCHANGE)
# here we consider that the first kind of symbol found will be the one used
# current order is: ADD_, UPCASE, NOCHANGE
if (DGEMV_ADD_)
set (SCALFMM_BLAS_ADD_ ON)
set (SCALFMM_BLAS_UPCASE OFF)
set (SCALFMM_BLAS_NOCHANGE OFF)
message (STATUS "BLAS dgemv_ symbol found, SCALFMM_BLAS_ADD_ is ON")
else (DGEMV_ADD_)
if (DGEMV_UPCASE)
set (SCALFMM_BLAS_ADD_ OFF)
set (SCALFMM_BLAS_UPCASE ON)
set (SCALFMM_BLAS_NOCHANGE OFF)
message (STATUS "BLAS DGEMV symbol found, SCALFMM_BLAS_UPCASE is ON")
else (DGEMV_UPCASE)
if (DGEMV_NOCHANGE)
set (SCALFMM_BLAS_ADD_ OFF)
set (SCALFMM_BLAS_UPCASE OFF)
set (SCALFMM_BLAS_NOCHANGE ON)
message (STATUS "BLAS dgemv symbol found, SCALFMM_BLAS_NOCHANGE is ON")
endif (DGEMV_NOCHANGE)
endif (DGEMV_UPCASE)
endif (DGEMV_ADD_)
if ( (NOT DGEMV_ADD_) AND (NOT DGEMV_UPCASE) AND (NOT DGEMV_NOCHANGE) )
message(FATAL_ERROR "BLAS Fortran mangling is not properly detected - please check your BLAS libraries")
endif ()
else (NOT SCALFMM_BLAS_ADD_ AND NOT SCALFMM_BLAS_UPCASE AND NOT SCALFMM_BLAS_NOCHANGE)
if (SCALFMM_BLAS_ADD_)
message (STATUS "SCALFMM_BLAS_ADD_ is set to ON")
endif()
if (SCALFMM_BLAS_UPCASE)
message (STATUS "SCALFMM_BLAS_UPCASE is set to ON")
endif()
if (SCALFMM_BLAS_NOCHANGE)
message (STATUS "SCALFMM_BLAS_NOCHANGE is set to ON")
endif()
endif (NOT SCALFMM_BLAS_ADD_ AND NOT SCALFMM_BLAS_UPCASE AND NOT SCALFMM_BLAS_NOCHANGE)
else()
MESSAGE(WARNING "BLAS: ${BLAS_FOUND}")
message(WARNING "BLAS has not been found, SCALFMM will continue to compile but some applications will be disabled.")
message(WARNING "If you have BLAS set BLAS_LIBDIR, BLAS_INCDIR or BLAS_DIR (CMake variables using -D or environment variables).")
set(SCALFMM_USE_BLAS OFF)
endif()
endif(SCALFMM_USE_BLAS)
#
# FFT options
# -----------
include(CMakeDependentOption)
CMAKE_DEPENDENT_OPTION(SCALFMM_USE_MKL_AS_FFTW "Set to ON to use MKL FFTW" ON "SCALFMM_USE_FFT;SCALFMM_USE_MKL_AS_BLAS" OFF )
CMAKE_DEPENDENT_OPTION(SCALFMM_USE_ESSL_AS_FFTW "Set to ON to use ESSL FFTW" ON "SCALFMM_USE_FFT;SCALFMM_USE_ESSL_AS_BLAS" OFF )
if(SCALFMM_USE_FFT)
message(STATUS "SCALFMM USE FFT Configure:")
# The package find_package(FFTW) can be used with the following COMPONENTS:
# MKL, ESSL, THREADS|OMP and/or SIMPLE|LONG|QUAD
# Default will find the real double precision fftw library version without THREADS|OMP
if(SCALFMM_USE_MKL_AS_FFTW)
message(STATUS " SCALFMM USE FFT from MKL")
set(BLA_VENDOR "Intel10_64lp_seq")
if(NOT TARGET blas::blas)
find_package(FFTW COMPONENTS MKL)
else()
set(FFTW_FOUND 1)
find_package(FFTW COMPONENTS MKL QUIET)
target_include_directories(${CMAKE_PROJECT_NAME} INTERFACE ${FFTW_INCLUDE_DIRS})
endif()
elseif (SCALFMM_USE_ESSL_AS_FFTW)
message(STATUS " SCALFMM USE FFT from ESSL ")
find_package(FFTW COMPONENTS ESSL)
else()
message(STATUS " SCALFMM USE FFTW")
find_package(FFTW COMPONENTS SIMPLE)
endif()
if(FFTW_FOUND)
list(APPEND FUSE_LIST FFT)
if(NOT SCALFMM_USE_MKL_AS_FFTW)
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE fftw::fftw)
list(APPEND SCALFMM_LIBRARIES FFTW)
endif()
else(FFTW_FOUND)
message(WARNING "FFTW has not been found, SCALFMM will continue to compile but some applications will be disabled.")
message(WARNING "If you have FFTW set FFTW_LIBDIR, FFTW_INCDIR or FFTW_DIR (CMake variables using -D or environment variables).")
set(SCALFMM_USE_FFT OFF)
endif(FFTW_FOUND)
endif(SCALFMM_USE_FFT)
message(STATUS "SCALFMM_USE_FFT = ${SCALFMM_USE_FFT}")
#
# STARPU Section
# --------------
message( STATUS "SCALFMM_USE_STARPU = ${SCALFMM_USE_STARPU}" )
CMAKE_DEPENDENT_OPTION( SCALFMM_USE_OPENCL "Set to ON to use OPENCL with StarPU" OFF "SCALFMM_USE_STARPU" OFF)
CMAKE_DEPENDENT_OPTION( SCALFMM_USE_CUDA "Set to ON to use OPENCL with StarPU" OFF "SCALFMM_USE_STARPU" OFF)
if( SCALFMM_USE_STARPU )
enable_language(C)
# Find StarPU with a list of optional components
set(SCALFMM_STARPU_VERSION "1.2.8" CACHE STRING " STARPU version desired")
# create list of components in order to make a single call to find_package(starpu...)
set(STARPU_COMPONENT_LIST "HWLOC")
if(SCALFMM_USE_CUDA)
message(WARNING "This release doest not include a full support for CUDA/OpenCl.")
#list(APPEND STARPU_COMPONENT_LIST "CUDA")
endif()
if(SCALFMM_USE_MPI)
list(APPEND STARPU_COMPONENT_LIST "MPI")
endif()
if(SCALFMM_USE_OPENCL)
message(WARNING "This release doest not include a full support for CUDA/OpenCl.")
#list(APPEND STARPU_COMPONENT_LIST "OPENCL")
endif()
find_package(STARPU ${SCALFMM_STARPU_VERSION} REQUIRED
COMPONENTS ${STARPU_COMPONENT_LIST})
if(STARPU_FOUND)
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE starpu::starpu_dep)
list(APPEND FUSE_LIST "STARPU")
list(APPEND SCALFMM_LIBRARIES "STARPU")
if(SCALFMM_USE_CUDA)
#list(APPEND FUSE_LIST "CUDA")
endif()
if(SCALFMM_USE_OPENCL)
#list(APPEND FUSE_LIST "OPENCL")
endif()
else(STARPU_FOUND)
message(FATAL_ERROR "StarPU not found.")
endif(STARPU_FOUND)
endif(SCALFMM_USE_STARPU)
# Additional options for developers
if( SCALFMM_ONLY_DEVEL )
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
option( SCALFMM_USE_OMP4 "Set to ON to disable the gcc/intel omp4" OFF )
else()
option( SCALFMM_USE_OMP4 "Set to ON to disable the gcc/intel omp4" ON )
endif()
option( SCALFMM_TIME_OMPTASKS "Set to ON to time omp4 tasks and generate output file" OFF )
# SIMGRID and peformance models options
option( SCALFMM_SIMGRID_NODATA "Set to ON to avoid the allocation of numerical parts in the group tree" OFF )
option( STARPU_SIMGRID_MLR_MODELS "Set to ON to enable MLR models need for calibration and simulation" OFF )
# OPENMP 4/5 support
option( OPENMP_SUPPORT_PRIORITY "Set to ON to enable tasks priority (OMP4.x/KSTAR/StarPU compiler only)" OFF )
# STARPU options
cmake_dependent_option(OPENMP_SUPPORT_COMMUTE "Set to ON to let tasks commute (KSTAR/StarPU compiler only)" OFF
"SCALFMM_USE_STARPU" OFF)
cmake_dependent_option(OPENMP_SUPPORT_TASK_NAME "Set to ON to enable a taskname clause for tasks (KSTAR/StarPU compiler only)" OFF
"SCALFMM_USE_STARPU" OFF)
cmake_dependent_option(SCALFMM_STARPU_USE_COMMUTE "Set to ON to enable commute with StarPU" ON "SCALFMM_USE_STARPU" OFF)
cmake_dependent_option(SCALFMM_STARPU_USE_REDUX "Set to ON to enable redux with StarPU" OFF "SCALFMM_USE_STARPU" OFF)
cmake_dependent_option(SCALFMM_STARPU_USE_PRIO "Set to ON to enable priority with StarPU" ON "SCALFMM_USE_STARPU" OFF)
cmake_dependent_option(SCALFMM_STARPU_FORCE_NO_SCHEDULER "Set to ON to disable heteroprio even if supported" OFF "SCALFMM_USE_STARPU" OFF)
cmake_dependent_option(SCALFMM_USE_STARPU_EXTRACT "Set to ON to enable extract with StarPU mpi implicit" ON "SCALFMM_USE_STARPU" OFF)
endif()
#
# Set ScalFMM compile flags
# -------------------------
set(SCALFMM_CXX_FLAGS "${SCALFMM_CXX_FLAGS}" CACHE STRING "Global compile flags for ScalFMM")
message(STATUS "ScalFMM final flags : ${SCALFMM_CXX_FLAGS}")
# And adding flags to target
# --------------------------
target_compile_options(${CMAKE_PROJECT_NAME} INTERFACE "${SCALFMM_CXX_FLAGS}")
#
# Set ScalFMM dependencies
# ------------------------
set(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES}" CACHE STRING "ScalFMM libraries dependencies")
message(STATUS "ScalFMM dependencies : ${SCALFMM_LIBRARIES}")
# #
# # Set ScalFMM link flags
# # ----------------------
# string(REPLACE ";" " " SCALFMM_LINK_FLAGS "${SCALFMM_LINK_FLAGS}")
# set(SCALFMM_LINK_FLAGS "${SCALFMM_LINK_FLAGS}" CACHE STRING "Global link flags for ScalFMM")
# message(STATUS "ScalFMM link flags : ${SCALFMM_LINK_FLAGS}")
# # And adding lin flags to the target
# # ----------------------------------
# target_link_options(${CMAKE_PROJECT_NAME} INTERFACE "${SCALFMM_LIBRARIES}")
#
# Set ScalFMM compile definitions
# -------------------------------
message(STATUS "ScalFMM compile definitions : ${SCALFMM_COMPILE_DEFINITIONS}")
# And adding definitions to target
# --------------------------------
target_compile_definitions(${CMAKE_PROJECT_NAME} INTERFACE "${SCALFMM_COMPILE_DEFINITIONS}")
#
# Generate ScalFmmConfig.h
# ------------------------
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/scalfmm/config/scalfmm-config.hpp.cmake
${CMAKE_CURRENT_BINARY_DIR}/include/scalfmm/config/scalfmm-config.hpp)
#
# Static analysis during build
# ----------------------------
CMAKE_DEPENDENT_OPTION(SCALFMM_USE_STATIC_ANALYSIS "Set to ON to use static analysis tools" ON "SCALFMM_ONLY_DEVEL" OFF )
CMAKE_DEPENDENT_OPTION(SCALFMM_USE_CPPCHECK "Set to ON to use static analysis tools" OFF "SCALFMM_USE_STATIC_ANALYSIS" OFF )
CMAKE_DEPENDENT_OPTION(SCALFMM_USE_CLANGTIDY "Set to ON to use static analysis tools" ON "SCALFMM_USE_STATIC_ANALYSIS" OFF )
CMAKE_DEPENDENT_OPTION(SCALFMM_USE_IWYU "Set to ON to use static analysis tools" ON "SCALFMM_USE_STATIC_ANALYSIS" OFF )
if(SCALFMM_USE_STATIC_ANALYSIS AND SCALFMM_USE_CPPCHECK)
find_program(CPPCHECK "cppcheck")
if (CPPCHECK)
set(CMAKE_CXX_CPPCHECK "${CPPCHECK}"
"--language=c++"
"$<GENEX_EVAL:-I$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>>"
"-I."
"-v"
"--enable=all"
"--force"
"--inline-suppr"
)
message(STATUS "CPPCHECK analysis is ON.")
endif()
#add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_GENEX_EVAL:${CMAKE_PROJECT_NAME},-I$<TARGET_PROPERTY:${CMAKE_PROJECT_NAME},INTERFACE_INCLUDE_DIRECTORIES>>)
endif(SCALFMM_USE_STATIC_ANALYSIS AND SCALFMM_USE_CPPCHECK)
if(SCALFMM_USE_STATIC_ANALYSIS AND SCALFMM_USE_CLANGTIDY)
find_program(CLANGTIDY "clang-tidy")
if(CLANGTIDY)
set(CMAKE_CXX_CLANG_TIDY "${CLANGTIDY};--header-filter=${CMAKE_SOURCE_DIR}/include/scalfmm/.;--checks=-*,boost-*,cppcoreguidelines-*,clang-analyser-cplusplus*,modernize-*,mpi-*,performance-*,portability-*,readability-*")
message(STATUS "Clang Tidy analysis is ON.")
endif()
endif(SCALFMM_USE_STATIC_ANALYSIS AND SCALFMM_USE_CLANGTIDY)
if(SCALFMM_USE_STATIC_ANALYSIS AND SCALFMM_USE_IWYU)
find_program(IWYU "include-what-you-use")
if(IWYU)
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${IWYU}")
message(STATUS "Include What You Use analysis is ON.")
endif()
endif(SCALFMM_USE_STATIC_ANALYSIS AND SCALFMM_USE_IWYU)
#
# Build Examples
# --------------
message(STATUS "SCALFMM_BUILD_EXAMPLES = ${SCALFMM_BUILD_EXAMPLES}" )
if( SCALFMM_BUILD_EXAMPLES )
# Build - Examples and drivers
add_subdirectory(examples)
endif()
#
# Build - Unitary and numerical Tests
# -----------------------------------
message( STATUS "SCALFMM_BUILD_UTESTS = ${SCALFMM_BUILD_UTESTS}" )
if( SCALFMM_BUILD_UNITS )
enable_testing()
include(CTest)
add_subdirectory(units)
endif()
#
# Add - doc
# ---------
message(STATUS "SCALFMM_BUILD_DOC = ${SCALFMM_BUILD_DOC}" )
if(SCALFMM_BUILD_DOC)
add_subdirectory(doc)
endif()
#
# Export Library
# --------------
install(TARGETS ${CMAKE_PROJECT_NAME} #xsimd
EXPORT ${CMAKE_PROJECT_NAME}-targets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin)
install(DIRECTORY ${${CMAKE_PROJECT_NAME}_SOURCE_DIR}/include
DESTINATION ${CMAKE_INSTALL_PREFIX}
PATTERN "scalfmm-config.hpp.cmake" EXCLUDE)
install(DIRECTORY ${${CMAKE_PROJECT_NAME}_SOURCE_DIR}/modules/inria
DESTINATION ${CMAKE_INSTALL_PREFIX}
PATTERN "scalfmm-config.hpp.cmake" EXCLUDE)
install(FILES ${${CMAKE_PROJECT_NAME}_BINARY_DIR}/include/scalfmm/config/scalfmm-config.hpp
DESTINATION include/scalfmm/config/scalfmm-config.hpp)
install(EXPORT ${CMAKE_PROJECT_NAME}-targets
FILE ${CMAKE_PROJECT_NAME}-targets.cmake
NAMESPACE ${CMAKE_PROJECT_NAME}::
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_PROJECT_NAME}ConfigVersion.cmake"
VERSION ${${CMAKE_PROJECT_NAME}_VERSION}
COMPATIBILITY SameMajorVersion)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/${CMAKE_PROJECT_NAME}/)
install(FILES "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake"
"${PROJECT_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake"
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
#
# build a CPack driven installer package
# --------------------------------------
# See CPackConfig.cmake for the details.
include(CPack)
#
# Print configure status
# ----------------------
# Use Mem stats
message(STATUS "SCALFMM_USE_MEM_STATS = ${SCALFMM_USE_MEM_STATS}" )
# Use Log
message(STATUS "SCALFMM_USE_LOG = ${SCALFMM_USE_LOG}" )
#
message(STATUS "SCALFMM_USE_MPI = ${SCALFMM_USE_MPI}" )
message(STATUS "SCALFMM_USE_BLAS = ${SCALFMM_USE_BLAS}")
message(STATUS "SCALFMM_USE_FFT = ${SCALFMM_USE_FFT}")
message(STATUS "SCALFMM_USE_MKL = ${SCALFMM_USE_MKL}")
#
if(SCALFMM_USE_STARPU)
message(STATUS "SCALFMM_USE_STARPU = ${SCALFMM_USE_STARPU}" )
message(STATUS "STARPU_LIBRARIES = ${STARPU_LIBRARIES}")
message(STATUS "SCALFMM_USE_CUDA = ${SCALFMM_USE_CUDA}" )
MESSAGE(STATUS "SCALFMM_USE_OPENCL = ${SCALFMM_USE_OPENCL}" )
endif(SCALFMM_USE_STARPU)
message(STATUS "SCALFMM_CXX_FLAGS = ${SCALFMM_CXX_FLAGS}")
message(STATUS "SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}")
message(STATUS "FUSE_LIST = ${FUSE_LIST}")
else(MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse_cmake")
message(STATUS "MORSE_DISTRIB_DIR is not set")
message(STATUS "Please indicate where is located your MORSE distribution directory."
" This is necessary to find cmake_modules.")
message(STATUS "If you are a MORSE developer, you normally have access to the svn repository of the MORSE_DISTRIB_DIR: "
"svn checkout svn+ssh://yourlogin@scm.gforge.inria.fr/svnroot/morse/trunk/morse_distrib")
endif(MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/morse_cmake")
set(CPACK_PACKAGE_VERSION_PATCH 0)
execute_process(
COMMAND git rev-list HEAD --count
OUTPUT_VARIABLE CPACK_PACKAGE_VERSION_PATCH
RESULT_VARIABLE RET
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
)
#string_TRIM(PATCH1 PATCH)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY "ON")
#
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENCE")
set(CPACK_PACKAGE_VERSION_MAJOR "${${CMAKE_PROJECT_NAME}_MAJOR_VERSION}")
set(CPACK_PACKAGE_VERSION_MINOR "${${CMAKE_PROJECT_NAME}_MINOR_VERSION}")
#
set(PACK_PACKAGE_VERSION "${${CMAKE_PROJECT_NAME}_VERSION}.${${CMAKE_PROJECT_NAME}_MINOR_VERSION}-${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "SCALFMM-${${CMAKE_PROJECT_NAME}_MAJOR_VERSION}.${${CMAKE_PROJECT_NAME}_MINOR_VERSION}-${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_SOURCE_IGNORE_FILES "\\\\.git;.DS_Store;.*~;/*.aux;/*.idx;/*.log;/*.out;/*.toc;/*.ilg;CMakeLists.txt.user;/.settings/")
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/Utils/;/Build*;/Obsolete/")
#
## This file should be placed in the root directory of your project.
## Then modify the CMakeLists.txt file in the root directory of your
## project to incorporate the testing dashboard.
## # The following are required to uses Dart and the Cdash dashboard
## ENABLE_TESTING()
## INCLUDE(CTest)
set(CTEST_PROJECT_NAME "ScalFMM")
set(CTEST_NIGHTLY_START_TIME "00:00:00 GMT")
set(CTEST_SUBMIT_URL "http://cdash.inria.fr/CDash/submit.php?project=scalfmm")
#--------------------------------------------------------------------
# BUILDNAME variable construction
# This variable will be used to set the build name which will appear
# on the Chameleon dashboard http://cdash.inria.fr/CDash/
#--------------------------------------------------------------------
# Start with the short system name, e.g. "Linux", "FreeBSD" or "Windows"
if(NOT BUILDNAME)
set(BUILDNAME "${CMAKE_SYSTEM_NAME}")
# Add i386 or amd64
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(BUILDNAME "${BUILDNAME}-amd64")
else()
set(BUILDNAME "${BUILDNAME}-i386")
endif()
# Add compiler name
get_filename_component(CMAKE_CXX_COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME)
set(BUILDNAME "${BUILDNAME}-${CMAKE_CXX_COMPILER_NAME}")
# Add the build type, e.g. "Debug, Release..."
if(CMAKE_BUILD_TYPE)
set(BUILDNAME "${BUILDNAME}-${CMAKE_BUILD_TYPE}")
endif(CMAKE_BUILD_TYPE)
# Specific options of Scalfmm
if(SCALFMM_USE_SSE)
set(BUILDNAME "${BUILDNAME}-sse")
endif()
if(SCALFMM_USE_BLAS)
set(BUILDNAME "${BUILDNAME}-blas")
endif()
if(SCALFMM_USE_MPI)
set(BUILDNAME "${BUILDNAME}-mpi")
endif()
endif()
# Examples
#---------
# List of source files
set(source_tests_files
sandbox.cpp
test_tensorial_interpolator.cpp
test-blas.cpp
test-xtensor.cpp
)
# Add execs - 1 cpp = 1 exec
foreach(exec ${source_tests_files})
set(compile_exec TRUE)
get_filename_component( execname ${exec} NAME_WE )
foreach(fuse_key ${FUSE_DEP_AVAILABLE})
file(STRINGS "${exec}" lines_fuse REGEX "@FUSE_${fuse_key}")
if(lines_fuse AND NOT ${fuse_key} IN_LIST FUSE_LIST)
message( STATUS "This needs ${fuse_key} = ${exec}" )
set(compile_exec FALSE)
endif()
endforeach()
# Dependency are OK
if( compile_exec )
add_executable( ${execname} ${exec})
list(APPEND SCALFMM_EXAMPLES_TARGETS ${execname})
list(APPEND SCALFMM_TESTS_TARGETS ${execname})
set_target_properties(${execname} PROPERTIES ENABLE_EXPORTS TRUE
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BUILD_TYPE}
)
target_compile_definitions(${execname} PUBLIC -DXTENSOR_USE_XSIMD)
target_link_libraries( ${execname} ${CMAKE_PROJECT_NAME})
# TODO: Remove these include derectories, ust temporary to reuse old components
target_include_directories( ${execname} PRIVATE ${CMAKE_SOURCE_DIR}/../include/)
target_include_directories( ${execname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions( ${execname} PRIVATE BYPASS_CONFIG)
install(TARGETS ${execname} RUNTIME DESTINATION bin)
endif()
endforeach(exec)
add_custom_target(scalfmm_examples ALL DEPENDS ${SCALFMM_EXAMPLES_TARGETS})
#ifndef TRAP_SCALFMM_CONFIG_HPP
#define TRAP_SCALFMM_CONFIG_HPP
#include <scalfmm/config/scalfmm-config.hpp>
#endif
//---------------------
// Experimental example
//---------------------
//#include <iosfwd>
//#include <string>
#include <algorithm>
#include <iostream>
#include <random>
#include <tuple>
#include <vector>
#include <inria/tcli/help_descriptor.hpp>
#include <inria/tcli/tcli.hpp>
#include <range/v3/algorithm/for_each.hpp>
#include <range/v3/algorithm/generate.hpp>
#include <range/v3/algorithm/result_types.hpp>
#include <range/v3/algorithm/sort.hpp>
#include <range/v3/core.hpp>
#include <range/v3/functional/concepts.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/view/generate.hpp>
#include <xsimd/xsimd.hpp>
#include <xtensor/xtensor.hpp>
#include <scalfmm/container/particle.hpp>
#include <scalfmm/container/particle_container.hpp>
#include <scalfmm/container/point.hpp>
#include <scalfmm/functional/utils.hpp>
#include <scalfmm/interpolation/uniform.hpp>
#include <scalfmm/tools/colorized.hpp>
#include <scalfmm/tree/box.hpp>
#include <scalfmm/tree/tree.hpp>
namespace args {
struct nb_particle : inria::tcli::required_tag {
inria::tcli::str_vec flags = {"--n-particles", "-nbp"};
const char *description = "Number of particles to generate.";
using type = std::size_t;
};
struct tree_height : inria::tcli::required_tag {
inria::tcli::str_vec flags = {"--tree-height", "-th"};
const char *description =
"Tree height (or initial height in case of an adaptive tree).";
using type = std::size_t;
};
struct thread_count : inria::tcli::required_tag {
inria::tcli::str_vec flags = {"--threads", "-t"};
const char *description = "Maximum thread count to be used.";
using type = std::size_t;
type def{1};
};
struct order : inria::tcli::required_tag {
inria::tcli::str_vec flags = {"--order", "-o"};
const char *description = "Precision order.";
using type = std::size_t;
};
struct file : inria::tcli::required_tag {
inria::tcli::str_vec flags = {"--input-file", "-fin"};
const char *description = "Input filename (.fma or .bfma).";
using type = std::string;
};
struct chunk_size {
inria::tcli::str_vec flags = {"--group-size", "-gs"};
const char *description = "Group tree chunk size.";
using type = std::size_t;
type def{250};
};
auto cli = inria::tcli::make_parser(nb_particle{}, tree_height{},
thread_count{}, file{}, inria::tcli::help{},
chunk_size{}, order{});
} // namespace args
/**
* \brief Store the PerfTest program parameters.
*/
struct params {
std::size_t m_nb_particle{}; ///< Tree height.
std::size_t m_tree_height{}; ///< Tree height.
std::size_t m_nb_threads{}; ///< Maximum thread count (when used).
std::string m_filename{}; ///< Particles file.
std::size_t m_group_size{}; ///< Group tree group size
std::size_t m_order{}; ///< Group tree group size
params() = default;
params(const decltype(args::cli) &cli) {
m_order = cli.get<args::order>();
m_nb_particle = cli.get<args::nb_particle>();
m_tree_height = cli.get<args::tree_height>();
m_nb_threads = cli.get<args::thread_count>();
m_filename = cli.get<args::file>();
m_group_size = cli.get<args::chunk_size>();
}
};
using namespace scalfmm;
CPP_template(class Iter, class Sent, class Fun)(
requires // ranges::Invocable<Fun&> &&
// ranges::OutputIterator<Iter,ranges::invoke_result_t<Fun&>> &&
// ranges::Sentinel<Sent, Iter>
ranges::Writable<
Iter, ranges::invoke_result_t<Fun &>>) void my_algorithm(Iter first,
Sent last,
Fun f) {
// ...
}
// Quick type displayer
template <typename T> class TD;
int main(int argc, char **argv) {
args::cli.parse(argc, argv);
params parameters(args::cli);
//interpolation::map<int>;
interpolation::uniform_interpolator<double, 3> unif_interpolator(
parameters.m_order, parameters.m_tree_height);
// variad<int,float> ot{{8,9},{1.3,2.6}};
// variad<int, float> copy{ot};
// std::cout << colors::blue << std::get<0>(copy)[0] << " " << colors::green
// << std::get<1>(copy)[0] << colors::reset << '\n';
// variad<int, float, double> v_{{1,2}, {3.3,4.4}, {5.5,6.6}};
// variad<int, float, double> v_(10);
// v_.push_back(std::make_tuple(2,1.1,2.2));
// std::cout << std::get<0>(v_).size() << '\n';
// std::cout << colors::blue << std::get<0>(v_)[0] << " " << colors::green <<
// std::get<1>(v_)[0] << " " << colors::yellow << std::get<2>(v_)[0] <<
// colors::reset << '\n';
// const std::size_t tree_height{parameters.m_tree_height};
// using source_t = container::particle<double,3,double,std::size_t>;
// using position_t = container::point<double,3>;
// using container_source_t = container::particle_container<source_t>;
// const std::size_t nb_of_part{parameters.m_nb_particle};
// container_source_t cs{nb_of_part};
// std::random_device rd;
// std::mt19937 gen(rd());
// std::uniform_real_distribution<double> dis(-1.0, 1.0);
// auto random_r = [&dis, &gen](){ return dis(gen); };
// auto make_particle = [&tree_height, &random_r]()
//{
// position_t pos = {random_r(), random_r(), random_r()};
// source_t part( pos
// , random_r()
// , index::get_morton_index(pos,
// component::box<position_t>{2.0, {0.0,0.0,0.0}}, tree_height)
// );
// return part.as_tuple();
//};
// auto print_particle = [](source_t p)
//{
// std::cout << colors::yellow << "=================" << colors::reset <<
// '\n'; std::cout << "x = " << std::get<0>(p) << '\n'; std::cout << "y = "
// << std::get<1>(p) << '\n'; std::cout << "z = " << std::get<2>(p) << '\n';
// std::cout << "p = " << std::get<3>(p) << '\n';
// std::cout << "x.p = " << p.position()[0] << '\n';
// std::cout << "norm2 = " << utils::norm2(p.position()) << '\n';
// std::cout << "morton = " << std::get<4>(p) << '\n';
//};
// auto pred = [](auto a, auto b)
//{
// return std::get<4>(a) < std::get<4>(b);
//};
// std::vector<std::tuple<int,float>> v = {{8,3.0},{9,2.1},{10,9.6}};
// my_algorithm(cs.begin(), cs.end(), make_particle);
// std::generate(cs.begin(), cs.end(), make_particle);
// std::sort(cs.begin(), cs.end(), pred);
// std::for_each(cs.begin(), cs.end(), print_particle);
// component::tree t{};
return 0;
}
#include <algorithm>
#include <array>
#include <chrono>
#include <functional>
#include <iostream>
#include <random>
#include <xtensor/xarray.hpp>
#include <xtensor/xio.hpp>
#include <scalfmm/container/particle.hpp>
#include <scalfmm/container/particle_container.hpp>
#include <scalfmm/interpolation/uniform.hpp>
#include <scalfmm/tools/colorized.hpp>
#include <scalfmm/tree/box.hpp>
int main()
{
using size_type = std::size_t;
namespace colors = scalfmm::colors;
constexpr size_type particle_dim{3};
constexpr size_type potential_dim{3};
constexpr size_type order{6};
using particle_type = scalfmm::container::particle<double, particle_dim, double, double, double>;
using point_type = scalfmm::container::point<double, particle_dim>;
using container_type = scalfmm::container::particle_container<particle_type>;
using interpolator_type = scalfmm::interpolation::uniform_interpolator<double, particle_dim>;
const size_type nb_particles{5000};
const size_type tree_height{5};
const double width{3.723};
container_type particles_source{nb_particles};
container_type particles_target{nb_particles};
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> dis(-1.0, 1.0);
auto random_r = [&dis, &gen]() { return dis(gen); };
point_type center = {0., 0., 0.};
auto make_particle = [&tree_height, &center, &width, &random_r]() {
point_type position = {random_r() * width, random_r() * width, random_r() * width};
position += center;
particle_type p(position, random_r(), random_r(), random_r());
return p.as_tuple();
};
std::generate(particles_source.begin(), particles_source.end(), make_particle);
center = {2. * width, 0., 0.};
std::generate(particles_target.begin(), particles_target.end(), make_particle);
auto start = std::chrono::high_resolution_clock::now();
interpolator_type s(order, tree_height);
auto end = std::chrono::high_resolution_clock::now();
std::cout << colors::green << "Interpolator construction time : "
<< std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << "ms\n"
<< colors::reset;
return 0;
}
// --------------------------------
// See LICENCE file at project root
// File : particle_container.cpp
// --------------------------------
#ifndef SCALFMM_CONCEPTS_LIBRARY_HPP
#define SCALFMM_CONCEPTS_LIBRARY_HPP
namespace scalfmm::concepts
{
template<typename R, typename Enabler> struct require_impl;
template<typename R> struct require_impl<R, void> { using type = R; };
template<typename Return, typename... Ts>
struct require_check : require_impl<Return,std::void_t<Ts...>>
{};
template<typename From, typename To>
using Convertible = std::enable_if_t<std::is_convertible_v<From,To>>;
template<typename T>
using Arithmetic = std::enable_if_t<std::is_arithmetic_v<T>>;
template<typename T>
using Integral = std::enable_if_t<std::is_integral_v<T>>;
template<bool Condition>
using If = std::enable_if_t<Condition>;
} // end namespace scalfmm::concepts
// Pseudo require macro
#define requires(...) -> typename ::concept::require_check<__VA_ARGS__>::type
#endif // SCALFMM_CONCEPTS_LIBRARY_HPP
// See LICENCE file at project root
///
/// File generated by cmake
// Do not remove any line
///////////////////////////////////////////////////////
#ifndef SCALFMM_CONFIG_SCALFMM_CONFIG_HPP
#define SCALFMM_CONFIG_SCALFMM_CONFIG_HPP
// Uncomment the next line to use debug mode
#cmakedefine SCALFMM_USE_LOG
///////////////////////////////////////////////////////
// Blas
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_BLAS
#cmakedefine SCALFMM_USE_MKL_AS_BLAS
// Fortran Mangling
#cmakedefine SCALFMM_BLAS_ADD_
#cmakedefine SCALFMM_BLAS_UPCASE
#cmakedefine SCALFMM_BLAS_NOCHANGE
////////////////////////////////////////////////////////
// FFT
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_FFT
#cmakedefine SCALFMM_USE_MKL_AS_FFTW
#cmakedefine SCALFMM_USE_ESSL_AS_FFTW
//////////////////////////////////////////////////////
// MPI
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_MPI
///////////////////////////////////////////////////////
// Memory trace
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_MEM_STATS
///////////////////////////////////////////////////////
// CUDA
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_CUDA
///////////////////////////////////////////////////////
// OPENCL
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_OPENCL
///////////////////////////////////////////////////////
// STARPU
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_STARPU
#cmakedefine SCALFMM_DISABLE_NATIVE_OMP4
///////////////////////////////////////////////////////
// To control starpu config
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_STARPU_USE_COMMUTE
#cmakedefine SCALFMM_STARPU_USE_REDUX
#cmakedefine SCALFMM_STARPU_USE_PRIO
#cmakedefine SCALFMM_STARPU_FORCE_NO_SCHEDULER
#cmakedefine SCALFMM_USE_STARPU_EXTRACT
#endif // CONFIG_H
// --------------------------------
// See LICENCE file at project root
// File : particle.hpp
// --------------------------------
#ifndef SCALFMM_CONTAINER_PARTICLE_HPP
#define SCALFMM_CONTAINER_PARTICLE_HPP
#include <inria/integer_sequence.hpp>
#include <scalfmm/container/point.hpp>
#include <scalfmm/meta/type_pack.hpp>
/**
* \brief Multi-purpose particle implementation
*
* This template implementation of a particle allows simple reuse for several
* use cases. The aim it to provide an interface that is compatible with the
* rest of ScalFMM. It is mainly intended to be used as an interface for the
* particle containers.
*
* The Types parameter pack can accept any type that is to be considered as a
* particle attribute. You can also specify scalfmm::pack type to factorise
* several types.
*
* In the following example, the two specialisations of the class will give the
* same final structure.
*
* ```
* using FReal = double;
* static constexpr std::size_t dimension = 3;
*
* particle<FReal, dimension, int, float, float, float, float>;
* particle<FReal, dimension, int, scalfmm::pack<4, float> >;
* ```
*
* The base of these two classes is
* ```
* std::tuple<double, double, double, int, float, float, float, float>;
* ```
*
* \warning Although the classes will have the same final layout, C++ considers
* these two classes to be different !
*
* ##### Example
*
* ```
* // Define a 3D particle with an int attribute
* using Particle = particle<double, 3, int>;
*
* Particle p;
* p.get<>
* ```
*
*
* \tparam FReal Floating point type
* \tparam dimension Space dimension count
* \tparam Types Attributes type list
*
*/
namespace scalfmm::container
{
template<typename ValueType, std::size_t Dim = 3, typename... Types>
class particle : public scalfmm::meta::pack_expand_tuple<scalfmm::meta::pack<Dim, ValueType>, Types...>
{
public:
/// Storage class : std::tuple<FReal,...(dimension times), Types...>
using tuple_data_t = scalfmm::meta::pack_expand_tuple<scalfmm::meta::pack<Dim, ValueType>, Types...>;
/// Expand Types list
using types_tuple_t = scalfmm::meta::pack_expand_tuple<Types...>;
/// Expand std::enable_if if possible
template<bool value>
using sfinae_check = typename std::enable_if<value, bool>::type;
/**
* \brief Check parameter pack size vs. attribute + dimension count at
* compile time
*
* \return true if the parameter pack is shorter than the attribute list
* size + the dimension
*/
template<typename... Ts>
constexpr static bool correct_attribute_list_size()
{
return std::tuple_size<tuple_data_t>::value >= sizeof...(Ts) + dimension;
}
/// Space dimensions
constexpr static std::size_t dimension = Dim;
/// Size of #tuple_data_t tuple
constexpr static std::size_t NbAttributes = std::tuple_size<tuple_data_t>::value - dimension;
/// Floating point type
using value_type = ValueType;
/// Position type, required by the FVariadicParticleContainer
using position_t = point<value_type, dimension>;
/// Default constructor
particle() = default;
/// Default copy constructor
particle(const particle&) = default;
/// Default copy operator
particle& operator=(const particle&) = default;
/// Default move constructor
particle(particle&&) noexcept = default;
/// Default move operator
particle& operator=(particle&&) noexcept = default;
/**
* \brief Constructor from position and types
*
* \tparam Ts Attributes parameter pack; if Ts is too long, this will not
* compile.
*
* \param pos Particle position
* \param ts Attributes
*
* \warning There may be less attributes than defined by the particle, in
* that case the missing ones are zero constructed.
*/
template<typename... Ts, sfinae_check<correct_attribute_list_size<Ts...>()> = 0>
particle(const position_t& pos, Ts&&... ts)
: particle(inria::make_index_sequence<dimension>(),
inria::make_index_sequence<std::tuple_size<tuple_data_t>::value - sizeof...(ts) - dimension>(),
pos, std::forward<Ts>(ts)...)
{
}
/// Constructor from tuple equivalent to #tuple_data_t
template<typename... Ts>
particle(const std::tuple<Ts...>& ts)
: tuple_data_t(ts)
{
}
/**
* \brief Position getter
*
* The position is stored in the #_data tuple, to extract it we need to
* recreate a position_t object. This is done by the position_impl() method.
*
* \return A new position_t object
*/
[[nodiscard]] position_t position() const { return position_impl(inria::make_index_sequence<dimension>()); }
/**
* \brief Position setter
*
* \parma pos The new position
*/
void set_position(const position_t& pos)
{
return set_position_impl(pos, inria::make_index_sequence<dimension>());
}
/**
* \brief Get a reference to the Ith attribute
*
* \tparam I Index of the attribute to get
*/
template<std::size_t I>
[[nodiscard]] auto attribute() -> decltype(std::get<dimension + I>(*this))
{
return std::get<dimension + I>(*this);
}
/**
* \brief Get a const reference to the Ith attribute
*
* \tparam I Index of the attribute to get
*/
template<std::size_t I>
[[nodiscard]] auto attribute() const -> decltype(std::get<dimension + I>(*this))
{
return std::get<dimension + I>(*this);
}
/**
* \brief Get a tuple filled with copies of the attributes
*/
[[nodiscard]] types_tuple_t attributes() const
{
return attributes_impl(inria::make_index_sequence<std::tuple_size<types_tuple_t>::value>());
}
/**
* \brief Convert particle to a tuple
*/
[[nodiscard]] tuple_data_t& as_tuple() { return *this; }
/**
* \brief Convert particle to a tuple
*/
[[nodiscard]] const tuple_data_t& as_tuple() const { return *this; }
~particle() = default;
private:
/**
* \brief Contructor implementation
*
* Builds the particle, zero constructing missing arguuments.
*/
template<typename... Ts, std::size_t... Is, std::size_t... Js>
particle(inria::index_sequence<Is...>, inria::index_sequence<Js...>, const position_t& pos, Ts&&... ts)
: tuple_data_t(pos[Is]..., std::forward<Ts>(ts)...,
typename std::tuple_element<dimension + Js + sizeof...(ts), tuple_data_t>::type(0)...)
{
// static_assert(sizeof...(Ts) == NbAttributes, "Parameter count is incorrect");
}
/**
* \brief #position method implementation
*
* \tparam Is Index sequence of the position elements in the tuple, deduced
* using arguments
*/
template<std::size_t... Is>
position_t position_impl(inria::index_sequence<Is...>) const
{
return position_t(std::get<Is>(this->as_tuple())...);
}
/**
* \brief #setPosition method implementation
*
* \tparam Is Index sequence of the position elements in the tuple, deduced
* using arguments
*
* \param pos new position
*/
template<std::size_t... Is>
void set_position_impl(const position_t& pos, inria::index_sequence<Is...>)
{
auto l = {std::get<Is>(this->as_tuple()) = pos[Is]...};
(void)l;
}
/**
* \brief #attributes method implementation
*
* \tparam Is Index sequence of the attributes in the tuple, deduced using
* arguments
*
* \param pos new position
*/
template<std::size_t... Is>
types_tuple_t attributes_impl(inria::index_sequence<Is...>) const
{
return types_tuple_t(std::get<Is + dimension>(*this)...);
}
};
} // namespace scalfmm::container
#endif // SCALFMM_CONTAINER_PARTICLE_HPP
// --------------------------------
// See LICENCE file at project root
// File : particle_container.hpp
// --------------------------------
#ifndef SCALFMM_CONTAINER_PARTICLE_CONTAINER_HPP
#define SCALFMM_CONTAINER_PARTICLE_CONTAINER_HPP
#include <vector>
#include <tuple>
#include <xsimd/config/xsimd_align.hpp>
#include <scalfmm/memory/aligned_allocator.hpp>
#include <scalfmm/container/variadic_container.hpp>
#include <scalfmm/meta/traits.hpp>
namespace scalfmm::container
{
template<typename Particle>
class particle_container
: public variadic_container
< memory::aligned_allocator< XSIMD_DEFAULT_ALIGNMENT
, typename Particle::tuple_data_t
>
, typename Particle::tuple_data_t
>
{
public:
// base type : concatenating the particle tuple with the indexes needed
// in order to allocate the vector
using value_type = typename Particle::tuple_data_t;
using allocator_type = typename memory::aligned_allocator< XSIMD_DEFAULT_ALIGNMENT, value_type>;
using base_type = variadic_container< allocator_type, value_type>;
using size_type = typename base_type::size_type;
using difference_type = typename base_type::difference_type;
using reference = typename base_type::reference_tuple;
using const_reference = typename base_type::const_reference_tuple;
using pointer = typename base_type::pointer_tuple;
using const_pointer = typename base_type::const_pointer_tuple;
using iterator = typename base_type::iterator;
using const_iterator = typename base_type::const_iterator;
using particle_type = Particle;
//Forwardind constructors
using base_type::base_type;
};
}
#endif // SCALFMM_CONTAINER_PARTICLE_CONTAINER_HPP
// See LICENCE file at project root
//
#ifndef SCALFMM_CONTAINER_POINT_HPP
#define SCALFMM_CONTAINER_POINT_HPP
#include <array>
#include <cmath>
#include <initializer_list>
#include <iterator>
#include <ostream>
#include <type_traits>
#include <scalfmm/meta/const_functions.hpp>
#include <scalfmm/meta/traits.hpp>
namespace scalfmm::container
{
template<typename Arithmetic, std::size_t Dim = 3, typename Enable = void><