ConfigManager API reference

Caliper provides several built-in performance measurement and reporting configurations. These can be activated from within a program with the ConfigManager API using a short configuration string. Configuration strings can be hard-coded in the program or provided by the user in some form, e.g. as a command-line parameter or in the programs’s configuration file.

To access and control the built-in configurations, create a cali::ConfigManager object. Add a configuration string with add(), start the requested configuration channels with start(), and trigger output with flush():

#include <caliper/cali-manager.h>

int main(int argc, char* argv[])
{
   cali::ConfigManager mgr;

   if (argc > 1)
      mgr.add(argv[1]);
   if (mgr.error())
      std::cerr << "Config error: " << mgr.error_msg() << std::endl;
   // ...
   mgr.start(); // start requested performance measurement channels
   // ... (program execution)
   mgr.flush(); // write performance results
}

API Reference

group ControlChannelAPI

An API for controlling Caliper built-in performance measurement configurations.

The control channel API provides means to access and control built-in Caliper configurations and enable measurements from within a target program.

Functions

void add_global_config_specs(const ConfigManager::ConfigInfo **configs)

Add a set of global ConfigManager configs.

class ChannelController
#include <ChannelController.h>

Base class for Caliper channel controllers.

A channel controller wraps a Caliper configuration and channel. The underlying channel is initially inactive, and will be created in the first call of the start() method. Derived classes can modify the configuration before the channel is created.

ChannelController objects can be copied and moved. The underlying Caliper channel will be deleted when the last ChannelController object referencing is destroyed.

Subclassed by cali::RegionProfile

Public Functions

void start()

Create and activate the Caliper channel, or reactivate a stopped Caliper channel.

void stop()

Deactivate the Caliper channel.

bool is_active() const

Returns true if channel exists and is active, false otherwise.

std::string name() const

Returns the name of the underlying channel.

virtual void flush()

Flush the underlying Caliper channel.

Allows derived classes to implement custom Caliper data processing. The base class implementation invokes Caliper::flush_and_write().

ChannelController(const char *name, int flags, const config_map_t &cfg)

Create channel controller with given name, flags, and config.

class ConfigManager
#include <ConfigManager.h>

Configure, enable, and manage built-in or custom Caliper configurations.

ConfigManager is the principal component for managing Caliper measurement configurations programmatically. It parses a configuration string and creates a set of control channels for the requested measurement configurations, and provides control methods to start, stop, and flush the created measurements channels. Example:

cali::ConfigManager mgr;

//   Add a configuration string creating a runtime report
// and event trace channel
mgr.add("runtime-report,event-trace(output=trace.cali)");

// Check for configuration string parse errors
if (mgr.error()) {
    std::cerr << "ConfigManager: " << mgr.error_msg() << std::endl;
}

// Activate all requested configuration channels
mgr.start();

// ...

//   Trigger output on all configured channel controllers.
// Must be done explicitly, the built-in Caliper configurations do not
// not flush results automatically.
mgr.flush();

ConfigManager provides a set of built-in configurations specifications like “runtime-report”. Users can also add custom specifications with add_config_spec().

Public Types

typedef cali::ChannelController *(*CreateConfigFn)(const char *name, const config_map_t &initial_cfg, const Options &opts)

Callback function to create a custom ChannelController for a config.

Example:

cali::ChannelController* make_controller(const char* name,
        const cali::config_map_t& initial_cfg,
        const cali::ConfigManager::Options& opts)
{
    class MyChannelController : public cali::ChannelController {
    public:
        MyChannelController(const char* name,
                const cali::config_map_t& initial_cfg,
                const cali::ConfigManager::Options& opts)
            : cali::ChannelController(name, 0, initial_cfg)
        {
            opts.update_channel_config(config());
        }
    };

    return new MyChannelController(name, initial_cfg, opts);
}

Return

A new ChannelController object.

Parameters

typedef std::string (*CheckArgsFn)(const Options &opts)

Callback function to implement custom options checking for a config spec.

Public Functions

ConfigManager(const char *config_string)

Construct ConfigManager and add the given configuration string.

void add_config_spec(const ConfigInfo &info)

Add a custom config spec to this ConfigManager.

Adds a new Caliper configuration specification for this ConfigManager using a custom ChannelController or option checking function.

