Skip to content
Merged
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
68 changes: 68 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
AlignConsecutiveAssignments: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: Inline
AllowShortLoopsOnASingleLine: 'false'
AlignConsecutiveDeclarations: 'false'
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BraceWrapping:
SplitEmptyRecord: false
AfterClass: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterControlStatement: Always
AfterEnum: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: false
# BeforeLambdaBody: false
# BeforeWhile: false
SplitEmptyFunction: false
SplitEmptyNamespace: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: 'true'
ColumnLimit: '120'
CompactNamespaces: 'false'
ConstructorInitializerIndentWidth: '2'
ContinuationIndentWidth: '2'
DerivePointerAlignment: 'true'
DisableFormat: 'false'
IncludeBlocks: Regroup
IndentCaseLabels: 'true'
IndentWidth: '2'
IndentWrappedFunctionNames: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
Language: Cpp
MaxEmptyLinesToKeep: '2'
NamespaceIndentation: All
PenaltyBreakAssignment: '50'
PointerAlignment: Left
ReflowComments: 'true'
SortIncludes: 'false'
SortUsingDeclarations: 'false'
SpaceAfterCStyleCast: 'false'
SpaceAfterLogicalNot: 'false'
SpaceAfterTemplateKeyword: 'false'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeCpp11BracedList: 'false'
SpaceBeforeCtorInitializerColon: 'true'
SpaceBeforeInheritanceColon: 'true'
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: '2'
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Auto
TabWidth: '0'
UseTab: Never

...
12 changes: 12 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

echo 'Creating single header implementation'
LOCAL_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
py "$LOCAL_DIR/../scripts/make_single_header_impl.py"

git add "single_header_impl"

if ! git diff --quiet --cached single_header_impl; then
echo "Contents of single_header_impl changed. Please check whether these changes are correct."
exit -1
fi
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.idea
cmake-build*
cmake-build*
.vs
out
13 changes: 9 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,15 @@ endif()
if(BUILD_TESTS)
find_package(GTest REQUIRED)
include(GoogleTest)
enable_testing()

add_executable(${SN_TESTS_EXECUTABLE_NAME} "test/test_case_gen.h" "test/sorting_network_tests.cpp")
add_executable(${SN_TESTS_EXECUTABLE_NAME}
"test/test_base.h"
"test/test_batcher_odd_even_merge_sort.cpp"
"test/test_bitonic_merge_sort.cpp"
"test/test_bose_nelson_sort.cpp"
"test/test_bubble_sort.cpp"
"test/test_insertion_sort.cpp"
"test/test_size_optimized_sort.cpp"
)
target_link_libraries(${SN_TESTS_EXECUTABLE_NAME} GTest::gtest GTest::gtest_main metal project_options)

gtest_discover_tests(${SN_TESTS_EXECUTABLE_NAME})
endif()
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ A single class `sorting_network` is available which encapsulates the implementat
Following listing gives a few examples:

```cpp
#include <sorting_network_cpp/sorting_network.hpp>
#include <sorting_network_cpp/sorting_network.h>

#include <array>
#include <cstdint>
Expand Down Expand Up @@ -57,7 +57,7 @@ void example()
// may be passed as follows:

// custom comparators
sorting_network<N>{}(data, compare_and_swap<int, std::less<int>>{});
sorting_network<N>{}(data, compare_and_swap<int, std::less<>>{});

// function objects
struct predicate
Expand Down Expand Up @@ -90,20 +90,23 @@ quxflux::sorting_net::sorting_network<N, quxflux::sorting_net::type::bitonic_mer
The compare and swap operation is the fundamental element a sorting network is composed of. The default implementation works well on scalar types, but if you want to specify a custom implementation (e.g. when hardware intrinsics should be used) you may do this by providing a compare and swap functor to the `sorting_network::operator()` as in following example:

```cpp
#include <sorting_network_cpp/sorting_network.hpp>
#include <sorting_network_cpp/sorting_network.h>

#include <array>

void example(std::array<float,3>& arr)
{
quxflux::sorting_net::sorting_network<3>{}(arr, [](float& a, float& b){
quxflux::sorting_net::sorting_network<3>{}(arr.begin(), [](float& a, float& b){
const auto b_cpy = b;
b = std::max(a, b);
a = std::min(a, b_cpy);
});
}
```

## Single header implementation
A single header implementation is available which allows experimenting with the sorting networks on [godbolt](https://godbolt.org/z/69WMqMY3c).

## Requirements
A compiler with C++17 support

Expand All @@ -114,6 +117,11 @@ For the bare sorting functionality no dependencies are required. If you want to
* Depending on the implementation of the comparator the performance advantage of a sorting net compared to a regular sorting algorithm (e.g. `std::sort`) may diminish or even result in worse performance. This can be seen in the [interactive benchmark results overview](https://raw.githack.com/quxflux/sorting_network_cpp/master/doc/data_explorer.htm) for the data type `Vec2i Z-order` which causes in most cases all variants of sorting networks being outperformed by `std::sort` (see [src/benchmark.cpp](src/benchmark.cpp) for the implementation of the aforementioned data type).
* msvc will fail compiling larger `insertion_sort` networks in certain (unknown) configurations with `fatal error C1202: recursive type or function dependency context too complex`

## Development notes
* A pre-push [githook](https://git-scm.com/docs/githooks) is available in [.githooks](./.githooks/) which will automatically create the single header implementation.
To enable the hook execute
`git config --local core.hooksPath .githooks` in the repository directory (python required)

## References / Acknowledgements
* ["A Sorting Problem"](https://dl.acm.org/doi/pdf/10.1145/321119.321126) by Bose et al.
* ["Sorting networks and their applications"](https://core.ac.uk/download/pdf/192393620.pdf) by Batcher
Expand All @@ -125,4 +133,4 @@ For the bare sorting functionality no dependencies are required. If you want to
* [Chart.js](https://www.chartjs.org/) and [Papa Parse](https://www.papaparse.com/) for the visualization of benchmark results

## License
[GPLv3](LICENSE)
[GPLv3](LICENSE)
Loading