autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: detection and support of OpenMP


From: Bruno Haible
Subject: Re: detection and support of OpenMP
Date: Thu, 17 May 2007 18:20:51 +0200
User-agent: KMail/1.5.4

Hello Ralf,

> It seems to me this macro does not actually check whether OpenMP code
> would be accepted by the compiler, nor whether any necessary runtime
> libraries are actually linked in.  Using an OpenMP function (or, even
> better, linking a small portable self-contained OpenMP program) could
> achieve this.

A "small portable self-contained OpenMP program" looks like this:

  int main ()
  {
    char buf[1000];
    int i;

    #pragma omp parallel for schedule(dynamic)
    for (i = 0; i < 1000; i++)
      buf[i] = i*i;

    return 0;
  }

But such a program is useless for an autoconf test, because the program
without the #pragma must be well-formed, and the #pragma can be ignored by
any compiler.

However, the test can be made a little sharper by testing for the presence
of <omp.h> and one of the simplest library functions.

> What if I want to create Fortran or C++ code that uses OpenMP?

For C++, the test should work the same. For Fortran, you have a separate
macro. I named the macro 'AC_C_...' to make it clear that it does not
apply to Fortran, Java, or Lisp.

> While I understand why you choose to set OPENMP_CFLAGS rather than
> amending CFLAGS, and it makes sense to me, too, it does not fit the other
> modes of operation of Autoconf macros.  Not sure if this
> inconsistency in Autoconf weighs less than the advantage.  Intruding into
> users' namespace is always a double-edged sword.

OPENMP_CFLAGS seems like a natural name; other autoconf macros set the
variable X_CFLAGS. I don't see an inconsistency.

