Skip to content

Commit

Permalink
Merge pull request #1714 from amirbous/electrostatic_amir
Browse files Browse the repository at this point in the history
Electrostatic amir
  • Loading branch information
pratikvn authored Nov 5, 2024
2 parents 427dab3 + 409d8b9 commit 1aaa756
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 48 deletions.
6 changes: 5 additions & 1 deletion examples/electrostatic-abb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ endif()
add_executable(electrostatic-abb electrostatic-abb.cpp)
target_link_libraries(electrostatic-abb Ginkgo::ginkgo)

# Copy config file
configure_file(electro.config electro.config COPYONLY)

# Copy the data files to the execution directory
configure_file(data/sphere.asc data/sphere.asc COPYONLY)
configure_file(data/sphere.amtx data/sphere.amtx COPYONLY)
configure_file(data/sphere.bmtx data/sphere.bmtx COPYONLY)
File renamed without changes.
Binary file added examples/electrostatic-abb/data/sphere.bmtx
Binary file not shown.
6 changes: 6 additions & 0 deletions examples/electrostatic-abb/electro.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
executor reference
solver gmres
problem sphere
mode ascii
writeResult false
initialGuess rhs
124 changes: 77 additions & 47 deletions examples/electrostatic-abb/electrostatic-abb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,40 @@
#include <iostream>
#include <map>
#include <string>
#include <type_traits>

#include <ginkgo/ginkgo.hpp>

#include "ginkgo/core/base/matrix_data.hpp"
#include "utils.hpp"


template <typename ValueType, typename IndexType>
std::vector<gko::matrix_data<ValueType, IndexType>> read_input(
std::string fstring)
int main(int argc, char* argv[])
{
std::string fname = "data/" + fstring + ".asc";
std::ifstream fstream;
fstream.open(fname);
int num_rows = 0;
fstream >> num_rows;
std::vector<gko::matrix_data<ValueType, IndexType>> mat_data{
gko::matrix_data<ValueType, IndexType>(gko::dim<2>(num_rows)),
gko::matrix_data<ValueType, IndexType>(gko::dim<2>(num_rows, 1))};
for (auto row = 0; row < num_rows; row++) {
int temp = 0;
fstream >> temp;
for (auto col = 0; col < num_rows; col++) {
ValueType mat_val = 0.0;
fstream >> mat_val;
mat_data[0].nonzeros.emplace_back(row, col, mat_val);
}
ValueType rhs_val = 0.0;
fstream >> rhs_val;
mat_data[1].nonzeros.emplace_back(row, 0, rhs_val);
}
return mat_data;
}
std::string executor_string, solver_string, problem_string, mode_string,
writeResult_string, initialGuess_string;

std::map<std::string, std::string> config_strings;
config_strings = read_config();

executor_string = config_strings.count("executor") > 0
? config_strings["executor"]
: "reference";
solver_string =
config_strings.count("solver") > 0 ? config_strings["solver"] : "gmres";
problem_string = config_strings.count("problem") > 0
? config_strings["problem"]
: "sphere";
mode_string =
config_strings.count("mode") > 0 ? config_strings["mode"] : "binary";
writeResult_string = config_strings.count("writeResult") > 0
? config_strings["writeResult"]
: "true";
initialGuess_string = config_strings.count("initialGuess") > 0
? config_strings["initialGuess"]
: "rhs";


int main(int argc, char* argv[])
{
using ValueType = double;
using RealValueType = gko::remove_complex<ValueType>;
using IndexType = int;
Expand All @@ -52,19 +50,23 @@ int main(int argc, char* argv[])
using bicgstab = gko::solver::Bicgstab<ValueType>;
using gmres = gko::solver::Gmres<ValueType>;
using bj = gko::preconditioner::Jacobi<ValueType, IndexType>;
using ilu = gko::preconditioner::Ilu<>;
// using ilu = gko::preconditioner::Ilu<>; ==>Not used for now, (only works
// when ValueType is double)


std::vector<gko::matrix_data<ValueType, IndexType>> data;


std::cout << gko::version_info::get() << std::endl;


if (argc == 2 && (std::string(argv[1]) == "--help")) {
std::cerr << "Usage: " << argv[0] << " [executor] [mat_name] "
<< std::endl;
std::exit(-1);
}

const auto executor_string = argc >= 2 ? argv[1] : "reference";
std::string solver_string = argc >= 3 ? argv[2] : "gmres";
const auto fname_string = argc >= 4 ? argv[3] : "sphere";

std::map<std::string, std::function<std::shared_ptr<gko::Executor>()>>
exec_map{
{"omp", [] { return gko::OmpExecutor::create(); }},
Expand All @@ -84,21 +86,34 @@ int main(int argc, char* argv[])
}},
{"reference", [] { return gko::ReferenceExecutor::create(); }}};


const auto exec = exec_map.at(executor_string)(); // throws if not valid

