<commit_before>/**
 * x86_energy_arch.h
 *
 *  Created on: 22.06.2018
 *      Author: rschoene
 */

#ifndef INCLUDE_X86_ENERGY_H_
#define INCLUDE_X86_ENERGY_H_

#include <stddef.h>
#include <stdint.h>

/* Describes granularities within the system
 * will be
 * system GRANULARITY_SYSTEM
 * -> package GRANULARITY_SOCKET
 *   -> node GRANULARITY_DIE
 *      -> module GRANULARITY_MODULE
 *        -> core GRANULARITY_CORE
 *          -> thread GRANULARITY_THREAD
 *   -> device GRANULARITY_DEVICE (TODO)
 */
enum x86_energy_granularity
{
    X86_ENERGY_GRANULARITY_SYSTEM, /**< The node represents the system (a Linux instance) */
    X86_ENERGY_GRANULARITY_SOCKET, /**< The node represents a physical processor */
    X86_ENERGY_GRANULARITY_DIE, /**< The node represents a NUM domain on the physical processor */
    X86_ENERGY_GRANULARITY_MODULE, /**< The node represents a module (a set of cores sharing L2) */
    X86_ENERGY_GRANULARITY_CORE,   /**< The node represents a core */
    X86_ENERGY_GRANULARITY_THREAD, /**< The node represents a hardware thread (each core holds at
                                      least one), or a Linux CPU  */
    X86_ENERGY_GRANULARITY_DEVICE, /** < The node represents a device (not used yet) */

    /** Non-ABI, always compare to >= X86_ENERGY_GRANULARITY_SIZE instead of == , since this might
       change */
    X86_ENERGY_GRANULARITY_SIZE
};

/**
 * Enum for different types of energy counters
 */
enum x86_energy_counter
{
    X86_ENERGY_COUNTER_PCKG = 0,     /**< one package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_CORES = 1,    /**< all cores of a package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_DRAM = 2,     /**< dram of one package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_GPU = 3,      /**< gpu of one package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_PLATFORM = 4, /**< whole platform  / X86_ENERGY_GRANULARITY_SYSTEM */
    X86_ENERGY_COUNTER_SINGLE_CORE = 5, /**< a single core / X86_ENERGY_GRANULARITY_CORE */

    /* Non ABI */
    X86_ENERGY_COUNTER_SIZE
};

typedef struct x86_energy_architecture_node x86_energy_architecture_node_t;

/**
 * This struct is used to describe the underlying hardware
 */
struct x86_energy_architecture_node
{
    enum x86_energy_granularity granularity; /**< granularity level of current node */
    int32_t id;                              /**< id (unique for level) */
    char* name;                              /**< a name that can be printed */
    size_t nr_children; /**< number of sub nodes, will be 0 for X86_ENERGY_GRANULARITY_THREAD */
    x86_energy_architecture_node_t* children; /**< the children, each system will have a number of
                                                 sockets, ... */
};

/**
 * Create a tree representation of the current hardware
 * @return the hardware tree, NULL if error occured
 */
x86_energy_architecture_node_t* x86_energy_init_architecture_nodes(void);

/**
 *  Free a tree representation of the current hardware that was created with
 * x86_energy_init_architecture_nodes
 *  @param root the tree gathered with x86_energy_init_architecture_nodes
 */
void x86_energy_free_architecture_nodes(x86_energy_architecture_node_t* root);

/**
 * Get hardware info for a specific CPU
 *
 * @param root the tree gathered with x86_energy_init_architecture_nodes
 * @param granularity the granularity to search for (e.g. find module for CPU 15 ->
 * X86_ENERGY_GRANULARITY_MODULE)
 * @param cpu the CPU to ssearch the info for
 * @return the node with the given granularity that is in the graph between root and the cpu with id
 * cpu
 */
x86_energy_architecture_node_t*
x86_energy_find_arch_for_cpu(x86_energy_architecture_node_t* root,
                             enum x86_energy_granularity granularity, int cpu);

/**
 *  count the number of, for example, sockets
 *
 *  @param root the tree gathered with x86_energy_init_architecture_nodes
 *  @param granularity  the type to count (e.g., count nr of cores: X86_ENERGY_GRANULARITY_CORE)
 */
int x86_energy_arch_count(x86_energy_architecture_node_t* root,
                          enum x86_energy_granularity granularity);

/**
 *  Prints the tree to stdout
 *
 *  @param root the tree gathered with x86_energy_init_architecture_nodes
 *  @param level: number of spaces at begin of first entry
 */
void x86_energy_print(x86_energy_architecture_node_t* root, int lvl);

/**
 * Defines available features at current system
 */
