Skip to content

Commit

Permalink
Merge pull request #92 from psteinb/support_mkl_gnuwrapper
Browse files Browse the repository at this point in the history
Support mkl gnuwrapper
  • Loading branch information
Peter Steinbach authored Aug 23, 2018
2 parents 7e45491 + e491d69 commit eb5cb77
Show file tree
Hide file tree
Showing 7 changed files with 315 additions and 10 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*~
debug*
release*
*.out
*.err
*.log
*.sh
build*
48 changes: 45 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -183,19 +183,19 @@ if(FFTW_FOUND AND GEARSHIFFT_FFTW)
list(APPEND FFTW_LIBS_TO_USE ${_LIBSTEM})
endforeach()

set(GEARSHIFFT_FFTW_THREADS 0)
set(GEARSHIFFT_FFTW_USE_THREADS 0)
if(GEARSHIFFT_FFTW_OPENMP AND OPENMP_FOUND AND "${FFTW_LIBRARIES}" MATCHES ".*_omp.*")
foreach(_LIBSTEM IN LISTS FFTW_OPENMP_LIBS)
list(APPEND FFTW_LIBS_TO_USE ${_LIBSTEM})
endforeach()
set(GEARSHIFFT_FFTW_THREADS 1)
set(GEARSHIFFT_FFTW_USE_THREADS 1)
endif()

if(GEARSHIFFT_FFTW_PTHREADS AND "${FFTW_LIBRARIES}" MATCHES ".*_threads.*")
foreach(_LIBSTEM IN LISTS FFTW_THREADS_LIBS)
list(APPEND FFTW_LIBS_TO_USE ${_LIBSTEM})
endforeach()
set(GEARSHIFFT_FFTW_THREADS 1)
set(GEARSHIFFT_FFTW_USE_THREADS 1)
endif()

set(FFTW_LIBRARIES ${FFTW_LIBS_TO_USE})
Expand All @@ -204,6 +204,48 @@ else()
message("<< FFTW benchmark disabled.")
endif()

#------------------------------------------------------------------------------
# FFTW Wrappers of MKL
#------------------------------------------------------------------------------

find_package(FFTWWrappers)
if(FFTWWrappers_FOUND) # found FFTWWrappers for GNU or Intel
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if(FFTWWrappers_GNU_LIBRARIES)
# gcc and fftwwrappers gnu libraries found

set(FFTWWrappers_LIBRARIES "${FFTWWrappers_GNU_LIBRARIES}")
endif()

elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
if(FFTWWrappers_INTEL_LIBRARIES)
# intel and fftwwrappers intel libraries found

set(FFTWWrappers_LIBRARIES "${FFTWWrappers_INTEL_LIBRARIES}")
endif()

else()
message(WARNING "Could not detect GNU or Intel compiler.")
endif()

# link_directories(${FFTWWrappers_LIBRARY_DIR})
endif(FFTWWrappers_FOUND)

