// ---------------------------------------------------------------------- #include "CLHEP/Random/Randomize.h" #include "CLHEP/Random/NonRandomEngine.h" #include "CLHEP/Random/defs.h" #include #include #include #define CLEAN_OUTPUT #ifdef CLEAN_OUTPUT std::ofstream output("testSaveEngineStatus.cout"); #else std::ostream & output = std::cout; #endif // Normally on for routine validation: #define TEST_ORIGINAL_SAVE // Normally off for routine validation: #ifdef TURNOFF #define TEST_MISSING_FILES #define CREATE_OLD_SAVES #define VERIFY_OLD_SAVES #endif #define VERBOSER #define VERBOSER2 using namespace CLHEP; double remembered_r2; double remembered_r1005; double remembered_r1006; double remembered_r1007; // Absolutely Safe Equals Without Registers Screwing Us Up bool equals01(const std::vector &ab) { return ab[1]==ab[0]; } bool equals(double a, double b) { std::vector ab(2); ab[0]=a; ab[1]=b; return (equals01(ab)); } // ------------------- The following should all FAIL ------------ int saveStepX() { double r = RandGauss::shoot(); output << "r(1) = " << r << std::endl; HepRandom::saveEngineStatus(); r = RandGauss::shoot(); output << "r(2) = " << r << std::endl; remembered_r2 = r; r = RandGauss::shoot(); output << "r(3) = " << r << std::endl; for (int i=0; i < 1001; i++) { r = RandGauss::shoot(); } r = RandGauss::shoot(); remembered_r1005 = r; output << "r1005= " << r << std::endl; r = RandGauss::shoot(); return 0; } int restoreStepX() { HepRandom::restoreEngineStatus(); double r = RandGauss::shoot(); output << "restored r(2) = " << r << std::endl; if ( ! equals(r,remembered_r2) ) { output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n"; } r = RandGauss::shoot(); output << "restored r(3) = " << r << std::endl; for (int i=0; i < 1001; i++) { r = RandGauss::shoot(); } r = RandGauss::shoot(); output << "restored r1005= " << r << std::endl; if ( !equals(r,remembered_r1005) ) { output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n"; } return 0; } int BsaveStepX() { int r = RandFlat::shootBit(); output << "r(1) = " << r << std::endl; HepRandom::saveEngineStatus(); r = RandFlat::shootBit(); output << "r(2) = " << r << std::endl; remembered_r2 = r; r = RandFlat::shootBit(); output << "r(3) = " << r << std::endl; double d; for (int i=0; i < 1001; i++) { d = RandFlat::shoot(); if (d > 1) output << "This line inserted so clever compilers don't warn about not using d\n"; } r = RandFlat::shootBit(); remembered_r1005 = r; output << "r1005= " << r << std::endl; r = RandFlat::shootBit(); return 0; } int BrestoreStepX() { HepRandom::restoreEngineStatus(); int r = RandFlat::shootBit(); output << "restored r(2) = " << r << std::endl; if ( r != remembered_r2 ) { output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n"; } r = RandFlat::shootBit(); output << "restored r(3) = " << r << std::endl; for (int i=0; i < 1001; i++) { r = RandFlat::shootBit(); } r = RandFlat::shootBit(); output << "restored r1005= " << r << std::endl; if ( r != remembered_r1005 ) { output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n"; } return 0; } // ------------------- The following should all WORK ------------ int saveStep() { int stat=0; double r = RandGauss::shoot(); output << "r(1) = " << r << std::endl; RandGauss::saveEngineStatus(); r = RandGauss::shoot(); output << "r(2) = " << r << std::endl; remembered_r2 = r; r = RandGauss::shoot(); output << "r(3) = " << r << std::endl; for (int i=0; i < 1001; i++) { r = RandGauss::shoot(); } r = RandGauss::shoot(); remembered_r1005 = r; output << "r1005= " << r << std::endl; r = RandGauss::shoot(); return stat; } int restoreStep() { int stat=0; RandGauss::restoreEngineStatus(); double r = RandGauss::shoot(); output << "restored r(2) = " << r << std::endl; if ( !equals(r,remembered_r2) ) { std::cout << "restored r(2) = " << r << std::endl; std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #ifdef CLEAN_OUTPUT output << "restored r(2) = " << r << std::endl; output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #endif stat += 1; } r = RandGauss::shoot(); output << "restored r(3) = " << r << std::endl; for (int i=0; i < 1001; i++) { r = RandGauss::shoot(); } r = RandGauss::shoot(); output << "restored r1005= " << r << std::endl; if ( !equals(r,remembered_r1005) ) { std::cout << "restored r1005= " << r << std::endl; std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #ifdef CLEAN_OUTPUT output << "restored r1005= " << r << std::endl; output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #endif stat += 2; } return stat; } int BsaveStep() { int stat=0; int r = RandFlat::shootBit(); output << "r(1) = " << r << std::endl; RandFlat::saveEngineStatus(); r = RandFlat::shootBit(); output << "r(2) = " << r << std::endl; remembered_r2 = r; r = RandFlat::shootBit(); output << "r(3) = " << r << std::endl; for (int i=0; i < 1001; i++) { r = RandFlat::shootBit(); } r = RandFlat::shootBit(); remembered_r1005 = r; output << "r1005 = " << r << std::endl; r = RandFlat::shootBit(); remembered_r1006 = r; output << "r1006 = " << r << std::endl; r = RandFlat::shootBit(); remembered_r1007 = r; output << "r1007 = " << r << std::endl; r = RandFlat::shootBit(); return stat; } int BrestoreStep() { int stat=0; RandFlat::restoreEngineStatus(); int r = RandFlat::shootBit(); output << "restored r(2) = " << r << std::endl; if ( r != remembered_r2 ) { stat += 4; std::cout << "restored r(2) = " << r << std::endl; std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #ifdef CLEAN_OUTPUT output << "restored r(2) = " << r << std::endl; output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #endif } r = RandFlat::shootBit(); output << "restored r(3) = " << r << std::endl; for (int i=0; i < 1001; i++) { r = RandFlat::shootBit(); } r = RandFlat::shootBit(); output << "restored r1005= " << r << std::endl; if ( r != remembered_r1005 ) { stat += 8; std::cout << "restored r1005= " << r << std::endl; std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #ifdef CLEAN_OUTPUT output << "restored r1005= " << r << std::endl; output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #endif } r = RandFlat::shootBit(); output << "restored r1006= " << r << std::endl; if ( r != remembered_r1006 ) { stat += 16; std::cout << "restored r1006= " << r << std::endl; std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #ifdef CLEAN_OUTPUT output << "restored r1006= " << r << std::endl; output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #endif } r = RandFlat::shootBit(); output << "restored r1007= " << r << std::endl; if ( r != remembered_r1007 ) { stat += 32; std::cout << "restored r1007= " << r << std::endl; std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #ifdef CLEAN_OUTPUT output << "restored r1007= " << r << std::endl; output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n"; #endif } return stat; } // --- The following should work, by failing in an expected way ------- template int fileNotThere() { int stat = 0; HepRandomEngine * old = D::getTheEngine(); E e(123); output << "File-not-found test restoring "< int fileNotThereEngine() { int stat = 0; stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); stat |= fileNotThere (); return stat; } int missingFile() { int stat = 0; stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); stat |= fileNotThereEngine(); return stat; } // -- The following was used to capture old-form engine states (sans name) -- template int saveEngine(const char* filename) { int stat = 0; HepRandomEngine * old = D::getTheEngine(); E e(123); D::setTheEngine(&e); double r=0; for (int i=0; i<3; i++) r += D::shoot(); D::saveEngineStatus(filename); if (r == -99999999.1) stat = 999; // This prevents clever compilers from // deducing that r is never needed D::setTheEngine(old); // If we don't do this, then the static engine shared // by every shoot() method reamins e -- which is about // to go out of scope and be destructed! return stat; } // -- The following checks on static engine restores, from old and new forms -- template int checkSaveEngine(const char* filename) { int stat = 0; HepRandomEngine * old = D::getTheEngine(); // Generate save with current format (default file name is fine) E e(123); D::setTheEngine(&e); double r=0; for (int i=0; i<3; i++) r += D::shoot(); D::saveEngineStatus(); // Figure out what the key variate value should be double keyValue = D::shoot(); // Restore state based on old file, and check for proper value D::restoreEngineStatus(filename); if (!equals(D::shoot(), keyValue)) { std::cout << "???? Value mismatch from file " << filename << "\n"; #ifdef CLEAN_OUTPUT output << "???? Value mismatch from file " << filename << "\n"; #endif stat |= 64; } // Restore state based on that save, and check for proper value D::restoreEngineStatus(); if (!equals(D::shoot(),keyValue)) { std::cout << "???? Value mismatch from new-format file \n"; #ifdef CLEAN_OUTPUT output << "???? Value mismatch from new-format file \n"; #endif stat |= 128; } D::setTheEngine(old); return stat; } // --------------------------------------------- // --------------------------------------------- // --------------------------------------------- int main() { int stat = 0; #ifdef TEST_ORIGINAL_SAVE output << "=====================================\n"; output << " Part I \n"; output << "Original tests of static save/restore\n"; output << "=====================================\n\n"; output << "Using old method or HepRandom::saveEngineStatus:\n"; output << "All these tests should have a chance of failure.\n"; output << RandGauss:: getTheEngine()->name(); output << RandGaussQ::getTheEngine()->name(); stat |= saveStepX(); stat |= restoreStepX(); stat |= BsaveStepX(); stat |= BrestoreStepX(); output << "Using the class-specific RandGauss::saveEngineStatus:\n"; output << "All these tests should work properly.\n"; stat |= saveStep(); stat |= restoreStep(); stat |= BsaveStep(); stat |= BrestoreStep(); #endif #ifdef TEST_MISSING_FILES output << "\n=======================================\n"; output << " Part Ia \n"; output << "Test of behavior when a file is missing \n"; output << "=======================================\n\n"; output << "Testing restoreEngineStatus with missing file:\n"; output << "Expect a number of messages!\n"; stat |= missingFile(); #endif #ifdef CREATE_OLD_SAVES stat |= saveEngine("DRand48Engine.oldsav"); stat |= saveEngine("DualRand.oldsav"); stat |= saveEngine("Hurd160Engine.oldsav"); stat |= saveEngine("Hurd288Engine.oldsav"); stat |= saveEngine("HepJamesRandom.oldsav"); stat |= saveEngine("MTwistEngine.oldsav"); stat |= saveEngine("RanecuEngine.oldsav"); stat |= saveEngine("Ranlux64Engine.oldsav"); stat |= saveEngine("RanluxEngine.oldsav"); stat |= saveEngine("RanshiEngine.oldsav"); stat |= saveEngine("TripleRand.oldsav"); #endif #ifdef VERIFY_OLD_SAVES output << "\n==============================================\n"; output << " Part Ib \n"; output << " Verification that changes wont invalidate \n"; output << "invalidate engine saves from previous versions \n"; output << "==============================================\n\n"; stat |= checkSaveEngine("DRand48Engine.oldsav"); stat |= checkSaveEngine("DualRand.oldsav"); stat |= checkSaveEngine("Hurd160Engine.oldsav"); stat |= checkSaveEngine("Hurd288Engine.oldsav"); stat |= checkSaveEngine("HepJamesRandom.oldsav"); stat |= checkSaveEngine("MTwistEngine.oldsav"); stat |= checkSaveEngine("Ranlux64Engine.oldsav"); stat |= checkSaveEngine("RanluxEngine.oldsav"); stat |= checkSaveEngine("RanshiEngine.oldsav"); stat |= checkSaveEngine("TripleRand.oldsav"); stat |= checkSaveEngine("RanecuEngine.oldsav"); #endif output << "\n=============================================\n\n"; if (stat != 0) { std::cout << "One or more problems detected: stat = " << stat << "\n"; output << "One or more problems detected: stat = " << stat << "\n"; } else { output << "testSaveEngineStatus passed with no problems detected.\n"; } if (stat == 0) return 0; if (stat > 0) return -(stat|1); return stat|1; }