Commit 238c7c82 authored by berenger-bramas's avatar berenger-bramas

Continue to clean code.

Remove the previous AbstractApplication >> MpiApplication.
Change it into a single file with define system.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@67 2616d619-271b-44dc-8df4-d4a8f33a7222
parent f5683784
......@@ -19,12 +19,6 @@ public:
virtual ~FAbstractKernels(){
}
/**
* Init the Kernels
* This function is called just before to start the computation
*/
virtual void init(){}
/**
* P2M
* particles to multipole
......
......@@ -22,9 +22,6 @@ public:
virtual ~FBasicKernels(){
}
/** When init the kernel */
virtual void init(){}
/** Print the number of particles */
virtual void P2M(CellClass* const , const FList<ParticleClass*>* const ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
......
......@@ -26,8 +26,7 @@
*
* Of course this class does not deallocate pointer given in arguements.
*
* Threaded & based on the inspector-executor model
* schedule(runtime)
* When using this algorithm the P2P is thread safe.
*/
template<template< class ParticleClass, class CellClass, int OctreeHeight> class KernelClass,
class ParticleClass, class CellClass,
......
This diff is collapsed.
......@@ -26,8 +26,8 @@
*
* Of course this class does not deallocate pointer given in arguements.
*
* Threaded & based on the inspector-executor model
* schedule(runtime)
* Because this is a Target source model you do not need the P2P to be safe.
* You should not write on sources in the P2P method!
*/
template<template< class ParticleClass, class CellClass, int OctreeHeight> class KernelClass,
class ParticleClass, class CellClass,
......@@ -90,10 +90,6 @@ public:
iterArray = new OctreeIterator[leafs];
assert(iterArray, "iterArray bad alloc", __LINE__, __FILE__);
for(int idxThread = 0 ; idxThread < MaxThreads ; ++idxThread){
this->kernels[idxThread]->init();
}
bottomPass();
upwardPass();
......
......@@ -26,8 +26,8 @@
*
* Of course this class does not deallocate pointer given in arguements.
*
* Threaded & based on the inspector-executor model
* schedule(runtime)
* This algorithms is unsafe for P2P, if you need to write on neigbors
* this can be a problem.
*/
template<template< class ParticleClass, class CellClass, int OctreeHeight> class KernelClass,
class ParticleClass, class CellClass,
......
......@@ -20,6 +20,8 @@
* It just iterates on a tree and call the kernels with good arguments.
*
* Of course this class does not deallocate pointer given in arguements.
*
* The differences with FmmAlgorithm is that it used target source model.
*/
template<template< class ParticleClass, class CellClass, int OctreeHeight> class KernelClass,
class ParticleClass, class CellClass,
......@@ -62,8 +64,6 @@ public:
void execute(){
FTRACE( FTrace::Controller.enterFunction(FTrace::FMM, __FUNCTION__ , __FILE__ , __LINE__) );
kernels->init();
bottomPass();
upwardPass();
......
#ifndef FABSTRACTAPPLICATION_HPP
#define FABSTRACTAPPLICATION_HPP
// /!\ Please, you must read the license at the bottom of this page
#include <sstream>
#include <iostream>
#include <string.h>
#include "FAssertable.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractApplication
* Please read the license
*
* This class is an interface for main application.
* It represents the core of the system
* Only one app can be instancied by program.
*
* @warning you have to implement run() and call execute to start the app
*
* Please refere to testApplication.cpp to see an example.
* <code>
* </code>
*/
class FAbstractApplication {
private:
const int argc; //< argc from command line
char ** const argv; //< argv from command line
protected:
/**
* This will be called as the main method
* @warning Must be impleted in the derived class
*/
virtual void run() = 0;
/**
* This function is called before the run if the process is the master one
*/
virtual void initMaster(){}
/**
* This function is called before the run if the process is a slave
*/
virtual void initSlave(){}
/**
* Send data to another process
*/
virtual void sendData(const int inReceiver, const int inSize, void* const inData, const int inTag) = 0;
/**
* Receive from any process
*/
virtual void receiveData(const int inSize, void* const inData, int* const inSource, int* const inTag, int* const inFilledSize) = 0;
/**
* To know if some data arrived
*/
virtual bool receivedData() = 0;
private:
/** Forbiden (private) default constructor */
FAbstractApplication():argc(0), argv(0){}
/** Forbiden (private) copy constructor */
FAbstractApplication(const FAbstractApplication&):argc(0), argv(0){}
/** Forbiden (private) copy */
FAbstractApplication& operator=(const FAbstractApplication&){return *this;}
public:
/**
* Constructor
* @param inArgc argc from command line
* @param inArgv argv from command line
* This will also set the current app in the assert system
*/
FAbstractApplication(const int inArgc, char ** const inArgv )
: argc(inArgc), argv(inArgv) {
FAssertable::SetCurrentApp(this);
}
/** Destructor */
virtual ~FAbstractApplication(){}
/**
* This function has to be called to execute the process run
* @return 0 if success
*/
int execute(){
if( isMaster() ) initMaster();
else initSlave();
run();
return 0;
}
/**
* To get the current process id
* @return the process numeber [0 ; processCount [
*/
virtual int processId() const = 0;
/**
* To get the number of process
* @return process count
*/
virtual int processCount() const = 0;
/**
* To make a barrier between process
*/
virtual void processBarrier() const = 0;
/**
* To kill all process
* @param inErrorCode the error to return to OS (default is 1)
*/
virtual void abort(const int inErrorCode = 1) const = 0;
/**
* This function has to be used to know if the current app is the master
* @return true if id() == 0
*/
bool isMaster() const {
return !processId();
}
/**
* This function has to be used to know if the current app is alone
* @return true if processCount() == 1
*/
bool isAlone() const {
return processCount() == 1;
}
/**
* This function has to be used to know if the current app is a slave
* @return true if id() != 0
*/
bool isSlave() const {
return processId();
}
/**
* This function gives the number of parameters (argc)
* @return argc
*/
int userParemetersCount() const{
return this->argc;
}
/**
* This function gives a parameter
* @parameter inArg parameter position has to be strictly less than argc/userParemetersCount
* @return argv[inArg]
*/
const char* userParemeterAt(const int inArg) const{
return this->argv[inArg];
}
/**
* This function gives a parameter in a standart type
* @parameter inArg parameter position has to be strictly less than argc/userParemetersCount
* @return argv[inArg] in the template VariableType form
* @warning VariableType need to work with istream >> operator
* <code> const int argInt = userParemetersAt<int>(1,-1); </code>
*/
template <class VariableType>
const VariableType userParemeterAt(const int inArg, const VariableType& defaultValue = VariableType()) const{
std::istringstream iss(this->argv[inArg],std::istringstream::in);
VariableType value;
iss >> value;
if( /*iss.tellg()*/ iss.eof() ) return value;
return defaultValue;
}
/**
* This function gives the parameter in a standart type after a key parameter
* Do not use pointer in template type!
* @parameter inArg parameter key
* @return argv[inArg.position + 1] in the template VariableType form
* @warning VariableType need to work with istream >> operator
* <code> const int argInt = userParemetersAt<int>(1,-1); </code>
*/
template <class VariableType>
const VariableType userParemeterFromKey(const char* const inKey, const VariableType& defaultValue = VariableType(), bool* const inState = 0) const{
const int keysArgc= this->argc - 1;
// loop from 1 to argc 1
for(int indexArg = 1 ; indexArg < keysArgc ; ++indexArg){
// if argv == inArg
if(strcmp(this->argv[indexArg] , inKey) == 0){
// the argv + 1 => variable to use
std::istringstream iss(this->argv[indexArg + 1],std::istringstream::in);
VariableType value;
iss >> value;
// if we can cast to the template type
if( iss.eof() ){
if( inState ) *inState = true;
return value;
}
break;
}
}
// cannot cast to template or key not found
if( inState ) *inState = false;
return defaultValue;
}
};
#endif //FABSTRACTAPPLICATION_HPP
// [--LICENSE--]
#include "FAssertable.hpp"
#include "FAbstractApplication.hpp"
/**
* Current application
*/
FAbstractApplication* FAssertable::CurrentApp(0);
// Simply quit the current app
void FAssertable::exitApplication(const int inExitCode) const{
if(CurrentApp) CurrentApp->abort(inExitCode);
}
......@@ -5,8 +5,6 @@
#include <sstream>
#include <iostream>
class FAbstractApplication;
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAssertable
......@@ -19,22 +17,12 @@ class FAbstractApplication;
* </code>
*/
class FAssertable {
private:
static FAbstractApplication* CurrentApp; //< You must have only one app
/**
* Called by Fapplication instance to set the current app
* @param inCurrentApp current app
*/
static void SetCurrentApp(FAbstractApplication* const inCurrentApp){
CurrentApp = inCurrentApp;
}
/** To set CurrentApp */
friend class FAbstractApplication;
private:
/** To quit current application */
void exitApplication(const int inExitCode) const;
void exitApplication(const int inExitCode) const{
}
protected:
/** Empty Destructor */
......@@ -47,7 +35,7 @@ protected:
* @param inLinePosition line number
* @param inFilePosition file name
*
* <code> assert(toto == titi, "toto is not equal titi!", __LINE__, __FILE__); </code>
* <code> assert(toto == titi, "problem : toto is not equal titi!", __LINE__, __FILE__); </code>
*
* To prevent use from multiple thread we use a ostringstream before printing
*/
......
#ifndef FCONVERT_HPP
#define FCONVERT_HPP
#include <sstream>
#include <iostream>
#include <string.h>
#include "../Containers/FTreeCoordinate.hpp"
#include "../Utils/F3DPosition.hpp"
......@@ -31,6 +35,22 @@ public :
return outPosition;
}
/**
* This function gives a parameter in a standart type
* @parameter inArg parameter position has to be strictly less than argc/userParemetersCount
* @return argv[inArg] in the template VariableType form
* @warning VariableType need to work with istream >> operator
* <code> const int argInt = userParemetersAt<int>(1,-1); </code>
*/
template <class VariableType>
static const VariableType charToOther(const char* const str, const VariableType& defaultValue = VariableType()){
std::istringstream iss(str,std::istringstream::in);
VariableType value;
iss >> value;
if( /*iss.tellg()*/ iss.eof() ) return value;
return defaultValue;
}
};
#endif
......
#ifndef FMPI_HPP
#define FMPI_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "FGlobal.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FMpi
* Please read the license
*
* This namespace is to compile with or without mpi
*/
#ifdef SCALFMM_USE_MPI
////////////////////////////////////////////////////////
// Use MPI
////////////////////////////////////////////////////////
#include <mpi.h>
namespace FMpi {
void init(int inArgc, char ** inArgv ) {
MPI_Init(&inArgc,&inArgv);
}
void destroy(){
MPI_Finalize();
}
void sendData(const int inReceiver, const int inSize, void* const inData, const int inTag){
MPI_Request request;
MPI_Isend(inData, inSize, MPI_CHAR , inReceiver, inTag, MPI_COMM_WORLD, &request);
}
void receiveData(const int inSize, void* const inData, int* const inSource, int* const inTag, int* const inFilledSize){
MPI_Status status;
MPI_Recv(inData, inSize, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG,MPI_COMM_WORLD, &status);
*inSource = status.MPI_SOURCE;
*inTag = status.MPI_TAG;
MPI_Get_count(&status,MPI_CHAR,inFilledSize);
}
bool receivedData(){
int flag;
MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, MPI_STATUS_IGNORE);
return flag;
}
int processId() {
int id;
MPI_Comm_rank(MPI_COMM_WORLD,&id);
return id;
}
int processCount() {
int count;
MPI_Comm_size(MPI_COMM_WORLD,&count);
return count;
}
void processBarrier() {
MPI_Barrier(MPI_COMM_WORLD);
}
void abort(const int inErrorCode = 1) {
MPI_Abort(MPI_COMM_WORLD, inErrorCode);
}
};
#else
////////////////////////////////////////////////////////
// Without MPI
////////////////////////////////////////////////////////
namespace FMpi {
void init(int inArgc, char ** inArgv ) {}
void destroy(){}
void sendData(const int, const int, void* const, const int ){}
void receiveData(const int, void* const, int* const inSource, int* const inTag, int* const inFilledSize){
*inSource = 0;
*inTag = 0;
*inFilledSize = 0;
}
bool receivedData(){
return false;
}
int processId() {
return 0;
}
int processCount() {
return 1;
}
void processBarrier() {}
void abort(const int inErrorCode = 1) {
exit(inErrorCode);
}
};
#endif
////////////////////////////////////////////////////////
// To use in any case
////////////////////////////////////////////////////////
namespace FMpi {
bool isMaster() {
return !processId();
}
bool isAlone() {
return processCount() == 1;
}
bool isSlave() {
return processId();
}
};
#endif //FMPI_HPP
// [--LICENSE--]
#ifndef FMPIAPPLICATION_HPP
#define FMPIAPPLICATION_HPP
// /!\ Please, you must read the license at the bottom of this page
#include <mpi.h>
#include "FAbstractApplication.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FMpiApplication
* Please read the license
*
* This class is an implementation of the abstract application with mpi
*
* @warning you have to implement run() and call execute to start the app
*
* Please refere to testApplication.cpp to see an example
* <code>
* </code>
*/
class FMpiApplication : public FAbstractApplication {
protected:
/**
* This will be called as the main method
* @warning Must be impleted in the derived class
*/
virtual void run() = 0;
void sendData(const int inReceiver, const int inSize, void* const inData, const int inTag){
MPI_Request request;
MPI_Isend(inData, inSize, MPI_CHAR , inReceiver, inTag, MPI_COMM_WORLD, &request);
}
void receiveData(const int inSize, void* const inData, int* const inSource, int* const inTag, int* const inFilledSize){
MPI_Status status;
MPI_Recv(inData, inSize, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG,MPI_COMM_WORLD, &status);
*inSource = status.MPI_SOURCE;
*inTag = status.MPI_TAG;
MPI_Get_count(&status,MPI_CHAR,inFilledSize);
}
/**
* To know if some data arrived
*/
virtual bool receivedData(){
int flag;
MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, MPI_STATUS_IGNORE);
return flag;
}
public:
/**
* Constructor
* @param inArgc argc from command line
* @param inArgv argv from command line
*/
FMpiApplication(int inArgc, char ** inArgv )
: FAbstractApplication(inArgc,inArgv) {
MPI_Init(&inArgc,&inArgv);
}
/** Destructor */
virtual ~FMpiApplication(){
MPI_Finalize();
}
/**
* To get the current process id
* @return the process numeber [0 ; processCount [
*/
int processId() const {
int id;
MPI_Comm_rank(MPI_COMM_WORLD,&id);
return id;
}
/**
* To get the number of process
* @return process count
*/
int processCount() const {
int count;
MPI_Comm_size(MPI_COMM_WORLD,&count);
return count;
}