Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typed vector and tensor #1092

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions regtest/basic/rt-make-0/config
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
type=make
#should we rename this to something meaningful? like "rt-VectorTensor"?
4 changes: 3 additions & 1 deletion regtest/basic/rt-make-4/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ int main () {
PLMD::TensorGeneric<4,4> mat;
PLMD::TensorGeneric<1,4> evec;
PLMD::VectorGeneric<4> eval_underlying;


//The both of the two following lines are scary, but on my machine are equivalent
//PLMD::Vector1d* eval=reinterpret_cast<PLMD::Vector1d*>(eval_underlying.data());
auto eval = new(&eval_underlying[0]) PLMD::VectorGeneric<1>;

mat[1][0]=mat[0][1]=3.0;
Expand Down
20 changes: 10 additions & 10 deletions src/tools/Communicator.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ class Communicator {
/// Init from reference
template <typename T> explicit Data(T&p): pointer(&p), size(1), nbytes(sizeof(T)), type(getMPIType<T>()) {}
/// Init from pointer to VectorGeneric
template <unsigned n> explicit Data(VectorGeneric<n> *p,int s): pointer(p), size(n*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
template <typename T, unsigned n> explicit Data(VectorTyped<T,n> *p,int s): pointer(p), size(n*s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
/// Init from reference to VectorGeneric
template <unsigned n> explicit Data(VectorGeneric<n> &p): pointer(&p), size(n), nbytes(sizeof(double)), type(getMPIType<double>()) {}
/// Init from pointer to TensorGeneric
template <unsigned n,unsigned m> explicit Data(TensorGeneric<n,m> *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
/// Init from reference to TensorGeneric
template <unsigned n,unsigned m> explicit Data(TensorGeneric<n,m> &p): pointer(&p), size(n*m), nbytes(sizeof(double)), type(getMPIType<double>()) {}
template <typename T, unsigned n> explicit Data(VectorTyped<T,n> &p): pointer(&p), size(n), nbytes(sizeof(T)), type(getMPIType<T>()) {}
/// Init from pointer to TensorTyped
template <typename T, unsigned n,unsigned m> explicit Data(TensorTyped<T,n,m> *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
/// Init from reference to TensorTyped
template <typename T, unsigned n,unsigned m> explicit Data(TensorTyped<T,n,m> &p): pointer(&p), size(n*m), nbytes(sizeof(T)), type(getMPIType<T>()) {}
/// Init from reference to std::vector
template <typename T> explicit Data(std::vector<T>&v) {
Data d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
Expand All @@ -104,10 +104,10 @@ class Communicator {
MPI_Datatype type;
template <typename T> explicit ConstData(const T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
template <typename T> explicit ConstData(const T&p): pointer(&p), size(1), nbytes(sizeof(T)), type(getMPIType<T>()) {}
template <unsigned n> explicit ConstData(const VectorGeneric<n> *p,int s): pointer(p), size(n*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
template <unsigned n> explicit ConstData(const VectorGeneric<n> &p): pointer(&p), size(n), nbytes(sizeof(double)), type(getMPIType<double>()) {}
template <unsigned n,unsigned m> explicit ConstData(const TensorGeneric<n,m> *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
template <unsigned n,unsigned m> explicit ConstData(const TensorGeneric<n,m> &p): pointer(&p), size(n*m), nbytes(sizeof(double)), type(getMPIType<double>()) {}
template <typename T,unsigned n> explicit ConstData(const VectorTyped<T,n> *p,int s): pointer(p), size(n*s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
template <typename T,unsigned n> explicit ConstData(const VectorTyped<T,n> &p): pointer(&p), size(n), nbytes(sizeof(T)), type(getMPIType<T>()) {}
template <typename T, unsigned n,unsigned m> explicit ConstData(const TensorTyped<T,n,m> *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
template <typename T, unsigned n,unsigned m> explicit ConstData(const TensorTyped<T,n,m> &p): pointer(&p), size(n*m), nbytes(sizeof(T)), type(getMPIType<T>()) {}
template <typename T> explicit ConstData(const std::vector<T>&v) {
ConstData d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
}
Expand Down
127 changes: 51 additions & 76 deletions src/tools/LoopUnroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,114 +47,89 @@ Implementation is made using template metaprogramming, that is:
Here xxx is any of the methods of the class.

*/
template<unsigned n>
//the typename is the second parameter argument so that it can be deduced
template<typename T, unsigned n>
class LoopUnroller {
public:
/// Set to zero.
/// Same as `for(unsigned i=0;i<n;i++) d[i]=0.0;`
static void _zero(double*d);
static void _zero(T*d);
/// Add v to d.
/// Same as `for(unsigned i=0;i<n;i++) d[i]+=v[i];`
static void _add(double*d,const double*v);
static void _add(T*d,const T*v);
/// Subtract v from d.
/// Same as `for(unsigned i=0;i<n;i++) d[i]-=v[i];`
static void _sub(double*d,const double*v);
static void _sub(T*d,const T*v);
/// Multiply d by s.
/// Same as `for(unsigned i=0;i<n;i++) d[i]*=s;`
static void _mul(double*d,const double s);
static void _mul(T*d,const T s);
/// Set d to -v.
/// Same as `for(unsigned i=0;i<n;i++) d[i]=-v[i];`
static void _neg(double*d,const double*v);
static void _neg(T*d,const T*v);
/// Squared modulo of d;
/// Same as `r=0.0; for(unsigned i=0;i<n;i++) r+=d[i]*d[i]; return r;`
static double _sum2(const double*d);
static T _sum2(const T*d);
/// Dot product of d and v
/// Same as `r=0.0; for(unsigned i=0;i<n;i++) r+=d[i]*v[i]; return r;`
static double _dot(const double*d,const double*v);
static T _dot(const T*d,const T*v);
};

template<unsigned n>
void LoopUnroller<n>::_zero(double*d) {
LoopUnroller<n-1>::_zero(d);
d[n-1]=0.0;
template<typename T, unsigned n>
void LoopUnroller<T,n>::_zero(T*d) {
if constexpr (n>1) {
LoopUnroller<T,n-1>::_zero(d);
}
d[n-1]=T(0);
}

template<>
inline
void LoopUnroller<1>::_zero(double*d) {
d[0]=0.0;
}

template<unsigned n>
void LoopUnroller<n>::_add(double*d,const double*a) {
LoopUnroller<n-1>::_add(d,a);
template<typename T, unsigned n>
void LoopUnroller<T,n>::_add(T*d,const T*a) {
if constexpr (n>1) {
LoopUnroller<T,n-1>::_add(d,a);
}
d[n-1]+=a[n-1];
}

template<>
inline
void LoopUnroller<1>::_add(double*d,const double*a) {
d[0]+=a[0];
}

template<unsigned n>
void LoopUnroller<n>::_sub(double*d,const double*a) {
LoopUnroller<n-1>::_sub(d,a);
template<typename T, unsigned n>
void LoopUnroller<T,n>::_sub(T*d,const T*a) {
if constexpr (n>1) {
LoopUnroller<T,n-1>::_sub(d,a);
}
d[n-1]-=a[n-1];
}

template<>
inline
void LoopUnroller<1>::_sub(double*d,const double*a) {
d[0]-=a[0];
}

template<unsigned n>
void LoopUnroller<n>::_mul(double*d,const double s) {
LoopUnroller<n-1>::_mul(d,s);
template<typename T, unsigned n>
void LoopUnroller<T,n>::_mul(T*d,const T s) {
if constexpr (n>1) {
LoopUnroller<T,n-1>::_mul(d,s);
}
d[n-1]*=s;
}

template<>
inline
void LoopUnroller<1>::_mul(double*d,const double s) {
d[0]*=s;
}

template<unsigned n>
void LoopUnroller<n>::_neg(double*d,const double*a ) {
LoopUnroller<n-1>::_neg(d,a);
template<typename T, unsigned n>
void LoopUnroller<T,n>::_neg(T*d,const T*a ) {
if constexpr (n>1) {
LoopUnroller<T,n-1>::_neg(d,a);
}
d[n-1]=-a[n-1];
}

template<>
inline
void LoopUnroller<1>::_neg(double*d,const double*a) {
d[0]=-a[0];
template<typename T, unsigned n>
T LoopUnroller<T,n>::_sum2(const T*d) {
if constexpr (n>1) {
return LoopUnroller<T,n-1>::_sum2(d)+d[n-1]*d[n-1];
} else {
return d[0]*d[0];
}
}

template<unsigned n>
double LoopUnroller<n>::_sum2(const double*d) {
return LoopUnroller<n-1>::_sum2(d)+d[n-1]*d[n-1];
}

template<>
inline
double LoopUnroller<1>::_sum2(const double*d) {
return d[0]*d[0];
}

template<unsigned n>
double LoopUnroller<n>::_dot(const double*d,const double*v) {
return LoopUnroller<n-1>::_dot(d,v)+d[n-1]*v[n-1];
}

template<>
inline
double LoopUnroller<1>::_dot(const double*d,const double*v) {
return d[0]*v[0];
}

template<typename T, unsigned n>
T LoopUnroller<T,n>::_dot(const T*d,const T*v) {
if constexpr (n>1) {
return LoopUnroller<T,n-1>::_dot(d,v)+d[n-1]*v[n-1];
} else {
return d[0]*v[0];
}
}
} //PLMD

#endif
#endif //__PLUMED_tools_LoopUnroller_h
Loading
Loading