Tool API Guide

This section describes Adiak’s tools interface, which provides routines for querying name/value pairs.

Basics

There are three ways to query Adiak name/value pairs:

  • Use adiak_register_cb() to register a callback function that is invoked every time an adiak name/value pair of a given category (or any category) is registered

  • Use adiak_list_namevals() to iterate over all currently registered name/value pairs

  • Use adiak_get_nameval() to query a specific name/value pair by name

Interpreting Adiak values

The Adiak query methods return a adiak_value_t union and a adiak_datatype_t object. The adiak_value_t union must be interpreted based on the datatype. For example, for a adiak_catstring type, use the v_ptr union member cast to char*. Compound types such as lists must be interpreted recursively. See the adiak_value_t reference for the complete list of datatypes.

Example

The print_nameval example below implements a Adiak callback function that prints Adiak name/value pairs.

static void print_value(adiak_value_t *val, adiak_datatype_t *t)
{
   if (!t)
      printf("ERROR");
   switch (t->dtype) {
      case adiak_type_unset:
         printf("UNSET");
         break;
      case adiak_long:
         printf("%ld", val->v_long);
         break;
      case adiak_ulong:
         printf("%lu", (unsigned long) val->v_long);
         break;
      case adiak_longlong:
         printf("%lld", val->v_longlong);
         break;
      case adiak_ulonglong:
         printf("%llu", (unsigned long long) val->v_longlong);
         break;
      case adiak_int:
         printf("%d", val->v_int);
         break;
      case adiak_uint:
         printf("%u", (unsigned int) val->v_int);
         break;
      case adiak_double:
         printf("%f", val->v_double);
         break;
      case adiak_date: {
         char datestr[512];
         signed long seconds_since_epoch = (signed long) val->v_long;
         struct tm *loc = localtime(&seconds_since_epoch);
         strftime(datestr, sizeof(datestr), "%a, %d %b %Y %T %z", loc);
         printf("%s", datestr);
         break;
      }
      case adiak_timeval: {
         struct timeval *tval = (struct timeval *) val->v_ptr;
         double duration = tval->tv_sec + (tval->tv_usec / 1000000.0);
         printf("%fs (timeval)", duration);
         break;
      }
      case adiak_version: {
         char *s = (char *) val->v_ptr;
         printf("%s (version)", s);
         break;
      }
      case adiak_string: {
         char *s = (char *) val->v_ptr;
         printf("%s (string)", s);
         break;
      }
      case adiak_catstring: {
         char *s = (char *) val->v_ptr;
         printf("%s (catstring)", s);
         break;
      }
      case adiak_path: {
         char *s = (char *) val->v_ptr;
         printf("%s (path)", s);
         break;
      }
      case adiak_range: {
         adiak_value_t subvals[2];
         adiak_datatype_t* subtypes[2];

         adiak_get_subval(t, val, 0, subtypes+0, subvals+0);
         adiak_get_subval(t, val, 1, subtypes+1, subvals+1);

         print_value(subvals+0, *(subtypes+0));
         printf(" - ");
         print_value(subvals+1, *(subtypes+1));
         break;
      }
      case adiak_set: {
         printf("[");
         for (int i = 0; i < adiak_num_subvals(t); i++) {
            adiak_value_t subval;
            adiak_datatype_t* subtype;
            adiak_get_subval(t, val, i, &subtype, &subval);
            print_value(&subval, subtype);
            if (i+1 != t->num_elements)
               printf(", ");
         }
         printf("]");
         break;
      }
      case adiak_list: {
         printf("{");
         for (int i = 0; i < adiak_num_subvals(t); i++) {
            adiak_value_t subval;
            adiak_datatype_t* subtype;
            adiak_get_subval(t, val, i, &subtype, &subval);
            print_value(&subval, subtype);
            if (i+1 != t->num_elements)
               printf(", ");
         }
         printf("}");
         break;
      }
      case adiak_tuple: {
         printf("(");
         for (int i = 0; i < adiak_num_subvals(t); i++) {
            adiak_value_t subval;
            adiak_datatype_t* subtype;
            adiak_get_subval(t, val, i, &subtype, &subval);
            print_value(&subval, subtype);
            if (i+1 != t->num_elements)
               printf(", ");
         }
         printf(")");
         break;
      }
   }
}

