Skip to content

Commit

Permalink
Merge pull request #178 from krasznaa/CopyOptimisation-main-20220530
Browse files Browse the repository at this point in the history
Copy Optimisation, main branch (2022.05.30.)
  • Loading branch information
krasznaa authored Jun 3, 2022
2 parents e95c4cd + 8efbcc2 commit b88f2a9
Show file tree
Hide file tree
Showing 14 changed files with 787 additions and 16 deletions.
12 changes: 12 additions & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,20 @@ if(VECMEM_SETUP_GOOGLEBENCHMARK)
endif()
endif()

# Build a common, helper library.
add_library( vecmem_benchmark_common STATIC
"common/make_jagged_sizes.hpp"
"common/make_jagged_sizes.cpp"
"common/make_jagged_vector.hpp"
"common/make_jagged_vector.cpp" )
target_link_libraries( vecmem_benchmark_common
PUBLIC vecmem::core )

# Include the library specific tests.
add_subdirectory(core)
if(VECMEM_BUILD_CUDA_LIBRARY)
add_subdirectory(cuda)
endif()
if(VECMEM_BUILD_SYCL_LIBRARY)
add_subdirectory(sycl)
endif()
35 changes: 35 additions & 0 deletions benchmarks/common/make_jagged_sizes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* VecMem project, part of the ACTS project (R&D line)
*
* (c) 2022 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

// Local include(s).
#include "make_jagged_sizes.hpp"

// System include(s).
#include <algorithm>
#include <random>

namespace vecmem::benchmark {

std::vector<std::size_t> make_jagged_sizes(std::size_t outerSize,
std::size_t maxInnerSize) {

// Set up a simple random number generator for the inner vector sizes.
std::default_random_engine eng;
eng.seed(outerSize + maxInnerSize);
std::uniform_int_distribution<std::size_t> gen(0, maxInnerSize);

// Generate the result vector.
std::vector<std::size_t> result(outerSize);
std::generate(result.begin(), result.end(),
[&eng, &gen]() { return gen(eng); });

// Give it to the user.
return result;
}

} // namespace vecmem::benchmark
30 changes: 30 additions & 0 deletions benchmarks/common/make_jagged_sizes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* VecMem project, part of the ACTS project (R&D line)
*
* (c) 2022 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

#pragma once

// System include(s).
#include <cstddef>
#include <vector>

namespace vecmem::benchmark {

/// Helper function for generating the sizes for a jagged vector (buffer)
///
/// It implements a pretty simple thing, but since this is used in multiple
/// places, it made sense to put it into a central location.
///
/// @param outerSize The fixed "outer size" of the jagged vector (buffer)
/// @param maxInnerSize The maximum for the random "inner sizes" of the
/// resulting vector (buffer)
/// @return A vector of sizes corresponding to the received parameters
///
std::vector<std::size_t> make_jagged_sizes(std::size_t outerSize,
std::size_t maxInnerSize);

} // namespace vecmem::benchmark
28 changes: 28 additions & 0 deletions benchmarks/common/make_jagged_vector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* VecMem project, part of the ACTS project (R&D line)
*
* (c) 2022 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

// Local include(s).
#include "make_jagged_vector.hpp"

namespace vecmem::benchmark {

jagged_vector<int> make_jagged_vector(const std::vector<std::size_t>& sizes,
memory_resource& mr) {

// Create the result object.
jagged_vector<int> result(&mr);
result.reserve(sizes.size());
for (std::size_t size : sizes) {
result.push_back(jagged_vector<int>::value_type(size, &mr));
}

// Return the vector.
return result;
}

} // namespace vecmem::benchmark
33 changes: 33 additions & 0 deletions benchmarks/common/make_jagged_vector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* VecMem project, part of the ACTS project (R&D line)
*
* (c) 2022 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

#pragma once

// VecMem include(s).
#include <vecmem/containers/jagged_vector.hpp>
#include <vecmem/memory/memory_resource.hpp>

