deglib 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. deglib-0.1.0/CMakeLists.txt +24 -0
  2. deglib-0.1.0/LICENSE +21 -0
  3. deglib-0.1.0/MANIFEST.in +5 -0
  4. deglib-0.1.0/PKG-INFO +203 -0
  5. deglib-0.1.0/README.md +162 -0
  6. deglib-0.1.0/lib/CMakeLists.txt +126 -0
  7. deglib-0.1.0/lib/cmake_modules/DetectCPUFeatures.cmake +52 -0
  8. deglib-0.1.0/lib/deglib/CMakeLists.txt +10 -0
  9. deglib-0.1.0/lib/deglib/include/analysis.h +246 -0
  10. deglib-0.1.0/lib/deglib/include/builder.h +1441 -0
  11. deglib-0.1.0/lib/deglib/include/concurrent.h +68 -0
  12. deglib-0.1.0/lib/deglib/include/config.h +55 -0
  13. deglib-0.1.0/lib/deglib/include/deglib.h +12 -0
  14. deglib-0.1.0/lib/deglib/include/distances.h +744 -0
  15. deglib-0.1.0/lib/deglib/include/graph/readonly_graph.h +850 -0
  16. deglib-0.1.0/lib/deglib/include/graph/sizebounded_graph.h +1026 -0
  17. deglib-0.1.0/lib/deglib/include/graph.h +55 -0
  18. deglib-0.1.0/lib/deglib/include/memory.h +19 -0
  19. deglib-0.1.0/lib/deglib/include/repository.h +165 -0
  20. deglib-0.1.0/lib/deglib/include/search.h +149 -0
  21. deglib-0.1.0/lib/deglib/include/visited_list_pool.h +105 -0
  22. deglib-0.1.0/pyproject.toml +52 -0
  23. deglib-0.1.0/setup.cfg +4 -0
  24. deglib-0.1.0/setup.py +214 -0
  25. deglib-0.1.0/src/deg_cpp/deglib_cpp.cpp +392 -0
  26. deglib-0.1.0/src/deglib/__init__.py +19 -0
  27. deglib-0.1.0/src/deglib/analysis.py +85 -0
  28. deglib-0.1.0/src/deglib/benchmark.py +156 -0
  29. deglib-0.1.0/src/deglib/builder.py +237 -0
  30. deglib-0.1.0/src/deglib/distances.py +88 -0
  31. deglib-0.1.0/src/deglib/graph.py +640 -0
  32. deglib-0.1.0/src/deglib/repository.py +29 -0
  33. deglib-0.1.0/src/deglib/search.py +109 -0
  34. deglib-0.1.0/src/deglib/std.py +12 -0
  35. deglib-0.1.0/src/deglib/utils.py +56 -0
  36. deglib-0.1.0/src/deglib.egg-info/PKG-INFO +203 -0
  37. deglib-0.1.0/src/deglib.egg-info/SOURCES.txt +40 -0
  38. deglib-0.1.0/src/deglib.egg-info/dependency_links.txt +1 -0
  39. deglib-0.1.0/src/deglib.egg-info/requires.txt +5 -0
  40. deglib-0.1.0/src/deglib.egg-info/top_level.txt +2 -0
  41. deglib-0.1.0/tests/test_builder.py +127 -0
  42. deglib-0.1.0/tests/test_graph.py +262 -0
