Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_accumulate.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_accumulate.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_accumulate.cpp	(revision 1521)
@@ -0,0 +1,103 @@
+#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;
+    }
+  }
+
+}
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_allocate.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_allocate.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_allocate.cpp	(revision 1521)
@@ -0,0 +1,88 @@
+#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);
+    //::MPI_Alloc_mem(size.mpi_aint, MPI_INFO_NULL_STD, 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);
+    //::MPI_Alloc_mem(size, MPI_INFO_NULL_STD, 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;
+  }
+
+}
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_barrier.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_barrier.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_barrier.hpp	(revision 1521)
@@ -0,0 +1,65 @@
+#ifndef EP_BARRIER_HPP_INCLUDED
+#define EP_BARRIER_HPP_INCLUDED
+
+
+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 // EP_BARRIER_HPP_INCLUDED
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_buffer.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_buffer.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_buffer.hpp	(revision 1521)
@@ -0,0 +1,19 @@
+#ifndef EP_BUFFER_HPP_INCLUDED
+#define EP_BUFFER_HPP_INCLUDED
+
+
+namespace ep_lib
+{
+
+  struct BUFFER
+  {
+    void * void_buffer[12];
+  };
+
+
+}
+
+
+
+#endif // EP_BUFFER_HPP_INCLUDED
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_comm.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_comm.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_comm.hpp	(revision 1521)
@@ -0,0 +1,76 @@
+#ifndef EP_COMM_HPP_INCLUDED
+#define EP_COMM_HPP_INCLUDED
+
+#include "ep_message.hpp"
+#include "ep_intercomm.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::vector<std::pair< std::pair<int, int>, std::pair<int, int> > > INTERCOMM_RANK_MAP;
+typedef std::list<ep_lib::MPI_Message > Message_list;
+
+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
+
+                                      // for intercomm : = size_rank_info of local_comm
+
+
+    ep_comm **comm_list;
+
+    Message_list *message_queue;
+
+
+    int comm_label;
+
+    ep_intercomm *intercomm;
+    
+  };
+  
+
+  class ep_comm
+  {
+    public:
+
+    bool is_ep;
+    bool is_intercomm;
+
+    BUFFER     *my_buffer;
+    
+    ep_barrier *ep_barrier;
+
+    EP_RANK_MAP   *ep_rank_map;      // for intercomm : = ep_rank_map of newcomm
+    
+
+
+    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 // EP_COMM_HPP_INCLUDED
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_compare.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_compare.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_compare.cpp	(revision 1521)
@@ -0,0 +1,23 @@
+#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));
+  }
+
+}
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_fetch.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_fetch.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_fetch.cpp	(revision 1521)
@@ -0,0 +1,23 @@
+#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));
+  }
+
+}
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_get.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_get.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_get.cpp	(revision 1521)
@@ -0,0 +1,58 @@
+#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;
+    }
+  }
+
+}
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_global.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_global.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_global.hpp	(revision 1521)
@@ -0,0 +1,12 @@
+#ifndef EP_GLOBAL_HPP_INCLUDED
+#define EP_GLOBAL_HPP_INCLUDED
+
+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 // EP_GLOBAL_HPP_INCLUDED
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_info.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_info.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_info.hpp	(revision 1521)
@@ -0,0 +1,26 @@
+#ifndef EP_INFO_HPP_INCLUDED
+#define EP_INFO_HPP_INCLUDED
+
+
+namespace ep_lib
+{
+
+  class ep_info
+  {
+    public:
+
+      void* mpi_info;
+
+      ep_info(){};
+      ep_info(void* info);
+  };
+  
+  typedef ep_info* MPI_Info;
+
+
+}
+
+
+
+#endif // EP_INFO_HPP_INCLUDED
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_intercomm.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_intercomm.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_intercomm.hpp	(revision 1521)
@@ -0,0 +1,45 @@
+#ifndef EP_INTERCOMM_HPP_INCLUDED
+#define EP_INTERCOMM_HPP_INCLUDED
+
+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::map<int, std::pair< int, std::pair<int, int> > > INTERCOMM_RANK_MAP;
+
+namespace ep_lib
+{
+
+  class ep_comm;
+
+  class ep_intercomm
+  {
+    public:
+
+    void *mpi_inter_comm;
+
+    INTERCOMM_RANK_MAP *intercomm_rank_map;  // quadruple : ep_rank_in_local_comm, ep_rank_loc_in_newcomm, mpi_rank_in_new_comm, comm_label
+                                             // of remote_comm
+    
+    EP_RANK_MAP *local_rank_map;             // = ep_rank_map of local_comm
+
+
+    RANK_MAP *inter_rank_map;  
+    RANK_MAP *loc_rank_map;
+    RANK_MAP *remote_rank_map;
+
+
+    SIZE_RANK_INFO size_rank_info[3];        // size_rank_info of newcomm
+
+
+    int intercomm_tag;                       // newcomm_ep_rank_loc of ep with ep_rank_loc==0 
+                                             // used in comm_dup_intercomm
+    
+  };
+
+
+}
+
+
+
+#endif // EP_INTERCOMM_HPP_INCLUDED
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_intercomm_unique.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_intercomm_unique.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_intercomm_unique.cpp	(revision 1521)
@@ -0,0 +1,228 @@
+#include "ep_lib.hpp"
+#include <mpi.h>
+#include "ep_declaration.hpp"
+#include "ep_mpi.hpp"
+
+using namespace std;
+
+
+namespace ep_lib
+{
+
+
+  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)
+  {
+    //! mpi_size of local comm = 1
+    //! same world rank of leaders
+
+    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;
+
+
+
+    std::vector<int> rank_info[4];  //! 0->rank_in_world of local_comm,  1->rank_in_local_parent of local_comm
+                                    //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm
+
+    int rank_in_world;
+
+    int rank_in_peer_mpi[2];
+
+    ::MPI_Comm_rank(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &rank_in_world);
+
+
+    int local_num_ep = num_ep;
+    int remote_num_ep;
+    int total_num_ep;
+
+    int leader_rank_in_peer[2];
+
+    int my_position;
+    int tag_label[2];
+
+    vector<int> send_buf(4);
+    vector<int> recv_buf(4);
+
+
+    if(ep_rank == local_leader)
+    {
+      MPI_Status status;
+
+
+
+      MPI_Comm_rank(peer_comm, &leader_rank_in_peer[0]);
+
+      send_buf[0] = local_num_ep;
+      send_buf[1] = leader_rank_in_peer[0];
+
+      MPI_Request req_s, req_r;
+
+      MPI_Isend(send_buf.data(), 2, MPI_INT, remote_leader, tag, peer_comm, &req_s);
+      MPI_Irecv(recv_buf.data(), 2, MPI_INT, remote_leader, tag, peer_comm, &req_r);
+
+
+      MPI_Wait(&req_s, &status);
+      MPI_Wait(&req_r, &status);
+
+      recv_buf[2] = leader_rank_in_peer[0];
+
+    }
+
+    MPI_Bcast(recv_buf.data(), 3, MPI_INT, local_leader, local_comm);
+
+    remote_num_ep = recv_buf[0];
+    leader_rank_in_peer[1] = recv_buf[1];
+    leader_rank_in_peer[0] = recv_buf[2];
+
+    total_num_ep = local_num_ep + remote_num_ep;
+
+
+    if(leader_rank_in_peer[0] < leader_rank_in_peer[1])
+    {
+      my_position = ep_rank_loc;
+      //! LEADER create EP
+      if(ep_rank == local_leader)
+      {
+        ::MPI_Comm *mpi_dup = new ::MPI_Comm;
+        
+        ::MPI_Comm_dup(to_mpi_comm(local_comm->mpi_comm), mpi_dup);
+
+        MPI_Comm *ep_intercomm;
+        MPI_Info info;
+        MPI_Comm_create_endpoints(mpi_dup, total_num_ep, info, ep_intercomm);
+
+
+        for(int i=0; i<total_num_ep; i++)
+        {
+          ep_intercomm[i]->is_intercomm = true;
+          ep_intercomm[i]->ep_comm_ptr->intercomm = new ep_lib::ep_intercomm;
+          ep_intercomm[i]->ep_comm_ptr->intercomm->mpi_inter_comm = 0;
+
+          ep_intercomm[i]->ep_comm_ptr->comm_label = leader_rank_in_peer[0];
+        }
+
+        tag_label[0] = TAG++;
+        tag_label[1] = rank_in_world;
+
+        #pragma omp critical (write_to_tag_list)
+        tag_list.push_back(make_pair( make_pair(tag_label[0], tag_label[1]) , ep_intercomm));
+
+        MPI_Request req_s;
+        MPI_Status sta_s;
+        MPI_Isend(tag_label, 2, MPI_INT, remote_leader, tag, peer_comm, &req_s);
+
+        MPI_Wait(&req_s, &sta_s);
+
+      }
+    }
+    else
+    {
+      //! Wait for EP creation
+      my_position = remote_num_ep + ep_rank_loc;
+      if(ep_rank == local_leader)
+      {
+        MPI_Status status;
+        MPI_Request req_r;
+        MPI_Irecv(tag_label, 2, MPI_INT, remote_leader, tag, peer_comm, &req_r);
+        MPI_Wait(&req_r, &status);
+      }
+    }
+
+    MPI_Bcast(tag_label, 2, MPI_INT, local_leader, local_comm);
+
+
+
+
+    #pragma omp critical (read_from_tag_list)
+    {
+      bool found = false;
+      while(!found)
+      {
+        for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
+        {
+          if((*iter).first == make_pair(tag_label[0], tag_label[1]))
+          {
+            *newintercomm =  iter->second[my_position];
+            found = true;
+            // tag_list.erase(iter);
+            break;
+          }
+        }
+      }
+    }
+
+    MPI_Barrier_local(local_comm);
+
+    if(leader_rank_in_peer[0] < leader_rank_in_peer[1])
+    {
+      for(std::list<std::pair < std::pair<int,int>, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++)
+        {
+          if((*iter).first == make_pair(tag_label[0], tag_label[1]))
+          {
+            tag_list.erase(iter);
+            break;
+          }
+        }
+    }
+
+
+
+    int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank;
+    int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size;
+
+    intercomm_ep_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[0].first;
+    intercomm_ep_rank_loc = (*newintercomm)->ep_comm_ptr->size_rank_info[1].first;
+    intercomm_mpi_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[2].first;
+    intercomm_ep_size = (*newintercomm)->ep_comm_ptr->size_rank_info[0].second;
+    intercomm_num_ep = (*newintercomm)->ep_comm_ptr->size_rank_info[1].second;
+    intercomm_mpi_size = (*newintercomm)->ep_comm_ptr->size_rank_info[2].second;
+
+
+
+    (*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map  = new RANK_MAP;
+    (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP;
+    (*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map->resize(local_num_ep);
+    (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->resize(remote_num_ep);
+
+    (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[0] = local_comm->ep_comm_ptr->size_rank_info[0];
+    (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[1] = local_comm->ep_comm_ptr->size_rank_info[1];
+    (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[2] = local_comm->ep_comm_ptr->size_rank_info[2];
+
+
+
+    int local_rank_map_ele[2];
+    local_rank_map_ele[0] = intercomm_ep_rank;
+    local_rank_map_ele[1] = (*newintercomm)->ep_comm_ptr->comm_label;
+
+    MPI_Allgather(local_rank_map_ele, 2, MPI_INT, 
+      (*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map->data(), 2, MPI_INT, local_comm);
+
+    if(ep_rank == local_leader)
+    {
+      MPI_Status status;
+      MPI_Request req_s, req_r;
+
+      MPI_Isend((*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map->data(), 2*local_num_ep, MPI_INT, remote_leader, tag, peer_comm, &req_s);
+      MPI_Irecv((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT, remote_leader, tag, peer_comm, &req_r);
+
+
+      MPI_Wait(&req_s, &status);
+      MPI_Wait(&req_r, &status);
+
+    }
+
+    MPI_Bcast((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT, local_leader, local_comm);
+    //(*newintercomm)->ep_comm_ptr->intercomm->local_comm = (local_comm->ep_comm_ptr->comm_list[ep_rank_loc]);
+    (*newintercomm)->ep_comm_ptr->intercomm->intercomm_tag = tag;
+
+
+    return MPI_SUCCESS;
+  }
+
+}
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_intracomm.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_intracomm.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_intracomm.hpp	(revision 1521)
@@ -0,0 +1,21 @@
+#ifndef EP_LIB_INTRACOMM_HPP_INCLUDED
+#define EP_LIB_INTRACOMM_HPP_INCLUDED
+
+namespace ep_lib
+{
+
+  typedef void* MPI_Datatype;
+  typedef void* MPI_Op;
+
+
+  int MPI_Barrier_intracomm(MPI_Comm comm);
+
+  int MPI_Comm_free_intracomm(MPI_Comm* comm);
+
+  int Message_Check_intracomm(MPI_Comm comm);
+  
+  int MPI_Comm_dup_intracomm(MPI_Comm comm, MPI_Comm *newcomm);
+
+}
+
+#endif // EP_LIB_INTRACOMM_HPP_INCLUDED
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_mpi.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_mpi.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_mpi.hpp	(revision 1521)
@@ -0,0 +1,34 @@
+#ifndef EP_LIB_MPI_HPP_INCLUDED
+#define EP_LIB_MPI_HPP_INCLUDED
+
+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_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_Abort_mpi(MPI_Comm comm, int errorcode);
+}
+
+#endif // EP_LIB_MPI_HPP_INCLUDED
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_tests.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_tests.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_tests.hpp	(revision 1521)
@@ -0,0 +1,28 @@
+#ifndef EP_LIB_TESTS_HPP_INCLUDED
+#define EP_LIB_TESTS_HPP_INCLUDED
+
+#include "ep_type.hpp"
+
+namespace ep_lib
+{
+  int check_test_1(MPI_Comm comm);  
+
+  int check_test_2(MPI_Comm comm);
+
+  int check_test_3(MPI_Comm comm);
+
+  int check_test_4(MPI_Comm comm);
+
+  int check_test_bcast(MPI_Comm comm);
+
+  int check_test_gather(MPI_Comm comm);
+
+  int check_test_gatherv(MPI_Comm comm);
+
+  int check_test_allgather(MPI_Comm comm);
+
+  int check_test_allgatherv(MPI_Comm comm);
+}
+
+
+#endif // EP_LIB_TESTS_HPP_INCLUDED
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_win.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_win.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_lib_win.hpp	(revision 1521)
@@ -0,0 +1,54 @@
+#ifndef EP_LIB_WIN_HPP_INCLUDED
+#define EP_LIB_WIN_HPP_INCLUDED
+
+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 // EP_LIB_COLLECTIVE_HPP_INCLUDED
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_memory.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_memory.cpp	(revision 1520)
+++ 	(revision )
@@ -1,28 +1,0 @@
-#include "ep_lib.hpp"
-#include <mpi.h>
-#include "ep_declaration.hpp"
-
-namespace ep_lib
-{
-
-
-
-  int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr)
-  {
-    ::MPI_Alloc_mem(*(static_cast< ::MPI_Aint*>(size.mpi_aint)), *(static_cast< ::MPI_Info*>(info.mpi_info)), baseptr);
-    //::MPI_Alloc_mem(size.mpi_aint, MPI_INFO_NULL_STD, 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);
-    //::MPI_Alloc_mem(size, MPI_INFO_NULL_STD, baseptr);
-    return 0;
-  }
-
-
-
-}
-
-
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_message.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_message.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_message.hpp	(revision 1521)
@@ -0,0 +1,27 @@
+#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
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_put.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_put.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_put.cpp	(revision 1521)
@@ -0,0 +1,60 @@
+#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;
+    }
+  }
+
+}
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_request.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_request.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_request.hpp	(revision 1521)
@@ -0,0 +1,46 @@
+#ifndef EP_REQUEST_HPP_INCLUDED
+#define EP_REQUEST_HPP_INCLUDED
+
+#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
+                   
+      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 // EP_REQUEST_HPP_INCLUDED
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_status.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_status.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_status.hpp	(revision 1521)
@@ -0,0 +1,29 @@
+#ifndef EP_STATUS_HPP_INCLUDED
+#define EP_STATUS_HPP_INCLUDED
+
+
+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 // EP_STATUS_HPP_INCLUDED
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_win.cpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_win.cpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_win.cpp	(revision 1521)
@@ -0,0 +1,181 @@
+#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;  
+  }
+
+}
+
+
Index: XIOS/dev/branch_openmp/extern/src_ep_dev/ep_window.hpp
===================================================================
--- XIOS/dev/branch_openmp/extern/src_ep_dev/ep_window.hpp	(revision 1521)
+++ XIOS/dev/branch_openmp/extern/src_ep_dev/ep_window.hpp	(revision 1521)
@@ -0,0 +1,26 @@
+#ifndef EP_WINDOW_HPP_INCLUDED
+#define EP_WINDOW_HPP_INCLUDED
+
+
+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 // EP_WINDOW_HPP_INCLUDED
+
