The C structures are roughly organized as a tree, with a trial object at the root.
-
taudb_trial: A top-level structure which contains the collections of all the performance data dimensions.
-
taudb_primary_metadata: Name/value pairs which describe the properties of the trial.
-
taudb_secondary_metadata: Name/value pairs which describe the properties of the trial. Unlike primary_metadata values, secondary_metadata objects can have complex value types. They are also associated with a measurement context - a thread of execution, a timer, a timestamp, an iteration, etc.
-
taudb_thread: A structure which represents a thread of execution in the parallel measurement.
-
taudb_time_range: A structure which holds a time-range value of beginning and ending iteration numbers or timestamps.
-
taudb_metric: A structure which represents a unit of measurement, such as TIME, FP_OPS, L1_DCM, etc.
-
taudb_timer: A structure which represents a region of code. For example, a phase, a function, a loop, a basic block, or even a line of code.
-
taudb_timer_parameter: A structure which represents parameter values, when parameter based profiling is used.
-
taudb_timer_group: A structure which represents a semantic grouping of timers, such as "I/O", "MPI", "OpenMP", etc.
-
taudb_timer_callpath: A structure which represents a node in the dynamic callpath tree. Timer_callpaths with a null parent are either top level timers, or a timers in a flat profile.
-
taudb_timer_call_data: A structure which represents a tuple between a thread of execution and a node on the timer callpath tree.
-
taudb_timer_value: A structure which represents a tuple between a timer_call_data object and a metric. The timer_value contains the measurement of one metric for one timer on one thread of execution.
-
taudb_counter: A structure which represents a counter in the profile. For example, the number of bytes transferred on an MPI_Send() timer.
-
taudb_counter_value: A structure which represents a counter measurement on one thread of execution.
Below are the object definitions, from the TAUdb C header file.
#ifndef TAUDB_STRUCTS_H
#define TAUDB_STRUCTS_H 1
#include "time.h"
#include "uthash.h"
#include "taudb_structs.h"
#if defined __TAUDB_POSTGRESQL__
#include "libpq-fe.h"
#elif defined __TAUDB_SQLITE__
#include "sqlite3.h"
#endif
#ifndef boolean
#define TRUE 1
#define FALSE 0
typedef int boolean;
#endif
typedef struct taudb_prepared_statement {
char* name;
UT_hash_handle hh; /* hash index for hashing by name */
} TAUDB_PREPARED_STATEMENT;
/* forward declarations to ease objects that need to know about
* each other and have doubly-linked relationships */
struct taudb_timer_call_data;
struct taudb_timer_value;
struct taudb_timer_callpath;
struct taudb_timer_group;
struct taudb_timer_parameter;
struct taudb_timer;
struct taudb_counter_value;
struct taudb_counter;
struct taudb_primary_metadata;
struct taudb_secondary_metadata;
struct taudb_time_range;
struct taudb_thread;
struct taudb_metric;
struct taudb_trial;
struct perfdmf_experiment;
struct perfdmf_application;
typedef struct taudb_configuration {
char* jdbc_db_type; /* to identify DBMS vendor.
* postgresql, mysql, h2, derby, etc. */
char* db_hostname; /* server host name */
char* db_portnum; /* server port number */
char* db_dbname; /* the database name at the server */
char* db_schemaprefix; /* the schema prefix. This is appended to
* all table names for some DBMSs */
char* db_username; /* the database username */
char* db_password; /* the database password for username */
char* db_schemafile; /* full or relative path to the schema file,
* used for configuration, not used in C API */
} TAUDB_CONFIGURATION;
typedef enum taudb_database_schema_version {
TAUDB_2005_SCHEMA,
TAUDB_2012_SCHEMA
} TAUDB_SCHEMA_VERSION;
typedef struct taudb_data_source {
int id;
char* name;
char*description;
UT_hash_handle hh1; /* hash index for hashing by id */
UT_hash_handle hh2; /* hash index for hashing by name */
} TAUDB_DATA_SOURCE;
typedef struct taudb_connection {
TAUDB_CONFIGURATION *configuration;
#if defined __TAUDB_POSTGRESQL__
PGconn *connection;
PGresult *res;
TAUDB_PREPARED_STATEMENT *statements;
#elif defined __TAUDB_SQLITE__
sqlite3 *connection;
sqlite3_stmt *ppStmt;
int rc;
#endif
TAUDB_SCHEMA_VERSION schema_version;
boolean inTransaction;
boolean inPortal;
TAUDB_DATA_SOURCE* data_sources_by_id;
TAUDB_DATA_SOURCE* data_sources_by_name;
} TAUDB_CONNECTION;
/* these are the derived thread indexes. */
#define TAUDB_MEAN_WITHOUT_NULLS -1
#define TAUDB_TOTAL -2
#define TAUDB_STDDEV_WITHOUT_NULLS -3
#define TAUDB_MIN -4
#define TAUDB_MAX -5
#define TAUDB_MEAN_WITH_NULLS -6
#define TAUDB_STDDEV_WITH_NULLS -7
/* trials are the top level structure */
typedef struct taudb_trial {
/* actual data from the database */
int id;
char* name;
struct taudb_data_source* data_source;
int node_count; /* i.e. number of processes. */
int contexts_per_node; /* rarely used, usually 1. */
int threads_per_context; /* max number of threads per process
* (can be less on individual processes) */
int total_threads; /* total number of threads */
/* arrays of data for this trial */
struct taudb_metric* metrics_by_id;
struct taudb_metric* metrics_by_name;
struct taudb_thread* threads;
struct taudb_time_range* time_ranges;
struct taudb_timer* timers_by_id;
struct taudb_timer* timers_by_name;
struct taudb_timer_group* timer_groups;
struct taudb_timer_callpath* timer_callpaths_by_id;
struct taudb_timer_callpath* timer_callpaths_by_name;
struct taudb_timer_call_data* timer_call_data_by_id;
struct taudb_timer_call_data* timer_call_data_by_key;
struct taudb_counter* counters_by_id;
struct taudb_counter* counters_by_name;
struct taudb_counter_value* counter_values;
struct taudb_primary_metadata* primary_metadata;
struct taudb_secondary_metadata* secondary_metadata;
struct taudb_secondary_metadata* secondary_metadata_by_key;
} TAUDB_TRIAL;
/*********************************************/
/* data dimensions */
/*********************************************/
/* thread represents one physical & logical
* location for a measurement. */
typedef struct taudb_thread {
int id; /* database id, also key to hash */
struct taudb_trial* trial;
int node_rank; /* which process does this thread belong to? */
int context_rank; /* which context? USUALLY 0 */
int thread_rank; /* what is this thread's rank in the process */
int index; /* what is this threads OVERALL index?
* ranges from 0 to trial.thread_count-1 */
struct taudb_secondary_metadata* secondary_metadata;
UT_hash_handle hh;
} TAUDB_THREAD;
/* metrics are things like TIME, PAPI counters, and derived metrics. */
typedef struct taudb_metric {
int id; /* database value, also key to hash */
char* name; /* key to hash hh2 */
boolean derived; /* was this metric measured, or created by a
* post-processing tool? */
UT_hash_handle hh1; /* hash index for hashing by id */
UT_hash_handle hh2; /* hash index for hashing by name */
} TAUDB_METRIC;
/* Time ranges are ways to delimit the profile data within time ranges.
They are also useful for secondary metadata which is associated with
a specific call to a function. */
typedef struct taudb_time_range {
int id; /* database value, also key to hash */
int iteration_start;
int iteration_end;
uint64_t time_start;
uint64_t time_end; /* was this metric measured,
* or created by a post-processing tool? */
UT_hash_handle hh;
} TAUDB_TIME_RANGE;
/* timers are interval timers, capturing some interval value.
* For callpath or phase profiles, the parent refers to the calling
* function or phase. Timers can also be sample locations, or
* phases (dynamic or static), or sample aggregations (intermediate) */
typedef struct taudb_timer {
int id; /* database value, also key to hash */
struct taudb_trial* trial; /* pointer back to trial - NOTE: Necessary? */
char* name; /* the full timer name, can have file, line, etc. */
char* short_name; /* just the function name, for example */
char* source_file; /* what source file does this function live in? */
int line_number; /* what line does the timer start on? */
int line_number_end; /* what line does the timer end on? */
int column_number; /* what column number does the timer start on? */
int column_number_end; /* what column number does the timer end on? */
struct taudb_timer_group* groups; /* hash of groups,
* using group hash handle hh2 */
struct taudb_timer_parameter* parameters; /* array of parameters */
UT_hash_handle trial_hash_by_id; /* hash key for id lookup */
UT_hash_handle trial_hash_by_name; /* hash key for name lookup
* in temporary hash */
UT_hash_handle group_hash_by_name; /* hash key for name lookup
* in timer group */
} TAUDB_TIMER;
/*********************************************/
/* timer related structures */
/*********************************************/
/* timer groups are the groups such as tau_default,
mpi, openmp, tau_phase, tau_callpath, tau_param, etc.
this mapping table allows for nxn mappings between timers
and groups */
typedef struct taudb_timer_group {
char* name;
struct taudb_timer* timers; /* hash of timers,
* using timer hash handle hh3 */
UT_hash_handle trial_hash_by_name; // hash handle for trial
UT_hash_handle timer_hash_by_name; // hash handle for timers
} TAUDB_TIMER_GROUP;
/* timer parameters are parameter based profile values.
an example is foo (x,y) where x=4 and y=10. in that example,
timer would be the index of the timer with the
name 'foo (x,y) <x>=<4> <y>=<10>'. this table would have two
entries, one for the x value and one for the y value.
The parameter can also be a phase / iteration index.
*/
typedef struct taudb_timer_parameter {
char* name;
char* value;
UT_hash_handle hh;
} TAUDB_TIMER_PARAMETER;
/* callpath objects contain the merged dynamic callgraph tree seen
* during execution */
typedef struct taudb_timer_callpath {
int id; /* link back to database, and hash key */
struct taudb_timer* timer; /* which timer is this? */
struct taudb_timer_callpath *parent; /* callgraph parent */
char* name; /* a string which has the aggregated callpath. */
UT_hash_handle hh1; /* hash key for hash by id */
UT_hash_handle hh2; /* hash key for name (a => b => c...) lookup */
} TAUDB_TIMER_CALLPATH;
/* timer_call_data objects are observations of a node of the callgraph
for one of the threads. */
typedef struct taudb_call_data_key {
struct taudb_timer_callpath *timer_callpath; /* link back to database */
struct taudb_thread *thread; /* link back to database, roundabout way */
char* timestamp; /* timestamp in case we are in a snapshot or something */
} TAUDB_TIMER_CALL_DATA_KEY;
typedef struct taudb_timer_call_data {
int id; /* link back to database */
TAUDB_TIMER_CALL_DATA_KEY key; /* hash table key */
int calls; /* number of times this timer was seen */
int subroutines; /* number of timers this timer calls */
struct taudb_timer_value* timer_values;
UT_hash_handle hh1;
UT_hash_handle hh2;
} TAUDB_TIMER_CALL_DATA;
/* finally, timer_values are specific measurements during one of the
observations of the node of the callgraph on a thread. */
typedef struct taudb_timer_value {
struct taudb_metric* metric; /* which metric is this? */
double inclusive; /* the inclusive value of this metric */
double exclusive; /* the exclusive value of this metric */
double inclusive_percentage; /* the inclusive percentage of
* total time of the application */
double exclusive_percentage; /* the exclusive percentage of
* total time of the application */
double sum_exclusive_squared; /* how much variance did we see
* every time we measured this timer? */
char *key; /* hash table key - metric name */
UT_hash_handle hh;
} TAUDB_TIMER_VALUE;
/*********************************************/
/* counter related structures */
/*********************************************/
/* counters measure some counted value. An example would be MPI message size
* for an MPI_Send. */
typedef struct taudb_counter {
int id; /* database reference */
struct taudb_trial* trial;
char* name;
UT_hash_handle hh1; /* hash key for hashing by id */
UT_hash_handle hh2; /* hash key for hashing by name */
} TAUDB_COUNTER;
/* counters are atomic counters, not just interval timers */
typedef struct taudb_counter_value_key {
struct taudb_counter* counter; /* the counter we are measuring */
struct taudb_thread* thread; /* where this measurement is */
struct taudb_timer_callpath* context; /* the calling context (can be null) */
char* timestamp; /* timestamp in case we are in a snapshot or something */
} TAUDB_COUNTER_VALUE_KEY;
typedef struct taudb_counter_value {
TAUDB_COUNTER_VALUE_KEY key;
int sample_count; /* how many times did we see take this count? */
double maximum_value; /* what was the max value we saw? */
double minimum_value; /* what was the min value we saw? */
double mean_value; /* what was the average value we saw? */
double standard_deviation; /* how much variance was there? */
UT_hash_handle hh1; /* hash key for hashing by key */
} TAUDB_COUNTER_VALUE;
/*********************************************/
/* metadata related structures */
/*********************************************/
/* primary metadata is metadata that is not nested, does not
contain unique data for each thread. */
typedef struct taudb_primary_metadata {
char* name;
char* value;
UT_hash_handle hh; /* uses the name as the key */
} TAUDB_PRIMARY_METADATA;
/* primary metadata is metadata that could be nested, could
contain unique data for each thread, and could be an array. */
typedef struct taudb_secondary_metadata_key {
struct taudb_timer_callpath *timer_callpath; /* link back to database */
struct taudb_thread *thread; /* link back to database, roundabout way */
struct taudb_secondary_metadata* parent; /* self-referencing */
struct taudb_time_range* time_range;
char* name;
} TAUDB_SECONDARY_METADATA_KEY;
typedef struct taudb_secondary_metadata {
char* id; /* link back to database */
TAUDB_SECONDARY_METADATA_KEY key;
int num_values; /* can have arrays of data */
char** value;
int child_count;
struct taudb_secondary_metadata* children; /* self-referencing */
UT_hash_handle hh; /* uses the id as a compound key */
UT_hash_handle hh2; /* uses the key as a compound key */
} TAUDB_SECONDARY_METADATA;
/* these are for supporting the older schema */
typedef struct perfdmf_experiment {
int id;
char* name;
struct taudb_primary_metadata* primary_metadata;
} PERFDMF_EXPERIMENT;
typedef struct perfdmf_application {
int id;
char* name;
struct taudb_primary_metadata* primary_metadata;
} PERFDMF_APPLICATION;
#endif /* TAUDB_STRUCTS_H */