Skip to content

Commit 1365331

Browse files
Merge pull request #5 from flaviomartins/update_build_1
Update build review
2 parents 690a7e6 + 552085a commit 1365331

43 files changed

Lines changed: 2702 additions & 1301 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/buildwheels.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Build and upload wheels
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v[0-9]+\.[0-9]+\.[0-9]+'
7+
pull_request: # Test builds on PR
8+
workflow_dispatch: # Allows manual triggering
9+
10+
# The Python project lives in the python_bindings/ subdirectory and reaches the
11+
# C++ sources through a `fastpfor` symlink to the repository root. That symlink
12+
# is fine for local builds but does not survive being copied into cibuildwheel's
13+
# build containers (and is not preserved on Windows checkouts). To stay portable
14+
# we build a self-contained sdist first (it bundles the real header/source
15+
# files) and build every wheel from that extracted sdist.
16+
jobs:
17+
build_sdist:
18+
name: Build source distribution
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v7
22+
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@v10.0.1
25+
26+
- name: Build sdist
27+
run: uv build --sdist
28+
working-directory: python_bindings
29+
30+
- uses: actions/upload-artifact@v7
31+
with:
32+
name: sdist-artifact
33+
path: python_bindings/dist/*.tar.gz
34+
if-no-files-found: error
35+
36+
build_wheels:
37+
name: Build wheels on ${{ matrix.os }}
38+
needs: build_sdist
39+
runs-on: ${{ matrix.os }}
40+
strategy:
41+
fail-fast: false
42+
matrix:
43+
# Native runners for each architecture we publish: x86_64 Linux,
44+
# aarch64 Linux, x86_64 macOS, Apple Silicon macOS, and x86_64 Windows.
45+
os: [ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-latest, windows-latest]
46+
47+
steps:
48+
- uses: actions/download-artifact@v8
49+
with:
50+
name: sdist-artifact
51+
path: dist
52+
53+
- name: Unpack sdist
54+
shell: bash
55+
run: |
56+
mkdir -p sdist_src
57+
tar -xzf dist/*.tar.gz -C sdist_src --strip-components=1
58+
59+
- name: Build wheels
60+
uses: pypa/cibuildwheel@v4.2.1
61+
with:
62+
package-dir: sdist_src
63+
64+
- uses: actions/upload-artifact@v7
65+
with:
66+
name: wheel-artifact-${{ matrix.os }}
67+
path: ./wheelhouse/*.whl
68+
if-no-files-found: error
69+
70+
upload_pypi:
71+
needs: [build_wheels, build_sdist]
72+
runs-on: ubuntu-latest
73+
# Only upload to PyPI when triggered by a tag (not manual workflow_dispatch).
74+
if: startsWith(github.ref, 'refs/tags/')
75+
steps:
76+
- uses: actions/download-artifact@v8
77+
with:
78+
path: dist
79+
merge-multiple: true
80+
81+
- uses: pypa/gh-action-pypi-publish@v1.14.2
82+
with:
83+
user: __token__
84+
password: ${{ secrets.PYPI_API_TOKEN }}

.gitignore

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C/C++ extensions and objects
7+
*.so
8+
*.o
9+
*.a
10+
11+
# Distribution / packaging
12+
.Python
13+
env/
14+
venv/
15+
build/
16+
develop-eggs/
17+
dist/
18+
eggs/
19+
.eggs/
20+
sdist/
21+
var/
22+
wheels/
23+
wheelhouse/
24+
*.egg-info/
25+
*.egg
26+
27+
# CMake build directories
28+
cmake-build-*/
29+
30+
# Editor / OS cruft
31+
.DS_Store
32+
*.swp

.travis.yml

Lines changed: 0 additions & 63 deletions
This file was deleted.