static void print_nameval(const char *name, int UNUSED(category), const char *UNUSED(subcategory), adiak_value_t *value, adiak_datatype_t *t, void *UNUSED(opaque_value))
{
   printf("%s: ", name);
   print_value(value, t);
   printf("\n");
}

int main(int argc, char* argv[])
{
   adiak_init(NULL);

   adiak_register_cb(1, adiak_category_all, print_nameval, NULL);

   adiak_executable();
   adiak_namevalue("countdown", adiak_general, NULL, "%lld", 9876543210);
   int ints[3] = { 1, 2, 3 };
   adiak_namevalue("ints", adiak_general, NULL, "{%d}", ints, 3);

   adiak_fini();
}

API reference

group ToolAPI

Adiak API for querying name/value pairs.

Adiak tool API

typedef void (*adiak_nameval_cb_t)(const char *name, int category, const char *subcategory, adiak_value_t *value, adiak_datatype_t *t, void *opaque_value)

Callback function for processing an Adiak name/value pair.

This callback function is called once for each queried name/value pair.

Param name

Name of the name/value pair

Param category

The Adiak category, e.g. adiak_general

Param subcategory

Optional user-defined sub-category. Can be NULL.

Param value

The value of the name/value pair. Refer to adiak_value_t to see which union value to choose based on the datatype t.

Param t

The datatype specification of the name/value pair.

Param opaque_value

Optional user-defined pass-through argument

void adiak_register_cb(int adiak_version, int category, adiak_nameval_cb_t nv, int report_on_all_ranks, void *opaque_val)

Register a callback function to be invoked when a name/value pair is set.

Parameters
  • adiak_version[in] Adiak API version. Currently 1.

  • category[in] The Adiak category (e.g., adiak_general) to capture. Callbacks will only be invoked for name/values of category. Can be adiak_category_all to capture all name/value pairs.

  • nv[in] User-provided callback function

  • report_on_all_ranks[in] If set to 0, reports only on the root rank in an MPI program. Otherwise reports on all ranks.

  • opaque_val[in] User-provided value passed through to the callback function.

void adiak_list_namevals(int adiak_version, int category, adiak_nameval_cb_t nv, void *opaque_val)

Iterate over the name/value pairs currently registered with Adiak.

Iterates over all currently set name/value pairs of category and invokes the callback function nv for each name/value pair.

Parameters
  • adiak_version[in] Adiak API version. Currently 1.

  • category[in] The Adiak category (e.g., adiak_general) to capture. Callbacks will only be invoked for name/values of category. Can be adiak_category_all to capture all name/value pairs.

  • nv[in] Pointer to the user-provided callback function.

  • opaque_val[in] User-provided value passed through to the callback function.

char *adiak_type_to_string(adiak_datatype_t *t, int long_form)

Return the type string descriptor for an Adiak datatype specification.

Note

The returned string is malloc’d. The user must free the returned string pointer.

Parameters
  • t[in] The Adiak datatype specification

  • long_form[in] If non-zero, the string will be human readable, such as “set of int”. If zero, the string will be in the printf-style format described in adiak_type_t. documentation, such as “[%d]”.

int adiak_get_nameval(const char *name, adiak_datatype_t **t, adiak_value_t **value, int *category, const char **subcat)

Query the currently set value for name.

Parameters
  • name[in] Name of the name/value pair to query

  • t[out] The datatype specification of the name/value pair

  • value[out] Value of the name/value pair

  • category[out] The Adiak category, e.g. adiak_general

  • subcat[out] Optional user-defined sub-category. Can be NULL.

int adiak_num_subvals(adiak_datatype_t *t)

Return the number of sub-values for the given container type t.

int adiak_get_subval(adiak_datatype_t *t, adiak_value_t *val, int elem, adiak_datatype_t **subtype, adiak_value_t *subval)

Return the nth sub-value from a container-type value.

Returns a subvalue from a container value as a adiak_value_t, regardless of whether the container type is a reference type or a Adiak copy.

This function works for both Adiak-created deep copies (where values are stored as individual adiak_value_t entries in val->v_subvals) and reference entries (where the original pointer is stored as val->v_ptr).

Returns NULL in subtype and in subvalue.v_ptr if the given value is not a container type or elem is out-of-bounds.

Parameters
  • t[in] The container datatype

  • val[in] The container value

  • elem[in] Index of the sub-element to return

  • subtype[out] Returns the selected sub-value’s datatype

  • subval[out] Returns the selected sub-value