From c9912c2db179a1b078eb2d05bb07199d03dae406 Mon Sep 17 00:00:00 2001 From: lpossner Date: Thu, 11 Jul 2024 12:35:10 +0200 Subject: [PATCH] OSX build test --- .github/workflows/main.yml | 217 +++++++++++++++++++------------------ doc/conf.py | 2 +- pygpc/GPC.py | 116 ++++++++++---------- setup.py | 18 +-- 4 files changed, 179 insertions(+), 174 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f2e96660..0e87b6b0 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,55 +6,100 @@ on: pull_request: branches: [ master, develop ] jobs: - linux: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - include: - - python-version: "3.9" - cibw-string: "cp39-*" - - python-version: "3.10" - cibw-string: "cp310-*" - - python-version: "3.11" - cibw-string: "cp311-*" - - python-version: "3.12" - cibw-string: "cp312-*" - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install Cython cibuildwheel twine - pip install -r requirements.txt - pip install . - - name: Test with unittest - run: | - cd tests - python -m unittest - cd .. - - name: Build with cibuildwheel - run: | - python -m cibuildwheel --output-dir wheelhouse - ls wheelhouse/ - env: - CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014" - CIBW_BEFORE_BUILD: "pip install numpy" - CIBW_BUILD: ${{ matrix.cibw-string }} - CIBW_SKIP: "*-musllinux_* *i686*" - - name: Upload with twine - if: "contains(github.event.head_commit.message, 'PyPI')" - run: | - python -m twine upload wheelhouse/*.whl - env: - TWINE_PASSWORD: ${{ secrets.twine_api_key }} - TWINE_USERNAME: __token__ - windows: - runs-on: windows-2019 + # linux: + # runs-on: ubuntu-latest + # strategy: + # matrix: + # python-version: ["3.9", "3.10", "3.11", "3.12"] + # include: + # - python-version: "3.9" + # cibw-string: "cp39-*" + # - python-version: "3.10" + # cibw-string: "cp310-*" + # - python-version: "3.11" + # cibw-string: "cp311-*" + # - python-version: "3.12" + # cibw-string: "cp312-*" + # steps: + # - uses: actions/checkout@v2 + # - name: Set up Python ${{ matrix.python-version }} + # uses: actions/setup-python@v1 + # with: + # python-version: ${{ matrix.python-version }} + # - name: Install dependencies + # run: | + # python -m pip install --upgrade pip + # pip install Cython cibuildwheel twine + # pip install -r requirements.txt + # pip install . + # - name: Test with unittest + # run: | + # cd tests + # python -m unittest + # cd .. + # - name: Build with cibuildwheel + # run: | + # python -m cibuildwheel --output-dir wheelhouse + # ls wheelhouse/ + # env: + # CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014" + # CIBW_BEFORE_BUILD: "pip install numpy" + # CIBW_BUILD: ${{ matrix.cibw-string }} + # CIBW_SKIP: "*-musllinux_* *i686*" + # - name: Upload with twine + # if: "contains(github.event.head_commit.message, 'PyPI')" + # run: | + # python -m twine upload wheelhouse/*.whl + # env: + # TWINE_PASSWORD: ${{ secrets.twine_api_key }} + # TWINE_USERNAME: __token__ + # windows: + # runs-on: windows-2019 + # strategy: + # matrix: + # python-version: ["3.9", "3.10", "3.11", "3.12"] + # include: + # - python-version: "3.9" + # cibw-string: "cp39-*" + # - python-version: "3.10" + # cibw-string: "cp310-*" + # - python-version: "3.11" + # cibw-string: "cp311-*" + # - python-version: "3.12" + # cibw-string: "cp312-*" + # steps: + # - uses: actions/checkout@v2 + # - name: Set up Python ${{ matrix.python-version }} + # uses: actions/setup-python@v1 + # with: + # python-version: ${{ matrix.python-version }} + # - name: Install dependencies + # run: | + # python -m pip install --upgrade pip + # pip install Cython cibuildwheel twine + # pip install -r requirements.txt + # pip install . + # - name: Test with unittest + # run: | + # cd tests + # python -m unittest + # cd .. + # - name: Build with cibuildwheel + # run: | + # python -m cibuildwheel --output-dir wheelhouse + # ls wheelhouse/ + # env: + # CIBW_BEFORE_BUILD: "pip install numpy" + # CIBW_BUILD: ${{ matrix.cibw-string }} + # - name: Upload with twine + # if: "contains(github.event.head_commit.message, 'PyPI')" + # run: | + # python -m twine upload wheelhouse/*.whl + # env: + # TWINE_PASSWORD: ${{ secrets.twine_api_key }} + # TWINE_USERNAME: __token__ + macos: + runs-on: macos-11 strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] @@ -75,22 +120,29 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | + brew install gcc@13 python -m pip install --upgrade pip - pip install Cython cibuildwheel twine + pip install Cython matplotlib seaborn cibuildwheel twine pip install -r requirements.txt - pip install . - - name: Test with unittest - run: | - cd tests - python -m unittest - cd .. + CC=gcc-13 CXX=g++-13 pip install . + # - name: Test with unittest + # run: | + # cd tests + # python -m unittest + # cd .. - name: Build with cibuildwheel run: | python -m cibuildwheel --output-dir wheelhouse ls wheelhouse/ env: - CIBW_BEFORE_BUILD: "pip install numpy" + # MACOSX_DEPLOYMENT_TARGET: "10.11" + # CIBW_BEFORE_BUILD: "pip install numpy" + # CIBW_ARCHS_MACOS: x86_64 CIBW_BUILD: ${{ matrix.cibw-string }} + # CIBW_REPAIR_WHEEL_COMMAND: "delocate-listdeps {wheel} && delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}" + CIBW_REPAIR_WHEEL_COMMAND: "" + # CC: gcc-13 + # CXX: g++-13 - name: Upload with twine if: "contains(github.event.head_commit.message, 'PyPI')" run: | @@ -98,54 +150,3 @@ jobs: env: TWINE_PASSWORD: ${{ secrets.twine_api_key }} TWINE_USERNAME: __token__ - macos: - runs-on: macos-11 - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - include: - - python-version: "3.9" - cibw-string: "cp39-*" - - python-version: "3.10" - cibw-string: "cp310-*" - - python-version: "3.11" - cibw-string: "cp311-*" - - python-version: "3.12" - cibw-string: "cp312-*" - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - brew install gcc@13 - python -m pip install --upgrade pip - pip install Cython matplotlib seaborn cibuildwheel twine - pip install -r requirements.txt - CC=gcc-13 CXX=g++-13 pip install . - - name: Test with unittest - run: | - cd tests - python -m unittest - cd .. - # - name: Build with cibuildwheel - # run: | - # python -m cibuildwheel --output-dir wheelhouse - # ls wheelhouse/ - # env: - # MACOSX_DEPLOYMENT_TARGET: "10.11" - # CIBW_BEFORE_BUILD: "pip install numpy" - # CIBW_ARCHS_MACOS: x86_64 - # CIBW_BUILD: ${{ matrix.cibw-string }} - # CIBW_REPAIR_WHEEL_COMMAND: "delocate-listdeps {wheel} && delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}" - # CC: gcc-13 - # CXX: g++-13 - # - name: Upload with twine - # if: "contains(github.event.head_commit.message, 'PyPI')" - # run: | - # python -m twine upload wheelhouse/*.whl - # env: - # TWINE_PASSWORD: ${{ secrets.twine_api_key }} - # TWINE_USERNAME: __token__ diff --git a/doc/conf.py b/doc/conf.py index b1320c87..6edfc299 100755 --- a/doc/conf.py +++ b/doc/conf.py @@ -21,7 +21,7 @@ # -- Project information ----------------------------------------------------- project = u'pygpc' -copyright = u'2023, Konstantin Weise' +copyright = u'2024, Konstantin Weise' author = u'Konstantin Weise' # The short X.Y version diff --git a/pygpc/GPC.py b/pygpc/GPC.py index f6deeb69..23593d69 100755 --- a/pygpc/GPC.py +++ b/pygpc/GPC.py @@ -12,18 +12,10 @@ from .misc import nrmsd from .misc import mat2ten from .misc import ten2mat -from .pygpc_extensions import create_gpc_matrix_cpu -from .pygpc_extensions import create_gpc_matrix_omp from .ValidationSet import * from .Computation import * from .Grid import * - -try: - from .pygpc_extensions_cuda import create_gpc_matrix_cuda -except ImportError: - pass - try: import fastmat as fm except ImportError: @@ -220,56 +212,44 @@ def create_gpc_matrix(self, b, x, gradient=False, gradient_idx=None, weighted=Fa iprint('Constructing gPC matrix...', verbose=verbose, tab=0) - # Python backend - if self.backend == "python": - if not gradient: - gpc_matrix = np.ones([x.shape[0], len(b)]) - for i_basis in range(len(b)): - for i_dim in range(self.problem.dim): - gpc_matrix[:, i_basis] *= b[i_basis][i_dim](x[:, i_dim]) - else: - gpc_matrix = np.ones([len(self.gradient_idx), len(b), self.problem.dim]) - for i_dim_gradient in range(self.problem.dim): - for i_basis in range(len(b)): - for i_dim in range(self.problem.dim): - if i_dim == i_dim_gradient: - derivative = True - else: - derivative = False - gpc_matrix[:, i_basis, i_dim_gradient] *= b[i_basis][i_dim](x[self.gradient_idx, i_dim], - derivative=derivative) - # CPU backend (CPU single core) - elif self.backend == "cpu": - if not gradient: - # the third dimension is important and should not be removed - # otherwise the code could produce undefined behaviour - gpc_matrix = np.empty([x.shape[0], len(b), 1]) - create_gpc_matrix_cpu(x, self.basis.b_array, gpc_matrix) - gpc_matrix = np.squeeze(gpc_matrix) - else: - gpc_matrix = np.empty([len(self.gradient_idx), len(b), self.problem.dim]) - create_gpc_matrix_cpu(x[self.gradient_idx, :], self.basis.b_array_grad, gpc_matrix) + if self.backend == "cpu": + try: + from .pygpc_extensions import create_gpc_matrix_cpu + if not gradient: + # the third dimension is important and should not be removed + # otherwise the code could produce undefined behaviour + gpc_matrix = np.empty([x.shape[0], len(b), 1]) + create_gpc_matrix_cpu(x, self.basis.b_array, gpc_matrix) + gpc_matrix = np.squeeze(gpc_matrix) + else: + gpc_matrix = np.empty([len(self.gradient_idx), len(b), self.problem.dim]) + create_gpc_matrix_cpu(x[self.gradient_idx, :], self.basis.b_array_grad, gpc_matrix) + except (ImportError): + print("The CPU-extension is not installed. Fall back to pure Python as backend.") + self.backend = "python" # OpenMP backend (CPU multi core) elif self.backend == "omp": - if not gradient: - # the third dimension is important and should not be removed - # otherwise the code could produce undefined behaviour - gpc_matrix = np.empty([x.shape[0], len(b), 1]) - create_gpc_matrix_omp(x, self.basis.b_array, gpc_matrix) - gpc_matrix = np.squeeze(gpc_matrix) - else: - gpc_matrix = np.empty([len(self.gradient_idx), len(b), self.problem.dim]) - create_gpc_matrix_omp(x[self.gradient_idx, :], self.basis.b_array_grad, gpc_matrix) + try: + from .pygpc_extensions import create_gpc_matrix_omp + if not gradient: + # the third dimension is important and should not be removed + # otherwise the code could produce undefined behaviour + gpc_matrix = np.empty([x.shape[0], len(b), 1]) + create_gpc_matrix_omp(x, self.basis.b_array, gpc_matrix) + gpc_matrix = np.squeeze(gpc_matrix) + else: + gpc_matrix = np.empty([len(self.gradient_idx), len(b), self.problem.dim]) + create_gpc_matrix_omp(x[self.gradient_idx, :], self.basis.b_array_grad, gpc_matrix) + except (ImportError): + print("The OMP-extension is not installed. Fall back to pure Python as backend.") + self.backend = "python" # CUDA backend (GPU multi core) elif self.backend == "cuda": try: from .pygpc_extensions_cuda import create_gpc_matrix_cuda - except (ImportError): - raise NotImplementedError("The CUDA-extension is not installed. Use the build script to install.") - else: if not gradient: # the third dimension is important and should not be removed # otherwise the code could produce undefined behaviour @@ -279,7 +259,28 @@ def create_gpc_matrix(self, b, x, gradient=False, gradient_idx=None, weighted=Fa else: gpc_matrix = np.empty([len(self.gradient_idx), len(b), self.problem.dim]) create_gpc_matrix_cuda(x[self.gradient_idx, :], self.basis.b_array_grad, gpc_matrix) + except (ImportError): + print("The CUDA-extension is not installed. Fall back to pure Python as backend.") + self.backend = "python" + # Python backend + if self.backend == "python": + if not gradient: + gpc_matrix = np.ones([x.shape[0], len(b)]) + for i_basis in range(len(b)): + for i_dim in range(self.problem.dim): + gpc_matrix[:, i_basis] *= b[i_basis][i_dim](x[:, i_dim]) + else: + gpc_matrix = np.ones([len(self.gradient_idx), len(b), self.problem.dim]) + for i_dim_gradient in range(self.problem.dim): + for i_basis in range(len(b)): + for i_dim in range(self.problem.dim): + if i_dim == i_dim_gradient: + derivative = True + else: + derivative = False + gpc_matrix[:, i_basis, i_dim_gradient] *= b[i_basis][i_dim](x[self.gradient_idx, i_dim], + derivative=derivative) else: raise NotImplementedError @@ -636,6 +637,15 @@ def get_approximation(self, coeffs, x, output_idx=None): if self.p_matrix is not None: x = np.matmul(x, self.p_matrix.transpose() / self.p_matrix_norm[np.newaxis, :]) + if self.backend == "cuda": + try: + from .pygpc_extensions_cuda import get_approximation_cuda + pce = np.empty([x.shape[0], coeffs.shape[1]]) + get_approximation_cuda(x, self.basis.b_array, coeffs, pce) + except ImportError: + print("The CUDA-extension is not installed. Fall back to pure Python as backend.") + self.backend = "python" + if self.backend == 'python' or self.backend == 'cpu' or self.backend == 'omp': # determine gPC matrix at coordinates x gpc_matrix = self.create_gpc_matrix(self.basis.b, x, gradient=False) @@ -643,14 +653,6 @@ def get_approximation(self, coeffs, x, output_idx=None): # multiply with gPC coeffs pce = np.matmul(gpc_matrix, coeffs) - elif self.backend == "cuda": - try: - from .pygpc_extensions_cuda import get_approximation_cuda - except ImportError: - raise NotImplementedError("The CUDA-extension is not installed. Use the build script to install.") - else: - pce = np.empty([x.shape[0], coeffs.shape[1]]) - get_approximation_cuda(x, self.basis.b_array, coeffs, pce) else: raise NotImplementedError diff --git a/setup.py b/setup.py index 7105815b..f10637a7 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ -import argparse import os +import sys import numpy as np from setuptools import setup, find_packages, Extension @@ -8,7 +8,7 @@ # analysis of complex systems. See also: # https://github.com/pygpc-polynomial-chaos/pygpc # -# Copyright (C) 2017-2023 the original author (Konstantin Weise), +# Copyright (C) 2017-2024 the original author (Konstantin Weise), # the Max-Planck-Institute for Human Cognitive Brain Sciences ("MPI CBS") # and contributors # @@ -32,12 +32,14 @@ pygpc_extensions_include_path = [os.path.join('pckg', 'pygpc_extensions', 'include'), np.get_include()] -extensions = [Extension('pygpc.pygpc_extensions', - sources=pygpc_extensions_src_file_path, - include_dirs=pygpc_extensions_include_path, - extra_compile_args=openmp_compile_args, - extra_link_args=openmp_link_args)] - +if sys.platform == 'darwin': + extensions = [] +else: + extensions = [Extension('pygpc.pygpc_extensions', + sources=pygpc_extensions_src_file_path, + include_dirs=pygpc_extensions_include_path, + extra_compile_args=openmp_compile_args, + extra_link_args=openmp_link_args)] setup(name='pygpc', version='0.3.9',