Guest User

Untitled

a guest
Apr 21st, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.05 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <omp.h>
  6.  
  7. // Default is 16 for each dimension
  8. static int N;
  9.  
  10. #define A(i,j) A[i*N+j] // A: N x N
  11. #define B(i,j) B[i*N+j] // B: N x N
  12. #define C(i,j) C[i*N+j] // C: N x N
  13. #define D(i,j) D[i*N+j] // D: N x N
  14.  
  15. static double *A, *B, *C, *D;
  16.  
  17. static void mm_base(double *A, double *B, double *C, int n)
  18. {
  19. int i, j, k;
  20.  
  21. for (i = 0; i < n; i++) {
  22. for (k = 0; k < n; k++) {
  23. for (j = 0; j < n; j++) {
  24. C(i,j) += A(i,k) * B(k,j);
  25. }
  26. }
  27. }
  28. }
  29.  
  30. #ifndef THRESHOLD
  31. #define THRESHOLD 4
  32. #endif
  33.  
  34. static void mm_dac(double *A, double *B, double *C, int size)
  35. {
  36. if (size <= THRESHOLD) {
  37. mm_base(A, B, C, size);
  38. } else {
  39. // Submatrix offsets
  40. int s11 = 0; // Upper left
  41. int s12 = size/2; // Upper right
  42. int s21 = (size/2) * N; // Lower left
  43. int s22 = (size/2) * N + size/2; // Lower right
  44.  
  45. // Recursive calls
  46. #pragma omp task
  47. mm_dac(A+s11, B+s11, C+s11, size/2); // C11 = A11 * B11
  48. #pragma omp task
  49. mm_dac(A+s11, B+s12, C+s12, size/2); // C12 = A11 * B12
  50. #pragma omp task
  51. mm_dac(A+s21, B+s11, C+s21, size/2); // C21 = A21 * B11
  52. mm_dac(A+s21, B+s12, C+s22, size/2); // C22 = A21 * B12
  53. #pragma omp taskwait
  54. #pragma omp task
  55. mm_dac(A+s12, B+s21, C+s11, size/2); // C11 += A12 * B21
  56. #pragma omp task
  57. mm_dac(A+s12, B+s22, C+s12, size/2); // C12 += A12 * B22
  58. #pragma omp task
  59. mm_dac(A+s22, B+s21, C+s21, size/2); // C21 += A22 * B21
  60. mm_dac(A+s22, B+s22, C+s22, size/2); // C22 += A22 * B22
  61. #pragma omp taskwait
  62. }
  63. }
  64.  
  65. static bool is_power_of_two(int n)
  66. {
  67. return n != 0 && (n & (n-1)) == 0;
  68. }
  69.  
  70. static bool equals(double *A, double *B)
  71. {
  72. int i, j;
  73.  
  74. for (i = 0; i < N; i++) {
  75. for (j = 0; j < N; j++) {
  76. if (A(i,j) != B(i,j)) {
  77. return false;
  78. }
  79. }
  80. }
  81.  
  82. return true;
  83. }
  84.  
  85. int main(int argc, char *argv[])
  86. {
  87. int i, j;
  88.  
  89. N = (argc > 1) ? atoi(argv[1]) : 16;
  90. assert(is_power_of_two(N));
  91.  
  92. // Allocate matrices
  93. A = (double *)malloc(N * N * sizeof(double));
  94. B = (double *)malloc(N * N * sizeof(double));
  95. C = (double *)malloc(N * N * sizeof(double));
  96. D = (double *)malloc(N * N * sizeof(double));
  97. assert(A && B && C && D);
  98.  
  99. // Setup matrix A
  100. for (i = 0; i < N; i++) {
  101. for (j = 0; j < N; j++) {
  102. A(i,j) = i * N + j + 1;
  103. }
  104. }
  105.  
  106. // Setup matrix B
  107. for (i = 0; i < N; i++) {
  108. for (j = 0; j < N; j++) {
  109. B(i,j) = (j >= i) ? 1 : 0;
  110. }
  111. }
  112.  
  113. // Setup matrices C and D
  114. for (i = 0; i < N; i++) {
  115. for (j = 0; j < N; j++) {
  116. C(i,j) = D(i,j) = 0.0;
  117. }
  118. }
  119.  
  120. #pragma omp parallel
  121. #pragma omp master
  122. mm_dac(A, B, C, N);
  123.  
  124. mm_base(A, B, D, N);
  125. assert(equals(C, D));
  126.  
  127. free(A);
  128. free(B);
  129. free(C);
  130. free(D);
  131.  
  132. return 0;
  133. }
Add Comment
Please, Sign In to add comment