Commit 7010d391 authored by Lorenz Huedepohl's avatar Lorenz Huedepohl
Browse files

Merge 'master' into u/loh/master

parents 77c7c405 c13fcc7b
......@@ -9,8 +9,8 @@ AM_LDFLAGS = $(SCALAPACK_LDFLAGS)
lib_LTLIBRARIES = libelpa@SUFFIX@.la
libelpa@SUFFIX@_la_LINK = $(FCLINK) $(AM_LDFLAGS) -version-info $(ELPA_SO_VERSION) -lstdc++
libelpa@SUFFIX@_la_SOURCES = src/elpa1.F90 src/elpa2.F90
libelpa@SUFFIX@_la_SOURCES += src/elpa_qr/qr_utils.F90 \
libelpa@SUFFIX@_la_SOURCES = src/elpa_utilities.F90 src/elpa1.F90 src/elpa2_utilities.F90 src/elpa2.F90
libelpa@SUFFIX@_la_SOURCES += src/elpa_qr/qr_utils.f90 \
src/elpa_qr/elpa_qrkernels.f90 \
src/elpa_qr/elpa_pdlarfb.f90 \
src/elpa_qr/elpa_pdgeqrf.f90
......
......@@ -170,8 +170,9 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(elpa_includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libelpa@SUFFIX@_la_LIBADD =
am__libelpa@SUFFIX@_la_SOURCES_DIST = src/elpa1.F90 src/elpa2.F90 \
src/elpa_qr/qr_utils.F90 src/elpa_qr/elpa_qrkernels.f90 \
am__libelpa@SUFFIX@_la_SOURCES_DIST = src/elpa_utilities.F90 \
src/elpa1.F90 src/elpa2_utilities.F90 src/elpa2.F90 \
src/elpa_qr/qr_utils.f90 src/elpa_qr/elpa_qrkernels.f90 \
src/elpa_qr/elpa_pdlarfb.f90 src/elpa_qr/elpa_pdgeqrf.f90 \
src/timer.F90 src/ftimings/ftimings.F90 \
src/ftimings/ftimings_type.F90 src/ftimings/ftimings_value.F90 \
......@@ -212,14 +213,14 @@ am__dirstamp = $(am__leading_dot)dirstamp
@WITH_REAL_AVX_BLOCK6_KERNEL_TRUE@am__objects_12 = src/elpa2_kernels/elpa2_kernels_real_sse-avx_6hv.lo
@WITH_COMPLEX_AVX_BLOCK1_KERNEL_TRUE@am__objects_13 = src/elpa2_kernels/elpa2_kernels_complex_sse-avx_1hv.lo
@WITH_COMPLEX_AVX_BLOCK2_KERNEL_TRUE@am__objects_14 = src/elpa2_kernels/elpa2_kernels_complex_sse-avx_2hv.lo
am_libelpa@SUFFIX@_la_OBJECTS = src/elpa1.lo src/elpa2.lo \
src/elpa_qr/qr_utils.lo src/elpa_qr/elpa_qrkernels.lo \
src/elpa_qr/elpa_pdlarfb.lo src/elpa_qr/elpa_pdgeqrf.lo \
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
$(am__objects_13) $(am__objects_14)
am_libelpa@SUFFIX@_la_OBJECTS = src/elpa_utilities.lo src/elpa1.lo \
src/elpa2_utilities.lo src/elpa2.lo src/elpa_qr/qr_utils.lo \
src/elpa_qr/elpa_qrkernels.lo src/elpa_qr/elpa_pdlarfb.lo \
src/elpa_qr/elpa_pdgeqrf.lo $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
$(am__objects_9) $(am__objects_10) $(am__objects_11) \
$(am__objects_12) $(am__objects_13) $(am__objects_14)
libelpa@SUFFIX@_la_OBJECTS = $(am_libelpa@SUFFIX@_la_OBJECTS)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am__elpa1_test_complex@SUFFIX@_SOURCES_DIST = test/test_complex.F90 \
......@@ -797,14 +798,14 @@ AM_LDFLAGS = $(SCALAPACK_LDFLAGS)
# libelpa
lib_LTLIBRARIES = libelpa@SUFFIX@.la
libelpa@SUFFIX@_la_LINK = $(FCLINK) $(AM_LDFLAGS) -version-info $(ELPA_SO_VERSION) -lstdc++
libelpa@SUFFIX@_la_SOURCES = src/elpa1.F90 src/elpa2.F90 \
src/elpa_qr/qr_utils.F90 src/elpa_qr/elpa_qrkernels.f90 \
src/elpa_qr/elpa_pdlarfb.f90 src/elpa_qr/elpa_pdgeqrf.f90 \
$(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_6) \
$(am__append_7) $(am__append_8) $(am__append_9) \
$(am__append_10) $(am__append_11) $(am__append_12) \
$(am__append_13) $(am__append_14)
libelpa@SUFFIX@_la_SOURCES = src/elpa_utilities.F90 src/elpa1.F90 \
src/elpa2_utilities.F90 src/elpa2.F90 src/elpa_qr/qr_utils.f90 \
src/elpa_qr/elpa_qrkernels.f90 src/elpa_qr/elpa_pdlarfb.f90 \
src/elpa_qr/elpa_pdgeqrf.f90 $(am__append_1) $(am__append_2) \
$(am__append_3) $(am__append_4) $(am__append_5) \
$(am__append_6) $(am__append_7) $(am__append_8) \
$(am__append_9) $(am__append_10) $(am__append_11) \
$(am__append_12) $(am__append_13) $(am__append_14)
#if WITH_AVX_SANDYBRIDGE
# libelpa@SUFFIX@_la_SOURCES += src/elpa2_kernels/elpa2_kernels_real_sse-avx_2hv.c \
......@@ -981,7 +982,11 @@ src/$(am__dirstamp):
src/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) src/$(DEPDIR)
@: > src/$(DEPDIR)/$(am__dirstamp)
src/elpa_utilities.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/elpa1.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/elpa2_utilities.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/elpa2.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/elpa_qr/$(am__dirstamp):
@$(MKDIR_P) src/elpa_qr
......
......@@ -5,12 +5,14 @@ This file contains the release notes for the ELPA 2015.02.001 version
What is new?
-------------
a)
a) ABI change
---------------------
Most importantly, the ABI of the ELPA libray changed!
A rebuild/relink of the user code using the ELPA library is mandatory!
b)
b) QR-decomposition
---------------------
The only major change (which results in point a) is in the ELPA-2
part of the library for real matrices:
......@@ -27,15 +29,33 @@ Note, that the environment variable always takes precedence over the setting in
the API call.
Furthernote, that if neither the environment variable or the API keyword are not
set, or set to "no" or ".false.", respectively, then no qr decomposition is used
set, or set to "no" or ".false.", respectively, then no QR-decomposition is used
(i.e. the previous behaviour is maintained).
The QR-decomposition fails, if the chosen matrix size is not a multiple of the
blocksize. The library will give a warning message if this happens and it will
abort.
c)
c) Debug messages
----------------------
By setting the environment variable "ELPA_DEBUG_MESSAGES" to "yes", ELPA will now
print more information if an error occurs.
d) Optimization flags
-----------------------
The configure procedure was adapted to be more consistent. No compiler omptimization
flags are set automatically anymore, this is up to the user at build time
e) OpenMP check
----------------------
The checks for OpenMP in the configure have been improved
Any incompatibles to previous version?
---------------------------------------
......
......@@ -6523,7 +6523,7 @@ $as_echo_n "checking whether we can compile with BGQ intrinsics... " >&6; }
cat > conftest.$ac_ext <<_ACEOF
 
