folly copyright 2015 -> copyright 2016
[folly.git] / folly / gen / test / ParallelTest.cpp
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <glog/logging.h>
18 #include <gtest/gtest.h>
19 #include <iostream>
20 #include <array>
21 #include <vector>
22 #include <folly/gen/Base.h>
23 #include <folly/gen/Parallel.h>
24
25 using namespace folly;
26 using namespace folly::gen;
27 using std::vector;
28
29 const auto square = [](int i) { return i * i; };
30 const auto even = [](int i) { return 0 == i % 2; };
31 static auto sleepyWork = [](int i) {
32   const auto sleepyTime = std::chrono::microseconds(100);
33   std::this_thread::sleep_for(sleepyTime);
34   return i;
35 };
36
37 static auto isPrime = [](int n) {
38   if (n < 2) {
39     return false;
40   } else if (n > 2) {
41     for (int d = 3; d * d <= n; d += 2) {
42       if (0 == n % d) {
43         return false;
44       }
45     }
46   }
47   return true;
48 };
49
50 struct {
51   template<class T>
52   std::unique_ptr<T> operator()(T t) const {
53     return std::unique_ptr<T>(new T(std::move(t)));
54   }
55 } makeUnique;
56
57 static auto primes = seq(1, 1 << 14)
58                    | filter(isPrime)
59                    | as<vector<size_t>>();
60
61 static auto primeFactors = [](int n) {
62   return from(primes)
63        | filter([&](int d) { return 0 == n % d; })
64        | count;
65 };
66
67 TEST(ParallelTest, Serial) {
68   EXPECT_EQ(
69             seq(1,10) | map(square) | filter(even) | sum,
70             seq(1,10) | parallel(map(square) | filter(even)) | sum);
71 }
72
73 auto heavyWork = map(primeFactors);
74
75 TEST(ParallelTest, ComputeBound64) {
76   int length = 1 << 10;
77   EXPECT_EQ(seq<size_t>(1, length) | heavyWork | sum,
78             seq<size_t>(1, length) | parallel(heavyWork) | sum);
79 }
80
81 TEST(ParallelTest, Take) {
82   int length = 1 << 18;
83   int limit = 1 << 14;
84   EXPECT_EQ(seq(1, length) | take(limit) | count,
85             seq(1, length) | parallel(heavyWork) | take(limit) | count);
86 }
87
88
89 TEST(ParallelTest, Unique) {
90   auto uniqued = from(primes) | map(makeUnique) | as<vector>();
91   EXPECT_EQ(primes.size(),
92             from(primes) | parallel(map(makeUnique)) |
93                 parallel(dereference | map(makeUnique)) | dereference | count);
94   EXPECT_EQ(2,
95             from(primes) | parallel(map(makeUnique)) |
96                 parallel(dereference | map(makeUnique)) | dereference |
97                 take(2) | count);
98 }
99
100 TEST(ParallelTest, PSum) {
101   EXPECT_EQ(from(primes) | map(sleepyWork) | sum,
102             from(primes) | parallel(map(sleepyWork) | sub(sum)) | sum);
103 }
104
105 int main(int argc, char *argv[]) {
106   testing::InitGoogleTest(&argc, argv);
107   gflags::ParseCommandLineFlags(&argc, &argv, true);
108   return RUN_ALL_TESTS();
109 }