File: NavigationSpecializer.h

package info (click to toggle)
vecgeom 1.2.8%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 24,016 kB
  • sloc: cpp: 88,803; ansic: 6,888; python: 1,035; sh: 582; sql: 538; makefile: 23
file content (254 lines) | stat: -rw-r--r-- 11,900 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
 * NavigationSpecializer.h
 *
 *  Created on: 11.09.2015
 *      Author: swenzel
 */

#ifndef VECGEOM_SERVICES_NAVIGATIONSPECIALIZER_H_
#define VECGEOM_SERVICES_NAVIGATIONSPECIALIZER_H_

#include "VecGeom/navigation/NavigationState.h"
#include <string>
#include <iosfwd>
#include <map>
#include <sstream>
#include <list>
#include <vector>
#include "VecGeom/base/Global.h"

namespace vecgeom {
inline namespace VECGEOM_IMPL_NAMESPACE {
class LogicalVolume;
class NavStatePool;

// A class providing convenient access to tabulated coordinate transformation data
// could make it a private subclass if we don't want to expose it
class TabulatedTransData {
public:
  TabulatedTransData(std::string name, bool soa = true)
      : fName(name), fTransCoefficients(3), fRotCoefficients(9), fSOA(soa), fTransVariableName(3), fRotVariableName(9),
        fVecTransVariableName(3), fVecRotVariableName(9)
  {
    for (size_t i = 0; i < 9; ++i)
      fRotCoefficients[i].resize(0);
    for (size_t i = 0; i < 3; ++i)
      fTransCoefficients[i].resize(0);
  }
  void Analyse();
  void SetRotCoef(size_t i, size_t index, double x) { fRotCoefficients[i][index] = x; }
  void SetTransCoef(size_t i, size_t index, double x) { fTransCoefficients[i][index] = x; }
  void ReserveRot(size_t index, size_t size)
  {
    fRotCoefficients[index].reserve(size);
    fRotCoefficients[index].resize(size, 0.);
  }
  void ReserveTrans(size_t index, size_t size)
  {
    fTransCoefficients[index].reserve(size);
    fTransCoefficients[index].resize(size, 0.);
  }
  void Print() const; // some debugging output

  void EmitTableDefinition(std::string /*classname*/, std::ostream &) const;
  void EmitTableDeclaration(std::ostream &);

  void EmitScalarGlobalTransformationCode(std::ostream &) const;
  void EmitScalarDeltaTransformationCode(std::ostream &) const;

  void EmitVectorGlobalTransformationCode(std::ostream &) const;

  //  void IsSOA() const {return fSOA;}

  void PrintStaticSOADefinition() const;
  void PrintStaticAOSDefinition(/*might need a name*/) const;

  bool RotIsZero(size_t index) const;     //
  bool RotIsOne(size_t index) const;      //
  bool RotIsMinusOne(size_t index) const; //
  bool TransIsZero(size_t index) const;   //
  bool RotIsConstant(size_t index) const;
  bool TransIsConstant(size_t index) const;

private:
  std::string fName; // a name addressing this transformation ( example: gGlobalTransf )
  std::vector<std::vector<double>> fTransCoefficients; // the raw numbers for transformations
  std::vector<std::vector<double>> fRotCoefficients;   // the raw number for rotations
  bool fSOA = false;                                   // emit SOA tables ( or AOS )

  // the following variables are initialized to true because its easier to convert them to false
  // during the analysis
  // they make only sense after a call to Analyse()
  bool fRotalwayszero[9]          = {true, true, true, true, true, true, true, true, true};
  bool fRotalwaysone[9]           = {true, true, true, true, true, true, true, true, true};
  bool fRotalwaysminusone[9]      = {true, true, true, true, true, true, true, true, true};
  bool fRotalwaysminusoneorone[9] = {true, true, true, true, true, true, true, true, true};
  bool fTransalwayszero[3]        = {true, true, true};
  bool fTransIsConstant[3]        = {true, true, true}; // indicates if this component is a constant for all entries
  bool fRotIsConstant[9]          = {true, true, true, true, true,
                            true, true, true, true}; // indicates if this component is a constant for all entries
  std::vector<std::string> fTransVariableName; // variable names which are set according to SOA/AOS choices etc
  std::vector<std::string> fRotVariableName;
  std::vector<std::string> fVecTransVariableName; // variable names which are set according to SOA/AOS choices etc
  std::vector<std::string> fVecRotVariableName;
};

/* A class which can produce (per logical volume) specialized C++ code
 * for navigation routines.
 *
 * A service which can transform generic navigation algorithms into specialized kernels
 * based on static analysis of the logical volume and the geometry hierarchy.
 * Example: It can convert a SimpleSafetyEstimator to FOOSafetyEstimator for a logical volume called
 *          FOO.
 * The output of the service are C++ files which can be (re- or just-in-time) compiled.
 *
 * Things which this service can (might) do are:
 *
 * a) avoid virtual functions in navigation methods
 * b) precompute all possible global transformations of a logical volume and cache them in the specialized kernels
 * c) provide a fast hard-coded lookup table to map NavigationStates objects to cached global transformations
 * d) vectorize loops over daughter volumes of the same type
 * e) loop splitting of daughter lists
 * f) realizing that daughtervolumes use the same rotations and do this transformation only once
 * g) ....
 *
 * The present class is an R&D prototype. Nothing is fix here!!
 *
 * 09/2015: idea and first implementation ( sandro.wenzel@cern.ch )
 */
class NavigationSpecializer {

public:
  // is this class a singleton ??
  NavigationSpecializer(std::string instatefile, std::string outstatefile)
      : fLogicalVolumeName(), fClassName(), fInStateFileName(instatefile), fOutStateFileName(outstatefile),
        fLogicalVolume(nullptr), fGeometryDepth(0), fIndexMap(), fStaticArraysInitStream(), fStaticArraysDefinitions(),
        fTransformationCode(), fVectorTransformVariables(),
        fVectorTransformationCode(), // to collect the many-path/SIMD transformation statements
        fTransformVariables(),       // stores the list of relevant transformation variables
        fUnrollLoops(false),         // whether to manually unroll all loops
        fUseBaseNavigator(false),    // whether to use the DaughterDetection from another navigator ( makes sense when
                                     // combined with voxel techniques )
        fBaseNavigator(), fGlobalTransData("globalTrans", true) // init 12 vectors : 3 for translation, 9 for rotation
        {};

  // produce a specialized SafetyEstimator class for a given logical volume
  // currently this is only done using the SimpleEstimator base algorithm
  // TODO: we could template here on some base algorithm in general and we could
  // specialize voxel algorithms and the like
  void ProduceSpecializedNavigator(LogicalVolume const *, std::ostream &);

private:
  typedef std::map<size_t, std::map<NavigationState::Value_t, size_t>> PathLevelIndexMap_t;

  // analysis functions
  void AnalyseLogicalVolume();
  void AnalysePaths(std::list<NavigationState *> const & /* inpaths */);
  void AnalyseTargetPaths(NavStatePool const &, NavStatePool const &);
  // void GeneratePathClassifierCode(std::list<std::pair<int, std::set<NavigationState::Value_t>>> const
  // &pathclassification,
  //                                 PathLevelIndexMap_t &map);

  void AddToIndexMap(size_t, NavigationState::Value_t);
  size_t PathToIndex(NavigationState const *);
  void AnalyseIndexCorrelations(std::list<NavigationState *> const &);

  // writer functions
  void DumpDisclaimer(std::ostream &);
  void DumpIncludeFiles(std::ostream &);
  void DumpNamespaceOpening(std::ostream &);
  void DumpNamespaceClosing(std::ostream &);
  void DumpStaticConstExprData(std::ostream &);
  void DumpStaticConstExprVariableDefinitions(std::ostream &);
  void DumpStaticInstanceFunction(std::ostream &);
  void DumpConstructor(std::ostream &) const;
  void DumpClassOpening(std::ostream &);
  void DumpClassDefinitions(std::ostream &);
  void DumpClassDeclarations(std::ostream &);
  void DumpClassClosing(std::ostream &);
  void DumpPathToIndexFunction(std::ostream &);
  void DumpVectorTransformationFunction(std::ostream &);
  void DumpLocalSafetyFunction(std::ostream &);
  void DumpPrivateClassDefinitions(std::ostream &);
  void DumpPublicClassDefinitions(std::ostream &);
  void DumpLocalSafetyFunctionDeclaration(std::ostream &);

  void DumpRelocateMethod(std::ostream &) const;

  void DumpLocalVectorSafetyFunctionDeclaration(std::ostream &);

  void DumpLocalVectorSafetyFunctionDeclarationPerSIMDVector(std::ostream &);

  void DumpSafetyFunctionDeclaration(std::ostream &);
  void DumpVectorSafetyFunctionDeclaration(std::ostream &);
  void DumpTransformationAsserts(std::ostream &);

  void DumpLocalHitDetectionFunction(std::ostream &) const;

  // they produce static component functions which are plugged into the generic implementation of VNavigatorHelper
  void DumpFoo(std::ostream &) const;
  void DumpStaticTreatGlobalToLocalTransformationFunction(std::ostream &) const;
  // the vector version of for the coordinate transformation
  void DumpStaticTreatGlobalToLocalTransformationsFunction(std::ostream &) const;

  void DumpStaticTreatDistanceToMotherFunction(std::ostream &) const;
  void DumpStaticPrepareOutstateFunction(std::ostream &) const;

public:
  void EnableLoopUnrolling() { fUnrollLoops = true; }
  void DisableLoopUnrolling() { fUnrollLoops = false; }

  void SetBaseNavigator(std::string const &nav)
  {
    fUseBaseNavigator = true;
    fBaseNavigator    = nav;
  }

  typedef std::pair<int, std::string> FinalDepthShapeType_t;

private:
  // private state
  std::string fLogicalVolumeName;
  std::string fClassName;
  std::string fInStateFileName;
  std::string fOutStateFileName;
  LogicalVolume const *fLogicalVolume;
  unsigned int fGeometryDepth; // the depth of instances of fLogicalVolumes in the geometry hierarchy ( must be unique )
  unsigned int fNumberOfPossiblePaths;
  PathLevelIndexMap_t fIndexMap;                // in memory structure; used to map a NavigationState object to an index
  std::stringstream fStaticArraysInitStream;    // stream to collect code for the static arrays
  std::stringstream fStaticArraysDefinitions;   // stream to collect code for constexpr static array definitions
  std::stringstream fTransformationCode;        // to collect the specialized transformation statements for points
  std::stringstream fTransformationCodeDir;     // to collect the specialized transformation statements for dirs
  std::stringstream fVectorTransformVariables;  // to collect relevant vector variables for transformation
  std::stringstream fVectorTransformationCode;  // to collect the many-path/SIMD transformation statements
  std::vector<std::string> fTransformVariables; // stores the list of relevant transformation variables
  bool fUnrollLoops;                            // whether to manually unroll all loops
  bool fUseBaseNavigator; // whether to use the DaughterDetection from another navigator ( makes sense when combined
                          // with voxel techniques )
  std::string fBaseNavigator;

  std::stringstream fDeltaTransformationCode;
  std::vector<std::string>
      fTransitionTransformVariables; // stores the vector of relevant variables for the relocation transformations

  //
  std::vector<std::string> fTransitionStrings;
  std::vector<FinalDepthShapeType_t> fTransitionTargetTypes; // the vector of possible relocation target types
  std::vector<size_t> fTransitionOrder; // the vector keeping the order of indices of relocation transitions (
                                        // as stored in fTransitionTargetsTypes )
  std::vector<unsigned int>
      fTargetVolIds; // the ids of the target volumes ( to quickly fetch a representative volume pointer )

  std::vector<std::vector<int>>
      fPathxTargetToMatrixTable; // an in - memory table to fetch the correct transition matrix index
  std::stringstream fPathxTargetToMatrixTableStringStream; // string represenation of the above

  // caching the transformation numbers --> to build a SOA/AOS form
  TabulatedTransData fGlobalTransData;

}; // end class
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom

#endif /* VECGEOM_SERVICES_NAVIGATIONSPECIALIZER_H_ */