Index: /XIOS/dev/branch_openmp/extern/ep_dev/ep_dup.cpp
===================================================================
--- /XIOS/dev/branch_openmp/extern/ep_dev/ep_dup.cpp	(revision 1517)
+++ /XIOS/dev/branch_openmp/extern/ep_dev/ep_dup.cpp	(revision 1518)
@@ -85,5 +85,5 @@
         printf("new out_comm[%d]->ep_comm_ptr->intercomm = %p\n", i, out_comm[i]->ep_comm_ptr->intercomm);
 #endif
-        out_comm[i]->ep_comm_ptr->intercomm->mpi_inter_comm = mpi_inter_comm;      
+        out_comm[i]->ep_comm_ptr->intercomm->mpi_inter_comm = mpi_inter_comm;
       }
 
@@ -104,4 +104,6 @@
     (*newcomm)->ep_comm_ptr->intercomm->size_rank_info[2] = comm->ep_comm_ptr->intercomm->size_rank_info[2];
 
+    (*newcomm)->ep_comm_ptr->intercomm->intercomm_tag = comm->ep_comm_ptr->intercomm->intercomm_tag;
+
 
     int ep_rank_loc = (*newcomm)->ep_comm_ptr->size_rank_info[1].first;
@@ -109,10 +111,12 @@
     if(ep_rank_loc == 0)
     {
-      //printf("in dup , ep_rank_loc = 0 :  ep %d\n", (*newcomm)->ep_comm_ptr->size_rank_info[0].first);
+      int world_rank;
+      MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
+
       (*newcomm)->ep_comm_ptr->intercomm->intercomm_rank_map = new INTERCOMM_RANK_MAP;
       (*newcomm)->ep_comm_ptr->intercomm->local_rank_map = new EP_RANK_MAP;
 
       *(*newcomm)->ep_comm_ptr->intercomm->intercomm_rank_map = *comm->ep_comm_ptr->intercomm->intercomm_rank_map;
-      *(*newcomm)->ep_comm_ptr->intercomm->local_rank_map = *comm->ep_comm_ptr->intercomm->local_rank_map;
+      *(*newcomm)->ep_comm_ptr->intercomm->local_rank_map     = *comm->ep_comm_ptr->intercomm->local_rank_map;
     }
 
@@ -121,6 +125,7 @@
     if(ep_rank_loc !=0 )
     {
-      (*newcomm)->ep_comm_ptr->intercomm->intercomm_rank_map = (*newcomm)->ep_comm_ptr->comm_list[0]->ep_comm_ptr->intercomm->intercomm_rank_map;
-      (*newcomm)->ep_comm_ptr->intercomm->local_rank_map = (*newcomm)->ep_comm_ptr->comm_list[0]->ep_comm_ptr->intercomm->local_rank_map;
+      int target = (*newcomm)->ep_comm_ptr->intercomm->intercomm_tag;
+      (*newcomm)->ep_comm_ptr->intercomm->intercomm_rank_map = (*newcomm)->ep_comm_ptr->comm_list[target]->ep_comm_ptr->intercomm->intercomm_rank_map; 
+      (*newcomm)->ep_comm_ptr->intercomm->local_rank_map     = (*newcomm)->ep_comm_ptr->comm_list[target]->ep_comm_ptr->intercomm->local_rank_map;
     }
 
Index: /XIOS/dev/branch_openmp/extern/ep_dev/ep_intercomm.hpp
===================================================================
--- /XIOS/dev/branch_openmp/extern/ep_dev/ep_intercomm.hpp	(revision 1517)
+++ /XIOS/dev/branch_openmp/extern/ep_dev/ep_intercomm.hpp	(revision 1518)
@@ -32,5 +32,6 @@
 
 
-    int intercomm_tag;
+    int intercomm_tag;                       // newcomm_ep_rank_loc of ep with ep_rank_loc==0 
+                                             // used in comm_dup_intercomm
     
   };