if(FFTWWrappers_LIBRARIES)
# if compiler supports OpenMP then add flag, as FFTWWrappers might need it
find_package( OpenMP )
if(OpenMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()
set(GEARSHIFFT_FFTW_USE_THREADS 1) #

list(APPEND FFTLIBS fftwwrappers)
message(">> FFTWWrappers -> ${FFTWWrappers_LIBRARIES}")
else()
message("<< FFTWWrappers benchmark disabled.")
endif()

if(NOT FFTLIBS)
message(FATAL_ERROR ">> No FFT library for benchmark found !!!")
Expand Down
2 changes: 1 addition & 1 deletion cmake/FindFFTW.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ find_package_handle_standard_args(FFTW DEFAULT_MSG
# HANDLE_COMPONENTS
)

if(NOT FFTW_VERBOSE_FIND)
if(NOT FFTW_FIND_QUIETLY)
message("++ FindFFTW")
message("++ FFTW_INCLUDES : ${FFTW_INCLUDES}")
message("++ FFTW_LIBRARIES : ${FFTW_LIBRARIES}")
Expand Down
207 changes: 207 additions & 0 deletions cmake/FindFFTWWrappers.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# - Find the FFTW library
#
# Usage:
# find_package(FFTWWrappers [REQUIRED] [QUIET])
#
# It sets the following variables:
# FFTWWrappers_FOUND ... true if fftw is found on the system
# FFTWWrappers_GNU_LIBRARIES ... list of library that were build with the GNU binary layout
# FFTWWrappers_INTEL_LIBRARIES ... list of library that were build with the intel binary layout
# FFTWWrappers_LIBRARIES ... list of library identifiers that were found (will be filled with serial/openmp/pthreads enabled file names if present, only stubs will be filled in not full paths)
# FFTWWrappers_MKL_LIBRARIES ... list of library in the MKL that need to be linked to (intel64)
# FFTWWrappers_MKL_INCLUDE_DIR ... folder containing fftw3.h
# FFTWWrappers_MKL_LIBRARY_DIRS ... folder containing the libraries in FFTWWrappers_MKL_LIBRARIES
# FFTWWrappers_LIBRARY_DIR ... fftw library directory
#
# The following variables will be checked by the function
# FFTWWrappers_ROOT ... if set, the libraries are exclusively searched
# under this path
# MKLROOT ... take the MKL libraries from here
#

#If environment variable FFTWWrappers_ROOT is defined, it has the same effect as the cmake variable
if( NOT FFTWWrappers_ROOT AND DEFINED ENV{FFTWWrappers_ROOT} )
if( EXISTS "$ENV{FFTWWrappers_ROOT}/" )
set( FFTWWrappers_ROOT $ENV{FFTWWrappers_ROOT} )
else()
message( "FFTWWrappers_ROOT set to ${FFTWWrappers_ROOT}, but folder does not exist")
endif()
endif()

#If environment variable MKLROOT is defined, it has the same effect as the cmake variable
if( NOT MKLROOT AND DEFINED ENV{MKLROOT})
if( EXISTS "$ENV{MKLROOT}/" )
set( MKLROOT $ENV{MKLROOT} )
else()
message( "MKLROOT set to ${MKLROOT}, but folder does not exist")
endif()
endif()

################################### FFTWWrappers related ##################################

#initialize library variables
find_library(
FFTWWrappers_GNU_LIBRARIES
NAMES libfftw3xc_gnu libfftw3xc_gnu.a
PATHS ${FFTWWrappers_ROOT}
PATH_SUFFIXES "lib" "lib64"
NO_DEFAULT_PATH
)
find_library(
FFTWWrappers_GNU_LIBRARIES
NAMES libfftw3xc_gnu libfftw3xc_gnu.a
PATHS ${MKLROOT}
PATH_SUFFIXES "lib/intel64"
NO_DEFAULT_PATH
)
find_library(
FFTWWrappers_GNU_LIBRARIES
NAMES libfftw3xc_gnu libfftw3xc_gnu.a
)

if(EXISTS ${FFTWWrappers_GNU_LIBRARIES})
get_filename_component(FFTWWrappers_LIBRARY_DIR ${FFTWWrappers_GNU_LIBRARIES} DIRECTORY)
endif()

find_library(
FFTWWrappers_INTEL_LIBRARIES
NAMES libfftw3xc_intel libfftw3xc_intel.a
PATHS ${FFTWWrappers_ROOT}
PATH_SUFFIXES "lib" "lib64"
NO_DEFAULT_PATH
)
find_library(
FFTWWrappers_INTEL_LIBRARIES
NAMES libfftw3xc_intel libfftw3xc_intel.a
PATHS ${MKLROOT}
PATH_SUFFIXES "lib/intel64_lin"
NO_DEFAULT_PATH
)
find_library(
FFTWWrappers_INTEL_LIBRARIES
NAMES libfftw3xc_intel libfftw3xc_intel.a
)

if(EXISTS ${FFTWWrappers_INTEL_LIBRARIES})
get_filename_component(FFTWWrappers_LIBRARY_DIR ${FFTWWrappers_INTEL_LIBRARIES} DIRECTORY)
endif()

######################################### MKL related #####################################

find_file(
FFTWWrapper_include_file
NAMES fftw3.h
PATHS ${MKLROOT} ${MKLROOT}/include/fftw
PATH_SUFFIXES "include" "include/fftw"
NO_DEFAULT_PATH
)

if(EXISTS ${FFTWWrapper_include_file})
get_filename_component(FFTWWrappers_MKL_INCLUDE_DIR ${FFTWWrapper_include_file} DIRECTORY)
else()
message( "FFTWWrappers was not able to find fftw3.h in ${MKLROOT}")
endif()

find_library(
MKL_INTEL_LP64
NAMES libmkl_intel_lp64 libmkl_intel_lp64.a
PATHS ${MKLROOT}
PATH_SUFFIXES "lib/intel64_lin" "lib/intel64"
NO_DEFAULT_PATH
)

if(EXISTS ${MKL_INTEL_LP64})
list(APPEND FFTWWrappers_MKL_LIBRARIES "${MKL_INTEL_LP64}")
else()
message( "FFTWWrappers was not able to find libmkl_intel_lp64.a in ${MKLROOT}")
endif()

find_library(
MKL_INTEL_THREAD
NAMES libmkl_intel_thread libmkl_intel_thread.a
PATHS ${MKLROOT}
PATH_SUFFIXES "lib/intel64_lin" "lib/intel64"
NO_DEFAULT_PATH
)

if(EXISTS ${MKL_INTEL_THREAD})
list(APPEND FFTWWrappers_MKL_LIBRARIES "${MKL_INTEL_THREAD}")
else()
message( "FFTWWrappers was not able to find libmkl_intel_thread.a in ${MKLROOT}")
endif()

find_library(
MKL_CORE
NAMES libmkl_core libmkl_core.a
PATHS ${MKLROOT}
PATH_SUFFIXES "lib/intel64_lin" "lib/intel64"
NO_DEFAULT_PATH
)

if(EXISTS ${MKL_CORE})
list(APPEND FFTWWrappers_MKL_LIBRARIES "${MKL_CORE}")
else()
message("FFTWWrappers was not able to find libmkl_core.a in ${MKLROOT}")
endif()

list(APPEND FFTWWrappers_MKL_LIBRARY_DIRS "${MKLROOT}/../compiler/lib/intel64")
list(APPEND FFTWWrappers_MKL_LIBRARY_DIRS "${MKLROOT}/../tbb/lib/intel64/gcc4.4")

find_library(
MKL_IOMP5
NAMES iomp5 libiomp5 libiomp5.a
PATHS ${MKLROOT} ${MKLROOT}/../compiler/lib/intel64 ${MKLROOT}/../tbb/lib/intel64/gcc4.4
NO_DEFAULT_PATH
)

if(EXISTS ${MKL_IOMP5})
list(APPEND FFTWWrappers_MKL_LIBRARIES "${MKL_IOMP5}")
else()

endif()

list(APPEND FFTWWrappers_MKL_LIBRARIES "m;dl")

if(NOT FFTW_FIND_QUIETLY)
message("++ FindFFTWWrappers")
message("++ FFTWWrappers_GNU_LIBRARIES : ${FFTWWrappers_GNU_LIBRARIES}")
message("++ FFTWWrappers_INTEL_LIBRARIES : ${FFTWWrappers_INTEL_LIBRARIES}")
message("++ FFTWWrappers_LIBRARY_DIR : ${FFTWWrappers_LIBRARY_DIR}")
message("++ FFTWWrappers_MKL_LIBRARIES : ${FFTWWrappers_MKL_LIBRARIES}")
message("++ FFTWWrappers_MKL_LIBRARY_DIRS : ${FFTWWrappers_MKL_LIBRARY_DIRS}")
message("++ FFTWWrappers_MKL_INCLUDE_DIR : ${FFTWWrappers_MKL_INCLUDE_DIR}")
endif()


######################################### EXPORTS #####################################

include(FindPackageHandleStandardArgs)

if(FFTWWrappers_GNU_LIBRARIES)
find_package_handle_standard_args(FFTWWrappers
REQUIRED_VARS FFTWWrappers_GNU_LIBRARIES
REQUIRED_VARS FFTWWrappers_MKL_LIBRARIES
REQUIRED_VARS FFTWWrappers_MKL_INCLUDE_DIR
)
set(FFTWWrappers_LIBRARIES "${FFTWWrappers_GNU_LIBRARIES}")

else()
find_package_handle_standard_args(FFTWWrappers
REQUIRED_VARS FFTWWrappers_INTEL_LIBRARIES
REQUIRED_VARS FFTWWrappers_MKL_LIBRARIES
REQUIRED_VARS FFTWWrappers_MKL_INCLUDE_DIR
)
set(FFTWWrappers_LIBRARIES "${FFTWWrappers_INTEL_LIBRARIES}")

endif()


mark_as_advanced(
FFTWWrappers_LIBRARIES
FFTWWrappers_GNU_LIBRARIES
FFTWWrappers_INTEL_LIBRARIES
FFTWWrappers_LIBRARY_DIR
FFTWWrappers_MKL_LIBRARIES
FFTWWrappers_MKL_LIBRARY_DIR
FFTWWrappers_MKL_INCLUDE_DIR
)
15 changes: 15 additions & 0 deletions cmake/FindFFTWWrappers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# MKL Wrappers for FFTW3

## Installation

- consult the [MKL webpage](https://software.intel.com/en-us/mkl-developer-reference-c-fftw3-interface-to-intel-math-kernel-library) on the matter
- setup parallel studio (using environment modules, singularity, or just the compilevars.sh that ships with parallel studio xe)
- then the following should work for you:
```
$ cd ${MKLROOT}
$ cd interfaces/fftw3xc
$ make libintel64 compiler=intel INSTALL_DIR=/my/path
$ make libintel64 compiler=gnu INSTALL_DIR=/my/path
$ ls /my/path/libfftw3xc_*.a
/my/path/libfftw3xc_gnu.a /my/path/libfftw3xc_intel.a
```
36 changes: 31 additions & 5 deletions inc/libraries/fftw/fftw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@
namespace gearshifft {
namespace fftw {

static inline bool native_fftw() {

static std::string version = fftw_version;
std::transform(version.begin(), version.end(), version.begin(), ::tolower);

static bool value = version.find("mkl") == std::string::npos;

return value;
}


class FftwOptions : public OptionsDefault {

public:
Expand All @@ -44,8 +55,11 @@ namespace fftw {
return FFTW_ESTIMATE;
if(rigor_ == "patient")
return FFTW_PATIENT;
if(rigor_ == "wisdom")
if(rigor_ == "wisdom"){
if(!native_fftw())
throw std::runtime_error("wisdom rigor not supported with mkl wrappers.");
return FFTW_WISDOM_ONLY;
}
if(rigor_ == "exhaustive")
return FFTW_EXHAUSTIVE;
throw std::runtime_error("Invalid FFTW rigor.");
Expand Down Expand Up @@ -345,7 +359,15 @@ namespace fftw {
struct FftwContext : public ContextDefault<FftwOptions> {

static const std::string title() {
return "Fftw";
if(native_fftw()){
return "Fftw";}
else{
#ifdef __INTEL_COMPILER
return "Fftw_mkl_intelwrapper";
#else
return "Fftw_mkl_gnuwrapper";
#endif
}
}

static std::string get_device_list() {
Expand Down Expand Up @@ -395,6 +417,10 @@ namespace fftw {
struct ImportWisdom {

void operator()() {

if(!native_fftw())
throw std::runtime_error("Wisdom files are only supported by native fftw, unable to proceed");

std::string filename = FftwContext::options().wisdom_file<T_Precision>();
std::string source;
std::ifstream ifs;
Expand Down Expand Up @@ -509,22 +535,22 @@ namespace fftw {
throw std::runtime_error("FFT data exceeds physical memory. "+ss.str());
}

#if GEARSHIFFT_FFTW_THREADS==1
#if GEARSHIFFT_FFTW_USE_THREADS==1
if( traits::thread_api<TPrecision>::init_threads()==0 )
throw std::runtime_error("fftw thread initialization failed.");

traits::thread_api<TPrecision>::plan_with_threads(FftwContext::options().getNumberDevices());
#endif

if(plan_rigor_ == FFTW_WISDOM_ONLY) {
if(plan_rigor_ == FFTW_WISDOM_ONLY && native_fftw()) {
ImportWisdom<TPrecision>()();
}
}

~FftwImpl(){

destroy();
#if GEARSHIFFT_FFTW_THREADS==1
#if GEARSHIFFT_FFTW_USE_THREADS==1
traits::thread_api<TPrecision>::cleanup_threads();
#else
traits::no_thread_api<TPrecision>::cleanup();
Expand Down
Loading

0 comments on commit eb5cb77

Please sign in to comment.