Commit 6be5d225 authored by Lluis Alonso's avatar Lluis Alonso
Browse files

Updated to EAR4.0a

parent 9fe1b60b
# EAR Configuration File
#---------------------------------------------------------------------------------------------------
# DB confguration:This configuration conrrespondons with the DB server installation
# DB confguration: This configuration conrrespondons with the DB server installation.
#---------------------------------------------------------------------------------------------------
DBIp=127.0.0.1
DBUser=ear_daemon
......@@ -15,47 +16,53 @@ DBMaxConnections=20
DBReportNodeDetail=1
# Extended signature information saves also the hardware counters.
DBreportSIGDetail=1
# Report loop signatures
# Report loop signatures.
DBReportLoops=1
#---------------------------------------------------------------------------------------------------
# EAR Daemon (EARD): Update that section to change EARD configuration
# EAR Daemon (EARD): Update this section to change EARD configuration.
#---------------------------------------------------------------------------------------------------
#Port is used for connections with the EAR plugin and commands
# Port is used for connections with the EAR plugin and commands.
NodeDaemonPort=50001
# Frequency at wich the periodic metrics are reported: In seconds
# Frequency at wich the periodic metrics are reported, in seconds.
NodeDaemonPowermonFreq=60
# Max frequency used by eard. It's max frequency but min pstate.
NodeDaemonMaxPstate=1
NodeDaemonTurbo=0
# Dedines if EARD used the DB or not
# Defines whether EARD uses the DB.
NodeUseDB=1
# Defines if EARD connects with EARDBD to report data or directly with the DB server. Only for testing
# Defines if EARD connects with EARDBD to report data or directly with the DB server. Only for testing.
NodeUseEARDBD=1
# Whe set to 1, this flag means EARD must set frequencies before job starts, if not, frequency is only changed in case job runs with EARL
# When set to 1, this flag means EARD must set frequencies before job starts. If not, frequency is only changed in case job runs with EARL.
NodeDaemonForceFrequencies=1
# Verbosity
# Verbosity.
NodeDaemonVerbose=1
# When set to 1, the output is saved in 'TmpDir'/eard.log (common configuration) as a log file.
NodeUseLog=1
#---------------------------------------------------------------------------------------------------
# EAR Database Manager (EARDBD): Update that section to change EARDBD configuration
# EAR Database Manager (EARDBD): Update this section to change EARDBD configuration.
#---------------------------------------------------------------------------------------------------
DBDaemonPortTCP=50002
DBDaemonPortSecTCP=50003
DBDaemonSyncPort=50004
# Aggregation time id frequency at which power metrics are aggregated in aggregated metrics: In seconds
# Aggregation time id frequency at which power metrics are aggregated in aggregated metrics, in seconds.
DBDaemonAggregationTime=60
# Frequency at which buffered data is sent to DB server
# Frequency at which buffered data is sent to DB server.
DBDaemonInsertionTime=30
# Memory size expressed in MB per process (server and/or mirror) to cache the values.
DBDaemonMemorySize=120
# The percentage of the memory buffer used by the previous field, by each type. These types are: mpi, non-mpi and learning applications, loops, energy metrics and aggregations and events, in that order. If a type gets 0% of space, this metric is discarded and not saved into the database.
#
# The percentage of the memory buffer used by the previous field, by each type.
# These types are: mpi, non-mpi and learning applications, loops, energy metrics and aggregations and events, in that order. If a type gets 0% of space, this metric is discarded and not saved into the database.
#
#DBDaemonMemorySizePerType=40,20,5,24,5,1,5
# When set to 1, the output is saved in 'TmpDir'/eardbd.log (common configuration) as a log file.
DBDaemonUseLog=1
#---------------------------------------------------------------------------------------------------
# EAR Library (EARL): These options modify internal EARL behaviour. Do not modify except you are an expert
# EAR Library (EARL): These options modify internal EARL behaviour. Do not modify except you are an expert.
#---------------------------------------------------------------------------------------------------
CoefficientsDir=@sysconfdir@/ear/coeffs
# Default power policy values
......@@ -63,23 +70,26 @@ MinTimePerformanceAccuracy=10000000
# DynAIS configuration
DynAISLevels=10
DynAISWindowSize=200
# Maximum time (in seconds) EAR will wait until a signature is computed. After 'DynaisTimeout
# seconds', if no signature is computed, EAR will go to periodic mode.
#
# Maximum time (in seconds) EAR will wait until a signature is computed.
# After 'DynaisTimeout' seconds, if no signature is computed, EAR will go to periodic mode.
#
DynaisTimeout=15
# When EAR goes to periodic mode, it will compute the app. signature every 'LibraryPeriod' seconds.
# When EAR goes to periodic mode, it will compute the application signature every 'LibraryPeriod' seconds.
LibraryPeriod=10
# EAR will check every N mpi calls whether it must go to periodic mode or not.
CheckEARModeEvery=1000
#---------------------------------------------------------------------------------------------------
# EAR Global Manager (EARGMD): Update that section to use EARGM
# EAR Global Manager (EARGMD): Update that section to use EARGM.
#---------------------------------------------------------------------------------------------------
EARGMHost=node1001
# Use aggregated periodic metrics or periodic power metrics. Aggregated metrics are only available
# when EARDBD is running
#
# Use aggregated periodic metrics or periodic power metrics.
# Aggregated metrics are only available when EARDBD is running.
#
EARGMUseAggregated=1
# Period T1 and T2 are specified in seconds T1 (ex. must be less than T2, ex. 10min and 1 month)
# Period T1 and T2 are specified in seconds (ex. T1 must be less than T2, ex. 10min and 1 month).
EARGMPeriodT1=90
EARGMPeriodT2=259200
# '-' are Joules, 'K' KiloJoules and 'M' MegaJoules.
......@@ -88,7 +98,7 @@ EARGMEnergyLimit=550000
EARGMPort=50000
# Two modes are supported '0=manual' and '1=automatic'.
EARGMMode=0
# Email address to report the warning level (and the action taken in automatic mode)
# Email address to report the warning level (and the action taken in automatic mode).
EARGMMail=nomail
# Percentage of accumulated energy to start the warning DEFCON level L4, L3 and L2.
EARGMWarningsPerc=85,90,95
......@@ -98,23 +108,28 @@ EARGMGracePeriods=3
EARGMVerbose=1
# When set to 1, the output is saved in 'TmpDir'/eargmd.log (common configuration) as a log file.
EARGMUseLog=1
#
# Format for action is: command_name energy_T1 energy_T2 energy_limit T2 T1 units "
# This action is automatically executed at each warning level (only once per grace periods)
# This action is automatically executed at each warning level (only once per grace periods).
#
EARGMEnergyAction=no_action
#### POWERCAP definition for EARGM: Powercap is still under development. Do not activate
#### POWERCAP definition for EARGM: Powercap is still under development. Do not activate.
# 0 means no powercap
EARGMPowerLimit=0
# Period at which the powercap thread is activated
# Period at which the powercap thread is activated.
EARGMPowerPeriod=120
# 1 means automatic, 0 is only monitoring
# 1 means automatic, 0 is only monitoring.
EARGMPowerCapMode=1
# Admins can specify to automatically execute a command in EARGMPowerCapSuspendAction when total_power >= EARGMPowerLimit*EARGMPowerCapResumeLimit/100
EARGMPowerCapSuspendLimit=90
# Format for action is: command_name current_power current_limit total_idle_nodes total_idle_power
EARGMPowerCapSuspendAction=no_action
#
# Admins can specify to automatically execute a command in EARGMPowerCapResumeAction to undo EARGMPowerCapSuspendAction
# when total_power >= EARGMPowerLimit*EARGMPowerCapResumeLimit/100. Note that this will only be executed if a suspend action was executed previously.
# when total_power >= EARGMPowerLimit*EARGMPowerCapResumeLimit/100.
# Note that this will only be executed if a suspend action was executed previously.
#
EARGMPowerCapResumeLimit=40
# Format for action is: command_name current_power current_limit total_idle_nodes total_idle_power
EARGMPowerCapResumeAction=no_action
......@@ -126,12 +141,14 @@ TmpDir=@localstatedir@
EtcDir=@sysconfdir@
InstDir=@prefix@
Verbose=0
# Network extension (using another network instead of the local one). If compute nodes must be accessed from login nodes with a network different than default, and can be accesed using a expension, uncommmet next line and define 'netext' accordingly.
# NetworkExtension=netext
# Network extension (using another network instead of the local one).
# If compute nodes must be accessed from login nodes with a network different than default,
# and can be accesed using a expension, uncommmet next line and define 'netext' accordingly.
#NetworkExtension=netext
#---------------------------------------------------------------------------------------------------
# Plugin configuration. These values are used for the whole cluster except a specific configuration is
# explicitly applied to one tag. They are mandatory since they are used by default
# explicitly applied to one tag. They are mandatory since they are used by default.
#---------------------------------------------------------------------------------------------------
## Energy readings sources: List of plugins available at $EAR_INSTALL_PATH/lib/plugins/energy
energy_plugin=energy_nm.so
......@@ -143,8 +160,10 @@ powercap_plugin=dvfs.so
#---------------------------------------------------------------------------------------------------
# Authorized Users
#---------------------------------------------------------------------------------------------------
# Authorized users,accounts and groups are allowed to change policies, thresholds, frequencies etc,
# they are supposed to be admins, all special name is supported
#
# Authorized users,accounts and groups are allowed to change policies, thresholds, frequencies, etc.
# They are supposed to be admins, all special name is supported.
#
AuthorizedUsers=usr1,usr2
AuthorizedAccounts=acc1,acc2,acc3
AuthorizedGroups=grp1,grp2
......@@ -166,20 +185,20 @@ Tag=6126 max_avx512=2.3 max_avx2=2.9 ceffs=coeffs.6126.default max_power=600 err
## Power policies
## ---------------------------------------------------------------------------------------------------
#
## policy names must be exactly file names for policies installeled in the system
## Policy names must be exactly file names for policies installeled in the system.
DefaultPowerPolicy=min_time
Policy=monitoring Settings=0 DefaultFreq=2.4 Privileged=0
Policy=min_time Settings=0.7 DefaultFreq=2.0 Privileged=0
Policy=min_energy Settings=0.05 DefaultFreq=2.4 Privileged=1
# For homogeneous systems, default frequencies can be easily specified using freqs, for heterogeneous systems it is preferred to use pstates or use tags
# Example with pstates (lower pstates corresponds with higher frequencies). Pstate=1 is nominal and 0 is turbo
#
# For homogeneous systems, default frequencies can be easily specified using freqs.
# For heterogeneous systems it is preferred to use pstates or use tags
#
# Example with pstates (lower pstates corresponds with higher frequencies). Pstate=1 is nominal and 0 is turbo.
#Policy=monitoring Settings=0 DefaultPstate=1 Privileged=0
#Policy=min_time Settings=0.7 DefaultPstate=4 Privileged=0
#Policy=min_energy Settings=0.05 DefaultPstate=1 Privileged=1
#Example with tags
#Policy=monitoring Settings=0 DefaultFreq=2.6 Privileged=0 tag=6126
#Policy=min_time Settings=0.7 DefaultFreq=2.1 Privileged=0 tag=6126
......@@ -191,18 +210,21 @@ Policy=min_energy Settings=0.05 DefaultFreq=2.4 Privileged=1
#---------------------------------------------------------------------------------------------------
# Energy Tags
#---------------------------------------------------------------------------------------------------
# Privileged users,accounts and groups are allowed to use EnergyTags. The "allowed" TAGs are defined
# by row together with the priviledged user/group/account.
#
# Privileged users, accounts and groups are allowed to use EnergyTags.
# The "allowed" TAGs are defined by row together with the priviledged user/group/account.
#
EnergyTag=cpu-intensive pstate=1
EnergyTag=memory-intensive pstate=4 users=usr1,usr2 groups=grp1,grp2 accounts=acc1,acc2
#---------------------------------------------------------------------------------------------------
# Node Isles
#---------------------------------------------------------------------------------------------------
# It is mandatory to specify all the nodes in the cluster, grouped by islands. More than one line
# per island must be supported to hold nodes with different names or for pointing to different
# EARDBDs through its IPs or hostnames.
#
#
# In the following example the nodes are clustered in two different islands, but the Island 1 have
# two types of EARDBDs configurations.
......@@ -210,11 +232,11 @@ EnergyTag=memory-intensive pstate=4 users=usr1,usr2 groups=grp1,grp2 accounts=ac
Island=0 Nodes=node10[01-80] DBIP=node1081 DBSECIP=node1082
# These nodes are in island0 using different DB connections and with a different architecture
# These nodes are in island0 using different DB connections and with a different architecture.
Island=0 Nodes=node11[01-80] DBIP=node1084 DBSECIP=node1085 tag=6126
# These nodes are is island0 and will use default values for DB connection (line 0 for island0) and default tag
# These nodes are is island0 and will use default values for DB connection (line 0 for island0) and default tag.
Island=0 Nodes=node12[01-80]
# Will use default tag
# Will use default tag.
Island=1 Nodes=node11[01-80] DBIP=node1181 DBSECIP=node1182
......@@ -688,6 +688,7 @@ void print_short_apps(application_t *apps, int num_apps, int fd)
gpu_power /= current_apps;
gpu_freq /= current_apps;
gpu_util /= current_apps;
gpu_mem_util /= current_apps;
}
#endif
......
......@@ -111,6 +111,8 @@ void fill_ip(char *buff, ip_table_t *table)
s = getaddrinfo(buff, NULL, &hints, &result);
if (s != 0) {
debug("getaddrinfo fails for node %s (%s)\n", buff, strerror(errno));
table->ip_int = 0;
strcpy(table->ip, "invalid node");
return;
}
......@@ -283,9 +285,12 @@ void usage(char *app)
"\n\t\t\t\t\t\t\t after the increase value to only target said node."\
"\n\t--red-powercap\t[reduction]\t\t->Reduces the powercap of all nodes. A node can be specified"\
"\n\t\t\t\t\t\t\t after the reduction value to only target said node."\
"\n\t--inc-th \t[new_th] [pol_name]\t->increases the threshold for all nodes"\
"\n\t--set-th \t[new_th] [pol_name]\t->sets the threshold for all nodes"\
"\n\t--red-def-freq \t[n_pstates]\t\t->reduces the default and max frequency by n pstates");
"\n\t--inc-th \t[new_th] [pol_name]\t->increases the threshold for all nodes"\
"\n\t--set-th \t[new_th] [pol_name]\t->sets the threshold for all nodes"\
"\n\t--red-def-freq \t[n_pstates]\t\t->reduces the default and max frequency by n pstates"\
"\n\t--set-risk \t[level] [target] [node]\t->sends a warning to all nodes or the a specific node (optional)"\
"\n\t\t\t\t\t\t\t->levels: WARNING1/WARNING2/PANIC \ttarget: ENERGY/POWER");
#endif
printf("\n\nThis app requires privileged access to execute.\n");
exit(0);
......@@ -790,21 +795,24 @@ int main(int argc, char *argv[])
printf("Warning: specified type is invalid (%s)\n", optarg);
break;
case 'r':
if (optarg)
arg = get_risk(optarg);
if (optind + 1 > argc)
{
arg = atoi(optarg);
if (optind+1 > argc)
{
printf("Sending risk level %d to all nodes\n", arg);
printf("Error: --set-risk requires at least two arguments (level and target)\n");
break;
}
else {
arg2 = get_target(argv[optind]);
if (optind + 2 > argc) {
set_risk_all_nodes(arg, arg2, &my_cluster_conf);
break;
}
int rc = eards_remote_connect(argv[optind], my_cluster_conf.eard.port);
if (rc < 0){
printf("Error connecting with node %s\n", argv[optind]);
}else{
printf("Sending risk level %d to %s\n", arg, argv[optind]);
eards_set_risk(arg, 0);
int rc = eards_remote_connect(argv[optind+1], my_cluster_conf.eard.port);
if (rc < 0) {
printf("Error connecting with node %s\n", argv[optind+1]);
} else {
printf("Sending risk level %d to %s\n", arg, argv[optind+1]);
eards_set_risk(arg, arg2);
eards_remote_disconnect();
}
}
......
......@@ -48,6 +48,9 @@
#define DEF_POWER_CAP -1
#define POWER_CAP_TYPE "node"
/* When set to 1, powercap events will be reported to database */
#define REPORT_POWERCAP 0
/* These definitions affects to the output generated by services EAR services
* When set to 1, some warning messages and written at syslog explicitly */
#define SYSLOG_MSG 1
......
......@@ -48,6 +48,9 @@
#define DEF_POWER_CAP -1
#define POWER_CAP_TYPE "node"
/* When set to 1, powercap events will be reported to database */
#define REPORT_POWERCAP 0
/* These definitions affects to the output generated by services EAR services
* When set to 1, some warning messages and written at syslog explicitly */
#define SYSLOG_MSG 1
......
......@@ -98,7 +98,7 @@
#define SCHED_TRY_TURBO "SLURM_TRY_TURBO"
#define SCHED_LOAD_BALANCE_TH "SLURM_LOAD_BALANCE_TH"
#define SCHED_EAR_REPORT_ADD "SLURM_EAR_REPORT_ADD"
#define SCHED_USE_ENERGY_MODELS "SLURM_USE_ENERGY_MODELS"
#define SCHED_USE_ENERGY_MODELS "SLURM_USE_ENERGY_MODELS"
......
......@@ -171,12 +171,14 @@ char *PERIODIC_METRIC_MYSQL_QUERY = PERIODIC_METRIC_QUERY_DETAIL;
long autoincrement_offset = 0;
void *xmalloc(size_t size)
#define xmalloc(size) _xmalloc(size, __FUNCTION__)
void *_xmalloc(size_t size, const char *caller_function)
{
void *ptr = malloc(size);
if (ptr == NULL)
{
error("Error allocationg memory (malloc fails), exiting");
error("%s: Error allocationg memory (malloc fails when trying to alloc %lu), exiting", caller_function, size);
exit(1);
}
return ptr;
......
This diff is collapsed.
......@@ -377,6 +377,7 @@ my_node_conf_t *get_my_node_conf(cluster_conf_t *my_conf, char *nodename)
n->energy_model = my_conf->tags[tag_id].energy_model;
n->powercap_plugin = my_conf->tags[tag_id].powercap_plugin;
n->powercap_gpu_plugin = my_conf->tags[tag_id].powercap_gpu_plugin;
n->coef_file = strlen(my_conf->tags[tag_id].coeffs) > 0 ? my_conf->tags[tag_id].coeffs : "coeffs.default";
......@@ -620,6 +621,7 @@ void set_default_tag_values(tag_t *tag)
strcpy(tag->energy_model, "");
strcpy(tag->energy_plugin, "");
strcpy(tag->powercap_plugin, "");
strcpy(tag->powercap_gpu_plugin, "");
}
......
......@@ -145,6 +145,10 @@ state_t TAG_parse_token(tag_t **tags_i, unsigned int *num_tags_i, char *line)
{
strcpy(tags[idx].powercap_plugin, value);
}
else if (!strcmp(key, "GPU_POWERCAP_PLUGIN"))
{
strcpy(tags[idx].powercap_gpu_plugin, value);
}
else if (!strcmp(key, "COEFFS"))
{
strcpy(tags[idx].coeffs, value);
......
......@@ -70,6 +70,7 @@ typedef struct my_node_conf
char *energy_plugin;
char *energy_model;
char *powercap_plugin;
char *powercap_gpu_plugin;
uint num_policies;
policy_conf_t *policies;
double min_sig_power;
......
......@@ -77,6 +77,7 @@ void log_report_eard_min_interval(uint secs)
void log_report_eard_powercap_event(uint usedb,uint useeardbd,job_id job,job_id sid,uint eventid,ulong value)
{
#if REPORT_POWERCAP
ear_event_t event;
event.timestamp=time(NULL);
......@@ -92,6 +93,7 @@ void log_report_eard_powercap_event(uint usedb,uint useeardbd,job_id job,job_id
}else{
debug("jid %lu sid %lu event type %u value %lu",job,sid,eventid,value);
}
#endif
}
void log_report_eard_rt_error(uint usedb,uint useeardbd,job_id job,job_id sid,uint eventid,ulong value)
......
/*
*
* This program is part of the EAR software.
*
* EAR provides a dynamic, transparent and ligth-weigth solution for
* Energy management. It has been developed in the context of the
* Barcelona Supercomputing Center (BSC)&Lenovo Collaboration project.
*
* Copyright © 2017-present BSC-Lenovo
* BSC Contact mailto:ear-support@bsc.es
* Lenovo contact mailto:hpchelp@lenovo.com
*
* This file is licensed under both the BSD-3 license for individual/non-commercial
* use and EPL-1.0 license for commercial use. Full text of both licenses can be
* found in COPYING.BSD and COPYING.EPL files.
*/
*
* This program is part of the EAR software.
*
* EAR provides a dynamic, transparent and ligth-weigth solution for
* Energy management. It has been developed in the context of the
* Barcelona Supercomputing Center (BSC)&Lenovo Collaboration project.
*
* Copyright © 2017-present BSC-Lenovo
* BSC Contact mailto:ear-support@bsc.es
* Lenovo contact mailto:hpchelp@lenovo.com
*
* This file is licensed under both the BSD-3 license for individual/non-commercial
* use and EPL-1.0 license for commercial use. Full text of both licenses can be
* found in COPYING.BSD and COPYING.EPL files.
*/
#include <stdlib.h>
#include <string.h>
......@@ -39,56 +39,56 @@
int create_loop_id(loop_id_t *lid,ulong event, ulong size, ulong level)
{
if (lid!=NULL){
lid->event = event;
lid->size = size;
lid->level = level;
return EAR_SUCCESS;
}else return EAR_ERROR;
if (lid!=NULL){
lid->event = event;
lid->size = size;
lid->level = level;
return EAR_SUCCESS;
}else return EAR_ERROR;
}
int create_loop(loop_t *l)
{
if (l!=NULL)
{
l->jid=0;
l->step_id=0;
l->total_iterations=0;
memset(&l->signature,0,sizeof(signature_t));
return EAR_SUCCESS;
}else return EAR_ERROR;
if (l!=NULL)
{
l->jid=0;
l->step_id=0;
l->total_iterations=0;
memset(&l->signature,0,sizeof(signature_t));
return EAR_SUCCESS;
}else return EAR_ERROR;
}
int loop_init(loop_t *loop, job_t *job,ulong event, ulong size, ulong level)
{
int ret;
if ((ret=create_loop(loop))!=EAR_SUCCESS) return ret;
if ((ret=create_loop_id(&loop->id,event,size,level))!=EAR_SUCCESS) return ret;
loop->jid = job->id;
loop->step_id=job->step_id;
gethostname(loop->node_id,sizeof(loop->node_id));
strtok(loop->node_id,".");
return EAR_SUCCESS;
int ret;
if ((ret=create_loop(loop))!=EAR_SUCCESS) return ret;
if ((ret=create_loop_id(&loop->id,event,size,level))!=EAR_SUCCESS) return ret;
loop->jid = job->id;
loop->step_id=job->step_id;
gethostname(loop->node_id,sizeof(loop->node_id));
strtok(loop->node_id,".");
return EAR_SUCCESS;
}
void clean_db_loop(loop_t *loop, double limit)
{
if (loop->id.event > INT_MAX) loop->id.event = INT_MAX;
if (loop->id.size > INT_MAX) loop->id.size = INT_MAX;
if (loop->id.level > INT_MAX) loop->id.level = INT_MAX;
clean_db_signature(&loop->signature, limit);
if (loop->id.event > INT_MAX) loop->id.event = INT_MAX;
if (loop->id.size > INT_MAX) loop->id.size = INT_MAX;
if (loop->id.level > INT_MAX) loop->id.level = INT_MAX;
clean_db_signature(&loop->signature, limit);
}
int set_null_loop(loop_t *loop)
{
return create_loop(loop);
return create_loop(loop);
}
/** Returns true if the loop data is not, return -1 in case of error */
int is_null(loop_t *loop)
{
if (loop==NULL) return EAR_ERROR;
return (loop->total_iterations==0);
if (loop==NULL) return EAR_ERROR;
return (loop->total_iterations==0);
}
......@@ -115,141 +115,141 @@ void print_loop_id_fd(int fd, loop_id_t *loop_id)
void print_loop_fd(int fd, loop_t *loop)
{
dprintf(fd,"%lu;%lu;", loop->jid, loop->step_id);
dprintf(fd,"%lu;%lu;", loop->jid, loop->step_id);
print_loop_id_fd(fd, &loop->id);
signature_print_fd(fd, &loop->signature, 1);
dprintf(fd, "%lu\n", loop->total_iterations);
dprintf(fd, "%lu\n", loop->total_iterations);
}
int append_loop_text_file(char *path, loop_t *loop,job_t *job)
{
#if DB_FILES
#if DB_FILES
if (path == NULL) {
return EAR_ERROR;
}
char *HEADER = "NODENAME;USERNAME;JOB_ID;APPNAME;POLICY;POLICY_TH;AVG.CPUFREQ;AVG.IMC.FREQ;DEF.FREQ;" \
"TIME;CPI;TPI;GBS;IO_MBS;P.MPI;DC-NODE-POWER;DRAM-POWER;PCK-POWER;CYCLES;INSTRUCTIONS;GFLOPS;L1_MISSES;" \
"L2_MISSES;L3_MISSES;SP_SINGLE;SP_128;SP_256;SP_512;DP_SINGLE;DP_128;DP_256;" \
"DP_512;FIRST_EVENT;LEVEL;SIZE;ITERATIONS";
"TIME;CPI;TPI;GBS;IO_MBS;P.MPI;DC-NODE-POWER;DRAM-POWER;PCK-POWER;CYCLES;INSTRUCTIONS;GFLOPS;L1_MISSES;" \
"L2_MISSES;L3_MISSES;SP_SINGLE;SP_128;SP_256;SP_512;DP_SINGLE;DP_128;DP_256;" \
"DP_512;FIRST_EVENT;LEVEL;SIZE;ITERATIONS";
int fd, ret;
fd = open(path, O_WRONLY | O_APPEND);
if (fd < 0)
{
if (errno == ENOENT)
{
fd = open(path, OPTIONS, PERMISSION);
// Write header
if (fd >= 0) {
ret = dprintf(fd, "%s\n", HEADER);
}
}
}
if (fd < 0) {
return EAR_ERROR;
}
assert(loop!=NULL);
assert(loop->node_id!=NULL);
if (errno == ENOENT)
{
fd = open(path, OPTIONS, PERMISSION);
// Write header
if (fd >= 0) {
ret = dprintf(fd, "%s\n", HEADER);
}
}
}
if (fd < 0) {
return EAR_ERROR;
}
assert(loop!=NULL);
assert(loop->node_id!=NULL);
dprintf(fd, "%s;", loop->node_id);
print_job_fd(fd, job);
signature_print_fd(fd, &loop->signature,1);
print_loop_id_fd(fd, &loop->id);
dprintf(fd, "%lu\n", loop->total_iterations);