> > In the macro, it would have been simpler to blindly test for the first
> > supported option in a list "-fopenmp -xopenmp -openmp -mp -omp -qsmp=omp",
> > but many compilers accept several of these options and do something
> > unrelated - like to create an output file called 'penmp' or to warn
> > about an unsupported compiler option. The code therefore applies each
> > option only to the brand of compiler that is known to be likely to
> > support it.
> 
> Another way to address this would be to enter a subdir `conftest' and
> ensure no file with such a name is created.

This catches the case of -openmp, but does not the case of options that
lead to a compiler warning at each compiler invocation.

> > In the doc, I'm not sure whether one should write "The
> > @code{AC_C_OPENMP} macro" or "The macro @code{AC_C_OPENMP}". Please
> > correct if needed.
> 
> FWIW, I'd slightly prefer the latter.

OK.

> > 2007-05-17  Bruno Haible  <address@hidden>
> >
> >     * lib/autoconf/c.m4 (AC_C_OPENMP): New macro.
> >     * doc/autoconf.texi (C Compiler): Document AC_C_OPENMP.
> 
> This change would need to be mentioned in NEWS.

Included below.

> > + AC_DEFUN([AC_C_OPENMP],
> > + [
> > +   AC_MSG_CHECKING([whether to use OpenMP])
> > +   AC_ARG_ENABLE(openmp,
> > +     [  --disable-openmp        do not use OpenMP],
> 
> The enable switch is not documented in the manual.
> Please use AS_HELP_STRING.

OK.

> > +     [ac_openmp_choice="$enableval"],
> 
> Superfluous double-quotes.

OK.

> > +     [ac_openmp_choice=yes])
> > +   AC_MSG_RESULT([$ac_openmp_choice])
> > +   OPENMP_CFLAGS=
> > +   if test "$ac_openmp_choice" = yes; then
> > +     AC_MSG_CHECKING([for $CC option to support OpenMP])
> > +     AC_CACHE_VAL([ac_cv_prog_cc_openmp], [
> > +       ac_cv_prog_cc_openmp=no
> > +       AC_COMPILE_IFELSE([
> > + #ifndef _OPENMP
> > +  Unlucky
> > + #endif
> > +         ], [ac_cv_prog_cc_openmp=none])
> > +       if test "$ac_cv_prog_cc_openmp" = no; then
> > +         dnl Try these flags:
> > +         dnl   GCC >= 4.2           -fopenmp
> > +         dnl   SunPRO C             -xopenmp
> > +         dnl   Intel C              -openmp
> > +         dnl   SGI C, PGI C         -mp
> > +         dnl   Tru64 Compaq C       -omp
> > +         dnl   AIX IBM C            -qsmp=omp
> 
> Doesn't AIX have a compiler for GNU/Linux as well?  Does it support OpenMP?

You mean, IBM? Yes, they sell a port of XLC for Linux [1]. But I have no
info about the command-line option for OpenMP in this compiler.
[1] 
http://www-306.ibm.com/software/info/ecatalog/en_US/products/Q860134T18351F02.html?&S_TACT=none&S_CMP=none

> The Intel compiler can fool the $GCC test with suitable compiler options

Does autoconf support this configuration? In the sense that all of autoconf
so far works fine with an Intel icc that defines __GNUC__ ?

> (no arms race between the Intel people making icc more like GCC and
> Autoconf detecting non-GCC compilers, please; this holds for some other
> compilers as well), but at least the version I just tried (8.1) does not
> understand -fopenmp, warns about it, but does not fail.  Dunno if that
> would be enough of a reason to try Intel first?

Yes, if a masqueraded Intel icc is supported, then feel free to move the
Intel C test before the GNU C test.

> > +         if test "$GCC" = yes; then
> > +           dnl --- Test for GCC.
> > +           gt_save_CFLAGS="$CFLAGS"
> 
> s/gt_/ac_/g  here and elsewhere.  Superfluous double-quotes here.

OK.

> > +           CFLAGS="$CFLAGS -fopenmp"
> > +           AC_COMPILE_IFELSE([
> > + #ifndef _OPENMP
> > +  Unlucky
> 
> Please use 'choke me'.

OK.

> Can we eliminate some of the redundancy in the code by a loop like this,
> if we decide to go the way of using preprocessor defines?
> Besides cutting down the size of the expanded macro quite a bit it would
> also help avoid inconsistencies when the macro is bugfixed later.

Yes, that's good for maintainability.

> > +     case $ac_cv_prog_cc_openmp in
> > +       none)
> 
> Why not just initialize $ac_cv_prog_cc_openmp with "none needed",
> "unsupported" etc. right away?

Indeed, that simplifies the code a bit.

> > +         AC_MSG_RESULT([none needed]) ;;
> > +       no)
> > +         AC_MSG_RESULT([unsupported]) ;;
> > +       *)
> > +         AC_MSG_RESULT([$ac_cv_prog_cc_openmp]) ;;
> [...]
> 
> Please ensure that the generated test for this new macro succeeds.
> You can run it verbosely like this:
>   make check TESTSUITEFLAGS='-k AC_C_OPENMP -v -d -x'

I don't understand what you mean, as I'm not familiar with the autoconf
test suite. Can you take over this part, please?

>> +     [ac_openmp_choice=yes])
>> +   AC_MSG_RESULT([$ac_openmp_choice])

> Why not eliminate ac_openmp_choice and use $enable_openmp instead?

Indeed, this simplifies it a bit more.

Here is an updated patch.


2007-05-17  Bruno Haible  <address@hidden>

        * lib/autoconf/c.m4 (AC_C_OPENMP): New macro.
        * doc/autoconf.texi (C Compiler): Document AC_C_OPENMP.
        * NEWS: Mention AC_C_OPENMP.

*** NEWS        14 May 2007 16:54:55 -0000      1.428
--- NEWS        17 May 2007 16:19:13 -0000
***************
*** 1,5 ****
--- 1,7 ----
  * Major changes in Autoconf 2.61b (????-??-??)
  
+ ** New macro AC_C_OPENMP.
+ 
  ** AC_C_BIGENDIAN now supports universal binaries a la Mac OS X.
  
  ** AC_C_RESTRICT now prefers to #define 'restrict' to a variant spelling
*** doc/autoconf.texi   14 May 2007 16:54:55 -0000      1.1154
--- doc/autoconf.texi   17 May 2007 16:19:22 -0000
***************
*** 6593,6598 ****
--- 6593,6622 ----
  if it accepts one of those, otherwise define @code{inline} to be empty.
  @end defmac
  
+ @defmac AC_C_OPENMP
+ @acindex{C_OPENMP}
+ @cvindex _OPENMP
+ OpenMP (@url{http://www.openmp.org/}) is an extension of the C language
+ that makes it possible to optimize programs for Shared Multiprocessing
+ architectures, such as multi-core CPUs, with very small effort.
+ 
+ The macro @code{AC_C_OPENMP} sets the variable @code{OPENMP_CFLAGS} to the
+ C compiler flags needed for supporting OpenMP.  If the compiler already
+ supports OpenMP or if it has no way to activate OpenMP support,
+ @code{OPENMP_CFLAGS} is set to empty.  Also, the user can reject OpenMP
+ support if it is not the default, by invoking @samp{configure} with the
+ @samp{--disable-openmp} option; then @code{OPENMP_CFLAGS} is set to empty
+ as well.
+ 
+ The @code{OPENMP_CFLAGS} need to be used when compiling programs and when
+ linking programs, like the @code{CFLAGS}.  The presence of OpenMP support
+ at compile time is revealed by the preprocessor macro @code{_OPENMP}.
+ 
+ Linking a program with @code{OPENMP_CFLAGS} typically adds one more shared
+ library to the program's dependencies, therefore its use is recommended only
+ on programs that actually use code conditional on @code{#ifdef _OPENMP}.
+ @end defmac
+ 
  @defmac AC_C_CHAR_UNSIGNED
  @acindex{C_CHAR_UNSIGNED}
  @cvindex __CHAR_UNSIGNED__
*** lib/autoconf/c.m4   14 May 2007 16:54:55 -0000      1.247
--- lib/autoconf/c.m4   17 May 2007 16:19:23 -0000
***************
*** 1841,1843 ****
--- 1841,1943 ----
      fi
    fi
  ])
+ 
+ 
+ # AC_C_OPENMP
+ # -----------
+ # Check which options need to be passed to the C compiler to support OpenMP.
+ # Set the OPENMP_CFLAGS variable to these options.
+ # The options are necessary at compile time (so the #pragmas are understood)
+ # and at link time (so the appropriate library is linked with).
+ # This macro takes care to not produce redundant options if $CC $CFLAGS 
already
+ # supports OpenMP. It also is careful to not pass options to compilers that
+ # misinterpret them; for example, most compilers accept "-openmp" and create
+ # an output file called 'penmp' rather than activating OpenMP support.
+ AC_DEFUN([AC_C_OPENMP],
+ [
+   AC_MSG_CHECKING([whether to use OpenMP])
+   AC_ARG_ENABLE(openmp,
+     [AS_HELP_STRING([--disable-openmp], [do not use OpenMP])],
+     [],
+     [enable_openmp=yes])
+   AC_MSG_RESULT([$enable_openmp])
+   OPENMP_CFLAGS=
+   if test "$enable_openmp" = yes; then
+     AC_MSG_CHECKING([for $CC option to support OpenMP])
+     AC_CACHE_VAL([ac_cv_prog_cc_openmp], [
+       ac_cv_prog_cc_openmp=unsupported
+       AC_LINK_IFELSE([
+ #ifndef _OPENMP
+  choke me
+ #endif
+ #include <omp.h>
+ int main () { return omp_get_num_threads (); }
+         ], [ac_cv_prog_cc_openmp="none needed"])
+       if test "$ac_cv_prog_cc_openmp" = unsupported; then
+         dnl Try these flags:
+         dnl   GCC >= 4.2           -fopenmp
+         dnl   SunPRO C             -xopenmp
+         dnl   Intel C              -openmp
+         dnl   SGI C, PGI C         -mp
+         dnl   Tru64 Compaq C       -omp
+         dnl   AIX IBM C            -qsmp=omp
+         for brand in GCC SunPRO Intel SGI/PGI Compaq AIX; do
+           case $brand in
+             GCC)
+               ac_conditional='defined __GNUC__'
+               ac_option='-fopenmp' ;;
+             SunPRO)
+               ac_conditional='defined __SUNPRO_C || defined __SUNPRO_CC'
+               ac_option='-xopenmp' ;;
+             Intel)
+               ac_conditional='defined __INTEL_COMPILER'
+               ac_option='-openmp' ;;
+             SGI/PGI)
+               ac_conditional='defined __sgi || defined __PGI || defined 
__PGIC__'
+               ac_option='-mp' ;;
+             Compaq)
+               ac_conditional='defined __DECC || defined __DECCXX'
+               ac_option='-omp' ;;
+             AIX)
+               ac_conditional='defined _AIX'
+               ac_option='-qsmp=omp' ;;
+           esac
+           if test $brand = GCC; then
+             if test "$GCC" = yes; then
+               ac_openmp_result=yes
+             else
+               ac_openmp_result=no
+             fi
+           else
+             AC_EGREP_CPP([Brand], [
+               #if $ac_conditional
+                Brand
+               #endif
+               ], [ac_openmp_result=yes], [ac_openmp_result=no])
+           fi
+           if test $ac_openmp_result = yes; then
+             ac_save_CFLAGS=$CFLAGS
+             CFLAGS="$CFLAGS $ac_option"
+             AC_LINK_IFELSE([
+ #ifndef _OPENMP
+  choke me
+ #endif
+ #include <omp.h>
+ int main () { return omp_get_num_threads (); }
+               ], [ac_cv_prog_cc_openmp=$ac_option])
+             CFLAGS=$ac_save_CFLAGS
+             break
+           fi
+         done
+       fi
+       ])
+     AC_MSG_RESULT([$ac_cv_prog_cc_openmp])
+     case $ac_cv_prog_cc_openmp in
+       "none needed" | unsupported)
+         OPENMP_CFLAGS= ;;
+       *)
+         OPENMP_CFLAGS=$ac_cv_prog_cc_openmp ;;
+     esac
+   fi
+   AC_SUBST([OPENMP_CFLAGS])
+ ])





reply via email to

[Prev in Thread] Current Thread [Next in Thread]