基于 MPI 的快速排序算法的实现

完整代码:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <mpi.h>

using namespace std;

struct Pair {
    int left;
    int right;
};

const int MAX_PROCESS = 128;
const int NUM = 8000;
const int MAX = 1000000;
const int MIN = 0;

int arr[NUM];
int temp[NUM];

Pair pairs[MAX_PROCESS];

int counter = -1;

void swap(int A[], int i, int j) {
    int temp = A[i];
    A[i] = A[j];
    A[j] = temp;
}

int findpivot(int i, int j) {
    return (i + j) / 2;
}

int partition(int A[], int l, int r, int pivot) {
    do {
        while (A[++l] < pivot);
        while ((r != 0 && (A[--r] > pivot)));
        swap(A, l, r);
    } while (l < r);
    swap(A, l, r);
    return l;
}

void quicksort(int A[], int i, int j, int currentdepth, int targetdepth) {
    if (currentdepth == targetdepth) {
        int rank = ++counter;
        pairs[rank].left = i;
        pairs[rank].right = j;
        cout << pairs[rank].left << " and " << pairs[rank].right << " : rank " << rank << endl;
        return;
    }
    if (j <= i) return;
    int pivotindex = findpivot(i, j);
    swap(A, pivotindex, j);
    int k = partition(A, i - 1, j, A[j]);
    swap(A, k, j);
    quicksort(A, i, k - 1, currentdepth + 1, targetdepth);
    quicksort(A, k + 1, j, currentdepth + 1, targetdepth);
}

void quicksort(int A[], int i, int j) {
    if (j <= i) return;
    int pivotindex = findpivot(i, j);
    swap(A, pivotindex, j);
    int k = partition(A, i - 1, j, A[j]);
    swap(A, k, j);
    quicksort(A, i, k - 1);
    quicksort(A, k + 1, j);
}

int main(int argc, char* argv[]) {
    MPI_Init(&argc, &argv);
    int RANK, SIZE, targetdepth, left, right, REAL_SIZE;

    MPI_Comm_rank(MPI_COMM_WORLD, &RANK);
    MPI_Comm_size(MPI_COMM_WORLD, &SIZE);
    REAL_SIZE = SIZE;
    if (RANK == 0) {
        cout << "Quick sort start..." << endl;
        cout << "Generate random data... ";

        memset(arr, 0, NUM * sizeof(arr[0]));
        srand(time(NULL));
        for (int i = 0; i < NUM; i++) {
            arr[i] = MIN + rand() % (MAX - MIN);
        }
        cout << "Done." << endl;
        targetdepth = log2(SIZE);
        cout << "Rank: " << RANK << endl;
        cout << "Sorting... ";
        quicksort(arr, 0, NUM - 1, 0, targetdepth);
        REAL_SIZE = counter + 1;
        for (int i = 1; i < SIZE; i++) {
            int left = pairs[i].left;
            int right = pairs[i].right;
            MPI_Send(&REAL_SIZE, 1, MPI_INT, i, 99, MPI_COMM_WORLD);
            MPI_Send(&left, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
            MPI_Send(&right, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
            MPI_Send(&arr, NUM, MPI_INT, i, 2, MPI_COMM_WORLD);
        }

        left = pairs[0].left;
        right = pairs[0].right;
        quicksort(arr, left, right);
        cout << "Process " << RANK <<" done."<< endl;
    }

    for (int process = 1; process < REAL_SIZE; process++) {
        if (RANK == process) {
            MPI_Status status;
            MPI_Recv(&REAL_SIZE, 1, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);
            MPI_Recv(&left, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
            MPI_Recv(&right, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
            MPI_Recv(&arr, NUM, MPI_INT, 0, 2, MPI_COMM_WORLD, &status);
            if (process < REAL_SIZE) {
                quicksort(arr, left, right);
                MPI_Send(&arr, NUM, MPI_INT, 0, 0, MPI_COMM_WORLD);
                cout << "Process " << RANK << " done." << endl;
            }
        }
    }

    if (RANK == 0) {
        for (int i = 1; i < REAL_SIZE; i++) {
            //cout << "Master is ready to receive data from process " << i << endl;
            MPI_Status status;
            MPI_Recv(&temp, NUM, MPI_INT, i, 0, MPI_COMM_WORLD, &status);
            for (int j = pairs[i].left; j <= pairs[i].right; j++) {
                arr[j] = temp[j];
            }
            //cout << "Master has combined data from process " << i << endl;
        }
        cout << "Done." << endl;
        cout << "Result:" << endl;
        int counter = 1;
        int row = 20;

        for (int i = 0; i < NUM; i++, counter++) {
            cout << arr[i] << " ";
            if (arr[i] < arr[max(i - 1, 0)]) {
                cerr << "Invalid! " << arr[i] << " > "<< arr[max(i - 1, 0)] <<" i is "<< i << endl;
            }
            if (counter % row == 0) cout << endl;
        }
    }
    MPI_Finalize();

}

运行截图:

猜你喜欢

转载自www.cnblogs.com/justsong/p/12219728.html
mpi