<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><div style="line-height:1.7;color:#000000;font-size:14px;font-family:Arial"><div>Hello, Balaji.</div><div><br></div><div>The example from OpenMPI is attached.</div><div><br></div><div>Thank you very much.</div><div></div><div id="divNeteaseMailCard"></div><br><pre><br>At 2015-01-25 03:16:35, "Balaji, Pavan" <balaji@anl.gov> wrote:
>
>You are missing some files needed to run your program.  Also, can you please attach files instead of copy-pasting code into the email?
>
>  -- Pavan
>
>> On Jan 24, 2015, at 7:57 AM, haozi <yidanyiji@163.com> wrote:
>> 
>> Hi.
>> The following server/client example is selected from OpenMPI. 
>> I compile and run the example by using OpenMPI, everything is OK.
>> BUT, I compile and run it by mpich(3.1.3), which is BLOCKED as my example!
>> 
>> This is a bug?
>> 
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>> #include <errno.h>
>> #include <unistd.h>
>> #include <mpi.h>
>> 
>> /*
>> 
>>    LOGIC:
>> 
>>      - the 'server' opens a port and write the info to a file
>>      - the 'clients' open the file and connect to the port
>>      - after each accept, the server and client do a merge to
>>        convert the intercomm to an intracomm
>> 
>>    DETAIL STEPS:
>> 
>>      - server open port
>>      - server does accept
>>      - client #1 does connect
>>      - server and client #1 do merge
>>      - server does accept
>>      - client #2 does connect
>>      - server, client #1 and client #2 do merge
>>      - server does accept
>>      - client #3 does connect
>>      - server, client #1, client #2 and client #3 do merge
>> 
>> */
>> 
>> #define TAG 0
>> 
>> #define CHK(code) do                            \
>>   {                                             \
>>     int retval = code ;                         \
>>     if (retval != MPI_SUCCESS)                  \
>>     {                                           \
>>       fprintf(stderr, "Error: " #code "\n") ;   \
>>       exit(1) ;                                 \
>>     }                                           \
>>   } while(0)
>> 
>> int main(int argc, char *argv[])
>> {
>>   char hostname[255] ;
>>   char buff[255] ;
>> 
>>   int role ;
>>   int num_clients ;
>>   int size, rank ;
>> 
>>   FILE *fp ;
>>   char server_port_name[MPI_MAX_PORT_NAME] ;
>> 
>>   MPI_Comm intercomm, intracomm ;
>>   MPI_Status status ;
>>   int msg_count ;
>>   int i ;
>> 
>>   /* sanity check the args */
>>   if(argc != 3)
>>   {
>>     fprintf(stderr, "usage %s <num clients> <1:server | 0:client>\n", argv[0]) ;
>>     exit(1) ;
>>   }
>> 
>>   num_clients = atoi(argv[1]) ;
>>   role = atoi(argv[2]) ;
>> 
>>   if (num_clients <= 0 || (role != 0 && role != 1))
>>   {
>>     fprintf(stderr, "usage %s <num clients> <1:server | 0:client>\n", argv[0]) ;
>>     exit(1) ;
>>   }
>> 
>>   /* initialize MPI  */
>>   CHK(MPI_Init(&argc, &argv)) ;
>> 
>>   /* get the node name */
>>   {
>>     int retval = gethostname(hostname, 255) ;
>>     if(retval == -1)
>>     {
>>       fprintf(stderr, "gethostname failed: %s\n", strerror(errno)) ;
>>       exit(1) ;
>>     }
>>   }
>> 
>>   /* server */
>>   if(role == 1)
>>   {
>>     printf("SERVER: on node '%s'\n", hostname) ;
>> 
>>     /* open port to establish connections */
>>     CHK(MPI_Open_port(MPI_INFO_NULL, server_port_name)) ;
>> 
>>     printf("SERVER: opened port=%s\n", server_port_name) ;
>> 
>>     /* store the port name */
>>     fp = fopen("server_port_name.txt", "w") ;
>>     if(fp == NULL)
>>     {
>>       fprintf(stderr, "fopen failed: %s\n", strerror(errno)) ;
>>       exit(1) ;
>>     }
>>     fprintf(fp, "%s", server_port_name) ;
>>     fclose(fp) ;
>> 
>>     /* the server accepts connections from all the clients */
>>     for(i = 0 ; i < num_clients ; i++ )
>>     {
>>       /* accept connections at this port */
>>       CHK(MPI_Comm_accept(server_port_name, MPI_INFO_NULL, 0,
>>                           i == 0 ? MPI_COMM_WORLD : intracomm,
>>                           &intercomm)) ;
>> 
>>       printf("SERVER: accepted connection from client %d\n", i+1) ;
>> 
>>       /* merge, to form one intra communicator */
>>       CHK(MPI_Intercomm_merge(intercomm, 0, &intracomm)) ;
>> 
>>       printf("SERVER: merged with client %d\n", i+1) ;
>> 
>>       CHK(MPI_Comm_size(intracomm, &size)) ;
>>       CHK(MPI_Comm_rank(intracomm, &rank)) ;
>> 
>>       printf("SERVER: after merging with client %d: size=%d rank=%d\n", i+1, size, rank) ;
>>     }
>>   } /* end server */
>> 
>>   /* client */
>>   if(role == 0)
>>   {
>>     printf("CLIENT: on node '%s'\n", hostname) ;
>> 
>>     fp = fopen("server_port_name.txt", "r") ;
>>     if(fp == NULL)
>>     {
>>       fprintf(stderr, "fopen failed: %s\n", strerror(errno)) ;
>>       exit(1) ;
>>     }
>>     fscanf(fp, "%s", server_port_name) ;
>>     fclose(fp) ;
>> 
>>     printf("CLIENT: attempting to connect to server on port=%s\n", server_port_name) ;
>> 
>>     /* connect to the server */
>>     CHK(MPI_Comm_connect (server_port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm)) ;
>> 
>>     printf("CLIENT: connected to server on port\n") ;
>> 
>>     /* merge the server and client to one intra communicator */
>>     CHK(MPI_Intercomm_merge(intercomm, 1, &intracomm)) ;
>> 
>>     printf("CLIENT: merged with existing intracomm\n") ;
>> 
>>     CHK(MPI_Comm_size(intracomm, &size)) ;
>>     CHK(MPI_Comm_rank(intracomm, &rank)) ;
>> 
>>     printf("CLIENT: after merging, new comm: size=%d rank=%d\n", size, rank) ;
>> 
>>     for (i = rank ; i < num_clients ; i++)
>>     {
>>       /* client performs a collective accept */
>>       CHK(MPI_Comm_accept(server_port_name, MPI_INFO_NULL, 0, intracomm, &intercomm)) ;
>> 
>>       printf("CLIENT: connected to server on port\n") ;
>> 
>>       /* merge the two intra comms back to one communicator */
>>       CHK(MPI_Intercomm_merge(intercomm, 0, &intracomm)) ;
>> 
>>       printf("CLIENT: merged with existing members\n") ;
>> 
>>       CHK(MPI_Comm_size(intracomm, &size)) ;
>>       CHK(MPI_Comm_rank(intracomm, &rank)) ;
>> 
>>       printf("CLIENT: new size after merging with existing members: size=%d rank=%d\n", size, rank) ;
>>     }
>> 
>>   } /* end client */
>> 
>>   CHK(MPI_Comm_size(intracomm, &size)) ;
>>   CHK(MPI_Comm_rank(intracomm, &rank)) ;
>> 
>>   printf("After fusion: size=%d rank=%d\n", size, rank) ;
>> 
>>   if(rank == 0)
>>   {
>>     msg_count = num_clients ;
>> 
>>     while(msg_count)
>>     {
>>       CHK(MPI_Recv(buff, 255, MPI_CHAR, MPI_ANY_SOURCE,
>>                    MPI_ANY_TAG, intracomm, &status)) ;
>> 
>>       printf("Received hello msg from '%s'\n", buff) ;
>>       msg_count-- ;
>>     }
>>   }
>>   else
>>   {
>>     /* all ranks > 0 */
>> 
>>     CHK(MPI_Send(hostname, strlen(hostname) + 1, MPI_CHAR, 0, TAG, intracomm)) ;
>>   }
>> 
>>   CHK(MPI_Finalize()) ;
>> 
>>   fprintf(stderr, "Rank %d is exiting\n", rank);
>>   return 0 ;
>> }
>> 
>> 
>> At 2015-01-24 10:43:07, "haozi" <yidanyiji@163.com> wrote:
>> Thanks, Bland and Lu.
>> 
>> You are right.
>> These functions (such as MPI_Comm_accept, MPI_Comm_connect, MPI_Intercomm_merge) can help me to get a new intra-communicator which contains ALL MPI processes.
>> 
>> Now, I have a more complicated example:
>>     I have a server and a client. 
>>     After they merge into an intra-communicator by using connect/accept/merge fucntions, another client would plant to join them, too.
>>     I thought that the code is simular, but the code CAN'T work: Second client CAN'T connect. The new comm CAN'T accept. They all BLOCK.
>> 
>>     As you see, the second client BLOCKs at MPI_Comm_connect, and processes of newcomm BLOCK at MPI_Comm_accept.
>>     What's Wrong with my code? 
>> 
>> //server
>> #include "mpi.h"
>> int main(int argc, char *argv[])
>> {
>>        MPI_Comm client, client2, newcomm, newcomm2;
>>        MPI_Status status;
>>        char port_name[MPI_MAX_PORT_NAME];
>>        char port_name2[MPI_MAX_PORT_NAME];
>>        int size, again, rank, myrank;
>> 
>>        MPI_Init(&argc, &argv);
>>        MPI_Open_port(MPI_INFO_NULL, port_name);//OK
>> 
>>        MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD,&client);//OK
>> 
>>        MPI_Intercomm_merge(client,11,&newcomm);//OK
>> 
>>        MPI_Barrier(newcomm);//OK
>> 
>>        MPI_Open_port(MPI_INFO_NULL, port_name2);// OK
>> 
>>        MPI_Comm_accept(port_name2, MPI_INFO_NULL, 0, newcomm,&client2);// BLOCK here, Wath's wrong?
>> 
>>        MPI_Intercomm_merge(client2,12,&newcomm2);
>> 
>>        MPI_Barrier(newcomm2);
>> 
>>        MPI_Close_port(port_name);
>>        MPI_Comm_disconnect(&client);
>>        MPI_Close_port(port_name2);
>>        MPI_Comm_disconnect(&client2);
>> 
>>        MPI_Finalize();
>>        return 0;
>> }
>> 
>> //first client
>> #include "mpi.h"
>> int main( int argc, char **argv )
>> {
>>        MPI_Comm server,newcomm,newcomm2,client2;
>>        char port_name[MPI_MAX_PORT_NAME];
>>        char port_name2[MPI_MAX_PORT_NAME];
>>        int size,rank;
>> 
>>        MPI_Init( &argc, &argv );
>>        
>>        strcpy( port_name, argv[1] );
>>        MPI_Comm_connect( port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF,&server );//OK
>> 
>>        MPI_Intercomm_merge(server,11,&newcomm);//OK
>> 
>>        MPI_Barrier(newcomm);//OK
>> 
>>        MPI_Open_port(MPI_INFO_NULL, port_name2);//OK
>>        
>>        MPI_Comm_accept(port_name2, MPI_INFO_NULL, 0, newcomm,&client2);// BLOCK here, Wath's wrong?
>> 
>>        MPI_Intercomm_merge(client2,12,&newcomm2);
>> 
>>        MPI_Barrier(newcomm2);
>> 
>>        MPI_Close_port(port_name2);
>>        MPI_Comm_disconnect(&client2);
>>        MPI_Comm_disconnect( &server );
>>        MPI_Finalize();
>>        return 0;
>> }
>> 
>> //second client
>> #include "mpi.h"
>> int main( int argc, char **argv )
>> {
>>        MPI_Comm server,newcomm;
>>        char port_name[MPI_MAX_PORT_NAME];
>>        int size,rank;
>> 
>>        MPI_Init( &argc, &argv );
>>        
>>        strcpy( port_name, argv[1] );//OK
>>        
>>        MPI_Comm_connect( port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF,&server );// BLOCK here, Wath's wrong?
>>        
>>        MPI_Comm_size(MPI_COMM_WORLD, &size);
>> 
>>        MPI_Intercomm_merge(server,11,&newcomm);
>> 
>>        MPI_Barrier(newcomm);
>>        
>>        MPI_Comm_disconnect( &server );
>>        MPI_Finalize();
>>        return 0;
>> }
>> 
>> 
>> 
>> 
>> At 2015-01-23 23:14:06, "Wesley Bland" <wbland@anl.gov> wrote:
>> The size of MPI_COMM_WORLD will never change. That communicator is set at initialization time and is not ever modified. However, when you finish connect/accept, you get a new communicator which you can merge into an intra-communicator which functions exactly like MPI_COMM_WORLD. Don’t be attached to the variable name MPI_COMM_WORLD. It’s just a variable and you can use a different one with very little extra work.
>> 
>> Thanks,
>> Wesley
>> 
>> 
>> On Thu, Jan 22, 2015 at 6:14 PM, haozi <yidanyiji@163.com> wrote:
>> Thanks, Lu.
>> My simple code is as following.
>> //server
>> #include "mpi.h"
>> 
>> int main(int argc, char *argv[])
>> {
>> MPI_Comm client;
>> MPI_Status status;
>> char port_name[MPI_MAX_PORT_NAME];
>> int size, again;
>> 
>> MPI_Init(&argc, &argv);
>> MPI_Comm_size(MPI_COMM_WORLD, &size);
>> MPI_Open_port(MPI_INFO_NULL, port_name);
>> printf("server port_name is %s\n\n", port_name);
>> MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD,&client);
>> MPI_Comm_size(MPI_COMM_WORLD, &size);
>> printf("At server, comm_size=%d @ MPI_COMM_WORLD=%x, Client_World=%x\n",size,MPI_COMM_WORLD, client);
>> MPI_Comm_size(client, &size);
>> printf("At server, client_size=%d @ MPI_COMM_WORLD=%x, Client_World=%x\n",size,MPI_COMM_WORLD, client);
>> 
>> MPI_Comm_disconnect(&client);
>> MPI_Finalize();
>> return 0;
>> }
>> 
>> //client
>> #include "mpi.h"
>> 
>> int main( int argc, char **argv )
>> {
>> MPI_Comm server;
>> char port_name[MPI_MAX_PORT_NAME];
>> int size;
>> 
>> MPI_Init( &argc, &argv );
>> strcpy( port_name, argv[1] );
>> printf("server port name:%s\n",port_name);
>> MPI_Comm_connect( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD,&server );
>> MPI_Comm_size(MPI_COMM_WORLD, &size);
>> printf("At client, comm_size=%d @ MPI_COMM_WORLD=%x, Server_World=%x\n",size,MPI_COMM_WORLD,server);
>> MPI_Comm_size(server, &size);
>> printf("At client, server_size=%d @ MPI_COMM_WORLD=%x, Server_World=%x\n",size,MPI_COMM_WORLD,server);
>> 
>> MPI_Comm_disconnect( &server );
>> MPI_Finalize();
>> return 0;
>> }
>> 
>> The run command is as following.
>> mpiexec -n 1 ./server
>> mpiexec -n 1 ./client
>> 
>> BUT, the SIZE is 1, NOT 2.
>> 
>> My question is as before: How does the size of MPI_COMM_WORLD change to 2 ?
>> 
>> 
>> At 2015-01-23 00:30:43, "Huiwei Lu" <huiweilu@mcs.anl.gov> wrote:
>> You may take a look at MPI_Comm_accept and MPI_Comm_connect, which will connect a new client process to a server process. See Chap. 10 of MPI 3.0 standard (www.mpi-forum.org/docs/mpi-3.0/mpi30-report.pdf) for a detail example.
>> 
>> --
>> Huiwei Lu
>> Postdoc Appointee
>> Mathematics and Computer Science Division
>> Argonne National Laboratory
>> http://www.mcs.anl.gov/~huiweilu/
>> 
>> On Thu, Jan 22, 2015 at 9:41 AM, haozi <yidanyiji@163.com> wrote:
>> Hi, guys.
>> 
>> This web page (http://wiki.mpich.org/mpich/index.php/PMI_v2_Design_Thoughts) says:
>>               Singleton init. This is the process by which a program that was not started with mpiexec can become an MPI process and make use of all MPI features, including MPI_Comm_spawn, needs to be designed and documented, with particular attention to the disposition of standard I/O. Not all process managers will want to or even be able to create a new mpiexec process, so this needs to be negotiated. Similarly, the dispostion of stdio needs to be negotiated between the singleton process and the process manager. To address these issues, a new singleton init protocol has been implemented and tested with the gforker process manager.
>> 
>> I am very interested in this function.
>> Can this function solve the following question:
>>               At beginning, the MPI job uses the mpiexec commond to start three MPI processes. That is to say, there are three MPI processes in MPI_COMM_WORLD. At some time, the job find itself to need another MPI process to cooperate the three MPI processes. So the question is: Could PMI help an non-MPI process to become a MPI process of the current MPI_COMM_WORLD? That is to say, Could the non-MPI process use the PMI function to become a member process of the current MPI job which would have FOUR MPI processes in MPI_COMM_WORLD?
>> 
>> Is there some method to solve question?
>> Is anybody have some example?
>> 
>> Thandks!!!
>> 
>> 
>> 
>> _______________________________________________
>> discuss mailing list     discuss@mpich.org
>> To manage subscription options or unsubscribe:
>> https://lists.mpich.org/mailman/listinfo/discuss
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> _______________________________________________
>> discuss mailing list     discuss@mpich.org
>> To manage subscription options or unsubscribe:
>> https://lists.mpich.org/mailman/listinfo/discuss
>
>--
>Pavan Balaji  ✉️
>http://www.mcs.anl.gov/~balaji
>
>_______________________________________________
>discuss mailing list     discuss@mpich.org
>To manage subscription options or unsubscribe:
>https://lists.mpich.org/mailman/listinfo/discuss
</pre></div><br><br><span title="neteasefooter"><span id="netease_mail_footer"></span></span>