Index: /XIOS/dev/branch_openmp/extern/ep_dev/ep_intercomm_kernel.cpp
===================================================================
--- /XIOS/dev/branch_openmp/extern/ep_dev/ep_intercomm_kernel.cpp	(revision 1517)
+++ /XIOS/dev/branch_openmp/extern/ep_dev/ep_intercomm_kernel.cpp	(revision 1518)
@@ -554,4 +554,5 @@
         {
           target = i;
+          (*newintercomm)->ep_comm_ptr->intercomm->intercomm_tag = target;
           break;
         }
@@ -559,4 +560,8 @@
       (*newintercomm)->ep_comm_ptr->intercomm->intercomm_rank_map = (*newintercomm)->ep_comm_ptr->comm_list[target]->ep_comm_ptr->intercomm->intercomm_rank_map;
       (*newintercomm)->ep_comm_ptr->intercomm->local_rank_map     = (*newintercomm)->ep_comm_ptr->comm_list[target]->ep_comm_ptr->intercomm->local_rank_map;
+    }
+    else
+    {
+      (*newintercomm)->ep_comm_ptr->intercomm->intercomm_tag = -1;
     }
 
Index: /XIOS/dev/branch_openmp/extern/ep_dev/ep_merge.cpp
===================================================================
--- /XIOS/dev/branch_openmp/extern/ep_dev/ep_merge.cpp	(revision 1517)
+++ /XIOS/dev/branch_openmp/extern/ep_dev/ep_merge.cpp	(revision 1518)
@@ -124,17 +124,88 @@
   int MPI_Intercomm_merge(MPI_Comm inter_comm, bool high, MPI_Comm *newintracomm)
   {
+    
 
     assert(inter_comm->is_intercomm);
 
-    //if(inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->comm_label == -99)
-    //{
-    //    return MPI_Intercomm_merge_unique_leader(inter_comm, high, newintracomm);
-    //}
+    // determine if only one MPI proc
+
+        // to be completed ......
+
+    // multiple MPI proc and high differs
+
+    int newcomm_ep_rank = inter_comm->ep_comm_ptr->intercomm->size_rank_info[0].first;
+    int newcomm_ep_rank_loc = inter_comm->ep_comm_ptr->intercomm->size_rank_info[1].first;
+    int newcomm_num_ep = inter_comm->ep_comm_ptr->intercomm->size_rank_info[1].second;
+
+    int ep_rank = inter_comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = inter_comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = inter_comm->ep_comm_ptr->size_rank_info[1].second;
+
+    if(newcomm_ep_rank_loc == 0)
+    {
+      ::MPI_Comm *mpi_intracomm = new ::MPI_Comm;
+      ::MPI_Intercomm_merge(to_mpi_comm(inter_comm->ep_comm_ptr->intercomm->mpi_inter_comm), high, mpi_intracomm);
+      
+      MPI_Info info;
+      MPI_Comm *ep_comm;
+      MPI_Comm_create_endpoints(mpi_intracomm, newcomm_num_ep, info, ep_comm);
+
+      inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge = ep_comm;
+    }
+
+    MPI_Barrier_local(inter_comm);
+
+    int remote_num_ep = newcomm_num_ep - num_ep;
+
+    *newintracomm = inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge[high? remote_num_ep+ep_rank_loc : ep_rank_loc];
+
+    int ep_size = inter_comm->ep_comm_ptr->size_rank_info[0].second;
+    int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->intercomm_rank_map->size();
+
+    //printf("ep_size = %d, remote_ep_size = %d\n", ep_size, remote_ep_size);
+
+    (*newintracomm)->ep_comm_ptr->size_rank_info[0].first = high? remote_ep_size+ep_rank : ep_rank;
+
+    int my_triple[3];
+    my_triple[0] = (*newintracomm)->ep_comm_ptr->size_rank_info[0].first;
+    my_triple[1] = (*newintracomm)->ep_comm_ptr->size_rank_info[1].first;
+    my_triple[2] = (*newintracomm)->ep_comm_ptr->size_rank_info[2].first;
+
+    int *my_triple_list = new int[3 * (*newintracomm)->ep_comm_ptr->size_rank_info[0].second];
+
+
+    MPI_Allgather(my_triple, 3, MPI_INT, my_triple_list, 3, MPI_INT, *newintracomm);
+
+    if((*newintracomm)->ep_comm_ptr->size_rank_info[1].first == 0)
+    {
+      (*newintracomm)->ep_rank_map->clear();
+      for(int i=0; i<(*newintracomm)->ep_comm_ptr->size_rank_info[0].second; i++)
+      {
+        (*newintracomm)->ep_rank_map->insert(std::pair< int, std::pair<int,int> >(my_triple_list[3*i], my_triple_list[3*i+1], my_triple_list[3*i+2]));
+      }
+    }
+
+#ifdef _showinfo
+    MPI_Barrier_local(inter_comm);
+    if((*newintracomm)->ep_comm_ptr->size_rank_info[0].first == 15)
+    {
+      for(std::map<int, std::pair<int, int> >::iterator it = (*newintracomm)->ep_rank_map->begin(); it != (*newintracomm)->ep_rank_map->end(); it++)
+      {
+        printf("(%d  %d  %d)\n", it->first, it->second.first, it->second.second);
+      }
+    }
+#endif
+    
+    delete my_triple_list;
+ 
+
+    return 0;
+
 
 
     Debug("intercomm_merge kernel\n");
 
-    int ep_rank_loc;
-    int num_ep;
+    //int ep_rank_loc;
+    //int num_ep;
 
     ep_rank_loc = inter_comm->ep_comm_ptr->size_rank_info[1].first;
@@ -143,5 +214,5 @@
 
 
-    int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->remote_rank_map->size();
+    //int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->remote_rank_map->size();
 
 
Index: /XIOS/dev/branch_openmp/extern/ep_dev/ep_recv.cpp
===================================================================
--- /XIOS/dev/branch_openmp/extern/ep_dev/ep_recv.cpp	(revision 1517)
+++ /XIOS/dev/branch_openmp/extern/ep_dev/ep_recv.cpp	(revision 1518)
@@ -65,6 +65,18 @@
     EP_PendingRequests->push_back(request);  
     int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
-    memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());                                                              
-                                          
+    memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());    
+
+#ifdef _showinfo
+    if(comm->is_intercomm)
+    {
+      int ep_dest_loc  = comm->ep_rank_map->at(dest_rank).first;
+      int ep_src_loc = comm->ep_comm_ptr->intercomm->intercomm_rank_map->at(src).first;
+      int mpi_tag     = tag_combine(tag, ep_src_loc, ep_dest_loc);
+      int mpi_dest    = comm->ep_comm_ptr->intercomm->intercomm_rank_map->at(src).second.first;
+
+      printf("Irecv : ep_src_loc = %d, ep_dest_loc = %d, mpi_src = %d, mpi_dest = %d, mpi_tag = %d\n", ep_src_loc, ep_dest_loc, comm->ep_comm_ptr->size_rank_info[2].first, mpi_dest, mpi_tag);
+    }                                                          
+#endif                                      
+
     return Request_Check();
   }
