【发布时间】:2013-12-24 05:58:50
【问题描述】:
我是 mpi 新手。我正在尝试使用 mpi 并行化我的代码(需要更快地运行一些实验)。它应该像这样工作:master 向从属发送一个字符串数组,它们做一些工作并将 status_ready 发送回主控。当所有从设备都准备好时,主设备进入一个循环并迭代地向从设备发送一个双精度向量,从设备处理这个向量并将它们的结果(2 个向量)发送回主设备。当收到所有 tje 消息时,master 将对其进行处理并循环迭代(master 将结果发送给 slave 等)它应该像这样工作
#include <iostream>
#include <mpi.h>
#include <cmath>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
//int mod(int z, int l);
int xGradient(Mat image, int x, int y)
{
return image.at<uchar>(y-1, x-1) +
2*image.at<uchar>(y, x-1) +
image.at<uchar>(y+1, x-1) -
image.at<uchar>(y-1, x+1) -
2*image.at<uchar>(y, x+1) -
image.at<uchar>(y+1, x+1);
}
int yGradient(Mat image, int x, int y)
{
return image.at<uchar>(y-1, x-1) +
2*image.at<uchar>(y-1, x) +
image.at<uchar>(y-1, x+1) -
image.at<uchar>(y+1, x-1) -
2*image.at<uchar>(y+1, x) -
image.at<uchar>(y+1, x+1);
}
int main()
{
Mat src, grey, dst;
double start, end;
int i, gx, gy, sum, argc, awal,akhir, size, rank, slave;
int master=0;
char **argv;
// MPI_Status status;
awal= MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
slave=size-1;
start=MPI_Wtime();
if( rank == master )
{
// start=MPI_Wtime();
src= imread("E:/tigaout/Debug/jari.jpg");
cvtColor(src,grey,CV_BGR2GRAY);
//MPI_Send(&(row_pointers[i*share+done][0]), 1, newtype, i, 1, MPI_COMM_WORLD);
dst = grey.clone();
if( !grey.data )
{
return -1;
}
for (i=1; i<slave; i++)
{
MPI_Send(&dst, 1, MPI_DOUBLE, i, 1, MPI_COMM_WORLD);
cout<<"master mengirim data ke rank 1"<<dst<<endl;
}
}
MPI_Barrier(MPI_COMM_WORLD);
if (rank != master)
{
MPI_Recv(&dst, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
cout<<"rank 1 menerima data"<<dst<<endl;
}
for(int y = 0; y < grey.rows; y++)
for(int x = 0; x < grey.cols; x++)
dst.at<uchar>(y,x) = 0;
for(int y = 1; y < grey.rows - 1; y++)
{
for(int x = 1; x < grey.cols - 1; x++)
{
gx = xGradient(grey, x, y);
gy = yGradient(grey, x, y);
sum = abs(gx) + abs(gy);
sum = sum > 255 ? 255:sum;
sum = sum < 0 ? 0 : sum;
dst.at<uchar>(y,x) = sum;
}
}
/* namedWindow("deteksi tepi sobel");
imshow("deteksi tepi sobel", dst);
namedWindow("grayscale");
imshow("grayscale", grey);
namedWindow("Original");
imshow("Original", src);*/
imwrite( "E:/tigaout/Debug/deteksi jari.jpg", dst );
MPI_Barrier(MPI_COMM_WORLD);
end=MPI_Wtime();
cout<<"waktu eksekusi adalah: "<< end-start << " detik " <<endl;
akhir=MPI_Finalize();
//waitKey();
return 0;
}
我已经尝试使用 mpi 点对点发送/接收来编写此代码。但是我的代码总是错的,我的错在哪里,我该如何解决这个问题?
【问题讨论】:
-
“我的代码总是错的”并没有告诉我们任何事情。您期望什么行为以及您的代码表现出什么行为?
-
if(rank==master){MPI_Send();}MPI_Barrier();if(rank!=master){MPI_Recv()}是一个死锁。进程master将等到收到消息并且 MPI_Barrier() 永远不会完成。尝试删除 MPI_Barrier() !更多:将 dest 从master复制到所有其他进程称为广播:请参阅 MPI_Bcast() mcs.anl.gov/research/projects/mpi/www/www3/MPI_Bcast.html -
您对
MPI_Barrier的第一次调用是一个死锁。删除它,运行您的代码,然后告诉我们出了什么问题。 -
您对 Sobel 算子的计算没有优化。您是否对速度快 10 倍且仍在一个线程中运行的解决方案感到满意?
标签: c++ opencv parallel-processing mpi