Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preliminary command-line options parser #140

Merged
merged 7 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion resolve/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ set(ReSolve_Targets_List
resolve_workspace
)

set(ReSolve_Object_List
resolve_options
resolve_version
)

# If CUDA support is enabled add CUDA SDK specific code and dependencies
if(RESOLVE_USE_CUDA)
add_subdirectory(cuda)
Expand Down Expand Up @@ -127,7 +132,7 @@ target_include_directories(ReSolve INTERFACE
)

target_link_libraries(ReSolve PUBLIC ${ReSolve_Targets_List})
target_link_libraries(ReSolve PRIVATE resolve_version)
target_link_libraries(ReSolve PRIVATE ${ReSolve_Object_List})

if(RESOLVE_USE_PROFILING)
if(RESOLVE_USE_HIP)
Expand Down
15 changes: 15 additions & 0 deletions resolve/LinSolverIterativeRandFGMRES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,21 @@ namespace ReSolve
return 0;
}

int LinSolverIterativeRandFGMRES::setSketchingMethod(std::string method)
{
if (method == "count") {
pelesh marked this conversation as resolved.
Show resolved Hide resolved
rand_method_ = LinSolverIterativeRandFGMRES::cs;
} else if (method == "fwht") {
rand_method_ = LinSolverIterativeRandFGMRES::fwht;
} else {
out::warning() << "Sketching method " << method << " not recognized!\n"
<< "Using default.\n";
rand_method_ = LinSolverIterativeRandFGMRES::cs;
return 1;
}
return 0;
}

//
// Private methods
//
Expand Down
2 changes: 1 addition & 1 deletion resolve/LinSolverIterativeRandFGMRES.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace ReSolve
int setupPreconditioner(std::string name, LinSolverDirect* LU_solver) override;

index_type getKrand();

int setSketchingMethod(std::string method);
private:
void setMemorySpace();
void precV(vector_type* rhs, vector_type* x); ///< Apply preconditioner
Expand Down
70 changes: 55 additions & 15 deletions resolve/SystemSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <resolve/vector/Vector.hpp>
#include <resolve/LinSolverIterativeFGMRES.hpp>
#include <resolve/LinSolverDirectSerialILU0.hpp>
#include <resolve/LinSolverDirectCpuILU0.hpp>
#include <resolve/GramSchmidt.hpp>
#include <resolve/workspace/LinAlgWorkspaceCpu.hpp>

Expand Down Expand Up @@ -178,6 +179,12 @@ namespace ReSolve
auto* rgmres = dynamic_cast<LinSolverIterativeRandFGMRES*>(iterativeSolver_);
status += rgmres->setup(A_);
status += gs_->setup(rgmres->getKrand(), rgmres->getRestart());
} else if (solveMethod_ == "fgmres") {
auto* fgmres = dynamic_cast<LinSolverIterativeFGMRES*>(iterativeSolver_);
status += fgmres->setup(A_);
status += gs_->setup(A_->getNumRows(), fgmres->getRestart());
} else {
// do nothing
}

return status;
Expand Down Expand Up @@ -261,7 +268,8 @@ namespace ReSolve
#elif defined(RESOLVE_USE_HIP)
preconditioner_ = new LinSolverDirectRocSparseILU0(workspaceHip_);
#else
preconditioner_ = new LinSolverDirectSerialILU0(workspaceCpu_);
// preconditioner_ = new LinSolverDirectSerialILU0(workspaceCpu_);
cameronrutherford marked this conversation as resolved.
Show resolved Hide resolved
preconditioner_ = new LinSolverDirectCpuILU0(workspaceCpu_);
#endif
} else {
out::error() << "Preconditioner method " << precondition_method_
Expand All @@ -281,12 +289,18 @@ namespace ReSolve
<< "Using default.\n";
sketch = LinSolverIterativeRandFGMRES::cs;
}

setGramSchmidtMethod(gsMethod_);
iterativeSolver_ = new LinSolverIterativeRandFGMRES(matrixHandler_,
vectorHandler_,
sketch,
gs_);
} else if (solveMethod_ == "fgmres") {
pelesh marked this conversation as resolved.
Show resolved Hide resolved
setGramSchmidtMethod(gsMethod_);
iterativeSolver_ = new LinSolverIterativeFGMRES(matrixHandler_,
vectorHandler_,
gs_);
} else {
// do nothing
}

return 0;
Expand Down Expand Up @@ -419,7 +433,7 @@ namespace ReSolve
int status = 0;

// Use Krylov solver if selected
if (solveMethod_ == "randgmres") {
if (solveMethod_ == "randgmres" || solveMethod_ == "fgmres") {
pelesh marked this conversation as resolved.
Show resolved Hide resolved
status += iterativeSolver_->resetMatrix(A_);
status += iterativeSolver_->solve(rhs, x);
return status;
Expand Down Expand Up @@ -532,15 +546,16 @@ namespace ReSolve
* @param[in] method - ID of the solve method
*
*/
void SystemSolver::setSolveMethod(std::string method)
int SystemSolver::setSolveMethod(std::string method)
{
solveMethod_ = method;

// Remove existing iterative solver and set IR to "none".
irMethod_ = "none";
if (iterativeSolver_)
delete iterativeSolver_;

if (method == "randgmres") {
irMethod_ = "none";
if (iterativeSolver_)
delete iterativeSolver_;

LinSolverIterativeRandFGMRES::SketchingMethod sketch;
if (sketching_method_ == "count") {
sketch = LinSolverIterativeRandFGMRES::cs;
Expand All @@ -557,8 +572,17 @@ namespace ReSolve
vectorHandler_,
sketch,
gs_);
} else if (solveMethod_ == "fgmres") {
setGramSchmidtMethod(gsMethod_);
iterativeSolver_ = new LinSolverIterativeFGMRES(matrixHandler_,
vectorHandler_,
gs_);
} else {
out::error() << "Solve method " << solveMethod_
<< " not recognized ...\n";
return 1;
}

return 0;
}

/**
Expand Down Expand Up @@ -690,15 +714,32 @@ namespace ReSolve
}

/**
* @brief Selekt sketching method for randomized solvers
* @brief Select sketching method for randomized solvers
*
* This is a brute force method that will delete randomized GMRES solver
* only to change its sketching function.
*
* This needs to be moved to LinSolverIterative class and accessed from there.
* @todo This needs to be moved to LinSolverIterative class and accessed from there.
cameronrutherford marked this conversation as resolved.
Show resolved Hide resolved
*
* @param sketching_method
* @param[in] sketching_method - string ID of the sketching method
*/
void SystemSolver::setSketchingMethod(std::string sketching_method)
int SystemSolver::setSketchingMethod(std::string sketching_method)
{
sketching_method_ = sketching_method;
if (solveMethod_ != "randgmres") {
cameronrutherford marked this conversation as resolved.
Show resolved Hide resolved
out::warning() << "Trying to set sketching method to an incompatible solver.\n";
out::warning() << "The setting will be ignored.\n";
return 1;
}
if (sketching_method_ != sketching_method) {
// For now use a brute force solution and just delete existing iterative solver
if (iterativeSolver_) {
delete iterativeSolver_;
iterativeSolver_ = nullptr;
}
sketching_method_ = sketching_method;
setSolveMethod("randgmres");
}
return 0;
}

//
Expand Down Expand Up @@ -734,5 +775,4 @@ namespace ReSolve
return 0;
}


} // namespace ReSolve
7 changes: 3 additions & 4 deletions resolve/SystemSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ namespace ReSolve
// Set solver parameters
void setFactorizationMethod(std::string method);
void setRefactorizationMethod(std::string method);
void setSolveMethod(std::string method);
int setSolveMethod(std::string method);
void setRefinementMethod(std::string method, std::string gs = "cgs2");

void setSketchingMethod(std::string sketching_method);
int setSketchingMethod(std::string method);
int setGramSchmidtMethod(std::string gs_method);

private:
int setGramSchmidtMethod(std::string gs_method);

LinSolverDirect* factorizationSolver_{nullptr};
LinSolverDirect* refactorizationSolver_{nullptr};
Expand Down
1 change: 1 addition & 0 deletions resolve/utilities/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
]]

add_subdirectory(logger)
add_subdirectory(params)
add_subdirectory(version)
27 changes: 27 additions & 0 deletions resolve/utilities/params/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#[[

@brief Build ReSolve function that returns version at runtime

@author Slaven Peles <[email protected]>

]]

set(Options_SRC
CliOptions.cpp
)

set(Options_HEADER_INSTALL
CliOptions.hpp
)

# Build shared library ReSolve
add_library(resolve_options OBJECT ${Options_SRC})
set_property(TARGET resolve_options PROPERTY POSITION_INDEPENDENT_CODE ON)

target_include_directories(resolve_options PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
$<INSTALL_INTERFACE:include>
)

install(FILES ${Options_HEADER_INSTALL} DESTINATION include/resolve/utilities/options)
cameronrutherford marked this conversation as resolved.
Show resolved Hide resolved
130 changes: 130 additions & 0 deletions resolve/utilities/params/CliOptions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <iostream>

#include "CliOptions.hpp"


namespace ReSolve
{

CliOptions::CliOptions(int argc, char* argv[])
: argc_(argc),
argv_(argv)
{
app_name_ = argv_[0];
parse();
}

CliOptions::~CliOptions()
{
}

std::string CliOptions::getAppName() const
{
return app_name_;
}

bool CliOptions::hasKey(const std::string& key) const
{
return options_.find(key) != options_.end();
}

CliOptions::Option* CliOptions::getParamFromKey(const std::string& key) const
{
const OptionsList::const_iterator i = options_.find(key);
CliOptions::Option* opt = 0;
if (i != options_.end()) {
opt = new CliOptions::Option((*i).first, (*i).second);
}
return opt;
}

void CliOptions::printOptionsList() const
{
OptionsList::const_iterator m = options_.begin();
int i = 0;
if (options_.empty()) {
std::cout << "No parameters\n";
}
for (; m != options_.end(); m++, ++i) {
std::cout << "Parameter [" << i << "] ["
<< (*m).first << " "
<< (*m).second << "]\n";
}
}

//
// Private methods
//

/**
* @brief Parse command line input and store it in a map
*
* @pre Pointer to command line options is copied to `argv_`
* @post Command line options are parsed and stored in map `options_`
*/
void CliOptions::parse()
{
Option* option = new std::pair<std::string, std::string>();
// Loop over argv entries skipping the first one (executable name)
for (const char* const* i = this->begin() + 1; i != this->end(); i++)
{
const std::string p = *i;
if (option->first == "" && p[0] == '-')
{
// Set option ID and continue
option->first = p;
if (i == this->last())
{
// If this is last entry, there is nothing else to do; set option.
options_.insert(Option(option->first, option->second));
}
continue;
}
else if (option->first != "" && p[0] == '-')
{
// Option ID has been set in prior cycle, string p is also option ID.
// Leave option value empty, since what follows is the next option ID.
option->second = "";
// Set option without parameter value
options_.insert(Option(option->first, option->second));
// Set parameter ID for the next option and continue
option->first = p;
option->second = "";
if (i == this->last())
{
// If this is last entry, there is nothing else to do; set option.
options_.insert(Option(option->first, option->second));
}
continue;
}
else if (option->first != "")
{
// String p does not start with '-', contains parameter value
option->second = p;
// Set option with parameter value
options_.insert(Option(option->first, option->second));
// Reset 'option' pair to receive the next entry and continue
option->first = "";
option->second = "";
continue;
}
}
}

const char* const *CliOptions::begin() const
{
return argv_;
}

const char* const *CliOptions::end() const
{
return argv_ + argc_;
}

const char* const *CliOptions::last() const
{
return argv_ + argc_ - 1;
}
cameronrutherford marked this conversation as resolved.
Show resolved Hide resolved


} // namespace ReSolve
Loading