void add_config_spec(const char *json)

Add a JSON config spec to this ConfigManager.

Adds a new Caliper configuration specification for this ConfigManager using a basic ChannelController.

This example adds a config spec to perform simple sample tracing:

const char* spec =
  "{"
  " \"name\"        : \"sampletracing\","
  " \"description\" : \"Perform sample tracing\","
  " \"services\"    : [ \"recorder\", \"sampler\", \"trace\" ],"
  " \"config\"      :
  "  { \"CALI_SAMPLER_FREQUENCY\"     : \"100\",  "
  "    \"CALI_CHANNEL_FLUSH_ON_EXIT\" : \"false\" "
  "  },"
  " \"categories\"  : [ \"output\" ],"
  " \"defaults\"    : { \"sample.threads\": \"true\" }, "
  " \"options\"     : "
  " [ "
  "  { \"name\"        : \"sample.threads\","
  "    \"description\" : \"Sample all threads\","
  "    \"type\"        : \"bool\","
  "    \"services\"    : [ \"pthread\" ]"
  "  }"
  " ]"
  "}";

ConfigManager mgr;
mgr.add_config_spec(spec);

// Add a thread sampling channel using the spec and start recording
mgr.add("sampletracing(sample.threads=true,output=trace.cali)");
mgr.start();
// ...
mgr.flush();

If there was an error parsing the config spec, the

error() method will return true and an error message can be retrieved with error_msg().
Config specification syntax

The config spec is a JSON dictionary with the following elements:

  • name: Name of the config spec.

  • description: A short one-line description. Included in the documentation string generated by get_documentation_for_spec().

  • services: List of Caliper services this config requires. Note that the config will only be available if all required services are present in Caliper.

  • config: A dictionary with Caliper configuration variables required for this config. Note that services will be added automatically based on the services entry.

  • categories: A list of option categories. Defines which options, in addition to the ones defined inside the config spec, apply to this config. The example above uses the “output” category, which makes the built-in output option for setting output file names available.

  • defaults: A dict with default values for any of the config’s options. Options not listed here default to empty/not set.

  • options: A list of custom options for this config.

See

add_option_spec()

void add_option_spec(const char *json)

Add a JSON option spec to this ConfigManager.

Allows one to define options for any config in a matching category. Option specifications must be added before querying or creating any configurations to be effective. If there was an error parsing the config spec, the error() method will return true and an error message can be retrieved with error_msg(). The following example adds a metric option to compute instructions counts using the papi service:

const char* spec =
  "{"
  " \"name\"        : \"count.instructions\","
  " \"category\"    : \"metric\","
  " \"description\" : \"Count total instructions\","
  " \"services\"    : [ \"papi\" ],"
  " \"config\"      : { \"CALI_PAPI_COUNTERS\": \"PAPI_TOT_INS\" },"
  " \"query_args\"  : "
  " ["
  "  { \"level\": \"local\", \"select\":"
  "   [ { \"expr\": \"sum(sum#papi.PAPI_TOT_INS)\" } ]"
  "  },"
  "  { \"level\": \"cross\", \"select\":"
  "   [ { \"expr\": \"avg(sum#sum#papi.PAPI_TOT_INS)\", \"as\": \"Avg instr./rank\" },"
  "     { \"expr\": \"max(sum#sum#papi.PAPI_TOT_INS)\", \"as\": \"Max instr./rank\" }"
  "   ]"
  "  }"
  " ]"
  "}";

ConfigManager mgr;
mgr.add_option_spec(spec);

//   Create a runtime-report channel using the count.instructions option
// and start recording.
mgr.add("runtime-report(count.instructions)");
mgr.start();

Option specification syntax

The option spec is a JSON dictionary with the following elements:

  • name: Name of the option.

  • category: The option’s category. The category defines which configs can use this option: An option is only available to configs which list this category in their “categories” setting.

  • description: A short one-line description. Included in the documentation string generated by get_documentation_for_spec().

  • services: List of Caliper services this option requires. Note that the option will only be available if all required services are present in Caliper.

  • config: A dictionary with Caliper configuration variables required for this option. Note that services will be added automatically based on the services entry.

  • query_args: Defines aggregation operations to compute performance metrics. Specific to “metric” options. There are two aggregation levels: local computes process-local metrics, and cross computes cross-process metrics in MPI programs. For each level, specify metrics using a list of “select” definitions, where expr defines an aggregation using a CalQL expression, and as provides a human-readable name for the metric. Metrics on the serial and local levels use runtime aggregation results from the “aggregate” service as input, metrics on the cross level use “local” metrics as input.

