-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsort_core.cpp
More file actions
73 lines (61 loc) · 2.43 KB
/
Copy pathsort_core.cpp
File metadata and controls
73 lines (61 loc) · 2.43 KB
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
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
#include <iomanip>
#include <omp.h>
struct Point {
double x, y;
int id;
};
int main() {
const int N = 1000;
std::vector<Point> grid(N * N);
std::mt19937_64 rng(42);
std::uniform_real_distribution<double> dist(0.0, 1.0);
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
grid[i * N + j] = { dist(rng), dist(rng), i * N + j };
auto is_monotone = [&]() -> bool {
for (int i = 0; i < N; ++i)
for (int j = 1; j < N; ++j)
if (grid[i*N + j].x < grid[i*N + j - 1].x) return false;
for (int j = 0; j < N; ++j)
for (int i = 1; i < N; ++i)
if (grid[i*N + j].y < grid[(i-1)*N + j].y) return false;
return true;
};
const int nthreads = omp_get_max_threads();
std::vector<std::vector<Point>> thread_cols(nthreads, std::vector<Point>(N));
auto start = std::chrono::high_resolution_clock::now();
int iterations = 0;
const int MAX_ITER = 1000;
while (iterations < MAX_ITER) {
if (is_monotone()) break;
// Lines
#pragma omp parallel for schedule(static)
for (int i = 0; i < N; ++i) {
std::sort(grid.begin() + i * N, grid.begin() + (i + 1) * N,
[](const Point& a, const Point& b) { return a.x < b.x; });
}
// Columns
#pragma omp parallel for schedule(static)
for (int j = 0; j < N; ++j) {
int tid = omp_get_thread_num();
auto& col = thread_cols[tid];
for (int i = 0; i < N; ++i) col[i] = grid[i * N + j];
std::sort(col.begin(), col.end(),
[](const Point& a, const Point& b) { return a.y < b.y; });
for (int i = 0; i < N; ++i) grid[i * N + j] = col[i];
}
++iterations;
}
auto end = std::chrono::high_resolution_clock::now();
double runtime_ms = std::chrono::duration<double, std::milli>(end - start).count();
std::cout << std::fixed << std::setprecision(3);
std::cout << "Available threads : " << omp_get_max_threads() << "\n";
std::cout << "Sort iterations : " << iterations << "\n";
std::cout << "Total runtime (ms) : " << runtime_ms << "\n";
std::cout << "check convergence : " << (is_monotone() ? "yes" : "no") << "\n";
}