Skip to content

Commit

Permalink
Merge Add an option for warmup solver iterations config
Browse files Browse the repository at this point in the history
Run solver warmup for fewer iterations

Related PR: #1033
  • Loading branch information
tcojean authored May 16, 2022
2 parents e3676bc + 6ede97c commit 198957c
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 52 deletions.
50 changes: 31 additions & 19 deletions benchmark/run_all_benchmarks.sh
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
#!/usr/bin/env bash
################################################################################
# Environment variable detection
#

print_default() {
local var=$1
echo "$var environment variable not set - assuming \"${!var}\"" 1>&2
}

if [ ! "${BENCHMARK}" ]; then
BENCHMARK="spmv"
echo "BENCHMARK environment variable not set - assuming \"${BENCHMARK}\"" 1>&2
print_default BENCHMARK
fi

if [ ! "${DRY_RUN}" ]; then
DRY_RUN="false"
echo "DRY_RUN environment variable not set - assuming \"${DRY_RUN}\"" 1>&2
print_default DRY_RUN
fi

if [ ! "${EXECUTOR}" ]; then
EXECUTOR="cuda"
echo "EXECUTOR environment variable not set - assuming \"${EXECUTOR}\"" 1>&2
print_default EXECUTOR
fi

if [ ! "${REPETITIONS}" ]; then
REPETITIONS=10
echo "REPETITIONS environment variable not set - assuming ${REPETITIONS}" 1>&2
print_default REPETITIONS
fi

if [ ! "${SOLVER_REPETITIONS}" ]; then
SOLVER_REPETITIONS=1
echo "SOLVER_REPETITIONS environment variable not set - assuming ${SOLVER_REPETITIONS}" 1>&2
print_default SOLVER_REPETITIONS
fi

if [ ! "${SEGMENTS}" ]; then
echo "SEGMENTS environment variable not set - running entire suite" 1>&2
echo "SEGMENTS environment variable not set - running entire suite" 1>&2
SEGMENTS=1
SEGMENT_ID=1
elif [ ! "${SEGMENT_ID}" ]; then
Expand All @@ -37,57 +44,62 @@ fi

if [ ! "${PRECONDS}" ]; then
PRECONDS="none"
echo "PRECONDS environment variable not set - assuming \"${PRECONDS}\"" 1>&2
print_default PRECONDS
fi

if [ ! "${FORMATS}" ]; then
echo "FORMATS environment variable not set - assuming \"csr,coo,ell,hybrid,sellp\"" 1>&2
FORMATS="csr,coo,ell,hybrid,sellp"
print_default FORMATS
fi

if [ ! "${ELL_IMBALANCE_LIMIT}" ]; then
echo "ELL_IMBALANCE_LIMIT environment variable not set - assuming 100" 1>&2
ELL_IMBALANCE_LIMIT=100
print_default ELL_IMBALANCE_LIMIT
fi

if [ ! "${SOLVERS}" ]; then
SOLVERS="bicgstab,cg,cgs,fcg,gmres,cb_gmres_reduce1,idr"
echo "SOLVERS environment variable not set - assuming \"${SOLVERS}\"" 1>&2
print_default SOLVERS
fi

if [ ! "${SOLVERS_PRECISION}" ]; then
SOLVERS_PRECISION=1e-6
echo "SOLVERS_PRECISION environment variable not set - assuming \"${SOLVERS_PRECISION}\"" 1>&2
print_default SOLVERS_PRECISION
fi

if [ ! "${SOLVERS_MAX_ITERATIONS}" ]; then
SOLVERS_MAX_ITERATIONS=10000
echo "SOLVERS_MAX_ITERATIONS environment variable not set - assuming \"${SOLVERS_MAX_ITERATIONS}\"" 1>&2
print_default SOLVERS_MAX_ITERATIONS
fi

if [ ! "${SOLVERS_WARMUP_MAX_ITERATIONS}" ]; then
SOLVERS_WARMUP_MAX_ITERATIONS=100
print_default SOLVERS_WARMUP_MAX_ITERATIONS
fi

if [ ! "${SOLVERS_GMRES_RESTART}" ]; then
SOLVERS_GMRES_RESTART=100
echo "SOLVERS_GMRES_RESTART environment variable not set - assuming \"${SOLVERS_GMRES_RESTART}\"" 1>&2
print_default SOLVERS_GMRES_RESTART
fi

if [ ! "${SYSTEM_NAME}" ]; then
SYSTEM_NAME="unknown"
echo "SYSTEM_MANE environment variable not set - assuming \"${SYSTEM_NAME}\"" 1>&2
print_default SYSTEM_NAME
fi

if [ ! "${DEVICE_ID}" ]; then
DEVICE_ID="0"
echo "DEVICE_ID environment variable not set - assuming \"${DEVICE_ID}\"" 1>&2
print_default DEVICE_ID
fi