// System include(s).
#include <cstddef>
#include <vector>

namespace vecmem::benchmark {

/// Function creating a jagged vector with some general size specifications
///
/// It creates a jagged vector with a fixed "outer size", and random sized
/// "inner vectors" that would not be larger than some specified value.
///
/// @param sizes The sizes of the vectors in the jagged vector
/// @param mr The memory resource to use
/// @return A jagged vector with the specifier properties
///
jagged_vector<int> make_jagged_vector(const std::vector<std::size_t>& sizes,
memory_resource& mr);

} // namespace vecmem::benchmark
5 changes: 4 additions & 1 deletion benchmarks/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@
include( vecmem-compiler-options-cpp )

# Set up the benchmark(s) for the core library.
add_executable(vecmem_benchmark_core "benchmark_core.cpp")
add_executable( vecmem_benchmark_core
"benchmark_core.cpp"
"benchmark_copy.cpp" )

target_link_libraries(
vecmem_benchmark_core

PRIVATE
vecmem::core
vecmem_benchmark_common
benchmark::benchmark
benchmark::benchmark_main
)
159 changes: 159 additions & 0 deletions benchmarks/core/benchmark_copy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* VecMem project, part of the ACTS project (R&D line)
*
* (c) 2022 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

// VecMem include(s).
#include <vecmem/memory/host_memory_resource.hpp>
#include <vecmem/utils/copy.hpp>

// Common benchmark include(s).
#include "../common/make_jagged_sizes.hpp"
#include "../common/make_jagged_vector.hpp"

// Google benchmark include(s).
#include <benchmark/benchmark.h>

// System include(s).
#include <numeric>
#include <vector>