@@ -0,0 +1,24 @@
1
+ # python-bindings/CMakeLists.txt
2
+ cmake_minimum_required(VERSION 3.19)
3
+ project(deglib_cpp)
4
+
5
+ # Add python executable
6
+ if(DEFINED PYTHON_EXECUTABLE)
7
+ set(Python_EXECUTABLE ${PYTHON_EXECUTABLE})
8
+ endif()
9
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
10
+
11
+ # Add pybind11
12
+ find_package(pybind11 CONFIG REQUIRED)
13
+
14
+ # disable benchmark building
15
+ set(ENABLE_BENCHMARKS OFF CACHE BOOL "Disable benchmarks" FORCE)
16
+
17
+ # Add cpp-deglib
18
+ add_subdirectory(${CMAKE_SOURCE_DIR}/lib/)
19
+ pybind11_add_module(deglib_cpp src/deg_cpp/deglib_cpp.cpp)
20
+
21
+ # Specify the include directories
22
+ include_directories(${CMAKE_SOURCE_DIR}/lib/deglib/include)
23
+
24
+ target_link_libraries(deglib_cpp PRIVATE compile-options)
deglib-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Visual Computing Group
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include LICENSE
2
+ include README.md
3
+ recursive-include src *.cpp
4
+ recursive-include lib *.h
5
+ global-include CMakeLists.txt *.cmake
deglib-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.1
2
+ Name: deglib
3
+ Version: 0.1.0
4
+ Summary: Python bindings for the Dynamic Exploration Graph library by Nico Hezel
5
+ Author: Nico Hezel
6
+ Author-email: Bruno Schilling <bruno.schilling@htw-berlin.de>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2024 Visual Computing Group
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: Homepage, https://github.com/Visual-Computing/DynamicExplorationGraph
30
+ Keywords: anns-search,graph,python
31
+ Classifier: Development Status :: 2 - Pre-Alpha
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: Programming Language :: Python :: 3
34
+ Requires-Python: >=3.11
35
+ Description-Content-Type: text/markdown
36
+ License-File: LICENSE
37
+ Requires-Dist: numpy>=1.21
38
+ Requires-Dist: psutil
39
+ Provides-Extra: test
40
+ Requires-Dist: pytest>=8.0; extra == "test"
41
+
42
+ # deglib: Python bindings for the Dynamic Exploration Graph
43
+
44
+ Python bindings for the C++ library Dynamic Exploration Graph used in the paper:
45
+ [Fast Approximate Nearest Neighbor Search with a Dynamic Exploration Graph using Continuous Refinement](https://arxiv.org/abs/2307.10479)
46
+
47
+ ## Table of Contents
48
+ - [Installation](#installation)
49
+ - [Examples](#examples)
50
+ - [Naming](#naming)
51
+ - [Limitations](#limitations)
52
+ - [Troubleshooting](#troubleshooting)
53
+
54
+ ## Installation
55
+
56
+ ### Using pip
57
+ ```shell
58
+ pip install deglib
59
+ ```
60
+ This will install a source package, that needs to compile the C++ code in order to create an optimized version for your system.
61
+
62
+ ### Compiling from Source
63
+
64
+ **Create Virtual Environment**
65
+ ```shell
66
+ # create virtualenv with virtualenvwrapper or venv
67
+ mkvirtualenv deglib
68
+ # or
69
+ python -m venv /path/to/deglib_env && . /path/to/deglib_env/bin/activate
70
+ ```
71
+
72
+ **Get the Source**
73
+ ```shell
74
+ # clone git repository
75
+ git clone git@github.com:Visual-Computing/DynamicExplorationGraph.git
76
+ cd DynamicExplorationGraph/python
77
+ ```
78
+
79
+ **Install the Package from Source**
80
+ ```shell
81
+ pip install setuptools pybind11 build
82
+ python setup.py copy_build_files # copy c++ library to ./lib/
83
+ pip install .
84
+ ```
85
+ This will compile the C++ code and install deglib into your virtual environment, so it may take a while.
86
+
87
+ **Testing**
88
+
89
+ To execute all tests.
90
+ ```shell
91
+ pytest
92
+ ```
93
+
94
+ **Building Packages**
95
+
96
+ Build packages (sdist and wheels):
97
+ ```shell
98
+ python -m build
99
+ ```
100
+
101
+ Note: If you want to publish linux wheels to pypi you have to convert
102
+ the wheel to musllinux-/manylinux-wheels.
103
+ This can be easily done using `cibuildwheel` (if docker is installed):
104
+
105
+ ```shell
106
+ cibuildwheel --archs auto64 --output-dir dist
107
+ ```
108
+
109
+ ## Examples
110
+ ### Loading Data
111
+ To load a dataset formatted like the [TexMex-Datasets](http://corpus-texmex.irisa.fr/):
112
+ ```python
113
+ import deglib
114
+ import numpy as np
115
+
116
+ dataset: np.ndarray = deglib.repository.fvecs_read("path/to/data.fvecs")
117
+ num_samples, dims = dataset.shape
118
+ ```
119
+ The dataset is a numpy array with shape (N, D), where N is the number of feature
120
+ vectors and D is the number of dimensions of each feature vector.
121
+
122
+ ### Building a Graph
123
+
124
+ ```python
125
+ graph = deglib.builder.build_from_data(dataset, edges_per_vertex=32, callback="progress")
126
+ graph.save_graph("/path/to/graph.deg")
127
+ rd_graph = deglib.graph.load_readonly_graph("/path/to/graph.deg")
128
+ ```
129
+
130
+ ### Searching the Graph
131
+ ```python
132
+ # query can have shape (D,) or (Q, D), where
133
+ # D is the dimensionality of the dataset and
134
+ # Q is the number of queries.
135
+ query = np.random.random((dims,)).astype(np.float32)
136
+ result, dists = graph.search(query, eps=0.1, k=10) # get 10 nearest features to query
137
+ print('best dataset index:', result[0])
138
+ best_match = dataset[result[0]]
139
+ ```
140
+
141
+ For more examples see [tests](tests).
142
+
143
+ ### Referencing C++ memory
144
+ Consider the following example:
145
+ ```python
146
+ feature_vector = graph.get_feature_vector(42)
147
+ del graph
148
+ print(feature_vector)
149
+ ```
150
+ This will crash as `feature_vector` is holding a reference to memory that is owned by `graph`. This can lead to undefined behaviour (most likely segmentation fault).
151
+ Be careful to keep objects in memory that are referenced. If you need it use the `copy=True` option:
152
+
153
+ ```python
154
+ feature_vector = graph.get_feature_vector(10, copy=True)
155
+ del graph
156
+ print(feature_vector) # no problem
157
+ ```
158
+
159
+ Copying feature vectors will be slower.
160
+
161
+ ## Naming
162
+ ### Vertex = Feature Vector
163
+ Each vertex in the graph corresponds to a feature vector of the dataset.
164
+
165
+ ### Internal Index vs External Label
166
+ There are two kinds of indices used in a graph: `internal_index` and `external_label`. Both are integers and specify
167
+ a vertex in a graph.
168
+
169
+ Internal Indices are dense, which means that every `internal_index < len(graph)` can be used.
170
+ For example: If you add 100 vertices and remove the vertex with internal_index 42, the last vertex in the graph will
171
+ be moved to index 42.
172
+
173
+ In contrast, external label is a user defined identifier for each added vertex
174
+ (see `builder.add_entry(external_label, feature_vector)`). Adding or Removing vertices to the graph will keep the
175
+ connection between external labels and associated feature vector.
176
+
177
+ When you create the external labels by starting with `0` and increasing it for each entry by `1` and don't remove
178
+ elements from the graph, external labels and internal indices are equal.
179
+
180
+ ```python
181
+ # as long as no elements are removed
182
+ # external labels and internal indices are equal
183
+ for i, vec in enumerate(data):
184
+ builder.add_entry(i, vec)
185
+ ```
186
+
187
+ ### Eps
188
+ The eps-search-parameter controls how many nodes are checked during search.
189
+ Lower eps values like 0.001 are faster but less accurate.
190
+ Higher eps values like 0.1 are slower but more accurate. Should always be greater 0.
191
+
192
+ ### Relative Neighborhood Graph / RNG-conform
193
+ TODO
194
+
195
+ ## Limitations
196
+ - The python wrapper at the moment only supports `float32` and `uint8` feature vectors.
197
+
198
+ ## Troubleshooting
199
+
200
+ ### BuildError: `pybind11/typing.h:104:58: error: ‘copy_n’ is not a member of ‘std’`
201
+
202
+ This is a pybind11 bug, that occurs when compiling it with gcc-14. Change the pybind version to 2.12.
203
+
deglib-0.1.0/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # deglib: Python bindings for the Dynamic Exploration Graph
2
+
3
+ Python bindings for the C++ library Dynamic Exploration Graph used in the paper:
4
+ [Fast Approximate Nearest Neighbor Search with a Dynamic Exploration Graph using Continuous Refinement](https://arxiv.org/abs/2307.10479)
5
+
6
+ ## Table of Contents
7
+ - [Installation](#installation)
8
+ - [Examples](#examples)
9
+ - [Naming](#naming)
10
+ - [Limitations](#limitations)
11
+ - [Troubleshooting](#troubleshooting)
12
+
13
+ ## Installation
14
+
15
+ ### Using pip
16
+ ```shell
17
+ pip install deglib
18
+ ```
19
+ This will install a source package, that needs to compile the C++ code in order to create an optimized version for your system.
20
+
21
+ ### Compiling from Source
22
+
23
+ **Create Virtual Environment**
24
+ ```shell
25
+ # create virtualenv with virtualenvwrapper or venv
26
+ mkvirtualenv deglib
27
+ # or
28
+ python -m venv /path/to/deglib_env && . /path/to/deglib_env/bin/activate
29
+ ```
30
+
31
+ **Get the Source**
32
+ ```shell
33
+ # clone git repository
34
+ git clone git@github.com:Visual-Computing/DynamicExplorationGraph.git
35
+ cd DynamicExplorationGraph/python
36
+ ```
37
+
38
+ **Install the Package from Source**
39
+ ```shell
40
+ pip install setuptools pybind11 build
41
+ python setup.py copy_build_files # copy c++ library to ./lib/
42
+ pip install .
43
+ ```
44
+ This will compile the C++ code and install deglib into your virtual environment, so it may take a while.
45
+
46
+ **Testing**
47
+
48
+ To execute all tests.
49
+ ```shell
50
+ pytest
51
+ ```
52
+
53
+ **Building Packages**
54
+
55
+ Build packages (sdist and wheels):
56
+ ```shell
57
+ python -m build
58
+ ```
59
+
60
+ Note: If you want to publish linux wheels to pypi you have to convert
61
+ the wheel to musllinux-/manylinux-wheels.
62
+ This can be easily done using `cibuildwheel` (if docker is installed):
63
+
64
+ ```shell
65
+ cibuildwheel --archs auto64 --output-dir dist
66
+ ```
67
+
68
+ ## Examples
69
+ ### Loading Data
70
+ To load a dataset formatted like the [TexMex-Datasets](http://corpus-texmex.irisa.fr/):
71
+ ```python
72
+ import deglib
73
+ import numpy as np
74
+
75
+ dataset: np.ndarray = deglib.repository.fvecs_read("path/to/data.fvecs")
76
+ num_samples, dims = dataset.shape
77
+ ```
78
+ The dataset is a numpy array with shape (N, D), where N is the number of feature
79
+ vectors and D is the number of dimensions of each feature vector.
80
+
81
+ ### Building a Graph
82
+
83
+ ```python
84
+ graph = deglib.builder.build_from_data(dataset, edges_per_vertex=32, callback="progress")
85
+ graph.save_graph("/path/to/graph.deg")
86
+ rd_graph = deglib.graph.load_readonly_graph("/path/to/graph.deg")
87
+ ```
88
+
89
+ ### Searching the Graph
90
+ ```python
91
+ # query can have shape (D,) or (Q, D), where
92
+ # D is the dimensionality of the dataset and
93
+ # Q is the number of queries.
94
+ query = np.random.random((dims,)).astype(np.float32)
95
+ result, dists = graph.search(query, eps=0.1, k=10) # get 10 nearest features to query
96
+ print('best dataset index:', result[0])
97
+ best_match = dataset[result[0]]
98
+ ```
99
+
100
+ For more examples see [tests](tests).
101
+
102
+ ### Referencing C++ memory
103
+ Consider the following example:
104
+ ```python
105
+ feature_vector = graph.get_feature_vector(42)
106
+ del graph
107
+ print(feature_vector)
108
+ ```
109
+ This will crash as `feature_vector` is holding a reference to memory that is owned by `graph`. This can lead to undefined behaviour (most likely segmentation fault).
110
+ Be careful to keep objects in memory that are referenced. If you need it use the `copy=True` option:
111
+
112
+ ```python
113
+ feature_vector = graph.get_feature_vector(10, copy=True)
114
+ del graph
115
+ print(feature_vector) # no problem
116
+ ```
117
+
118
+ Copying feature vectors will be slower.
119
+
120
+ ## Naming
121
+ ### Vertex = Feature Vector
122
+ Each vertex in the graph corresponds to a feature vector of the dataset.
123
+
124
+ ### Internal Index vs External Label
125
+ There are two kinds of indices used in a graph: `internal_index` and `external_label`. Both are integers and specify
126
+ a vertex in a graph.
127
+
128
+ Internal Indices are dense, which means that every `internal_index < len(graph)` can be used.
129
+ For example: If you add 100 vertices and remove the vertex with internal_index 42, the last vertex in the graph will
130
+ be moved to index 42.
131
+
132
+ In contrast, external label is a user defined identifier for each added vertex
133
+ (see `builder.add_entry(external_label, feature_vector)`). Adding or Removing vertices to the graph will keep the
134
+ connection between external labels and associated feature vector.
135
+
136
+ When you create the external labels by starting with `0` and increasing it for each entry by `1` and don't remove
137
+ elements from the graph, external labels and internal indices are equal.
138
+
139
+ ```python
140
+ # as long as no elements are removed
141
+ # external labels and internal indices are equal
142
+ for i, vec in enumerate(data):
143
+ builder.add_entry(i, vec)
144
+ ```
145
+
146
+ ### Eps
147
+ The eps-search-parameter controls how many nodes are checked during search.
148
+ Lower eps values like 0.001 are faster but less accurate.
149
+ Higher eps values like 0.1 are slower but more accurate. Should always be greater 0.
150
+
151
+ ### Relative Neighborhood Graph / RNG-conform
152
+ TODO
153
+
154
+ ## Limitations
155
+ - The python wrapper at the moment only supports `float32` and `uint8` feature vectors.
156
+
157
+ ## Troubleshooting
158
+
159
+ ### BuildError: `pybind11/typing.h:104:58: error: ‘copy_n’ is not a member of ‘std’`
160
+
161
+ This is a pybind11 bug, that occurs when compiling it with gcc-14. Change the pybind version to 2.12.
162
+
@@ -0,0 +1,126 @@
1
+ cmake_minimum_required(VERSION 3.19)
2
+
3
+ # Only interpret if() arguments as variables or keywords when unquoted. More
4
+ # details run "cmake --help-policy CMP0054"
5
+ cmake_policy(SET CMP0054 NEW)
6
+
7
+ project(
8
+ deg_lib
9
+ HOMEPAGE_URL "https://github.com/Neiko2002/DEG"
10
+ DESCRIPTION
11
+ "Dynamic Exploration Graphs for fast approximate nearest neighbor search and navigation in large image datasets"
12
+ VERSION 0.0.1
13
+ LANGUAGES CXX
14
+ )
15
+
16
+ # build options
17
+ option(ENABLE_BENCHMARKS "compile benchmarks" ON)
18
+ option(FORCE_AVX2 "compile for avx2 support. Otherwise compile for this machine." OFF)
19
+
20
+ # https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html
21
+ set(CMAKE_CXX_STANDARD 20)
22
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
23
+ set(CMAKE_CXX_EXTENSIONS OFF)
24
+
25
+ add_library(compile-options INTERFACE)
26
+ target_compile_features(compile-options INTERFACE cxx_std_20)
27
+ target_compile_definitions(compile-options INTERFACE $<$<PLATFORM_ID:Windows>:NOMINMAX>)
28
+
29
+ # detecting CPU instruction support
30
+ # https://github.com/lemire/FastPFor/blob/master/CMakeLists.txt
31
+ if (APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
32
+ message(WARNING "You are compiling on an Apple M chip. At the moment deglib does not support ARM optimizations, so using deglib will be slow!")
33
+ endif()
34
+
35
+ if (FORCE_AVX2)
36
+ message(NOTICE "Compiling for avx2, ignoring native optimizations.")
37
+
38
+ # setup compiler flags
39
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
40
+ target_compile_options(
41
+ compile-options
42
+ INTERFACE -O3
43
+ -mavx2
44
+ -mfma
45
+ -fpic
46
+ -w
47
+ -fopenmp
48
+ -pthread
49
+ -ftree-vectorize
50
+ -ftree-vectorizer-verbose=0
51
+ )
52
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
53
+ target_compile_options(
54
+ compile-options
55
+ INTERFACE -O2
56
+ -mavx2
57
+ -mfma
58
+ -fpic)
59
+ elseif(MSVC)
60
+ target_compile_options(
61
+ compile-options
62
+ INTERFACE /O2
63
+ /arch:AVX2
64
+ /W1
65
+ /openmp
66
+ /EHsc)
67
+ else()
68
+ message(WARNING "Unknown compiler for AVX2 Build: ${CMAKE_CXX_COMPILER_ID}")
69
+ endif()
70
+
71
+ else() # Native build
72
+ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
73
+ include(DetectCPUFeatures)
74
+
75
+ # setup compiler flags
76
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
77
+ target_compile_options(
78
+ compile-options
79
+ INTERFACE -O3
80
+ -march=native
81
+ -mavx2
82
+ -mfma
83
+ -fpic
84
+ -w
85
+ -fopenmp
86
+ -pthread
87
+ -ftree-vectorize
88
+ -ftree-vectorizer-verbose=0)
89
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
90
+ target_compile_options(
91
+ compile-options
92
+ INTERFACE -O2
93
+ -DNDEBUG
94
+ -march=native
95
+ -fpic)
96
+ elseif(MSVC)
97
+ # warning level 4 (show all)
98
+ target_compile_options(compile-options INTERFACE /W4)
99
+
100
+ # detecting SUPPORT_AVX2 or SSE2 support
101
+ cmake_host_system_information(RESULT SUPPORT_SSE2 QUERY HAS_SSE2)
102
+ if(SUPPORT_AVX2)
103
+ target_compile_options(compile-options INTERFACE /arch:AVX2)
104
+ elseif(SUPPORT_SSE2)
105
+ target_compile_options(compile-options INTERFACE /arch:SSE2)
106
+ else()
107
+ target_compile_options(compile-options INTERFACE /arch:native)
108
+ endif()
109
+
110
+ # disable string optimizations and function level linking
111
+ # https://stackoverflow.com/questions/5063334/what-is-the-difference-between-the-ox-and-o2-compiler-options
112
+ target_compile_options(compile-options INTERFACE $<$<CONFIG:Release>:/Ox>)
113
+ else()
114
+ message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
115
+ endif()
116
+ endif()
117
+
118
+ message("C++ compiler flags: ${CMAKE_CXX_FLAGS}")
119
+ message("C++ compiler flags release: ${CMAKE_CXX_FLAGS_RELEASE}")
120
+
121
+ add_subdirectory(deglib)
122
+
123
+ if (ENABLE_BENCHMARKS)
124
+ add_subdirectory(external/fmt)
125
+ add_subdirectory(benchmark)
126
+ endif()
@@ -0,0 +1,52 @@
1
+ include(CheckCXXSourceCompiles)
2
+
3
+ set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
4
+
5
+ set(SSE4PROG "
6
+
7
+ #include<smmintrin.h>
8
+ int main(){
9
+ __m128 x=_mm_set1_ps(0.5);
10
+ x=_mm_dp_ps(x,x,0x77);
11
+ return _mm_movemask_ps(x);
12
+ }")
13
+
14
+ set(AVXPROG "
15
+
16
+ #include<immintrin.h>
17
+ int main(){
18
+ __m128 x=_mm_set1_ps(0.5);
19
+ x=_mm_permute_ps(x,1);
20
+ return _mm_movemask_ps(x);
21
+ }")
22
+
23
+ set(AVX2PROG "
24
+
25
+ #include<immintrin.h>
26
+ int main(){
27
+ __m256i x=_mm256_set1_epi32(5);
28
+ x=_mm256_add_epi32(x,x);
29
+ return _mm256_movemask_epi8(x);
30
+ }")
31
+
32
+ if(MSVC)
33
+ set(CMAKE_REQUIRED_FLAGS "/EHsc /arch:SSE2")
34
+ check_cxx_source_compiles("${SSE4PROG}" SUPPORT_SSE42)
35
+ message(STATUS "SUPPORT_SSE42 ${SUPPORT_SSE42}")
36
+ set(CMAKE_REQUIRED_FLAGS "/EHsc /arch:AVX")
37
+ check_cxx_source_compiles("${AVXPROG}" SUPPORT_AVX)
38
+ message(STATUS "SUPPORT_AVX ${SUPPORT_AVX}")
39
+ set(CMAKE_REQUIRED_FLAGS "/EHsc /arch:AVX2")
40
+ check_cxx_source_compiles("${AVX2PROG}" SUPPORT_AVX2)
41
+ message(STATUS "SUPPORT_AVX2 ${SUPPORT_AVX2}")
42
+ else()
43
+ set(CMAKE_REQUIRED_FLAGS "-march=native -msse4.2")
44
+ check_cxx_source_compiles("${SSE4PROG}" SUPPORT_SSE42)
45
+ set(CMAKE_REQUIRED_FLAGS "-march=native -mavx")
46
+ check_cxx_source_compiles("${AVXPROG}" SUPPORT_AVX)
47
+ set(CMAKE_REQUIRED_FLAGS "-march=native -mavx2")
48
+ check_cxx_source_compiles("${AVX2PROG}" SUPPORT_AVX2)
49
+ endif()
50
+
51
+ set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
52
+
@@ -0,0 +1,10 @@
1
+ cmake_minimum_required (VERSION 3.19)
2
+
3
+ project(deglib)
4
+
5
+ # setup the deg lib
6
+ # http://mariobadr.com/creating-a-header-only-library-with-cmake.html
7
+ add_library(DEG_LIB INTERFACE)
8
+ target_include_directories(DEG_LIB INTERFACE ${PROJECT_SOURCE_DIR}/include)
9
+ target_include_directories(DEG_LIB INTERFACE ${PROJECT_SOURCE_DIR}/include/graph)
10
+ target_compile_features(DEG_LIB INTERFACE cxx_std_20)