Skip to content

Commit

Permalink
LapH: computing eigensystem for the Laplacial Heaviside method
Browse files Browse the repository at this point in the history
  • Loading branch information
Luigi Scorzato committed Sep 10, 2011
1 parent a276ba5 commit 7052d6f
Show file tree
Hide file tree
Showing 45 changed files with 2,626 additions and 21 deletions.
218 changes: 218 additions & 0 deletions LapH_ev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/***********************************************************************
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Carsten Urbach
*
* This file is part of tmLQCD.
*
* tmLQCD is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* tmLQCD 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with tmLQCD. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************/
/*
* Program for computing the eigensystem of the Laplacian operator
* Authors Luigi Scorzato, Marco Cristoforetti
*
*
*******************************************************************************/

#define MAIN_PROGRAM

#ifdef HAVE_CONFIG_H
# include "config.h"
#else
#error "no config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string.h>
#if (defined BGL && !defined BGP)
# include <rts.h>
#endif
#ifdef MPI
# include <mpi.h>
#endif
#include "global.h"
#include <io/params.h>
#include <io/gauge.h>
#include "su3.h"
#include "ranlxd.h"
#include "geometry_eo.h"
#include "read_input.h"
#include "start.h"
#include "xchange.h"
#include "init_gauge_field.h"
#include "init_geometry_indices.h"
#include "mpi_init.h"
#include "solver/eigenvalues_Jacobi.h"
#include "init_jacobi_field.h"

int main(int argc,char *argv[])
{
int tslice,j,k;
char conf_filename[50];

#ifdef MPI
MPI_Init(&argc, &argv);
#endif

/* Read the input file */
read_input("LapH.input");

tmlqcd_mpi_init(argc, argv);

if(g_proc_id==0) {
#ifdef SSE
printf("# The code was compiled with SSE instructions\n");
#endif
#ifdef SSE2
printf("# The code was compiled with SSE2 instructions\n");
#endif
#ifdef SSE3
printf("# The code was compiled with SSE3 instructions\n");
#endif
#ifdef P4
printf("# The code was compiled for Pentium4\n");
#endif
#ifdef OPTERON
printf("# The code was compiled for AMD Opteron\n");
#endif
#ifdef _GAUGE_COPY
printf("# The code was compiled with -D_GAUGE_COPY\n");
#endif
#ifdef BGL
printf("# The code was compiled for Blue Gene/L\n");
#endif
#ifdef BGP
printf("# The code was compiled for Blue Gene/P\n");
#endif
#ifdef _USE_HALFSPINOR
printf("# The code was compiled with -D_USE_HALFSPINOR\n");
#endif
#ifdef _USE_SHMEM
printf("# the code was compiled with -D_USE_SHMEM\n");
# ifdef _PERSISTENT
printf("# the code was compiled for persistent MPI calls (halfspinor only)\n");
# endif
#endif
#ifdef MPI
# ifdef _NON_BLOCKING
printf("# the code was compiled for non-blocking MPI calls (spinor and gauge)\n");
# endif
#endif
printf("\n");
fflush(stdout);
}


#ifndef WITHLAPH
printf(" Error: WITHLAPH not defined");
exit(0);
#error " Error: WITHLAPH not defined"
#endif
#ifdef MPI
#ifndef _INDEX_INDEP_GEOM
printf(" Error: _INDEX_INDEP_GEOM not defined");
exit(0);
#error " Error: _INDEX_INDEP_GEOM not defined"
#endif
#ifndef _USE_TSPLITPAR
printf(" Error: _USE_TSPLITPAR not defined");
exit(0);
#error " Error: _USE_TSPLITPAR not defined"
#endif
#endif
#ifdef FIXEDVOLUME
printf(" Error: FIXEDVOLUME not allowed");
exit(0);
#error " Error: FIXEDVOLUME not defined"
#endif


init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 0);
init_geometry_indices(VOLUMEPLUSRAND + g_dbw2rand);

if(g_proc_id == 0) {
fprintf(stdout,"The number of processes is %d \n",g_nproc);
printf("# The lattice size is %d x %d x %d x %d\n",
(int)(T*g_nproc_t), (int)(LX*g_nproc_x), (int)(LY*g_nproc_y), (int)(g_nproc_z*LZ));
printf("# The local lattice size is %d x %d x %d x %d\n",
(int)(T), (int)(LX), (int)(LY),(int) LZ);
printf("# Computing LapH eigensystem \n");

fflush(stdout);
}

/* define the geometry */
geometry();

start_ranlux(1, 123456);

/* Read Gauge field */
sprintf(conf_filename, "%s.%.4d", gauge_input_filename, nstore);
if (g_cart_id == 0) {
printf("#\n# Trying to read gauge field from file %s in %s precision.\n",
conf_filename, (gauge_precision_read_flag == 32 ? "single" : "double"));
fflush(stdout);
}
if( (j = read_gauge_field(conf_filename)) !=0) {
fprintf(stderr, "Error %d while reading gauge field from %s\n Aborting...\n", j, conf_filename);
exit(-2);
}


if (g_cart_id == 0) {
printf("# Finished reading gauge field.\n");
fflush(stdout);
}

#ifdef MPI
/*For parallelization: exchange the gaugefield */
xchange_gauge();
#endif

/* Init Jacobi field */
init_jacobi_field(SPACEVOLUME+SPACERAND,3);

#ifdef MPI
{
/* for debugging in parallel set i_gdb = 0 */
volatile int i_gdb = 8;
char hostname[256];
gethostname(hostname, sizeof(hostname));
printf("PID %d on %s ready for attach\n", getpid(), hostname);
fflush(stdout);
if(g_cart_id == 0){
while (0 == i_gdb){
sleep(5);
}
}
}

MPI_Barrier(MPI_COMM_WORLD);
#endif

for (k=0 ; k<3 ; k++)
random_jacobi_field(g_jacobi_field[k],SPACEVOLUME);


/* Compute LapH Eigensystem */

for(tslice=0; tslice<T; tslice++){
eigenvalues_Jacobi(&no_eigenvalues,5000, eigenvalue_precision,0,tslice,nstore);
}

#ifdef MPI
MPI_Finalize();
#endif
return(0);
}
5 changes: 3 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ MODULES = read_input gamma hybrid_update observables start \
little_D block sf_gauge_monomial sf_utils sf_calc_action \
sf_get_staples sf_get_rectangle_staples sf_observables \
Dov_psi operator poly_monomial measurements pion_norm Dov_proj \
xchange_field_tslice temporalgauge spinor_fft X_psi P_M_eta
xchange_field_tslice temporalgauge spinor_fft X_psi P_M_eta \
xchange_jacobi jacobi init_jacobi_field


## the GPU modules (all .cu files in $GPUDIR)
Expand All @@ -81,7 +82,7 @@ NOOPTMOD = test/check_xchange test/check_geometry

PROGRAMS = hmc_tm benchmark invert gwc2ildg \
ildg2gwc single2double double2single reducenoise gen_sources \
check_locallity test_lemon hopping_test
check_locallity test_lemon hopping_test LapH_ev

ALLOBJ = ${MODULES} ${PROGRAMS} ${SMODULES}
SUBDIRS = ${USESUBDIRS}
Expand Down
3 changes: 3 additions & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,8 @@
/* Define if we want to use CUDA GPU */
#undef HAVE_GPU

/* Define if we want to compute the LapH eigenvectors */
#undef WITHLAPH

#endif

44 changes: 30 additions & 14 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,17 @@ else
AC_MSG_RESULT(no)
fi

AC_MSG_CHECKING(whether we want to compute the LapH eigenvalues)
AC_ARG_ENABLE(laph,
[ --enable-laph enable computation of LapH eigensystem [default=no]],
enable_laph=$enableval, enable_laph=no)
if test $enable_laph = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(WITHLAPH,1,LapH eigensystem)
else
AC_MSG_RESULT(no)
fi


AC_MSG_CHECKING(whether we want to use CUDA GPU)
AC_ARG_ENABLE(gpu,
Expand Down Expand Up @@ -676,20 +687,25 @@ AC_SUBST(GPUMPICOMPILER)


AC_MSG_CHECKING(checking consistency)
if test $enable_iig = yes && test $withpersistent = yes ; then
AC_MSG_ERROR(ERROR! indexindepgeom is not compatible with persistent communications )
fi
if test $enable_iig = yes && test $enable_shmem = yes ; then
AC_MSG_ERROR(ERROR! indexindepgeom is not compatible with shmem API )
fi
if test $enable_tsp = yes && test $enable_iig = no; then
AC_MSG_ERROR(ERROR! tsplitpar needs indexindepgeom)
fi
if test $enable_tsp = yes && test $enable_sse2 != yes ; then
AC_MSG_ERROR(ERROR! tsplitpar needs at least SSE2 )
fi
if test $enable_tsp = yes && test $enable_gaugecopy != yes ; then
AC_MSG_ERROR(ERROR! tsplitpar needs gaugecopy)
if test $enable_mpi = yes ; then
if test $enable_iig = yes && test $withpersistent = yes ; then
AC_MSG_ERROR(ERROR! indexindepgeom is not compatible with persistent communications )
fi
if test $enable_iig = yes && test $enable_shmem = yes ; then
AC_MSG_ERROR(ERROR! indexindepgeom is not compatible with shmem API )
fi
if test $enable_tsp = yes && test $enable_iig = no; then
AC_MSG_ERROR(ERROR! tsplitpar needs indexindepgeom)
fi
if test $enable_tsp = yes && test $enable_sse2 != yes ; then
AC_MSG_ERROR(ERROR! tsplitpar needs at least SSE2 )
fi
if test $enable_tsp = yes && test $enable_gaugecopy != yes ; then
AC_MSG_ERROR(ERROR! tsplitpar needs gaugecopy)
fi
if test $enable_laph = yes && test $enable_tsp != yes ; then
AC_MSG_ERROR(ERROR! laph needs tsplitpar)
fi
fi

if test ! -e lib; then
Expand Down
3 changes: 2 additions & 1 deletion fixed_volume.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
# define LZ (Zdef/N_PROC_Z)
# define L LX
# define VOLUME (T*LX*LY*LZ)
# define SPACEVOLUME (LX*LY*LZ)
# define TEOSLICE ((LX*LY*LZ)/2)

# ifdef PARALLELT
Expand All @@ -64,7 +65,7 @@
/* Note that VOLUMEPLUSRAND is in general not equal to VOLUME+RAND */
/* VOLUMEPLUSRAND rather includes the edges */
# define VOLUMEPLUSRAND (VOLUME + RAND + EDGES)

# define SPACERAND (RAND/T)
# endif

#endif
55 changes: 55 additions & 0 deletions geometry_eo.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,11 @@ int Index(const int x0, const int x1, const int x2, const int x3) {
int Index(const int x0, const int x1, const int x2, const int x3) {
int y0, y1, y2, y3, ix;

#ifdef WITHLAPH
y0 = x0;
#else
y0 = (x0 + T ) % T;
#endif
y1 = (x1 + LX) % LX;
y2 = (x2 + LY) % LY;
y3 = (x3 + LZ) % LZ;
Expand Down Expand Up @@ -890,6 +894,35 @@ void geometry(){
}
}


#ifdef WITHLAPH
tempT=T;
T=1;
tempV=VOLUME;
VOLUME=SPACEVOLUME;
tempR=RAND;
RAND=SPACERAND;
x0=0;
for (x1 = 0; x1 < (LX); x1++){
for (x2 = 0; x2 < (LY); x2++){
for (x3 = 0; x3 < (LZ); x3++){
ix=Index(x0, x1, x2, x3);
g_iup3d[ix][0] = -1;
g_idn3d[ix][0] = -1;
g_iup3d[ix][1] = Index(x0, x1+1, x2, x3);
g_idn3d[ix][1] = Index(x0, x1-1, x2, x3);
g_iup3d[ix][2] = Index(x0, x1, x2+1, x3);
g_idn3d[ix][2] = Index(x0, x1, x2-1, x3);
g_iup3d[ix][3] = Index(x0, x1, x2, x3+1);
g_idn3d[ix][3] = Index(x0, x1, x2, x3-1);
}
}
}
T=tempT;
VOLUME=tempV;
RAND=tempR;
#endif

i_even=0;
i_odd=0;
/*For the spinor fields we need only till VOLUME+RAND */
Expand Down Expand Up @@ -1099,6 +1132,28 @@ void geometry(){
gI_m1_0_0_m2=Index(-1,0,0,-2);
#endif /* _INDEX_INDEP_GEOM */

#ifdef WITHLAPH
tempT=T;
T=1;
tempV=VOLUME;
VOLUME=SPACEVOLUME;
tempR=RAND;
RAND=SPACERAND;
gI_0_0_0=Index(0,0,0,0);
gI_L_0_0=Index(0,LX,0,0);
gI_Lm1_0_0=Index(0,LX-1,0,0);
gI_m1_0_0=Index(0,-1,0,0);
gI_0_L_0=Index(0,0,LY,0);
gI_0_Lm1_0=Index(0,0,LY-1,0);
gI_0_m1_0=Index(0,0,-1,0);
gI_0_0_L=Index(0,0,0,LZ);
gI_0_0_Lm1=Index(0,0,0,LZ-1);
gI_0_0_m1=Index(0,0,0,-1);
T=tempT;
VOLUME=tempV;
RAND=tempR;
#endif

#if ( defined PARALLELXYZT || defined PARALLELXYZ )
check_struct_zt=0;
ix = 0;
Expand Down
Loading

0 comments on commit 7052d6f

Please sign in to comment.