24#ifndef OLB_CORE_INTROSPECTION_H
25#define OLB_CORE_INTROSPECTION_H
39template<
typename T,
typename DESCRIPTOR, Platform PLATFORM>
class ConcreteBlockLattice;
41namespace introspection {
43template <
typename DYNAMICS>
48 using DESCRIPTOR =
typename DYNAMICS::descriptor_t;
52 exprLattice.
setDynamics(0,
meta::id<
typename DYNAMICS::template exchange_value_type<Expr>>{});
57 catch (std::domain_error& error) {
65template <
typename OPERATOR,
typename DESCRIPTOR>
87 catch (std::domain_error& error) {
92template <
typename DYNAMICS>
97 using DESCRIPTOR =
typename DYNAMICS::descriptor_t;
101 exprLattice.
setDynamics(0,
meta::id<
typename DYNAMICS::template exchange_value_type<Expr>>{});
103 std::size_t size = 0;
104 for (
int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
105 size += exprLattice.
get(0)[iPop].size();
109 catch (std::domain_error& error) {
117template <concepts::IntrospectableDynamics DYNAMICS>
121 using DESCRIPTOR =
typename DYNAMICS::descriptor_t;
125 exprLattice.
setDynamics(0,
meta::id<
typename DYNAMICS::template exchange_value_type<Expr>>{});
128 catch (std::domain_error& error) {
134template <
typename OPERATOR,
typename DESCRIPTOR>
154 catch (std::domain_error& error) {
160template <
typename DYNAMICS>
166template <
typename T,
typename DESCRIPTOR,
typename DYNAMICS>
173 std::set<FieldTypePromise<T,DESCRIPTOR>> preCollide;
174 lattice.
getData().forEach([&](
auto& anyFieldType) {
175 preCollide.emplace(anyFieldType.getPromise());
181 std::set<FieldTypePromise<T,DESCRIPTOR>> postCollide;
182 lattice.
getData().forEach([&](
auto& anyFieldType) {
183 postCollide.emplace(anyFieldType.getPromise());
186 std::set<FieldTypePromise<T,DESCRIPTOR>> accessed;
187 std::set_difference(postCollide.begin(), postCollide.end(),
188 preCollide.begin(), preCollide.end(),
189 std::inserter(accessed, accessed.end()));
193template <
typename T,
typename DESCRIPTOR,
typename DYNAMICS>
202 std::set<FieldTypePromise<T,DESCRIPTOR>> preCollide;
203 lattice.
getData().forEach([&](
auto& anyFieldType) {
204 preCollide.emplace(anyFieldType.getPromise());
209 std::set<FieldTypePromise<T,DESCRIPTOR>> postCollide;
210 lattice.
getData().forEach([&](
auto& anyFieldType) {
211 postCollide.emplace(anyFieldType.getPromise());
214 std::set<FieldTypePromise<T,DESCRIPTOR>> accessed;
215 std::set_difference(postCollide.begin(), postCollide.end(),
216 preCollide.begin(), preCollide.end(),
217 std::inserter(accessed, accessed.end()));
221template <
typename T,
typename DESCRIPTOR,
typename OPERATOR>
228 std::set<FieldTypePromise<T,DESCRIPTOR>> prePostProcess;
229 lattice.
getData().forEach([&](
auto& anyFieldType) {
230 prePostProcess.emplace(anyFieldType.getPromise());
243 std::set<FieldTypePromise<T,DESCRIPTOR>> postPostProcess;
244 lattice.
getData().forEach([&](
auto& anyFieldType) {
245 postPostProcess.emplace(anyFieldType.getPromise());
248 std::set<FieldTypePromise<T,DESCRIPTOR>> accessed;
249 std::set_difference(postPostProcess.begin(), postPostProcess.end(),
250 prePostProcess.begin(), prePostProcess.end(),
251 std::inserter(accessed, accessed.end()));
256template <
typename DYNAMICS>
260 using DESCRIPTOR = DYNAMICS::descriptor_t;
268 exprLattice.
setDynamics(0,
meta::id<
typename DYNAMICS::template exchange_value_type<T>>{});
270 std::size_t bandwidth = 0;
273 auto cell = exprLattice.
get(pos);
274 for (
int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
275 cell[iPop] =
"cell[" + std::to_string(iPop) +
"]";
278 bandwidth += DESCRIPTOR::q;
283 for (
auto field : accessedFields) {
284 if (
auto dim = field.dimension()) {
287 std::vector<T> initExpr;
288 for (
unsigned iD=0; iD < dim; ++iD) {
291 field.setPlaceholderExpression(cell, initExpr);
298 for (
int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
299 if (!cell[iPop].isSymbol(
"cell[" + std::to_string(iPop) +
"]")) {
306 for (
auto field : accessedFields) {
307 if (
auto dim = field.dimension()) {
308 auto postExpr = field.getPlaceholderExpression(cell);
309 for (
unsigned iD=0; iD < dim; ++iD) {
310 if (!postExpr[iD].isSymbol(
"cell["
312 +
"][" + std::to_string(iD) +
"]")) {
322 catch (std::domain_error& error) {
330 std::regex removeBaseTypeAndDescriptorRe(
"(float|double|Expr),\\s?descriptors::D[23]Q[0-9]+<([^<>]*|<([^<>]*|<[^<>]*>)*>)*>,?\\s?");
331 std::regex lineBreakRe(
"((dynamics|collision|forcing|equilibria)::[a-zA-Z]+|momenta::Tuple<)");
335 std::regex_replace(std::back_inserter(stage0),
336 name.begin(), name.end(), removeBaseTypeAndDescriptorRe,
338 std::regex_replace(std::back_inserter(stage1),
339 stage0.begin(), stage0.end(), lineBreakRe,
void defineDynamics(LatticeR< DESCRIPTOR::d > latticeR, DynamicsPromise< T, DESCRIPTOR > &&promise)
Assign promised DYNAMICS to latticeR.
void setStatisticsEnabled(bool state)
void setIntrospectability(bool state)
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
Implementation of BlockLattice on a concrete PLATFORM.
void collide() override
Apply collision step of non-overlap interior.
void postProcess(std::type_index stage) override
Execute post processors of stage.
void addPostProcessor(std::type_index stage, LatticeR< DESCRIPTOR::d > latticeR, PostProcessorPromise< T, DESCRIPTOR > &&promise) override
Schedule post processor for application to latticeR in stage.
void setDynamics(CellID iCell, DynamicsPromise< T, DESCRIPTOR > &&promise) override
Set dynamics at iCell to promised dynamics.
ConcreteData< T, DESCRIPTOR, PLATFORM > & getData()
Basic value-substitute enabling extraction of expression trees for code generation.
static void reset()
Resets FLOP counter.
static std::size_t count()
Return accumulated FLOPs.
std::string remove_array_from_name(const std::string &arg)
Unwrap FIELD type from FieldArray.
std::optional< std::size_t > getArithmeticOperationCount()
std::optional< std::size_t > getMemoryBandwidthOfCollision()
Returns estimate of number of scalar reads and writes for DYNAMICS::collide.
std::optional< std::size_t > getComplexity()
std::set< FieldTypePromise< T, DESCRIPTOR > > getFieldsAccessedByCollision()
std::string getSimplifiedDynamicsName(std::string name)
Return reduced and reasonable newline-separated version of given full dynamics name.
std::set< FieldTypePromise< T, DESCRIPTOR > > getFieldsAccessedByOperator()
std::set< FieldTypePromise< T, DESCRIPTOR > > getFieldsAccessedByDynamics()
Top level namespace for all of OpenLB.
@ PerBlock
Per-block application, i.e. OPERATOR::apply is passed a ConcreteBlockLattice.
LB initialisation routine – header file.
Seperate step only used for extracting expression tree.