> first of all thank you very much for your quick and detailed answer.
> Nevertheless i think i did not explain my concern.
> using your code snippet, imagine i have
>
>
> int nelements = 42;
> Matrix expensive_to_construct_scratchspace
>
> for_each(par, 0, N,
> [nelements, expensive_to_construct_scratchspace](int i)
> {
> // the captured 'nelements' is initialized from the outer
> // variable and each copy of the lambda has its own private
> // copy
> HERE as i understand the lambda vould capture by value my
> "expensive_to_construct_scratchspace", which as i understand implies that
> i would have one allocation per every "i". --> are u telling that this is
> not the case? If so that would be a problem since constructing it would be
> very expensive.
No, that would be the case, your analysis is correct.
> On the contrary, if the lambda does not copy by value ... what if i do
> need that behaviour?
>
> note that i could definitely construct a blocked range of iterators and
> define a lambda acting on a given range of iterators, however that would
> be very very verbose...
Looks like I misunderstood what firstprivate actually does...
OTOH, in the openmp spec I read:
firstprivate Specifies that each thread should have its own instance of
a variable, and that the variable should be initialized with the value
of the variable, because it exists before the parallel construct.
So each thread gets its own copy, which implies copying/allocation. What do I
miss?
If however you want to share the variable in between threads, just capture it
by reference:
Matrix expensive_to_construct_scratchspace
for_each(par, 0, N,
[&expensive_to_construct_scratchspace](int i)
{
});
In this case you'd be responsible for making any operations on the shared
variable thread safe, however.
Is that what you need?
Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu
>
>
> anyway,
> thanks again for your attention
> Riccardo
>
>
> On Sun, Sep 11, 2016 at 4:48 PM, Hartmut Kaiser <[email protected]>
> wrote:
> Riccardo,
>
> > i am writing since i am an OpenMP user, but i am actually quite
> > curious in understanding the future directions of c++.
> >
> > my parallel usage is actually relatively trivial, and is covered by
> OpenMP
> > 2.5 (openmp 3.1 with supports for iterators would be better but is not
> > available in msvc)
> > 99% of my user needs are about parallel loops, and with c++11 lambdas i
> > could do a lot.
>
> Right. It is a fairly simple transformation in order to turn an OpenMP
> parallel loop into the equivalent parallel algorithm. We specificly added
> the parallel::for_loop() (not I the Parallelism TS/C++17) to support that
> migration:
>
> #pragma omp parallel for
> for(int i = 0; i != N; ++i)
> {
> // some iteration
> }
>
> Would be equivalent to
>
> hpx::parallel::for_loop(
> hpx::parallel::par,
> 0, N, [](int i)
> {
> // some iteration
> });
>
> (for more information about for_loop() see here: http://www.open-
> std.org/jtc1/sc22/wg21/docs/papers/2015/p0075r0.pdf)
>
> > However i am really not clear on how i should equivalently handle
> > "private" and "firstprivate of OpenMP, which allow to create objects
> that
> > persist in the threadprivate memory during the whole lenght of a for
> loop.
> > I now use OpenMP 2.5 and i have a code that looks like the following
> >
> >
> https://kratos.cimne.upc.es/projects/kratos/repository/entry/kratos/kratos
> >
> /solving_strategies/builder_and_solvers/residualbased_block_builder_and_so
> > lver.h
> > which does an openmp parallel Finite Element assembly.
> > The code i am thinking of is somethign like:
>
> [snipped code]
>
> > the big question is ... how shall i handle the threadprivate
> scratchspace
> > in HPX?? Lambdas do not allow to do this ...
> > that is, what is the equivalente of private & of firstprivate??
> > thanks you in advance for any clarification or pointer to examples
>
> For 'firstprivate' you can simply use lambda captures:
>
> int nelements = 42;
>
> for_each(par, 0, N,
> [nelements](int i)
> {
> // the captured 'nelements' is initialized from the outer
> // variable and each copy of the lambda has its own private
> // copy
> //
> // use private 'nelements' here:
> cout << nelements << endl;
> });
>
> Note, that 'nelements' will be const by default. If you want to modify its
> value, the lambda has to be made mutable:
>
> int nelements = 42;
>
> for_each(par, 0, N,
> [nelements](int i) mutable // makes captures non-const
> {
> ++nelements;
> });
>
> Please don't be fooled however that this might give you one variable
> instance per iteration. HPX runs several iterations 'in one go' (depending
> on the partitioning, very much like openmp), so you will create one
> variable instance per created partition. As long as you don't modify the
> variable this shouldn't make a difference, however.
>
> Emulating 'private' is even simpler. All you need is a local variable for
> each iteration after all. Thus simply creating it on the stack inside the
> lambda is the solution:
>
> for_loop(par, 0, N, [](int i)
> {
> // create 'private' variable
> int my_private = 0;
> // ...
> });
>
> This also gives you a hint on how you can have one instance of your
> variable per iteration and still initialize it like it was firstprivate:
>
> int nelements = 42;
> for_loop(par, 0, N, [nelements](int i)
> {
> // create 'private' variable
> int my_private = nelements;
> // ...
> ++my_private; // modifies instance for this iteration only.
> });
>
> Things become a bit more interesting if you need reductions. Please see
> the linked document above for more details, but here is a simple example
> (taken from that paper):
>
> float dot_saxpy(int n, float a, float x[], float y[])
> {
> float s = 0;
> for_loop(par, 0, n,
> reduction(s, 0.0f, std::plus<float>()),
> [&](int i, float& s_)
> {
> y[i] += a*x[i];
> s_ += y[i]*y[i];
> });
> return s;
> }
>
> Here 's' is the reduction variable, and s_ is the thread-local reference
> to it.
>
> HTH
> Regards Hartmut
> ---------------
> http://boost-spirit.com
> http://stellar.cct.lsu.edu
>
>
>
>
> --
> Riccardo Rossi
> PhD, Civil Engineer
>
> member of the Kratos Team: www.cimne.com/kratos
> Tenure Track Lecturer at Universitat Politècnica de Catalunya,
> BarcelonaTech (UPC)
> Full Research Professor at International Center for Numerical Methods in
> Engineering (CIMNE)
>
> C/ Gran Capità, s/n, Campus Nord UPC, Ed. C1, Despatx C9
> 08034 – Barcelona – Spain – www.cimne.com -
> T.(+34) 93 401 56 96 skype: rougered4
>
>
>
> Les dades personals contingudes en aquest missatge són tractades amb la
> finalitat de mantenir el contacte professional entre CIMNE i voste. Podra
> exercir els drets d'accés, rectificació, cancel·lació i oposició,
> dirigint-se a [email protected]. La utilització de la seva adreça de
> correu electronic per part de CIMNE queda subjecte a les disposicions de
> la Llei 34/2002, de Serveis de la Societat de la Informació i el Comerç
> Electronic.
> Imprimiu aquest missatge, només si és estrictament necessari.
_______________________________________________
hpx-users mailing list
[email protected]
https://mail.cct.lsu.edu/mailman/listinfo/hpx-users