Skip to content

Commit 977aa1b

Browse files
authored
Revive benchmarks (#2854)
Revive benchmarks
1 parent 2be98b4 commit 977aa1b

File tree

7 files changed

+253
-33
lines changed

7 files changed

+253
-33
lines changed

.github/workflows/benchmarks.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: benchmarks
2+
on:
3+
workflow_dispatch:
4+
pull_request:
5+
push:
6+
branches: [master]
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }}
9+
cancel-in-progress: true
10+
defaults:
11+
run:
12+
shell: bash -e -l {0}
13+
jobs:
14+
build:
15+
runs-on: ubuntu-24.04
16+
name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} - ${{ matrix.sys.name }}
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
sys:
21+
- {compiler: clang, version: '20', name: xsimd, flags: -DXTENSOR_USE_XSIMD=ON}
22+
- {compiler: clang, version: '20', name: xsimd-tbb, flags: -DXTENSOR_USE_XSIMD=ON -DXTENSOR_USE_TBB=ON}
23+
- {compiler: gcc, version: '14', name: xsimd, flags: -DXTENSOR_USE_XSIMD=ON}
24+
- {compiler: gcc, version: '14', name: xsimd-tbb, flags: -DXTENSOR_USE_XSIMD=ON -DXTENSOR_USE_TBB=ON}
25+
26+
steps:
27+
- name: Install GCC
28+
if: matrix.sys.compiler == 'gcc'
29+
uses: egor-tensin/setup-gcc@v1
30+
with:
31+
version: ${{matrix.sys.version}}
32+
platform: x64
33+
34+
- name: Install LLVM and Clang
35+
if: matrix.sys.compiler == 'clang'
36+
run: |
37+
wget https://apt.llvm.org/llvm.sh
38+
chmod +x llvm.sh
39+
sudo ./llvm.sh ${{matrix.sys.version}}
40+
sudo apt-get install -y clang-tools-${{matrix.sys.version}}
41+
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${{matrix.sys.version}} 200
42+
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${{matrix.sys.version}} 200
43+
sudo update-alternatives --install /usr/bin/clang-scan-deps clang-scan-deps /usr/bin/clang-scan-deps-${{matrix.sys.version}} 200
44+
sudo update-alternatives --set clang /usr/bin/clang-${{matrix.sys.version}}
45+
sudo update-alternatives --set clang++ /usr/bin/clang++-${{matrix.sys.version}}
46+
sudo update-alternatives --set clang-scan-deps /usr/bin/clang-scan-deps-${{matrix.sys.version}}
47+
48+
- name: Checkout code
49+
uses: actions/checkout@v3
50+
51+
- name: Set conda environment
52+
uses: mamba-org/setup-micromamba@main
53+
with:
54+
environment-name: myenv
55+
environment-file: environment-dev.yml
56+
init-shell: bash
57+
cache-downloads: true
58+
create-args: |
59+
${{ (matrix.sys.name == 'tbb' || matrix.sys.name == 'xsimd-tbb' ) && 'tbb-devel' || '' }}
60+
61+
- name: Configure using CMake
62+
run: |
63+
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
64+
cmake -G Ninja -Bbuild -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DBUILD_BENCHMARK=ON ${{ matrix.sys.flags }}
65+
66+
- name: Build
67+
working-directory: build
68+
run: cmake --build . --target benchmark_xtensor --parallel 8
69+
70+
- name: Run benchmark
71+
timeout-minutes: 10 # Consider increasing timeout
72+
working-directory: build/benchmark
73+
run: ./benchmark_xtensor

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# The full license is in the file LICENSE, distributed with this software. #
88
############################################################################
99

10-
cmake_minimum_required(VERSION 3.29)
10+
cmake_minimum_required(VERSION 3.22)
1111
project(xtensor CXX)
1212

