LLNL/Caliper

Question: Is there a way to have Caliper output a custom string with the built in configs?

balos1 opened this issue ยท 6 comments

I would like, for example, the runtime-report to print out a string containing a git version string for our library.

Hi @balos1 ,

Currently that's not possible, but it is an interesting idea. We might be able to add that.

However, we have a C++ API that lets you write reports into a custom C++ stream, which might be a workaround. It requires MPI support. Here's an example:

https://software.llnl.gov/Caliper/ConfigManagerAPI.html#_CPPv4N4cali30make_collective_output_channelEPKc

Hope this helps!
-David

Thanks for the reply @daboehme.

The reasoning for wanting this: we would like to know exactly what version of our library was used when the report was generated. There are certainly ways we could work around this (I will take a look at the link), but it would be a very convenient feature if one could just set an environment variable like CALI_PKG_REVISION=$(git rev-parse HEAD) (or through a runtime API option) and have that string in the report.

Ok, I'll try to come up with something.

So just ran across this and, having done something like this myself, figured I'd shared what I think in the context of Caliper the solution could be: a metadata service (maybe enabled by default) which registers a bunch of (obviously) metadata at start-up and then there would a cali_add_metadata function that users can use to add their own metadata.

E.g. at start-up:

// uses strftime
auto _launch_date = get_local_datetime("%D", settings::get_launch_time());
auto _launch_time = get_local_datetime("%H:%M", settings::get_launch_time());
auto _cpu_info    = cpu::get_info();
auto _user        = get_env<std::string>("USER", "nobody");

for(auto&& itr : { "SHELL", "HOME", "PWD" })
{
    auto _var = get_env<std::string>(itr, "");
    if(!_var.empty())
        add_metadata(itr, _var);
}

add_metadata("USER", _user);
add_metadata("LAUNCH_DATE", _launch_date);
add_metadata("LAUNCH_TIME", _launch_time);

// these would be computed in CMake and put into a generated version.h header
add_metadata("CALIPER_VERSION", CALIPER_VERSION_STRING);
add_metadata("CALIPER_GIT_DESCRIBE", CALIPER_GIT_DESCRIBE);
add_metadata("CALIPER_GIT_REVISION", CALIPER_GIT_REVISION);

add_metadata("CPU_MODEL", _cpu_info.model);
add_metadata("CPU_VENDOR", _cpu_info.vendor);
add_metadata("CPU_FEATURES", _cpu_info.features);
add_metadata("CPU_FREQUENCY", _cpu_info.frequency);
add_metadata("HW_CONCURRENCY", threading::hw_concurrency());
add_metadata("HW_PHYSICAL_CPU", threading::hw_physicalcpu());

for(int i = 0; i < 3; ++i)
{
    auto              _cache_size = cpu::cache_size::get(i + 1);
    std::stringstream _cache_lvl;
    _cache_lvl << "HW_L" << (i + 1) << "_CACHE_SIZE";
    add_metadata(_cache_lvl.str(), _cache_size);
}

We actually have a metadata collection API much like the one suggested by @jrmadsen . Metadata attributes are called "global attributes" in Caliper, and you can use the cali_set_global_[int|double|string]_byname calls to set them, e.g. cali_set_global_string_byname("MY_VERSION", "v4.2");. However, the preferred way to do this is through the Adiak library and the adiak_import service. Adiak has functions to grab some common info like launch date, as well as key-value style functions to add custom application-specific metadata.

There is also a way to import metadata from environment variables: the env service. I totally forgot about that ๐Ÿ˜„. You can use CALI_ENV_EXTRA to specify the names of environment variables that should be imported, e.g.

$ export MY_GIT_REVISION="xyzabc"
$ export MY_VERSION="v4.2"
$ CALI_SERVICES_ENABLE=env,... CALI_ENV_EXTRA="MY_GIT_REVISION,MY_VERSION" ./app

Caliper adds this metadata to the machine-readable .json and .cali outputs, but we're still missing a way to print them together with the human-readable tree or table reports. This shouldn't be difficult though, and I'll add that.

I'm closing this now since you answered my question over a year ago. Thanks!