Skip to content

Feat: Adding Linear Algebra Dot operation support #116

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

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 63 additions & 63 deletions .github/workflows/build_wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ on:
- "quaddtype-v*"
paths:
- "quaddtype/**"
- ".github/workflows/**"
pull_request:
paths:
- "quaddtype/**"
- ".github/workflows/**"
workflow_dispatch:

jobs:
Expand All @@ -19,12 +21,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ">=3.10.0"

- name: Verify QuadBLAS submodule
run: |
ls -la quaddtype/numpy_quaddtype/QBLAS/
ls -la quaddtype/numpy_quaddtype/QBLAS/include/quadblas/

- name: Install cibuildwheel
run: pip install cibuildwheel==2.20.0

Expand All @@ -34,16 +43,23 @@ jobs:
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
CIBW_BUILD_VERBOSITY: "3"
CIBW_BEFORE_ALL: |
yum update -y
yum install -y cmake gcc gcc-c++ make git pkgconfig
# Install SLEEF in container
git clone --branch 3.8 https://github.com/shibatch/sleef.git
cd sleef
cmake -S . -B build -DSLEEF_BUILD_QUAD:BOOL=ON -DSLEEF_BUILD_SHARED_LIBS:BOOL=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON
cmake -S . -B build \
-DSLEEF_BUILD_QUAD:BOOL=ON \
-DSLEEF_BUILD_SHARED_LIBS:BOOL=ON \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
cmake --build build/ --clean-first -j
cmake --install build --prefix /usr/local
CIBW_ENVIRONMENT: >
CFLAGS="-I/usr/local/include $CFLAGS"
CXXFLAGS="-I/usr/local/include $CXXFLAGS"
LDFLAGS="-L/usr/local/lib64 $LDFLAGS"
LD_LIBRARY_PATH="/usr/local/lib64:$LD_LIBRARY_PATH"
CFLAGS="-I/usr/local/include -I{project}/numpy_quaddtype/QBLAS/include $CFLAGS"
CXXFLAGS="-I/usr/local/include -I{project}/numpy_quaddtype/QBLAS/include -fext-numeric-literals $CXXFLAGS"
LDFLAGS="-L/usr/local/lib64 -L/usr/local/lib -Wl,-rpath,/usr/local/lib64 -Wl,-rpath,/usr/local/lib -fopenmp $LDFLAGS"
LD_LIBRARY_PATH="/usr/local/lib64:/usr/local/lib:$LD_LIBRARY_PATH"
PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
CIBW_REPAIR_WHEEL_COMMAND: |
auditwheel repair -w {dest_dir} --plat manylinux_2_28_x86_64 {wheel}
CIBW_TEST_COMMAND: |
Expand All @@ -68,46 +84,59 @@ jobs:

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Install dependencies
run: |
brew install cmake libomp git

- name: Install SLEEF
env:
MACOSX_DEPLOYMENT_TARGET: "11.0"
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os == 'macos-13' && '13.0' || '14.0' }}
run: |
git clone --branch 3.8 https://github.com/shibatch/sleef.git
cd sleef
cmake -S . -B build \
-DSLEEF_BUILD_QUAD:BOOL=ON \
-DSLEEF_BUILD_SHARED_LIBS:BOOL=ON \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
-DCMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.os == 'macos-13' && '13.0' || '14.0' }} \
-DCMAKE_INSTALL_RPATH="@loader_path/../lib" \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
cmake --build build/ --clean-first -j
sudo cmake --install build --prefix /usr/local

- name: Verify QuadBLAS submodule
run: |
ls -la quaddtype/numpy_quaddtype/QBLAS/
ls -la quaddtype/numpy_quaddtype/QBLAS/include/quadblas/

- name: Install cibuildwheel
run: pip install cibuildwheel==2.20.0

