parallel read and write is added-we still need to consider integrating it with fields

This commit is contained in:
Hamidreza Norouzi 2023-10-17 20:30:20 +03:30
parent 6e5fe608c6
commit d2cd132b62
48 changed files with 2151 additions and 1071 deletions

View File

@ -4,9 +4,9 @@ list(APPEND validFiles *.C *.cpp *.cxx *.c *.cu *.H *.hpp *.hxx *.h *.cuh)
macro(Kokkos_cmake_settings)
mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA)
#mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA)
mark_as_advanced(FORCE var Kokkos_CXX_STANDARD)
mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_CONSTEXPR)
#mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_CONSTEXPR)
mark_as_advanced(FORCE var Kokkos_ENABLE_OPENMP)
mark_as_advanced(FORCE var Kokkos_ENABLE_SERIAL)
mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA)

View File

@ -21,7 +21,8 @@ streams/TStream/iTstream.cpp
streams/TStream/oTstream.cpp
streams/Fstream/iFstream.cpp
streams/Fstream/oFstream.cpp
streams/Fstream/fileStream.cpp
streams/Fstream/fileStream.cpp
streams/dataIO/dataIO.cpp
streams/streams.cpp
fileSystem/fileSystem.cpp
@ -33,6 +34,12 @@ dictionary/entry/iEntry.cpp
dictionary/entry/dataEntry.cpp
dictionary/twoPartEntry/twoPartEntry.cpp
containers/Vector/Vectors.cpp
repository/IOobject/objectFile.cpp
repository/IOobject/IOfileHeader.cpp
repository/IOobject/IOobject.cpp
)
set(link_libs)

View File

@ -25,6 +25,7 @@ Licence:
#include "KokkosTypes.hpp"
#include "pFlowMacros.hpp"
#include "types.hpp"
#include "span.hpp"
#include "iOstream.hpp"
namespace pFlow
@ -41,7 +42,7 @@ template<typename ExecutionSpace>
INLINE_FUNCTION_H
bool constexpr isDeviceAccessible()
{
return Kokkos::SpaceAccessibility<ExecutionSpace,DefaultExecutionSpace>::accessible;
return Kokkos::SpaceAccessibility<ExecutionSpace,DefaultExecutionSpace::memory_space>::accessible;
}
/// Is MemoerySpace accessible from ExecutionSpace
@ -56,7 +57,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocInit( ViewType1D<Type,Properties...>& view, int32 len)
void reallocInit( ViewType1D<Type,Properties...>& view, uint32 len)
{
Kokkos::realloc(Kokkos::WithoutInitializing, view, len);
}
@ -65,7 +66,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocNoInit(ViewType1D<Type,Properties...>& view, int32 len)
void reallocNoInit(ViewType1D<Type,Properties...>& view, uint32 len)
{
Kokkos::realloc(Kokkos::WithoutInitializing, view, len);
}
@ -74,7 +75,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocFill( ViewType1D<Type,Properties...>& view, int32 len, Type val)
void reallocFill( ViewType1D<Type,Properties...>& view, uint32 len, Type val)
{
reallocNoInit(view, len);
Kokkos::deep_copy(view, val);
@ -84,7 +85,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocInit( ViewType2D<Type,Properties...>& view, int32 len1, int32 len2)
void reallocInit( ViewType2D<Type,Properties...>& view, uint32 len1, uint32 len2)
{
Kokkos::realloc(view, len1, len2);
}
@ -93,7 +94,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocNoInit(ViewType2D<Type,Properties...>& view, int32 len1, int32 len2)
void reallocNoInit(ViewType2D<Type,Properties...>& view, uint32 len1, uint32 len2)
{
Kokkos::realloc(Kokkos::WithoutInitializing, view, len1, len2);
}
@ -102,7 +103,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocFill( ViewType2D<Type,Properties...>& view, int32 len1, int32 len2, Type val)
void reallocFill( ViewType2D<Type,Properties...>& view, uint32 len1, uint32 len2, Type val)
{
reallocNoInit(view, len1, len2);
Kokkos::deep_copy(view, val);
@ -112,7 +113,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocInit( ViewType3D<Type,Properties...>& view, int32 len1, int32 len2, int32 len3)
void reallocInit( ViewType3D<Type,Properties...>& view, uint32 len1, uint32 len2, uint32 len3)
{
Kokkos::realloc(view, len1, len2, len3);
}
@ -121,7 +122,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocNoInit(ViewType3D<Type,Properties...>& view, int32 len1, int32 len2, int32 len3)
void reallocNoInit(ViewType3D<Type,Properties...>& view, uint32 len1, uint32 len2, uint32 len3)
{
Kokkos::realloc(Kokkos::WithoutInitializing, view, len1, len2, len3);
@ -131,7 +132,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void reallocFill( ViewType3D<Type,Properties...>& view, int32 len1, int32 len2, int32 len3, Type val)
void reallocFill( ViewType3D<Type,Properties...>& view, uint32 len1, uint32 len2, uint32 len3, Type val)
{
reallocNoInit(view, len1, len2, len3);
Kokkos::deep_copy(view, val);
@ -141,7 +142,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void resizeInit(ViewType1D<Type,Properties...>& view, int32 newLen)
void resizeInit(ViewType1D<Type,Properties...>& view, uint32 newLen)
{
Kokkos::resize(view, newLen);
}
@ -150,7 +151,7 @@ template <
typename Type,
typename... Properties>
INLINE_FUNCTION_H
void resizeNoInit(ViewType1D<Type,Properties...>& view, int32 newLen)
void resizeNoInit(ViewType1D<Type,Properties...>& view, uint32 newLen)
{
Kokkos::resize(Kokkos::WithoutInitializing, view, newLen);
}
@ -177,6 +178,22 @@ iOstream& operator <<(iOstream& os, const Pair<T1,T2>& p)
return os;
}
template<typename T, typename... properties>
INLINE_FUNCTION_H
iOstream& operator <<(iOstream& os, const ViewType1D<T, properties...> & v)
{
using ExSpace = typename ViewType1D<T, properties...>::execution_space;
static_assert(isHostAccessible<ExSpace>(), "View memory is not accessible from Host");
span<T> spn(v.data(), v.size());
os<<spn;
return os;
}
} // pFlow
#endif //__KokkosUtilities_hpp__

View File

@ -129,6 +129,12 @@ public Kokkos::pair<T,T>
return end()-start();
}
INLINE_FUNCTION_HD
auto getPair()const
{
return Pair(this->first, this->second);
}
};
template<typename T>
@ -143,6 +149,10 @@ using range32 = Range<int32>;
using range64 = Range<int64>;
using rangeU32 = Range<uint32>;
using rangeU64 = Range<uint64>;
} // pFlow

View File

@ -35,16 +35,16 @@ namespace pFlow
{
template<typename T, typename... properties>
INLINE_FUNCTION_H
int32 count(
uint32 count(
const ViewType1D<T, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
const T& val)
{
using ExecutionSpace = typename ViewType1D<T, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
return pFlow::algorithms::KOKKOS::count<T, ExecutionSpace>
(
@ -59,11 +59,11 @@ INLINE_FUNCTION_H
void fill
(
ViewType1D<T, properties...>& view,
range32 span,
rangeU32 span,
T val
)
{
auto subV = Kokkos::subview(view, span);
auto subV = Kokkos::subview(view, span.getPair() );
Kokkos::deep_copy(subV, val);
}
@ -71,12 +71,12 @@ template<typename T, typename... properties>
void fill
(
ViewType1D<T, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
T val
)
{
fill(view, range32(start,end),val);
fill(view, rangeU32(start, end),val);
}
template<
@ -84,14 +84,14 @@ template<
typename... properties>
void fillSequence(
ViewType1D<Type, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
const Type startVal
)
{
using ExecutionSpace = typename ViewType1D<Type, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
pFlow::algorithms::KOKKOS::fillSequence<Type, ExecutionSpace>(
view.data()+start,
@ -110,24 +110,27 @@ template<
bool fillSelected
(
ViewType1D<Type, properties...> view,
const ViewType1D<indexType, indexProperties...> indices,
const int32 numElems,
const Type val
ViewType1D<indexType, indexProperties...> indices,
uint32 numElems,
Type val
)
{
static_assert(
areAccessible<
typename ViewType1D<Type, properties...>::execution_space,
typename ViewType1D<indexType, indexProperties...>::memory_space>(),
"In fillSelected arguments view and indices must have similar spaces");
"In fillSelected, arguments view and indices must have similar spaces");
using ExecutionSpace = typename ViewType1D<Type, properties...>::execution_space;
pFlow::algorithms::KOKKOS::fillSelected<Type, indexType, ExecutionSpace>(
view.data(),
indices.data(),
numElems,
val);
using ExSpace = typename ViewType1D<Type, properties...>::execution_space;
using policy = Kokkos::RangePolicy<ExSpace,Kokkos::IndexType<uint32> >;
Kokkos::parallel_for(
"ViewAlgorithms::fillSelected",
policy(0,numElems),
LAMBDA_HD(uint32 i){
//view[indices[i]]= val;
});
Kokkos::fence();
return true;
}
@ -141,7 +144,7 @@ bool fillSelected(
ViewType1D<Type, properties...> view,
const ViewType1D<indexType, indexProperties...> indices,
const ViewType1D<Type, properties...> vals,
const int32 numElems )
const uint32 numElems )
{
static_assert(
@ -167,14 +170,15 @@ template<typename T, typename... properties>
INLINE_FUNCTION_H
T min(
const ViewType1D<T, properties...>& view,
int32 start,
int32 end)
uint32 start,
uint32 end)
{
using ExecutionSpace = typename ViewType1D<T, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
return
pFlow::algorithms::KOKKOS::min<T, ExecutionSpace>(
view.data()+start,
numElems);
@ -184,13 +188,13 @@ template<typename T, typename... properties>
INLINE_FUNCTION_H
T max(
const ViewType1D<T, properties...>& view,
int32 start,
int32 end)
uint32 start,
uint32 end)
{
using ExecutionSpace = typename ViewType1D<T, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
return
pFlow::algorithms::KOKKOS::max<T, ExecutionSpace>(
@ -220,10 +224,10 @@ template <
INLINE_FUNCTION_H
void copy(
const ViewType1D<dType, dProperties...>& dst,
int32 dStart,
uint32 dStart,
const ViewType1D<sType, sProperties...>& src,
int32 sStart,
int32 sEnd
uint32 sStart,
uint32 sEnd
)
{
@ -244,7 +248,7 @@ INLINE_FUNCTION_H
void getNth(
dType& dst,
const ViewType1D<sType, sProperties...>& src,
const int32 n
const uint32 n
)
{
range32 span(n,n+1);
@ -259,12 +263,12 @@ template<typename T, typename... properties>
INLINE_FUNCTION_H
void sort(
ViewType1D<T, properties...>& view,
int32 start,
int32 end)
uint32 start,
uint32 end)
{
using ExecutionSpace = typename ViewType1D<T, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
if constexpr( isHostAccessible<ExecutionSpace>())
{
@ -291,14 +295,14 @@ template<typename T, typename... properties, typename CompareFunc>
INLINE_FUNCTION_H
void sort(
ViewType1D<T, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
CompareFunc compare)
{
using ExecutionSpace = typename ViewType1D<T, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
if constexpr( isHostAccessible<ExecutionSpace>())
{
@ -330,10 +334,10 @@ template<
typename... permProperties>
void permuteSort(
const ViewType1D<Type, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
ViewType1D<permType, permProperties...>& permuteView,
int32 permStart )
uint32 permStart )
{
static_assert(
areAccessible<
@ -343,7 +347,7 @@ void permuteSort(
using ExecutionSpace = typename ViewType1D<Type, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
pFlow::algorithms::STD::permuteSort<Type,permType,true>(
view.data()+start,
@ -367,8 +371,9 @@ void permuteSort(
template<typename T>
INLINE_FUNCTION_HD
int binarySearch_(const T* array, int length, const T& val)
int32 binarySearch_(const T* array, int32 length, const T& val)
{
if(length <= 0) return -1;
int low = 0;
int high = length - 1;
@ -401,8 +406,8 @@ template<
INLINE_FUNCTION_HD
int32 binarySearch(
const ViewType1D<Type, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
const Type& val)
{
@ -424,10 +429,10 @@ template<
typename... dProperties>
void exclusiveScan(
const ViewType1D<Type, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
ViewType1D<dType, dProperties...>& dView,
int32 dStart )
uint32 dStart )
{
static_assert
@ -441,7 +446,7 @@ void exclusiveScan(
using ExecutionSpace = typename ViewType1D<Type, properties...>::execution_space;
int32 numElems = end-start;
uint32 numElems = end-start;
pFlow::algorithms::KOKKOS::exclusiveScan<Type,dType,ExecutionSpace>(
view.data()+start,
@ -457,10 +462,10 @@ template<
typename... dProperties>
void inclusiveScan(
const ViewType1D<Type, properties...>& view,
int32 start,
int32 end,
uint32 start,
uint32 end,
ViewType1D<dType, dProperties...>& dView,
int32 dStart)
uint32 dStart)
{
using ExecutionSpace = typename ViewType1D<Type, properties...>::execution_space;
@ -473,7 +478,7 @@ void inclusiveScan(
);
int32 numElems = end-start;
uint32 numElems = end-start;
pFlow::algorithms::KOKKOS::inclusiveScan<Type,dType,ExecutionSpace>(
view.data()+start,

View File

@ -21,7 +21,7 @@ Licence:
#ifndef __phsicFlowKokkos_hpp__
#define __phsicFlowKokkos_hpp__
#include "kokkosTypes.hpp"
#include "KokkosTypes.hpp"
#include "KokkosUtilities.hpp"
#include "ViewAlgorithms.hpp"
#include "Range.hpp"

View File

@ -64,16 +64,16 @@ protected:
bool copy(const ListPtrType& src);
// - return ith pointer
T* ptr(label i);
T* ptr(size_t i);
// - return ith const poiter
const T* ptr(label i)const;
const T* ptr(size_t i)const;
// - iterator position of ith element
auto pos(label i);
auto pos(size_t i);
// - const iterator position of ith element
auto pos(label i) const;
auto pos(size_t i) const;
public:
@ -141,15 +141,15 @@ public:
//// - Methods
// - set the ith element
T* set(label i, T* ptr);
T* set(size_t i, T* ptr);
// - set the ith element and take the ownership from uniquePtr
uniquePtr<T> set(label i, uniquePtr<T>& ptr );
uniquePtr<T> set(size_t i, uniquePtr<T>& ptr );
// - create the object in-place and set the pointer in ith position
// if oject creation fails, uniquePtr deletes the memeory
template<typename... Args>
uniquePtr<T> setSafe(label i, Args&&... args);
uniquePtr<T> setSafe(size_t i, Args&&... args);
// - put the pointer at the end
void push_back(T* ptr);
@ -163,11 +163,11 @@ public:
// - access to ith element
// fatalexit if out of range or nullptr
T& operator[](label i);
T& operator[](size_t i);
// - const access to ith element
// fatalexit if out of range or nullptr
const T& operator[](label i) const;
const T& operator[](size_t i) const;
// size of container
size_t size()const;
@ -176,13 +176,13 @@ public:
auto empty() const;
// release the ownership of ith pointer
uniquePtr<T> release(label i);
uniquePtr<T> release(size_t i);
// - clear the content of list and delete objects
void clear();
// - clear the ith element
void clear(label i);
void clear(size_t i);
// - clone the object

View File

@ -39,7 +39,7 @@ inline bool pFlow::ListPtr<T>::copy(const ListPtrType& src)
}
template<typename T>
T* pFlow::ListPtr<T>::ptr(label i)
T* pFlow::ListPtr<T>::ptr(size_t i)
{
if(i >= size() ) return nullptr;
@ -53,7 +53,7 @@ T* pFlow::ListPtr<T>::ptr(label i)
template<typename T>
const T* pFlow::ListPtr<T>::ptr
(
label i
size_t i
) const
{
@ -68,7 +68,7 @@ const T* pFlow::ListPtr<T>::ptr
template<typename T>
auto pFlow::ListPtr<T>::pos
(
label i
size_t i
)
{
if(i >= size() )
@ -86,7 +86,7 @@ auto pFlow::ListPtr<T>::pos
template<typename T>
auto pFlow::ListPtr<T>::pos
(
label i
size_t i
)const
{
if(i >= size() )
@ -146,7 +146,7 @@ pFlow::ListPtr<T>& pFlow::ListPtr<T>::operator=
template<typename T>
T* pFlow::ListPtr<T>::set
(
label i, T* ptr
size_t i, T* ptr
)
{
uniquePtr<T> uptr(ptr);
@ -157,7 +157,7 @@ T* pFlow::ListPtr<T>::set
template<typename T>
pFlow::uniquePtr<T> pFlow::ListPtr<T>::set
(
label i,
size_t i,
uniquePtr<T>& ptr
)
{
@ -182,7 +182,7 @@ template<typename T>
template<typename... Args>
pFlow::uniquePtr<T> pFlow::ListPtr<T>::setSafe
(
label i,
size_t i,
Args&&... args
)
{
@ -216,7 +216,7 @@ void pFlow::ListPtr<T>::push_backSafe(Args&&... args)
template<typename T>
T& pFlow::ListPtr<T>::operator[]
(
label i
size_t i
)
{
T* p = ptr(i);
@ -234,7 +234,7 @@ T& pFlow::ListPtr<T>::operator[]
template<typename T>
const T& pFlow::ListPtr<T>::operator[]
(
label i
size_t i
) const
{
const T* p = ptr(i);
@ -263,7 +263,7 @@ auto pFlow::ListPtr<T>::empty() const
template<typename T>
pFlow::uniquePtr<T> pFlow::ListPtr<T>::release
(
label i
size_t i
)
{
auto p = ptr(i);
@ -288,7 +288,7 @@ void pFlow::ListPtr<T>::clear()
template<typename T>
void pFlow::ListPtr<T>::clear
(
label i
size_t i
)
{
T* p = ptr(i);

View File

@ -138,7 +138,7 @@ template<typename T>
using wordMap = Map<word,T>;
template<typename T>
using labelMap = Map<label,T>;
using uint64Map = Map<uint64,T>;
template<typename T>
using uint32Map = Map<uint32,T>;
@ -155,7 +155,7 @@ template<typename T>
inline iOstream& printKeys(iOstream& os, const wordMap<T> & m);
template<typename T>
inline iOstream& printKeys(iOstream& os, const labelMap<T> & m);
inline iOstream& printKeys(iOstream& os, const uint64Map<T> & m);
template<typename T>
inline iOstream& printKeys(iOstream& os, const uint32Map<T> & m);

View File

@ -92,7 +92,7 @@ inline iOstream& printKeys(iOstream& os, const uint32Map<T> & m)
}
template<typename T>
inline iOstream& printKeys(iOstream& os, const labelMap<T> & m)
inline iOstream& printKeys(iOstream& os, const uint64Map<T> & m)
{
if (m.empty())
return os<<"labelMap is empty"<<endl;

View File

@ -140,7 +140,7 @@ template<typename T>
using wordHashMap = hashMap<word,T>;
template<typename T>
using labelHashMap = hashMap<label,T>;
using uint64HashMap = hashMap<uint64,T>;
template<typename T>
using uint32HashMap = hashMap<uint32,T>;
@ -155,7 +155,7 @@ template<typename T>
inline iOstream& printKeys(iOstream& os, const wordHashMap<T> & m);
template<typename T>
inline iOstream& printKeys(iOstream& os, const labelHashMap<T> & m);
inline iOstream& printKeys(iOstream& os, const uint64HashMap<T> & m);
template<typename T>
inline iOstream& printKeys(iOstream& os, const uint32HashMap<T> & m);

View File

@ -80,7 +80,7 @@ inline iOstream& printKeys(iOstream& os, const wordHashMap<T> & m)
template<typename T>
inline iOstream& printKeys(iOstream& os, const labelHashMap<T> & m)
inline iOstream& printKeys(iOstream& os, const uint64HashMap<T> & m)
{
if (m.empty())
return os<<"labelHashMap is empty"<<endl;

View File

@ -19,12 +19,6 @@ Licence:
-----------------------------------------------------------------------------*/
template<typename T, typename Allocator>
pFlow::Vector<T, Allocator>::Vector(iIstream& is)
{
readVector(is);
}
template<typename T, typename Allocator>
bool pFlow::Vector<T, Allocator>::readVector
(
@ -33,7 +27,6 @@ bool pFlow::Vector<T, Allocator>::readVector
)
{
if(is.isBinary() && !std::is_same_v<T,word>)
{
this->resize(len);
@ -90,8 +83,6 @@ bool pFlow::Vector<T, Allocator>::readVector
}
}
return true;
}
@ -102,8 +93,12 @@ bool pFlow::Vector<T, Allocator>::writeVector
iOstream& os
) const
{
span<T> s( const_cast<T*>(this->data()), this->size());
os<<s;
// start of
if( os.isBinary() && !std::is_same_v<T,word>)
/*if( os.isBinary() && !std::is_same_v<T,word>)
{
os.write(reinterpret_cast<const char*>(this->data()), this->size()*sizeof(T));
}
@ -113,12 +108,12 @@ bool pFlow::Vector<T, Allocator>::writeVector
auto len = size();
auto stride = getVectorStride(len);
os << token::BEGIN_LIST;
label i = 0;
size_t i = 0;
while( i<len )
{
os << this->operator[](i++);
for(label j=0; j<stride-1 && i<len; j++ )
for(size_t j=0; j<stride-1 && i<len; j++ )
{
os << token::SPACE << this->operator[](i++);
}
@ -130,12 +125,12 @@ bool pFlow::Vector<T, Allocator>::writeVector
os << token::END_LIST;
os.check(FUNCTION_NAME);
}
}*/
return true;
}
template<typename T, typename Allocator>
/*template<typename T, typename Allocator>
bool pFlow::Vector<T, Allocator>::deleteElement_sorted
(
const Vector<label>& indices
@ -384,4 +379,4 @@ inline bool pFlow::Vector<T, Allocator>::insertSetElement
}
return true;
}
}*/

View File

@ -29,7 +29,7 @@ Licence:
#include "error.hpp"
#include "uniquePtr.hpp"
#include "stdAlgorithms.hpp"
#include "indexContainer.hpp"
#include "span.hpp"
#include "iOstream.hpp"
#include "iIstream.hpp"
@ -93,16 +93,6 @@ protected:
// - name of the vector
word name_;
static inline size_t getVectorStride(const size_t& len)
{
size_t stride = 1;
if( len < 6 ) stride = len;
else if( len <16 ) stride = 3;
else if( len < 31) stride = 2;
else stride = 1;
return stride;
}
static constexpr bool isHostAccessible_ = true;
@ -119,37 +109,28 @@ public:
//// - Constructors
// - empty Vector
/// Empty Vector
inline Vector()
:
Vector("Vector")
{}
/// Empty Vector with a name
inline Vector(const word& name)
:
name_(name)
{}
// - with sepcified length
inline Vector(const size_t len)
:
Vector("Vector",len)
{}
// - with specified length and name
/// Vector with specified length and name
inline Vector(const word& name, size_t len)
:
vectorType(len),
name_(name)
{
}
// - with length and value
inline Vector(size_t len, const T& val)
:
Vector("Vector", len, val)
{}
/// Vector with name, length and value
inline Vector(const word& name, size_t len, const T& val)
:
Vector(name, len)
@ -157,20 +138,7 @@ public:
this->assign(len, val);
}
// - zero length with specified capacity, use Logical
// to make it different from previous constructor.
inline Vector(const size_t cap, RESERVE ):
Vector("Vector", cap, 0, RESERVE())
{
}
inline Vector(const size_t cap, const size_t len, RESERVE )
:
Vector("Vector", cap, len, RESERVE())
{
}
/// Vector with name, size and reserved capacity
Vector(const word& name, size_t cap, size_t len, RESERVE ):
name_(name)
{
@ -178,142 +146,157 @@ public:
this->resize(len);
}
inline Vector(const size_t cap, const size_t len, const T& val, RESERVE )
{
name_ = "Vector";
reserve(cap);
this->assign(len, val);
}
// from initializer list
inline Vector(const initList &l)
/// Vector from name and initializer list
inline Vector(const word& name, const initList &l)
:
vectorType(l)
vectorType(l),
name_(name)
{}
// - from src and a new name
/// Construct with a name and form std::vector (host memory)
inline Vector(const word& name, const vectorType& src)
:
vectorType(src),
name_(name)
{}
/// Construct with a name and form std::vector (host memory)
/// and with a desired capacity.
inline Vector(const word& name, const vectorType& src, size_t cap)
:
Vector(name, cap, src.size(), RESERVE())
{
this->assign(src.begin(), src.end());
}
/// Copy construct
inline Vector(const VectorType& src) = default;
/// Copy from src with a new name
inline Vector(const word name, const Vector<T>& src):
vectorType(src),
name_(name)
{}
// copy construct
inline Vector(const VectorType& src) = default;
// move construct
inline Vector( VectorType && mv) = default;
inline Vector(const vectorType& src)
:
vectorType(src),
name_("Vector")
{
}
// copy assignment
/// Copy assignment
inline VectorType& operator=( const VectorType& rhs ) = default;
/// Copy assignment from std::vector
inline VectorType& operator=(const vectorType& rhs)
{
Vector::assign(rhs.begin(), rhs.end());
return *this;
}
// move assignment
/// Move construct
inline Vector( VectorType && mv) = default;
/// Move assignment
inline VectorType& operator=( VectorType && mv) = default;
// scalar assignment
/// Scalar assignment
inline void operator=(const T& val)
{
fill(val);
}
/// Destructor
inline ~Vector()
{
vectorType::clear();
}
/// Clone as a uniquePtr
inline uniquePtr<VectorType> clone() const
{
return makeUnique<VectorType>(*this);
}
/// Clone as a pointer
inline VectorType* clonePtr()const
{
return new VectorType(*this);
}
inline auto clear()
{
return vectorType::clear();
}
//// - Methods
// access to this, mostly used by derived classes
const VectorType& VectorField() const
{
return *this;
}
VectorType& VectorField()
{
return *this;
}
/// Access to this, mostly used by derived classes
const VectorType& VectorField() const
{
return *this;
}
VectorType& VectorField()
{
return *this;
}
const vectorType& vectorField()const
{
return *this;
}
const vectorType& vectorField()const
{
return *this;
}
vectorType& vectorField()
{
return *this;
}
vectorType& vectorField()
{
return *this;
}
auto& deviceVectorAll()
{
return *this;
}
auto& deviceVectorAll()
{
return *this;
}
const auto& deviceVectorAll()const
{
return *this;
}
const auto& deviceVectorAll()const
{
return *this;
}
auto& deviceVector()
{
return *this;
}
auto& deviceVector()
{
return *this;
}
const auto& deviceVector()const
{
return *this;
}
const auto& deviceVector()const
{
return *this;
}
/// Name of the vector
const word& name()const
{
return name_;
}
const word& name()const
{
return name_;
}
/// Size of the vector
inline auto size()const
{
return vectorType::size();
}
inline auto size()const
{
return vectorType::size();
}
/// Capacity of the vector
inline auto capacity()const
{
return vectorType::capacity();
}
inline auto capacity()const
{
return vectorType::capacity();
}
/// If vector is empty
inline bool empty()const
{
return vectorType::empty();
}
inline auto reserve(label len)
{
return vectorType::reserve(len);
}
/// Reserve capacity for vector
/// Preserve the content.
inline void reserve(size_t cap)
{
vectorType::reserve(cap);
}
// - delete elemens of vector based on sorted indices
/*// - delete elemens of vector based on sorted indices
// return false if out of range
bool deleteElement_sorted(const Vector<label>& indices );
@ -346,7 +329,7 @@ public:
// - set or insert a new element into the vecor
// return false if it fails
inline bool insertSetElement(int32 idx, const T& val);
inline bool insertSetElement(int32 idx, const T& val);*/
// - fill the whole content of vector, [begin, end), with val
inline void fill( const T& val);
@ -368,12 +351,7 @@ public:
inline VectorType operator -()const;
// from iIstream and specified size
//Vector(iIstream & is, size_t len);
// from iIstream and free size
Vector(iIstream& is);
bool readVector(iIstream& is, size_t len=0);
bool writeVector(iOstream& os) const;

View File

@ -77,7 +77,7 @@ inline void pFlow::Vector<T, Allocator>::operator +=( const Vector<T, Allocator>
fatalExit;
}
for(label i=0; i<v.size(); i++)
for(size_t i=0; i<v.size(); i++)
{
this->operator[](i) += v[i];
}
@ -96,7 +96,7 @@ inline void pFlow::Vector<T, Allocator>::operator -=( const Vector<T, Allocator>
fatalExit;
}
for(label i=0; i<v.size(); i++)
for(size_t i=0; i<v.size(); i++)
{
this->operator[](i) -= v[i];
}
@ -115,7 +115,7 @@ inline void pFlow::Vector<T, Allocator>::operator *=( const Vector<T, Allocator>
fatalExit;
}
for(label i=0; i<v.size(); i++)
for(size_t i=0; i<v.size(); i++)
{
this->operator[](i) *= v[i];
}
@ -134,7 +134,7 @@ inline void pFlow::Vector<T, Allocator>::operator /=( const Vector<T, Allocator>
fatalExit;
}
for(label i=0; i<v.size(); i++)
for(size_t i=0; i<v.size(); i++)
{
this->operator[](i) /= v[i];
}

View File

@ -18,12 +18,14 @@ Licence:
-----------------------------------------------------------------------------*/
namespace pFlow
{
#define VecFunc(fnName) \
template<typename T, typename Allocator> \
inline pFlow::Vector<T, Allocator> pFlow::fnName(const Vector<T,Allocator>& v) \
inline Vector<T, Allocator> fnName(const Vector<T,Allocator>& v) \
{ \
Vector<T, Allocator> res(v.capacity(), Logical()); \
Vector<T, Allocator> res(v.name(), v.capacity(), 0 ,RESERVE()); \
for(auto& e:v) \
{ \
res.push_back( fnName(e) ); \
@ -31,10 +33,10 @@ inline pFlow::Vector<T, Allocator> pFlow::fnName(const Vector<T,Allocator>& v) \
return std::move(res); \
} \
template<typename T, typename Allocator, typename indexFunc> \
inline pFlow::Vector<T, Allocator> pFlow::fnName(const Vector<T, Allocator>& v, indexFunc iFn) \
inline Vector<T, Allocator> fnName(const Vector<T, Allocator>& v, indexFunc iFn) \
{ \
Vector<T, Allocator> res(v.capacity(), Logical()); \
for(label i=0; i<v.size(); i++) \
Vector<T, Allocator> res(v.name(), v.capacity(), 0, RESERVE()); \
for(size_t i=0; i<v.size(); i++) \
{ \
if( iFn(i) ) \
res.push_back(fnName(v[i])); \
@ -46,20 +48,20 @@ inline pFlow::Vector<T, Allocator> pFlow::fnName(const Vector<T, Allocator>& v,
#define VecFunc2(fnName) \
template<typename T, typename Allocator> \
inline pFlow::Vector<T, Allocator> pFlow::fnName(const Vector<T, Allocator>& v1, const Vector<T, Allocator>& v2) \
inline Vector<T, Allocator> fnName(const Vector<T, Allocator>& v1, const Vector<T, Allocator>& v2) \
{ \
Vector<T, Allocator> res(v1.capacity(), Logical()); \
for(label i=0; i<v1.size(); i++) \
Vector<T, Allocator> res(v1.name(), v1.capacity(), 0 ,RESERVE()); \
for(size_t i=0; i<v1.size(); i++) \
{ \
res.push_back( fnName(v1[i], v2[i])); \
} \
return std::move(res); \
} \
template<typename T, typename Allocator, typename indexFunc> \
inline pFlow::Vector<T, Allocator> pFlow::fnName(const Vector<T, Allocator>& v1, const Vector<T, Allocator>& v2, indexFunc iFn) \
inline Vector<T, Allocator> fnName(const Vector<T, Allocator>& v1, const Vector<T, Allocator>& v2, indexFunc iFn) \
{ \
Vector<T, Allocator> res(v1.capacity(), Logical()); \
for(label i=0; i<v1.size(); i++) \
Vector<T, Allocator> res(v1.name(), v1.capacity(), 0 ,RESERVE()); \
for(size_t i=0; i<v1.size(); i++) \
{ \
if( iFn(i) ) \
res.push_back(fnName(v1[i], v2[i])); \
@ -77,6 +79,8 @@ inline pFlow::Vector<T, Allocator> pFlow::fnName(const Vector<T, Allocator>& v1,
// min, max
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * //
VecFunc(abs);
VecFunc2(mod);
VecFunc(exp);
@ -100,6 +104,9 @@ VecFunc(acosh);
VecFunc(atanh);
#undef VecFunc
}
//// special implementation of math functions
namespace pFlow
@ -108,7 +115,7 @@ namespace pFlow
template<typename T, typename Allocator>
inline Vector<T, Allocator> pow(const Vector<T, Allocator>& v, T e)
{
Vector<T, Allocator> res(v.capacity(), Logical());
Vector<T, Allocator> res(v.name(), v.capacity(), 0 ,RESERVE());
for(auto& elm:v)
{
res.push_back(pow(elm,e));
@ -119,8 +126,8 @@ inline Vector<T, Allocator> pow(const Vector<T, Allocator>& v, T e)
template<typename T, typename Allocator, typename indexFunc>
inline Vector<T,Allocator> pow(const Vector<T,Allocator>& v, T e, indexFunc iFn)
{
Vector<T, Allocator> res(v.capacity(), Logical());
for(label i=0; i<v.size(); i++)
Vector<T, Allocator> res(v.name(), v.capacity(), 0 ,RESERVE());
for(size_t i=0; i<v.size(); i++)
{
if(iFn(i))
{
@ -149,7 +156,7 @@ template<typename T, typename Allocator, typename indexFunc>
inline T min(const Vector<T, Allocator>& v, indexFunc iFn)
{
T minVal(largestPositive<T>());
for(label i=0; i<v.size(); i++)
for(size_t i=0; i<v.size(); i++)
{
if(iFn(i))
{
@ -175,7 +182,7 @@ template<typename T, typename Allocator ,typename indexFunc>
inline T max(const Vector<T, Allocator>& v, indexFunc iFn)
{
T maxVal(largestNegative<T>());
for(label i=0; i<v.size(); i++)
for(size_t i=0; i<v.size(); i++)
{
if(iFn(i))
{
@ -201,7 +208,7 @@ template<typename T, typename Allocator, typename indexFunc>
inline T sum(const Vector<T, Allocator>& v, indexFunc iFn)
{
T s = static_cast<T>(0);
for(label i=0; i<v.size(); ++i)
for(size_t i=0; i<v.size(); ++i)
{
if(iFn(i))
s += v[i];

View File

@ -21,25 +21,20 @@ Licence:
#include "Vectors.hpp"
// instantiation just for numeral types
template class pFlow::Vector<pFlow::int8>;
template class pFlow::Vector<pFlow::int16>;
template class pFlow::Vector<pFlow::int8>;
template class pFlow::Vector<pFlow::int32>;
template class pFlow::Vector<pFlow::int64>;
template class pFlow::Vector<pFlow::uint32>;
template class pFlow::Vector<pFlow::label>;
template class pFlow::Vector<pFlow::real>;
template class pFlow::Vector<pFlow::realx3>;
template class pFlow::Vector<pFlow::realx3x3>;
//template class pFlow::Vector<pFlow::word>;

View File

@ -31,69 +31,25 @@ namespace pFlow
using int8Vector = Vector<int8>;
using int16Vector = Vector<int16>;
using int32Vector = Vector<int32>;
using int64Vector = Vector<int64>;
using uint32Vector = Vector<uint32>;
using uint8Vector = Vector<uint8>;
using labelVector = Vector<label>;
using uint32Vector = Vector<uint32>;
using uint64Vector = Vector<uint64>;
using realVector = Vector<real> ;
using realx3Vector = Vector<realx3>;
using uint16x3Vector= Vector<uint16x3>;
using uint32x3Vector= Vector<uint32x3>;
using int32x3Vector = Vector<int32x3>;
using int64x3Vector = Vector<int64x3>;
using uint16x3x3Vector = Vector<uint16x3x3>;
using uint32x3x3Vector = Vector<uint32x3x3>;
using int32x3x3Vector = Vector<int32x3x3>;
using realx3x3Vector = Vector<realx3x3>;
using wordVector = Vector<word>;
/*template<>
inline word Vector<label>::TYPENAME() { return "labelVector"; }
typedef Vector<label> labelVector;
template<>
inline word Vector<real>::TYPENAME() { return "realVector"; }
typedef Vector<real> realVector;
template<>
inline word Vector<unit3>::TYPENAME() { return "unit3Vector"; }
typedef Vector<unit3> unit3Vector;
template<>
inline word Vector<real3>::TYPENAME() { return "real3Vector"; }
typedef Vector<real3> real3Vector;
template<>
inline word Vector<real33>::TYPENAME() { return "real33Vector"; }
typedef Vector<real33> real33Vector;
template<>
inline word Vector<bool>::TYPENAME() { return "boolVector"; }
typedef Vector<bool> boolVector;
template<>
inline word Vector<word>::TYPENAME() { return "wordVector"; }
typedef Vector<word> wordVector;
template<>
inline word Vector<sint>::TYPENAME() { return "sintVector"; }
typedef Vector<sint> sintVector;*/
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,197 @@
/*------------------------------- 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.
-----------------------------------------------------------------------------*/
template<typename T, typename MemorySpace>
INLINE_FUNCTION_H
bool pFlow::VectorSingle<T,MemorySpace>::insertSetElement(uint32IndexContainer indices, const T& val)
{
if(indices.empty()) return true;
auto maxInd = indices.max();
if(this->empty() || maxInd > size()-1 )
{
resize(maxInd+1);
}
using policy = Kokkos::RangePolicy<executionSpace,Kokkos::IndexType<uint32>>;
if constexpr( isDeviceAccessible_ )
{
auto v = view_;
auto ind = indices.deviceView();
Kokkos::parallel_for(
"VectorSingle::insertSetElement",
policy(0,indices.size()),
LAMBDA_HD(uint32 i){
v[ind[i]]= val;
});
Kokkos::fence();
}
else
{
auto v = view_;
auto ind = indices.hostView();
Kokkos::parallel_for(
"VectorSingle::insertSetElement",
policy(0,indices.size()),
LAMBDA_HD(uint32 i){
v[ind[i]]= val;
});
Kokkos::fence();
}
return true;
}
template<typename T, typename MemorySpace>
INLINE_FUNCTION_H
bool pFlow::VectorSingle<T,MemorySpace>::insertSetElement
(
const uint32IndexContainer indices,
const std::vector<T>& vals
)
{
if(indices.size() == 0)return true;
if(indices.size() != vals.size())return false;
auto maxInd = indices.max();
if(this->empty() || maxInd > size()-1 )
{
resize(maxInd+1);
}
using policy = Kokkos::RangePolicy<executionSpace,Kokkos::IndexType<uint32>>;
hostViewType1D<const T> hVals( vals.data(), vals.size());
if constexpr( isDeviceAccessible_ )
{
deviceViewType1D<T> dVals("dVals", indices.size());
copy(dVals, hVals);
auto dVec = view_;
auto ind = indices.deviceView();
Kokkos::parallel_for(
"VectorSingle::insertSetElement",
policy(0,indices.size()), LAMBDA_HD(int32 i){
dVec(ind(i))= dVals(i);}
);
Kokkos::fence();
}
else
{
auto dVec = view_;
auto ind = indices.hostView();
Kokkos::parallel_for(
"VectorSingle::insertSetElement",
policy(0,indices.size()), LAMBDA_HD(int32 i){
dVec(ind(i))= hVals(i);}
);
Kokkos::fence();
}
return true;
}
template<typename T, typename MemorySpace>
INLINE_FUNCTION_H
bool pFlow::VectorSingle<T,MemorySpace>::reorderItems(uint32IndexContainer indices)
{
if(indices.size() == 0)
{
setSize(0);
return true;
}
auto maxInd = indices.max();
if(maxInd >= this->size())
{
fatalErrorInFunction<<"In reordering the VectorSingle ("
<< this->name()<< ") maximum index ("<< maxInd <<
") exceeds the size of the vector (" << this->size()<<")"<<endl;
return false;
}
uint32 newSize = indices.size();
setSize(newSize);
viewType sortedView(this->name(), newSize);
using policy = Kokkos::RangePolicy< executionSpace,Kokkos::IndexType<uint32>>;
if constexpr( isDeviceAccessible_)
{
auto d_indices = indices.deviceView();
auto d_view = view_;
Kokkos::parallel_for
(
"VectorSingle::sortItems",
policy(0,newSize),
LAMBDA_HD(uint32 i)
{
sortedView(i) = d_view(d_indices(i));
}
);
Kokkos::fence();
}
else
{
auto h_indices = indices.hostView();
auto d_view = view_;
Kokkos::parallel_for
(
"VectorSingle::sortItems",
policy(0,newSize),
LAMBDA_HD(uint32 i)
{
sortedView(i) = d_view(h_indices(i));
}
);
Kokkos::fence();
}
copy(deviceVector(), sortedView);
return true;
}

View File

@ -33,10 +33,6 @@ typedef VectorSingle<int8> int8Vector_D;
typedef VectorSingle<int8, HostSpace> int8Vector_H;
typedef VectorSingle<int16> int16Vector_D;
typedef VectorSingle<int16, HostSpace> int16Vector_H;
typedef VectorSingle<int32> int32Vector_D;
typedef VectorSingle<int32, HostSpace> int32Vector_H;
@ -45,13 +41,17 @@ typedef VectorSingle<int64> int64Vector_D;
typedef VectorSingle<int64, HostSpace> int64Vector_H;
typedef VectorSingle<uint8> uint8Vector_D;
typedef VectorSingle<uint8, HostSpace> uint8Vector_H;
typedef VectorSingle<uint32> uint32Vector_D;
typedef VectorSingle<uint32, HostSpace> uint32Vector_H;
typedef VectorSingle<label> labelVector_D;
typedef VectorSingle<uint64> uint64Vector_D;
typedef VectorSingle<label, HostSpace> labelVector_H;
typedef VectorSingle<uint64, HostSpace> uint64Vector_H;
typedef VectorSingle<real> realVector_D;
@ -61,14 +61,6 @@ typedef VectorSingle<realx3> realx3Vector_D;
typedef VectorSingle<realx3, HostSpace> realx3Vector_H;
typedef VectorSingle<uint16x3> uint16x3Vector_D;
typedef VectorSingle<uint16x3, HostSpace> uint16x3Vector_H;
typedef VectorSingle<uint32x3> uint32x3Vector_D;
typedef VectorSingle<uint32x3, HostSpace> uint32x3Vector_H;
typedef VectorSingle<int32x3> int32x3Vector_D;
typedef VectorSingle<int32x3, HostSpace> int32x3Vector_H;
@ -77,6 +69,10 @@ typedef VectorSingle<int64x3> int64x3Vector_D;
typedef VectorSingle<int64x3, HostSpace> int64x3Vector_H;
typedef VectorSingle<uint32x3> uint32x3Vector_D;
typedef VectorSingle<uint32x3, HostSpace> uint32x3Vector_H;
typedef VectorSingle<realx3x3> realx3x3Vector_D;
typedef VectorSingle<realx3x3, HostSpace> realx3x3Vector_H;

View File

@ -21,32 +21,41 @@ Licence:
#ifndef __indexContainer_hpp__
#define __indexContainer_hpp__
#include "span.hpp"
#include "KokkosTypes.hpp"
#include "KokkosUtilities.hpp"
#include "ViewAlgorithms.hpp"
#include <vector>
#include "phasicFlowKokkos.hpp"
namespace pFlow
{
/**
* It holds two vectors of indecis on Host and Device.
* Host vector should be used for threads running on
* Host and Device vector should be used for threads
* running on Device.
*/
template<typename IndexType>
class indexContainer
{
public:
using DualViewType = Kokkos::DualView<IndexType*>;
using DVType = DualViewType1D<IndexType>;
/// Device type on device
using DeviceViewType = typename DVType::t_dev;
// - viewType of data on device
using DeviceViewType = typename DualViewType::t_dev;
/// Host type on device
using HostViewType = typename DVType::t_host;
// - viewType of data on host
using HostViewType = typename DualViewType::t_host;
/// Host memory type
using HostType = typename HostViewType::device_type;
using HostType = typename HostViewType::device_type;
using DeviceType = typename DeviceViewType::device_type;
/// Device memory ype
using DeviceType = typename DeviceViewType::device_type;
/**
* Helper class for accessing index on host or device
*/
template<typename ViewType>
class IndexAccessor
{
@ -58,169 +67,207 @@ public:
view_(v){}
INLINE_FUNCTION_HD
IndexType operator()(int32 i)const
IndexType operator()(uint32 i)const
{
return view_[i];
}
uint32 size()const
{
return view_.extent(0);
}
};
protected:
int32 min_ = 0;
int32 max_ = 0;
size_t size_ = 0;
/// min value in indices
IndexType min_ = 0;
DualViewType views_;
/// max value in the indices
IndexType max_ = 0;
/// number/size of index vector
uint32 size_ = 0;
/// views to hold indices on Host and Device
DVType views_;
public:
indexContainer(){}
//// - Constructors
// half open [begin,end)
indexContainer(IndexType begin, IndexType end)
:
min_(begin),
max_(end-1),
size_(end-begin),
views_("indexContainer", size_)
{
pFlow::fillSequence(views_.h_view, 0, size_, min_);
copy(views_.d_view, views_.h_view);
}
/// Default
indexContainer(){}
/// Construct from a Range (half open)
template<typename T>
indexContainer(const Range<T>& rng)
:
indexContainer
(
static_cast<IndexType>(rng.begin()),
static_cast<IndexType>(rng.end())
)
{}
indexContainer(IndexType* data, int32 numElems)
:
size_(numElems),
views_("indexContainer", numElems)
{
HostViewType hData(data, numElems);
copy(views_.h_view, hData);
copy(views_.d_view, views_.h_view);
min_ = pFlow::min(views_.d_view, 0, numElems);
max_ = pFlow::max(views_.d_view, 0, numElems);
}
indexContainer(const indexContainer&) = default;
indexContainer& operator = (const indexContainer&) = default;
indexContainer(indexContainer&&) = default;
indexContainer& operator = (indexContainer&&) = default;
~indexContainer() = default;
INLINE_FUNCTION_HD
size_t size()const
{
return size_;
}
INLINE_FUNCTION_HD
size_t empty()const
{
return size_==0;
}
INLINE_FUNCTION_HD
IndexType min()const
{
return min_;
}
INLINE_FUNCTION_HD
IndexType max()const
{
return max_;
}
template<typename executionSpace>
INLINE_FUNCTION_HD
IndexType operator()(selectSide<executionSpace>,int32 i)const
{
if constexpr (isHostAccessible<executionSpace>())
/// Construct half open [begin,end)
indexContainer(IndexType begin, IndexType end)
:
min_(begin),
max_(end-1),
size_(end-begin),
views_("indexContainer", size_)
{
return views_.h_view(i);
}else
{
return views_.d_view(i);
}
}
const HostViewType& hostView()const
{
return views_.h_view;
}
const DeviceViewType& deviceView()const
{
return views_.d_view;
}
HostViewType& hostView()
{
return views_.h_view;
}
DeviceViewType& deviceView()
{
return views_.d_view;
}
auto indicesHost()const
{
return IndexAccessor<HostViewType>(views_.h_view);
}
auto indicesDevice()const
{
return IndexAccessor<DeviceViewType>(views_.d_view);
}
void modifyOnHost()
{
views_.modify_host();
}
void modifyOnDevice()
{
views_.modify_device();
}
void syncViews()
{
bool findMinMax = false;
if(views_.template need_sync<HostType>())
{
Kokkos::deep_copy(views_.d_view, views_.h_view);
findMinMax = true;
}
else if(views_.template need_sync<DeviceType>())
{
Kokkos::deep_copy(views_.h_view, views_.d_view);
findMinMax = true;
pFlow::fillSequence(views_.h_view, 0, size_, min_);
copy(views_.d_view, views_.h_view);
}
if(findMinMax)
/// From data and number of elements in data.
/// data is a pointer in the Host memory
indexContainer(IndexType* data, int32 numElems)
:
size_(numElems),
views_("indexContainer", numElems)
{
min_ = pFlow::min(views_.d_view, 0, size_);
max_ = pFlow::max(views_.d_view, 0, size_);
HostViewType hData(data, numElems);
copy(views_.h_view, hData);
copy(views_.d_view, views_.h_view);
min_ = pFlow::min(views_.d_view, 0, numElems);
max_ = pFlow::max(views_.d_view, 0, numElems);
}
indexContainer(std::vector<IndexType> &ind)
:
indexContainer(ind.data(), ind.size())
{}
/// Copy
indexContainer(const indexContainer&) = default;
/// Copy assignment
indexContainer& operator = (const indexContainer&) = default;
/// Move
indexContainer(indexContainer&&) = default;
/// Mover assignement
indexContainer& operator = (indexContainer&&) = default;
/// Destructor
~indexContainer() = default;
//// - Methods
/// Size
INLINE_FUNCTION_HD
auto size()const
{
return size_;
}
/// If the container empty
INLINE_FUNCTION_HD
bool empty()const
{
return size_==0;
}
/// Min value of indices
INLINE_FUNCTION_HD
IndexType min()const
{
return min_;
}
/// Max value of indices
INLINE_FUNCTION_HD
IndexType max()const
{
return max_;
}
/// Return Host veiw
const HostViewType& hostView()const
{
return views_.h_view;
}
/// Return Device view
const DeviceViewType& deviceView()const
{
return views_.d_view;
}
/// Return Host veiw
HostViewType& hostView()
{
return views_.h_view;
}
/// Return Device veiw
DeviceViewType& deviceView()
{
return views_.d_view;
}
/// Return index accessor that works on Host
auto indicesHost()const
{
return IndexAccessor<HostViewType>(views_.h_view);
}
/// Return index accessor that works on Device
auto indicesDevice()const
{
return IndexAccessor<DeviceViewType>(views_.d_view);
}
/// Mark host is modified
void modifyOnHost()
{
views_.modify_host();
}
/// Mark device is modified
void modifyOnDevice()
{
views_.modify_device();
}
/// synchronize views
void syncViews()
{
bool findMinMax = false;
if(views_.template need_sync<HostType>())
{
Kokkos::deep_copy(views_.d_view, views_.h_view);
views_.clear_sync_state();
findMinMax = true;
}
else if(views_.template need_sync<DeviceType>())
{
Kokkos::deep_copy(views_.h_view, views_.d_view);
views_.clear_sync_state();
findMinMax = true;
}
if(findMinMax)
{
min_ = pFlow::min(views_.d_view, 0, size_);
max_ = pFlow::max(views_.d_view, 0, size_);
}
}
}
size_t setSize(size_t ns)
{
auto tmp = size_;
size_ = ns;
return tmp;
}
};
using int32IndexContainer = indexContainer<int32>;
using int64IndexContainer = indexContainer<int64>;
using uint32IndexContainer = indexContainer<uint32>;
using uint64IndexContainer = indexContainer<uint64>;
}

View File

@ -51,7 +51,7 @@ protected:
T* data_ = nullptr;
label size_ = 0;
uint32 size_ = 0;
public:
@ -63,7 +63,7 @@ public:
INLINE_FUNCTION_HD
span(T* data, label size)
span(T* data, uint32 size)
: data_(data), size_(size)
{}
@ -98,7 +98,7 @@ public:
/// Returns the number of elements in the span
INLINE_FUNCTION_HD
label size() const
uint32 size() const
{
return size_;
}
@ -131,6 +131,18 @@ public:
return data_ + size_;
}
INLINE_FUNCTION_HD
T& operator[](uint32 i)
{
return data_[i];
}
INLINE_FUNCTION_HD
const T& operator[](uint32 i)const
{
return data_[i];
}
INLINE_FUNCTION_HD
T& operator[](int32 i)
{
@ -143,16 +155,35 @@ public:
return data_[i];
}
INLINE_FUNCTION_HD
T& operator[](label i)
/// Write in ASCII format, can be sued for all variable types
INLINE_FUNCTION_H
bool writeASCII(iOstream& os) const
{
return data_[i];
os << token::BEGIN_LIST;
if(size()>0)
{
for(uint32 i=0; i<size()-1; i++)
{
os << data_[i]<<token::NL;
}
os << data_[size()-1] << token::END_LIST;
}
else
{
os<< token::END_LIST;
}
os.check(FUNCTION_NAME);
return true;
}
INLINE_FUNCTION_HD
const T& operator[](label i)const
/// Write in Binray format, can be used for numeral types (Not word or similar ones)
INLINE_FUNCTION_H
bool writeBinary(iOstream& os) const
{
return data_[i];
os.write(reinterpret_cast<const char*>(data_), this->size()*sizeof(T));
os.check(FUNCTION_NAME);
return true;
}
};
@ -161,15 +192,15 @@ template<typename T>
inline
iOstream& operator<<(iOstream& os, const span<T>& s)
{
os << token::BEGIN_LIST;
for(size_t i=0; i<s.size(); i++)
{
os << s[i]<<token::NL;
}
os << token::END_LIST;
os.check(FUNCTION_NAME);
if( os.isBinary() && !std::is_same_v<T,word>)
{
s.writeBinary(os);
}
else
{
s.writeASCII(os);
}
return os;
}

View File

@ -12,12 +12,12 @@ Licence:
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
phasicFlow is distribute+d 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 "IOfileHeader.hpp"
#include "repository.hpp"
@ -133,9 +133,24 @@ bool pFlow::IOfileHeader::readIfPresent()const
return fileExist() && isReadIfPresent();
}
bool pFlow::IOfileHeader::writeHeader(iOstream& os, const word& typeName) const
bool pFlow::IOfileHeader::writeHeader()const
{
if( !this->readWriteHeader() ) return false;
if( !processors::isMaster() ) return false;
if( !implyWrite() ) return false;
return true;
}
bool pFlow::IOfileHeader::writeHeader
(
iOstream& os,
const word& typeName,
bool forceWrite
) const
{
if(!forceWrite && !writeHeader()) return true;
writeBanner(os);
@ -158,14 +173,22 @@ bool pFlow::IOfileHeader::writeHeader(iOstream& os, const word& typeName) const
return true;
}
bool pFlow::IOfileHeader::writeHeader(iOstream& os) const
bool pFlow::IOfileHeader::writeHeader(iOstream& os, bool forceWrite) const
{
return writeHeader(os, objectType_);
return writeHeader(os, objectType_, forceWrite);
}
bool pFlow::IOfileHeader::readHeader()const
{
if( !this->readWriteHeader() ) return false;
return true;
}
bool pFlow::IOfileHeader::readHeader(iIstream& is, bool silent)
{
if(!readHeader()) return true;
if( !is.findTokenAndNextSilent("objectName", objectName_) )
{
if(!silent)
@ -200,6 +223,19 @@ bool pFlow::IOfileHeader::readHeader(iIstream& is, bool silent)
return false;
}
return true;
}
bool pFlow::IOfileHeader::writeData()const
{
if( processors::isMaster() || this->differentDataOnProcessors())
return true;
else
return false;
}
bool pFlow::IOfileHeader::readData()const
{
return true;
}

View File

@ -95,26 +95,45 @@ public:
// read the header of the file to check if it is ok
bool headerOk(bool silent = false);
// - imply read
/// Imply read
bool implyRead() const;
// - imply write
/// Imply write
bool implyWrite() const;
// - check if file exists
/// Check if file exists
bool fileExist() const;
// - check read if present
/// Check read if present
bool readIfPresent()const;
// - write the header in the file , typeName comes from caller
bool writeHeader(iOstream& os, const word& typeName) const;
/// Check if the header should be written to file
/// True: on master + implyWrite + readWriteHeader = true
/// False: slave or NOT implyWrite
bool writeHeader()const;
// - write the header in the file, typeName comes from the one read from file
bool writeHeader(iOstream& os) const;
// - read the header in the file
/// Write the header to the file , typeName comes from caller
bool writeHeader(iOstream& os, const word& typeName, bool forceWrite = false ) const;
/// Write the header to the file, typeName comes from the one read from file
bool writeHeader(iOstream& os, bool forceWrite = false) const;
/// Check if the data should be written to file
/// True: on master or differentDataOnProcessor is true
/// False: otherwise
bool writeData()const;
/// Check if header should be read from file
/// True: All processors, read the file header
/// False: readWriteHeader = false
bool readHeader()const;
/// Read the header in the file
bool readHeader(iIstream& is, bool silent=false);
/// Check if data should be read from file
/// Always return true
bool readData()const;
// - write the banner
bool writeBanner(iOstream& os)const;

View File

@ -61,23 +61,25 @@ private:
:
public iObject
{
public:
protected:
dataType data_;
public:
template<typename... Args,
typename = std::enable_if_t<!std::is_constructible<object_t, Args&&...>::value>>
typename = std::enable_if_t<std::is_constructible<dataType, Args&&...>::value>>
object_t(Args&&... args)
:
data_(std::forward<Args>(args)...)
{}
{
/*constexpr word msg(dataType::TYPENAME()+"input is not a member function.")
static_assert(std::is_member_function_pointer<decltype(&dataType::write)>::value,
msg.c_str());*/
}
// cunstruct by copying data
object_t(const dataType& data): data_(data){}
// construct by moving data
//object_t(dataType&& data): data_(std::move(data)){}
object_t(const dataType& data): data_(data)
{}
virtual uniquePtr<iObject> clone() const
@ -100,6 +102,16 @@ private:
return data_.write(os);
}
auto& data()
{
return data_;
}
const auto& data()const
{
return data_;
}
};
protected:
@ -107,8 +119,9 @@ protected:
//// - data members
// underlaying data object
uniquePtr<iObject> object_;
uniquePtr<iObject> object_ = nullptr;
public:
@ -127,6 +140,42 @@ public:
// - construct from components, transfer the ownership of IOobject to the owner (no read happens)
IOobject(const objectFile& objf, const repository* owner, uniquePtr<IOobject>&& obj);
template<typename T,
typename = std::enable_if_t<
!std::is_same<T, uniquePtr<IOobject::iObject>>::value &&
!std::is_same<T, uniquePtr<IOobject>>::value>>
IOobject(const objectFile& objf, const repository* owner, const T& data)
:
IOfileHeader(objf, owner),
object_(makeUnique<object_t<T>>(data))
{
if(!read(this->readWriteHeader()))
{
fatalErrorInFunction<<
"error in reading " << name() << " from path " << path()<<endl;
fatalExit;
}
}
template<typename T,
typename = std::enable_if_t<
!std::is_same<T, uniquePtr<IOobject::iObject>>::value &&
!std::is_same<T, uniquePtr<IOobject>>::value>>
IOobject(const objectFile& objf, const repository* owner, T&& data)
:
IOfileHeader(objf, owner),
object_(makeUnique<object_t<T>>(data))
{
if(!read(this->readWriteHeader()))
{
fatalErrorInFunction<<
"error in reading " << name() << " from path " << path()<<endl;
fatalExit;
}
}
// - copy construct
IOobject(const IOobject& src)=delete;
@ -142,7 +191,7 @@ public:
// - construct object_t with the Args as the arguments of object constructor
template<typename T, typename... Args>
static auto make_object_t(Args&&... args);
static uniquePtr<iObject> make_object_t(Args&&... args);
//// - Access to data object
@ -158,7 +207,6 @@ public:
template<typename T>
const auto& getObject()const;
//// - IO operations

View File

@ -18,6 +18,7 @@ Licence:
-----------------------------------------------------------------------------*/
template<typename T, typename... Args>
auto pFlow::IOobject::make
(
@ -32,7 +33,7 @@ auto pFlow::IOobject::make
}
template<typename T, typename... Args>
auto pFlow::IOobject::make_object_t(Args&&... args)
pFlow::uniquePtr<pFlow::IOobject::iObject> pFlow::IOobject::make_object_t(Args&&... args)
{
auto ptr = makeUnique<object_t<T>>(std::forward<Args>(args)...);
return ptr;
@ -47,7 +48,7 @@ auto& pFlow::IOobject::getObject()
"accessing an invalid objecct "<< name() <<endl;
fatalExit;
}
return dynamic_cast<object_t<T>&>(*object_).data_;
return static_cast<object_t<T>&>(*object_).data();
}
@ -60,5 +61,5 @@ const auto& pFlow::IOobject::getObject()const
"accessing an invalid objecct "<< name() <<endl;
fatalExit;
}
return dynamic_cast<const object_t<T>&>(*object_).data_;
return static_cast<const object_t<T>&>(*object_).data();
}

View File

@ -25,10 +25,7 @@ pFlow::objectFile::objectFile
const word& name
)
:
name_(name),
rFlag_(READ_NEVER),
wFlag_(WRITE_NEVER),
localPath_("")
name_(name)
{}
pFlow::objectFile::objectFile
@ -37,13 +34,15 @@ pFlow::objectFile::objectFile
const fileSystem& localPath,
const readFlag& rf,
const writeFlag& wf,
bool rwHeader
bool diffDataOnProcessors,
bool rwHdr
)
:
name_(name),
rFlag_(rf),
wFlag_(wf),
localPath_(localPath),
readWriteHeader_(rwHeader)
differentDataOnProcessors_(diffDataOnProcessors),
readWriteHeader_(rwHdr)
{
}

View File

@ -49,18 +49,30 @@ public:
protected:
// name of the entity
/// Name of the entity
word name_;
// read flag
readFlag rFlag_;
/// Read flag
readFlag rFlag_ = READ_NEVER;
// write flag
writeFlag wFlag_;
/// Write flag
writeFlag wFlag_ = WRITE_NEVER;
// local path of entity
fileSystem localPath_;
/// Local path of entity
fileSystem localPath_ = "";
/// Number of bytes used for writing/reading real variable (mostly used for binray)
int numBytesForReal_ = numBytesForReal__;
/// All processors have the different set of data or not?
/// 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
bool readWriteHeader_ = true;
public:
@ -80,7 +92,8 @@ public:
const fileSystem& localPath,
const readFlag& rf = READ_NEVER,
const writeFlag& wf = WRITE_NEVER,
bool rwHeader = true
bool diffDataOnProcessors = true,
bool rwHdr = true
);
// copy construct
@ -92,6 +105,7 @@ public:
objectFile& operator = (objectFile && rhs) = default;
virtual ~objectFile()=default;
virtual word name() const
@ -104,41 +118,55 @@ public:
return localPath_;
}
inline
readFlag rFlag()const
{
return rFlag_;
}
inline
writeFlag wFlag()const
{
return wFlag_;
}
inline
bool isReadAlways()const
{
return rFlag_ == READ_ALWAYS;
}
inline
bool isReadNever()const
{
return rFlag_ == READ_NEVER;
}
inline
bool isReadIfPresent()const
{
return rFlag_ == READ_IF_PRESENT;
}
inline
bool isWriteAlways()const
{
return wFlag_ == WRITE_ALWAYS;
}
inline
bool isWriteNever()const
{
return wFlag_ == WRITE_NEVER;
}
inline
bool differentDataOnProcessors()const
{
return differentDataOnProcessors_;
}
inline
bool readWriteHeader()const
{
return readWriteHeader_;

View File

@ -858,6 +858,36 @@ pFlow::iIstream& pFlow::Istream::read
return *this;
}
size_t pFlow::Istream::findBinaryBlockStart()
{
size_t pos = 0;
char getChar = 'a';
unsigned char bFlag = 255;
int numFound = 0;
while( is_.good() && !is_.eof() )
{
getChar = is_.get();
pos++;
if( numFound <3 &&
static_cast<unsigned char>(getChar) == bFlag )
{
numFound++;
}
else if(numFound == 3 && static_cast<unsigned char>(getChar) == 0 )
{
return pos;
}
else
{
numFound = 0;
}
}
return static_cast<size_t>(-1);
}
void pFlow::Istream::rewind()
{
lineNumber_ = 1; // Reset line number

View File

@ -153,6 +153,8 @@ public:
iIstream& read(char* buffer, std::streamsize count) override;
size_t findBinaryBlockStart()override;
/// Rewind the stream so that it may be read again
virtual void rewind();

View File

@ -222,6 +222,13 @@ pFlow::iOstream& pFlow::Ostream::write(const double val)
return *this;
}
pFlow::iOstream& pFlow::Ostream::write(const size_t val)
{
os_ << val;
setState(os_.rdstate());
return *this;
}
pFlow::iOstream& pFlow::Ostream::write
(
const char* binaryData,
@ -239,11 +246,19 @@ pFlow::iOstream& pFlow::Ostream::write
os_.write(binaryData, count);
os_ << token::END_LIST;
setState(os_.rdstate());
return *this;
}
pFlow::iOstream& pFlow::Ostream::writeBinaryBlockFlag()
{
write( static_cast<char>(255));
write( static_cast<char>(255));
write( static_cast<char>(255));
write( static_cast<char>(0));
return *this;
}
void pFlow::Ostream::indent()
{
for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i)

View File

@ -124,9 +124,14 @@ public:
/// Write double
iOstream& write(const double val) override;
/// Write size_t
iOstream& write(const size_t val) override;
/// Write a block of binray data
iOstream& write(const char* binaryData, std::streamsize count) override;
iOstream& writeBinaryBlockFlag() override;
/// Add indentation characters
void indent() override;

View File

@ -155,6 +155,14 @@ pFlow::iOstream& pFlow::oTstream::write(const double val)
return *this;
}
pFlow::iOstream& pFlow::oTstream::write(const size_t val)
{
append(token(static_cast<int64>(val))); // tokenType::INT64
return *this;
}
pFlow::iOstream& pFlow::oTstream::write
(
const char* binaryData,

View File

@ -129,6 +129,9 @@ public:
/// Write double
virtual iOstream& write(const double val) override;
/// Write double
virtual iOstream& write(const size_t val) override;
/// Write a block of binray data
iOstream& write(
const char* binaryData,

View File

@ -0,0 +1,612 @@
#include "phasicFlowConfig.H"
#ifdef pFlow_Build_MPI
#include <mpi.h>
#endif
#include <cstdio>
#include <numeric>
#include "dataIO.hpp"
#include "fileSystem.hpp"
#include "streams.hpp"
static const size_t numcharFlag = 8;
static inline unsigned char binaryFlag__[numcharFlag] = {255, 255, 255, 255, 255, 255, 255 ,0};
inline
pFlow::uint64 chunkSizeOffeset(pFlow::uint64 procNo)
{
// 1 is added for number of processors
return (1+procNo)*sizeof(pFlow::uint64);
}
bool writeBinaryBlockFlagSTD(std::FILE* fh)
{
std::size_t nw = std::fwrite( binaryFlag__ , sizeof(unsigned char), numcharFlag, fh );
if(nw < numcharFlag)
return false;
else
return true;
}
pFlow::uint64 findBindaryBlockFlagSTD(std::FILE* fh)
{
// get the current postion
long fpos;
if( fpos = std::ftell( fh) ; fpos == -1L )
{
fatalErrorInFunction;
return -1;
}
pFlow::uint64 filePos = static_cast<pFlow::uint64>(fpos);
// start reading char by char
int c;
unsigned char ch;
int currPos = 0;
while ( std::fread(&ch, sizeof(ch), 1, fh) == 1 )
{
if(std::ferror(fh)) return -1;
if(std::feof(fh))return -1;
filePos++;
if(ch == binaryFlag__[currPos] )
{
currPos++;
if(currPos == numcharFlag) return filePos;
}
else
{
currPos = 0;
}
}
return -1;
}
#ifdef pFlow_Build_MPI
pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh)
{
// 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);
// start reading char by char
unsigned char ch;
int currPos = 0;
while( MPI_File_read(
fh,
&ch,
1,
MPI_UNSIGNED_CHAR,
MPI_STATUS_IGNORE) == MPI_SUCCESS )
{
filePos++;
if(ch == binaryFlag__[currPos] )
{
currPos++;
if(currPos == numcharFlag) return filePos;
}
else
{
currPos = 0;
}
}
return -1;
}
#endif
bool pFlow::dataIO::writeDataToFileEndSTD
(
const fileSystem& filePath,
const span<unsigned char>& data
)
{
if(!processors::isMaster()) return true;
// openfile
word wFile = filePath.wordPath();
auto fh = std::fopen(wFile.c_str(), "ab");
if(!fh)
{
fatalErrorInFunction<<
"Error in Opening file "<< filePath <<endl;
std::fclose(fh);
return false;
}
// write the start of binary block flag
if(std::fseek(fh, 0 , SEEK_END)!=0)
{
fatalErrorInFunction<<
"error at reaching end of file "<<filePath<<endl;
std::fclose(fh);
return false;
}
if(!writeBinaryBlockFlagSTD(fh) )
{
fatalErrorInFunction<<
"Error in writing to file "<< filePath<<endl;
std::fclose(fh);
return false;
}
uint64 numChunks = 1;
// write number of data chunks
auto wc = std::fwrite(&numChunks, sizeof(numChunks), 1, fh);
if(wc < 1)
{
fatalErrorInFunction<<
"Error in writing numChunks to file "<< filePath <<endl;
std::fclose(fh);
return false;
}
// write size of each data chunk
uint64 sizeOfData = data.size();
wc = std::fwrite(&sizeOfData, sizeof(sizeOfData), 1, fh);
if(wc <1)
{
fatalErrorInFunction<<
"Error in writing size of data chunk to file "<< filePath <<endl;
std::fclose(fh);
return false;
}
if(sizeOfData>0 )
{
// write data chunk to file
wc = std::fwrite(data.data(), sizeof(unsigned char), sizeOfData, fh);
if(wc < sizeOfData )
{
fatalErrorInFunction<<
"Error in writing size of data to file "<< filePath <<endl;
std::fclose(fh);
return false;
}
}
// close the file
std::fclose(fh);
return true;
}
bool pFlow::dataIO::writeDataToFileEndMPI
(
const fileSystem& filePath,
const span<unsigned char>& data
)
{
#ifdef pFlow_Build_MPI
// collect information from other processes
uint64 numProc = processors::globalSize();
uint64 thisSize = data.size();
uint64 offset;
CheckMPI
(
MPI_Scan(&thisSize, &offset, 1, MPI_UINT64_T, MPI_SUM, MPI_COMM_WORLD),
true
);
word wFile = filePath.wordPath();
MPI_File fh;
if( MPI_File_open(
MPI_COMM_WORLD,
wFile.c_str(),
MPI_MODE_WRONLY+MPI_MODE_APPEND,
MPI_INFO_NULL,
&fh) != MPI_SUCCESS)
{
fatalErrorInFunction<<
"Cannot open file "<< filePath<<endl;
return false;
}
uint64 startPos;
if( processors::isMaster())
{
// set position to the end of file
MPI_File_seek(fh, 0 , MPI_SEEK_END);
if( MPI_File_write(
fh,
binaryFlag__,
numcharFlag,
MPI_UNSIGNED_CHAR,
MPI_STATUS_IGNORE
) != MPI_SUCCESS )
{
fatalErrorInFunction<<
"Cannot write binary block flag into "<< filePath<<endl;
return false;
}
MPI_Offset posOfBlock;
if( MPI_File_get_position(fh, &posOfBlock) != MPI_SUCCESS )
{
fatalErrorInFunction<<
"Cannot get the end pos of file "<< filePath<<endl;
return false;
}
startPos = static_cast<uint64>(posOfBlock);
}
if( MPI_Bcast(
&startPos,
1,
MPI_UINT64_T,
processors::masterNo(),
MPI_COMM_WORLD) != MPI_SUCCESS)
{
fatalErrorInFunction;
return false;
}
if( processors::isMaster())
{
uint64 numProc = processors::globalSize();
if(MPI_File_write(
fh,
&numProc,
1,
MPI_UINT64_T,
MPI_STATUS_IGNORE) != MPI_SUCCESS)
{
fatalErrorInFunction<<
"Cannot write number of chunks into "<<filePath<<endl;
return false;
}
}
uint64 sizeOffset = startPos + chunkSizeOffeset(processors::globalRank());
if(MPI_File_write_at_all(
fh,
sizeOffset,
&thisSize,
1,
MPI_UINT64_T,
MPI_STATUS_IGNORE)!= MPI_SUCCESS)
{
fatalErrorInFunction<<
"Cannot write size of chunk into "<<filePath<<endl;
return false;
}
offset -= thisSize;
uint64 chunkOffset = startPos + chunkSizeOffeset(processors::globalSize()) + offset;
if(MPI_File_write_at_all(
fh,
chunkOffset,
data.data(),
thisSize,
MPI_UNSIGNED_CHAR,
MPI_STATUS_IGNORE) != MPI_SUCCESS)
{
fatalErrorInFunction<<
"Cannot write data into "<<filePath<<endl;
return false;;
}
MPI_File_close(&fh);
MPI_Barrier(MPI_COMM_WORLD);
return true;
#else
return writeDataToFileEndSTD(filePath, data);
#endif
}
bool pFlow::dataIO::readDataSTD
(
const fileSystem& filePath,
const std::vector<uint64> chunkSizes,
span<unsigned char>& data,
uint64 binaryBlockStart
)
{
// sum of all chuncks
uint64 toRecv = std::accumulate(
chunkSizes.begin(),
chunkSizes.end(),
static_cast<uint64>(0));
if( data.size() != toRecv )
{
fatalErrorInFunction;
return false;
}
word wFile = filePath.wordPath();
auto fh = std::fopen(wFile.c_str(), "rb");
if(!fh)
{
fatalErrorInFunction<<
"Error in Opening file "<< filePath<<endl;
return false;
}
// start of data chunks
uint64 offset = binaryBlockStart + chunkSizeOffeset(chunkSizes.size());
if(auto res = std::fseek(fh, offset, SEEK_SET); res!= 0 )
{
fatalErrorInFunction<<
"Error in file seek "<< filePath<<endl;
std::fclose(fh);
return false;
}
if(auto res = std::fread(
data.data(),
sizeof(unsigned char),
data.size(),
fh);
res!= data.size() )
{
fatalErrorInFunction<<
"Error in reading file "<< filePath<<endl;
std::fclose(fh);
return false;
}
std::fclose(fh);
return true;
}
bool pFlow::dataIO::readDataMPI
(
const fileSystem& filePath,
const std::vector<uint64> chunkSizes,
span<unsigned char>& data,
uint64 binaryBlockStart
)
{
#ifdef pFlow_Build_MPI
if(chunkSizes.size() != processors::globalSize() )
{
fatalErrorInFunction;
return false;
}
word wFile = filePath.wordPath();
MPI_File fh;
if( MPI_File_open(
MPI_COMM_WORLD,
wFile.c_str(),
MPI_MODE_RDONLY,
MPI_INFO_NULL,
&fh))
{
fatalErrorInFunction;
return false;
}
auto procNo = processors::globalRank();
uint64 toRecv = chunkSizes[procNo];
// start of data chunks
uint64 offset = binaryBlockStart + chunkSizeOffeset(processors::globalSize());
for(auto i=0; i<procNo; i++)
{
offset += chunkSizes[i];
}
if( data.size() != toRecv )
{
fatalErrorInFunction;
return false;
}
MPI_Status status;
if( MPI_File_read_at_all(
fh,
offset,
data.data(),
data.size(),
MPI_UNSIGNED_CHAR,
&status) != MPI_SUCCESS )
{
fatalErrorInFunction;
return false;
}
#else
#endif
return true;
}
bool pFlow::dataIO::readMetaMPI
(
const fileSystem& filePath,
std::vector<uint64>& chunkSizes,
uint64 &startPosBinaryBlock
)
{
word wFile = filePath.wordPath();
#ifdef pFlow_Build_MPI
MPI_File fh;
if(MPI_File_open(
MPI_COMM_WORLD,
wFile.c_str(),
MPI_MODE_RDONLY,
MPI_INFO_NULL,
&fh) != MPI_SUCCESS)
{
fatalErrorInFunction;
return false;
}
uint64 startPos = findBindaryBlockFlagMPI(fh);
if( startPos == -1 )
{
fatalErrorInFunction;
return false;
}
startPosBinaryBlock = startPos;
uint64 numProcInFile;
if( MPI_File_read_at_all(
fh,
startPos,
&numProcInFile,
1,
MPI_UINT64_T,
MPI_STATUS_IGNORE) != MPI_SUCCESS)
{
fatalErrorInFunction;
return false;
}
chunkSizes.resize(numProcInFile);
if(MPI_File_read_at_all(
fh,
startPos + sizeof(numProcInFile),
chunkSizes.data(),
chunkSizes.size(),
MPI_UINT64_T,
MPI_STATUS_IGNORE) != MPI_SUCCESS)
{
fatalErrorInFunction;
return false;
}
MPI_File_close(&fh);
#endif
return true;
}
bool pFlow::dataIO::readMetaSTD
(
const fileSystem& filePath,
std::vector<uint64>& chunkSizes,
uint64 &startPosBinaryBlock
)
{
// only on master
if( !processors::isMaster()) return true;
word wFile = filePath.wordPath();
std::FILE *fh = std::fopen(wFile.c_str(), "rb");
if(!fh)
{
fatalErrorInFunction<<
"Error in Opening file "<< filePath<<endl;
return false;
}
uint64 startPos = findBindaryBlockFlagSTD(fh);
if(startPos == -1 )
{
fatalErrorInFunction;
return false;
}
startPosBinaryBlock = startPos;
std::fseek(fh, startPos, SEEK_SET);
uint64 numProcInFile;
auto res = std::fread(&numProcInFile, sizeof(numProcInFile), 1, fh);
if(res != 1 )
{
fatalErrorInFunction<<
"Error in reading file "<< filePath<<endl;
std::fclose(fh);
return false;
}
chunkSizes.resize(numProcInFile);
res = std::fread(chunkSizes.data(), sizeof(numProcInFile), numProcInFile, fh);
if(res!= numProcInFile)
{
fatalErrorInFunction<<
"Error in reading chunkSizes from file "<< filePath<<endl;
std::fclose(fh);
return false;
}
std::fclose(fh);
return true;
}

View File

@ -0,0 +1,103 @@
#ifndef __dataIO_hpp__
#define __dataIO_hpp__
#include <vector>
#include "types.hpp"
#include "span.hpp"
#include "processors.hpp"
namespace pFlow
{
class fileSystem;
class dataIO
{
public:
/**
* Type of input/output
* 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:
IOType IOType_;
bool writeDataToFileEndSTD(
const fileSystem& filePath,
const span<unsigned char>& data);
bool writeDataToFileEndMPI(
const fileSystem& filePath,
const span<unsigned char>& data);
bool readDataSTD(
const fileSystem& filePath,
const std::vector<uint64> chunkSizes,
span<unsigned char>& data,
uint64 binaryBlockStart);
bool readDataMPI(
const fileSystem& filePath,
const std::vector<uint64> chunkSizes,
span<unsigned char>& data,
uint64 binaryBlockStart);
bool readMetaMPI(
const fileSystem& filePath,
std::vector<uint64>& chunkSizes,
uint64 &startPosBinaryBlock);
bool readMetaSTD(
const fileSystem& filePath,
std::vector<uint64>& chunkSizes,
uint64 &startPosBinaryBlock);
public:
dataIO(IOType ioT)
:
IOType_(ioT)
{}
~dataIO()=default;
template<typename T>
bool writeDataEnd(
const fileSystem& filePath,
const span<T>& data);
template<typename T>
bool readData(
const fileSystem& filePath,
std::vector<T>& data);
};
}
#include "dataIOTemplate.cpp"
#endif

View File

@ -0,0 +1,112 @@
template<typename T>
bool pFlow::dataIO::writeDataEnd(
const fileSystem& filePath,
const span<T>& data)
{
span<unsigned char> charSpan(
reinterpret_cast<unsigned char*> (const_cast<T*>(data.data())),
data.size()*sizeof(T));
switch (IOType_)
{
case MasterProcessor:
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;
}
template<typename T>
bool pFlow::dataIO::readData
(
const fileSystem& filePath,
std::vector<T>& data
)
{
std::vector<uint64> chunkSizes;
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();
if(IOType_ == MasterProcessor)
{
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));
readDataSTD(filePath, chunkSizes, charSpan, startPosBinaryBlock);
}
if( IOType_ == AllProcessorsDifferent )
{
auto thisProc = processors::globalRank();
data.resize(chunkSizes[thisProc]/sizeof(T));
span<unsigned char> charSpan(
reinterpret_cast<unsigned char*>(data.data()),
data.size()*sizeof(T));
std::cout<<"MPI part"<<std::endl;
readDataMPI(filePath, chunkSizes, charSpan, startPosBinaryBlock);
}
return true;
}

View File

@ -75,6 +75,12 @@ bool pFlow::iIstream::peekBack(token& tok)
return putBack_;
}
size_t pFlow::iIstream::findBinaryBlockStart()
{
notImplementedFunction;
return 0;
}
bool pFlow::iIstream::findToken( const word & w )
{
rewind();

View File

@ -128,8 +128,8 @@ public:
/// Read a doubleScalar
virtual iIstream& read(double&) = 0;
/// Write a block of binray data
virtual iIstream& read(char* buffer, std::streamsize count) =0;
/// Rewind the stream so that it may be read again
virtual void rewind() = 0;
@ -137,6 +137,11 @@ public:
////- find and lookups
/// It seek for a character sequence that indicates the start of
/// a binary block
/// char sequence is 255 255 255 0
virtual size_t findBinaryBlockStart();
/// search for all tokesn and find the first word token tbat matchs w
virtual bool findToken( const word & w );

View File

@ -21,9 +21,16 @@ Licence:
#include "iOstream.hpp"
#include "token.hpp"
#include "error.hpp"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
pFlow::iOstream& pFlow::iOstream::writeBinaryBlockFlag()
{
notImplementedFunction;
return *this;
}
void pFlow::iOstream::decrIndent()
{
if (!indentLevel_)

View File

@ -135,8 +135,14 @@ public:
/// Write double
virtual iOstream& write(const double val) = 0;
/// Write size_t
virtual iOstream& write(const size_t val) = 0;
/// Write a block of binray data
virtual iOstream& write(const char* binaryData, std::streamsize count) = 0;
/// Write the flag to indicate the start of a binary block
virtual iOstream& writeBinaryBlockFlag();
//// - Indent
@ -411,6 +417,11 @@ inline iOstream& operator<<( iOstream& os, const double& val)
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const size_t& val)
{
return os.write(val);
}
// Useful aliases for tab and newline characters
constexpr char tab = '\t';
constexpr char nl = '\n';

View File

@ -153,6 +153,15 @@ pFlow::iOstream& pFlow::masterOstream::write(const double val)
return *this;
}
pFlow::iOstream& pFlow::masterOstream::write(const size_t val)
{
if(showOutput())
{
Ostream::write(val);
}
return *this;
}
pFlow::iOstream& pFlow::masterOstream::write
(

View File

@ -64,11 +64,20 @@ public:
//// - Methods
/// Set if this processor is slave or master
void setMasterSlave(bool master)
{
isThisMaster_ = master;
}
/// Write token to stream or otherwise handle it.
/// return false if the token type was not handled by this method
bool write(const token& tok)
// to prevent compiler warning, this method is overriden agian
{
return Ostream::write(tok);
}
/// Write character
iOstream& write(const char c)override;
@ -105,6 +114,9 @@ public:
/// Write double
iOstream& write(const double val) override;
/// Write double
iOstream& write(const size_t val) override;
/// Write a block of binray data
iOstream& write(const char* binaryData, std::streamsize count) override;

View File

@ -134,6 +134,11 @@ pFlow::iOstream& pFlow::processorOstream::write(const double val)
return Ostream::write(val);
}
pFlow::iOstream& pFlow::processorOstream::write(const size_t val)
{
checkForPrefix();
return Ostream::write(val);
}
pFlow::iOstream& pFlow::processorOstream::write
(

View File

@ -85,6 +85,14 @@ public:
printPrefix_ = true;
}
/// Write token to stream or otherwise handle it.
/// return false if the token type was not handled by this method
bool write(const token& tok)
// to prevent compiler warning, this method is overriden agian
{
return Ostream::write(tok);
}
/// Write character
iOstream& write(const char c)override;
@ -121,6 +129,9 @@ public:
/// Write double
iOstream& write(const double val) override;
/// Write double
iOstream& write(const size_t val) override;
/// Write a block of binray data
iOstream& write(const char* binaryData, std::streamsize count) override;

View File

@ -64,6 +64,8 @@ using size_t = std::size_t;
using word = std::string;
inline const int numBytesForReal__ = sizeof(real);
inline
word floatingPointDescription()
{

View File

@ -23,11 +23,15 @@ Licence:
#include <cmath>
#include "pFlowMacros.hpp"
#include "builtinTypes.hpp"
#ifdef __CUDACC__
#include "math.h"
#endif
#include "builtinTypes.hpp"
//* * * * * * * * * * * List of functinos * * * * * * * * //
// abs, mod, exp, log, log10, pow, sqrt, cbrt