Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/RNGTest/StatTest.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 Random number generator statistical test
9 : : \details This file defines a generic random number generator statistical
10 : : test class. The class uses runtime polymorphism without client-side
11 : : inheritance: inheritance is confined to the internals of the class,
12 : : invisible to client-code. The class exclusively deals with ownership
13 : : enabling client-side value semantics. Credit goes to Sean Parent at Adobe:
14 : : https://github.com/sean-parent/
15 : : sean-parent.github.com/wiki/Papers-and-Presentations.
16 : : */
17 : : // *****************************************************************************
18 : : #ifndef StatTest_h
19 : : #define StatTest_h
20 : :
21 : : #include <functional>
22 : : #include <memory>
23 : :
24 : : #include "NoWarning/charm++.hpp"
25 : :
26 : : #include "Macro.hpp"
27 : : #include "Options/RNG.hpp"
28 : :
29 : : namespace rngtest {
30 : :
31 : : //! \brief Random number generator statistical test
32 : : //! \details This class uses runtime polymorphism without client-side
33 : : //! inheritance: inheritance is confined to the internals of the this class,
34 : : //! invisible to client-code. The class exclusively deals with ownership
35 : : //! enabling client-side value semantics. Credit goes to Sean Parent at Adobe:
36 : : //! https://github.com/sean-parent/sean-parent.github.com/wiki/
37 : : //! Papers-and-Presentations. For example client code that models a Battery,
38 : : //! see rngtest::TestU01.
39 : 276 : class StatTest {
40 : :
41 : : public:
42 : : //! \brief Constructor taking a function pointer to a constructor of an
43 : : //! object modeling Concept
44 : : //! \details Passing std::function allows late execution of the constructor
45 : : //! of T, i.e., at some future time, and thus usage from a factory. Note
46 : : //! that the value of the first function argument, std::function<T()>, is
47 : : //! not used here, but its constructor type, T, is used to enable the
48 : : //! compiler to deduce the model constructor type, used to create its
49 : : //! Charm proxy, defined by T::Proxy. The actual constructor of T is not
50 : : //! called here but at some future time by the Charm++ runtime system,
51 : : //! here only an asynchrounous ckNew() is called, i.e., a message (or
52 : : //! request) for a future call to T's constructor. This overload can only
53 : : //! be used for Charm++ chare objects defining typedef 'Proxy', which must
54 : : //! define the Charm++ proxy. All optional constructor arguments are
55 : : //! forwarded to ckNew() and thus to T's constructor. If it was somehow
56 : : //! possible to obtain all bound arguments' types and values from an
57 : : //! already-bound std::function, we could use those instead of having to
58 : : //! explicitly forward the model constructor arguments via this host
59 : : //! constructor.
60 : : //! \param[in] c Function pointer to a constructor of an object modeling
61 : : //! Concept
62 : : //! \param[in] args Constructor arguments
63 : : //! \see See also tk::recordCharmModel().
64 : : template< typename T, typename... CtrArgs >
65 : 120 : explicit StatTest( std::function<T()> c [[maybe_unused]], CtrArgs... args )
66 : : : self( std::make_unique< Model< typename T::Proxy > >
67 : 120 : (std::move(T::Proxy::ckNew(std::forward<CtrArgs>(args)...))) ) {
68 : : Assert( c == nullptr, "std::function argument to StatTest Charm "
69 : : "constructor must be nullptr" );
70 : 120 : }
71 : :
72 : : //! Public interface to contribute number of results/test, i.e., p-values
73 [ + - ][ - - ]: 40 : void npval() const { self->npval(); }
74 : :
75 : : //! Public interface to contribute test name(s)
76 : 40 : void names() const { self->names(); }
77 : :
78 : : //! Public interface to running a test
79 [ + - ]: 120 : void run() const { self->run(); }
80 : :
81 : : //! Public interface to contributing a test's run time measured in seconds
82 : 120 : void time() const { self->time(); }
83 : :
84 : : //! Copy assignment
85 : : StatTest& operator=( const StatTest& x )
86 : : { StatTest tmp(x); *this = std::move(tmp); return *this; }
87 : : //! Copy constructor
88 : : StatTest( const StatTest& x ) : self( x.self->copy() ) {}
89 : : //! Move assignment
90 : : StatTest& operator=( StatTest&& ) noexcept = default;
91 : : //! Move constructor
92 : : StatTest( StatTest&& ) noexcept = default;
93 : :
94 : : private:
95 : : //! Concept is a pure virtual base class specifying the requirements of
96 : : //! polymorphic objects deriving from it
97 : : struct Concept {
98 : : Concept() = default;
99 : 0 : Concept( const Concept& ) = default;
100 : : virtual ~Concept() = default;
101 : : virtual Concept* copy() const = 0;
102 : : virtual void npval() = 0;
103 : : virtual void names() = 0;
104 : : virtual void run() = 0;
105 : : virtual void time() = 0;
106 : : };
107 : :
108 : : //! Model models the Concept above by deriving from it and overriding the
109 : : //! the virtual functions required by Concept
110 : : template< typename T >
111 [ - - ][ - - ]: 0 : struct Model : Concept {
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
112 [ + - ][ + - ]: 120 : explicit Model( T x ) : data( std::move(x) ) {}
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
113 : 0 : Concept* copy() const override { return new Model( *this ); }
114 : 40 : void npval() override { data.npval(); }
115 : 40 : void names() override { data.names(); }
116 : 120 : void run() override { data.run(); }
117 : 120 : void time() override { data.time(); }
118 : : T data;
119 : : };
120 : :
121 : : std::unique_ptr< Concept > self; //!< Base pointer used polymorphically
122 : : };
123 : :
124 : : } // rngtest::
125 : :
126 : : #endif // StatTest_h
|