Main Page | Namespace List | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Globals

communicator.h

Go to the documentation of this file.
00001 
00005 template <class T, class S> class communicator
00006 {
00007 private:
00008         vector<T> _rpos;        
00009         vector<S> _rsca;        
00010         vector<T> _rcom;        
00011         vector<T> _rcnt;        
00012         vector<T> _rdsp;        
00013         vector<S> _rvec;        
00014         vector<S> _svec;        
00015         vector<S> _rcol;        
00016 public:
00021         void collect(S &_t)
00022         {
00023                 network::allgather(&_t, sizeof(S), &_rcol[0], sizeof(S));
00024                 S s = 0.0;
00025                 for(int i = 0; i < (int)_rcol.size(); i++) s += _rcol[i];
00026                 _t = s;
00027         }
00032         void collect(vector<S> &_t)
00033         {
00034                 int m = (int)_t.size();
00035                 int n = (int)_rcnt.size();
00036                 _rcol.resize(n * m);
00037                 network::allgather(&_t[0], m * sizeof(S), &_rcol[0], m * sizeof(S));
00038 
00039                 S *r = &_rcol[0];
00040                 for(int i = 0; i < m; i++)
00041                 {
00042                         S s = 0.0;
00043                         for(int j = 0; j < n; j++) s += r[m * j + i];
00044                         _t[i] = s;
00045                 }
00046 
00047         }
00052         void distribute(vector<S> &_x)
00053         {
00054                 if(_rpos.size() == 0) return;
00055                 S *x = &_x[0];
00056                 for(int i = 0; i < (int)_rpos.size(); i++)
00057                 {
00058                         x[_rpos[i]] *= _rsca[i];
00059                 }
00060         }
00065         void distribute(packed_vector<S> &_x)
00066         {
00067                 if(_rpos.size() == 0) return;
00068                 S *x = &_x[0];
00069                 S *s = &_rsca[0];
00070                 T *p = &_rpos[0];
00071                 int m = (int)_rpos.size();
00072                 int n = _x.numrhs() * _x.numdof();
00073                 for(int i = 0; i < m; i++)
00074                 {
00075                         T k = n * p[i];
00076                         S t = s[i];
00077                         for(int j = 0; j < n; j++)
00078                         {
00079                                 x[k + j] *= t;
00080                         }
00081                 }
00082         }
00087         void accumulate(vector<S> &_x)
00088         {
00089                 if(_rcom.size() == 0) return;
00090                 for(int i = 0; i < (int)_rcom.size(); i++) _svec[i] = _x[_rcom[i]];
00091                 for(int i = 0; i < (int)_rcnt.size(); i++) _rcnt[i] *= sizeof(S), _rdsp[i] *= sizeof(S);
00092                 network::alltoallv(&_svec[0], &_rcnt[0], &_rdsp[0], &_rvec[0], &_rcnt[0], &_rdsp[0]);
00093                 for(int i = 0; i < (int)_rcnt.size(); i++) _rcnt[i] /= sizeof(S), _rdsp[i] /= sizeof(S);
00094                 for(int i = 0; i < (int)_rcom.size(); i++) _x[_rcom[i]] += _rvec[i];
00095         }
00100         void accumulate(packed_vector<S> &_x)
00101         {
00102                 if(_rcom.size() == 0) return;
00103                 int n = _x.numrhs() * _x.numdof();
00104                 _svec.resize(n * _rcom.size());
00105                 _rvec.resize(n * _rcom.size());
00106                 S *x = &_x[0], *s = &_svec[0], *r = &_rvec[0];
00107                 int m = (int)_rcom.size();
00108                 for(int i = 0; i < m; i++)
00109                 {
00110                         T k = n * i;
00111                         T l = n * _rcom[i];
00112                         for(int j = 0; j < n; j++)
00113                         {
00114                                 s[k + j] = x[l + j];
00115                         }
00116                 }
00117 
00118                 for(int i = 0; i < (int)_rcnt.size(); i++) _rcnt[i] *= n * sizeof(S), _rdsp[i] *= n * sizeof(S);
00119                 network::alltoallv(&_svec[0], &_rcnt[0], &_rdsp[0], &_rvec[0], &_rcnt[0], &_rdsp[0]);
00120                 for(int i = 0; i < (int)_rcnt.size(); i++) _rcnt[i] /= n * sizeof(S), _rdsp[i] /= n * sizeof(S);
00121 
00122                 for(int i = 0; i < m; i++)
00123                 {
00124                         T k = n * i;
00125                         T l = n * _rcom[i];
00126                         for(int j = 0; j < n; j++)
00127                         {
00128                                 x[l + j] += r[k + j];
00129                         }
00130                 }
00131         }
00136         communicator(const vector<T> &_gnod)
00137         {
00138                 vector<T> _rnod(_gnod);
00139                 int size, rank;
00140                 network::size(size);
00141                 network::rank(rank);
00142                 _rcol.resize(size);
00143 
00144                 int rnod0 = (int)_rnod.size();
00145                 vector<T> rnod(rnod0);
00146                 for(int i = 0; i < rnod0; i++) rnod[i] = i;
00147                 binary_sort_copy(_rnod, rnod);
00148 
00149                 _rcnt.resize(size);
00150                 network::allgather(&rnod0, sizeof(T), &_rcnt[0], sizeof(T));
00151                 int rcom0 = bucket_sort_size(_rcnt);
00152                 _rcom.resize(rcom0);
00153                 _rdsp.resize(size);
00154                 bucket_sort_offset(_rcnt, _rdsp);
00155 
00156                 for(int i = 0; i < (int)_rcnt.size(); i++) _rcnt[i] *= sizeof(T), _rdsp[i] *= sizeof(T);
00157                 network::allgatherv(&_rnod[0], rnod0 * sizeof(T), &_rcom[0], &_rcnt[0], &_rdsp[0]);
00158                 for(int i = 0; i < (int)_rcnt.size(); i++) _rcnt[i] /= sizeof(T), _rdsp[i] /= sizeof(T);
00159 
00160                 global_intersection(size, rank, _rnod, rnod, _rcom, _rcnt, _rdsp);
00161                 rcom0 = (int)_rcom.size();
00162                 _rvec.resize(rcom0);
00163                 _svec.resize(rcom0);
00164 
00165                 _rpos.assign(_rcom.begin(), _rcom.end());
00166                 _rsca.resize(rcom0, 1.0);
00167                 binary_sort(_rpos);
00168                 unique_accumulate(_rpos, _rsca);
00169                 for(int i = 0; i < (int)_rsca.size(); i++)
00170                 {
00171                         _rsca[i] = 1.0/(1.0 + _rsca[i]);
00172                 }
00173         }
00174 
00175 };

Generated on Wed Apr 26 17:41:45 2006 for Parallel Toolbox by  doxygen 1.4.2