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