[Git][debian-gis-team/pykdtree][upstream] New upstream version 1.3.7+ds

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sun Jun 11 16:37:52 BST 2023



Antonio Valentino pushed to branch upstream at Debian GIS Project / pykdtree


Commits:
eec8c02f by Antonio Valentino at 2023-06-11T07:34:00+00:00
New upstream version 1.3.7+ds
- - - - -


4 changed files:

- + .github/dependabot.yml
- .github/workflows/deploy-wheels.yml
- README.rst
- setup.py


Changes:

=====================================
.github/dependabot.yml
=====================================
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+  - package-ecosystem: "github-actions" # See documentation for possible values
+    directory: "/" # Location of package manifests
+    schedule:
+      interval: "weekly"


=====================================
.github/workflows/deploy-wheels.yml
=====================================
@@ -12,7 +12,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout source
-        uses: actions/checkout at v2
+        uses: actions/checkout at v3
 
       - name: Create sdist
         shell: bash -l {0}
@@ -21,7 +21,7 @@ jobs:
           python -m build -s
 
       - name: Upload sdist to build artifacts
-        uses: actions/upload-artifact at v2
+        uses: actions/upload-artifact at v3
         with:
           name: sdist
           path: dist/*.tar.gz
@@ -46,7 +46,7 @@ jobs:
             docker-image: manylinux_2_24_i686
 
     steps:
-      - uses: actions/checkout at v2
+      - uses: actions/checkout at v3
       - run: |
           git fetch --prune --unshallow
 
@@ -102,7 +102,7 @@ jobs:
           path: dist
       - name: Publish package to PyPI
         if: github.event.action == 'published'
-        uses: pypa/gh-action-pypi-publish at v1.4.1
+        uses: pypa/gh-action-pypi-publish at v1.7.1
         with:
           user: ${{ secrets.pypi_username }}
           password: ${{ secrets.pypi_password }}


=====================================
README.rst
=====================================
@@ -31,16 +31,17 @@ Or, if in a conda-based environment, with conda from the conda-forge channel:
 
     conda install -c conda-forge pykdtree
     
-Note that by default these packages are only built with OpenMP for linux platforms.
+Note that by default these packages (the binary wheels on PyPI and the binary
+package on conda-forge) are only built with OpenMP for linux platforms.
 To attempt to build from source with OpenMP support do:
 
 .. code-block:: bash
 
-    export USE_OMP=1
+    export USE_OMP="probe"
     pip install --no-binary pykdtree pykdtree
     
 This may not work on some systems that don't have OpenMP installed. See the below development
-instructions for more guidance. Disabling OpenMP can be accomplished by setting `USE_OMP` to `0`
+instructions for more guidance. Disabling OpenMP can be accomplished by setting `USE_OMP` to ``"0"``
 in the above commands.
 
 Development Installation
@@ -82,6 +83,26 @@ Note evironment variables are by default not exported when using sudo so in this
 
     $ USE_OMP=0 sudo -E pip install -e .
 
+
+Control OpenMP usage
+^^^^^^^^^^^^^^^^^^^^
+
+The ``USE_OMP`` variable can be set to one of a couple different options. If
+set to ``"probe"``, the installation process (``setup.py``) will attempt to
+determine what variant of OpenMP is available based on the compiler being used,
+the platform being run on, and the Python environment being run with. It will
+then use the flags specified by one of the other ``USE_OMP`` modes. Note that
+in the case of MacOS, it will also try to identify if OpenMP is available from
+macports or homebrew and include the necessary include and library paths.
+
+If set to ``"gcc"`` or ``"gomp"`` then compiler and linking flags will be set
+appropriately for "GNU OpenMP" (gomp) library. If set to ``"clang"`` or 
+``"omp"`` then the flags will be set to support the "omp" library. If set to
+``"msvc"`` then flags will be set for the Microsoft Visual C++ compiler's
+OpenMP variant. For backwards compatibility the previous ``"1"`` has the same
+behavior as ``"probe"``. As mentioned above ``"0"`` can be used to disable
+any detection of OpenMP or attempt to compile with it.
+
 Usage
 -----
 


=====================================
setup.py
=====================================
@@ -17,33 +17,33 @@
 
 import os
 import sys
+import re
 from setuptools import setup, Extension
 from setuptools.command.build_ext import build_ext
 
 
-def is_conda_interpreter():
-    """Is the running interpreter from Anaconda or miniconda?
-
-    See https://stackoverflow.com/a/21318941/433202
-
-    Examples::
-
-        2.7.6 |Anaconda 1.8.0 (x86_64)| (default, Jan 10 2014, 11:23:15)
-        2.7.6 |Continuum Analytics, Inc.| (default, Jan 10 2014, 11:23:15)
-        3.6.6 | packaged by conda-forge | (default, Jul 26 2018, 09:55:02)
-
-    """
-    return 'conda' in sys.version or 'Continuum' in sys.version
-
-
-# Get OpenMP setting from environment
-try:
-    use_omp = int(os.environ['USE_OMP'])
-except KeyError:
-    # OpenMP is not supported with default clang
-    # Conda provides its own compiler which does support openmp
-    use_omp = 'darwin' not in sys.platform or is_conda_interpreter()
-
+OMP_SETTING_TABLE = {
+    '1': 'probe',
+    '0': None,
+    'gcc': 'gomp',
+    'gomp': 'gomp',
+    'clang': 'omp',
+    'omp': 'omp',
+    'msvc': 'msvc',
+    'probe': 'probe'
+}
+
+OMP_COMPILE_ARGS = {
+    'gomp': ['-fopenmp'],
+    'omp': ['-Xpreprocessor', '-fopenmp'],
+    'msvc': ['/openmp']
+}
+
+OMP_LINK_ARGS = {
+    'gomp': ['-lgomp'],
+    'omp': ['-lomp'],
+    'msvc': []
+}
 
 def set_builtin(name, value):
     if isinstance(__builtins__, dict):
@@ -52,23 +52,17 @@ def set_builtin(name, value):
         setattr(__builtins__, name, value)
 
 
-# Custom builder to handler compiler flags. Edit if needed.
 class build_ext_subclass(build_ext):
+
     def build_extensions(self):
         comp = self.compiler.compiler_type
+        omp_comp, omp_link = _omp_compile_link_args(comp)
         if comp in ('unix', 'cygwin', 'mingw32'):
-            # Check if build is with OpenMP
-            if use_omp:
-                extra_compile_args = ['-std=c99', '-O3', '-fopenmp']
-                extra_link_args=['-lgomp']
-            else:
-                extra_compile_args = ['-std=c99', '-O3']
-                extra_link_args = []
+            extra_compile_args = ['-std=c99', '-O3'] + omp_comp
+            extra_link_args = omp_link
         elif comp == 'msvc':
-            extra_compile_args = ['/Ox']
-            extra_link_args = []
-            if use_omp:
-                extra_compile_args.append('/openmp')
+            extra_compile_args = ['/Ox'] + omp_comp
+            extra_link_args = omp_link
         else:
             # Add support for more compilers here
             raise ValueError('Compiler flags undefined for %s. Please modify setup.py and add compiler flags'
@@ -89,12 +83,125 @@ class build_ext_subclass(build_ext):
         import numpy
         self.include_dirs.append(numpy.get_include())
 
+
+def _omp_compile_link_args(compiler):
+    # Get OpenMP setting from environment
+    use_omp = OMP_SETTING_TABLE[os.environ.get('USE_OMP', 'probe')]
+
+    compile_args = []
+    link_args = []
+    if use_omp == "probe":
+        use_omp, compile_args, link_args = _probe_omp_for_compiler_and_platform(compiler)
+
+    print(f"Will use {use_omp} for OpenMP." if use_omp else "OpenMP support not available.")
+    compile_args += OMP_COMPILE_ARGS.get(use_omp, [])
+    link_args += OMP_LINK_ARGS.get(use_omp, [])
+    print(f"Compiler: {compiler} / OpenMP: {use_omp} / OpenMP compile args: {compile_args} / OpenMP link args: {link_args}")
+    return compile_args, link_args
+
+
+def _probe_omp_for_compiler_and_platform(compiler):
+    compile_args = []
+    link_args = []
+    if compiler == "msvc":
+        use_omp = "msvc"
+    elif _is_conda_interpreter():
+        # Conda provides its own compiler which does support openmp
+        use_omp = "gomp"
+    elif _is_macOS():
+        # OpenMP is not supported with system clang but homebrew and macports have libomp packages
+        compile_args, link_args = _macOS_omp_options_from_probe()
+        if not (compile_args or link_args):
+            print("Probe for libomp failed, skipping use of OpenMP with clang.")
+            print("It may be possible to build with OpenMP using USE_OMP=clang with CFLAGS and LDFLAGS explicit settings to use libomp.")
+            use_omp = None
+        else:
+            use_omp = "omp"
+    else:
+        use_omp = "gomp"
+    return use_omp, compile_args, link_args
+
+
+def _is_conda_interpreter():
+    """Is the running interpreter from Anaconda or miniconda?
+
+    See https://stackoverflow.com/a/21318941/433202
+
+    Examples::
+
+        2.7.6 |Anaconda 1.8.0 (x86_64)| (default, Jan 10 2014, 11:23:15)
+        2.7.6 |Continuum Analytics, Inc.| (default, Jan 10 2014, 11:23:15)
+        3.6.6 | packaged by conda-forge | (default, Jul 26 2018, 09:55:02)
+
+    """
+    return 'conda' in sys.version or 'Continuum' in sys.version
+
+
+def _is_macOS():
+    return 'darwin' in sys.platform
+
+
+def _macOS_omp_options_from_probe():
+    """Get common include and library paths for libomp installation on macOS.
+
+    For example ``(['-I/opt/local/include/libomp'], ['-L/opt/local/lib/libomp'])``.
+
+    """
+    for cmd in ["brew ls --verbose libomp", "port contents libomp"]:
+        inc, lib = _compile_link_paths_from_manifest(cmd)
+        if inc and lib:
+            return [f"-I{inc}"], [f"-L{lib}"]
+    return [], []    
+
+
+def _compile_link_paths_from_manifest(cmd):
+    """Parse include and library paths from OSX package managers.
+
+    Example executions::
+
+        # Homebrew
+        $ brew ls --verbose libomp
+        /opt/homebrew/Cellar/libomp/15.0.7/INSTALL_RECEIPT.json
+        /opt/homebrew/Cellar/libomp/15.0.7/.brew/libomp.rb
+        /opt/homebrew/Cellar/libomp/15.0.7/include/ompt.h
+        /opt/homebrew/Cellar/libomp/15.0.7/include/omp.h
+        /opt/homebrew/Cellar/libomp/15.0.7/include/omp-tools.h
+        /opt/homebrew/Cellar/libomp/15.0.7/lib/libomp.dylib
+        /opt/homebrew/Cellar/libomp/15.0.7/lib/libomp.a
+
+        # MacPorts
+        $ port contents libomp
+        Port libomp contains:
+          /opt/local/include/libomp/omp-tools.h
+          /opt/local/include/libomp/omp.h
+          /opt/local/include/libomp/ompt.h
+          /opt/local/lib/libomp/libgomp.dylib
+          /opt/local/lib/libomp/libiomp5.dylib
+          /opt/local/lib/libomp/libomp.dylib
+          /opt/local/share/doc/libomp/LICENSE.TXT
+          /opt/local/share/doc/libomp/README.txt
+
+    """
+    from subprocess import run
+    query = run(cmd, shell=True, check=False, capture_output=True)
+    if query.returncode != 0:
+        return None, None
+    manifest = query.stdout.decode("UTF-8")
+    # find all the unique directories mentioned in the manifest
+    dirs = set(os.path.split(filename)[0] for filename in re.findall(r'^\s*(/.*?)\s*$', manifest, re.MULTILINE))
+    # find a unique libdir and incdir
+    inc = tuple(d for d in dirs if re.search(r'/include(\W|$)', d))
+    lib = tuple(d for d in dirs if re.search(r'/lib(\W|$)', d))
+    # only return success if there's no ambiguity
+    return (inc + lib) if len(inc) == 1 and len(lib) == 1 else (None, None)
+
+
 with open('README.rst', 'r') as readme_file:
     readme = readme_file.read()
 
 setup(
     name='pykdtree',
-    version='1.3.6',
+    version='1.3.7',
     url="https://github.com/storpipfugl/pykdtree",
     description='Fast kd-tree implementation with OpenMP-enabled queries',
     long_description=readme,
@@ -119,3 +226,4 @@ setup(
       'Topic :: Scientific/Engineering'
       ]
     )
+



View it on GitLab: https://salsa.debian.org/debian-gis-team/pykdtree/-/commit/eec8c02f140427350e3bcbbd69118b222dcd6ace

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pykdtree/-/commit/eec8c02f140427350e3bcbbd69118b222dcd6ace
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20230611/639fd699/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list