diff --git a/CMakeLists.txt b/CMakeLists.txt index a180f836d..ddd78cebc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,7 @@ # You should have received a copy of the GNU General Public License along with Swiftest. # If not, see: https://www.gnu.org/licenses. -# CMake project file for SWIFTEST - +# CMake project file for Swiftest ################################################## # Define the project and the depencies that it has ################################################## @@ -16,56 +15,50 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.20.1) # Get version stored in text file FILE(READ "version.txt" VERSION) -PROJECT(swiftest VERSION ${VERSION} LANGUAGES Fortran) +PROJECT(swiftest VERSION ${VERSION} LANGUAGES C Fortran) + +# The following section is modified from Numpy f2py documentation +IF(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) + MESSAGE(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n") +ENDIF() + +# Ensure scikit-build modules +IF (NOT SKBUILD) + FIND_PACKAGE(Python3 COMPONENTS Interpreter Development REQUIRED) + EXECUTE_PROCESS( + COMMAND "${Python3_EXECUTABLE}" + -c "import os, skbuild; print(os.path.dirname(skbuild.__file__))" + OUTPUT_VARIABLE SKBLD_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + LIST(APPEND CMAKE_MODULE_PATH "${SKBLD_DIR}/resources/cmake") + MESSAGE(STATUS "Looking in ${SKBLD_DIR}/resources/cmake for CMake modules") +ENDIF() + +# scikit-build style includes +FIND_PACKAGE(Cython REQUIRED) +SET(PYTHON_EXTENSION_MODULE_SUFFIX "${Python3_SOABI}" CACHE STRING "Suffix for python extension modules") + +# Communicate version number and other CMake build variables to the source code +SET(SETUP_PY_IN "${PROJECT_SOURCE_DIR}/setup.py.in") +SET(SETUP_PY_OUT "${PROJECT_SOURCE_DIR}/setup.py") +CONFIGURE_FILE(${SETUP_PY_IN} ${SETUP_PY_OUT}) INCLUDE(CTest) -# Add our local modlues to the module path -SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/") - -# Uncomment if it is required that Fortran 90 is supported -IF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) - MESSAGE(FATAL_ERROR "Fortran compiler does not support F90") -ENDIF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) - - -IF (CMAKE_Fortran_COMPILER_ID MATCHES "^Intel") - SET(COMPILER_OPTIONS "Intel" CACHE STRING "Compiler identified as Intel") -ELSEIF (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - SET(COMPILER_OPTIONS "GNU" CACHE STRING "Compiler identified as gfortran") -ELSE () - MESSAGE(FATAL_ERROR "Compiler not recognized!") -ENDIF () +# Add our local modules to the module path +LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/") -# Set some options the user may choose -OPTION(USE_COARRAY "Use Coarray Fortran for parallelization of test particles" OFF) -OPTION(USE_OPENMP "Use OpenMP for parallelization" ON) -OPTION(USE_SIMD "Use SIMD vectorization" ON) -OPTION(BUILD_SHARED_LIBS "Build using shared libraries" ON) - -INCLUDE(${CMAKE_MODULE_PATH}/SetParallelizationLibrary.cmake) -INCLUDE(${CMAKE_MODULE_PATH}/SetUpNetCDF.cmake) -IF (COMPILER_OPTIONS STREQUAL "Intel") - INCLUDE(${CMAKE_MODULE_PATH}/SetMKL.cmake) -ENDIF () - -# This INCLUDE statement executes code that sets the compile flags for DEBUG, -# RELEASE, PROFILING, and TESTING. -INCLUDE(${CMAKE_MODULE_PATH}/SetFortranFlags.cmake) - -INCLUDE_DIRECTORIES($ENV{NETCDF_FORTRAN_HOME}/include;$ENV{NETCDF_HOME}/include) ############################################################ # Define the actual files and folders that make up the build ############################################################ - # Define some directories SET(SRC ${CMAKE_SOURCE_DIR}/src) SET(LIB ${CMAKE_SOURCE_DIR}/lib) SET(BIN ${CMAKE_SOURCE_DIR}/bin) SET(MOD ${CMAKE_SOURCE_DIR}/include) -#SET(TEST ${CMAKE_SOURCE_DIR}/test) -SET(PY ${CMAKE_SOURCE_DIR}/python) +#SET(TEST ${CMAKE_SOURCE_DIR}/tests) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB}) @@ -76,7 +69,6 @@ SET(CMAKE_Fortran_MODULE_DIRECTORY ${MOD}) # The source for the SWIFTEST binary and have it placed in the bin folder ADD_SUBDIRECTORY(${SRC} ${BIN}) -ADD_SUBDIRECTORY(${PY}) # # Set up test directory # ENABLE_TESTING() diff --git a/Dockerfile b/Dockerfile index 3114bb0e7..4f9be765b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,10 +16,11 @@ FROM intel/oneapi-hpckit:2023.1.0-devel-ubuntu20.04 as build_deps ENV INSTALL_DIR="/usr/local" -ENV CC="${ONEAPI_ROOT}/compiler/latest/linux/bin/icx" -ENV FC="${ONEAPI_ROOT}/compiler/latest/linux/bin/ifx" -ENV CXX="${ONEAPI_ROOT}/compiler/latest/linux/bin/icpx" +ENV FC="${ONEAPI_ROOT}/mpi/latest/bin/mpiifort" +ENV CC="${ONEAPI_ROOT}/mpi/latest/bin/mpicc -cc=icx" +ENV CXX="${ONEAPI_ROOT}/mpi/latest/bin/mpicc -cc=icpx" ENV F77="${FC}" +ENV CFLAGS="-fPIC" # Get the HDF5, NetCDF-C, and NetCDF-Fortran libraries RUN wget -qO- https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.14/hdf5-1.14.1/src/hdf5-1.14.1-2.tar.gz | tar xvz && \ @@ -65,7 +66,6 @@ ENV HDF5_INCLUDE_DIR="${HDF5_ROOT}/include" ENV HDF5_PLUGIN_PATH="${HDF5_LIBDIR}/plugin" # NetCDF-Fortran library -ENV CFLAGS="-fPIC" ENV FCFLAGS="${CFLAGS} -standard-semantics" ENV FFLAGS=${CFLAGS} ENV CPPFLAGS="-I${INSTALL_DIR}/include" @@ -77,7 +77,8 @@ RUN cd netcdf-fortran-4.6.1 && \ FROM intel/oneapi-hpckit:2023.1.0-devel-ubuntu20.04 as build_driver SHELL ["/bin/bash", "-c"] -COPY --from=build_deps /usr/local/. /usr/local/ +ENV INSTALL_DIR="/usr/local" +COPY --from=build_deps ${INSTALL_DIR}/. ${INSTALL_DIR}/ ENV PATH /root/miniconda3/bin:$PATH RUN wget https://repo.anaconda.com/miniconda/Miniconda3-py311_23.5.2-0-Linux-x86_64.sh && \ @@ -89,12 +90,6 @@ RUN wget https://repo.anaconda.com/miniconda/Miniconda3-py311_23.5.2-0-Linux-x86 conda install -c conda-forge scikit-build -y&& \ conda install -c anaconda cython -y -ENV INSTALL_DIR="/usr/local" -ENV CC="${ONEAPI_ROOT}/compiler/latest/linux/bin/icx" -ENV FC="${ONEAPI_ROOT}/compiler/latest/linux/bin/ifx" -ENV CXX="${ONEAPI_ROOT}/compiler/latest/linux/bin/icpx" -ENV F77="${FC}" - # The MACHINE_CODE_VALUE argument is a string that is used when compiling the swiftest_driver. It is appended to the "-x" compiler # option: (-x${MACHINE_CODE_VALUE}). The default value is set to "sse2" which allows for certain SIMD instructions to be used while # remaining # compatible with a wide range of CPUs. To get the highest performance, you can pass "host" as an argument, but the @@ -119,7 +114,7 @@ ENV FC="${ONEAPI_ROOT}/mpi/latest/bin/mpiifort" ENV CC="${ONEAPI_ROOT}/mpi/latest/bin/mpicc -cc=icx" ENV CXX="${ONEAPI_ROOT}/mpi/latest/bin/mpicc -cc=icpx" ENV FFLAGS="-fPIC -standard-semantics" -ENV LDFLAGS="-L/usr/local/lib" +ENV LDFLAGS="-L${INSTALL_DIR}/lib" ENV LIBS="-lhdf5_hl -lhdf5 -lz" COPY ./cmake/ /swiftest/cmake/ @@ -138,8 +133,8 @@ RUN cd swiftest && \ cmake --build build && \ cmake --install build -RUN cd swiftest/python && \ - python setup.py build_ext --inplace +# RUN cd swiftest/python && \ +# python setup.py build_ext --inplace # This build target creates a container that executes just the driver program @@ -159,19 +154,20 @@ COPY --from=build_driver /usr/local/lib/libswiftest.a / FROM scratch as export_module COPY --from=build_driver /swiftest/include/ /swiftest/ - # This build target creates a container with a conda environment with all dependencies needed to run the Python front end and # analysis tools FROM continuumio/miniconda3 as python SHELL ["/bin/bash", "--login", "-c"] +ENV INSTALL_DIR="/usr/local" +ENV CONDA_DIR="/opt/conda" ENV SHELL="/bin/bash" -ENV PATH="/opt/conda/bin:${PATH}" -ENV LD_LIBRARY_PATH="/usr/local/lib" +ENV PATH="${CONDA_DIR}/bin:${PATH}" +ENV LD_LIBRARY_PATH="${INSTALL_DIR}/lib" -COPY --from=build_driver /usr/local/bin/swiftest_driver /opt/conda/bin/swiftest_driver -COPY --from=build_driver /usr/local/lib/libswiftest.a /opt/conda/lib/libswiftest.a -COPY --from=build_driver /swiftest/include/ /opt/conda/include/swiftest/ -COPY ./python/. /opt/conda/pkgs/swiftest/ +COPY --from=build_driver ${INSTALL_DIR}/bin/swiftest_driver ${CONDA_DIR}/bin/swiftest_driver +COPY --from=build_driver ${INSTALL_DIR}/lib/libswiftest.a ${CONDA_DIR}/conda/lib/libswiftest.a +COPY --from=build_driver /swiftest/include/ ${CONDA_DIR}/include/swiftest/ +COPY ./python/. ${CONDA_DIR}/pkgs/swiftest/ COPY environment.yml . RUN conda update --all -y && \ diff --git a/cmake/Modules/FindCoarray_Fortran.cmake b/cmake/Modules/FindCoarray_Fortran.cmake index 93f73f466..01324b152 100644 --- a/cmake/Modules/FindCoarray_Fortran.cmake +++ b/cmake/Modules/FindCoarray_Fortran.cmake @@ -23,7 +23,7 @@ #============================================================================= -INCLUDE (${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) +INCLUDE (FindPackageHandleStandardArgs) STRING(TOUPPER "${CMAKE_BUILD_TYPE}" BT) IF(BT STREQUAL "DEBUG") diff --git a/cmake/Modules/FindOpenMP_Fortran.cmake b/cmake/Modules/FindOpenMP_Fortran.cmake index d3a0bc29b..012b7ac75 100644 --- a/cmake/Modules/FindOpenMP_Fortran.cmake +++ b/cmake/Modules/FindOpenMP_Fortran.cmake @@ -23,7 +23,7 @@ #============================================================================= -INCLUDE (${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) +INCLUDE (FindPackageHandleStandardArgs) IF (COMPILER_OPTIONS STREQUAL "Intel") IF (USE_SIMD) diff --git a/cmake/Modules/SetFortranFlags.cmake b/cmake/Modules/SetFortranFlags.cmake index c4c18cced..a4df6a012 100644 --- a/cmake/Modules/SetFortranFlags.cmake +++ b/cmake/Modules/SetFortranFlags.cmake @@ -14,7 +14,7 @@ #################################################################### # Make sure that the default build type is RELEASE if not specified. #################################################################### -INCLUDE(${CMAKE_MODULE_PATH}/SetCompileFlag.cmake) +INCLUDE(SetCompileFlag) # Make sure the build type is uppercase STRING(TOUPPER "${CMAKE_BUILD_TYPE}" BT) diff --git a/python/.gitignore b/python/.gitignore deleted file mode 100644 index e8e3a7829..000000000 --- a/python/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!setup.py.in diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt deleted file mode 100644 index 9a6026279..000000000 --- a/python/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -FIND_PACKAGE(Python COMPONENTS Interpreter REQUIRED) -IF(NOT ${PYTHON}) - find_program(PYTHON "python") -ENDIF() - -# Communicate version number and other CMake build variables to the source code -SET(SETUP_PY_IN "${PY}/setup.py.in") -SET(SETUP_PY_OUT "${PY}/setup.py") - -CONFIGURE_FILE(${SETUP_PY_IN} ${SETUP_PY_OUT}) - -# ADD_LIBRARY(pybindings MODULE hello/_hello.cxx) -# python_extension_module(_hello) -# install(TARGETS _hello LIBRARY DESTINATION hello) \ No newline at end of file diff --git a/python/setup.py b/python/setup.py deleted file mode 100644 index bb22ad5ce..000000000 --- a/python/setup.py +++ /dev/null @@ -1,42 +0,0 @@ -""" - Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh - This file is part of Swiftest. - Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY - without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with Swiftest. - If not, see: https://www.gnu.org/licenses. -""" - -#from skbuild import setup -from setuptools import setup -from setuptools import find_packages, Extension -from Cython.Build import cythonize -import os - -# Build the pybindings extension that allows us to run the Fortran driver as a Python module. -root_dir = 'pybindings' -include_dirs = "/Users/daminton/git/swiftest/apple_install/usr/local/include;/Users/daminton/git/swiftest/apple_install/usr/local/include" -include_dirs = include_dirs.split() -include_dirs.append(root_dir) -link_flags = " -static-libgfortran -static-libgcc -static-libstdc++ -L/Users/daminton/git/swiftest/lib -lswiftest /Users/daminton/git/swiftest/apple_install/usr/local/lib/libnetcdff.a /Users/daminton/git/swiftest/apple_install/usr/local/lib/libnetcdf.a -L/Users/daminton/git/swiftest/apple_install/usr/local/lib -lhdf5_hl -lhdf5 -lm -lz -lbz2 -lxml2 -lcurl" -link_flags = link_flags.split() - -pybindings_extension = [Extension('swiftest.bindings', - [os.path.join(root_dir,'pybindings.pyx')], - extra_compile_args=['-fPIC', '-O3'], - extra_link_args=link_flags, - include_dirs=include_dirs, - )] - -setup(name='swiftest', - version='2023.08.00', - author='David A. Minton', - author_email='daminton@purdue.edu', - url='https://github.itap.purdue.edu/MintonGroup/swiftest', - python_requires=">3.8", - license="GPLv3", - ext_modules = cythonize(pybindings_extension), - packages=find_packages()) diff --git a/python/setup.py.in b/setup.py similarity index 90% rename from python/setup.py.in rename to setup.py index e59a074e2..108cee6ee 100644 --- a/python/setup.py.in +++ b/setup.py @@ -10,18 +10,17 @@ If not, see: https://www.gnu.org/licenses. """ -#from skbuild import setup -from setuptools import setup +from skbuild import setup from setuptools import find_packages, Extension from Cython.Build import cythonize import os # Build the pybindings extension that allows us to run the Fortran driver as a Python module. root_dir = 'pybindings' -include_dirs = "${SWIFTEST_INCLUDE_DIR}" +include_dirs = "" include_dirs = include_dirs.split() include_dirs.append(root_dir) -link_flags = "${SWIFTEST_LINK_FLAGS}" +link_flags = "" link_flags = link_flags.split() pybindings_extension = [Extension('swiftest.bindings', @@ -32,7 +31,7 @@ )] setup(name='swiftest', - version='${CMAKE_PROJECT_VERSION}', + version='2023.8.0', author='David A. Minton', author_email='daminton@purdue.edu', url='https://github.itap.purdue.edu/MintonGroup/swiftest', diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b10437cba..d42627f7a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,37 @@ set(GLOBAL_MODULE_IN ${SRC}/globals/globals_module.f90.in) set(GLOBAL_MODULE_OUT ${SRC}/globals/globals_module.f90) CONFIGURE_FILE(${GLOBAL_MODULE_IN} ${GLOBAL_MODULE_OUT}) +IF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) + MESSAGE(FATAL_ERROR "Fortran compiler does not support F90") +ENDIF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) + +IF (CMAKE_Fortran_COMPILER_ID MATCHES "^Intel") + SET(COMPILER_OPTIONS "Intel" CACHE STRING "Compiler identified as Intel") +ELSEIF (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + SET(COMPILER_OPTIONS "GNU" CACHE STRING "Compiler identified as gfortran") +ELSE () + MESSAGE(FATAL_ERROR "Compiler not recognized!") +ENDIF () + +# Set some options the user may choose +OPTION(USE_COARRAY "Use Coarray Fortran for parallelization of test particles" OFF) +OPTION(USE_OPENMP "Use OpenMP for parallelization" ON) +OPTION(USE_SIMD "Use SIMD vectorization" ON) +OPTION(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +INCLUDE(SetParallelizationLibrary) +INCLUDE(SetUpNetCDF) +IF (COMPILER_OPTIONS STREQUAL "Intel") + INCLUDE(SetMKL) +ENDIF () + +# This INCLUDE statement executes code that sets the compile flags for DEBUG, +# RELEASE, PROFILING, and TESTING. +INCLUDE(SetFortranFlags) + +INCLUDE_DIRECTORIES($ENV{NETCDF_FORTRAN_HOME}/include;$ENV{NETCDF_HOME}/include) + + # Add the source files SET(STRICT_MATH_FILES ${SRC}/collision/collision_generate.f90 diff --git a/src/globals/globals_module.f90 b/src/globals/globals_module.f90 index a708b080d..309a5d14e 100644 --- a/src/globals/globals_module.f90 +++ b/src/globals/globals_module.f90 @@ -44,7 +44,7 @@ module globals integer(I4B), parameter :: UPPERCASE_OFFSET = iachar('A') - iachar('a') !! ASCII character set parameter for lower to upper !! conversion - offset between upper and lower - character(*), parameter :: VERSION = "2023.08.00" !! Swiftest version + character(*), parameter :: VERSION = "2023.8.0" !! Swiftest version !> Symbolic name for integrator types character(*), parameter :: UNKNOWN_INTEGRATOR = "UKNOWN INTEGRATOR" diff --git a/python/swiftest/__init__.py b/swiftest/__init__.py similarity index 100% rename from python/swiftest/__init__.py rename to swiftest/__init__.py diff --git a/python/swiftest/constants.py b/swiftest/constants.py similarity index 100% rename from python/swiftest/constants.py rename to swiftest/constants.py diff --git a/python/swiftest/init_cond.py b/swiftest/init_cond.py similarity index 100% rename from python/swiftest/init_cond.py rename to swiftest/init_cond.py diff --git a/python/swiftest/io.py b/swiftest/io.py similarity index 100% rename from python/swiftest/io.py rename to swiftest/io.py diff --git a/python/swiftest/simulation_class.py b/swiftest/simulation_class.py similarity index 100% rename from python/swiftest/simulation_class.py rename to swiftest/simulation_class.py diff --git a/python/swiftest/tool.py b/swiftest/tool.py similarity index 100% rename from python/swiftest/tool.py rename to swiftest/tool.py diff --git a/python/swiftest/visualize.py b/swiftest/visualize.py similarity index 100% rename from python/swiftest/visualize.py rename to swiftest/visualize.py diff --git a/test/CMakeLists.txt b/tests/CMakeLists.txt similarity index 100% rename from test/CMakeLists.txt rename to tests/CMakeLists.txt diff --git a/python/tests/test_suite.py b/tests/test_suite.py similarity index 100% rename from python/tests/test_suite.py rename to tests/test_suite.py