Skip to content
Snippets Groups Projects
Commit f55814a9 authored by Podhorszki, Norbert's avatar Podhorszki, Norbert
Browse files

int --> unsigned int in Heat Transfer example and preliminary ADIOS2 IO module

parent 3a4e6940
No related branches found
No related tags found
1 merge request!8Integrate groupless
...@@ -27,7 +27,7 @@ HeatTransfer::HeatTransfer( const Settings& settings ) ...@@ -27,7 +27,7 @@ HeatTransfer::HeatTransfer( const Settings& settings )
m_T1[0] = new double[ (m_s.ndx+2) * (m_s.ndy+2) ]; m_T1[0] = new double[ (m_s.ndx+2) * (m_s.ndy+2) ];
m_T2 = new double*[ m_s.ndx+2 ]; m_T2 = new double*[ m_s.ndx+2 ];
m_T2[0] = new double[ (m_s.ndx+2) * (m_s.ndy+2) ]; m_T2[0] = new double[ (m_s.ndx+2) * (m_s.ndy+2) ];
for (int i = 1; i < m_s.ndx+2; i++) for (unsigned int i = 1; i < m_s.ndx+2; i++)
{ {
m_T1[i] = m_T1[i-1] + m_s.ndy+2; m_T1[i] = m_T1[i-1] + m_s.ndy+2;
m_T2[i] = m_T2[i-1] + m_s.ndy+2; m_T2[i] = m_T2[i-1] + m_s.ndy+2;
...@@ -49,8 +49,8 @@ void HeatTransfer::init(bool init_with_rank) ...@@ -49,8 +49,8 @@ void HeatTransfer::init(bool init_with_rank)
{ {
if (init_with_rank) if (init_with_rank)
{ {
for (int i = 0; i < m_s.ndx+2; i++) for (unsigned int i = 0; i < m_s.ndx+2; i++)
for (int j = 0; j < m_s.ndy+2; j++) for (unsigned int j = 0; j < m_s.ndy+2; j++)
m_T1[i][j] = m_s.rank; m_T1[i][j] = m_s.rank;
} }
else else
...@@ -59,10 +59,10 @@ void HeatTransfer::init(bool init_with_rank) ...@@ -59,10 +59,10 @@ void HeatTransfer::init(bool init_with_rank)
const double hy = 2.0 * 4.0*atan(1.0)/m_s.ndy; const double hy = 2.0 * 4.0*atan(1.0)/m_s.ndy;
double x, y; double x, y;
for (int i = 0; i < m_s.ndx+2; i++) for (unsigned int i = 0; i < m_s.ndx+2; i++)
{ {
x = 0.0 + hx*(i-1); x = 0.0 + hx*(i-1);
for (int j = 0; j < m_s.ndy+2; j++) for (unsigned int j = 0; j < m_s.ndy+2; j++)
{ {
y = 0.0 + hy*(j-1); y = 0.0 + hy*(j-1);
m_T1[i][j] = cos(8*x) + cos(6*x) - cos(4*x) + cos(2*x) - cos(x) + m_T1[i][j] = cos(8*x) + cos(6*x) - cos(4*x) + cos(2*x) - cos(x) +
...@@ -88,10 +88,10 @@ void HeatTransfer::printT(std::string message, MPI_Comm comm) const ...@@ -88,10 +88,10 @@ void HeatTransfer::printT(std::string message, MPI_Comm comm) const
} }
std::cout << "Rank " << rank << " " << message << std::endl; std::cout << "Rank " << rank << " " << message << std::endl;
for (int i = 0; i < m_s.ndx+2; i++) for (unsigned int i = 0; i < m_s.ndx+2; i++)
{ {
std::cout << " T[" << i << "][] = "; std::cout << " T[" << i << "][] = ";
for (int j = 0; j < m_s.ndy+2; j++) for (unsigned int j = 0; j < m_s.ndy+2; j++)
{ {
std::cout << std::setw(6) << m_TCurrent[i][j]; std::cout << std::setw(6) << m_TCurrent[i][j];
} }
...@@ -115,9 +115,9 @@ void HeatTransfer::switchCurrentNext() ...@@ -115,9 +115,9 @@ void HeatTransfer::switchCurrentNext()
void HeatTransfer::iterate() void HeatTransfer::iterate()
{ {
for( int i = 1; i <= m_s.ndx; ++i) for( unsigned int i = 1; i <= m_s.ndx; ++i)
{ {
for( int j = 1; j <= m_s.ndy; ++j) for( unsigned int j = 1; j <= m_s.ndy; ++j)
{ {
m_TNext[i][j] = m_TNext[i][j] =
omega/4*(m_TCurrent[i-1][j] + omega/4*(m_TCurrent[i-1][j] +
...@@ -134,19 +134,19 @@ void HeatTransfer::heatEdges() ...@@ -134,19 +134,19 @@ void HeatTransfer::heatEdges()
{ {
// Heat the whole global edges // Heat the whole global edges
if( m_s.posx==0 ) if( m_s.posx==0 )
for( int j = 0; j < m_s.ndy+2; ++j) for( unsigned int j = 0; j < m_s.ndy+2; ++j)
m_TCurrent[0][j]= edgetemp; m_TCurrent[0][j]= edgetemp;
if( m_s.posx==m_s.npx-1 ) if( m_s.posx==m_s.npx-1 )
for( int j = 0; j < m_s.ndy+2; ++j) for( unsigned int j = 0; j < m_s.ndy+2; ++j)
m_TCurrent[m_s.ndx+1][j]= edgetemp; m_TCurrent[m_s.ndx+1][j]= edgetemp;
if (m_s.posy==0) if (m_s.posy==0)
for( int i = 0; i < m_s.ndx+2; ++i) for( unsigned int i = 0; i < m_s.ndx+2; ++i)
m_TCurrent[i][0]= edgetemp; m_TCurrent[i][0]= edgetemp;
if (m_s.posy==m_s.npy-1) if (m_s.posy==m_s.npy-1)
for( int i = 0; i < m_s.ndx+2; ++i) for( unsigned int i = 0; i < m_s.ndx+2; ++i)
m_TCurrent[i][m_s.ndy+1]= edgetemp; m_TCurrent[i][m_s.ndy+1]= edgetemp;
} }
...@@ -163,7 +163,7 @@ void HeatTransfer::exchange( MPI_Comm comm ) ...@@ -163,7 +163,7 @@ void HeatTransfer::exchange( MPI_Comm comm )
if( m_s.rank_left >= 0 ) if( m_s.rank_left >= 0 )
{ {
std::cout << "Rank " << m_s.rank << " send left to rank " << m_s.rank_left << std::endl; std::cout << "Rank " << m_s.rank << " send left to rank " << m_s.rank_left << std::endl;
for( int i = 0; i < m_s.ndx+2; ++i) for( unsigned int i = 0; i < m_s.ndx+2; ++i)
send_x[i] = m_TCurrent[i][1]; send_x[i] = m_TCurrent[i][1];
MPI_Send(send_x, m_s.ndx+2, MPI_REAL8, m_s.rank_left, tag, comm); MPI_Send(send_x, m_s.ndx+2, MPI_REAL8, m_s.rank_left, tag, comm);
} }
...@@ -171,7 +171,7 @@ void HeatTransfer::exchange( MPI_Comm comm ) ...@@ -171,7 +171,7 @@ void HeatTransfer::exchange( MPI_Comm comm )
{ {
std::cout << "Rank " << m_s.rank << " receive from right from rank " << m_s.rank_right << std::endl; std::cout << "Rank " << m_s.rank << " receive from right from rank " << m_s.rank_right << std::endl;
MPI_Recv(recv_x, m_s.ndx+2, MPI_REAL8, m_s.rank_right, tag, comm, &status); MPI_Recv(recv_x, m_s.ndx+2, MPI_REAL8, m_s.rank_right, tag, comm, &status);
for( int i = 0; i < m_s.ndx+2; ++i) for( unsigned int i = 0; i < m_s.ndx+2; ++i)
m_TCurrent[i][m_s.ndy+1] = recv_x[i]; m_TCurrent[i][m_s.ndy+1] = recv_x[i];
} }
...@@ -180,7 +180,7 @@ void HeatTransfer::exchange( MPI_Comm comm ) ...@@ -180,7 +180,7 @@ void HeatTransfer::exchange( MPI_Comm comm )
if( m_s.rank_right >= 0 ) if( m_s.rank_right >= 0 )
{ {
std::cout << "Rank " << m_s.rank << " send right to rank " << m_s.rank_right << std::endl; std::cout << "Rank " << m_s.rank << " send right to rank " << m_s.rank_right << std::endl;
for( int i = 0; i < m_s.ndx+2; ++i) for( unsigned int i = 0; i < m_s.ndx+2; ++i)
send_x[i] = m_TCurrent[i][m_s.ndy]; send_x[i] = m_TCurrent[i][m_s.ndy];
MPI_Send(send_x, m_s.ndx+2, MPI_REAL8, m_s.rank_right, tag, comm); MPI_Send(send_x, m_s.ndx+2, MPI_REAL8, m_s.rank_right, tag, comm);
} }
...@@ -188,7 +188,7 @@ void HeatTransfer::exchange( MPI_Comm comm ) ...@@ -188,7 +188,7 @@ void HeatTransfer::exchange( MPI_Comm comm )
{ {
std::cout << "Rank " << m_s.rank << " receive from left from rank " << m_s.rank_left << std::endl; std::cout << "Rank " << m_s.rank << " receive from left from rank " << m_s.rank_left << std::endl;
MPI_Recv(recv_x, m_s.ndx+2, MPI_REAL8, m_s.rank_left, tag, comm, &status); MPI_Recv(recv_x, m_s.ndx+2, MPI_REAL8, m_s.rank_left, tag, comm, &status);
for( int i = 0; i < m_s.ndx+2; ++i) for( unsigned int i = 0; i < m_s.ndx+2; ++i)
m_TCurrent[i][0] = recv_x[i]; m_TCurrent[i][0] = recv_x[i];
} }
...@@ -230,7 +230,7 @@ void HeatTransfer::exchange( MPI_Comm comm ) ...@@ -230,7 +230,7 @@ void HeatTransfer::exchange( MPI_Comm comm )
std::vector<double> HeatTransfer::data_noghost() const std::vector<double> HeatTransfer::data_noghost() const
{ {
std::vector<double>d( m_s.ndx * m_s.ndy ); std::vector<double>d( m_s.ndx * m_s.ndy );
for( int i = 1; i <= m_s.ndx; ++i ) for( unsigned int i = 1; i <= m_s.ndx; ++i )
{ {
std::memcpy( &d[(i-1)*m_s.ndy], m_TCurrent[i]+1, m_s.ndy*sizeof(double)); std::memcpy( &d[(i-1)*m_s.ndy], m_TCurrent[i]+1, m_s.ndy*sizeof(double));
} }
......
...@@ -6,18 +6,91 @@ ...@@ -6,18 +6,91 @@
*/ */
#include "IO.h" #include "IO.h"
#include "ADIOS_CPP.h"
#include <string>
static int rank_saved;
adios::ADIOS * ad = nullptr;
std::shared_ptr<adios::Engine> bpWriter;
adios::Variable<double> * varT = nullptr;
IO::IO( const Settings& s, MPI_Comm comm ) IO::IO( const Settings& s, MPI_Comm comm )
{ {
rank_saved = s.rank;
m_outputfilename = s.outputfile + ".bp"; m_outputfilename = s.outputfile + ".bp";
ad = new adios::ADIOS( "adios2.xml", comm, adios::INFO );
//Define method for engine creation
// 1. Get method def from config file or define new one
adios::Method& bpWriterSettings = ad->DeclareMethod( "output" );
if( ! bpWriterSettings.isUserDefined())
{
// if not defined by user, we can change the default settings
bpWriterSettings.SetEngine( "BP" ); // BP is the default engine
bpWriterSettings.SetAvailableCores( 2); // no threading for data processing (except for staging)
bpWriterSettings.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport
// Passing parameters to the transport
bpWriterSettings.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine
bpWriterSettings.SetParameters( "Aggregation", std::to_string((s.nproc+1)/2) ); // number of aggregators
}
// define T as 2D global array
varT = &ad->DefineVariable<double>(
"T",
{s.gndx,s.gndy}, // Global dimensions
{s.ndx,s.ndy}, // local size, could be defined later using SetSelection()
{s.offsx,s.offsy} // offset of the local array in the global space
);
//add transform to variable
//adios::Transform tr = adios::transform::BZIP2( );
//varT.AddTransform( tr, "" );
// varT.AddTransform( tr,"accuracy=0.001" ); // for ZFP
bpWriter = ad->Open( m_outputfilename, "w", comm, bpWriterSettings, adios::COLLECTIVE_IO);
if( bpWriter == nullptr )
throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" );
} }
IO::~IO() IO::~IO()
{ {
bpWriter->Close();
delete ad;
}
void /*IO::*/old_style_write(int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm )
{
bpWriter->Write<double>( *varT, ht.data_noghost().data());
bpWriter->Advance( );
} }
void IO::write(int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm ) void IO::write(int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm )
{ {
/* This selection is redundant and not required, since we defined
* the selection already in DefineVariable(). It is here just as an example.
*/
// Make a selection to describe the local dimensions of the variable we write and
// its offsets in the global spaces. This could have been done in adios.DefineVariable()
adios::Selection sel = adios.SelectionBoundingBox( {s.ndx,s.ndy}, {s.offsx,s.offsy} ); // local dims and offsets; both as list
var2D.SetSelection( sel );
/* Select the area that we want to write from the data pointer we pass to the writer.
Think HDF5 memspace, just not hyperslabs, only a bounding box selection.
Engine will copy this bounding box from the data pointer into the output buffer.
Size of the bounding box should match the "space" selection which was given above.
Default memspace is always the full selection.
*/
adios::Selection memspace = adios.SelectionBoundingBox( {s.ndx,s.ndy}, {1,1} );
var2D.SetMemorySelection( memspace );
bpWriter->Write<double>( *varT, ht.data());
bpWriter->Advance( );
} }
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "Settings.h" #include "Settings.h"
static int convertToInt( std::string varName, char *arg ) static unsigned int convertToUint( std::string varName, char *arg )
{ {
char *end; char *end;
int retval = std::strtoll( arg, &end, 10); int retval = std::strtoll( arg, &end, 10);
...@@ -22,26 +22,32 @@ static int convertToInt( std::string varName, char *arg ) ...@@ -22,26 +22,32 @@ static int convertToInt( std::string varName, char *arg )
throw std::invalid_argument( "Invalid value given for " + varName + ": " throw std::invalid_argument( "Invalid value given for " + varName + ": "
+ std::string(arg) ); + std::string(arg) );
} }
return retval; if( retval < 0 )
{
throw std::invalid_argument( "Negative value given for " + varName + ": "
+ std::string(arg) );
}
return (unsigned int) retval;
} }
Settings::Settings( int argc, char* argv [], int rank, int nproc ) Settings::Settings( int argc, char* argv [], int rank, int nproc )
: rank{rank}, nproc{nproc} : rank{rank}
{ {
if (argc < 8) if (argc < 8)
{ {
throw std::invalid_argument( "Not enough arguments" ); throw std::invalid_argument( "Not enough arguments" );
} }
this->nproc = (unsigned int) nproc;
outputfile = argv[1]; outputfile = argv[1];
npx = convertToInt("N", argv[2]); npx = convertToUint("N", argv[2]);
npy = convertToInt("M", argv[3]); npy = convertToUint("M", argv[3]);
ndx = convertToInt("nx", argv[4]); ndx = convertToUint("nx", argv[4]);
ndy = convertToInt("ny", argv[5]); ndy = convertToUint("ny", argv[5]);
steps = convertToInt("steps", argv[6]); steps = convertToUint("steps", argv[6]);
iterations = convertToInt("iterations", argv[7]); iterations = convertToUint("iterations", argv[7]);
if( npx * npy != nproc ) if( npx * npy != this->nproc )
{ {
throw std::invalid_argument( "N*M must equal the number of processes" ); throw std::invalid_argument( "N*M must equal the number of processes" );
} }
......
...@@ -16,27 +16,27 @@ class Settings ...@@ -16,27 +16,27 @@ class Settings
public: public:
// user arguments // user arguments
std::string outputfile; std::string outputfile;
int npx; // Number of processes in X (slow) dimension unsigned int npx; // Number of processes in X (slow) dimension
int npy; // Number of processes in Y (fast) dimension unsigned int npy; // Number of processes in Y (fast) dimension
int ndx; // Local array size in X dimension per process unsigned int ndx; // Local array size in X dimension per process
int ndy; // Local array size in y dimension per process unsigned int ndy; // Local array size in y dimension per process
int steps; // Number of output steps unsigned int steps; // Number of output steps
int iterations; // Number of computing iterations between steps unsigned int iterations; // Number of computing iterations between steps
// calculated values from those arguments and number of processes // calculated values from those arguments and number of processes
int gndx; // Global array size in slow dimension unsigned int gndx; // Global array size in slow dimension
int gndy; // Global array size in fast dimension unsigned int gndy; // Global array size in fast dimension
// X dim positions: rank 0, npx, 2npx... are in the same X position // X dim positions: rank 0, npx, 2npx... are in the same X position
// Y dim positions: npx number of consecutive processes belong to one row (npx columns) // Y dim positions: npx number of consecutive processes belong to one row (npx columns)
int posx; // Position of this process in X dimension unsigned int posx; // Position of this process in X dimension
int posy; // Position of this process in Y dimension unsigned int posy; // Position of this process in Y dimension
int offsx; // Offset of local array in X dimension on this process unsigned int offsx; // Offset of local array in X dimension on this process
int offsy; // Offset of local array in Y dimension on this process unsigned int offsy; // Offset of local array in Y dimension on this process
int rank; // MPI rank int rank; // MPI rank
int nproc; // number of processors unsigned int nproc; // number of processors
// neighbours by their MPI ranks // neighbors by their MPI ranks, -1 if there is no such neighbor
int rank_left; int rank_left;
int rank_right; int rank_right;
int rank_up; int rank_up;
......
...@@ -68,11 +68,11 @@ int main( int argc, char* argv [] ) ...@@ -68,11 +68,11 @@ int main( int argc, char* argv [] )
ht.printT("Heated T:", mpiHeatTransferComm); ht.printT("Heated T:", mpiHeatTransferComm);
io.write( 0, ht, settings, mpiHeatTransferComm ); io.write( 0, ht, settings, mpiHeatTransferComm );
for( int t = 1; t <= settings.steps; ++t ) for( unsigned int t = 1; t <= settings.steps; ++t )
{ {
if( rank == 0 ) if( rank == 0 )
std::cout << "Step " << t << ":\n"; std::cout << "Step " << t << ":\n";
for( int iter = 1; iter <= settings.iterations; ++iter ) for( unsigned int iter = 1; iter <= settings.iterations; ++iter )
{ {
ht.iterate(); ht.iterate();
ht.exchange( mpiHeatTransferComm ); ht.exchange( mpiHeatTransferComm );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment