Guest User

Untitled

a guest
Jun 20th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.62 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <math.h>
  4. #include <mpi.h>
  5.  
  6. /// Math part
  7. int fact( int x );
  8. int CNM( int n, int m );
  9. double** MatrixCreate( int dim );
  10. void MatrixDelete( double** m, int dim);
  11. void MatrixCopy( double** dest, double** src, int dim);
  12. void MatrixMul( double** m1, double** m2, int dim, double** res );
  13. void MatrixPow( double** m1, int dim, int power, double** res );
  14. /// Calculation part
  15. int GetK( double** matr, int dim, double delta );
  16. void Getf( double** matr, int dim, int K, double *f, int numproc, int myid );
  17. double GetM( double *f, int count );
  18. double GetD( double *f, int count );
  19. double* ParallelMfromN( int procCount, int M, double *f, int K );
  20. double* ParallelAND( int procCount, double *f, int K );
  21. double* ParallelOR( int procCount, double *f, int K );
  22. double* Consecutive( int procCount, double **f, int K );
  23. /// Other stuff
  24. void InitMyMatrix( double** matrix, int dim );
  25. /// Entry point
  26. int main( int argc, char **argv, char **envp )
  27. {
  28. // Всякий разный MPI шит
  29. MPI_Init( &argc, &argv );
  30. int numprocs,myid;
  31. MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
  32. MPI_Comm_rank(MPI_COMM_WORLD,&myid);
  33. if( myid == 0 ){
  34. printf( "proc count = %i\nID = %i\n", numprocs, myid );
  35. fflush( stdout );
  36. } else {
  37. printf( "Start Child proc id = %i\n", myid);
  38. }
  39.  
  40. double start, end;
  41. start= MPI_Wtime( );
  42.  
  43.  
  44.  
  45. int dim = 8, I = 5, M = 2, L = 7;
  46. double delta = 0.000001;
  47. double **mymatrix = MatrixCreate( dim );
  48. InitMyMatrix( mymatrix, dim );
  49. int K = GetK( mymatrix, dim, delta );
  50. double *f = new double[K];
  51.  
  52. // Эта функция работает через библиотеку MPI
  53. Getf( mymatrix, dim, K, f, numprocs, myid);
  54.  
  55. if (myid == 0) { // Поэтому все последующие вычисления буду проходить в главном потоке
  56. // он-же поток с id == 0
  57.  
  58. double *fMN = ParallelMfromN( I, M, f, K );
  59. double *fAND = ParallelAND( L, f, K );
  60. double **f3 = new double*[3];
  61. f3[0] = new double[K];
  62. f3[1] = new double[K];
  63. f3[2] = new double[K];
  64. for( int i = 0; i < K; i++ )
  65. {
  66. f3[2][i] = fMN[i];
  67. f3[0][i] = f[i];
  68. f3[1][i] = fAND[i];
  69. }
  70. double *fRes = Consecutive( 3, f3, K );
  71. double getM = GetM( fRes, 3 * K );
  72. double getD = GetD( fRes, 3 * K );
  73. // The end
  74.  
  75. // Cчитаем время выполнения и финализируем MPI
  76. end = MPI_Wtime( );
  77. MPI_Finalize( );
  78. printf("Time = %f\n\n", end-start );
  79.  
  80.  
  81. double sum = 0; //some stuff
  82. double *fsum = fMN;
  83. for( int i = 0; i < K; i++ )
  84. {
  85. sum += fsum[i];
  86. printf( "f[%i]\t=\t%e\n", i + 1, fsum[i] );
  87. }
  88. printf( "\n=====[%f]=====\n\n", sum );
  89. sum = 0;
  90. for( int i = 0; i < 3 * K; i++ )
  91. sum += fRes[i];
  92. printf( "=====\nsum = %f\n", sum );
  93. printf( "=====\nM = %f\nD = %f\n", getM, getD );
  94. fflush( stdout );
  95. MatrixDelete( mymatrix, dim );
  96. delete f;
  97. delete fMN;
  98. delete fAND;
  99. delete f3[0];
  100. delete f3[1];
  101. delete f3[2];
  102. delete[] f3;
  103. delete fRes;
  104. return 0;
  105. }
  106. // Это выполняют все остальные потоки кроме главного
  107. MPI_Finalize();
  108. delete f;
  109. return 0;
  110. }
  111. /// Math part
  112. int fact( int x )
  113. {
  114. int res = 1;
  115. for( int i = 2; i <= x; i++ )
  116. res *= i;
  117. return res;
  118. }
  119. int CNM( int n, int m )
  120. { return fact( n ) / (fact( m ) * fact( n - m )); }
  121. double** MatrixCreate( int dim )
  122. {
  123. double** matrix = new double*[dim];
  124. for( int i = 0; i < dim; i++ )
  125. matrix[i] = new double[dim];
  126. return matrix;
  127. }
  128. void MatrixDelete( double** m, int dim)
  129. {
  130. for( int i = 0; i < dim; i++ )delete m[i];
  131. delete[] m;
  132. }
  133. void MatrixCopy( double** dest, double** src, int dim)
  134. {
  135. for( int i = 0; i < dim; i++ )
  136. for( int j = 0; j < dim; j++ )
  137. dest[i][j] = src[i][j];
  138. }
  139. void MatrixMul( double** m1, double** m2, int dim, double** res )
  140. {
  141. double** tmpBuf = MatrixCreate( dim );
  142. double sum;
  143. for( int i = 0; i < dim; i++ )
  144. for( int j = 0; j < dim; j++ )
  145. {
  146. sum = 0;
  147. for( int k = 0; k < dim; k++ )
  148. sum += m1[i][k] * m2[k][j];
  149. tmpBuf[i][j] = sum;
  150. }
  151. MatrixCopy( res, tmpBuf, dim );
  152. MatrixDelete( tmpBuf, dim );
  153. }
  154.  
  155. void MatrixPow( double** m1, int dim, int power, double** res )
  156. {
  157. if( power == 0 )
  158. {
  159. for( int i = 0; i < dim; i++ )
  160. for( int j = 0; j < dim; j++ )
  161. res[i][j] = (i == j ? 1 : 0);
  162. return;
  163. }
  164. double** m2 = m1;
  165. if( m1 == res )
  166. {
  167. m2 = MatrixCreate( dim );
  168. MatrixCopy( m2, m1, dim );
  169. }
  170. MatrixCopy( res, m1, dim );
  171. for( int i = 1; i < power; i++ )
  172. MatrixMul( res, m2, dim, res );
  173. }
  174. /// Calculation part
  175. int GetK( double** matr, int dim, double delta )
  176. {
  177. double** tmpMatr = MatrixCreate( dim );
  178. int k = 0;
  179. do{
  180. k++;
  181. MatrixPow( matr, dim, k, tmpMatr );
  182. }while( (1 - tmpMatr[0][dim - 1]) >= delta );
  183. MatrixDelete( tmpMatr, dim );
  184. return k;
  185. }
  186. /**
  187. ##########################################################################################
  188. РЕАЛИЗОВАНА С ПОМОЩЬЮ БИБЛИОТЕКИ MPI.
  189. ##########################################################################################
  190. **/
  191. void Getf( double** matr, int dim, int K, double *f , int numprocs, int myid)
  192. {
  193. double sum;
  194.  
  195. double** m1 = MatrixCreate( dim );
  196. double** m2 = MatrixCreate( dim );
  197. sum = 0;
  198. double* fm1 = new double[K];
  199. double* fm2 = new double[K];
  200.  
  201. /**
  202. ##########################################################################################
  203. ЦИКЛ ВИДА:
  204.  
  205. for (int cnt = 0; cnt < MAX_CNT; cnt++)
  206.  
  207. ПЕРЕД ВОЗВЕДЕНИЕМ В СТЕПЕНЬ ДЛЯ ТОГО, ЧТОБЫ БОЛЕЕ ЧЕТКО ВИДЕТЬ
  208. РАЗЛИЧИЯ В ПРОИЗВОДИТЕЛЬНОСТИ В MPI РЕЖИМЕ
  209. ##########################################################################################
  210. **/
  211.  
  212. int MAX_CNT = 100;
  213.  
  214. for( int i = 1; i <= K; i++ )
  215. {
  216. if (numprocs == 1) { // Все выполняется в одном процессе
  217. for (int cnt = 0; cnt < MAX_CNT; cnt++)MatrixPow( matr, dim, i, m1 );
  218. for (int cnt = 0; cnt < MAX_CNT; cnt++)MatrixPow( matr, dim, i - 1, m2 );
  219.  
  220. fm1[i-1] = m1[0][dim - 1];
  221. fm2[i-1] = m2[0][dim - 1];
  222.  
  223. //if (i == 1) printf("ONE THREAD MODE\n");
  224.  
  225. } else { // Процессов несколько
  226. if (myid == 0) { // Первую матрицу возводим в главном процессе
  227. for (int cnt = 0; cnt < MAX_CNT; cnt++)MatrixPow( matr, dim, i, m1 );
  228. fm1[i-1] = m1[0][dim - 1];
  229.  
  230. //if (i == 1)printf("MPI MODE; ID = %i; START = %f\n", myid, MPI_Wtime( ));
  231. //if (i == K)printf("MPI MODE; ID = %i; END = %f\n", myid, MPI_Wtime( ));
  232. }
  233. if (myid == 1) { // Вторую матрицу в отдельном специальном процессе
  234. for (int cnt = 0; cnt < MAX_CNT; cnt++)MatrixPow( matr, dim, i - 1, m2 );
  235. fm2[i-1] = m2[0][dim - 1];
  236.  
  237. //if (i == 1)printf("MPI MODE; ID = %i; START = %f\n", myid, MPI_Wtime( ));
  238. //if (i == K)printf("MPI MODE; ID = %i; END = %f\n", myid, MPI_Wtime( ));
  239. }
  240. }
  241. }
  242.  
  243. if (numprocs != 1) {
  244. double start, end;
  245. start= MPI_Wtime( );
  246. // И синхронизируемся с главным процессом
  247. MPI_Bcast(fm2, K , MPI_DOUBLE, 1, MPI_COMM_WORLD);
  248. end = MPI_Wtime( );
  249. printf("ID=%i\tTime = %f\n\n", myid, end-start );
  250. }
  251.  
  252. // Все вспомогательные вычисления только в главном потоке
  253. if (myid == 0) {
  254.  
  255. printf("STUFF TIME = %f\n", MPI_Wtime( ));
  256.  
  257. for( int i = 1; i <= K; i++ ) {
  258. if (myid == 0) { // Только в главном процессе
  259. f[i - 1] = fm1[i-1] - fm2[i-1]; //m1[0][dim - 1] - m2[0][dim - 1];
  260. sum += f[i - 1];
  261. }
  262. }
  263. }
  264.  
  265. MatrixDelete( m1, dim );
  266. MatrixDelete( m2, dim );
  267. }
  268.  
  269. double GetM( double *f, int count )
  270. {
  271. double res = 0;
  272. for( int i = 0; i < count; i++ )
  273. res += i * f[i];
  274. return res;
  275. }
  276. double GetD( double *f, int count )
  277. {
  278. double M = GetM( f, count );
  279. double res = 0;
  280. for( int i = 0; i < count; i++ )
  281. res += pow( i - M, 2 ) * f[i];
  282. return res;
  283. }
  284. double* ParallelMfromN( int procCount, int M, double *f, int K )
  285. {
  286. double *fAND = ParallelAND( M, f, K );
  287. double *fMN = ParallelOR( CNM( procCount, M ), fAND, K );
  288. return fMN;
  289. }
  290. double* ParallelAND( int procCount, double *f, int K )
  291. {
  292. double *fAnd = new double[K];
  293. double S, M, res;
  294. for( int k = 0; k < K; k++ )
  295. {
  296. S = 0;
  297. for( int n = 1; n <= procCount; n++ )
  298. {
  299. M = 1;
  300. for( int i = 1; i <= procCount; i++ )
  301. {
  302. if( n == i )
  303. res = 1;
  304. else
  305. {
  306. res = 0;
  307. for( int ki = 0; ki < K; ki++ )
  308. if( (i < n && ki < k) || (i >= n && ki <= k) )
  309. res += f[ki];
  310. }
  311. M *= res;
  312. }
  313. S += f[k] * M;
  314. }
  315. fAnd[k] = S;
  316. }
  317. return fAnd;
  318. }
  319. double* ParallelOR( int procCount, double *f, int K )
  320. {
  321. double *fOr = new double[K];
  322. double S, M, res;
  323. for( int k = 0; k < K; k++ )
  324. {
  325. S = 0;
  326. for( int n = 1; n <= procCount; n++ )
  327. {
  328. M = 1;
  329. for( int i = 1; i <= procCount; i++ )
  330. {
  331. if( n == i )
  332. res = 1;
  333. else
  334. {
  335. res = 0;
  336. for( int ki = 0; ki < K; ki++ )
  337. if( (i < n && ki > k) || (i >= n && ki >= k) )
  338. res += f[ki];
  339. }
  340. M *= res;
  341. }
  342. S += f[k] * M;
  343. }
  344. fOr[k] = S;
  345. }
  346. return fOr;
  347. }
  348. double* Consecutive( int procCount, double **f, int k )
  349. {
  350. double S;
  351. double *f2 = new double[k * procCount];
  352. double *f1 = new double[k * procCount];
  353. for( int i = 0; i < k * procCount; i++ )
  354. f1[i] = f2[i] = 0;
  355. for( int i = 0; i < k; i++ )
  356. f1[i] = f[0][i];
  357. for( int j = 2; j <= procCount; j++ ){
  358. for( int l = 1;l <= k * j; l++ ){
  359. S = 0;
  360. for( int m = 1; m <= k * procCount; m++ )
  361. if( m < l && m <= k * (j - 1) && l - m <= k )
  362. S += f1[m - 1] * f[j - 1][l - m - 1];
  363. f2[l - 1] = S;
  364. }
  365. for( int i = 0; i < k * j; i++ )
  366. f1[i] = f2[i];
  367. }
  368. delete f2;
  369. return f1;
  370. }
  371. /// Other stuff
  372. void InitMyMatrix( double** m, int dim )
  373. {
  374. if( dim < 8 ) return;
  375. for( int i = 0; i < dim; i++ )
  376. for( int j = 0; j < dim; j++ )
  377. m[i][j] = 0;
  378. m[0][1] = m[2][3] = m[3][4] = m[4][5] = m[7][7] = 1;
  379. m[1][2] = m[1][3] = m[5][4] = m[5][6] = 0.5;
  380. m[6][4] = m[6][7] = 0.5;
  381. //0{0.0, 1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  382. //1{0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0},
  383. //2{0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
  384. //3{0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
  385. //4{0.0, 0.0, 0.0, 0.0, 0.0, 1, 0.0, 0.0},
  386. //5{0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0},
  387. //6{0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5},
  388. //7{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}
  389. }
  390. /// EOF
Add Comment
Please, Sign In to add comment