Python module mutli-platform setup (#519)

* Change to pyproject.toml file

* Switch to cmake for building the extension

* Update readme

* Update CHANGELOG

* Add hint fot CLBlast discovery

* Update README about detecting the library

* Switch to scikit-build-core for using CMake
pull/525/head
vathomass 2024-01-21 11:58:38 +02:00 committed by GitHub
parent 9535155ad8
commit 162783a414
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 126 additions and 75 deletions

View File

@ -6,6 +6,8 @@ Development version (next version)
* Convert float scalar values to cl_half for fp16 routines
* Amax/amin, max/min routines accept unsigned integer buffers for index
- Generator script now always use LF endings, independent of the platform
- Switch to pyproject.toml file for installing python bindings
- Build python binding using Cmake, adding Windows support
Version 1.6.1
- Fix pointer error in pyclblast on Arm

View File

@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.20)
project(${SKBUILD_PROJECT_NAME} LANGUAGES CXX)
# Find python and numpy
find_package(
Python3
REQUIRED
COMPONENTS Interpreter Development.Module NumPy
)
# Run the cython compiler
cmake_path(APPEND CMAKE_CURRENT_SOURCE_DIR "./src"
OUTPUT_VARIABLE Cython_SOURCE_DIR)
find_program(CYTHON "cython")
add_custom_command(
OUTPUT "${Cython_SOURCE_DIR}/pyclblast.cpp"
DEPENDS "${Cython_SOURCE_DIR}/pyclblast.pyx"
VERBATIM
COMMAND "${CYTHON}" -3 "${Cython_SOURCE_DIR}/pyclblast.pyx"
--output-file "${Cython_SOURCE_DIR}/pyclblast.cpp")
# Add module target
Python3_add_library(pyclblast MODULE WITH_SOABI
"${Cython_SOURCE_DIR}/pyclblast.cpp")
# Numpy libraries - NOTE: clean NPY_LIBRARIES cache (may fail for venv)
cmake_path(GET Python3_NumPy_INCLUDE_DIRS PARENT_PATH Python3_NumPy_CORE_DIR)
unset(NPY_LIBRARIES CACHE)
find_library(NPY_LIBRARIES
NAMES npymath
PATHS ${Python3_NumPy_CORE_DIR}
PATH_SUFFIXES lib
DOC "Numpy math library"
REQUIRED
NO_DEFAULT_PATH)
target_link_libraries(pyclblast PRIVATE ${NPY_LIBRARIES})
target_include_directories(pyclblast PRIVATE ${Python3_NumPy_INCLUDE_DIRS})
# CLBlast library
set(CLBLAST_HINTS
${CLBLAST_ROOT}
$ENV{CLBLAST_ROOT}
)
find_package(CLBlast CONFIG REQUIRED HINTS ${CLBLAST_HINTS})
target_link_libraries(pyclblast PRIVATE clblast)
install(TARGETS pyclblast DESTINATION .)
# In windows pyclblast cannot find the dll, even on path.
# Probably related to change in 3.8, that loads dll only for trusted location
# see https://stackoverflow.com/questions/41365446/how-to-resolve-importerror-dll-load-failed-on-python
# One workaround is to copy the dll to the same dir as the module.
# TODO: add python version check
if (WIN32)
cmake_path(APPEND CLBlast_DIR "../../../bin" OUTPUT_VARIABLE CLBlast_BINDIR)
cmake_path(SET CLBlast_BINDIR NORMALIZE "${CLBlast_BINDIR}")
unset(CLBlast_SHARED_LIBPATH CACHE)
find_file(CLBlast_SHARED_LIBPATH
NAMES clblast.dll
PATHS ${CLBlast_BINDIR}
DOC "CLBlast shared library"
REQUIRED)
# copy dll to build
install(FILES ${CLBlast_SHARED_LIBPATH} DESTINATION .)
endif()

View File

