1 //===- llvm/unittest/Support/ParallelTest.cpp -----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Parallel.h unit tests. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Support/Parallel.h" 15 #include "gtest/gtest.h" 16 #include <array> 17 #include <random> 18 19 uint32_t array[1024 * 1024]; 20 21 using namespace llvm; 22 23 // Tests below are hanging up on mingw. Investigating. 24 #if !defined(__MINGW32__) 25 26 TEST(Parallel, sort) { 27 std::mt19937 randEngine; 28 std::uniform_int_distribution<uint32_t> dist; 29 30 for (auto &i : array) 31 i = dist(randEngine); 32 33 parallelSort(std::begin(array), std::end(array)); 34 ASSERT_TRUE(llvm::is_sorted(array)); 35 } 36 37 TEST(Parallel, parallel_for) { 38 // We need to test the case with a TaskSize > 1. We are white-box testing 39 // here. The TaskSize is calculated as (End - Begin) / 1024 at the time of 40 // writing. 41 uint32_t range[2050]; 42 std::fill(range, range + 2050, 1); 43 parallelFor(0, 2049, [&range](size_t I) { ++range[I]; }); 44 45 uint32_t expected[2049]; 46 std::fill(expected, expected + 2049, 2); 47 ASSERT_TRUE(std::equal(range, range + 2049, expected)); 48 // Check that we don't write past the end of the requested range. 49 ASSERT_EQ(range[2049], 1u); 50 } 51 52 TEST(Parallel, TransformReduce) { 53 // Sum an empty list, check that it works. 54 auto identity = [](uint32_t v) { return v; }; 55 uint32_t sum = parallelTransformReduce(ArrayRef<uint32_t>(), 0U, 56 std::plus<uint32_t>(), identity); 57 EXPECT_EQ(sum, 0U); 58 59 // Sum the lengths of these strings in parallel. 60 const char *strs[] = {"a", "ab", "abc", "abcd", "abcde", "abcdef"}; 61 size_t lenSum = 62 parallelTransformReduce(strs, static_cast<size_t>(0), std::plus<size_t>(), 63 [](const char *s) { return strlen(s); }); 64 EXPECT_EQ(lenSum, static_cast<size_t>(21)); 65 66 // Check that we handle non-divisible task sizes as above. 67 uint32_t range[2050]; 68 std::fill(std::begin(range), std::end(range), 1); 69 sum = parallelTransformReduce(range, 0U, std::plus<uint32_t>(), identity); 70 EXPECT_EQ(sum, 2050U); 71 72 std::fill(std::begin(range), std::end(range), 2); 73 sum = parallelTransformReduce(range, 0U, std::plus<uint32_t>(), identity); 74 EXPECT_EQ(sum, 4100U); 75 76 // Avoid one large task. 77 uint32_t range2[3060]; 78 std::fill(std::begin(range2), std::end(range2), 1); 79 sum = parallelTransformReduce(range2, 0U, std::plus<uint32_t>(), identity); 80 EXPECT_EQ(sum, 3060U); 81 } 82 83 TEST(Parallel, ForEachError) { 84 int nums[] = {1, 2, 3, 4, 5, 6}; 85 Error e = parallelForEachError(nums, [](int v) -> Error { 86 if ((v & 1) == 0) 87 return createStringError(std::errc::invalid_argument, "asdf"); 88 return Error::success(); 89 }); 90 EXPECT_TRUE(e.isA<ErrorList>()); 91 std::string errText = toString(std::move(e)); 92 EXPECT_EQ(errText, std::string("asdf\nasdf\nasdf")); 93 } 94 95 TEST(Parallel, TaskGroupSequentialFor) { 96 size_t Count = 0; 97 { 98 parallel::TaskGroup tg; 99 for (size_t Idx = 0; Idx < 500; Idx++) 100 tg.spawn([&Count, Idx]() { EXPECT_EQ(Count++, Idx); }, true); 101 } 102 EXPECT_EQ(Count, 500ul); 103 } 104 105 #endif 106