Skip to content

Commit

Permalink
support compiling/installing --enable-threads --enable-openmp at the …
Browse files Browse the repository at this point in the history
…same time, although in this case the test program only uses the threads variety. Update documentation accordingly, and in general expand the documentation of the OpenMP support
  • Loading branch information
stevengj committed Jul 5, 2011
1 parent 1b13a76 commit e50fbe1
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 81 deletions.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ALTIVEC_LIBS = dft/simd/altivec/libdft_altivec_codelets.la \
rdft/simd/altivec/librdft_altivec_codelets.la
endif

if SMP
if THREADS
if COMBINED_THREADS
COMBINED_THREADLIBS=threads/libfftw3@PREC_SUFFIX@_@[email protected]
endif
Expand Down
34 changes: 13 additions & 21 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ AC_SUBST(PREC_SUFFIX)

dnl Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AX_COMPILER_VENDOR
AC_PROG_CC_STDC
AC_PROG_INSTALL
Expand Down Expand Up @@ -456,35 +457,25 @@ have_smp="no"
AC_ARG_ENABLE(openmp, [AC_HELP_STRING([--enable-openmp],[use OpenMP directives for parallelism])], enable_openmp=$enableval, enable_openmp=no)

if test "$enable_openmp" = "yes"; then
AC_DEFINE(HAVE_OPENMP,1,[Define to enable OpenMP])
have_smp="yes"
THREADSUFF=omp
AC_DEFINE(HAVE_OPENMP,1,[Define to enable OpenMP])
AX_OPENMP([], [AC_MSG_ERROR([don't know how to enable OpenMP])])
fi

AC_ARG_ENABLE(threads, [AC_HELP_STRING([--enable-threads],[compile FFTW SMP threads library])], enable_threads=$enableval, enable_threads=no)

if test "$enable_threads" = "yes"; then
AC_DEFINE(HAVE_THREADS,1,[Define to enable SMP threads])
if test "$enable_openmp" = "yes"; then
AC_MSG_ERROR([--enable-threads/--enable-openmp are mutually exclusive])
fi
have_smp="yes"
THREADSUFF=threads
fi

AC_SUBST(THREADSUFF)

if test "$enable_openmp"x != "nox" -a "$enable_threads"x != "nox"; then
AC_MSG_ERROR([--enable-threads/--enable-openmp are mutually exclusive])
fi

AC_ARG_WITH(combined-threads, [AC_HELP_STRING([--with-combined-threads],[combine threads into main libfftw3])], with_combined_threads=$withval, with_combined_threads=no)

if test "$enable_openmp"x != nox; then
AX_OPENMP([THREADLIBS=" "
AC_DEFINE(USING_OPENMP_THREADS, 1, [Define if we have and are using OpenMP multithreading directives])
CFLAGS="$CFLAGS $OPENMP_CFLAGS"],
[AC_MSG_ERROR([don't know how to enable OpenMP])])
if test "$with_combined_threads" = yes; then
if test "$enable_openmp" = "yes"; then
AC_MSG_ERROR([--with-combined-threads incompatible with --enable-openmp])
fi
if test "$enable_threads" != "yes"; then
AC_MSG_ERROR([--with-combined-threads requires --enable-threads])
fi
fi

dnl Check for threads library...
Expand All @@ -493,7 +484,6 @@ if test "$enable_threads" = "yes"; then
# POSIX threads, the default choice:
if test -z "$THREADLIBS"; then
ACX_PTHREAD([THREADLIBS="$PTHREAD_LIBS "
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
CC="$PTHREAD_CC"
AC_DEFINE(USING_POSIX_THREADS, 1, [Define if we have and are using POSIX threads.])])
fi
Expand All @@ -512,7 +502,9 @@ if test "$enable_threads" = "yes"; then
AC_DEFINE(HAVE_THREADS, 1, [Define if we have a threads library.])
fi
AC_SUBST(THREADLIBS)
AM_CONDITIONAL(SMP, test "$have_smp" = "yes")
AM_CONDITIONAL(THREADS, test "$enable_threads" = "yes")
AM_CONDITIONAL(OPENMP, test "$enable_openmp" = "yes")
AM_CONDITIONAL(SMP, test "$enable_threads" = "yes" -o "$enable_openmp" = "yes")
AM_CONDITIONAL(COMBINED_THREADS, test x"$with_combined_threads" = xyes)

dnl -----------------------------------------------------------------------
Expand Down
27 changes: 13 additions & 14 deletions doc/install.texi
Original file line number Diff line number Diff line change
Expand Up @@ -129,23 +129,22 @@ the threads routines are not compiled.
@item
@code{--enable-openmp}: Like @code{--enable-threads}, but using OpenMP
compiler directives in order to induce parallelism rather than
spawning its own threads directly. Useful especially for programs
already employing such directives, in order to minimize conflicts
between different parallelization mechanisms. Use either
@code{--enable-openmp} or @code{--enable-threads}, not both; in either
case the multi-threaded FFTW interface/library (@pxref{Multi-threaded
FFTW}) is compiled (with different back ends).
spawning its own threads directly, and installing an @samp{fftw3_omp} library
rather than an @samp{fftw3_threads} library (@pxref{Multi-threaded
FFTW}). You can use both @code{--enable-openmp} and @code{--enable-threads}
since they compile/install libraries with different names. By default,
the OpenMP routines are not compiled.

@item
@code{--with-combined-threads}: By default, if @code{--enable-threads}
or @code{--enable-openmp} are used, the threads support is compiled
into a separate library that must be linked in addition to the main
FFTW library. This is so that users of the serial library do not need
to link the system threads libraries. If
@code{--with-combined-threads} is specified, however, then no separate
threads library is created, and threads are included in the main FFTW
library. This is mainly useful under Windows, where no system threads
library is required and inter-library dependencies are problematic.
is used, the threads support is compiled into a separate library that
must be linked in addition to the main FFTW library. This is so that
users of the serial library do not need to link the system threads
libraries. If @code{--with-combined-threads} is specified, however,
then no separate threads library is created, and threads are included
in the main FFTW library. This is mainly useful under Windows, where
no system threads library is required and inter-library dependencies
are problematic.

@item
@cindex MPI
Expand Down
62 changes: 43 additions & 19 deletions doc/threads.texi
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,31 @@ subdirectory of the FFTW package. On Unix systems, the FFTW threads
libraries and header files can be automatically configured, compiled,
and installed along with the uniprocessor FFTW libraries simply by
including @code{--enable-threads} in the flags to the @code{configure}
script (@pxref{Installation on Unix}).
script (@pxref{Installation on Unix}), or @code{--enable-openmp} to use
@uref{http://www.openmp.org,OpenMP} threads.
@fpindex configure


@cindex portability
@cindex OpenMP
The threads routines require your operating system to have some sort
of shared-memory threads support. Specifically, the FFTW threads
package works with POSIX threads (available on most Unix variants,
from GNU/Linux to MacOS X) and Win32 threads. We also support using
@uref{http://www.openmp.org,OpenMP}, enabled by using
@code{--enable-openmp} (@emph{instead} of @code{--enable-threads}).
(This may be useful if you are employing that sort of directive in
your own code, in order to minimize conflicts.) If you have a
from GNU/Linux to MacOS X) and Win32 threads. OpenMP threads, which
are supported in many common compilers (e.g. gcc) are also supported,
and may give better performance on some systems. (OpenMP threads are
also useful if you are employing OpenMP in your own code, in order to
minimize conflicts between threading models.) If you have a
shared-memory machine that uses a different threads API, it should be
a simple matter of programming to include support for it; see the file
@code{threads/threads.c} for more detail.

You can compile FFTW with @emph{both} @code{--enable-threads} and
@code{--enable-openmp} at the same time, since they install libraries
with different names (@samp{fftw3_threads} and @samp{fftw3_omp}, as
described below). However, your programs may only link to @emph{one}
of these two libraries at a time.

Ideally, of course, you should also have multiple processors in order to
get any benefit from the threaded transforms.

Expand All @@ -70,10 +78,13 @@ of the uniprocessor FFTW routines, described elsewhere in this manual.
We only describe what one has to change in order to use the
multi-threaded routines.

First, programs using the parallel complex transforms should be linked with
@code{-lfftw3_threads -lfftw3 -lm} on Unix. You will also need to link
@cindex OpenMP
First, programs using the parallel complex transforms should be linked
with @code{-lfftw3_threads -lfftw3 -lm} on Unix, or @code{-lfftw3_omp
-lfftw3 -lm} if you compiled with OpenMP. You will also need to link
with whatever library is responsible for threads on your system
(e.g. @code{-lpthread} on GNU/Linux).
(e.g. @code{-lpthread} on GNU/Linux) or include whatever compiler flag
enables OpenMP (e.g. @code{-fopenmp} with gcc).
@cindex linking on Unix


Expand Down Expand Up @@ -108,10 +119,22 @@ before a call to @code{fftw_plan_with_nthreads} are unaffected. If you
pass an @code{nthreads} argument of @code{1} (the default), threads are
disabled for subsequent plans.

@cindex OpenMP
With OpenMP, to configure FFTW to use all of the currently running
OpenMP threads (set by @code{omp_set_num_threads(nthreads)} or by the
@code{OMP_NUM_THREADS} environment variable), you can do:
@code{fftw_plan_with_nthreads(omp_get_num_threads())}. (The @samp{omp_}
OpenMP functions are declared via @code{#include <omp.h>}.)

@cindex thread safety
Given a plan, you then execute it as usual with
@code{fftw_execute(plan)}, and the execution will use the number of
threads specified when the plan was created. When done, you destroy it
as usual with @code{fftw_destroy_plan}.
threads specified when the plan was created. When done, you destroy
it as usual with @code{fftw_destroy_plan}. As described in
@ref{Thread safety}, plan @emph{execution} is thread-safe, but plan
creation and destruction are @emph{not}: you should create/destroy
plans only from a single thread, but can safely execute multiple plans
in parallel.

There is one additional routine: if you want to get rid of all memory
and other resources allocated internally by FFTW, you can call:
Expand Down Expand Up @@ -157,13 +180,14 @@ parallelization.
@section Thread safety

@cindex threads
@cindex OpenMP
@cindex thread safety
Users writing multi-threaded programs must concern themselves with the
@dfn{thread safety} of the libraries they use---that is, whether it is
safe to call routines in parallel from multiple threads. FFTW can be
used in such an environment, but some care must be taken because the
planner routines share data (e.g. wisdom and trigonometric tables)
between calls and plans.
Users writing multi-threaded programs (including OpenMP) must concern
themselves with the @dfn{thread safety} of the libraries they
use---that is, whether it is safe to call routines in parallel from
multiple threads. FFTW can be used in such an environment, but some
care must be taken because the planner routines share data
(e.g. wisdom and trigonometric tables) between calls and plans.

The upshot is that the only thread-safe (re-entrant) routine in FFTW is
@code{fftw_execute} (and the new-array variants thereof). All other routines
Expand All @@ -181,13 +205,13 @@ threads. However, since a given plan operates by default on a fixed
array, you need to use one of the new-array execute functions (@pxref{New-array Execute Functions}) so that different threads compute the transform of different data.

(Users should note that these comments only apply to programs using
shared-memory threads. Parallelism using MPI or forked processes
shared-memory threads or OpenMP. Parallelism using MPI or forked processes
involves a separate address-space and global variables for each process,
and is not susceptible to problems of this sort.)

If you are configured FFTW with the @code{--enable-debug} or
@code{--enable-debug-malloc} flags (@pxref{Installation on Unix}),
then @code{fftw_execute} is not thread-safe. This flags are not
then @code{fftw_execute} is not thread-safe. These flags are not
documented because they are intended only for developing
and debugging FFTW, but if you must use @code{--enable-debug} then you
should also specifically pass @code{--disable-debug-malloc} for
Expand Down
8 changes: 6 additions & 2 deletions mpi/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ libfftw3@PREC_SUFFIX@_mpi_la_SOURCES = $(SRC) $(TRANSPOSE_SRC) $(DFT_SRC) $(RDFT

libfftw3@PREC_SUFFIX@_mpi_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@

if SMP
if THREADS
mpi_bench_CFLAGS = $(PTHREAD_CFLAGS)
if !COMBINED_THREADS
LIBFFTWTHREADS = $(top_builddir)/threads/libfftw3@PREC_SUFFIX@_threads.la
endif
else
LIBFFTWTHREADS =
if OPENMP
mpi_bench_CFLAGS = $(OPENMP_CFLAGS)
LIBFFTWTHREADS = $(top_builddir)/threads/libfftw3@PREC_SUFFIX@_omp.la
endif
endif

mpi_bench_SOURCES = mpi-bench.c $(top_srcdir)/tests/fftw-bench.c $(top_srcdir)/tests/hook.c
Expand Down
8 changes: 6 additions & 2 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/kernel -I$(top_srcdir)/libbench2 \
noinst_PROGRAMS = bench
EXTRA_DIST = check.pl README

if SMP
if THREADS
bench_CFLAGS = $(PTHREAD_CFLAGS)
if !COMBINED_THREADS
LIBFFTWTHREADS = $(top_builddir)/threads/libfftw3@PREC_SUFFIX@_threads.la
endif
else
LIBFFTWTHREADS =
if OPENMP
bench_CFLAGS = $(OPENMP_CFLAGS)
LIBFFTWTHREADS = $(top_builddir)/threads/libfftw3@PREC_SUFFIX@_omp.la
endif
endif

bench_SOURCES = bench.c hook.c fftw-bench.c fftw-bench.h
Expand Down
4 changes: 3 additions & 1 deletion tests/fftw-bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <string.h>
#include "fftw-bench.h"

#ifdef HAVE_OPENMP
#ifdef _OPENMP
# include <omp.h>
#endif

Expand Down Expand Up @@ -72,7 +72,9 @@ void rdwisdom(void)
if (threads_ok) {
BENCH_ASSERT(FFTW(init_threads)());
FFTW(plan_with_nthreads)(nthreads);
#ifdef _OPENMP
omp_set_num_threads(nthreads);
#endif
}
else if (nthreads > 1 && verbose > 1) {
fprintf(stderr, "bench: WARNING - nthreads = %d, but threads not supported\n", nthreads);
Expand Down
26 changes: 20 additions & 6 deletions threads/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,33 @@ AM_CPPFLAGS = -I$(top_srcdir)/kernel -I$(top_srcdir)/dft \
-I$(top_srcdir)/rdft -I$(top_srcdir)/api
AM_CFLAGS = $(STACK_ALIGN_CFLAGS)

if SMP
if OPENMP
FFTWOMPLIB = libfftw3@PREC_SUFFIX@_omp.la
else
FFTWOMPLIB =
endif

if THREADS
if COMBINED_THREADS
noinst_LTLIBRARIES = libfftw3@PREC_SUFFIX@_@THREADSUFF@.la
noinst_LTLIBRARIES = libfftw3@PREC_SUFFIX@_threads.la
else
lib_LTLIBRARIES = libfftw3@PREC_SUFFIX@_@THREADSUFF@.la
lib_LTLIBRARIES = libfftw3@PREC_SUFFIX@_threads.la $(FFTWOMPLIB)
endif
else
lib_LTLIBRARIES = $(FFTWOMPLIB)
endif

# pkgincludedir = $(includedir)/fftw3@PREC_SUFFIX@
# pkginclude_HEADERS = threads.h

libfftw3@PREC_SUFFIX@_@THREADSUFF@_la_SOURCES = api.c conf.c threads.c \
openmp.c threads.h dft-vrank-geq1.c ct.c rdft-vrank-geq1.c hc2hc.c \
libfftw3@PREC_SUFFIX@_threads_la_SOURCES = api.c conf.c threads.c \
threads.h dft-vrank-geq1.c ct.c rdft-vrank-geq1.c hc2hc.c \
vrank-geq1-rdft2.c f77api.c f77funcs.h
libfftw3@PREC_SUFFIX@_threads_la_CFLAGS = $(PTHREAD_CFLAGS)
libfftw3@PREC_SUFFIX@_threads_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@

libfftw3@PREC_SUFFIX@_@THREADSUFF@_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@
libfftw3@PREC_SUFFIX@_omp_la_SOURCES = api.c conf.c openmp.c \
threads.h dft-vrank-geq1.c ct.c rdft-vrank-geq1.c hc2hc.c \
vrank-geq1-rdft2.c f77api.c f77funcs.h
libfftw3@PREC_SUFFIX@_omp_la_CFLAGS = $(OPENMP_CFLAGS)
libfftw3@PREC_SUFFIX@_omp_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@
4 changes: 0 additions & 4 deletions threads/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,10 @@

static const solvtab s =
{
#if defined(HAVE_THREADS) || defined(HAVE_OPENMP)

SOLVTAB(X(dft_thr_vrank_geq1_register)),
SOLVTAB(X(rdft_thr_vrank_geq1_register)),
SOLVTAB(X(rdft2_thr_vrank_geq1_register)),

#endif

SOLVTAB_END
};

Expand Down
4 changes: 0 additions & 4 deletions threads/openmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@

#include "threads.h"

#ifdef HAVE_OPENMP

#if !defined(_OPENMP)
#error OpenMP enabled but not using an OpenMP compiler
#endif
Expand Down Expand Up @@ -76,5 +74,3 @@ void X(spawn_loop)(int loopmax, int nthr, spawn_function proc, void *data)
void X(threads_cleanup)(void)
{
}

#endif /* HAVE_OPENMP */
3 changes: 0 additions & 3 deletions threads/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#include "threads.h"

#ifdef HAVE_THREADS
#if defined(USING_POSIX_THREADS)

#include <pthread.h>
Expand Down Expand Up @@ -438,5 +437,3 @@ void X(threads_cleanup)(void)
os_mutex_destroy(&queue_lock);
os_sem_destroy(&termination_semaphore);
}

#endif /* HAVE_THREADS */
Loading

0 comments on commit e50fbe1

Please sign in to comment.