From 157e38add62b53827709e0687a13447f94e6c5b9 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Fri, 19 Aug 2022 18:35:32 -0700 Subject: [PATCH] CI: Windows (#205) * CI: Windows Add windows testing to continuous integration. * Windows: Fix Python Tests * Use AMReX PR 2918 * Install Python Deps * Wheel: Separate Directory The `pip_install` target did not yet work on Windows, because it has no universal wildcard `*` support for our pip install logic. Fix this by creating the wheel in a sub-directory and installing it by "finding all wheels for `pywarpx` in a given prefix". - Avoid wildcards by using a separate directory. - Avoid downloading deps during `wheel` build again. * Fix: MANIFEST.in * `setup.py`: Support IMPACTX_CMAKE_... Support `IMPACTX_CMAKE_...` environment variables for any CMake option. * CTest: --build-config * Update Docs & CI * BUILD_SHARED_LIBS=OFF * MSVC: RelWithDebInfo See if this avoids timeouts in app runs. * Win: Skip Python Running for Now Skip for now: - pytest - analysis - plot - python tests --- .github/workflows/windows.yml | 102 +++++++++++++++++++++++++++ CMakeLists.txt | 6 +- MANIFEST.in | 5 +- README.md | 21 +++--- cmake/dependencies/ABLASTR.cmake | 2 +- docs/source/developers/testing.rst | 4 +- docs/source/install/cmake.rst | 3 +- docs/source/install/dependencies.rst | 23 +++--- examples/CMakeLists.txt | 2 +- setup.py | 17 +++++ 10 files changed, 148 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 000000000..eae5104a1 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,102 @@ +name: 🪟 Windows + +on: [push, pull_request] + +concurrency: + group: ${{ github.ref }}-${{ github.head_ref }}-windows + cancel-in-progress: true + +jobs: + build_win_msvc: + name: MSVC C++17 w/o MPI + runs-on: windows-latest + if: github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + name: Install Python + with: + python-version: '3.x' + - name: CCache Cache + uses: actions/cache@v2 + # - once stored under a key, they become immutable (even if local cache path content changes) + # - for a refresh the key has to change, e.g., hash of a tracked file in the key + with: + path: | + ~/.ccache + ~/.cache/ccache + key: ccache-windows-winmsvc-${{ hashFiles('.github/workflows/windows.yml') }}-${{ hashFiles('cmake/dependencies/ABLASTR.cmake') }} + restore-keys: | + ccache-windows-winmsvc-${{ hashFiles('.github/workflows/windows.yml') }}- + ccache-windows-winmsvc- + - name: Build & Install + run: | + python3 -m pip install -U pip setuptools wheel pytest + python3 -m pip install -r requirements.txt + python3 -m pip install -r examples/requirements.txt + + cmake -S . -B build ` + -DBUILD_SHARED_LIBS=OFF ` + -DCMAKE_BUILD_TYPE=RelWithDebInfo ` + -DCMAKE_VERBOSE_MAKEFILE=ON ` + -DImpactX_COMPUTE=NOACC ` + -DImpactX_MPI=OFF ` + -DImpactX_PYTHON=ON + if(!$?) { Exit $LASTEXITCODE } + cmake --build build --config RelWithDebInfo --parallel 2 + if(!$?) { Exit $LASTEXITCODE } + cmake --build build --config RelWithDebInfo --target pip_install + if(!$?) { Exit $LASTEXITCODE } + + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure -E "(AMReX|py|pytest|analysis|plot)" + if(!$?) { Exit $LASTEXITCODE } + + build_win_clang: + name: Clang C++17 w/ OMP w/o MPI + runs-on: windows-2019 + if: github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + name: Install Python + with: + python-version: '3.x' + - name: CCache Cache + uses: actions/cache@v2 + # - once stored under a key, they become immutable (even if local cache path content changes) + # - for a refresh the key has to change, e.g., hash of a tracked file in the key + with: + path: | + ~/.ccache + ~/.cache/ccache + key: ccache-windows-winclang-${{ hashFiles('.github/workflows/windows.yml') }}-${{ hashFiles('cmake/dependencies/ABLASTR.cmake') }} + restore-keys: | + ccache-windows-winclang-${{ hashFiles('.github/workflows/windows.yml') }}- + ccache-windows-winclang- + - uses: seanmiddleditch/gha-setup-ninja@master + - name: Build & Install + shell: cmd + run: | + python3 -m pip install -U pip setuptools wheel pytest + python3 -m pip install -r requirements.txt + python3 -m pip install -r examples/requirements.txt + + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\vc\Auxiliary\build\vcvarsall.bat" x64 + cmake -S . -B build ^ + -G "Ninja" ^ + -DCMAKE_C_COMPILER=clang-cl ^ + -DCMAKE_CXX_COMPILER=clang-cl ^ + -DBUILD_SHARED_LIBS=OFF ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_VERBOSE_MAKEFILE=ON ^ + -DImpactX_COMPUTE=OMP ^ + -DImpactX_MPI=OFF ^ + -DImpactX_PYTHON=ON + if errorlevel 1 exit 1 + cmake --build build --config Release --parallel 2 + if errorlevel 1 exit 1 + cmake --build build --config Release --target pip_install + if errorlevel 1 exit 1 + + ctest --test-dir build --build-config Release --output-on-failure -E "(AMReX|py|pytest|analysis|plot)" + if errorlevel 1 exit 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 093e0a856..c063f15b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -374,10 +374,10 @@ if(ImpactX_PYTHON) # build the wheel by re-using the lib library we build add_custom_target(${ImpactX_CUSTOM_TARGET_PREFIX}pip_wheel - ${CMAKE_COMMAND} -E rm -f "impactx*.whl" + ${CMAKE_COMMAND} -E rm -f -r impactx-whl COMMAND ${CMAKE_COMMAND} -E env PYIMPACTX_LIBDIR=$ - ${Python_EXECUTABLE} -m pip wheel -v --no-build-isolation ${ImpactX_SOURCE_DIR} + ${Python_EXECUTABLE} -m pip wheel -v --no-build-isolation --no-deps --wheel-dir=impactx-whl ${ImpactX_SOURCE_DIR} WORKING_DIRECTORY ${ImpactX_BINARY_DIR} DEPENDS @@ -408,7 +408,7 @@ if(ImpactX_PYTHON) # because otherwise pip would also force reinstall all dependencies. add_custom_target(${ImpactX_CUSTOM_TARGET_PREFIX}pip_install ${CMAKE_COMMAND} -E env IMPACTX_MPI=${ImpactX_MPI} - ${Python_EXECUTABLE} -m pip install --force-reinstall --no-deps ${PYINSTALLOPTIONS} "impactx*.whl" + ${Python_EXECUTABLE} -m pip install --force-reinstall --no-index --no-deps ${PYINSTALLOPTIONS} --find-links=impactx-whl impactx WORKING_DIRECTORY ${ImpactX_BINARY_DIR} DEPENDS diff --git a/MANIFEST.in b/MANIFEST.in index 8ea37b3b7..d3738e8dd 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,7 @@ -include README.md LICENSE +include README.md LICENSE.txt include CODE_OF_CONDUCT.rst CONTRIBUTING.rst include pyproject.toml -include requirements.txt +include requirements.txt requirements_mpi.txt global-include CMakeLists.txt *.cmake *.in @@ -9,7 +9,6 @@ recursive-include cmake * recursive-include docs * recursive-include etc * recursive-include examples * -recursive-include include * recursive-include src * recursive-include tests * diff --git a/README.md b/README.md index a9367a2f8..f2f0196e6 100644 --- a/README.md +++ b/README.md @@ -179,27 +179,27 @@ spack add fftw spack add hdf5 # for openPMD spack add mpi spack add pkgconfig # for fftw +spack add python +spack add py-pip +spack add py-setuptools +spack add py-wheel # OpenMP support on macOS [[ $OSTYPE == 'darwin'* ]] && spack add llvm-openmp -# optional: -# spack add cuda -# spack add python -# spack add py-pip -# spack add py-pandas -# spack add py-numpy -# spack add py-scipy +# optional: Linux only +#spack add cuda spack install +python3 -m pip install matplotlib numpy openpmd-api pandas pytest scipy ``` -(in new terminals, re-activate the environment with `spack env activate impactx-dev` again) +In new terminals, re-activate the environment with `spack env activate impactx-dev` again. ### Conda (Linux/macOS/Windows) ```bash -conda create -n impactx-dev -c conda-forge adios2 ccache cmake compilers git hdf5 fftw matplotlib ninja numpy pandas scipy +conda create -n impactx-dev -c conda-forge adios2 ccache cmake compilers git hdf5 fftw matplotlib ninja numpy pandas pytest scipy conda activate impactx-dev # compile with -DImpactX_MPI=OFF @@ -294,8 +294,7 @@ Examples: In order to run our tests, you need to have a few Python packages installed: ```console -python3 -m pip install -U pip setuptools wheel -python3 -m pip install -r requirements.txt +python3 -m pip install -U pip setuptools wheel pytest python3 -m pip install -r examples/requirements.txt ``` diff --git a/cmake/dependencies/ABLASTR.cmake b/cmake/dependencies/ABLASTR.cmake index ad6776def..5a80c425f 100644 --- a/cmake/dependencies/ABLASTR.cmake +++ b/cmake/dependencies/ABLASTR.cmake @@ -142,7 +142,7 @@ set(ImpactX_ablastr_branch "22.08" set(ImpactX_amrex_repo "https://github.com/AMReX-Codes/amrex.git" CACHE STRING "Repository URI to pull and build AMReX from if(ImpactX_amrex_internal)") -set(ImpactX_amrex_branch "1bda173b489024d5f4ec79627f3f612c350e521f" +set(ImpactX_amrex_branch "bd5f6a9f6a1a3a66c51eefd7950432d3bf3319a1" CACHE STRING "Repository branch for ImpactX_amrex_repo if(ImpactX_amrex_internal)") diff --git a/docs/source/developers/testing.rst b/docs/source/developers/testing.rst index 8d2a94faa..9ea7bbf91 100644 --- a/docs/source/developers/testing.rst +++ b/docs/source/developers/testing.rst @@ -12,8 +12,8 @@ In order to run our tests, you need to have a few :ref:`Python packages installe .. code-block:: sh - python3 -m pip install -U pip setuptools wheel - python3 -m pip install -r requirements.txt + python3 -m pip install -U pip setuptools wheel pytest + python3 -m pip install -r examples/requirements.txt Run --- diff --git a/docs/source/install/cmake.rst b/docs/source/install/cmake.rst index d2bd05f3b..effe4e28a 100644 --- a/docs/source/install/cmake.rst +++ b/docs/source/install/cmake.rst @@ -76,7 +76,8 @@ Compile including Python Bindings .. code-block:: bash - python3 -m pip install -U pip setuptools wheel + python3 -m pip install -U pip setuptools wheel pytest + python3 -m pip install -r examples/requirements.txt For PICMI Python bindings, add a configure option and call our ``pip_install`` *CMake target*: diff --git a/docs/source/install/dependencies.rst b/docs/source/install/dependencies.rst index 8b95c170c..438aeb09f 100644 --- a/docs/source/install/dependencies.rst +++ b/docs/source/install/dependencies.rst @@ -44,28 +44,21 @@ Spack (macOS/Linux) spack add hdf5 # for openPMD spack add mpi spack add pkgconfig # for fftw + spack add python + spack add py-pip + spack add py-setuptools + spack add py-wheel # OpenMP support on macOS [[ $OSTYPE == 'darwin'* ]] && spack add llvm-openmp - # optional: - # spack add cuda - # spack add python - # spack add py-pip - # spack add py-pip - # spack add py-pandas - # spack add py-numpy - # spack add py-scipy + # optional: Linux only + #spack add cuda spack install + python3 -m pip install matplotlib numpy openpmd-api pandas pytest scipy -(in new terminals, re-activate the environment with ``spack env activate impactx-dev`` again) - -If you also want to run runtime tests and added Python (``spack add python`` and ``spack add py-pip``) above, install also these additional Python packages in the active Spack environment: - -.. code-block:: bash - - python3 -m pip install matplotlib yt scipy numpy openpmd-api +In new terminals, re-activate the environment with ``spack env activate impactx-dev`` again. Brew (macOS/Linux) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 53d9d4342..eaefe62cd 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -22,7 +22,7 @@ function(impactx_test_set_pythonpath test_name) if(WIN32) string(REPLACE ";" "\\;" WIN_PYTHONPATH "$ENV{PYTHONPATH}") string(REGEX REPLACE "/" "\\\\" WIN_PYTHON_OUTPUT_DIRECTORY ${CMAKE_PYTHON_OUTPUT_DIRECTORY}) - set_tests_properties(TEST ${test_name} + set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "PYTHONPATH=${WIN_PYTHON_OUTPUT_DIRECTORY}\;${WIN_PYTHONPATH}" ) else() diff --git a/setup.py b/setup.py index 11b1bb5d8..0e4dca3ea 100644 --- a/setup.py +++ b/setup.py @@ -125,6 +125,9 @@ def build_extension(self, ext): #if ImpactX_pyamrex_src: # cmake_args.append('-DImpactX_pyamrex_src=' + ImpactX_pyamrex_src) + if CMAKE_INTERPROCEDURAL_OPTIMIZATION is not None: + cmake_args.append('-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=' + + CMAKE_INTERPROCEDURAL_OPTIMIZATION) if sys.platform == "darwin": cmake_args.append('-DCMAKE_INSTALL_RPATH=@loader_path') else: @@ -132,6 +135,8 @@ def build_extension(self, ext): # just as well win32 & cygwin (although Windows has no RPaths) cmake_args.append('-DCMAKE_INSTALL_RPATH=$ORIGIN') + cmake_args += extra_cmake_args + cfg = 'Debug' if self.debug else 'Release' build_args = ['--config', cfg] @@ -186,6 +191,8 @@ def build_extension(self, ext): ImpactX_SPACEDIM = os.environ.get('IMPACTX_SPACEDIM', '3') BUILD_SHARED_LIBS = os.environ.get('IMPACTX_BUILD_SHARED_LIBS', 'OFF') +CMAKE_INTERPROCEDURAL_OPTIMIZATION = os.environ.get( + 'CMAKE_INTERPROCEDURAL_OPTIMIZATION', None) # CMake dependency control (developers & package managers) ImpactX_amrex_src = os.environ.get('IMPACTX_AMREX_SRC') ImpactX_amrex_internal = os.environ.get('IMPACTX_AMREX_INTERNAL', 'ON') @@ -198,6 +205,16 @@ def build_extension(self, ext): # 'https://github.com/AMReX-Codes/pyamrex.git') #ImpactX_pyamrex_branch = os.environ.get('IMPACTX_PYAMREX_BRANCH', 'development') +# extra CMake arguments +extra_cmake_args = [] +for k, v in os.environ.items(): + extra_cmake_args_prefix = "IMPACTX_CMAKE_" + if k.startswith(extra_cmake_args_prefix) and \ + len(k) > len(extra_cmake_args_prefix): + extra_cmake_args.append("-D{0}={1}".format( + k[len(extra_cmake_args_prefix):], + v)) + # https://cmake.org/cmake/help/v3.0/command/if.html if ImpactX_MPI.upper() in ['1', 'ON', 'TRUE', 'YES']: ImpactX_MPI = "ON"