Guest User

Untitled

a guest
Feb 11th, 2023
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.79 KB | None | 0 0
  1. #include <iostream>
  2. #include "mpi.h"
  3. #include <random>
  4. #include <cassert>
  5.  
  6. using namespace std;
  7.  
  8. //#define VECTOR_SIZE 200000
  9. #define VECTOR_SIZE 21
  10.  
  11.  
  12. inline int generateRandomInRange(int a, int b) {
  13.     random_device rd;
  14.     uniform_int_distribution gen(a, b);
  15.     return gen(rd);
  16. }
  17.  
  18. void fill_vector_values(int *vec){
  19.     for(size_t i = 0; i < VECTOR_SIZE; i++){
  20.         vec[i] = generateRandomInRange(1, 100);
  21.     }
  22.  
  23. }
  24.  
  25.  
  26. void print_vec(int *vec, int n){
  27.     for(size_t i = 0; i < n; i++){
  28.         std::cout << vec[i] << endl;
  29.     }
  30.  
  31. }
  32.  
  33.  
  34. int calculate(const int *vec1, const int *vec2){
  35.     int res = 0;
  36.     for (int i = 0; i < VECTOR_SIZE; i++){
  37.         for (int j = 0; j < VECTOR_SIZE; j++){
  38.             res += vec1[i] * vec2[j];
  39.         }
  40.     }
  41.     return res;
  42. }
  43.  
  44.  
  45.  
  46. int main(int argc, char **argv){
  47.     int rank, size;
  48.     int VEC_SIZE = VECTOR_SIZE;
  49.  
  50.  
  51.     MPI_Init(&argc, &argv);
  52.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  53.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  54.     size_t sub_size = VEC_SIZE / size;
  55.     size_t rest = VEC_SIZE % size;
  56.  
  57.  
  58.     int curr_res = 0;
  59.  
  60.     auto* received_vec1 = new int[sub_size];
  61.     auto* received_vec2  = new int[VECTOR_SIZE];
  62.  
  63.     if(rank == 0) {
  64.         int result = 0;
  65.         std::cout << sub_size << " " << rest << endl;
  66.  
  67.         auto *vec1 = new int[VECTOR_SIZE];
  68.         auto *vec2 = new int[VECTOR_SIZE];
  69.  
  70.  
  71.         fill_vector_values(vec1);
  72.         fill_vector_values(vec2);
  73.  
  74.  
  75.         MPI_Scatter(vec1, sub_size, MPI_INT, received_vec1, sub_size, MPI_INT, 0, MPI_COMM_WORLD);
  76.    
  77.  
  78.         MPI_Bcast(vec2, (int)VEC_SIZE, MPI_INT, 0, MPI_COMM_WORLD);
  79.  
  80.    
  81.      
  82.         for(size_t i = 0; i < rest; i++){
  83.  
  84.             //std::cout << sub_size*size + i << endl;
  85.             if(i == 0){
  86.                 for(size_t j = 0; j < VECTOR_SIZE; j++){
  87.                     result += vec1[sub_size*size + i]*vec2[j];
  88.                 }
  89.                 continue;
  90.             }
  91.  
  92.             MPI_Send(&vec1[sub_size*size + i], 1, MPI_INT, (int)i, (int)i, MPI_COMM_WORLD);
  93.             MPI_Send(vec2, VEC_SIZE, MPI_INT, (int)i, (int)i, MPI_COMM_WORLD);
  94.         }
  95.  
  96.      
  97.         for(size_t i = 0; i < sub_size; i++){
  98.             int fixed_el = vec1[i];
  99.             //std::cout << i << endl;
  100.             for(size_t j = 0; j < VECTOR_SIZE; j++){
  101.                 result += fixed_el*vec2[j];
  102.             }
  103.         }
  104.  
  105.        
  106.  
  107.         MPI_Reduce(&result, &curr_res, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
  108.  
  109.    
  110.  
  111.         std::cout << "Result " << result << endl;
  112.         std::cout << "calculate " << calculate(vec1, vec2) << endl;
  113.  
  114.         delete []vec1;
  115.         delete []vec2;
  116.     }
  117.  
  118.     if(rank != 0){
  119.         MPI_Recv(received_vec1, (int)sub_size, MPI_INT, 0, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  120.         MPI_Recv(received_vec2, VEC_SIZE, MPI_INT, 0, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  121.  
  122.  
  123.         for(size_t i = 0; i < sub_size; i++){
  124.             int fixed_el = received_vec1[i];
  125.             for(size_t j = 0; j < VECTOR_SIZE; j++){
  126.                 curr_res += fixed_el*received_vec2[j];
  127.             }
  128.         }
  129.  
  130.  
  131.         if(rank + 1 <= rest){
  132.          
  133.             MPI_Recv(received_vec1, (int)sub_size, MPI_INT, 0, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  134.             MPI_Recv(received_vec2, VEC_SIZE, MPI_INT, 0, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  135.  
  136.             for(size_t i = 0; i < sub_size; i++){
  137.                 int fixed_el = received_vec1[i];
  138.                 for(size_t j = 0; j < VECTOR_SIZE; j++){
  139.                     curr_res += fixed_el*received_vec2[j];
  140.                 }
  141.             }
  142.         }
  143.        
  144.  
  145.  
  146.         MPI_Send(&curr_res, 1, MPI_INT, 0, rank, MPI_COMM_WORLD);
  147.  
  148.     }
  149.  
  150.  
  151.     delete []received_vec1;
  152.     delete []received_vec2;
  153.     MPI_Finalize();
  154.  
  155.     return 0;
  156. }
  157.  
Advertisement
Add Comment
Please, Sign In to add comment