Index: /XIOS/dev/branch_openmp/extern/ep_dev/ep_send.cpp
===================================================================
--- /XIOS/dev/branch_openmp/extern/ep_dev/ep_send.cpp	(revision 1517)
+++ /XIOS/dev/branch_openmp/extern/ep_dev/ep_send.cpp	(revision 1518)
@@ -223,5 +223,5 @@
 
 #ifdef _showinfo
-    printf("ep_src_loc = %d, ep_dest_loc = %d, mpi_src = %d, mpi_dest = %d, mpi_tag = %d\n", ep_src_loc, ep_dest_loc, comm->ep_comm_ptr->size_rank_info[2].first, mpi_dest, mpi_tag);
+    printf("Send : ep_src_loc = %d, ep_dest_loc = %d, mpi_src = %d, mpi_dest = %d, mpi_tag = %d\n", ep_src_loc, ep_dest_loc, comm->ep_comm_ptr->size_rank_info[2].first, mpi_dest, mpi_tag);
 #endif
     
Index: /XIOS/dev/branch_openmp/extern/ep_dev/main.cpp
===================================================================
--- /XIOS/dev/branch_openmp/extern/ep_dev/main.cpp	(revision 1517)
+++ /XIOS/dev/branch_openmp/extern/ep_dev/main.cpp	(revision 1518)
@@ -826,19 +826,19 @@
       MPI_Barrier(comm);
 
-      if(color==2 && split_rank==1)
+      if(color==2 && split_rank==0)
       {
         double sendbuf[9]={1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
         MPI_Request send_request;
         MPI_Status send_status;
-        MPI_Isend(sendbuf, 9, MPI_DOUBLE, 5, 10, inter_comm, &send_request);
+        MPI_Isend(sendbuf, 9, MPI_DOUBLE, 0, 10, inter_comm, &send_request);
         MPI_Wait(&send_request, &send_status);
       }
 
-      if(color==1 && split_rank==5)
+      if(color==1 && split_rank==0)
       {
         double recvbuf[9];
         MPI_Request recv_request;
         MPI_Status recv_status;
-        MPI_Irecv(recvbuf, 9, MPI_DOUBLE, 1, 10, inter_comm, &recv_request);
+        MPI_Irecv(recvbuf, 9, MPI_DOUBLE, 0, 10, inter_comm, &recv_request);
         MPI_Wait(&recv_request, &recv_status);
         for(int i=0; i<9; i++)
@@ -867,4 +867,176 @@
       MPI_Comm_dup(inter_comm, &inter_comm_dup);
 
+      int inter_comm_dup_size;
+      int inter_comm_dup_remote_size;
+      MPI_Comm_size(inter_comm_dup, &inter_comm_dup_size);
+
+      MPI_Comm_remote_size(inter_comm_dup, &inter_comm_dup_remote_size);
+
+      bool high = inter_comm_dup_size>inter_comm_dup_remote_size;
+
+
+      //printf("rank = %d, high = %d, inter_comm_dup_size = %d, inter_comm_dup_remote_size = %d\n", rank, high, inter_comm_dup_size, inter_comm_dup_remote_size);
+
+      MPI_Comm inter_comm_dup_merged;
+
+      MPI_Intercomm_merge(inter_comm_dup, high, &inter_comm_dup_merged);
+      
+      int inter_comm_dup_merged_rank;
+      MPI_Comm_rank(inter_comm_dup_merged, &inter_comm_dup_merged_rank);
+
+      int inter_comm_dup_merged_size;
+      MPI_Comm_size(inter_comm_dup_merged, &inter_comm_dup_merged_size);
+
+      printf("rank = %d, inter_comm_dup_merged_rank = %d, inter_comm_dup_merged_size = %d\n", rank, inter_comm_dup_merged_rank, inter_comm_dup_merged_size);
+
+      // TEST OF GATHER
+      {
+        int gather_root = 99;
+  
+        if(inter_comm_dup_merged_rank == 0) 
+        {
+          gather_root = rand() % inter_comm_dup_merged_size;
+        }
+  
+        MPI_Bcast(&gather_root, 1, MPI_INT, 0, inter_comm_dup_merged);
+
+        double sendbuf[2];
+        sendbuf[0] = inter_comm_dup_merged_rank * 1.0;
+        sendbuf[1] = inter_comm_dup_merged_size * (-1.0);
+
+        std::vector<double>recvbuf(2*inter_comm_dup_merged_size, 0);
+
+        MPI_Gather(sendbuf, 2, MPI_DOUBLE, recvbuf.data(), 2, MPI_DOUBLE, gather_root, inter_comm_dup_merged);
+
+        bool gather_result = true;
+
+        if(inter_comm_dup_merged_rank == gather_root)
+        {
+          for(int i=0; i<inter_comm_dup_merged_size; i++)
+          {
+            if(abs(recvbuf[2*i] - i) > 1.e-10 || abs(recvbuf[2*i+1] + inter_comm_dup_merged_size) > 1.e-10)
+            {
+              gather_result = false;
+              break;
+            }  
+          }
+
+          if(gather_result) printf("root = %d : \t test MPI_Gather for merged comm\t OK \n", gather_root);
+          else              printf("root = %d : \t test MPI_Gather for merged comm\t FAILED\n", gather_root);
+        }
+      }
+
+      // TEST OF ALLREDUCE
+      {
+ 
+        int sendbuf[2];
+        sendbuf[0] = inter_comm_dup_merged_rank;
+        sendbuf[1] = -inter_comm_dup_merged_size;
+
+        std::vector<int>recvbuf(2, 0);
+
+        MPI_Op op = MPI_MIN;
+
+        MPI_Allreduce(sendbuf, recvbuf.data(), 2, MPI_INT, op, inter_comm_dup_merged);
+
+
+        int allreduce_test = 1;
+
+      
+        if((op == MPI_SUM && (abs(recvbuf[0]-(inter_comm_dup_merged_size-1)*inter_comm_dup_merged_size/2) > 1.e-10 || abs(recvbuf[1] + inter_comm_dup_merged_size * inter_comm_dup_merged_size) > 1.e-10) ) ||
+           (op == MPI_MAX && (abs(recvbuf[0]-(inter_comm_dup_merged_size-1)) > 1.e-10 || abs(recvbuf[1] + inter_comm_dup_merged_size) > 1.e-10) )               ||
+           (op == MPI_MIN && (abs(recvbuf[0]) > 1.e-10 || abs(recvbuf[1] + inter_comm_dup_merged_size) > 1.e-10) ) )
+        {
+          allreduce_test = 0; printf("%d %d\n", recvbuf[0], recvbuf[1]);
+        }  
+      
+
+        int allreduce_result;
+        MPI_Reduce(&allreduce_test, &allreduce_result, 1, MPI_INT, MPI_MIN, 0, inter_comm_dup_merged);
+
+        if(inter_comm_dup_merged_rank == 0 && allreduce_result)  printf("            \t test MPI_Allreduce for merged comm \t OK\n");
+        if(inter_comm_dup_merged_rank == 0 && !allreduce_result) printf("            \t test MPI_Allreduce for merged comm \t FAILED\n");
+    
+      }
+
+      // TEST OF EXSCAN
+      {
+ 
+        std::vector<int>sendbuf(2, inter_comm_dup_merged_rank);
+        std::vector<int>recvbuf(2, -1);
+
+        MPI_Op op = MPI_SUM;
+           
+
+        MPI_Exscan(sendbuf.data(), recvbuf.data(), 2, MPI_INT, op, inter_comm_dup_merged);
+
+        int exscan_test = 1;
+
+        if(inter_comm_dup_merged_rank >0)
+        if((op == MPI_SUM && (abs(recvbuf[0]-inter_comm_dup_merged_rank*(inter_comm_dup_merged_rank-1)/2) > 1.e-10 || abs(recvbuf[1]-inter_comm_dup_merged_rank*(inter_comm_dup_merged_rank-1)/2) > 1.e-10) ) ||
+           (op == MPI_MIN && (abs(recvbuf[0] ) > 1.e-10 || abs(recvbuf[1]) > 1.e-10) )  || 
+           (op == MPI_MAX && (abs(recvbuf[0] - inter_comm_dup_merged_rank+1) > 1.e-10 || abs(recvbuf[1] - inter_comm_dup_merged_rank+1) > 1.e-10) ) )
+        {
+          exscan_test = 0; 
+        }
+
+        //printf(" ID=%d : sendbuf = (%d, %d), recvbuf = (%d, %d), exscan_test = %d \n", inter_comm_dup_merged_rank, sendbuf[0], sendbuf[1], recvbuf[0], recvbuf[1], exscan_test); 
+        
+        int exscan_result;
+        MPI_Reduce(&exscan_test, &exscan_result, 1, MPI_INT, MPI_MIN, 0, inter_comm_dup_merged);
+    
+        if(inter_comm_dup_merged_rank == 0 && exscan_result)  printf("            \t test MPI_Exscan for merged comm \t OK\n");
+        if(inter_comm_dup_merged_rank == 0 && !exscan_result) printf("            \t test MPI_Exscan for merged comm \t FAILED %d\n", exscan_result);
+      }
+
+      // TEST OF SCATTERV
+      {
+
+        int scatterv_root;
+  
+        if(inter_comm_dup_merged_rank == 0) scatterv_root = rand() % inter_comm_dup_merged_size;
+  
+        MPI_Bcast(&scatterv_root, 1, MPI_INT, 0, inter_comm_dup_merged);
+ 
+        std::vector<int>sendbuf(2*inter_comm_dup_merged_size, inter_comm_dup_merged_rank);
+        std::vector<int>recvbuf(2, -1);
+        std::vector<int>sendcounts(inter_comm_dup_merged_size, 2);
+        std::vector<int>displs(inter_comm_dup_merged_size, 0);
+
+        for(int i=0; i<inter_comm_dup_merged_size; i++) displs[i] = 2*(inter_comm_dup_merged_size-1-i);
+
+        if(inter_comm_dup_merged_rank == scatterv_root) 
+        {
+          for(int i=0; i<inter_comm_dup_merged_size; i++) 
+          {
+            sendbuf[2*i] = i;
+            sendbuf[2*i+1] = inter_comm_dup_merged_size;
+          }
+        }
+
+
+        MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT, recvbuf.data(), 2, MPI_INT, scatterv_root, inter_comm_dup_merged);
+
+        //printf("ID = %d : %d %d\n", inter_comm_dup_merged_rank, recvbuf[0], recvbuf[1]);
+
+        int scatterv_test = 1;
+
+     
+        if( abs(recvbuf[0]-(inter_comm_dup_merged_size-1-inter_comm_dup_merged_rank)) > 1.e-10 || abs(recvbuf[1]-inter_comm_dup_merged_size) > 1.e-10 )
+        {
+          scatterv_test = 0; printf("%d %d  id = %d\n", recvbuf[0], recvbuf[1], inter_comm_dup_merged_rank);
+        }  
+    
+
+        int scatterv_result;
+        MPI_Reduce(&scatterv_test, &scatterv_result, 1, MPI_INT, MPI_MIN, scatterv_root, inter_comm_dup_merged);
+
+        if(inter_comm_dup_merged_rank == scatterv_root && scatterv_result)  printf("root = %d : \t test MPI_Scatterv for merged comm \t OK\n", scatterv_root);
+        if(inter_comm_dup_merged_rank == scatterv_root && !scatterv_result) printf("root = %d : \t test MPI_Scatterv for merged comm \t FAILED\n", scatterv_root);
+      }
+
+
+
+
       MPI_Barrier(comm);
       MPI_Barrier(comm);
@@ -872,4 +1044,11 @@
 
       MPI_Comm_free(&inter_comm_dup);
+
+      MPI_Barrier(comm);
+      MPI_Barrier(comm);
+
+
+      MPI_Comm_free(&inter_comm_dup_merged);
+
 
 
