Skip to content

Commit

Permalink
Added back openmp.
Browse files Browse the repository at this point in the history
Rationalized threads naming conventions:

  * threads explicitly managed by us are enabled by --enable-threads,
    predicated on HAVE_THREADS, etc.
  * openmp is enabled by --enable-openmp, predicated on HAVE_OPENMP, etc.
  * SMP denotes either THREADS or OPENMP.
  • Loading branch information
matteo-frigo committed Oct 27, 2006
1 parent 22cd21b commit 9809db5
Show file tree
Hide file tree
Showing 15 changed files with 174 additions and 48 deletions.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ else
SIMD_LIBS=
endif

if THREADS
if SMP
if COMBINED_THREADS
COMBINED_THREADLIBS=threads/libfftw3@PREC_SUFFIX@_threads.la
endif
Expand Down
37 changes: 27 additions & 10 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -352,23 +352,40 @@ if test "x$enable_fortran" = xyes; then
fi

dnl -----------------------------------------------------------------------
have_smp="no"
AC_ARG_ENABLE(openmp, [AC_HELP_STRING([--enable-openmp],[use OpenMP directives for parallelism])], enable_openmp=$enableval, enable_openmp=no)

AC_ARG_WITH(openmp, [AC_HELP_STRING([--with-openmp],[use OpenMP directives instead of a threads library])], with_openmp=$withval, with_openmp=no)
if test "$enable_openmp" = "yes"; then
AC_DEFINE(HAVE_OPENMP,1,[Define to enable OpenMP])
have_smp="yes"
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"
fi

AC_ARG_ENABLE(threads, [AC_HELP_STRING([--enable-threads],[compile FFTW SMP threads library])], enable_threads=$enableval, enable_threads=$with_openmp)
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])])
fi

dnl Check for threads library...
THREADLIBS=""
if test "$enable_threads" = "yes"; then
if test "$with_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])])
fi