if [ ! "${SOLVERS_JACOBI_MAX_BS}" ]; then
SOLVERS_JACOBI_MAX_BS="32"
echo "SOLVERS_JACOBI_MAX_BS environment variable not set - assuming \"${SOLVERS_JACOBI_MAX_BS}\"" 1>&2
print_default SOLVERS_JACOBI_MAX_BS
fi

if [ ! "${BENCHMARK_PRECISION}" ]; then
BENCHMARK_PRECISION="double"
echo "BENCHMARK_PRECISION not set - assuming \"${BENCHMARK_PRECISION}\"" 1>&2
print_default BENCHMARK_PRECISION
fi

if [ "${BENCHMARK_PRECISION}" == "double" ]; then
Expand Down Expand Up @@ -123,7 +135,7 @@ fi

if [ ! "${SOLVERS_INITIAL_GUESS}" ]; then
SOLVERS_INITIAL_GUESS="rhs"
echo "SOLVERS_RHS environment variable not set - assuming \"${SOLVERS_INITIAL_GUESS}\"" 1>&2
print_default SOLVERS_INITIAL_GUESS
fi

if [ "${SOLVERS_INITIAL_GUESS}" == "random" ]; then
Expand All @@ -140,7 +152,7 @@ fi

if [ ! "${GPU_TIMER}" ]; then
GPU_TIMER="false"
echo "GPU_TIMER environment variable not set - assuming \"${GPU_TIMER}\"" 1>&2
print_default GPU_TIMER
fi

# Control whether to run detailed benchmarks or not.
Expand Down
76 changes: 43 additions & 33 deletions benchmark/solver/solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
DEFINE_uint32(max_iters, 1000,
"Maximal number of iterations the solver will be run for");

DEFINE_uint32(warmup_max_iters, 100,
"Maximal number of warmup iterations the solver will be run for");

DEFINE_double(rel_res_goal, 1e-6, "The relative residual goal of the solver");

DEFINE_bool(
Expand Down Expand Up @@ -196,7 +199,7 @@ void validate_option_object(const rapidjson::Value& value)


std::shared_ptr<const gko::stop::CriterionFactory> create_criterion(
std::shared_ptr<const gko::Executor> exec)
std::shared_ptr<const gko::Executor> exec, std::uint32_t max_iters)
{
std::shared_ptr<const gko::stop::CriterionFactory> residual_stop;
if (FLAGS_rel_residual) {
Expand All @@ -212,7 +215,7 @@ std::shared_ptr<const gko::stop::CriterionFactory> create_criterion(
.on(exec));
}
auto iteration_stop = gko::share(
gko::stop::Iteration::build().with_max_iters(FLAGS_max_iters).on(exec));
gko::stop::Iteration::build().with_max_iters(max_iters).on(exec));
std::vector<std::shared_ptr<const gko::stop::CriterionFactory>>
criterion_vector{residual_stop, iteration_stop};
return gko::stop::combine(criterion_vector);
Expand All @@ -222,9 +225,9 @@ std::shared_ptr<const gko::stop::CriterionFactory> create_criterion(
template <typename SolverIntermediate>
std::unique_ptr<gko::LinOpFactory> add_criteria_precond_finalize(
SolverIntermediate inter, const std::shared_ptr<const gko::Executor>& exec,
std::shared_ptr<const gko::LinOpFactory> precond)
std::shared_ptr<const gko::LinOpFactory> precond, std::uint32_t max_iters)
{
return inter.with_criteria(create_criterion(exec))
return inter.with_criteria(create_criterion(exec, max_iters))
.with_preconditioner(give(precond))
.on(exec);
}
Expand All @@ -233,16 +236,17 @@ std::unique_ptr<gko::LinOpFactory> add_criteria_precond_finalize(
template <typename Solver>
std::unique_ptr<gko::LinOpFactory> add_criteria_precond_finalize(
const std::shared_ptr<const gko::Executor>& exec,
std::shared_ptr<const gko::LinOpFactory> precond)
std::shared_ptr<const gko::LinOpFactory> precond, std::uint32_t max_iters)
{
return add_criteria_precond_finalize(Solver::build(), exec, precond);
return add_criteria_precond_finalize(Solver::build(), exec, precond,
max_iters);
}


std::unique_ptr<gko::LinOpFactory> generate_solver(
const std::shared_ptr<const gko::Executor>& exec,
std::shared_ptr<const gko::LinOpFactory> precond,
const std::string& description)
const std::string& description, std::uint32_t max_iters)
{
std::string cb_gmres_prefix("cb_gmres_");
if (description.find(cb_gmres_prefix) == 0) {
Expand Down Expand Up @@ -270,33 +274,33 @@ std::unique_ptr<gko::LinOpFactory> generate_solver(
gko::solver::CbGmres<etype>::build()
.with_krylov_dim(FLAGS_gmres_restart)
.with_storage_precision(s_prec),
exec, precond);
exec, precond, max_iters);
} else if (description == "bicgstab") {
return add_criteria_precond_finalize<gko::solver::Bicgstab<etype>>(
exec, precond);
exec, precond, max_iters);
} else if (description == "bicg") {
return add_criteria_precond_finalize<gko::solver::Bicg<etype>>(exec,
precond);
return add_criteria_precond_finalize<gko::solver::Bicg<etype>>(
exec, precond, max_iters);
} else if (description == "cg") {
return add_criteria_precond_finalize<gko::solver::Cg<etype>>(exec,
precond);
return add_criteria_precond_finalize<gko::solver::Cg<etype>>(
exec, precond, max_iters);
} else if (description == "cgs") {
return add_criteria_precond_finalize<gko::solver::Cgs<etype>>(exec,
precond);
return add_criteria_precond_finalize<gko::solver::Cgs<etype>>(
exec, precond, max_iters);
} else if (description == "fcg") {
return add_criteria_precond_finalize<gko::solver::Fcg<etype>>(exec,
precond);
return add_criteria_precond_finalize<gko::solver::Fcg<etype>>(
exec, precond, max_iters);
} else if (description == "idr") {
return add_criteria_precond_finalize(
gko::solver::Idr<etype>::build()
.with_subspace_dim(FLAGS_idr_subspace_dim)
.with_kappa(static_cast<rc_etype>(FLAGS_idr_kappa)),
exec, precond);
exec, precond, max_iters);
} else if (description == "gmres") {
return add_criteria_precond_finalize(
gko::solver::Gmres<etype>::build().with_krylov_dim(
FLAGS_gmres_restart),
exec, precond);
exec, precond, max_iters);
} else if (description == "lower_trs") {
return gko::solver::LowerTrs<etype>::build()
.with_num_rhs(FLAGS_nrhs)
Expand All @@ -306,8 +310,8 @@ std::unique_ptr<gko::LinOpFactory> generate_solver(
.with_num_rhs(FLAGS_nrhs)
.on(exec);
} else if (description == "overhead") {
return add_criteria_precond_finalize<gko::Overhead<etype>>(exec,
precond);
return add_criteria_precond_finalize<gko::Overhead<etype>>(
exec, precond, max_iters);
}
throw std::range_error(std::string("The provided string <") + description +
"> does not match any solver!");
Expand Down Expand Up @@ -402,19 +406,15 @@ void solve_system(const std::string& solver_name,
IterationControl ic{get_timer(exec, FLAGS_gpu_timer)};

// warm run
auto it_logger = std::make_shared<IterationLogger>(exec);
std::shared_ptr<gko::LinOp> solver;
for (auto _ : ic.warmup_run()) {
auto x_clone = clone(x);
auto precond = precond_factory.at(precond_name)(exec);
auto solver = generate_solver(exec, give(precond), solver_name)
->generate(system_matrix);
solver->add_logger(it_logger);
solver = generate_solver(exec, give(precond), solver_name,
FLAGS_warmup_max_iters)
->generate(system_matrix);
solver->apply(lend(b), lend(x_clone));
exec->synchronize();
solver->remove_logger(gko::lend(it_logger));
}
if (FLAGS_warmup > 0) {
it_logger->write_data(solver_json["apply"], allocator);
}

// detail run
Expand All @@ -427,8 +427,9 @@ void solve_system(const std::string& solver_name,
exec->add_logger(gen_logger);

auto precond = precond_factory.at(precond_name)(exec);
auto solver = generate_solver(exec, give(precond), solver_name)
->generate(system_matrix);
solver = generate_solver(exec, give(precond), solver_name,
FLAGS_max_iters)
->generate(system_matrix);

exec->remove_logger(gko::lend(gen_logger));
gen_logger->write_data(solver_json["generate"]["components"],
Expand Down Expand Up @@ -473,25 +474,34 @@ void solve_system(const std::string& solver_name,
}

// timed run
auto it_logger = std::make_shared<IterationLogger>(exec);
auto generate_timer = get_timer(exec, FLAGS_gpu_timer);
auto apply_timer = ic.get_timer();
auto x_clone = clone(x);
std::shared_ptr<const gko::LinOp> solver;
for (auto status : ic.run(false)) {
x_clone = clone(x);

exec->synchronize();
generate_timer->tic();
auto precond = precond_factory.at(precond_name)(exec);
solver = generate_solver(exec, give(precond), solver_name)
solver = generate_solver(exec, give(precond), solver_name,
FLAGS_max_iters)
->generate(system_matrix);
generate_timer->toc();

exec->synchronize();
if (ic.get_num_repetitions() == 0) {
solver->add_logger(it_logger);
}
apply_timer->tic();
solver->apply(lend(b), lend(x_clone));
apply_timer->toc();
if (ic.get_num_repetitions() == 0) {
solver->remove_logger(gko::lend(it_logger));
}
}
it_logger->write_data(solver_json["apply"], allocator);

if (b->get_size()[1] == 1 && !FLAGS_overhead) {
// a solver is considered direct if it didn't log any iterations
if (solver_json["apply"].HasMember("iterations") &&
Expand Down

0 comments on commit 198957c

Please sign in to comment.