| 143 | } |
| 144 | |
| 145 | __forceinline size_t partition(V& leftReduction, V& rightReduction) |
| 146 | { |
| 147 | /* partition the individual ranges for each task */ |
| 148 | parallel_for(numTasks,[&] (const size_t taskID) { |
| 149 | const size_t startID = (taskID+0)*N/numTasks; |
| 150 | const size_t endID = (taskID+1)*N/numTasks; |
| 151 | V local_left(identity); |
| 152 | V local_right(identity); |
| 153 | const size_t mid = serial_partitioning(array,startID,endID,local_left,local_right,is_left,reduction_t); |
| 154 | counter_start[taskID] = startID; |
| 155 | counter_left [taskID] = mid-startID; |
| 156 | leftReductions[taskID] = local_left; |
| 157 | rightReductions[taskID] = local_right; |
| 158 | }); |
| 159 | counter_start[numTasks] = N; |
| 160 | counter_left[numTasks] = 0; |
| 161 | |
| 162 | /* finalize the reductions */ |
| 163 | for (size_t i=0; i<numTasks; i++) { |
| 164 | reduction_v(leftReduction,leftReductions[i]); |
| 165 | reduction_v(rightReduction,rightReductions[i]); |
| 166 | } |
| 167 | |
| 168 | /* calculate mid point for partitioning */ |
| 169 | size_t mid = counter_left[0]; |
| 170 | for (size_t i=1; i<numTasks; i++) |
| 171 | mid += counter_left[i]; |
| 172 | const range<ssize_t> globalLeft (0,mid); |
| 173 | const range<ssize_t> globalRight(mid,N); |
| 174 | |
| 175 | /* calculate all left and right ranges that are on the wrong global side */ |
| 176 | size_t numMisplacedRangesLeft = 0; |
| 177 | size_t numMisplacedRangesRight = 0; |
| 178 | size_t numMisplacedItemsLeft MAYBE_UNUSED = 0; |
| 179 | size_t numMisplacedItemsRight MAYBE_UNUSED = 0; |
| 180 | |
| 181 | for (size_t i=0; i<numTasks; i++) |
| 182 | { |
| 183 | const range<ssize_t> left_range (counter_start[i], counter_start[i] + counter_left[i]); |
| 184 | const range<ssize_t> right_range(counter_start[i] + counter_left[i], counter_start[i+1]); |
| 185 | const range<ssize_t> left_misplaced = globalLeft. intersect(right_range); |
| 186 | const range<ssize_t> right_misplaced = globalRight.intersect(left_range); |
| 187 | |
| 188 | if (!left_misplaced.empty()) |
| 189 | { |
| 190 | numMisplacedItemsLeft += left_misplaced.size(); |
| 191 | leftMisplacedRanges[numMisplacedRangesLeft++] = left_misplaced; |
| 192 | } |
| 193 | |
| 194 | if (!right_misplaced.empty()) |
| 195 | { |
| 196 | numMisplacedItemsRight += right_misplaced.size(); |
| 197 | rightMisplacedRanges[numMisplacedRangesRight++] = right_misplaced; |
| 198 | } |
| 199 | } |
| 200 | assert( numMisplacedItemsLeft == numMisplacedItemsRight ); |
| 201 | |
| 202 | /* if no items are misplaced we are done */ |
nothing calls this directly
no test coverage detected