Skip to content

Commit b7d7f61

Browse files
committed
arm update
1 parent 1e61945 commit b7d7f61

21 files changed

Lines changed: 832 additions & 19 deletions

.github/workflows/ubuntu-arm.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: "Ubuntu 24.04 ARM64 CI (NEON)"
2+
on: [push, pull_request]
3+
4+
5+
jobs:
6+
make-arm:
7+
name: "make (SSE intrinsics mapped to ARM NEON)"
8+
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]') && ! contains(toJSON(github.event.commits.*.message), '[skip github]')"
9+
runs-on: ubuntu-24.04-arm
10+
steps:
11+
- uses: actions/checkout@v4
12+
- name: "Build and test"
13+
run: make && ./unit
14+
15+
cmake-arm:
16+
name: "cmake + ctest + install"
17+
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]') && ! contains(toJSON(github.event.commits.*.message), '[skip github]')"
18+
runs-on: ubuntu-24.04-arm
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: "Configure"
22+
run: cmake -S . -B build -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/_install
23+
- name: "Build"
24+
run: cmake --build build -j
25+
- name: "Test"
26+
run: ctest --test-dir build --output-on-failure
27+
- name: "Install"
28+
run: cmake --install build
29+
- name: "Consume via find_package"
30+
run: |
31+
cmake -S tests/find_package -B build_consumer \
32+
-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/_install
33+
cmake --build build_consumer
34+
./build_consumer/consumer

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ compflatstat
66
compress
77
entropy
88
*.o
9+
ramtocache
910
simplesynth
1011
testcodecs
1112
testintegration
1213
uncompress
1314
unit
1415
*.a
16+
build/
17+
build_consumer/
18+
_install/

