Commit 948d7eb1 authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

XML database parser

1) XML Database parser
2) todo Solver::Solver(std::string solverName, std::string prefix,
INMOST_MPI_Comm _comm)
parent 9915f5f8
...@@ -264,7 +264,6 @@ set(INMOST_INSTALL_HEADERS Source/Headers/inmost.h ...@@ -264,7 +264,6 @@ set(INMOST_INSTALL_HEADERS Source/Headers/inmost.h
Source/Headers/inmost_partitioner.h Source/Headers/inmost_partitioner.h
Source/Headers/inmost_solver.h Source/Headers/inmost_solver.h
Source/Headers/inmost_solver_interface.h Source/Headers/inmost_solver_interface.h
Source/Headers/inmost_solver_parameters.h
Source/Headers/inmost_sparse.h Source/Headers/inmost_sparse.h
Source/Headers/inmost_xml.h Source/Headers/inmost_xml.h
Source/Headers/inmost_utils.h Source/Headers/inmost_utils.h
...@@ -297,7 +296,6 @@ set_property(TARGET inmost PROPERTY PUBLIC_HEADER ...@@ -297,7 +296,6 @@ set_property(TARGET inmost PROPERTY PUBLIC_HEADER
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_partitioner.h" "${PROJECT_SOURCE_DIR}/Source/Headers/inmost_partitioner.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_solver.h" "${PROJECT_SOURCE_DIR}/Source/Headers/inmost_solver.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_solver_interface.h" "${PROJECT_SOURCE_DIR}/Source/Headers/inmost_solver_interface.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_solver_parameters.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_sparse.h" "${PROJECT_SOURCE_DIR}/Source/Headers/inmost_sparse.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_variable.h" "${PROJECT_SOURCE_DIR}/Source/Headers/inmost_variable.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_xml.h" "${PROJECT_SOURCE_DIR}/Source/Headers/inmost_xml.h"
......
...@@ -13,7 +13,6 @@ set(HEADER ...@@ -13,7 +13,6 @@ set(HEADER
${CMAKE_CURRENT_SOURCE_DIR}/inmost_mesh.h ${CMAKE_CURRENT_SOURCE_DIR}/inmost_mesh.h
${CMAKE_CURRENT_SOURCE_DIR}/inmost_solver.h ${CMAKE_CURRENT_SOURCE_DIR}/inmost_solver.h
${CMAKE_CURRENT_SOURCE_DIR}/inmost_solver_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/inmost_solver_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/inmost_solver_parameters.h
${CMAKE_CURRENT_SOURCE_DIR}/inmost_partitioner.h ${CMAKE_CURRENT_SOURCE_DIR}/inmost_partitioner.h
${CMAKE_CURRENT_SOURCE_DIR}/inmost_autodiff.h ${CMAKE_CURRENT_SOURCE_DIR}/inmost_autodiff.h
${CMAKE_CURRENT_SOURCE_DIR}/inmost_expression.h ${CMAKE_CURRENT_SOURCE_DIR}/inmost_expression.h
......
...@@ -30,6 +30,7 @@ namespace INMOST ...@@ -30,6 +30,7 @@ namespace INMOST
class Solver class Solver
{ {
private: private:
static std::vector<SolverParameters> parameters;
static int *argc; static int *argc;
static char ***argv; static char ***argv;
static const char *database; static const char *database;
...@@ -278,17 +279,23 @@ namespace INMOST ...@@ -278,17 +279,23 @@ namespace INMOST
/// @return Condition number or 1.0e100 if not converged. /// @return Condition number or 1.0e100 if not converged.
INMOST_DATA_REAL_TYPE Condest(INMOST_DATA_REAL_TYPE tol, INMOST_DATA_ENUM_TYPE maxits = 100); INMOST_DATA_REAL_TYPE Condest(INMOST_DATA_REAL_TYPE tol, INMOST_DATA_ENUM_TYPE maxits = 100);
/// Checks if solver available
/// @param name Solver name
static bool isSolverAvailable(std::string name); static bool isSolverAvailable(std::string name);
/// Return the list of all available solvers
static std::vector<std::string> getAvailableSolvers(); static std::vector<std::string> getAvailableSolvers();
~Solver(); ~Solver();
private: private:
static std::string parseDatabase(std::string solverName);
static void parseXMLDatabase(const char* xml_database);
}; };
typedef std::vector<std::string>::iterator solvers_names_iterator_t; typedef std::vector<std::string>::iterator solvers_names_iterator_t;
typedef std::vector<SolverParameters>::iterator solver_parameters_iterator_t;
} }
#endif #endif
......
...@@ -9,6 +9,22 @@ namespace INMOST { ...@@ -9,6 +9,22 @@ namespace INMOST {
#if defined(USE_SOLVER) #if defined(USE_SOLVER)
class SolverParameters {
public:
const std::string solverName;
const std::string solverPrefix;
const std::string internalFile;
std::vector<std::pair<std::string, std::string> > parameters;
SolverParameters(std::string solverName, std::string solverPrefix, std::string internalFile);
SolverParameters(const SolverParameters &other);
~SolverParameters();
};
typedef std::vector<std::pair<std::string, std::string> >::iterator parameters_iterator_t;
class SolverInterface { class SolverInterface {
protected: protected:
INMOST_MPI_Comm communicator; INMOST_MPI_Comm communicator;
...@@ -19,7 +35,7 @@ namespace INMOST { ...@@ -19,7 +35,7 @@ namespace INMOST {
virtual void Assign(const SolverInterface *other) = 0; virtual void Assign(const SolverInterface *other) = 0;
virtual void Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix) = 0; virtual void Setup(int *argc, char ***argv, SolverParameters &p) = 0;
virtual void SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) = 0; virtual void SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) = 0;
......
#ifndef INMOST_SOLVER_PARAMETERS_H
#define INMOST_SOLVER_PARAMETERS_H
#include <string>
#include "inmost_utils.h"
#include "inmost_common.h"
namespace INMOST {
#if defined(USE_SOLVER)
#endif
}
#endif //INMOST_SOLVER_PARAMETERS_H
...@@ -21,6 +21,8 @@ namespace INMOST { ...@@ -21,6 +21,8 @@ namespace INMOST {
return ss.str(); return ss.str();
} }
std::string string_to_lower(const std::string &str);
} }
#endif //INMOST_UTILS_H #endif //INMOST_UTILS_H
...@@ -226,6 +226,9 @@ public: ...@@ -226,6 +226,9 @@ public:
}; };
void WriteXML(const XMLReader::XMLTree & t, std::ostream & output, int offset = 0); void WriteXML(const XMLReader::XMLTree & t, std::ostream & output, int offset = 0);
typedef std::vector<XMLReader::XMLTree>::iterator xml_reader_tree_iterator_t;
typedef std::vector<XMLReader::XMLAttrib>::iterator xml_reader_attrib_iterator_t;
} }
......
...@@ -1457,9 +1457,15 @@ namespace INMOST ...@@ -1457,9 +1457,15 @@ namespace INMOST
ret.finish = ReadCloseTag(); //retrive '>' ret.finish = ReadCloseTag(); //retrive '>'
if( !include.empty() ) if( !include.empty() )
{ {
if( verbose > 1 ) Report("info: switching to stream %s",(GetFolder(get_Stream().src) + "/" + include).c_str());
PushStream((GetFolder(get_Stream().src) + "/" + include).c_str()); //switch to the included file std::string folder = GetFolder(get_Stream().src);
if (!folder.empty()) {
folder += "/";
}
if( verbose > 1 ) Report("info: switching to stream %s",(folder + include).c_str());
PushStream((folder + include).c_str()); //switch to the included file
} }
} }
else //encountered '</' of the root tag, no tag was red else //encountered '</' of the root tag, no tag was red
......
#include "inmost_solver_parameters.h" #include "inmost_solver_interface.h"
#include "inmost_solver.h"
namespace INMOST { namespace INMOST {
SolverParameters::SolverParameters(std::string solverName, std::string solverPrefix, std::string internalFile) : solverName(solverName),
solverPrefix(solverPrefix),
internalFile(internalFile) {}
SolverParameters::SolverParameters(const SolverParameters &other) : solverName(other.solverName), solverPrefix(other.solverPrefix),
internalFile(other.internalFile),
parameters(other.parameters) {
}
SolverParameters::~SolverParameters() {}
} }
...@@ -29,15 +29,21 @@ ...@@ -29,15 +29,21 @@
#endif #endif
#if defined(USE_SOLVER_SUPERLU) #if defined(USE_SOLVER_SUPERLU)
#include "solver_superlu/SolverSUPERLU.h" #include "solver_superlu/SolverSUPERLU.h"
#endif #endif
#if defined(HAVE_SOLVER_K3BIILU2) #if defined(HAVE_SOLVER_K3BIILU2)
#include "solver_k3biilu2/SolverK3BIILU2.h" #include "solver_k3biilu2/SolverK3BIILU2.h"
#endif #endif
#if defined(HAVE_SOLVER_FCBIILU2) #if defined(HAVE_SOLVER_FCBIILU2)
#include "solver_fcbiilu2/SolverFCBIILU2.h" #include "solver_fcbiilu2/SolverFCBIILU2.h"
#endif #endif
namespace INMOST { namespace INMOST {
...@@ -47,21 +53,50 @@ namespace INMOST { ...@@ -47,21 +53,50 @@ namespace INMOST {
const char *Solver::database = NULL; const char *Solver::database = NULL;
bool Solver::is_initialized = false; bool Solver::is_initialized = false;
bool Solver::is_finalized = false; bool Solver::is_finalized = false;
std::vector<SolverParameters> Solver::parameters = std::vector<SolverParameters>();
Solver::Solver(std::string solverName, std::string prefix, INMOST_MPI_Comm _comm) { Solver::Solver(std::string solverName, std::string prefix, INMOST_MPI_Comm _comm) {
this->solver = SolverMaster::getSolver(solverName); std::string lowerName = string_to_lower(solverName);
this->prefix = prefix; this->solver = SolverMaster::getSolver(lowerName);
this->prefix = string_to_lower(prefix);
solver->SetCommunicator(_comm); solver->SetCommunicator(_comm);
std::string solverDatabasePath = Solver::parseDatabase(solverName); //TODO find easiest way
solver->Initialize(argc, argv, solverDatabasePath.c_str(), prefix); bool parametersFound = false;
if (Solver::parameters.size() > 0) {
for (solver_parameters_iterator_t parameters = Solver::parameters.end() - 1; parameters >= Solver::parameters.begin(); parameters--) {
if ((*parameters).solverName == lowerName && (*parameters).solverPrefix == (this->prefix)) {
solver->Setup(argc, argv, *parameters);
parametersFound = true;
break;
}
}
}
if (!parametersFound) {
SolverParameters emptyParameters(lowerName, this->prefix, "");
solver->Setup(argc, argv, emptyParameters);
}
} }
Solver::Solver(const Solver &other) { Solver::Solver(const Solver &other) {
this->solver = SolverMaster::copySolver(other.solver); this->solver = SolverMaster::copySolver(other.solver);
this->prefix = other.prefix; this->prefix = other.prefix;
solver->SetCommunicator(other.solver->GetCommunicator()); solver->SetCommunicator(other.solver->GetCommunicator());
std::string solverDatabasePath = Solver::parseDatabase(solver->SolverName()); //TODO find easiest way
solver->Initialize(argc, argv, solverDatabasePath.c_str(), this->prefix); bool parametersFound = false;
if (Solver::parameters.size() > 0) {
for (solver_parameters_iterator_t parameters = Solver::parameters.end() - 1; parameters >= Solver::parameters.begin(); parameters--) {
if ((*parameters).solverName == other.solver->SolverName() && (*parameters).solverPrefix == (this->prefix)) {
solver->Setup(argc, argv, *parameters);
parametersFound = true;
break;
}
}
}
if (!parametersFound) {
SolverParameters emptyParameters(other.solver->SolverName(), this->prefix, "");
solver->Setup(argc, argv, emptyParameters);
}
} }
Solver &Solver::operator=(const Solver &other) { Solver &Solver::operator=(const Solver &other) {
...@@ -126,6 +161,18 @@ namespace INMOST { ...@@ -126,6 +161,18 @@ namespace INMOST {
#if defined(HAVE_SOLVER_FCBIILU2) #if defined(HAVE_SOLVER_FCBIILU2)
SolverMaster::registerSolver<SolverFCBIILU2>("fcbiilu2"); SolverMaster::registerSolver<SolverFCBIILU2>("fcbiilu2");
#endif #endif
Solver::parseXMLDatabase(database);
//Debug
// for (auto p = parameters.begin(); p < parameters.end(); p++) {
// std::cout << "============================================================================" << std::endl;
// std::cout << (*p).solverName << ":" << (*p).solverPrefix << ":" << (*p).internalFile << std::endl;
// for (auto pp = (*p).parameters.begin(); pp < (*p).parameters.end(); pp++) {
// std::cout << (*pp).first << " = " << (*pp).second << std::endl;
// }
// std::cout << "============================================================================" << std::endl;
// }
Sparse::CreateRowEntryType(); Sparse::CreateRowEntryType();
} }
...@@ -214,33 +261,79 @@ namespace INMOST { ...@@ -214,33 +261,79 @@ namespace INMOST {
delete solver; delete solver;
} }
std::string Solver::parseDatabase(std::string solverName) { void Solver::parseXMLDatabase(const char *xml_database) {
const char *name = solverName.c_str(); if (xml_database == NULL) return;
if (database != NULL) {
FILE *f = fopen(database, "r"); std::ifstream input;
if (f != NULL) { input.open(xml_database);
char str[4096];
while (!feof(f) && fgets(str, 4096, f)) { if (input.fail()) {
int k = 0, l; std::cout << __FILE__ << ": XML database file not found " << std::endl;
for (k = 0; k < (int) strlen(str); ++k) { return;
if (str[k] == ':') break; }
XMLReader reader(std::string(xml_database), input);
try {
XMLReader::XMLTree root = reader.ReadXML();
if (root.tag.name != "SolverParameters") {
std::cout << __FILE__ << ": Bad XML database file" << std::endl;
return;
}
for (xml_reader_tree_iterator_t solver = root.children.begin(); solver < root.children.end(); solver++) {
std::string solverName = string_to_lower((*solver).tag.name);
std::string internalFile = "";
if ((*solver).tag.attributes.size() != 0) {
for (xml_reader_attrib_iterator_t attr = (*solver).tag.attributes.begin(); attr < (*solver).tag.attributes.end(); attr++) {
if ((*attr).name == "File" || (*attr).name == "file" || (*attr).name == "FILE") {
internalFile = (*attr).value;
}
} }
if (k == strlen(str)) continue; //invalid line }
for (l = 0; l < k; ++l) str[l] = tolower(str[l]);
l = (int) strlen(str) - 1; // Right-trim string if ((*solver).children.size() == 0) {
while (l > 0 && isspace(str[l])) --l; //Internal solver
str[l + 1] = 0; parameters.push_back(SolverParameters(solverName, "", internalFile));
l = k + 1; } else {
while (l < (int) strlen(str) && isspace(str[l])) ++l; //Inner solver
if (l == strlen(str)) continue; //skip empty entry for (xml_reader_tree_iterator_t prefix = (*solver).children.begin(); prefix < (*solver).children.end(); prefix++) {
if (!strncmp(str, name, k)) { internalFile = "";
return std::string(str + l); std::string solverPrefix = string_to_lower((*prefix).tag.name);
if ((*prefix).tag.attributes.size() != 0) {
for (xml_reader_attrib_iterator_t attr = (*prefix).tag.attributes.begin(); attr < (*prefix).tag.attributes.end(); attr++) {
if ((*attr).name == "File" || (*attr).name == "file" || (*attr).name == "FILE") {
internalFile = (*attr).value;
}
}
}
SolverParameters prefix_p = SolverParameters(solverName, solverPrefix, internalFile);
for (xml_reader_tree_iterator_t p = (*prefix).children.begin(); p < (*prefix).children.end(); p++) {
if ((*p).tag.attributes.size() == 1) {
if ((*p).tag.attributes[0].name == "value" || (*p).tag.attributes[0].name == "Value") {
prefix_p.parameters.push_back(std::make_pair((*p).tag.name, (*p).tag.attributes[0].value));
}
}
}
parameters.push_back(prefix_p);
} }
} }
fclose(f);
} }
} catch (...) {
std::cout << __FILE__ << ": Error while parsing xml database file" << std::endl;
} }
return std::string("");
} }
} }
\ No newline at end of file
...@@ -14,7 +14,7 @@ namespace INMOST { ...@@ -14,7 +14,7 @@ namespace INMOST {
throw INMOST::SolverUnsupportedOperation; //later throw INMOST::SolverUnsupportedOperation; //later
} }
void SolverANI::Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix) { void SolverANI::Setup(int *argc, char ***argv, SolverParameters &p) {
solver.n = 0; solver.n = 0;
m.n = 0; m.n = 0;
} }
......
...@@ -19,7 +19,7 @@ namespace INMOST { ...@@ -19,7 +19,7 @@ namespace INMOST {
virtual void Assign(const SolverInterface *other); virtual void Assign(const SolverInterface *other);
virtual void Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix); virtual void Setup(int *argc, char ***argv, SolverParameters &p);
virtual void SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner); virtual void SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner);
......
...@@ -28,9 +28,9 @@ namespace INMOST { ...@@ -28,9 +28,9 @@ namespace INMOST {
} }
} }
void SolverFCBIILU2::Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix) { void SolverFCBIILU2::Setup(int *argc, char ***argv, SolverParameters &p) {
SolverInitDataFcbiilu2(&solver_data, communicator, prefix.c_str()); SolverInitDataFcbiilu2(&solver_data, communicator, p.solverPrefix.c_str());
SolverInitializeFcbiilu2(argc, argv, parameters_file); SolverInitializeFcbiilu2(argc, argv, p.internalFile.c_str());
} }
void SolverFCBIILU2::SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) { void SolverFCBIILU2::SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) {
......
...@@ -18,7 +18,7 @@ namespace INMOST { ...@@ -18,7 +18,7 @@ namespace INMOST {
virtual void Assign(const SolverInterface *other); virtual void Assign(const SolverInterface *other);
virtual void Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix); virtual void Setup(int *argc, char ***argv, SolverParameters &p);
virtual void SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner); virtual void SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner);
......
...@@ -3,24 +3,24 @@ ...@@ -3,24 +3,24 @@
namespace INMOST { namespace INMOST {
SolverInner::SolverInner() { SolverInner::SolverInner() {
iters = 2500; maximum_iterations = 2500;
scale_iters = 6; rescale_iterations = 6;
condest = 1; condition_estimation = 1;
ddpqatol = 1; adapt_ddpq_tolerance = 1;
overlap = 1; schwartz_overlap = 1;
ell = 2; gmres_substeps = 2;
reorder_nnz = 1; reorder_nnz = 1;
atol = 1.0e-5; atol = 1.0e-5;
rtol = 1.0e-12; rtol = 1.0e-12;
dtol = 1.0e+100; dtol = 1.0e+100;
tau = 0.005; drop_tolerance = 0.005;
tau2 = 0.00005; reuse_tolerance = 0.00005;
ddpqtol = 0.75; ddpq_tolerance = 0.75;
fill = 3; fill_level = 3;
} }
SolverInner::SolverInner(const SolverInterface *other): SolverInterface(other) { SolverInner::SolverInner(const SolverInterface *other) : SolverInterface(other) {
//You should not really want to copy solver's information //You should not really want to copy solver's information
throw INMOST::SolverUnsupportedOperation; throw INMOST::SolverUnsupportedOperation;
} }
...@@ -30,28 +30,35 @@ namespace INMOST { ...@@ -30,28 +30,35 @@ namespace INMOST {
throw INMOST::SolverUnsupportedOperation; throw INMOST::SolverUnsupportedOperation;
} }
void SolverInner::Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix) { void SolverInner::Setup(int *argc, char ***argv, SolverParameters &p) {
// FILE *databaseFile = fopen(parameters_file, "r"); if (!p.internalFile.empty()) {
// if (!databaseFile) { FILE *databaseFile = fopen(p.internalFile.c_str(), "r");
// return; if (!databaseFile) {
// } return;
// char *tmp = (char *) calloc(256, sizeof(char)); }
// char *parameterName = (char *) calloc(128, sizeof(char)); char *tmp = (char *) calloc(256, sizeof(char));
// char *parameterValue = (char *) calloc(128, sizeof(char)); char *parameterName = (char *) calloc(128, sizeof(char));
// while (!feof(databaseFile) && fgets(tmp, 256, databaseFile)) { char *parameterValue = (char *) calloc(128, sizeof(char));
// char *line = tmp; while (!feof(databaseFile) && fgets(tmp, 256, databaseFile)) {
// //Comment str char *line = tmp;
// if (line[0] == '#') continue; //Comment str
// sscanf(line, "%s %s", parameterName, parameterValue);