-
Notifications
You must be signed in to change notification settings - Fork 3
/
HPCPatternStatistics.h
300 lines (251 loc) · 8.11 KB
/
HPCPatternStatistics.h
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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
#pragma once
#include "HPCParallelPattern.h"
#include <string>
#include "Helpers.h"
#define NUMOFDIFFSTATS 5
#define CSV_SEPARATOR_CHAR ","
#ifndef HPCPATTERNASTTREVERSAL_H
#include "HPCPatternInstrHandler.h"
#endif
/**
* Abstract class for pattern statistics.
* Statistics have to inherit from this class and implement the virtual methods.
*/
class HPCPatternStatistic
{
public:
/**
* Calculate the statistics value(s).
*/
virtual void Calculate() = 0;
/**
* Print the statistic in human-readable form to std::cout
*/
virtual void Print() = 0;
/**
* Export the statistic value(s) to a csv file.
*/
virtual void CSVExport(std::string FileName) = 0;
};
/**
* A statistic class that calculates the cyclomatic complexity as defined by McCabe.
* We adapted this software engineering metric for our pattern use case.
* The cyclomatic complexity is calculated as C = (edges - nodes) + 2 * ConnectedComponents
* Edges are countes as follows: the connection between two PatternCodeRegion is defined as an edge.
* Function nodes are ignored.
* The number of nodes is the number of unique PatternCodeRegions.
*/
class CyclomaticComplexityStatistic : public HPCPatternStatistic
{
public:
CyclomaticComplexityStatistic();
/**
* @brief Calls CyclomaticComplexityStatistic::CountEdges(), CyclomaticComplexityStatistic::CountNodes() and CyclomaticComplexityStatistic::CountConnectedComponents() to calculate the Cyclomatic Complexity Statistic C = (Edges - Nodes) + 2 * ConnectedComponents
*/
void Calculate();
/**
* @brief Prints the number of edges, nodes, connected components and the resulting cyclomatic complexity.
*/
void Print();
/**
* @brief Function for csv output of the form "cycl. complexity, edges, nodes, connectedcomponents".
*
* @param FileName The file name of the desired output file.
**/
void CSVExport(std::string FileName);
private:
/**
* @brief Set a node to visited for calculation of the number of edges in the pattern tree.
*
* @param Node The node that is set visited.
**/
void SetNodeVisited(PatternGraphNode* Node);
/**
* @brief Enquire if the node is visited (see CyclomaticComplexityStatistic::SetNodeVisited()).
*
* @param Node Node that is checked.
*
* @return True if visited, false else.
**/
bool IsNodeVisited(PatternGraphNode* Node);
std::vector<PatternGraphNode*> VisitedNodes;
/**
* @brief Calls CyclomaticComplexityStatistic::CountEdges(PatternGraphNode*) with the entries of all functions in the FunctionDeclDatabase.
*
* @return The number of edges in the pattern tree.
**/
int CountEdges();
/**
* @brief Counts the number of edges in the pattern tree (Disregarding function calls) recursively.
*
* @param Current The node with which the counting starts.
*
* @return The number of edges.
**/
int CountEdges(PatternGraphNode* Root);
/**
* @brief Counts the number of nodes in the pattern tree (i.e. only PatternCodeRegions) by requesting from the HPCPatternDatabase.
*
* @return The number of nodes.
**/
int CountNodes();
/**
* @brief Connected components are marked by call of GraphAlgorithms::MarkConnectedComponents().
* Then, the number of connected components is calculated.
*
* @return The number of connected components.
**/
int CountConnectedComponents();
void MarkConnectedComponent(PatternGraphNode * Node, int ComponentID);
int Nodes, Edges, ConnectedComponents = 0;
int CyclomaticComplexity = 0;
};
/**
* A simple statistic class that prints the lines of code for each pattern.
*/
class LinesOfCodeStatistic : public HPCPatternStatistic
{
public:
void Calculate();
/**
* @brief Prints statistics about lines of code for each HPCParallelPattern and PatternOccurrence.
*/
void Print();
/**
* @brief CSV export of the statistic. Format "Patternname, NumRegions, LOCByRegions (list), TotalLOCs".
*
* @param FileName File name of the output file.
**/
void CSVExport(std::string FileName);
};
/**
* A statistic that prints for each pattern how many occurrences there are.
*/
class SimplePatternCountStatistic : public HPCPatternStatistic
{
public:
SimplePatternCountStatistic();
/**
* @brief Dummy function.
*/
void Calculate();
/**
* @brief Prints for each pattern, how often it occurs in the code.
*/
void Print();
/**
* @brief CSV export of the static. Format "Patternname, Count".
*
* @param FileName File name of the output file.
**/
void CSVExport(std::string FileName);
};
/**
* This statistic calculates the fan-in and fan-out numbers for every pattern which occurs in the code.
* The fan-in number is calculated as the number of patterns which are a direct parent to the pattern in question.
* The fan-out number is the number of patterns which are direct children to this pattern.
*/
class FanInFanOutStatistic : public HPCPatternStatistic
{
public:
/**
* @brief Constructor for the Fan-In Fan-Out statistic.
*
* @param maxdepth The maximum recursion depth when descending in the tree.
**/
FanInFanOutStatistic(int maxdepth);
/**
* @brief Calculates the Fan-In and Fan-Out statistic for each Pattern.
* First, all children and parents for all PatternOccurrence and PatternCodeRegions are gathered.
* Then, duplicates are removed.
* The remaining patterns are counted and saved in FanInFanOutStatistic::FanInFanOutCounter objects.
*/
void Calculate();
/**
* @brief Print Fan-In and Fan-Out for all patterns previously encountered.
*/
void Print();
/**
* @brief CSV export of the results. Format "PatternName, Fan-In, Fan-Out".
*
* @param FileName File name of the output file.
**/
void CSVExport(std::string FileName);
/**
*@brief this method is used to gether the CallTreeNodes which are suitable to be used by this statistic.
**/
std::vector<PatternCodeRegion*> GetCodeRegions(HPCParallelPattern* Pattern);
private:
struct FanInFanOutCounter
{
HPCParallelPattern* Pattern;
int FanIn = 0;
int FanOut = 0;
};
void VisitFunctionCall(FunctionNode* FnEntry, int depth, int maxdepth);
void VisitPattern(PatternCodeRegion* PatternOcc, int depth, int maxdepth);
/**
* @brief Retrieve the fan-in fan-out counter for a specific pattern.
*
* @param Pattern The pattern to find.
*
* @return The counter that belongs to the pattern.
**/
FanInFanOutCounter* LookupFIFOCounter(HPCParallelPattern* Pattern);
/**
* @brief Create a fan-in fan-out counter for a pattern.
* Adds the counter to the list of counters.
*
* @param Pattern
*
* @return The counter created.
**/
FanInFanOutCounter* AddFIFOCounter(HPCParallelPattern* Pattern);
/**
* @brief Finds the parent patterns, beginning from a PatternCodeRegion.
* Saves the parent patterns in the list of PatternOccurrence passed as second parameter.
*
* @param Start Initial PatternCodeRegion from which the search is started.
* @param Parents Reference to a std::vector of PatternOccurrence* in which the encountered occurrences are saved.
* @param maxdepth Maximum depth of the recursion.
**/
void FindParentPatterns(PatternCodeRegion* Start, std::vector<PatternOccurrence*>& Parents, int maxdepth);
/**
* @brief Finds the child patterns from a starting point. See FanInFanOutStatistic::FindParentPatterns().
**/
void FindChildPatterns(PatternCodeRegion* Start, std::vector<PatternOccurrence*>& Children, int maxdepth);
int maxdepth;
std::vector<HPCParallelPattern*> Pattern;
std::vector<FanInFanOutCounter*> FIFOCounter;
};
//int HalsteadAnzOperator;
class Halstead : public HPCPatternStatistic{
public:
Halstead();
void Calculate();
void Print();
void CSVExport(std::string FileName);
void insertPattern(HPCParallelPattern* Pat);
private:
int numOfOperators;
std::vector <HPCParallelPattern*> HPatterns;
};
/*
class HalsteadMetrikPattern : public HPCPatternStatistic
{
public:
HalsteadMetrikPattern();
void Calculate();
void Print();
void CSVExport(std::string FileName);
private:
int CalculateProgrammLength();
int CalculateVolume();
int CalculateDifficulty();
int CalculateEffort();
int CalculateHalsteadTime();
int CalculateNumberOfOperands();
int CalculateNumberOfOperators();
bool IsOperand(HPCParallelPattern* Pattern);
bool IsOperator(HPCParallelPattern* Pattern);
}*/