48 template<
class T,
unsigned Dim >
52 compressible_m( a.compressible_m ),
83 template<
class T,
unsigned Dim >
89 Layout->checkout(*
this);
99 template<
class T,
unsigned Dim >
113 template<
class T,
unsigned Dim >
127 template<
class T,
unsigned Dim >
149 template<
class T,
unsigned Dim >
158 if ( ! getLayout().fitsGuardCells(Gc)) {
160 ERRORMSG(
" One or more vnodes is too small for the guard cells." <<
endl);
170 Locals_ac.reserve( getLayout().size_iv() );
174 v_i != getLayout().end_iv();
182 int vnode = (*v_i).second->getVnode();
193 Locals_ac.insert( end_if(),
197 getLayout().checkin( *
this , Gc );
207 template<
class T,
unsigned Dim>
220 for (
iterator_if local = begin_if(); local != end_if() ; ++local) {
230 rhs.putMessage(*mess);
241 for (
iterator_if local = begin_if(); local != end_if() ; ++local) {
252 for ( ; getloc != l.
end() ; ++putloc, ++getloc ) {
260 int remaining = getLayout().size_rdv();
263 for ( ; remaining > 0; --remaining) {
278 for (
unsigned elems=lo.
size(); elems > 0; ++putloc, ++rhs, --elems)
297 template<
class T,
unsigned Dim >
322 #ifdef IPPL_PRINTDEBUG
334 typedef std::multimap< NDIndex<Dim> ,
LField<T,Dim>* , std::less<NDIndex<Dim> > > ac_recv_type;
335 ac_recv_type recv_ac;
336 bool* recvmsg =
new bool[nprocs];
342 #ifdef IPPL_PRINTDEBUG
343 int* ndomains =
new int[nprocs];
346 for (iproc=0; iproc<nprocs; ++iproc) {
348 recvmsg[iproc] =
false;
349 #ifdef IPPL_PRINTDEBUG
355 for (lf_i = ncf.
begin_if(); lf_i != lf_e; ++lf_i) {
358 LField<T,Dim> &lf = *((*lf_i).second);
364 for (rv_i = rrange.first; rv_i != rrange.second; ++rv_i) {
370 int rnode = (*rv_i).second->getNode();
371 recvmsg[rnode] =
true;
377 #ifdef IPPL_PRINTDEBUG
378 msg <<
"Finding send overlap regions for domain " << lo <<
endl;
385 for (remote_i = range.first; remote_i != range.second; ++remote_i) {
389 int rnode = (*remote_i).second->getNode();
390 #ifdef IPPL_PRINTDEBUG
391 msg <<
" Overlap domain = " << (*remote_i).first <<
endl;
392 msg <<
" Inters. domain = " << intersection;
393 msg <<
" --> node " << rnode <<
endl;
399 LFI msgval = lf.
begin(intersection, compressed_value);
403 if (!mess[rnode]) mess[rnode] =
new Message;
405 mess[rnode]->
put(intersection);
406 mess[rnode]->
put(msgval);
407 #ifdef IPPL_PRINTDEBUG
415 for (iproc=0; iproc<nprocs; ++iproc)
416 if (recvmsg[iproc]) ++remaining;
425 for (iproc=0; iproc<nprocs; ++iproc) {
427 #ifdef IPPL_PRINTDEBUG
428 msg <<
"fillGuardCells: Sending message to node " << iproc <<
endl
429 <<
" number of domains = " << ndomains[iproc] <<
endl
430 <<
" number of MsgItems = " << mess[iproc]->
size() <<
endl;
437 #ifdef IPPL_PRINTDEBUG
446 for (lf_i = ncf.
begin_if(); lf_i != lf_e; ++lf_i)
449 LField<T,Dim> &lf = *(*lf_i).second;
464 LField<T,Dim> &rf = *(*rf_i).second;
487 if ( !( c1 && c2 && c3 ) )
505 #ifdef IPPL_PRINTDEBUG
506 msg <<
" Inters. domain=" << intersection <<
endl;
514 #ifdef IPPL_PRINTDEBUG
516 msg <<
" Both sides compressed and equal ... val = ";
527 while (remaining>0) {
537 int ndoms = rmess->
size() / (
Dim + 3);
538 #ifdef IPPL_PRINTDEBUG
539 msg <<
"fillGuardCells: Message received from node " << any_node
540 <<
", number of domains = " << ndoms <<
endl;
542 for (
int idom=0; idom<ndoms; ++idom) {
549 LFI rhs(compressed_value);
551 #ifdef IPPL_PRINTDEBUG
552 msg <<
"Received remote overlap region = " << intersection <<
endl;
557 PAssert( hit != recv_ac.end() );
559 LField<T,Dim> &lf = *(*hit).second;
561 #ifdef IPPL_PRINTDEBUG
562 msg <<
" LHS compressed ? " << lf.IsCompressed();
563 msg <<
", LHS value = " << *lf.begin() <<
endl;
565 msg <<
", RHS value = " << *rhs <<
endl;
566 msg <<
" *rhs == *lf.begin() ? " << (*rhs == *lf.begin()) << endl;
568 if ( !(rhs.IsCompressed() && lf.IsCompressed() &&
569 (*rhs == *lf.begin())) )
573 LFI lhs = lf.begin(intersection);
575 #ifdef IPPL_PRINTDEBUG
576 msg <<
" Doing copy." <<
endl;
582 recv_ac.erase( hit );
593 for (lf_i = ncf.
begin_if(); lf_i != lf_e; ++lf_i)
634 if ( !( c1 && c2 && c3 ) )
652 #ifdef IPPL_PRINTDEBUG
653 msg <<
" Inters. domain=" << intersection <<
endl;
661 #ifdef IPPL_PRINTDEBUG
663 msg <<
" Both sides compressed and equal ... val = ";
681 template <
class T,
unsigned Dim>
697 for (lf_i = ncf.
begin_if(); lf_i != lf_e; ++lf_i) {
724 for (
unsigned int idim = 0; idim <
Dim; ++idim) {
726 dom[idim] =
Index(adom[idim].first(),
727 adom[idim].first() + Gc.left(idim) - 1);
728 if (!dom[idim].empty()) {
736 dom[idim] =
Index(adom[idim].last() - Gc.right(idim) + 1,
738 if (!dom[idim].empty()) {
747 dom[idim] = adom[idim];
763 template <
class T,
unsigned Dim>
774 #ifdef IPPL_PRINTDEBUG
786 typedef std::multimap< NDIndex<Dim> ,
LField<T,Dim>* , std::less<NDIndex<Dim> > > ac_recv_type;
787 ac_recv_type recv_ac;
788 bool* recvmsg =
new bool[nprocs];
794 #ifdef IPPL_PRINTDEBUG
795 int* ndomains =
new int[nprocs];
798 for (iproc=0; iproc<nprocs; ++iproc) {
800 recvmsg[iproc] =
false;
801 #ifdef IPPL_PRINTDEBUG
807 for (lf_i = begin_if(); lf_i != lf_e; ++lf_i) {
810 LField<T,Dim> &lf = *((*lf_i).second);
814 rrange( getLayout().touch_range_rdv(lo,Gc) );
816 for (rv_i = rrange.first; rv_i != rrange.second; ++rv_i) {
821 int rnode = (*rv_i).second->getNode();
822 recvmsg[rnode] =
true;
828 #ifdef IPPL_PRINTDEBUG
829 msg <<
"Finding send overlap regions for domain " << lf_domain <<
endl;
834 range(getLayout().touch_range_rdv(lf_domain));
836 for (remote_i = range.first; remote_i != range.second; ++remote_i) {
840 int rnode = (*remote_i).second->getNode();
841 #ifdef IPPL_PRINTDEBUG
842 msg <<
" Overlap domain = " << (*remote_i).first <<
endl;
843 msg <<
" Inters. domain = " << intersection;
844 msg <<
" --> node " << rnode <<
endl;
850 LFI msgval = lf.
begin(intersection, compressed_value);
854 if (!mess[rnode]) mess[rnode] =
new Message;
856 mess[rnode]->
put(intersection);
857 mess[rnode]->
put(msgval);
858 #ifdef IPPL_PRINTDEBUG
866 for (iproc=0; iproc<nprocs; ++iproc)
867 if (recvmsg[iproc]) ++remaining;
876 for (iproc=0; iproc<nprocs; ++iproc) {
878 #ifdef IPPL_PRINTDEBUG
879 msg <<
"accumGuardCells: Sending message to node " << iproc <<
endl
880 <<
" number of domains = " << ndomains[iproc] <<
endl
881 <<
" number of MsgItems = " << mess[iproc]->
size() <<
endl;
888 #ifdef IPPL_PRINTDEBUG
897 for (lf_i=begin_if(); lf_i != lf_e; ++lf_i)
900 LField<T,Dim> &lf = *(*lf_i).second;
911 for (
iterator_if rf_i = begin_if(); rf_i != end_if(); ++rf_i)
915 LField<T,Dim> &rf = *(*rf_i).second;
950 #ifdef IPPL_PRINTDEBUG
951 msg <<
" Inters. domain=" << intersection <<
endl;
964 while (remaining>0) {
974 int ndoms = rmess->
size() / (
Dim + 3);
975 #ifdef IPPL_PRINTDEBUG
976 msg <<
"accumGuardCells: Message received from node " << any_node
977 <<
", number of domains = " << ndoms <<
endl;
979 for (
int idom=0; idom<ndoms; ++idom) {
986 LFI rhs(compressed_value);
988 #ifdef IPPL_PRINTDEBUG
989 msg <<
"Received remote overlap region = " << intersection <<
endl;
994 PAssert( hit != recv_ac.end() );
997 LField<T,Dim> &lf = *(*hit).second;
1001 LFI lhs = lf.begin(intersection);
1007 recv_ac.erase( hit );
1018 for (lf_i=begin_if(); lf_i != lf_e; ++lf_i)
1032 for (
iterator_if rf_i = begin_if(); rf_i != end_if(); ++rf_i)
1070 #ifdef IPPL_PRINTDEBUG
1071 msg <<
" Inters. domain=" << intersection <<
endl;
1086 fillGuardCellsIfNotDirty();
1099 template<
class T,
unsigned Dim >
1111 ncid = nccreate(fname, NC_CLOBBER);
1114 int fillmode = ncsetfill(ncid,NC_NOFILL);
1128 dimids[0] = ncdimdef(ncid,
"nx", domain[0].length());
1132 dimids[1] = ncdimdef(ncid,
"nx", domain[1].length());
1133 dimids[0] = ncdimdef(ncid,
"ny", domain[0].length());
1137 dimids[2] = ncdimdef(ncid,
"nx", domain[0].length());
1138 dimids[1] = ncdimdef(ncid,
"ny", domain[1].length());
1139 dimids[0] = ncdimdef(ncid,
"nz", domain[2].length());
1143 ERRORMSG(
"BareField: Can't write more than 3 dimensions." <<
endl);
1145 varVID = ncvardef(ncid, fname, NC_DOUBLE,
Dim, dimids);
1147 int errRet = ncendef(ncid);
1150 long startIndex[
Dim];
1151 long countIndex[
Dim];
1161 for(
unsigned int i = 0 ; i <
Dim ; i++ )
1163 startIndex[Dim - i - 1] = Owned[i].first();
1164 countIndex[Dim - i - 1] = Owned[i].length();
1165 size *= countIndex[Dim - i - 1];
1167 double* buffer =
new double[
size];
1173 int n0 = ldf->
size(0);
1174 for (
int i0=0; i0<n0; ++i0)
1175 buffer[icount++] = lf_bi.
offset(i0);
1179 int n0 = ldf->
size(0);
1180 int n1 = ldf->
size(1);
1181 for (
int i1=0; i1<n1; ++i1)
1182 for (
int i0=0; i0<n0; ++i0)
1183 buffer[icount++] = lf_bi.
offset(i0,i1);
1187 int n0 = ldf->
size(0);
1188 int n1 = ldf->
size(1);
1189 int n2 = ldf->
size(2);
1190 for (
int i2=0; i2<n2; ++i2)
1191 for (
int i1=0; i1<n1; ++i1)
1192 for (
int i0=0; i0<n0; ++i0)
1193 buffer[icount++] = lf_bi.
offset(i0,i1,i2);
1195 rcode = ncvarput(ncid, varVID, startIndex,countIndex, buffer);
1198 ERRORMSG(
"BareField: ncvarput() error, rcode=" << rcode <<
endl);
1202 rcode = ncclose(ncid);
1204 ERRORMSG(
"[Bare]Field::write(\"filename\") requires that you run 'conf' "
1206 <<
"with the NETCDF option when building libippl.a; you haven't."
1219 template<
class T,
unsigned Dim >
1233 outC <<
"vnode = " << icount++ <<
endl;
1237 int n0 = ldf->
size(0);
1238 int l0 = -Gc.left(0);
1239 int r0 = n0 + Gc.right(0);
1240 for (
int i0=l0; i0<r0; ++i0)
1243 outC <<
"]=" << lf_bi.
offset(i0);
1248 int n0 = ldf->
size(0);
1249 int n1 = ldf->
size(1);
1250 int l0 = -Gc.left(0);
1251 int l1 = -Gc.left(1);
1252 int r0 = n0 + Gc.right(0);
1253 int r1 = n1 + Gc.right(1);
1254 for (
int i1=l1; i1<r1; ++i1)
1256 for (
int i0=l0; i0<r0; ++i0)
1260 outC <<
"]=" << lf_bi.
offset(i0,i1);
1267 int n0 = ldf->
size(0);
1268 int n1 = ldf->
size(1);
1269 int n2 = ldf->
size(2);
1270 int l0 = -Gc.left(0);
1271 int l1 = -Gc.left(1);
1272 int l2 = -Gc.left(2);
1273 int r0 = n0 + Gc.right(0);
1274 int r1 = n1 + Gc.right(1);
1275 int r2 = n2 + Gc.right(2);
1276 for (
int i2=l2; i2<r2; ++i2)
1278 for (
int i1=l1; i1<r1; ++i1)
1279 for (
int i0=l0; i0<r0; ++i0)
1284 outC <<
"]=" << lf_bi.
offset(i0,i1,i2);
1291 ERRORMSG(
" can not write for larger than three dimensions " << endl);
1293 outC <<
"------------------ " <<
endl;
1303 template<
class T,
unsigned Dim>
1309 if (!compressible_m)
return;
1314 (*lf_i).second->TryCompress(isDirty());
1317 template<
class T,
unsigned Dim>
1333 template<
class T,
unsigned Dim>
1357 double reduced_elements[2] = { 0.0, 0.0};
1361 return reduced_elements[1]/reduced_elements[0];
1366 template<
class T,
unsigned Dim>
1391 template<
class T,
unsigned Dim>
1399 if (Layout != 0 && Layout->get_Id() == userlist->
getUserListID()) {
1408 WARNMSG(
"BareField: notified of unknown UserList being deleted.");
1415 template<
unsigned Dim,
bool exists>
1432 T* newptr = ptr + pos[0].first() - alloc[0].first();
1440 T* newptr = ptr + pos[0].first() - alloc[0].first() +
1441 alloc[0].length() * ( pos[1].first() - alloc[1].first() );
1449 T* newptr = ptr + pos[0].first() - alloc[0].first() +
1450 alloc[0].length() * ( pos[1].first() - alloc[1].first() +
1451 alloc[1].length() * ( pos[2].first() - alloc[2].first() ) );
1455 template <
class T,
unsigned Dim>
1461 for (
unsigned int d=0; d<
Dim; ++d) {
1462 newptr += n * (pos[d].first() - alloc[d].first());
1463 n *= alloc[d].length();
1474 template<
class T,
unsigned Dim>
1488 for ( ; lf_i != lf_end ; ++lf_i ) {
1506 ERRORMSG(
"BareField::localElement: attempt to access non-local index ");
1508 ERRORMSG(
"Occurred in a BareField with layout = " << getLayout() <<
endl);
1511 return *((*((*(begin_if())).second)).begin());
1521 template <
class T,
unsigned int Dim>
1534 if ( (!Indexes.
touches(Layout->getDomain())) &&
1536 getsingle_bc(Indexes,r);
1546 if ( (*lf_i).second->getOwned().contains( Indexes ) ) {
1576 ERRORMSG(
"Illegal single-value index " << Indexes);
1590 template<
class T,
unsigned D>
1598 int authority_proc = -1;
1605 if ( (*lf_i).second->getAllocated().contains( Indexes ) ) {
1626 Layout->touch_range_rdv(Indexes,Gc);
1628 p!=range.second;++p)
1630 if ( authority_proc > (*p).second->getNode() )
1632 authority_proc = (*p).second->getNode();
std::pair< iterator, bool > insert(const value_type &x)
static void abort(const char *=0, int exitcode=(-1))
Layout_t & getLayout() const
ac_id_larray::iterator iterator_if
bool IsCompressed() const
void getsingle(const NDIndex< Dim > &, T &) const
const NDIndex< Dim > & getOwned() const
touch_range_dv touch_range_rdv(const NDIndex< Dim > &domain, const GuardCellSizes< Dim > &gc=gc0()) const
virtual void Repartition(UserList *)
ID_t getUserListID() const
bool OverlapCacheInitialized()
Message & getMessage(Message &m)
OverlapIterator BeginOverlap()
void Uncompress(bool fill_domain=true)
void getsingle_bc(const NDIndex< Dim > &, T &) const
void setGuardCells(const T &) const
NDIndex< Dim > AddGuardCells(const NDIndex< Dim > &idx, const GuardCellSizes< Dim > &g)
#define F_GUARD_CELLS_TAG
int next_tag(int t, int s=1000)
T & localElement(const NDIndex< Dim > &) const
void reserve(size_type n)
const iterator & begin() const
virtual void fillGuardCells(bool reallyFill=true) const
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
OverlapIterator EndOverlap()
const iterator & end() const
Message & getMessage(Message &m)
ac_id_vnodes::iterator iterator_iv
bool touches(const NDIndex< Dim > &) const
virtual int broadcast_others(Message *, int, bool delmsg=true)
const NDIndex< Dim > & getAllocated() const
int size(unsigned d) const
bool IsCompressed() const
std::pair< typename Unique::type, my_auto_ptr< LField< T, Dim > > > value_type
T * value_type(const SliceIterator< T > &)
ac_id_larray::const_iterator const_iterator_if
Message & put(const T &val)
T * PtrOffset(T *ptr, const NDIndex< 1U > &pos, const NDIndex< 1U > &alloc, LFieldDimTag< 1U, true >)
ac_id_larray::size_type size_if() const
void write(std::ostream &)
const GuardCellSizes< Dim > & getGC() const
void writeb(char *) const
void getMessage(Message &m, T &t)
bool CanCompress(const T &) const
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
std::vector< LField< T, Dim > * >::iterator OverlapIterator
Message & putMessage(Message &m) const
std::string::iterator iterator
void putMessage(Message &m, const T &t)
double CompressedFraction() const
Message * receive_block(int &node, int &tag)
virtual void notifyUserOfDelete(UserList *)
static Communicate * Comm
bool send(Message *, int node, int tag, bool delmsg=true)
int size(unsigned d) const
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
void checkin(FieldLayoutUser &f, const GuardCellSizes< Dim > &gc=gc0())
void initialize(Layout_t &)
void AddToOverlapCache(LField< T, Dim > *newCacheItem)
Inform & endl(Inform &inf)