Helios++
Helios software for LiDAR simulations
SM_ParallelMergeSortSubTask.h
1 #pragma once
2 
3 #include <SharedSubTask.h>
4 #include <SharedTaskSequencer.h>
5 #include <surfaceinspector/maths/Scalar.hpp>
6 
7 #include <algorithm>
8 
10 
11 namespace helios{ namespace hpc {
12 
85 template <typename RandomAccessIterator, typename Comparator>
87 protected:
88  // *** ATTRIBUTES *** //
89  // ******************** //
94  std::shared_ptr<SharedTaskSequencer> stSequencer;
98  size_t tIdx;
102  size_t numThreads;
106  size_t minElements;
110  int maxDepth;
114  RandomAccessIterator begin;
118  RandomAccessIterator end;
122  Comparator comparator;
123 
124 public:
125  // *** CONSTRUCTION / DESTRUCTION *** //
126  // ************************************ //
132  std::shared_ptr<SharedTaskSequencer> ch,
133  size_t const tIdx,
134  size_t const numThreads,
135  size_t const minElements,
136  int const maxDepth,
137  RandomAccessIterator begin,
138  RandomAccessIterator end,
139  Comparator comparator
140  ) :
141  SharedSubTask(ch),
142  stSequencer(ch),
143  tIdx(tIdx),
147  begin(begin),
148  end(end),
150  {}
151  virtual ~SM_ParallelMergeSortSubTask() = default;
152 
153  // *** RUNNABLE SHARED TASK *** //
154  // ****************************** //
161  void run() override{
162  // Handle single thread sort cases
163  size_t const numElements = std::distance(begin, end); // m
164  if(numElements < minElements || numThreads==1){
165  std::sort(begin, end, comparator);
166  return;
167  }
168 
169  // Prepare handling of parallel cases
170  int const initDepth = (int) std::ceil(std::log2(tIdx+1)); // d_*
171  RandomAccessIterator workA = begin;
172  std::vector<RandomAccessIterator> workB(1, end);
173  vector<std::shared_ptr<SM_ParallelMergeSortSubTask<
174  RandomAccessIterator, Comparator
175  >>> childrenTasks(0);
176 
177  // Compute workload distribution
178  for(int depth = 0 ; depth < maxDepth ; ++depth){
179  // Distribute workload to another thread if available
180  size_t const k = 1 + depth - initDepth;
181  size_t const rightIdx = \
184  if(rightIdx < numThreads){
185  RandomAccessIterator workSplit = workA +
186  std::distance(workA, workB[depth]) / 2;
187  std::shared_ptr<SM_ParallelMergeSortSubTask> childTask = \
188  std::make_shared<SM_ParallelMergeSortSubTask<
189  RandomAccessIterator, Comparator
190  >>(
191  stSequencer,
192  rightIdx,
193  numThreads,
194  minElements,
195  maxDepth,
196  workSplit,
197  workB[depth],
198  comparator
199  );
200  childrenTasks.push_back(childTask);
201  stSequencer->start(childTask);
202  workB.push_back(workSplit);
203  }
204  else{
205  break;
206  }
207  }
208 
209  // Compute workload itself (partial sorting)
210  std::sort(workA, workB[workB.size()-1], comparator);
211 
212  // Merge computed workload (merge partial sortings)
213  for(int i = childrenTasks.size()-1 ; i >= 0 ; --i){
214  std::shared_ptr<SM_ParallelMergeSortSubTask> childTask = \
215  childrenTasks[i];
216  childTask->getThread()->join();
217  std::inplace_merge(workA, workB[i+1], workB[i], comparator);
218  }
219  return;
220  }
221 
222 };
223 
224 }}
A shared task is said to be a collection of shared sub-tasks. Each shared sub-task can be computed in...
Definition: SharedSubTask.h:16
std::shared_ptr< SharedSubTaskCompletionHandler > ch
The shared sub-task completion handler that handles what must be done after a shared sub-task executi...
Definition: SharedSubTask.h:28
Class providing common operations to work with scalars.
Definition: Scalar.hpp:18
Shared sub-task to sort a sequence using a parallel mergesort like algorithm for shared memory contex...
Definition: SM_ParallelMergeSortSubTask.h:86
size_t numThreads
Definition: SM_ParallelMergeSortSubTask.h:102
SM_ParallelMergeSortSubTask(std::shared_ptr< SharedTaskSequencer > ch, size_t const tIdx, size_t const numThreads, size_t const minElements, int const maxDepth, RandomAccessIterator begin, RandomAccessIterator end, Comparator comparator)
Main constructor for shared context parallel merge sort sub-task.
Definition: SM_ParallelMergeSortSubTask.h:131
RandomAccessIterator end
Definition: SM_ParallelMergeSortSubTask.h:118
std::shared_ptr< SharedTaskSequencer > stSequencer
Definition: SM_ParallelMergeSortSubTask.h:94
int maxDepth
Definition: SM_ParallelMergeSortSubTask.h:110
RandomAccessIterator begin
Definition: SM_ParallelMergeSortSubTask.h:114
size_t tIdx
Thread index in .
Definition: SM_ParallelMergeSortSubTask.h:98
size_t minElements
Definition: SM_ParallelMergeSortSubTask.h:106
void run() override
Implementation of the sort method itself.
Definition: SM_ParallelMergeSortSubTask.h:161
Comparator comparator
Definition: SM_ParallelMergeSortSubTask.h:122