HILA
Loading...
Searching...
No Matches
globals.h
Go to the documentation of this file.
1#ifndef HILA_GLOBAL_H_
2#define HILA_GLOBAL_H_
3/**
4 * @file globals.h
5 * @brief Definition of global variable class
6 */
7
8namespace hila {
9/**
10 * @brief Global variable class within hila namespace
11 *
12 * @details Special wrapper for "simple" types (elementary types, simple structs etc.).
13 * Implemented on gpus automatically using `__constant__` memory. All global variables
14 * exist for the whole program lifetime.
15 *
16 * ## Variable declaration:
17 *
18 * Declaration is possible on top (file) level only, not inside functions!
19 * \code{.cpp}
20 * hila::global<type> globalvar;
21 * \endcode
22 * For example
23 * \code{.cpp}
24 * hila::global<Vector<4,Complex<double>> cvec1, cvec2;
25 * \endcode
26 *
27 * ## Variable assingment:
28 * \code{.cpp}
29 * globalvar.set(<value>);
30 * \endcode
31 *
32 * Assignment is not possible inside loops
33 * Only "full" assignment is possible, not e.g. by struct records. Value must be convertible
34 * to the type of the global
35 *
36 * ## Variable access
37 *
38 * The value of the variable is obtained with .get() -method
39 * \code{.cpp}
40 * globalvar.get();
41 * \endcode
42 * .get() returns a const reference to the variable, it does no copying
43 * Variable can be used everywhere in the source file.
44 *
45 * \code{.cpp}
46 * // at global file level
47 * struct param_t { double a,b[2]; };
48 *
49 * hila::global<param_t> params;
50 * params.set( {1,2,3} );
51 *
52 * // define some function
53 * double myfunc(double dv) {
54 * return cos( dv / params.get().a );
55 * }
56 *
57 * ...
58 * // inside main() or some other function - use helper struct to assign values
59 * param_t tmp;
60 * tmp.a = 3*M_PI;
61 * tmp.b[0] = ....
62 * tmp.b[1] = ...
63 * params.set(tmp); // do the full struct assignment to global
64 *
65 * ...
66 * Field<double> df;
67 * onsites(ALL) {
68 * df[X] = myfunc(X.x()) + params.get().b[0]/params.get().b[1];
69 * }
70 * hila::out0 << "Parameter a is " << params().a << '\n';
71 * \endcode
72 *
73 * ## Additional information
74 *
75 * "extern" and "static" can be used, if there are several source files, with the usual meaning:
76 *
77 * \code{.cpp}
78 * extern hila::global<double> a; // variable a (of identical type) is defined
79 * // in some other file
80 * static hila::global<mytype> par; // par is invisible to other files
81 * \endcode
82 *
83 * Declarations can be enclosed in namespaces:
84 * \code{.cpp}
85 * namespace myglobals {
86 * hila::global<double> a, b;
87 * }
88 * ...
89 *
90 * myglobals::a.set(3);
91 * hila::out0 << "a has value " << myglobals::a.get() << '\n';
92 * \endcode
93 *
94 * Variables cannot be initialized in declaration, because (possible) GPUs are not initialized.
95 */
96template <typename T, typename custom = void>
97class global {
98
99 static_assert(std::is_trivial<T>::value && std::is_standard_layout<T>::value,
100 "hila::global<> expects only pod-type elements (plain old data): default "
101 "constructor, copy and delete");
102
103 private:
104 T val;
105
106 // empty stub, will be specialized by hilapp (if needed)
107 void copy_to_device() const {}
108
109 public:
110 // Get the value of the variable with operator()
111
112 const T &get() const {
113 return val;
114 }
115
116 const T &operator()() const {
117 return val;
118 }
119
120 template <typename S, std::enable_if_t<hila::is_assignable<T &, S>::value, int> = 0>
121 void set(const S &rhs) {
122 assert(hila::is_initialized && "Assign to global possible only after hila::initialize()");
123
124 val = rhs;
125
126 copy_to_device();
127 }
128
129
130 // assignment is possible from compatible rhs values
131 template <typename S, std::enable_if_t<hila::is_assignable<T &, S>::value, int> = 0>
132 void operator=(const S &rhs) {
133 this->set(rhs);
134 }
135};
136} // namespace hila
137
138#endif
Global variable class within hila namespace.
Definition globals.h:97
Implement hila::swap for gauge fields.
Definition array.h:982