typedef struct x86_energy_mechanism_struct
{
    char* name; /** < Will tell you which mechanism is accessible (e.g. "Intel RAPL"), each
                   mechanism has different implementations for access (sources), e.g. Likwid, sysfs
                   */
    enum x86_energy_granularity
        source_granularities[X86_ENERGY_COUNTER_SIZE]; /**< will tell you the granularity for each
                                                          possible counter, if it is >=
                                                          X86_ENERGY_GRANULARITY_SIZE, it is not
                                                          available */
    size_t nr_avail_sources;                           /** < length of avail_sources */
    struct x86_energy_access_source* avail_sources;    /** < holds a list of possible interfaces to
                                                          access your mechanism, just try them ;) */
} x86_energy_mechanisms_t;

/**
 * Gets the available mechanism on your system, including a description.
 */
x86_energy_mechanisms_t* x86_energy_get_avail_mechanism(void);

/**
 * Hardware energy measurement might have in overflows.
 * Internal threads will take care of this. If you know what you do, you can override their update
 * rate with this function. You can also disable threads by setting it to 0.
 * This will not influence existing threads, so you should call this before calling any
 * x86_energy_access_source_t.setup(...) and not afterwards!
 * @param time_in_us the new update rate in us, if 0, the thread(s) will be disabled.
 */
void x86_energy_set_internal_update_thread_rate(long long int time_in_us);

/**
 * Will be used by access sources
 */
typedef void* x86_energy_single_counter_t;

/**
 * One possible access source, e.g., likwid, perf, ...
 */
typedef struct x86_energy_access_source
{
    char* name;        /**< The name of the source (e.g., Likwid, sysfs, perf) */
    int (*init)(void); /**< Call this for initialization, will return != 0 on error */
    x86_energy_single_counter_t (*setup)(enum x86_energy_counter,
                                         size_t index); /**< Call this for adding a counter, will
                                                           return NULL on error */
    double (*read)(x86_energy_single_counter_t t); /**< Read the current energy value in Joules,
                                                      will return < 0.0 on error */
    void (*close)(x86_energy_single_counter_t t);  /**< Close a single counter */
    void (*fini)(void);                            /**< Finalize a source */<commit_msg>export error message<commit_after>/**
 * x86_energy_arch.h
 *
 *  Created on: 22.06.2018
 *      Author: rschoene
 */

#ifndef INCLUDE_X86_ENERGY_H_
#define INCLUDE_X86_ENERGY_H_

#include <stddef.h>
#include <stdint.h>

/* Describes granularities within the system
 * will be
 * system GRANULARITY_SYSTEM
 * -> package GRANULARITY_SOCKET
 *   -> node GRANULARITY_DIE
 *      -> module GRANULARITY_MODULE
 *        -> core GRANULARITY_CORE
 *          -> thread GRANULARITY_THREAD
 *   -> device GRANULARITY_DEVICE (TODO)
 */
enum x86_energy_granularity
{
    X86_ENERGY_GRANULARITY_SYSTEM, /**< The node represents the system (a Linux instance) */
    X86_ENERGY_GRANULARITY_SOCKET, /**< The node represents a physical processor */
    X86_ENERGY_GRANULARITY_DIE, /**< The node represents a NUM domain on the physical processor */
    X86_ENERGY_GRANULARITY_MODULE, /**< The node represents a module (a set of cores sharing L2) */
    X86_ENERGY_GRANULARITY_CORE,   /**< The node represents a core */
    X86_ENERGY_GRANULARITY_THREAD, /**< The node represents a hardware thread (each core holds at
                                      least one), or a Linux CPU  */
    X86_ENERGY_GRANULARITY_DEVICE, /** < The node represents a device (not used yet) */

    /** Non-ABI, always compare to >= X86_ENERGY_GRANULARITY_SIZE instead of == , since this might
       change */
    X86_ENERGY_GRANULARITY_SIZE
};

/**
 * Enum for different types of energy counters
 */
enum x86_energy_counter
{
    X86_ENERGY_COUNTER_PCKG = 0,     /**< one package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_CORES = 1,    /**< all cores of a package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_DRAM = 2,     /**< dram of one package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_GPU = 3,      /**< gpu of one package / X86_ENERGY_GRANULARITY_SOCKET */
    X86_ENERGY_COUNTER_PLATFORM = 4, /**< whole platform  / X86_ENERGY_GRANULARITY_SYSTEM */
    X86_ENERGY_COUNTER_SINGLE_CORE = 5, /**< a single core / X86_ENERGY_GRANULARITY_CORE */

    /* Non ABI */
    X86_ENERGY_COUNTER_SIZE
};

typedef struct x86_energy_architecture_node x86_energy_architecture_node_t;

/**
 * This struct is used to describe the underlying hardware
 */
struct x86_energy_architecture_node
{
    enum x86_energy_granularity granularity; /**< granularity level of current node */
    int32_t id;                              /**< id (unique for level) */
    char* name;                              /**< a name that can be printed */
    size_t nr_children; /**< number of sub nodes, will be 0 for X86_ENERGY_GRANULARITY_THREAD */
    x86_energy_architecture_node_t* children; /**< the children, each system will have a number of
                                                 sockets, ... */
};

/**
 * Create a tree representation of the current hardware
 * @return the hardware tree, NULL if error occured
 */
x86_energy_architecture_node_t* x86_energy_init_architecture_nodes(void);

/**
 *  Free a tree representation of the current hardware that was created with
 * x86_energy_init_architecture_nodes
 *  @param root the tree gathered with x86_energy_init_architecture_nodes
 */
void x86_energy_free_architecture_nodes(x86_energy_architecture_node_t* root);

/**
 * Get hardware info for a specific CPU
 *
 * @param root the tree gathered with x86_energy_init_architecture_nodes
 * @param granularity the granularity to search for (e.g. find module for CPU 15 ->
 * X86_ENERGY_GRANULARITY_MODULE)
 * @param cpu the CPU to ssearch the info for
 * @return the node with the given granularity that is in the graph between root and the cpu with id
 * cpu
 */
x86_energy_architecture_node_t*
x86_energy_find_arch_for_cpu(x86_energy_architecture_node_t* root,
                             enum x86_energy_granularity granularity, int cpu);

/**
 *  count the number of, for example, sockets
 *
 *  @param root the tree gathered with x86_energy_init_architecture_nodes
 *  @param granularity  the type to count (e.g., count nr of cores: X86_ENERGY_GRANULARITY_CORE)
 */
int x86_energy_arch_count(x86_energy_architecture_node_t* root,
                          enum x86_energy_granularity granularity);

/**
 *  Prints the tree to stdout
 *
 *  @param root the tree gathered with x86_energy_init_architecture_nodes
 *  @param level: number of spaces at begin of first entry
 */
void x86_energy_print(x86_energy_architecture_node_t* root, int lvl);

/**
 * Defines available features at current system
 */
typedef struct x86_energy_mechanism_struct
{
    char* name; /** < Will tell you which mechanism is accessible (e.g. "Intel RAPL"), each
                   mechanism has different implementations for access (sources), e.g. Likwid, sysfs
                   */
    enum x86_energy_granularity
        source_granularities[X86_ENERGY_COUNTER_SIZE]; /**< will tell you the granularity for each
                                                          possible counter, if it is >=
                                                          X86_ENERGY_GRANULARITY_SIZE, it is not
                                                          available */
    size_t nr_avail_sources;                           /** < length of avail_sources */
    struct x86_energy_access_source* avail_sources;    /** < holds a list of possible interfaces to
                                                          access your mechanism, just try them ;) */
} x86_energy_mechanisms_t;

/**
 * Gets the available mechanism on your system, including a description.
 */
x86_energy_mechanisms_t* x86_energy_get_avail_mechanism(void);

char * x86_energy_error_string( void );

/**
 * Hardware energy measurement might have in overflows.
 * Internal threads will take care of this. If you know what you do, you can override their update
 * rate with this function. You can also disable threads by setting it to 0.
 * This will not influence existing threads, so you should call this before calling any
 * x86_energy_access_source_t.setup(...) and not afterwards!
 * @param time_in_us the new update rate in us, if 0, the thread(s) will be disabled.
 */
void x86_energy_set_internal_update_thread_rate(long long int time_in_us);

/**
 * Will be used by access sources
 */
typedef void* x86_energy_single_counter_t;

/**
 * One possible access source, e.g., likwid, perf, ...
 */
typedef struct x86_energy_access_source
{
    char* name;        /**< The name of the source (e.g., Likwid, sysfs, perf) */
    int (*init)(void); /**< Call this for initialization, will return != 0 on error */
    x86_energy_single_counter_t (*setup)(enum x86_energy_counter,
                                         size_t index); /**< Call this for adding a counter, will
                                                           return NULL on error */
    double (*read)(x86_energy_single_counter_t t); /**< Read the current energy value in Joules,
                                                      will return < 0.0 on error */
    void (*close)(x86_energy_single_counter_t t);  /**< Close a single counter */
    void (*fini)(void);                            /**< Finalize a source */
{'fraction_non_alphanumeric': 0.07858546168958742, 'fraction_numerical': 0.02301431378052203, 'mean_word_length': 2.7030397505845674, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4698342', 'n_tokens_mistral': 4587, 'n_tokens_neox': 4139, 'n_words': 1293}