32 template<
class T,
unsigned Dim,
class M,
class C>
class Field;
39 template <
unsigned Dim,
class T>
48 template <
unsigned Dim>
64 DiscField(
const char* fname,
const char* config,
unsigned int numFields,
65 const char* typestr = 0);
70 DiscField(
const char* fname,
unsigned int numFields,
71 const char* typestr = 0);
76 DiscField(
const char* fname,
const char* config);
92 void query(
int& numRecords,
int& numFields, std::vector<int>& size)
const;
139 template <
class T,
class M,
class C>
141 unsigned int varID,
unsigned int record) {
144 bool canread =
false;
146 ERRORMSG(
"Cannot read in DiscField::read - config file error." <<
endl);
151 ERRORMSG(
"DiscField::read called for DiscField opened for write."<<
endl);
153 ERRORMSG(varID <<
" is a bad Field ID in DiscField::read." <<
endl);
156 ERRORMSG(record <<
" is a bad record number in DiscField::read."<<
endl);
159 ERRORMSG(
"DiscField::read - the total field domain ");
163 ERRORMSG(
"DiscField::read - the DiscField domain ");
205 for (
unsigned int sf=0; sf <
numFiles(); ++sf) {
209 int outputDatafd = (-1);
212 std::vector<DFOffsetData<Dim,T> > offdata;
244 for (
int vn=0; vn < vnodes; ++vn) {
251 if (! vnodeblock.
touches(readDomain)) {
261 offdata[vn].isCompressed);
266 currblock[msdim] =
Index(vnodeblock[msdim].first() - 1,
267 vnodeblock[msdim].first() - 1);
268 for (
unsigned int md = (msdim+1); md <
Dim; ++md)
269 currblock[md] =
Index(vnodeblock[md].first(),vnodeblock[md].first());
277 int unread = vnodeblock.
size();
284 bool incrhigher=(currblock[msdim].last()==vnodeblock[msdim].last());
285 int a = (incrhigher ?
286 vnodeblock[msdim].first() :
287 currblock[msdim].last() + 1);
288 int b = a + chunkblock[msdim].length() - 1;
289 if (b > vnodeblock[msdim].last())
290 b = vnodeblock[msdim].last();
293 currblock[msdim] =
Index(a, b);
297 for (
unsigned int cd = (msdim+1); cd <
Dim; ++cd) {
298 if (currblock[cd].last() < vnodeblock[cd].last()) {
300 currblock[cd] =
Index(currblock[cd].first() + 1,
301 currblock[cd].last() + 1);
305 currblock[cd] =
Index(vnodeblock[cd].first(),
306 vnodeblock[cd].first());
314 int nelems = currblock.
size();
318 if (!offdata[vn].isCompressed && seekpos < 0) {
319 seekpos = offdata[vn].offset *
sizeof(
T);
324 if (! currblock.
touches(readDomain)) {
327 seekpos += readbytes;
339 if (!offdata[vn].isCompressed) {
341 if (outputDatafd < 0) {
353 long nbytes = maxsize*
sizeof(
T);
358 T * readbuffer = buffer;
364 seekpos += readbytes;
367 read_data(outputDatafd, readbuffer, readbytes, readoffset);
378 int remaining = readDomainSection.
size();
386 for (rv_i = range.first; rv_i != range.second; ++rv_i) {
392 int rnode = (*rv_i).second->getNode();
398 LFI cbi(buffer, ri, currblock, offdata[vn].compressedVal);
400 cbi.putMessage(*msg,
false);
404 remaining -= ri.
size();
410 for (; remaining > 0 && lf_i != f.
end_if(); ++lf_i) {
425 offdata[vn].isCompressed &&
431 LFI rhs_i(buffer, ri, currblock, offdata[vn].compressedVal);
443 LFI lhs_i = lf.
begin(ri);
446 Expr_t(lhs_i,rhs_i).apply();
454 int bsize = ri.
size();
462 Ippl::abort(
"remaining > 0 at end of box0 vnode read!!!");
468 if (outputDatafd >= 0)
474 while (expected > 0) {
484 T rhs_compressed_data;
485 LFI rhs_i(rhs_compressed_data);
486 rhs_i.getMessage(*msg);
490 bool foundlf =
false;
491 for (; lf_i != f.
end_if(); ++lf_i) {
502 (*rhs_i == *lf.
begin())) ) {
512 LFI lhs_i = lf.
begin(ro);
515 Expr_t(lhs_i,rhs_i).apply();
519 expected -= ro.
size();
531 ERRORMSG(
"Did not find destination local vnode for received domain ");
533 Ippl::abort(
"DID NOT FIND DESINATION LOCAL VNODE IN DISCFIELD::READ");
571 template <
class T,
class M,
class C>
576 template <
class T,
class M,
class C>
578 unsigned int varID) {
579 return read(f, readDomain, varID, 0);
582 template <
class T,
class M,
class C>
587 template <
class T,
class M,
class C>
589 return read(f, readDomain, 0, 0);
592 template <
class T,
class M,
class C>
614 template<
class T,
class M,
class C>
619 ERRORMSG(
"Cannot write in DiscField::write - config file error."<<
endl);
624 ERRORMSG(
"DiscField::write called for DiscField opened for read."<<
endl);
629 ERRORMSG(varID <<
" is a bad variable ID in DiscField::write." <<
endl);
634 ERRORMSG(
"DiscField:write - attempt to overwrite Field " << varID);
659 ERRORMSG(
"DiscField::write - all Field's must have the same ");
660 ERRORMSG(
"global domain in a single DiscField.\n");
676 for (
unsigned int i=0; i <
NumFields; ++i)
715 ".offset", std::string(
"a"));
716 int wVarID = (int)varID;
717 if (fwrite(&wVarID,
sizeof(
int), 1, outputOffset) != 1) {
718 ERRORMSG(
"DiscField::write - cannot write field number to .offset ");
721 fclose(outputOffset);
733 int fromothers = unreceived - layout.
size_iv();
741 while (unreceived > 0) {
744 bool checkremote = (fromothers > 0);
745 while (checkremote) {
757 T rhs_compressed_data;
758 LFI cbi(rhs_compressed_data);
759 cbi.getMessage(*msg);
777 if (local != f.
end_if()) {
792 if (outputDatafd >= 0)
796 if (outputOffset != 0)
797 fclose(outputOffset);
812 cbi.putMessage(*msg,
false);
832 template<
class T,
class M,
class C>
921 void initialize(
const char* base,
const char* config,
922 const char* typestr,
unsigned int numFields);
929 FILE *
open_df_file(
const std::string& fnm,
const std::string& suffix,
930 const std::string&
mode);
937 int open_df_file_fd(
const std::string& fnm,
const std::string& suf,
int flags);
1067 long elems = owned.
size();
1069 long chunksize = chunkbytes /
sizeof(
T);
1070 if (chunksize < 1 || chunksize > elems)
1083 int needwrite = elems;
1084 while (needwrite > 0) {
1086 int amount = chunksize;
1087 if (amount > needwrite)
1094 size_t nbytes = amount*
sizeof(
T);
1106 T *bufend = buffer + amount;
1107 for ( ; bufptr != bufend; ++bufptr, ++cbi)
1108 new (bufptr)
T(*cbi);
1119 if (::lseek(outputDatafd, seekoffset, SEEK_SET) == seekoffset) {
1120 char *wbuf = (
char *)buffer;
1121 nout =
::write(outputDatafd, wbuf, nbytes);
1131 ERRORMSG(
"Seek error in DiscField::write_offset_and_data" <<
endl);
1132 ERRORMSG(
"Could not seek to position " << seekoffset <<
endl);
1136 if (nout != nbytes) {
1137 ERRORMSG(
"Write error in DiscField::write_offset_and_data" <<
endl);
1138 ERRORMSG(
"Could not write " << nbytes <<
" bytes." <<
endl);
1143 needwrite -= amount;
1155 ERRORMSG(
"Write error in DiscField::write_offset_and_data" <<
endl);
1167 unsigned int record,
1174 ".offset", std::string(
"r"));
1180 if (fseek(outputOffset, seekpos, SEEK_SET) != 0) {
1181 ERRORMSG(
"Error seeking to position " << static_cast<long>(seekpos));
1184 fclose(outputOffset);
1190 unsigned int checked = 0;
1194 if (fread(&rVarID,
sizeof(
int), 1, outputOffset) != 1) {
1195 ERRORMSG(
"Error reading field ID from .offset file" <<
endl);
1197 fclose(outputOffset);
1202 if ((
unsigned int) rVarID == varID) {
1205 offdata.resize(vnodes);
1207 offdata.size(), outputOffset);
1208 if (result != offdata.size()) {
1209 ERRORMSG(
"Read error in DiscField::find_file_in_offset" <<
endl);
1210 ERRORMSG(
"Results is " << result <<
", should be ");
1212 ERRORMSG(
"outputOffset is " << (
void *)outputOffset <<
endl);
1214 fclose(outputOffset);
1219 fclose(outputOffset);
1227 if (fseek(outputOffset, seekpos, SEEK_SET) != 0) {
1228 ERRORMSG(
"Error seeking to position " << static_cast<long>(seekpos));
1231 fclose(outputOffset);
1237 ERRORMSG(
"Could not find data for field " << varID <<
" of record ");
1240 fclose(outputOffset);
1254 int &vnodes,
int &maxsize,
1264 vnodes = offdata.size();
1288 int nextvnode = pernode;
1303 int numvnodes = pernode;
1313 msg->
put(numvnodes);
1314 if (numvnodes > 0) {
1317 msg->
putmsg(static_cast<void *>(&(offdata[nextvnode])),
1326 nextvnode += numvnodes;
1331 if ((
unsigned int) nextvnode != offdata.size())
1332 Ippl::abort(
"ERROR: Could not give away all my vnodes!");
1345 offdata.resize(vnodes);
1358 for (
int v=0; v < vnodes; ++v) {
1362 if (dom.
touches(readDomain)) {
1364 int msdim = (
Dim-1);
1367 offdata[v].isCompressed);
1370 int dsize = chunkblock.
size();
1371 if (dsize > maxsize) {
1393 off_t seekoffset = seekpos;
1394 size_t nbytes = readsize;
1402 if (::lseek(outputDatafd, seekoffset, SEEK_SET) == seekoffset) {
1403 char *rbuf = (
char *)buffer;
1404 nout =
::read(outputDatafd, rbuf, nbytes);
1414 ERRORMSG(
"Seek error in DiscField::read_data" <<
endl);
1415 ERRORMSG(
"Could not seek to position " << seekoffset <<
endl);
1419 if (nout != nbytes) {
1420 ERRORMSG(
"Read error in DiscField::read_data" <<
endl);
1421 ERRORMSG(
"Could not read " << nbytes <<
" bytes." <<
endl);
1435 for (
unsigned int i=0; i <
Dim; ++i) {
1437 int stride = *(dptr + 1);
1438 int length = *(dptr + 2);
1439 domain[i] =
Index(first, first + (length - 1)*stride, stride);
1450 for (
unsigned int i=0; i <
Dim; ++i) {
1452 *dptr++ = domain[i].first();
1453 *dptr++ = domain[i].stride();
1454 *dptr++ = domain[i].length();
1471 #endif // DISC_FIELD_H
Expression Expr_t
type of an expression
unsigned int mySMP() const
Message & put(const T &val)
const NDIndex< Dim > & getOwned() const
std::vector< bool > ValidField
bool write(Field< T, Dim, M, C > &f)
Message & putMessage(Message &m) const
std::vector< int > * NumVnodes
bool read_NDIndex(FILE *, NDIndex< Dim > &)
unsigned int get_NumRecords() const
unsigned int getNumFiles() const
bool touches(const NDIndex< Dim > &) const
const NDIndex< Dim > & getAllocated() const
unsigned int getNumSMPNodes() const
touch_range_dv touch_range_rdv(const NDIndex< Dim > &domain, const GuardCellSizes< Dim > &gc=gc0()) const
bool make_globalID(FieldLayout< Dim > &)
bool read(Field< T, Dim, M, C > &f, const NDIndex< Dim > &readDomain)
bool write_NDIndex(FILE *, const NDIndex< Dim > &)
Message * receive_block(int &node, int &tag)
DiscField(const char *fname, const char *config, unsigned int numFields, const char *typestr=0)
bool compressible() const
unsigned int getSMPBox0() const
void distribute_offsets(std::vector< DFOffsetData< Dim, T > > &offdata, int &vnodes, int &maxsize, const NDIndex< Dim > &readDomain)
const char * get_TypeString()
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
bool IsCompressed() const
std::vector< int > * VnodeTally
Message & setDelete(const bool c)
void Uncompress(bool fill_domain=true)
int next_tag(int t, int s=1000)
void fillGuardCellsIfNotDirty() const
Message & get(const T &cval)
void write_offset_and_data(FILE *outputOffset, int outputDatafd, CompressedBrickIterator< T, Dim > &cbi, const NDIndex< Dim > &owned)
Message & putmsg(void *, int, int=0)
Inform & endl(Inform &inf)
Timing::TimerRef TimerRef
void initialize(const char *base, const char *config, const char *typestr, unsigned int numFields)
unsigned int numSMPs() const
unsigned int fileSMPs() const
static void startTimer(TimerRef t)
Message & setCopy(const bool c)
void offset_data_to_domain(DFOffsetData< Dim, T > &offdata, NDIndex< Dim > &domain)
static void * resize(long sz)
bool read(Field< T, Dim, M, C > &f)
if write to the Free Software Temple MA USA Also add information on how to contact you by electronic and paper mail If the program is make it output a short notice like this when it starts in an interactive mode
unsigned int numSMPs() const
bool read_data(int outputDatafd, T *buffer, Offset_t readsize, Offset_t seekpos)
bool contains(const NDIndex< Dim > &a) const
static Communicate * Comm
unsigned int fileSMPs() const
void PETE_apply(const OpPeriodic< T > &, T &a, const T &b)
void query(int &numRecords, int &numFields, std::vector< int > &size) const
unsigned int DataDimension
void domain_to_offset_data(const NDIndex< Dim > &domain, DFOffsetData< Dim, T > &offdata)
unsigned int myBox0() const
Layout_t & getLayout() const
unsigned int getSMPNode(unsigned int n) const
bool parse_config(const char *, bool)
unsigned int pNodesPerSMP(unsigned int node) const
static bool perSMPParallelIO()
bool send(Message *, int node, int tag, bool delmsg=true)
NDIndex< Dim > get_Domain() const
const std::string & getFilename(unsigned int fn) const
NDIndex< Dim > chunk_domain(const NDIndex< Dim > &currblock, int chunkelems, int &msdim, bool iscompressed)
void getMessage_iter(Message &m, OutputIterator o)
bool read(Field< T, Dim, M, C > &f, const NDIndex< Dim > &readDomain, unsigned int varID)
bool IsCompressed() const
Message * receive(int &node, int &tag)
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
bool read(Field< T, Dim, M, C > &f, unsigned int varID)
unsigned int numFiles() const
int compute_expected(const FieldLayout< Dim > &, const NDIndex< Dim > &)
bool read(Field< T, Dim, M, C > &f, unsigned int varID, unsigned int record)
unsigned int get_NumFields() const
unsigned int numFiles(unsigned int s) const
const char * get_DiscType()
unsigned int mySMP() const
ac_id_larray::iterator iterator_if
static TimerRef getTimer(const char *nm)
bool read(Field< T, Dim, M, C > &f, const NDIndex< Dim > &readDomain, unsigned int varID, unsigned int record)
bool write(Field< T, Dim, M, C > &f, unsigned int varID)
unsigned int getNodeSMPIndex(unsigned int n) const
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it contains
Message & getMessage(Message &m)
FILE * open_df_file(const std::string &fnm, const std::string &mode)
static void stopTimer(TimerRef t)
const NDIndex< Dim > & getDomain() const
unsigned int pNodesPerSMP(unsigned int node) const
int open_df_file_fd(const std::string &fnm, const std::string &suf, int flags)
DiscField & operator=(const DiscField< Dim > &)
static void abort(const char *=0)
const iterator & begin() const
int read_layout(int record, int sf)
vmap< NDIndex< Dim >, int > GlobalIDList_t
unsigned int get_Dimension() const
bool read_offset(unsigned int varID, unsigned int record, unsigned int sf, std::vector< DFOffsetData< Dim, T > > &offdata, int vnodes)
ac_id_vnodes::size_type size_iv() const