Commit 3a0fb34f authored by Andreas Marek's avatar Andreas Marek
Browse files

C autotune test programs

parent 997cee12
...@@ -173,7 +173,7 @@ for lang, m, g, q, t, p, d, s, lay in product(sorted(language_flag.keys()), ...@@ -173,7 +173,7 @@ for lang, m, g, q, t, p, d, s, lay in product(sorted(language_flag.keys()),
print("endif\n" * endifs) print("endif\n" * endifs)
for p, d in product(sorted(prec_flag.keys()), sorted(domain_flag.keys())): for lang, p, d in product(sorted(language_flag.keys()), sorted(prec_flag.keys()), sorted(domain_flag.keys())):
endifs = 0 endifs = 0
if (p == "single"): if (p == "single"):
if (d == "real"): if (d == "real"):
...@@ -184,12 +184,20 @@ for p, d in product(sorted(prec_flag.keys()), sorted(domain_flag.keys())): ...@@ -184,12 +184,20 @@ for p, d in product(sorted(prec_flag.keys()), sorted(domain_flag.keys())):
raise Exception("Oh no!") raise Exception("Oh no!")
endifs += 1 endifs += 1
name = "test_autotune_{0}_{1}".format(d, p) name = "test_autotune{langsuffix}_{d}_{p}".format(langsuffix=language_flag[lang], d=d, p=p)
print("check_SCRIPTS += " + name + ".sh")
print("noinst_PROGRAMS += " + name) print("noinst_PROGRAMS += " + name)
print(name + "_SOURCES = test/Fortran/test_autotune.F90") if lang == "Fortran":
print(name + "_LDADD = $(test_program_ldadd)") print(name + "_SOURCES = test/Fortran/test_autotune.F90")
print(name + "_FCFLAGS = $(test_program_fcflags) \\") print(name + "_LDADD = $(test_program_ldadd)")
print(name + "_FCFLAGS = $(test_program_fcflags) \\")
elif lang == "C":
print(name + "_SOURCES = test/C/test_autotune.c")
print(name + "_LDADD = $(test_program_ldadd) $(FCLIBS)")
print(name + "_CFLAGS = $(test_program_fcflags) \\")
print(" " + " \\\n ".join([ print(" " + " \\\n ".join([
domain_flag[d], domain_flag[d],
prec_flag[p]])) prec_flag[p]]))
......
noinst_PROGRAMS += \ noinst_PROGRAMS += \
autotune_c_version@SUFFIX@ \
legacy_real_1stage@SUFFIX@ \ legacy_real_1stage@SUFFIX@ \
legacy_complex_1stage@SUFFIX@ \ legacy_complex_1stage@SUFFIX@ \
legacy_real_2stage@SUFFIX@ \ legacy_real_2stage@SUFFIX@ \
...@@ -73,10 +72,6 @@ noinst_PROGRAMS += \ ...@@ -73,10 +72,6 @@ noinst_PROGRAMS += \
endif endif
endif endif
autotune_c_version@SUFFIX@_SOURCES = test/C/autotune_c_version.c
autotune_c_version@SUFFIX@_LDADD = $(test_program_ldadd) $(FCLIBS)
autotune_c_version@SUFFIX@_FCFLAGS = $(test_program_fcflags)
legacy_real_1stage_c_version@SUFFIX@_SOURCES = test/C/elpa1/legacy_interface/legacy_real_1stage_c_version.c legacy_real_1stage_c_version@SUFFIX@_SOURCES = test/C/elpa1/legacy_interface/legacy_real_1stage_c_version.c
legacy_real_1stage_c_version@SUFFIX@_LDADD = $(test_program_ldadd) $(FCLIBS) legacy_real_1stage_c_version@SUFFIX@_LDADD = $(test_program_ldadd) $(FCLIBS)
legacy_real_1stage_c_version@SUFFIX@_FCFLAGS = $(test_program_fcflags) legacy_real_1stage_c_version@SUFFIX@_FCFLAGS = $(test_program_fcflags)
......
/* This file is part of ELPA. */ /* 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: */ consisting of the following organizations:
/* */
/* - Max Planck Computing and Data Facility (MPCDF), formerly known as */ - Max Planck Computing and Data Facility (MPCDF), formerly known as
/* Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG), */ Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
/* - Bergische Universität Wuppertal, Lehrstuhl für angewandte */ - Bergische Universität Wuppertal, Lehrstuhl für angewandte
/* Informatik, */ Informatik,
/* - Technische Universität München, Lehrstuhl für Informatik mit */ - Technische Universität München, Lehrstuhl für Informatik mit
/* Schwerpunkt Wissenschaftliches Rechnen , */ Schwerpunkt Wissenschaftliches Rechnen ,
/* - Fritz-Haber-Institut, Berlin, Abt. Theorie, */ - Fritz-Haber-Institut, Berlin, Abt. Theorie,
/* - Max-Plack-Institut für Mathematik in den Naturwissenschaften, */ - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
/* Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition, */ Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
/* and */ and
/* - IBM Deutschland GmbH */ - IBM Deutschland GmbH
/* */
/* */
/* More information can be found here: */ More information can be found here:
/* http://elpa.mpcdf.mpg.de/ */ http://elpa.mpcdf.mpg.de/
/* */
/* ELPA is free software: you can redistribute it and/or modify */ ELPA is free software: you can redistribute it and/or modify
/* it under the terms of the version 3 of the license of the */ it under the terms of the version 3 of the license of the
/* GNU Lesser General Public License as published by the Free */ GNU Lesser General Public License as published by the Free
/* Software Foundation. */ Software Foundation.
/* */
/* ELPA is distributed in the hope that it will be useful, */ ELPA is distributed in the hope that it will be useful,
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ but WITHOUT ANY WARRANTY; without even the implied warranty of
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/* GNU Lesser General Public License for more details. */ GNU Lesser General Public License for more details.
/* */
/* You should have received a copy of the GNU Lesser General Public License */ You should have received a copy of the GNU Lesser General Public License
/* along with ELPA. If not, see <http://www.gnu.org/licenses/> */ along with ELPA. If not, see <http://www.gnu.org/licenses/>
/* */
/* ELPA reflects a substantial effort on the part of the original */ ELPA reflects a substantial effort on the part of the original
/* ELPA consortium, and we ask you to respect the spirit of the */ ELPA consortium, and we ask you to respect the spirit of the
/* license that we chose: i.e., please contribute any changes you */ license that we chose: i.e., please contribute any changes you
/* may have back to the original ELPA library distribution, and keep */ may have back to the original ELPA library distribution, and keep
/* any derivatives of ELPA under the same license that we chose for */ any derivatives of ELPA under the same license that we chose for
/* the original distribution, the GNU Lesser General Public License. */ the original distribution, the GNU Lesser General Public License.
/* */ */
/* */
#include "config.h"
#include "config-f90.h"
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef WITH_MPI #ifdef WITH_MPI
...@@ -53,143 +53,120 @@ ...@@ -53,143 +53,120 @@
#include <elpa/elpa.h> #include <elpa/elpa.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include "test/shared/generated.h"
#include <test/shared/generated.h>
#define DOUBLE_PRECISION_REAL 1 #if !(defined(TEST_REAL) ^ defined(TEST_COMPLEX))
//#error "define exactly one of TEST_REAL or TEST_COMPLEX"
#endif
#define assert_elpa_ok(x) assert(x == ELPA_OK) #if !(defined(TEST_SINGLE) ^ defined(TEST_DOUBLE))
//#error "define exactly one of TEST_SINGLE or TEST_DOUBLE"
#endif
int main(int argc, char** argv) { #if !(defined(TEST_SOLVER_1STAGE) ^ defined(TEST_SOLVER_2STAGE))
int myid; //#error "define exactly one of TEST_SOLVER_1STAGE or TEST_SOLVER_2STAGE"
int nprocs;
#ifndef WITH_MPI
int MPI_COMM_WORLD;
#endif #endif
int na, nev, nblk;
int status; #ifdef TEST_SINGLE
# define EV_TYPE float
# ifdef TEST_REAL
# define MATRIX_TYPE float
# else
# define MATRIX_TYPE complex float
# endif
#else
# define EV_TYPE double
# ifdef TEST_REAL
# define MATRIX_TYPE double
# else
# define MATRIX_TYPE complex double
# endif
#endif
int np_cols, np_rows, np_colsStart; #define assert_elpa_ok(x) assert(x == ELPA_OK)
int my_blacs_ctxt, my_prow, my_pcol;
int mpierr; int main(int argc, char** argv) {
/* matrix dimensions */
int na, nev, nblk;
int my_mpi_comm_world; /* mpi */
int mpi_comm_rows, mpi_comm_cols; int myid, nprocs;
int na_cols, na_rows;
int np_cols, np_rows;
int my_prow, my_pcol;
int mpi_comm;
int info, *sc_desc; /* blacs */
int my_blacs_ctxt, sc_desc[9], info;
int na_rows, na_cols; /* The Matrix */
double startVal; MATRIX_TYPE *a, *as, *z;
#ifdef DOUBLE_PRECISION_REAL EV_TYPE *ev;
double *a, *z, *as, *ev;
#else
float *a, *z, *as, *ev;
#endif
int success; int error, status;
elpa_t handle; elpa_t handle;
elpa_autotune_t autotune_handle; elpa_autotune_t autotune_handle;
int value, error, unfinished, i; int i, unfinished;
int value;
#ifdef WITH_MPI #ifdef WITH_MPI
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_rank(MPI_COMM_WORLD, &myid);
#else #else
nprocs = 1; nprocs = 1;
myid=0; myid = 0;
MPI_COMM_WORLD=1;
#endif #endif
na = 100;
nev = 50;
nblk = 16;
if (myid == 0) { if (argc == 4) {
printf("This is the c version of an ELPA test-programm\n"); na = atoi(argv[1]);
printf("\n"); nev = atoi(argv[2]);
printf("It will call the 2stage ELPA real solver for an\n"); nblk = atoi(argv[3]);
printf("matrix of size %d. It will compute %d eigenvalues\n",na,nev); } else {
printf("and uses a blocksize of %d\n",nblk); na = 1000;
printf("\n"); nev = 500;
printf("This is an example program with much less functionality\n"); nblk = 16;
printf("as it's Fortran counterpart. It's only purpose is to show how \n");
printf("to evoke ELPA2 from a c programm\n");
printf("\n");
#ifdef DOUBLE_PRECISION_REAL
printf(" Double precision version of ELPA2 is used. \n");
#else
printf(" Single precision version of ELPA2 is used. \n");
#endif
} }
status = 0; for (np_cols = (int) sqrt((double) nprocs); np_cols > 1; np_cols--) {
if (nprocs % np_cols == 0) {
startVal = sqrt((double) nprocs); break;
np_colsStart = (int) round(startVal);
for (np_cols=np_colsStart;np_cols>1;np_cols--){
if (nprocs %np_cols ==0){
break;
} }
} }
np_rows = nprocs/np_cols; np_rows = nprocs/np_cols;
if (myid == 0) {
printf("\n");
printf("Number of processor rows %d, cols %d, total %d \n",np_rows,np_cols,nprocs);
}
/* set up blacs */ /* set up blacs */
/* convert communicators before */ /* convert communicators before */
#ifdef WITH_MPI #ifdef WITH_MPI
my_mpi_comm_world = MPI_Comm_c2f(MPI_COMM_WORLD); mpi_comm = MPI_Comm_c2f(MPI_COMM_WORLD);
#else #else
my_mpi_comm_world = 1; mpi_comm = 0;
#endif #endif
set_up_blacsgrid_f(my_mpi_comm_world, np_rows, np_cols, 'C', &my_blacs_ctxt, &my_prow, &my_pcol); set_up_blacsgrid_f(mpi_comm, np_rows, np_cols, 'C', &my_blacs_ctxt, &my_prow, &my_pcol);
if (myid == 0) {
printf("\n");
printf("Past BLACS_Gridinfo...\n");
printf("\n");
}
sc_desc = malloc(9*sizeof(int));
set_up_blacs_descriptor_f(na, nblk, my_prow, my_pcol, np_rows, np_cols, &na_rows, &na_cols, sc_desc, my_blacs_ctxt, &info); set_up_blacs_descriptor_f(na, nblk, my_prow, my_pcol, np_rows, np_cols, &na_rows, &na_cols, sc_desc, my_blacs_ctxt, &info);
if (myid == 0) {
printf("\n");
printf("Past scalapack descriptor setup...\n");
printf("\n");
}
/* allocate the matrices needed for elpa */ /* allocate the matrices needed for elpa */
if (myid == 0) { a = calloc(na_rows*na_cols, sizeof(MATRIX_TYPE));
printf("\n"); z = calloc(na_rows*na_cols, sizeof(MATRIX_TYPE));
printf("Allocating matrices with na_rows=%d and na_cols=%d\n",na_rows, na_cols); as = calloc(na_rows*na_cols, sizeof(MATRIX_TYPE));
printf("\n"); ev = calloc(na, sizeof(EV_TYPE));
}
#ifdef DOUBLE_PRECISION_REAL #ifdef TEST_REAL
a = malloc(na_rows*na_cols*sizeof(double)); #ifdef TEST_DOUBLE
z = malloc(na_rows*na_cols*sizeof(double));
as = malloc(na_rows*na_cols*sizeof(double));
ev = malloc(na*sizeof(double));
#else
a = malloc(na_rows*na_cols*sizeof(float));
z = malloc(na_rows*na_cols*sizeof(float));
as = malloc(na_rows*na_cols*sizeof(float));
ev = malloc(na*sizeof(float));
#endif
#ifdef DOUBLE_PRECISION_REAL
prepare_matrix_random_real_double_f(na, myid, na_rows, na_cols, sc_desc, a, z, as); prepare_matrix_random_real_double_f(na, myid, na_rows, na_cols, sc_desc, a, z, as);
#else #else
prepare_matrix_random_real_single_f(na, myid, na_rows, na_cols, sc_desc, a, z, as); prepare_matrix_random_real_single_f(na, myid, na_rows, na_cols, sc_desc, a, z, as);
#endif
#else
#ifdef TEST_DOUBLE
prepare_matrix_random_complex_double_f(na, myid, na_rows, na_cols, sc_desc, a, z, as);
#else
prepare_matrix_random_complex_single_f(na, myid, na_rows, na_cols, sc_desc, a, z, as);
#endif
#endif #endif
if (elpa_init(CURRENT_API_VERSION) != ELPA_OK) { if (elpa_init(CURRENT_API_VERSION) != ELPA_OK) {
...@@ -207,6 +184,9 @@ int main(int argc, char** argv) { ...@@ -207,6 +184,9 @@ int main(int argc, char** argv) {
elpa_set(handle, "nev", nev, &error); elpa_set(handle, "nev", nev, &error);
assert_elpa_ok(error); assert_elpa_ok(error);
if (myid == 0) {
printf("Setting the matrix parameters na=%d, nev=%d \n",na,nev);
}
elpa_set(handle, "local_nrows", na_rows, &error); elpa_set(handle, "local_nrows", na_rows, &error);
assert_elpa_ok(error); assert_elpa_ok(error);
...@@ -230,16 +210,11 @@ int main(int argc, char** argv) { ...@@ -230,16 +210,11 @@ int main(int argc, char** argv) {
/* Setup */ /* Setup */
assert_elpa_ok(elpa_setup(handle)); assert_elpa_ok(elpa_setup(handle));
/* Set tunables */
elpa_set(handle, "gpu", 0, &error); elpa_set(handle, "gpu", 0, &error);
assert_elpa_ok(error); assert_elpa_ok(error);
#ifdef WITH_MPI
mpierr = MPI_Barrier(MPI_COMM_WORLD);
#endif
autotune_handle = elpa_autotune_setup(handle, ELPA_AUTOTUNE_FAST, ELPA_AUTOTUNE_DOMAIN_REAL); autotune_handle = elpa_autotune_setup(handle, ELPA_AUTOTUNE_FAST, ELPA_AUTOTUNE_DOMAIN_REAL);
/* mimic 10 scf steps */ /* mimic 20 scf steps */
for (i=0; i < 20; i++) { for (i=0; i < 20; i++) {
...@@ -256,12 +231,23 @@ int main(int argc, char** argv) { ...@@ -256,12 +231,23 @@ int main(int argc, char** argv) {
assert_elpa_ok(error); assert_elpa_ok(error);
/* check the results */ /* check the results */
#ifdef DOUBLE_PRECISION_REAL #ifdef TEST_REAL
#ifdef TEST_DOUBLE
status = check_correctness_evp_numeric_residuals_real_double_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid); status = check_correctness_evp_numeric_residuals_real_double_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid);
memcpy(a, as, na_rows*na_cols*sizeof(double)); memcpy(a, as, na_rows*na_cols*sizeof(double));
#else #else
status = check_correctness_evp_numeric_residuals_real_single_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid); status = check_correctness_evp_numeric_residuals_real_single_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid);
memcpy(a, as, na_rows*na_cols*sizeof(float)); memcpy(a, as, na_rows*na_cols*sizeof(float));
#endif
#else
#ifdef TEST_DOUBLE
status = check_correctness_evp_numeric_residuals_complex_double_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid);
memcpy(a, as, na_rows*na_cols*sizeof(complex double));
#else
status = check_correctness_evp_numeric_residuals_complex_single_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid);
memcpy(a, as, na_rows*na_cols*sizeof(complex float));
#endif
#endif #endif
if (status !=0){ if (status !=0){
...@@ -296,7 +282,6 @@ int main(int argc, char** argv) { ...@@ -296,7 +282,6 @@ int main(int argc, char** argv) {
} }
} }
free(sc_desc);
free(a); free(a);
free(z); free(z);
free(as); free(as);
...@@ -305,5 +290,6 @@ int main(int argc, char** argv) { ...@@ -305,5 +290,6 @@ int main(int argc, char** argv) {
#ifdef WITH_MPI #ifdef WITH_MPI
MPI_Finalize(); MPI_Finalize();
#endif #endif
return 0;
return !!status;
} }
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