Untitled

mail@pastecode.io avatar
unknown
c_cpp
4 years ago
5.2 kB
6
Indexable
Never
#include <iostream>
#include <fstream>
#include "mpi.h"
#include <vector>
#include <ctime>
using namespace std;

void printVector(vector<int> givenVector) {
    for (int i = 0; i < givenVector.size(); i++) {
        cout << givenVector[i] << " ";
    }
    cout << endl;
}

void readFile(string fileName, vector<int>& number) {
    ifstream f(fileName);
    int N, nr;
    f >> N;
    while (N > 0) {
        f >> nr;
        number.push_back(nr);
        N--;
    }
}

void addZeros(int nrProcese, vector<int>& firstNumber, vector<int>& secondNumber) {
    while (firstNumber.size() > secondNumber.size()) {
        secondNumber.insert(secondNumber.begin(), 0);
    }
    while (secondNumber.size() > firstNumber.size()) {
        firstNumber.insert(firstNumber.begin(), 0);
    }

    while (firstNumber.size() % nrProcese != 0) {
        firstNumber.insert(firstNumber.begin(), 0);
        secondNumber.insert(secondNumber.begin(), 0);
    }
}

void addZerosBefore(int nrProcese, vector<int>& firstNumber, vector<int>& secondNumber) {
    while (firstNumber.size() > secondNumber.size()) {
        secondNumber.push_back(0);
    }
    while (secondNumber.size() > firstNumber.size()) {
        firstNumber.push_back(0);
    }

    while (firstNumber.size() % nrProcese != 0) {
        firstNumber.push_back(0);
        secondNumber.push_back(0);
    }
}

void removeZeros(vector<int>& number) {
    while (number[0] == 0) {
        number.erase(number.begin());
    }
}

// ****************************************************************************************************
// VARIANTA 0
// ****************************************************************************************************

void varianta0() {

    clock_t startTime, endTime;
    startTime = clock();

    vector<int> firstNumberRO, secondNumberRO, sum;
    readFile("Numar1.txt", firstNumberRO);
    readFile("Numar2.txt", secondNumberRO);
    addZeros(5, firstNumberRO, secondNumberRO);

    printVector(firstNumberRO);
    printVector(secondNumberRO);

    int size1 = firstNumberRO.size();
    int size2 = secondNumberRO.size();
    int carry = 0;

    while (size1) {
        int aux = firstNumberRO[size1 - 1] + secondNumberRO[size2 - 1] + carry;
        carry = aux / 10;
        sum.push_back(aux % 10);
        size1--;
        size2--;
    }

    reverse(sum.begin(), sum.end());
    removeZeros(sum);
    printVector(sum);

    endTime = clock();
    cout<< endl <<"TIMP:";
    cout << (double)(endTime - startTime) / CLOCKS_PER_SEC * 1000; //milisecunde
}

// ****************************************************************************************************
// VARIANTA 1
// ****************************************************************************************************

void varianta1() {
    int buf;
    int rc, nr_procese, rank;
    vector<int> a, b, c, a_local, b_local, c_local;
    int nr_elem;
    MPI_Status stare;

    clock_t startTime, endTime;
    startTime = clock();

    rc = MPI_Init(NULL, NULL);
    if (rc != MPI_SUCCESS) {
        cout << "Eroare initializare\n";
        MPI_Abort(MPI_COMM_WORLD, rc);
    }

    MPI_Comm_size(MPI_COMM_WORLD, &nr_procese);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);


    int carryFlag = 0;

    if (rank == 0) {

        readFile("Numar1.txt", a);
        readFile("Numar2.txt", b);
        // printVector(a);

        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());

        addZerosBefore(nr_procese, a, b);

        /// PRINT REVERSED NUMBERS
        // printVector(a);
        // printVector(b);

        c.resize(a.size() + 1);
        nr_elem = a.size() / nr_procese;
    }

    MPI_Bcast(&nr_elem, 1, MPI_INT, 0, MPI_COMM_WORLD);


    a_local.resize(nr_elem);
    b_local.resize(nr_elem);
    c_local.resize(nr_elem);
    MPI_Scatter(a.data(), nr_elem, MPI_INT, a_local.data(), nr_elem, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Scatter(b.data(), nr_elem, MPI_INT, b_local.data(), nr_elem, MPI_INT, 0, MPI_COMM_WORLD);

    // Receive carry flag from last process
    if (rank > 0) {
        MPI_Recv(&carryFlag, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD, &stare);
        c_local[0] = carryFlag;
    }

    for (int i = 0; i < nr_elem; i++) {
        int aux = a_local[i] + b_local[i] + carryFlag;
        c_local[i] = aux % 10;
        carryFlag = aux / 10;
    }

    // Send unless last process
    if (rank + 1 != nr_procese) {
          MPI_Send(&carryFlag, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
    }

    // Only for Visual Studio Run
    if (nr_procese == 1) {

      c_local.resize(nr_elem + 1);

      c_local[nr_elem] = carryFlag;
      nr_elem ++;
    }


    MPI_Gather(c_local.data(), nr_elem, MPI_INT, c.data(), nr_elem, MPI_INT, 0, MPI_COMM_WORLD);

    if (rank == 0) {
        reverse(c.begin(), c.end());
        removeZeros(c);

        ofstream output("Numar3.txt");

        for (int i = 0; i < c.size(); i++) {
            cout << c[i] << "";
            output << c[i] << "";
        }
        output.close();
    }

    endTime = clock();
    cout<< endl <<"TIMP:";
    cout << (double)(endTime - startTime) / CLOCKS_PER_SEC * 1000; //milisecunde

    MPI_Finalize();
}