CMakeLists.txt

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
3+
project(SIMDCompressionAndIntersection
4+
VERSION 0.1.0
5+
LANGUAGES C CXX)
6+
7+
# ---------------------------------------------------------------------------
8+
# Standards
9+
# ---------------------------------------------------------------------------
10+
set(CMAKE_C_STANDARD 99)
11+
set(CMAKE_C_STANDARD_REQUIRED ON)
12+
set(CMAKE_CXX_STANDARD 11)
13+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
14+
15+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
16+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
17+
endif()
18+
19+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
20+
21+
# Is this the top-level project, or are we being added via add_subdirectory()?
22+
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
23+
set(SIMDCOMP_IS_TOP_LEVEL ON)
24+
else()
25+
set(SIMDCOMP_IS_TOP_LEVEL OFF)
26+
endif()
27+
28+
option(SIMDCOMP_BUILD_TESTS
29+
"Build the test, benchmark and example executables" ${SIMDCOMP_IS_TOP_LEVEL})
30+
option(SIMDCOMP_INSTALL
31+
"Generate install rules for SIMDCompressionAndIntersection" ${SIMDCOMP_IS_TOP_LEVEL})
32+
33+
# Defines CMAKE_INSTALL_{LIB,INCLUDE,BIN}DIR; needed before they are referenced
34+
# in the library's INSTALL_INTERFACE include directories below.
35+
include(GNUInstallDirs)
36+
37+
# Release builds define NDEBUG (disabling assertions), which is the CMake
38+
# default for the Release / RelWithDebInfo / MinSizeRel configurations.
39+
40+
# ---------------------------------------------------------------------------
41+
# SIMD flags
42+
#
43+
# On x86/x64 the code is built for AVX (AVX itself is not required at runtime,
44+
# but the default build assumes it, matching the Makefile). On AArch64 the SSE
45+
# intrinsics are mapped to ARM NEON via include/neon_sse.h, and NEON is baseline
46+
# so no architecture flag is needed.
47+
# ---------------------------------------------------------------------------
48+
set(SIMD_FLAGS "")
49+
if(NOT MSVC)
50+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(^|;)(x86_64|amd64|AMD64|i.86|x86)$")
51+
set(SIMD_FLAGS -mavx)
52+
endif()
53+
endif()
54+
55+
if(NOT MSVC)
56+
add_compile_options(
57+
${SIMD_FLAGS}
58+
-Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith
59+
-Winit-self -Wno-sign-conversion)
60+
# -Weffc++ and -pedantic only on the C++ sources (matches the Makefile).
61+
add_compile_options(
62+
$<$<COMPILE_LANGUAGE:CXX>:-Weffc++>
63+
$<$<COMPILE_LANGUAGE:CXX>:-pedantic>
64+
$<$<COMPILE_LANGUAGE:C>:-pedantic>)
65+
else()
66+
add_compile_options(/arch:AVX)
67+
endif()
68+
69+
# ---------------------------------------------------------------------------
70+
# Library
71+
# ---------------------------------------------------------------------------
72+
set(SIMDCOMP_SOURCES
73+
src/codecfactory.cpp
74+
src/bitpacking.cpp
75+
src/integratedbitpacking.cpp
76+
src/simdbitpacking.cpp
77+
src/usimdbitpacking.cpp
78+
src/simdintegratedbitpacking.cpp
79+
src/intersection.cpp
80+
src/varintdecode.c
81+
src/streamvbyte.c
82+
src/simdpackedsearch.c
83+
src/simdpackedselect.c
84+
src/frameofreference.cpp
85+
src/for.c)
86+
87+
add_library(SIMDCompressionAndIntersection STATIC ${SIMDCOMP_SOURCES})
88+
# Same-name namespaced alias so consumers can use the identical target name
89+
# whether they add_subdirectory() this project or find_package() an install.
90+
add_library(SIMDCompressionAndIntersection::SIMDCompressionAndIntersection
91+
ALIAS SIMDCompressionAndIntersection)
92+
target_include_directories(SIMDCompressionAndIntersection PUBLIC
93+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
94+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SIMDCompressionAndIntersection>)
95+
96+
# ---------------------------------------------------------------------------
97+
# Test / benchmark / example executables (optional)
98+
# ---------------------------------------------------------------------------
99+
if(SIMDCOMP_BUILD_TESTS)
100+
foreach(prog unit testcodecs testintegration benchintersection benchsearch)
101+
add_executable(${prog} src/${prog}.cpp)
102+
target_link_libraries(${prog} PRIVATE SIMDCompressionAndIntersection)
103+
endforeach()
104+
105+
add_executable(example example.cpp)
106+
target_link_libraries(example PRIVATE SIMDCompressionAndIntersection)
107+
108+
# Advanced benchmarking tools
109+
foreach(prog simplesynth compress uncompress budgetedtest ramtocache entropy compflatstat)
110+
add_executable(${prog} advancedbenchmarking/src/${prog}.cpp)
111+
target_link_libraries(${prog} PRIVATE SIMDCompressionAndIntersection)
112+
target_include_directories(${prog} PRIVATE
113+
${CMAKE_CURRENT_SOURCE_DIR}/advancedbenchmarking/include)
114+
endforeach()
115+
116+
enable_testing()
117+
add_test(NAME unit COMMAND unit)
118+
add_test(NAME testintegration COMMAND testintegration)
119+
endif()
120+
121+
# ---------------------------------------------------------------------------
122+
# Installation
123+
# ---------------------------------------------------------------------------
124+
if(SIMDCOMP_INSTALL)
125+
include(CMakePackageConfigHelpers)
126+
127+
set(SIMDCOMP_INSTALL_CMAKEDIR
128+
"${CMAKE_INSTALL_LIBDIR}/cmake/SIMDCompressionAndIntersection"
129+
CACHE STRING "Path (relative to prefix) to install the CMake package config")
130+
131+
# Library + export set.
132+
install(TARGETS SIMDCompressionAndIntersection
133+
EXPORT SIMDCompressionAndIntersectionTargets
134+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
135+
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
136+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
137+
138+
# Public headers (flat layout, matching the in-tree include/ directory).
139+
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
140+
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/SIMDCompressionAndIntersection"
141+
FILES_MATCHING PATTERN "*.h")
142+
143+
# Exported targets file -> SIMDCompressionAndIntersection::SIMDCompressionAndIntersection
144+
install(EXPORT SIMDCompressionAndIntersectionTargets
145+
FILE SIMDCompressionAndIntersectionTargets.cmake
146+
NAMESPACE SIMDCompressionAndIntersection::
147+
DESTINATION "${SIMDCOMP_INSTALL_CMAKEDIR}")
148+
149+
# Package config + version files, so find_package() works.
150+
configure_package_config_file(
151+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/SIMDCompressionAndIntersectionConfig.cmake.in"
152+
"${CMAKE_CURRENT_BINARY_DIR}/SIMDCompressionAndIntersectionConfig.cmake"
153+
INSTALL_DESTINATION "${SIMDCOMP_INSTALL_CMAKEDIR}")
154+
155+
write_basic_package_version_file(
156+
"${CMAKE_CURRENT_BINARY_DIR}/SIMDCompressionAndIntersectionConfigVersion.cmake"
157+
VERSION "${PROJECT_VERSION}"
158+
COMPATIBILITY SameMajorVersion)
159+
160+
install(FILES
161+
"${CMAKE_CURRENT_BINARY_DIR}/SIMDCompressionAndIntersectionConfig.cmake"
162+
"${CMAKE_CURRENT_BINARY_DIR}/SIMDCompressionAndIntersectionConfigVersion.cmake"
163+
DESTINATION "${SIMDCOMP_INSTALL_CMAKEDIR}")
164+
endif()

