0

我正在努力修改一个程序,该程序将两个文件作为输入(每个文件代表一个向量)并计算它们之间的点积。它应该并行完成,但有人告诉我,每个文件中的点数可能无法被可用处理器的数量整除,并且每个进程可能从文件中的错误位置读取。我的意思是,如果有四个处理器,前 250 个点可能会被正确读取和计算,但第二个处理器可能会读取相同的 250 个点并提供不正确的结果。这是我到目前为止所做的。我所做的任何修改都会被记录下来。

#include "fstream"
#include "stdlib.h"
#include "stdio.h"
#include "iostream"
#include "mpi.h"

int main(int argc, char *argv[]){

  MPI_Init(&argc, argv);

  //parse command line arguments
  if( argc < 3 || argc > 3){
    std::cout << "*** syntax: " << argv[0] << " vecFile1.txt vecFile2.txt" << std::endl;
    return(0);
  }

  //get input file names
  std::string vecFile1(argv[1]);
  std::string vecFile2(argv[2]);

  //open file streams
  std::ifstream vecStream1(vecFile1.c_str());
  std::ifstream vecStream2(vecFile2.c_str());

  //check that streams opened properly
  if(!vecStream1.is_open() || !vecStream2.is_open()){
    std::cout << "*** Could not open Files ***" << std::endl;
    return(0);
  }

  //if files are open read their lengths and make sure they are compatible
  long vecLength1 = 0; vecStream1 >> vecLength1;
  long vecLength2 = 0; vecStream2 >> vecLength2;

  if( vecLength1 != vecLength2){
    std::cout << "*** Vectors are no the same length ***" << std::endl;
    return(0);
  }

  int numProc;    //New variable for managing number of processors
  MPI_Comm_size(&numProc,MPI_COMM_WORLD);    //Added line to obtain number of processors
  int subDomainSize = (vecLength1+numProc-1)/numProc;    //Not sure if this is correct calculation; meant to account for divisibility with remainders



  //read in the vector components and perform dot product
  double dotSum = 0.;
  for(long i = 0; i < subDomainSize; i++){    //Original parameter used was vecLength1; subDomainSize used instead for each process
    double ind1 = 0.; vecStream1 >> ind1;
    double ind2 = 0.; vecStream2 >> ind2;

    dotSum += ind1*ind2;
  }

  std::cout << "VECTOR DOT PRODUCT: " << dotSum << std::endl;
  MPI_Finalize();
}

除了这些变化,我不知道从这里去哪里。我可以做些什么来使这个程序使用并行处理以两个文本文件作为输入来正确计算两个向量的点积?每个包含 100000 个点,因此手动修改文件是不切实际的。

4

1 回答 1

1

我不会在这里写代码,因为它似乎是一个分配问题,但我会尝试给你一些提示,让你朝着正确的方向前进。

  1. 每个处理器都有一个分配的等级,可以使用MPI_Comm_rank API 找到。因此,对于并行处理,您可以在处理器之间划分文件的向量,以便具有等级的处理器r将向量处理r*subdomainsize(r+1)*subdomainsize - 1.
  2. 您需要确保特定处理器从文件中读取来自正确位置的向量。使用seek api转到正确的偏移量,然后调用文件流的 read(>>) 运算符。
  3. 对于计算子域大小,我不确定您提到的方程式是否有效。可以有几种方法。最简单的就是使用vectorlength/numProcas subdomainsize。每个处理器都可以处理subdomainsize元素,但是最后一个处理器(rank == numProc)将处理剩余的元素。
  4. 在 for 循环之后,您应该使用归约操作从处理器收集各个总和,并将其全局汇总以获得最终结果。请参阅MPI_Reduce
  5. 使用Barrier在处理器之间进行同步。必须在 for 循环之后和调用归约之前放置屏障。
于 2014-07-03T00:17:49.340 回答