Commit 73192f0a authored by Pavel Kus's avatar Pavel Kus

load parameters implemented

parent 43d89656
......@@ -241,3 +241,16 @@ for lang, p, d in product(sorted(language_flag.keys()), sorted(prec_flag.keys())
prec_flag[p]]))
print("endif\n" * endifs)
print("endif")
name = "test_multiple_objs_real_double"
print("if ENABLE_AUTOTUNING")
print("check_SCRIPTS += " + name + "_extended.sh")
print("noinst_PROGRAMS += " + name)
print(name + "_SOURCES = test/Fortran/test_multiple_objs.F90")
print(name + "_LDADD = $(test_program_ldadd)")
print(name + "_FCFLAGS = $(test_program_fcflags) \\")
print(" " + " \\\n ".join([
domain_flag['real'],
prec_flag['double']]))
print("endif")
......@@ -155,6 +155,7 @@ module elpa_api
procedure(print_all_parameters_i), deferred, public :: print_all_parameters !< method to print all parameters
procedure(save_all_parameters_i), deferred, public :: save_all_parameters !< method to save all parameters
procedure(load_all_parameters_i), deferred, public :: load_all_parameters !< method to save all parameters
#ifdef ENABLE_AUTOTUNING
! Auto-tune
procedure(elpa_autotune_setup_i), deferred, public :: autotune_setup !< method to prepare the ELPA autotuning
......@@ -253,7 +254,7 @@ module elpa_api
!> \brief abstract definition of the print_all_parameters method
!> Parameters
!> \details
!> \param self class(elpa_t): the ELPA object, which should be tuned
!> \param self class(elpa_t): the ELPA object
!> Prints all the elpa parameters
abstract interface
subroutine print_all_parameters_i(self)
......@@ -266,7 +267,7 @@ module elpa_api
!> \brief abstract definition of the save_all_parameters method
!> Parameters
!> \details
!> \param self class(elpa_t): the ELPA object, which should be tuned
!> \param self class(elpa_t): the ELPA object
!> \param file_name string, the name of the file where to save the parameters
!> Saves all the elpa parameters
abstract interface
......@@ -274,7 +275,22 @@ module elpa_api
import elpa_t
implicit none
class(elpa_t), intent(inout) :: self
character(*), intent(in) :: file_name
character(*), intent(in) :: file_name
end subroutine
end interface
!> \brief abstract definition of the load_all_parameters method
!> Parameters
!> \details
!> \param self class(elpa_t): the ELPA object
!> \param file_name string, the name of the file from which to load the parameters
!> Loads all the elpa parameters
abstract interface
subroutine load_all_parameters_i(self, file_name)
import elpa_t
implicit none
class(elpa_t), intent(inout) :: self
character(*), intent(in) :: file_name
end subroutine
end interface
......
......@@ -157,6 +157,7 @@ module elpa_impl
procedure, public :: print_all_parameters => elpa_print_all_parameters
procedure, public :: save_all_parameters => elpa_save_all_parameters
procedure, public :: load_all_parameters => elpa_load_all_parameters
#ifdef ENABLE_AUTOTUNING
procedure, public :: autotune_setup => elpa_autotune_setup
procedure, public :: autotune_step => elpa_autotune_step
......@@ -1097,13 +1098,11 @@ module elpa_impl
implicit none
class(elpa_impl_t), intent(inout) :: self
!print *, "The following parameters have been set"
if (elpa_index_print_all_parameters_c(self%index, c_null_char) /= 1) then
stop "This should not happen (in elpa_print_all_parameters())"
endif
end subroutine
!> \brief function to save all the parameters, that have been set
!> Parameters
!> \param self class(elpa_impl_t) the allocated ELPA object
......@@ -1111,14 +1110,27 @@ module elpa_impl
subroutine elpa_save_all_parameters(self, file_name)
implicit none
class(elpa_impl_t), intent(inout) :: self
character(*), intent(in) :: file_name
character(*), intent(in) :: file_name
!print *, "The following parameters have been set"
if (elpa_index_print_all_parameters_c(self%index, file_name // c_null_char) /= 1) then
stop "This should not happen (in elpa_save_all_parameters())"
endif
end subroutine
!> \brief function to load all the parameters, which have been saved to a file
!> Parameters
!> \param self class(elpa_impl_t) the allocated ELPA object
!> \param file_name string, the name of the file from which to load the parameters
subroutine elpa_load_all_parameters(self, file_name)
implicit none
class(elpa_impl_t), intent(inout) :: self
character(*), intent(in) :: file_name
if (elpa_index_load_all_parameters_c(self%index, file_name // c_null_char) /= 1) then
stop "This should not happen (in elpa_load_all_parameters())"
endif
end subroutine
!> \brief function to print the state of the autotuning
!> Parameters
......
......@@ -44,6 +44,8 @@
//
// Authors: L. Huedepohl and A. Marek, MPCDF
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <elpa/elpa.h>
#include "elpa_index.h"
......@@ -386,6 +388,22 @@ FOR_ALL_TYPES(IMPLEMENT_LOC_FUNCTION)
}
FOR_ALL_TYPES(IMPLEMENT_SET_FUNCTION)
#define IMPLEMENT_SET_FROM_LOAD_FUNCTION(TYPE, PRINTF_SPEC, ...) \
int elpa_index_set_from_load_##TYPE##_value(elpa_index_t index, char *name, TYPE value, int explicit) { \
if (sizeof(TYPE##_entries) == 0) { \
return ELPA_ERROR_ENTRY_NOT_FOUND; \
} \
int n = find_##TYPE##_entry(name); \
if (n < 0) { \
return ELPA_ERROR_ENTRY_NOT_FOUND; \
}; \
index->TYPE##_options.values[n] = value; \
if(explicit) \
index->TYPE##_options.is_set[n] = 1; \
return ELPA_OK; \
}
FOR_ALL_TYPES(IMPLEMENT_SET_FROM_LOAD_FUNCTION)
#define IMPLEMENT_IS_SET_FUNCTION(TYPE, ...) \
int elpa_index_##TYPE##_value_is_set(elpa_index_t index, char *name) { \
......@@ -973,11 +991,12 @@ int elpa_index_autotune_cardinality(elpa_index_t index, int autotune_level, int
void elpa_index_print_int_parameter(elpa_index_t index, char* buff, int i)
{
int value = index->int_options.values[i];
sprintf(buff, "%s = ", int_entries[i].base.name);
if (int_entries[i].to_string) {
sprintf(buff, "%s%s\n", buff, int_entries[i].to_string(index->int_options.values[i]));
sprintf(buff, "%s%d -> %s\n", buff, value, int_entries[i].to_string(value));
} else {
sprintf(buff, "%s%d\n", buff, index->int_options.values[i]);
sprintf(buff, "%s%d\n", buff, value);
}
}
......@@ -1099,15 +1118,19 @@ int elpa_index_print_autotune_state(elpa_index_t index, int autotune_level, int
return 1;
}
const char STRUCTURE_PARAMETERS[] = "* Parameters describing structure of the computation:\n";
const char EXPLICIT_PARAMETERS[] = "* Parameters explicitly set by the user:\n";
const char DEFAULT_PARAMETERS[] = "* Parameters with default or environment value:\n";
int elpa_index_print_all_parameters(elpa_index_t index, char *file_name) {
const int LEN =10000;
char out_structure[LEN], out_set[LEN], out_defaults[LEN], out_nowhere[LEN], buff[100];
char (*out)[LEN];
FILE *f;
sprintf(out_structure, "Parameters describing structure of the computation:\n");
sprintf(out_set, "Parameters explicitly set by the user:\n");
sprintf(out_defaults, "Parameters with default or environment value:\n");
sprintf(out_structure, "%s", STRUCTURE_PARAMETERS);
sprintf(out_set, "%s", EXPLICIT_PARAMETERS);
sprintf(out_defaults, "%s", DEFAULT_PARAMETERS);
sprintf(out_nowhere, "Not to be printed:\n");
int is_process_id_zero = elpa_index_get_int_value(index, "is_process_id_zero", NULL);
if(is_process_id_zero){
......@@ -1144,3 +1167,45 @@ int elpa_index_print_all_parameters(elpa_index_t index, char *file_name) {
return 1;
}
int elpa_index_load_all_parameters(elpa_index_t index, char *file_name) {
const int LEN = 1000;
char line[LEN], s[LEN];
int n;
FILE *f;
int is_process_id_zero = elpa_index_get_int_value(index, "is_process_id_zero", NULL);
int skip, explicit;
//if(is_process_id_zero){
f = fopen(file_name, "r");
if (f == NULL) {
fprintf(stderr, "Cannont open file %s\n", file_name);
return(0);
}
skip = 1;
explicit = 0;
while ((fgets(line, LEN, f)) != NULL) {
if(strcmp(line, EXPLICIT_PARAMETERS) == 0){
skip = 0;
explicit = 1;
}
if(strcmp(line, DEFAULT_PARAMETERS) == 0){
skip = 0;
explicit = 0;
}
if(line[0] != '\n' && line[0] != '*'){
sscanf(line, "%s = %d\n", &s, &n);
if(! skip){
int error = elpa_index_set_from_load_int_value(index, s, n, explicit);
}
}
}
fclose(f);
// }
return 1;
}
......@@ -449,6 +449,20 @@ int elpa_index_print_autotune_parameters(elpa_index_t index, int autotune_level,
*/
int elpa_index_print_all_parameters(elpa_index_t index, char* filename);
/*
!f> interface
!f> function elpa_index_load_all_parameters_c(index, file_name) result(success) &
!f> bind(C, name="elpa_index_load_all_parameters")
!f> import c_int, c_ptr, c_char
!f> type(c_ptr), intent(in), value :: index
!f> character(kind=c_char), intent(in) :: file_name(*)
!f> integer(kind=c_int) :: success
!f> end function
!f> end interface
!f>
*/
int elpa_index_load_all_parameters(elpa_index_t index, char* filename);
/*
!f> interface
!f> function elpa_index_print_autotune_state_c(index, autotune_level, autotune_domain, min_loc, &
......
......@@ -219,8 +219,8 @@ program test
do while (e%autotune_step(tune_state))
iter=iter+1
write(iter_string,'(I5.5)') iter
call e%print_all_parameters()
call e%save_all_parameters("saved_parameters_"//trim(iter_string)//".txt")
!call e%print_all_parameters()
!call e%save_all_parameters("saved_parameters_"//trim(iter_string)//".txt")
call e%timer_start("eigenvectors: iteration "//trim(iter_string))
call e%eigenvectors(a, ev, z, error)
call e%timer_stop("eigenvectors: iteration "//trim(iter_string))
......@@ -233,8 +233,8 @@ program test
status = check_correctness_analytic(na, nev, ev, z, nblk, myid, np_rows, np_cols, my_prow, my_pcol, &
.true., .true., print_times=.false.)
a(:,:) = as(:,:)
call e%autotune_print_state(tune_state)
call e%autotune_save_state(tune_state, "saved_state_"//trim(iter_string)//".txt")
!call e%autotune_print_state(tune_state)
!call e%autotune_save_state(tune_state, "saved_state_"//trim(iter_string)//".txt")
end do
! set and print the autotuned-settings
......
! This file is part of ELPA.
!
! The ELPA library was originally created by the ELPA consortium,
! consisting of the following organizations:
!
! - Max Planck Computing and Data Facility (MPCDF), formerly known as
! 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 Naturwissenschaften,
! Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
! and
! - IBM Deutschland GmbH
!
!
! More information can be found here:
! http://elpa.mpcdf.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.
!
!
#include "config-f90.h"
! Define one of TEST_REAL or TEST_COMPLEX
! Define one of TEST_SINGLE or TEST_DOUBLE
! Define one of TEST_SOLVER_1STAGE or TEST_SOLVER_2STAGE
! Define TEST_GPU \in [0, 1]
! Define either TEST_ALL_KERNELS or a TEST_KERNEL \in [any valid kernel]
#if !(defined(TEST_REAL) ^ defined(TEST_COMPLEX))
error: define exactly one of TEST_REAL or TEST_COMPLEX
#endif
#if !(defined(TEST_SINGLE) ^ defined(TEST_DOUBLE))
error: define exactly one of TEST_SINGLE or TEST_DOUBLE
#endif
#ifdef TEST_SINGLE
# define EV_TYPE real(kind=C_FLOAT)
# ifdef TEST_REAL
# define MATRIX_TYPE real(kind=C_FLOAT)
# else
# define MATRIX_TYPE complex(kind=C_FLOAT_COMPLEX)
# endif
#else
# define EV_TYPE real(kind=C_DOUBLE)
# ifdef TEST_REAL
# define MATRIX_TYPE real(kind=C_DOUBLE)
# else
# define MATRIX_TYPE complex(kind=C_DOUBLE_COMPLEX)
# endif
#endif
#ifdef TEST_REAL
# define AUTOTUNE_DOMAIN ELPA_AUTOTUNE_DOMAIN_REAL
#else
# define AUTOTUNE_DOMAIN ELPA_AUTOTUNE_DOMAIN_COMPLEX
#endif
#include "assert.h"
program test
use elpa
use test_util
use test_setup_mpi
use test_prepare_matrix
use test_read_input_parameters
use test_blacs_infrastructure
use test_check_correctness
use test_analytic
use iso_fortran_env
#ifdef HAVE_REDIRECT
use test_redirect
#endif
implicit none
! matrix dimensions
integer :: na, nev, nblk
! mpi
integer :: myid, nprocs
integer :: na_cols, na_rows ! local matrix size
integer :: np_cols, np_rows ! number of MPI processes per column/row
integer :: my_prow, my_pcol ! local MPI task position (my_prow, my_pcol) in the grid (0..np_cols -1, 0..np_rows -1)
integer :: mpierr
! blacs
character(len=1) :: layout
integer :: my_blacs_ctxt, sc_desc(9), info, nprow, npcol
! The Matrix
MATRIX_TYPE, allocatable :: a(:,:), as(:,:)
! eigenvectors
MATRIX_TYPE, allocatable :: z(:,:)
! eigenvalues
EV_TYPE, allocatable :: ev(:)
integer :: error, status
type(output_t) :: write_to_file
class(elpa_t), pointer :: e1, e2, e_ptr
class(elpa_autotune_t), pointer :: tune_state
integer :: iter
character(len=5) :: iter_string
call read_input_parameters(na, nev, nblk, write_to_file)
call setup_mpi(myid, nprocs)
#ifdef HAVE_REDIRECT
#ifdef WITH_MPI
call MPI_BARRIER(MPI_COMM_WORLD, mpierr)
call redirect_stdout(myid)
#endif
#endif
if (elpa_init(CURRENT_API_VERSION) /= ELPA_OK) then
print *, "ELPA API version not supported"
stop 1
endif
layout = 'C'
do np_cols = NINT(SQRT(REAL(nprocs))),2,-1
if(mod(nprocs,np_cols) == 0 ) exit
enddo
np_rows = nprocs/np_cols
assert(nprocs == np_rows * np_cols)
if (myid == 0) then
print '((a,i0))', 'Matrix size: ', na
print '((a,i0))', 'Num eigenvectors: ', nev
print '((a,i0))', 'Blocksize: ', nblk
#ifdef WITH_MPI
print '((a,i0))', 'Num MPI proc: ', nprocs
print '(3(a,i0))','Number of processor rows=',np_rows,', cols=',np_cols,', total=',nprocs
print '(a)', 'Process layout: ' // layout
#endif
print *,''
endif
call set_up_blacsgrid(mpi_comm_world, np_rows, np_cols, layout, &
my_blacs_ctxt, my_prow, my_pcol)
call set_up_blacs_descriptor(na, nblk, my_prow, my_pcol, np_rows, np_cols, &
na_rows, na_cols, sc_desc, my_blacs_ctxt, info)
allocate(a (na_rows,na_cols))
allocate(as(na_rows,na_cols))
allocate(z (na_rows,na_cols))
allocate(ev(na))
a(:,:) = 0.0
z(:,:) = 0.0
ev(:) = 0.0
call prepare_matrix_analytic(na, a, nblk, myid, np_rows, np_cols, my_prow, my_pcol, print_times=.false.)
as(:,:) = a(:,:)
e1 => elpa_allocate()
call set_basic_params(e1, na, nev, na_rows, na_cols, my_prow, my_pcol)
call e1%set("timings",1, error)
call e1%set("debug",1)
call e1%set("gpu", 0)
!call e1%set("max_stored_rows", 15, error)
assert_elpa_ok(e1%setup())
call e1%save_all_parameters("initial_parameters.txt")
! try to load parameters into another object
e2 => elpa_allocate()
call set_basic_params(e2, na, nev, na_rows, na_cols, my_prow, my_pcol)
call e2%load_all_parameters("initial_parameters.txt")
assert_elpa_ok(e2%setup())
if(myid == 0) print *, "parameters of e1"
call e1%print_all_parameters()
if(myid == 0) print *, ""
if(myid == 0) print *, "parameters of e2"
call e2%print_all_parameters()
e_ptr => e2
tune_state => e_ptr%autotune_setup(ELPA_AUTOTUNE_MEDIUM, AUTOTUNE_DOMAIN, error)
assert_elpa_ok(error)
iter=0
do while (e_ptr%autotune_step(tune_state))
iter=iter+1
write(iter_string,'(I5.5)') iter
call e_ptr%print_all_parameters()
call e_ptr%save_all_parameters("saved_parameters_"//trim(iter_string)//".txt")
call e_ptr%timer_start("eigenvectors: iteration "//trim(iter_string))
call e_ptr%eigenvectors(a, ev, z, error)
call e_ptr%timer_stop("eigenvectors: iteration "//trim(iter_string))
assert_elpa_ok(error)
if (myid .eq. 0) then
print *, ""
call e_ptr%print_times("eigenvectors: iteration "//trim(iter_string))
endif
status = check_correctness_analytic(na, nev, ev, z, nblk, myid, np_rows, np_cols, my_prow, my_pcol, &
.true., .true., print_times=.false.)
a(:,:) = as(:,:)
call e_ptr%autotune_print_state(tune_state)
call e_ptr%autotune_save_state(tune_state, "saved_state_"//trim(iter_string)//".txt")
end do
! set and print the autotuned-settings
call e_ptr%autotune_set_best(tune_state)
if (myid .eq. 0) then
print *, "The best combination found by the autotuning:"
flush(output_unit)
call e_ptr%autotune_print_best(tune_state)
endif
! de-allocate autotune object
call elpa_autotune_deallocate(tune_state)
if (myid .eq. 0) then
print *, "Running once more time with the best found setting..."
endif
call e_ptr%timer_start("eigenvectors: best setting")
call e_ptr%eigenvectors(a, ev, z, error)
call e_ptr%timer_stop("eigenvectors: best setting")
assert_elpa_ok(error)
if (myid .eq. 0) then
print *, ""
call e_ptr%print_times("eigenvectors: best setting")
endif
status = check_correctness_analytic(na, nev, ev, z, nblk, myid, np_rows, np_cols, my_prow, my_pcol, &
.true., .true., print_times=.false.)
call elpa_deallocate(e_ptr)
deallocate(a)
deallocate(as)
deallocate(z)
deallocate(ev)
call elpa_uninit()
#ifdef WITH_MPI
call blacs_gridexit(my_blacs_ctxt)
call mpi_finalize(mpierr)
#endif
call exit(status)
contains
subroutine set_basic_params(elpa, na, nev, na_rows, na_cols, my_prow, my_pcol)
implicit none
class(elpa_t), pointer :: elpa
integer, intent(in) :: na, nev, na_rows, na_cols, my_prow, my_pcol
call elpa%set("na", na, error)
assert_elpa_ok(error)
call elpa%set("nev", nev, error)
assert_elpa_ok(error)
call elpa%set("local_nrows", na_rows, error)
assert_elpa_ok(error)
call elpa%set("local_ncols", na_cols, error)
assert_elpa_ok(error)
call elpa%set("nblk", nblk, error)
assert_elpa_ok(error)
#ifdef WITH_MPI
call elpa%set("mpi_comm_parent", MPI_COMM_WORLD, error)
assert_elpa_ok(error)
call elpa%set("process_row", my_prow, error)
assert_elpa_ok(error)
call elpa%set("process_col", my_pcol, error)
assert_elpa_ok(error)
#endif
end subroutine
end program
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment