Parallel IO before round 2

This commit is contained in:
Hamidreza Norouzi 2023-10-28 12:09:40 +03:30
parent 66fc880fcd
commit d65aa02cbb
39 changed files with 1618 additions and 516 deletions

View File

@ -4,8 +4,6 @@ types/basicTypes/bTypesFunctions.cpp
types/basicTypes/Logical.cpp types/basicTypes/Logical.cpp
types/types.cpp types/types.cpp
globals/error.cpp globals/error.cpp
streams/token/tokenIO.cpp streams/token/tokenIO.cpp
@ -35,10 +33,16 @@ dictionary/entry/dataEntry.cpp
dictionary/twoPartEntry/twoPartEntry.cpp dictionary/twoPartEntry/twoPartEntry.cpp
containers/Vector/Vectors.cpp containers/Vector/Vectors.cpp
containers/Field/Fields.cpp
repository/IOobject/objectFile.cpp repository/IOobject/objectFile.cpp
repository/IOobject/IOfileHeader.cpp repository/IOobject/IOfileHeader.cpp
repository/IOobject/IOobject.cpp repository/IOobject/IOobject.cpp
repository/IOobject/IOPattern.cpp
structuredData/line/line.cpp
structuredData/infinitePlane/infinitePlane.cpp
structuredData/plane/plane.cpp
) )

View File

@ -18,7 +18,7 @@ Licence:
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
template<template<class, class> class VectorField, class T, class PropType> /*template<template<class, class> class VectorField, class T, class PropType>
bool pFlow::Field<VectorField, T, PropType>::readUniform bool pFlow::Field<VectorField, T, PropType>::readUniform
( (
iIstream& is, iIstream& is,
@ -94,10 +94,10 @@ bool pFlow::Field<VectorField, T, PropType>::readNonUniform
return true; return true;
} }*/
template<template<class, class> class VectorField, class T, class PropType> /*template<template<class, class> class VectorField, class T, class PropType>
bool pFlow::Field<VectorField, T, PropType>::readField bool pFlow::Field<VectorField, T, PropType>::readField
( (
iIstream& is, iIstream& is,
@ -177,6 +177,50 @@ bool pFlow::Field<VectorField, T, PropType>::writeField(iOstream& os)const
os.endEntry(); os.endEntry();
return true;
}*/
template<template<class, class> class VectorField, class T, class PropType>
bool pFlow::Field<VectorField, T, PropType>::read
(
iIstream& is,
IOPattern::IOType iotype
)
{
bool tokenFound;
tokenFound = is.findToken(fieldKey_);
if( !tokenFound )
{
ioErrorInFile( is.name(), is.lineNumber() ) <<
" error in searching for filedkey " << fieldKey_<<endl;
return false;
}
if( !VectorType::read(is, iotype) )
{
ioErrorInFile(is.name(), is.lineNumber())<<
"error in reading field data from field "<< this->name()<<endl;
}
is.readEndStatement("Field::read");
return true;
}
template<template<class, class> class VectorField, class T, class PropType>
bool pFlow::Field<VectorField, T, PropType>::write(
iOstream& os,
IOPattern::IOType iotype)const
{
os.writeWordKeyword(fieldKey_)<<endl;
VectorType::write(os, iotype);
os.endEntry();
return true; return true;
} }

View File

