00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011
00012
00013
00014 #ifndef _REGIONGATHERI_H_
00015 #define _REGIONGATHERI_H_
00016
00017 #ifndef _REGIONGATHER_CPP_
00018 template < > void regionGather<Real>(const LayoutData<Real>& a_local,
00019 const RegionGather& a_copier,
00020 LayoutData<Vector<GatherObject<Real> > >& a_gatherObjects);
00021 #endif
00022
00023 class GatherBuffer
00024 {
00025 public:
00026 GatherBuffer(const RegionGather::Message* a_message):message(a_message){;}
00027 bool operator < (const GatherBuffer& rhs) const
00028 {
00029 return rhs.message->operator<(*(message));
00030 }
00031
00032 const RegionGather::Message* message;
00033 char* buffer;
00034
00035 };
00036
00037
00038 template <class T>
00039 void regionGather(const LayoutData<T>& a_local,
00040 const RegionGather& a_copier,
00041 LayoutData<Vector<GatherObject<T> > >& a_gatherObjects)
00042 {
00043
00044 const BoxLayout& layout_input = a_local.boxLayout();
00045 const BoxLayout& layout_out = a_gatherObjects.boxLayout();
00046
00047 if(!(layout_input == layout_out))
00048 {
00049 a_gatherObjects.define(layout_input);
00050 }
00051
00052 DataIterator dit=a_local.dataIterator();
00053
00054 #ifdef CH_MPI
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 Vector<T> sendBuffer;
00071 Vector<T> recvBuffer;
00072 std::list<GatherBuffer> glist;
00073 int count = 0;
00074 for(dit.begin(); dit.ok(); ++dit)
00075 {
00076 const Vector<RegionGather::Message>& m = a_copier.m_messages[dit];
00077 for(int i=0; i<m.size(); ++i)
00078 {
00079 glist.push_back(&(m[i]));
00080 count++;
00081 }
00082 }
00083
00084 glist.sort();
00085
00086 sendBuffer.resize(count);
00087 recvBuffer.resize(count);
00088
00089 Vector<MPI_Request> receives;
00090 Vector<MPI_Request> sends;
00091
00092 std::list<GatherBuffer>::iterator iter;
00093 iter = glist.begin();
00094 int messageSize = 0;
00095 int plast;
00096 int index = 0;
00097 {
00098 CH_TIME("MPI_GatherSendRecv");
00099 for(int i=0; i<count; )
00100 {
00101 iter->buffer = (char*)&(recvBuffer[i]);
00102 sendBuffer[i] = a_local[iter->message->srcIndex];
00103 plast = iter->message->procID;
00104 ++messageSize;
00105 ++i;
00106 ++iter;
00107 if(i==count || plast != iter->message->procID)
00108 {
00109 receives.push_back(MPI_Request());
00110 sends.push_back(MPI_Request());
00111 int numChar = messageSize*sizeof(T);
00112 MPI_Isend(&(sendBuffer[index]), numChar, MPI_CHAR, plast,
00113 0, Chombo_MPI::comm, &(sends[sends.size()-1]));
00114 MPI_Irecv(&(recvBuffer[index]), numChar, MPI_CHAR, plast,
00115 0, Chombo_MPI::comm, &(receives[receives.size()-1]));
00116 messageSize = 0;
00117 index = i;
00118
00119 }
00120 }
00121 }
00122
00123
00124
00125 #endif
00126
00127
00128
00129 for(dit.begin(); dit.ok(); ++dit)
00130 {
00131 const T& val = a_local[dit];
00132 GatherObject<T> g;
00133 g.m_value = val;
00134 const Vector<RegionGather::Message>& local = a_copier.m_local[dit];
00135 for(int i=0; i<local.size(); ++i)
00136 {
00137 const RegionGather::Message& message = local[i];
00138 g.m_offset = message.distance;
00139 Vector<GatherObject<T> >& gather = a_gatherObjects[message.destIndex];
00140 gather.push_back(g);
00141 }
00142 }
00143
00144 #ifdef CH_MPI
00145
00146
00147
00148 if(sends.size() > 0){
00149 Vector<MPI_Status> status;
00150 status.resize(sends.size());
00151 int result;
00152 {
00153 CH_TIME("MPI_GatherSendWaitall");
00154 result = MPI_Waitall(sends.size(), &(sends[0]),
00155 &(status[0]));
00156 }
00157 }
00158 if(receives.size() > 0){
00159 Vector<MPI_Status> status;
00160 status.resize(receives.size());
00161 int result;
00162 {
00163 CH_TIME("MPI_GatherRecvWaitall");
00164 result = MPI_Waitall(receives.size(), &(receives[0]),
00165 &(status[0]));
00166 }
00167 iter = glist.begin();
00168
00169 for(int i=0; i<count; ++i, ++iter)
00170 {
00171 GatherObject<T> g;
00172 g.m_value = *((T*)iter->buffer);
00173 g.m_offset = -iter->message->distance;
00174 Vector<GatherObject<T> >& gather = a_gatherObjects[iter->message->srcIndex];
00175 gather.push_back(g);
00176 }
00177 }
00178 #endif
00179
00180 }
00181
00182 #endif