1313
set(XTENSOR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

benchmark/CMakeLists.txt

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
# The full license is in the file LICENSE, distributed with this software. #
77
############################################################################
88

9-
cmake_minimum_required(VERSION 3.5)
9+
cmake_minimum_required(VERSION 3.22)
10+
include(FetchContent)
1011

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

3233
if(NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
33-
CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
34-
if (HAS_CPP14_FLAG)
35-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
34+
CHECK_CXX_COMPILER_FLAG("-std=c++20" HAS_CPP20_FLAG)
35+
if (HAS_CPP20_FLAG)
36+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")
3637
else()
37-
message(FATAL_ERROR "Unsupported compiler -- xtensor requires C++14 support!")
38+
message(FATAL_ERROR "Unsupported compiler -- xtensor requires C++17 support!")
3839
endif()
3940
endif()
4041

@@ -74,31 +75,17 @@ endif()
7475

7576

7677
if(DOWNLOAD_GBENCHMARK OR GBENCHMARK_SRC_DIR)
77-
if(DOWNLOAD_GBENCHMARK)
78-
# Download and unpack googlebenchmark at configure time
79-
configure_file(downloadGBenchmark.cmake.in googlebenchmark-download/CMakeLists.txt)
80-
else()
81-
# Copy local source of googlebenchmark at configure time
82-
configure_file(copyGBenchmark.cmake.in googlebenchmark-download/CMakeLists.txt)
83-
endif()
84-
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
85-
RESULT_VARIABLE result
86-
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-download )
87-
if(result)
88-
message(FATAL_ERROR "CMake step for googlebenchmark failed: ${result}")
89-
endif()
90-
execute_process(COMMAND ${CMAKE_COMMAND} --build .
91-
RESULT_VARIABLE result
92-
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-download )
93-
if(result)
94-
message(FATAL_ERROR "Build step for googlebenchmark failed: ${result}")
95-
endif()
78+
FetchContent_Declare(googletest
79+
GIT_REPOSITORY https://github.com/google/googletest.git
80+
GIT_TAG main)
9681

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

86+
FetchContent_MakeAvailable(
87+
googletest
88+
googlebenchmark)
10289
set(GBENCHMARK_INCLUDE_DIRS "${googlebenchmark_SOURCE_DIR}/include")
10390
set(GBENCHMARK_LIBRARIES benchmark)
10491
else()
@@ -129,9 +116,11 @@ set(XTENSOR_BENCHMARK
129116
benchmark_view_access.cpp
130117
benchmark_view_assignment.cpp
131118
benchmark_view_adapt.cpp
119+
benchmark_stl.cpp
132120
main.cpp
133121
)
134122

123+
135124
set(XTENSOR_BENCHMARK_TARGET benchmark_xtensor)
136125
add_executable(${XTENSOR_BENCHMARK_TARGET} EXCLUDE_FROM_ALL ${XTENSOR_BENCHMARK} ${XTENSOR_HEADERS})
137126
target_link_libraries(${XTENSOR_BENCHMARK_TARGET} PUBLIC xtensor ${GBENCHMARK_LIBRARIES})

benchmark/benchmark_stl.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/***************************************************************************
2+
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3+
* *
4+
* Distributed under the terms of the BSD 3-Clause License. *
5+
* *
6+
* The full license is in the file LICENSE, distributed with this software. *
7+
****************************************************************************/
8+
9+
#include <benchmark/benchmark.h>
10+
11+
#include "xtensor/containers/xtensor.hpp"
12+
#include "xtensor/core/xmath.hpp"
13+
#include "xtensor/generators/xrandom.hpp"
14+
15+
namespace xt
16+
{
17+
namespace
18+
{
19+
constexpr std::array<size_t, 2> cContainerAssignShape{2000, 2000};
20+
21+
template <class Shape>
22+
auto generateRandomInt16From0To100(Shape&& x)
23+
{
24+
return xt::random::randint(x, 0, 100);
25+
}
26+
}
27+
28+
static void Xtensor_Uint16_2000x2000_DivideBy2_StdTransform(benchmark::State& aState)
29+
{
30+
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
31+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
32+
33+
for (auto _ : aState)
34+
{
35+
std::transform(
36+
vInput.begin(),
37+
vInput.end(),
38+
vOutput.begin(),
39+
[](auto&& aInputValue)
40+
{
41+
return aInputValue / 2;
42+
}
43+
);
44+
}
45+
}
46+
47+
static void Xtensor_Uint16_2000x2000_DivideBy2_Xtensor(benchmark::State& aState)
48+
{
49+
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
50+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
51+
52+
for (auto _ : aState)
53+
{
54+
vOutput = vInput / 2;
55+
}
56+
}
57+
58+
static void Xtensor_Uint16_2000x2000_DivideBy2Double_StdTransform(benchmark::State& aState)
59+
{
60+
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
61+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
62+
63+
for (auto _ : aState)
64+
{
65+
std::transform(
66+
vInput.begin(),
67+
vInput.end(),
68+
vOutput.begin(),
69+
[](auto&& aInputValue)
70+
{
71+
return aInputValue / 2.0;
72+
}
73+
);
74+
}
75+
}
76+
77+
static void Xtensor_Uint16_2000x2000_DivideBy2Double_Xtensor(benchmark::State& aState)
78+
{
79+
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
80+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
81+
82+
for (auto _ : aState)
83+
{
84+
vOutput = vInput / 2.0;
85+
}
86+
}
87+
88+
static void Xtensor_Uint16_2000x2000_MultiplyBy2_StdTransform(benchmark::State& aState)
89+
{
90+
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
91+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
92+
93+
for (auto _ : aState)
94+
{
95+
std::transform(
96+
vInput.begin(),
97+
vInput.end(),
98+
vOutput.begin(),
99+
[](auto&& aInputValue)
100+
{
101+
return aInputValue * 2;
102+
}
103+
);
104+
}
105+
}
106+
107+
static void Xtensor_Uint16_2000x2000_MultiplyBy2_Xtensor(benchmark::State& aState)
108+
{
109+
xt::xtensor<uint16_t, 2> vInput = generateRandomInt16From0To100(cContainerAssignShape);
110+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
111+
112+
for (auto _ : aState)
113+
{
114+
vOutput = vInput * 2;
115+
}
116+
}
117+
118+
static void Xtensor_Uint16_2000x2000_Maximum_StdTransform(benchmark::State& aState)
119+
{
120+
xt::xtensor<uint16_t, 2> vInput1 = generateRandomInt16From0To100(cContainerAssignShape);
121+
xt::xtensor<uint16_t, 2> vInput2 = generateRandomInt16From0To100(cContainerAssignShape);
122+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
123+
124+
for (auto _ : aState)
125+
{
126+
auto vInput2It = vInput2.begin();
127+
std::transform(
128+
vInput1.begin(),
129+
vInput1.end(),
130+
vOutput.begin(),
131+
[&vInput2It](auto&& aInput1Value)
132+
{
133+
return std::max(aInput1Value, *vInput2It++);
134+
}
135+
);
136+
}
137+
}
138+
139+
static void Xtensor_Uint16_2000x2000_Maximum_Xtensor(benchmark::State& aState)
140+
{
141+
xt::xtensor<uint16_t, 2> vInput1 = generateRandomInt16From0To100(cContainerAssignShape);
142+
xt::xtensor<uint16_t, 2> vInput2 = generateRandomInt16From0To100(cContainerAssignShape);
143+
auto vOutput = xt::xtensor<uint16_t, 2>::from_shape(cContainerAssignShape);
144+
145+
for (auto _ : aState)
146+
{
147+
vOutput = xt::maximum(vInput1, vInput2);
148+
}
149+
}
150+
151+
BENCHMARK(Xtensor_Uint16_2000x2000_Maximum_Xtensor);
152+
BENCHMARK(Xtensor_Uint16_2000x2000_Maximum_StdTransform);
153+
BENCHMARK(Xtensor_Uint16_2000x2000_MultiplyBy2_Xtensor);
154+
BENCHMARK(Xtensor_Uint16_2000x2000_MultiplyBy2_StdTransform);
155+
BENCHMARK(Xtensor_Uint16_2000x2000_DivideBy2Double_Xtensor);
156+
BENCHMARK(Xtensor_Uint16_2000x2000_DivideBy2Double_StdTransform);
157+
}

benchmark/benchmark_view_assignment.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,6 @@ namespace xt
155155
// BENCHMARK(assign_create_strided_view);
156156
BENCHMARK(assign_create_view);
157157
BENCHMARK(assign_create_manual_view);
158-
BENCHMARK(data_offset);
158+
// BENCHMARK(data_offset);
159159
BENCHMARK(data_offset_view);
160160
}

benchmark/copyGBenchmark.cmake.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The full license is in the file LICENSE, distributed with this software. #
77
############################################################################
88

9-
cmake_minimum_required(VERSION 2.8.2)
9+
cmake_minimum_required(VERSION 3.5)
1010

1111
project(googlebenchmark-download NONE)
1212

benchmark/downloadGBenchmark.cmake.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@
66
# The full license is in the file LICENSE, distributed with this software. #
77
############################################################################
88

9-
cmake_minimum_required(VERSION 2.8.2)
9+
cmake_minimum_required(VERSION 3.5)
1010

1111
project(googlebenchmark-download NONE)
1212

1313
include(ExternalProject)
1414
ExternalProject_Add(googlebenchmark
1515
GIT_REPOSITORY https://github.com/google/benchmark.git
16-
GIT_TAG v1.3.0
16+
GIT_TAG v1.9.4
1717
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-src"
1818
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googlebenchmark-build"
1919
CONFIGURE_COMMAND ""
2020
BUILD_COMMAND ""
21+
CMAKE_ARGS "BENCHMARK_DOWNLOAD_DEPENDENCIES=TRUE"
2122
INSTALL_COMMAND ""
2223
TEST_COMMAND ""
2324
)

0 commit comments

Comments
 (0)