unknown
2004-10-29 18:27:07 UTC
Dear all,
thanks to Andreas Pommer for helping me out in my earlier problem.
Now I have another problem. basically I'm using a for loop to distribute
different pieces of a matrix to other processes including itself. I know
it's definitely a common occurence (data decomposition).
but my code below sends and receive correctly if mpirun -np 1 but for
mpirun -np 2, process 0 receives correctly but process 1 receives zeros.
likewise for higher values. I know i'm giving MPI_Send the correct
values cos it prints fine and it returns the errorvalue 0. I tried using
MPI_Ssend then it just hangs there. So basically my MPI_Recv works for
process 0 but not for process > 0.
Basic question about MPI, I compile one program that contains checks for
the process rank it's on. then every process will run the same program,
ignoring parts which doesn't not involve it's own process rank, right?
so when debugging programs, if it is clear that for process 0 it is
running that code fragment, process 1,2, ... should run that fragment
too right?
How? Been perusing google groups already and the internet but no avail.
maybe not using proper search terms. please help? thanks for your time
and patience.
tylim
/*---------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#define MAT_M 4
#define MAT_N 3
/* BLOCK DECOMPOSITION MACROS taken from
* Micheal J Quinn, Parallel programming in C with MPI and OpenMP
* International Edition 2003 Chapter 5.4.3 pg 120 */
/* first or lowest index controlled by process (id)*/
#define BLOCK_LOW(id,p,n) ((id)*(n)/(p))
/* last, or highest index controlled by the process (id) */
#define BLOCK_HIGH(id,p,n) (BLOCK_LOW((id)+1,p,n) - 1)
/* number of elements controlled by process (id) */
#define BLOCK_SIZE(id,p,n) (BLOCK_LOW((id)+1,p,n)-BLOCK_LOW(id,p,n))
/* rank of process controlling element (index) of array */
#define BLOCK_OWNER(index,p,n) (((p)*((index)+1)-1)/(n))
int main (int argc, char *argv[])
{
int i,j,k, tag = 99, errorcode;
int id; /* Process Rank */
int p; /* Number of processes */
int mat_A[MAT_M][MAT_N]={1,2,3,4,5,6,7,8,9,10,11,12};
int *mat_B, *recv_block, *sending;
int begin_row, end_row, rows_per_process, total_elements;
MPI_Status status;
MPI_Init( &argc, &argv);
MPI_Comm_rank( MPI_COMM_WORLD, &id);
MPI_Comm_size( MPI_COMM_WORLD, &p);
/* allocate and send process k's share of the matrix
* runs only on process 0 */
if(id==0) {
for( k=0;k<p;k++) {
begin_row = BLOCK_LOW(k,p,MAT_M);
end_row = BLOCK_HIGH(k,p,MAT_M);
rows_per_process = BLOCK_SIZE(k,p,MAT_M);
total_elements = BLOCK_SIZE(k,p,MAT_M)*MAT_N;
printf("id %d begin %d end %d total elements
%d\n",k,begin_row,end_row, total_elements);
sending = (int *) malloc(total_elements*sizeof(int));
if(sending==NULL) {
printf("Error:malloc\n");
MPI_Finalize();
}
/* a(no of columns * i + j) = a[i][j]*/
printf("Send to Process %d from \n",k,id);
for(i=begin_row; i<=end_row; i++)
for(j=0;j<MAT_N;j++) {
sending[MAT_N*i+j]=mat_A[i][j];
printf("%d ",sending[MAT_N*i+j]);
if((j+1)%MAT_N==0) printf("\n");
}
errorcode = MPI_Send(
sending,total_elements,MPI_INT,k,tag,MPI_COMM_WORLD);
printf("errorcode: %lu\n",errorcode);
free(sending);
}
}
/* figure out this process share of mat_A
* runs on all process including process 0 */
begin_row = BLOCK_LOW(id,p,MAT_M);
end_row = BLOCK_HIGH(id,p,MAT_M);
rows_per_process = BLOCK_SIZE(id,p,MAT_M);
total_elements = BLOCK_SIZE(id,p,MAT_M)*MAT_N;
printf("process %d begin at row %d end at row %d total elements
%d\n",id,begin_row,end_row, total_elements);
recv_block = (int *) malloc(total_elements*sizeof(int));
if(recv_block==NULL) {
printf("Error:malloc\n");
MPI_Finalize();
}
MPI_Recv( recv_block,total_elements,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
/* refers to local index of matrix A*/
printf("Recv Process %d\n",id);
fflush(stdout);
for(i=0;i<total_elements;i++) {
printf("%d ",recv_block[i]);
if((i+1)%MAT_N==0) printf("\n");
}
free(recv_block);
MPI_Finalize();
}
/*---------------------------------------------------------*/
thanks to Andreas Pommer for helping me out in my earlier problem.
Now I have another problem. basically I'm using a for loop to distribute
different pieces of a matrix to other processes including itself. I know
it's definitely a common occurence (data decomposition).
but my code below sends and receive correctly if mpirun -np 1 but for
mpirun -np 2, process 0 receives correctly but process 1 receives zeros.
likewise for higher values. I know i'm giving MPI_Send the correct
values cos it prints fine and it returns the errorvalue 0. I tried using
MPI_Ssend then it just hangs there. So basically my MPI_Recv works for
process 0 but not for process > 0.
Basic question about MPI, I compile one program that contains checks for
the process rank it's on. then every process will run the same program,
ignoring parts which doesn't not involve it's own process rank, right?
so when debugging programs, if it is clear that for process 0 it is
running that code fragment, process 1,2, ... should run that fragment
too right?
How? Been perusing google groups already and the internet but no avail.
maybe not using proper search terms. please help? thanks for your time
and patience.
tylim
/*---------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#define MAT_M 4
#define MAT_N 3
/* BLOCK DECOMPOSITION MACROS taken from
* Micheal J Quinn, Parallel programming in C with MPI and OpenMP
* International Edition 2003 Chapter 5.4.3 pg 120 */
/* first or lowest index controlled by process (id)*/
#define BLOCK_LOW(id,p,n) ((id)*(n)/(p))
/* last, or highest index controlled by the process (id) */
#define BLOCK_HIGH(id,p,n) (BLOCK_LOW((id)+1,p,n) - 1)
/* number of elements controlled by process (id) */
#define BLOCK_SIZE(id,p,n) (BLOCK_LOW((id)+1,p,n)-BLOCK_LOW(id,p,n))
/* rank of process controlling element (index) of array */
#define BLOCK_OWNER(index,p,n) (((p)*((index)+1)-1)/(n))
int main (int argc, char *argv[])
{
int i,j,k, tag = 99, errorcode;
int id; /* Process Rank */
int p; /* Number of processes */
int mat_A[MAT_M][MAT_N]={1,2,3,4,5,6,7,8,9,10,11,12};
int *mat_B, *recv_block, *sending;
int begin_row, end_row, rows_per_process, total_elements;
MPI_Status status;
MPI_Init( &argc, &argv);
MPI_Comm_rank( MPI_COMM_WORLD, &id);
MPI_Comm_size( MPI_COMM_WORLD, &p);
/* allocate and send process k's share of the matrix
* runs only on process 0 */
if(id==0) {
for( k=0;k<p;k++) {
begin_row = BLOCK_LOW(k,p,MAT_M);
end_row = BLOCK_HIGH(k,p,MAT_M);
rows_per_process = BLOCK_SIZE(k,p,MAT_M);
total_elements = BLOCK_SIZE(k,p,MAT_M)*MAT_N;
printf("id %d begin %d end %d total elements
%d\n",k,begin_row,end_row, total_elements);
sending = (int *) malloc(total_elements*sizeof(int));
if(sending==NULL) {
printf("Error:malloc\n");
MPI_Finalize();
}
/* a(no of columns * i + j) = a[i][j]*/
printf("Send to Process %d from \n",k,id);
for(i=begin_row; i<=end_row; i++)
for(j=0;j<MAT_N;j++) {
sending[MAT_N*i+j]=mat_A[i][j];
printf("%d ",sending[MAT_N*i+j]);
if((j+1)%MAT_N==0) printf("\n");
}
errorcode = MPI_Send(
sending,total_elements,MPI_INT,k,tag,MPI_COMM_WORLD);
printf("errorcode: %lu\n",errorcode);
free(sending);
}
}
/* figure out this process share of mat_A
* runs on all process including process 0 */
begin_row = BLOCK_LOW(id,p,MAT_M);
end_row = BLOCK_HIGH(id,p,MAT_M);
rows_per_process = BLOCK_SIZE(id,p,MAT_M);
total_elements = BLOCK_SIZE(id,p,MAT_M)*MAT_N;
printf("process %d begin at row %d end at row %d total elements
%d\n",id,begin_row,end_row, total_elements);
recv_block = (int *) malloc(total_elements*sizeof(int));
if(recv_block==NULL) {
printf("Error:malloc\n");
MPI_Finalize();
}
MPI_Recv( recv_block,total_elements,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
/* refers to local index of matrix A*/
printf("Recv Process %d\n",id);
fflush(stdout);
for(i=0;i<total_elements;i++) {
printf("%d ",recv_block[i]);
if((i+1)%MAT_N==0) printf("\n");
}
free(recv_block);
MPI_Finalize();
}
/*---------------------------------------------------------*/