Commit 9ddf5d28 authored by Geoffroy Lesur's avatar Geoffroy Lesur 👻
Browse files

working new template implementation of Get

parent f7f517b9
......@@ -16,32 +16,32 @@ void ErrorHandler(const int ErrorType,
const int ErrorLine,
std::string ErrorFile) {
if (ErrorType == ERROR_WARNING) {
idfx::cout << std::endl
idfx::cerr << std::endl
<< "------------------------------------------------------------------------------"
<< std::endl;
idfx::cout << "## WARNING in function " << ErrorFunction << " file " << ErrorFile << " line "
idfx::cerr << "## WARNING in function " << ErrorFunction << " file " << ErrorFile << " line "
<< ErrorLine << std::endl;
idfx::cout << ErrorMessage.str() << std::endl;
idfx::cout << "------------------------------------------------------------------------------"
idfx::cerr << ErrorMessage.str() << std::endl;
idfx::cerr << "------------------------------------------------------------------------------"
<< std::endl;
} else if (ErrorType == ERROR_DEPRECATED) {
idfx::cout << std::endl
idfx::cerr << std::endl
<< "------------------------------------------------------------------------------"
<< std::endl;
idfx::cout << "## DEPRECATED call in function " << ErrorFunction << " file " << ErrorFile
idfx::cerr << "## DEPRECATED call in function " << ErrorFunction << " file " << ErrorFile
<< std::endl
<< "## This function will be removed in the next Idefix release." << std::endl;
idfx::cout << ErrorMessage.str() << std::endl;
idfx::cout << "------------------------------------------------------------------------------"
idfx::cerr << ErrorMessage.str() << std::endl;
idfx::cerr << "------------------------------------------------------------------------------"
<< std::endl;
} else {
idfx::cout << std::endl
idfx::cerr << std::endl
<< "------------------------------------------------------------------------------"
<< std::endl;
idfx::cout << "### FATAL ERROR in function " << ErrorFunction << " file " << ErrorFile
idfx::cerr << "### FATAL ERROR in function " << ErrorFunction << " file " << ErrorFile
<< " line " << ErrorLine << std::endl;
idfx::cout << ErrorMessage.str() << std::endl;
idfx::cout << "------------------------------------------------------------------------------"
idfx::cerr << ErrorMessage.str() << std::endl;
idfx::cerr << "------------------------------------------------------------------------------"
<< std::endl;
#ifdef WITH_MPI
MPI_Abort(MPI_COMM_WORLD,1);
......@@ -56,46 +56,46 @@ void ErrorHandler(const int ErrorType,
const int ErrorLine,
std::string ErrorFile) {
if (ErrorType == ERROR_WARNING) {
idfx::cout << std::endl
idfx::cerr << std::endl
<< "------------------------------------------------------------------------------"
<< std::endl;
idfx::cout << "## WARNING in function " << ErrorFunction << " file " << ErrorFile << " line "
idfx::cerr << "## WARNING in function " << ErrorFunction << " file " << ErrorFile << " line "
<< ErrorLine << std::endl;
idfx::cout << ErrorMessage << std::endl;
idfx::cout << "------------------------------------------------------------------------------"
idfx::cerr << ErrorMessage << std::endl;
idfx::cerr << "------------------------------------------------------------------------------"
<< std::endl;
if(idfx::warningsAreErrors) {
idfx::cout << "Warnings are considered as errors" << std::endl;
idfx::cerr << "Warnings are considered as errors" << std::endl;
#ifdef WITH_MPI
MPI_Abort(MPI_COMM_WORLD,1);
#endif
exit(1);
}
} else if (ErrorType == ERROR_DEPRECATED) {
idfx::cout << std::endl
idfx::cerr << std::endl
<< "------------------------------------------------------------------------------"
<< std::endl;
idfx::cout << "## DEPRECATED call in function " << ErrorFunction << " file " << ErrorFile
idfx::cerr << "## DEPRECATED call in function " << ErrorFunction << " file " << ErrorFile
<< std::endl
<< "## This function will be removed in the next Idefix release." << std::endl;
idfx::cout << ErrorMessage << std::endl;
idfx::cout << "------------------------------------------------------------------------------"
idfx::cerr << ErrorMessage << std::endl;
idfx::cerr << "------------------------------------------------------------------------------"
<< std::endl;
if(idfx::warningsAreErrors) {
idfx::cout << "Warnings are considered as errors" << std::endl;
idfx::cerr << "Warnings are considered as errors" << std::endl;
#ifdef WITH_MPI
MPI_Abort(MPI_COMM_WORLD,1);
#endif
exit(1);
}
} else {
idfx::cout << std::endl
idfx::cerr << std::endl
<< "------------------------------------------------------------------------------"
<< std::endl;
idfx::cout << "### FATAL ERROR in function " << ErrorFunction << " file " << ErrorFile
idfx::cerr << "### FATAL ERROR in function " << ErrorFunction << " file " << ErrorFile
<< " line " << ErrorLine << std::endl;
idfx::cout << ErrorMessage << std::endl;
idfx::cout << "------------------------------------------------------------------------------"
idfx::cerr << ErrorMessage << std::endl;
idfx::cerr << "------------------------------------------------------------------------------"
<< std::endl;
#ifdef WITH_MPI
MPI_Abort(MPI_COMM_WORLD,1);
......
......@@ -20,7 +20,8 @@ double mpiCallsTimer = 0.0;
bool warningsAreErrors{false};
IdefixOstream cout;
IdefixOutStream cout;
IdefixErrStream cerr;
Profiler prof;
LoopPattern defaultLoopPattern;
......@@ -75,7 +76,7 @@ void popRegion() {
}
// Init the iostream with defined rank
void IdefixOstream::init(int rank) {
void IdefixOutStream::init(int rank) {
std::stringstream sslogFileName;
sslogFileName << "idefix." << rank << ".log";
......@@ -88,8 +89,9 @@ void IdefixOstream::init(int rank) {
this->toscreen=false;
}
// disable the log file
void IdefixOstream::disableLogFile() {
void IdefixOutStream::disableLogFile() {
my_fstream << "Log files have been disabled (e.g. using -nowrite)." << std::endl;
my_fstream.close();
this->logFileEnabled = false;
......
......@@ -13,12 +13,14 @@
namespace idfx {
int initialize(); // Initialisation routine for idefix
class IdefixOstream;
class IdefixOutStream;
class IdefixErrStream;
class Profiler;
extern int prank; //< parallel rank
extern int psize;
extern IdefixOstream cout; //< custom cout for idefix
extern IdefixOutStream cout; //< custom cout for idefix
extern IdefixErrStream cerr; //< custom cerr for idefix
extern Profiler prof; //< profiler (for memory usage)
extern double mpiCallsTimer; //< time significant MPI calls
extern LoopPattern defaultLoopPattern; //< default loop patterns (for idefix_for loops)
......@@ -41,19 +43,19 @@ IdefixArray1D<T> ConvertVectorToIdefixArray(std::vector<T> &inputVector) {
} // namespace idfx
class idfx::IdefixOstream {
class idfx::IdefixOutStream {
public:
void init(int);
void disableLogFile();
// for regular output of variables and stuff
template<typename T> IdefixOstream& operator<<(const T& something) {
template<typename T> IdefixOutStream& operator<<(const T& something) {
if(toscreen) std::cout << something;
if(logFileEnabled) my_fstream << something;
return *this;
}
// for manipulators like std::endl
typedef std::ostream& (*stream_function)(std::ostream&);
IdefixOstream& operator<<(stream_function func) {
IdefixOutStream& operator<<(stream_function func) {
if(toscreen) func(std::cout);
if(logFileEnabled) func(my_fstream);
return *this;
......@@ -64,4 +66,19 @@ class idfx::IdefixOstream {
bool logFileEnabled{true}; //< whether streams are also written to a log file
};
class idfx::IdefixErrStream {
public:
// for error output of variables and stuff
template<typename T> IdefixErrStream& operator<<(const T& something) {
std::cerr << something;
return *this;
}
// for manipulators like std::endl
typedef std::ostream& (*stream_function)(std::ostream&);
IdefixErrStream& operator<<(stream_function func) {
func(std::cerr);
return *this;
}
};
#endif // GLOBAL_HPP_
......@@ -311,104 +311,18 @@ std::string Input::getFileExtension(const std::string file_name) {
}
// Get a string in a block, parameter, position of the file
std::string Input::GetString(std::string blockName, std::string paramName, int num) {
std::stringstream msg;
std::string value;
IdefixInputContainer::iterator block = inputParameters.find(blockName);
if(block != inputParameters.end()) {
// Block exists
IdefixBlockContainer::iterator param = block->second.find(paramName);
if(param != block->second.end()) {
// Parameter exist
if(num<param->second.size()) {
// Vector is long enough
value=param->second[num];
} else {
// Vector is not long enough
msg << "Index " << num << " cannot be found in block:parameter" << blockName << ":"
<< paramName;
IDEFIX_ERROR(msg);
}
} else {
msg << "Parameter " << paramName << " cannot be found in block [" << blockName <<"]";
IDEFIX_ERROR(msg);
}
} else {
msg << "BlockName " << blockName << " cannot be found";
IDEFIX_ERROR(msg);
}
return(value);
std::string Input::GetAString(std::string blockName, std::string paramName, int num) {
return(Get<std::string>(blockName, paramName, num));
}
// Get a real number in a block, parameter, position of the file
real Input::GetReal(std::string blockName, std::string paramName, int num) {
std::stringstream msg;
real value;
IdefixInputContainer::iterator block = inputParameters.find(blockName);
if(block != inputParameters.end()) {
// Block exists
IdefixBlockContainer::iterator param = block->second.find(paramName);
if(param != block->second.end()) {
// Parameter exist
if(num<param->second.size()) {
// Vector is long enough
#ifdef USE_DOUBLE
value = std::stod(param->second[num], NULL);
#else
value = std::stof(param->second[num], NULL);
#endif
} else {
// Vector is not long enough
msg << "Index " << num << " cannot be found in block:parameter" << blockName << ":"
<< paramName;
IDEFIX_ERROR(msg);
}
} else {
msg << "Parameter " << paramName << " cannot be found in block [" << blockName <<"]";
IDEFIX_ERROR(msg);
}
} else {
msg << "BlockName " << blockName << " cannot be found";
IDEFIX_ERROR(msg);
}
return(value);
real Input::GetAReal(std::string blockName, std::string paramName, int num) {
return(Get<real>(blockName, paramName, num));
}
// Get an integer number in a block, parameter, position of the file
int Input::GetInt(std::string blockName, std::string paramName, int num) {
std::stringstream msg;
int value;
IdefixInputContainer::iterator block = inputParameters.find(blockName);
if(block != inputParameters.end()) {
// Block exists
IdefixBlockContainer::iterator param = block->second.find(paramName);
if(param != block->second.end()) {
// Parameter exist
if(num<param->second.size()) {
// Vector is long enough
value = std::stoi(param->second[num], NULL);
} else {
// Vector is not long enough
msg << "Index " << num << " cannot be found in block:parameter" << blockName
<< ":" << paramName;
IDEFIX_ERROR(msg);
}
} else {
msg << "Parameter " << paramName << " cannot be found in block [" << blockName <<"]";
IDEFIX_ERROR(msg);
}
} else {
msg << "BlockName " << blockName << " cannot be found";
IDEFIX_ERROR(msg);
}
return(value);
int Input::GetAInt(std::string blockName, std::string paramName, int num) {
return(Get<int>(blockName, paramName, num));
}
// Check that an entry is present in the ini file.
......
......@@ -26,11 +26,20 @@ class Input {
// Accessor to input parameters
// the parameters are always: BlockName, EntryName, ParameterNumber (starting from 0)
std::string GetString(std::string, std::string, int); ///< Read a string from the input file
real GetReal(std::string, std::string, int); ///< Read a real number from the input file
int GetInt(std::string, std::string, int); ///< Read an integer from the input file
std::string GetAString(std::string, std::string, int); ///< Read a string from the input file
real GetAReal(std::string, std::string, int); ///< Read a real number from the input file
int GetAInt(std::string, std::string, int); ///< Read an integer from the input file
int CheckEntry(std::string, std::string); ///< Check that a block+entry is present
///< in the input file
template<typename T>
T Get(std::string, std::string, int); ///< read a variable from the input file
///< (abort if not found)
template<typename T>
T GetOrSet(std::string, std::string, int, T); ///< read a variable from the input file
///< (set it to T if not found)
bool CheckBlock(std::string); ///< check that whether a block is defined
///< in the input file
bool CheckForAbort(); // have we been asked for an abort?
......@@ -63,4 +72,72 @@ class Input {
double lastStopFileCheck;
};
// Template functions
template<typename T>
T Input::Get(std::string blockName, std::string paramName, int num) {
if(CheckEntry(blockName, paramName) <= num) {
std::stringstream msg;
msg << "Mandatory parameter [" << blockName << "]:" << paramName << "(" << num+1
<< "). Cannot be found in the input file" << std::endl;
IDEFIX_ERROR(msg);
}
// Fetch it
std::string paramString = inputParameters[blockName][paramName][num];
T value;
try {
if(typeid(T) == typeid(int)) {
int *v = reinterpret_cast<int*>( &value);
*v = std::stoi(paramString, NULL);
} else if(typeid(T) == typeid(double)) {
double *v = reinterpret_cast<double*>( &value);
*v = std::stod(paramString, NULL);
} else if(typeid(T) == typeid(float)) {
float *v = reinterpret_cast<float*>( &value);
*v = std::stof(paramString, NULL);
} else if(typeid(T) == typeid(int64_t)) {
int64_t *v = reinterpret_cast<int64_t *>( &value);
*v = std::stol(paramString, NULL);
} else if(typeid(T) == typeid(std::string)) {
std::string *v = reinterpret_cast<std::string*>( &value);
*v = paramString;
} else {
IDEFIX_ERROR("Unknown type has been requested from the input file");
}
} catch(const std::exception& e) {
std::stringstream errmsg;
errmsg << e.what() << std::endl
<< "Input::Get: Error while reading [" << blockName << "]:" << paramName << "(" << num+1
<< ")." << std::endl
<< "\"" << paramString << "\" cannot be converted to number." << std::endl;
IDEFIX_ERROR(errmsg);
}
return(value);
}
template<typename T>
T Input::GetOrSet(std::string blockName, std::string paramName, int num, T def) {
int entrySize = CheckEntry(blockName, paramName);
if(entrySize <= num ) {
// the requested entry has not been set, add it (if we can), otherwise throw an error
if(entrySize < 0 && num>0) {
std::stringstream msg;
msg << "Entry [" << blockName << "]:" << paramName << "is not defined." << std::endl
<< "Only the first (index 0) parameter can be set by default." << std::endl;
IDEFIX_ERROR(msg);
}
if(entrySize+1 < num) {
std::stringstream msg;
msg << "Entry [" << blockName << "]:" << paramName << "has " << entrySize << " parameters."
<< std::endl << ". Only the " << entrySize << "th (index " << entrySize-1
<< ") parameter can be set by default." << std::endl;
IDEFIX_ERROR(msg);
}
inputParameters[blockName][paramName].push_back(std::to_string(def));
}
return(Get<T>(blockName, paramName, num));
}
#endif // INPUT_HPP_
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment