xref: /aosp_15_r20/external/swiftshader/third_party/marl/examples/primes.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The Marl Authors.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker // This is an example application that uses Marl to find and print all the prime
16*03ce13f7SAndroid Build Coastguard Worker // numbers in the range 1 to 10000000.
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "marl/defer.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "marl/scheduler.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "marl/thread.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "marl/ticket.h"
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker #include <vector>
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker #include <math.h>
26*03ce13f7SAndroid Build Coastguard Worker 
27*03ce13f7SAndroid Build Coastguard Worker // searchMax defines the upper limit on primes to find.
28*03ce13f7SAndroid Build Coastguard Worker constexpr int searchMax = 10000000;
29*03ce13f7SAndroid Build Coastguard Worker 
30*03ce13f7SAndroid Build Coastguard Worker // searchChunkSize is the number of numbers searched, per task, for primes.
31*03ce13f7SAndroid Build Coastguard Worker constexpr int searchChunkSize = 10000;
32*03ce13f7SAndroid Build Coastguard Worker 
33*03ce13f7SAndroid Build Coastguard Worker // isPrime returns true if i is prime.
isPrime(int i)34*03ce13f7SAndroid Build Coastguard Worker bool isPrime(int i) {
35*03ce13f7SAndroid Build Coastguard Worker   auto c = static_cast<int>(sqrt(i));
36*03ce13f7SAndroid Build Coastguard Worker   for (int j = 2; j <= c; j++) {
37*03ce13f7SAndroid Build Coastguard Worker     if (i % j == 0) {
38*03ce13f7SAndroid Build Coastguard Worker       return false;
39*03ce13f7SAndroid Build Coastguard Worker     }
40*03ce13f7SAndroid Build Coastguard Worker   }
41*03ce13f7SAndroid Build Coastguard Worker   return true;
42*03ce13f7SAndroid Build Coastguard Worker }
43*03ce13f7SAndroid Build Coastguard Worker 
main()44*03ce13f7SAndroid Build Coastguard Worker int main() {
45*03ce13f7SAndroid Build Coastguard Worker   // Create a marl scheduler using the full number of logical cpus.
46*03ce13f7SAndroid Build Coastguard Worker   // Bind this scheduler to the main thread so we can call marl::schedule()
47*03ce13f7SAndroid Build Coastguard Worker   marl::Scheduler scheduler(marl::Scheduler::Config::allCores());
48*03ce13f7SAndroid Build Coastguard Worker   scheduler.bind();
49*03ce13f7SAndroid Build Coastguard Worker   defer(scheduler.unbind());  // unbind before destructing the scheduler.
50*03ce13f7SAndroid Build Coastguard Worker 
51*03ce13f7SAndroid Build Coastguard Worker   // Create a ticket queue. This will be used to ensure that the primes are
52*03ce13f7SAndroid Build Coastguard Worker   // printed in ascending order.
53*03ce13f7SAndroid Build Coastguard Worker   marl::Ticket::Queue queue;
54*03ce13f7SAndroid Build Coastguard Worker 
55*03ce13f7SAndroid Build Coastguard Worker   // Iterate over the range [1, searchMax] in steps of searchChunkSize.
56*03ce13f7SAndroid Build Coastguard Worker   for (int searchBase = 1; searchBase <= searchMax;
57*03ce13f7SAndroid Build Coastguard Worker        searchBase += searchChunkSize) {
58*03ce13f7SAndroid Build Coastguard Worker     // Take a ticket from the ticket queue for this task.
59*03ce13f7SAndroid Build Coastguard Worker     auto ticket = queue.take();
60*03ce13f7SAndroid Build Coastguard Worker 
61*03ce13f7SAndroid Build Coastguard Worker     // Schedule the task.
62*03ce13f7SAndroid Build Coastguard Worker     marl::schedule([=] {
63*03ce13f7SAndroid Build Coastguard Worker       // Find all the primes in [searchBase, searchBase+searchChunkSize-1].
64*03ce13f7SAndroid Build Coastguard Worker       // Note this is run in parallel with the other scheduled tasks.
65*03ce13f7SAndroid Build Coastguard Worker       std::vector<int> primes;
66*03ce13f7SAndroid Build Coastguard Worker       for (int i = searchBase; i < searchBase + searchChunkSize; i++) {
67*03ce13f7SAndroid Build Coastguard Worker         if (isPrime(i)) {
68*03ce13f7SAndroid Build Coastguard Worker           primes.push_back(i);
69*03ce13f7SAndroid Build Coastguard Worker         }
70*03ce13f7SAndroid Build Coastguard Worker       }
71*03ce13f7SAndroid Build Coastguard Worker 
72*03ce13f7SAndroid Build Coastguard Worker       // Wait until the ticket is called. This ensures that the primes are
73*03ce13f7SAndroid Build Coastguard Worker       // printed in ascending order. This may cause this task to yield and allow
74*03ce13f7SAndroid Build Coastguard Worker       // other tasks to be executed while waiting for this ticket to be called.
75*03ce13f7SAndroid Build Coastguard Worker       ticket.wait();
76*03ce13f7SAndroid Build Coastguard Worker 
77*03ce13f7SAndroid Build Coastguard Worker       // Print the primes.
78*03ce13f7SAndroid Build Coastguard Worker       for (auto prime : primes) {
79*03ce13f7SAndroid Build Coastguard Worker         printf("%d is prime\n", prime);
80*03ce13f7SAndroid Build Coastguard Worker       }
81*03ce13f7SAndroid Build Coastguard Worker 
82*03ce13f7SAndroid Build Coastguard Worker       // Call the next ticket so that those primes can be printed.
83*03ce13f7SAndroid Build Coastguard Worker       ticket.done();
84*03ce13f7SAndroid Build Coastguard Worker     });
85*03ce13f7SAndroid Build Coastguard Worker   }
86*03ce13f7SAndroid Build Coastguard Worker 
87*03ce13f7SAndroid Build Coastguard Worker   // take a ticket and wait on it to ensure that all the primes have been
88*03ce13f7SAndroid Build Coastguard Worker   // calculated and printed.
89*03ce13f7SAndroid Build Coastguard Worker   queue.take().wait();
90*03ce13f7SAndroid Build Coastguard Worker 
91*03ce13f7SAndroid Build Coastguard Worker   return 0;
92*03ce13f7SAndroid Build Coastguard Worker }
93