bool add(const char *config_string)

Parse the config_string configuration string and create the specified configuration channels.

Parses configuration strings of the following form:

<config> ( <option> = value, … ), …

e.g., “runtime-report,event-trace(output=trace.cali)”

If there was an error parsing the configuration string, the error() method will return true and an error message can be retrieved with error_msg().

If the configuration string was parsed successfully, ChannelController instances for the requested configurations will be created and can be accessed through get_all_channels() or get_channel(). The channels are initially inactive and must be activated explicitly with ConfigManager::start().

add() can be invoked multiple times.

In this add() version, key-value pairs in the config string that neither represent a valid configuration or configuration option will be marked as a parse error.

Return

false if there was a parse error, true otherwise

bool add(const char *config_string, argmap_t &extra_kv_pairs)

Parse the config_string configuration string and create the specified configuration channels.

Works similar to ConfigManager::add(const char*), but does not mark extra key-value pairs in the config string that do not represent a configuration name or option as errors, and instead returns them in extra_kv_pairs.

void set_default_parameter(const char *key, const char *value)

Pre-set parameter key to value for all configurations.

bool error() const

Returns true if there was an error parsing configuration strings.

std::string error_msg() const

Returns an error message if there was an error parsing configuration strings.

ChannelList get_all_channels()

Return a list of channel controller instances for the requested configurations.

Return

An STL container with C++ shared_ptr objects to the ChannelController instances created from the configuration strings.

ChannelPtr get_channel(const char *name)

Return a channel controller instance for configuration name.

Returns a C++ shared pointer containing the channel controller instance with the given name, or an empty shared_ptr object when no such channel exists.

void start()

Start all configured measurement channels, or re-start paused ones.

Invokes the ChannelController::start() method on all configuration channel controllers created by the ConfigManager. Equivalent to

ConfigManager mgr;
// ...
auto channels = mgr.get_all_channels();
for (auto& channel : channels)
    channel->start();

void stop()

Pause all configured measurement channels.

Invokes the ChannelController::stop() method on all configuration channel controllers created by the ConfigManager.

void flush()

Flush all configured measurement channels.

Invokes the ChannelController::flush() method on all configuration channel controllers created by the ConfigManager. Equivalent to

auto channels = mgr.get_all_channels();
for (auto& channel : channels)
    channel->flush();

std::string check(const char *config_string, bool allow_extra_kv_pairs = false) const

Check if the given config string is valid.

If allow_extra_kv_pairs is set to false, extra key-value pairs in the config string that do not represent configurations or parameters will be marked as errors.

Return

Error message, or empty string if input is valid.

std::vector<std::string> available_config_specs() const

Return names of available config specs.

Returns only the specifications whose requirements (e.g., available services) are met in this Caliper instance.

Return

Names of all available config specs for this ConfigManager.

std::string get_documentation_for_spec(const char *name) const

Return description and options for the given config spec.

Public Static Functions

static std::vector<std::string> available_configs()

Return names of global config specs.

static std::vector<std::string> get_config_docstrings()

Return descriptions for available global configs.

static std::string check_config_string(const char *config_string, bool allow_extra_kv_pairs = false)

Check if given config string is valid for global config specs. Deprecated.

If allow_extra_kv_pairs is set to false, extra key-value pairs in the config string that do not represent configurations or parameters will be marked as errors.

Return

Error message, or empty string if input is valid.

struct ConfigInfo
#include <ConfigManager.h>

Define a config spec with custom ChannelController creation and option checking functions.

Public Members

const char *spec

JSON config spec.

See

ConfigManager::add_config_spec(const char*)

CreateConfigFn create

Optional custom ChannelController creation function, or nullptr to use the default.

CheckArgsFn check_args

Optional argument checking function, or nullptr to use the default.

class Options
#include <ConfigManager.h>

Manages the list of options given to a ConfigManager config controller. Internal use.

Public Functions

bool is_set(const char *option) const

