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
73 changes: 73 additions & 0 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: benchmarks
on:
workflow_dispatch:
pull_request:
push:
branches: [master]
concurrency:
group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash -e -l {0}
jobs:
build:
runs-on: ubuntu-24.04
name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} - ${{ matrix.sys.name }}
strategy:
fail-fast: false
matrix:
sys:
- {compiler: clang, version: '20', name: xsimd, flags: -DXTENSOR_USE_XSIMD=ON}
- {compiler: clang, version: '20', name: xsimd-tbb, flags: -DXTENSOR_USE_XSIMD=ON -DXTENSOR_USE_TBB=ON}
- {compiler: gcc, version: '14', name: xsimd, flags: -DXTENSOR_USE_XSIMD=ON}
- {compiler: gcc, version: '14', name: xsimd-tbb, flags: -DXTENSOR_USE_XSIMD=ON -DXTENSOR_USE_TBB=ON}

steps:
- name: Install GCC
if: matrix.sys.compiler == 'gcc'
uses: egor-tensin/setup-gcc@v1
with:
version: ${{matrix.sys.version}}
platform: x64

- name: Install LLVM and Clang
if: matrix.sys.compiler == 'clang'
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh ${{matrix.sys.version}}
sudo apt-get install -y clang-tools-${{matrix.sys.version}}
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${{matrix.sys.version}} 200
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${{matrix.sys.version}} 200
sudo update-alternatives --install /usr/bin/clang-scan-deps clang-scan-deps /usr/bin/clang-scan-deps-${{matrix.sys.version}} 200
sudo update-alternatives --set clang /usr/bin/clang-${{matrix.sys.version}}
sudo update-alternatives --set clang++ /usr/bin/clang++-${{matrix.sys.version}}
sudo update-alternatives --set clang-scan-deps /usr/bin/clang-scan-deps-${{matrix.sys.version}}

- name: Checkout code
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
create-args: |
${{ (matrix.sys.name == 'tbb' || matrix.sys.name == 'xsimd-tbb' ) && 'tbb-devel' || '' }}

- name: Configure using CMake
run: |
if [[ "${{matrix.sys.compiler}}" = "gcc" ]]; then export CC=gcc-${{matrix.sys.version}}; export CXX=g++-${{matrix.sys.version}}; else export CC=clang; export CXX=clang++; fi
cmake -G Ninja -Bbuild -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DBUILD_BENCHMARK=ON ${{ matrix.sys.flags }}

- name: Build
working-directory: build
run: cmake --build . --target benchmark_xtensor --parallel 8

- name: Run benchmark
timeout-minutes: 10 # Consider increasing timeout
working-directory: build/benchmark
run: ./benchmark_xtensor
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

cmake_minimum_required(VERSION 3.29)
cmake_minimum_required(VERSION 3.22)
project(xtensor CXX)

set(XTENSOR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
Expand Down
45 changes: 17 additions & 28 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.22)
include(FetchContent)

if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
project(xtensor-benchmark)
Expand All @@ -30,11 +31,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU"
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -g -Wunused-parameter -Wextra -Wreorder")

