Branch data Line data Source code
1 : : // ***************************************************************************** 2 : : /*! 3 : : \file src/RNGTest/TestU01Suite.hpp 4 : : \copyright 2012-2015 J. Bakosi, 5 : : 2016-2018 Los Alamos National Security, LLC., 6 : : 2019-2021 Triad National Security, LLC. 7 : : All rights reserved. See the LICENSE file for details. 8 : : \brief TestU01 random number generator test suite 9 : : \details This file declares the TestU01 random number generator test suite, 10 : : which facilitates subjecting any supported random number generator to a 11 : : battery of statistical tests interfaced to the TestU01 library. 12 : : */ 13 : : // ***************************************************************************** 14 : : #ifndef TestU01Suite_h 15 : : #define TestU01Suite_h 16 : : 17 : : #include <vector> 18 : : #include <map> 19 : : #include <utility> 20 : : #include <functional> 21 : : #include <iosfwd> 22 : : #include <cstddef> 23 : : #include <type_traits> 24 : : 25 : : #include "Tags.hpp" 26 : : #include "Types.hpp" 27 : : #include "Exception.hpp" 28 : : #include "StatTest.hpp" 29 : : #include "RNGTestPrint.hpp" 30 : : #include "RNGTest/InputDeck/InputDeck.hpp" 31 : : #include "RNGTest/Options/Battery.hpp" 32 : : #include "NoWarning/testu01suite.decl.h" 33 : : 34 : : extern "C" { 35 : : #include <swrite.h> 36 : : #include <gdef.h> 37 : : } 38 : : 39 : : namespace rngtest { 40 : : 41 : : extern ctr::InputDeck g_inputdeck; 42 : : extern ctr::InputDeck g_inputdeck_defaults; 43 : : 44 : : //! \brief TestU01 random number generator test suite used polymorphically with 45 : : //! Battery 46 : : //! \details This class is a Charm++ chare and does the asynchronous 47 : : //! distribution, run, and evaluation of all statistical tests within a 48 : : //! TestU01 battery. 49 : : class TestU01Suite : public CBase_TestU01Suite { 50 : : 51 : : public: 52 : : using Proxy = CProxy_TestU01Suite; 53 : : 54 : : //! \brief Configure all instances of the TestU01 library running on a node 55 : : //! \details The Charm++ runtime system executes the nodeInit routine below 56 : : //! exactly once on every logical node early on in the Charm++ init 57 : : //! sequence. Must be static as it is called without and object. See also: 58 : : //! Section "Initializations at Program Startup" at in the Charm++ manual 59 : : //! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. 60 : 16 : static void nodeInit() { 61 : 16 : swrite_Basic = FALSE; // want no screen output from TestU01 library 62 : 16 : } 63 : : 64 : : //! Constructor 65 : : explicit TestU01Suite( ctr::BatteryType suite ); 66 : : 67 : : //! Collect number of p-values from a test 68 : : void npval( std::size_t n ); 69 : : 70 : : //! Collect test name(s) from a test 71 : : void names( std::vector< std::string > n ); 72 : : 73 : : //! Evaluate a statistical test 74 : : void evaluate( std::vector< std::vector< std::string > > status ); 75 : : 76 : : //! Collect test run time from a test 77 : : void time( std::pair< std::string, tk::real > t ); 78 : : 79 : : private: 80 : : std::vector< std::function< StatTest() > > m_ctrs; //! Tests constructors 81 : : std::vector< StatTest > m_tests; //!< Constructed statistical tests 82 : : std::string m_name; //!< Test suite name 83 : : std::size_t m_npval; //!< Number of results from all tests 84 : : std::size_t m_ncomplete; //!< Number of completed tests 85 : : std::size_t m_ntest; //!< Number of tests info received from 86 : : std::map< std::string, std::size_t > m_nfail; //! Number of failed tests/RNG 87 : : std::map< std::string, tk::real > m_time; //!< Measured time/RNG 88 : : 89 : : //! Information bundle for a failed test 90 : : struct Failed { 91 : : std::string test; //!< Test name 92 : : std::string rng; //!< RNG tested 93 : : std::string pval; //!< Resulting p-value 94 : : //! Constructor 95 : 7 : Failed( std::string t, std::string r, std::string p ) : 96 : 7 : test( std::move(t) ), rng( std::move(r) ), pval( std::move(p) ) {} 97 : : }; 98 : : std::vector< Failed > m_failed; //!< Details of failed tests 99 : : 100 : : //! Add all statistical tests to suite, return suite name 101 : : //! \return Test suite name 102 : : template< class Suite > 103 : 4 : std::string addTests() { 104 [ + - ]: 8 : const auto rngs = g_inputdeck.get< tag::selected, tag::rng >(); 105 [ - + ][ - - ]: 4 : ErrChk( !rngs.empty(), "No RNGs selected" ); [ - - ][ - - ] 106 : : Suite suite; 107 [ + + ][ + - ]: 16 : for (const auto& r : rngs) suite.addTests( m_ctrs, r, thisProxy ); 108 [ + - ]: 8 : return suite.name(); 109 : : } 110 : : 111 : : //! Return number of statistical tests 112 : : std::size_t ntest() const; 113 : : 114 : : //! Output final assessment 115 : : void assess(); 116 : : 117 : : //! Create pretty printer specialized to RNGTest 118 : : //! \return Pretty printer 119 : 168 : RNGTestPrint printer() const { 120 : : const auto& def = 121 : 168 : g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(); 122 : 168 : auto nrestart = g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(); 123 : 336 : return RNGTestPrint( g_inputdeck.get< tag::cmd >().logname( def, nrestart ), 124 : 168 : g_inputdeck.get< tag::cmd, tag::verbose >() ? std::cout : std::clog, 125 [ + - ][ + - ]: 504 : std::ios_base::app ); 126 : : } 127 : : }; 128 : : 129 : : } // rngtest:: 130 : : 131 : : #endif // TestU01Suite_h