auto data = read_input<ValueType, IndexType>(fname_string);
// reading data from input files
if (mode_string.compare("ascii") == 0) {
data = read_inputAscii<ValueType, IndexType>(problem_string);
} else {
data = read_inputBinary<ValueType, IndexType>(problem_string);
}

// initialising matrix
auto A = gko::share(mtx::create(exec));
A->read(data[0]);
std::cout << "Matrix size: " << A->get_size() << std::endl;

// initialising rhs
auto b = gko::share(mtx::create(exec));
b->read(data[1]);
auto x = gko::clone(b);
// std::ofstream fout("sphere.mtx");
// std::ofstream fout2("sphere_b.mtx");
// gko::write(fout, A);
// gko::write(fout2, b);

const RealValueType reduction_factor{1e-16};
// initialising initial guess
auto x = gko::share(mtx::create(exec, gko::dim<2>(A->get_size()[0], 1)));
if (initialGuess_string.compare("zero") == 0) {
x->fill(ValueType(0.0));
} else {
x = gko::clone(b);
}

const RealValueType reduction_factor{1e-6};
std::shared_ptr<const gko::log::Convergence<ValueType>> logger =
gko::log::Convergence<ValueType>::create();
auto gmres_gen =
Expand All @@ -107,16 +122,16 @@ int main(int argc, char* argv[])
gko::stop::ResidualNorm<ValueType>::build()
.with_reduction_factor(reduction_factor))
// .with_preconditioner(bj::build().with_max_block_size(1u))
.with_preconditioner(ilu::build())
.on(exec);
auto bicgstab_gen =
bicgstab::build()
.with_criteria(gko::stop::Iteration::build().with_max_iters(200u),
gko::stop::ResidualNorm<ValueType>::build()
.with_reduction_factor(reduction_factor))
// .with_preconditioner(bj::build().with_max_block_size(1u))
.with_preconditioner(ilu::build())
.on(exec);


std::shared_ptr<gko::LinOp> solver;
if (solver_string.compare("gmres") == 0) {
std::cout << "Using " << solver_string << std::endl;
Expand All @@ -130,15 +145,15 @@ int main(int argc, char* argv[])
}
solver->add_logger(logger);

double apply_time = 0.0;

auto x_clone = gko::clone(x);
// Warmup
for (int i = 0; i < 3; ++i) {
x_clone->copy_from(x.get());
solver->apply(b, x_clone);
}

double apply_time = 0.0;
// Warmpu
x_clone->copy_from(x.get());
solver->apply(b, x_clone);

// Solving
int num_reps = 3;
for (int i = 0; i < num_reps; ++i) {
x_clone->copy_from(x.get());
Expand All @@ -155,13 +170,28 @@ int main(int argc, char* argv[])
}
x->copy_from(x_clone.get());

// getting results
auto one = gko::initialize<vec>({1.0}, exec);
auto neg_one = gko::initialize<vec>({-1.0}, exec);
auto res = gko::initialize<real_vec>({0.0}, exec->get_master());
auto real_time = apply_time / num_reps;
A->apply(one, x, neg_one, b);
b->compute_norm2(res);

// writing resutlts
if (writeResult_string.compare("true") == 0) {
std::string solution_fileName =
problem_string + solver_string + "_sol.mtx";
std::ofstream outFile(solution_fileName);
gko::write(outFile, x);
}
std::cout << "Residual norm sqrt(r^T r): " << res->get_values()[0]
<< "\nIteration count: " << logger->get_num_iterations()
<< "\nApply time: " << apply_time / num_reps << std::endl;
<< "\nApply time: " << real_time << std::endl;

std::ofstream logFile;
logFile.open("log_ginkgo.txt", std::ios_base::app);
logFile << problem_string << " " << A->get_size()[0] << " " << real_time
<< "\n";
logFile.close();
}
38 changes: 38 additions & 0 deletions examples/electrostatic-abb/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Ginkgo for casopt generated matrices - Electrostatic field simulation

## Structure

- `electrostatic-abb.cpp`: to run ginkgo solver instance for a given matrix file

- `utils.hpp`: helper functions defined by user, handle input/output, display progres ...

- `/data`: sub directory for example matrix file

## Usage

### Building and running
After building, the executable `electrostatic-abb` should be generated in the corresponding build folder

the working directory should include a config file, config file name set to `electro.config` can be changed in the code - check config file format for further description of the config file.

- config file format: multiple lines with format `'option' 'value'`

available options can set from the config file, not all options should be included, but then the default value will be used

*possible options*
```
<executor> <executor module (default reference)>
<solver> <algebraic solver (default gmres)>
<problem name> <name of existing .bmtx/.amtx file in data/ folderm >
<input mode> <binary/ascii depending on type of method used>
<writeResult> <true/false, write output file>
<initialGuess> <zero/rhs initial vector guess used>
```

### Chanding ValueType

In this example, the valueType is defined as runtime. To switch between double and float, that should be done in the source, and then recompiling/rebuilding the electrostatic module.




Loading

0 comments on commit 1aaa756

Please sign in to comment.