Advertisement
Guest User

Untitled

a guest
Nov 18th, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.71 KB | None | 0 0
  1. #include <mpi.h>
  2. #include <stdio.h>
  3. #include <algorithm>
  4. #include <vector>
  5. #include "kruskal.h"
  6. #include <math.h>
  7. #include <iostream>
  8. #include <stdlib.h>
  9. #include <utility>
  10. #include <time.h>
  11. #include <stddef.h>
  12. using namespace std;
  13.  
  14. template<typename T>
  15. struct tree_element {
  16. tree_element* parent;
  17. T elem;
  18. int operation_counter;
  19. int rank;
  20. tree_element(T e) {
  21. operation_counter = 0;
  22. elem = e;
  23. parent = this;
  24. rank = 0;
  25. }
  26. tree_element() {
  27. elem = 0;
  28. parent = this;
  29. rank = 0;
  30. }
  31. tree_element* Union(tree_element& e) {
  32. tree_element* a = find_set(this);
  33. tree_element* b = find_set(&e);
  34. e.operation_counter++;
  35. if(a->rank > b->rank) {
  36. b->parent = a;
  37. } else {
  38. a->parent = b;
  39. if(rank == e.rank) {
  40. b->rank++;
  41. }
  42. }
  43. return parent;
  44. }
  45. static tree_element* find_set(tree_element* e);
  46. void print() {
  47. tree_element* current = this;
  48. printf("%d\n", current->elem);
  49. while(current != current->parent) {
  50. current = current->parent;
  51. printf("%d\n", current->elem);
  52. }
  53. }
  54. };
  55.  
  56. template<typename T>
  57. tree_element<T>* tree_element<T>::find_set(tree_element<T>* e) {
  58. e->operation_counter++;
  59. if (e != e->parent) {
  60. e->parent = find_set(e->parent);
  61. e->operation_counter++;
  62. }
  63. return e->parent;
  64. }
  65.  
  66.  
  67.  
  68. struct Edge{
  69. int in;
  70. int out;
  71. double cost;
  72. int used;
  73. int range;
  74. int inconsistent;
  75. };
  76.  
  77. struct Node {
  78. double x;
  79. double y;
  80. int id;
  81. };
  82.  
  83. double getDistance(Node& n1, Node& n2) {
  84. return sqrt((n1.x - n2.x) * (n1.x - n2.x) + (n1.y - n2.y) * (n1.y - n2.y));
  85. }
  86.  
  87. long long int operation_counter = 0;
  88.  
  89. bool operator<(const Edge &e1, const Edge &e2) {
  90. operation_counter++;
  91. return e1.cost < e2.cost;
  92. }
  93.  
  94. void null_element_usage(vector<Edge> edges_vector) {
  95. std::vector<Edge>::iterator it = edges_vector.begin();
  96. for(;it!=edges_vector.end(); it++) {
  97. it->used = false;
  98. }
  99. }
  100.  
  101. void null_element_usage(Edge* edges_vector, int size) {
  102. for(int i = 0; i < size; i++) {
  103. edges_vector[i].used = false;
  104. }
  105. }
  106.  
  107. void unnull_element_usage(Edge* edges_vector, int size) {
  108. for(int i = 0; i < size; i++) {
  109. edges_vector[i].used = false;
  110. }
  111. }
  112.  
  113. Edge* concat_arrays(Edge* arr1, Edge* arr2, int size1, int size2) {
  114. Edge* new_edges = new Edge[size1+size2];
  115. copy(arr1, arr1 + size1, new_edges);
  116. copy(arr2, arr2 + size2, new_edges + size1);
  117. return new_edges;
  118. }
  119.  
  120. pair<Edge*,int> run_MST(Edge* edges, int N, int size) {
  121. vector<Edge> edges_vector;
  122. for(int i = 0; i < size; i++) {
  123. edges_vector.push_back(edges[i]);
  124. }
  125. sort(edges_vector.begin(), edges_vector.end());
  126. tree_element<int>* elements = new tree_element<int>[N];
  127. std::vector<Edge>::iterator it = edges_vector.begin();
  128. int operation_counter = 0;
  129. int len = 0;
  130. Edge* edges_recieved = new Edge[2*N];
  131. for(;it != edges_vector.end();it++) {
  132. operation_counter++;
  133. if(!it->used && tree_element<int>::find_set(&elements[it->in]) != tree_element<int>::find_set(&elements[it->out])) {
  134. it->used = true;
  135. it->range = len;
  136. elements[it->in].Union(elements[it->out]);
  137. edges_recieved[len] = *it;
  138. len++;
  139. operation_counter++;
  140. }
  141. }
  142. for(int kk = 0; kk < N; kk++) {
  143. operation_counter += elements[kk].operation_counter;
  144. }
  145. delete [] elements;
  146. return make_pair(edges_recieved, len);
  147. }
  148.  
  149. int main(int argc, char **argv) {
  150. const int tag = 13;
  151. int rank, wsize;
  152. MPI_Init (&argc, &argv); /* starts MPI */
  153. MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
  154. MPI_Comm_size (MPI_COMM_WORLD, &wsize); /* get number of processes */
  155. int highest_rank = 0;
  156. int size = wsize - 1;
  157. while(size/2 > 0) {
  158. highest_rank++;
  159. size = size / 2;
  160. }
  161. size = wsize - 1;
  162. int number_of_processes = wsize;
  163. //construct Edge type
  164. const int nitems=6;
  165. int blocklengths[6] = {1,1,1,1,1,1};
  166. MPI_Datatype types[6] = {MPI_INT, MPI_INT, MPI_DOUBLE, MPI_INT, MPI_INT, MPI_INT};
  167. MPI_Datatype mpi_edge;
  168. MPI_Aint offsets[6];
  169. offsets[0] = offsetof(struct Edge, in);
  170. offsets[1] = offsetof(struct Edge, out);
  171. offsets[2] = offsetof(struct Edge, cost);
  172. offsets[3] = offsetof(struct Edge, used);
  173. offsets[4] = offsetof(struct Edge, range);
  174. offsets[5] = offsetof(struct Edge, inconsistent);
  175. MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_edge);
  176. MPI_Type_commit(&mpi_edge);
  177. //construct Node type
  178. const int nitems_=3;
  179. int blocklengths_[6] = {1,1,1};
  180. MPI_Datatype types_[3] = {MPI_DOUBLE, MPI_DOUBLE, MPI_INT};
  181. MPI_Datatype mpi_node;
  182. MPI_Aint offsets_[6];
  183. offsets_[0] = offsetof(struct Node, x);
  184. offsets_[1] = offsetof(struct Node, y);
  185. offsets_[2] = offsetof(struct Node, id);
  186. MPI_Type_create_struct(nitems_, blocklengths_, offsets_, types_, &mpi_node);
  187. MPI_Type_commit(&mpi_node);
  188. MPI_Status status;
  189. //main process
  190. if(rank == 0) {
  191. const clock_t begin_time = clock();
  192. int cases = 1;
  193. FILE* pf = fopen("./tests1000.txt","r");
  194. FILE* pfresult = fopen("./result.txt", "a");
  195. FILE* out_MST = fopen("./MST.txt", "w");
  196. FILE* out_clasters = fopen("./clasters.txt", "w");
  197. FILE* out_cluster_points = fopen("./cluster_points.txt", "w");
  198. int N;
  199. fscanf(pf,"%d", &N);
  200. int each = N / (number_of_processes - 1);
  201. tree_element<int>* elements = new tree_element<int>[N];
  202. Node* nodes = new Node[N];
  203. MPI_Bcast(&N, 1 , MPI_INT, 0, MPI_COMM_WORLD);
  204.  
  205. for(int j = 0; j < N; j++) {
  206. double x,y;
  207. fscanf(pf,"%lf %lf", &x, &y);
  208. Node n;
  209. n.x = x;
  210. n.y = y;
  211. n.id = j;
  212. elements[j].elem = j;
  213. nodes[j] = n;
  214. }
  215. MPI_Bcast(nodes, N , mpi_node, 0, MPI_COMM_WORLD);
  216. vector<Edge> edges_used;
  217. int full_size = 0;
  218. int result_size = 0;
  219. MPI_Recv(&result_size, 1 , MPI_INT, 1, tag, MPI_COMM_WORLD, &status);
  220. operation_counter++;
  221. Edge* edges_new_recieved = new Edge[result_size];
  222. MPI_Recv(edges_new_recieved, result_size , mpi_edge, 1, tag, MPI_COMM_WORLD, &status);
  223. operation_counter++;
  224. for(int k = 0; k < result_size; k++) {
  225. if(edges_new_recieved[k].used) {
  226. edges_used.push_back(edges_new_recieved[k]);
  227. full_size++;
  228. }
  229. }
  230. vector<Edge> edges_vector_;
  231. for(int j = 0; j < full_size; j++) {
  232. edges_used[j].used = false;
  233. edges_vector_.push_back(edges_used[j]);
  234. }
  235. delete [] elements;
  236. elements = new tree_element<int>[N];
  237. sort(edges_vector_.begin(), edges_vector_.end());
  238. std::vector<Edge>::iterator it = edges_vector_.begin();
  239. int len = 0;
  240. for(;it != edges_vector_.end();it++) {
  241. if(!it->used && tree_element<int>::find_set(&elements[it->in]) != tree_element<int>::find_set(&elements[it->out])) {
  242. it->used = true;
  243. len++;
  244. it->range = len;
  245. elements[it->in].Union(elements[it->out]);
  246. }
  247. }
  248. for(int kk = 0; kk < N; kk++) {
  249. operation_counter += elements[kk].operation_counter;
  250. }
  251. it = edges_vector_.begin();
  252. long long int* op_counts = new long long int [number_of_processes];
  253. long long int all_operation_counter = operation_counter;
  254. long long int new_counter;
  255. MPI_Recv(&new_counter, 1 , MPI_LONG_LONG_INT, 1, tag, MPI_COMM_WORLD, &status);
  256. operation_counter++;
  257. all_operation_counter += new_counter;
  258. double clusters = 10;
  259. fprintf(pfresult, "time: %lf ; number_of_processes: %d ; data vol: %d ; number of operations: %lld ; flops: %lf \n", float( clock () - begin_time ) / CLOCKS_PER_SEC, number_of_processes, N , all_operation_counter, all_operation_counter / (float( clock () - begin_time ) / CLOCKS_PER_SEC));
  260. for(;it != edges_vector_.end();it++) {
  261. if(it->used) {
  262. fprintf(out_MST, "%lf %lf %lf %lf %lf\n", nodes[it->in].x, nodes[it->in].y, nodes[it->out].x, nodes[it->out].y, it->cost);
  263. if(it->range <= len - clusters) {
  264. fprintf(out_clasters, "%lf %lf %lf %lf %lf\n", nodes[it->in].x, nodes[it->in].y, nodes[it->out].x, nodes[it->out].y, it->cost);
  265. } else {
  266. it->inconsistent = true;
  267. }
  268. }
  269. }
  270. it = edges_vector_.begin();
  271. tree_element<int>* elements_new = new tree_element<int>[N];
  272. for(;it != edges_vector_.end();it++) {
  273. if(it->used && !it->inconsistent) {
  274. elements_new[it->in].Union(elements_new[it->out]);
  275. }
  276. }
  277. for(int k = 0; k < N; k++) {
  278. elements_new[k].elem = k;
  279. }
  280. for(int k = 0; k < N; k++) {
  281. int cluster = tree_element<int>::find_set(&elements_new[k])->elem;
  282. fprintf(out_cluster_points, "%lf %lf %d\n", nodes[k].x, nodes[k].y, cluster);
  283. }
  284. delete [] elements_new;
  285. } else {
  286. int N;
  287. MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
  288. tree_element<int>* elements = new tree_element<int>[N];
  289. Node* nodes = new Node[N];
  290. int each = N / (number_of_processes - 1);
  291. MPI_Bcast(nodes, N , mpi_node, 0, MPI_COMM_WORLD);
  292. int len = 0;
  293. int result_start = N - each * (rank - 1);
  294. vector<Edge> edges_vector;
  295. for(int i = N - result_start; i < (N - (result_start - each)); i++) {
  296. operation_counter++;
  297. for(int j = i + 1; j < N; j++) {
  298. double dist = getDistance(nodes[i], nodes[j]);
  299. operation_counter++;
  300. Edge e;
  301. e.in = nodes[i].id;
  302. e.out = nodes[j].id;
  303. e.cost = dist;
  304. e.used = 0;
  305. e.inconsistent = 0;
  306. edges_vector.push_back(e);
  307. len++;
  308. }
  309. }
  310.  
  311. sort(edges_vector.begin(), edges_vector.end());
  312. std::vector<Edge>::iterator it = edges_vector.begin();
  313. Edge* edges_recieved = new Edge[2*N];
  314. int kk = len;
  315. len = 0;
  316. for(;it != edges_vector.end();it++) {
  317. operation_counter++;
  318. if(!it->used && tree_element<int>::find_set(&elements[it->in]) != tree_element<int>::find_set(&elements[it->out])) {
  319. it->used = true;
  320. it->range = len;
  321. elements[it->in].Union(elements[it->out]);
  322. edges_recieved[len] = *it;
  323. len++;
  324. operation_counter++;
  325. }
  326. }
  327. delete [] elements;
  328. for(int kk = 0; kk < N; kk++) {
  329. operation_counter += elements[kk].operation_counter;
  330. }
  331. operation_counter++;
  332. int mult = 1;
  333. while(highest_rank > 0) {
  334. mult*=2;
  335. highest_rank--;
  336. if((rank -1) % mult == 0) {
  337. int result_size = 0;
  338. MPI_Recv(&result_size, 1 , MPI_INT, rank+(mult/2), tag, MPI_COMM_WORLD, &status);
  339. Edge* edges_new_recieved = new Edge[result_size];
  340. MPI_Recv(edges_new_recieved, result_size , mpi_edge, rank+(mult/2), tag, MPI_COMM_WORLD, &status);
  341. long long int new_counter;
  342. MPI_Recv(&new_counter, 1 , MPI_LONG_LONG_INT, rank+(mult/2), tag, MPI_COMM_WORLD, &status);
  343. operation_counter += new_counter;
  344. Edge* concated_edges = concat_arrays(edges_recieved, edges_new_recieved, len, result_size);
  345. delete [] edges_recieved;
  346. delete [] edges_new_recieved;
  347. null_element_usage(concated_edges,len+result_size);
  348. pair<Edge*,int> result = run_MST(concated_edges, N, len+result_size);
  349. len = result.second;
  350. edges_recieved = result.first;
  351. } else {
  352. MPI_Send(&len, 1 , MPI_INT, rank-(mult/2), tag, MPI_COMM_WORLD);
  353. MPI_Send(edges_recieved, len , mpi_edge, rank-(mult/2), tag, MPI_COMM_WORLD);
  354. MPI_Send(&operation_counter, 1 , MPI_LONG_LONG_INT, rank-(mult/2), tag, MPI_COMM_WORLD);
  355. break;
  356. }
  357. }
  358. if(highest_rank ==0 && rank == 1) {
  359. MPI_Send(&len, 1 , MPI_INT, 0, tag, MPI_COMM_WORLD);
  360. MPI_Send(edges_recieved, len , mpi_edge, 0, tag, MPI_COMM_WORLD);
  361. MPI_Send(&operation_counter, 1 , MPI_LONG_LONG_INT, 0, tag, MPI_COMM_WORLD);
  362. }
  363. }
  364. MPI_Finalize();
  365. return 0;
  366. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement