Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_accumulate.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_accumulate.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_accumulate.cpp	(revision 1651)
@@ -0,0 +1,105 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+	int MPI_Accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+                     int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    if(num_ep==1)
+      return  ::MPI_Accumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                               to_mpi_op(op), to_mpi_win(win->server_win[target_local_rank]));
+
+    else
+    	return  ::MPI_Accumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                               to_mpi_op(op), to_mpi_win(win->client_win));
+  }
+
+  int MPI_Raccumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+                     int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request *request)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    ::MPI_Request mpi_request;
+
+    if(num_ep==1)
+    {
+      int return_value = ::MPI_Raccumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                                   to_mpi_op(op), to_mpi_win(win->server_win[target_local_rank]), &mpi_request);
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+
+    else
+    {
+      int return_value = ::MPI_Raccumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                                   to_mpi_op(op), to_mpi_win(win->client_win), &mpi_request);
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+  }
+
+
+  int MPI_Get_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr, 
+                         int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
+                         int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    if(num_ep==1)
+      return ::MPI_Get_accumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), result_addr, result_count, to_mpi_type(result_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count,
+                                  to_mpi_type(target_datatype), to_mpi_op(op), to_mpi_win(win->server_win[target_local_rank]));
+    else
+      return ::MPI_Get_accumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), result_addr, result_count, to_mpi_type(result_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count,
+                                  to_mpi_type(target_datatype), to_mpi_op(op), to_mpi_win(win->client_win));
+  }
+
+  int MPI_Rget_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr, 
+                         int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
+                         int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request *request)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    ::MPI_Request mpi_request;
+    if(num_ep==1)
+    {
+      int return_value = ::MPI_Rget_accumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), result_addr, result_count, to_mpi_type(result_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count,
+                                      to_mpi_type(target_datatype), to_mpi_op(op), to_mpi_win(win->server_win[target_local_rank]), &mpi_request);
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+    else
+    {
+      int return_value = ::MPI_Rget_accumulate(origin_addr, origin_count, to_mpi_type(origin_datatype), result_addr, result_count, to_mpi_type(result_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count,
+                                      to_mpi_type(target_datatype), to_mpi_op(op), to_mpi_win(win->client_win), &mpi_request);
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allgather.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allgather.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allgather.cpp	(revision 1651)
@@ -0,0 +1,138 @@
+#ifdef _usingEP
+/*!
+   \file ep_gather.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Gather, MPI_Allgather
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include <string.h>
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  int MPI_Allgather_local(const void *sendbuf, int count, MPI_Datatype datatype, void *recvbuf, MPI_Comm comm)
+  {
+    assert(valid_type(datatype));
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+
+    #pragma omp critical (write_buffer)
+    comm->my_buffer->void_buffer[ep_rank_loc] = const_cast< void* >(sendbuf);
+
+    MPI_Barrier_local(comm);
+
+    #pragma omp critical (read_buffer)
+    {
+      for(int i=0; i<num_ep; i++)
+        memcpy(recvbuf + datasize * i * count, comm->my_buffer->void_buffer[i], datasize * count);
+    }
+    MPI_Barrier_local(comm);
+  }
+
+  int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
+  {
+
+    if(!comm->is_ep) return ::MPI_Allgather(const_cast<void*>(sendbuf), sendcount, to_mpi_type(sendtype), recvbuf, recvcount, to_mpi_type(recvtype), to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Allgather_intercomm(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
+
+
+    assert(sendcount == recvcount);
+
+    assert(valid_type(sendtype) && valid_type(recvtype));
+
+    MPI_Datatype datatype = sendtype;
+    int count = sendcount;
+
+    ::MPI_Aint datasize, lb;
+
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    bool is_master = ep_rank_loc==0;
+
+    void* local_recvbuf;
+    void* tmp_recvbuf;
+
+
+    if(is_master)
+    {
+      local_recvbuf = new void*[datasize * num_ep * count];
+      tmp_recvbuf = new void*[datasize * count * ep_size];
+    }
+
+    MPI_Gather_local(sendbuf, count, datatype, local_recvbuf, 0, comm);
+
+
+    int* mpi_recvcounts;
+    int *mpi_displs;
+    
+    if(is_master)
+    {
+      
+      mpi_recvcounts = new int[mpi_size];
+      mpi_displs = new int[mpi_size];
+
+      int local_sendcount = num_ep * count;
+
+      ::MPI_Allgather(&local_sendcount, 1, to_mpi_type(MPI_INT), mpi_recvcounts, 1, to_mpi_type(MPI_INT), to_mpi_comm(comm->mpi_comm));
+
+      mpi_displs[0] = 0;
+      for(int i=1; i<mpi_size; i++)
+      {
+        mpi_displs[i] = mpi_displs[i-1] + mpi_recvcounts[i-1];
+      }
+
+    
+      ::MPI_Allgatherv(local_recvbuf, num_ep * count, to_mpi_type(datatype), tmp_recvbuf, mpi_recvcounts, mpi_displs, to_mpi_type(datatype), to_mpi_comm(comm->mpi_comm));
+
+
+      // reorder 
+      int offset;
+      for(int i=0; i<ep_size; i++)
+      {
+        offset = mpi_displs[comm->ep_rank_map->at(i).second] + comm->ep_rank_map->at(i).first * sendcount; 
+        memcpy(recvbuf + i*sendcount*datasize, tmp_recvbuf+offset*datasize, sendcount*datasize);
+      }
+
+      delete[] mpi_recvcounts;
+      delete[] mpi_displs;
+    }
+
+    MPI_Bcast_local(recvbuf, count*ep_size, datatype, 0, comm);
+
+    if(is_master)
+    {
+      delete[] local_recvbuf;
+      delete[] tmp_recvbuf;
+
+    }
+
+  }
+
+  int MPI_Allgather_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
+  {
+    printf("MPI_Allgather_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allgatherv.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allgatherv.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allgatherv.cpp	(revision 1651)
@@ -0,0 +1,124 @@
+#ifdef _usingEP
+/*!
+   \file ep_gather.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Gatherv, MPI_Allgatherv
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm)
+  {
+
+    if(!comm->is_ep) return ::MPI_Allgatherv(sendbuf, sendcount, to_mpi_type(sendtype), recvbuf, recvcounts, displs, to_mpi_type(recvtype), to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Allgatherv_intercomm(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
+
+
+    assert(valid_type(sendtype) && valid_type(recvtype));
+
+    MPI_Datatype datatype = sendtype;
+    int count = sendcount;
+
+    ::MPI_Aint datasize, lb;
+
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    assert(sendcount == recvcounts[ep_rank]);
+
+    bool is_master = ep_rank_loc==0;
+
+    void* local_recvbuf;
+    void* tmp_recvbuf;
+
+    int recvbuf_size = 0;
+    for(int i=0; i<ep_size; i++)
+      recvbuf_size = max(recvbuf_size, displs[i]+recvcounts[i]);
+
+
+    vector<int>local_recvcounts(num_ep, 0);
+    vector<int>local_displs(num_ep, 0);
+
+    MPI_Gather_local(&sendcount, 1, MPI_INT, local_recvcounts.data(), 0, comm);
+    for(int i=1; i<num_ep; i++) local_displs[i] = local_displs[i-1] + local_recvcounts[i-1]; 
+
+
+    if(is_master)
+    {
+      local_recvbuf = new void*[datasize * std::accumulate(local_recvcounts.begin(), local_recvcounts.end(), 0)];
+      tmp_recvbuf = new void*[datasize * std::accumulate(recvcounts, recvcounts+ep_size, 0)];
+    }
+
+    MPI_Gatherv_local(sendbuf, count, datatype, local_recvbuf, local_recvcounts.data(), local_displs.data(), 0, comm);
+
+
+    if(is_master)
+    {
+      std::vector<int>mpi_recvcounts(mpi_size, 0);
+      std::vector<int>mpi_displs(mpi_size, 0);
+
+      int local_sendcount = std::accumulate(local_recvcounts.begin(), local_recvcounts.end(), 0);
+      ::MPI_Allgather(&local_sendcount, 1, to_mpi_type(MPI_INT), mpi_recvcounts.data(), 1, to_mpi_type(MPI_INT), to_mpi_comm(comm->mpi_comm));
+
+      for(int i=1; i<mpi_size; i++)
+        mpi_displs[i] = mpi_displs[i-1] + mpi_recvcounts[i-1];
+
+
+      ::MPI_Allgatherv(local_recvbuf, local_sendcount, to_mpi_type(datatype), tmp_recvbuf, mpi_recvcounts.data(), mpi_displs.data(), to_mpi_type(datatype), to_mpi_comm(comm->mpi_comm));
+
+      // reorder 
+      int offset;
+      for(int i=0; i<ep_size; i++)
+      {
+        int extra = 0;
+        for(int j=0, k=0; j<ep_size, k<comm->ep_rank_map->at(i).first; j++)
+          if(comm->ep_rank_map->at(i).second == comm->ep_rank_map->at(j).second)
+          {
+            extra += recvcounts[j];
+            k++;
+          }  
+
+        offset = mpi_displs[comm->ep_rank_map->at(i).second] +  extra;
+
+        memcpy(recvbuf+displs[i]*datasize, tmp_recvbuf+offset*datasize, recvcounts[i]*datasize);
+        
+      }
+
+    }
+
+    MPI_Bcast_local(recvbuf, recvbuf_size, datatype, 0, comm);
+
+    if(is_master)
+    {
+      delete[] local_recvbuf;
+      delete[] tmp_recvbuf;
+    }
+  }
+
+
+  int MPI_Allgatherv_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm)
+  {
+    printf("MPI_Allgatherv_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allocate.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allocate.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allocate.cpp	(revision 1651)
@@ -0,0 +1,88 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+
+
+
+  int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr)
+  {
+    ::MPI_Alloc_mem(to_mpi_aint(size), to_mpi_info(info), baseptr);
+    return 0;
+   }
+   
+  int MPI_Alloc_mem(unsigned long size, MPI_Info info, void *baseptr)
+  {
+    ::MPI_Alloc_mem(size, *(static_cast< ::MPI_Info*>(info->mpi_info)), baseptr);
+    return 0;
+  }
+
+  int MPI_Win_allocate (MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *baseptr, MPI_Win *win)
+  {
+    int rank, rank_loc, num_ep;
+    MPI_Comm_rank(comm, &rank);
+    rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    
+    *win = new ep_win;
+    
+    (*win)->is_ep = comm->is_ep;
+
+    int num_ep_max;
+    MPI_Allreduce(&num_ep, &num_ep_max, 1, MPI_INT, MPI_MAX, comm);
+
+    assert(num_ep_max > 1);
+    
+    info = new ep_info;
+
+    if(num_ep == 1)  // server
+    {
+      for(int i=0; i<num_ep_max; i++)
+      {
+        (*win)->server_win[i] = new ::MPI_Win;
+      }
+
+      printf("Calling MPI_Win_allocate from server, rank = %d\n", rank);
+      for(int i=0; i<num_ep_max; i++)
+      {
+        ::MPI_Win_allocate(to_mpi_aint(size), disp_unit, to_mpi_info(info), to_mpi_comm(comm->mpi_comm), baseptr, static_cast< ::MPI_Win*>((*win)->server_win[i]));
+        (*win)->comm = comm;
+      }
+    }
+    else  // client
+    {
+      (*win)->client_win = new ::MPI_Win;
+      
+      for(int i=0; i<num_ep; i++)
+      {
+        if(rank_loc == i)
+        {
+          printf("Calling MPI_Win_allocate from client, rank = %d\n", rank);
+          ::MPI_Win_allocate(to_mpi_aint(size), disp_unit, to_mpi_info(info), to_mpi_comm(comm->mpi_comm), baseptr, static_cast< ::MPI_Win*>((*win)->client_win)); 
+          (*win)->comm = comm;
+        }
+        MPI_Barrier_local(comm);
+      }
+
+      if(num_ep_max > num_ep)
+      {
+        #pragma omp master
+        {
+          for(int i=0; i<num_ep_max-num_ep; i++)
+          {
+            (*win)->null_win[i] = new ::MPI_Win;
+            ::MPI_Win_allocate(0, disp_unit, to_mpi_info(info), to_mpi_comm(comm->mpi_comm), baseptr, static_cast< ::MPI_Win*>((*win)->null_win[i])); 
+          }  
+        }  
+      }
+
+    }
+    return 0;
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allreduce.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allreduce.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_allreduce.cpp	(revision 1651)
@@ -0,0 +1,75 @@
+#ifdef _usingEP
+/*!
+   \file ep_reduce.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Reduce, MPI_Allreduce
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+
+namespace ep_lib
+ {
+
+  int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Allreduce(sendbuf, recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Allreduce_intercomm(sendbuf, recvbuf, count, datatype, op, comm);
+
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+
+    ::MPI_Aint datasize, lb;
+
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+    bool is_master = ep_rank_loc==0;
+
+    void* local_recvbuf;
+
+    if(is_master)
+    {
+      local_recvbuf = new void*[datasize * count];
+    }
+
+    MPI_Reduce_local(sendbuf, local_recvbuf, count, datatype, op, 0, comm);
+   
+
+
+    if(is_master)
+    {
+      ::MPI_Allreduce(local_recvbuf, recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+    }
+
+    MPI_Bcast_local(recvbuf, count, datatype, 0, comm);
+
+
+    if(is_master)
+    {
+      delete[] local_recvbuf;
+    }
+
+  }
+
+
+  int MPI_Allreduce_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    printf("MPI_Allreduce_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_alltoall.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_alltoall.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_alltoall.cpp	(revision 1651)
@@ -0,0 +1,67 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_mpi.hpp"
+
+
+namespace ep_lib
+{
+
+  int MPI_Alltoall(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Alltoall(sendbuf, sendcount, to_mpi_type(sendtype), recvbuf, recvcount, to_mpi_type(recvtype), to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Alltoall_intercomm(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
+
+
+    assert(valid_type(sendtype) && valid_type(recvtype));
+    assert(sendcount == recvcount);
+
+    ::MPI_Aint datasize, llb;
+    ::MPI_Type_get_extent(to_mpi_type(sendtype), &llb, &datasize);
+
+    int count = sendcount;
+    
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    void* tmp_recvbuf;
+    if(ep_rank == 0) tmp_recvbuf = new void*[count * ep_size * ep_size * datasize];
+
+    MPI_Gather(sendbuf, count*ep_size, sendtype, tmp_recvbuf, count*ep_size, recvtype, 0, comm);
+    
+    // reorder tmp_buf
+    void* tmp_sendbuf;
+    if(ep_rank == 0) tmp_sendbuf = new void*[count * ep_size * ep_size * datasize];
+
+    if(ep_rank == 0)
+    for(int i=0; i<ep_size; i++)
+    {
+      for(int j=0; j<ep_size; j++)
+      {
+        memcpy(tmp_sendbuf + j*ep_size*count*datasize + i*count*datasize, tmp_recvbuf + i*ep_size*count*datasize + j*count*datasize, count*datasize);
+      }
+    }
+
+    MPI_Scatter(tmp_sendbuf, ep_size*count, sendtype, recvbuf, ep_size*recvcount, recvtype, 0, comm);
+
+    if(ep_rank == 0)
+    {
+      delete[] tmp_recvbuf;
+      delete[] tmp_sendbuf;
+    }
+  }
+
+
+  int MPI_Alltoall_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
+  {
+    printf("MPI_Alltoall_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+}
+
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_barrier.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_barrier.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_barrier.cpp	(revision 1651)
@@ -0,0 +1,54 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+
+  int MPI_Barrier(MPI_Comm comm)
+  {
+
+    if(comm->is_ep) 
+    {
+      return MPI_Barrier_endpoint(comm);
+    }
+
+    
+    return MPI_Barrier_mpi(comm);
+
+  }
+
+  int MPI_Barrier_endpoint(MPI_Comm comm)
+  {
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+
+    MPI_Barrier_local(comm);
+
+    if(ep_rank_loc == 0)
+    {
+      ::MPI_Comm mpi_comm = to_mpi_comm(comm->mpi_comm);
+
+      ::MPI_Barrier(mpi_comm);
+    }
+
+    MPI_Barrier_local(comm);
+  }
+
+
+  int MPI_Barrier_mpi(MPI_Comm comm)
+  {
+    return ::MPI_Barrier(to_mpi_comm(comm->mpi_comm));
+  }
+
+
+  int MPI_Barrier_local(MPI_Comm comm)
+  {
+    comm->ep_barrier->wait();
+  }
+
+
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_barrier.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_barrier.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_barrier.hpp	(revision 1651)
@@ -0,0 +1,66 @@
+#ifndef EP_BARRIER_HPP_INCLUDED
+#define EP_BARRIER_HPP_INCLUDED
+
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  class ep_barrier
+  {
+    private:
+      int nbThreads;          //<The number of threads for this barrier
+      int currentNbThread;    //<The current number of threads waiting
+      bool sense;             //<Direct barrier feedback protection
+      omp_lock_t mutex;       //<To have an atomic int
+
+      ep_barrier(ep_barrier&){}
+      ep_barrier& operator=(ep_barrier&){return *this;}
+
+    public:
+      /** Constructor with the number of threads */
+      explicit ep_barrier(const int inNbThreads)
+          : nbThreads(inNbThreads), currentNbThread(0), sense(false) {
+          omp_init_lock( &mutex );
+      }
+
+      /** Destructor, release the omp lock */
+      ~ep_barrier(){
+          omp_destroy_lock( &mutex );
+      }
+
+      /** Perform a barrier */
+      void wait(){
+          const bool mySense = sense;
+          omp_set_lock( &mutex );
+          const int nbThreadsArrived = (++currentNbThread);
+          omp_unset_lock( &mutex );
+
+          if(nbThreadsArrived == nbThreads) {
+              currentNbThread = 0;
+              sense = !sense;
+              #pragma omp flush
+          }
+          else {
+              volatile const bool* const ptSense = &sense;
+              while( (*ptSense) == mySense){
+              }
+          }
+      }
+
+
+      /** Change the number of threads */
+      void setNbThreads(const int inNbThread){
+          omp_set_lock( &mutex );
+          nbThreads = inNbThread;
+          omp_unset_lock( &mutex );
+      }
+  };
+
+
+}
+#endif
+
+
+#endif // EP_BARRIER_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_bcast.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_bcast.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_bcast.cpp	(revision 1651)
@@ -0,0 +1,81 @@
+#ifdef _usingEP
+/*!
+   \file ep_bcast.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Bcast
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  int MPI_Bcast_local(void *buffer, int count, MPI_Datatype datatype, int local_root, MPI_Comm comm)
+  {
+    assert(valid_type(datatype));
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+    
+
+    if(ep_rank_loc == local_root)
+    {
+      comm->my_buffer->void_buffer[local_root] = buffer;
+    }
+
+    MPI_Barrier_local(comm);
+
+    if(ep_rank_loc != local_root)
+    {
+      #pragma omp critical (_bcast)      
+      memcpy(buffer, comm->my_buffer->void_buffer[local_root], datasize * count);
+    }
+
+    MPI_Barrier_local(comm);
+  }
+
+  int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
+  {
+
+    if(!comm->is_ep) return ::MPI_Bcast(buffer, count, to_mpi_type(datatype), root, to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Bcast_intercomm(buffer, count, datatype, root, comm);
+
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+
+    int root_mpi_rank = comm->ep_rank_map->at(root).second;
+    int root_ep_rank_loc = comm->ep_rank_map->at(root).first;
+
+    //printf("ep_rank = %d, root_mpi_rank = %d, root_ep_rank_loc = %d\n", ep_rank, root_mpi_rank, root_ep_rank_loc);
+
+
+    if((ep_rank_loc==0 && mpi_rank != root_mpi_rank ) || ep_rank == root)
+    {
+      ::MPI_Bcast(buffer, count, to_mpi_type(datatype), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+    }
+
+    if(mpi_rank == root_mpi_rank) MPI_Bcast_local(buffer, count, datatype, root_ep_rank_loc, comm);
+    else                          MPI_Bcast_local(buffer, count, datatype, 0, comm);
+
+  }
+
+
+  int MPI_Bcast_intercomm(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
+  {
+    printf("MPI_Bcast_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_buffer.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_buffer.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_buffer.hpp	(revision 1651)
@@ -0,0 +1,19 @@
+#ifndef EP_BUFFER_HPP_INCLUDED
+#define EP_BUFFER_HPP_INCLUDED
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  struct BUFFER
+  {
+    void * void_buffer[12];
+  };
+
+
+}
+
+
+#endif
+#endif // EP_BUFFER_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_comm.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_comm.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_comm.hpp	(revision 1651)
@@ -0,0 +1,67 @@
+#ifndef EP_COMM_HPP_INCLUDED
+#define EP_COMM_HPP_INCLUDED
+#ifdef _usingEP
+#include "ep_message.hpp"
+#include "ep_barrier.hpp"
+#include "ep_buffer.hpp"
+
+typedef std::pair< int, int > SIZE_RANK_INFO; // < rank, size>
+typedef std::vector< std::pair<int, int> > RANK_MAP;  // at(ep_rank) = <ep_rank_local, mpi_rank>
+typedef std::map<int, std::pair<int, int> > EP_RANK_MAP;  // key(ep_rank) = <ep_rank_local, mpi_rank>
+typedef std::list<ep_lib::MPI_Message > Message_list;
+typedef std::map<int, int > INTER_RANK_MAP;
+
+namespace ep_lib
+{
+
+  class ep_comm;
+  
+  class ep_communicator
+  {
+    public:
+
+    SIZE_RANK_INFO size_rank_info[3]; // 0: ep_rank,     ep_size
+                                      // 1: ep_rank_loc, num_ep
+                                      // 2: mpi_rank,    mpi_size
+
+    ep_comm **comm_list;
+
+    Message_list *message_queue;
+
+  };
+  
+
+  class ep_comm
+  {
+    public:
+
+    bool is_ep;
+    bool is_intercomm;
+
+    BUFFER     *my_buffer;
+    
+    ep_barrier *ep_barrier;
+
+    EP_RANK_MAP   *ep_rank_map;
+    
+    INTER_RANK_MAP *inter_rank_map;
+
+    void* mpi_comm;
+    ep_communicator *ep_comm_ptr;
+    ep_comm    **mem_bridge;
+    void* mpi_bridge;
+
+    ep_comm(){};  
+    ep_comm(void* comm);
+
+  };
+  
+  typedef ep_comm*  MPI_Comm;
+
+
+}
+
+
+#endif
+#endif // EP_COMM_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_compare.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_compare.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_compare.cpp	(revision 1651)
@@ -0,0 +1,25 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+	int MPI_Compare_and_swap(const void *origin_addr, const void *compare_addr, void *result_addr, MPI_Datatype datatype, int target_rank, MPI_Aint target_disp, MPI_Win win)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    if(num_ep==1)
+      return  ::MPI_Compare_and_swap(origin_addr, compare_addr, result_addr, to_mpi_type(datatype), target_mpi_rank, to_mpi_aint(target_disp), to_mpi_win(win->server_win[target_local_rank]));
+
+    else
+    	return  ::MPI_Compare_and_swap(origin_addr, compare_addr, result_addr, to_mpi_type(datatype), target_mpi_rank, to_mpi_aint(target_disp), to_mpi_win(win->client_win));
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_create.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_create.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_create.cpp	(revision 1651)
@@ -0,0 +1,138 @@
+#ifdef _usingEP
+/*!
+   \file ep_create.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI endpoint function: MPI_Comm_create_endpoints
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib {
+
+  /*!
+    Dynamic creation of endpoints for each MPI process.
+    The output of this function is an array of communicator handles of length num_ep, where each handle
+    corresponds to a nez local randk in the output communicator.
+    Once created, endpoints behave as MPI processes.
+    \param [in] mpi_comm Parent MPI communicator.
+    \param [in] num_ep Number of endpoints per process.
+    \param [out] info Information of the EP creation.
+    \param [out] out_comm_hdls Handles of EP communicators.
+  */
+  
+  int MPI_Comm_create_endpoints(void* base_comm_ptr, int num_ep, MPI_Info info, MPI_Comm *& out_comm_hdls)
+  {
+
+    int base_rank;
+    int base_size;
+    
+    ::MPI_Comm mpi_base_comm = to_mpi_comm(base_comm_ptr);
+
+    ::MPI_Comm_size(mpi_base_comm, &base_size);  // ep_lib::mpi_comm_size
+    ::MPI_Comm_rank(mpi_base_comm, &base_rank);  // ep_lib::mpi_comm_rank
+                    // parent_comm can also be endpoints communicators
+
+    std::vector<int> recv_num_ep(base_size);
+
+    out_comm_hdls = new MPI_Comm[num_ep];
+#ifdef _showinfo
+    printf("new out_comm_hdls = %p\n", out_comm_hdls);
+#endif
+
+    ::MPI_Comm *parent_comm = new ::MPI_Comm;
+    ::MPI_Comm_dup(to_mpi_comm(base_comm_ptr), parent_comm);
+
+#ifdef _showinfo
+    printf("new out_comm_hdls->mpi_comm = %p\n", parent_comm);
+#endif
+    
+    for (int idx = 0; idx < num_ep; ++idx)
+    {
+
+      out_comm_hdls[idx] = new ep_comm;
+#ifdef _showinfo
+      printf("new out_comm_hdls[%d] = %p\n", idx, out_comm_hdls[idx]);
+#endif
+
+      out_comm_hdls[idx]->is_ep = true;
+      out_comm_hdls[idx]->is_intercomm = false;
+      
+      out_comm_hdls[idx]->ep_comm_ptr = new ep_communicator;     
+#ifdef _showinfo
+      printf("new out_comm_hdls[%d]->ep_comm_ptr = %p\n", idx, out_comm_hdls[idx]->ep_comm_ptr);
+#endif
+
+
+      out_comm_hdls[idx]->mpi_comm = parent_comm;
+      out_comm_hdls[idx]->ep_comm_ptr->comm_list = out_comm_hdls;
+    }
+
+    ::MPI_Allgather(&num_ep, 1, to_mpi_type(MPI_INT), &recv_num_ep[0], 1, to_mpi_type(MPI_INT), mpi_base_comm);
+
+
+    int sum = 0;  // representing total ep number of process with smaller rank
+    for (int i = 0; i < base_rank; ++i) {sum += recv_num_ep[i]; }
+
+    int ep_size = std::accumulate(recv_num_ep.begin(), recv_num_ep.end(), 0);
+
+    out_comm_hdls[0]->ep_barrier = new ep_barrier(num_ep);
+#ifdef _showinfo
+    printf("new out_comm_hdls[0]->ep_barrier = %p\n", out_comm_hdls[0]->ep_barrier);
+#endif
+
+    out_comm_hdls[0]->my_buffer = new BUFFER;
+#ifdef _showinfo
+    printf("new out_comm_hdls[0]->my_buffer = %p\n", out_comm_hdls[0]->my_buffer);
+#endif
+
+    out_comm_hdls[0]->ep_rank_map = new EP_RANK_MAP;
+#ifdef _showinfo
+    printf("new out_comm_hdls[0]->ep_rank_map = %p\n", out_comm_hdls[0]->ep_rank_map);
+#endif
+
+    for (int i = 1; i < num_ep; i++)
+    {
+      out_comm_hdls[i]->ep_barrier = out_comm_hdls[0]->ep_barrier;
+      out_comm_hdls[i]->my_buffer  = out_comm_hdls[0]->my_buffer;
+      out_comm_hdls[i]->ep_rank_map= out_comm_hdls[0]->ep_rank_map;
+    }
+
+
+    for (int i = 0; i < num_ep; i++)
+    {
+      out_comm_hdls[i]->ep_comm_ptr->size_rank_info[0] = std::make_pair(sum+i, ep_size);
+      out_comm_hdls[i]->ep_comm_ptr->size_rank_info[1] = std::make_pair(i, num_ep);
+      out_comm_hdls[i]->ep_comm_ptr->size_rank_info[2] = std::make_pair(base_rank, base_size);
+
+      out_comm_hdls[i]->ep_comm_ptr->message_queue = new Message_list;
+#ifdef _showinfo
+      printf("new out_comm_hdls[%d]->ep_comm_ptr->message_queue = %p\n", i, out_comm_hdls[i]->ep_comm_ptr->message_queue);
+#endif
+
+    }
+
+
+    int ind = 0;
+
+    for(int i=0; i<base_size; i++)
+    {
+      for(int j=0; j<recv_num_ep[i]; j++)
+      {
+        //out_comm_hdls[0]->ep_rank_map->insert(std::pair< int, std::pair<int,int> >(ind, j, i));
+        (*(out_comm_hdls[0]->ep_rank_map))[ind] = std::make_pair(j,i);//->insert(std::pair< int, std::pair<int,int> >(ind, j, i));
+        ind++;
+      }
+    }
+
+  } //MPI_Comm_create_endpoints
+
+  
+
+} //namespace ep_lib
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_declaration.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_declaration.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_declaration.cpp	(revision 1651)
@@ -0,0 +1,113 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+
+#include <mpi.h>
+
+::MPI_Comm MPI_COMM_WORLD_STD = MPI_COMM_WORLD;
+#undef MPI_COMM_WORLD
+
+
+::MPI_Comm MPI_COMM_NULL_STD = MPI_COMM_NULL;
+#undef MPI_COMM_NULL
+
+
+::MPI_Request MPI_REQUEST_NULL_STD = MPI_REQUEST_NULL;
+#undef MPI_REQUEST_NULL
+
+::MPI_Info MPI_INFO_NULL_STD = MPI_INFO_NULL;
+#undef MPI_INFO_NULL
+
+::MPI_Datatype MPI_INT_STD = MPI_INT;
+::MPI_Datatype MPI_FLOAT_STD = MPI_FLOAT;
+::MPI_Datatype MPI_DOUBLE_STD = MPI_DOUBLE;
+::MPI_Datatype MPI_LONG_STD = MPI_LONG;
+::MPI_Datatype MPI_CHAR_STD = MPI_CHAR;
+::MPI_Datatype MPI_UNSIGNED_LONG_STD = MPI_UNSIGNED_LONG;
+::MPI_Datatype MPI_UNSIGNED_CHAR_STD = MPI_UNSIGNED_CHAR;
+::MPI_Datatype MPI_UINT64_T_STD = MPI_UINT64_T;
+::MPI_Datatype MPI_LONG_LONG_INT_STD = MPI_LONG_LONG_INT;
+
+#undef MPI_INT
+#undef MPI_FLOAT
+#undef MPI_DOUBLE
+#undef MPI_LONG
+#undef MPI_CHAR
+#undef MPI_UNSIGNED_LONG
+#undef MPI_UNSIGNED_CHAR
+#undef MPI_UINT64_T
+#undef MPI_LONG_LONG_INT
+
+
+::MPI_Op MPI_SUM_STD = MPI_SUM;
+::MPI_Op MPI_MAX_STD = MPI_MAX;
+::MPI_Op MPI_MIN_STD = MPI_MIN;
+::MPI_Op MPI_LOR_STD = MPI_LOR;
+::MPI_Op MPI_REPLACE_STD = MPI_REPLACE;
+
+#undef MPI_SUM
+#undef MPI_MAX
+#undef MPI_MIN
+#undef MPI_LOR
+#undef MPI_REPLACE
+
+
+// _STD defined in ep_type.cpp
+
+extern ::MPI_Datatype MPI_INT_STD;
+extern ::MPI_Datatype MPI_FLOAT_STD;
+extern ::MPI_Datatype MPI_DOUBLE_STD;
+extern ::MPI_Datatype MPI_LONG_STD;
+extern ::MPI_Datatype MPI_CHAR_STD;
+extern ::MPI_Datatype MPI_UNSIGNED_LONG_STD;
+extern ::MPI_Datatype MPI_UNSIGNED_CHAR_STD;
+extern ::MPI_Datatype MPI_UINT64_T_STD;
+extern ::MPI_Datatype MPI_LONG_LONG_INT_STD;
+
+
+extern ::MPI_Op MPI_SUM_STD;
+extern ::MPI_Op MPI_MAX_STD;
+extern ::MPI_Op MPI_MIN_STD;
+extern ::MPI_Op MPI_LOR_STD;
+extern ::MPI_Op MPI_REPLACE_STD;
+
+extern ::MPI_Comm MPI_COMM_WORLD_STD;
+extern ::MPI_Comm MPI_COMM_NULL_STD;
+
+extern ::MPI_Status MPI_STATUS_IGNORE_STD;
+extern ::MPI_Request MPI_REQUEST_NULL_STD;
+extern ::MPI_Info MPI_INFO_NULL_STD;
+
+ep_lib::MPI_Datatype MPI_INT = &MPI_INT_STD;
+ep_lib::MPI_Datatype MPI_FLOAT = &MPI_FLOAT_STD;
+ep_lib::MPI_Datatype MPI_DOUBLE = &MPI_DOUBLE_STD;
+ep_lib::MPI_Datatype MPI_CHAR = &MPI_CHAR_STD;
+ep_lib::MPI_Datatype MPI_LONG = &MPI_LONG_STD;
+ep_lib::MPI_Datatype MPI_UNSIGNED_LONG = &MPI_UNSIGNED_LONG_STD;
+ep_lib::MPI_Datatype MPI_UNSIGNED_CHAR = &MPI_UNSIGNED_CHAR_STD;
+ep_lib::MPI_Datatype MPI_UINT64_T = &MPI_UINT64_T_STD;
+ep_lib::MPI_Datatype MPI_LONG_LONG_INT = &MPI_LONG_LONG_INT_STD;
+
+
+ep_lib::MPI_Op MPI_SUM = &MPI_SUM_STD;
+ep_lib::MPI_Op MPI_MAX = &MPI_MAX_STD;
+ep_lib::MPI_Op MPI_MIN = &MPI_MIN_STD;
+ep_lib::MPI_Op MPI_LOR = &MPI_LOR_STD;
+ep_lib::MPI_Op MPI_REPLACE = &MPI_REPLACE_STD;
+
+ep_lib::ep_comm EP_COMM_WORLD(&MPI_COMM_WORLD_STD);
+ep_lib::ep_comm EP_COMM_NULL(&MPI_COMM_NULL_STD);
+
+ep_lib::MPI_Comm MPI_COMM_WORLD = &EP_COMM_WORLD;
+ep_lib::MPI_Comm MPI_COMM_NULL = &EP_COMM_NULL;
+
+//ep_lib::ep_status EP_STATUS_IGNORE(&MPI_STATUS_IGNORE_STD);
+ep_lib::ep_request EP_REQUEST_NULL(&MPI_REQUEST_NULL_STD);
+ep_lib::ep_info EP_INFO_NULL(&MPI_INFO_NULL_STD);
+
+//ep_lib::MPI_Status MPI_STATUS_IGNORE = &EP_STATUS_IGNORE;
+ep_lib::MPI_Request MPI_REQUEST_NULL = &EP_REQUEST_NULL;
+ep_lib::MPI_Info MPI_INFO_NULL = &EP_INFO_NULL;
+
+
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_declaration.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_declaration.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_declaration.hpp	(revision 1651)
@@ -0,0 +1,55 @@
+#ifndef EP_DECLARATION_HPP_INCLUDED
+#define EP_DECLARATION_HPP_INCLUDED
+
+#ifdef _usingEP
+
+#undef MPI_INT
+#undef MPI_FLOAT
+#undef MPI_DOUBLE
+#undef MPI_CHAR
+#undef MPI_LONG
+#undef MPI_UNSIGNED_LONG
+#undef MPI_UNSIGNED_CHAR
+#undef MPI_UINT64_T
+#undef MPI_LONG_LONG_INT
+
+#undef MPI_SUM
+#undef MPI_MAX
+#undef MPI_MIN
+#undef MPI_LOR
+#undef MPI_REPLACE
+
+#undef MPI_COMM_WORLD
+#undef MPI_COMM_NULL
+
+#undef MPI_REQUEST_NULL
+#undef MPI_STATUS_IGNORE
+#undef MPI_INFO_NULL
+
+extern ep_lib::MPI_Datatype MPI_INT;
+extern ep_lib::MPI_Datatype MPI_FLOAT;
+extern ep_lib::MPI_Datatype MPI_DOUBLE;
+extern ep_lib::MPI_Datatype MPI_CHAR;
+extern ep_lib::MPI_Datatype MPI_LONG;
+extern ep_lib::MPI_Datatype MPI_UNSIGNED_LONG;
+extern ep_lib::MPI_Datatype MPI_UNSIGNED_CHAR;
+extern ep_lib::MPI_Datatype MPI_UINT64_T;
+extern ep_lib::MPI_Datatype MPI_LONG_LONG_INT;
+
+extern ep_lib::MPI_Op MPI_SUM;
+extern ep_lib::MPI_Op MPI_MAX;
+extern ep_lib::MPI_Op MPI_MIN;
+extern ep_lib::MPI_Op MPI_LOR;
+extern ep_lib::MPI_Op MPI_REPLACE;
+
+extern ep_lib::MPI_Comm MPI_COMM_WORLD;
+extern ep_lib::MPI_Comm MPI_COMM_NULL;
+
+extern ep_lib::MPI_Status MPI_STATUS_IGNORE;
+extern ep_lib::MPI_Request MPI_REQUEST_NULL;
+extern ep_lib::MPI_Info MPI_INFO_NULL;
+
+#endif
+
+#endif // EP_DECLARATION_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_dup.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_dup.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_dup.cpp	(revision 1651)
@@ -0,0 +1,76 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+
+  
+  int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm)
+  {
+    
+    if(!comm->is_ep)
+    {
+      Debug("MPI_Comm_dup with MPI\n");
+      return MPI_Comm_dup_mpi(comm, newcomm); 
+    }
+
+    return MPI_Comm_dup_endpoint(comm, newcomm); 
+   
+  }
+
+
+  
+  int MPI_Comm_dup_endpoint(MPI_Comm comm, MPI_Comm *newcomm)
+  {
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep      = comm->ep_comm_ptr->size_rank_info[1].second;
+
+
+    if(0 == ep_rank_loc)
+    {
+      MPI_Info info;
+      MPI_Comm *out_comm;
+
+      MPI_Comm_create_endpoints(comm->mpi_comm, num_ep, info, out_comm);
+      comm->ep_comm_ptr->comm_list[0]->mem_bridge = out_comm;
+    }
+
+    MPI_Barrier_local(comm);
+
+    *newcomm = (comm->ep_comm_ptr->comm_list[0]->mem_bridge[ep_rank_loc]);
+
+    if(comm->is_intercomm)
+    {
+      (*newcomm)->is_intercomm = true;
+      (*newcomm)->ep_comm_ptr->size_rank_info[0] = comm->ep_comm_ptr->size_rank_info[0];
+      (*newcomm)->inter_rank_map = new INTER_RANK_MAP;
+
+      for(INTER_RANK_MAP::iterator it = comm->inter_rank_map->begin(); it !=comm->inter_rank_map->end(); it++)
+      {
+        (*newcomm)->inter_rank_map->insert(std::make_pair(it->first, it->second));
+      }
+
+    }
+    
+  }
+
+  int MPI_Comm_dup_mpi(MPI_Comm comm, MPI_Comm *newcomm)
+  {
+    newcomm = new MPI_Comm;
+    (*newcomm)->is_ep = false;
+
+    ::MPI_Comm *output = new ::MPI_Comm;
+      
+    ::MPI_Comm_dup(to_mpi_comm(comm->mpi_comm), output);
+
+    (*newcomm)->mpi_comm = output;
+  }
+
+
+
+}
+#endif
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_exscan.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_exscan.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_exscan.cpp	(revision 1651)
@@ -0,0 +1,366 @@
+#ifdef _usingEP
+/*!
+   \file ep_scan.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Exscan
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+  template<typename T>
+  T max_op(T a, T b)
+  {
+    return max(a,b);
+  }
+
+  template<typename T>
+  T min_op(T a, T b)
+  {
+    return min(a,b);
+  }
+
+  template<typename T>
+  void reduce_max(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, max_op<T>);
+  }
+
+  template<typename T>
+  void reduce_min(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, min_op<T>);
+  }
+
+  template<typename T>
+  void reduce_sum(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, std::plus<T>());
+  }
+
+
+  int MPI_Exscan_local(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    valid_op(op);
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+    if(ep_rank_loc == 0 && mpi_rank != 0)
+    {
+      comm->my_buffer->void_buffer[0] = recvbuf;
+    }
+    if(ep_rank_loc == 0 && mpi_rank == 0)
+    {
+      comm->my_buffer->void_buffer[0] = const_cast<void*>(sendbuf);  
+    } 
+      
+
+    MPI_Barrier_local(comm);
+
+    memcpy(recvbuf, comm->my_buffer->void_buffer[0], datasize*count);
+
+    MPI_Barrier_local(comm);
+
+    comm->my_buffer->void_buffer[ep_rank_loc] = const_cast<void*>(sendbuf);  
+    
+    MPI_Barrier_local(comm);
+
+    if(op == MPI_SUM)
+    {
+      if(datatype == MPI_INT )
+      {
+        assert(datasize == sizeof(int));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_sum<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);    
+      }
+     
+      else if(datatype == MPI_FLOAT )
+      {
+        assert(datasize == sizeof(float));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_sum<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);    
+      }
+      
+
+      else if(datatype == MPI_DOUBLE )
+      {
+        assert(datasize == sizeof(double));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_sum<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_CHAR )
+      {
+        assert(datasize == sizeof(char));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_sum<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_LONG )
+      {
+        assert(datasize == sizeof(long));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_sum<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_UNSIGNED_LONG )
+      {
+        assert(datasize == sizeof(unsigned long));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_sum<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);    
+      }
+      
+      else if(datatype == MPI_LONG_LONG_INT )
+      {
+        assert(datasize == sizeof(long long int));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_sum<long long int>(static_cast<long long int*>(comm->my_buffer->void_buffer[i]), static_cast<long long int*>(recvbuf), count);    
+      }
+
+      else 
+      {
+        printf("datatype Error in ep_exscan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+        MPI_Abort(comm, 0);
+      }
+
+      
+    }
+
+    else if(op == MPI_MAX)
+    {
+      if(datatype == MPI_INT )
+      {
+        assert(datasize == sizeof(int));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_max<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_FLOAT )
+      {
+        assert(datasize == sizeof(float));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_max<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_DOUBLE )
+      {
+        assert(datasize == sizeof(double));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_max<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_CHAR )
+      {
+        assert(datasize == sizeof(char));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_max<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_LONG )
+      {
+        assert(datasize == sizeof(long));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_max<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_UNSIGNED_LONG )
+      {
+        assert(datasize == sizeof(unsigned long));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_max<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);    
+      }
+     
+      else if(datatype == MPI_LONG_LONG_INT )
+      {
+        assert(datasize == sizeof(long long int));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_max<long long int>(static_cast<long long int*>(comm->my_buffer->void_buffer[i]), static_cast<long long int*>(recvbuf), count);    
+      }
+
+      else 
+      {
+        printf("datatype Error in ep_exscan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+        MPI_Abort(comm, 0);
+      }
+    }
+
+    else if(op == MPI_MIN)
+    {
+      if(datatype == MPI_INT )
+      {
+        assert(datasize == sizeof(int));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_min<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_FLOAT )
+      {
+        assert(datasize == sizeof(float));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_min<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_DOUBLE )
+      {
+        assert(datasize == sizeof(double));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_min<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_CHAR )
+      {
+        assert(datasize == sizeof(char));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_min<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_LONG )
+      {
+        assert(datasize == sizeof(long));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_min<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_UNSIGNED_LONG )
+      {
+        assert(datasize == sizeof(unsigned long));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_min<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_LONG_LONG_INT )
+      {
+        assert(datasize == sizeof(long long int));
+        for(int i=0; i<ep_rank_loc; i++)
+          reduce_min<long long int>(static_cast<long long int*>(comm->my_buffer->void_buffer[i]), static_cast<long long int*>(recvbuf), count);    
+      }
+
+      else 
+      {
+        printf("datatype Error in ep_exscan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+        MPI_Abort(comm, 0);
+      }
+    }
+    
+    else
+    {
+      printf("op type Error in ep_exscan : MPI_MAX, MPI_MIN, MPI_SUM\n");
+      MPI_Abort(comm, 0);
+    }
+
+    MPI_Barrier_local(comm);
+
+  }
+
+  int MPI_Exscan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Exscan(sendbuf, recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Exscan_intercomm(sendbuf, recvbuf, count, datatype, op, comm);
+    
+    assert(valid_type(datatype));
+    assert(valid_op(op));
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+    
+    void* tmp_sendbuf;
+    tmp_sendbuf = new void*[datasize * count];
+
+    int my_src = 0;
+    int my_dst = ep_rank;
+
+    std::vector<int> my_map(mpi_size, 0);
+
+    for(int i=0; i<comm->ep_rank_map->size(); i++) my_map[comm->ep_rank_map->at(i).second]++;
+
+    for(int i=0; i<mpi_rank; i++) my_src += my_map[i];
+    my_src += ep_rank_loc;
+
+     
+    for(int i=0; i<mpi_size; i++)
+    {
+      if(my_dst < my_map[i])
+      {
+        my_dst = get_ep_rank(comm, my_dst, i); 
+        break;
+      }
+      else
+        my_dst -= my_map[i];
+    }
+
+    if(ep_rank != my_dst) 
+    {
+      MPI_Request request[2];
+      MPI_Status status[2];
+
+      MPI_Isend(sendbuf,     count, datatype, my_dst, my_dst,  comm, &request[0]);
+    
+      MPI_Irecv(tmp_sendbuf, count, datatype, my_src, ep_rank, comm, &request[1]);
+    
+      MPI_Waitall(2, request, status);
+    }
+
+    else memcpy(tmp_sendbuf, sendbuf, datasize*count);
+    
+
+    void* tmp_recvbuf;
+    tmp_recvbuf = new void*[datasize * count];    
+
+    MPI_Reduce_local(tmp_sendbuf, tmp_recvbuf, count, datatype, op, 0, comm);
+
+    if(ep_rank_loc == 0)
+    {
+      ::MPI_Exscan(MPI_IN_PLACE, tmp_recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+    }
+    
+    MPI_Exscan_local(tmp_sendbuf, tmp_recvbuf, count, datatype, op, comm);
+
+
+    if(ep_rank != my_src) 
+    {
+      MPI_Request request[2];
+      MPI_Status status[2];
+
+      MPI_Isend(tmp_recvbuf, count, datatype, my_src, my_src,  comm, &request[0]);
+    
+      MPI_Irecv(recvbuf,     count, datatype, my_dst, ep_rank, comm, &request[1]);
+    
+      MPI_Waitall(2, request, status);
+    }
+
+    else memcpy(recvbuf, tmp_recvbuf, datasize*count);
+
+    delete[] tmp_sendbuf;
+    delete[] tmp_recvbuf;
+
+  }
+
+
+  int MPI_Exscan_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    printf("MPI_Exscan_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_fetch.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_fetch.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_fetch.cpp	(revision 1651)
@@ -0,0 +1,25 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+	int MPI_Fetch_and_op(const void *origin_addr, void *result_addr, MPI_Datatype datatype, int target_rank, MPI_Aint target_disp, MPI_Op op, MPI_Win win)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    if(num_ep==1)
+      return  ::MPI_Fetch_and_op(origin_addr, result_addr, to_mpi_type(datatype), target_mpi_rank, to_mpi_aint(target_disp), to_mpi_op(op), to_mpi_win(win->server_win[target_local_rank]));
+
+    else
+    	return  ::MPI_Fetch_and_op(origin_addr, result_addr, to_mpi_type(datatype), target_mpi_rank, to_mpi_aint(target_disp), to_mpi_op(op), to_mpi_win(win->client_win));
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_finalize.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_finalize.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_finalize.cpp	(revision 1651)
@@ -0,0 +1,26 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+
+  int MPI_Finalize()
+  {
+    #pragma omp master
+    {
+      printf("calling EP Finalize\n");
+      ::MPI_Finalize();
+    }
+  }
+
+  int MPI_Abort(MPI_Comm comm, int errorcode)
+  {
+    return ::MPI_Abort(to_mpi_comm(comm->mpi_comm), errorcode);
+  }
+
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_fortran.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_fortran.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_fortran.cpp	(revision 1651)
@@ -0,0 +1,90 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include "ep_lib_fortran.hpp"
+#include <mpi.h>
+#include <map>
+#include <utility>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+
+//namespace ep_lib
+//{
+
+  void* EP_Comm_c2f(ep_lib::MPI_Comm comm)
+  {
+    Debug("MPI_Comm_c2f");
+    void* fint = new MPI_Fint;
+    #ifdef _intelmpi
+    *static_cast< ::MPI_Fint*>(fint) = (::MPI_Fint)(to_mpi_comm(comm->mpi_comm));
+    #elif _openmpi
+    *static_cast< MPI_Fint*>(fint) = MPI_Comm_c2f(to_mpi_comm(comm->mpi_comm));
+    #endif
+    
+    std::map<std::pair< MPI_Fint, int>, ep_lib::MPI_Comm > ::iterator it;
+    
+    #pragma omp critical (fc_comm_map)
+    {
+      it = ep_lib::fc_comm_map.find(std::make_pair(*static_cast< MPI_Fint*>(fint), omp_get_thread_num()));
+      if(it == ep_lib::fc_comm_map.end())
+      {
+        ep_lib::fc_comm_map.insert(std::make_pair( std::make_pair( *static_cast< MPI_Fint*>(fint), omp_get_thread_num()) , comm));
+        printf("EP_Comm_c2f : MAP %p insert: %d, %d, %p\n", &(ep_lib::fc_comm_map), *static_cast< MPI_Fint*>(fint), omp_get_thread_num(), comm->ep_comm_ptr);
+      }
+    }
+    
+    
+    return fint;
+    
+  }
+
+  ep_lib::MPI_Comm EP_Comm_f2c(void* comm)
+  {
+    Debug("MPI_Comm_f2c");
+    
+    
+    std::map<std::pair< MPI_Fint, int>, ep_lib::MPI_Comm > ::iterator it;
+    
+    #pragma omp critical (fc_comm_map)
+    it = ep_lib::fc_comm_map.find(std::make_pair(*static_cast< MPI_Fint*>(comm), omp_get_thread_num()));
+    
+    if(it != ep_lib::fc_comm_map.end())
+    {
+      ep_lib::MPI_Comm comm_ptr;
+      comm_ptr = it->second;
+      printf("EP_Comm_f2c : MAP %p find: %d, %d, %p\n", &(ep_lib::fc_comm_map), it->first.first, it->first.second, comm_ptr->ep_comm_ptr);
+      return  comm_ptr;
+    }
+       
+      
+    
+    MPI_Comm *base_comm = new MPI_Comm;
+    #ifdef _intelmpi
+    *base_comm = (MPI_Comm)(*static_cast< MPI_Fint*>(comm));
+    #elif _openmpi
+    *base_comm = MPI_Comm_f2c(*static_cast< MPI_Fint*>(comm));
+    #endif
+
+    if(*base_comm != to_mpi_comm(MPI_COMM_NULL->mpi_comm))
+    {
+      if(omp_get_thread_num() == 0)
+      {
+        int num_ep = omp_get_num_threads();
+        ep_lib::MPI_Comm *new_comm;
+        ep_lib::MPI_Info info;
+        ep_lib::MPI_Comm_create_endpoints(base_comm, num_ep, info, new_comm);
+        ep_lib::passage = new_comm;
+      }
+      #pragma omp barrier
+
+      ep_lib::MPI_Comm return_comm = ep_lib::passage[omp_get_thread_num()];
+      return return_comm;
+        
+    }
+    return MPI_COMM_NULL;
+
+  }
+
+//}
+#endif
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_free.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_free.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_free.cpp	(revision 1651)
@@ -0,0 +1,111 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+
+  int MPI_Comm_free(MPI_Comm *comm)
+  {
+    if(! (*comm)->is_ep) return MPI_Comm_free_mpi(comm);
+    else return MPI_Comm_free_endpoint(comm);
+  }
+
+
+
+  int MPI_Comm_free_mpi(MPI_Comm *comm)
+  {
+    Debug("MPI_Comm_free with MPI\n");
+    return ::MPI_Comm_free(to_mpi_comm_ptr((*comm)->mpi_comm));
+  }
+
+  int MPI_Comm_free_endpoint(MPI_Comm *comm)
+  {
+    Debug("MPI_Comm_free with EP_intracomm\n");
+
+    int ep_rank_loc, num_ep;
+
+    ep_rank_loc = (*comm)->ep_comm_ptr->size_rank_info[1].first;
+    num_ep = (*comm)->ep_comm_ptr->size_rank_info[1].second;
+
+    MPI_Barrier_local(*comm);
+
+    if(ep_rank_loc == 0)
+    {
+
+      if((*comm)->is_intercomm)
+      {
+        for(int i=0; i<num_ep; i++)
+        {
+          (*comm)->ep_comm_ptr->comm_list[i]->inter_rank_map->clear();
+#ifdef _showinfo
+          printf("delete (*comm)->ep_comm_ptr->comm_list[%d]->inter_rank_map = %p\n", i, (*comm)->ep_comm_ptr->comm_list[i]->inter_rank_map);
+#endif
+          delete (*comm)->ep_comm_ptr->comm_list[i]->inter_rank_map;
+        }
+      }
+
+
+
+#ifdef _showinfo
+      printf("delete (*comm)->my_buffer = %p\n", (*comm)->my_buffer);
+#endif
+      delete (*comm)->my_buffer;
+
+
+      
+#ifdef _showinfo        
+      printf("delete (*comm)->ep_barrier = %p\n", (*comm)->ep_barrier);
+#endif
+      delete (*comm)->ep_barrier;
+      
+
+
+      (*comm)->ep_rank_map->clear();
+#ifdef _showinfo
+      printf("delete (*comm)->ep_rank_map = %p\n", (*comm)->ep_rank_map);
+#endif
+      delete (*comm)->ep_rank_map;
+      
+
+      for(int i=0; i<num_ep; i++)
+      {
+        (*comm)->ep_comm_ptr->comm_list[i]->ep_comm_ptr->message_queue->clear();
+#ifdef _showinfo
+        printf("delete (*comm)->ep_comm_ptr->comm_list[%d]->ep_comm_ptr->message_queue = %p\n", i, (*comm)->ep_comm_ptr->comm_list[i]->ep_comm_ptr->message_queue);
+#endif
+        delete (*comm)->ep_comm_ptr->comm_list[i]->ep_comm_ptr->message_queue;
+          
+
+#ifdef _showinfo
+        printf("delete (*comm)->ep_comm_ptr->comm_list[%d]->ep_comm_ptr = %p\n", i, (*comm)->ep_comm_ptr->comm_list[i]->ep_comm_ptr);
+#endif
+        delete (*comm)->ep_comm_ptr->comm_list[i]->ep_comm_ptr;
+
+
+#ifdef _showinfo
+        printf("delete (*comm)->ep_comm_ptr->comm_list[%d] = %p\n", i, (*comm)->ep_comm_ptr->comm_list[i]);
+#endif
+        delete (*comm)->ep_comm_ptr->comm_list[i];
+      }
+
+#ifdef _showinfo
+      printf("delete (*comm)->mpi_comm = %p\n", (*comm)->mpi_comm);
+#endif
+      ::MPI_Comm_free(to_mpi_comm_ptr((*comm)->mpi_comm));
+      
+#ifdef _showinfo
+      printf("delete (*comm)->ep_comm_ptr->comm_list = %p\n", (*comm)->ep_comm_ptr->comm_list);
+#endif
+      delete[] (*comm)->ep_comm_ptr->comm_list;
+    }
+  }
+
+
+
+}
+
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_gather.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_gather.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_gather.cpp	(revision 1651)
@@ -0,0 +1,129 @@
+#ifdef _usingEP
+/*!
+   \file ep_gather.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Gather, MPI_Allgather
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  int MPI_Gather_local(const void *sendbuf, int count, MPI_Datatype datatype, void *recvbuf, int local_root, MPI_Comm comm)
+  {
+    assert(valid_type(datatype));
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+
+    #pragma omp critical (_gather)
+    comm->my_buffer->void_buffer[ep_rank_loc] = const_cast< void* >(sendbuf);
+
+    MPI_Barrier_local(comm);
+
+    if(ep_rank_loc == local_root)
+    {
+      for(int i=0; i<num_ep; i++)
+        memcpy(recvbuf + datasize * i * count, comm->my_buffer->void_buffer[i], datasize * count);
+    }
+
+    MPI_Barrier_local(comm);
+  }
+
+  int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Gather(const_cast<void*>(sendbuf), sendcount, to_mpi_type(sendtype), recvbuf, recvcount, to_mpi_type(recvtype),
+                                         root, to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Gather_intercomm(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
+
+    assert(sendcount == recvcount && sendtype == recvtype);
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    int root_mpi_rank = comm->ep_rank_map->at(root).second;
+    int root_ep_loc = comm->ep_rank_map->at(root).first;
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(sendtype), &lb, &datasize);
+
+    bool is_master = (ep_rank_loc==0 && mpi_rank != root_mpi_rank ) || ep_rank == root;
+    bool is_root = ep_rank == root;
+
+    void* local_recvbuf;
+
+    if(is_master)
+    {
+      local_recvbuf = new void*[datasize * num_ep * sendcount];
+    }
+
+    void* tmp_recvbuf;
+    if(is_root) tmp_recvbuf = new void*[datasize * recvcount * ep_size];
+
+
+    if(mpi_rank == root_mpi_rank) MPI_Gather_local(sendbuf, sendcount, sendtype, local_recvbuf, root_ep_loc, comm);
+    else                          MPI_Gather_local(sendbuf, sendcount, sendtype, local_recvbuf, 0, comm);
+
+    std::vector<int> recvcounts(mpi_size, 0);
+    std::vector<int> displs(mpi_size, 0);
+
+
+    if(is_master)
+    {
+      for(int i=0; i<ep_size; i++)
+      {
+        recvcounts[comm->ep_rank_map->at(i).second]+=sendcount;
+      }
+
+      for(int i=1; i<mpi_size; i++)
+        displs[i] = displs[i-1] + recvcounts[i-1];
+
+      ::MPI_Gatherv(local_recvbuf, sendcount*num_ep, to_mpi_type(sendtype), tmp_recvbuf, recvcounts.data(), displs.data(), to_mpi_type(recvtype), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+    }   
+
+
+    // reorder data
+    if(is_root)
+    {
+      int offset;
+      for(int i=0; i<ep_size; i++)
+      {
+        offset = displs[comm->ep_rank_map->at(i).second] + comm->ep_rank_map->at(i).first * sendcount; 
+        memcpy(recvbuf + i*sendcount*datasize, tmp_recvbuf+offset*datasize, sendcount*datasize);
+
+
+      }
+
+    }
+
+
+    if(is_master)
+    {
+      delete[] local_recvbuf;
+    }
+    if(is_root) delete[] tmp_recvbuf;
+    
+  }
+
+
+  int MPI_Gather_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+    printf("MPI_Gather_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_gatherv.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_gatherv.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_gatherv.cpp	(revision 1651)
@@ -0,0 +1,199 @@
+#ifdef _usingEP
+/*!
+   \file ep_gather.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Gatherv, MPI_Allgatherv
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  int MPI_Gatherv_local(const void *sendbuf, int count, MPI_Datatype datatype, void *recvbuf, const int recvcounts[], const int displs[], int local_root, MPI_Comm comm)
+  {
+    assert(valid_type(datatype));
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+
+
+    #pragma omp critical (_gatherv)
+    comm->my_buffer->void_buffer[ep_rank_loc] = const_cast< void* >(sendbuf);
+
+    MPI_Barrier_local(comm);
+
+    if(ep_rank_loc == local_root)
+    {
+      for(int i=0; i<num_ep; i++)
+        memcpy(recvbuf + datasize*displs[i], comm->my_buffer->void_buffer[i], datasize*recvcounts[i]);
+
+    }
+
+    MPI_Barrier_local(comm);
+  }
+
+  int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int input_recvcounts[], const int input_displs[],
+                  MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+  
+    if(!comm->is_ep) return ::MPI_Gatherv(const_cast<void*>(sendbuf), sendcount, to_mpi_type(sendtype), recvbuf, const_cast<int*>(input_recvcounts), const_cast<int*>(input_displs),
+                                          to_mpi_type(recvtype), root, to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Gatherv_intercomm(sendbuf, sendcount, sendtype, recvbuf, input_recvcounts, input_displs, recvtype, root, comm);
+
+    assert(sendtype == recvtype);
+
+    
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    int root_mpi_rank = comm->ep_rank_map->at(root).second;
+    int root_ep_loc = comm->ep_rank_map->at(root).first;
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(sendtype), &lb, &datasize);
+
+    int *recvcounts;
+    int* displs;
+
+    recvcounts = new int[ep_size];
+    displs = new int[ep_size];
+
+
+    bool is_master = (ep_rank_loc==0 && mpi_rank != root_mpi_rank ) || ep_rank == root;
+    bool is_root = ep_rank == root;
+
+    void* local_recvbuf;
+    std::vector<int>local_recvcounts(num_ep, 0);
+    std::vector<int>local_displs(num_ep, 0);
+
+
+    if(is_root)
+    { 
+      copy(input_recvcounts, input_recvcounts+ep_size, recvcounts);
+      copy(input_displs, input_displs+ep_size, displs);
+    }
+
+    MPI_Bcast(recvcounts, ep_size, MPI_INT, root, comm);
+    MPI_Bcast(displs, ep_size, MPI_INT, root, comm);
+
+    if(mpi_rank == root_mpi_rank) MPI_Gather_local(&sendcount, 1, MPI_INT, local_recvcounts.data(), root_ep_loc, comm);
+    else                          MPI_Gather_local(&sendcount, 1, MPI_INT, local_recvcounts.data(), 0, comm);
+
+    
+    //if(is_root) printf("rank %d =================local_recvcounts = %d %d\n", ep_rank, local_recvcounts[0], local_recvcounts[1]);
+    //if(!is_root && ep_rank_loc==0 && mpi_rank != root_mpi_rank) printf("rank %d =================local_recvcounts = %d %d\n", ep_rank, local_recvcounts[0], local_recvcounts[1]);
+
+    if(is_master)
+    {
+      int local_recvbuf_size = std::accumulate(local_recvcounts.begin(), local_recvcounts.end(), 0);
+      
+      for(int i=1; i<num_ep; i++)
+        local_displs[i] = local_displs[i-1] + local_recvcounts[i-1];
+
+      local_recvbuf = new void*[datasize * local_recvbuf_size];
+    }
+
+    if(mpi_rank == root_mpi_rank) MPI_Gatherv_local(sendbuf, sendcount, sendtype, local_recvbuf, local_recvcounts.data(), local_displs.data(), root_ep_loc, comm);
+    else                          MPI_Gatherv_local(sendbuf, sendcount, sendtype, local_recvbuf, local_recvcounts.data(), local_displs.data(), 0, comm);
+
+    
+    //if(is_root) printf("rank %d =================local_recvbuf = %d %d\n", ep_rank, static_cast<int*>(local_recvbuf)[0], static_cast<int*>(local_recvbuf)[1]);
+    //if(!is_root && ep_rank_loc==0 && mpi_rank != root_mpi_rank && ep_rank!=6) printf("rank %d =================local_recvbuf = %d %d\n", ep_rank, static_cast<int*>(local_recvbuf)[0], static_cast<int*>(local_recvbuf)[1]);
+    //if(!is_root && ep_rank_loc==0 && mpi_rank != root_mpi_rank && ep_rank==6) printf("rank %d =================local_recvbuf = %d %d %d\n", ep_rank, static_cast<int*>(local_recvbuf)[0], static_cast<int*>(local_recvbuf)[1], static_cast<int*>(local_recvbuf)[2]);
+
+    void* tmp_recvbuf;
+    int tmp_recvbuf_size = std::accumulate(recvcounts, recvcounts+ep_size, 0);
+
+
+
+    if(is_root) tmp_recvbuf = new void*[datasize * tmp_recvbuf_size];
+
+
+    std::vector<int> mpi_recvcounts(mpi_size, 0);
+    std::vector<int> mpi_displs(mpi_size, 0);
+
+
+    if(is_master)
+    {
+      int sendcount_mpi = 0;
+      for(int i=0; i<num_ep; i++)
+      {
+        sendcount_mpi += local_recvcounts[i];
+      }
+
+      for(int i=0; i<ep_size; i++)
+      {
+        mpi_recvcounts[comm->ep_rank_map->at(i).second]+=recvcounts[i];
+      }
+
+      for(int i=1; i<mpi_size; i++)
+        mpi_displs[i] = mpi_displs[i-1] + mpi_recvcounts[i-1];
+
+
+      ::MPI_Gatherv(local_recvbuf, sendcount_mpi, to_mpi_type(sendtype), tmp_recvbuf, mpi_recvcounts.data(), mpi_displs.data(), to_mpi_type(recvtype), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+      //printf("****************** rank %d, sendcount*num_ep = %d, sendcount_mpi = %d\n", ep_rank, sendcount*num_ep, sendcount_mpi);
+
+      /*if(is_root) printf("rank %d =================tmp_recvbuf = %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", ep_rank, static_cast<int*>(tmp_recvbuf)[0], static_cast<int*>(tmp_recvbuf)[1], static_cast<int*>(tmp_recvbuf)[2],
+                                                                                                                                 static_cast<int*>(tmp_recvbuf)[3], static_cast<int*>(tmp_recvbuf)[4], static_cast<int*>(tmp_recvbuf)[5],
+                                                                                                                                 static_cast<int*>(tmp_recvbuf)[6], static_cast<int*>(tmp_recvbuf)[7], static_cast<int*>(tmp_recvbuf)[8],
+                                                                                                                                 static_cast<int*>(tmp_recvbuf)[9], static_cast<int*>(tmp_recvbuf)[10], static_cast<int*>(tmp_recvbuf)[11],
+                                                                                                                                 static_cast<int*>(tmp_recvbuf)[12], static_cast<int*>(tmp_recvbuf)[13], static_cast<int*>(tmp_recvbuf)[14],
+                                                                                                                                 static_cast<int*>(tmp_recvbuf)[15], static_cast<int*>(tmp_recvbuf)[16]);*/
+    }   
+
+
+    // reorder data
+    if(is_root)
+    {
+      int offset;
+      for(int i=0; i<ep_size; i++)
+      {
+        int extra = 0;
+        for(int j=0, k=0; j<ep_size, k<comm->ep_rank_map->at(i).first; j++)
+          if(comm->ep_rank_map->at(i).second == comm->ep_rank_map->at(j).second)
+          {
+            extra += recvcounts[j];
+            k++;
+          }  
+
+        offset = mpi_displs[comm->ep_rank_map->at(i).second] +  extra;
+
+        memcpy(recvbuf+displs[i]*datasize, tmp_recvbuf+offset*datasize, recvcounts[i]*datasize);
+        
+      }
+
+    }
+
+    delete[] recvcounts;
+    delete[] displs;
+
+    if(is_master)
+    {
+      delete[] local_recvbuf;
+    }
+    if(is_root) delete[] tmp_recvbuf;
+  }
+
+  int MPI_Gatherv_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int input_recvcounts[], const int input_displs[],
+                            MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+    printf("MPI_Gatherv_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_get.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_get.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_get.cpp	(revision 1651)
@@ -0,0 +1,60 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+	int MPI_Get(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+  	          int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    if(num_ep==1)
+      return  ::MPI_Get(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+    	               to_mpi_win(win->server_win[target_local_rank]));
+
+    else
+    	return  ::MPI_Get(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+    	               to_mpi_win(win->client_win));
+  }
+
+  int MPI_Rget(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+              int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request *request)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+
+    ::MPI_Request mpi_request;
+    if(num_ep==1)
+    {
+      int return_value = ::MPI_Rget(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                         to_mpi_win(win->server_win[target_local_rank]), &mpi_request);
+
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+    else
+    {
+      int return_value = ::MPI_Rget(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                         to_mpi_win(win->client_win), &mpi_request);
+
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_global.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_global.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_global.hpp	(revision 1651)
@@ -0,0 +1,13 @@
+#ifndef EP_GLOBAL_HPP_INCLUDED
+#define EP_GLOBAL_HPP_INCLUDED
+#ifdef _usingEP
+
+extern int MPI_MODE_NOPRECEDE;
+extern int MPI_MODE_NOCHECK;
+extern int MPI_MODE_NOPUT;
+extern int MPI_MODE_NOSTORE;
+extern int MPI_MODE_NOSUCCEED;
+    
+
+#endif
+#endif // EP_GLOBAL_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_info.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_info.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_info.hpp	(revision 1651)
@@ -0,0 +1,27 @@
+#ifndef EP_INFO_HPP_INCLUDED
+#define EP_INFO_HPP_INCLUDED
+
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  class ep_info
+  {
+    public:
+
+      void* mpi_info;
+
+      ep_info(){};
+      ep_info(void* info);
+  };
+  
+  typedef ep_info* MPI_Info;
+
+
+}
+
+#endif
+
+#endif // EP_INFO_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_init.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_init.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_init.cpp	(revision 1651)
@@ -0,0 +1,46 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+extern MPI_Group MPI_GROUP_WORLD;
+
+namespace ep_lib
+{
+
+
+
+  int MPI_Init_thread(int *argc, char*** argv, int required, int*provided)
+  {
+    Debug("MPI_Init_thread with EP/MPI\n");
+
+    #pragma omp master
+    {
+      ::MPI_Init_thread(argc, argv, required, provided);
+      ::MPI_Comm_group(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &MPI_GROUP_WORLD);
+    }
+  }
+
+  int MPI_Init(int *argc, char ***argv)
+  {
+    Debug("MPI_Init with EP/MPI\n");
+
+    #pragma omp master
+    {
+      ::MPI_Init(argc, argv);
+    }
+  }
+
+  int MPI_Initialized(int *flag)
+  {
+    Debug("MPI_Initialized with EP/MPI\n");
+
+    return ::MPI_Initialized(flag);
+  }
+
+
+
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_intercomm.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_intercomm.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_intercomm.cpp	(revision 1651)
@@ -0,0 +1,367 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+extern std::map<std::pair<int, int>, MPI_Group* > * tag_group_map;
+
+extern std::map<int, std::pair<ep_lib::MPI_Comm*, std::pair<int, int> > > * tag_comm_map;
+
+extern MPI_Group MPI_GROUP_WORLD;
+
+namespace ep_lib
+{
+
+  int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm)
+  {
+    if(!local_comm->is_ep) return MPI_Intercomm_create_mpi(local_comm, local_leader, peer_comm, remote_leader, tag, newintercomm);
+
+    int ep_rank = local_comm->ep_comm_ptr->size_rank_info[0].first;
+    
+    
+    // check if local leaders are in the same mpi proc
+    // by checking their mpi_rank in peer_comm
+    
+    int mpi_rank_of_leader[2];
+    
+    if(ep_rank == local_leader)
+    {
+      mpi_rank_of_leader[0] = peer_comm->ep_comm_ptr->size_rank_info[2].first;
+      mpi_rank_of_leader[1] = peer_comm->ep_rank_map->at(remote_leader).second;      
+    }
+    
+    MPI_Bcast(mpi_rank_of_leader, 2, MPI_INT, local_leader, local_comm);
+    
+    if(mpi_rank_of_leader[0] != mpi_rank_of_leader[1])
+    {
+      Debug("calling MPI_Intercomm_create_kernel\n");
+      return MPI_Intercomm_create_endpoint(local_comm, local_leader, peer_comm, remote_leader, tag, newintercomm);
+    }
+    else
+    {
+      printf("local leaders are in the same MPI proc. Routine not yet implemented\n");
+      MPI_Abort(local_comm, 0);
+    }
+  }
+  
+  
+  
+  int MPI_Intercomm_create_endpoint(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm)
+  {
+    int ep_rank, ep_rank_loc, mpi_rank;
+    int ep_size, num_ep, mpi_size;
+
+    ep_rank     = local_comm->ep_comm_ptr->size_rank_info[0].first;
+    ep_rank_loc = local_comm->ep_comm_ptr->size_rank_info[1].first;
+    mpi_rank    = local_comm->ep_comm_ptr->size_rank_info[2].first;
+    ep_size     = local_comm->ep_comm_ptr->size_rank_info[0].second;
+    num_ep      = local_comm->ep_comm_ptr->size_rank_info[1].second;
+    mpi_size    = local_comm->ep_comm_ptr->size_rank_info[2].second;
+
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    // step 1 : local leaders exchange ep_size, leader_rank_in_peer, leader_rank_in_peer_mpi, leader_rank_in_world. //
+    //          local leaders bcast results to all ep in local_comm                                                 //
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    bool is_local_leader = ep_rank==local_leader? true: false;
+    
+    
+    int local_leader_rank_in_peer;
+    int local_leader_rank_in_peer_mpi;
+    int local_leader_rank_in_world;
+
+    int remote_ep_size;
+    int remote_leader_rank_in_peer;
+    int remote_leader_rank_in_peer_mpi;
+    int remote_leader_rank_in_world;
+
+    int send_quadruple[4];
+    int recv_quadruple[4];
+
+
+    if(is_local_leader)
+    {
+      MPI_Comm_rank(peer_comm, &local_leader_rank_in_peer);
+      ::MPI_Comm_rank(to_mpi_comm(peer_comm->mpi_comm), &local_leader_rank_in_peer_mpi);
+      ::MPI_Comm_rank(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &local_leader_rank_in_world);
+
+      send_quadruple[0] = ep_size;
+      send_quadruple[1] = local_leader_rank_in_peer;
+      send_quadruple[2] = local_leader_rank_in_peer_mpi;
+      send_quadruple[3] = local_leader_rank_in_world;
+
+      MPI_Status status;
+      MPI_Sendrecv(send_quadruple, 4, MPI_INT, remote_leader, tag, recv_quadruple, 4, MPI_INT, remote_leader, tag, peer_comm, &status);
+
+      remote_ep_size                 = recv_quadruple[0];
+      remote_leader_rank_in_peer     = recv_quadruple[1];
+      remote_leader_rank_in_peer_mpi = recv_quadruple[2];
+      remote_leader_rank_in_world    = recv_quadruple[3];
+
+    }
+
+    MPI_Bcast(send_quadruple, 4, MPI_INT, local_leader, local_comm);
+    MPI_Bcast(recv_quadruple, 4, MPI_INT, local_leader, local_comm);
+
+    if(!is_local_leader)
+    {
+      local_leader_rank_in_peer     = send_quadruple[1];
+      local_leader_rank_in_peer_mpi = send_quadruple[2];
+      local_leader_rank_in_world    = send_quadruple[3];
+
+      remote_ep_size                 = recv_quadruple[0];
+      remote_leader_rank_in_peer     = recv_quadruple[1];
+      remote_leader_rank_in_peer_mpi = recv_quadruple[2];
+      remote_leader_rank_in_world    = recv_quadruple[3];
+    }
+
+
+
+    ///////////////////////////////////////////////////////////////////
+    // step 2 : gather ranks in world for both local and remote comm //
+    ///////////////////////////////////////////////////////////////////
+
+    int rank_in_world;
+    ::MPI_Comm_rank(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &rank_in_world);
+
+    int *ranks_in_world_local  = new int[ep_size];
+    int *ranks_in_world_remote = new int[remote_ep_size];
+
+    MPI_Allgather(&rank_in_world, 1, MPI_INT, ranks_in_world_local, 1, MPI_INT, local_comm);
+
+    if(is_local_leader)
+    {
+      MPI_Status status;
+      MPI_Sendrecv(ranks_in_world_local, ep_size, MPI_INT, remote_leader, tag, ranks_in_world_remote, remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &status);
+    }
+
+    MPI_Bcast(ranks_in_world_remote, remote_ep_size, MPI_INT, local_leader, local_comm);
+
+
+    //////////////////////////////////////////////////////////////
+    // step 3 : determine the priority and ownership of each ep //
+    //////////////////////////////////////////////////////////////
+
+    bool priority = local_leader_rank_in_peer < remote_leader_rank_in_peer? true : false;
+
+
+    int ownership = 1;
+
+    if(rank_in_world == ranks_in_world_local[local_leader]) ownership = 1;
+    if(rank_in_world == remote_leader_rank_in_world)   ownership = 0;
+    
+
+
+    //////////////////////////////////////////////////////
+    // step 4 : extract local_comm and create intercomm //
+    //////////////////////////////////////////////////////
+
+    bool is_involved = is_local_leader || (!is_local_leader && ep_rank_loc == 0 && rank_in_world != local_leader_rank_in_world);
+
+
+
+    if(is_involved)
+    {
+      ::MPI_Group local_group;
+      ::MPI_Group extracted_group;
+      ::MPI_Comm extracted_comm;
+
+
+      ::MPI_Comm_group(to_mpi_comm(local_comm->mpi_comm), &local_group);
+
+      int *ownership_list = new int[mpi_size];
+      int *mpi_rank_list = new int[mpi_size];
+
+      ::MPI_Allgather(&ownership, 1, to_mpi_type(MPI_INT), ownership_list, 1, to_mpi_type(MPI_INT), to_mpi_comm(local_comm->mpi_comm));
+      ::MPI_Allgather(&mpi_rank,  1, to_mpi_type(MPI_INT), mpi_rank_list,  1, to_mpi_type(MPI_INT), to_mpi_comm(local_comm->mpi_comm));
+
+      
+      int n=0;
+      for(int i=0; i<mpi_size; i++)
+      { 
+        n+=ownership_list[i];
+      }
+
+      int *new_mpi_rank_list = new int[n];
+      int j=0;
+      for(int i=0; i<mpi_size; i++)
+      { 
+        if(ownership_list[i] !=0)
+        {
+          new_mpi_rank_list[j++] = mpi_rank_list[i];
+        }
+      }
+
+
+      ::MPI_Group_incl(local_group, n, new_mpi_rank_list, &extracted_group);
+
+      ::MPI_Comm_create(to_mpi_comm(local_comm->mpi_comm), extracted_group, &extracted_comm);
+
+      ::MPI_Comm mpi_inter_comm;
+
+      int local_leader_rank_in_extracted_comm;
+
+      if(is_local_leader)
+      {
+        ::MPI_Comm_rank(extracted_comm, &local_leader_rank_in_extracted_comm);
+      }
+
+      ::MPI_Bcast(&local_leader_rank_in_extracted_comm, 1, to_mpi_type(MPI_INT), local_comm->ep_rank_map->at(local_leader).second, to_mpi_comm(local_comm->mpi_comm));
+
+      ::MPI_Comm *intracomm = new ::MPI_Comm;
+      bool is_real_involved = ownership && extracted_comm != to_mpi_comm(MPI_COMM_NULL->mpi_comm);
+
+      if(is_real_involved)
+      {
+        #pragma omp critical (_mpi_call)
+        ::MPI_Intercomm_create(extracted_comm, local_leader_rank_in_extracted_comm, to_mpi_comm(peer_comm->mpi_comm), remote_leader_rank_in_peer_mpi, tag, &mpi_inter_comm);
+        ::MPI_Intercomm_merge(mpi_inter_comm, !priority, intracomm);
+      }
+        
+        
+
+      ////////////////////////////////////
+      // step 5 :: determine new num_ep //
+      ////////////////////////////////////
+
+      int num_ep_count=0;
+
+      for(int i=0; i<ep_size; i++)
+      {
+        if(rank_in_world == ranks_in_world_local[i])
+          num_ep_count++;
+      }
+      
+      for(int i=0; i<remote_ep_size; i++)
+      {
+        if(rank_in_world == ranks_in_world_remote[i])
+          num_ep_count++;
+      }
+
+
+      ///////////////////////////////////////////////////
+      // step 6 : create endpoints from extracted_comm //
+      ///////////////////////////////////////////////////
+
+      if(is_real_involved)
+      {
+        MPI_Comm *ep_comm;
+        MPI_Info info;
+        MPI_Comm_create_endpoints(intracomm, num_ep_count, info, ep_comm);
+      
+
+
+        #pragma omp critical (write_to_tag_list)      
+        intercomm_list.push_back(make_pair( make_pair(tag, min(local_leader_rank_in_world, remote_leader_rank_in_world)) , make_pair(ep_comm , make_pair(num_ep_count, 0))));
+        #pragma omp flush
+  
+        ::MPI_Comm_free(intracomm);
+        delete intracomm;
+      }
+
+
+      delete ownership_list;
+      delete mpi_rank_list;
+      delete new_mpi_rank_list;
+
+    }
+
+    int repeated=0;
+    for(int i=0; i<remote_ep_size; i++)
+    {
+      if(rank_in_world == ranks_in_world_remote[i])
+        repeated++;
+    }
+
+    int new_ep_rank_loc = ownership==1? ep_rank_loc : ep_rank_loc+repeated;
+
+
+
+    MPI_Barrier_local(local_comm);
+
+
+    #pragma omp flush
+    #pragma omp critical (read_from_intercomm_list)
+    {
+      bool flag=true;
+      while(flag)
+      {
+        for(std::list<std::pair<std::pair<int, int> , std::pair<MPI_Comm * , std::pair<int, int> > > >::iterator iter = intercomm_list.begin(); iter!=intercomm_list.end(); iter++)
+        {
+          if(iter->first == make_pair(tag, min(local_leader_rank_in_world, remote_leader_rank_in_world)))
+          {
+            *newintercomm = iter->second.first[new_ep_rank_loc];
+            
+            iter->second.second.second++;
+            
+            if(iter->second.second.first == iter->second.second.second)
+              intercomm_list.erase(iter);
+
+            flag = false;
+            break; 
+          }
+        }
+      }
+    }
+    
+
+
+
+
+    //////////////////////////////////////////////////////////
+    // step 7 : create intercomm_rank_map for local leaders //
+    //////////////////////////////////////////////////////////
+
+    (*newintercomm)->is_intercomm = true;
+    
+    (*newintercomm)->inter_rank_map = new INTER_RANK_MAP;
+    
+    
+    int rank_info[2];
+    rank_info[0] = ep_rank;
+    rank_info[1] = (*newintercomm)->ep_comm_ptr->size_rank_info[0].first;
+
+
+
+    int *local_rank_info = new int[2*ep_size];
+    int *remote_rank_info = new int[2*remote_ep_size];
+
+    MPI_Allgather(rank_info, 2, MPI_INT, local_rank_info, 2, MPI_INT, local_comm);
+
+    if(is_local_leader)
+    {
+      MPI_Status status;
+      MPI_Sendrecv(local_rank_info, 2*ep_size, MPI_INT, remote_leader, tag, remote_rank_info, 2*remote_ep_size, MPI_INT, remote_leader, tag, peer_comm, &status);
+    }
+
+    MPI_Bcast(remote_rank_info, 2*remote_ep_size, MPI_INT, local_leader, local_comm);
+
+    for(int i=0; i<remote_ep_size; i++)
+    {
+      (*newintercomm)->inter_rank_map->insert(make_pair(remote_rank_info[2*i], remote_rank_info[2*i+1]));
+    }
+    
+    (*newintercomm)->ep_comm_ptr->size_rank_info[0] = local_comm->ep_comm_ptr->size_rank_info[0];
+
+    
+    delete[] local_rank_info;
+    delete[] remote_rank_info;
+    delete[] ranks_in_world_local;
+    delete[] ranks_in_world_remote;
+
+ 
+  }
+    
+  
+  
+  int MPI_Intercomm_create_mpi(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm)
+  {
+    printf("MPI_Intercomm_create_mpi not yet implemented\n");
+    MPI_Abort(local_comm, 0);
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib.cpp	(revision 1651)
@@ -0,0 +1,252 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include <iostream>
+#include <fstream>
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+std::list< ep_lib::MPI_Request* > * EP_PendingRequests = 0;
+#pragma omp threadprivate(EP_PendingRequests)
+
+
+std::map<std::pair<int, int>, MPI_Group* > * tag_group_map = 0;
+
+std::map<int, std::pair<ep_lib::MPI_Comm*, std::pair<int, int> > > * tag_comm_map = 0;
+
+
+MPI_Group MPI_GROUP_WORLD;
+
+namespace ep_lib
+{ 
+
+  int tag_combine(int real_tag, int src, int dest)
+  {
+    int a = real_tag << 16;
+    int b = src << 8;
+    int c = dest;
+
+    return a+b+c;
+  }
+
+  int get_ep_rank(MPI_Comm comm, int ep_rank_loc, int mpi_rank)
+  {    
+    int ep_rank = -1;
+    for(std::map<int, std::pair<int, int> >::iterator it = comm->ep_rank_map->begin(); it != comm->ep_rank_map->end(); it++)
+    {
+      if(   ( it->second.first  == ep_rank_loc )
+         && ( it->second.second == mpi_rank ) )
+      {
+        ep_rank = it->first;
+      }
+    }
+
+    if(comm->is_intercomm)
+    {
+      for(std::map<int, int>::iterator it = comm->inter_rank_map->begin(); it!=comm->inter_rank_map->end(); it++)
+      {
+        if(it->second == ep_rank)
+        {
+          ep_rank = it->first;
+        }
+      }
+    }
+    if(ep_rank >= 0) return ep_rank;
+    else
+    {
+      printf("rank not find, intercomm = %d, ep_rank_loc = %d, mpi_rank = %d\n", comm->is_intercomm, ep_rank_loc, mpi_rank);
+      return MPI_Abort(comm, 0);
+    }
+  }
+
+  int get_ep_rank2(MPI_Comm comm, int ep_rank_loc, int mpi_rank)
+  {    
+    for(std::map<int, std::pair<int, int> >::iterator it = comm->ep_rank_map->begin(); it != comm->ep_rank_map->end(); it++)
+    {
+      if(   ( it->second.first  == ep_rank_loc )
+         && ( it->second.second == mpi_rank ) )
+      {
+        return it->first;
+      }
+    }
+    printf("rank not find for EP_intracomm\n");
+    return MPI_Abort(comm, 0);
+  }
+  
+
+  int MPI_Get_count(const MPI_Status *status, MPI_Datatype datatype, int *count)
+  {
+    return ::MPI_Get_count(to_mpi_status_ptr(*status), to_mpi_type(datatype), count);
+  }
+
+  double MPI_Wtime()
+  {
+    return ::MPI_Wtime();
+  }
+
+  int MPI_Comm_test_inter(MPI_Comm comm, int *flag)
+  {
+    if(comm->is_ep) return *flag = comm->is_intercomm;
+    else return ::MPI_Comm_test_inter(to_mpi_comm(comm->mpi_comm), flag);
+  }
+
+  void check_sum_send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, int type)
+  {
+
+    int src_rank;
+    int int_count;
+    ::MPI_Aint datasize, intsize, charsize, lb;
+    
+    ::MPI_Type_get_extent(*(static_cast< ::MPI_Datatype*>(datatype)), &lb, &datasize);
+    ::MPI_Type_get_extent(*(static_cast< ::MPI_Datatype*>(MPI_CHAR)), &lb, &intsize);
+
+    int_count = count * datasize / intsize ;
+
+    char *buffer = static_cast< char* >(const_cast< void*> (buf));
+    
+    unsigned long sum = 0;
+    for(int i = 0; i<int_count; i++)
+      sum += *(buffer+i); 
+
+
+    MPI_Comm_rank(comm, &src_rank);
+    
+    ofstream myfile;
+    myfile.open ("send_log.txt", ios::app);
+    if (myfile.is_open())
+    {
+      myfile << "type = " << type << " src = "<< src_rank<< " dest = "<< dest <<" tag = "<< tag << "  count = "<< count << " sum = "<< sum << "\n";
+      myfile.close();  
+    }
+    else printf("Unable to open file\n");
+
+  }
+
+
+  void check_sum_recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, int type)
+  {
+
+    int dest_rank;
+    int int_count;
+    ::MPI_Aint datasize, intsize, charsize, lb;
+    
+    ::MPI_Type_get_extent(*(static_cast< ::MPI_Datatype*>(datatype)), &lb, &datasize);
+    ::MPI_Type_get_extent(*(static_cast< ::MPI_Datatype*>(MPI_CHAR)), &lb, &intsize);
+
+    int_count = count * datasize / intsize ;
+
+    char *buffer = static_cast< char* >(buf);
+    
+    unsigned long sum = 0;
+    for(int i = 0; i<int_count; i++)
+      sum += *(buffer+i); 
+
+
+    MPI_Comm_rank(comm, &dest_rank);
+    
+    ofstream myfile;
+    myfile.open ("recv_log.txt", ios::app);
+    if (myfile.is_open())
+    {
+      myfile << "type = " << type << " src = "<< src << " dest = "<< dest_rank <<" tag = "<< tag << "  count = "<< count << " sum = "<< sum << "\n";
+      myfile.close();  
+    }
+    else printf("Unable to open file\n");
+
+
+  }
+
+
+  bool valid_type(MPI_Datatype datatype)
+  {
+    if(   datatype == MPI_INT 
+       || datatype == MPI_FLOAT
+       || datatype == MPI_DOUBLE 
+       || datatype == MPI_CHAR 
+       || datatype == MPI_LONG 
+       || datatype == MPI_UNSIGNED_LONG
+       || datatype == MPI_LONG_LONG)
+    {
+      return true;
+    }
+
+    return false;
+  }
+
+
+  bool valid_op(MPI_Op op)
+  {
+    if(   op == MPI_MAX 
+       || op == MPI_MIN
+       || op == MPI_SUM
+       || op == MPI_LOR)
+    {
+      return true;
+    }
+
+    return false;
+  }
+
+
+}
+
+
+MPI_Datatype to_mpi_type(ep_lib::MPI_Datatype type)
+{
+  return *static_cast< MPI_Datatype* >(type);
+}
+
+MPI_Op to_mpi_op(ep_lib::MPI_Op op)
+{
+  return *static_cast< MPI_Op* >(op);
+}
+
+MPI_Comm to_mpi_comm(void* comm)
+{
+  return *(static_cast< MPI_Comm* >(comm));
+} 
+
+MPI_Comm* to_mpi_comm_ptr(void* comm)
+{
+  return static_cast< MPI_Comm* >(comm);
+}  
+
+MPI_Message to_mpi_message(void* message)
+{
+  return *(static_cast< MPI_Message* >(message));
+}
+
+MPI_Message* to_mpi_message_ptr(ep_lib::MPI_Message message)
+{
+  return static_cast< MPI_Message* >(message->mpi_message);
+}
+
+MPI_Info to_mpi_info(ep_lib::MPI_Info info)
+{
+  return *(static_cast< MPI_Info* >(info->mpi_info));
+}
+
+MPI_Win to_mpi_win(void* win)
+{
+  return *(static_cast< MPI_Win* >(win));
+}
+
+MPI_Aint to_mpi_aint(ep_lib::MPI_Aint aint)
+{
+  return *(static_cast< MPI_Aint* >(aint.mpi_aint));
+}
+
+MPI_Status* to_mpi_status_ptr(ep_lib::MPI_Status status)
+{
+  return static_cast< MPI_Status* >(status.mpi_status);
+}
+
+MPI_Request* to_mpi_request_ptr(ep_lib::MPI_Request request)
+{
+  return static_cast< MPI_Request* >(request->mpi_request);
+}
+
+#endif
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib.hpp	(revision 1651)
@@ -0,0 +1,94 @@
+#ifndef EP_LIB_HPP_INCLUDED
+#define EP_LIB_HPP_INCLUDED
+#ifdef _usingEP
+
+#include "ep_type.hpp"
+#include "ep_lib_intercomm.hpp"
+#include "ep_lib_endpoint.hpp"
+#include "ep_lib_local.hpp"
+#include "ep_lib_collective.hpp"
+#include "ep_lib_fortran.hpp"
+#include "ep_lib_win.hpp"
+#include "ep_lib_mpi.hpp"
+
+
+namespace ep_lib
+{
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+  int MPI_Init_thread(int* argc, char*** argv, int required, int*provided);
+
+  int MPI_Init(int *argc, char ***argv);
+
+  int MPI_Initialized(int *flag);
+
+  int MPI_Comm_rank(MPI_Comm comm, int* rank);
+
+  int MPI_Comm_size(MPI_Comm comm, int* rank);
+
+  int MPI_Comm_free(MPI_Comm* comm);
+
+  int MPI_Finalize();
+  
+  double MPI_Wtime();
+
+  int MPI_Abort(MPI_Comm comm, int errorcode);
+
+  int MPI_Get_count(const MPI_Status *status, MPI_Datatype datatype, int *count);
+  
+  int MPI_Comm_remote_size(MPI_Comm comm, int *size);
+
+
+  int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);
+  int MPI_Ssend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);
+  int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request);
+  int MPI_Issend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request);
+
+  int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, 
+                         void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag,
+                   MPI_Comm comm, MPI_Status *status);
+  
+  int MPI_Recv  (void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status *status);
+  int MPI_Irecv (void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *request);
+  int MPI_Mrecv (void *buf, int count, MPI_Datatype datatype, MPI_Message *message, MPI_Status *status);
+  int MPI_Imrecv(void *buf, int count, MPI_Datatype datatype, MPI_Message *message, MPI_Request *request);
+
+
+  int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status);
+  int MPI_Testall(int count, MPI_Request *array_of_requests, int *flag, MPI_Status *array_of_statuses);
+
+  int MPI_Wait(MPI_Request *request, MPI_Status *status);
+  int MPI_Waitall(int count, MPI_Request *array_of_requests, MPI_Status *array_of_statuses);
+
+
+  int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status);
+  int MPI_Improbe(int source, int tag, MPI_Comm comm, int *flag, MPI_Message *message, MPI_Status *status);
+  
+  int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr);
+  int MPI_Alloc_mem(unsigned long size, MPI_Info info, void *baseptr);
+
+  int MPI_Comm_test_inter(MPI_Comm comm, int *flag);
+
+
+  void check_sum_send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, int type);
+  void check_sum_recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, int type);
+
+  bool valid_type(MPI_Datatype type);
+  bool valid_op(MPI_Op op);
+
+  int tag_combine(int real_tag, int src, int dest);
+  int get_ep_rank(MPI_Comm comm, int ep_rank_loc, int mpi_rank);
+
+  int Message_Check(MPI_Comm comm);
+
+  int Request_Check();
+  
+  void show_EP_PendingRequests(std::list< ep_lib::MPI_Request* > * EP_PendingRequest);
+
+  int test_sendrecv(MPI_Comm comm);
+
+
+}
+#endif
+#endif // EP_LIB_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_collective.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_collective.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_collective.hpp	(revision 1651)
@@ -0,0 +1,67 @@
+#ifndef EP_LIB_COLLECTIVE_HPP_INCLUDED
+#define EP_LIB_COLLECTIVE_HPP_INCLUDED
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+
+  int MPI_Barrier(MPI_Comm comm);
+ 
+
+  int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm);
+
+  int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
+
+  int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Reduce_scatter(const void *sendbuf, void *recvbuf, const int recvcounts[], MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Scan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Exscan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm);
+
+  int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm);
+  
+  int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm);
+
+  int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[],
+                  MPI_Datatype recvtype, int root, MPI_Comm comm);
+  int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[],
+                     MPI_Datatype recvtype, MPI_Comm comm);
+
+
+  int MPI_Scatter(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm);
+
+  int MPI_Scatterv(const void *sendbuf, const int sendcounts[], const int displs[], MPI_Datatype sendtype, void *recvbuf, int recvcount,
+                   MPI_Datatype recvtype, int root, MPI_Comm comm);
+
+  int MPI_Alltoall(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm);
+
+  int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm);
+
+  int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm);
+
+  
+  
+  
+  //int MPI_Intercomm_create_from_world(MPI_Comm local_comm, int local_leader, void* peer_comm_ptr, int mpi_remote_leader, int tag, MPI_Comm *newintercomm);
+  
+  //int MPI_Intercomm_create_unique_leader(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm);
+
+  int MPI_Comm_create_endpoints(void* base_comm_ptr, int num_ep, MPI_Info info, MPI_Comm *& out_comm_hdls); // from EP to create endpoints
+
+
+
+  int MPI_Intercomm_merge(MPI_Comm intercomm, bool high, MPI_Comm *newintracomm);
+
+  //int MPI_Intercomm_merge_unique_leader(MPI_Comm intercomm, bool high, MPI_Comm *newintracomm);
+
+}
+#endif
+#endif // EP_LIB_COLLECTIVE_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_endpoint.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_endpoint.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_endpoint.hpp	(revision 1651)
@@ -0,0 +1,27 @@
+#ifndef EP_LIB_ENDPOINT_HPP_INCLUDED
+#define EP_LIB_ENDPOINT_HPP_INCLUDED
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+
+  int MPI_Barrier_endpoint(MPI_Comm comm);
+
+  int MPI_Comm_free_endpoint(MPI_Comm* comm);
+
+  int Message_Check_endpoint(MPI_Comm comm);
+  
+  int MPI_Comm_dup_endpoint(MPI_Comm comm, MPI_Comm *newcomm);
+  
+  int MPI_Iprobe_endpoint(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status);
+  int MPI_Improbe_endpoint(int source, int tag, MPI_Comm comm, int *flag, MPI_Message *message, MPI_Status *status);
+  
+  int MPI_Intercomm_create_endpoint(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm);
+
+}
+#endif
+#endif // EP_LIB_ENDPOINT_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_fortran.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_fortran.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_fortran.hpp	(revision 1651)
@@ -0,0 +1,15 @@
+#ifndef EP_LIB_FORTRAN_HPP_INCLUDED
+#define EP_LIB_FORTRAN_HPP_INCLUDED
+#ifdef _usingEP
+
+#include "ep_type.hpp"
+
+//namespace ep_lib
+//{
+
+  void* EP_Comm_c2f(ep_lib::MPI_Comm comm);
+  ep_lib::MPI_Comm EP_Comm_f2c(void* comm);
+//}
+#endif
+
+#endif // EP_LIB_FORTRAN_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_intercomm.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_intercomm.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_intercomm.hpp	(revision 1651)
@@ -0,0 +1,38 @@
+#ifndef EP_LIB_INTERCOMM_HPP_INCLUDED
+#define EP_LIB_INTERCOMM_HPP_INCLUDED
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+  int MPI_Allgather_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm);
+  int MPI_Allgatherv_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm);
+
+  int MPI_Allreduce_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Alltoall_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm);
+
+  int MPI_Bcast_intercomm(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm);
+
+  int MPI_Exscan_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+  int MPI_Scan_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Gather_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm);
+
+  int MPI_Gatherv_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int input_recvcounts[], const int input_displs[],
+                            MPI_Datatype recvtype, int root, MPI_Comm comm);
+
+  int MPI_Reduce_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
+
+  int MPI_Reduce_scatter_intercomm(const void *sendbuf, void *recvbuf, const int recvcounts[], MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Scatter_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm);
+  int MPI_Scatterv_intercomm(const void *sendbuf, const int sendcounts[], const int displs[], MPI_Datatype sendtype, void *recvbuf, int recvcount,
+                   MPI_Datatype recvtype, int root, MPI_Comm comm);
+}
+
+#endif
+#endif // EP_LIB_INTERCOMM_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_local.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_local.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_local.hpp	(revision 1651)
@@ -0,0 +1,36 @@
+#ifndef EP_LIB_LOCAL_HPP_INCLUDED
+#define EP_LIB_LOCAL_HPP_INCLUDED
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+
+  int MPI_Reduce_local       (const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int local_root, MPI_Comm comm);
+
+  int MPI_Scan_local       (const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Exscan_local       (const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+
+  int MPI_Bcast_local      (void *buffer, int count, MPI_Datatype datatype, int local_root, MPI_Comm comm);
+  
+  int MPI_Gather_local      (const void *sendbuf, int count, MPI_Datatype datatype, void *recvbuf, int local_root, MPI_Comm comm);
+  
+  int MPI_Allgather_local      (const void *sendbuf, int count, MPI_Datatype datatype, void *recvbuf, MPI_Comm comm);
+
+  int MPI_Gatherv_local       (const void *sendbuf, int count, MPI_Datatype datatype, void *recvbuf,
+                               const int recvcounts[], const int displs[], int local_root, MPI_Comm comm);
+
+  int MPI_Scatter_local(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int local_root, MPI_Comm comm);
+
+  int MPI_Scatterv_local(const void *sendbuf, const int sendcounts[], const int displs[], MPI_Datatype sendtype, void *recvbuf, int recvcount,
+                   MPI_Datatype recvtype, int local_root, MPI_Comm comm);
+
+  int MPI_Barrier_local(MPI_Comm comm);
+
+}
+#endif
+#endif // EP_LIB_LOCAL_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_mpi.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_mpi.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_mpi.hpp	(revision 1651)
@@ -0,0 +1,38 @@
+#ifndef EP_LIB_MPI_HPP_INCLUDED
+#define EP_LIB_MPI_HPP_INCLUDED
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+
+  int MPI_Send_mpi      (void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);
+  int MPI_Ssend_mpi      (void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);
+  int MPI_Isend_mpi      (const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request);
+  int MPI_Issend_mpi      (const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request);
+  
+  
+  int MPI_Recv_mpi      (void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status *status);
+  int MPI_Irecv_mpi      (void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *request);
+
+  int MPI_Iprobe_mpi(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status);
+  int MPI_Improbe_mpi(int src, int tag, MPI_Comm comm, int *flag, MPI_Message *message, MPI_Status *status);
+  
+  int MPI_Comm_rank_mpi(MPI_Comm comm, int* rank);
+  int MPI_Comm_size_mpi(MPI_Comm comm, int* size);
+  int MPI_Comm_remote_size_mpi(MPI_Comm comm, int* size);
+
+  int MPI_Comm_dup_mpi(MPI_Comm comm, MPI_Comm *newcomm);
+  int MPI_Comm_free_mpi(MPI_Comm *comm);
+
+  int MPI_Barrier_mpi(MPI_Comm comm);
+  
+  int MPI_Intercomm_create_mpi(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm);
+
+}
+#endif
+
+#endif // EP_LIB_MPI_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_win.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_win.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_lib_win.hpp	(revision 1651)
@@ -0,0 +1,55 @@
+#ifndef EP_LIB_WIN_HPP_INCLUDED
+#define EP_LIB_WIN_HPP_INCLUDED
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+
+  int MPI_Win_create(void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win);
+  
+  int MPI_Win_free(MPI_Win *win);
+  int MPI_Win_fence(int assert, MPI_Win win);
+
+  int MPI_Put(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+  	          int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win);
+
+  int MPI_Rput(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+              int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request *request);
+
+  int MPI_Get(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+  	          int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win);
+
+  int MPI_Rget(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+              int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request *request);
+
+  int MPI_Accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+  	                 int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win);
+
+  int MPI_Raccumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+                     int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request *request);
+
+  int MPI_Get_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr, 
+                         int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
+                         int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win);
+  
+  int MPI_Rget_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr, 
+                         int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
+                         int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request *request);
+
+  int MPI_Win_allocate (MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *baseptr, MPI_Win *win);
+
+  int MPI_Fetch_and_op(const void *origin_addr, void *result_addr, MPI_Datatype datatype, int target_rank, 
+                      MPI_Aint target_disp, MPI_Op op, MPI_Win win);
+
+  int MPI_Compare_and_swap(const void *origin_addr, const void *compare_addr, void *result_addr, MPI_Datatype datatype, 
+                           int target_rank, MPI_Aint target_disp, MPI_Win win);
+                           
+  // MPI_lock & MPI_Unlock
+
+}
+#endif
+#endif // EP_LIB_COLLECTIVE_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_merge.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_merge.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_merge.cpp	(revision 1651)
@@ -0,0 +1,107 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+
+namespace ep_lib 
+{
+
+  int MPI_Intercomm_merge(MPI_Comm inter_comm, bool high, MPI_Comm *newintracomm)
+  {
+    
+    int ep_rank = inter_comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_size = inter_comm->ep_comm_ptr->size_rank_info[0].second;
+    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;
+    int mpi_rank = inter_comm->ep_comm_ptr->size_rank_info[2].first;
+
+    int remote_ep_size = inter_comm->inter_rank_map->size();
+
+    int new_ep_rank = high? remote_ep_size + ep_rank : ep_rank;
+
+
+    MPI_Comm_dup(inter_comm, newintracomm);
+
+    (*newintracomm)->is_intercomm = false;
+    (*newintracomm)->inter_rank_map->clear();
+    delete (*newintracomm)->inter_rank_map;
+
+    (*newintracomm)->ep_comm_ptr->size_rank_info[0].second = ep_size + remote_ep_size;
+    
+    ///////////////////////////////////
+    int int_high = high? 1 : 0;
+    int sum_high;
+    
+    MPI_Allreduce(&int_high, &sum_high, 1, MPI_INT, MPI_SUM, *newintracomm);
+
+    if(sum_high==0 || sum_high==ep_size+remote_ep_size)
+    {
+      printf("MPI_Intercomm_merge error: please define high with different value...\n");
+      MPI_Abort(inter_comm, 0);
+    }
+    
+    
+    
+    ///////////////////////////////////
+    
+    (*newintracomm)->ep_comm_ptr->size_rank_info[0].first = new_ep_rank;
+
+    // modif ep_rank_map
+    int my_triple[3] = {new_ep_rank, ep_rank_loc, mpi_rank};
+    int *my_triple_list = new int[3*(ep_size+remote_ep_size)];
+
+    
+    MPI_Allgather(my_triple, 3, MPI_INT, my_triple_list, 3, MPI_INT, *newintracomm); 
+
+
+#ifdef _showinfo
+    for(int i=0; i<ep_size+remote_ep_size; i++)
+    {
+      if(new_ep_rank == i)
+      {
+        for(int j=0; j<ep_size+remote_ep_size; j++)
+        {
+          printf("rank %d : my_triple_list[%d] = %d %d %d\n", i, j, my_triple_list[3*j], my_triple_list[3*j+1], my_triple_list[3*j+2]);
+        }
+        printf("\n");
+      }
+      MPI_Barrier(*newintracomm);
+    }
+#endif
+
+    if((*newintracomm)->ep_comm_ptr->size_rank_info[1].first==0)
+    {
+      for(int i=0; i<ep_size+remote_ep_size; i++)
+      {
+        (*newintracomm)->ep_comm_ptr->comm_list[0]->ep_rank_map->at(my_triple_list[3*i]) = std::make_pair(my_triple_list[3*i+1], my_triple_list[3*i+2]);
+      }
+    }
+
+    MPI_Barrier_local(*newintracomm);
+
+#ifdef _showinfo
+
+    for(int i=0; i<ep_size+remote_ep_size; i++)
+    {
+      if(new_ep_rank == i)
+      {
+        for(EP_RANK_MAP::iterator it = (*newintracomm)->ep_rank_map->begin(); it != (*newintracomm)->ep_rank_map->end(); it++)
+        {
+          printf("rank %d : ep_rank_map[%d] = %d %d\n", i, it->first, it->second.first, it->second.second);
+        }
+        printf("\n");
+      }
+      MPI_Barrier(*newintracomm);
+    }
+#endif
+
+    delete[] my_triple_list;
+
+  }
+  
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_message.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_message.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_message.cpp	(revision 1651)
@@ -0,0 +1,240 @@
+#ifdef _usingEP
+/*!
+   \file ep_message.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI endpoint function: Message_Check
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+extern std::list< ep_lib::MPI_Request* > * EP_PendingRequests;
+#pragma omp threadprivate(EP_PendingRequests)
+
+namespace ep_lib
+{
+  int Request_Check()
+  {
+    if(EP_PendingRequests == 0 ) EP_PendingRequests = new std::list< MPI_Request* >;
+    
+    if(EP_PendingRequests->size() == 0) return 0;
+    
+    show_EP_PendingRequests(EP_PendingRequests);
+    
+    MPI_Status status;
+    MPI_Message *message;
+    int probed = false;
+    int recv_count = 0;
+    std::list<MPI_Request* >::iterator it;
+    
+    show_EP_PendingRequests(EP_PendingRequests);
+    
+    
+    for(it = EP_PendingRequests->begin(); it!=EP_PendingRequests->end(); it++)
+    { 
+      if(*(*it) == 0)
+      {
+        EP_PendingRequests->erase(it);
+        
+        memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());
+        it = EP_PendingRequests->begin();
+        continue;
+      }
+      
+      if((*(*it))->state == 2)
+      {
+        EP_PendingRequests->erase(it);
+        
+        memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());
+        it = EP_PendingRequests->begin();
+        continue;
+      }
+      
+      Message_Check(((*(*it))->comm));
+    }
+    
+    
+
+
+    for(it = EP_PendingRequests->begin(); it!=EP_PendingRequests->end(); )
+    {
+      if(*(*it) == 0)
+      {
+        EP_PendingRequests->erase(it);
+        
+        memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());
+        it = EP_PendingRequests->begin();
+        continue;
+      }
+      
+      if((*(*it))->state == 2)
+      {
+        EP_PendingRequests->erase(it);
+        
+        memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());
+        it = EP_PendingRequests->begin();
+        continue;
+      }
+      
+      if((*(*it))->probed == false)
+      {
+        #pragma omp critical (_query0)
+        {
+          MPI_Iprobe_endpoint((*(*it))->ep_src, (*(*it))->ep_tag, ((*(*it))->comm), &probed, &status);
+          if(probed)
+          {
+            message = new MPI_Message;
+            *message = new ep_message;
+        
+            memcheck("new "<< message <<" : in ep_lib::Request_Check, message = new MPI_Message");
+            memcheck("new "<< *message <<" : in ep_lib::Request_Check, *message = new ep_message");
+          
+          
+            MPI_Improbe_endpoint((*(*it))->ep_src, (*(*it))->ep_tag, (*(*it))->comm, &probed, message, &status);
+        
+          }
+        }
+      
+        
+        if(probed)
+        {
+          MPI_Get_count(&status, (*(*it))->ep_datatype, &recv_count);
+          
+          MPI_Imrecv((*(*it))->buf, recv_count, (*(*it))->ep_datatype, message, *it);
+          (*(*it))->type = 3;
+          (*(*it))->probed = true;
+
+          memcheck("delete "<< status.mpi_status <<" : in ep_lib::Request_Check, delete status.mpi_status");
+          delete status.mpi_status;          
+
+          memcheck("delete "<< *message <<" : in ep_lib::Request_Check, delete *message");
+          memcheck("delete "<< message <<" : in ep_lib::Request_Check, delete message");
+
+          delete *message;
+          delete message;
+        
+          it++;
+          continue;      
+        }              
+      }
+      
+      it++;
+    }
+    
+    show_EP_PendingRequests(EP_PendingRequests);
+  }
+  
+  
+  
+  int Message_Check(MPI_Comm comm)
+  {
+    if(comm->is_ep) return Message_Check_endpoint(comm);
+  }
+  
+  
+  int Message_Check_endpoint(MPI_Comm comm)
+  {
+    
+    int flag = true;
+    ::MPI_Status status;
+    ::MPI_Message message;
+
+    while(flag) // loop until the end of global queue
+    {
+      Debug("Message probing for intracomm\n");
+/*     
+      #pragma omp critical (_mpi_call)
+      {
+        ::MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, to_mpi_comm(comm->mpi_comm), &flag, &status);
+        if(flag)
+        {
+          Debug("find message in mpi comm \n");
+          ::MPI_Mprobe(status.MPI_SOURCE, status.MPI_TAG, to_mpi_comm(comm->mpi_comm), &message, &status);
+        }
+      }
+
+*/    
+      ::MPI_Improbe(MPI_ANY_SOURCE, MPI_ANY_TAG, to_mpi_comm(comm->mpi_comm), &flag, &message, &status);      
+
+      if(flag)
+      {
+        MPI_Message msg = new ep_message; 
+        msg->mpi_message = new ::MPI_Message(message);
+
+        memcheck("new "<< msg <<" : in ep_lib::Message_Check, msg = new ep_message");
+        memcheck("new "<< msg->mpi_message <<" : in ep_lib::Message_Check, msg->mpi_message = new ::MPI_Message");
+              
+
+        msg->ep_tag  = bitset<15>(status.MPI_TAG >> 16).to_ulong(); 
+        int src_loc  = bitset<8> (status.MPI_TAG >> 8) .to_ulong(); 
+        int dest_loc = bitset<8> (status.MPI_TAG)	    .to_ulong();
+        int src_mpi  = status.MPI_SOURCE;
+             
+        msg->ep_src  = get_ep_rank(comm, src_loc,  src_mpi);  
+
+#ifdef _showinfo
+        printf("status.MPI_TAG = %d, src_loc = %d, dest_loc = %d, ep_tag = %d\n", status.MPI_TAG, src_loc, dest_loc, msg->ep_tag);
+#endif
+
+        msg->mpi_status = new ::MPI_Status(status);  
+        memcheck("new "<< msg->mpi_status <<" : in ep_lib::Message_Check, msg->mpi_status = new ::MPI_Status");
+
+        #pragma omp critical (_query)
+        {
+          #pragma omp flush
+          comm->ep_comm_ptr->comm_list[dest_loc]->ep_comm_ptr->message_queue->push_back(msg);  
+          int dest_mpi = comm->ep_comm_ptr->size_rank_info[2].first;
+          memcheck("message_queue["<<dest_mpi<<","<<dest_loc<<"]->size = "<<comm->ep_comm_ptr->comm_list[dest_loc]->ep_comm_ptr->message_queue->size());
+          #pragma omp flush
+        }
+      }
+    }
+
+    return MPI_SUCCESS;
+  }
+
+  
+  void show_EP_PendingRequests(std::list< ep_lib::MPI_Request* > * EP_PendingRequest)
+  {
+#ifdef _showinfo
+    std::list<MPI_Request* >::iterator it;
+    
+    int i=0;
+    
+    for(it = EP_PendingRequests->begin(); it!=EP_PendingRequests->end(); it++)
+    { 
+      if(*(*it) == 0)
+      {
+        EP_PendingRequests->erase(it);
+            
+        memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());
+        it = EP_PendingRequests->begin();
+        continue;
+      }
+      
+      if((*(*it))->state == 2)
+      {
+        EP_PendingRequests->erase(it);
+        
+        memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());
+        it = EP_PendingRequests->begin();
+        continue;
+      }
+          
+      if((*(*it))->ep_src>6)
+        printf("EP_PendingRequests[%d] : ep_src = %d, ep_tag = %d, type = %d, state = %d, comm = %d\n", i, (*(*it))->ep_src, (*(*it))->ep_tag, (*(*it))->type, (*(*it))->state, to_mpi_comm(((*(*it))->comm)->mpi_comm));
+      i++;
+    }
+#endif
+
+  }
+
+  
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_message.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_message.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_message.hpp	(revision 1651)
@@ -0,0 +1,28 @@
+#ifdef _usingEP
+#ifndef EP_MESSAGE_HPP_INCLUDED
+#define EP_MESSAGE_HPP_INCLUDED
+
+
+namespace ep_lib
+{
+
+  class ep_message
+  {
+    public:
+
+      void* mpi_message;
+      int ep_src;
+      int ep_tag;
+      void* mpi_status;
+
+  };
+  
+  typedef ep_message* MPI_Message;
+
+
+}
+
+
+
+#endif // EP_MESSAGE_HPP_INCLUDED
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_mpi.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_mpi.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_mpi.hpp	(revision 1651)
@@ -0,0 +1,20 @@
+#ifndef EP_MPI_HPP_INCLUDED
+#define EP_MPI_HPP_INCLUDED
+
+#ifdef _usingEP
+#include "ep_type.hpp"
+
+MPI_Datatype to_mpi_type(ep_lib::MPI_Datatype type);
+MPI_Op       to_mpi_op(ep_lib::MPI_Op op);
+MPI_Comm     to_mpi_comm(void* comm);
+MPI_Comm*    to_mpi_comm_ptr(void* comm);
+MPI_Message  to_mpi_message(void* message);
+MPI_Info     to_mpi_info(ep_lib::MPI_Info info);
+MPI_Win      to_mpi_win(void* win);
+MPI_Aint     to_mpi_aint(ep_lib::MPI_Aint aint);
+MPI_Status*  to_mpi_status_ptr (ep_lib::MPI_Status status);
+MPI_Request* to_mpi_request_ptr(ep_lib::MPI_Request request);
+MPI_Message* to_mpi_message_ptr(ep_lib::MPI_Message message);
+#endif
+
+#endif // EP_MPI_HPP_INCLUDED
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_probe.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_probe.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_probe.cpp	(revision 1651)
@@ -0,0 +1,319 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+  int MPI_Iprobe_mpi(int src, int tag, MPI_Comm comm, int *flag, MPI_Status *status)
+  {
+    ::MPI_Status mpi_status;
+
+    ::MPI_Iprobe(src<0? MPI_ANY_SOURCE : src, tag<0? MPI_ANY_TAG: tag, to_mpi_comm(comm->mpi_comm), flag, &mpi_status);
+
+    status->mpi_status = new ::MPI_Status(mpi_status);
+    status->ep_src = src;
+    status->ep_tag = tag;
+  }
+
+
+  int MPI_Improbe_mpi(int src, int tag, MPI_Comm comm, int *flag, MPI_Message *message, MPI_Status *status)
+  {
+    ::MPI_Status mpi_status;
+    ::MPI_Message mpi_message;
+
+    #ifdef _openmpi
+    #pragma omp critical (_mpi_call)
+    {
+      ::MPI_Iprobe(src<0? MPI_ANY_SOURCE : src, tag<0? MPI_ANY_TAG: tag, to_mpi_comm(comm->mpi_comm), flag, &mpi_status);
+      if(*flag)
+      {
+        ::MPI_Mprobe(src<0? MPI_ANY_SOURCE : src, tag<0? MPI_ANY_TAG: tag, to_mpi_comm(comm->mpi_comm), &mpi_message, &mpi_status);
+      }
+    }
+    #elif _intelmpi
+    ::MPI_Improbe(src<0? MPI_ANY_SOURCE : src, tag<0? MPI_ANY_TAG: tag, to_mpi_comm(comm->mpi_comm), flag, &mpi_message, &mpi_status);
+    #endif
+      
+    status->mpi_status = new ::MPI_Status(mpi_status);
+    status->ep_src = src;
+    status->ep_tag = tag;
+
+    (*message)->mpi_message = &message;
+    (*message)->ep_src = src;
+    (*message)->ep_tag = tag;
+  }
+
+
+  int MPI_Iprobe(int src, int tag, MPI_Comm comm, int *flag, MPI_Status *status)
+  {
+    *flag = false;
+    if(src>=0) status->ep_src = src;
+    if(comm->is_intercomm)
+    {
+      if(src>=0) src = comm->inter_rank_map->at(src);
+    }
+
+    ::MPI_Status mpi_status;
+    
+    if(src>=0)
+    {
+
+      int mpi_src = comm->ep_rank_map->at(src).second;
+      int mpi_tag = tag_combine(tag, comm->ep_rank_map->at(src).first, comm->ep_comm_ptr->size_rank_info[1].first);
+      //printf("MPI_Iprobe with src\n");
+      
+      ::MPI_Iprobe(mpi_src, mpi_tag, to_mpi_comm(comm->mpi_comm), flag, &mpi_status);
+      if(*flag)
+      {
+        //printf("proc %d probe from proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, src);
+        status->mpi_status = new ::MPI_Status(mpi_status);
+      }
+      return MPI_SUCCESS;
+    }
+    else
+    {
+      //printf("MPI_Iprobe with ANY_SOURCE\n");
+      //for(int i=0; i<comm->ep_comm_ptr->size_rank_info[1].second; i++)
+      for(int i=0; i<4; i++)
+      {
+        int mpi_tag = tag_combine(tag, i, comm->ep_comm_ptr->size_rank_info[1].first);
+        ::MPI_Iprobe(MPI_ANY_SOURCE, mpi_tag, to_mpi_comm(comm->mpi_comm), flag, &mpi_status);
+        if(*flag) 
+        {
+          //printf("proc %d probe from proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, get_ep_rank(comm, i, mpi_status.MPI_SOURCE));
+          status->mpi_status = new ::MPI_Status(mpi_status);
+          //printf("get_ep_rank in MPI_Iprobe\n");
+          status->ep_src = get_ep_rank(comm, i, mpi_status.MPI_SOURCE);
+          return MPI_SUCCESS;
+        }
+    
+      }
+      
+    }
+
+  }
+
+
+
+  int MPI_Iprobe2(int src, int tag, MPI_Comm comm, int *flag, MPI_Status *status)
+  {
+    if(!comm->is_ep)
+    {
+      Debug("MPI_Iprobe with MPI\n");
+      return MPI_Iprobe_mpi(src, tag, comm, flag, status);
+    }
+
+    if(comm->is_intercomm)
+    {
+      if(src>=0) src = comm->inter_rank_map->at(src);
+    } 
+    
+    return MPI_Iprobe_endpoint(src, tag, comm, flag, status);
+  }
+
+  int MPI_Iprobe_endpoint(int src, int tag, MPI_Comm comm, int *flag, MPI_Status *status)
+  {
+    Debug("MPI_Iprobe with EP\n");
+
+    *flag = false;
+    
+    #pragma omp critical (_query)
+    for(Message_list::iterator it = comm->ep_comm_ptr->message_queue->begin(); it!= comm->ep_comm_ptr->message_queue->end(); ++it)
+    {
+      bool src_matched = src<0? true: (*it)->ep_src == src;
+      bool tag_matched = tag<0? true: (*it)->ep_tag == tag;
+      
+      if(src_matched && tag_matched)        
+      {
+        Debug("find message\n");
+         
+        status->mpi_status = new ::MPI_Status(*static_cast< ::MPI_Status*>((*it)->mpi_status));
+        status->ep_src = (*it)->ep_src;
+        status->ep_tag = (*it)->ep_tag;
+        
+        if(comm->is_intercomm)
+        {
+          for(INTER_RANK_MAP::iterator iter = comm->inter_rank_map->begin(); iter != comm->inter_rank_map->end(); iter++)
+          {
+            if(iter->second == (*it)->ep_src) status->ep_src=iter->first;
+          }
+        }
+
+        *flag = true;
+        break;
+      }
+    }
+    if(*flag) return 0;
+    
+    Message_Check(comm);
+
+    #pragma omp flush
+
+    #pragma omp critical (_query)
+    for(Message_list::iterator it = comm->ep_comm_ptr->message_queue->begin(); it!= comm->ep_comm_ptr->message_queue->end(); ++it)
+    {
+      bool src_matched = src<0? true: (*it)->ep_src == src;
+      bool tag_matched = tag<0? true: (*it)->ep_tag == tag;
+      
+      if(src_matched && tag_matched)        
+      {
+        Debug("find message\n");
+         
+        status->mpi_status = new ::MPI_Status(*static_cast< ::MPI_Status*>((*it)->mpi_status));
+        status->ep_src = (*it)->ep_src;
+        status->ep_tag = (*it)->ep_tag;
+        
+        if(comm->is_intercomm)
+        {
+          for(INTER_RANK_MAP::iterator iter = comm->inter_rank_map->begin(); iter != comm->inter_rank_map->end(); iter++)
+          {
+            if(iter->second == (*it)->ep_src) status->ep_src=iter->first;
+          }
+        }
+
+        *flag = true;
+        break;
+      }
+    }
+    if(*flag) return 0;
+  }
+
+  
+
+  int MPI_Improbe(int src, int tag, MPI_Comm comm, int *flag, MPI_Message *message, MPI_Status *status)
+  {
+    if(!comm->is_ep)
+    {
+      Debug("MPI_Iprobe with MPI\n");
+      return MPI_Improbe_mpi(src, tag, comm, flag, message, status);
+    }
+
+    if(comm->is_intercomm)
+    {
+      src = comm->inter_rank_map->at(src);
+      *message = new ep_message;
+      printf("============= new *message = %p\n", *message);
+    } 
+    
+    return MPI_Improbe_endpoint(src, tag, comm, flag, message, status);
+  }
+
+
+
+  int MPI_Improbe_endpoint(int src, int tag, MPI_Comm comm, int *flag, MPI_Message *message, MPI_Status *status)
+  {
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank    = comm->ep_comm_ptr->size_rank_info[2].first;
+
+    *flag = false;
+    
+    #pragma omp critical (_query)
+    if(! comm->ep_comm_ptr->message_queue->empty())
+    {
+      for(Message_list::iterator it = comm->ep_comm_ptr->message_queue->begin(); it!= comm->ep_comm_ptr->message_queue->end(); ++it)
+      {
+                                          
+        bool src_matched = src<0? true: (*it)->ep_src == src;
+        bool tag_matched = tag<0? true: (*it)->ep_tag == tag;
+        
+        if(src_matched && tag_matched)
+        {
+          *flag = true;
+
+          status->mpi_status = new ::MPI_Status(*static_cast< ::MPI_Status*>((*it)->mpi_status));
+          memcheck("new "<< status->mpi_status << " : in ep_lib::MPI_Improbe, status->mpi_status = new ::MPI_Status");
+          status->ep_src = (*it)->ep_src;
+          status->ep_tag = (*it)->ep_tag;
+
+          (*message)->mpi_message = new ::MPI_Message(*static_cast< ::MPI_Message*>((*it)->mpi_message));
+          memcheck("new "<< (*message)->mpi_message <<" : in ep_lib::MPI_Improbe, (*message)->mpi_message = new ::MPI_Message");
+          (*message)->ep_src = (*it)->ep_src;
+          (*message)->ep_tag = (*it)->ep_tag;
+                                      
+
+          #pragma omp critical (_query2)
+          {              
+            memcheck("delete "<< (*it)->mpi_message <<" : in ep_lib::Message_Check, delete (*it)->mpi_message");
+            memcheck("delete "<< (*it)->mpi_status <<" : in ep_lib::Message_Check, delete (*it)->mpi_status");
+            memcheck("delete "<< (*it) <<" : in ep_lib::Message_Check, delete (*it)");
+            
+            
+            delete (*it)->mpi_message;     
+            delete (*it)->mpi_status; 
+            delete *it;
+            
+                       
+            comm->ep_comm_ptr->message_queue->erase(it);
+            memcheck("message_queue["<<mpi_rank<<","<<ep_rank_loc<<"]->size = "<<comm->ep_comm_ptr->message_queue->size());
+            #pragma omp flush
+          }
+          
+          break;
+        }
+
+      }
+    }
+
+    if(*flag) return 0;
+   
+    Message_Check(comm);
+    
+    #pragma omp flush
+
+    #pragma omp critical (_query)
+    if(! comm->ep_comm_ptr->message_queue->empty())
+    {
+      for(Message_list::iterator it = comm->ep_comm_ptr->message_queue->begin(); it!= comm->ep_comm_ptr->message_queue->end(); ++it)
+      {
+                                          
+        bool src_matched = src<0? true: (*it)->ep_src == src;
+        bool tag_matched = tag<0? true: (*it)->ep_tag == tag;
+        
+        if(src_matched && tag_matched)
+        {
+          *flag = true;
+
+          status->mpi_status = new ::MPI_Status(*static_cast< ::MPI_Status*>((*it)->mpi_status));
+          memcheck("new "<< status->mpi_status << " : in ep_lib::MPI_Improbe, status->mpi_status = new ::MPI_Status");
+          status->ep_src = (*it)->ep_src;
+          status->ep_tag = (*it)->ep_tag;
+
+          (*message)->mpi_message = new ::MPI_Message(*static_cast< ::MPI_Message*>((*it)->mpi_message));
+          memcheck("new "<< (*message)->mpi_message <<" : in ep_lib::MPI_Improbe, (*message)->mpi_message = new ::MPI_Message");
+          (*message)->ep_src = (*it)->ep_src;
+          (*message)->ep_tag = (*it)->ep_tag;
+                                      
+
+          #pragma omp critical (_query2)
+          {              
+            memcheck("delete "<< (*it)->mpi_message <<" : in ep_lib::Message_Check, delete (*it)->mpi_message");
+            memcheck("delete "<< (*it)->mpi_status <<" : in ep_lib::Message_Check, delete (*it)->mpi_status");
+            memcheck("delete "<< (*it) <<" : in ep_lib::Message_Check, delete (*it)");
+            
+            
+            delete (*it)->mpi_message;     
+            delete (*it)->mpi_status; 
+            delete *it;
+            
+                       
+            comm->ep_comm_ptr->message_queue->erase(it);
+            memcheck("message_queue["<<mpi_rank<<","<<ep_rank_loc<<"]->size = "<<comm->ep_comm_ptr->message_queue->size());
+            #pragma omp flush
+          }
+          
+          break;
+        }
+
+      }
+    }
+
+    if(*flag) return 0;
+
+  }
+
+}
+
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_put.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_put.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_put.cpp	(revision 1651)
@@ -0,0 +1,62 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+	int MPI_Put(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+  	          int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    if(num_ep==1)
+      return  ::MPI_Put(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+    	               to_mpi_win(win->server_win[target_local_rank]));
+
+    else
+    	return  ::MPI_Put(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+    	               to_mpi_win(win->client_win));
+  }
+
+  int MPI_Rput(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, 
+              int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request *request)
+  {
+    int target_mpi_rank   = win->comm->ep_rank_map->at(target_rank).second;
+    int target_local_rank = win->comm->ep_rank_map->at(target_rank).first;
+    int num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    
+    ::MPI_Request mpi_request;
+
+    if(num_ep==1)
+    {
+      int return_value = ::MPI_Rput(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                           to_mpi_win(win->server_win[target_local_rank]), &mpi_request);
+
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+
+    else
+    {
+      int return_value = ::MPI_Rput(origin_addr, origin_count, to_mpi_type(origin_datatype), target_mpi_rank, to_mpi_aint(target_disp), target_count, to_mpi_type(target_datatype), 
+                         to_mpi_win(win->client_win), &mpi_request);
+
+      (*request)->mpi_request = new ::MPI_Request(mpi_request);
+
+      (*request)->ep_datatype = origin_datatype;
+      (*request)->type = 1;
+      return return_value;
+    }
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_rank.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_rank.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_rank.cpp	(revision 1651)
@@ -0,0 +1,32 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+
+  int MPI_Comm_rank(MPI_Comm comm, int* rank)
+  {
+    if(comm->is_ep)
+    {
+      Debug("MPI_Comm_rank with EP");
+      return *rank = comm->ep_comm_ptr->size_rank_info[0].first;      
+    }
+
+    return MPI_Comm_rank_mpi(comm, rank);
+  }
+
+
+  int MPI_Comm_rank_mpi(MPI_Comm comm, int* rank)
+  {
+    Debug("MPI_Comm_rank with MPI");
+    return ::MPI_Comm_rank(to_mpi_comm(comm->mpi_comm), rank);
+  }
+
+
+}
+
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_recv.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_recv.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_recv.cpp	(revision 1651)
@@ -0,0 +1,262 @@
+#ifdef _usingEP
+/*!
+   \file ep_recv.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI receive functions: MPI_Recv, MPI_Mrecv, MPI_Irecv, MPI_Imrecv
+ */
+
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+extern std::list< ep_lib::MPI_Request* > * EP_PendingRequests;
+#pragma omp threadprivate(EP_PendingRequests)
+
+namespace ep_lib 
+{
+
+  int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status *status)
+  {
+
+    if(src>=0) status->ep_src = src;
+    
+    if(comm->is_intercomm)
+    {
+      if(src>=0) src = comm->inter_rank_map->at(src);
+    }
+
+    ::MPI_Status mpi_status;
+    if(src>=0)
+    {
+
+      int mpi_src = comm->ep_rank_map->at(src).second;
+      int mpi_tag = tag_combine(tag, comm->ep_rank_map->at(src).first, comm->ep_comm_ptr->size_rank_info[1].first);
+
+      //printf("MPI_Recv with src\n");
+      //printf("proc %d recv from proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, src);
+      ::MPI_Recv(buf, count, to_mpi_type(datatype), mpi_src, mpi_tag, to_mpi_comm(comm->mpi_comm), &mpi_status);
+      status->mpi_status = new ::MPI_Status(mpi_status);
+      return MPI_SUCCESS;
+    }
+    else
+    {
+      //printf("MPI_Recv with ANY_SOURCE\n");
+      int probed=false;
+      int mpi_tag;
+      while(!probed)
+      {
+        //for(int i=0; i<comm->ep_comm_ptr->size_rank_info[1].second; i++)
+        for(int i=0; i<4; i++)
+        {
+          mpi_tag = tag_combine(tag, i, comm->ep_comm_ptr->size_rank_info[1].first);
+          ::MPI_Iprobe(MPI_ANY_SOURCE, mpi_tag, to_mpi_comm(comm->mpi_comm), &probed, &mpi_status);
+          if(probed) 
+          {
+            //printf("proc %d recv from proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, get_ep_rank(comm, i, mpi_status.MPI_SOURCE));
+            ::MPI_Recv(buf, count, to_mpi_type(datatype), mpi_status.MPI_SOURCE, mpi_status.MPI_TAG, to_mpi_comm(comm->mpi_comm), &mpi_status);
+            //printf("get_ep_rank in MPI_Recv\n");
+            status->ep_src = get_ep_rank(comm, i, mpi_status.MPI_SOURCE);
+            status->mpi_status = new ::MPI_Status(mpi_status);
+            return MPI_SUCCESS;
+          }
+        }
+      }
+    }
+    
+  }
+
+  int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *request)
+  {
+    if(comm->is_intercomm)
+    {
+      if(src>=0) src = comm->inter_rank_map->at(src);
+    }
+
+    *request = new ep_request;
+    //printf("MPI_Irecv : *request = new ep_request => *request = %p\n", *request);
+
+    (*request)->mpi_request = new ::MPI_Request;
+    //printf("MPI_Irecv : (*request)->mpi_request = new ::MPI_Request => (*request)->mpi_request = %p\n", (*request)->mpi_request);
+
+
+    if(src>=0)
+    {
+      int mpi_src = comm->ep_rank_map->at(src).second;
+      int mpi_tag = tag_combine(tag, comm->ep_rank_map->at(src).first, comm->ep_comm_ptr->size_rank_info[1].first);
+      //printf("MPI_Irecv with src\n");
+      //printf("proc %d recv from proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, src);
+      return ::MPI_Irecv(buf, count, to_mpi_type(datatype), mpi_src, mpi_tag, to_mpi_comm(comm->mpi_comm), to_mpi_request_ptr(*request));
+    }
+    else
+    {
+      //printf("MPI_Irecv with ANY_SOURCE\n");
+      int probed=false;
+      int mpi_tag;
+      ::MPI_Status mpi_status;
+      while(!probed)
+      {
+        //for(int i=0; i<comm->ep_comm_ptr->size_rank_info[1].second; i++)
+        for(int i=0; i<4; i++)
+        {
+          mpi_tag = tag_combine(tag, i, comm->ep_comm_ptr->size_rank_info[1].first);
+          ::MPI_Iprobe(MPI_ANY_SOURCE, mpi_tag, to_mpi_comm(comm->mpi_comm), &probed, &mpi_status);
+          if(probed)
+          {
+            //printf("proc %d recv from proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, get_ep_rank(comm, i, mpi_status.MPI_SOURCE));
+            return ::MPI_Irecv(buf, count, to_mpi_type(datatype), mpi_status.MPI_SOURCE, mpi_status.MPI_TAG, to_mpi_comm(comm->mpi_comm), to_mpi_request_ptr(*request));
+          }
+        }
+      }
+    }
+    
+
+  }
+
+  
+
+
+  int MPI_Irecv2(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *request)
+  {
+    if(!comm->is_ep) return MPI_Irecv_mpi(buf, count, datatype, src, tag, comm, request);
+
+    if(comm->is_intercomm)
+    {
+      if(src>=0) src = comm->inter_rank_map->at(src);
+    }
+    
+    Debug("MPI_Irecv with EP");
+    int dest_rank;
+    MPI_Comm_rank(comm, &dest_rank);
+    
+    *request = new ep_request;   
+    memcheck("new " << *request <<" : in ep_lib::MPI_Irecv, *request = new ep_request");
+
+    (*request)->mpi_request = new ::MPI_Request;
+    memcheck("new " << (*request)->mpi_request << " : in ep_lib::MPI_Irecv, (*request)->mpi_request = new ::MPI_Request");
+    
+    (*request)->buf = buf;
+    (*request)->comm = comm;
+    (*request)->type = 2;
+    (*request)->probed = false;
+    (*request)->state = 0;
+
+    (*request)->ep_src = src;
+    (*request)->ep_tag = tag;
+    (*request)->ep_datatype = datatype;
+  
+    if(EP_PendingRequests == 0 ) EP_PendingRequests = new std::list< MPI_Request* >;
+
+    EP_PendingRequests->push_back(request); 
+    
+    //memcheck("EP_PendingRequests["<<ep_rank<<"]->size() = " << EP_PendingRequests->size());    
+    
+    show_EP_PendingRequests(EP_PendingRequests);
+
+#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();
+  }
+  
+  int MPI_Mrecv(void *buf, int count, MPI_Datatype datatype, MPI_Message *message, MPI_Status *status)
+  {
+    Debug("MPI_Mrecv with MPI/EP");
+
+    status->mpi_status = new ::MPI_Status;
+    memcheck("new " << status->mpi_status << " : in ep_lib::MPI_Mrecv, status->mpi_status = new ::MPI_Status");
+    
+    ::MPI_Mrecv(buf, count, to_mpi_type(datatype), static_cast< ::MPI_Message* >((*message)->mpi_message), to_mpi_status_ptr(*status));
+
+    
+    status->ep_src = (*message)->ep_src;
+    status->ep_datatype = datatype;
+    status->ep_tag = (*message)->ep_tag;
+
+    memcheck("delete " << (*message)->mpi_message << " : in ep_lib::MPI_Mrecv, delete (*message)->mpi_message");
+    delete (*message)->mpi_message;
+    memcheck("delete " << *message << " : in ep_lib::MPI_Imrecv, delete *message");
+    delete *message;
+
+#ifdef _check_sum
+    check_sum_recv(buf, count, datatype, message->ep_src, message->ep_tag);
+#endif
+
+    return Request_Check();
+  }
+
+
+  int MPI_Imrecv(void *buf, int count, MPI_Datatype datatype, MPI_Message *message, MPI_Request *request)
+  {
+    Debug("MPI_Imrecv with MPI/EP");
+
+    (*request)->type = 3;
+    (*request)->ep_datatype = datatype;
+    (*request)->ep_tag = (*message)->ep_tag;
+    (*request)->ep_src = (*message)->ep_src;
+    
+    (*request)->probed = true;
+    (*request)->state = 1;
+	
+    ::MPI_Imrecv(buf, count, to_mpi_type(datatype), to_mpi_message_ptr(*message), to_mpi_request_ptr(*request));		
+    
+    memcheck("delete " << (*message)->mpi_message << " : in ep_lib::MPI_Imrecv, delete (*message)->mpi_message");
+    delete (*message)->mpi_message;
+
+
+#ifdef _check_sum
+    check_sum_recv(buf, count, datatype, message->ep_src, message->ep_tag);
+#endif
+
+    
+    //return Request_Check();
+  }
+
+
+   int MPI_Recv_mpi(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status *status)
+  {
+    Debug("MPI_Recv with MPI");
+    status->ep_src = src;
+    status->ep_tag = tag;
+    status->ep_datatype = datatype;
+    
+    return ::MPI_Recv(buf, count, to_mpi_type(datatype), src<0? MPI_ANY_SOURCE : src, tag<0? MPI_ANY_TAG: tag, to_mpi_comm(comm->mpi_comm), to_mpi_status_ptr(*status)); 
+  }
+  
+  int MPI_Irecv_mpi(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *request)
+  {
+    Debug("MPI_Irecv with MPI");
+    int dest_rank;
+    MPI_Comm_rank(comm, &dest_rank);
+    
+    *request = new ep_request;
+    memcheck("new "<< *request <<" : in ep_lib::MPI_Irecv, *request = new ep_request");
+
+    (*request)->mpi_request = new ::MPI_Request;
+    memcheck("new "<< (*request)->mpi_request <<" : in ep_lib::MPI_Irecv, (*request)->mpi_request = new ::MPI_Request");
+      
+    (*request)->ep_src = src;
+    (*request)->ep_datatype = datatype;
+    (*request)->type = 2;
+    (*request)->ep_tag = tag;
+    
+    return ::MPI_Irecv(buf, count, to_mpi_type(datatype), src<0? MPI_ANY_SOURCE : src, tag<0? MPI_ANY_TAG: tag, to_mpi_comm(comm->mpi_comm), to_mpi_request_ptr(*request));
+  }
+}
+
+
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_reduce.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_reduce.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_reduce.cpp	(revision 1651)
@@ -0,0 +1,344 @@
+#ifdef _usingEP
+/*!
+   \file ep_reduce.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Reduce, MPI_Allreduce
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+
+namespace ep_lib {
+
+  template<typename T>
+  T max_op(T a, T b)
+  {
+    return max(a,b);
+  }
+
+  template<typename T>
+  T min_op(T a, T b)
+  {
+    return min(a,b);
+  }
+
+  template<typename T>
+  T lor_op(T a, T b)
+  {
+    return a||b;
+  }
+
+  template<typename T>
+  void reduce_max(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, max_op<T>);
+  }
+
+  template<typename T>
+  void reduce_min(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, min_op<T>);
+  }
+
+  template<typename T>
+  void reduce_sum(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, std::plus<T>());
+  }
+
+  template<typename T>
+  void reduce_lor(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, lor_op<T>);
+  }
+
+  int MPI_Reduce_local(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int local_root, MPI_Comm comm)
+  {
+    assert(valid_type(datatype));
+    assert(valid_op(op));
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+
+    #pragma omp critical (_reduce)
+    comm->my_buffer->void_buffer[ep_rank_loc] = const_cast< void* >(sendbuf);
+
+    MPI_Barrier_local(comm);
+
+    if(ep_rank_loc == local_root)
+    {
+
+      memcpy(recvbuf, comm->my_buffer->void_buffer[0], datasize * count);
+
+      if(op == MPI_MAX)
+      {
+        if(datatype == MPI_INT)
+        {
+          assert(datasize == sizeof(int));
+          for(int i=1; i<num_ep; i++)
+            reduce_max<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_FLOAT)
+        {
+          assert(datasize == sizeof(float));
+          for(int i=1; i<num_ep; i++)
+            reduce_max<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_DOUBLE)
+        {
+          assert(datasize == sizeof(double));
+          for(int i=1; i<num_ep; i++)
+            reduce_max<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_CHAR)
+        {
+          assert(datasize == sizeof(char));
+          for(int i=1; i<num_ep; i++)
+            reduce_max<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_LONG)
+        {
+          assert(datasize == sizeof(long));
+          for(int i=1; i<num_ep; i++)
+            reduce_max<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_UNSIGNED_LONG)
+        {
+          assert(datasize == sizeof(unsigned long));
+          for(int i=1; i<num_ep; i++)
+            reduce_max<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_LONG_LONG_INT)
+        {
+          assert(datasize == sizeof(long long));
+          for(int i=1; i<num_ep; i++)
+            reduce_max<long long>(static_cast<long long*>(comm->my_buffer->void_buffer[i]), static_cast<long long*>(recvbuf), count);
+        }
+
+        else 
+        {
+          printf("datatype Error in ep_reduce : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+          MPI_Abort(comm, 0);
+        }
+
+      }
+
+      else if(op == MPI_MIN)
+      {
+        if(datatype ==MPI_INT)
+        {
+          assert(datasize == sizeof(int));
+          for(int i=1; i<num_ep; i++)
+            reduce_min<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_FLOAT)
+        {
+          assert(datasize == sizeof(float));
+          for(int i=1; i<num_ep; i++)
+            reduce_min<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_DOUBLE)
+        {
+          assert(datasize == sizeof(double));
+          for(int i=1; i<num_ep; i++)
+            reduce_min<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_CHAR)
+        {
+          assert(datasize == sizeof(char));
+          for(int i=1; i<num_ep; i++)
+            reduce_min<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_LONG)
+        {
+          assert(datasize == sizeof(long));
+          for(int i=1; i<num_ep; i++)
+            reduce_min<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_UNSIGNED_LONG)
+        {
+          assert(datasize == sizeof(unsigned long));
+          for(int i=1; i<num_ep; i++)
+            reduce_min<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_LONG_LONG_INT)
+        {
+          assert(datasize == sizeof(long long));
+          for(int i=1; i<num_ep; i++)
+            reduce_min<long long>(static_cast<long long*>(comm->my_buffer->void_buffer[i]), static_cast<long long*>(recvbuf), count);
+        }
+
+        else 
+        {
+          printf("datatype Error in ep_reduce : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+          MPI_Abort(comm, 0);
+        }
+
+      }
+
+
+      else if(op == MPI_SUM)
+      {
+        if(datatype==MPI_INT)
+        {
+          assert(datasize == sizeof(int));
+          for(int i=1; i<num_ep; i++)
+            reduce_sum<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_FLOAT)
+        {
+          assert(datasize == sizeof(float));
+          for(int i=1; i<num_ep; i++)
+            reduce_sum<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_DOUBLE)
+        {
+          assert(datasize == sizeof(double));
+          for(int i=1; i<num_ep; i++)
+            reduce_sum<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_CHAR)
+        {
+          assert(datasize == sizeof(char));
+          for(int i=1; i<num_ep; i++)
+            reduce_sum<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+        }
+
+        else if(datatype == MPI_LONG)
+        {
+          assert(datasize == sizeof(long));
+          for(int i=1; i<num_ep; i++)
+            reduce_sum<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+        }
+
+        else if(datatype ==MPI_UNSIGNED_LONG)
+        {
+          assert(datasize == sizeof(unsigned long));
+          for(int i=1; i<num_ep; i++)
+            reduce_sum<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);
+        }
+        
+        else if(datatype ==MPI_LONG_LONG_INT)
+        {
+          assert(datasize == sizeof(long long));
+          for(int i=1; i<num_ep; i++)
+            reduce_sum<long long>(static_cast<long long*>(comm->my_buffer->void_buffer[i]), static_cast<long long*>(recvbuf), count);
+        }
+
+        else 
+        {
+          printf("datatype Error in ep_reduce : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+          MPI_Abort(comm, 0);
+        }
+
+      }
+
+      else if(op == MPI_LOR)
+      {
+        if(datatype != MPI_INT)
+          printf("datatype Error, must be MPI_INT\n");
+        else
+        {
+          assert(datasize == sizeof(int));
+          for(int i=1; i<num_ep; i++)
+            reduce_lor<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);
+        }
+      }
+      
+      else
+      {
+        printf("op type Error in ep_reduce : MPI_MAX, MPI_MIN, MPI_SUM, MPI_LOR\n");
+        MPI_Abort(comm, 0);
+      }
+    }
+
+    MPI_Barrier_local(comm);
+
+  }
+
+
+  int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
+  {
+
+    if(!comm->is_ep) return ::MPI_Reduce(sendbuf, recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), root, to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Reduce_intercomm(sendbuf, recvbuf, count, datatype, op, root, comm);
+
+
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    int root_mpi_rank = comm->ep_rank_map->at(root).second;
+    int root_ep_loc = comm->ep_rank_map->at(root).first;
+
+    ::MPI_Aint datasize, lb;
+
+    ::MPI_Type_get_extent(*(static_cast< ::MPI_Datatype*>(datatype)), &lb, &datasize);
+
+    bool is_master = (ep_rank_loc==0 && mpi_rank != root_mpi_rank ) || ep_rank == root;
+    bool is_root = ep_rank == root;
+
+    void* local_recvbuf;
+
+    if(is_master)
+    {
+      local_recvbuf = new void*[datasize * count];
+    }
+
+    if(mpi_rank == root_mpi_rank) MPI_Reduce_local(sendbuf, local_recvbuf, count, datatype, op, root_ep_loc, comm);
+    else                          MPI_Reduce_local(sendbuf, local_recvbuf, count, datatype, op, 0, comm);
+
+
+
+    if(is_master)
+    {
+      ::MPI_Reduce(local_recvbuf, recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+      
+    }
+
+    if(is_master)
+    {
+      delete[] local_recvbuf;
+    }
+
+    MPI_Barrier_local(comm);
+  }
+
+
+  int MPI_Reduce_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
+  {
+    printf("MPI_Reduce_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_reduce_scatter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_reduce_scatter.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_reduce_scatter.cpp	(revision 1651)
@@ -0,0 +1,91 @@
+#ifdef _usingEP
+/*!
+   \file ep_reduce.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Reduce, MPI_Allreduce
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+
+namespace ep_lib {
+
+
+  int MPI_Reduce_scatter(const void *sendbuf, void *recvbuf, const int recvcounts[], MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Reduce_scatter(sendbuf, recvbuf, recvcounts, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Reduce_scatter_intercomm(sendbuf, recvbuf, recvcounts, datatype, op, comm);
+
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+
+    ::MPI_Aint datasize, lb;
+
+    ::MPI_Type_get_extent(*(static_cast< ::MPI_Datatype*>(datatype)), &lb, &datasize);
+
+    bool is_master = ep_rank_loc==0;
+
+    void* local_recvbuf;
+
+    int count = accumulate(recvcounts, recvcounts+ep_size, 0);
+    if(is_master)
+    {
+      local_recvbuf = new void*[datasize * count]; 
+    }
+
+    MPI_Reduce_local(sendbuf, local_recvbuf, count, datatype, op, 0, comm);
+
+    
+    if(is_master)
+    {  
+      ::MPI_Allreduce(MPI_IN_PLACE, local_recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+    }
+
+
+    // master have reduced data
+    // local scatterv
+
+    std::vector<int> local_recvcounts(num_ep, 0);
+    std::vector<int>local_displs(num_ep, 0);
+
+    int my_recvcount = recvcounts[ep_rank];
+    MPI_Gather_local(&my_recvcount, 1, MPI_INT, local_recvcounts.data(), 0, comm);
+    MPI_Bcast_local(local_recvcounts.data(), num_ep, MPI_INT, 0, comm);
+
+    int my_displs = std::accumulate(recvcounts, recvcounts+ep_rank, 0);
+    MPI_Gather_local(&my_displs, 1, MPI_INT, local_displs.data(), 0, comm);
+    MPI_Bcast_local(local_displs.data(), num_ep, MPI_INT, 0, comm);
+
+    
+
+    MPI_Scatterv_local(local_recvbuf, local_recvcounts.data(), local_displs.data(), datatype, recvbuf, recvcounts[ep_rank], datatype, 0, comm);
+
+    if(is_master)
+    {
+      delete[] local_recvbuf;
+    }
+
+  }
+
+  int MPI_Reduce_scatter_intercomm(const void *sendbuf, void *recvbuf, const int recvcounts[], MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    printf("MPI_Reduce_scatter_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+  
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_request.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_request.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_request.hpp	(revision 1651)
@@ -0,0 +1,48 @@
+#ifndef EP_REQUEST_HPP_INCLUDED
+#define EP_REQUEST_HPP_INCLUDED
+#ifdef _usingEP
+
+#include "ep_comm.hpp"
+
+namespace ep_lib
+{
+  
+  class ep_request
+  {
+    public:
+
+      void* mpi_request;
+
+      int type;	//! type of the non-blocking communication. 
+                // 1: Isend or Issend
+                // 2: Irecv 
+                // 3: Imrecv 
+                
+      int state; // 0: new 
+                 // 1: imrecvd
+                 // 2: tested or waited
+      bool probed;
+                   
+      void* buf;
+
+      int ep_src;
+      int ep_tag;
+      void* ep_datatype;
+      
+      
+
+      ep_comm *comm;	//! EP communicator related to the communication
+
+      ep_request() {}
+      ep_request(void* request);
+  };
+  
+  typedef ep_request* MPI_Request;
+
+
+}
+
+#endif
+
+#endif // EP_REQUEST_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scan.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scan.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scan.cpp	(revision 1651)
@@ -0,0 +1,531 @@
+#ifdef _usingEP
+/*!
+   \file ep_scan.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Scan
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+  template<typename T>
+  T max_op(T a, T b)
+  {
+    return max(a,b);
+  }
+
+  template<typename T>
+  T min_op(T a, T b)
+  {
+    return min(a,b);
+  }
+
+  template<typename T>
+  void reduce_max(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, max_op<T>);
+  }
+
+  template<typename T>
+  void reduce_min(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, min_op<T>);
+  }
+
+  template<typename T>
+  void reduce_sum(const T * buffer, T* recvbuf, int count)
+  {
+    transform(buffer, buffer+count, recvbuf, recvbuf, std::plus<T>());
+  }
+
+
+  int MPI_Scan_local(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    valid_op(op);
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+
+    if(ep_rank_loc == 0 && mpi_rank != 0)
+    {
+      if(op == MPI_SUM)
+      {
+        if(datatype == MPI_INT)
+        {
+          assert(datasize == sizeof(int));
+          reduce_sum<int>(static_cast<int*>(const_cast<void*>(sendbuf)), static_cast<int*>(recvbuf), count);    
+        }
+          
+        else if(datatype == MPI_FLOAT)
+        {
+          assert( datasize == sizeof(float));
+          reduce_sum<float>(static_cast<float*>(const_cast<void*>(sendbuf)), static_cast<float*>(recvbuf), count);    
+        } 
+             
+        else if(datatype == MPI_DOUBLE )
+        {
+          assert( datasize == sizeof(double));
+          reduce_sum<double>(static_cast<double*>(const_cast<void*>(sendbuf)), static_cast<double*>(recvbuf), count);
+        }
+      
+        else if(datatype == MPI_CHAR)
+        {
+          assert( datasize == sizeof(char));
+          reduce_sum<char>(static_cast<char*>(const_cast<void*>(sendbuf)), static_cast<char*>(recvbuf), count);
+        } 
+          
+        else if(datatype == MPI_LONG)
+        {
+          assert( datasize == sizeof(long));
+          reduce_sum<long>(static_cast<long*>(const_cast<void*>(sendbuf)), static_cast<long*>(recvbuf), count);
+        } 
+          
+            
+        else if(datatype == MPI_UNSIGNED_LONG)
+        {
+          assert(datasize == sizeof(unsigned long));
+          reduce_sum<unsigned long>(static_cast<unsigned long*>(const_cast<void*>(sendbuf)), static_cast<unsigned long*>(recvbuf), count);    
+        }
+        
+        else if(datatype == MPI_LONG_LONG_INT)
+        {
+          assert(datasize == sizeof(long long int));
+          reduce_sum<long long int>(static_cast<long long int*>(const_cast<void*>(sendbuf)), static_cast<long long int*>(recvbuf), count);    
+        }
+            
+        else 
+        {
+          printf("datatype Error in ep_scan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+          MPI_Abort(comm, 0);
+        }
+      }
+
+      else if(op == MPI_MAX)
+      {
+        if(datatype == MPI_INT)
+        {
+          assert( datasize == sizeof(int));
+          reduce_max<int>(static_cast<int*>(const_cast<void*>(sendbuf)), static_cast<int*>(recvbuf), count);    
+        } 
+          
+        else if(datatype == MPI_FLOAT )
+        {
+          assert( datasize == sizeof(float));
+          reduce_max<float>(static_cast<float*>(const_cast<void*>(sendbuf)), static_cast<float*>(recvbuf), count);    
+        }
+
+        else if(datatype == MPI_DOUBLE )
+        {
+          assert( datasize == sizeof(double));
+          reduce_max<double>(static_cast<double*>(const_cast<void*>(sendbuf)), static_cast<double*>(recvbuf), count);
+        }
+      
+        else if(datatype == MPI_CHAR )
+        {
+          assert(datasize == sizeof(char));
+          reduce_max<char>(static_cast<char*>(const_cast<void*>(sendbuf)), static_cast<char*>(recvbuf), count);
+        }
+      
+        else if(datatype == MPI_LONG)
+        {
+          assert( datasize == sizeof(long));
+          reduce_max<long>(static_cast<long*>(const_cast<void*>(sendbuf)), static_cast<long*>(recvbuf), count);
+        } 
+            
+        else if(datatype == MPI_UNSIGNED_LONG)
+        {
+          assert( datasize == sizeof(unsigned long));
+          reduce_max<unsigned long>(static_cast<unsigned long*>(const_cast<void*>(sendbuf)), static_cast<unsigned long*>(recvbuf), count);    
+        } 
+            
+        else if(datatype == MPI_LONG_LONG_INT)
+        {
+          assert(datasize == sizeof(long long int));
+          reduce_max<long long int>(static_cast<long long int*>(const_cast<void*>(sendbuf)), static_cast<long long int*>(recvbuf), count);    
+        }
+            
+        else 
+        {
+          printf("datatype Error in ep_scan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+          MPI_Abort(comm, 0);
+        }
+      }
+
+      else if(op == MPI_MIN)
+      {
+        if(datatype == MPI_INT )
+        {
+          assert (datasize == sizeof(int));
+          reduce_min<int>(static_cast<int*>(const_cast<void*>(sendbuf)), static_cast<int*>(recvbuf), count);    
+        }
+          
+        else if(datatype == MPI_FLOAT )
+        {
+          assert( datasize == sizeof(float));
+          reduce_min<float>(static_cast<float*>(const_cast<void*>(sendbuf)), static_cast<float*>(recvbuf), count);    
+        }
+             
+        else if(datatype == MPI_DOUBLE )
+        {
+          assert( datasize == sizeof(double));
+          reduce_min<double>(static_cast<double*>(const_cast<void*>(sendbuf)), static_cast<double*>(recvbuf), count);
+        }
+      
+        else if(datatype == MPI_CHAR )
+        {
+          assert( datasize == sizeof(char));
+          reduce_min<char>(static_cast<char*>(const_cast<void*>(sendbuf)), static_cast<char*>(recvbuf), count);
+        }
+      
+        else if(datatype == MPI_LONG )
+        { 
+          assert( datasize == sizeof(long));
+          reduce_min<long>(static_cast<long*>(const_cast<void*>(sendbuf)), static_cast<long*>(recvbuf), count);
+        }
+            
+        else if(datatype == MPI_UNSIGNED_LONG )
+        {
+          assert( datasize == sizeof(unsigned long));
+          reduce_min<unsigned long>(static_cast<unsigned long*>(const_cast<void*>(sendbuf)), static_cast<unsigned long*>(recvbuf), count);    
+        }
+            
+        else if(datatype == MPI_LONG_LONG_INT)
+        {
+          assert(datasize == sizeof(long long int));
+          reduce_min<long long int>(static_cast<long long int*>(const_cast<void*>(sendbuf)), static_cast<long long int*>(recvbuf), count);    
+        }
+            
+        else 
+        {
+          printf("datatype Error in ep_scan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+          MPI_Abort(comm, 0);
+        }
+      }
+      
+      else
+      {
+        printf("op type Error in ep_scan : MPI_MAX, MPI_MIN, MPI_SUM\n");
+        MPI_Abort(comm, 0);
+      }
+
+      comm->my_buffer->void_buffer[0] = recvbuf;
+    }
+    else
+    {
+      comm->my_buffer->void_buffer[ep_rank_loc] = const_cast<void*>(sendbuf);  
+      memcpy(recvbuf, sendbuf, datasize*count);
+    } 
+      
+
+
+    MPI_Barrier_local(comm);
+
+    memcpy(recvbuf, comm->my_buffer->void_buffer[0], datasize*count);
+
+
+    if(op == MPI_SUM)
+    {
+      if(datatype == MPI_INT )
+      {
+        assert (datasize == sizeof(int));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_sum<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);    
+      }
+     
+      else if(datatype == MPI_FLOAT )
+      {
+        assert(datasize == sizeof(float));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_sum<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);    
+      }
+      
+
+      else if(datatype == MPI_DOUBLE )
+      {
+        assert(datasize == sizeof(double));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_sum<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_CHAR )
+      {
+        assert(datasize == sizeof(char));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_sum<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_LONG )
+      {
+        assert(datasize == sizeof(long));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_sum<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_UNSIGNED_LONG )
+      {
+        assert(datasize == sizeof(unsigned long));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_sum<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);    
+      }
+      
+      else if(datatype == MPI_LONG_LONG_INT )
+      {
+        assert(datasize == sizeof(long long int));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_sum<long long int>(static_cast<long long int*>(comm->my_buffer->void_buffer[i]), static_cast<long long int*>(recvbuf), count);    
+      }
+
+      else 
+      {
+        printf("datatype Error in ep_scan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+        MPI_Abort(comm, 0);
+      }
+
+      
+    }
+
+    else if(op == MPI_MAX)
+    {
+      if(datatype == MPI_INT)
+      {
+        assert(datasize == sizeof(int));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_max<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_FLOAT )
+      {
+        assert(datasize == sizeof(float));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_max<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_DOUBLE )
+      {
+        assert(datasize == sizeof(double));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_max<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_CHAR )
+      {
+        assert(datasize == sizeof(char));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_max<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_LONG )
+      {
+        assert(datasize == sizeof(long));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_max<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_UNSIGNED_LONG )
+      {
+        assert(datasize == sizeof(unsigned long));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_max<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);    
+      }
+     
+      else if(datatype == MPI_LONG_LONG_INT )
+      {
+        assert(datasize == sizeof(long long int));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_max<long long int>(static_cast<long long int*>(comm->my_buffer->void_buffer[i]), static_cast<long long int*>(recvbuf), count);    
+      }
+
+      else 
+      {
+        printf("datatype Error in ep_scan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+        MPI_Abort(comm, 0);
+      }
+
+    }
+
+    else if(op == MPI_MIN)
+    {
+      if(datatype == MPI_INT )
+      {
+        assert(datasize == sizeof(int));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_min<int>(static_cast<int*>(comm->my_buffer->void_buffer[i]), static_cast<int*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_FLOAT )
+      {
+        assert(datasize == sizeof(float));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_min<float>(static_cast<float*>(comm->my_buffer->void_buffer[i]), static_cast<float*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_DOUBLE )
+      {
+        assert(datasize == sizeof(double));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_min<double>(static_cast<double*>(comm->my_buffer->void_buffer[i]), static_cast<double*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_CHAR )
+      {
+        assert(datasize == sizeof(char));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_min<char>(static_cast<char*>(comm->my_buffer->void_buffer[i]), static_cast<char*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_LONG )
+      {
+        assert(datasize == sizeof(long));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_min<long>(static_cast<long*>(comm->my_buffer->void_buffer[i]), static_cast<long*>(recvbuf), count);
+      }
+
+      else if(datatype == MPI_UNSIGNED_LONG )
+      {
+        assert(datasize == sizeof(unsigned long));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_min<unsigned long>(static_cast<unsigned long*>(comm->my_buffer->void_buffer[i]), static_cast<unsigned long*>(recvbuf), count);    
+      }
+
+      else if(datatype == MPI_LONG_LONG_INT )
+      {
+        assert(datasize == sizeof(long long int));
+        for(int i=1; i<ep_rank_loc+1; i++)
+          reduce_min<long long int>(static_cast<long long int*>(comm->my_buffer->void_buffer[i]), static_cast<long long int*>(recvbuf), count);    
+      }
+
+      else 
+      {
+        printf("datatype Error in ep_scan : INT, FLOAT, DOUBLE, CHAR, LONG, UNSIGNED_LONG, LONG_LONG_INT\n");
+        MPI_Abort(comm, 0);
+      }
+
+    }
+    
+    else
+    {
+      printf("op type Error in ep_scan : MPI_MAX, MPI_MIN, MPI_SUM\n");
+      MPI_Abort(comm, 0);
+    }
+
+    MPI_Barrier_local(comm);
+
+  }
+
+
+  int MPI_Scan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Scan(sendbuf, recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Scan_intercomm(sendbuf, recvbuf, count, datatype, op, comm);
+    
+    valid_type(datatype);
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+    
+    void* tmp_sendbuf;
+    tmp_sendbuf = new void*[datasize * count];
+
+    int my_src = 0;
+    int my_dst = ep_rank;
+
+    std::vector<int> my_map(mpi_size, 0);
+
+    for(int i=0; i<comm->ep_rank_map->size(); i++) my_map[comm->ep_rank_map->at(i).second]++;
+
+    for(int i=0; i<mpi_rank; i++) my_src += my_map[i];
+    my_src += ep_rank_loc;
+
+     
+    for(int i=0; i<mpi_size; i++)
+    {
+      if(my_dst < my_map[i])
+      {
+        my_dst = get_ep_rank(comm, my_dst, i); 
+        break;
+      }
+      else
+        my_dst -= my_map[i];
+    }
+
+    //printf("ID = %d : send to %d, recv from %d\n", ep_rank, my_dst, my_src);
+    MPI_Barrier(comm);
+
+    if(my_dst == ep_rank && my_src == ep_rank) memcpy(tmp_sendbuf, sendbuf, datasize*count);
+
+    if(ep_rank != my_dst) 
+    {
+      MPI_Request request[2];
+      MPI_Status status[2];
+
+      MPI_Isend(sendbuf,     count, datatype, my_dst, my_dst,  comm, &request[0]);
+    
+      MPI_Irecv(tmp_sendbuf, count, datatype, my_src, ep_rank, comm, &request[1]);
+    
+      MPI_Waitall(2, request, status);
+    }
+    
+
+    void* tmp_recvbuf;
+    tmp_recvbuf = new void*[datasize * count];    
+
+    MPI_Reduce_local(tmp_sendbuf, tmp_recvbuf, count, datatype, op, 0, comm);
+
+    if(ep_rank_loc == 0)
+      ::MPI_Exscan(MPI_IN_PLACE, tmp_recvbuf, count, to_mpi_type(datatype), to_mpi_op(op), to_mpi_comm(comm->mpi_comm));
+
+    //printf(" ID=%d : %d  %d \n", ep_rank, static_cast<int*>(tmp_recvbuf)[0], static_cast<int*>(tmp_recvbuf)[1]);
+    
+    MPI_Scan_local(tmp_sendbuf, tmp_recvbuf, count, datatype, op, comm);
+
+    // printf(" ID=%d : after local tmp_sendbuf = %d %d ; tmp_recvbuf = %d  %d \n", ep_rank, static_cast<int*>(tmp_sendbuf)[0], static_cast<int*>(tmp_sendbuf)[1], static_cast<int*>(tmp_recvbuf)[0], static_cast<int*>(tmp_recvbuf)[1]);
+
+
+
+    if(ep_rank != my_src) 
+    {
+      MPI_Request request[2];
+      MPI_Status status[2];
+
+      MPI_Isend(tmp_recvbuf, count, datatype, my_src, my_src,  comm, &request[0]);
+    
+      MPI_Irecv(recvbuf,     count, datatype, my_dst, ep_rank, comm, &request[1]);
+    
+      MPI_Waitall(2, request, status);
+    }
+
+    else memcpy(recvbuf, tmp_recvbuf, datasize*count);
+    
+
+    delete[] tmp_sendbuf;
+    delete[] tmp_recvbuf;
+
+  }
+
+  int MPI_Scan_intercomm(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+  {
+    printf("MPI_Scan_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scatter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scatter.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scatter.cpp	(revision 1651)
@@ -0,0 +1,135 @@
+#ifdef _usingEP
+/*!
+   \file ep_gather.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Scatter
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  int MPI_Scatter_local(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int local_root, MPI_Comm comm)
+  {
+    assert(valid_type(sendtype) && valid_type(recvtype));
+    assert(recvcount == sendcount);
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(sendtype), &lb, &datasize);
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+
+
+    if(ep_rank_loc == local_root)
+      comm->my_buffer->void_buffer[local_root] = const_cast<void*>(sendbuf);
+
+    MPI_Barrier_local(comm);
+
+    #pragma omp critical (_scatter)      
+    memcpy(recvbuf, comm->my_buffer->void_buffer[local_root]+datasize*ep_rank_loc*sendcount, datasize * recvcount);
+    
+
+    MPI_Barrier_local(comm);
+  }
+
+  int MPI_Scatter(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Scatter(sendbuf, sendcount, to_mpi_type(sendtype), recvbuf, recvcount, to_mpi_type(recvtype), root, to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Scatter_intercomm(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
+   
+    assert(sendcount == recvcount);
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    int root_mpi_rank = comm->ep_rank_map->at(root).second;
+    int root_ep_loc = comm->ep_rank_map->at(root).first;
+
+    bool is_master = (ep_rank_loc==0 && mpi_rank != root_mpi_rank ) || ep_rank == root;
+    bool is_root = ep_rank == root;
+
+    MPI_Datatype datatype = sendtype;
+    int count = sendcount;
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+    
+    void *tmp_sendbuf;
+    if(is_root) tmp_sendbuf = new void*[ep_size * count * datasize];
+
+    // reorder tmp_sendbuf
+    std::vector<int>local_ranks(num_ep);
+    std::vector<int>ranks(ep_size);
+
+    if(mpi_rank == root_mpi_rank) MPI_Gather_local(&ep_rank, 1, MPI_INT, local_ranks.data(), root_ep_loc, comm);
+    else                          MPI_Gather_local(&ep_rank, 1, MPI_INT, local_ranks.data(), 0, comm);
+
+
+    std::vector<int> recvcounts(mpi_size, 0);
+    std::vector<int> displs(mpi_size, 0);
+
+
+    if(is_master)
+    {
+      for(int i=0; i<ep_size; i++)
+      {
+        recvcounts[comm->ep_rank_map->at(i).second]++;
+      }
+
+      for(int i=1; i<mpi_size; i++)
+        displs[i] = displs[i-1] + recvcounts[i-1];
+
+      ::MPI_Gatherv(local_ranks.data(), num_ep, to_mpi_type(MPI_INT), ranks.data(), recvcounts.data(), displs.data(), to_mpi_type(MPI_INT), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+    }
+
+
+    if(is_root)
+    for(int i=0; i<ep_size; i++)
+    {
+      memcpy(tmp_sendbuf + i*datasize*count, sendbuf + ranks[i]*datasize*count, count*datasize);
+    }
+
+    // MPI_Scatterv from root to masters
+    void* local_recvbuf;
+    if(is_master) local_recvbuf = new void*[datasize * num_ep * count];
+
+
+    if(is_master)
+    {
+      int local_sendcount = num_ep * count;
+      ::MPI_Gather(&local_sendcount, 1, to_mpi_type(MPI_INT), recvcounts.data(), 1, to_mpi_type(MPI_INT), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+      
+      if(is_root) for(int i=1; i<mpi_size; i++) displs[i] = displs[i-1] + recvcounts[i-1];
+
+      ::MPI_Scatterv(tmp_sendbuf, recvcounts.data(), displs.data(), to_mpi_type(sendtype), local_recvbuf, num_ep*count, to_mpi_type(recvtype), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+
+    }
+
+    if(mpi_rank == root_mpi_rank) MPI_Scatter_local(local_recvbuf, count, sendtype, recvbuf, recvcount, recvtype, root_ep_loc, comm);
+    else                          MPI_Scatter_local(local_recvbuf, count, sendtype, recvbuf, recvcount, recvtype, 0, comm);
+
+    if(is_root)   delete[] tmp_sendbuf;
+    if(is_master) delete[] local_recvbuf;
+  }
+
+
+  int MPI_Scatter_intercomm(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+    printf("MPI_Scatter_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scatterv.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scatterv.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_scatterv.cpp	(revision 1651)
@@ -0,0 +1,156 @@
+#ifdef _usingEP
+/*!
+   \file ep_gather.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI collective function: MPI_Scatterv
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  int MPI_Scatterv_local(const void *sendbuf, const int sendcounts[], const int displs[], MPI_Datatype sendtype, void *recvbuf, int recvcount,
+                   MPI_Datatype recvtype, int local_root, MPI_Comm comm)
+  {
+
+    assert(valid_type(sendtype) && valid_type(recvtype));
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(sendtype), &lb, &datasize);
+
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+
+    assert(recvcount == sendcounts[ep_rank_loc]);
+
+    if(ep_rank_loc == local_root)
+      comm->my_buffer->void_buffer[local_root] = const_cast<void*>(sendbuf);
+
+    MPI_Barrier_local(comm);
+
+    #pragma omp critical (_scatterv)      
+    memcpy(recvbuf, comm->my_buffer->void_buffer[local_root]+datasize*displs[ep_rank_loc], datasize * recvcount);
+    
+
+    MPI_Barrier_local(comm);
+  }
+
+  int MPI_Scatterv(const void *sendbuf, const int sendcounts[], const int displs[], MPI_Datatype sendtype, void *recvbuf, int recvcount,
+                   MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+    if(!comm->is_ep) return ::MPI_Scatterv(sendbuf, sendcounts, displs, to_mpi_type(sendtype), recvbuf, recvcount, to_mpi_type(recvtype), root, to_mpi_comm(comm->mpi_comm));
+    if(comm->is_intercomm) return MPI_Scatterv_intercomm(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
+   
+    assert(sendtype == recvtype);
+
+    int ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    int ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    int ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    int num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    int mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    int root_mpi_rank = comm->ep_rank_map->at(root).second;
+    int root_ep_loc = comm->ep_rank_map->at(root).first;
+
+    bool is_master = (ep_rank_loc==0 && mpi_rank != root_mpi_rank ) || ep_rank == root;
+    bool is_root = ep_rank == root;
+
+    MPI_Datatype datatype = sendtype;
+    int count = recvcount;
+
+    ::MPI_Aint datasize, lb;
+    ::MPI_Type_get_extent(to_mpi_type(datatype), &lb, &datasize);
+    
+    void *tmp_sendbuf;
+    if(is_root) tmp_sendbuf = new void*[ep_size * count * datasize];
+
+    // reorder tmp_sendbuf
+    std::vector<int>local_ranks(num_ep);
+    std::vector<int>ranks(ep_size);
+
+    if(mpi_rank == root_mpi_rank) MPI_Gather_local(&ep_rank, 1, MPI_INT, local_ranks.data(), root_ep_loc, comm);
+    else                          MPI_Gather_local(&ep_rank, 1, MPI_INT, local_ranks.data(), 0, comm);
+
+
+    std::vector<int> recvcounts(mpi_size, 0);
+    std::vector<int> my_displs(mpi_size, 0);
+
+
+    if(is_master)
+    {
+      for(int i=0; i<ep_size; i++)
+      {
+        recvcounts[comm->ep_rank_map->at(i).second]++;
+      }
+
+      for(int i=1; i<mpi_size; i++)
+        my_displs[i] = my_displs[i-1] + recvcounts[i-1];
+
+      ::MPI_Gatherv(local_ranks.data(), num_ep, to_mpi_type(MPI_INT), ranks.data(), recvcounts.data(), my_displs.data(), to_mpi_type(MPI_INT), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+    }
+
+
+    if(is_root)
+    {
+      int local_displs = 0;
+      for(int i=0; i<ep_size; i++)
+      {
+        memcpy(tmp_sendbuf+local_displs, sendbuf + displs[ranks[i]]*datasize, sendcounts[ranks[i]]*datasize);
+        local_displs += sendcounts[ranks[i]]*datasize;
+      }
+    }
+
+    // MPI_Scatterv from root to masters
+  
+    void* local_sendbuf;
+    int local_sendcount;
+    if(mpi_rank == root_mpi_rank) MPI_Reduce_local(&recvcount, &local_sendcount, 1, MPI_INT, MPI_SUM, root_ep_loc, comm);
+    else                          MPI_Reduce_local(&recvcount, &local_sendcount, 1, MPI_INT, MPI_SUM, 0, comm);
+
+    if(is_master) 
+    {
+      local_sendbuf = new void*[datasize * local_sendcount];
+ 
+      ::MPI_Gather(&local_sendcount, 1, to_mpi_type(MPI_INT), recvcounts.data(), 1, to_mpi_type(MPI_INT), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+
+      if(is_root) for(int i=1; i<mpi_size; i++) my_displs[i] = my_displs[i-1] + recvcounts[i-1];
+
+      ::MPI_Scatterv(tmp_sendbuf, recvcounts.data(), my_displs.data(), to_mpi_type(sendtype), local_sendbuf, num_ep*count, to_mpi_type(recvtype), root_mpi_rank, to_mpi_comm(comm->mpi_comm));
+    }
+
+    std::vector<int>local_sendcounts(num_ep, 0);
+    std::vector<int>local_displs(num_ep, 0);
+
+    MPI_Gather_local(&recvcount, 1, MPI_INT, local_sendcounts.data(), 0, comm);
+    MPI_Bcast_local(local_sendcounts.data(), num_ep, MPI_INT, 0, comm);
+    for(int i=1; i<num_ep; i++)
+      local_displs[i] = local_displs[i-1] + local_sendcounts[i-1];
+    
+
+    if(mpi_rank == root_mpi_rank) MPI_Scatterv_local(local_sendbuf, local_sendcounts.data(), local_displs.data(), sendtype, recvbuf, recvcount, recvtype, root_ep_loc, comm);
+    else                          MPI_Scatterv_local(local_sendbuf, local_sendcounts.data(), local_displs.data(), sendtype, recvbuf, recvcount, recvtype, 0, comm);
+
+
+    if(is_root) delete[] tmp_sendbuf;
+    if(is_master) delete[] local_sendbuf;
+  }
+
+
+  int MPI_Scatterv_intercomm(const void *sendbuf, const int sendcounts[], const int displs[], MPI_Datatype sendtype, void *recvbuf, int recvcount,
+                   MPI_Datatype recvtype, int root, MPI_Comm comm)
+  {
+    printf("MPI_Scatterv_intercomm not yet implemented\n");
+    MPI_Abort(comm, 0);
+  }
+
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_send.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_send.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_send.cpp	(revision 1651)
@@ -0,0 +1,181 @@
+#ifdef _usingEP
+/*!
+   \file ep_send.hpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI send functions: MPI_Send, MPI_Ssend, MPI_Isend, MPI_Issend
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+
+namespace ep_lib 
+{
+  
+  int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
+  {
+    if(comm->is_intercomm) dest = comm->inter_rank_map->at(dest);
+    
+    Debug("\nMPI_Send with EP\n");
+    
+    int ep_src_loc  = comm->ep_comm_ptr->size_rank_info[1].first;
+    int ep_dest_loc = comm->ep_comm_ptr->comm_list[0]->ep_rank_map->at(dest).first;
+    int mpi_tag     = tag_combine(tag, ep_src_loc, ep_dest_loc);
+    int mpi_dest    = comm->ep_comm_ptr->comm_list[0]->ep_rank_map->at(dest).second;
+
+    //printf("proc %d send to proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, dest);
+
+
+
+    return ::MPI_Send(buf, count, to_mpi_type(datatype), mpi_dest, mpi_tag, to_mpi_comm(comm->mpi_comm));
+  }
+
+
+
+
+  int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
+  {
+    if(comm->is_intercomm) dest = comm->inter_rank_map->at(dest);
+
+    Debug("\nMPI_Isend with EP\n");
+   
+    int src_rank;
+    MPI_Comm_rank(comm, &src_rank);
+    
+    *request = new ep_request;
+    //printf("MPI_Isend : *request = new ep_request => *request = %p\n", *request);
+
+    (*request)->mpi_request = new ::MPI_Request;
+    //printf("MPI_Isend : (*request)->mpi_request = new ::MPI_Request => (*request)->mpi_request = %p\n", (*request)->mpi_request);
+
+
+    int ep_src_loc  = comm->ep_comm_ptr->size_rank_info[1].first;
+    int ep_dest_loc = comm->ep_comm_ptr->comm_list[0]->ep_rank_map->at(dest).first;
+    int mpi_tag     = tag_combine(tag, ep_src_loc, ep_dest_loc);
+    int mpi_dest    = comm->ep_comm_ptr->comm_list[0]->ep_rank_map->at(dest).second;
+
+    //printf("proc %d send to proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, dest);
+    return ::MPI_Isend(buf, count, to_mpi_type(datatype), mpi_dest, mpi_tag, to_mpi_comm(comm->mpi_comm), to_mpi_request_ptr(*request));
+  }
+
+
+
+
+  int MPI_Issend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
+  {
+ 
+    if(comm->is_intercomm) dest = comm->inter_rank_map->at(dest);
+
+    Debug("\nMPI_Isend with EP\n");
+   
+    int src_rank;
+    MPI_Comm_rank(comm, &src_rank);
+    
+    *request = new ep_request;
+    //printf("MPI_Issend : *request = new ep_request => *request = %p\n", *request);
+
+    (*request)->mpi_request = new ::MPI_Request;
+    //printf("MPI_Issend : (*request)->mpi_request = new ::MPI_Request => (*request)->mpi_request = %p\n", (*request)->mpi_request);
+
+
+    int ep_src_loc  = comm->ep_comm_ptr->size_rank_info[1].first;
+    int ep_dest_loc = comm->ep_comm_ptr->comm_list[0]->ep_rank_map->at(dest).first;
+    int mpi_tag     = tag_combine(tag, ep_src_loc, ep_dest_loc);
+    int mpi_dest    = comm->ep_comm_ptr->comm_list[0]->ep_rank_map->at(dest).second;
+
+    //printf("proc %d send to proc %d\n", comm->ep_comm_ptr->size_rank_info[0].first, dest);
+    return ::MPI_Issend(buf, count, to_mpi_type(datatype), mpi_dest, mpi_tag, to_mpi_comm(comm->mpi_comm), to_mpi_request_ptr(*request));
+  }
+  
+
+
+  int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, 
+                         void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag,
+                   MPI_Comm comm, MPI_Status *status)
+  {
+    int mpi_dest = comm->ep_rank_map->at(dest).second;
+    int mpi_src = comm->ep_rank_map->at(source).second;
+    int rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    int mpi_sendtag = tag_combine(sendtag, rank_loc, comm->ep_rank_map->at(dest).first);
+    int mpi_recvtag = tag_combine(sendtag, comm->ep_rank_map->at(source).first, rank_loc);
+
+    status->mpi_status = new ::MPI_Status;
+    //printf("MPI_Sendrecv : status->mpi_status = new ::MPI_Status => status->mpi_status = %p\n", status->mpi_status);
+    
+    return ::MPI_Sendrecv(sendbuf, sendcount, to_mpi_type(sendtype), mpi_dest, mpi_sendtag, recvbuf, recvcount, to_mpi_type(recvtype), mpi_src, mpi_recvtag, to_mpi_comm(comm->mpi_comm), to_mpi_status_ptr(*status));
+  }
+
+
+
+  int MPI_Send_mpi(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
+  {
+    Debug("\nMPI_Send with MPI\n");
+    return ::MPI_Send(buf, count, to_mpi_type(datatype), dest, tag, to_mpi_comm(comm->mpi_comm));
+  }
+ 
+  
+  int MPI_Ssend_mpi(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
+  {
+    Debug("\nMPI_Ssend with MPI\n");
+    return ::MPI_Ssend(buf, count, to_mpi_type(datatype), dest, tag, to_mpi_comm(comm->mpi_comm));
+  }
+  
+
+  int MPI_Isend_mpi(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
+  {
+    Debug("\nMPI_Isend with MPI\n");
+    
+    int src_rank;
+    MPI_Comm_rank(comm, &src_rank);
+    
+    *request = new ep_request;
+    memcheck("new "<< *request <<" : in ep_lib::MPI_Isend_mpi, *request = new ep_request");
+
+    (*request)->mpi_request = new ::MPI_Request;
+    memcheck("new "<< (*request)->mpi_request <<" : in ep_lib::MPI_Isend_mpi, (*request)->mpi_request = new ::MPI_Request");
+      
+    (*request)->ep_src = src_rank;
+    (*request)->ep_tag = tag;
+    (*request)->ep_datatype = datatype;
+    (*request)->type = 1;
+    (*request)->comm = comm;
+    
+    return ::MPI_Isend(buf, count, to_mpi_type(datatype), dest, tag, to_mpi_comm(comm->mpi_comm), to_mpi_request_ptr(*request));
+  }
+  
+  
+
+
+  int MPI_Issend_mpi(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
+  {
+    Debug("\nMPI_Issend with MPI\n");
+    
+    int src_rank;
+    MPI_Comm_rank(comm, &src_rank);
+    
+    *request = new ep_request;
+    memcheck("new "<< *request <<" : in ep_lib::MPI_Issend_mpi, *request = new ep_request");
+
+    (*request)->mpi_request = new ::MPI_Request;
+    memcheck("new "<< (*request)->mpi_request <<" : in ep_lib::MPI_Issend_mpi, (*request)->mpi_request = new ::MPI_Request");
+      
+    (*request)->ep_src = src_rank;
+    (*request)->ep_tag = tag;
+    (*request)->ep_datatype = datatype;
+    (*request)->type = 1;
+    (*request)->comm = comm;
+    
+    return ::MPI_Issend(buf, count, to_mpi_type(datatype), dest, tag, to_mpi_comm(comm->mpi_comm), to_mpi_request_ptr(*request));
+  }
+
+
+}
+#endif
+
+
+
+
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_size.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_size.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_size.cpp	(revision 1651)
@@ -0,0 +1,45 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+namespace ep_lib
+{
+
+  int MPI_Comm_size(MPI_Comm comm, int* size)
+  {
+    if(comm->is_ep)
+    {
+      Debug("MPI_Comm_size with EP");
+      return *size = comm->ep_comm_ptr->size_rank_info[0].second;
+    }
+
+    return MPI_Comm_size_mpi(comm, size);
+  }
+
+  int MPI_Comm_remote_size(MPI_Comm comm, int *size)
+  {
+    if(comm->is_ep)
+    {
+      return *size = comm->is_intercomm? comm->inter_rank_map->size() : 0;
+    }
+    return MPI_Comm_remote_size_mpi(comm, size);
+  }
+
+
+  int MPI_Comm_size_mpi(MPI_Comm comm, int* size)
+  {
+    Debug("MPI_Comm_size with MPI");
+    return ::MPI_Comm_size(to_mpi_comm(comm->mpi_comm), size);
+  }
+
+  int MPI_Comm_remote_size_mpi(MPI_Comm comm, int *size)
+  {
+    Debug("MPI_Comm_remote_size with MPI");
+    return ::MPI_Comm_remote_size(to_mpi_comm(comm->mpi_comm), size);
+  }
+
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_split.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_split.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_split.cpp	(revision 1651)
@@ -0,0 +1,324 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+namespace ep_lib
+{
+
+  void vec_simplify(std::vector<int> *in_vector, std::vector<int> *out_vector)
+  {
+    int found=false;
+    for(std::vector<int>::iterator it_in = in_vector->begin() ; it_in != in_vector->end(); ++it_in)
+    {
+      for(std::vector<int>::iterator it = out_vector->begin() ; it != out_vector->end(); ++it)
+      {
+        if(*it_in == *it)
+        {
+          found=true;
+          break;
+        }
+        else found=false;
+      }
+      if(found == false)
+      {
+        out_vector->push_back(*it_in);
+      }
+    }
+  }
+
+
+
+  int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)
+  {
+    int ep_rank, ep_rank_loc, mpi_rank;
+    int ep_size, num_ep, mpi_size;
+
+    ep_rank = comm->ep_comm_ptr->size_rank_info[0].first;
+    ep_rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    mpi_rank = comm->ep_comm_ptr->size_rank_info[2].first;
+    ep_size = comm->ep_comm_ptr->size_rank_info[0].second;
+    num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    mpi_size = comm->ep_comm_ptr->size_rank_info[2].second;
+
+    int num_color = 0;
+
+    int color_index;
+
+    vector<int> matched_number;
+    vector<int> matched_number_loc;
+    
+    vector<int> all_color(ep_size);
+    vector<int> all_color_loc(num_ep);
+
+    MPI_Allgather(&color, 1, MPI_INT, all_color.data(), 1, MPI_INT, comm);
+    MPI_Allgather_local(&color, 1, MPI_INT, all_color_loc.data(), comm);
+
+    list<int> color_list(all_color.begin(), all_color.end());
+    list<int> color_list_loc(all_color_loc.begin(), all_color_loc.end());
+
+    vector<int> all_color_simplified;
+    vec_simplify(&all_color, &all_color_simplified);
+    int number_of_color;
+    for(int i=0; i<all_color_simplified.size(); i++)
+    {
+      if(color == all_color_simplified[i])
+      {
+        number_of_color = i;
+        break;
+      }
+    }
+
+    matched_number.resize(all_color_simplified.size(), 0);
+    matched_number_loc.resize(all_color_simplified.size(), 0);
+
+
+    while(!color_list.empty())
+    {
+      int target_color = color_list.front();
+      for(list<int>::iterator it = color_list.begin(); it != color_list.end(); ++it)
+      {
+        if(*it == target_color)
+        {
+          matched_number[num_color]++;
+        }
+      }
+      for(list<int>::iterator it = color_list_loc.begin(); it != color_list_loc.end(); ++it)
+      {
+        if(*it == target_color)
+        {
+          matched_number_loc[num_color]++;
+        }
+      }
+      color_list.remove(target_color);
+      color_list_loc.remove(target_color);
+      num_color++;
+    }
+        
+
+    vector<int> all_key(ep_size);
+    vector<int> all_key_loc(num_ep);
+    
+    vector<int> colored_key[num_color];
+    vector<int> colored_key_loc[num_color];
+    
+
+    MPI_Allgather(&key, 1, MPI_INT, all_key.data(),1, MPI_INT, comm);
+    MPI_Allgather_local(&key, 1, MPI_INT, all_key_loc.data(), comm);
+    
+    vector<int> all_ep_rank(ep_size);
+    vector<int> all_ep_rank_loc(num_ep);
+    
+    vector<int> colored_ep_rank[num_color];
+    vector<int> colored_ep_rank_loc[num_color];
+    
+    MPI_Allgather(&ep_rank, 1, MPI_INT, all_ep_rank.data(),1, MPI_INT, comm);
+    MPI_Allgather_local(&ep_rank, 1, MPI_INT, all_ep_rank_loc.data(), comm);
+
+    for(int i=0; i<num_ep; i++)
+    {
+      for(int j = 0; j<num_color; j++)
+      {
+        if(all_color_loc[i] == all_color_simplified[j])
+        {
+          colored_key_loc[j].push_back(all_key_loc[i]);
+          colored_ep_rank_loc[j].push_back(all_ep_rank_loc[i]);
+        }
+      }
+    }
+    
+    for(int i=0; i<ep_size; i++)
+    {
+      for(int j = 0; j<num_color; j++)
+      {
+        if(all_color[i] == all_color_simplified[j])
+        {
+          colored_key[j].push_back(all_key[i]);
+          colored_ep_rank[j].push_back(all_ep_rank[i]);
+        }
+      }
+    }
+    
+    int my_offset=0;
+    for(int i=0; i<colored_key[number_of_color].size(); i++)
+    {
+      if(key == colored_key[number_of_color][i])
+      {
+        if(ep_rank != colored_ep_rank[number_of_color][i])
+        {
+          my_offset++;
+        }
+        else
+          break;
+      }
+    }
+    
+    int my_offset_loc=0;
+    for(int i=0; i<colored_key_loc[number_of_color].size(); i++)
+    {
+      if(key == colored_key_loc[number_of_color][i])
+      {
+        if(ep_rank != colored_ep_rank_loc[number_of_color][i])
+        {
+          my_offset_loc++;
+        }
+        else
+          break;
+      }
+    }
+    
+    
+    
+    for(int i=0; i<num_color; i++)
+    {
+      std::sort(colored_key[i].begin(), colored_key[i].end());
+      std::sort(colored_key_loc[i].begin(), colored_key_loc[i].end());
+    }
+
+    int new_ep_rank;
+    
+    for(int i=0; i<colored_key[number_of_color].size(); i++)
+    {
+      if(key == colored_key[number_of_color][i])
+      {
+        new_ep_rank = i+my_offset;
+        break;
+      }
+    }
+    
+    int new_ep_rank_loc;
+    
+    for(int i=0; i<colored_key_loc[number_of_color].size(); i++)
+    {
+      if(key == colored_key_loc[number_of_color][i])
+      {
+        new_ep_rank_loc = i+my_offset_loc;
+        break;
+      }
+    }
+
+#ifdef _showinfo
+    printf("ep_rank = %d, color = %d, key = %d, new_ep_rank = %d, new_ep_rank_loc = %d\n", ep_rank, color, key, new_ep_rank, new_ep_rank_loc);
+#endif
+
+    MPI_Barrier(comm);
+    MPI_Barrier(comm);
+    MPI_Barrier(comm);
+    
+
+    ::MPI_Comm **split_mpi_comm;
+    split_mpi_comm = new ::MPI_Comm* [num_color];
+    for(int ii=0; ii<num_color; ii++)
+      split_mpi_comm[ii] = new ::MPI_Comm;
+
+    for(int j=0; j<num_color; j++)
+    {
+      if(ep_rank_loc == 0)
+      {
+        int master_color = 1;
+        if(matched_number_loc[j] == 0) master_color = MPI_UNDEFINED;
+
+        ::MPI_Comm_split(to_mpi_comm(comm->mpi_comm), master_color, mpi_rank, split_mpi_comm[j]);
+        
+        comm->ep_comm_ptr->comm_list[0]->mpi_bridge = split_mpi_comm[j];
+      }
+      
+      MPI_Barrier_local(comm);
+      
+      int num_new_ep = 0;
+
+      if(new_ep_rank_loc == 0 && color == all_color_simplified[j])
+      {
+        num_new_ep = matched_number_loc[j];
+        MPI_Info info;
+        MPI_Comm *ep_comm;
+
+        MPI_Comm_create_endpoints(comm->ep_comm_ptr->comm_list[0]->mpi_bridge, num_new_ep, info, ep_comm);
+
+        comm->ep_comm_ptr->comm_list[0]->mem_bridge = ep_comm;
+        
+        (*ep_comm)->ep_rank_map->clear();
+        
+        memcheck("in MPI_Split ep_rank="<< ep_rank <<" : *ep_comm = "<< *ep_comm);
+      }
+      
+      MPI_Barrier_local(comm);
+      
+      if(color == all_color_simplified[j])
+      {
+        *newcomm = comm->ep_comm_ptr->comm_list[0]->mem_bridge[new_ep_rank_loc];
+        memcheck("in MPI_Split ep_rank="<< ep_rank <<" : *newcomm = "<< *newcomm);
+        
+        (*newcomm)->ep_comm_ptr->size_rank_info[0].first = new_ep_rank;
+        (*newcomm)->ep_comm_ptr->size_rank_info[1].first = new_ep_rank_loc;
+        
+        int my_triple[3];
+        vector<int> my_triple_vector;
+        vector<int> my_triple_vector_recv;
+        my_triple[0] = new_ep_rank;
+        my_triple[1] = new_ep_rank_loc;
+        my_triple[2] = (*newcomm)->ep_comm_ptr->size_rank_info[2].first; // new_mpi_rank
+        
+        int new_ep_size = (*newcomm)->ep_comm_ptr->size_rank_info[0].second;
+        int new_num_ep  = (*newcomm)->ep_comm_ptr->size_rank_info[1].second;
+        
+        int new_mpi_size = (*newcomm)->ep_comm_ptr->size_rank_info[2].second;
+        
+        if(new_ep_rank_loc == 0) my_triple_vector.resize(3*new_ep_size);
+        if(new_ep_rank_loc == 0) my_triple_vector_recv.resize(3*new_ep_size);
+        
+        MPI_Gather_local(my_triple, 3, MPI_INT, my_triple_vector.data(), 0, *newcomm);
+        
+        if(new_ep_rank_loc == 0)
+        {
+          int *recvcounts = new int[new_mpi_size];
+          int *displs = new int[new_mpi_size];
+          int new_num_epx3 = new_num_ep * 3;
+          ::MPI_Allgather(&new_num_epx3, 1, to_mpi_type(MPI_INT), recvcounts, 1, to_mpi_type(MPI_INT), to_mpi_comm((*newcomm)->mpi_comm));
+          displs[0]=0;
+          for(int i=1; i<new_mpi_size; i++)
+            displs[i] = displs[i-1] + recvcounts[i-1];
+             
+          ::MPI_Allgatherv(my_triple_vector.data(), 3*new_num_ep, to_mpi_type(MPI_INT), my_triple_vector_recv.data(), recvcounts, displs, to_mpi_type(MPI_INT), to_mpi_comm((*newcomm)->mpi_comm));
+          
+          for(int i=0; i<new_ep_size; i++)
+          {
+            //(*newcomm)->ep_comm_ptr->comm_list[0]->ep_rank_map->insert(std::pair< int, std::pair<int,int> >(my_triple_vector_recv[3*i], my_triple_vector_recv[3*i+1], my_triple_vector_recv[3*i+2]));
+            (*((*newcomm)->ep_comm_ptr->comm_list[0]->ep_rank_map)) [ my_triple_vector_recv[3*i] ] = std::make_pair(my_triple_vector_recv[3*i+1], my_triple_vector_recv[3*i+2]);
+          }
+          
+          (*newcomm)->ep_rank_map = (*newcomm)->ep_comm_ptr->comm_list[0]->ep_rank_map;
+          
+          delete recvcounts;
+          delete displs;
+        } 
+      }
+    }
+
+#ifdef _Memory_check   
+    for(int i=0; i<ep_size; i++)
+    {
+      MPI_Barrier(comm);
+      MPI_Barrier(comm);
+      if(ep_rank==i) 
+      {
+        printf("ep_rank_map for endpoint %d = \n", ep_rank);
+        for(std::map<int, std::pair<int, int> > :: iterator it = (*newcomm)->ep_rank_map->begin(); it != (*newcomm)->ep_rank_map->end(); it++)
+        {
+          printf("\t\t\t %d %d %d\n", it->first, it->second.first, it->second.second);
+        }
+        printf("\n");
+      }
+      MPI_Barrier(comm);
+      MPI_Barrier(comm);
+    }   
+#endif
+    
+    return 0;
+  }
+
+}
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_status.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_status.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_status.hpp	(revision 1651)
@@ -0,0 +1,30 @@
+#ifndef EP_STATUS_HPP_INCLUDED
+#define EP_STATUS_HPP_INCLUDED
+
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  class ep_status
+  {
+    public:
+
+      void* ep_datatype;
+      int ep_src;
+      int ep_tag;
+      void* mpi_status;
+      
+      ep_status() {}; 
+      ~ep_status() {}; 
+      ep_status(void* status);
+  };
+  
+  typedef ep_status MPI_Status;
+
+}
+
+#endif
+
+#endif // EP_STATUS_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_test.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_test.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_test.cpp	(revision 1651)
@@ -0,0 +1,164 @@
+#ifdef _usingEP
+/*!
+   \file ep_test.cpp
+   \since 2 may 2016
+
+   \brief Definitions of MPI test function: MPI_Test, MPI_Testsome, MPI_Testany, MPI_Testall
+ */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+
+namespace ep_lib {
+
+  int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)
+  {
+    ::MPI_Status mpi_status;
+    ::MPI_Test(to_mpi_request_ptr(*request), flag, &mpi_status);
+    
+    if(*flag)
+    {
+      status->mpi_status=new ::MPI_Status(mpi_status);
+      //printf("MPI_Test : delete (*request)->mpi_request => (*request)->mpi_request = %p\n", (*request)->mpi_request);
+      delete (*request)->mpi_request;
+      //printf("MPI_Test : delete *request => *request = %p\n", *request);
+      delete *request;
+    }
+  }
+
+
+  int MPI_Test2(MPI_Request *request, int *flag, MPI_Status *status)
+  {
+    Debug("MPI_Test with EP");
+    
+    if(*request==0) return *flag=true;
+    
+    if((*request)->type !=1 && (*request)->type !=2 && (*request)->type !=3) 
+    {
+      printf("MPI_Test : Error in request type\n");
+      exit(1);
+    }
+
+    if((*request)->type == 2)   // irecv message not probed
+    {
+      *flag = false;
+      return Request_Check();
+    }
+    
+    else //(*request)->type == 1 || (*request)->type == 3      // isend or imrecv
+    {
+      
+      ::MPI_Status mpi_status;
+      ::MPI_Test(to_mpi_request_ptr(*request), flag, &mpi_status);
+      
+      if(*flag) 
+      {
+
+        status->mpi_status=new ::MPI_Status(mpi_status);
+        status->ep_src = (*request)->ep_src;
+        status->ep_tag = (*request)->ep_tag;
+        status->ep_datatype = (*request)->ep_datatype;
+        
+        (*request)->state = 2;
+                
+        memcheck("delete "<< (*request)->mpi_request << " : in ep_lib::MPI_Test, delete (*request)->mpi_request");
+        delete (*request)->mpi_request;
+        delete *request;
+        *request=0;
+      }
+    }
+    
+    return Request_Check();
+  }
+
+
+  int MPI_Testall(int count, MPI_Request *array_of_requests, int *flag, MPI_Status *array_of_statuses)
+  {
+    ::MPI_Request* mpi_request = new ::MPI_Request[count];
+    ::MPI_Status* mpi_status = new ::MPI_Status[count];
+
+    for(int i=0; i<count; i++)
+    {
+      mpi_request[i] = *static_cast< ::MPI_Request*>(array_of_requests[i]->mpi_request);  
+    }
+
+    ::MPI_Testall(count, mpi_request, flag, mpi_status);
+
+    if(*flag)
+    {
+      for(int i=0; i<count; i++)
+      {
+        array_of_statuses[i].mpi_status = new ::MPI_Status(mpi_status[i]);
+      
+        //printf("MPI_Testall : delete array_of_requests[%d]->mpi_request => array_of_requests[%d]->mpi_request = %p\n", i, i, array_of_requests[i]->mpi_request);
+        delete array_of_requests[i]->mpi_request;
+        //printf("MPI_Testall : delete array_of_requests[%d] => array_of_requests[%d] = %p\n", i, i, array_of_requests[i]);
+        delete array_of_requests[i];
+      }
+    }
+    
+    delete[] mpi_request;
+    delete[] mpi_status;
+    
+    return 0;
+  }  /* end of mpi_waitall*/
+
+
+  int MPI_Testall2(int count, MPI_Request *array_of_requests, int *flag, MPI_Status *array_of_statuses)
+  {
+    Debug("MPI_Testall with EP");
+    *flag = false;
+   
+    int rank = array_of_requests[0]->comm->ep_comm_ptr->size_rank_info[0].first;
+    
+    for(int i=0; i<count; i++)
+    {
+      if(array_of_requests[i]->type == 2)
+      {
+        *flag=false;
+        return Request_Check();
+      }
+    }
+    
+    ::MPI_Request* mpi_request = new ::MPI_Request[count];
+    ::MPI_Status* mpi_status = new ::MPI_Status[count];
+
+
+    for(int i=0; i<count; i++)
+    {
+      mpi_request[i] = *static_cast< ::MPI_Request*>(array_of_requests[i]->mpi_request);
+    }
+
+    ::MPI_Testall(count, mpi_request, flag, mpi_status);
+
+    if(*flag)
+    {
+      for(int i=0; i<count; i++)
+      {
+        array_of_statuses[i].mpi_status = new ::MPI_Status(mpi_status[i]);
+        array_of_statuses[i].ep_src = array_of_requests[i]->ep_src;
+        array_of_statuses[i].ep_tag = array_of_requests[i]->ep_tag;
+        array_of_statuses[i].ep_datatype = array_of_requests[i]->ep_datatype;
+        
+        array_of_requests[i]->state = 2;
+      
+        memcheck("delete "<< array_of_requests[i]->mpi_request <<" : in ep_lib::MPI_Testall, array_of_requests["<<i<<"]->mpi_request");
+        delete array_of_requests[i]->mpi_request;
+        delete array_of_requests[i];
+        array_of_requests[i]=0;
+        
+      }
+    }
+
+    return Request_Check();
+  }
+
+
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_type.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_type.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_type.cpp	(revision 1651)
@@ -0,0 +1,45 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include <iostream>
+#include <fstream>
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+
+namespace ep_lib
+{ 
+  ep_comm::ep_comm(void* comm)
+  {
+    is_ep = false;
+    is_intercomm = false;
+    mpi_comm = static_cast< ::MPI_Comm*>(comm);
+  }
+
+  ep_info::ep_info(void* info)
+  {
+    mpi_info = static_cast< ::MPI_Info*>(info);
+  }
+
+  ep_request::ep_request(void* request)
+  {
+    mpi_request = static_cast< ::MPI_Request*>(request);
+  }
+  
+  ep_status::ep_status(void* status)
+  {
+    mpi_status = static_cast< ::MPI_Status*>(status);
+  }
+
+}
+
+
+
+
+#endif
+
+
+
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_type.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_type.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_type.hpp	(revision 1651)
@@ -0,0 +1,96 @@
+#ifndef EP_TYPE_HPP_INCLUDED
+#define EP_TYPE_HPP_INCLUDED
+
+#ifdef _usingEP
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <list>
+#include <map>
+#include <omp.h>
+#include <vector>
+#include <numeric>
+#include <bitset>
+#include <algorithm>
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef _Debug
+#define Debug(x) std::cout << x << std::endl
+#else
+#define Debug(x)
+#endif
+
+#ifdef _Memory_check
+#define memcheck(x) std::cout << x << std::endl
+#else
+#define memcheck(x)
+#endif
+
+
+#define BUFFER_SIZE 10000
+
+#include "ep_status.hpp"
+#include "ep_request.hpp"
+#include "ep_info.hpp"
+#include "ep_message.hpp"
+#include "ep_barrier.hpp"
+#include "ep_comm.hpp"
+#include "ep_window.hpp"
+
+
+
+namespace ep_lib
+{
+
+  class ep_communicator;
+  class ep_intercomm;
+
+
+  class MPI_Aint
+  {
+    public:
+
+    void* mpi_aint;
+
+    MPI_Aint() {}
+    MPI_Aint(void* aint);
+    MPI_Aint(int aint);
+    MPI_Aint operator=(int a);
+  };
+
+  class EP_Fint
+  {
+    public:
+  
+    void* mpi_fint;
+    
+    EP_Fint() {}
+    EP_Fint(void* fint);
+                                 
+  };
+ 
+  
+
+
+  static MPI_Comm *passage;
+
+  static int TAG = 40000;
+
+  static std::list<std::pair<std::pair<int, int>, MPI_Comm * > > tag_list;
+
+  static std::list< std::pair<std::pair<int, int> , std::pair<MPI_Comm * , std::pair<int, int> > > > intercomm_list;
+
+  static std::map<std::pair<int, int>, MPI_Comm >  fc_comm_map;
+
+  
+
+
+}
+
+
+#endif
+#endif // EP_TYPE_HPP_INCLUDED
+
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_wait.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_wait.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_wait.cpp	(revision 1651)
@@ -0,0 +1,156 @@
+#ifdef _usingEP
+/*!
+  \file ep_wait.cpp
+  \since 2 may 2016
+
+  \brief Definitions of MPI wait function: MPI_Wait, MPI_Waitall, MPI_Waitsome, MPI_Waitany
+  */
+
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+extern std::list< ep_lib::MPI_Request* > * EP_PendingRequests;
+#pragma omp threadprivate(EP_PendingRequests)
+
+
+
+namespace ep_lib 
+{
+  
+  int MPI_Wait(MPI_Request *request, MPI_Status *status)
+  {
+    
+    ::MPI_Status mpi_status;
+    ::MPI_Wait(to_mpi_request_ptr(*request), &mpi_status);
+
+    status->mpi_status=new ::MPI_Status(mpi_status);
+    //printf("MPI_Wait : delete (*request)->mpi_request => (*request)->mpi_request = %p\n", (*request)->mpi_request);
+    delete (*request)->mpi_request;
+    //printf("MPI_Wait : delete *request => *request = %p\n", *request);
+    delete *request;
+
+  }   /*end of mpi_wait*/
+
+
+  int MPI_Waitall(int count, MPI_Request *array_of_requests, MPI_Status *array_of_statuses)
+  {
+    ::MPI_Request* mpi_request = new ::MPI_Request[count];
+    ::MPI_Status* mpi_status = new ::MPI_Status[count];
+
+    for(int i=0; i<count; i++)
+    {
+      mpi_request[i] = *static_cast< ::MPI_Request*>(array_of_requests[i]->mpi_request);  
+    }
+
+    ::MPI_Waitall(count, mpi_request, mpi_status);
+
+    for(int i=0; i<count; i++)
+    {
+      array_of_statuses[i].mpi_status = new ::MPI_Status(mpi_status[i]);
+      
+      //printf("MPI_Waitall : delete array_of_requests[%d]->mpi_request => array_of_requests[%d]->mpi_request = %p\n", i, i, array_of_requests[i]->mpi_request);
+      delete array_of_requests[i]->mpi_request;
+      //printf("MPI_Waitall : delete array_of_requests[%d] => array_of_requests[%d] = %p\n", i, i, array_of_requests[i]);
+      delete array_of_requests[i];
+    }
+
+    delete[] mpi_request;
+    delete[] mpi_status;
+    
+    return 0;
+  }  /* end of mpi_waitall*/
+
+
+
+    int MPI_Wait2(MPI_Request *request, MPI_Status *status)
+  {
+    if((*request)->type !=1 && (*request)->type !=2 && (*request)->type !=3) 
+    {
+      printf("MPI_Wait : Error in request type\n");
+      exit(1);
+    }
+
+    while((*request)->type == 2) Request_Check();
+    
+    ::MPI_Status mpi_status;
+    
+    ::MPI_Wait(to_mpi_request_ptr(*request), &mpi_status);
+
+    status->mpi_status = new ::MPI_Status(mpi_status);
+    status->ep_src = (*request)->ep_src;
+    status->ep_tag = (*request)->ep_tag;
+    status->ep_datatype = (*request)->ep_datatype;
+    
+    (*request)->state = 2;
+
+    memcheck("delete "<< (*request)->mpi_request << " : in ep_lib::MPI_Wait, delete (*request)->mpi_request");
+
+    delete (*request)->mpi_request;
+    delete *request;
+    *request=0;
+    
+    return Request_Check();
+
+  }   /*end of mpi_wait*/
+
+
+
+  int MPI_Waitall2(int count, MPI_Request *array_of_requests, MPI_Status *array_of_statuses)
+  {
+    std::vector<int> finished(count, 0);
+
+    ::MPI_Request* mpi_request = new ::MPI_Request[count];
+    ::MPI_Status* mpi_status = new ::MPI_Status[count];
+
+    while(std::accumulate(finished.begin(), finished.end(), 0) < count)
+    {
+      
+      for(int i=0; i<count; i++)
+      {
+        if(array_of_requests[i]->type !=1 && array_of_requests[i]->type !=2 && array_of_requests[i]->type !=3) 
+        {
+          printf("Error in request type\n");
+ 
+          exit(1);
+        }
+        
+        if(array_of_requests[i]->type == 2) Request_Check(); 
+        if(array_of_requests[i]->type != 2 && finished.at(i) == 0) 
+        {
+          finished.at(i) = 1;
+          mpi_request[i] = *static_cast< ::MPI_Request*>(array_of_requests[i]->mpi_request);
+        }
+      }    
+    }
+
+    ::MPI_Waitall(count, mpi_request, mpi_status);
+
+    for(int i=0; i<count; i++)
+    {
+      array_of_statuses[i].mpi_status = new ::MPI_Status(mpi_status[i]);
+      array_of_statuses[i].ep_src = array_of_requests[i]->ep_src;
+      array_of_statuses[i].ep_tag = array_of_requests[i]->ep_tag;
+      array_of_statuses[i].ep_datatype = array_of_requests[i]->ep_datatype;
+      
+      array_of_requests[i]->state = 2;
+      
+      memcheck("delete "<< array_of_requests[i]->mpi_request <<" : in ep_lib::MPI_Waitall, array_of_requests["<<i<<"]->mpi_request");
+      delete array_of_requests[i]->mpi_request;
+      delete array_of_requests[i];
+      array_of_requests[i] = 0;
+    }
+
+    delete[] mpi_request;
+    delete[] mpi_status;
+    
+    return Request_Check();
+  }  /* end of mpi_waitall*/
+
+
+}
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_win.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_win.cpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_win.cpp	(revision 1651)
@@ -0,0 +1,183 @@
+#ifdef _usingEP
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+
+namespace ep_lib
+{
+
+
+  int MPI_Win_create(void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win)
+  {
+    int rank, rank_loc, num_ep;
+    MPI_Comm_rank(comm, &rank);
+    rank_loc = comm->ep_comm_ptr->size_rank_info[1].first;
+    num_ep = comm->ep_comm_ptr->size_rank_info[1].second;
+    
+    *win = new ep_win;
+    
+    (*win)->is_ep = comm->is_ep;
+
+    int num_ep_max;
+    MPI_Allreduce(&num_ep, &num_ep_max, 1, MPI_INT, MPI_MAX, comm);
+
+    assert(num_ep_max > 1);
+    
+    info = new ep_info;
+    
+    
+
+    if(num_ep == 1)  // server
+    {
+      for(int i=0; i<num_ep_max; i++)
+      {
+        (*win)->server_win[i] = new ::MPI_Win;
+      }
+
+      printf("Calling MPI_Win_create from server, rank = %d\n", rank);
+      for(int i=0; i<num_ep_max; i++)
+      {
+        ::MPI_Win_create(base, to_mpi_aint(size), disp_unit, to_mpi_info(info), to_mpi_comm(comm->mpi_comm), static_cast< ::MPI_Win*>((*win)->server_win[i]));
+        (*win)->comm = comm;
+      }
+    }
+    else  // client
+    {
+      (*win)->client_win = new ::MPI_Win;
+      
+      for(int i=0; i<num_ep; i++)
+      {
+        if(rank_loc == i)
+        {
+          printf("Calling MPI_Win_create from client, rank = %d\n", rank);
+          ::MPI_Win_create(base, to_mpi_aint(size), disp_unit, to_mpi_info(info), to_mpi_comm(comm->mpi_comm), static_cast< ::MPI_Win*>((*win)->client_win)); 
+          (*win)->comm = comm;
+        }
+        MPI_Barrier_local(comm);
+      }
+
+      if(num_ep_max > num_ep)
+      {
+
+        #pragma omp master
+        {
+          for(int i=0; i<num_ep_max-num_ep; i++)
+          {
+            (*win)->null_win[i] = new ::MPI_Win;
+            ::MPI_Win_create(NULL, 0, disp_unit, to_mpi_info(info), to_mpi_comm(comm->mpi_comm), static_cast< ::MPI_Win*>((*win)->null_win[i])); 
+          }  
+        }  
+      }
+
+    }
+    return 0;
+  }
+
+
+
+  int MPI_Win_free(MPI_Win *win)
+  {
+    int rank, rank_loc, num_ep;
+    
+
+    MPI_Comm_rank((*win)->comm, &rank);
+    rank_loc = (*win)->comm->ep_comm_ptr->size_rank_info[1].first;
+    num_ep = (*win)->comm->ep_comm_ptr->size_rank_info[1].second;
+    
+    
+    int num_ep_max;
+    MPI_Allreduce(&num_ep, &num_ep_max, 1, MPI_INT, MPI_MAX, (*win)->comm);
+
+    //printf("rank_loc = %d, thread_num = %d, num_ep_max = %d\n", rank_loc, omp_get_thread_num(), num_ep_max);
+
+    if(num_ep == 1)
+    {
+      printf("Calling MPI_Win_free from server, rank = %d\n", rank);
+      for(int i=0; i<num_ep_max; i++)
+      {
+        ::MPI_Win_free(static_cast< ::MPI_Win*>((*win)->server_win[i]));
+      }
+    }
+    else
+    {
+      for(int i=0; i<num_ep; i++)
+      {
+        if(rank_loc == i)
+        {
+          printf("Calling MPI_Win_free from client, rank = %d\n", rank);
+          ::MPI_Win_free(static_cast< ::MPI_Win*>((*win)->client_win)); 
+        }
+        MPI_Barrier_local((*win)->comm);
+      }
+
+
+      if(num_ep_max > num_ep)
+      {
+        #pragma omp master
+        {
+          for(int i=0; i<num_ep_max-num_ep; i++)
+          {
+            ::MPI_Win_free(static_cast< ::MPI_Win*>((*win)->null_win[i])); 
+          }  
+        }  
+      }
+
+    }
+    return 0;
+  }
+
+
+
+  int MPI_Win_fence(int assert, MPI_Win win)
+  {
+    int rank, rank_loc, num_ep;
+    
+    MPI_Comm_rank(win->comm, &rank);
+    rank_loc = win->comm->ep_comm_ptr->size_rank_info[1].first;
+    num_ep = win->comm->ep_comm_ptr->size_rank_info[1].second;
+    
+    int num_ep_max;
+    MPI_Allreduce(&num_ep, &num_ep_max, 1, MPI_INT, MPI_MAX, win->comm);
+
+    if(num_ep == 1)
+    {
+      printf("Calling MPI_Win_fence from server, rank = %d\n", rank);
+      for(int i=0; i<num_ep_max; i++)
+      {
+        ::MPI_Win_fence(assert, *static_cast< ::MPI_Win*>(win->server_win[i]));
+      }
+    }
+    else
+    {
+      for(int i=0; i<num_ep; i++)
+      {
+        if(rank_loc == i)
+        {
+          printf("Calling MPI_Win_fence from client, rank = %d\n", rank);
+          ::MPI_Win_fence(assert, *static_cast< ::MPI_Win*>(win->client_win)); 
+        }
+        MPI_Barrier_local(win->comm);
+      }
+
+
+      if(num_ep_max > num_ep)
+      {
+        #pragma omp master
+        {
+          for(int i=0; i<num_ep_max-num_ep; i++)
+          {
+            ::MPI_Win_fence(assert, *static_cast< ::MPI_Win*>(win->null_win[i])); 
+          }  
+        }  
+      }
+    }
+
+    return 0;  
+  }
+
+}
+
+
+#endif
Index: XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_window.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_window.hpp	(revision 1651)
+++ XIOS/dev/dev_trunk_omp/extern/src_ep_dev2/ep_window.hpp	(revision 1651)
@@ -0,0 +1,27 @@
+#ifndef EP_WINDOW_HPP_INCLUDED
+#define EP_WINDOW_HPP_INCLUDED
+
+#ifdef _usingEP
+
+namespace ep_lib
+{
+
+  class ep_win
+  {
+    public:
+    bool is_ep;
+    MPI_Comm comm;
+
+    void* server_win[16];
+    void* client_win;
+    void* null_win[16];
+  };
+  
+  typedef ep_win* MPI_Win;
+
+}
+
+#endif
+
+#endif // EP_WINDOW_HPP_INCLUDED
+
