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

New FsGrid operators and lerp method #21

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
183 changes: 167 additions & 16 deletions fsgrid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,21 @@ template <typename T, int stencil> class FsGrid : public FsGridTools{
* \param MPI_Comm The MPI communicator this grid should use.
* \param isPeriodic An array specifying, for each dimension, whether it is to be treated as periodic.
*/
FsGrid(std::array<int32_t,3> globalSize, MPI_Comm parent_comm, std::array<bool,3> isPeriodic, FsGridCouplingInformation& coupling)
: globalSize(globalSize),coupling(coupling) {
FsGrid(std::array<int32_t, 3> globalSize, MPI_Comm parent_comm, std::array<bool, 3> isPeriodic, FsGridCouplingInformation &coupling)
: globalSize(globalSize), coupling(coupling){
this->parentCom = parent_comm;
kstppd marked this conversation as resolved.
Show resolved Hide resolved
this->init(parent_comm,isPeriodic);
}

//Copy constructor
FsGrid(const FsGrid<T, stencil> &other)
: periodic(other.periodic), globalSize(other.globalSize), coupling(other.coupling){
this->parentCom=other.parentCom;
init(parentCom,periodic);
this->data = other.data;
}

void init(MPI_Comm &parent_comm,std::array<bool, 3> isPeriodic){
int status;
int size;

Expand Down Expand Up @@ -965,27 +978,60 @@ template <typename T, int stencil> class FsGrid : public FsGridTools{
//! Copy the entire data from another FsGrid of the same signature over.
FsGrid<T, stencil>& operator=(const FsGrid<T, stencil>& other) {

// Don't copy if sizes mismatch.
// (Should this instead crash the program?)
if(other.localSize[0] != localSize[0] ||
other.localSize[1] != localSize[1] ||
other.localSize[2] != localSize[2]) {
return *this;
}
// Fail if sizes mismatch.
assert(other.localSize[0] == this->localSize[0]);
assert(other.localSize[1] == this->localSize[1]);
assert(other.localSize[2] == this->localSize[2]);
data = other.data;
return *this;
}

FsGrid<T, stencil>& operator+=(const FsGrid<T, stencil>& rhs) {
assert(this->data.size()==rhs.data.size());
for (size_t i=0; i< this->data.size(); i++){
this->data[i] = this->data[i]+rhs.data[i];
}
return *this;
}

FsGrid<T, stencil>& operator-=(const FsGrid<T, stencil>& rhs) {
assert(this->data.size()==rhs.data.size());
for (size_t i=0; i< this->data.size(); i++){
this->data[i] = this->data[i]-rhs.data[i];
}
return *this;
}

FsGrid<T, stencil>& operator*=(const FsGrid<T, stencil>& rhs) {
assert(this->data.size()==rhs.data.size());
for (size_t i=0; i< this->data.size(); i++){
this->data[i] = this->data[i]*rhs.data[i];
}
return *this;
}

FsGrid<T, stencil>& operator/=(const FsGrid<T, stencil>& rhs) {
assert(this->data.size()==rhs.data.size());
for (size_t i=0; i< this->data.size(); i++){
this->data[i] = this->data[i]/rhs.data[i];
}
return *this;
}

template <typename S, typename std::enable_if<std::is_arithmetic<S>::value>::type * = nullptr>
kstppd marked this conversation as resolved.
Show resolved Hide resolved
FsGrid<T, stencil> &operator*(S mult){
for (size_t i=0; i< this->data.size(); i++){
this->data[i] = this->data[i]*mult;
}
return *this;
}




private:
//! MPI Cartesian communicator used in this grid
MPI_Comm comm3d;
int rank; //!< This task's rank in the communicator
std::vector<MPI_Request> requests;
uint numRequests;
MPI_Comm comm3d, parentCom;
int rank; //!< This task's rank in the communicator
std::vector<MPI_Request> requests;
uint numRequests;

std::array<int, 27> neighbour; //!< Tasks of the 26 neighbours (plus ourselves)
std::vector<char> neighbour_index; //!< Lookup table from rank to index in the neighbour array
Expand Down Expand Up @@ -1040,3 +1086,108 @@ template <typename T, int stencil> class FsGrid : public FsGridTools{
array[2] = a;
}
};


//Array Operator Overloads
kstppd marked this conversation as resolved.
Show resolved Hide resolved
template <typename T, size_t N>
static inline std::array<T,N> operator+(const std::array<T, N>& arr1, const std::array<T, N>& arr2){
std::array<T, N> res;
for (size_t i = 0; i < N; ++i){
res[i] = arr1[i] + arr2[i];
}
return res;
}

template <typename T, size_t N>
static inline std::array<T,N> operator-(const std::array<T, N>& arr1, const std::array<T, N>& arr2){
std::array<T, N> res;
for (size_t i = 0; i < N; ++i){
res[i] = arr1[i] - arr2[i];
}
return res;
}

template <typename T, size_t N>
static inline std::array<T, N> operator*(const std::array<T, N> &arr1, const std::array<T, N> &arr2){
std::array<T, N> res;
for (size_t i = 0; i < N; ++i){
res[i] = arr1[i] * arr2[i];
}
return res;
}

template <typename T, size_t N>
static inline std::array<T,N> operator/(const std::array<T, N>& arr1, const std::array<T, N>& arr2){
std::array<T, N> res;
for (size_t i = 0; i < N; ++i){
res[i] = arr1[i] / arr2[i];
}
return res;
}

template <typename T, size_t N,typename S,typename std::enable_if<std::is_arithmetic<S>::value>::type* = nullptr>
std::array<T,N> operator*(std::array<T, N>& arr, S mult){
for (size_t i = 0; i < N; ++i)
arr[i]*=mult;
return arr;
}



// FsGrid Operator Overloads
template <class T, int stencil>
static inline FsGrid<T, stencil> operator+(const FsGrid<T, stencil> &lhs, const FsGrid<T, stencil> &rhs){
FsGrid<T, stencil> a(lhs);
return a+=rhs;
}

template <class T, int stencil>
static inline FsGrid<T, stencil> operator-(const FsGrid<T, stencil> &lhs, const FsGrid<T, stencil> &rhs){
FsGrid<T, stencil> a(lhs);
return a-=rhs;
}

template <class T, int stencil>
static inline FsGrid<T, stencil> operator*(const FsGrid<T, stencil> &lhs, const FsGrid<T, stencil> &rhs){
FsGrid<T, stencil> a(lhs);
return a *= rhs;
}

template <class T, int stencil>
static inline FsGrid<T, stencil> operator/(const FsGrid<T, stencil> &lhs, const FsGrid<T, stencil> &rhs){
FsGrid<T, stencil> a(lhs);
return a /= rhs;
}

template <class T, int stencil,typename S,typename std::enable_if<std::is_arithmetic<S>::value>::type* = nullptr>
static inline FsGrid<T, stencil> lerp_t(const FsGrid<T, stencil> &lhs, const FsGrid<T, stencil> &rhs,S t0, S t1,S t){

//Sanity check for timestamps. If sizes mismatch then this will make it crash in the '=' operator
bool doAble = (t0<=t) && (t<=t1);
if (!doAble){
#pragma message(": warning<FsGrid lerp_t>: We should probably crash here instead of returning nonesense")
//Do we crash here?
std::cerr<<"Interpolation not doable in the range of "<<t0<<" "<<t<<" "<<t1<<std::endl;
return lhs;
}
kstppd marked this conversation as resolved.
Show resolved Hide resolved

//First let's create the targer grid by copying one of the inputs
FsGrid<T, stencil> targetGrid(lhs);

//Let's now calculate the intepolation weights;
S range=t1-t0;
S d0= abs(t-t0);
S d1= abs(t-t1);
S w0= 1.- (d0/range);
S w1= 1.- (d1/range);
kstppd marked this conversation as resolved.
Show resolved Hide resolved

//Do interpolate-targetGrid=w0*lhs+w1*rhs
FsGrid<T, stencil> fsgrid_tmp(lhs);
targetGrid=fsgrid_tmp*w0;
fsgrid_tmp=rhs;
targetGrid += fsgrid_tmp * w1;

return targetGrid;
}


8 changes: 5 additions & 3 deletions tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
CXX=CC
CXX=mpic++
CXXFLAGS= -O3 -std=c++11 -march=native -g -Wall

all: benchmark test ddtest
all: benchmark test ddtest operators

benchmark: benchmark.cpp ../fsgrid.hpp
$(CXX) $(CXXFLAGS) -o $@ $<
operators: operators.cpp ../fsgrid.hpp
$(CXX) $(CXXFLAGS) -o $@ $<
test: test.cpp ../fsgrid.hpp
$(CXX) $(CXXFLAGS) -o $@ $<
ddtest: ddtest.cpp
$(CXX) $(CXXFLAGS) -o $@ $<

clean:
-rm test
-rm test benchmark ddtest operators
5 changes: 3 additions & 2 deletions tests/benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
*/

template<class T, int stencil> void timeit(std::array<int32_t, 3> globalSize, std::array<bool, 3> isPeriodic, int iterations){
double t1,t2;
FsGrid<T ,stencil> testGrid(globalSize, MPI_COMM_WORLD, isPeriodic);
double t1,t2;
FsGridCouplingInformation gridCoupling;
FsGrid<T ,stencil> testGrid(globalSize, MPI_COMM_WORLD, isPeriodic,gridCoupling);
int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
Expand Down
81 changes: 81 additions & 0 deletions tests/operators.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <iostream>
#include "../fsgrid.hpp"
/*
Copyright (C) 2016 Finnish Meteorological Institute
Copyright (C) 2016 CSC -IT Center for Science

This file is part of fsgrid

fsgrid is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

fsgrid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY;
without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with fsgrid. If not, see <http://www.gnu.org/licenses/>.
*/



int main(int argc, char** argv) {
typedef float Real;
MPI_Init(&argc,&argv);

int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

// Create a 8×8 Testgrid
std::array<int32_t, 3> globalSize{2000,1000,1};
std::array<int32_t, 3> globalSize2{3000,1000,1};
std::array<bool, 3> isPeriodic{false,false,true};



FsGridCouplingInformation gridCoupling;
FsGrid<std::array<Real, 1>, 2> A(globalSize, MPI_COMM_WORLD, isPeriodic, gridCoupling);
FsGrid<std::array<Real, 1>, 2> B(globalSize, MPI_COMM_WORLD, isPeriodic, gridCoupling);
FsGrid<std::array<Real, 1>, 2> C(globalSize, MPI_COMM_WORLD, isPeriodic, gridCoupling);
FsGrid<std::array<Real, 1>, 2> D(globalSize2, MPI_COMM_WORLD, isPeriodic, gridCoupling);

// FsGrid<std::array<float, 1>, 2> newGuy(A + B);
// +
A=B+C;
// +=
A+=B;
// -
A=A-C;
// -=
A-=B;
D=D*3.0;
C=lerp_t(A,B,5.,10.,7.);
//supposed to fail;
// A=B+D;



















MPI_Finalize();
return 0;
}
5 changes: 2 additions & 3 deletions tests/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ int main(int argc, char** argv) {
// Create a 8×8 Testgrid
std::array<int32_t, 3> globalSize{20,20,1};
std::array<bool, 3> isPeriodic{false,false,true};
FsGridCouplingInformation gridCoupling;
{
FsGrid<int,1> testGrid(globalSize, MPI_COMM_WORLD, isPeriodic);
FsGrid<int,1> testGrid(globalSize, MPI_COMM_WORLD, isPeriodic,gridCoupling);
/*
if(rank == 0) {
std::cerr << " --- Test task mapping functions ---" << std::endl;
Expand Down Expand Up @@ -190,9 +191,7 @@ int main(int argc, char** argv) {
}
}
}



MPI_Finalize();

return 0;
Expand Down