From ec09973eed972fa3052e191418e8027528d88b98 Mon Sep 17 00:00:00 2001 From: Zachary Ferguson Date: Fri, 1 May 2026 11:00:43 -0400 Subject: [PATCH 1/3] Add env var to disable SIMD in setup.py - Add `IPCTK_WITH_SIMD` environment variable to control SIMD support in Python builds - Reformat `setup.py` to match standard Python style guidelines --- .github/workflows/python.yml | 2 ++ setup.py | 38 ++++++++++++++++-------------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 2bbdd9551..bfc934b9a 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -78,6 +78,8 @@ jobs: ccache --show-stats && ccache --zero-stats - name: Build and Install + env: + IPCTK_WITH_SIMD: "0" run: | pip install --verbose . && ccache --show-stats diff --git a/setup.py b/setup.py index bb8cdcb6e..7104e9b86 100755 --- a/setup.py +++ b/setup.py @@ -30,20 +30,22 @@ def build_extension(self, ext): out = subprocess.check_output(["cmake", "--version"]) except OSError: raise RuntimeError( - "CMake must be installed to build the following extensions: " + - ", ".join(e.name for e in self.extensions)) + "CMake must be installed to build the following extensions: " + + ", ".join(e.name for e in self.extensions) + ) - extdir = os.path.abspath(os.path.dirname( - self.get_ext_fullpath(ext.name))) + extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) # required for auto-detection & inclusion of auxiliary "native" libs if not extdir.endswith(os.path.sep): extdir += os.path.sep - debug = (int(os.environ.get("DEBUG", 0)) if self.debug is None - else self.debug) + debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug cfg = "Debug" if debug else "Release" + # Allow users to disable SIMD support with an environment variable, since it can cause build issues on some platforms. + with_simd = "OFF" if os.environ.get("IPCTK_WITH_SIMD", "1") == "0" else "ON" + # CMake lets you override the generator - we need to check this. # Can be set with Conda-Build, for example. cmake_generator = os.environ.get("CMAKE_GENERATOR", "") @@ -55,13 +57,13 @@ def build_extension(self, ext): f"-DCMAKE_BUILD_TYPE={cfg}", # not used on MSVC, but no harm "-DIPC_TOOLKIT_BUILD_TESTS=OFF", "-DIPC_TOOLKIT_BUILD_PYTHON=ON", + f"-DIPC_TOOLKIT_WITH_SIMD={with_simd}", ] build_args = [] # Adding CMake arguments set as environment variable # (needed e.g. to build for ARM OSx on conda-forge) if "CMAKE_ARGS" in os.environ: - cmake_args += [ - item for item in os.environ["CMAKE_ARGS"].split(" ") if item] + cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item] if self.compiler.compiler_type != "msvc": # Using Ninja-build since it a) is available as a wheel and b) @@ -73,8 +75,7 @@ def build_extension(self, ext): try: import ninja # noqa: F401 - ninja_executable_path = os.path.join( - ninja.BIN_DIR, "ninja") + ninja_executable_path = os.path.join(ninja.BIN_DIR, "ninja") cmake_args += [ "-GNinja", f"-DCMAKE_MAKE_PROGRAM:FILEPATH={ninja_executable_path}", @@ -83,10 +84,8 @@ def build_extension(self, ext): pass else: - # Single config generators are handled "normally" - single_config = any( - x in cmake_generator for x in {"NMake", "Ninja"}) + single_config = any(x in cmake_generator for x in {"NMake", "Ninja"}) # CMake allows an arch-in-generator style for backward compatibility contains_arch = any(x in cmake_generator for x in {"ARM", "Win64"}) @@ -108,8 +107,7 @@ def build_extension(self, ext): # Cross-compile support for macOS - respect ARCHFLAGS if set archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", "")) if archs: - cmake_args += [ - "-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))] + cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))] # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level # across all generators. @@ -126,14 +124,12 @@ def build_extension(self, ext): if not os.path.exists(build_temp): os.makedirs(build_temp) - subprocess.check_call(["cmake", ext.sourcedir] + - cmake_args, cwd=build_temp) - subprocess.check_call(["cmake", "--build", "."] + - build_args, cwd=build_temp) + subprocess.check_call(["cmake", ext.sourcedir] + cmake_args, cwd=build_temp) + subprocess.check_call(["cmake", "--build", "."] + build_args, cwd=build_temp) setup( - ext_modules=[CMakeExtension('ipctk')], + ext_modules=[CMakeExtension("ipctk")], cmdclass={"build_ext": CMakeBuild}, - zip_safe=False + zip_safe=False, ) From 6af29eb287449582bc5b9288d2014d56642b4a2b Mon Sep 17 00:00:00 2001 From: Zachary Ferguson Date: Fri, 1 May 2026 11:17:03 -0400 Subject: [PATCH 2/3] Update IPCTK_WITH_SIMD parsing and CI config - Support "off", "false", and "no" values for IPCTK_WITH_SIMD in setup.py - Re-enable SIMD for macOS and Windows Python CI builds --- .github/workflows/python.yml | 2 +- setup.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index bfc934b9a..9451bb919 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -79,7 +79,7 @@ jobs: - name: Build and Install env: - IPCTK_WITH_SIMD: "0" + IPCTK_WITH_SIMD: ${{ runner.os == 'Linux' && '0' || '1' }} run: | pip install --verbose . && ccache --show-stats diff --git a/setup.py b/setup.py index 7104e9b86..99f473084 100755 --- a/setup.py +++ b/setup.py @@ -43,8 +43,9 @@ def build_extension(self, ext): debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug cfg = "Debug" if debug else "Release" - # Allow users to disable SIMD support with an environment variable, since it can cause build issues on some platforms. - with_simd = "OFF" if os.environ.get("IPCTK_WITH_SIMD", "1") == "0" else "ON" + # Allow users to disable SIMD via IPCTK_WITH_SIMD=0/off/false/no. + _simd_env = os.environ.get("IPCTK_WITH_SIMD", "1").strip().lower() + with_simd = "OFF" if _simd_env in {"0", "off", "false", "no"} else "ON" # CMake lets you override the generator - we need to check this. # Can be set with Conda-Build, for example. From 2b35e1b84a39701741a4224fca88bdc8d433f503 Mon Sep 17 00:00:00 2001 From: Zachary Ferguson Date: Fri, 1 May 2026 11:23:02 -0400 Subject: [PATCH 3/3] Add SIMD build instructions to Python README - Document the `IPCTK_WITH_SIMD` environment variable for `pip install` - List accepted falsy values for disabling SIMD optimizations - Add a note on forcing a source build from PyPI to apply the flag --- python/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/python/README.md b/python/README.md index 7d1ed38b4..7ce91cbbe 100644 --- a/python/README.md +++ b/python/README.md @@ -38,6 +38,23 @@ You can test that the installation was successful by doing python -c "import ipctk" ``` +#### SIMD + +SIMD optimizations are enabled by default. To disable them (e.g., for compatibility with older or cross-compiled targets), set `IPCTK_WITH_SIMD=0` before installing: + +```sh +IPCTK_WITH_SIMD=0 pip install . +``` + +Accepted falsy values: `0`, `off`, `false`, `no` (case-insensitive). Any other value keeps SIMD enabled. + +:::{note} +Pre-built binary wheels from PyPI have SIMD support baked in at wheel-build time. The `IPCTK_WITH_SIMD` variable only applies when building from source. To force a source build from PyPI, use: +```sh +IPCTK_WITH_SIMD=0 pip install --no-binary ipctk ipctk +``` +::: + ### CMake Build Alternatively, you can use `cmake` directly. To do this, use the following commands from the root of the repository: