mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-03 21:44:33 +00:00 
			
		
		
		
	Options to use mersenne twister OR ranlux48 via --enable-rng flag at configure time.
Can save and restore RNG state via new (serial) I/O routines in a NERSC header style file. Store a Parallel (one per site) and a single serial RNG file.
This commit is contained in:
		
							
								
								
									
										40
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@@ -749,6 +749,7 @@ enable_openmp
 | 
				
			|||||||
enable_simd
 | 
					enable_simd
 | 
				
			||||||
enable_precision
 | 
					enable_precision
 | 
				
			||||||
enable_comms
 | 
					enable_comms
 | 
				
			||||||
 | 
					enable_rng
 | 
				
			||||||
enable_chroma
 | 
					enable_chroma
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
      ac_precious_vars='build_alias
 | 
					      ac_precious_vars='build_alias
 | 
				
			||||||
@@ -1395,6 +1396,8 @@ Optional Features:
 | 
				
			|||||||
  --enable-precision=single|double
 | 
					  --enable-precision=single|double
 | 
				
			||||||
                          Select default word size of Real
 | 
					                          Select default word size of Real
 | 
				
			||||||
  --enable-comms=none|mpi Select communications
 | 
					  --enable-comms=none|mpi Select communications
 | 
				
			||||||
 | 
					  --enable-rng=ranlux48|mt19937
 | 
				
			||||||
 | 
					                          Select Random Number Generator to be used
 | 
				
			||||||
  --enable-chroma         Expect chroma compiled under c++11
 | 
					  --enable-chroma         Expect chroma compiled under c++11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Some influential environment variables:
 | 
					Some influential environment variables:
 | 
				
			||||||
@@ -6387,6 +6390,10 @@ done
 | 
				
			|||||||
#Please install or provide the correct path to your installation
 | 
					#Please install or provide the correct path to your installation
 | 
				
			||||||
#Info at: http://www.mpfr.org/)])
 | 
					#Info at: http://www.mpfr.org/)])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# SIMD instructions selection
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Check whether --enable-simd was given.
 | 
					# Check whether --enable-simd was given.
 | 
				
			||||||
if test "${enable_simd+set}" = set; then :
 | 
					if test "${enable_simd+set}" = set; then :
 | 
				
			||||||
  enableval=$enable_simd; \
 | 
					  enableval=$enable_simd; \
 | 
				
			||||||
@@ -6519,6 +6526,10 @@ $as_echo "#define GRID_DEFAULT_PRECISION_DOUBLE 1" >>confdefs.h
 | 
				
			|||||||
     ;;
 | 
					     ;;
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Comms selection
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Check whether --enable-comms was given.
 | 
					# Check whether --enable-comms was given.
 | 
				
			||||||
if test "${enable_comms+set}" = set; then :
 | 
					if test "${enable_comms+set}" = set; then :
 | 
				
			||||||
  enableval=$enable_comms; ac_COMMS=${enable_comms}
 | 
					  enableval=$enable_comms; ac_COMMS=${enable_comms}
 | 
				
			||||||
@@ -6562,6 +6573,35 @@ else
 | 
				
			|||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# RNG selection
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Check whether --enable-rng was given.
 | 
				
			||||||
 | 
					if test "${enable_rng+set}" = set; then :
 | 
				
			||||||
 | 
					  enableval=$enable_rng; \
 | 
				
			||||||
 | 
						ac_RNG=${enable_rng}
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  ac_RNG=ranlux48
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case ${ac_RNG} in
 | 
				
			||||||
 | 
					     ranlux48)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$as_echo "#define RNG_RANLUX 1" >>confdefs.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     ;;
 | 
				
			||||||
 | 
					     mt19937)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$as_echo "#define RNG_MT19937 1" >>confdefs.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     ;;
 | 
				
			||||||
 | 
					     *)
 | 
				
			||||||
 | 
					     as_fn_error $? "${ac_RNG} unsupported --enable-rng option" "$LINENO" 5;
 | 
				
			||||||
 | 
					     ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Chroma regression tests
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
# Check whether --enable-chroma was given.
 | 
					# Check whether --enable-chroma was given.
 | 
				
			||||||
if test "${enable_chroma+set}" = set; then :
 | 
					if test "${enable_chroma+set}" = set; then :
 | 
				
			||||||
  enableval=$enable_chroma; ac_CHROMA=yes
 | 
					  enableval=$enable_chroma; ac_CHROMA=yes
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								configure.ac
									
									
									
									
									
								
							@@ -66,6 +66,10 @@ AC_CHECK_FUNCS([gettimeofday])
 | 
				
			|||||||
#Please install or provide the correct path to your installation
 | 
					#Please install or provide the correct path to your installation
 | 
				
			||||||
#Info at: http://www.mpfr.org/)])
 | 
					#Info at: http://www.mpfr.org/)])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# SIMD instructions selection
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AC_ARG_ENABLE([simd],[AC_HELP_STRING([--enable-simd=SSE4|AVX|AVXFMA4|AVX2|AVX512|IMCI],\
 | 
					AC_ARG_ENABLE([simd],[AC_HELP_STRING([--enable-simd=SSE4|AVX|AVXFMA4|AVX2|AVX512|IMCI],\
 | 
				
			||||||
	[Select instructions to be SSE4.0, AVX 1.0, AVX 2.0+FMA, AVX 512, IMCI])],\
 | 
						[Select instructions to be SSE4.0, AVX 1.0, AVX 2.0+FMA, AVX 512, IMCI])],\
 | 
				
			||||||
	[ac_SIMD=${enable_simd}],[ac_SIMD=AVX2])
 | 
						[ac_SIMD=${enable_simd}],[ac_SIMD=AVX2])
 | 
				
			||||||
@@ -160,6 +164,10 @@ case ${ac_PRECISION} in
 | 
				
			|||||||
     ;;
 | 
					     ;;
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Comms selection
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AC_ARG_ENABLE([comms],[AC_HELP_STRING([--enable-comms=none|mpi],[Select communications])],[ac_COMMS=${enable_comms}],[ac_COMMS=none])
 | 
					AC_ARG_ENABLE([comms],[AC_HELP_STRING([--enable-comms=none|mpi],[Select communications])],[ac_COMMS=${enable_comms}],[ac_COMMS=none])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case ${ac_COMMS} in
 | 
					case ${ac_COMMS} in
 | 
				
			||||||
@@ -179,6 +187,26 @@ esac
 | 
				
			|||||||
AM_CONDITIONAL(BUILD_COMMS_MPI,[ test "X${ac_COMMS}X" == "XmpiX" ])
 | 
					AM_CONDITIONAL(BUILD_COMMS_MPI,[ test "X${ac_COMMS}X" == "XmpiX" ])
 | 
				
			||||||
AM_CONDITIONAL(BUILD_COMMS_NONE,[ test "X${ac_COMMS}X" == "XnoneX" ])
 | 
					AM_CONDITIONAL(BUILD_COMMS_NONE,[ test "X${ac_COMMS}X" == "XnoneX" ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# RNG selection
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937],\
 | 
				
			||||||
 | 
						[Select Random Number Generator to be used])],\
 | 
				
			||||||
 | 
						[ac_RNG=${enable_rng}],[ac_RNG=ranlux48])
 | 
				
			||||||
 | 
					case ${ac_RNG} in
 | 
				
			||||||
 | 
					     ranlux48)
 | 
				
			||||||
 | 
					     AC_DEFINE([RNG_RANLUX],[1],[RNG_RANLUX] )
 | 
				
			||||||
 | 
					     ;;
 | 
				
			||||||
 | 
					     mt19937)
 | 
				
			||||||
 | 
					     AC_DEFINE([RNG_MT19937],[1],[RNG_MT19937] )
 | 
				
			||||||
 | 
					     ;;
 | 
				
			||||||
 | 
					     *)
 | 
				
			||||||
 | 
					     AC_MSG_ERROR([${ac_RNG} unsupported --enable-rng option]); 
 | 
				
			||||||
 | 
					     ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Chroma regression tests
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
AC_ARG_ENABLE([chroma],[AC_HELP_STRING([--enable-chroma],[Expect chroma compiled under c++11 ])],ac_CHROMA=yes,ac_CHROMA=no)
 | 
					AC_ARG_ENABLE([chroma],[AC_HELP_STRING([--enable-chroma],[Expect chroma compiled under c++11 ])],ac_CHROMA=yes,ac_CHROMA=no)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case ${ac_CHROMA} in
 | 
					case ${ac_CHROMA} in
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,6 +143,12 @@
 | 
				
			|||||||
