MPI中的图像处理

MPI中的图像处理,mpi,Mpi,这是我在MPI中编写经典平滑像素平均算法的尝试。我几乎让它工作了,但是光环交换发生了一些奇怪的事情,因为可以看到边缘的线条。我好像找不到窃听器。我是否正确地交换光环?我应该收集最终阵列的哪个部分 int next=rank+1; int prev=排名-1; 如果(下一步>=大小){ next=MPI\U PROC\U NULL; } 如果(上一个

这是我在MPI中编写经典平滑像素平均算法的尝试。我几乎让它工作了,但是光环交换发生了一些奇怪的事情,因为可以看到边缘的线条。我好像找不到窃听器。我是否正确地交换光环?我应该收集最终阵列的哪个部分

int next=rank+1;
int prev=排名-1;
如果(下一步>=大小){
next=MPI\U PROC\U NULL;
}
如果(上一个<0){
prev=MPI\u PROC\u NULL;
}
int行=y/px;
int cols=x;
int d=1;
对于(int-iter=0;iter对于(int p=iMin;pOK),这里有很多问题

首先,由于只交换深度为1的光晕,因此代码只能使用d=1。如果要处理距离为d的邻居,则需要交换深度为d的光晕

其次,在第一次扫描阵列后进行第一次光晕交换,因此在迭代1中读取垃圾光晕数据-在开始处理阵列之前,需要进行光晕交换

第三,当你把新的复制回旧的时候,你从索引2开始:你需要包括从1到lrows和从1到lcols的所有像素

最后,你的Imin,Imax等的逻辑似乎是错误的。你不想在并行程序中截断边上的范围-你需要离开边来获取光晕数据。我只是设置Imin=-d,Imax=d等

通过这些修复,代码似乎运行正常,即没有明显的光环效应,但在不同数量的进程上仍然会给出不同的结果


PS我也很高兴看到您使用了我自己的MPI示例中的“ArrayAlloc2D”代码;我很高兴看到这些培训代码对人们很有用!

初始化中有一个错误-新的[I][j x rgb+c]=0应该是“+k”。您没有给我们足够的信息来调试代码,因为您没有说,例如,什么“prev”和“next”是。但是,我猜聚集是错误的-您希望聚集旧阵列的内部(不包括光晕),但实际上是从[0][0]开始收集截面这还包括一些光环和边缘数据。@DavidHenty谢谢。我已经更新了我的问题并修复了打字错误。你是对的,聚集似乎是错误的,但我不知道收集什么。这应该是
MPI\u聚集(&old[1][1],rows*cols*rgb,MPI\u INT,&Finalbuffer[0][0],rows*cols*rgb,MPI_INT,0,MPI_COMM_WORLD);
请编辑您的帖子并添加一个。同时,仔细检查您的数据是否在连续内存中。这不起作用,因为聚集将收集连续数据和“旧”区域的核心(即不包括光环的中心)是不连续的。正如@GillesGouaillardet指出的,这个问题的解决方案取决于原始数组是否是连续分配的(如果使用了“malloc”,则可能不是).@DavidEnty数组是连续分配的。我必须说,这只适用于1个列组。当使用多个列组时,我可以看到分割分解的线条。但是图像构建正确,但不完全相同。@U David Henty我无法修复它。你介意分享你的更改吗?理论上,所有输出都应该相同。我不明白。。。我正在检查我的代码,但它为多个进程生成了无效的图像。我重新运行了您的原始代码,并获得了相同的效果。您可以让我访问您的测试PNG输入文件,并确切说明您在运行时使用的参数吗?@_DavidHenty要运行此
/binary input.PNG output.PNG 25 1
。您不能向我们咨询吗我上传的PNG文件是什么?
int next = rank + 1;
int prev = rank - 1;

if (next >= size) {
  next = MPI_PROC_NULL;
}

if (prev < 0) {
  prev = MPI_PROC_NULL;
}

int rows = y / px;
int cols = x;
int d = 1;

for (int iter = 0; iter < TotalIter; iter++) {
  for (int i = 0; i < rows + 2; i++)
    for (int j = 0; j < cols + 2; j++)
      for (int k = 0; k < rgb; k++)
        new[i][j * rgb + k] = 0;

  for (int i = 1; i < rows + 1; i++) {

    int iMin = -min(d, i - 1);
    int iMax = min(d, (rows + 1 - i - 1));

    for (int j = 1; j < cols + 1; j++) {
      int jMin = -min(d, j - 1);
      int iMax = min(d, (cols + 1 - j - 1));

      int counter = 0;

      for (int p = iMin; p <= iMax; p++)
        for (int q = jMin; q <= jMax; q++) {
          counter = counter + 1;
          for (int k = 0; k < rgb; k++) {
            new[i][j * rgb + k] += old[i + p][(j + q) * rgb + k];
          }
        }

      for (int k = 0; k < rgb; k++) {
        new[i][j * rgb + k] -= old[i][j * rgb + k];
        new[i][j * rgb + k] /= (counter - 1);
      }
    }
  }

  for (int i = 2; i < rows; i++)
    for (int j = 2; j < cols; j++)
      for (int k = 0; k < rgb; k++) {
        old[i][j * rgb + k] = new[i][j * rgb + k];
      }

  MPI_Sendrecv(&old[rows][1], cols * rgb, MPI_INT, next, 1, &old[0][1],
               cols * rgb, MPI_INT, prev, 1, MPI_COMM_WORLD, &status);

  MPI_Sendrecv(&old[1][1], cols * rgb, MPI_INT, prev, 2, &old[rows + 1][1],
               cols * rgb, MPI_INT, next, 2, MPI_COMM_WORLD, &status);
}

 for (int i = 1; i< rows+1; i++)
    for (int j = 1; j< cols+1; j++)
        for (int k = 0; k< rgb; k++) {
           buf[i-1][(j-1)*rgb+k] =  old[i][j*rgb+k] ;
         }

MPI_Gather(&buf[0][0], rows *cols *rgb, MPI_INT, &Finalbuffer[0][0],
           rows *cols *rgb, MPI_INT, 0, MPI_COMM_WORLD);