CMakeLists.txt

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
# Apache License Version 2.0 http://www.apache.org/licenses/.
44
#
55
# This is a modified version of the CMakeFile
6-
# for the project https://github.com/lemire/FastPFor
7-
# This file can be used to
6+
# for the project https://github.com/lemire/FastPFor
7+
# This file can be used to
88
# 1) Build a library separately. Then, this library
99
# will be re-used by the Python build process
1010
# 2) Build and run unit and performance tests.
1111
#
12-
cmake_minimum_required(VERSION 2.8.7)
12+
cmake_minimum_required(VERSION 3.10)
1313
if (NOT CMAKE_BUILD_TYPE)
1414
message(STATUS "No build type selected, default to Release")
1515
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
@@ -21,7 +21,7 @@ include(AppendCompilerFlags)
2121

2222

2323
project(PyFastPFor CXX C)
24-
set(PROJECT_URL "https://github.com/searchivarius/PyFastPFOR")
24+
set(PROJECT_URL "https://github.com/fast-pack/PyFastPFOR")
2525
set(PROJECT_DESCRIPTION "Python bindings for the FastPFOR C++ library: Fast integer compression")
2626
include(DetectCPUFeatures)
2727
#
@@ -54,8 +54,10 @@ MESSAGE( STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER} )
5454
MESSAGE( STATUS "CXX_COMPILER_VERSION: " ${CXX_COMPILER_VERSION} )
5555
if( SUPPORT_SSE42 )
5656
MESSAGE( STATUS "SSE 4.2 support detected" )
57+
elseif( SUPPORT_NEON )
58+
MESSAGE( STATUS "ARM NEON detected: SSE intrinsics are emulated via fastpfor_neon.h" )
5759
else()
58-
MESSAGE( STATUS "SSE 4.2 support not detected" )
60+
MESSAGE( STATUS "Neither SSE 4.2 nor ARM NEON support detected" )
5961
endif()
6062

6163
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
@@ -79,14 +81,21 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
7981
set (CMAKE_CXX_FLAGS_DEBUG "-Wall -ggdb -std=c++11 -DHAVE_CXX0X -march=native")
8082
set (CMAKE_C_FLAGS_RELEASE "-Wall -Ofast -DNDEBUG -std=c99 -march=native")
8183
set (CMAKE_C_FLAGS_DEBUG "-Wall -ggdb -std=c99 -march=native")
82-
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
84+
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
8385
if (CXX_COMPILER_VERSION VERSION_LESS 4.2.1)
8486
message(STATUS "Clang version must be at least 4.2.1!" )
8587
endif()
86-
set (CMAKE_CXX_FLAGS_RELEASE "-Wall -Wcast-align -O3 -DNDEBUG -std=c++11 -DHAVE_CXX0X -msse4.1 -march=native")
87-
set (CMAKE_CXX_FLAGS_DEBUG "-Wall -Wcast-align -ggdb -std=c++11 -DHAVE_CXX0X -msse4.1 -march=native")
88-
set (CMAKE_C_FLAGS_RELEASE "-Wall -Wcast-align -O3 -DNDEBUG -std=c99 -msse4.1 -march=native")
89-
set (CMAKE_C_FLAGS_DEBUG "-Wall -Wcast-align -ggdb -std=c99 -msse4.1 -march=native")
88+
# -msse4.1 is x86-only and rejected on ARM; -march=native already enables the
89+
# available SIMD (SSE/AVX on x86, NEON on ARM), so only add it off ARM.
90+
if (SUPPORT_NEON)
91+
set (SIMD_FLAGS "-march=native")
92+
else()
93+
set (SIMD_FLAGS "-msse4.1 -march=native")
94+
endif()
95+
set (CMAKE_CXX_FLAGS_RELEASE "-Wall -Wcast-align -O3 -DNDEBUG -std=c++11 -DHAVE_CXX0X ${SIMD_FLAGS}")
96+
set (CMAKE_CXX_FLAGS_DEBUG "-Wall -Wcast-align -ggdb -std=c++11 -DHAVE_CXX0X ${SIMD_FLAGS}")
97+
set (CMAKE_C_FLAGS_RELEASE "-Wall -Wcast-align -O3 -DNDEBUG -std=c99 ${SIMD_FLAGS}")
98+
set (CMAKE_C_FLAGS_DEBUG "-Wall -Wcast-align -ggdb -std=c99 ${SIMD_FLAGS}")
9099
elseif(WIN32)
91100
# TODO add support for later versions?
92101
if(NOT MSVC12)

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ or via pip:
1919
```
2020
pip install pyfastpfor
2121
```
22-
Due to some compilation quirks this currently seem to work with GCC only. I will fix it in some not so distant future. You may also need to install Python dev-files. On Ubuntu, for Python 3 you can do it as follows:
22+
The bindings build with GCC or Clang, on both x86-64 (SSE/AVX) and ARM/aarch64 (NEON, including Apple Silicon). You may also need to install Python dev-files. On Ubuntu, for Python 3 you can do it as follows:
2323