/* Define to the version of this package. */
 | 
					/* Define to the version of this package. */
 | 
				
			||||||
#undef PACKAGE_VERSION
 | 
					#undef PACKAGE_VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RNG_MT19937 */
 | 
				
			||||||
 | 
					#undef RNG_MT19937
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RNG_RANLUX */
 | 
				
			||||||
 | 
					#undef RNG_RANLUX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SSE4 Intrinsics */
 | 
					/* SSE4 Intrinsics */
 | 
				
			||||||
#undef SSE4
 | 
					#undef SSE4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,11 +81,39 @@ namespace Grid {
 | 
				
			|||||||
    int _seeded;
 | 
					    int _seeded;
 | 
				
			||||||
    // One generator per site.
 | 
					    // One generator per site.
 | 
				
			||||||
    // Uniform and Gaussian distributions from these generators.
 | 
					    // Uniform and Gaussian distributions from these generators.
 | 
				
			||||||
    std::vector<std::ranlux48>             _generators;
 | 
					#ifdef RNG_RANLUX
 | 
				
			||||||
 | 
					    typedef uint64_t      RngStateType;
 | 
				
			||||||
 | 
					    typedef std::ranlux48 RngEngine;
 | 
				
			||||||
 | 
					    static const int RngStateCount = 15;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    typedef std::mt19937 RngEngine;
 | 
				
			||||||
 | 
					    typedef uint32_t     RngStateType;
 | 
				
			||||||
 | 
					    static const int     RngStateCount = std::mt19937::state_size;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    std::vector<RngEngine>             _generators;
 | 
				
			||||||
    std::uniform_real_distribution<double> _uniform;
 | 
					    std::uniform_real_distribution<double> _uniform;
 | 
				
			||||||
    std::normal_distribution<double>       _gaussian;
 | 
					    std::normal_distribution<double>       _gaussian;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void GetState(std::vector<RngStateType> & saved,int gen) {
 | 
				
			||||||
 | 
					      saved.resize(RngStateCount);
 | 
				
			||||||
 | 
					      std::stringstream ss;
 | 
				
			||||||
 | 
					      //      std::cout << _generators[gen]<<std::endl;
 | 
				
			||||||
 | 
					      ss<<_generators[gen];
 | 
				
			||||||
 | 
					      ss.seekg(0,ss.beg);
 | 
				
			||||||
 | 
					      for(int i=0;i<RngStateCount;i++){
 | 
				
			||||||
 | 
						ss>>saved[i];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    void SetState(std::vector<RngStateType> & saved,int gen){
 | 
				
			||||||
 | 
					      assert(saved.size()==RngStateCount);
 | 
				
			||||||
 | 
					      std::stringstream ss;
 | 
				
			||||||
 | 
					      for(int i=0;i<RngStateCount;i++){
 | 
				
			||||||
 | 
						ss<< saved[i]<<" ";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      ss.seekg(0,ss.beg);
 | 
				
			||||||
 | 
					      ss>>_generators[gen];
 | 
				
			||||||
 | 
					      //      std::cout << _generators[gen]<<std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  class GridSerialRNG : public GridRNGbase {
 | 
					  class GridSerialRNG : public GridRNGbase {
 | 
				
			||||||
@@ -98,7 +126,7 @@ namespace Grid {
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      typename source::result_type init = src();
 | 
					      typename source::result_type init = src();
 | 
				
			||||||
      CartesianCommunicator::BroadcastWorld(0,(void *)&init,sizeof(init));
 | 
					      CartesianCommunicator::BroadcastWorld(0,(void *)&init,sizeof(init));
 | 
				
			||||||
      _generators[0] = std::ranlux48(init);
 | 
					      _generators[0] = RngEngine(init);
 | 
				
			||||||
      _seeded=1;
 | 
					      _seeded=1;
 | 
				
			||||||
    }    
 | 
					    }    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -185,8 +213,6 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  class GridParallelRNG : public GridRNGbase {
 | 
					  class GridParallelRNG : public GridRNGbase {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    // One generator per site.
 | 
					 | 
				
			||||||
    std::vector<std::ranlux48>             _generators;
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Uniform and Gaussian distributions from these generators.
 | 
					    // Uniform and Gaussian distributions from these generators.
 | 
				
			||||||
    std::uniform_real_distribution<double> _uniform;
 | 
					    std::uniform_real_distribution<double> _uniform;
 | 
				
			||||||
@@ -220,7 +246,7 @@ namespace Grid {
 | 
				
			|||||||
      int gsites = _grid->_gsites;
 | 
					      int gsites = _grid->_gsites;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      typename source::result_type init = src();
 | 
					      typename source::result_type init = src();
 | 
				
			||||||
      std::ranlux48 pseeder(init);
 | 
					      RngEngine pseeder(init);
 | 
				
			||||||
      std::uniform_int_distribution<uint64_t> ui;
 | 
					      std::uniform_int_distribution<uint64_t> ui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for(int gidx=0;gidx<gsites;gidx++){
 | 
					      for(int gidx=0;gidx<gsites;gidx++){
 | 
				
			||||||
@@ -241,7 +267,7 @@ namespace Grid {
 | 
				
			|||||||
	if( rank == _grid->ThisRank() ){
 | 
						if( rank == _grid->ThisRank() ){
 | 
				
			||||||
	  fixedSeed ssrc(site_seeds);
 | 
						  fixedSeed ssrc(site_seeds);
 | 
				
			||||||
	  typename source::result_type sinit = ssrc();
 | 
						  typename source::result_type sinit = ssrc();
 | 
				
			||||||
	  _generators[l_idx] = std::ranlux48(sinit);
 | 
						  _generators[l_idx] = RngEngine(sinit);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      _seeded=1;
 | 
					      _seeded=1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -232,6 +232,110 @@ class BinaryIO {
 | 
				
			|||||||
    return csum;
 | 
					    return csum;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static inline uint32_t writeRNGSerial(GridSerialRNG &serial,GridParallelRNG ¶llel,std::string file,int offset)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    typedef typename GridSerialRNG::RngStateType RngStateType;
 | 
				
			||||||
 | 
					    const int RngStateCount = GridSerialRNG::RngStateCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GridBase *grid = parallel._grid;
 | 
				
			||||||
 | 
					    int gsites = grid->_gsites;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    // Serialise through node zero
 | 
				
			||||||
 | 
					    //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    std::cout<< GridLogMessage<< "Serial RNG write I/O "<< file<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::ofstream fout;
 | 
				
			||||||
 | 
					    if ( grid->IsBoss() ) {
 | 
				
			||||||
 | 
					      fout.open(file,std::ios::binary|std::ios::out|std::ios::in);
 | 
				
			||||||
 | 
					      fout.seekp(offset);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    uint32_t csum=0;
 | 
				
			||||||
 | 
					    std::vector<RngStateType> saved(RngStateCount);
 | 
				
			||||||
 | 
					    int bytes = sizeof(RngStateType)*saved.size();
 | 
				
			||||||
 | 
					    std::vector<int> gcoor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int gidx=0;gidx<gsites;gidx++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int rank,o_idx,i_idx;
 | 
				
			||||||
 | 
					      grid->GlobalIndexToGlobalCoor(gidx,gcoor);
 | 
				
			||||||
 | 
					      grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor);
 | 
				
			||||||
 | 
					      int l_idx=parallel.generator_idx(o_idx,i_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if( rank == grid->ThisRank() ){
 | 
				
			||||||
 | 
						//	std::cout << "rank" << rank<<" Getting state for index "<<l_idx<<std::endl;
 | 
				
			||||||
 | 
						parallel.GetState(saved,l_idx);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      grid->Broadcast(rank,(void *)&saved[0],bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if ( grid->IsBoss() ) {
 | 
				
			||||||
 | 
						Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
				
			||||||
 | 
						fout.write((char *)&saved[0],bytes);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( grid->IsBoss() ) {
 | 
				
			||||||
 | 
					      serial.GetState(saved,0);
 | 
				
			||||||
 | 
					      Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
				
			||||||
 | 
					      fout.write((char *)&saved[0],bytes);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return csum;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static inline uint32_t readRNGSerial(GridSerialRNG &serial,GridParallelRNG ¶llel,std::string file,int offset)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    typedef typename GridSerialRNG::RngStateType RngStateType;
 | 
				
			||||||
 | 
					    const int RngStateCount = GridSerialRNG::RngStateCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GridBase *grid = parallel._grid;
 | 
				
			||||||
 | 
					    int gsites = grid->_gsites;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    // Serialise through node zero
 | 
				
			||||||
 | 
					    //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    std::cout<< GridLogMessage<< "Serial RNG read I/O "<< file<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::ifstream fin(file,std::ios::binary|std::ios::in);
 | 
				
			||||||
 | 
					    fin.seekg(offset);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    uint32_t csum=0;
 | 
				
			||||||
 | 
					    std::vector<RngStateType> saved(RngStateCount);
 | 
				
			||||||
 | 
					    int bytes = sizeof(RngStateType)*saved.size();
 | 
				
			||||||
 | 
					    std::vector<int> gcoor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int gidx=0;gidx<gsites;gidx++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int rank,o_idx,i_idx;
 | 
				
			||||||
 | 
					      grid->GlobalIndexToGlobalCoor(gidx,gcoor);
 | 
				
			||||||
 | 
					      grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor);
 | 
				
			||||||
 | 
					      int l_idx=parallel.generator_idx(o_idx,i_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if ( grid->IsBoss() ) {
 | 
				
			||||||
 | 
						fin.read((char *)&saved[0],bytes);
 | 
				
			||||||
 | 
						Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      grid->Broadcast(0,(void *)&saved[0],bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if( rank == grid->ThisRank() ){
 | 
				
			||||||
 | 
						parallel.SetState(saved,l_idx);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( grid->IsBoss() ) {
 | 
				
			||||||
 | 
					      fin.read((char *)&saved[0],bytes);
 | 
				
			||||||
 | 
					      serial.SetState(saved,0);
 | 
				
			||||||
 | 
					      Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return csum;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<class vobj,class fobj,class munger>
 | 
					  template<class vobj,class fobj,class munger>
 | 
				
			||||||
  static inline uint32_t readObjectParallel(Lattice<vobj> &Umu,std::string file,munger munge,int offset,const std::string &format)
 | 
					  static inline uint32_t readObjectParallel(Lattice<vobj> &Umu,std::string file,munger munge,int offset,const std::string &format)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@@ -284,6 +388,7 @@ class BinaryIO {
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      uint32_t tmp = IOnode;
 | 
					      uint32_t tmp = IOnode;
 | 
				
			||||||
      grid->GlobalSum(tmp);
 | 
					      grid->GlobalSum(tmp);
 | 
				
			||||||
 | 
					      std::cout<< std::dec ;
 | 
				
			||||||
      std::cout<< GridLogMessage<< "Parallel read I/O to "<< file << " with " <<tmp<< " IOnodes for subslice ";
 | 
					      std::cout<< GridLogMessage<< "Parallel read I/O to "<< file << " with " <<tmp<< " IOnodes for subslice ";
 | 
				
			||||||
      for(int d=0;d<grid->_ndimension;d++){
 | 
					      for(int d=0;d<grid->_ndimension;d++){
 | 
				
			||||||
	std::cout<< range[d];
 | 
						std::cout<< range[d];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -181,9 +181,12 @@ inline void NerscMachineCharacteristics(NerscField &header)
 | 
				
			|||||||
class NerscIO : public BinaryIO { 
 | 
					class NerscIO : public BinaryIO { 
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static inline void truncate(std::string file){
 | 
				
			||||||
 | 
					    std::ofstream fout(file,std::ios::out);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  static inline unsigned int writeHeader(NerscField &field,std::string file)
 | 
					  static inline unsigned int writeHeader(NerscField &field,std::string file)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    std::ofstream fout(file,std::ios::out);
 | 
					    std::ofstream fout(file,std::ios::out|std::ios::in);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    fout.seekp(0,std::ios::beg);
 | 
					    fout.seekp(0,std::ios::beg);
 | 
				
			||||||
    fout << "BEGIN_HEADER"      << std::endl;
 | 
					    fout << "BEGIN_HEADER"      << std::endl;
 | 
				
			||||||
@@ -201,8 +204,7 @@ class NerscIO : public BinaryIO {
 | 
				
			|||||||
      fout << "BOUNDARY_"<<i+1<<" = " << field.boundary[i] << std::endl;
 | 
					      fout << "BOUNDARY_"<<i+1<<" = " << field.boundary[i] << std::endl;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fout << "CHECKSUM = "<< std::hex << std::setw(10) << field.checksum << std::endl;
 | 
					    fout << "CHECKSUM = "<< std::hex << std::setw(10) << field.checksum << std::dec<<std::endl;
 | 
				
			||||||
    fout << std::dec;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fout << "ENSEMBLE_ID = "     << field.ensemble_id      << std::endl;
 | 
					    fout << "ENSEMBLE_ID = "     << field.ensemble_id      << std::endl;
 | 
				
			||||||
    fout << "ENSEMBLE_LABEL = "  << field.ensemble_label   << std::endl;
 | 
					    fout << "ENSEMBLE_LABEL = "  << field.ensemble_label   << std::endl;
 | 
				
			||||||
@@ -287,9 +289,6 @@ static inline int readHeader(std::string file,GridBase *grid,  NerscField &field
 | 
				
			|||||||
  return field.data_start;
 | 
					  return field.data_start;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
// Now the meat: the object readers
 | 
					// Now the meat: the object readers
 | 
				
			||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@@ -377,6 +376,8 @@ static inline void writeConfiguration(Lattice<iLorentzColourMatrix<vsimd> > &Umu
 | 
				
			|||||||
  uint32_t csum;
 | 
					  uint32_t csum;
 | 
				
			||||||
  int offset;
 | 
					  int offset;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  truncate(file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( two_row ) { 
 | 
					  if ( two_row ) { 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    header.floating_point = std::string("IEEE64BIG");
 | 
					    header.floating_point = std::string("IEEE64BIG");
 | 
				
			||||||
@@ -392,8 +393,7 @@ static inline void writeConfiguration(Lattice<iLorentzColourMatrix<vsimd> > &Umu
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    std::cout << GridLogMessage << " TESTING PARALLEL WRITE offsets " << offset1 << " "<< offset << std::endl;
 | 
					    std::cout << GridLogMessage << " TESTING PARALLEL WRITE offsets " << offset1 << " "<< offset << std::endl;
 | 
				
			||||||
    std::cout << GridLogMessage <<std::hex<< " TESTING PARALLEL WRITE csums   " << csum1 << " "<< csum << std::endl;
 | 
					    std::cout << GridLogMessage << " TESTING PARALLEL WRITE csums   " << csum1 << " "<<std::hex<< csum << std::dec<< std::endl;
 | 
				
			||||||
    std::cout << std::dec;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(offset1==offset);  
 | 
					    assert(offset1==offset);  
 | 
				
			||||||
    assert(csum1==csum);  
 | 
					    assert(csum1==csum);  
 | 
				
			||||||
@@ -410,7 +410,81 @@ static inline void writeConfiguration(Lattice<iLorentzColourMatrix<vsimd> > &Umu
 | 
				
			|||||||
  std::cout<<GridLogMessage <<"Written NERSC Configuration "<<file<< " checksum "<<std::hex<<csum<< std::dec<<" plaq "<< header.plaquette <<std::endl;
 | 
					  std::cout<<GridLogMessage <<"Written NERSC Configuration "<<file<< " checksum "<<std::hex<<csum<< std::dec<<" plaq "<< header.plaquette <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////
 | 
				
			||||||
 | 
					    // RNG state
 | 
				
			||||||
 | 
					    ///////////////////////////////
 | 
				
			||||||
 | 
					static inline void writeRNGState(GridSerialRNG &serial,GridParallelRNG ¶llel,std::string file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  typedef typename GridParallelRNG::RngStateType RngStateType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Following should become arguments
 | 
				
			||||||
 | 
					  NerscField header;
 | 
				
			||||||
 | 
					  header.sequence_number = 1;
 | 
				
			||||||
 | 
					  header.ensemble_id     = "UKQCD";
 | 
				
			||||||
 | 
					  header.ensemble_label  = "DWF";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridBase *grid = parallel._grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NerscGrid(grid,header);
 | 
				
			||||||
 | 
					  header.link_trace=0.0;
 | 
				
			||||||
 | 
					  header.plaquette=0.0;
 | 
				
			||||||
 | 
					  NerscMachineCharacteristics(header);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint32_t csum;
 | 
				
			||||||
 | 
					  int offset;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					#ifdef RNG_RANLUX
 | 
				
			||||||
 | 
					    header.floating_point = std::string("UINT64");
 | 
				
			||||||
 | 
					    header.data_type      = std::string("RANLUX48");
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    header.floating_point = std::string("UINT32");
 | 
				
			||||||
 | 
					    header.data_type      = std::string("MT19937");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  truncate(file);
 | 
				
			||||||
 | 
					  offset = writeHeader(header,file);
 | 
				
			||||||
 | 
					  csum=BinaryIO::writeRNGSerial(serial,parallel,file,offset);
 | 
				
			||||||
 | 
					  header.checksum = csum;
 | 
				
			||||||
 | 
					  offset = writeHeader(header,file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage <<"Written NERSC RNG STATE "<<file<< " checksum "<<std::hex<<csum<<std::dec<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					static inline void readRNGState(GridSerialRNG &serial,GridParallelRNG & parallel,NerscField& header,std::string file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  typedef typename GridParallelRNG::RngStateType RngStateType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridBase *grid = parallel._grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int offset = readHeader(file,grid,header);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NerscField clone(header);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::string format(header.floating_point);
 | 
				
			||||||
 | 
					  std::string data_type(header.data_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RNG_RANLUX
 | 
				
			||||||
 | 
					  assert(format == std::string("UINT64"));
 | 
				
			||||||
 | 
					  assert(data_type == std::string("RANLUX48"));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  assert(format == std::string("UINT32"));
 | 
				
			||||||
 | 
					  assert(data_type == std::string("MT19937"));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // depending on datatype, set up munger;
 | 
				
			||||||
 | 
					  // munger is a function of <floating point, Real, data_type>
 | 
				
			||||||
 | 
					  uint32_t csum=BinaryIO::readRNGSerial(serial,parallel,file,offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(csum == header.checksum );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage <<"Read NERSC RNG file "<<file<< " format "<< data_type <<std::endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					}}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,19 +56,25 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
    GridRedBlackCartesian rbFine(latt_size,simd_layout,mpi_layout);
 | 
					    GridRedBlackCartesian rbFine(latt_size,simd_layout,mpi_layout);
 | 
				
			||||||
    GridParallelRNG       FineRNG(&Fine);
 | 
					    GridParallelRNG       FineRNG(&Fine);
 | 
				
			||||||
    GridSerialRNG       SerialRNG;
 | 
					    GridSerialRNG       SerialRNG;
 | 
				
			||||||
 | 
					    GridSerialRNG       SerialRNG1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FineRNG.SeedRandomDevice();
 | 
					    FineRNG.SeedRandomDevice();
 | 
				
			||||||
 | 
					    SerialRNG.SeedRandomDevice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::cout <<"SerialRNG" << SerialRNG._generators[0] <<std::endl;
 | 
					    std::cout <<"SerialRNG" << SerialRNG._generators[0] <<std::endl;
 | 
				
			||||||
    std::stringstream output(std::stringstream::out|std::stringstream::binary);
 | 
					 | 
				
			||||||
    output <<SerialRNG._generators[0]<<std::endl;
 | 
					 | 
				
			||||||
    std::cout << output.str();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {
 | 
					    std::vector<typename GridSerialRNG::RngStateType> saved;
 | 
				
			||||||
      std::ofstream of("rngstate",std::ios::out|std::ios::binary);
 | 
					    SerialRNG.GetState(saved,0);
 | 
				
			||||||
      of << SerialRNG._generators[0];
 | 
					    SerialRNG1.SetState(saved,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RealD dd1,dd2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << "Testing RNG state save restore"<<std::endl;
 | 
				
			||||||
 | 
					    for(int i=0;i<10;i++){
 | 
				
			||||||
 | 
					      random(SerialRNG,dd1);
 | 
				
			||||||
 | 
					      random(SerialRNG1,dd2);
 | 
				
			||||||
 | 
					      std::cout << "i "<<i<<" "<<dd1<< " " <<dd2<<std::endl;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    LatticeColourMatrix Foo(&Fine);
 | 
					    LatticeColourMatrix Foo(&Fine);
 | 
				
			||||||
    LatticeColourMatrix Bar(&Fine);
 | 
					    LatticeColourMatrix Bar(&Fine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,30 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  GridCartesian     Fine(latt_size,simd_layout,mpi_layout);
 | 
					  GridCartesian     Fine(latt_size,simd_layout,mpi_layout);
 | 
				
			||||||
  GridCartesian     Coarse(clatt_size,simd_layout,mpi_layout);
 | 
					  GridCartesian     Coarse(clatt_size,simd_layout,mpi_layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridParallelRNG   pRNGa(&Fine);
 | 
				
			||||||
 | 
					  GridParallelRNG   pRNGb(&Fine);
 | 
				
			||||||
 | 
					  GridSerialRNG     sRNGa;
 | 
				
			||||||
 | 
					  GridSerialRNG     sRNGb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pRNGa.SeedRandomDevice();
 | 
				
			||||||
 | 
					  sRNGa.SeedRandomDevice();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::string rfile("./ckpoint_rng.4000");
 | 
				
			||||||
 | 
					  NerscIO::writeRNGState(sRNGa,pRNGa,rfile);
 | 
				
			||||||
 | 
					  NerscField rngheader;
 | 
				
			||||||
 | 
					  NerscIO::readRNGState (sRNGb,pRNGb,rngheader,rfile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeComplex tmpa(&Fine); random(pRNGa,tmpa);
 | 
				
			||||||
 | 
					  LatticeComplex tmpb(&Fine); random(pRNGb,tmpb);
 | 
				
			||||||
 | 
					  tmpa = tmpa - tmpb;
 | 
				
			||||||
 | 
					  std::cout << " difference between restored randoms and orig "<<norm2( tmpa ) <<" / "<< norm2(tmpb)<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ComplexD a,b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  random(sRNGa,a);
 | 
				
			||||||
 | 
					  random(sRNGb,b);
 | 
				
			||||||
 | 
					  std::cout << " serial RNG numbers "<<a<<" "<<b<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LatticeGaugeField Umu(&Fine);
 | 
					  LatticeGaugeField Umu(&Fine);
 | 
				
			||||||
  LatticeGaugeField Umu_diff(&Fine);
 | 
					  LatticeGaugeField Umu_diff(&Fine);
 | 
				
			||||||
  LatticeGaugeField Umu_saved(&Fine);
 | 
					  LatticeGaugeField Umu_saved(&Fine);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user