Makefile

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@ else
1616
endif # debug
1717
else #intel
1818
CXX ?= g++-4.7
19+
# On x86 we target AVX; on ARM (AArch64) NEON is baseline, so no -m flag is
20+
# needed (the SSE intrinsics are mapped to NEON via include/neon_sse.h).
21+
ARCH := $(shell uname -m)
22+
ifneq (,$(filter x86_64 amd64 i386 i686,$(ARCH)))
23+
SIMDFLAGS ?= -mavx
24+
else
25+
SIMDFLAGS ?=
26+
endif
1927
ifeq ($(DEBUG),1)
20-
CXXFLAGS = -fpic -mavx -std=c++11 -Weffc++ -pedantic -ggdb -DDEBUG=1 -D_GLIBCXX_DEBUG -Wall -Wextra -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
21-
CCFLAGS = -fpic -mavx -std=c99 -pedantic -ggdb -DDEBUG=1 -D_GLIBCXX_DEBUG -Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
28+
CXXFLAGS = -fpic $(SIMDFLAGS) -std=c++11 -Weffc++ -pedantic -ggdb -DDEBUG=1 -D_GLIBCXX_DEBUG -Wall -Wextra -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
29+
CCFLAGS = -fpic $(SIMDFLAGS) -std=c99 -pedantic -ggdb -DDEBUG=1 -D_GLIBCXX_DEBUG -Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
2230
else
23-
CXXFLAGS = -fpic -mavx -std=c++11 -Weffc++ -pedantic -O3 -Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
24-
CCFLAGS = -fpic -mavx -std=c99 -pedantic -O3 -Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
31+
CXXFLAGS = -fpic $(SIMDFLAGS) -std=c++11 -Weffc++ -pedantic -O3 -DNDEBUG=1 -Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
32+
CCFLAGS = -fpic $(SIMDFLAGS) -std=c99 -pedantic -O3 -DNDEBUG=1 -Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion
2533
endif #debug
2634
endif #intel
2735

README.md

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,42 @@ To run tests, you can do
7070
(follow the instructions)
7171

7272

73+
Building and installing with CMake
74+
------------------------
75+
76+
A CMake build is also provided. It works on x86/x64 (SSE/AVX) and on 64-bit ARM
77+
(the SSE intrinsics are mapped to ARM NEON), and it builds the same library and
78+
tests as the Makefile.
79+
80+
```
81+
cmake -S . -B build
82+
cmake --build build
83+
ctest --test-dir build # runs the unit tests
84+
```
85+
86+
To install the library, headers and a CMake package configuration:
87+
88+
```
89+
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/your/prefix -DSIMDCOMP_BUILD_TESTS=OFF
90+
cmake --build build
91+
cmake --install build
92+
```
93+
94+
Downstream CMake projects can then locate it with `find_package` and link the
95+
imported target:
96+
97+
```cmake
98+
find_package(SIMDCompressionAndIntersection REQUIRED)
99+
target_link_libraries(yourapp PRIVATE
100+
SIMDCompressionAndIntersection::SIMDCompressionAndIntersection)
101+
```
102+
103+
The installed headers live under `<prefix>/include/SIMDCompressionAndIntersection`
104+
and are added to your include path by the imported target, so `#include
105+
<codecfactory.h>` works directly. Useful options: `-DSIMDCOMP_BUILD_TESTS=OFF`
106+
to skip the tests/benchmarks and `-DSIMDCOMP_INSTALL=OFF` to disable install
107+
rules (handy when consuming the project via `add_subdirectory`).
108+
73109