# POSIX threads, the default choice:
if test -z "$THREADLIBS"; then
ACX_PTHREAD([THREADLIBS="$PTHREAD_LIBS "
Expand All @@ -391,7 +408,7 @@ if test "$enable_threads" = "yes"; then
AC_DEFINE(HAVE_THREADS, 1, [Define if we have a threads library.])
fi
AC_SUBST(THREADLIBS)
AM_CONDITIONAL(THREADS, test x"$THREADLIBS" != x)
AM_CONDITIONAL(SMP, test "$have_smp" = "yes")
AM_CONDITIONAL(COMBINED_THREADS, test x"$with_combined_threads" = xyes)

dnl -----------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion kernel/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct minfo {

static struct minfo *minfo[HASHSZ] = {0};

#ifdef HAVE_THREADS
#if defined(HAVE_THREADS) || defined(HAVE_OPENMP)
int X(in_thread) = 0;
#endif

Expand Down
2 changes: 1 addition & 1 deletion kernel/ifftw.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ IFFTW_EXTERN void *X(malloc_plain)(size_t sz);

#endif

#if defined(FFTW_DEBUG) && defined(FFTW_DEBUG_MALLOC) && defined(HAVE_THREADS)
#if defined(FFTW_DEBUG) && defined(FFTW_DEBUG_MALLOC) && (defined(HAVE_THREADS) || defined(HAVE_OPENMP))
extern int X(in_thread);
# define IN_THREAD X(in_thread)
# define THREAD_ON { int in_thread_save = X(in_thread); X(in_thread) = 1
Expand Down
2 changes: 1 addition & 1 deletion mpi/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ libfftw3@PREC_SUFFIX@_mpi_la_SOURCES = api.c any-true.c block.c conf.c fftw3-mpi

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

if THREADS
if SMP
if !COMBINED_THREADS
LIBFFTWTHREADS = $(top_builddir)/threads/libfftw3@PREC_SUFFIX@_threads.la
endif
Expand Down
10 changes: 5 additions & 5 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/kernel -I$(top_srcdir)/libbench2 \
noinst_PROGRAMS = bench
EXTRA_DIST = check.pl README

if THREADS
if SMP
if !COMBINED_THREADS
LIBFFTWTHREADS = $(top_builddir)/threads/libfftw3@PREC_SUFFIX@_threads.la
endif
Expand All @@ -23,7 +23,7 @@ check-local: bench$(EXEEXT)
@echo "--------------------------------------------------------------"
@echo " FFTW transforms passed basic tests!"
@echo "--------------------------------------------------------------"
if THREADS
if SMP
perl -w $(srcdir)/check.pl -r -c=30 -v --nthreads=2 `pwd`/bench
@echo "--------------------------------------------------------------"
@echo " FFTW threaded transforms passed basic tests!"
Expand All @@ -35,7 +35,7 @@ bigcheck: bench$(EXEEXT)
@echo "--------------------------------------------------------------"
@echo " FFTW transforms passed big tests!"
@echo "--------------------------------------------------------------"
if THREADS
if SMP
perl -w $(srcdir)/check.pl -a -v --nthreads=2 `pwd`/bench
perl -w $(srcdir)/check.pl -a -v --nthreads=3 `pwd`/bench
perl -w $(srcdir)/check.pl -a -v --nthreads=10 `pwd`/bench
Expand All @@ -50,15 +50,15 @@ smallcheck: bench$(EXEEXT)
@echo "--------------------------------------------------------------"
@echo " FFTW transforms passed a few tests!"
@echo "--------------------------------------------------------------"
if THREADS
if SMP
perl -w $(srcdir)/check.pl -r --estimate -c=2 -v --nthreads=2 `pwd`/bench
@echo "--------------------------------------------------------------"
@echo " FFTW threaded transforms passed a few tests!"
@echo "--------------------------------------------------------------"
endif

paranoid-check: bench$(EXEEXT)
if THREADS
if SMP
perl -w $(srcdir)/check.pl -a -o=exhaustive --nthreads=10 --paranoid `pwd`/bench
perl -w $(srcdir)/check.pl -a -o=exhaustive --nthreads=7 --paranoid `pwd`/bench
perl -w $(srcdir)/check.pl -a -o=exhaustive --nthreads=3 --paranoid `pwd`/bench
Expand Down
10 changes: 7 additions & 3 deletions tests/fftw-bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include <string.h>
#include "fftw-bench.h"

#if defined(HAVE_THREADS) || defined(HAVE_OPENMP)
#define HAVE_SMP
#endif

FFTW(plan) the_plan = 0;

static const char *wisdat = "wis.dat";
Expand Down Expand Up @@ -52,7 +56,7 @@ void rdwisdom(void)

if (havewisdom) return;

#ifdef HAVE_THREADS
#ifdef HAVE_SMP
BENCH_ASSERT(FFTW(init_threads)());
FFTW(plan_with_nthreads)(nthreads);
#endif
Expand Down Expand Up @@ -147,7 +151,7 @@ void setup(bench_problem *p)
rdwisdom();
install_hook();

#ifdef HAVE_THREADS
#ifdef HAVE_SMP
if (verbose > 1 && nthreads > 1) printf("NTHREADS = %d\n", nthreads);
#endif

Expand Down Expand Up @@ -190,7 +194,7 @@ void done(bench_problem *p)
void cleanup(void)
{
wrwisdom();
#ifdef HAVE_THREADS
#ifdef HAVE_SMP
FFTW(cleanup_threads)();
#else
FFTW(cleanup)();
Expand Down
4 changes: 2 additions & 2 deletions threads/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
AM_CPPFLAGS = -I$(top_srcdir)/kernel -I$(top_srcdir)/dft \
-I$(top_srcdir)/rdft -I$(top_srcdir)/api

if THREADS
if SMP
if COMBINED_THREADS
noinst_LTLIBRARIES = libfftw3@PREC_SUFFIX@_threads.la
else
Expand All @@ -13,7 +13,7 @@ endif
# pkginclude_HEADERS = threads.h

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 \
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@_threads_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@
17 changes: 16 additions & 1 deletion threads/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@

static int threads_inited = 0;

static void threads_register_hooks(void)
{
X(mksolver_ct_hook) = X(mksolver_ct_threads);
X(mksolver_hc2hc_hook) = X(mksolver_hc2hc_threads);
}

static void threads_unregister_hooks(void)
{
X(mksolver_ct_hook) = 0;
X(mksolver_hc2hc_hook) = 0;
}

/* should be called before all other FFTW functions! */
int X(init_threads)(void)
{
Expand All @@ -32,6 +44,8 @@ int X(init_threads)(void)
if (X(ithreads_init)())
return 0;

threads_register_hooks();

/* this should be the first time the_planner is called,
and hence the time it is configured */
plnr = X(the_planner)();
Expand All @@ -42,11 +56,13 @@ int X(init_threads)(void)
return 1;
}


void X(cleanup_threads)(void)
{
X(cleanup)();
if (threads_inited) {
X(threads_cleanup)();
threads_unregister_hooks();
threads_inited = 0;
}
}
Expand All @@ -62,5 +78,4 @@ void X(plan_with_nthreads)(int nthreads)
A(threads_inited);
plnr = X(the_planner)();
plnr->nthr = X(imax)(1, nthreads);
X(threads_setmax)(plnr->nthr);
}
4 changes: 2 additions & 2 deletions threads/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@

static const solvtab s =
{
#ifdef HAVE_THREADS
#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 /* HAVE_THREADS */
#endif

SOLVTAB_END
};
Expand Down
80 changes: 80 additions & 0 deletions threads/openmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2003, 2006 Matteo Frigo
* Copyright (c) 2003, 2006 Massachusetts Institute of Technology
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

/* openmp.c: thread spawning via OpenMP */

#include "threads.h"

#ifdef HAVE_OPENMP

#if !defined(_OPENMP)
#error OpenMP enabled but not using an OpenMP compiler
#endif

int X(ithreads_init)(void)
{
return 0; /* no error */
}

/* Distribute a loop from 0 to loopmax-1 over nthreads threads.
proc(d) is called to execute a block of iterations from d->min
to d->max-1. d->thr_num indicate the number of the thread
that is executing proc (from 0 to nthreads-1), and d->data is
the same as the data parameter passed to X(spawn_loop).
This function returns only after all the threads have completed. */
void X(spawn_loop)(int loopmax, int nthr, spawn_function proc, void *data)
{
int block_size;
spawn_data d;
int i;

A(loopmax >= 0);
A(nthr > 0);
A(proc);

if (!loopmax) return;

/* Choose the block size and number of threads in order to (1)
minimize the critical path and (2) use the fewest threads that
achieve the same critical path (to minimize overhead).
e.g. if loopmax is 5 and nthr is 4, we should use only 3
threads with block sizes of 2, 2, and 1. */
block_size = (loopmax + nthr - 1) / nthr;
nthr = (loopmax + block_size - 1) / block_size;

THREAD_ON; /* prevent debugging mode from failing under threads */
#pragma omp parallel for private(d)
for (i = 0; i < nthr; ++i) {
d.max = (d.min = i * block_size) + block_size;
if (d.max > loopmax)
d.max = loopmax;
d.thr_num = i;
d.data = data;
proc(&d);
}
THREAD_OFF; /* prevent debugging mode from failing under threads */
}

void X(threads_cleanup)(void)
{
}

#endif /* HAVE_OPENMP */
Loading

0 comments on commit 9809db5

Please sign in to comment.