[MPICH] Sockets code inside MPI
Rajeev Thakur
thakur at mcs.anl.gov
Tue May 22 13:01:58 CDT 2007
Andrew,
I am able to run your program with MPI_Init enabled without any
problem.
Rajeev
> -----Original Message-----
> From: owner-mpich-discuss at mcs.anl.gov
> [mailto:owner-mpich-discuss at mcs.anl.gov] On Behalf Of Andrew Hakman
> Sent: Tuesday, May 22, 2007 11:38 AM
> To: mpich-discuss at mcs.anl.gov
> Subject: [MPICH] Sockets code inside MPI
>
> Hi
>
> Is there something special I have to do to write sockets code in my
> MPI program? The master process needs to be a network server and
> receive requests from a client process. The code works when I don't
> include any MPI calls, but as soon as I introduce MPI calls, the
> socket receive always returns -1. Here is the code
>
> const short MYPORT = 6000;
>
> int main(int argc, char **argv)
> {
> //MPI variables
> int my_rank;
> int com_size;
>
> //start MPI
> MPI_Init(&argc, &argv);
> MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
> MPI_Comm_size(MPI_COMM_WORLD, &com_size);
>
> //start "evaluate server" and wait for requests
> struct sockaddr_in my_addr, from;
> socklen_t from_len;
> int sd, client_sd, sendlen, recvlen;
> double result;
> socklen_t len;
> int i;
> bzero((char *)&my_addr, sizeof(my_addr));
> if ((sd=socket(AF_INET,SOCK_STREAM,0)) < 0)
> {
> printf("Problem creating socket\n");
> exit(1);
> }
> my_addr.sin_family = AF_INET;
> my_addr.sin_addr.s_addr=INADDR_ANY; //fill with local IP
> my_addr.sin_port = htons(MYPORT);
> if (bind(sd, (struct sockaddr *)&my_addr, sizeof(my_addr))<0)
> {
> printf("Error binding to socket\n");
> exit(1);
> }
> if (listen(sd,5)<0)
> {
> printf("Error listening\n");
> exit(1);
> }
> printf("Evaluate Server Ready and listening...\n");
> for (;;)
> {
> client_sd=accept(sd,(struct sockaddr *)&from,&from_len);
> printf("got request, solving profile\n");
> double var[nParams];
> double result;
> double f=0.0;
> recvlen=-1;
> while(recvlen<0)
> {
> recvlen=recv(client_sd,&var,sizeof(double)*nParams,0);
> }
> printf("master, ");
> for (int j=0; j<nParams; j++)
> {
> printf("%f, ",var[j]);
> }
> printf("\n");
> /* MPI_Bcast(&var, nParams, MPI_DOUBLE, 0, MPI_COMM_WORLD);
>
> //collect up fitness values
> MPI_Reduce(&f, &result, 1, MPI_DOUBLE, MPI_SUM, 0,
> MPI_COMM_WORLD);
> */
> //send total fitness value back to the client
> sendlen=send(client_sd,(void *)&result,sizeof(result),0);
> close(client_sd);
> }
> MPI_Finalize();
> return 0;
> }
>
> To summarize, a fixed length double array is sent from the client to
> the server, and a single double is to be sent back to the client as a
> result.
>
> If I comment out MPI_Init and MPI_Finalize, the receive (just after
> the accept) works perfectly. If I have MPI_Init and MPI_Finalize in,
> the program spins forever in the while(recvlen<0) loop.
>
> I can't see it being an issue with something else using port 6000 as I
> would expect (and do see when I kill the process and restart it too
> quickly) error when calling bind.
>
> A self contained example client code would be the following (the real
> client code is somewhat convoluted as it's tied into Matlab):
>
> int main()
> {
> int i;
> double returnval;
> double var[] = {3.455, 0.38, 20.21, 3.39959, 0.156085, -4.10835,
> 0.700964, 0.123453, -17.3804, 2.77002, 4.0, 0.6, 1.40733, 9.0, 0.6,
> -5.61955, 0.031321};
> // for (i=0; i<nParams; i++)
> // {
> // printf("element %d = %f\n",i,var[i]);
> // }
> returnval = evaluate(var);
> printf("returnval=%f\n",returnval);
> }
>
> /*************************************************************
> ****************\
> | This evaluate function is an interface to talk to MPI from
> MATLAB |
> \*************************************************************
> ****************/
> double evaluate(const double * var)
> {
> //open socket to "evaluate server" on the master node
> struct sockaddr_in my_addr;
> struct hostent *hp;
> int sd, sendlen, recvlen;
> double result;
> socklen_t len;
>
> bzero((char *)&my_addr, sizeof(my_addr));
> if ((sd=socket(AF_INET,SOCK_STREAM,0)) < 0)
> {
> printf("Problem creating socket\n");
> exit(1);
> }
> my_addr.sin_family = AF_INET;
> if ((hp = gethostbyname(MYHOST))==0)
> {
> printf("Invalid or unknown host\n");
> exit(1);
> }
> memcpy(&my_addr.sin_addr.s_addr, hp->h_addr, hp->h_length);
> my_addr.sin_port = htons(MYPORT);
> if (connect(sd,(sockaddr*)&my_addr,sizeof(my_addr))<0)
> {
> printf("Error connecting to evaluate server\n");
> exit(1);
> }
> for (int k=0; k<nParams; k++)
> {
> mexPrintf("var[k]=%f\n",var[k]);
> }
> sendlen=send(sd,(void*)var,sizeof(double)*nParams,0);
> mexPrintf("sendlen=%d\n",sendlen);
> recvlen=recv(sd,&result,sizeof(result),0);
> close(sd);
> return result;
> }
>
> Thanks,
> Andrew
>
>
More information about the mpich-discuss
mailing list