Commit 6326e7ba authored by Kirill Terekhov's avatar Kirill Terekhov

Features

Better handling of bad xml files, avoid infinite loops.

More verbosity in parallel part
parent 234b8df5
......@@ -179,67 +179,68 @@ namespace INMOST
void Mesh::SynchronizeMarker(MarkerType marker, ElementType mask, SyncBitOp op)
{
ENTER_FUNC();
#if defined(USE_MPI)
if( m_state == Mesh::Parallel )
{
Tag t = CreateTag("TEMP_SYNC_MARKER",DATA_BULK,mask,mask,1);
//workaround for old gcc compiler
const Element::Status SGhost = Element::Ghost;
const Element::Status SAny = Element::Any;
Element::Status Expr = (Element::Shared | ((op != SYNC_BIT_SET) ? SGhost : SAny));
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
if( it->GetMarker(marker) && (it->GetStatus() & Expr) )
it->Bulk(t) = 1;
switch(op)
{
case SYNC_BIT_SET:
ExchangeData(t,mask,0);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( it->GetStatus() == Element::Ghost )
case SYNC_BIT_SET:
ExchangeData(t,mask,0);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( it->HaveData(t) ) it->SetMarker(marker); else it->RemMarker(marker);
if( it->GetStatus() == Element::Ghost )
{
if( it->HaveData(t) ) it->SetMarker(marker); else it->RemMarker(marker);
}
}
}
break;
case SYNC_BIT_OR:
ReduceData(t,mask,0,UnpackSyncMarkerOR);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( it->GetStatus() & (Element::Ghost | Element::Shared) )
break;
case SYNC_BIT_OR:
ReduceData(t,mask,0,UnpackSyncMarkerOR);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( !it->GetMarker(marker) && it->HaveData(t) ) it->SetMarker(marker);
if( it->GetStatus() & (Element::Ghost | Element::Shared) )
{
if( !it->GetMarker(marker) && it->HaveData(t) ) it->SetMarker(marker);
}
}
}
break;
case SYNC_BIT_AND:
ReduceData(t,mask,0,UnpackSyncMarkerAND);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( it->GetStatus() & (Element::Ghost | Element::Shared))
break;
case SYNC_BIT_AND:
ReduceData(t,mask,0,UnpackSyncMarkerAND);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( it->HaveData(t) && it->Bulk(t) ) it->SetMarker(marker); else it->RemMarker(marker);
if( it->GetStatus() & (Element::Ghost | Element::Shared))
{
if( it->HaveData(t) && it->Bulk(t) ) it->SetMarker(marker); else it->RemMarker(marker);
}
}
}
break;
case SYNC_BIT_XOR:
ReduceData(t,mask,0,UnpackSyncMarkerXOR);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( it->GetStatus() & (Element::Ghost | Element::Shared))
break;
case SYNC_BIT_XOR:
ReduceData(t,mask,0,UnpackSyncMarkerXOR);
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); ++it)
{
if( it->HaveData(t) && it->Bulk(t) ) it->SetMarker(marker); else it->RemMarker(marker);
if( it->GetStatus() & (Element::Ghost | Element::Shared))
{
if( it->HaveData(t) && it->Bulk(t) ) it->SetMarker(marker); else it->RemMarker(marker);
}
}
}
break;
break;
}
DeleteTag(t,mask);
}
#else//USE_MPI
......@@ -247,29 +248,34 @@ namespace INMOST
(void) mask;
(void) op;
#endif//USE_MPI
EXIT_FUNC();
}
ElementType Mesh::SynchronizeElementType(ElementType etype)
{
ENTER_FUNC();
ElementType etypeout = etype;
#if defined(USE_MPI)
MPI_Allreduce(&etype,&etypeout,1,INMOST_MPI_DATA_BULK_TYPE,MPI_BOR,GetCommunicator());
REPORT_MPI(MPI_Allreduce(&etype,&etypeout,1,INMOST_MPI_DATA_BULK_TYPE,MPI_BOR,GetCommunicator()));
#endif//USE_MPI
return etypeout;
}
Storage::integer Mesh::TotalNumberOf(ElementType mask)
{
ENTER_FUNC();
Storage::integer number = 0, ret = 0;
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); it++)
if( it->GetStatus() != Element::Ghost ) number++;
ret = number;
#if defined(USE_MPI)
MPI_Allreduce(&number,&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Allreduce(&number,&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm));
#endif//USE_MPI
EXIT_FUNC();
return ret;
}
Storage::integer Mesh::EnumerateSet(const ElementSet & set, const Tag & num_tag, Storage::integer start, bool define_sparse)
{
ENTER_FUNC();
Storage::integer shift = 0, ret = 0;
ElementType mask = CELL | FACE | EDGE | NODE;
#if defined(USE_MPI)
......@@ -277,7 +283,7 @@ namespace INMOST
for(ElementSet::iterator it = set.Begin(); it != set.End(); it++)
if( it->GetStatus() != Element::Ghost && (define_sparse || it->HaveData(num_tag)) )
number++;
MPI_Scan(&number,&shift,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Scan(&number,&shift,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm));
shift -= number;
#endif//USE_MPI
shift += start;
......@@ -290,44 +296,48 @@ namespace INMOST
ExchangeData(num_tag,mask,0);
ret = shift;
#if defined(USE_MPI)
MPI_Bcast(&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,GetProcessorsNumber()-1,comm);
REPORT_MPI(MPI_Bcast(&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,GetProcessorsNumber()-1,comm));
//MPI_Allreduce(&shift,&ret,1,INMOST_DATA_INTEGER_TYPE,MPI_MAX,comm);
#endif//USE_MPI
EXIT_FUNC();
return ret;
}
Storage::integer Mesh::Enumerate(const HandleType * set, enumerator n, const Tag & num_tag, Storage::integer start, bool define_sparse)
{
ENTER_FUNC();
Storage::integer shift = 0, ret = 0;
ElementType mask = CELL | FACE | EDGE | NODE;
#if defined(USE_MPI)
Storage::integer number = 0;
for(const HandleType * it = set; it != set+n; ++it)
if( GetStatus(*it) != Element::Ghost && (define_sparse || HaveData(*it,num_tag))) number++;
MPI_Scan(&number,&shift,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Scan(&number,&shift,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm));
shift -= number;
#endif//USE_MPI
shift += start;
for(const HandleType * it = set; it != set+n; ++it)
if( GetStatus(*it) == Element::Owned && (define_sparse || HaveData(*it,num_tag))) Integer(*it,num_tag) = shift++;
for(const HandleType * it = set; it != set+n; ++it)
for(const HandleType * it = set; it != set+n; ++it)
if( GetStatus(*it) == Element::Shared && (define_sparse || HaveData(*it,num_tag))) Integer(*it,num_tag) = shift++;
ExchangeData(num_tag,mask,0);
ret = shift;
#if defined(USE_MPI)
MPI_Bcast(&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,GetProcessorsNumber()-1,comm);
REPORT_MPI(MPI_Bcast(&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,GetProcessorsNumber()-1,comm));
//MPI_Allreduce(&shift,&ret,1,INMOST_DATA_INTEGER_TYPE,MPI_MAX,comm);
#endif//USE_MPI
EXIT_FUNC();
return ret;
}
Storage::integer Mesh::Enumerate(ElementType mask, Tag num_tag, Storage::integer start, bool define_sparse)
{
ENTER_FUNC();
Storage::integer shift = 0, ret = 0;
#if defined(USE_MPI)
Storage::integer number = 0;
for(Mesh::iteratorElement it = BeginElement(mask); it != EndElement(); it++)
if( it->GetStatus() != Element::Ghost && (define_sparse || it->HaveData(num_tag)) )
number++;
MPI_Scan(&number,&shift,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Scan(&number,&shift,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm));
shift -= number;
#endif//USE_MPI
shift += start;
......@@ -340,188 +350,217 @@ namespace INMOST
ExchangeData(num_tag,mask,0);
ret = shift;
#if defined(USE_MPI)
MPI_Bcast(&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,GetProcessorsNumber()-1,comm);
REPORT_MPI(MPI_Bcast(&ret,1,INMOST_MPI_DATA_INTEGER_TYPE,GetProcessorsNumber()-1,comm));
//MPI_Allreduce(&shift,&ret,1,INMOST_DATA_INTEGER_TYPE,MPI_MAX,comm);
#endif//USE_MPI
EXIT_FUNC();
return ret;
}
Storage::real Mesh::Integrate(Storage::real input)
{
ENTER_FUNC();
Storage::real output = input;
#if defined(USE_MPI)
MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_SUM,comm));
#else//USE_MPI
(void) input;
#endif//USE_MPI
EXIT_FUNC();
return output;
}
Storage::integer Mesh::Integrate(Storage::integer input)
{
ENTER_FUNC();
Storage::integer output = input;
#if defined(USE_MPI)
MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm));
#else//USE_MPI
(void) input;
#endif//USE_MPI
EXIT_FUNC();
return output;
}
void Mesh::Integrate(Storage::real * input, Storage::integer size)
{
ENTER_FUNC();
#if defined(USE_MPI)
static dynarray<Storage::real,64> temp;
temp.resize(size);
memcpy(temp.data(),input,sizeof(Storage::real)*size);
MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_REAL_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_REAL_TYPE,MPI_SUM,comm));
#else//USE_MPI
(void) input;
(void) size;
(void) input;
(void) size;
#endif//USE_MPI
EXIT_FUNC();
}
void Mesh::Integrate(Storage::integer * input, Storage::integer size)
{
ENTER_FUNC();
#if defined(USE_MPI)
static dynarray<Storage::integer,64> temp;
temp.resize(size);
memcpy(temp.data(),input,sizeof(Storage::integer)*size);
MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm));
#else//USE_MPI
(void) input;
(void) size;
(void) size;
#endif//USE_MPI
EXIT_FUNC();
}
Storage::integer Mesh::ExclusiveSum(Storage::integer input)
{
ENTER_FUNC();
Storage::integer output = 0;
#if defined(USE_MPI)
MPI_Scan(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Scan(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_SUM,comm));
output -= input;
#else//USE_MPI
(void) input;
#endif//USE_MPI
EXIT_FUNC();
return output;
}
Storage::real Mesh::Integrate(const Tag & t, enumerator entry, ElementType mask)
{
ENTER_FUNC();
Storage::real output = 0, input = 0;
for(iteratorElement it = BeginElement(mask); it != EndElement(); it++)
if( GetStatus(*it) != Element::Ghost && HaveData(*it,t) )
if( GetStatus(*it) != Element::Ghost && HaveData(*it,t) )
{
real_array arr = RealArray(*it,t);
if( arr.size() > entry ) input += arr[entry];
}
output = input;
#if defined(USE_MPI)
MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_SUM,comm);
REPORT_MPI(MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_SUM,comm));
#endif//USE_MPI
EXIT_FUNC();
return output;
}
Storage::real Mesh::AggregateMax(Storage::real input)
{
ENTER_FUNC();
Storage::real output = input;
#if defined(USE_MPI)
MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_MAX,comm);
REPORT_MPI(MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_MAX,comm));
#else //USE_MPI
(void) input;
#endif //USE_MPI
EXIT_FUNC();
return output;
}
Storage::integer Mesh::AggregateMax(Storage::integer input)
{
ENTER_FUNC();
Storage::integer output = input;
#if defined(USE_MPI)
MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MAX,comm);
REPORT_MPI(MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MAX,comm));
#else //USE_MPI
(void) input;
#endif //USE_MPI
EXIT_FUNC();
return output;
}
void Mesh::AggregateMax(Storage::real * input, Storage::integer size)
{
ENTER_FUNC();
#if defined(USE_MPI)
static dynarray<Storage::real,64> temp;
temp.resize(size);
memcpy(temp.data(),input,sizeof(Storage::real)*size);
MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_REAL_TYPE,MPI_MAX,comm);
REPORT_MPI(MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_REAL_TYPE,MPI_MAX,comm));
#else//USE_MPI
(void) input;
(void) size;
(void) size;
#endif//USE_MPI
EXIT_FUNC();
}
void Mesh::AggregateMax(Storage::integer * input, Storage::integer size)
{
ENTER_FUNC();
#if defined(USE_MPI)
static dynarray<Storage::integer,64> temp;
temp.resize(size);
memcpy(temp.data(),input,sizeof(Storage::integer)*size);
MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MAX,comm);
REPORT_MPI(MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MAX,comm));
#else//USE_MPI
(void) input;
(void) size;
(void) size;
#endif//USE_MPI
EXIT_FUNC();
}
Storage::real Mesh::AggregateMin(Storage::real input)
{
ENTER_FUNC();
Storage::real output = input;
#if defined(USE_MPI)
MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_MIN,comm);
REPORT_MPI(MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_REAL_TYPE,MPI_MIN,comm));
#else //USE_MPI
(void) input;
#endif //USE_MPI
EXIT_FUNC();
return output;
}
Storage::integer Mesh::AggregateMin(Storage::integer input)
{
ENTER_FUNC();
Storage::integer output = input;
#if defined(USE_MPI)
MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MIN,comm);
REPORT_MPI(MPI_Allreduce(&input,&output,1,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MIN,comm));
#else //USE_MPI
(void) input;
#endif //USE_MPI
EXIT_FUNC();
return output;
}
void Mesh::AggregateMin(Storage::real * input, Storage::integer size)
{
ENTER_FUNC();
#if defined(USE_MPI)
static dynarray<Storage::real,64> temp;
temp.resize(size);
memcpy(temp.data(),input,sizeof(Storage::real)*size);
MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_REAL_TYPE,MPI_MIN,comm);
REPORT_MPI(MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_REAL_TYPE,MPI_MIN,comm));
#else//USE_MPI
(void) input;
(void) size;
(void) size;
#endif//USE_MPI
EXIT_FUNC();
}
void Mesh::AggregateMin(Storage::integer * input, Storage::integer size)
{
ENTER_FUNC();
#if defined(USE_MPI)
static dynarray<Storage::integer,64> temp;
temp.resize(size);
memcpy(temp.data(),input,sizeof(Storage::integer)*size);
MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MIN,comm);
REPORT_MPI(MPI_Allreduce(temp.data(),input,size,INMOST_MPI_DATA_INTEGER_TYPE,MPI_MIN,comm));
#else//USE_MPI
(void) input;
(void) size;
(void) size;
#endif//USE_MPI
EXIT_FUNC();
}
INMOST_MPI_Comm Mesh::GetCommunicator() const
{
#if defined(USE_MPI)
......
......@@ -329,7 +329,7 @@ namespace INMOST
}
if( get_iStream().fail() )
{
Report("Stream failed while getting the char");
Report("Stream failed while getting the char, state %s",StateName(_state).c_str());
WAITNL;
_state = Failure;
}
......@@ -359,6 +359,16 @@ namespace INMOST
while(!done)
{
c = GetChar();
if( _state == Failure )
{
Report("Unexpected failure while skipping comments");
done = true;
}
else if( _state == EndOfFile )
{
Report("Unexpected end of file while skipping comments");
done = true;
}
tmp[ntmp] = c;
if( tmp[ntmp] == '>' && tmp[(ntmp-1+3)%3] == '-' && tmp[(ntmp-2+3)%3] == '-' )
{
......@@ -373,6 +383,16 @@ namespace INMOST
while(!done)
{
c = GetChar();
if( _state == Failure )
{
Report("Unexpected failure while skipping comments");
done = true;
}
else if( _state == EndOfFile )
{
Report("Unexpected end of file while skipping comments");
done = true;
}
tmp[ntmp] = c;
if( tmp[ntmp] == '>' && tmp[(ntmp-1+2)%2] == '?' )
{
......@@ -505,7 +525,7 @@ namespace INMOST
}
else if(!isspace(c))
{
if( verbose > 1 ) Report("info: encountered %c instead of expected '<' symbol",c);
if( verbose > 1 ) Report("info: encountered %x instead of expected '<'(%x) symbol",c,'<');
RetChar();
return false;
}
......@@ -643,9 +663,9 @@ namespace INMOST
if( verbose > 1 ) Report("info: closed tag");
return 2; //tag was halted with />
}
Report("Encountered '%c%c' while expecting '/>' for tag closing",tmp[0],tmp[1]);
Report("Encountered %x%x while expecting '/>'(%x%x) for tag closing",tmp[0],tmp[1],'/','>');
}
Report("Encountered '%c' while expecting '>' for tag closing",tmp[0]);
Report("Encountered %x while expecting '>'(%x) for tag closing",tmp[0],'>');
_state = Failure;
return 0;
}
......@@ -726,7 +746,10 @@ namespace INMOST
char c;
if( _state == EndTag ) return "";
if( _state != WaitAttribute )
Report("Attribute was not expected, state %s",StateName(_state).c_str());
{
Report("Attribute name was not expected, state %s",StateName(_state).c_str());
done = true;
}
while(!done)
{
c = GetChar();
......@@ -807,7 +830,10 @@ namespace INMOST
char c;
if( _state == EndTag ) return "";
if( _state != WaitAttributeValue )
Report("Attribute was not expected, state %s",StateName(_state).c_str());
{
Report("Attribute value was not expected, state %s",StateName(_state).c_str());
done = true;
}
while(!done)
{
c = GetChar();
......@@ -1422,7 +1448,9 @@ namespace INMOST
XMLTag ret;
XMLAttrib attr;
bool istag = ExpectOpenTag();
if( !istag )
if( _state == Failure || _state == EndOfFile )
ret.finish = 0; //there is an error
else if( !istag )
ret.finish = 5; //there is no tag opening, probably pure text
else
{
......@@ -1438,7 +1466,7 @@ namespace INMOST
{
if( verbose > 1 ) Report("info: reading tag attributes");
attr.name = AttributeName();
while(!isTagEnded())
while(!isTagEnded() && !isFailure() && !isEof())
{
attr.value = AttributeValue();
if( attr.name == "Include" ) //some file was included
......@@ -1490,6 +1518,16 @@ namespace INMOST
do
{
c = GetChar();
if( _state == Failure )
{
Report("Unexpected failure while searching for %s",stop.c_str());
break;
}
else if( _state == Failure )
{
Report("Unexpected end of file while searching for %s",stop.c_str());
break;
}
ret.push_back(c);
}
while( ret.size() < stop.size() || ret.substr(ret.size()-stop.size()) != stop );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment