[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