qsadfasdgfgads

Untitled

Mar 13th, 2023
582
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.24 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <mpi.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #define N 1000
  8. #define START (-100)
  9. #define STOP (100)
  10. #define ITERATIONS_COUNT 10000
  11.  
  12. void calculateRightPart(int rank, const int *b_send_counts, const int *b_displs, const double *b, double *right_part) {
  13.     double *start_b = (double *)malloc(b_send_counts[rank] * sizeof(double));
  14.     MPI_Scatterv(b, b_send_counts, b_displs, MPI_DOUBLE, start_b, b_send_counts[rank], MPI_DOUBLE, 0, MPI_COMM_WORLD);
  15.     size_t local_sum = 0;
  16.     size_t global_sum = 0;
  17.     for (int i = 0; i < b_send_counts[rank]; i++) {
  18.         local_sum += start_b[i];
  19.     }
  20.     MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  21.  
  22.     double epsilon = powl(10, -5);
  23.  
  24.     if(rank == 0){
  25.         (*right_part) = global_sum * epsilon * epsilon;
  26.     }
  27.     MPI_Bcast(right_part, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  28.     free(start_b);
  29. }
  30.  
  31.  
  32. double * generate_double_arr(size_t n){
  33.     return (double *) malloc(n * sizeof(double));
  34. }
  35.  
  36. int * generate_int_arr(size_t n){
  37.     return (int *) malloc(n * sizeof(int));
  38. }
  39.  
  40. double* read_matrix_from_file(const char* filename) {
  41.     FILE* fp = fopen(filename, "r");
  42.     if (fp == NULL) {
  43.         printf("Error opening file %s\n", filename);
  44.         return NULL;
  45.     }
  46.  
  47.     size_t n;
  48.     fscanf(fp, "%zd", &n);
  49.     char c = fgetc(fp);
  50.  
  51.     // Allocate memory for the matrix
  52.     double* arr = generate_double_arr(n*n);
  53.  
  54.     // Read the matrix elements from the file
  55.     for (int i = 0; i < n; i++) {
  56.         for (int j = 0; j < n; j++) {
  57.             double res;
  58.             fscanf(fp, "%lf", &res);
  59.             arr[i* n + j] = res;
  60.             fgetc(fp);
  61.         }
  62.     }
  63.  
  64.     fclose(fp);
  65.     return arr;
  66. }
  67.  
  68. double* read_vector_from_file(const char* filename) {
  69.     FILE* fp = fopen(filename, "r");
  70.     if (fp == NULL) {
  71.         printf("Error opening file %s\n", filename);
  72.         return NULL;
  73.     }
  74.  
  75.     size_t n;
  76.     fscanf(fp, "%zd", &n);
  77.     fgetc(fp);
  78.  
  79.     // Allocate memory for the matrix
  80.     double* arr = generate_double_arr(n);
  81.  
  82.     // Read the matrix elements from the file
  83.     for (int i = 0; i < n; i++) {
  84.         double res;
  85.         fscanf(fp, "%lf", &res);
  86.         arr[i] = res;
  87.         fgetc(fp);
  88.     }
  89.  
  90.     fclose(fp);
  91.     return arr;
  92. }
  93.  
  94.  
  95.  
  96. void fill_vector_with_value(double *res, double value) {
  97.     for (size_t i = 0; i < N; i++) {
  98.         res[i] = value;
  99.     }
  100. }
  101.  
  102.  
  103. double multiple_row_and_column_vector(double *row, double *column, size_t size){
  104.     double res = 0;
  105.     for(size_t i = 0; i < size; i++){
  106.         res += row[i] * column[i];
  107.     }
  108.     return res;
  109. }
  110.  
  111. void print_vec(double *vec, size_t size){
  112.     for(size_t i = 0; i < size; i++){
  113.         printf("%lf\n", vec[i]);
  114.     }
  115.     printf("\n\n");
  116. }
  117.  
  118. void subtract_vectors(const double *vec1, const double *vec2, double *res, int size){
  119.     for(size_t i = 0; i < (size_t)size; i++){
  120.         res[i] = vec1[i] - vec2[i];
  121.     }
  122. }
  123.  
  124. void multiple_matrix_and_vector(const double *matrix, const double *vec, double *res){
  125.     memset(res, 0, sizeof(double) * N);
  126.     for(size_t i = 0; i < N; i++) {
  127.         for (size_t j = 0; j < N; j++) {
  128.             res[j] += matrix[j*N + i] * vec[i];
  129.         }
  130.     }
  131.  
  132. }
  133.  
  134. void calculate_vector_y(const double *matrix_a, double* x, double *b, double *res) {
  135.     multiple_matrix_and_vector(matrix_a, x, res);
  136.     subtract_vectors(res, b, res, N);
  137. }
  138.  
  139. int main(int argc, char ** argv){
  140.     int rank, size, n, rest;
  141.     MPI_Init( & argc, & argv);
  142.     MPI_Comm_size(MPI_COMM_WORLD, & size);
  143.     MPI_Comm_rank(MPI_COMM_WORLD, & rank);
  144.  
  145.     n = N / size;
  146.     rest = N % size;
  147.  
  148.     int * matrix_send_counts = generate_int_arr(size);
  149.     int *  matrix_displs = generate_int_arr(size);
  150.  
  151.     int *  b_send_counts = generate_int_arr(size);
  152.     int * b_displs = generate_int_arr(size);
  153.  
  154.     n = N / size;
  155.     rest = N % size;
  156.  
  157.     int offset = 0;
  158.     for (int i = 0; i < size; i++) {
  159.         matrix_send_counts[i] = N / size * N;
  160.         if (i < rest) {
  161.             matrix_send_counts[i] += N;
  162.         }
  163.         matrix_displs[i] = offset;
  164.         offset += matrix_send_counts[i];
  165.     }
  166.  
  167.  
  168.  
  169.     offset = 0;
  170.     for (int i = 0; i < size; i++) {
  171.         b_send_counts[i] = N / size;
  172.         if (i < rest) {
  173.             b_send_counts[i] += 1;
  174.         }
  175.         b_displs[i] = offset;
  176.         offset += b_send_counts[i];
  177.     }
  178.  
  179.     double *a, *b, *x, *y, *tau_y;
  180.     x = generate_double_arr(N);
  181.     if(rank == 0){
  182.         a = read_matrix_from_file("matrix.txt");
  183.         b = read_vector_from_file("vector.txt");
  184.         fill_vector_with_value(x, 0);
  185.         y = generate_double_arr(N);
  186.         tau_y = generate_double_arr(N);
  187.     }
  188.     double right_part;
  189.     calculateRightPart(rank, b_send_counts, b_displs, b, &right_part);
  190.  
  191.     if(rank == 0){
  192.         printf("%f", right_part);
  193.     }
  194.  
  195.     double *matrix_rec_row = generate_double_arr(matrix_send_counts[rank]);
  196.     double *vec_rec1 = generate_double_arr(b_send_counts[rank]);
  197.  
  198.     MPI_Scatterv(a, matrix_send_counts, matrix_displs, MPI_DOUBLE, matrix_rec_row, matrix_send_counts[rank], MPI_DOUBLE, 0, MPI_COMM_WORLD);
  199.     MPI_Bcast(x, N, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  200.     MPI_Scatterv(b, b_send_counts, b_displs, MPI_DOUBLE, vec_rec1, b_send_counts[rank], MPI_DOUBLE, 0, MPI_COMM_WORLD);
  201.  
  202.     int num_handle_rows = matrix_send_counts[rank] / N;
  203.  
  204.     //cout << num_handle_rows << "\n";
  205.  
  206.  
  207.     for(size_t i = 0; i < num_handle_rows; i++){
  208.         vec_rec1[i] = multiple_row_and_column_vector(&matrix_rec_row[num_handle_rows*i], x, b_send_counts[rank]) - vec_rec1[i*num_handle_rows];
  209.         //cout << b[i*N] << "\n";
  210.     }
  211.  
  212.     MPI_Gatherv(vec_rec1, num_handle_rows, MPI_DOUBLE, y, b_send_counts,  b_displs, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  213.  
  214.     if(rank == 0){
  215.         print_vec(y, 10);
  216.         double *kek = generate_double_arr(N);
  217.         calculate_vector_y(a, x, b, kek);
  218.         print_vec(kek, 10);
  219.         free(kek);
  220.     }
  221.  
  222.     free(matrix_send_counts);
  223.     free(b_send_counts);
  224.     free(matrix_displs);
  225.     free(b_displs);
  226.     free(matrix_rec_row);
  227.     free(vec_rec1);
  228.     if(rank == 0){
  229.         free(a);
  230.         free(b);
  231.         free(y);
  232.         free(tau_y);
  233.     }
  234.     MPI_Finalize();
  235. }
  236.  
  237.  
Advertisement
Add Comment
Please, Sign In to add comment