[Networkit] build broken with --openmp=no and clang

Matteo Riondato matteo at cs.brown.edu
Fri Jul 14 15:11:26 CEST 2017


> On Jul 14, 2017, at 3:29 AM, Henning Meyerhenke <henning.meyerhenke at kit.edu> wrote:
> 
> Am 13.07.17 um 17:19 schrieb Matteo Riondato:
>> Hi all,
>> 
>> The build is broken when building with “scons —target=Lib —optimize=True —openmp=no” and the compiler is Clang.
> 
> Indeed, we should fix that. Thanks for pointing it out.

It should be possible to catch these kind of breakages with Travis CI.

>> Actually, in many cases, the correct solution is to refactor the code that calls these functions to use user-defined custom openmp reductions. Much of this code is essentially populating data structures in parallel in a for loop, so defining a custom openmp reduction in these cases is usually straightforward.
> 
> What would be the benefit of having user-defined custom operations? I
> don't think we will replace OpenMP by some other threading mechanism any
> time soon. But maybe I am overlooking your motivation here.


I’m not suggesting to replace OpenMP, rather to use all its functionalities.

OpenMP 4 introduced “user-defined reductions” (see Sect 2.16 of http://www.openmp.org/wp-content/uploads/openmp-4.5.pdf).

I find them very flexible and relative straightforward to write.

They allow me to remove most use of omp_* functions and only rely on pragmas, which has the net effect to be able to easily switch off openmp and to use compilers that may not support openmp.

Additionally, I suspect (but I’d love to be proven wrong), that they are more efficient for populating data structures in parallel than the use of a vector of size omp_get_max_threads() which is then merged in parallel.

IMHO, they are definitively more elegant for the reason described above.

For example, the following show how to populate a std::vector in parallel when it is not known how many elements it will contain, which may be typical in STL-style algorithms:

#pragma omp declare reduction (vec_double_merge : std::vector<double> : \
        omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) \
        initializer(omp_priv = omp_orig)

template<typename Iterator> void  myfunction(Iterator begin, Iterator end) {
  std::vector<double> v;
    #pragma omp parallel for reduction(vec_double_merge: vec)
    for (auto i = begin; i != end; ++i)
        v.push_back(impl::elltwosquared(*i) / 2);
  // do somehting with v.
}

The code doesn’t need to include <omp.h> or use any omp_* function, and everything works as expected if your compiler doesn’t support openmp or openmp is disabled.
Caveat: the order is not preserved. Other tricks are possible if you need to preserve the order, but you may have to call some omp_*function. See https://stackoverflow.com/a/18671256.

Matteo

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP
URL: <http://lists.ira.uni-karlsruhe.de/pipermail/networkit/attachments/20170714/4b8a60b4/attachment.sig>


More information about the NetworKit mailing list