- name: Build wheels
env:
CIBW_BUILD: "cp310-* cp311-* cp312-*"
CIBW_ARCHS_MACOS: ${{ matrix.os == 'macos-13' && 'x86_64' || 'arm64' }}
CIBW_BUILD_VERBOSITY: "1"
CIBW_BUILD_VERBOSITY: "3"
CIBW_ENVIRONMENT: >
MACOSX_DEPLOYMENT_TARGET="11.0"
MACOSX_DEPLOYMENT_TARGET="${{ matrix.os == 'macos-13' && '13.0' || '14.0' }}"
DYLD_LIBRARY_PATH="/usr/local/lib:$DYLD_LIBRARY_PATH"
CFLAGS="-I/usr/local/include $CFLAGS"
CXXFLAGS="-I/usr/local/include $CXXFLAGS"
CFLAGS="-I/usr/local/include -I{project}/numpy_quaddtype/QBLAS/include $CFLAGS"
CXXFLAGS="-I/usr/local/include -I{project}/numpy_quaddtype/QBLAS/include $CXXFLAGS"
LDFLAGS="-L/usr/local/lib $LDFLAGS"
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
CIBW_REPAIR_WHEEL_COMMAND: >
delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}
CIBW_TEST_COMMAND: |
pip install {package}[test]
pytest {project}/tests
pytest -s {project}/tests
CIBW_TEST_EXTRAS: "test"
run: |
python -m cibuildwheel --output-dir wheelhouse
Expand All @@ -118,6 +147,7 @@ jobs:
path: ./quaddtype/wheelhouse/*.whl
name: wheels-${{ matrix.os }}

# disabling QBLAS optimization for windows due to incompatibility with MSVC
build_wheels_windows:
name: Build wheels on Windows
runs-on: windows-latest
Expand All @@ -127,6 +157,8 @@ jobs:

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
Expand All @@ -142,6 +174,12 @@ jobs:
- name: Install CMake
uses: lukka/get-cmake@latest

- name: Verify QuadBLAS submodule
shell: pwsh
run: |
Get-ChildItem quaddtype/numpy_quaddtype/QBLAS/
Get-ChildItem quaddtype/numpy_quaddtype/QBLAS/include/quadblas/

- name: Clone and Build SLEEF
shell: pwsh
run: |
Expand All @@ -151,16 +189,6 @@ jobs:
cmake --build build --config Release
cmake --install build --prefix "C:/sleef" --config Release

- name: Setup build environment
shell: pwsh
run: |
$env:INCLUDE += ";C:\sleef\include"
$env:LIB += ";C:\sleef\lib"
$env:PATH = "C:\sleef\bin;$env:PATH"
echo "INCLUDE=$env:INCLUDE" >> $env:GITHUB_ENV
echo "LIB=$env:LIB" >> $env:GITHUB_ENV
echo "PATH=$env:PATH" >> $env:GITHUB_ENV

- name: Install build dependencies
shell: bash -l {0}
run: |
Expand All @@ -177,10 +205,17 @@ jobs:
MSSdk: "1"
CIBW_BEFORE_BUILD: |
pip install meson meson-python ninja numpy
CIBW_ENVIRONMENT: >
INCLUDE="C:/sleef/include;{project}/numpy_quaddtype/QBLAS/include;$INCLUDE"
LIB="C:/sleef/lib;$LIB"
PATH="C:/sleef/bin;$PATH"
CFLAGS="/IC:/sleef/include /I{project}/numpy_quaddtype/QBLAS/include /DDISABLE_QUADBLAS $CFLAGS"
CXXFLAGS="/IC:/sleef/include /I{project}/numpy_quaddtype/QBLAS/include /DDISABLE_QUADBLAS $CXXFLAGS"
LDFLAGS="C:/sleef/lib/sleef.lib C:/sleef/lib/sleefquad.lib $LDFLAGS"
CIBW_REPAIR_WHEEL_COMMAND: 'delvewheel repair -w {dest_dir} {wheel} --add-path C:\sleef\bin'
CIBW_TEST_COMMAND: |
pip install {package}[test]
python -m pytest -v {project}/test
pytest -s {project}/tests
CIBW_TEST_EXTRAS: test
CIBW_TEST_FAIL_FAST: 1
shell: pwsh
Expand All @@ -199,56 +234,21 @@ jobs:
needs: [build_wheels_linux, build_wheels_macos, build_wheels_windows]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/quaddtype-v')

environment:
name: quadtype_release
url: https://pypi.org/p/numpy-quaddtype

permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all workflow run artifacts
uses: actions/download-artifact@v4
with:
path: dist

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/*

# With the current setup, we are not creating a release on GitHub.
# create_release:
# name: Create Release
# needs: [build_wheels_linux, build_wheels_macos, build_wheels_windows]
# runs-on: ubuntu-latest
# if: startsWith(github.ref, 'refs/tags/quaddtype-v')

# steps:
# - name: Checkout code
# uses: actions/checkout@v2

# - name: Download all workflow run artifacts
# uses: actions/download-artifact@v4
# with:
# path: artifacts

# - name: Create Release
# id: create_release
# uses: actions/create-release@v1
# env:
# GITHUB_TOKEN: ${{ secrets.QUADDTYPE_GITHUB_TOKEN }}
# with:
# tag_name: ${{ github.ref }}
# release_name: Release ${{ github.ref }}
# draft: false
# prerelease: false

# - name: Upload Release Assets
# uses: softprops/action-gh-release@v1
# if: startsWith(github.ref, 'refs/tags/')
# with:
# files: ./artifacts/**/*.whl
# env:
# GITHUB_TOKEN: ${{ secrets.QUADDTYPE_GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "quaddtype/numpy_quaddtype/QBLAS"]
path = quaddtype/numpy_quaddtype/QBLAS
url = https://github.com/SwayamInSync/QBLAS
5 changes: 4 additions & 1 deletion quaddtype/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ source temp/bin/activate
# Install the package
pip install meson-python numpy pytest

