-
Notifications
You must be signed in to change notification settings - Fork 88
PAPI Logger draft
Let N be the number of types of counters we want to support, and C a small constant. Then, adding PAPI support to Ginkgo (after Ginkgo's general logging facilities are set up), will cost:
- If using
papi_sde_register_counter
: C + 4N statements. - If using
papi_sde_log
: C + 2N statements.
In both cases, the user has to add 1 additional statement to enable PAPI integration for a Ginkgo object in their application.
This is a simplified version that shows the differences between an implementation based on papi_sde_register_counter
and papi_sde_log
.
The code uses some of the internal Ginkgo's base classes, which do not depend on PAPI in any way. For reference, the implementation of these classes is at the end of the page.
class PapiLogger : public Logger {
public:
static std::unique_ptr<PapiLogger> create(void *handle)
{
return xstd::make_unique<PapiLogger>(handle);
}
void on_iteration_complete(/* parameters */) const override
{
++num_iterations;
}
// implementation for on_<event_type> for other events
// we export to PAPI - we don't need implementations for
// events we do not export
protected:
PapiLogger(void *handle) : handle_(handle)
{
const auto mode = /*something, report doesn't specify what*/;
papi_sde_register_counter(handle_, "gko::num_iterations",
PAPI_SDE_LLINT, mode, &num_iterations);
// register other counters we export to PAPI
}
private:
void *handle_;
mutable gko::int64 num_iterations;
// counters for other events we export to PAPI
};
class PapiLogger : public Logger {
public:
static std::unique_ptr<PapiLogger> create(void *handle)
{
return xstd::make_unique<PapiLogger>(handle);
}
void on_iteration_complete(/* parameters */) const override
{
papi_sde_log(handle_, "gko::num_iterations");
}
// implementation for on_<event_type> for other events
// we export to PAPI - we don't need implementations for
// events we do not export
protected:
PapiLogger(void *handle) : handle_(handle)
{}
private:
void *handle_;
};
auto mtx = /* get the system matrix */;
auto b = /* get RHS */;
auto x = /* get initial solution */;
void *handle = /* obtain a PAPI handle */; # PAPI init
auto factory = Cg::Factory::create(/* parameters */);
auto cg = factory->generate(gko::give(matrix));
cg->add_logger(PapiLogger::create(handle)); # Add PAPI to solver
cg->apply(gko::lend(b), gko::lend(x));
The code is the same with both versions of the PapiLogger
,
and there are no changes needed within the CG solver itself to support PAPI.
Nothing related to PAPI in this section.
// abstract interface that is called by Loggable objects
class Logger {
public:
virtual ~Logger() = default;
virtual void on_iteration_complete(/* parameters */) const {}
// other on_<event_type> methods
};
// Inteface for recognizing loggable objects
class Loggable {
public:
virtual ~Loggable() = default;
virtual void add_logger(std::shared_Ptr<const Logger> logger) = 0;
};
// MixIn to easily enable Logging for different classes
template <typename ConcreteLogger>
class EnableLogging : public Loggable {
public:
void add_logger(std::shared_ptr<const Logger> logger) override {
loggers.push_back(std::move(logger));
}
protected:
void log_iteration_complete(/* parameters */) const {
for(auto &logger : loggers) {
logger->on_iteration_complete(/* parameters */);
}
}
// other log_<event_type> methods
std::vector<std::shared_ptr<const Logger>> loggers;
};
An example implementation of a loggable object (e.g. a solver):
class Cg : public BasicLinOp<Cg>, public EnableLogging<Cg> {
public:
void apply(/* parameters */) {
// setup
for (int i = 0; i < num_iters; ++i) {
// do iteration
this->log_iteration_complete(/* parameters */); // doesn't have to know about PAPI
}
}
};
Tutorial: Building a Poisson Solver
- Getting Started
- Implement: Matrices
- Implement: Solvers
- Optimize: Measuring Performance
- Optimize: Monitoring Progress
- Optimize: More Suitable Matrix Formats
- Optimize: Using a Preconditioner
- Optimize: Using GPUs
- Customize: Loggers
- Customize: Stopping Criterions
- Customize: Matrix Formats
- Customize: Solvers
- Customize: Preconditioners