Commit 0ebe4802 authored by Lorenz Huedepohl's avatar Lorenz Huedepohl

First implementation of an autotuning procedure

To be used like this

   class(elpa_t), pointer      :: e
   class(elpa_autotune_t), pointer :: tune_state

   e => elpa_allocate()
   call e%set(...)
   [...]
   assert_elpa_ok(e%setup())

   tune_state => e%autotune_setup(ELPA_AUTOTUNE_FAST, ELPA_AUTOTUNE_DOMAIN_REAL)

   ! Autotuning loop, continues until all combinations have been tried
   do while (e%autotune_step(tune_state))
     ! Do the steps that are representative of your calculation
     call e%eigenvectors(a, ev, z, error)
   end do

   ! Fix best parameters, and de-allocate the autotune object
   call e%autotune_set_best(tune_state)
   call elpa_autotune_deallocate(tune_state)
parent 67c4a5dd
......@@ -35,6 +35,7 @@ noinst_LTLIBRARIES += libelpa@SUFFIX@_private.la
libelpa@SUFFIX@_private_la_FCFLAGS = $(AM_FCFLAGS) $(FC_MODOUT)private_modules $(FC_MODINC)private_modules
libelpa@SUFFIX@_private_la_SOURCES = \
src/elpa_impl.F90 \
src/elpa_autotune_impl.F90 \
src/elpa_abstract_impl.F90 \
src/helpers/mod_precision.F90 \
src/helpers/mod_mpi.F90 \
......
......@@ -98,3 +98,21 @@ enum ELPA_CONSTANTS {
ELPA_2STAGE_NUMBER_OF_REAL_KERNELS = (0 ELPA_FOR_ALL_2STAGE_REAL_KERNELS(ELPA_ENUM_SUM)),
};
#define ELPA_FOR_ALL_AUTOTUNE_LEVELS(X, ...) \
X(ELPA_AUTOTUNE_NOT_TUNABLE, 0) \
X(ELPA_AUTOTUNE_FAST, 1) \
X(ELPA_AUTOTUNE_MEDIUM, 2)
enum ELPA_AUTOTUNE_LEVELS {
ELPA_FOR_ALL_AUTOTUNE_LEVELS(ELPA_ENUM_ENTRY)
};
#define ELPA_FOR_ALL_AUTOTUNE_DOMAINS(X, ...) \
X(ELPA_AUTOTUNE_DOMAIN_REAL, 1) \
X(ELPA_AUTOTUNE_DOMAIN_COMPLEX, 2) \
X(ELPA_AUTOTUNE_DOMAIN_ANY, 3)
enum ELPA_AUTOTUNE_DOMAINS {
ELPA_FOR_ALL_AUTOTUNE_DOMAINS(ELPA_ENUM_ENTRY)
};
......@@ -123,3 +123,28 @@ for m, g, t, p, d, s, l in product(
matrix_flag[m]] + extra_flags))
print("endif\n" * endifs)
for p, d in product(sorted(prec_flag.keys()), sorted(domain_flag.keys())):
endifs = 0
if (p == "single"):
if (d == "real"):
print("if WANT_SINGLE_PRECISION_REAL")
elif (d == "complex"):
print("if WANT_SINGLE_PRECISION_COMPLEX")
else:
raise Exception("Oh no!")
endifs += 1
name = "test_autotune_{0}_{1}".format(d, p)
print("noinst_PROGRAMS += " + name)
print("check_SCRIPTS += " + name + ".sh")
print(name + "_SOURCES = test/Fortran/test_autotune.F90")
print(name + "_LDADD = $(test_program_ldadd)")
print(name + "_FCFLAGS = $(test_program_fcflags) \\")
print(" " + " \\\n ".join([
domain_flag[d],
prec_flag[p]]))
print("endif\n" * endifs)
......@@ -218,4 +218,10 @@ module elpa
deallocate(obj)
end subroutine
subroutine elpa_autotune_deallocate(obj)
class(elpa_autotune_t), pointer :: obj
call obj%destroy()
deallocate(obj)
end subroutine
end module
......@@ -72,6 +72,7 @@ module elpa_abstract_impl
type, abstract, extends(elpa_t) :: elpa_abstract_impl_t
#ifdef HAVE_DETAILED_TIMINGS
type(timer_t) :: timer
type(timer_t) :: autotune_timer
#else
type(timer_dummy_t) :: timer
#endif
......@@ -79,21 +80,6 @@ module elpa_abstract_impl
logical :: eigenvalues_only
contains
! set private fields in the index
generic, public :: set_private => &
elpa_set_private_integer, &
elpa_set_private_double
generic, public :: get_private => &
elpa_get_private_integer, &
elpa_get_private_double
procedure, private :: elpa_set_private_integer
procedure, private :: elpa_set_private_double
procedure, private :: elpa_get_private_integer
procedure, private :: elpa_get_private_double
procedure, public :: elpa_set_integer !< private methods to implement the setting of an integer/double key/value pair
procedure, public :: elpa_set_double
......@@ -110,7 +96,7 @@ module elpa_abstract_impl
!> \param name string, the key
!> \param value integer, the value to be set
!> \result error integer, the error code
subroutine elpa_set_private_integer(self, name, value, error)
subroutine elpa_set_integer(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
......@@ -118,7 +104,7 @@ module elpa_abstract_impl
integer, optional :: error
integer :: actual_error
actual_error = elpa_index_set_int_value_c(self%index, name // c_null_char, value, 0)
actual_error = elpa_index_set_int_value_c(self%index, name // c_null_char, value)
if (present(error)) then
error = actual_error
......@@ -135,7 +121,7 @@ module elpa_abstract_impl
!> \param name string, the key
!> \param value integer, the value of the key/vaue pair
!> \param error integer, optional, to store an error code
subroutine elpa_get_private_integer(self, name, value, error)
subroutine elpa_get_integer(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
......@@ -158,7 +144,7 @@ module elpa_abstract_impl
!> \param name string, the key
!> \param value double, the value to be set
!> \result error integer, the error code
subroutine elpa_set_private_double(self, name, value, error)
subroutine elpa_set_double(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
......@@ -166,7 +152,7 @@ module elpa_abstract_impl
integer, optional :: error
integer :: actual_error
actual_error = elpa_index_set_double_value_c(self%index, name // c_null_char, value, 0)
actual_error = elpa_index_set_double_value_c(self%index, name // c_null_char, value)
if (present(error)) then
error = actual_error
......@@ -182,7 +168,7 @@ module elpa_abstract_impl
!> \param name string, the key
!> \param value double, the value of the key/vaue pair
!> \param error integer, optional, to store an error code
subroutine elpa_get_private_double(self, name, value, error)
subroutine elpa_get_double(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
......@@ -199,128 +185,4 @@ module elpa_abstract_impl
end if
end subroutine
subroutine elpa_set_integer(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
integer(kind=c_int), intent(in) :: value
integer, optional :: error
integer :: actual_error
integer :: is_private
is_private = elpa_index_int_is_private_c(name // C_NULL_CHAR)
if (is_private == 0) then
call self%set_private(name, value, error)
else
if (is_private == 1) then
actual_error = ELPA_ERROR_ENTRY_NOT_FOUND
else
actual_error = is_private
endif
if (present(error)) then
error = actual_error
else
write(error_unit,'(a)') "ELPA: Error setting option '" // name // "'" // &
" (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
endif
endif
end subroutine
subroutine elpa_set_double(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
real(kind=c_double), intent(in) :: value
integer, optional :: error
integer :: actual_error
integer :: is_private
is_private = elpa_index_double_is_private_c(name // C_NULL_CHAR)
if (is_private == 0) then
call self%set_private(name, value, error)
else
if (is_private == 1) then
actual_error = ELPA_ERROR_ENTRY_NOT_FOUND
else
actual_error = is_private
endif
if (present(error)) then
error = actual_error
else
write(error_unit,'(a)') "ELPA: Error setting option '" // name // "'" // &
" (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
endif
endif
end subroutine
subroutine elpa_get_integer(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
integer(kind=c_int) :: value
integer, intent(out), optional :: error
integer :: actual_error
integer :: is_private
is_private = elpa_index_int_is_private_c(name // C_NULL_CHAR)
if (is_private == 0) then
call self%get_private(name, value, error)
else
if (is_private == 1) then
actual_error = ELPA_ERROR_ENTRY_NOT_FOUND
else
actual_error = is_private
endif
if (present(error)) then
error = actual_error
else
write(error_unit,'(a)') "ELPA: Error getting option '" // name // "'" // &
" (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
endif
endif
end subroutine
subroutine elpa_get_double(self, name, value, error)
use iso_c_binding
class(elpa_abstract_impl_t) :: self
character(*), intent(in) :: name
real(kind=c_double) :: value
integer, intent(out), optional :: error
integer :: actual_error
integer :: is_private
is_private = elpa_index_double_is_private_c(name // C_NULL_CHAR)
if (is_private == 0) then
call self%get_private(name, value, error)
else
if (is_private == 1) then
actual_error = ELPA_ERROR_ENTRY_NOT_FOUND
else
actual_error = is_private
endif
if (present(error)) then
error = actual_error
else
write(error_unit,'(a)') "ELPA: Error getting option '" // name // "'" // &
" (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
endif
endif
end subroutine
end module
This diff is collapsed.
#include "config-f90.h"
module elpa_autotune_impl
use elpa_abstract_impl
use, intrinsic :: iso_c_binding
implicit none
type, extends(elpa_autotune_t) :: elpa_autotune_impl_t
class(elpa_abstract_impl_t), pointer :: parent => NULL()
integer :: i = 0
real(kind=C_DOUBLE) :: min_val = 0.0_C_DOUBLE
integer :: min_loc = 0
integer :: N = 0
integer :: level = 0
integer :: domain = 0
contains
procedure, public :: print => elpa_autotune_print
procedure, public :: destroy => elpa_autotune_destroy
end type
contains
subroutine elpa_autotune_print(self)
implicit none
class(elpa_autotune_impl_t), intent(in) :: self
print *, "Print me"
end subroutine
subroutine elpa_autotune_destroy(self)
implicit none
class(elpa_autotune_impl_t), intent(inout) :: self
! nothing to do atm
end subroutine
end module
......@@ -129,8 +129,11 @@ module elpa_impl
procedure, public :: associate_int => elpa_associate_int !< public method to set some pointers
end type elpa_impl_t
procedure, public :: autotune_setup => elpa_autotune_setup
procedure, public :: autotune_step => elpa_autotune_step
procedure, public :: autotune_set_best => elpa_autotune_set_best
end type elpa_impl_t
!> \brief the implementation of the generic methods
contains
......@@ -545,10 +548,15 @@ module elpa_impl
call self%get("solver", solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_1stage_double_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_2stage_double_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -623,10 +631,15 @@ module elpa_impl
call self%get("solver",solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_1stage_single_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_2stage_single_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -706,10 +719,15 @@ module elpa_impl
call self%get("solver", solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_1stage_double_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_2stage_double_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -786,10 +804,15 @@ module elpa_impl
call self%get("solver", solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_1stage_single_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_2stage_single_impl(self, a, ev, q)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -867,10 +890,15 @@ module elpa_impl
call self%get("solver", solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_1stage_double_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_2stage_double_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -939,10 +967,15 @@ module elpa_impl
call self%get("solver",solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_1stage_single_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_real_2stage_single_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -1015,10 +1048,15 @@ module elpa_impl
call self%get("solver", solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_1stage_double_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_2stage_double_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -1089,10 +1127,15 @@ module elpa_impl
call self%get("solver", solver)
if (solver .eq. ELPA_SOLVER_1STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_1stage_single_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else if (solver .eq. ELPA_SOLVER_2STAGE) then
call self%autotune_timer%start("accumulator")
success_l = elpa_solve_evp_complex_2stage_single_impl(self, a, ev)
call self%autotune_timer%stop("accumulator")
else
print *,"unknown solver"
stop
......@@ -2043,9 +2086,88 @@ module elpa_impl
#endif
call timer_free(self%timer)
call timer_free(self%autotune_timer)
call elpa_index_free_c(self%index)
end subroutine
function elpa_autotune_setup(self, level, domain) result(tune_state)
class(elpa_impl_t), intent(inout), target :: self
integer, intent(in) :: level, domain
type(elpa_autotune_impl_t), pointer :: ts_impl
class(elpa_autotune_t), pointer :: tune_state
allocate(ts_impl)
ts_impl%parent => self
ts_impl%level = level
ts_impl%domain = domain
ts_impl%i = -1
ts_impl%min_loc = -1
ts_impl%N = elpa_index_autotune_cardinality_c(self%index, level, domain)
tune_state => ts_impl
call self%autotune_timer%enable()
end function
function elpa_autotune_step(self, tune_state) result(unfinished)
implicit none
class(elpa_impl_t), intent(inout) :: self
class(elpa_autotune_t), intent(inout), target :: tune_state
type(elpa_autotune_impl_t), pointer :: ts_impl
logical :: unfinished
integer :: i
real(kind=C_DOUBLE) :: time_spent
select type(tune_state)
class is (elpa_autotune_impl_t)
ts_impl => tune_state
class default
print *, "This should not happen"
end select
unfinished = .false.
if (ts_impl%i >= 0) then
time_spent = self%autotune_timer%get("accumulator")
print *, time_spent
if (ts_impl%min_loc == -1 .or. (time_spent < ts_impl%min_val)) then
ts_impl%min_val = time_spent
ts_impl%min_loc = ts_impl%i
end if
call self%autotune_timer%free()
endif
do while (ts_impl%i < ts_impl%N)
ts_impl%i = ts_impl%i + 1
if (elpa_index_set_autotune_parameters_c(self%index, ts_impl%level, ts_impl%domain, ts_impl%i) == 1) then
unfinished = .true.
return
end if
end do
end function
subroutine elpa_autotune_set_best(self, tune_state)
implicit none
class(elpa_impl_t), intent(inout) :: self
class(elpa_autotune_t), intent(in), target :: tune_state
type(elpa_autotune_impl_t), pointer :: ts_impl
select type(tune_state)
class is (elpa_autotune_impl_t)
ts_impl => tune_state
class default
print *, "This should not happen"
end select
print *, "set best, i = ", ts_impl%min_loc, "best time = ", ts_impl%min_val
if (elpa_index_set_autotune_parameters_c(self%index, ts_impl%level, ts_impl%domain, ts_impl%min_loc) /= 1) then
stop "This should not happen (in elpa_autotune_set_best())"
endif
end subroutine
end module
This diff is collapsed.
......@@ -89,13 +89,14 @@ typedef struct {
char *env_force;
int once;
int readonly;
int private;
} elpa_index_entry_t;
typedef struct {
elpa_index_entry_t base;
int default_value;
int autotune_level;
int autotune_domain;
elpa_index_valid_int_t valid;
elpa_index_cardinality_t cardinality;
elpa_index_enumerate_int_option_t enumerate;
......@@ -164,18 +165,17 @@ int elpa_index_get_int_value(elpa_index_t index, char *name, int *success);
/*
!f> interface
!f> function elpa_index_set_int_value_c(index, name, value, force_writable) result(success) &
!f> function elpa_index_set_int_value_c(index, name, value) result(success) &
!f> bind(C, name="elpa_index_set_int_value")
!f> import c_ptr, c_int, c_char
!f> type(c_ptr), value :: index
!f> character(kind=c_char), intent(in) :: name(*)
!f> integer(kind=c_int),intent(in), value :: value
!f> integer(kind=c_int),intent(in), value :: force_writable
!f> integer(kind=c_int) :: success
!f> end function
!f> end interface
*/
int elpa_index_set_int_value(elpa_index_t index, char *name, int value, int force_writable);
int elpa_index_set_int_value(elpa_index_t index, char *name, int value);
/*
......@@ -191,30 +191,6 @@ int elpa_index_set_int_value(elpa_index_t index, char *name, int value, int forc
int elpa_index_int_value_is_set(elpa_index_t index, char *name);
/*
!f> interface
!f> function elpa_index_int_is_private_c(name) result(success) bind(C, name="elpa_index_int_is_private")
!f> import c_int, c_char
!f> character(kind=c_char), intent(in) :: name(*)
!f> integer(kind=c_int) :: success
!f> end function
!f> end interface
*/
int elpa_index_int_is_private(char *name);
/*
!f> interface
!f> function elpa_index_double_is_private_c(name) result(success) bind(C, name="elpa_index_double_is_private")
!f> import c_int, c_char
!f> character(kind=c_char), intent(in) :: name(*)
!f> integer(kind=c_int) :: success
!f> end function
!f> end interface
*/
int elpa_index_double_is_private(char *name);
/*
!f> interface
!f> function elpa_index_get_int_loc_c(index, name) result(loc) bind(C, name="elpa_index_get_int_loc")
......@@ -244,18 +220,17 @@ double elpa_index_get_double_value(elpa_index_t index, char *name, int *success)
/*
!f> interface
!f> function elpa_index_set_double_value_c(index, name, value, force_writable) result(success) &
!f> function elpa_index_set_double_value_c(index, name, value) result(success) &
!f> bind(C, name="elpa_index_set_double_value")
!f> import c_ptr, c_int, c_double, c_char
!f> type(c_ptr), value :: index
!f> character(kind=c_char), intent(in) :: name(*)
!f> real(kind=c_double),intent(in), value :: value
!f> integer(kind=c_int),intent(in), value :: force_writable
!f> integer(kind=c_int) :: success
!f> end function
!f> end interface
*/
int elpa_index_set_double_value(elpa_index_t index, char *name, double value, int force_writable);
int elpa_index_set_double_value(elpa_index_t index, char *name, double value);
/*
......@@ -387,7 +362,8 @@ int elpa_option_enumerate(char *name, int i);
/*
!f> interface
!f> function elpa_index_int_is_valid_c(index, name, new_value) result(success) bind(C, name="elpa_index_int_is_valid")
!f> function elpa_index_int_is_valid_c(index, name, new_value) result(success) &
!f> bind(C, name="elpa_index_int_is_valid")
!f> import c_int, c_ptr, c_char
!f> type(c_ptr), intent(in), value :: index
!f> character(kind=c_char), intent(in) :: name(*)
......@@ -398,3 +374,33 @@ int elpa_option_enumerate(char *name, int i);
!f>
*/
int elpa_index_int_is_valid(elpa_index_t index, char *name, int new_value);
/*
!f> interface
!f> function elpa_index_autotune_cardinality_c(index, autotune_level, autotune_domain) result(n) &
!f> bind(C, name="elpa_index_autotune_cardinality")
!f> import c_int, c_ptr, c_char
!f> type(c_ptr), intent(in), value :: index
!f> integer(kind=c_int), intent(in), value :: autotune_level, autotune_domain
!f> integer(kind=c_int) :: n
!f> end function
!f> end interface
!f>
*/
int elpa_index_autotune_cardinality(elpa_index_t index, int autotune_level, int autotune_domain);
/*
!f> interface
!f> function elpa_index_set_autotune_parameters_c(index, autotune_level, autotune_domain, n) result(success) &
!f> bind(C, name="elpa_index_set_autotune_parameters")
!f> import c_int, c_ptr, c_char
!f> type(c_ptr), intent(in), value :: index
!f> integer(kind=c_int), intent(in), value :: autotune_level, autotune_domain, n
!f> integer(kind=c_int) :: success
!f> end function
!f> end interface
!f>
*/
int elpa_index_set_autotune_parameters(elpa_index_t index, int autotune_level, int autotune_domain, int n);
......@@ -23,3 +23,8 @@
ELPA_FOR_ALL_2STAGE_COMPLEX_KERNELS_AND_DEFAULT(FORTRAN_CONSTANT)
#undef ELPA_2STAGE_NUMBER_OF_COMPLEX_KERNELS
FORTRAN_CONSTANT(ELPA_2STAGE_NUMBER_OF_COMPLEX_KERNELS, & NEWLINE (0 ELPA_FOR_ALL_2STAGE_COMPLEX_KERNELS(ELPA_ENUM_SUM)))
! Autotune
ELPA_FOR_ALL_AUTOTUNE_LEVELS(FORTRAN_CONSTANT)
ELPA_FOR_ALL_AUTOTUNE_DOMAINS(FORTRAN_CONSTANT)
......@@ -503,9 +503,6 @@ program test
#ifdef TEST_MATRIX_ANALYTIC
status = check_correctness_analytic(na, nev, ev, z, nblk, myid, np_rows, np_cols, my_prow, my_pcol, check_all_evals)
#else
!#elif defined(TEST_MATRIX_FRANK)
! status = check_correctness_evp_numeric_residuals(na, nev, as, z, ev, sc_desc, nblk, myid, np_rows,np_cols, my_prow, my_pcol)
!#elif defined(TEST_MATRIX_RANDOM)
if (nev .ge. 1) then
status = check_correctness_evp_numeric_residuals(na, nev, as, z, ev, sc_desc, nblk, myid, np_rows,np_cols, my_prow, my_pcol)
else
......@@ -514,9 +511,6 @@ program test
subdiagonalElement, ev, z, myid)
endif
call check_status(status, myid)
!#else
!#error "MATRIX TYPE"
!#endif
#endif
#endif /* defined(TEST_EIGENVECTORS) || defined(TEST_QR_DECOMPOSITION) */
......@@ -542,89 +536,6 @@ program test
call check_status(status, myid)
#endif
!#ifdef TEST_COMPLEX
! status = 0
!
! !-------------------------------------------------------------------------------
! ! Test correctness of result (using plain scalapack routines)
! allocate(tmp1(na_rows,na_cols))
! allocate(tmp2(na_rows,na_cols))
!#ifdef TEST_DOUBLE
! tmp1(:,:) = (0.0_c_double, 0.0_c_double)