13a57fbd6SZachary Turner //===- llvm/unittest/Support/ParallelTest.cpp -----------------------------===//
23a57fbd6SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63a57fbd6SZachary Turner //
73a57fbd6SZachary Turner //===----------------------------------------------------------------------===//
83a57fbd6SZachary Turner ///
93a57fbd6SZachary Turner /// \file
105f8f34e4SAdrian Prantl /// Parallel.h unit tests.
113a57fbd6SZachary Turner ///
123a57fbd6SZachary Turner //===----------------------------------------------------------------------===//
133a57fbd6SZachary Turner
143a57fbd6SZachary Turner #include "llvm/Support/Parallel.h"
153a57fbd6SZachary Turner #include "gtest/gtest.h"
163a57fbd6SZachary Turner #include <array>
173a57fbd6SZachary Turner #include <random>
183a57fbd6SZachary Turner
193a57fbd6SZachary Turner uint32_t array[1024 * 1024];
203a57fbd6SZachary Turner
213a57fbd6SZachary Turner using namespace llvm;
223a57fbd6SZachary Turner
23cf84800eSNAKAMURA Takumi // Tests below are hanging up on mingw. Investigating.
24cf84800eSNAKAMURA Takumi #if !defined(__MINGW32__)
25cf84800eSNAKAMURA Takumi
TEST(Parallel,sort)263a57fbd6SZachary Turner TEST(Parallel, sort) {
273a57fbd6SZachary Turner std::mt19937 randEngine;
283a57fbd6SZachary Turner std::uniform_int_distribution<uint32_t> dist;
293a57fbd6SZachary Turner
303a57fbd6SZachary Turner for (auto &i : array)
313a57fbd6SZachary Turner i = dist(randEngine);
323a57fbd6SZachary Turner
33932f0276SReid Kleckner parallelSort(std::begin(array), std::end(array));
341647ff6eSGeorgii Rymar ASSERT_TRUE(llvm::is_sorted(array));
353a57fbd6SZachary Turner }
363a57fbd6SZachary Turner
TEST(Parallel,parallel_for)373a57fbd6SZachary Turner TEST(Parallel, parallel_for) {
383a57fbd6SZachary Turner // We need to test the case with a TaskSize > 1. We are white-box testing
393a57fbd6SZachary Turner // here. The TaskSize is calculated as (End - Begin) / 1024 at the time of
403a57fbd6SZachary Turner // writing.
413a57fbd6SZachary Turner uint32_t range[2050];
423a57fbd6SZachary Turner std::fill(range, range + 2050, 1);
43*7effcbdaSNico Weber parallelFor(0, 2049, [&range](size_t I) { ++range[I]; });
443a57fbd6SZachary Turner
453a57fbd6SZachary Turner uint32_t expected[2049];
463a57fbd6SZachary Turner std::fill(expected, expected + 2049, 2);
473a57fbd6SZachary Turner ASSERT_TRUE(std::equal(range, range + 2049, expected));
483a57fbd6SZachary Turner // Check that we don't write past the end of the requested range.
493a57fbd6SZachary Turner ASSERT_EQ(range[2049], 1u);
503a57fbd6SZachary Turner }
51cf84800eSNAKAMURA Takumi
TEST(Parallel,TransformReduce)52c0a922b3SReid Kleckner TEST(Parallel, TransformReduce) {
53c0a922b3SReid Kleckner // Sum an empty list, check that it works.
54c0a922b3SReid Kleckner auto identity = [](uint32_t v) { return v; };
55c0a922b3SReid Kleckner uint32_t sum = parallelTransformReduce(ArrayRef<uint32_t>(), 0U,
56c0a922b3SReid Kleckner std::plus<uint32_t>(), identity);
57c0a922b3SReid Kleckner EXPECT_EQ(sum, 0U);
58c0a922b3SReid Kleckner
59c0a922b3SReid Kleckner // Sum the lengths of these strings in parallel.
60c0a922b3SReid Kleckner const char *strs[] = {"a", "ab", "abc", "abcd", "abcde", "abcdef"};
61c0a922b3SReid Kleckner size_t lenSum =
62c0a922b3SReid Kleckner parallelTransformReduce(strs, static_cast<size_t>(0), std::plus<size_t>(),
63c0a922b3SReid Kleckner [](const char *s) { return strlen(s); });
64c0a922b3SReid Kleckner EXPECT_EQ(lenSum, static_cast<size_t>(21));
65c0a922b3SReid Kleckner
66c0a922b3SReid Kleckner // Check that we handle non-divisible task sizes as above.
67c0a922b3SReid Kleckner uint32_t range[2050];
68c0a922b3SReid Kleckner std::fill(std::begin(range), std::end(range), 1);
69c0a922b3SReid Kleckner sum = parallelTransformReduce(range, 0U, std::plus<uint32_t>(), identity);
70c0a922b3SReid Kleckner EXPECT_EQ(sum, 2050U);
71c0a922b3SReid Kleckner
72c0a922b3SReid Kleckner std::fill(std::begin(range), std::end(range), 2);
73c0a922b3SReid Kleckner sum = parallelTransformReduce(range, 0U, std::plus<uint32_t>(), identity);
74c0a922b3SReid Kleckner EXPECT_EQ(sum, 4100U);
75c0a922b3SReid Kleckner
76c0a922b3SReid Kleckner // Avoid one large task.
77c0a922b3SReid Kleckner uint32_t range2[3060];
78c0a922b3SReid Kleckner std::fill(std::begin(range2), std::end(range2), 1);
79c0a922b3SReid Kleckner sum = parallelTransformReduce(range2, 0U, std::plus<uint32_t>(), identity);
80c0a922b3SReid Kleckner EXPECT_EQ(sum, 3060U);
81c0a922b3SReid Kleckner }
82c0a922b3SReid Kleckner
TEST(Parallel,ForEachError)83c0a922b3SReid Kleckner TEST(Parallel, ForEachError) {
84c0a922b3SReid Kleckner int nums[] = {1, 2, 3, 4, 5, 6};
85c0a922b3SReid Kleckner Error e = parallelForEachError(nums, [](int v) -> Error {
86c0a922b3SReid Kleckner if ((v & 1) == 0)
87c0a922b3SReid Kleckner return createStringError(std::errc::invalid_argument, "asdf");
88c0a922b3SReid Kleckner return Error::success();
89c0a922b3SReid Kleckner });
90c0a922b3SReid Kleckner EXPECT_TRUE(e.isA<ErrorList>());
91c0a922b3SReid Kleckner std::string errText = toString(std::move(e));
92c0a922b3SReid Kleckner EXPECT_EQ(errText, std::string("asdf\nasdf\nasdf"));
93c0a922b3SReid Kleckner }
94c0a922b3SReid Kleckner
95cf84800eSNAKAMURA Takumi #endif
96