@ -21,8 +21,13 @@ Licence:
#ifndef __Field_hpp__ #ifndef __Field_hpp__
#define __Field_hpp__ #define __Field_hpp__
#include "VectorSingle.hpp" //#include "VectorSingle.hpp"
#include "vocabs.hpp" //#include "vocabs.hpp"
#include "types.hpp"
#include "Vector.hpp"
namespace pFlow namespace pFlow
{ {
@ -62,144 +67,108 @@ protected:
const word fieldKey_ = FKey; const word fieldKey_ = FKey;
bool readUniform( iIstream& is, size_t len, bool readLength = true); /*bool readUniform( iIstream& is, size_t len, bool readLength = true);
bool readNonUniform( iIstream& is, size_t len); bool readNonUniform( iIstream& is, size_t len);*/
public: public:
// - type info /// type info
TypeInfoTemplateNV2("Field", T, VectorType::memoerySpaceName()); TypeInfoTemplateNV2("Field", T, VectorType::memoerySpaceName());
//// - Constructors //// - Constructors
// construct an empty Filed with default fieldKey /// construct an empty Filed with default fieldKey
Field() Field()
: :
VectorType() VectorType()
{} {}
// construct an empty Field with fieldKey
Field(const word& fieldKey) /// Construct an empty field with name and fieldKey
:
VectorType(),
fieldKey_(fieldKey)
{}
// construct an empty field with name and fieldKey
Field(const word& name, const word& fieldKey) Field(const word& name, const word& fieldKey)
: :
VectorType(name), VectorType(name),
fieldKey_(fieldKey) fieldKey_(fieldKey)
{} {}
// construct an empty Filed with default fieldKey
Field(size_t len) /// Construct a field with name and fieldKey and specified len
:
VectorType(len)
{}
// construct an empty Field with fieldKey
Field(const word& fieldKey, size_t len)
:
VectorType(len),
fieldKey_(fieldKey)
{}
// construct an empty field with name and fieldKey
Field(const word& name, const word& fieldKey, size_t len) Field(const word& name, const word& fieldKey, size_t len)
: :
VectorType(name, len), VectorType(name, len),
fieldKey_(fieldKey) fieldKey_(fieldKey)
{} {}
// construct an empty Filed with default fieldKey and set vector to val
Field(size_t len, const T& val) /// Construct a field with name, fieldKey and
: /// set length to len and value to val
VectorType(len, val)
{}
// construct an empty Field with fieldKey and set vector to val
Field(const word& fieldKey, size_t len, const T& val)
:
VectorType(len, val),
fieldKey_(fieldKey)
{}
// construct an empty field with name and fieldKey and set vector to val
Field(const word& name, const word& fieldKey, size_t len, const T& val) Field(const word& name, const word& fieldKey, size_t len, const T& val)
: :
VectorType(name, len, val), VectorType(name, len, val),
fieldKey_(fieldKey) fieldKey_(fieldKey)
{} {}
// construct a field with capacity and len and default fieldKey /// Construct a field with name, fieldKey, capacity and len
Field(size_t capacity, size_t len, RESERVE)
:
VectorType(capacity, len, RESERVE())
{}
// construct an empty Field with fieldKey
Field(const word& fieldKey, size_t capacity, size_t len, RESERVE)
:
VectorType(capacity, len, RESERVE()),
fieldKey_(fieldKey)
{}
// construct an empty field with name and fieldKey
Field(const word& name, const word& fieldKey, size_t capacity, size_t len, RESERVE) Field(const word& name, const word& fieldKey, size_t capacity, size_t len, RESERVE)
: :
VectorType(name, capacity, len, RESERVE()), VectorType(name, capacity, len, RESERVE()),
fieldKey_(fieldKey) fieldKey_(fieldKey)
{} {}
// construct with vec and default fieldKey /// Construct a field with fieldKey and Vector vec
Field(const Vector<T>& vec)
:
VectorType(vec)
{}
// construct an empty Field with fieldKey
Field(const word& fieldKey, const Vector<T>& vec) Field(const word& fieldKey, const Vector<T>& vec)
: :
VectorType(vec), VectorType(vec.name(), vec.vectorField()),
fieldKey_(fieldKey) fieldKey_(fieldKey)
{} {}
// construct an empty field with name and fieldKey /// Construct a field with name, fieldKey and Vector vec
Field(const word& name, const word& fieldKey, const Vector<T>& vec) Field(const word& name, const word& fieldKey, const Vector<T>& vec)
:
VectorType(name, vec.vectorField()),
fieldKey_(fieldKey)
{}
/// Construct a field with name and fieldKey and std::vector
Field(const word& name, const word& fieldKey, const std::vector<T>& vec)
: :
VectorType(name, vec), VectorType(name, vec),
fieldKey_(fieldKey) fieldKey_(fieldKey)
{} {}
/// Copy construct with new name and fieldkey
// - copy construct with new name and fieldkey
Field(const word& name, const word& fieldKey, const FieldType& src): Field(const word& name, const word& fieldKey, const FieldType& src):
VectorType(name, src), VectorType(name, src),
fieldKey_(fieldKey) fieldKey_(fieldKey)
{} {}
// - default copy constructor /// Default copy constructor
Field(const FieldType&) = default; Field(const FieldType&) = default;
// - default copy assignment /// Copy assignment, name and fieldKey
FieldType& operator = (const FieldType&) = default; /// on the left hand side are preserved
FieldType& operator = (const FieldType& rhs)
{
if(&rhs == this) return *this;
VectorType::operator=(rhs);
return *this;
}
// - no move constructor /// Move constructor
Field(FieldType&&) = delete; Field(FieldType&&) = default;
// - no move assignment /// Move assignment
FieldType& operator = (FieldType&&) = delete; FieldType& operator = (FieldType&&) = default;
// - clone as a uniquePtr /// clone as a uniquePtr
INLINE_FUNCTION_H INLINE_FUNCTION_H
uniquePtr<FieldType> clone() const uniquePtr<FieldType> clone() const
{ {
return makeUnique<FieldType>(*this); return makeUnique<FieldType>(*this);
} }
// - clone as a raw pointer /// clone as a raw pointer
INLINE_FUNCTION_H INLINE_FUNCTION_H
FieldType* clonePtr()const FieldType* clonePtr()const
{ {
@ -208,31 +177,27 @@ public:
//// - Methods //// - Methods
/// return field key
const word& fieldKey()const const word& fieldKey()const
{ {
return fieldKey_; return fieldKey_;
} }
//// - IO operations //// - IO operations
bool readField(iIstream& is, const size_t len, bool resume, bool readLength = true); /*bool readField(iIstream& is, const size_t len, bool resume, bool readLength = true);
bool readField(iIstream& is, bool resume ); bool readField(iIstream& is, bool resume );
bool writeField(iOstream& os)const; bool writeField(iOstream& os)const;*/
bool read(iIstream& is, bool resume = false) bool read(iIstream& is, IOPattern::IOType iotype);
{
return readField(is, resume);
}
bool write(iOstream& os)const bool write(iOstream& os, IOPattern::IOType iotype )const;
{
return writeField(os);
}
}; };
@ -240,7 +205,7 @@ public:
template<template<class, class> class VectorField, class T, class PropType> template<template<class, class> class VectorField, class T, class PropType>
inline iIstream& operator >> (iIstream & is, Field<VectorField, T, PropType> & ifld ) inline iIstream& operator >> (iIstream & is, Field<VectorField, T, PropType> & ifld )
{ {
if( !ifld.readField(is, false) ) if( !ifld.read(is, IOPattern::MasterProcessor) )
{ {
ioErrorInFile (is.name(), is.lineNumber()); ioErrorInFile (is.name(), is.lineNumber());
fatalExit; fatalExit;
@ -252,7 +217,7 @@ template<template<class, class> class VectorField, class T, class PropType>
inline iOstream& operator << (iOstream& os, const Field<VectorField, T, PropType>& ofld ) inline iOstream& operator << (iOstream& os, const Field<VectorField, T, PropType>& ofld )
{ {
if( !ofld.writeField(os) ) if( !ofld.write(os, IOPattern::AllProcessorsDifferent) )
{ {
ioErrorInFile(os.name(), os.lineNumber()); ioErrorInFile(os.name(), os.lineNumber());
fatalExit; fatalExit;

View File

@ -23,7 +23,7 @@ Licence:
template class pFlow::Field<pFlow::VectorSingle, pFlow::int8>; template class pFlow::Field<pFlow::VectorSingle, pFlow::int8>;
template class pFlow::Field<pFlow::VectorSingle, pFlow::int8, pFlow::HostSpace>; /*template class pFlow::Field<pFlow::VectorSingle, pFlow::int8, pFlow::HostSpace>;
template class pFlow::Field<pFlow::VectorSingle, pFlow::int16>; template class pFlow::Field<pFlow::VectorSingle, pFlow::int16>;
@ -76,6 +76,6 @@ template class pFlow::Field<pFlow::VectorDual, pFlow::realx3>;
template class pFlow::Field<pFlow::VectorDual, pFlow::realx3x3>; template class pFlow::Field<pFlow::VectorDual, pFlow::realx3x3>;
template class pFlow::Field<pFlow::Vector, pFlow::word, pFlow::vecAllocator<pFlow::word>>; template class pFlow::Field<pFlow::Vector, pFlow::word, pFlow::vecAllocator<pFlow::word>>;*/

View File

@ -24,22 +24,17 @@ Licence:
#include "types.hpp" #include "types.hpp"
#include "Field.hpp" #include "Field.hpp"
#include "VectorSingle.hpp" #include "VectorSingle.hpp"
#include "VectorDual.hpp" //#include "VectorDual.hpp"
namespace pFlow namespace pFlow
{ {
using int8Field_D = Field<VectorSingle, int8>; using int8Field_D = Field<VectorSingle, int8>;
using int8Field_H = Field<VectorSingle, int8, HostSpace>; using int8Field_H = Field<VectorSingle, int8, HostSpace>;
using int16Field_D = Field<VectorSingle, int16>; /*using int32Field_D = Field<VectorSingle, int32>;
using int16Field_H = Field<VectorSingle, int16, HostSpace>;
using int32Field_D = Field<VectorSingle, int32>;
using int32Field_H = Field<VectorSingle, int32, HostSpace>; using int32Field_H = Field<VectorSingle, int32, HostSpace>;
@ -81,16 +76,14 @@ using int64x3Field_H = Field<VectorSingle, int64x3, HostSpace>;
using realx3x3Field_D = Field<VectorSingle, realx3x3>; using realx3x3Field_D = Field<VectorSingle, realx3x3>;
using realx3x3Field_H = Field<VectorSingle, realx3x3, HostSpace>; using realx3x3Field_H = Field<VectorSingle, realx3x3, HostSpace>;*/
// - no typedef on device (since word does not compile on CUDA) // - no typedef on device (since word does not compile on CUDA)
using wordField_H = Field<VectorSingle, word, HostSpace>; using wordField_H = Field<VectorSingle, word, HostSpace>;
// host device fields // host device fields
using int8Field_HD = Field<VectorDual, int8>; /*using int8Field_HD = Field<VectorDual, int8>;
using int16Field_HD = Field<VectorDual, int16>;
using int32Field_HD = Field<VectorDual, int32>; using int32Field_HD = Field<VectorDual, int32>;
@ -104,15 +97,13 @@ using realField_HD = Field<VectorDual, real>;
using realx3Field_HD = Field<VectorDual, realx3>; using realx3Field_HD = Field<VectorDual, realx3>;
using uint16x3Field_HD = Field<VectorDual, uint32x3>;
using uint32x3Field_HD = Field<VectorDual, uint32x3>; using uint32x3Field_HD = Field<VectorDual, uint32x3>;
using int32x3Field_HD = Field<VectorDual, int32x3>; using int32x3Field_HD = Field<VectorDual, int32x3>;
using int64x3Field_HD = Field<VectorDual, int64x3>; using int64x3Field_HD = Field<VectorDual, int64x3>;
using realx3x3Field_HD = Field<VectorDual, realx3x3>; using realx3x3Field_HD = Field<VectorDual, realx3x3>;*/
using wordField = Field<Vector, word , vecAllocator<word>>; using wordField = Field<Vector, word , vecAllocator<word>>;

View File

@ -23,111 +23,21 @@ template<typename T, typename Allocator>
bool pFlow::Vector<T, Allocator>::readVector bool pFlow::Vector<T, Allocator>::readVector
( (
iIstream& is, iIstream& is,
size_t len IOPattern::IOType iotype
) )
{ {
return readStdVector(is, vectorField(), iotype);
if(is.isBinary() && !std::is_same_v<T,word>)
{
this->resize(len);
is.read(reinterpret_cast<char*>(this->data()), this->size()*sizeof(T));
}
else
{
this->clear();
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
T val{};
if( firstToken.isPunctuation() ) // start of vector
{
if(firstToken != token::BEGIN_LIST)
{
warningInFunction
<< "expected token "<< token::BEGIN_LIST
<< " but found "<< firstToken ;
return false;
}
token lastToken(is);
is.fatalCheck(FUNCTION_NAME);
while
( !(
lastToken.isPunctuation()
&& lastToken == token::END_LIST
)
)
{
is.putBack(lastToken);
is >> val;
this->push_back(val);
is >> lastToken;
is.fatalCheck(FUNCTION_NAME);
}
} else
{
warningInFunction
<< "expected token "<< token::BEGIN_LIST
<< " but found "<< firstToken ;
return false;
}
}
return true;
} }
template<typename T, typename Allocator> template<typename T, typename Allocator>
bool pFlow::Vector<T, Allocator>::writeVector bool pFlow::Vector<T, Allocator>::writeVector
( (
iOstream& os iOstream& os,
IOPattern::IOType iotype
) const ) const
{ {
return writeStdVector(os, vectorField(), iotype);
span<T> s( const_cast<T*>(this->data()), this->size());
os<<s;
// start of
/*if( os.isBinary() && !std::is_same_v<T,word>)
{
os.write(reinterpret_cast<const char*>(this->data()), this->size()*sizeof(T));
}
else
{
auto len = size();
auto stride = getVectorStride(len);
os << token::BEGIN_LIST;
size_t i = 0;
while( i<len )
{
os << this->operator[](i++);
for(size_t j=0; j<stride-1 && i<len; j++ )
{
os << token::SPACE << this->operator[](i++);
}
if(i<len)
os<< token::NL;
}
os << token::END_LIST;
os.check(FUNCTION_NAME);
}*/
return true;
} }
/*template<typename T, typename Allocator> /*template<typename T, typename Allocator>

View File

@ -33,6 +33,8 @@ Licence:
#include "iOstream.hpp" #include "iOstream.hpp"
#include "iIstream.hpp" #include "iIstream.hpp"
#include "stdVectorHelper.hpp"
#ifndef __RESERVE__ #ifndef __RESERVE__
#define __RESERVE__ #define __RESERVE__
struct RESERVE{}; struct RESERVE{};
@ -40,7 +42,7 @@ Licence:
namespace pFlow namespace pFlow
{ {
template<typename T, typename Allocator> template<typename T, typename Allocator>
class Vector; class Vector;
@ -48,18 +50,7 @@ class Vector;
#include "VectorFwd.hpp" #include "VectorFwd.hpp"
template <class T>
class noConstructAllocator
: public std::allocator<T>
{
public:
using std::allocator<T>::allocator;
template <class U, class... Args> void construct(U*, Args&&...) {}
};
template<typename T>
using vecAllocator = std::allocator<T>;
template<typename T, typename Allocator = vecAllocator<T> > template<typename T, typename Allocator = vecAllocator<T> >
class Vector class Vector
@ -351,19 +342,20 @@ public:
inline VectorType operator -()const; inline VectorType operator -()const;
/// Read vector (assume ASCII in input)
bool readVector(iIstream& is, size_t len=0); bool readVector(iIstream& is, IOPattern::IOType iotype);
bool writeVector(iOstream& os) const; /// write vector
bool writeVector(iOstream& os, IOPattern::IOType iotype) const;
bool read(iIstream& is) bool read(iIstream& is, IOPattern::IOType iotype)
{ {
return readVector(is); return readVector(is, iotype);
} }
bool write(iOstream& os)const bool write(iOstream& os, IOPattern::IOType iotype)const
{ {
return writeVector(os); return writeVector(os, iotype);
} }
}; };
@ -372,7 +364,7 @@ public:
template<typename T, typename Allocator> template<typename T, typename Allocator>
inline iIstream& operator >> (iIstream & is, Vector<T, Allocator> & ivec ) inline iIstream& operator >> (iIstream & is, Vector<T, Allocator> & ivec )
{ {
if( !ivec.readVector(is) ) if( !ivec.readVector(is, IOPattern::MasterProcessor) )
{ {
ioErrorInFile (is.name(), is.lineNumber()); ioErrorInFile (is.name(), is.lineNumber());
fatalExit; fatalExit;
@ -382,19 +374,16 @@ inline iIstream& operator >> (iIstream & is, Vector<T, Allocator> & ivec )
template<typename T, typename Allocator> template<typename T, typename Allocator>
inline iOstream& operator << (iOstream& os, const Vector<T, Allocator>& ovec ) inline iOstream& operator << (iOstream& os, const Vector<T, Allocator>& ovec )
{ {
if( !ovec.writeVector(os, IOPattern::AllProcessorsDifferent) )
if( !ovec.writeVector(os) )
{ {
ioErrorInFile(os.name(), os.lineNumber()); ioErrorInFile(os.name(), os.lineNumber());
fatalExit; fatalExit;
} }
return os; return os;
} }
} // pFlow } // pFlow

View File

@ -22,7 +22,7 @@ Licence:
// instantiation just for numeral types // instantiation just for numeral types
template class pFlow::Vector<pFlow::int8>; /*template class pFlow::Vector<pFlow::int8>;
template class pFlow::Vector<pFlow::int32>; template class pFlow::Vector<pFlow::int32>;
@ -32,7 +32,7 @@ template class pFlow::Vector<pFlow::real>;
template class pFlow::Vector<pFlow::realx3>; template class pFlow::Vector<pFlow::realx3>;
template class pFlow::Vector<pFlow::realx3x3>; template class pFlow::Vector<pFlow::realx3x3>;*/

View File

@ -0,0 +1,132 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __stdVectorHelper_hpp__
#define __stdVectorHelper_hpp__
#include <vector>
#include <algorithm>
#include "span.hpp"
#include "iOstream.hpp"
#include "iIstream.hpp"
#include "dataIO.hpp"
namespace pFlow
{
template <class T>
class noConstructAllocator
: public std::allocator<T>
{
public:
using std::allocator<T>::allocator;
template <class U, class... Args> void construct(U*, Args&&...) {}
};
template<typename T>
using vecAllocator = std::allocator<T>;
template<typename T>
inline
bool writeSpan(
iOstream& os,
const span<T>& sp,
IOPattern::IOType iotype)
{
dataIO io(iotype);
if(!io.writeData(os, sp))
{
fatalErrorInFunction;
return false;
}
return true;
}
template<typename T, typename Allocator>
bool writeStdVector
(
iOstream& os,
const std::vector<T,Allocator>& vec,
IOPattern::IOType iotype
)
{
span<T> sp( const_cast<T*>(vec.data()), vec.size());
return writeSpan(os, sp, iotype);
}
template<typename T, typename Allocator>
bool readStdVector
(
iIstream& is,
std::vector<T,Allocator>& vec,
IOPattern::IOType iotype
)
{
dataIO io(iotype);
if(!io.readData(is, vec))
{
fatalErrorInFunction;
return false;
}
return true;
}
template<typename T, typename Allocator>
iOstream& operator<<( iOstream& os, const std::vector<T,Allocator>& vec)
{
if(!writeStdVector(os, vec, IOPattern::AllProcessorsDifferent))
{
fatalErrorInFunction;
fatalExit;
}
return os;
}
/// Always assume ASCII is in the input stream
template<typename T, typename Allocator>
iIstream& operator>>(iIstream& is, std::vector<T,Allocator>& vec)
{
if( !readStdVector(is,vec, IOPattern::MasterProcessor))
{
fatalErrorInFunction;
fatalExit;
}
return is;
}
} // pFlow
#endif

View File

@ -26,7 +26,6 @@ Licence:
#include "globalSettings.hpp" #include "globalSettings.hpp"
#include "typeInfo.hpp"
#include "types.hpp" #include "types.hpp"
#include "error.hpp" #include "error.hpp"
#include "indexContainer.hpp" #include "indexContainer.hpp"
@ -35,7 +34,7 @@ Licence:
#include "span.hpp" #include "span.hpp"
#include "Vector.hpp" #include "Vector.hpp"
#include "phasicFlowKokkos.hpp" #include "phasicFlowKokkos.hpp"
#include "dataIO.hpp"
#ifndef __RESERVE__ #ifndef __RESERVE__
@ -240,7 +239,7 @@ public:
: :
VectorSingle(src.name(), src) VectorSingle(src.name(), src)
{ {
copy(deviceVector(), src.deviceVector()); //copy(deviceVector(), src.deviceVector());
} }
/// Copy construct with a new name (perform deep copy) /// Copy construct with a new name (perform deep copy)
@ -577,34 +576,27 @@ public:
//// - IO operations //// - IO operations
/// Read vector from is stream (ASCII or Binary) /// Read vector from stream (ASCII)
/// For binary read, len should be provided
FUNCTION_H FUNCTION_H
bool readVector(iIstream& is, size_t len=0) bool read(iIstream& is, IOPattern::IOType iotype)
{ {
Vector<T> vecFromFile; std::vector<T> vecFromFile;
if( !vecFromFile.readVector(is,len) ) return false; if(! readStdVector(is, vecFromFile, iotype)) return false;
this->assign(vecFromFile); this->assign(vecFromFile);
return true; return true;
} }
/// Read vector from stream (ASCII) /// Write the vector to os
FUNCTION_H FUNCTION_H
bool read(iIstream& is) bool write(iOstream& os, IOPattern::IOType iotype)const
{
return readVector(is);
}
/// Write the vector to os (ASCII or Binary)
FUNCTION_H
bool write(iOstream& os)const
{ {
auto hVec = hostVector(); auto hVec = hostVector();
auto sp = span<T>( const_cast<T*>(hVec.data()), hVec.size()); auto sp = span<T>( const_cast<T*>(hVec.data()), hVec.size());
os<<sp;
return true; return writeSpan(os, sp, iotype);
} }
}; // class VectorSingle }; // class VectorSingle
@ -612,7 +604,7 @@ public:
template<typename T, typename MemorySpace> template<typename T, typename MemorySpace>
inline iIstream& operator >> (iIstream & is, VectorSingle<T, MemorySpace> & ivec ) inline iIstream& operator >> (iIstream & is, VectorSingle<T, MemorySpace> & ivec )
{ {
if( !ivec.read(is) ) if( !ivec.read(is, IOPattern::MasterProcessor ) )
{ {
ioErrorInFile (is.name(), is.lineNumber()); ioErrorInFile (is.name(), is.lineNumber());
fatalExit; fatalExit;
@ -624,7 +616,7 @@ template<typename T, typename MemorySpace>
inline iOstream& operator << (iOstream& os, const VectorSingle<T, MemorySpace>& ovec ) inline iOstream& operator << (iOstream& os, const VectorSingle<T, MemorySpace>& ovec )
{ {
if( !ovec.write(os) ) if( !ovec.write(os, IOPattern::AllProcessorsDifferent) )
{ {
ioErrorInFile(os.name(), os.lineNumber()); ioErrorInFile(os.name(), os.lineNumber());
fatalExit; fatalExit;
@ -634,8 +626,6 @@ inline iOstream& operator << (iOstream& os, const VectorSingle<T, MemorySpace>&
} }
} // - pFlow } // - pFlow
#include "VectorSingleAlgorithms.hpp" #include "VectorSingleAlgorithms.hpp"

View File

@ -159,6 +159,7 @@ public:
INLINE_FUNCTION_H INLINE_FUNCTION_H
bool writeASCII(iOstream& os) const bool writeASCII(iOstream& os) const
{ {
os<< size()<<endl;
os << token::BEGIN_LIST; os << token::BEGIN_LIST;
if(size()>0) if(size()>0)
{ {
@ -177,34 +178,22 @@ public:
return true; return true;
} }
/// Write in Binray format, can be used for numeral types (Not word or similar ones)
INLINE_FUNCTION_H
bool writeBinary(iOstream& os) const
{
os.write(reinterpret_cast<const char*>(data_), this->size()*sizeof(T));
os.check(FUNCTION_NAME);
return true;
}
}; };
template<typename T> template<typename T>
inline inline
iOstream& operator<<(iOstream& os, const span<T>& s) iOstream& operator<<(iOstream& os, const span<T>& s)
{ {
if( os.isBinary() && !std::is_same_v<T,word>) s.writeASCII(os);
{
s.writeBinary(os);
}
else
{
s.writeASCII(os);
}
return os; return os;
} }
} // pFlow } // pFlow
#endif //__span_hpp__ #endif //__span_hpp__

View File

@ -41,6 +41,18 @@ bool pFlow::fileSystem::checkFileName(const word& name)
} }
/// From full path
pFlow::fileSystem::fileSystem(const word & wPath)
:
path_(wPath),
isDir_(std::filesystem::is_directory(path_))
{
std::cout<<"file name is " << fileName()<<std::endl;
if( !isDir_ && !checkFileName(fileName()))
{
fatalExit;
}
}
pFlow::fileSystem::fileSystem( const word& dir, const word& file) pFlow::fileSystem::fileSystem( const word& dir, const word& file)
{ {
@ -74,10 +86,9 @@ pFlow::fileSystem::fileSystem( const char* dir, const char* file)
pFlow::fileSystem::fileSystem( const pathType& path ) pFlow::fileSystem::fileSystem( const pathType& path )
: :
path_(path) path_(path),
{ isDir_(std::filesystem::is_directory(path_))
isDir_ = isDirectory(*this); {}
}
pFlow::fileSystem pFlow::fileSystem::dirPath() const pFlow::fileSystem pFlow::fileSystem::dirPath() const
{ {
@ -175,9 +186,7 @@ bool pFlow::fileSystem::dirExist
} }
bool pFlow::fileSystem::exist bool pFlow::fileSystem::exist()const
(
)const
{ {
try try
{ {
@ -321,7 +330,7 @@ pFlow::fileSystemList pFlow::subDirectories
auto dOps = std::filesystem::directory_options::skip_permission_denied; auto dOps = std::filesystem::directory_options::skip_permission_denied;
for( auto& subPath: std::filesystem::directory_iterator(path.path(), dOps) ) for( auto& subPath: std::filesystem::directory_iterator(path.path(), dOps) )
{ {
if(isDirectory( subPath.path() ) ) if(isDirectory( fileSystem(subPath.path()) ) )
{ {
dirs.emplace_back(subPath.path()); dirs.emplace_back(subPath.path());
} }

View File

@ -71,19 +71,19 @@ public:
protected: protected:
/// File path /// File path
std::filesystem::path path_; pathType path_;
/// Is this a directory path? /// Is this a directory path?
bool isDir_; bool isDir_;
/// Not premitted chars in file name /// Not premitted chars in file name
inline static word notPermittedCharsFile = word(" ") + word("\t\n\0;:?*/<>\"?\'"); inline static word notPermittedCharsFile = word(" ") + word("&\t\n;:?*/<>\"?\'");
/// Is name is valid for a file? /// Is name is valid for a file?
bool static validFileName(const word& name) bool static validFileName(const word& name)
{ {
return name.find_first_of(notPermittedCharsFile); return name.find_first_of(notPermittedCharsFile)==word::npos;
} }
/// Is a valid file name? /// Is a valid file name?
@ -107,13 +107,18 @@ public:
isDir_(true) isDir_(true)
{} {}
/// From full path
explicit
fileSystem(const word & wPath);
/// From dir and file name /// From dir and file name
fileSystem( const word& dir, const word& file = ""); fileSystem( const word& dir, const word& file);
/// From dir and file name /// From dir and file name
fileSystem( const char* dir, const char* file = ""); fileSystem( const char* dir, const char* file="");
/// Copy /// Copy
explicit
fileSystem( const pathType& path ); fileSystem( const pathType& path );
/// Copy /// Copy

View File

@ -82,14 +82,14 @@ public:
~processors(); ~processors();
/// Master processors number (globaly in MPI). /// Master processors number (globaly in MPI).
static static inline
int masterNo() int masterNo()
{ {
return 0; return 0;
} }
/// Is this a parallel MPI run. /// Is this a parallel MPI run.
static static inline
bool isParallel() bool isParallel()
{ {
return processors::globalSize()>1; return processors::globalSize()>1;
@ -104,21 +104,21 @@ public:
bool isFinalized(); bool isFinalized();
/// Is this processor the master processor? /// Is this processor the master processor?
static static inline
bool isMaster() bool isMaster()
{ {
return processors::globalRank() == processors::masterNo(); return processors::globalRank() == processors::masterNo();
} }
/// Global size of processors /// Global size of processors
static static inline
int globalSize() int globalSize()
{ {
return globalSize_; return globalSize_;
} }
/// Rank of the processor in the global MPI /// Rank of the processor in the global MPI
static static inline
int globalRank() int globalRank()
{ {
return globalRank_; return globalRank_;

View File

@ -0,0 +1,31 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#include "processors.hpp"
#include "IOPattern.hpp"
pFlow::IOPattern::IOPattern( IOType iotype)
:
ioType_(iotype),
globalSize_(processors::globalSize()),
globalRank_(processors::globalRank()),
isMaster_(processors::isMaster()),
isParallel_(processors::isParallel())
{}

View File

@ -0,0 +1,152 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __IOPattern_hpp__
#define __IOPattern_hpp__
#include "processors.hpp"
namespace pFlow
{
class IOPattern
{
public:
/**
* Type of input/output
*
* MasterProcessorOnly: Read or write is done on master processor
* and the data on master processor is affected.
*
* MasterProcessorDistribute: Read is done on master processor, but
* the data should be distributed between processors based on an externally
* specified pattern. Write is done on master processors and the data is
* collected from all processors (collection is done based on the externally
* specified pattern).
*
* AllProcessorsSimilar: Read is done on all processors and processors
* read the same data. Write is done on master processor, since
* all processors have the same copy of data.
*/
enum IOType : int
{
MasterProcessorOnly = 0,
AllProcessorsSimilar = 1,
MasterProcessorDistribute = 4
};
protected:
IOType ioType_;
int globalSize_ = 1;
int globalRank_ = 0;
bool isMaster_ = true;
bool isParallel_ = false;
public:
IOPattern( IOType iotype);
IOPattern(const IOPattern&)=default;
IOPattern& operator=(const IOPattern&)=default;
~IOPattern() = default;
inline
bool isMasterProcessorOnly()const
{
return ioType_ == MasterProcessorOnly;
}
inline
bool isAllProcessorSimilar()const
{
return ioType_ == AllProcessorsSimilar;
}
inline
bool isMasterProcessorDistribute()const
{
return ioType_ == MasterProcessorDistribute;
}
inline
bool isMaster()const
{
return isMaster_;
}
inline
bool isParallel()const
{
return isParallel_;
}
inline
bool thisProcReadData()const
{
if(isMasterProcessor() && !isMaster())return false;
if(isMasterProcessorDistribute() && !isMaster()) return false;
return true;
}
inline
bool thisProcWriteData()const
{
return isMaster();
}
inline
bool thisProcReadHeader()const
{
return thisProcReadData();
}
inline
bool thisProcWriteHeader()const
{
return isMaster();
}
inline
auto globalSize()const
{
return globalSize_;
}
inline
auto globalRank()const
{
return globalRank_;
}
};
}
#endif //__IOPattern_hpp__

View File

@ -135,6 +135,7 @@ bool pFlow::IOfileHeader::readIfPresent()const
bool pFlow::IOfileHeader::writeHeader()const bool pFlow::IOfileHeader::writeHeader()const
{ {
if( !this->readWriteHeader() ) return false; if( !this->readWriteHeader() ) return false;
if( !processors::isMaster() ) return false; if( !processors::isMaster() ) return false;
if( !implyWrite() ) return false; if( !implyWrite() ) return false;
@ -150,7 +151,10 @@ bool pFlow::IOfileHeader::writeHeader
) const ) const
{ {
if(!forceWrite && !writeHeader()) return true; if(!forceWrite)
{
if(!writeHeader()) return true;
}
writeBanner(os); writeBanner(os);
@ -180,8 +184,9 @@ bool pFlow::IOfileHeader::writeHeader(iOstream& os, bool forceWrite) const
bool pFlow::IOfileHeader::readHeader()const bool pFlow::IOfileHeader::readHeader()const
{ {
if( !this->readWriteHeader() ) return false; if( !implyRead())return false;
return true; if( !this->readWriteHeader() ) return false;
return ioPattern().thisProcReadHeader();
} }
bool pFlow::IOfileHeader::readHeader(iIstream& is, bool silent) bool pFlow::IOfileHeader::readHeader(iIstream& is, bool silent)
@ -228,15 +233,14 @@ bool pFlow::IOfileHeader::readHeader(iIstream& is, bool silent)
bool pFlow::IOfileHeader::writeData()const bool pFlow::IOfileHeader::writeData()const
{ {
if( processors::isMaster() || this->differentDataOnProcessors()) if(!implyWrite())return false;
return true; return ioPattern().thisProcWriteData();
else
return false;
} }
bool pFlow::IOfileHeader::readData()const bool pFlow::IOfileHeader::readData()const
{ {
return true; if(!implyRead())return false;
return ioPattern().thisProcReadData();
} }
bool pFlow::IOfileHeader::writeBanner(iOstream& os)const bool pFlow::IOfileHeader::writeBanner(iOstream& os)const

View File

@ -109,7 +109,7 @@ public:
/// Check if the header should be written to file /// Check if the header should be written to file
/// True: on master + implyWrite + readWriteHeader = true /// True: on master + implyWrite + readWriteHeader = true
/// False: slave or NOT implyWrite /// False: otherwise
bool writeHeader()const; bool writeHeader()const;
/// Write the header to the file , typeName comes from caller /// Write the header to the file , typeName comes from caller
@ -119,13 +119,9 @@ public:
bool writeHeader(iOstream& os, bool forceWrite = false) const; bool writeHeader(iOstream& os, bool forceWrite = false) const;
/// Check if the data should be written to file /// Check if the data should be written to file
/// True: on master or differentDataOnProcessor is true
/// False: otherwise
bool writeData()const; bool writeData()const;
/// Check if header should be read from file /// Check if header should be read from file
/// True: All processors, read the file header
/// False: readWriteHeader = false
bool readHeader()const; bool readHeader()const;
/// Read the header in the file /// Read the header in the file
@ -135,10 +131,10 @@ public:
/// Always return true /// Always return true
bool readData()const; bool readData()const;
// - write the banner /// write the banner
bool writeBanner(iOstream& os)const; bool writeBanner(iOstream& os)const;
// - wirte a separator line /// wirte a separator line
bool writeSeparator(iOstream& os)const; bool writeSeparator(iOstream& os)const;
}; };

View File

@ -30,11 +30,11 @@ pFlow::objectFile::objectFile
pFlow::objectFile::objectFile pFlow::objectFile::objectFile
( (
const word& name, const word& name,
const fileSystem& localPath, const fileSystem& localPath,
const readFlag& rf, const readFlag& rf,
const writeFlag& wf, const writeFlag& wf,
bool diffDataOnProcessors, IOPattern::IOType ioType,
bool rwHdr bool rwHdr
) )
: :
@ -42,7 +42,7 @@ pFlow::objectFile::objectFile
rFlag_(rf), rFlag_(rf),
wFlag_(wf), wFlag_(wf),
localPath_(localPath), localPath_(localPath),
differentDataOnProcessors_(diffDataOnProcessors), ioPattern_(ioType),
readWriteHeader_(rwHdr) readWriteHeader_(rwHdr)
{ {
} }

View File

@ -23,6 +23,7 @@ Licence:
#include "types.hpp" #include "types.hpp"
#include "fileSystem.hpp" #include "fileSystem.hpp"
#include "IOPattern.hpp"
namespace pFlow namespace pFlow
@ -47,6 +48,7 @@ public:
WRITE_NEVER WRITE_NEVER
}; };
protected: protected:
/// Name of the entity /// Name of the entity
@ -61,16 +63,10 @@ protected:
/// Local path of entity /// Local path of entity
fileSystem localPath_ = ""; fileSystem localPath_ = "";
/// Number of bytes used for writing/reading real variable (mostly used for binray) /// Number of bytes used for writing/reading real variable (used for binray)
int numBytesForReal_ = numBytesForReal__; int numBytesForReal_ = numBytesForReal__;
/// All processors have the different set of data or not? IOPattern ioPattern_ = {IOPattern::MasterProcessor};
/// True: Each processor should read its own part of data from file and should write
/// its own part of data to the file.
/// Flase: All processors read the same data from file and in writing, only master data
/// write the data to the file.
bool differentDataOnProcessors_ = true;
/// Does the objectFile write the header or not /// Does the objectFile write the header or not
bool readWriteHeader_ = true; bool readWriteHeader_ = true;
@ -89,10 +85,10 @@ public:
objectFile objectFile
( (
const word& name, const word& name,
const fileSystem& localPath, const fileSystem& localPath,
const readFlag& rf = READ_NEVER, const readFlag& rf = READ_NEVER,
const writeFlag& wf = WRITE_NEVER, const writeFlag& wf = WRITE_NEVER,
bool diffDataOnProcessors = true, IOPattern::IOType ioType = IOPattern::MasterProcessor,
bool rwHdr = true bool rwHdr = true
); );
@ -160,10 +156,9 @@ public:
return wFlag_ == WRITE_NEVER; return wFlag_ == WRITE_NEVER;
} }
inline const IOPattern& ioPattern()const
bool differentDataOnProcessors()const
{ {
return differentDataOnProcessors_; return ioPattern_;
} }
inline inline

View File

@ -899,6 +899,28 @@ void pFlow::Istream::rewind()
stdStream().rdbuf()->pubseekpos(0, std::ios_base::in); stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
} }
void pFlow::Istream::seek(size_t pos)
{
stdStream().clear(); // Clear the iostate error state flags
setGood(); // Sync local copy of iostate
resetPutBack();
// pubseekpos() rather than seekg() so that it works with gzstream
stdStream().rdbuf()->pubseekpos(pos, std::ios_base::in);
}
size_t pFlow::Istream::tell()
{
auto pos = static_cast<size_t>(stdStream().tellg());
if(stdStream().fail())
{
fatalErrorInFunction<<
"Error in getting current position from stream "<<
this->name()<<endl;
fatalExit;
}
return pos;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -156,7 +156,12 @@ public:
size_t findBinaryBlockStart()override; size_t findBinaryBlockStart()override;
/// Rewind the stream so that it may be read again /// Rewind the stream so that it may be read again
virtual void rewind(); void rewind() override;
void seek(size_t pos) override;
/// Return current position indicator
size_t tell() override;
/// Set stream flags /// Set stream flags

View File

@ -258,6 +258,10 @@ pFlow::iOstream& pFlow::Ostream::writeBinaryBlockFlag()
return *this; return *this;
} }
void pFlow::Ostream::seek(size_t pos)
{
os_.seekp(pos, std::ios_base::cur);
}
void pFlow::Ostream::indent() void pFlow::Ostream::indent()
{ {
@ -267,6 +271,18 @@ void pFlow::Ostream::indent()
} }
} }
void pFlow::Ostream::startOfBinaryStreaming()
{
this->endl();
this->flush();
}
void pFlow::Ostream::endOfBinaryStreaming()
{
os_.seekp(0, std::ios_base::end);
this->endl();
this->flush();
}
void pFlow::Ostream::flush() void pFlow::Ostream::flush()
{ {

View File

@ -132,12 +132,20 @@ public:
iOstream& writeBinaryBlockFlag() override; iOstream& writeBinaryBlockFlag() override;
void seek(size_t pos) override;
/// Add indentation characters /// Add indentation characters
void indent() override; void indent() override;
/// Set stream flags /// Set stream flags
ios_base::fmtflags flags(const ios_base::fmtflags f) override; ios_base::fmtflags flags(const ios_base::fmtflags f) override;
/// Add a new line and flush stream
void startOfBinaryStreaming() override;
/// Reach end of file add a new line and flush stream
void endOfBinaryStreaming() override ;
/// Flush stream /// Flush stream
void flush() override; void flush() override;

View File

@ -309,6 +309,10 @@ void pFlow::iTstream::rewind()
setGood(); setGood();
} }
void pFlow::iTstream::seek(size_t pos)
{
notImplementedFunction;
}
void pFlow::iTstream::reset() void pFlow::iTstream::reset()
{ {
@ -318,6 +322,12 @@ void pFlow::iTstream::reset()
setGood(); setGood();
} }
size_t pFlow::iTstream::tell()
{
notImplementedFunction;
return -1;
}
const pFlow::tokenList& pFlow::iTstream::tokens()const const pFlow::tokenList& pFlow::iTstream::tokens()const
{ {
return tokenList_; return tokenList_;

View File

@ -130,7 +130,11 @@ public:
iIstream& read(char* buffer, std::streamsize count) override; iIstream& read(char* buffer, std::streamsize count) override;
/// Rewind the stream so that it may be read again /// Rewind the stream so that it may be read again
virtual void rewind(); virtual void rewind()override;
void seek(size_t pos) override;
size_t tell() override;
/// reset the iTstream and make the stream empty /// reset the iTstream and make the stream empty
virtual void reset(); virtual void reset();

View File

@ -173,6 +173,10 @@ pFlow::iOstream& pFlow::oTstream::write
return *this; return *this;
} }
void pFlow::oTstream::seek(size_t pos)
{
notImplementedFunction;
}
void pFlow::oTstream::append(const token& tok) void pFlow::oTstream::append(const token& tok)
{ {

View File

@ -132,6 +132,8 @@ public:
/// Write double /// Write double
virtual iOstream& write(const size_t val) override; virtual iOstream& write(const size_t val) override;
void seek(size_t pos) override;
/// Write a block of binray data /// Write a block of binray data
iOstream& write( iOstream& write(
const char* binaryData, const char* binaryData,
@ -157,6 +159,14 @@ public:
virtual void indent() virtual void indent()
{} {}
/// Add a new line and flush stream
virtual void startOfBinaryStreaming()
{}
/// Reach end of file add a new line and flush stream
virtual void endOfBinaryStreaming()
{}
/// Flush stream /// Flush stream
virtual void flush() virtual void flush()
{} {}

View File

@ -7,12 +7,9 @@
#include <cstdio> #include <cstdio>
#include <numeric> #include <numeric>
#include "dataIO.hpp" #include "dataIO.hpp"
#include "fileSystem.hpp"
#include "streams.hpp"
static const size_t numcharFlag = 8; static const size_t numcharFlag = 8;
@ -43,19 +40,18 @@ pFlow::uint64 findBindaryBlockFlagSTD(std::FILE* fh)
if( fpos = std::ftell( fh) ; fpos == -1L ) if( fpos = std::ftell( fh) ; fpos == -1L )
{ {
fatalErrorInFunction; fatalErrorInFunction;
return -1; return pFlow::dataIO::ErrorReturn;
} }
pFlow::uint64 filePos = static_cast<pFlow::uint64>(fpos); pFlow::uint64 filePos = static_cast<pFlow::uint64>(fpos);
// start reading char by char // start reading char by char
int c;
unsigned char ch; unsigned char ch;
int currPos = 0; int currPos = 0;
while ( std::fread(&ch, sizeof(ch), 1, fh) == 1 ) while ( std::fread(&ch, sizeof(ch), 1, fh) == 1 )
{ {
if(std::ferror(fh)) return -1; if(std::ferror(fh)) return pFlow::dataIO::ErrorReturn;
if(std::feof(fh))return -1; if(std::feof(fh))return pFlow::dataIO::ErrorReturn;
filePos++; filePos++;
@ -71,22 +67,16 @@ pFlow::uint64 findBindaryBlockFlagSTD(std::FILE* fh)
} }
} }
return -1; return pFlow::dataIO::ErrorReturn;
} }
#ifdef pFlow_Build_MPI #ifdef pFlow_Build_MPI
pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh) pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh, pFlow::uint64 startPosSearch)
{ {
// get the current postion
MPI_Offset fpos;
if( MPI_File_get_position( fh, &fpos) != MPI_SUCCESS )
{
fatalErrorInFunction;
return false;
}
pFlow::uint64 filePos = static_cast<pFlow::uint64>(fpos); pFlow::uint64 filePos = static_cast<pFlow::uint64>(startPosSearch);
// start reading char by char // start reading char by char
unsigned char ch; unsigned char ch;
@ -114,7 +104,7 @@ pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh)
} }
} }
return -1; return pFlow::dataIO::ErrorReturn;
} }
#endif #endif
@ -122,21 +112,18 @@ pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh)
bool pFlow::dataIO::writeDataToFileEndSTD bool pFlow::dataIO::writeDataToFileEndSTD
( (
const fileSystem& filePath, const word& wordPath,
const span<unsigned char>& data const span<unsigned char>& data
) )
{ {
if(!processors::isMaster()) return true;
// openfile // openfile
word wFile = filePath.wordPath(); auto fh = std::fopen(wordPath.c_str(), "ab");
auto fh = std::fopen(wFile.c_str(), "ab");
if(!fh) if(!fh)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in Opening file "<< filePath <<endl; "Error in Opening file "<< wordPath <<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
@ -145,15 +132,16 @@ bool pFlow::dataIO::writeDataToFileEndSTD
if(std::fseek(fh, 0 , SEEK_END)!=0) if(std::fseek(fh, 0 , SEEK_END)!=0)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"error at reaching end of file "<<filePath<<endl; "error at reaching end of file "<<wordPath<<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
if(!writeBinaryBlockFlagSTD(fh) ) if(!writeBinaryBlockFlagSTD(fh) )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in writing to file "<< filePath<<endl; "Error in writing to file "<< wordPath<<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
@ -166,7 +154,7 @@ bool pFlow::dataIO::writeDataToFileEndSTD
if(wc < 1) if(wc < 1)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in writing numChunks to file "<< filePath <<endl; "Error in writing numChunks to file "<< wordPath <<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
@ -179,7 +167,7 @@ bool pFlow::dataIO::writeDataToFileEndSTD
if(wc <1) if(wc <1)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in writing size of data chunk to file "<< filePath <<endl; "Error in writing size of data chunk to file "<< wordPath <<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
@ -191,12 +179,15 @@ bool pFlow::dataIO::writeDataToFileEndSTD
if(wc < sizeOfData ) if(wc < sizeOfData )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in writing size of data to file "<< filePath <<endl; "Error in writing size of data to file "<< wordPath <<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
} }
lastPosRead_ = static_cast<uint64>(std::ftell(fh));
// close the file // close the file
std::fclose(fh); std::fclose(fh);
@ -205,7 +196,7 @@ bool pFlow::dataIO::writeDataToFileEndSTD
bool pFlow::dataIO::writeDataToFileEndMPI bool pFlow::dataIO::writeDataToFileEndMPI
( (
const fileSystem& filePath, const word& wordPath,
const span<unsigned char>& data const span<unsigned char>& data
) )
{ {
@ -223,19 +214,18 @@ bool pFlow::dataIO::writeDataToFileEndMPI
true true
); );
word wFile = filePath.wordPath();
MPI_File fh; MPI_File fh;
if( MPI_File_open( if( MPI_File_open(
MPI_COMM_WORLD, MPI_COMM_WORLD,
wFile.c_str(), wordPath.c_str(),
MPI_MODE_WRONLY+MPI_MODE_APPEND, MPI_MODE_WRONLY+MPI_MODE_APPEND,
MPI_INFO_NULL, MPI_INFO_NULL,
&fh) != MPI_SUCCESS) &fh) != MPI_SUCCESS)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Cannot open file "<< filePath<<endl; "Cannot open file "<< wordPath<<endl;
return false; return false;
} }
@ -255,7 +245,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
) != MPI_SUCCESS ) ) != MPI_SUCCESS )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Cannot write binary block flag into "<< filePath<<endl; "Cannot write binary block flag into "<< wordPath<<endl;
return false; return false;
} }
@ -263,7 +253,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
if( MPI_File_get_position(fh, &posOfBlock) != MPI_SUCCESS ) if( MPI_File_get_position(fh, &posOfBlock) != MPI_SUCCESS )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Cannot get the end pos of file "<< filePath<<endl; "Cannot get the end pos of file "<< wordPath<<endl;
return false; return false;
} }
@ -295,7 +285,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
MPI_STATUS_IGNORE) != MPI_SUCCESS) MPI_STATUS_IGNORE) != MPI_SUCCESS)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Cannot write number of chunks into "<<filePath<<endl; "Cannot write number of chunks into "<<wordPath<<endl;
return false; return false;
} }
} }
@ -312,7 +302,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
MPI_STATUS_IGNORE)!= MPI_SUCCESS) MPI_STATUS_IGNORE)!= MPI_SUCCESS)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Cannot write size of chunk into "<<filePath<<endl; "Cannot write size of chunk into "<<wordPath<<endl;
return false; return false;
} }
@ -330,30 +320,50 @@ bool pFlow::dataIO::writeDataToFileEndMPI
MPI_STATUS_IGNORE) != MPI_SUCCESS) MPI_STATUS_IGNORE) != MPI_SUCCESS)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Cannot write data into "<<filePath<<endl; "Cannot write data into "<<wordPath<<endl;
return false;; return false;;
} }
MPI_File_close(&fh); MPI_File_close(&fh);
MPI_Barrier(MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);
return true;
uint64 lastPos = chunkOffset + thisSize;
return maxReduction(lastPos, lastPosWrite_);
/*if( MPI_Allreduce(
&lastPos,
&lastPosWrite_,
1,
MPI_UINT64_T,
MPI_MAX,
MPI_COMM_WORLD) != MPI_SUCCESS )
{
fatalErrorInFunction<<
"Error in max_reduction for write operation"<<endl;
return false;
}
return true;*/
#else #else
return writeDataToFileEndSTD(filePath, data); // if MPI is not active, we use std routins
return writeDataToFileEndSTD(wordPath, data);
#endif #endif
} }
bool pFlow::dataIO::readDataSTD bool pFlow::dataIO::readDataSTD
( (
const fileSystem& filePath, const word& wordPath,
const std::vector<uint64> chunkSizes, const std::vector<uint64> chunkSizes,
span<unsigned char>& data, span<unsigned char>& data,
uint64 binaryBlockStart uint64 binaryBlockStart
) )
{ {
// sum of all chuncks // sum of all chuncks
uint64 toRecv = std::accumulate( uint64 toRecv = std::accumulate(
chunkSizes.begin(), chunkSizes.begin(),
@ -366,27 +376,29 @@ bool pFlow::dataIO::readDataSTD
return false; return false;
} }
word wFile = filePath.wordPath();
auto fh = std::fopen(wFile.c_str(), "rb"); auto fh = std::fopen(wordPath.c_str(), "rb");
if(!fh) if(!fh)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in Opening file "<< filePath<<endl; "Error in Opening file "<< wordPath<<endl;
return false; return false;
} }
// start of data chunks // start of data chunks
uint64 offset = binaryBlockStart + chunkSizeOffeset(chunkSizes.size()); uint64 offset = binaryBlockStart + chunkSizeOffeset(chunkSizes.size());
if(auto res = std::fseek(fh, offset, SEEK_SET); res!= 0 ) if(auto res = std::fseek(fh, offset, SEEK_SET); res!= 0 )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in file seek "<< filePath<<endl; "Error in file seek "<< wordPath<<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
if(auto res = std::fread( if(auto res = std::fread(
data.data(), data.data(),
sizeof(unsigned char), sizeof(unsigned char),
@ -395,11 +407,13 @@ bool pFlow::dataIO::readDataSTD
res!= data.size() ) res!= data.size() )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in reading file "<< filePath<<endl; "Error in reading file "<< wordPath<<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
lastPosRead_ = static_cast<uint64>(std::ftell(fh));
std::fclose(fh); std::fclose(fh);
return true; return true;
} }
@ -407,7 +421,7 @@ bool pFlow::dataIO::readDataSTD
bool pFlow::dataIO::readDataMPI bool pFlow::dataIO::readDataMPI
( (
const fileSystem& filePath, const word& wordPath,
const std::vector<uint64> chunkSizes, const std::vector<uint64> chunkSizes,
span<unsigned char>& data, span<unsigned char>& data,
uint64 binaryBlockStart uint64 binaryBlockStart
@ -416,19 +430,12 @@ bool pFlow::dataIO::readDataMPI
#ifdef pFlow_Build_MPI #ifdef pFlow_Build_MPI
if(chunkSizes.size() != processors::globalSize() )
{
fatalErrorInFunction;
return false;
}
word wFile = filePath.wordPath();
MPI_File fh; MPI_File fh;
if( MPI_File_open( if( MPI_File_open(
MPI_COMM_WORLD, MPI_COMM_WORLD,
wFile.c_str(), wordPath.c_str(),
MPI_MODE_RDONLY, MPI_MODE_RDONLY,
MPI_INFO_NULL, MPI_INFO_NULL,
&fh)) &fh))
@ -470,29 +477,47 @@ bool pFlow::dataIO::readDataMPI
fatalErrorInFunction; fatalErrorInFunction;
return false; return false;
} }
#else
MPI_File_close(&fh);
uint64 lastPos = offset + data.size();
/*if( MPI_Allreduce(
&lastPos,
&lastPosRead_,
1,
MPI_UINT64_T,
MPI_MAX,
MPI_COMM_WORLD) != MPI_SUCCESS)
{
fatalErrorInFunction<<
"Error in max_reduction for lastPosRead_"<<endl;
return false;
}*/
return maxReduction(lastPos, lastPosRead_);
#else
return readDataSTD(wordPath, chunkSizes, data, binaryBlockStart);
#endif #endif
return true;
} }
bool pFlow::dataIO::readMetaMPI bool pFlow::dataIO::readMetaMPI
( (
const fileSystem& filePath, const word& wordPath,
std::vector<uint64>& chunkSizes, std::vector<uint64>& chunkSizes,
uint64 startPosSearch,
uint64 &startPosBinaryBlock uint64 &startPosBinaryBlock
) )
{ {
word wFile = filePath.wordPath();
#ifdef pFlow_Build_MPI #ifdef pFlow_Build_MPI
MPI_File fh; MPI_File fh;
if(MPI_File_open( if(MPI_File_open(
MPI_COMM_WORLD, MPI_COMM_WORLD,
wFile.c_str(), wordPath.c_str(),
MPI_MODE_RDONLY, MPI_MODE_RDONLY,
MPI_INFO_NULL, MPI_INFO_NULL,
&fh) != MPI_SUCCESS) &fh) != MPI_SUCCESS)
@ -502,8 +527,8 @@ bool pFlow::dataIO::readMetaMPI
} }
uint64 startPos = findBindaryBlockFlagMPI(fh); uint64 startPos = findBindaryBlockFlagMPI(fh, startPosSearch);
if( startPos == -1 ) if( startPos == pFlow::dataIO::ErrorReturn )
{ {
fatalErrorInFunction; fatalErrorInFunction;
return false; return false;
@ -539,36 +564,53 @@ bool pFlow::dataIO::readMetaMPI
fatalErrorInFunction; fatalErrorInFunction;
return false; return false;
} }
MPI_File_close(&fh); MPI_File_close(&fh);
#endif uint64 lastPos = startPos + sizeof(numProcInFile) + chunkSizes.size();
return maxReduction(lastPos, lastPosRead_);
return true; /*if( MPI_Allreduce(
&lastPos,
&lastPosRead_,
1,
MPI_UINT64_T,
MPI_MAX,
MPI_COMM_WORLD) != MPI_SUCCESS)
{
fatalErrorInFunction<<
"Error in max_reduction for lastPosRead_"<<endl;
return false;
}*/
#else
return readMetaSTD(wordPath, chunkSizes, startPosBinaryBlock);
#endif
} }
bool pFlow::dataIO::readMetaSTD bool pFlow::dataIO::readMetaSTD
( (
const fileSystem& filePath, const word& wordPath,
std::vector<uint64>& chunkSizes, std::vector<uint64>& chunkSizes,
uint64 startPosSearch,
uint64 &startPosBinaryBlock uint64 &startPosBinaryBlock
) )
{ {
// only on master
if( !processors::isMaster()) return true;
word wFile = filePath.wordPath(); std::FILE *fh = std::fopen(wordPath.c_str(), "rb");
std::FILE *fh = std::fopen(wFile.c_str(), "rb");
if(!fh) if(!fh)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in Opening file "<< filePath<<endl; "Error in Opening file "<< wordPath<<endl;
return false; return false;
} }
// set the start position for search
std::fseek(fh, startPosSearch, SEEK_SET);
uint64 startPos = findBindaryBlockFlagSTD(fh); uint64 startPos = findBindaryBlockFlagSTD(fh);
if(startPos == -1 ) if(startPos == ErrorReturn )
{ {
fatalErrorInFunction; fatalErrorInFunction;
return false; return false;
@ -587,7 +629,7 @@ bool pFlow::dataIO::readMetaSTD
if(res != 1 ) if(res != 1 )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in reading file "<< filePath<<endl; "Error in reading file "<< wordPath<<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
@ -600,13 +642,76 @@ bool pFlow::dataIO::readMetaSTD
if(res!= numProcInFile) if(res!= numProcInFile)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Error in reading chunkSizes from file "<< filePath<<endl; "Error in reading chunkSizes from file "<< wordPath<<endl;
std::fclose(fh); std::fclose(fh);
return false; return false;
} }
lastPosRead_ = static_cast<uint64>(std::ftell(fh));
std::fclose(fh); std::fclose(fh);
return true; return true;
} }
bool pFlow::dataIO::waitForAllMPI()
{
#ifdef pFlow_Build_MPI
MPI_Barrier(MPI_COMM_WORLD);
#endif
return true;
}
bool pFlow::dataIO::maxReduction( uint64& src, uint64& dst)
{
#ifdef pFlow_Build_MPI
if(processors::isParallel())
{
if(MPI_Allreduce(
&src,
&dst,
1,
MPI_UINT64_T,
MPI_MAX,
MPI_COMM_WORLD) != MPI_SUCCESS )
{
fatalErrorInFunction<<
"Error in max_reduction for write operation"<<endl;
return false;
}
return true;
}
else
{
dst = src;
return true;
}
#else
dst = src;
return true;
#endif
}
bool pFlow::dataIO::BcastPos(uint64 & pos)
{
#ifdef pFlow_Build_MPI
if(processors::isParallel())
{
if( MPI_Bcast(
& pos,
1,
MPI_UINT64_T,
processors::masterNo(),
MPI_COMM_WORLD)!=MPI_SUCCESS )
{
fatalErrorInFunction<<
"Error in Bcast position"<<endl;
return false;
}
}
#endif
return true;
}

View File

@ -6,7 +6,7 @@
#include "types.hpp" #include "types.hpp"
#include "span.hpp" #include "span.hpp"
#include "processors.hpp" #include "IOPattern.hpp"
namespace pFlow namespace pFlow
{ {
@ -19,80 +19,133 @@ class dataIO
public: public:
/**
* Type of input/output static inline const uint64 ErrorReturn = static_cast<uint64>(-1);
* MasterProcessor: Read or write is done on master processor
* and the data on master processor is affected.
* AllProcessorsDifferent: Read or write is done on all processors,
* and each processor munipulates its own data.
* AllProcessorsSimilar: Read is done on all processors but the read data
* is similar on processors. Write is done on master processor, since
* all processors have the same copy of data.
*/
enum IOType : int
{
MasterProcessor,
AllProcessorsDifferent,
AllProcessorsSimilar
};
protected: protected:
IOType IOType_; IOPattern ioPattern_;
uint64 lastPosWrite_ = 0;
uint64 lastPosRead_ = 0;
bool writeDataToFileEndSTD( bool writeDataToFileEndSTD(
const fileSystem& filePath, const word& wordPath,
const span<unsigned char>& data); const span<unsigned char>& data);
bool writeDataToFileEndMPI( bool writeDataToFileEndMPI(
const fileSystem& filePath, const word& wordPath,
const span<unsigned char>& data); const span<unsigned char>& data);
bool readDataSTD( bool readDataSTD(
const fileSystem& filePath, const word& wordPath,
const std::vector<uint64> chunkSizes, const std::vector<uint64> chunkSizes,
span<unsigned char>& data, span<unsigned char>& data,
uint64 binaryBlockStart); uint64 binaryBlockStart);
bool readDataMPI( bool readDataMPI(
const fileSystem& filePath, const word& wordPath,
const std::vector<uint64> chunkSizes, const std::vector<uint64> chunkSizes,
span<unsigned char>& data, span<unsigned char>& data,
uint64 binaryBlockStart); uint64 binaryBlockStart);
bool readMetaMPI( bool readMetaMPI(
const fileSystem& filePath, const word& wordPath,
std::vector<uint64>& chunkSizes, std::vector<uint64>& chunkSizes,
uint64 startPosSearch,
uint64 &startPosBinaryBlock); uint64 &startPosBinaryBlock);
bool readMetaSTD( bool readMetaSTD(
const fileSystem& filePath, const word& wordPath,
std::vector<uint64>& chunkSizes, std::vector<uint64>& chunkSizes,
uint64 startPosSearch,
uint64 &startPosBinaryBlock); uint64 &startPosBinaryBlock);
bool waitForAllMPI();
bool maxReduction( uint64& src, uint64& dst);
bool BcastPos(uint64 & pos);
public: public:
dataIO(IOType ioT) dataIO(IOPattern::IOType iotype)
: :
IOType_(ioT) ioPattern_(iotype)
{} {}
~dataIO()=default; ~dataIO()=default;
template<typename T> template<typename T>
bool writeDataEnd( bool writeDataEnd(
const fileSystem& filePath, const word& wordPath,
const span<T>& data); const span<T>& data);
template<typename T>
bool writeAsciiEnd(
iOstream& os,
const span<T>& data);
template<typename T>
bool readDataBinary(
const word& wordPath,
std::vector<T>& data,
uint64 startPos = 0);
template<typename T>
bool readAscii(
iIstream& is,
std::vector<T>& vec );
template<typename T> template<typename T>
bool readData( bool readData(
const fileSystem& filePath, iIstream& is,
std::vector<T>& data); std::vector<T>& vec,
bool resume = false); // resume only works for binary
// for ascii, by default it starts from the current position
template<typename T>
bool writeData(iOstream& os,
const span<T>& data);
}; };
template<>
inline
bool pFlow::dataIO::writeData<pFlow::word>
(
iOstream& os,
const span<word>& data
)
{
if( !writeAsciiEnd(os, data) )
{
fatalErrorInFunction;
return false;
}
return true;
}
template<>
inline
bool pFlow::dataIO::readData<pFlow::word>(
iIstream& is,
std::vector<word>& vec,
bool resume)
{
if(!readAscii(is, vec))
{
fatalErrorInFunction;
return false;
}
return true;
}
} }
#include "dataIOTemplate.cpp" #include "dataIOTemplate.cpp"

View File

@ -1,112 +1,320 @@
template<typename T> template<typename T>
bool pFlow::dataIO::writeDataEnd( bool pFlow::dataIO::writeDataEnd(
const fileSystem& filePath, const word& wordPath,
const span<T>& data) const span<T>& data)
{ {
span<unsigned char> charSpan( if( ioPattern_.thisProcWriteData() )
{
span<unsigned char> charSpan(
reinterpret_cast<unsigned char*> (const_cast<T*>(data.data())), reinterpret_cast<unsigned char*> (const_cast<T*>(data.data())),
data.size()*sizeof(T)); data.size()*sizeof(T));
switch (IOType_) if( ioPattern_.isParallel() )
{
return writeDataToFileEndMPI(wordPath, charSpan);
}
else
{
return writeDataToFileEndSTD(wordPath, charSpan);
}
}
else
{ {
case MasterProcessor: return true;
case AllProcessorsSimilar:
{
// This means that only master processor should write
// in this case we perform write on master processor only
// this means that the data
if(processors::isMaster())
{
return writeDataToFileEndSTD(filePath, charSpan);
}
else
{
return true;
}
break;
}
case AllProcessorsDifferent:
{
// This means that all processors should write their own
// copy of data
return writeDataToFileEndMPI(filePath, charSpan);
break;
}
} }
return false; return false;
} }
template<typename T> template<typename T>
bool pFlow::dataIO::readData bool pFlow::dataIO::writeAsciiEnd
( (
const fileSystem& filePath, iOstream& os,
std::vector<T>& data const span<T>& data
) )
{ {
if(ioPattern_.thisProcWriteData())
{
return data.writeASCII(os);
}
else
return true;
}
template<typename T>
bool pFlow::dataIO::readDataBinary
(
const word& wordPath,
std::vector<T>& data,
uint64 startPos
)
{
std::vector<uint64> chunkSizes; std::vector<uint64> chunkSizes;
uint64 startPosBinaryBlock; uint64 startPosBinaryBlock;
// read meta data
switch (IOType_)
{
case MasterProcessor:
{
if(!readMetaSTD(
filePath,
chunkSizes,
startPosBinaryBlock))
{
return false;
}
break;
}
case AllProcessorsDifferent:
case AllProcessorsSimilar:
{
if(!readMetaMPI(
filePath,
chunkSizes,
startPosBinaryBlock))
{
return false;
}
break;
}
}
data.clear(); data.clear();
if(IOType_ == MasterProcessor)
if( ioPattern_.thisProcReadData())
{ {
auto sizeOfData = std::accumulate(
// read meta
if(!readMetaSTD(
wordPath,
chunkSizes,
startPos,
startPosBinaryBlock))
{
fatalErrorInFunction;
return false;
}
if( ioPattern_.isMasterProcessor() ||
ioPattern_.isAllProcessorSimilar()
)
{
auto sizeOfData = std::accumulate(
chunkSizes.begin(), chunkSizes.begin(),
chunkSizes.end(), chunkSizes.end(),
static_cast<uint64>(0)); static_cast<uint64>(0));
data.resize(sizeOfData/sizeof(T));
data.resize(sizeOfData/sizeof(T)); span<unsigned char> charSpan(
reinterpret_cast<unsigned char*>(data.data()),
data.size()*sizeof(T));
span<unsigned char> charSpan( if(!readDataSTD(wordPath, chunkSizes, charSpan, startPosBinaryBlock))
reinterpret_cast<unsigned char*>(data.data()), {
data.size()*sizeof(T)); fatalErrorInFunction;
return false;
}
readDataSTD(filePath, chunkSizes, charSpan, startPosBinaryBlock); return true;
}
else if( ioPattern_.isAllProcessorDifferent() )
{
if(chunkSizes.size() != ioPattern_.globalSize())
{
if( ioPattern_.isMaster())
{
auto sizeOfData = std::accumulate(
chunkSizes.begin(),
chunkSizes.end(),
static_cast<uint64>(0));
data.resize(sizeOfData/sizeof(T));
span<unsigned char> charSpan(
reinterpret_cast<unsigned char*>(data.data()),
data.size()*sizeof(T));
if(!readDataSTD(wordPath, chunkSizes, charSpan, startPosBinaryBlock))
{
fatalErrorInFunction;
return false;
}
return true;
}
else
{
return true;
}
}
else
{
auto thisProc = ioPattern_.globalRank();
data.resize(chunkSizes[thisProc]/sizeof(T));
span<unsigned char> charSpan(
reinterpret_cast<unsigned char*>(data.data()),
data.size()*sizeof(T));
if( !readDataMPI(wordPath, chunkSizes, charSpan, startPosBinaryBlock) )
{
fatalErrorInFunction;
return false;
}
return true;
}
}
else
{
fatalErrorInFunction;
return false;
}
} }
if( IOType_ == AllProcessorsDifferent ) else
{ {
auto thisProc = processors::globalRank(); return true;
}
data.resize(chunkSizes[thisProc]/sizeof(T)); return false;
}
span<unsigned char> charSpan( template<typename T>
reinterpret_cast<unsigned char*>(data.data()), bool pFlow::dataIO::readAscii
data.size()*sizeof(T)); (
iIstream& is,
std::vector<T>& vec
)
{
std::cout<<"MPI part"<<std::endl; if( !ioPattern_.thisProcReadData() ) return true;
readDataMPI(filePath, chunkSizes, charSpan, startPosBinaryBlock);
is.fatalCheck(FUNCTION_NAME);
vec.clear();
token firstToken(is);
size_t len = 0;
if( firstToken.isInt64())
{
len = firstToken.int64Token();
vec.reserve(len);
firstToken = token(is);
}
T val{};
if( firstToken.isPunctuation() ) // start of vector
{
if(firstToken != token::BEGIN_LIST)
{
warningInFunction
<< "expected token "<< token::BEGIN_LIST
<< " but found "<< firstToken ;
return false;
}
token lastToken(is);
is.fatalCheck(FUNCTION_NAME);
while(!(lastToken.isPunctuation()
&& lastToken == token::END_LIST ))
{
is.putBack(lastToken);
is >> val;
vec.push_back(val);
is >> lastToken;
is.fatalCheck(FUNCTION_NAME);
}
} else
{
warningInFunction
<< "expected token "<< token::BEGIN_LIST
<< " but found "<< firstToken<<endl; ;
return false;
} }
if(len>0&& len != vec.size())
{
warningInFunction<<"vector lendth specified "<< len <<
" is different from number of elements "<< vec.size()<<endl;
return false;
}
return true; return true;
} }
template<typename T>
bool pFlow::dataIO::readData
(
iIstream& is,
std::vector<T>& vec,
bool resume
)
{
if(is.isBinary())
{
uint64 currPos = 0;
if( resume )
{
currPos = is.tell();
}
if(! BcastPos(currPos) ) return false;
if(!this->readDataBinary(is.name(), vec, currPos))
{
fatalErrorInFunction;
return false;
}
auto lastPos = lastPosRead_;
maxReduction( lastPos, lastPosRead_);
//std::cout<<"last post read "<< lastPosRead_<<std::endl;
/// set the stream indicator to the last position
is.seek(lastPosRead_);
return true;
}
else
{
if(!readAscii(is, vec))
{
fatalErrorInFunction;
return false;
}
return true;
}
}
template<typename T>
bool pFlow::dataIO::writeData
(
iOstream& os,
const span<T>& sp
)
{
if( os.isBinary() )
{
os.startOfBinaryStreaming();
if(!writeDataEnd(os.name(), sp))
{
fatalErrorInFunction;
return false;
}
os.endOfBinaryStreaming();
}
else
{
if( !writeAsciiEnd(os, sp) )
{
fatalErrorInFunction;
return false;
}
}
return true;
}

View File

@ -180,7 +180,7 @@ public:
bool isBinary()const bool isBinary()const
{ {
return writeFormat_ == BINARY; return writeFormat_ == BINARY;
} }
/// Return true if next operation might succeed /// Return true if next operation might succeed
bool good() const bool good() const

View File

@ -134,6 +134,10 @@ public:
/// Rewind the stream so that it may be read again /// Rewind the stream so that it may be read again
virtual void rewind() = 0; virtual void rewind() = 0;
virtual void seek(size_t pos) = 0;
/// Return current position indicator
virtual size_t tell() = 0;
////- find and lookups ////- find and lookups

View File

@ -144,7 +144,7 @@ public:
/// Write the flag to indicate the start of a binary block /// Write the flag to indicate the start of a binary block
virtual iOstream& writeBinaryBlockFlag(); virtual iOstream& writeBinaryBlockFlag();
virtual void seek(size_t pos) = 0;
//// - Indent //// - Indent
/// Add indentation characters /// Add indentation characters
@ -238,6 +238,12 @@ public:
////- Stream state functions ////- Stream state functions
/// Add a new line and flush stream
virtual void startOfBinaryStreaming() =0;
/// Reach end of file add a new line and flush stream
virtual void endOfBinaryStreaming() = 0 ;
/// Flush stream /// Flush stream
virtual void flush() = 0; virtual void flush() = 0;

View File

@ -0,0 +1,64 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#include "infinitePlane.hpp"
pFlow::infinitePlane::infinitePlane
(
const realx3& p1,
const realx3& p2,
const realx3& p3
)
{
auto ln = cross(p2-p1, p3-p1);
if( equal(ln.length(),0.0) )
{
fatalErrorInFunction<<
"invalid input to form a infinte wall "<< realx3x3(p1,p2,p3)<<endl;
fatalExit;
}
normal_ = normalize(ln);
d_ = -dot(normal_, p1);
}
bool pFlow::infinitePlane::write(iOstream& os)const
{
os.writeWordEntry("normal", normal_);
os.writeWordEntry("d", d_);
return os.check(FUNCTION_NAME);
}
bool pFlow::infinitePlane::read(iIstream & is)
{
if(!is.nextData<realx3>("normal", normal_)) return false;
if(!is.nextData<real>("d", d_)) return false;
return true;
}
bool pFlow::infinitePlane::validPlane3
(
const realx3& p1,
const realx3& p2,
const realx3& p3
)
{
return !equal(cross(p2-p1, p3-p1).length(), 0.0);
}

View File

@ -0,0 +1,165 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __infinitePlane_hpp__
#define __infinitePlane_hpp__
#include "types.hpp"
//#include "dictionary.hpp"
#include "iIstream.hpp"
#include "iOstream.hpp"
namespace pFlow
{
class infinitePlane
{
protected:
/// normal vector
realx3 normal_{1,0,0};
/// distance value
real d_ = 0;
public:
// - type info
TypeInfoNV("infinitePlane");
//// - Constructors
/// Default
INLINE_FUNCTION_HD
infinitePlane(){}
/// From components
INLINE_FUNCTION_HD
infinitePlane(const realx3& normal, const real& d)
:
normal_(normal),
d_(d)
{}
INLINE_FUNCTION_HD
infinitePlane(const realx3& normal, const realx3& p)
:
normal_(normal),
d_(-dot(normal,p))
{}
/// From 3 points
infinitePlane(const realx3& p1, const realx3& p2, const realx3& p3);
FUNCTION_HD
infinitePlane(const infinitePlane&) = default;
FUNCTION_HD
infinitePlane(infinitePlane&&) = default;
FUNCTION_HD
infinitePlane& operator=(const infinitePlane&) = default;
FUNCTION_HD
infinitePlane& operator=(infinitePlane&&) = default;
~infinitePlane()=default;
/*FUNCTION_H
infinitePlane(const dictionary& dict);
FUNCTION_H
infinitePlane(iIstream& is);*/
//// - Methods
INLINE_FUNCTION_HD
real pointFromPlane(const realx3& p)const
{
return dot(normal_, p) + d_;
}
INLINE_FUNCTION_HD
bool pointInPositiveSide(const realx3& p)const
{
return pointFromPlane(p)>=0;
}
INLINE_FUNCTION_HD
bool pointInNegativeSide(const realx3& p)const
{
return pointFromPlane(p)<0;
}
INLINE_FUNCTION_HD
bool pointOnPlane(const realx3& p)const
{
return equal(pointFromPlane(p),0.0);
}
INLINE_FUNCTION_HD
realx3 projectPoint(const realx3& p)const
{
real t = -(dot(normal_, p) + d_);
return t*normal_ + p;
}
//// - IO operation
FUNCTION_H
bool write(iOstream& os)const;
bool read(iIstream & is);
/*FUNCTION_H
bool read(iIstream & is);
FUNCTION_H
bool write(iOstream& os)const;
FUNCTION_H
bool read(const dictionary& dict);
FUNCTION_H
bool write(dictionary& dict)const;*/
static bool validPlane3(
const realx3& p1,
const realx3& p2,
const realx3& p3);
};
/*FUNCTION_H
iIstream& operator >>(iIstream& is, box& b);
FUNCTION_H
iOstream& operator << (iOstream& os, const box& b);
INLINE_FUNCTION_HD
box extendBox(const box& b, const realx3& dl)
{
return box(b.minPoint()-dl , b.maxPoint()+dl);
}*/
}
#endif // __infinitePlane_hpp__

View File

@ -55,19 +55,27 @@ public:
FUNCTION_HD FUNCTION_HD
line(const realx3 &lp1, const realx3 &lp2); line(const realx3 &lp1, const realx3 &lp2);
INLINE_FUNCTION_HD
line(const realx3 &v21, const realx3 &p1, bool)
:
v21_(v21),
p1_(p1)
{}
FUNCTION_H FUNCTION_H
line(const dictionary& dict); line(const dictionary& dict);
FUNCTION_HD INLINE_FUNCTION_HD
line(const line& src) = default; line(const line& src) = default;
FUNCTION_HD INLINE_FUNCTION_HD
line(line&& src) = default; line(line&& src) = default;
FUNCTION_HD INLINE_FUNCTION_HD
line& operator = (const line&) = default; line& operator = (const line&) = default;
FUNCTION_HD INLINE_FUNCTION_HD
line& operator = (line&&) = default; line& operator = (line&&) = default;

View File

@ -0,0 +1,68 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#include "plane.hpp"
pFlow::plane::plane
(
const realx3& p1,
const realx3& p2,
const realx3& p3,
const realx3& p4
)
:
infinitePlane(p1,p2,p3),
p1_(p1),
p2_(p2),
p3_(p3),
p4_(p4)
{
if(!pointOnPlane(p4))
{
fatalErrorInFunction<<
"points "<< realx4x3(p1,p2,p3,p4)<<" do not form a planner surface"<<endl;
fatalExit;
}
}
pFlow::plane pFlow::plane::parallelPlane(real distance)const
{
auto pp1 = line(normal_, p1_, true).point(distance);
auto pp2 = line(normal_, p2_, true).point(distance);
auto pp3 = line(normal_, p3_, true).point(distance);
auto pp4 = line(normal_, p4_, true).point(distance);
return plane(pp1, pp2, pp3, pp4);
}
bool pFlow::plane::validPlane4
(
const realx3& p1,
const realx3& p2,
const realx3& p3,
const realx3& p4
)
{
if( !validPlane3(p1,p2,p3)) return false;
if( !infinitePlane(p1,p2,p3).pointOnPlane(p4)) return false;
return true;
}

View File

@ -0,0 +1,136 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __plane_hpp__
#define __plane_hpp__
#include "infinitePlane.hpp"
#include "line.hpp"
namespace pFlow
{
class plane
:
public infinitePlane
{
protected:
/// First point
realx3 p1_;
/// Second point
realx3 p2_;
/// Third point
realx3 p3_;
/// Fourth point
realx3 p4_;
public:
INLINE_FUNCTION_HD
plane(){}
plane(
const realx3& p1,
const realx3& p2,
const realx3& p3,
const realx3& p4);
INLINE_FUNCTION_HD
plane(const plane&) = default;
INLINE_FUNCTION_HD
plane(plane&&) = default;
INLINE_FUNCTION_HD
plane& operator = (const plane&) = default;
INLINE_FUNCTION_HD
plane& operator =( plane&&)=default;
INLINE_FUNCTION_HD
~plane()=default;
INLINE_FUNCTION_HD
const realx3& p1()const
{
return p1_;
}
INLINE_FUNCTION_HD
const realx3& p2()const
{
return p2_;
}
INLINE_FUNCTION_HD
const realx3& p3()const
{
return p3_;
}
INLINE_FUNCTION_HD
const realx3& p4()const
{
return p4_;
}
INLINE_FUNCTION_HD
line line1()const
{
return line(p1_,p2_);
}
INLINE_FUNCTION_HD
line line2()const
{
return line(p2_,p3_);
}
INLINE_FUNCTION_HD
line line3()const
{
return line(p3_,p4_);
}
INLINE_FUNCTION_HD
line line4()const
{
return line(p4_,p1_);
}
// return the parallel plane to this plane
plane parallelPlane(real distance)const;
static
bool validPlane4(
const realx3& p1,
const realx3& p2,
const realx3& p3,
const realx3& p4);
};
}
#endif //__plane_hpp__