Commit aa2091b7 authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

WIP: ttsp optimizer draft

parent c69db085
......@@ -34,6 +34,7 @@ option(USE_SOLVER_MONDRIAAN "Use Mondriaan for matrix reordering" OFF)
option(USE_SOLVER_PETSC "Use PETSc solvers" OFF)
option(USE_SOLVER_TRILINOS "Use Trilinos solvers" OFF)
option(USE_SOLVER_SUPERLU "Use SuperLU solver" OFF)
option(USE_SOLVER_TTSP_FEATURE "Use Trace and Tune Solver Parameters optimization toolkit" OFF)
#option(USE_AUTODIFF_ASMJIT "Use AsmJit for automatic differentiation" OFF)
#option(USE_AUTODIFF_EXPRESSION_TEMPLATES "Use c++ expression templates for automatic differentiation" OFF)
......@@ -45,7 +46,7 @@ endif( MSVC )
add_subdirectory(Source)
add_definitions(${SOLVER_DEFINITIONS})
add_library(inmost STATIC ${SOURCE} ${HEADER})
add_library(inmost STATIC ${SOURCE} ${HEADER} Source/Solver/ttsp/optimization_parameters.cpp Source/Solver/ttsp/optimization_parameters.h Source/Solver/ttsp/optimizers/bruteforce/ttsp_bruteforce.cpp Source/Solver/ttsp/optimizers/bruteforce/ttsp_bruteforce.h)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_find/")
......
......@@ -8,6 +8,7 @@ endif(USE_MESH)
if(USE_SOLVER)
add_subdirectory(DrawMatrix)
add_subdirectory(MatSolve)
add_subdirectory(TTSPSolve)
endif(USE_SOLVER)
if(USE_SOLVER AND USE_MESH)
add_subdirectory(FVDiscr)
......
......@@ -339,7 +339,7 @@ int main(int argc, char **argv) {
}
mat.Load(matrixFileName, ENUMUNDEF, ENUMUNDEF, orderingFileName);
} else {
mat.Load(matrixFileName); //if interval parameters not set, matrix will be divided automatically
mat.Load(matrixFileName); //ifinterval parameters not set, matrix will be divided automatically
}
if (processorsCount == 1) {
ps_inmost(mat, "a.ps"); //db !IK!
......
*.mtx
*.rhs
\ No newline at end of file
project(TTSPSolve)
set(SOURCE main.cpp)
add_executable(TTSPSolve ${SOURCE})
target_link_libraries(TTSPSolve inmost)
if(USE_MPI)
message("linking TTSPSolve with MPI")
target_link_libraries(TTSPSolve ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(TTSPSolve PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
if(USE_SOLVER)
if(USE_SOLVER_ANI)
message("linking TTSPSolve with ani3d and BLAS")
target_link_libraries(TTSPSolve ani3d ${BLAS_LIBRARIES})
if(BLAS_LINKER_FLAGS)
set_target_properties(TTSPSolve PROPERTIES LINK_FLAGS "${BLAS_LINKER_FLAGS}")
endif()
endif()
if(USE_SOLVER_PETSC)
message("linking TTSPSolve with PETSc")
target_link_libraries(TTSPSolve ${PETSC_LIBRARIES})
endif()
if(USE_SOLVER_TRILINOS)
message("linking TTSPSolve with Trilinos")
target_link_libraries(TTSPSolve ${Trilinos_LIBRARIES} ${Trilinos_TPL_LIBRARIES})
endif()
if(USE_SOLVER_METIS)
message("linking TTSPSolve with Metis")
target_link_libraries(TTSPSolve ${METIS_LIBRARIES})
endif()
if(USE_SOLVER_MONDRIAAN)
message("linking TTSPSolve with Mondriaan")
target_link_libraries(TTSPSolve ${MONDRIAAN_LIBRARIES})
endif()
if(USE_SOLVER_SUPERLU)
message("linking TTSPSolve with SuperLU")
target_link_libraries(TTSPSolve ${SUPERLU_LIBRARIES})
endif()
endif()
if(USE_PARTITIONER)
if(USE_PARTITIONER_ZOLTAN)
message("linking TTSPSolve with Zoltan")
target_link_libraries(TTSPSolve ${ZOLTAN_LIBRARIES})
endif()
if(USE_PARTITIONER_PARMETIS)
message("linking TTSPSolve with ParMETIS")
target_link_libraries(TTSPSolve ${PARMETIS_LIBRARIES})
endif()
endif()
install(TARGETS TTSPSolve EXPORT inmost-targets RUNTIME DESTINATION bin)
1 !01 ipart (...partitioning option = -1,0,1,2)
'tst.mtx' !02 name_a
'tst.rhs' !03 name_b
1e-6 !04 eps
0999 !05 nit
1 !06 kgmr (BiCGStab: kgmr=1; GMR[kdeg]: kgmr>3*kdeg+2)
1 !07 kdeg (ignored if kgmr=1)
0 !08 kovl
1e-3 !09 tau
'res' !10 name_out
'none' !11 name_x
<SolverParameters>
<inner_ilu2>
<test file="inner_options.txt" />
</inner_ilu2>
<inner_ddpqiluc2>
<test file="inner_options.txt" />
</inner_ddpqiluc2>
<inner_mptiluc>
<test file="inner_options.txt" />
</inner_mptiluc>
<inner_mptilu2>
<test file="inner_options.txt" />
</inner_mptilu2>
<fcbiilu2>
<test file="inner_options.txt" />
</fcbiilu2>
<k3biilu2>
<test file="inner_options.txt" />
</k3biilu2>
<petsc>
<test file="petsc_options.txt" />
</petsc>
<trilinos_ifpack>
<test file="trilinos_ifpack_options.xml" />
</trilinos_ifpack>
</SolverParameters>
maximum_iterations 300
gmres_substeps 4
relative_tolerance 1.0e-5
absolute_tolerance 1.0e-10
divergence_tolerance 1e+200
reorder_nonzeros 0
rescale_iterations 8
adapt_ddpq_tolerance 0
drop_tolerance 3.0e-5
reuse_tolerance 1.0e-5
ddpq_tolerance 0.0
condition_estimation 1
schwartz_overlap 6
q 0
tau 1e-2
msglev 0
#include "inmost.h"
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include "Source/Solver/ttsp/optimization_parameters.h"
#include "Source/Solver/ttsp/optimizer_interface.h"
#include "Source/Solver/ttsp/optimizers/bruteforce/ttsp_bruteforce.h"
using namespace INMOST;
#if defined(USE_MPI)
#define BARRIER MPI_Barrier(MPI_COMM_WORLD)
#else
#define BARRIER
#endif
int main(int argc, char **argv) {
int rank = 0, size = 1;
#if defined(USE_MPI)
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); // Get the rank of the current process
MPI_Comm_size(MPI_COMM_WORLD, &size); // Get the total number of processors used
#endif
{
std::string matrixFileName = "";
std::string vectorBFileName = "";
std::string parametersFileName = "";
std::string solverName = "fcbiilu2";
bool matrixFound = false;
bool vectorBFound = false;
bool parametersFound = false;
bool typeFound = false;
//Parse argv parameters
if (argc == 1) goto helpMessage;
int i;
for (i = 1; i < argc; i++) {
//Print help message and exit
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
helpMessage:
if (rank == 0) {
std::cout << "Help message: " << std::endl;
std::cout << "Command line options: " << std::endl;
std::cout << "Required: " << std::endl;
std::cout << "-m, --matrix <Matrix file name>" << std::endl;
std::cout << "Optional: " << std::endl;
std::cout << "-b, --bvector <RHS vector file name>" << std::endl;
std::cout << "-d, --database <Solver parameters file name>" << std::endl;
std::cout << "-t, --type <Solver type name>" << std::endl;
std::cout << " Available solvers:" << std::endl;
Solver::Initialize(NULL, NULL, NULL);
std::vector<std::string> availableSolvers = Solver::getAvailableSolvers();
for (auto it = availableSolvers.begin(); it != availableSolvers.end(); it++) {
std::cout << " " << *it << std::endl;
}
Solver::Finalize();
}
return 0;
}
//Matrix file name found with -m or --matrix options
if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--matrix") == 0) {
matrixFound = true;
matrixFileName = std::string(argv[i + 1]);
FILE *matrixFile = fopen(matrixFileName.c_str(), "r");
if (matrixFile == NULL) {
if (rank == 0) {
std::cout << "Matrix file not found: " << argv[i + 1] << std::endl;
exit(1);
}
} else {
if (rank == 0) {
std::cout << "Matrix file found: " << argv[i + 1] << std::endl;
}
}
fclose(matrixFile);
i++;
continue;
}
//B vector file name found with -b or --bvector options
if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "--bvector") == 0) {
if (rank == 0) {
std::cout << "B vector file found: " << argv[i + 1] << std::endl;
}
vectorBFound = true;
vectorBFileName = std::string(argv[i + 1]);
i++;
continue;
}
//Parameters file name found with -d or --database options
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--database") == 0) {
if (rank == 0) {
std::cout << "Solver parameters file found: " << argv[i + 1] << std::endl;
}
parametersFound = true;
parametersFileName = std::string(argv[i + 1]);
i++;
continue;
}
//Solver type found with -t ot --type options
if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--type") == 0) {
if (rank == 0) {
std::cout << "Solver type index found: " << argv[i + 1] << std::endl;
}
typeFound = true;
solverName = std::string(argv[i + 1]);
i++;
continue;
}
}
if (!matrixFound) {
if (rank == 0) {
std::cout <<
"Matrix not found, you can specify matrix file name using -m or --matrix options, otherwise specify -h option to see all options, exiting...";
}
return -1;
}
if (!typeFound) {
if (rank == 0) {
std::cout <<
"Solver type not found in command line, you can specify solver type with -t or --type option, using INNER_ILU2 solver by default."
<<
std::endl;
}
}
if (!vectorBFound) {
if (rank == 0) {
std::cout <<
"B vector not found, you can specify b vector file name with -b or --bvector option, using identity vector by default."
<<
std::endl;
}
}
// Initialize the linear solver in accordance with args
Solver::Initialize(&argc, &argv, parametersFound ? parametersFileName.c_str() : NULL);
if (!Solver::isSolverAvailable(solverName)) {
if (rank == 0) std::cout << "Solver " << solverName << " is not available" << std::endl;
Solver::Finalize();
exit(1);
}
Solver solver = Solver(solverName, "test");
if (rank == 0) std::cout << "Solving with " << solverName << std::endl;
Sparse::Matrix mat("A"); // Declare the matrix of the linear system to be solved
Sparse::Vector b("rhs"); // Declare the right-hand side vector
Sparse::Vector x("sol"); // Declare the solution vector
double timer = Timer();
mat.Load(matrixFileName); //ifinterval parameters not set, matrix will be divided automatically
if (rank == 0) std::cout << "Load matrix time: " << Timer() - timer << std::endl;
timer = Timer();
if (vectorBFound) {
b.Load(vectorBFileName); //if interval parameters not set, matrix will be divided automatically
} else { // Set local RHS to 1 if it was not specified
INMOST_DATA_ENUM_TYPE mbeg, mend, k;
mat.GetInterval(mbeg, mend);
b.SetInterval(mbeg, mend);
for (k = mbeg; k < mend; ++k) b[k] = 1.0;
}
if (rank == 0) std::cout << "Load vector time: " << Timer() - timer << std::endl;
TTSP::OptimizationParameter tau("tau", { 1e-4, 3e-4, 5e-4, 7e-4,
1e-3, 3e-3, 5e-3, 7e-3,
1e-2, 3e-2, 5e-2, 7e-2,
1e-1, 3e-1, 5e-1, 7e-1 }, 1e-3);
TTSP::OptimizationParameters parameters;
parameters.push_back(std::make_pair(tau, 1e-3));
TTSP::OptimizationParametersSpace space(solverName, "test", parameters);
TTSP::BruteforceOptimizer optimizer(space);
// BARRIER;
// timer = Timer();
// solver.SetMatrix(mat); // Compute the preconditioner for the original matrix
// BARRIER;
//
// if (rank == 0) std::cout << "Preconditioner time: " << Timer() - timer << std::endl;
//
// BARRIER;
// timer = Timer();
// bool isSuccess = solver.Solve(b, x); // Solve the linear system with the previously computted preconditioner
// BARRIER;
optimizer.Solve(solver, mat, b, x);
std::cout << "Best optimization parameters found for current iteration:" << std::endl;
const TTSP::OptimizationParameterPoints &best = optimizer.GetParametersCurrentValues();
std::for_each(best.begin(), best.end(), [](const TTSP::OptimizationParameterPoint &p) {
std::cout << "\t" << p.first << " = " << p.second << std::endl;
});
if (rank == 0) {
std::cout << "Solved with " << solver.SolverName()
<< " on " << solver.Iterations()
<< " iterations and " << solver.Residual()
<< " residual. Reason: " << solver.ReturnReason()
<< std::endl;
}
}
Solver::Finalize(); // Finalize solver and close MPI activity
return 0;
}
......@@ -15,6 +15,7 @@
#cmakedefine USE_PARTITIONER_PARMETIS
#cmakedefine USE_SOLVER
#cmakedefine USE_SOLVER_TTSP_FEATURE
#cmakedefine USE_SOLVER_MONDRIAAN
#cmakedefine USE_SOLVER_METIS
#cmakedefine USE_SOLVER_PETSC
......
......@@ -32,6 +32,10 @@ endif()
if (USE_SOLVER_SUPERLU)
add_subdirectory(solver_superlu)
endif()
if (USE_SOLVER_TTSP_FEATURE)
add_subdirectory(ttsp)
endif()
endif(USE_SOLVER)
set(HEADER ${HEADER} PARENT_SCOPE)
......
set(SOURCE ${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/optimization_parameters.cpp)
set(HEADER ${HEADER}
${CMAKE_CURRENT_SOURCE_DIR}/optimizer_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/optimization_parameters.h)
add_subdirectory(optimizers)
set(HEADER ${HEADER} PARENT_SCOPE)
set(SOURCE ${SOURCE} PARENT_SCOPE)
\ No newline at end of file
//
// Created by bvdmitri on 31.01.19.
//
#include "optimization_parameters.h"
#include <algorithm>
namespace TTSP {
void OptimizationParameter::swap(OptimizationParameter &left, OptimizationParameter &right) {
std::swap(left.name, right.name);
std::swap(left.values, right.values);
std::swap(left.default_value, right.default_value);
}
OptimizationParameter::OptimizationParameter(const std::string &name,
const OptimizationParameterRange &range,
double step, double default_value) :
name(name),
values(static_cast<unsigned long>((range.second - range.first) / step)),
default_value(default_value) {
int index = 0;
double value = range.first;
while (value < range.second) {
values[index++] = value;
value += step;
}
}
OptimizationParameter::OptimizationParameter(const std::string &name, const std::vector<double> &values,
double default_value) :
name(name), values(values), default_value(default_value) {}
OptimizationParameter::OptimizationParameter(const OptimizationParameter &other) :
name(other.name), values(other.values), default_value(other.default_value) {}
OptimizationParameter::OptimizationParameter(OptimizationParameter &&other) noexcept {
OptimizationParameter::swap(*this, other);
}
OptimizationParameter &TTSP::OptimizationParameter::operator=(const OptimizationParameter &other) {
OptimizationParameter tmp(other);
OptimizationParameter::swap(*this, tmp);
return *this;
}
const std::string &OptimizationParameter::GetName() const {
return name;
}
const std::vector<double> &OptimizationParameter::GetValues() const {
return values;
}
const double &OptimizationParameter::GetDefaultValue() const {
return default_value;
}
void OptimizationParametersSpace::swap(OptimizationParametersSpace &left, OptimizationParametersSpace &right) {
std::swap(left.solver_name, right.solver_name);
std::swap(left.solver_prefix, right.solver_prefix);
std::swap(left.parameters, right.parameters);
}
OptimizationParametersSpace::OptimizationParametersSpace(const std::string &solver_name,
const std::string &solver_prefix,
const OptimizationParameters &parameters) :
solver_name(solver_name), solver_prefix(solver_prefix), parameters(parameters) {}
OptimizationParametersSpace::OptimizationParametersSpace(const OptimizationParametersSpace &other) :
solver_name(other.solver_name), solver_prefix(other.solver_prefix), parameters(other.parameters) {}
OptimizationParametersSpace::OptimizationParametersSpace(OptimizationParametersSpace &&other) noexcept {
OptimizationParametersSpace::swap(*this, other);
}
OptimizationParametersSpace &OptimizationParametersSpace::operator=(const OptimizationParametersSpace &other) {
OptimizationParametersSpace tmp(other);
OptimizationParametersSpace::swap(*this, tmp);
return *this;
}
bool OptimizationParametersSpace::isSolverNameMatch(const std::string &solver_name) const {
return this->solver_name == solver_name;
}
bool OptimizationParametersSpace::isSolverPrefixMatch(const std::string &solver_prefix) const {
return this->solver_prefix == solver_prefix;
}
const std::string &OptimizationParametersSpace::GetSolverName() const {
return solver_name;
}
const std::string &OptimizationParametersSpace::GetSolverPrefix() const {
return solver_prefix;
}
const OptimizationParameters &OptimizationParametersSpace::GetParameters() const {
return parameters;
}
const OptimizationParameterPoints OptimizationParametersSpace::GetPoints() const {
OptimizationParameterPoints points(parameters.size());
std::transform(parameters.begin(), parameters.end(), points.begin(), [](const OptimizationParametersEntry &p) {
return std::make_pair(p.first.GetName(), p.second);
});
return points;
}
void OptimizationParametersSpace::Update(const OptimizationParameterPoints &update) {
for (int i = 0; i < update.size(); ++i) {
parameters[i].second = update[i].second;
}
}
}
//
// Created by bvdmitri on 31.01.19.
//
#ifndef INMOST_OPTIMIZATION_PARAMETERS_H
#define INMOST_OPTIMIZATION_PARAMETERS_H
#include <string>
#include <vector>
namespace TTSP {
typedef std::pair<double, double> OptimizationParameterRange;
typedef std::pair<std::string, double> OptimizationParameterPoint;
typedef std::vector<OptimizationParameterPoint> OptimizationParameterPoints;
class OptimizationParameter {
private:
std::string name;
std::vector<double> values;
double default_value;
static void swap(OptimizationParameter &left, OptimizationParameter &right);
public:
OptimizationParameter(const std::string &name, const OptimizationParameterRange &range,
double step, double default_value);
OptimizationParameter(const std::string &name, const std::vector<double> &values, double default_value);
OptimizationParameter(const OptimizationParameter &other);
OptimizationParameter(OptimizationParameter &&other) noexcept;
OptimizationParameter &operator=(const OptimizationParameter &other);
const std::string &GetName() const;
const std::vector<double> &GetValues() const;
const double &GetDefaultValue() const;
};
typedef std::pair<OptimizationParameter, double> OptimizationParametersEntry;
typedef std::vector<OptimizationParametersEntry> OptimizationParameters;
class OptimizationParametersSpace {
private:
std::string solver_name;
std::string solver_prefix;
OptimizationParameters parameters;
static void swap(OptimizationParametersSpace &left, OptimizationParametersSpace &right);
public:
OptimizationParametersSpace(const std::string &solver_name, const std::string &solver_prefix,
const OptimizationParameters &parameters);
OptimizationParametersSpace(const OptimizationParametersSpace &other);
OptimizationParametersSpace(OptimizationParametersSpace &&other) noexcept;
OptimizationParametersSpace &operator=(const OptimizationParametersSpace &other);
bool isSolverNameMatch(const std::string &solver_name) const;
bool isSolverPrefixMatch(const std::string &solver_prefix) const;