Zunächst einmal habe ich this code als Referenz verwendet, die die Verwendung von MPI_Gather
ohne MPI_Scatter
als das ist, was ich hier erreichen möchte. Ich arbeite schon lange daran und kann das Problem einfach nicht lösen. Dieser Sobel-Kantenerkennungsalgorithmus verstärkt die Umrisse von Objekten innerhalb von Bildern.MPI Sammeln nur sammeln von Root-Prozess
Ich werde meinen Code unten posten, da es nicht zu viel gibt, aber ich gebe zuerst eine schnelle Code-Beschreibung.
Ich versuche, ein sequenzielles Programm in ein paralleles Programm zu konvertieren. Also ist der ganze Nicht-MPI-Code korrekt.
So kann es nur einen Fehler mit meinem Code MPI
irgendwo geben.
int main(int argc, char **argv) {
FILE *inFile, *oFile;
int grayImage[N][N], edgeImage[N][N];
char type[2];
int w, h, max;
int r, g, b, y, x, i, j, sum, sumx, sumy;
int tid;
int GX[3][3], GY[3][3];
double elapsed_time;
struct timeval tv1, tv2;
int error = 0;
char buffer[BUFSIZ];
int rank, NP;
// Code lies here for reading from the image file and storing into the grayImage array.
// This works so I saw no reason to include it
/* 3x3 Sobel masks. */
GX[0][0] = -1; GX[0][1] = 0; GX[0][2] = 1;
GX[1][0] = -2; GX[1][1] = 0; GX[1][2] = 2;
GX[2][0] = -1; GX[2][1] = 0; GX[2][2] = 1;
GY[0][0] = 1; GY[0][1] = 2; GY[0][2] = 1;
GY[1][0] = 0; GY[1][1] = 0; GY[1][2] = 0;
GY[2][0] = -1; GY[2][1] = -2; GY[2][2] = -1;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &NP);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// This calculates the block size.MPI
// On 4 processors the block size for a 100x100 image would be 25x100 each
int blksz = (int)ceil((double)N/NP);
// This creates a local array for each processor, soon to be gathered
int tempEdge[blksz][N];
// this line shows it's working correctly
printf("processor %d, width: %d, height: %d, blksz: %d, begin: %d, end: %d\n", rank, w, h, blksz, rank*blksz, (rank+1)*blksz);
for(x=rank*blksz; x < (rank+1)*blksz && x<h; x++){
// Any code in this loop can be ignored as it works correctly.
for(y=0; y < w; ++y){
sumx = 0;
sumy = 0;
// handle image boundaries
if(x==0 || x==(h-1) || y==0 || y==(w-1))
sum = 0;
else{
//x gradient approx
for(i=-1; i<=1; i++) {
for(j=-1; j<=1; j++){
sumx += (grayImage[x+i][y+j] * GX[i+1][j+1]);
}
}
//y gradient approx
for(i=-1; i<=1; i++) {
for(j=-1; j<=1; j++){
sumy += (grayImage[x+i][y+j] * GY[i+1][j+1]);
}
}
//gradient magnitude approx
sum = (abs(sumx) + abs(sumy));
}
tempEdge[x][y] = clamp(sum);
}
}
// Here is the line I am guessing is causing the problem
MPI_Gather(&tempEdge, w*blksz, MPI_INT,
&edgeImage, w*blksz, MPI_INT, 0,
MPI_COMM_WORLD);
// Finally, I output edgeImage to a file here.
if(rank==0){
// output edgeImage to File
}
MPI_Finalize();
return 0;
}
Das Eingangsbild ich verwende, ist dies:
Aber der Ausgang nur geben diese:
Wie Sie es sehen können, ist nur die oberes Viertel (N/4) oder blksz
des Bildes.
Dies würde bedeuten, dass MPI_Gather
nur von Prozess mit Rang 0 sammelt?
Ich habe so viel Zeit damit verbracht, jede Hilfe würde sehr geschätzt werden!
Ich kann wirklich nicht glauben, dass ich das verpasst habe! Jetzt fühle ich mich dumm, dies auf SO zu veröffentlichen. Vielen Dank für den ganzen Code! –
Ich weiß, Debugging MPI-Code ist schwer, wie man die Anzahl der verwendbaren parallelen Debugger an den Fingern einer Hand zählen kann und die meisten von ihnen sind kommerziell. –