Line data Source code
1 : /*
2 : * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Martin Rupp
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 :
34 : #include "registry/registry.h"
35 :
36 : #include "lib_algebra/cpu_algebra_types.h"
37 : #include "suffix_tag.h"
38 :
39 : #include <boost/mpl/if.hpp>
40 : #include <boost/mpl/list.hpp>
41 : #include <boost/mpl/empty.hpp>
42 : #include <boost/mpl/front.hpp>
43 : #include <boost/mpl/pop_front.hpp>
44 :
45 : #include "boost/mpl/size.hpp"
46 :
47 : #include "common/util/end_boost_list.h"
48 :
49 : #ifndef UTIL_ALGEBRA_DEPENDENT_H
50 : #define UTIL_ALGEBRA_DEPENDENT_H
51 :
52 :
53 :
54 : namespace ug{
55 : namespace bridge{
56 :
57 : /// \addtogroup bridge
58 : /// \{
59 :
60 : ////////////////////////////////////////////////////////////////////////////////
61 : // Default Algebra List
62 : ////////////////////////////////////////////////////////////////////////////////
63 :
64 : typedef boost::mpl::list<
65 : #ifdef UG_GPU
66 : GPUAlgebra,
67 : #endif
68 :
69 : #ifdef UG_CPU_1
70 : CPUAlgebra,
71 : #endif
72 :
73 : #ifdef UG_CPU_2
74 : CPUBlockAlgebra<2>,
75 : #endif
76 :
77 : #ifdef UG_CPU_3
78 : CPUBlockAlgebra<3>,
79 : #endif
80 :
81 : #ifdef UG_CPU_4
82 : CPUBlockAlgebra<4>,
83 : #endif
84 :
85 : #ifdef UG_CPU_5
86 : CPUBlockAlgebra<5>,
87 : #endif
88 :
89 : #ifdef UG_CPU_6
90 : CPUBlockAlgebra<6>,
91 : #endif
92 :
93 : #ifdef UG_CPU_VAR
94 : CPUVariableBlockAlgebra,
95 : #endif
96 :
97 : end_boost_list // see common/util/end_boost_list.h
98 : > CompileAlgebraList;
99 :
100 :
101 : static const size_t NUM_ALGEBRA_TYPES = boost::mpl::size<CompileAlgebraList>::type::value - 1;
102 :
103 :
104 : struct AlgebraTypeIDProvider
105 : {
106 : public:
107 0 : static AlgebraTypeIDProvider& instance()
108 : {
109 0 : static AlgebraTypeIDProvider instance;
110 0 : return instance;
111 : }
112 :
113 : // helper structs for storage of algebra type indices
114 : struct AlgebraIDBase
115 : {
116 : // needed - otherwise compiler will assume AlgebraIDBase is not polymorphic
117 : virtual ~AlgebraIDBase() {};
118 : };
119 :
120 : template <typename TAlgebra>
121 0 : struct AlgebraID : public AlgebraIDBase {};
122 :
123 : template <typename TAlgebra>
124 : void reg()
125 : {
126 0 : m_aid[n++] = (new AlgebraID<TAlgebra>());
127 : }
128 :
129 : template <typename TAlgebra>
130 0 : size_t id()
131 : {
132 : // maybe this can be done faster
133 : // however, unless number of algebra types grows significantly,
134 : // this should be fine
135 0 : for (size_t i = 0; i < NUM_ALGEBRA_TYPES; ++i)
136 : {
137 0 : AlgebraID<TAlgebra>* p_aid = dynamic_cast<AlgebraID<TAlgebra>*>(m_aid[i]);
138 0 : if (p_aid) return i;
139 : }
140 0 : UG_THROW("Cannot provide Algebra type index. Algebra type unknown.");
141 : return 0;
142 : }
143 :
144 : private:
145 : // helper struct for filling storage of indices via boost::mpl::list
146 : template <typename List = CompileAlgebraList>
147 : struct RegisterAlgebraIndices
148 : {
149 : RegisterAlgebraIndices(AlgebraTypeIDProvider& atidp)
150 : {
151 : static const bool isEmpty = boost::mpl::empty<List>::value;
152 0 : (typename boost::mpl::if_c<isEmpty, RegEnd, RegNext>::type (atidp));
153 : }
154 :
155 : struct RegEnd
156 : {
157 : RegEnd(AlgebraTypeIDProvider&) {}
158 : };
159 :
160 : struct RegNext
161 : {
162 0 : RegNext(AlgebraTypeIDProvider& atidp)
163 : {
164 : typedef typename boost::mpl::front<List>::type AlgebraType;
165 : typedef typename boost::mpl::pop_front<List>::type NextList;
166 : atidp.reg<AlgebraType>();
167 : (RegisterAlgebraIndices<NextList> (atidp));
168 0 : }
169 : };
170 : };
171 :
172 : // constructor
173 : AlgebraTypeIDProvider()
174 0 : {
175 0 : n = 0;
176 : RegisterAlgebraIndices<>(*this);
177 : }
178 :
179 : // prevent copy constructor and assignment
180 : AlgebraTypeIDProvider(AlgebraTypeIDProvider const&); // do not implement
181 : void operator=(AlgebraTypeIDProvider const&); // do not implement
182 :
183 : private:
184 : // storage for algebra types (index in array corresponds to algebra type index)
185 : AlgebraIDBase* m_aid[NUM_ALGEBRA_TYPES];
186 : size_t n;
187 : };
188 :
189 :
190 : template <typename Functionality, typename List = CompileAlgebraList>
191 : struct RegisterAlgebraDependent
192 : {
193 48 : RegisterAlgebraDependent(Registry& reg, std::string grp)
194 : {
195 : static const bool isEmpty = boost::mpl::empty<List>::value;
196 48 : typename boost::mpl::if_c<isEmpty, RegEnd, RegNext>::type (reg,grp);
197 48 : }
198 :
199 : struct RegEnd{
200 : RegEnd(Registry& reg, std::string grp)
201 : {
202 : }
203 : };
204 : struct RegNext
205 : {
206 36 : RegNext(Registry& reg, std::string grp)
207 : {
208 : typedef typename boost::mpl::front<List>::type AlgebraType;
209 : typedef typename boost::mpl::pop_front<List>::type NextList;
210 72 : Functionality::template Algebra<AlgebraType>(reg,grp);
211 36 : RegisterAlgebraDependent<Functionality, NextList>(reg,grp);
212 36 : }
213 : };
214 : };
215 :
216 : // end group bridge
217 : /// \}
218 :
219 : }
220 : }
221 : #endif /* UTIL_ALGEBRA_DEPENDENT_H */
222 :
|