/05 Lastverteilung/apfelseq.c

https://bitbucket.org/martin_weidner/paralleleprogrammierung · C · 151 lines · 93 code · 26 blank · 32 comment · 18 complexity · 6ec85e10ddc7a5ce060be9f400d254b7 MD5 · raw file

  1. /* (c) 1997 Ingo Boesnach */
  2. /* mandelbrot set (serial version)
  3. * argv[1]: smallest real part considered
  4. * argv[2]: smallest imaginary part considered
  5. * argv[3]: extent of square area considered
  6. * argv[4]: resolution
  7. * argv[5]: maximum number of interations
  8. * argv[6]: display
  9. * e.g. "poe a.out -procs 2 -1.5 -1 2 400 200 i90s14.ira.uka.de:0.0"
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <complex.h>
  14. #include <assert.h>
  15. #include "mpi.h"
  16. #include "random.h"
  17. #include "bitmap.h"
  18. #define DISPLAY 1
  19. int iProc, nProc;
  20. #define komplex double _Complex
  21. typedef struct {int start; int end; } Work;
  22. /*********** Mandelbrot specific code ******************************/
  23. #define LARGE 2.0
  24. komplex z0;
  25. double extent; /* a_0 in the book */
  26. int resolution; /* n in the book */
  27. double step; /* a_0/n */
  28. int maxiter; /* m_max in the book */
  29. int withgraph; /* Flag: display results ? */
  30. komplex _complex(double i, double j){
  31. return i + j * _Complex_I;
  32. }
  33. /* perform a single Mandelbrot iteration starting at c and return
  34. * number of iterations
  35. */
  36. int iterate(int pos)
  37. {
  38. int iter;
  39. komplex c = z0 + _complex((double)(pos % resolution) * step,
  40. (double)(pos / resolution) * step);
  41. komplex z = c;
  42. for (iter = 1; iter < maxiter && abs(z) <= LARGE; iter++) z = z*z + c;
  43. return iter;
  44. }
  45. /*********** Server Code **********************/
  46. void server(char *display)
  47. { int i, x, y, length;
  48. MPI_Status status;
  49. int *recvBuffer = (int*)malloc(resolution * resolution * sizeof(int));
  50. assert(recvBuffer != 0);
  51. if(withgraph) bitmapInit(resolution, resolution, display, "blub");
  52. /* Get an interval size and a sequence of integers
  53. * encoding one element of the Mandelbrot set each.
  54. * The interval size can be ignored here.
  55. * But we need it in some parallel codes
  56. * using the same data format.
  57. */
  58. MPI_Recv(recvBuffer, resolution*resolution, MPI_INT,
  59. MPI_ANY_SOURCE, DISPLAY, MPI_COMM_WORLD, &status);
  60. MPI_Get_count(&status, MPI_INT, &length);
  61. printf("plotting %d pixels out of %d\n", length-1, recvBuffer[0]);
  62. for (i = 1; i < length; i++) {
  63. x = recvBuffer[i] % resolution;
  64. y = recvBuffer[i] / resolution;
  65. bitmapSetPixel(x, resolution - y - 1);
  66. /* remember: (0,0) of bitmap corresponds to complex (z0 + i*n) */
  67. }
  68. if(withgraph) bitmapDisplay();
  69. free(recvBuffer);
  70. }
  71. /*********** Worker Code **********************/
  72. /* work on an interval of integers representing candidate elements
  73. * of the Mandelbrot set.
  74. */
  75. void worker(Work work)
  76. {
  77. int elem;
  78. int *result;
  79. /* contains interval size and a sequence of integers encoding one element of
  80. * the Mandelbrot set each
  81. */
  82. result = (int*)malloc(resolution * resolution * sizeof(int) + 1);
  83. assert(result != 0);
  84. elem = 1;
  85. result[0] = work.start; /* remember where this interval started */
  86. printf("starting work on %d to %d\n", work.start, work.end);
  87. for (; work.start <= work.end; work.start++) {
  88. if (iterate(work.start) == maxiter) {
  89. /* we assume to have an element of the Mandelbrot set here */
  90. result[elem] = work.start;
  91. elem++;
  92. }
  93. }
  94. /* send results to server */
  95. result[0] = work.end - result[0] + 1;
  96. MPI_Send(result, elem, MPI_INT, 0, DISPLAY, MPI_COMM_WORLD);
  97. free(result);
  98. }
  99. /*********************************************************************/
  100. int main(int argc, char **argv)
  101. { Work work;
  102. MPI_Init(&argc, &argv);
  103. assert(argc >= 6);
  104. assert(argc <= 7);
  105. z0 = _complex(atof(argv[1]), atof(argv[2]));
  106. extent = atof(argv[3]);
  107. resolution = atoi(argv[4]);
  108. step = extent / resolution;
  109. maxiter = atoi(argv[5]);
  110. if(argc == 6) withgraph = 0; else withgraph = 1;
  111. MPI_Comm_size(MPI_COMM_WORLD, &nProc);
  112. assert(nProc == 2);
  113. MPI_Comm_rank(MPI_COMM_WORLD, &iProc);
  114. if(iProc == 0) server(argv[6]);
  115. else {
  116. work.start = 0;
  117. work.end = resolution*resolution - 1;
  118. worker(work);
  119. }
  120. if(!iProc)
  121. printf("Enter q to close.\n");
  122. getchar();
  123. MPI_Finalize();
  124. return 0;
  125. }