namespace vecmem::benchmark {

/// The (host) memory resource to use in the benchmark(s).
static host_memory_resource host_mr;
/// The copy object to use in the benchmark(s).
static copy host_copy;

/// Function benchmarking "unknown" host-to-device jagged vector copies
void jaggedVectorUnknownHtoDCopy(::benchmark::State& state) {

// Generate the sizes of the jagged vector/buffer for the test.
const std::vector<std::size_t> sizes =
make_jagged_sizes(state.range(0), state.range(1));

// Set custom "counters" for the benchmark.
const std::size_t bytes = std::accumulate(sizes.begin(), sizes.end(),
static_cast<std::size_t>(0u)) *
sizeof(int);
state.counters["Bytes"] = static_cast<double>(bytes);
state.counters["Rate"] =
::benchmark::Counter(static_cast<double>(bytes),
::benchmark::Counter::kIsIterationInvariantRate,
::benchmark::Counter::kIs1024);

// Create the "source vector".
jagged_vector<int> source = make_jagged_vector(sizes, host_mr);
const data::jagged_vector_data<int> source_data = get_data(source);
// Create the "destination buffer".
data::jagged_vector_buffer<int> dest(sizes, host_mr);
host_copy.setup(dest);

// Perform the copy benchmark.
for (auto _ : state) {
host_copy(source_data, dest);
}
}
// Set up the benchmark.
BENCHMARK(jaggedVectorUnknownHtoDCopy)->Ranges({{10, 100000}, {50, 5000}});

/// Function benchmarking "known" host-to-device jagged vector copies
void jaggedVectorKnownHtoDCopy(::benchmark::State& state) {

// Generate the sizes of the jagged vector/buffer for the test.
const std::vector<std::size_t> sizes =
make_jagged_sizes(state.range(0), state.range(1));

// Set custom "counters" for the benchmark.
const std::size_t bytes = std::accumulate(sizes.begin(), sizes.end(),
static_cast<std::size_t>(0u)) *
sizeof(int);
state.counters["Bytes"] = static_cast<double>(bytes);
state.counters["Rate"] =
::benchmark::Counter(static_cast<double>(bytes),
::benchmark::Counter::kIsIterationInvariantRate,
::benchmark::Counter::kIs1024);

// Create the "source vector".
jagged_vector<int> source = make_jagged_vector(sizes, host_mr);
const data::jagged_vector_data<int> source_data = get_data(source);
// Create the "destination buffer".
data::jagged_vector_buffer<int> dest(sizes, host_mr);
host_copy.setup(dest);

// Perform the copy benchmark.
for (auto _ : state) {
host_copy(source_data, dest, copy::type::host_to_device);
}
}
// Set up the benchmark.
BENCHMARK(jaggedVectorKnownHtoDCopy)->Ranges({{10, 100000}, {50, 5000}});

/// Function benchmarking "unknown" device-to-host jagged vector copies
void jaggedVectorUnknownDtoHCopy(::benchmark::State& state) {

// Generate the sizes of the jagged vector/buffer for the test.
const std::vector<std::size_t> sizes =
make_jagged_sizes(state.range(0), state.range(1));

// Set custom "counters" for the benchmark.
const std::size_t bytes = std::accumulate(sizes.begin(), sizes.end(),
static_cast<std::size_t>(0u)) *
sizeof(int);
state.counters["Bytes"] = static_cast<double>(bytes);
state.counters["Rate"] =
::benchmark::Counter(static_cast<double>(bytes),
::benchmark::Counter::kIsIterationInvariantRate,
::benchmark::Counter::kIs1024);

// Create the "source buffer".
data::jagged_vector_buffer<int> source(sizes, host_mr);
host_copy.setup(source);
// Create the "destination vector".
jagged_vector<int> dest = make_jagged_vector(sizes, host_mr);
data::jagged_vector_data<int> dest_data = get_data(dest);

// Perform the copy benchmark.
for (auto _ : state) {
host_copy(source, dest_data);
}
}
// Set up the benchmark.
BENCHMARK(jaggedVectorUnknownDtoHCopy)->Ranges({{10, 100000}, {50, 5000}});

/// Function benchmarking "known" device-to-host jagged vector copies
void jaggedVectorKnownDtoHCopy(::benchmark::State& state) {

// Generate the sizes of the jagged vector/buffer for the test.
const std::vector<std::size_t> sizes =
make_jagged_sizes(state.range(0), state.range(1));

// Set custom "counters" for the benchmark.
const std::size_t bytes = std::accumulate(sizes.begin(), sizes.end(),
static_cast<std::size_t>(0u)) *
sizeof(int);
state.counters["Bytes"] = static_cast<double>(bytes);
state.counters["Rate"] =
::benchmark::Counter(static_cast<double>(bytes),
::benchmark::Counter::kIsIterationInvariantRate,
::benchmark::Counter::kIs1024);

// Create the "source buffer".
data::jagged_vector_buffer<int> source(sizes, host_mr);
host_copy.setup(source);
// Create the "destination vector".
jagged_vector<int> dest = make_jagged_vector(sizes, host_mr);
data::jagged_vector_data<int> dest_data = get_data(dest);

// Perform the copy benchmark.
for (auto _ : state) {
host_copy(source, dest_data, copy::type::device_to_host);
}
}
// Set up the benchmark.
BENCHMARK(jaggedVectorKnownDtoHCopy)->Ranges({{10, 100000}, {50, 5000}});

} // namespace vecmem::benchmark
5 changes: 4 additions & 1 deletion benchmarks/cuda/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ include( vecmem-compiler-options-cpp )
include( vecmem-compiler-options-cuda )

# Set up the benchmark(s) for the CUDA library.
add_executable(vecmem_benchmark_cuda "benchmark_cuda.cpp")
add_executable( vecmem_benchmark_cuda
"benchmark_cuda.cpp"
"benchmark_copy.cpp" )

target_link_libraries(
vecmem_benchmark_cuda

PRIVATE
vecmem::cuda
vecmem_benchmark_common
benchmark::benchmark
benchmark::benchmark_main
)
Loading

0 comments on commit b88f2a9

Please sign in to comment.