mpi_scatterv不将任何值返回到recvbuf

MPI_Scatterv not returning any values to the recvbuf

本文关键字:返回 recvbuf 任何值 scatterv mpi      更新时间:2023-10-16

我正在尝试实现并行的QuickSort算法。不幸的是,我遇到了一些问题,只是分发数据。由于某种原因,调用MPI_Scatterv()函数后,我的list矢量没有被填充。

我对C 或指针一般不熟悉,所以我怀疑我的缓冲区可能是问题所在。代码的骨干来自这里。

实际代码:

// n-dimensional hypercube quicksorting program
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <math.h>
#include <time.h>       /* clock_t, clock, CLOCKS_PER_SEC */
using namespace std;
vector<int> parseInput(string _file);
void parseOutput(vector<int> _content, string _file);
void quickSort(vector<int>& a, int first, int last);
int pivot(vector<int>& a, int first, int last);
void swap(int& a, int& b);
string dec2bin(unsigned n);
int bin2dec(string s);
int main (int argc, char *argv[]){
    int rank, rank2, tasks;     // for storing this process' rank, and the number of processes
    int * sendcounts;    // array describing how many elements to send to each process
    int * displs;        // array describing the displacements where each segment begins
    int rem;                     // elements remaining after division among processes
    int sum = 0;                // Sum of counts. Used to calculate displacements
    clock_t t;          // timekeeping variable 
    vector<int> lists, list, l1, l2, c;
    string id, id2;
    int pivot;
    int d, x;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &tasks);
    MPI_Status *status;
    MPI_Request request;
    // the data to be distributed
    lists = parseInput("input.txt");
    // Allocating memory for the receiving buffers to a large engouh size to accomodate any incoming message.
    list.reserve(lists.size()/tasks);
    l1.reserve(lists.size()/tasks);
    l2.reserve(lists.size()/tasks);
    c.reserve(lists.size()/tasks);
    sendcounts = (int*) malloc(tasks * sizeof(int));
    displs = (int*) malloc(tasks * sizeof(int));
    // calculate send counts and displacements
    for (int i = 0; i < tasks; i++){
        sendcounts[i] = (lists.size())/tasks;
        rem =(lists.size())%tasks;
        if (rem > 0) {
            sendcounts[i]++;
            rem--;
        }
        displs[i] = sum;
        sum += sendcounts[i];
    }
    // print calculated send counts and displacements for each process
    if (0 == rank) {
        for (int i = 0; i < tasks; i++) {
            printf("sendcounts[%d] = %dtdispls[%d] = %dn", i, sendcounts[i], i, displs[i]);
        }
    }
    // divide the data among processes as described by sendcounts and displs
    MPI_Scatterv(&lists[0], sendcounts, displs, MPI_INT, &list[0], lists.size()/tasks, MPI_INT, 0, MPI_COMM_WORLD);
    cout << id << ": " << list.size() << endl;
    MPI_Finalize();
    free(sendcounts);
    free(displs);
    return 0;
}

parseInput()的代码将.txt文件带有由新行分开的整数并返回向量:

vector<int> parseInput(string _file){
    string filename = _file;
    vector<int> numbers;
    int number;
    ifstream inputFile(filename.c_str());
    if(inputFile){
        while(inputFile >> number){
            numbers.push_back(number);
        }
    } else {
        cout << "There was an error opening the file.";
    }
    inputFile.close();
    return numbers;
}

我已经在大脑中失去了几个小时,它所做的就是返回空矢量。老实说,任何帮助都将不胜感激。

基于此代码,我不确定您的MPI_Scatterv调用应该做什么。看起来您正在尝试阅读数据,然后通过MPI_Scatterv函数将其分配给作业中的所有过程。但是,看来所有过程实际上都在文件中从文件中读取的数据,因此MPI_Scatterv调用没有真正的原因。

您可能需要重组您的代码以确保:

  1. 只有等级0是读取数据,然后将其分配给所有过程。或...

  2. 每个人都在阅读数据,他们只能挑出哪一部分对他们很重要。

如果您选择#1,请确保正确填充了RecvCBONT变量。如果每个人都无法访问lists.size(),则会引起问题。