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

Improve solver and preconditioner benchmarks #660

Merged
merged 7 commits into from
Nov 10, 2020
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
6 changes: 4 additions & 2 deletions BENCHMARKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ The supported environment variables are described in the following list:
benchmark runs (downloads the collections, creates the result structure,
etc.) and outputs the list of commands that would normally be run, but does
not run the benchmarks themselves. Default is `false`.
* `PRECONDS={jacobi,adaptive-jacobi,ilu,parict,parilu,parilut,none}` the
preconditioners to use for either `solver` or `preconditioner` benchmarks.
* `PRECONDS={jacobi,ilu,parict,parilu,parilut,ilu-isai,parict-isai,parilu-isai,parilut-isai,none}`
the preconditioners to use for either `solver` or `preconditioner` benchmarks.
Multiple options can be passed to this variable. Default is `none`.
* `FORMATS={csr,coo,ell,hybrid,sellp,hybridxx,cusp_xx,hipsp_xx}` the matrix
formats to benchmark for the `spmv` phase of the benchmark. Run
Expand All @@ -299,5 +299,7 @@ The supported environment variables are described in the following list:
the solver should stop. The default is `1e-6`.
* `SOLVERS_MAX_ITERATION=<number>` - the maximum number of iterations with which
a solver should be ran. The default is `10000`.
* `SOLVERS_RHS={unit, random}` - whether to use a vector of all ones or random
values as the right-hand side in solver benchmarks. Default is `unit`.
* `DETAILED={0,1}` - selects whether detailed benchmarks should be ran for the
solver benchmarks, can be either `0` (off) or `1` (on). The default is `0`.
144 changes: 37 additions & 107 deletions benchmark/preconditioner/preconditioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,112 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "benchmark/utils/formats.hpp"
#include "benchmark/utils/general.hpp"
#include "benchmark/utils/loggers.hpp"
#include "benchmark/utils/preconditioners.hpp"
#include "benchmark/utils/spmv_common.hpp"


// Command-line arguments
DEFINE_uint32(max_block_size, 32,
"Maximal block size of the block-Jacobi preconditioner");

DEFINE_uint32(num_iterations, 5,
"Number of iterations for the ParICT/ParILU(T) preconditioner");

DEFINE_bool(
approx_select, true,
"Use approximate selection for the threshold filtering in ParICT/ParILUT");

DEFINE_double(fill_limit, 2.0, "The fill-in limit used in ParICT/ParILUT");

DEFINE_string(preconditioners, "jacobi,parilu,parilut,ilu",
"A comma-separated list of preconditioners to run."
"Supported values are: jacobi, parict, parilu, parilut, ilu");

DEFINE_string(storage_optimization, "0,0",
"Defines the kind of storage optimization to perform on "
"preconditioners that support it. Supported values are: "
"autodetect and <X>,<Y> where <X> and <Y> are the input "
"parameters used to construct a precision_reduction object.");

DEFINE_double(accuracy, 1e-1,
"This value is used as the accuracy flag of the adaptive Jacobi "
"preconditioner.");


// some shortcuts
using etype = double;


// parses the storage optimization command line argument
gko::precision_reduction parse_storage_optimization(const std::string &flag)
{
if (flag == "autodetect") {
return gko::precision_reduction::autodetect();
}
const auto parts = split(flag, ',');
if (parts.size() != 2) {
throw std::runtime_error(
"storage_optimization has to be a list of two integers");
}
return gko::precision_reduction(std::stoi(parts[0]), std::stoi(parts[1]));
}


// preconditioner mapping
const std::map<std::string, std::function<std::unique_ptr<gko::LinOpFactory>(
std::shared_ptr<const gko::Executor> exec)>>
precond_factory{
{"jacobi",
[](std::shared_ptr<const gko::Executor> exec) {
return gko::preconditioner::Jacobi<etype>::build()
.with_max_block_size(FLAGS_max_block_size)
.with_storage_optimization(
parse_storage_optimization(FLAGS_storage_optimization))
.with_accuracy(FLAGS_accuracy)
.on(exec);
}},
{"parict",
[](std::shared_ptr<const gko::Executor> exec) {
auto ict_fact = std::shared_ptr<gko::LinOpFactory>(
gko::factorization::ParIct<etype>::build()
.with_iterations(FLAGS_num_iterations)
.with_approximate_select(FLAGS_approx_select)
.with_fill_in_limit(FLAGS_fill_limit)
.on(exec));
return gko::preconditioner::Ilu<>::build()
.with_factorization_factory(ict_fact)
.on(exec);
}},
{"parilu",
[](std::shared_ptr<const gko::Executor> exec) {
auto ilu_fact = std::shared_ptr<gko::LinOpFactory>(
gko::factorization::ParIlu<etype>::build()
.with_iterations(FLAGS_num_iterations)
.on(exec));
return gko::preconditioner::Ilu<>::build()
.with_factorization_factory(ilu_fact)
.on(exec);
}},
{"parilut",
[](std::shared_ptr<const gko::Executor> exec) {
auto ilut_fact = std::shared_ptr<gko::LinOpFactory>(
gko::factorization::ParIlut<etype>::build()
.with_iterations(FLAGS_num_iterations)
.with_approximate_select(FLAGS_approx_select)
.with_fill_in_limit(FLAGS_fill_limit)
.on(exec));
return gko::preconditioner::Ilu<>::build()
.with_factorization_factory(ilut_fact)
.on(exec);
}},
{"ilu", [](std::shared_ptr<const gko::Executor> exec) {
auto ilu_fact = std::shared_ptr<gko::LinOpFactory>(
gko::factorization::Ilu<etype>::build().on(exec));
return gko::preconditioner::Ilu<>::build()
.with_factorization_factory(ilu_fact)
.on(exec);
}}};


// preconditioner generation and application

std::string encode_parameters(const char *precond_name)
Expand All @@ -159,31 +61,59 @@ std::string encode_parameters(const char *precond_name)
{"jacobi",
[] {
std::ostringstream oss;
oss << "jacobi-" << FLAGS_max_block_size << "-"
<< FLAGS_storage_optimization;
oss << "jacobi-" << FLAGS_jacobi_max_block_size << "-"
<< FLAGS_jacobi_storage;
return oss.str();
}},
{"parict",
[] {
std::ostringstream oss;
oss << "parict-" << FLAGS_num_iterations << '-'
<< FLAGS_approx_select << '-' << FLAGS_fill_limit;
oss << "parict-" << FLAGS_parilu_iterations << '-'
<< FLAGS_parilut_approx_select << '-' << FLAGS_parilut_limit;
return oss.str();
}},
{"parilu",
[] {
std::ostringstream oss;
oss << "parilu-" << FLAGS_num_iterations;
oss << "parilu-" << FLAGS_parilu_iterations;
return oss.str();
}},
{"parilut",
[] {
std::ostringstream oss;
oss << "parilut-" << FLAGS_num_iterations << '-'
<< FLAGS_approx_select << '-' << FLAGS_fill_limit;
oss << "parilut-" << FLAGS_parilu_iterations << '-'
<< FLAGS_parilut_approx_select << '-' << FLAGS_parilut_limit;
return oss.str();
}},
{"ilu", [] { return std::string{"ilu"}; }}};
{"parict-isai",
[] {
std::ostringstream oss;
oss << "parict-isai-" << FLAGS_parilu_iterations << '-'
<< FLAGS_parilut_approx_select << '-' << FLAGS_parilut_limit
<< '-' << FLAGS_isai_power;
return oss.str();
}},
{"parilu-isai",
[] {
std::ostringstream oss;
oss << "parilu-isai-" << FLAGS_parilu_iterations << '-'
<< FLAGS_isai_power;
return oss.str();
}},
{"parilut-isai",
[] {
std::ostringstream oss;
oss << "parilut-isai-" << FLAGS_parilu_iterations << '-'
<< FLAGS_parilut_approx_select << '-' << FLAGS_parilut_limit
<< '-' << FLAGS_isai_power;
return oss.str();
}},
{"ilu-isai", [] {
return std::string{"ilu-isai-"} + std::to_string(FLAGS_isai_power);
}}};
if (encoder.find(precond_name) == encoder.end()) {
return precond_name;
}
return encoder[precond_name]();
}

Expand Down
17 changes: 14 additions & 3 deletions benchmark/run_all_benchmarks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ if [ ! "${DEVICE_ID}" ]; then
DEVICE_ID="0"
fi

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

if [ "${SOLVERS_RHS}" == "random" ]; then
SOLVERS_RHS_FLAG="--random_rhs=true"
else
SOLVERS_RHS_FLAG="--random_rhs=false"
fi

# Control whether to run detailed benchmarks or not.
# Default setting is detailed=false. To activate, set DETAILED=1.
if [ ! "${DETAILED}" ] || [ "${DETAILED}" -eq 0 ]; then
Expand Down Expand Up @@ -167,7 +178,7 @@ run_solver_benchmarks() {
--executor="${EXECUTOR}" --solvers="${SOLVERS}" \
--preconditioners="${PRECONDS}" \
--max_iters=${SOLVERS_MAX_ITERATIONS} --rel_res_goal=${SOLVERS_PRECISION} \
${DETAILED_STR} --device_id="${DEVICE_ID}" \
${SOLVERS_RHS_FLAG} ${DETAILED_STR} --device_id="${DEVICE_ID}" \
<"$1.imd" 2>&1 >"$1"
keep_latest "$1" "$1.bkp" "$1.bkp2" "$1.imd"
}
Expand All @@ -191,8 +202,8 @@ run_preconditioner_benchmarks() {
./preconditioner/preconditioner \
--backup="$1.bkp" --double_buffer="$1.bkp2" \
--executor="${EXECUTOR}" --preconditioners="jacobi" \
--max_block_size="${bsize}" \
--storage_optimization="${prec}" \
--jacobi_max_block_size="${bsize}" \
--jacobi_storage="${prec}" \
--device_id="${DEVICE_ID}" \
<"$1.imd" 2>&1 >"$1"
keep_latest "$1" "$1.bkp" "$1.bkp2" "$1.imd"
Expand Down
Loading