• 基于 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();
    
    }
    

    运行截图:

  • 相关阅读:
    Ubuntu分区挂载
    YOLOv3:Demo needs OpenCV for webcam images
    tf.strided_slice函数
    numpy:np.random.seed()
    python:split()函数
    python:set() 函数
    python:zip() 函数
    python:enumerate 函数
    电脑无法上网,DNS出现fec0:0:0:ffff::1%1问题
    python:map 函数
  • 原文地址:https://www.cnblogs.com/justsong/p/12219728.html
Copyright © 2020-2023  润新知