AimRT/_deps/libunifex-src/test/bulk_schedule_test.cpp
2025-01-12 20:42:42 +08:00

115 lines
3.6 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License Version 2.0 with LLVM Exceptions
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://llvm.org/LICENSE.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <unifex/bulk_schedule.hpp>
#include <unifex/single_thread_context.hpp>
#include <unifex/sync_wait.hpp>
#include <unifex/bulk_transform.hpp>
#include <unifex/bulk_join.hpp>
#include <unifex/let_value_with_stop_source.hpp>
#include <gtest/gtest.h>
TEST(bulk, bulk_transform) {
unifex::single_thread_context ctx;
auto sched = ctx.get_scheduler();
const std::size_t count = 1000;
std::vector<int> output;
output.resize(count);
unifex::sync_wait(
unifex::bulk_join(
unifex::bulk_transform(
unifex::bulk_transform(
unifex::bulk_schedule(sched, count),
[](std::size_t index) noexcept {
// Reverse indices
return count - 1 - index;
}, unifex::par_unseq),
[&](std::size_t index) noexcept {
output[index] = static_cast<int>(index);
}, unifex::par_unseq)));
for (std::size_t i = 0; i < count; ++i) {
EXPECT_EQ(i, output[i]);
}
}
TEST(bulk, cancellation) {
unifex::single_thread_context ctx;
auto sched = ctx.get_scheduler();
const std::size_t count = 1000;
std::vector<int> output(count, 0);
// Cancel after two chunks
// For the serial implementation this will stop the third chunk onwards from
// being dispatched.
const std::size_t compare_index = unifex::bulk_cancellation_chunk_size*2 - 1;
// Bulk, but sequential to test strict cancellation of later work
unifex::sync_wait(
unifex::let_value_with_stop_source([&](unifex::inplace_stop_source& stopSource) {
return unifex::bulk_join(
unifex::bulk_transform(
unifex::bulk_schedule(sched, count),
[&](std::size_t index) noexcept {
// Stop after second chunk
if(index == compare_index) {
stopSource.request_stop();
}
output[index] = static_cast<int>(index);
}, unifex::seq));
}));
for (std::size_t i = 0; i <= compare_index; ++i) {
EXPECT_EQ(static_cast<int>(i), output[i]);
}
for (std::size_t i = compare_index+1; i < count; ++i) {
EXPECT_EQ(0, output[i]);
}
}
TEST(bulk, Pipeable) {
unifex::single_thread_context ctx;
auto sched = ctx.get_scheduler();
const std::size_t count = 1000;
std::vector<int> output;
output.resize(count);
unifex::bulk_schedule(sched, count)
| unifex::bulk_transform(
[](std::size_t index) noexcept {
// Reverse indices
return count - 1 - index;
}, unifex::par_unseq)
| unifex::bulk_transform(
[&](std::size_t index) noexcept {
output[index] = static_cast<int>(index);
}, unifex::par_unseq)
| unifex::bulk_join()
| unifex::sync_wait();
for (std::size_t i = 0; i < count; ++i) {
EXPECT_EQ(i, output[i]);
}
}