74110
Usage (Windows users)
75111
------------------------
@@ -125,18 +161,26 @@ As far as the authors know, this work is patent-free.
125161
Requirements
126162
------------------------
127163

128-
A CPU (AMD or Intel) with support for SSE2 (Pentium 4 or better) is required
129-
while a CPU with SSE 4.1* (Penryn [2007] processors or better) is recommended.
164+
On x86/x64, a CPU (AMD or Intel) with support for SSE2 (Pentium 4 or better) is
165+
required while a CPU with SSE 4.1* (Penryn [2007] processors or better) is
166+
recommended.
130167

168+
On 64-bit ARM (AArch64, e.g. Apple Silicon and ARM servers), the SSE intrinsics
169+
are mapped to ARM NEON via `include/neon_sse.h`, so no x86 hardware is needed.
170+
NEON is baseline on AArch64, so no special compiler flag is required.
131171

132172
A recent GCC (4.7 or better), Clang, Intel or Visual C++ compiler.
133173

134-
A processor support AVX (Intel or AMD).
174+
On x86, a processor supporting AVX (Intel or AMD) is assumed by the default
175+
makefile (but AVX is not required, see below).
135176

136-
Tested on Linux, MacOS and Windows. It should be portable to other platforms.
177+
Tested on Linux, MacOS and Windows, on both x64 and ARM64. It should be portable
178+
to other platforms.
137179

138-
*- The default makefile might assume AVX support, but AVX is not required. For GCC
139-
compilers, you might need the -msse2 flag, but you will not need the -mavx flag.
180+
*- On x86, the default makefile might assume AVX support, but AVX is not
181+
required. For GCC compilers, you might need the -msse2 flag, but you will not
182+
need the -mavx flag. On ARM64 the makefile automatically drops the x86 `-mavx`
183+
flag.
140184

141185
For advanced benchmarking, please see
142186

advancedbenchmarking/src/budgetedtest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ class TestHelper {
433433
}
434434
assert(i == onePost.end());
435435
assert(sanitycheck == onePost.size());
436+
(void)sanitycheck;
436437
compPostings.emplace(id, subposts);
437438
uncompsizes.emplace(id, subsizes);
438439
packTime += static_cast<double>(z.split());
@@ -772,6 +773,7 @@ class TestHelper {
772773
}
773774
assert(i == onePost.end());
774775
assert(sanitycheck == onePost.size());
776+
(void)sanitycheck;
775777
packTime += static_cast<double>(z.split());
776778
}
777779
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@PACKAGE_INIT@
2+
3+
# Imported targets (defines SIMDCompressionAndIntersection::SIMDCompressionAndIntersection)
4+
include("${CMAKE_CURRENT_LIST_DIR}/SIMDCompressionAndIntersectionTargets.cmake")
5+
6+
check_required_components(SIMDCompressionAndIntersection)

include/VarIntG8IU.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
* This code is released under the
33
* Apache License Version 2.0 http://www.apache.org/licenses/.
44
*/
5+
#include "platform.h" /* SIMD intrinsics; defines __SSSE3__ on ARM/NEON */
56
#ifndef __SSSE3__
67
#pragma message \
78
"Disabling varintg8iu due to lack of SSSE3 support, try adding -mssse3 or the equivalent on your compiler"
89
#else
910
#ifndef VARINTG8IU_H__
1011
#define VARINTG8IU_H__
11-
#include <emmintrin.h>
1212
#include "codecs.h"
1313
#include "delta.h"
1414
#ifdef __GNUC__

include/common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#include <errno.h>
1111
#include <fcntl.h>
12-
#include <immintrin.h>
12+
#include "platform.h" /* pulls in the SIMD intrinsics (SSE on x86, NEON on ARM) */
1313
#include <iso646.h>
1414
#include <limits.h>
1515
#ifndef _MSC_VER

include/compositecodec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class CompositeCodec : public IntegerCODEC {
5555
}
5656
nvalue = mynvalue1;
5757
assert(initin + length >= in2);
58+
(void)initin;
59+
(void)length;
5860
return in2;
5961
}
6062
string name() const {

0 commit comments

Comments
 (0)