src/IplPaws/DLDescriptor.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://www.acl.lanl.gov/POOMS for more details
00023  *
00024  ***************************************************************************/
00025 
00026 #include "Paws/PawsMessage.h"
00027 #include "IpplPaws/DLDescriptor.h"
00028 #include "Field/LField.h"
00029 #include "Field/BareField.h"
00030 #include "Utility/PAssert.h"
00031 
00032 
00034 //
00035 // Construct a DLRepresentation given a global domain.
00036 // Right now this does not subdivide the representation at all.
00037 // IPPL Fields are always stored in column-major order.
00038 //
00040 
00041 template<class D, unsigned Dim, class C, class T>
00042 DLDescriptor<D,Dim,C,T>::DLDescriptor(DLRepresentation<D,Dim>& rep, C* coll)
00043   : PawsArrayDescriptor<T>(rep, PAWS_COLUMN, PAWS_PARALLEL), collection(coll)
00044 {
00045 }
00046 
00047 
00049 //
00050 // Update the DLDescriptor with a pointer to new data and a new representation
00051 //
00053 template<class D, unsigned Dim, class C, class T>
00054 void
00055 DLDescriptor<D,Dim,C,T>::update(const DLRepresentation<D,Dim>& rep, C* coll)
00056 {
00057    PawsArrayDescriptor<T>::update(rep);
00058    collection = coll;
00059 }
00060 
00061 
00063 //
00064 // Using the Abstract Schedule, pack the data for sending
00065 // packData() can handle local anomalies such as compression
00066 //
00068 
00069 template<class D, unsigned Dim, class C, class T>
00070 PawsMessage*
00071 DLDescriptor<D,Dim,C,T>::packData(const char* loc_id, const char* rem_id,
00072                               PawsAbstractMessage* am,
00073                               PawsRepresentation& remote_rep, int snum)
00074 {
00075   static char* id = "DLDescriptor:packData()";
00076   PDebug(PAWSD_APP, ("%s entering\n", id));
00077 
00078   int i;
00079   const char* header = am->header().c_str();
00080   int src_block = am->srcBlock();
00081   int first[Dim];
00082   int last[Dim];
00083   int stride[Dim];
00084   am->srcDomain(Dim, first, last, stride);
00085   D src_domain = makeDomain(first, last, stride);
00086 
00087   // Create an empty message to fill with data and send
00088   //
00089   PawsMessage* message = app->myComm()->createMessage();
00090   message->pack(N_SENDING_DATA);
00091   message->pack(loc_id);
00092   message->pack(rem_id);
00093   message->pack(snum);
00094   message->pack(header);
00095   message->pack(PAWS_COLUMN);
00096 
00097   // Collection* data is a BareField, iterate over all the local LFields
00098   //
00099   BareField<T,Dim>::iterator_if lfield;
00100   int block_num = 0;
00101   for (lfield = collection->begin_if(); lfield != collection->end_if();
00102                                                 ++lfield, block_num++) {
00103     if (src_block == block_num) {
00104         LField<T,Dim>& l = *((*lfield).second);
00105         LField<T,Dim>::iterator send;
00106 
00107         // Find out if LField is compressed and handle differently
00108         int num_data = 1;
00109         l.TryCompress();
00110 
00111         if (l.IsCompressed()) {
00112           PDebug(PAWSD_APP, ("%s Send Compressed %d\n", id, num_data));
00113           message->pack(num_data);
00114           message->pack(l.getCompressedData());
00115 
00116         } else {
00117           for (i = 0; i < Dim; i++)
00118             num_data *= (src_domain[i].last() - src_domain[i].first() + 1);
00119           message->pack(num_data);
00120           PDebug(PAWSD_APP, ("%s Send Uncompressed %d\n", id, num_data));
00121 
00122           // Move data in contiguous chunks into buffer
00123           int n = 0;
00124           send = l.begin(src_domain);
00125           int data_width = send.size(0);
00126           while (send != l.end()) {
00127             message->pack(&(*send), data_width);
00128             n += data_width;
00129             for (i = 0; i < data_width; ++i)
00130               ++send;
00131           }
00132         }
00133         PDebug(PAWSD_APP, ("%s header=%s seq=%d num=%d\n", id, header, snum, num_data));
00134     }
00135   }
00136 
00137   PDebug(PAWSD_APP, ("%s exiting\n", id));
00138   return message;
00139 }
00140 
00141 
00143 //
00144 // Pack the data for sending according to the AbstractMessage
00145 // Pack in standard format must send compressed data in uncompressed form
00146 //
00148 
00149 template<class D, unsigned Dim, class C, class T>
00150 PawsMessage*
00151 DLDescriptor<D,Dim,C,T>::packStdData(const char* loc_id, const char* rem_id,
00152                         PawsAbstractMessage* am,
00153                         PawsRepresentation& remote_rep, int snum)
00154 {
00155   static char* id = "DLDescriptor:packStdData()";
00156   PDebug(PAWSD_APP, ("%s entering\n", id));
00157 
00158   int i;
00159   const char* header = am->header().c_str();
00160   int src_block = am->srcBlock();
00161   int first[Dim];
00162   int last[Dim];
00163   int stride[Dim];
00164   am->srcDomain(Dim, first, last, stride);
00165   D src_domain = makeDomain(first, last, stride);
00166 
00167   // Create an empty message to fill with data and send
00168   //
00169   PawsMessage* message = app->myComm()->createMessage();
00170   message->pack(N_SENDING_DATA);
00171   message->pack(loc_id);
00172   message->pack(rem_id);
00173   message->pack(snum);
00174   message->pack(header);
00175   message->pack(PAWS_COLUMN);
00176 
00177   // Collection* data is really the Field<T,Dim> which is a BareField
00178   // BareField has an iterator over all local LFields
00179   //
00180   BareField<T,Dim>::iterator_if lfield;
00181   int block_num = 0;
00182   for (lfield = collection->begin_if(); lfield != collection->end_if();
00183                                                 ++lfield, block_num++) {
00184       if (src_block == block_num) {
00185         LField<T,Dim>& l = *((*lfield).second);
00186         LField<T,Dim>::iterator send;
00187 
00188         // Find out if LField is compressed and handle differently
00189         int num_data = 1;
00190         for (i = 0; i < Dim; i++)
00191             num_data *= (src_domain[i].last() - src_domain[i].first() + 1);
00192         l.TryCompress();
00193 
00194         if (l.IsCompressed()) {
00195           PDebug(PAWSD_APP, ("%s Send Compressed Expanded\n", id));
00196           message->pack(num_data);
00197           T value = l.getCompressedData();
00198           for (i = 0; i < num_data; i++)
00199               message->pack(value);
00200 
00201         } else {
00202           message->pack(num_data);
00203           PDebug(PAWSD_APP, ("%s Send Uncompressed %d\n", id, num_data));
00204 
00205           // Move data in contiguous chunks into buffer
00206           int n = 0;
00207           send = l.begin(src_domain);
00208           int data_width = send.size(0);
00209           while (send != l.end()) {
00210             message->pack(&(*send), data_width);
00211             n += data_width;
00212             for (int i = 0; i < data_width; ++i)
00213               ++send;
00214           }
00215         }
00216         PDebug(PAWSD_APP, ("%s header=%s seq=%d num=%d\n", id, header, snum, num_data));
00217       }
00218   }
00219 
00220   PDebug(PAWSD_APP, ("%s exiting\n", id));
00221   return message;
00222 }
00223 
00224 
00226 //
00227 // Unpack data into space pointed at by DLRepresentation
00228 //
00230 
00231 template<class D, unsigned Dim, class C, class T>
00232 void
00233 DLDescriptor<D,Dim,C,T>::unpackData(PawsMessage& message, const char* header)
00234 {
00235   static char* id = "DLDescriptor: unpackData()";
00236   PDebug(PAWSD_APP, ("%s entering\n", id));
00237 
00238   int num_data = 0;
00239   int remote_order = PAWS_COLUMN;
00240   T value;
00241   PawsAbstractMessage recv_message;
00242   recv_message.unpack(header);
00243   int dst_block = recv_message.dstBlock();
00244 
00245   int first[Dim];
00246   int last[Dim];
00247   int stride[Dim];
00248   recv_message.dstDomain(Dim, first, last, stride);
00249   D dst_domain = makeDomain(first, last, stride);
00250 
00251   // Fill the correct LField's sub_domain with the following data
00252   // Iterate through all the LFields looking for the correct one
00253   //
00254   BareField<T,Dim>::iterator_if lfield;
00255   int block_num = 0;
00256   for (lfield = collection->begin_if(); lfield != collection->end_if();
00257                                                 ++lfield, block_num++) {
00258     if (block_num == dst_block) {
00259       LField<T,Dim>& l = *((*lfield).second);
00260       LField<T,Dim>::iterator recv = l.begin(dst_domain);
00261       D& lfield_domain = (D&) l.getOwned();
00262 
00263       // Deal with compression, if number of data sent is one,
00264       // and dst_domain = lfield_domain then send LField can be compressed
00265       //
00266       message.unpack(&remote_order);
00267       if (remote_order != PAWS_COLUMN) {
00268           PDebug(PAWSD_APP, ("%s Bad incoming storage order %d\n", id, remote_order));
00269           PAssert(false);
00270       }
00271       message.unpack(&num_data);
00272       if (num_data == 1) {
00273         message.unpack(&value);
00274 
00275         if (lfield_domain == dst_domain) {
00276           PDebug(PAWSD_APP, ("%s Compressed to Compressed %d\n", id, num_data));
00277           l.Compress(value);
00278         } else {
00279           PDebug(PAWSD_APP, ("%s Compressed to Uncompressed %d\n", id, num_data));
00280           l.Uncompress();
00281           for (recv = l.begin(dst_domain); recv != l.end(); ++recv)
00282             (*recv) = value;
00283         }
00284       } else {
00285         // Send LField is not compressed, uncompress receive LField
00286         //
00287         if (l.IsCompressed()) {
00288           PDebug(PAWSD_APP, ("%s Uncompressed to Compressed %d\n", id, num_data));
00289         } else {
00290           PDebug(PAWSD_APP, ("%s Uncompressed to Uncompressed %d\n", id, num_data));
00291         }
00292         l.Uncompress();
00293         int n = 0;
00294         recv = l.begin(dst_domain);
00295         int data_width = recv.size(0);
00296         while (recv != l.end()) {
00297           message.unpack(&(*recv), data_width);
00298           n += data_width;
00299           for (int i = 0; i < data_width; ++i)
00300             ++recv;
00301         }
00302       }
00303     }
00304   }
00305 
00306   PDebug(PAWSD_APP, ("%s exiting\n", id));
00307 }
00308 
00309 
00311 //
00312 // Unpack data into space pointed at by the collection
00313 //
00315 
00316 template<class D, unsigned Dim, class C, class T>
00317 void
00318 DLDescriptor<D,Dim,C,T>::unpackStdData(PawsMessage& message, const char* header)
00319 {
00320   static char* id = "DLDescriptor: unpackStdData()";
00321   PDebug(PAWSD_APP, ("%s entering\n", id));
00322 
00323   int num_data = 0;
00324   int remote_order = PAWS_COLUMN;
00325   T value;
00326   PawsAbstractMessage recv_message;
00327   recv_message.unpack(header);
00328   int dst_block = recv_message.dstBlock();
00329 
00330   int first[Dim];
00331   int last[Dim];
00332   int stride[Dim];
00333   recv_message.dstDomain(Dim, first, last, stride);
00334   D dst_domain = makeDomain(first, last, stride);
00335 
00336   // Fill the correct LField's sub_domain with the following data
00337   // Iterate through all the LFields looking for the correct one
00338   //
00339   BareField<T,Dim>::iterator_if lfield;
00340   int block_num = 0;
00341   for (lfield = collection->begin_if(); lfield != collection->end_if();
00342                                                 ++lfield, ++block_num) {
00343     if (block_num == dst_block) {
00344       LField<T,Dim>& l = *((*lfield).second);
00345       LField<T,Dim>::iterator recv = l.begin(dst_domain);
00346       D& lfield_domain = (D&) l.getOwned();
00347 
00348       // Deal with compression, if number of data sent is one,
00349       // and dst_domain = lfield_domain then send LField can be compressed
00350       //
00351       message.unpack(&remote_order);
00352       if (remote_order != PAWS_COLUMN) {
00353           PDebug(PAWSD_APP, ("%s Bad incoming storage order %d\n", id, remote_order));
00354           PAssert(false);
00355       }
00356       message.unpack(&num_data);
00357 
00358       if (num_data == 1) {
00359         message.unpack(&value);
00360 
00361         if (lfield_domain == dst_domain) {
00362           PDebug(PAWSD_APP, ("%s Compressed to Compressed %d\n", id, num_data));
00363           l.Compress(value);
00364         } else {
00365           PDebug(PAWSD_APP, ("%s Compressed to Uncompressed %d\n", id, num_data));
00366           l.Uncompress();
00367           for (recv = l.begin(dst_domain); recv != l.end(); ++recv)
00368             (*recv) = value;
00369         }
00370 
00371       } else {
00372         // Send LField is not compressed, uncompress receive LField
00373         //
00374         if (l.IsCompressed()) {
00375           PDebug(PAWSD_APP, ("%s Uncompressed to Compressed %d\n", id, num_data));
00376         } else {
00377           PDebug(PAWSD_APP, ("%s Uncompressed to Uncompressed %d\n", id, num_data));
00378         }
00379 
00380         l.Uncompress();
00381         int n = 0;
00382         recv = l.begin(dst_domain);
00383         int data_width = recv.size(0);
00384         while (recv != l.end()) {
00385           message.unpack(&(*recv), data_width);
00386           n += data_width;
00387           for (int i = 0; i < data_width; ++i)
00388             ++recv;
00389         }
00390       }
00391     }
00392   }
00393 
00394   PDebug(PAWSD_APP, ("%s exiting\n", id));
00395 }
00396 
00397 
00399 //
00400 // Make a local domain given first, last and stride elements
00401 //
00403 
00404 template<class D, unsigned Dim, class C, class T>
00405 D
00406 DLDescriptor<D,Dim,C,T>::makeDomain(const int* first,
00407                                 const int* last,
00408                                 const int* stride)
00409 {
00410   D new_domain;
00411 
00412   for (int i = 0; i < Dim; i++)
00413     new_domain[i] = Index(first[i], last[i], stride[i]);
00414 
00415   return new_domain;
00416 }
00417 
00419 //
00420 // Print out the descriptor
00421 //
00423 template <class D, unsigned Dim, class C, class T>
00424 ostream& operator<<(ostream& out, DLDescriptor<D,Dim,C,T>& dlDesc)
00425 {
00426   out << (PawsArrayDescriptor<T>&)dlDesc << endl;
00427   return out;
00428 }
00429 
00430 /***************************************************************************
00431  * $RCSfile: DLDescriptor.cpp,v $   $Author: adelmann $
00432  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:32 $
00433  * IPPL_VERSION_ID: $Id: DLDescriptor.cpp,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $ 
00434  ***************************************************************************/
00435 

Generated on Mon Jan 16 13:23:49 2006 for IPPL by  doxygen 1.4.6