ls1-MarDyn
ls1-MarDyn molecular dynamics code
QuickschedTraversal.h
1/*
2 * QuickschedTraversal.h
3 *
4 * Created on: 20 May 2017
5 * Author: gratlf
6 */
7
8#ifndef SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_QUICKSCHEDTRAVERSAL_H
9#define SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_QUICKSCHEDTRAVERSAL_H
10
11#include "C08BasedTraversals.h"
12#include "utils/Logger.h"
13#include "Simulation.h"
14#include "particleContainer/LinkedCells.h"
15
16#ifdef QUICKSCHED
17#include "quicksched.h"
18#endif
19
20using Log::global_log;
21
23 std::array<unsigned long, 3> taskBlockSize;
24};
25
26template<class CellTemplate>
27class QuickschedTraversal : public C08BasedTraversals<CellTemplate> {
28public:
29 QuickschedTraversal(std::vector<CellTemplate> &cells,
30 const std::array<unsigned long, 3> &dims,
31 const std::array<unsigned long, 3> &taskBlockSize);
32
34
35
36 virtual void rebuild(std::vector<CellTemplate> &cells,
37 const std::array<unsigned long, 3> &dims, double cellLength[3], double cutoff,
39
40 void traverseCellPairs(CellProcessor &cellProcessor);
41
42 void traverseCellPairsOuter(CellProcessor &cellProcessor);
43
44 void traverseCellPairsInner(CellProcessor &cellProcessor, unsigned stage, unsigned stageCount);
45
46private:
47 enum taskType {
48 PackedAdjustable
49 };
50
51 void init();
52
53 static void runner(int type, void *data);
54
55 array<unsigned long, 3> _taskBlocksize;
56 CellProcessor *_contextCellProcessor;
57
58 struct qsched *_scheduler;
59 taskType _taskTypeSelector;
60};
61
62template<class CellTemplate>
63QuickschedTraversal<CellTemplate>::QuickschedTraversal(std::vector<CellTemplate> &cells,
64 const std::array<unsigned long, 3> &dims,
65 const std::array<unsigned long, 3> &taskBlockSize)
66#ifdef QUICKSCHED
68 _taskBlocksize(taskBlockSize),
69 _contextCellProcessor(nullptr),
70 _scheduler(new struct qsched),
71 _taskTypeSelector(PackedAdjustable) {
72 mardyn_assert((is_base_of<ParticleCellBase, CellTemplate>::value));
73 qsched_init(_scheduler, mardyn_get_max_threads(), qsched_flag_none);
74}
75
76#else
77 : C08BasedTraversals<CellTemplate>(cells, dims) {}
78#endif /* QUICKSCHED */
79
80template<class CellTemplate>
81void QuickschedTraversal<CellTemplate>::rebuild(std::vector<CellTemplate> &cells,
82 const std::array<unsigned long, 3> &dims, double cellLength[3], double cutoff,
84#ifdef QUICKSCHED
85 if (QuickschedTraversalData *qui_data = dynamic_cast<QuickschedTraversalData *>(data)) {
86 CellPairTraversals<CellTemplate>::rebuild(cells, dims, cellLength, cutoff, data);
87 qsched_reset(_scheduler);
88 _taskBlocksize = qui_data->taskBlockSize;
89 init();
90 } else {
91 global_log->error() << "QuickschedTraversal::rebuild was called with incompatible Traversal data!" << endl;
92 }
93#endif /* QUICKSCHED */
94}
95
96template<class CellTemplate>
98#ifdef QUICKSCHED
99 qsched_res_t resourceId;
100 qsched_task_t taskId;
101 unsigned long cellIndex;
102 // macro for easier access and to avoid aliasing
103//#define m_cells (*((vector<ParticleCellBase> *)(this->_cells)))
104// vector<ParticleCellBase> m_cells = *(dynamic_cast<vector<ParticleCellBase> *>(this->_cells));
105 vector<ParticleCell> m_cells = *((vector<ParticleCell> *)(this->_cells));
106
107 switch (_taskTypeSelector) {
108 case PackedAdjustable: {
109 // check that blocksize is within domain size
110 for (int i = 0; i < 3; ++i) {
111 if (_taskBlocksize[i] > this->_dims[i]) {
112 global_log->error() << "Blocksize is bigger than number of cells in dimension "
113 << (char) ('x' + i) << ". (" << _taskBlocksize[i] << " > "
114 << this->_dims[i] << ")" << std::endl;
116 }
117 }
118
119 global_log->info() << "Generating resource and task ids" << std::endl;
120 for (unsigned long z = 0; z < this->_dims[2]; ++z) {
121 for (unsigned long y = 0; y < this->_dims[1]; ++y) {
122 for (unsigned long x = 0; x < this->_dims[0]; ++x) {
123 cellIndex = threeDimensionalMapping::threeToOneD(x, y, z, this->_dims);
124 resourceId = qsched_addres(_scheduler, qsched_owner_none, qsched_res_none);
125 m_cells[cellIndex].setResourceId(resourceId);
126 // only create tasks with offset blocksize-1.
127 // -1 because they need to overlap
128 // skip tasks for rear halo layer as they would only contain halo cells
129 if ((z % (_taskBlocksize[2] - 1) == 0
130 && y % (_taskBlocksize[1] - 1) == 0
131 && x % (_taskBlocksize[0] - 1) == 0)
132 &&
133 (x < this->_dims[0] - 1
134 && y < this->_dims[1] - 1
135 && z < this->_dims[2] - 1)) {
136 // also save the pointers as long
137 unsigned long payload[]{x, y, z, (unsigned long) this};
138 taskId = qsched_addtask(_scheduler,
139 PackedAdjustable,
140 task_flag_none,
141 payload,
142 sizeof(payload),
143 1);
144 m_cells[cellIndex].setTaskId(taskId);
145 }
146 } /* end for-x */
147 } /* end for-y*/
148 } /* end for-z */
149
150 // set dependencies
151 global_log->info() << "Setting task dependencies" << std::endl;
152 for (unsigned long z = 0; z < this->_dims[2] - 1; z += _taskBlocksize[2] - 1) {
153 for (unsigned long y = 0; y < this->_dims[1] - 1; y += _taskBlocksize[1] - 1) {
154 for (unsigned long x = 0; x < this->_dims[0] - 1; x += _taskBlocksize[0] - 1) {
155 cellIndex = threeDimensionalMapping::threeToOneD(x, y, z, this->_dims);
156
157 // create locks for all 8 corners of the block
158 for (unsigned long i = 0; i < _taskBlocksize[0]
159 && x + i < this->_dims[0]; i += _taskBlocksize[0] - 1) {
160 for (unsigned long j = 0; j < _taskBlocksize[1]
161 && y + j < this->_dims[1]; j += _taskBlocksize[1] - 1) {
162 for (unsigned long k = 0; k < _taskBlocksize[2]
163 && z + k < this->_dims[2]; k += _taskBlocksize[2] - 1) {
164 qsched_addlock(_scheduler,
165 m_cells[cellIndex].getTaskId(),
166 m_cells[threeDimensionalMapping::threeToOneD(x + i,
167 y + j,
168 z + k,
169 this->_dims)].getRescourceId());
170 }
171 }
172 }
173 } /* end for-x */
174 } /* end for-y*/
175 } /* end for-z */
176 break;
177 } /* end case PackedAdjustable */
178 default:
179 global_log->error() << "QuickschedHandler::init() received non existing task type!"
180 << std::endl;
181 }
182#endif // QUICKSCHED
183}
184
185template<class CellTemplate>
187#ifdef QUICKSCHED
188 qsched_free(_scheduler);
189 delete (_scheduler);
190#endif // QUICKSCHED
191}
192
193template<class CellTemplate>
195#ifdef QUICKSCHED
196
197 QuickschedTraversal *context = ((QuickschedTraversal **) data)[3];
198#ifdef PRINT_SCHEDULING_TIMINGS
199 struct VectorizedCellProcessor::Timings timing ;
200 if(_simulation.getSimStep() > 10){
201 timing.start = _rdtsc();
202 }
203#endif
204 switch (type) {
205 case PackedAdjustable: {
206 // TODO optimize calculation order (1. corners 2. edges 3. rest) and gradually release resources
207 unsigned long x = ((unsigned long *) data)[0];
208 unsigned long y = ((unsigned long *) data)[1];
209 unsigned long z = ((unsigned long *) data)[2];
210
211 // traverse over block
212 for (unsigned long i = 0; i < context->_taskBlocksize[0] - 1
213 && i < context->_dims[0] - 1; ++i) {
214 for (unsigned long j = 0; j < context->_taskBlocksize[1] - 1
215 && j < context->_dims[1] - 1; ++j) {
216 for (unsigned long k = 0; k < context->_taskBlocksize[2] - 1
217 && k < context->_dims[2] - 1; ++k) {
218
219 //process cell
220 unsigned long baseIndex = threeDimensionalMapping::threeToOneD(x + i,
221 y + j,
222 z + k,
223 context->_dims);
224 context->processBaseCell(
225 *(context->_contextCellProcessor),
226 baseIndex);
227 }
228 }
229 }
230 break;
231 } /* end case PackedAdjustable */
232 default:
233 global_log->error() << "Undefined Quicksched task type: " << type << std::endl;
234 }
235#ifdef PRINT_SCHEDULING_TIMINGS
236 if(_simulation.getSimStep() > 10){
237 timing.end = _rdtsc();
238 (dynamic_cast<VectorizedCellProcessor*>(_contextCellProcessor))->getThreadData()[omp_get_thread_num()]->_timings.push_back(timing);
239 }
240#endif
241#endif /* QUICKSCHED */
242}
243
244template<class CellTemplate>
246 _contextCellProcessor = &cellProcessor;
247#ifdef QUICKSCHED
248 qsched_run(_scheduler, mardyn_get_max_threads(), runner);
249#endif /* QUICKSCHED */
250}
251
252template<class CellTemplate>
254 unsigned stageCount) {
255 global_log->error() << "QuickschedTraversal::traverseCellPairsInner is not implemented!" << std::endl;
256}
257
258template<class CellTemplate>
260 global_log->error() << "QuickschedTraversal::traverseCellPairsOuter is not implemented!" << std::endl;
261}
262
263#endif //SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_QUICKSCHEDTRAVERSAL_H
Definition: C08BasedTraversals.h:17
virtual void rebuild(std::vector< CellTemplate > &cells, const std::array< unsigned long, 3 > &dims, double cellLength[3], double cutoff, CellPairTraversalData *data)
Definition: CellPairTraversals.h:32
Definition: CellProcessor.h:29
Definition: QuickschedTraversal.h:27
virtual void rebuild(std::vector< CellTemplate > &cells, const std::array< unsigned long, 3 > &dims, double cellLength[3], double cutoff, CellPairTraversalData *data)
Definition: QuickschedTraversal.h:81
static void exit(int exitcode)
Terminate simulation with given exit code.
Definition: Simulation.cpp:155
Vectorized calculation of the force.
Definition: VectorizedCellProcessor.h:29
Enumeration class corresponding to the type schema type.
Definition: vtk-unstructured.h:1746
Definition: CellPairTraversals.h:16
Definition: QuickschedTraversal.h:22