program test_bgq
VECTOR(REAL(8))::QPX_x1
VECTOR(REAL(8))::QPX_x2
real*8 :: hh(10,2))
QPX_h2 = VEC_SPLATS(hh(2,2))
 
......
......@@ -450,7 +450,7 @@ AC_MSG_CHECKING([whether we can compile with BGQ intrinsics])
AC_LINK_IFELSE([AC_LANG_SOURCE([
program test_bgq
VECTOR(REAL(8))::QPX_x1
VECTOR(REAL(8))::QPX_x2
real*8 :: hh(10,2))
QPX_h2 = VEC_SPLATS(hh(2,2))
......
This diff is collapsed.
This diff is collapsed.
! This file is part of ELPA.
!
! The ELPA library was originally created by the ELPA consortium,
! The ELPA library was originally created by the ELPA consortium,
! consisting of the following organizations:
!
! - Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
! - Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
! - Bergische Universität Wuppertal, Lehrstuhl für angewandte
! Informatik,
! - Technische Universität München, Lehrstuhl für Informatik mit
! Schwerpunkt Wissenschaftliches Rechnen ,
! - Fritz-Haber-Institut, Berlin, Abt. Theorie,
! - Max-Plack-Institut für Mathematik in den Naturwissenschaftrn,
! Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
! and
! Schwerpunkt Wissenschaftliches Rechnen ,
! - Fritz-Haber-Institut, Berlin, Abt. Theorie,
! - Max-Plack-Institut für Mathematik in den Naturwissenschaftrn,
! Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
! and
! - IBM Deutschland GmbH
!
!
......@@ -19,8 +19,8 @@
! http://elpa.rzg.mpg.de/
!
! ELPA is free software: you can redistribute it and/or modify
! it under the terms of the version 3 of the license of the
! GNU Lesser General Public License as published by the Free
! it under the terms of the version 3 of the license of the
! GNU Lesser General Public License as published by the Free
! Software Foundation.
!
! ELPA is distributed in the hope that it will be useful,
......@@ -44,7 +44,7 @@
! This file contains the compute intensive kernels for the Householder transformations.
!
! *** Special IBM BlueGene/Q version with QPX intrinsics in Fortran ***
!
!
! Copyright of the original code rests with the authors inside the ELPA
! consortium. The copyright of any additional modifications shall rest
! with their original authors, but shall adhere to the licensing terms
......
! This file is part of ELPA.
!
! The ELPA library was originally created by the ELPA consortium,
! consisting of the following organizations:
!
! - Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
! - Bergische Universität Wuppertal, Lehrstuhl für angewandte
! Informatik,
! - Technische Universität München, Lehrstuhl für Informatik mit
! Schwerpunkt Wissenschaftliches Rechnen ,
! - Fritz-Haber-Institut, Berlin, Abt. Theorie,
! - Max-Plack-Institut für Mathematik in den Naturwissenschaftrn,
! Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
! and
! - IBM Deutschland GmbH
!
!
! More information can be found here:
! http://elpa.rzg.mpg.de/
!
! ELPA is free software: you can redistribute it and/or modify
! it under the terms of the version 3 of the license of the
! GNU Lesser General Public License as published by the Free
! Software Foundation.
!
! ELPA 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 Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
! along with ELPA. If not, see <http://www.gnu.org/licenses/>
!
! ELPA reflects a substantial effort on the part of the original
! ELPA consortium, and we ask you to respect the spirit of the
! license that we chose: i.e., please contribute any changes you
! may have back to the original ELPA library distribution, and keep
! any derivatives of ELPA under the same license that we chose for
! the original distribution, the GNU Lesser General Public License.
!
!
! ELPA1 -- Faster replacements for ScaLAPACK symmetric eigenvalue routines
!
! Copyright of the original code rests with the authors inside the ELPA
! consortium. The copyright of any additional modifications shall rest
! with their original authors, but shall adhere to the licensing terms
! distributed along with the original code in the file "COPYING".
! ELPA2 -- 2-stage solver for ELPA
!
! Copyright of the original code rests with the authors inside the ELPA
! consortium. The copyright of any additional modifications shall rest
! with their original authors, but shall adhere to the licensing terms
! distributed along with the original code in the file "COPYING".
#include "config-f90.h"
module ELPA2_utilities
#ifdef HAVE_ISO_FORTRAN_ENV
use iso_fortran_env, only : error_unit
#endif
implicit none
PRIVATE ! By default, all routines contained are private
! The following routines are public:
public :: get_actual_real_kernel_name, get_actual_complex_kernel_name
public :: REAL_ELPA_KERNEL_GENERIC, REAL_ELPA_KERNEL_GENERIC_SIMPLE, &
REAL_ELPA_KERNEL_BGP, REAL_ELPA_KERNEL_BGQ, &
REAL_ELPA_KERNEL_SSE, REAL_ELPA_KERNEL_AVX_BLOCK2, &
REAL_ELPA_KERNEL_AVX_BLOCK4, REAL_ELPA_KERNEL_AVX_BLOCK6
public :: COMPLEX_ELPA_KERNEL_GENERIC, COMPLEX_ELPA_KERNEL_GENERIC_SIMPLE, &
COMPLEX_ELPA_KERNEL_BGP, COMPLEX_ELPA_KERNEL_BGQ, &
COMPLEX_ELPA_KERNEL_SSE, COMPLEX_ELPA_KERNEL_AVX_BLOCK1, &
COMPLEX_ELPA_KERNEL_AVX_BLOCK2
public :: REAL_ELPA_KERNEL_NAMES, COMPLEX_ELPA_KERNEL_NAMES
public :: get_actual_complex_kernel, get_actual_real_kernel
public :: check_allowed_complex_kernels, check_allowed_real_kernels
public :: AVAILABLE_COMPLEX_ELPA_KERNELS, AVAILABLE_REAL_ELPA_KERNELS
public :: print_available_real_kernels, print_available_complex_kernels
public :: qr_decomposition_via_environment_variable
#ifndef HAVE_ISO_FORTRAN_ENV
integer, parameter :: error_unit = 6
#endif
integer, parameter :: number_of_real_kernels = 8
integer, parameter :: REAL_ELPA_KERNEL_GENERIC = 1
integer, parameter :: REAL_ELPA_KERNEL_GENERIC_SIMPLE = 2
integer, parameter :: REAL_ELPA_KERNEL_BGP = 3
integer, parameter :: REAL_ELPA_KERNEL_BGQ = 4
integer, parameter :: REAL_ELPA_KERNEL_SSE = 5
integer, parameter :: REAL_ELPA_KERNEL_AVX_BLOCK2 = 6
integer, parameter :: REAL_ELPA_KERNEL_AVX_BLOCK4 = 7
integer, parameter :: REAL_ELPA_KERNEL_AVX_BLOCK6 = 8
#if defined(WITH_REAL_AVX_BLOCK2_KERNEL)
integer, parameter :: DEFAULT_REAL_ELPA_KERNEL = REAL_ELPA_KERNEL_GENERIC
#else
integer, parameter :: DEFAULT_REAL_ELPA_KERNEL = REAL_ELPA_KERNEL_GENERIC
#endif
character(35), parameter, dimension(number_of_real_kernels) :: &
REAL_ELPA_KERNEL_NAMES = (/"REAL_ELPA_KERNEL_GENERIC ", &
"REAL_ELPA_KERNEL_GENERIC_SIMPLE ", &
"REAL_ELPA_KERNEL_BGP ", &
"REAL_ELPA_KERNEL_BGQ ", &
"REAL_ELPA_KERNEL_SSE ", &
"REAL_ELPA_KERNEL_AVX_BLOCK2 ", &
"REAL_ELPA_KERNEL_AVX_BLOCK4 ", &
"REAL_ELPA_KERNEL_AVX_BLOCK6 "/)
integer, parameter :: number_of_complex_kernels = 7
integer, parameter :: COMPLEX_ELPA_KERNEL_GENERIC = 1
integer, parameter :: COMPLEX_ELPA_KERNEL_GENERIC_SIMPLE = 2
integer, parameter :: COMPLEX_ELPA_KERNEL_BGP = 3
integer, parameter :: COMPLEX_ELPA_KERNEL_BGQ = 4
integer, parameter :: COMPLEX_ELPA_KERNEL_SSE = 5
integer, parameter :: COMPLEX_ELPA_KERNEL_AVX_BLOCK1 = 6
integer, parameter :: COMPLEX_ELPA_KERNEL_AVX_BLOCK2 = 7
#if defined(WITH_COMPLEX_AVX_BLOCK1_KERNEL)
integer, parameter :: DEFAULT_COMPLEX_ELPA_KERNEL = COMPLEX_ELPA_KERNEL_GENERIC
#else
integer, parameter :: DEFAULT_COMPLEX_ELPA_KERNEL = COMPLEX_ELPA_KERNEL_GENERIC
#endif
character(35), parameter, dimension(number_of_complex_kernels) :: &
COMPLEX_ELPA_KERNEL_NAMES = (/"COMPLEX_ELPA_KERNEL_GENERIC ", &
"COMPLEX_ELPA_KERNEL_GENERIC_SIMPLE ", &
"COMPLEX_ELPA_KERNEL_BGP ", &
"COMPLEX_ELPA_KERNEL_BGQ ", &
"COMPLEX_ELPA_KERNEL_SSE ", &
"COMPLEX_ELPA_KERNEL_AVX_BLOCK1 ", &
"COMPLEX_ELPA_KERNEL_AVX_BLOCK2 "/)
integer, parameter :: &
AVAILABLE_REAL_ELPA_KERNELS(number_of_real_kernels) = &
(/ &
#if WITH_REAL_GENERIC_KERNEL
1 &
#else
0 &
#endif
#if WITH_REAL_GENERIC_SIMPLE_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_REAL_BGP_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_REAL_BGQ_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_REAL_SSE_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_REAL_AVX_BLOCK2_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_REAL_AVX_BLOCK4_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_REAL_AVX_BLOCK6_KERNEL
,1 &
#else
,0 &
#endif
/)
integer, parameter :: &
AVAILABLE_COMPLEX_ELPA_KERNELS(number_of_complex_kernels) = &
(/ &
#if WITH_COMPLEX_GENERIC_KERNEL
1 &
#else
0 &
#endif
#if WITH_COMPLEX_GENERIC_SIMPLE_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_COMPLEX_BGP_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_COMPLEX_BGQ_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_COMPLEX_SSE_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_COMPLEX_AVX_BLOCK1_KERNEL
,1 &
#else
,0 &
#endif
#if WITH_COMPLEX_AVX_BLOCK2_KERNEL
,1 &
#else
,0 &
#endif
/)
!******
contains
subroutine print_available_real_kernels
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
integer :: i
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("print_available_real_kernels")
#endif
do i=1, number_of_real_kernels
if (AVAILABLE_REAL_ELPA_KERNELS(i) .eq. 1) then
write(error_unit,*) REAL_ELPA_KERNEL_NAMES(i)
endif
enddo
write(error_unit,*) " "
write(error_unit,*) " At the moment the following kernel would be choosen:"
write(error_unit,*) get_actual_real_kernel_name()
#ifdef HAVE_DETAILED_TIMINGS
call timer%stop("print_available_real_kernels")
#endif
end subroutine print_available_real_kernels
subroutine print_available_complex_kernels
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
integer :: i
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("print_available_complex_kernels")
#endif
do i=1, number_of_complex_kernels
if (AVAILABLE_COMPLEX_ELPA_KERNELS(i) .eq. 1) then
write(error_unit,*) COMPLEX_ELPA_KERNEL_NAMES(i)
endif
enddo
write(error_unit,*) " "
write(error_unit,*) " At the moment the following kernel would be choosen:"
write(error_unit,*) get_actual_complex_kernel_name()
#ifdef HAVE_DETAILED_TIMINGS
call timer%stop("print_available_complex_kernels")
#endif
end subroutine print_available_complex_kernels
function get_actual_real_kernel() result(actual_kernel)
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
integer :: actual_kernel
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("get_actual_real_kernel")
#endif
! if kernel is not choosen via api
! check whether set by environment variable
actual_kernel = real_kernel_via_environment_variable()
if (actual_kernel .eq. 0) then
! if not then set default kernel
actual_kernel = DEFAULT_REAL_ELPA_KERNEL
endif
#ifdef HAVE_DETAILED_TIMINGS
call timer%stop("get_actual_real_kernel")
#endif
end function get_actual_real_kernel
function get_actual_real_kernel_name() result(actual_kernel_name)
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
character(35) :: actual_kernel_name
integer :: actual_kernel
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("get_actual_real_kernel_name")
#endif
actual_kernel = get_actual_real_kernel()
actual_kernel_name = REAL_ELPA_KERNEL_NAMES(actual_kernel)
#ifdef HAVE_DETAILED_TIMINGS
call timer%stop("get_actual_real_kernel_name")
#endif
end function get_actual_real_kernel_name
function get_actual_complex_kernel() result(actual_kernel)
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
integer :: actual_kernel
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("get_actual_complex_kernel")
#endif
! if kernel is not choosen via api
! check whether set by environment variable
actual_kernel = complex_kernel_via_environment_variable()
if (actual_kernel .eq. 0) then
! if not then set default kernel
actual_kernel = DEFAULT_COMPLEX_ELPA_KERNEL
endif
#ifdef HAVE_DETAILED_TIMINGS
call timer%stop("get_actual_complex_kernel")
#endif
end function get_actual_complex_kernel
function get_actual_complex_kernel_name() result(actual_kernel_name)
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
character(35) :: actual_kernel_name
integer :: actual_kernel
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("get_actual_complex_kernel_name")
#endif
actual_kernel = get_actual_complex_kernel()
actual_kernel_name = COMPLEX_ELPA_KERNEL_NAMES(actual_kernel)
#ifdef HAVE_DETAILED_TIMINGS
call timer%stop("get_actual_complex_kernel_name")
#endif
end function get_actual_complex_kernel_name
function check_allowed_real_kernels(THIS_REAL_ELPA_KERNEL) result(err)
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
integer, intent(in) :: THIS_REAL_ELPA_KERNEL
logical :: err
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("check_allowed_real_kernels")
#endif
err = .false.
if (AVAILABLE_REAL_ELPA_KERNELS(THIS_REAL_ELPA_KERNEL) .ne. 1) err=.true.
#ifdef HAVE_DETAILED_TIMINGS
call timer%stop("check_allowed_real_kernels")
#endif
end function check_allowed_real_kernels
function check_allowed_complex_kernels(THIS_COMPLEX_ELPA_KERNEL) result(err)
#ifdef HAVE_DETAILED_TIMINGS
use timings
#endif
implicit none
integer, intent(in) :: THIS_COMPLEX_ELPA_KERNEL
logical :: err
#ifdef HAVE_DETAILED_TIMINGS
call timer%start("check_allowed_complex_kernels")
#endif
err = .false.
if (AVAILABLE_COMPLEX_ELPA_KERNELS(THIS_COMPLEX_ELPA_KERNEL) .ne. 1) err=.true.