export LDFLAGS="-Wl,-rpath,$SLEEF_DIR/lib"
export LDFLAGS="-Wl,-rpath,$SLEEF_DIR/lib -fopenmp -latomic -lpthread"
export CFLAGS="-fPIC"
export CXXFLAGS="-fPIC"

python -m pip install . -v --no-build-isolation -Cbuilddir=build -C'compile-args=-v'

# Run the tests
Expand Down
14 changes: 12 additions & 2 deletions quaddtype/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@ incdir_numpy = run_command(py,
check : true
).stdout().strip()

# Add OpenMP dependency (optional, for threading)
openmp_dep = dependency('openmp', required: false)
dependencies = [sleef_dep, py_dep]
if openmp_dep.found()
dependencies += openmp_dep
endif

includes = include_directories(
[
incdir_numpy,
'numpy_quaddtype/QBLAS/include',
'numpy_quaddtype/src',
]
)
Expand All @@ -45,7 +53,9 @@ srcs = [
'numpy_quaddtype/src/umath.h',
'numpy_quaddtype/src/umath.cpp',
'numpy_quaddtype/src/dragon4.h',
'numpy_quaddtype/src/dragon4.c'
'numpy_quaddtype/src/dragon4.c',
'numpy_quaddtype/src/quadblas_interface.h',
'numpy_quaddtype/src/quadblas_interface.cpp'
]

py.install_sources(
Expand All @@ -60,7 +70,7 @@ py.extension_module('_quaddtype_main',
srcs,
link_args: is_windows ? ['/DEFAULTLIB:sleef', '/DEFAULTLIB:sleefquad'] : ['-lsleef', '-lsleefquad'],
link_language: 'cpp',
dependencies: [sleef_dep, py_dep],
dependencies: dependencies,
install: true,
subdir: 'numpy_quaddtype',
include_directories: includes
Expand Down
1 change: 1 addition & 0 deletions quaddtype/numpy_quaddtype/QBLAS
Submodule QBLAS added at 0eabb6
21 changes: 17 additions & 4 deletions quaddtype/numpy_quaddtype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@
QuadPrecision,
QuadPrecDType,
is_longdouble_128,
get_sleef_constant
get_sleef_constant,
qblas_dot as dot,
set_num_threads,
get_num_threads,
get_quadblas_version
)

import multiprocessing

__all__ = [
'QuadPrecision', 'QuadPrecDType', 'SleefQuadPrecision', 'LongDoubleQuadPrecision',
'SleefQuadPrecDType', 'LongDoubleQuadPrecDType', 'is_longdouble_128', 'pi', 'e',
'log2e', 'log10e', 'ln2', 'ln10', 'max_value', 'min_value', 'epsilon'
'SleefQuadPrecDType', 'LongDoubleQuadPrecDType', 'is_longdouble_128',
# Constants
'pi', 'e', 'log2e', 'log10e', 'ln2', 'ln10', 'max_value', 'min_value', 'epsilon',
# QuadBLAS related functions
'dot', 'set_num_threads', 'get_num_threads', 'get_quadblas_version'
]

def SleefQuadPrecision(value):
Expand All @@ -31,4 +40,8 @@ def LongDoubleQuadPrecDType():
ln10 = get_sleef_constant("ln10")
max_value = get_sleef_constant("quad_max")
min_value = get_sleef_constant("quad_min")
epsilon = get_sleef_constant("epsilon")
epsilon = get_sleef_constant("epsilon")

num_cores = multiprocessing.cpu_count()
# set default number of threads for QuadBLAS
set_num_threads(num_cores)
Loading
Loading