Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
2401 Discussions

Computing Pi - how to use lambda expression

mikajlo_m_
Beginner
99 Views

Hi, every one.

I want to calculate PI using multi-core parallel algorithms. I have following code:



It seems to work well, but I can't write this with lambda expression.I tried to use example from this topic, but still something is wrong.. Please, show me how it could be look like..

[cpp]

#include <stdio.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_reduce.h>
#include <tbb/task_scheduler_init.h>


class Pi_MC
{
private:
    long num_steps;
    double step;

public:
 
    double pi;

    void operator () (const tbb::blocked_range<long> &r)
    {
        double x, sum = 0.0;

        long end = r.end();

        for (int i = r.begin(); i != end; i++)
        {
            x = (i - 0.5) * step;
            sum = sum + 4.0 / (1.0 + x*x);
        }
        pi += sum * step;
    }

    void join(Pi_MC &p)
    {
        pi += p.pi;
    }

    Pi_MC(Pi_MC &p, tbb::split)
    {
        pi = 0.0;
        num_steps = p.num_steps;
        step = p.step;
    }

    Pi_MC(long n)
    {
        pi = 0.0;
        num_steps = n;
        step = 1.0 / (double) num_steps;
    }
};


int main()
{
    tbb::task_scheduler_init init;

    const long n = 100000000;

    Pi_MC pi(n);

    tbb::parallel_reduce(tbb::blocked_range<long>(0, n, 1000000), pi);
    printf ("Pi = %.16f steps: %d \n", pi.pi, n);

    system("pause");    
}

[/cpp]

0 Kudos
6 Replies
RafSchietekat
Black Belt
99 Views
Something like this perhaps (not tested): [cpp] #include <stdio.h> #include <functional> #include <tbb/blocked_range.h> #include <tbb/parallel_reduce.h> int main() { const long num_steps = 100000000; const double step = 1.0 / num_steps; const double result = tbb::parallel_reduce( tbb::blocked_range<long>(0, num_steps), 0.0, [] (const tbb::blocked_range<long> &r, const double value) -> double { double sum = 0.0; for (int i = r.begin(), end = r.end(); i != end; i++) { const double x = (i - 0.5) * step; sum += 4.0 / (1.0 + x*x); } return value + sum * step; }, std::plus<double>() ); printf ("Pi = %.16f steps: %d n", result, num_steps); system("pause"); } [/cpp] Edited on 2013-01-02, after next 3 postings: added missing "#include <functional>", and another self-indulgent "const" with the "value" parameter ("const" should have been the default all along, and "var" should have been an additional keyword...).
mikajlo_m_
Beginner
99 Views
This code didn't want to be accepted: [cpp] std::plus() [/cpp] replaced it: [cpp] []( double s1, double s2 ) { return s1+s2; } [/cpp] and Viola! Happy 2013!
RafSchietekat
Black Belt
99 Views
Did you use "#include <functional>"? I'll assume that the template argument failed to show up because you wrote "std::plus<double>()" instead of the workaround syntax "std::plus&lt;double&gt;()" to assure correct visualisation in this forum.
mikajlo_m_
Beginner
99 Views
I didnt have include.. Works! ;)
RafSchietekat
Black Belt
99 Views
Now for a finishing touch: does the following work instead of that for loop to determine "sum" (with "#include <numeric>", of course)? [cpp] const double sum = std::accumulate(r.begin(), r.end(), 0.0, [] (const double acc, const long i) -> double { const double x = (i - 0.5) * step; return acc + 4.0 / (1.0 + x*x); }); [/cpp] Actually using that might be a bit pedantic, though, as it doesn't really make the code more concise... although perhaps it does illustrate intent a little bit better. It could also be interesting to compare timing results, because it seems more challenging to optimise around that lambda than with a straightforward loop.
mikajlo_m_
Beginner
99 Views
Ok, thx for advice!
Reply