0

I'm working on a library that implements a template function which is parallelized using OpenMP.

I want to compile my library using the -fopenmp option so that anyone who links against my library gets the parallel version, at least as long as they're using instantiations with the same types used internally in the library.

However, since the template function is defined in a header, my understanding is the user's compiler will also compile the function. If they don't use -fopenmp won't there be two separate versions of the template, one with OpenMP and one without? Which version will the user's code get?

anderspitman
  • 9,230
  • 10
  • 40
  • 61
  • 1
    It will probably be unpredictable which version is used at any given call site (including internally to the library). This depends on inlining choices and linker choices. It doesn't sound like a good idea to me. It is basically a ODR violation. – user17732522 Apr 07 '23 at 00:17
  • If it's unpredictable I completely agree it's a bad idea. What do you think would be the best way to avoid this? Only thing I can think of is not using the template internally in the library, but that seems overly restrictive. – anderspitman Apr 07 '23 at 00:19
  • 1
    If you only want to allow the template being used with a finite set of internal types, define it in your library `.cpp` and explicitly instantiate it there. Then users won't see the definition and can't generate a "false" instantiation. – user17732522 Apr 07 '23 at 00:23
  • Unfortunately we want to allow users to implement their own types to be used with the template. – anderspitman Apr 07 '23 at 00:26
  • 1
    Alternatively you can use explicit specialization (declared in the header and defined in your library's .cpp) for the specific types from your library and still provide the primary template definition to the user. Then they can't instantiate for the specific types in your library. But honestly, I think it would be better to make the template dependent on a template parameter to switch between the OpenMP and non-OpenMP implementation somehow (not sure whether there is a way to detect whether it is enabled, probably should be). – user17732522 Apr 07 '23 at 00:30
  • 1
    see this answer, https://stackoverflow.com/a/12004302/1466970 , that says "OpenMP is a set of code transforming pragmas, i.e. they are only applied at compile time.". Also see this SO post about detecting if OpenMP is enabled or not. https://stackoverflow.com/q/30803126/1466970 – Richard Chambers Apr 07 '23 at 00:52
  • 1
    This function, what is the set of types you would like to support? If it's a small number you could always define the template in a cpp file and then explicitly instantiate the template for each type you want to support. – NathanOliver Apr 07 '23 at 01:19
  • 1
    Put in your header: `#ifndef __OPENMP #error this needs omp #endif` (on three lines, of course) – Victor Eijkhout Apr 07 '23 at 13:04
  • @NathanOliver unfortunately the set of supported types is unbounded, since users can define their own types. – anderspitman Apr 07 '23 at 21:25
  • @VictorEijkhout, This is a good suggestion, thanks. But it seems like even if the user does compile with OpenMP, there can still be a ODR violation if they have a different version of OpenMP, right? – anderspitman Apr 07 '23 at 21:27

0 Answers0