if(NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
if (HAS_CPP14_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
CHECK_CXX_COMPILER_FLAG("-std=c++20" HAS_CPP20_FLAG)
if (HAS_CPP20_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")
else()
message(FATAL_ERROR "Unsupported compiler -- xtensor requires C++14 support!")
message(FATAL_ERROR "Unsupported compiler -- xtensor requires C++17 support!")
endif()
endif()

Expand Down Expand Up @@ -74,31 +75,17 @@ endif()


if(DOWNLOAD_GBENCHMARK OR GBENCHMARK_SRC_DIR)
if(DOWNLOAD_GBENCHMARK)
# Download and unpack googlebenchmark at configure time
configure_file(downloadGBenchmark.cmake.in googlebenchmark-download/CMakeLists.txt)
else()
# Copy local source of googlebenchmark at configure time
configure_file(copyGBenchmark.cmake.in googlebenchmark-download/CMakeLists.txt)
endif()
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-download )
if(result)
message(FATAL_ERROR "CMake step for googlebenchmark failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-download )
if(result)
message(FATAL_ERROR "Build step for googlebenchmark failed: ${result}")
endif()
FetchContent_Declare(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG main)

# Add googlebenchmark directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-src
${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-build)
FetchContent_Declare(googlebenchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG main) # need main for benchmark::benchmark

FetchContent_MakeAvailable(
googletest
googlebenchmark)
set(GBENCHMARK_INCLUDE_DIRS "${googlebenchmark_SOURCE_DIR}/include")
set(GBENCHMARK_LIBRARIES benchmark)
else()
Expand Down Expand Up @@ -129,9 +116,11 @@ set(XTENSOR_BENCHMARK
benchmark_view_access.cpp
benchmark_view_assignment.cpp
benchmark_view_adapt.cpp
benchmark_stl.cpp
main.cpp
)


set(XTENSOR_BENCHMARK_TARGET benchmark_xtensor)
add_executable(${XTENSOR_BENCHMARK_TARGET} EXCLUDE_FROM_ALL ${XTENSOR_BENCHMARK} ${XTENSOR_HEADERS})
target_link_libraries(${XTENSOR_BENCHMARK_TARGET} PUBLIC xtensor ${GBENCHMARK_LIBRARIES})
Expand Down
157 changes: 157 additions & 0 deletions benchmark/benchmark_stl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#include <benchmark/benchmark.h>

#include "xtensor/containers/xtensor.hpp"
#include "xtensor/core/xmath.hpp"
#include "xtensor/generators/xrandom.hpp"

namespace xt
{
namespace
{
constexpr std::array<size_t, 2> cContainerAssignShape{2000, 2000};

template <class Shape>
auto generateRandomInt16From0To100(Shape&& x)
{
return xt::random::randint(x, 0, 100);
}
}

static void Xtensor_Uint16_2000x2000_DivideBy2_StdTransform(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
std::transform(
vInput.begin(),
vInput.end(),
vOutput.begin(),
[](auto&& aInputValue)
{
return aInputValue / 2;
}
);
}
}

static void Xtensor_Uint16_2000x2000_DivideBy2_Xtensor(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
vOutput = vInput / 2;
}
}

static void Xtensor_Uint16_2000x2000_DivideBy2Double_StdTransform(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
std::transform(
vInput.begin(),
vInput.end(),
vOutput.begin(),
[](auto&& aInputValue)
{
return aInputValue / 2.0;
}
);
}
}

static void Xtensor_Uint16_2000x2000_DivideBy2Double_Xtensor(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
vOutput = vInput / 2.0;
}
}

static void Xtensor_Uint16_2000x2000_MultiplyBy2_StdTransform(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
std::transform(
vInput.begin(),
vInput.end(),
vOutput.begin(),
[](auto&& aInputValue)
{
return aInputValue * 2;
}
);
}
}

static void Xtensor_Uint16_2000x2000_MultiplyBy2_Xtensor(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
vOutput = vInput * 2;
}
}

static void Xtensor_Uint16_2000x2000_Maximum_StdTransform(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput1 = generateRandomInt16From0To100(cContainerAssignShape);
xt::xtensor<uint16_t, 2> vInput2 = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
auto vInput2It = vInput2.begin();
std::transform(
vInput1.begin(),
vInput1.end(),
vOutput.begin(),
[&vInput2It](auto&& aInput1Value)
{
return std::max(aInput1Value, *vInput2It++);
}
);
}
}

static void Xtensor_Uint16_2000x2000_Maximum_Xtensor(benchmark::State& aState)
{
xt::xtensor<uint16_t, 2> vInput1 = generateRandomInt16From0To100(cContainerAssignShape);
xt::xtensor<uint16_t, 2> vInput2 = generateRandomInt16From0To100(cContainerAssignShape);
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);

for (auto _ : aState)
{
vOutput = xt::maximum(vInput1, vInput2);
}
}

BENCHMARK(Xtensor_Uint16_2000x2000_Maximum_Xtensor);
BENCHMARK(Xtensor_Uint16_2000x2000_Maximum_StdTransform);
BENCHMARK(Xtensor_Uint16_2000x2000_MultiplyBy2_Xtensor);
BENCHMARK(Xtensor_Uint16_2000x2000_MultiplyBy2_StdTransform);
BENCHMARK(Xtensor_Uint16_2000x2000_DivideBy2Double_Xtensor);
BENCHMARK(Xtensor_Uint16_2000x2000_DivideBy2Double_StdTransform);
}
2 changes: 1 addition & 1 deletion benchmark/benchmark_view_assignment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,6 @@ namespace xt
// BENCHMARK(assign_create_strided_view);
BENCHMARK(assign_create_view);
BENCHMARK(assign_create_manual_view);
BENCHMARK(data_offset);
// BENCHMARK(data_offset);
BENCHMARK(data_offset_view);
}
2 changes: 1 addition & 1 deletion benchmark/copyGBenchmark.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

cmake_minimum_required(VERSION 2.8.2)
cmake_minimum_required(VERSION 3.5)

project(googlebenchmark-download NONE)

Expand Down
5 changes: 3 additions & 2 deletions benchmark/downloadGBenchmark.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

cmake_minimum_required(VERSION 2.8.2)
cmake_minimum_required(VERSION 3.5)

project(googlebenchmark-download NONE)

include(ExternalProject)
ExternalProject_Add(googlebenchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG v1.3.0
GIT_TAG v1.9.4
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
CMAKE_ARGS "BENCHMARK_DOWNLOAD_DEPENDENCIES=TRUE"
INSTALL_COMMAND ""
TEST_COMMAND ""
)