2424
```
2525
sudo apt-get install python3-dev
@@ -28,7 +28,7 @@ sudo apt-get install python3-dev
2828

2929
# Documentation
3030

31-
The library supports all the codecs implemented in the original [FastPFor](https://github.com/lemire/FastPFor) library by July 2023. To get a list of codecs, use the function ``getCodecList``.
31+
The library supports all the codecs implemented in the original [FastPFor](https://github.com/lemire/FastPFor) library (v0.5.0). To get a list of codecs, use the function ``getCodecList``.
3232

3333
Typical light-weight compression does not take context into account and, consequently, works well only for small integers. When integers are large, data differencing is a common trick to make integers small. In particular, we often deal with sorted lists of integers, which can be represented by differences between neighboring numbers.
3434

cmake_modules/DetectCPUFeatures.cmake

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,17 @@ else()
4747
check_cxx_source_compiles("${AVXPROG}" SUPPORT_AVX)
4848
set(CMAKE_REQUIRED_FLAGS "-march=native -mavx2")
4949
check_cxx_source_compiles("${AVX2PROG}" SUPPORT_AVX2)
50-
endif()
50+
endif()
5151

5252
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
53+
54+
# On ARM the SSE intrinsics used throughout FastPFor are provided by the
55+
# fastpfor_neon.h shim (mapped onto NEON), so there is no SSE4.2 support but the
56+
# code still compiles. Flag ARM builds so the SIMD-specific compiler options
57+
# (e.g. -msse4.1) can be skipped.
58+
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm"
59+
OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64"
60+
OR CMAKE_GENERATOR_PLATFORM MATCHES "ARM64" OR CMAKE_GENERATOR_PLATFORM MATCHES "ARM")
61+
set(SUPPORT_NEON ON)
62+
endif ()
5363

headers/VarIntG8IU.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* This code is released under the
33
* Apache License Version 2.0 http://www.apache.org/licenses/.
44
*/
5-
#if !defined(__SSSE3__) && !(defined(_MSC_VER) && defined(__AVX__))
5+
#if (!defined(__SSSE3__) && !(defined(_MSC_VER) && defined(__AVX__))) && !(defined(__ARM_NEON) || defined(__aarch64__))
66
#ifndef _MSC_VER
77
#pragma message \
88
"Disabling varintg8iu due to lack of SSSE3 support, try adding -mssse3 or the equivalent on your compiler"
@@ -12,7 +12,12 @@
1212
#else
1313
#ifndef VARINTG8IU_H__
1414
#define VARINTG8IU_H__
15+
#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
1516
#include <emmintrin.h>
17+
#elif defined(__aarch64__)
18+
/* GCC-compatible compiler, targeting ARM with native NEON */
19+
#include "fastpfor_neon.h"
20+
#endif
1621
#include "codecs.h"
1722
#ifdef __GNUC__
1823
#define PREDICT_FALSE(x) (__builtin_expect(x, 0))

headers/blockpacking.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class ByteAlignedPacking : public IntegerCODEC {
286286

287287
const uint32_t *decodeArray(const uint32_t *in, const size_t length,
288288
uint32_t *out, size_t &nvalue) {
289+
(void)length;
289290
const uint32_t actuallength = *in++;
290291
const uint8_t *inbyte = reinterpret_cast<const uint8_t *>(in);
291292
const uint32_t *const initout(out);

headers/codecfactory.h

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,54 @@ class CODECFactory {
2121
public:
2222
CODECFactory();
2323

24-
std::vector<std::shared_ptr<IntegerCODEC>> allSchemes();
24+
std::vector<std::shared_ptr<IntegerCODEC>> allSchemes() const;
2525

26-
std::vector<std::string> allNames();
26+
std::vector<std::string> allNames() const;
2727

28-
std::shared_ptr<IntegerCODEC> &getFromName(std::string name);
28+
std::shared_ptr<IntegerCODEC> const& getFromName(std::string name) const;
2929
private:
3030
CodecMap scodecmap;
3131
};
3232

33+
std::unique_ptr<IntegerCODEC> fastbinarypacking8_codec();
34+
std::unique_ptr<IntegerCODEC> fastbinarypacking16_codec();
35+
std::unique_ptr<IntegerCODEC> fastbinarypacking32_codec();
36+
std::unique_ptr<IntegerCODEC> BP32_codec();
37+
std::unique_ptr<IntegerCODEC> vsencoding_codec();
38+
std::unique_ptr<IntegerCODEC> fastpfor128_codec();
39+
std::unique_ptr<IntegerCODEC> fastpfor256_codec();
40+
std::unique_ptr<IntegerCODEC> simdfastpfor128_codec();
41+
std::unique_ptr<IntegerCODEC> simdfastpfor256_codec();
42+
std::unique_ptr<IntegerCODEC> simplepfor_codec();
43+
std::unique_ptr<IntegerCODEC> simdsimplepfor_codec();
44+
std::unique_ptr<IntegerCODEC> pfor_codec();
45+
std::unique_ptr<IntegerCODEC> simdpfor_codec();
46+
std::unique_ptr<IntegerCODEC> pfor2008_codec();
47+
std::unique_ptr<IntegerCODEC> simdnewpfor_codec();
48+
std::unique_ptr<IntegerCODEC> newpfor_codec();
49+
std::unique_ptr<IntegerCODEC> optpfor_codec();
50+
std::unique_ptr<IntegerCODEC> simdoptpfor_codec();
51+
std::unique_ptr<IntegerCODEC> varint_codec();
52+
std::unique_ptr<IntegerCODEC> vbyte_codec();
53+
std::unique_ptr<IntegerCODEC> maskedvbyte_codec();
54+
std::unique_ptr<IntegerCODEC> streamvbyte_codec();
55+
std::unique_ptr<IntegerCODEC> varintgb_codec();
56+
std::unique_ptr<IntegerCODEC> simple16_codec();
57+
std::unique_ptr<IntegerCODEC> simple9_codec();
58+
std::unique_ptr<IntegerCODEC> simple9_rle_codec();
59+
std::unique_ptr<IntegerCODEC> simple8b_codec();
60+
std::unique_ptr<IntegerCODEC> simple8b_rle_codec();
61+
#ifdef VARINTG8IU_H__
62+
std::unique_ptr<IntegerCODEC> varintg8iu_codec();
63+
#endif
64+
#ifdef USESNAPPY
65+
std::unique_ptr<IntegerCODEC> snappy_codec();
66+
#endif
67+
std::unique_ptr<IntegerCODEC> simdbinarypacking_codec();
68+
std::unique_ptr<IntegerCODEC> simdgroupsimple_codec();
69+
std::unique_ptr<IntegerCODEC> simdgroupsimple_ringbuf_codec();
70+
std::unique_ptr<IntegerCODEC> copy_codec();
71+
3372
} // namespace FastPForLib
3473

3574
#endif /* CODECFACTORY_H_ */

headers/codecs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ class IntegerCODEC {
5353
* of the variable nvalue gets updated with the number actually use
5454
* (if nvalue exceeds the original value, there might be a buffer
5555
* overrun).
56+
*
57+
* NOTE: Decoding can be performed with an unknown input length. This
58+
* case is indicated by a length of 0; however, nvalue must be provided
59+
* in order for the decoder knows how many values to decode.
5660
*/
5761
virtual const uint32_t *decodeArray(const uint32_t *in, const size_t length,
5862
uint32_t *out, size_t &nvalue) = 0;

0 commit comments

Comments
 (0)