Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: Windows + Python #208

Merged
merged 17 commits into from
Jan 4, 2023
53 changes: 41 additions & 12 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,48 @@ jobs:
restore-keys: |
ccache-windows-winmsvc-${{ hashFiles('.github/workflows/windows.yml') }}-
ccache-windows-winmsvc-
- name: Build & Install
- name: Build
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 `
-DBUILD_SHARED_LIBS=OFF `
-DCMAKE_BUILD_TYPE=RelWithDebInfo `
-DCMAKE_VERBOSE_MAKEFILE=ON `
-DImpactX_COMPUTE=NOACC `
-DImpactX_MPI=OFF `
-DImpactX_PYTHON=ON
-DImpactX_PYTHON=ON `
-DPython_EXECUTABLE=python3
if(!$?) { Exit $LASTEXITCODE }
cmake --build build --config RelWithDebInfo --parallel 2
if(!$?) { Exit $LASTEXITCODE }
- name: Install
run: |
cmake --build build --config RelWithDebInfo --target install
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 }
- name: Add debugger to the PATH
shell: bash
run: echo "C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x64" >> $GITHUB_PATH

- name: Add install .dll location to the PATH
shell: bash
run: echo "C:\\Program Files (x86)\\ImpactX\\bin" >> $GITHUB_PATH

- name: Test
run: |
(Get-Command python3).Path
gflags /i (Get-Command python3).Path +sls
cdb -c "g;q" python3 D:\a\impactx\impactx\examples\fodo\run_fodo.py
if(!$?) { Exit $LASTEXITCODE }

gflags /i (Get-Command ctest).Path +sls
cdb -c "g;q" ctest --test-dir build --build-config RelWithDebInfo --output-on-failure -E AMReX -R py
if(!$?) { Exit $LASTEXITCODE }

build_win_clang:
name: Clang C++17 w/ OMP w/o MPI
Expand All @@ -74,7 +95,7 @@ jobs:
ccache-windows-winclang-${{ hashFiles('.github/workflows/windows.yml') }}-
ccache-windows-winclang-
- uses: seanmiddleditch/gha-setup-ninja@master
- name: Build & Install
- name: Build
shell: cmd
run: |
python3 -m pip install -U pip setuptools wheel pytest
Expand All @@ -86,17 +107,25 @@ jobs:
-G "Ninja" ^
-DCMAKE_C_COMPILER=clang-cl ^
-DCMAKE_CXX_COMPILER=clang-cl ^
-DBUILD_SHARED_LIBS=OFF ^
-DBUILD_SHARED_LIBS=OFF ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_VERBOSE_MAKEFILE=ON ^
-DImpactX_COMPUTE=OMP ^
-DImpactX_MPI=OFF ^
-DImpactX_PYTHON=ON
-DImpactX_PYTHON=ON ^
-DPython_EXECUTABLE=python3
if errorlevel 1 exit 1
cmake --build build --config Release --parallel 2
if errorlevel 1 exit 1
- name: Install Python
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\vc\Auxiliary\build\vcvarsall.bat" x64
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
- name: Test
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\vc\Auxiliary\build\vcvarsall.bat" x64
ctest --test-dir build --build-config Release --output-on-failure -E AMReX -R py
if errorlevel 1 exit 1
22 changes: 16 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,21 @@ if(ImpactX_PYTHON)
PDB_OUTPUT_DIRECTORY ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/impactx
COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/impactx
)
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
foreach(CFG IN LISTS CMAKE_CONFIGURATION_TYPES)
string(TOUPPER "${CFG}" CFG_UPPER)
set_target_properties(pyImpactX PROPERTIES
# build output directories - mainly set to run tests from CMake & IDEs
# note: same as above, but for Multi-Config generators
ARCHIVE_OUTPUT_DIRECTORY_${CFG_UPPER} ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/impactx
LIBRARY_OUTPUT_DIRECTORY_${CFG_UPPER} ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/impactx
RUNTIME_OUTPUT_DIRECTORY_${CFG_UPPER} ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/impactx
PDB_OUTPUT_DIRECTORY_${CFG_UPPER} ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/impactx
COMPILE_PDB_OUTPUT_DIRECTORY_${CFG_UPPER} ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/impactx
)
endforeach()
endif()
if(EMSCRIPTEN)
set_target_properties(pyImpactX PROPERTIES
PREFIX "")
Expand Down Expand Up @@ -328,19 +343,14 @@ install(TARGETS ${ImpactX_INSTALL_TARGET_NAMES}

# simplified library alias
if(ImpactX_LIB)
if(WIN32)
set(mod_ext "dll")
else()
set(mod_ext "so")
endif()
if(IS_ABSOLUTE ${CMAKE_INSTALL_LIBDIR})
set(ABS_INSTALL_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
else()
set(ABS_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
endif()
install(CODE "file(CREATE_LINK
$<TARGET_FILE_NAME:lib>
${ABS_INSTALL_LIB_DIR}/libImpactX.${mod_ext}
${ABS_INSTALL_LIB_DIR}/libImpactX$<TARGET_FILE_SUFFIX:lib>
COPY_ON_ERROR SYMBOLIC)")
endif()

Expand Down
23 changes: 13 additions & 10 deletions cmake/ImpactXFunctions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,23 @@ macro(impactx_set_default_install_dirs_python)
endmacro()


# function to set the PYTHONPATH on a test
# function to set the PYTHONPATH and PATH (for .dll files) on a test
# this avoids that we need to install our python packages to run ctest
#
function(impactx_test_set_pythonpath test_name)
if(WIN32)
string(REPLACE ";" "\\;" WIN_PYTHONPATH "$ENV{PYTHONPATH}")
string(REPLACE ";" "\\;" WIN_PATH "$ENV{PATH}") # DLLs
string(REGEX REPLACE "/" "\\\\" WIN_PYTHON_OUTPUT_DIRECTORY ${CMAKE_PYTHON_OUTPUT_DIRECTORY})
# shared library note:
# For Windows Python 3.8+, this also needs to be injected via
# os.add_dll_directory.
# https://github.com/python/cpython/issues/80266
# https://docs.python.org/3.8/library/os.html#os.add_dll_directory
set_property(TEST ${test_name}
APPEND PROPERTY ENVIRONMENT "PYTHONPATH=${WIN_PYTHON_OUTPUT_DIRECTORY}\;${WIN_PYTHONPATH}"
APPEND PROPERTY ENVIRONMENT
"PYTHONPATH=${WIN_PYTHON_OUTPUT_DIRECTORY}\;${WIN_PYTHONPATH}"
"PATH=$<TARGET_FILE_DIR:lib>\;${WIN_PATH}$"
)
else()
set_property(TEST ${test_name}
Expand Down Expand Up @@ -241,9 +249,9 @@ function(impactx_set_binary_name)
list(APPEND ImpactX_bin_names app)
endif()
if(ImpactX_LIB)
list(APPEND ImpactX_bin_names shared)
list(APPEND ImpactX_bin_names lib)
endif()
foreach(tgt IN LISTS _ALL_TARGETS)
foreach(tgt IN LISTS ImpactX_bin_names)
set_target_properties(${tgt} PROPERTIES OUTPUT_NAME "impactx")

if(ImpactX_MPI)
Expand Down Expand Up @@ -287,15 +295,10 @@ function(impactx_set_binary_name)
)
endif()
if(ImpactX_LIB)
if(WIN32) # TODO: handle static lib extensions
set(mod_ext "dll")
else()
set(mod_ext "so")
endif()
add_custom_command(TARGET lib POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink
$<TARGET_FILE_NAME:lib>
$<TARGET_FILE_DIR:lib>/libimpactx.${mod_ext}
$<TARGET_FILE_DIR:lib>/libimpactx$<TARGET_FILE_SUFFIX:lib>
)
endif()
endfunction()
Expand Down
2 changes: 1 addition & 1 deletion cmake/dependencies/ABLASTR.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ macro(find_ablastr)
# BETWEEN MULTIPLE PYTHON MODULES
# TODO this is likely an export/symbol hiding issue that we could
# alleviate later on
set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE)
set(AMReX_BUILD_SHARED_LIBS ON CACHE BOOL "Build AMReX shared library" FORCE)
endif()

if(ImpactX_ablastr_src)
Expand Down
2 changes: 1 addition & 1 deletion cmake/dependencies/pyAMReX.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ option(ImpactX_pyamrex_internal "Download & build pyAMReX" ON)
set(ImpactX_pyamrex_repo "https://github.com/AMReX-Codes/pyamrex.git"
CACHE STRING
"Repository URI to pull and build pyamrex from if(ImpactX_pyamrex_internal)")
set(ImpactX_pyamrex_branch "23.01"
set(ImpactX_pyamrex_branch "4372b5b4d325bc9c8c73ce18013dbe8fc18cfe9f"
CACHE STRING
"Repository branch for ImpactX_pyamrex_repo if(ImpactX_pyamrex_internal)")

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def build_extension(self, ext):
cmake_args += [
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}".format(
cfg.upper(), os.path.join(extdir, "impactx")
)
),
]
if sys.maxsize > 2**32:
cmake_args += ["-A", "x64"]
Expand Down
18 changes: 18 additions & 0 deletions src/python/impactx/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
import os

# Python 3.8+ on Windows: DLL search paths for dependent
# shared libraries
# Refs.:
# - https://github.com/python/cpython/issues/80266
# - https://docs.python.org/3.8/library/os.html#os.add_dll_directory
if os.name == "nt":
# add anything in the current directory
pwd = __file__.rsplit(os.sep, 1)[0] + os.sep
os.add_dll_directory(pwd)
# add anything in PATH
paths = os.environ.get("PATH", "")
for p in paths.split(";"):
if os.path.exists(p):
os.add_dll_directory(p)

# import core bindings to C++
from . import impactx_pybind as cxx
from .impactx_pybind import * # noqa
from .madx_to_impactx import read_beam, read_lattice # noqa
Expand Down
2 changes: 1 addition & 1 deletion tests/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ add_test(NAME ${pytest_name}
WORKING_DIRECTORY ${pytest_rundir}
)

# set PYTHONPATH
# set PYTHONPATH and PATH (for .dll files)
impactx_test_set_pythonpath(${pytest_name})