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
8 changes: 8 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
BasedOnStyle: WebKit
AlignAfterOpenBracket: Align
AlignConsecutiveDeclarations: 'false'
BreakBeforeBraces: Allman
NamespaceIndentation: All

...
129 changes: 129 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Linux build
on: [push, pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash -l {0}
jobs:
build:
runs-on: ubuntu-latest
name: '${{ matrix.sys.compiler }} ${{ matrix.sys.version }} - ${{ matrix.sys.flags }}'
strategy:
matrix:
sys:
- { compiler: 'gcc', version: '12', flags: 'force_no_instr_set' }
- { compiler: 'gcc', version: '13', flags: 'enable_xtl_complex' }
- { compiler: 'gcc', version: '14', flags: 'avx' }
- { compiler: 'gcc', version: '13', flags: 'avx512' }
- { compiler: 'gcc', version: '12', flags: 'i386' }
- { compiler: 'gcc', version: '13', flags: 'avx512pf' }
- { compiler: 'gcc', version: '13', flags: 'avx512vbmi' }
- { compiler: 'gcc', version: '14', flags: 'avx512vbmi2' }
- { compiler: 'gcc', version: '13', flags: 'avx512vnni' }
- { compiler: 'clang', version: '16', flags: 'force_no_instr_set' }
- { compiler: 'clang', version: '16', flags: 'enable_xtl_complex' }
- { compiler: 'clang', version: '17', flags: 'avx' }
- { compiler: 'clang', version: '17', flags: 'sse3' }
- { compiler: 'clang', version: '18', flags: 'avx512' }
steps:
- name: Setup compiler
if: ${{ matrix.sys.compiler == 'gcc' }}
run: |
GCC_VERSION=${{ matrix.sys.version }}
sudo apt-get update
sudo apt-get --no-install-suggests --no-install-recommends install g++-$GCC_VERSION
sudo dpkg --add-architecture i386
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get --no-install-suggests --no-install-recommends install gcc-$GCC_VERSION-multilib g++-$GCC_VERSION-multilib linux-libc-dev:i386
CC=gcc-$GCC_VERSION
echo "CC=$CC" >> $GITHUB_ENV
CXX=g++-$GCC_VERSION
echo "CXX=$CXX" >> $GITHUB_ENV
- name: Setup compiler
if: ${{ matrix.sys.compiler == 'clang' }}
run: |
LLVM_VERSION=${{ matrix.sys.version }}
sudo apt-get update || exit 1
sudo apt-get --no-install-suggests --no-install-recommends install clang-$LLVM_VERSION || exit 1
sudo apt-get --no-install-suggests --no-install-recommends install g++ g++-multilib || exit 1
sudo ln -s /usr/include/asm-generic /usr/include/asm
CC=clang-$LLVM_VERSION
echo "CC=$CC" >> $GITHUB_ENV
CXX=clang++-$LLVM_VERSION
echo "CXX=$CXX" >> $GITHUB_ENV
- name: Checkout xsimd-algorithm
uses: actions/checkout@v3
- name: Set conda environment
uses: mamba-org/setup-micromamba@main
with:
environment-name: myenv
environment-file: environment-dev.yml
init-shell: bash
cache-downloads: true
- name: Setup SDE
if: startswith(matrix.sys.flags, 'avx512')
run: sh install_sde.sh
- name: Configure build
env:
CC: ${{ env.CC }}
CXX: ${{ env.CXX }}
run: |
if [[ '${{ matrix.sys.flags }}' == 'enable_xtl_complex' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DENABLE_XTL_COMPLEX=ON"
fi
if [[ '${{ matrix.sys.flags }}' == 'avx' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=sandybridge"
fi
if [[ '${{ matrix.sys.flags }}' == 'sse3' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=nocona"
fi
if [[ '${{ matrix.sys.flags }}' == 'avx512' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=skylake-avx512"
fi
if [[ '${{ matrix.sys.flags }}' == 'avx512pf' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=knl"
fi
if [[ '${{ matrix.sys.flags }}' == 'avx512vbmi' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=cannonlake"
fi
if [[ '${{ matrix.sys.flags }}' == 'avx512vbmi2' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=icelake-server"
fi
if [[ '${{ matrix.sys.flags }}' == 'avx512vnni' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=knm"
fi
if [[ '${{ matrix.sys.flags }}' == 'i386' ]]; then
CXX_FLAGS="$CXX_FLAGS -m32"
fi
if [[ '${{ matrix.sys.flags }}' == 'force_no_instr_set' ]]; then
:
else
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DXSIMD_ENABLE_WERROR=ON"
fi

# Cheap way of spotting uninitialized read
CXX_FLAGS="$CXX_FLAGS -ftrivial-auto-var-init=pattern"

mkdir _build
cd _build
cmake .. -DBUILD_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=$CC \
-DCMAKE_CXX_COMPILER=$CXX \
$CMAKE_EXTRA_ARGS \
-DCMAKE_CXX_FLAGS='$CXX_FLAGS' \
-G Ninja
- name: Build
run: ninja -C _build
- name: Test
run: |
cd _build
cd test
if echo '${{ matrix.sys.flags }}' | grep -q 'avx512' ; then
../../sde-external-9.48.0-2024-11-25-lin/sde64 -tgl -- ./test_xsimd_algorithm
else
./test_xsimd_algorithm
fi
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@
*.exe
*.out
*.app

# Build
build/
build_*/
67 changes: 67 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.15..3.29)
project(xsimd-algorithm CXX)

set(XSIMDALGO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

# Dependencies
# ============

set(xsimd_REQUIRED_VERSION 13.2.0)
if(TARGET xsimd)
set(xsimd_VERSION ${XSIMD_VERSION_MAJOR}.${XSIMD_VERSION_MINOR}.${XSIMD_VERSION_PATCH})
if(${xsimd_VERSION} VERSION_LESS ${xsimd_REQUIRED_VERSION})
message(ERROR "Mismatch xsimd versions. Found '${xsimd_VERSION}' but requires: '${xsimd_REQUIRED_VERSION}'")
else()
message(STATUS "Found xsimd v${xsimd_VERSION}")
endif()
else()
find_package(xsimd ${xsimd_REQUIRED_VERSION} REQUIRED)
message(STATUS "Found xsimd: ${xsimd_INCLUDE_DIRS}/xsimd")
endif()

# Build
# =====

set(XSIMDALGO_HEADERS
${XSIMDALGO_INCLUDE_DIR}/xsimd_algo/algorithms.hpp
)

add_library(xsimd-algorithm INTERFACE)

target_include_directories(xsimd-algorithm INTERFACE
$<BUILD_INTERFACE:${XSIMDALGO_INCLUDE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>)

target_compile_features(xsimd-algorithm INTERFACE cxx_std_20)
target_link_libraries(xsimd-algorithm INTERFACE xsimd)

OPTION(BUILD_TESTS "xsimd-algorithm test suite" OFF)

if(BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif()

# Installation
# ============

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

install(TARGETS xsimd-algorithm
EXPORT ${PROJECT_NAME}-targets)

# Makes the project importable from the build directory
export(EXPORT ${PROJECT_NAME}-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake")

install(DIRECTORY ${XSIMDALGO_INCLUDE_DIR}/xsimd_algo
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

set(XSIMDALGO_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}" CACHE
STRING "install path for xsimd-algorithmConfig.cmake")

configure_package_config_file(${PROJECT_NAME}Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${XSIMDALGO_CMAKECONFIG_INSTALL_DIR})
8 changes: 8 additions & 0 deletions environment-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: xsimd-algorithm
channels:
- conda-forge
dependencies:
- cmake
- xsimd=13.2.0
- doctest
- ninja
18 changes: 18 additions & 0 deletions include/xsimd_algorithm/algorithms.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/***************************************************************************
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
* Martin Renou *
* Copyright (c) QuantStack *
* Copyright (c) Serge Guelton *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XSIMD_ALGORITHMS_HPP
#define XSIMD_ALGORITHMS_HPP

#include "xsimd_algorithm/stl/reduce.hpp"
#include "xsimd_algorithm/stl/transform.hpp"

#endif
90 changes: 90 additions & 0 deletions include/xsimd_algorithm/stl/reduce.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/***************************************************************************
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
* Martin Renou *
* Copyright (c) QuantStack *
* Copyright (c) Serge Guelton *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XSIMD_ALGORITHMS_REDUCE_HPP
#define XSIMD_ALGORITHMS_REDUCE_HPP

#include <array>
#include <cstddef>
#include <iterator>
#include <type_traits>

#include "xsimd/xsimd.hpp"

namespace xsimd
{
// TODO: Remove this once we drop C++11 support
namespace detail
{
struct plus
{
template <class X, class Y>
auto operator()(X&& x, Y&& y) noexcept -> decltype(x + y) { return x + y; }
};
}

template <class Arch = default_arch, class Iterator1, class Iterator2, class Init, class BinaryFunction = detail::plus>
Init reduce(Iterator1 first, Iterator2 last, Init init, BinaryFunction&& binfun = detail::plus {}) noexcept
{
using value_type = typename std::decay<decltype(*first)>::type;
using batch_type = batch<value_type, Arch>;

std::size_t size = static_cast<std::size_t>(std::distance(first, last));
constexpr std::size_t simd_size = batch_type::size;

if (size < simd_size)
{
while (first != last)
{
init = binfun(init, *first++);
}
return init;
}

const auto* const ptr_begin = &(*first);

std::size_t align_begin = xsimd::get_alignment_offset(ptr_begin, size, simd_size);
std::size_t align_end = align_begin + ((size - align_begin) & ~(simd_size - 1));

// reduce initial unaligned part
for (std::size_t i = 0; i < align_begin; ++i)
{
init = binfun(init, first[i]);
}

// reduce aligned part
auto ptr = ptr_begin + align_begin;
batch_type batch_init = batch_type::load_aligned(ptr);
ptr += simd_size;
for (auto const end = ptr_begin + align_end; ptr < end; ptr += simd_size)
{
batch_type batch = batch_type::load_aligned(ptr);
batch_init = binfun(batch_init, batch);
}

// reduce across batch
alignas(batch_type) std::array<value_type, simd_size> arr;
xsimd::store_aligned(arr.data(), batch_init);
for (auto x : arr)
init = binfun(init, x);

// reduce final unaligned part
for (std::size_t i = align_end; i < size; ++i)
{
init = binfun(init, first[i]);
}

return init;
}

}

#endif
Loading