@ -1,2 +1,3 @@
include README.md setup.py src/*.pyx
include README.md src/*.pyx
include samples/*.py
include CMakeLists.txt

View File

@ -15,29 +15,39 @@ Non-Python requirements:
* OpenCL
* [CLBlast](https://github.com/CNugteren/CLBlast)
Python requirements:
* Cython
* [PyOpenCL](https://github.com/pyopencl/pyopencl/)
Getting started
-------------
After installation OpenCL and CLBlast, simply use pip to install PyCLBlast, e.g.:
After installing OpenCL and CLBlast, simply use pip to install PyCLBlast, e.g.:
pip install --user pyclblast
To start using the library, browse the [CLBlast](https://github.com/CNugteren/CLBlast) documentation or check out the PyCLBlast samples provides in the `samples` subfolder.
To start using the library, browse the [CLBlast](https://github.com/CNugteren/CLBlast) documentation or check out the PyCLBlast samples provided in the `samples` subfolder.
For developers, first install CLBlast, followed by the Python requirements (e.g. in a Python3 virtualenv):
For developers, install CLBlast and [cython](https://cython.org/) (e.g. in a Python3 virtualenv):
pip install Cython numpy pybind11
pip install pyopencl
pip install Cython
And then compile the library from this location using the `setup.py` file:
And then compile the bindings from this location using pip:
python setup.py install
pip install .
Detecting CLBlast
-------------
The CLBlast library should be present and detectable to your system, to successfully install the PyCLBlast bindings. In some systems, this is done automatically. But if the CLBlast library cannot be detected, the PyCLBlast installation will fail. To ensure detection, one can apply either of the following:
* Add the CLBLast root directory to the environment path.
* Create the environment variable `CLBLAST_ROOT` that holds the path to the CLBLast root directory.
* Define the `cmake` variables `CMAKE_PREFIX_PATH` or the `CLBLAST_ROOT` variable that point to the CLBlast root directory, as:
pip install . -C skbuild.cmake.args="-DCMAKE_PREFIX_PATH=/root/path/to/clblast"
* Create the environment variable `CLBlast_DIR` that holds the path to the directory where either of the `CLBlastConfig.cmake` or `clblast-config.cmake` files reside.
Note that the aforementioned environment variables should be set only during the installation of PyCLBlast and can be unset during normal use.
Testing PyCLBlast
@ -53,6 +63,6 @@ How to release a new version on PyPi
Following [the guide](https://packaging.python.org/tutorials/packaging-projects/), in essence doing (after changing the version number in `setup.py`):
python3 setup.py sdist bdist_wheel
python3 -m build
python3 -m twine upload --repository pypi dist/pyclblast-1.4.0.tar.gz
# use '__token__' as username and supply the token from your PyPi account

View File

@ -0,0 +1,32 @@
[build-system]
requires = ["scikit-build-core", "cython", "numpy"]
build-backend = "scikit_build_core.build"
[project]
name = "pyclblast"
version = "1.4.0"
description = "Python bindings for CLBlast, the tuned OpenCL BLAS library"
authors = [
{name = "Cedric Nugteren", email = "web@cedricnugteren.nl"}
]
license = {text = "Apache Software License"}
readme = "README.md"
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
]
keywords = ["OpenCL", "BLAS", "CLBlast", "GEMM", "matrix-multiplication"]
dependencies = [
"numpy",
"pyopencl"
]
[project.urls]
Homepage = "https://github.com/CNugteren/CLBlast/blob/master/src/pyclblast"
[tool.setuptools.packages.find]
where = ["src"]

View File

@ -1,61 +0,0 @@
# This file is part of the CLBlast project. The project is licensed under Apache Version 2.0.
# This file follows the PEP8 Python style guide and uses a max-width of 100 characters per line.
#
# Author(s):
# Cedric Nugteren <www.cedricnugteren.nl>
from setuptools import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import platform
import numpy
import os
np_incdir = numpy.get_include()
np_libdir = os.path.join(np_incdir, '..', 'lib', '')
runtime_library_dirs = list()
if platform.system() == "Linux":
runtime_library_dirs.append("/usr/local/lib")
elif platform.system() == "Windows":
runtime_library_dirs.append("C:/Program Files/clblast/lib")
runtime_library_dirs.append("C:/Program Files (x86)/clblast/lib")
ext_modules = list()
ext_modules.append(
Extension(
"pyclblast",
["src/pyclblast.pyx"],
libraries=["clblast", "npymath"],
runtime_library_dirs=runtime_library_dirs,
library_dirs=[np_libdir],
include_dirs=[np_incdir],
language="c++"
)
)
setup(
name="pyclblast",
version="1.4.0",
author="Cedric Nugteren",
author_email="web@cedricnugteren.nl",
url="https://github.com/CNugteren/CLBlast/blob/master/src/pyclblast",
description="Python bindings for CLBlast, the tuned OpenCL BLAS library",
license="Apache Software License",
requires=["numpy", "pyopencl", "cython"],
package_dir={'': 'src'},
scripts=[],
ext_modules=ext_modules,
cmdclass={"build_ext": build_ext},
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Topic :: Software Development :: Libraries',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
],
keywords="OpenCL BLAS CLBlast GEMM matrix-multiplication"
)