Indicates if option is in the options list.

bool is_enabled(const char *option) const

Indicates if option is enabled.

An option is enabled if it is present in the options list, and, for boolean options, set to true.

StringConverter get(const char *option, const char *default_value = "") const

Return the value for option, or default_value if it is not set in the options list.

std::string check() const

Perform a validity check.

std::vector<std::string> enabled_options() const

Return a list of all enabled boolean options.

void update_channel_config(config_map_t &config) const

Update the config controller’s Caliper configuration according to the requirements of the selected options.

Updates CALI_SERVICES_ENABLE and adds any additional configuration flags that may be required.

std::string query_select(const char *level, const std::string &in, bool use_alias = true) const

Returns a CalQL SELECT expression to compute metrics in the option list.

Return

The SELECT list (comma-separated string), but without the ‘SELECT’ keyword

Parameters
  • level: The aggregation level (‘local’ or ‘cross’)

  • in: Base SELECT expression as required by the controller

  • use_alias: Wether to add aliases to the expression (as in SELECT x AS y)

std::string query_groupby(const char *level, const std::string &in) const

Returns a CalQL GROUP BY list for metrics in the option list.

Return

The GROUP BY list (comma-separated string), but without the ‘GROUP BY’ keyword

Parameters
  • level: The aggregation level (‘local’ or ‘cross’)

  • in: Base GROUP BY list as required by the controller

std::string query_let(const char *level, const std::string &in) const

Returns a CalQL LET list for metrics in the option list.

Return

The LET clause (‘LET’ + comma-separated list of definitions), or an empty string if there is no LET input

Parameters
  • level: The aggregation level (‘local’ or ‘cross’)

  • in: Base LET list as required by the controller

class RegionProfile : public cali::ChannelController
#include <RegionProfile.h>

Collect and return time profiles for annotated Caliper regions in a C++ map.

The RegionProfile class is a Caliper controller that allows one to collect and examine time spent in Caliper-annotated code regions within an instrumented program. It can compute inclusive or exclusive profiles. Start/stop profiling with the start() and stop() methods. Once started, time profiles can be retrieved at any time with exclusive_region_times() or inclusive_region_times().

Public Types

typedef std::tuple<std::map<std::string, double>, double, double> region_profile_t

A tuple containing the computed time profiles.

The first member is a string -> double STL map that stores the times per region. The map keys are the region names used in the annotations, e.g., “work” for CALI_MARK_BEGIN(“work”). Note that nested regions with the same name can’t be distinguished.

The second member stores the total time spent in the selected region type, and the third member stores the total time spent profiling.

Public Functions

RegionProfile()

Create a RegionProfile controller object.

Note that profiling must be started explicitly with the start() method.

region_profile_t exclusive_region_times(const std::string &region_type = "")

Return an exclusive time profile for annotated regions.

Exclusive time is the time spent in within a begin/end region itself, excluding time spent in sub-regions that are nested within.

Profiling must have been started with start().

By default, the result contains times for all region types with the CALI_ATTR_NESTED flag. Specifically, this includes regions marked with the Caliper annotations macros such as CALI_MARK_BEGIN. With the optional region_type argument, profiles can be calculated for a specific region type (Caliper attribute) only. In this case, the second value in the result tuple contains the total time spent in regions with the selected type.

As an example, the following code returns a profile for “function” regions:

RegionProfile rp;
rp.start();

// ...

std::map<std::string, double> function_times;
double total_function_time;
double total_profiling_time;

std::tie(function_times, total_function_time, total_profiling_time) = 
    rp.exclusive_region_times("function");

Return

A region_profile_t tuple with exclusive time per region in a region name -> time STL map, the total time for the selected region time, and the total time spent profiling. All time values are in seconds.

See

region_profile_t

region_profile_t inclusive_region_times(const std::string &region_type = "")

Return an inclusive time profile for annotated regions.

Inclusive time is time spent within a begin/end region, including time spent in sub-regions that are nested within.

Other than returning inclusive rather than exclusive times, this method works the same as exclusive_region_times().

Return

A region_profile_t tuple with inclusive time per region in a region name -> time STL map, the total time for the selected region time, and the total time spent profiling. All time values are in seconds.

See

region_profile_t, exclusive_region_times()

void clear()

Reset the profiling database.