commit b47435992c6ef48df230168c9a3ff372eed71b03
parent 7624330c92d33ecf6bce87e0c5c7d1306b9bb407
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 26 Oct 2020 17:00:44 +0100
Improve warn/err reporting on settings
Diffstat:
| M | src/green-compute.c | | | 222 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
1 file changed, 132 insertions(+), 90 deletions(-)
diff --git a/src/green-compute.c b/src/green-compute.c
@@ -23,6 +23,7 @@
#include <rsys/logger.h>
#include <rsys/text_reader.h>
#include <rsys/dynamic_array.h>
+#include <rsys/mem_allocator.h>
#include <math.h>
#include <string.h>
@@ -39,43 +40,32 @@ enum log_record_type {
struct log_record {
enum log_record_type type;
+ int line_num, var_num;
struct str name;
const char* keep_line;
double default_value;
+ struct mem_allocator* allocator;
};
-static FINLINE void
-log_record_init
- (struct mem_allocator* allocator,
- struct log_record* data)
-{
- data->type = RECORD_TYPES_UNDEF__;
- data->keep_line = NULL;
- data->default_value = INF;
- str_init(allocator, &data->name);
-}
-
-static FINLINE res_T
-log_record_copy
- (struct log_record* dst,
- struct log_record const* src)
-{
- dst->type = src->type;
- dst->keep_line = src->keep_line;
- dst->default_value = src->default_value;
- return str_copy(&dst->name, &src->name);
-}
-
-
static FINLINE res_T
-log_record_copy_and_release
- (struct log_record* dst,
- struct log_record* src)
+log_record_create
+ (struct mem_allocator* allocator,
+ const enum log_record_type type,
+ struct log_record** out_record)
{
- dst->type = src->type;
- dst->keep_line = src->keep_line;
- dst->default_value = src->default_value;
- return str_copy_and_release(&dst->name, &src->name);
+ struct log_record* record;
+ ASSERT(allocator && out_record);
+ record = MEM_ALLOC(allocator, sizeof(*record));
+ if(!record) return RES_MEM_ERR;
+ record->type = type;
+ record->line_num = UINT_MAX;
+ record->var_num = UINT_MAX;
+ record->keep_line = NULL;
+ record->default_value = INF;
+ str_init(allocator, &record->name);
+ record->allocator = allocator;
+ *out_record = record;
+ return RES_OK;
}
static FINLINE void
@@ -83,14 +73,11 @@ log_record_release
(struct log_record* data)
{
str_release(&data->name);
+ MEM_RM(data->allocator, data);
}
#define DARRAY_NAME logs
-#define DARRAY_DATA struct log_record
-#define DARRAY_FUNCTOR_INIT log_record_init
-#define DARRAY_FUNCTOR_COPY log_record_copy
-#define DARRAY_FUNCTOR_COPY_AND_RELEASE log_record_copy_and_release
-#define DARRAY_FUNCTOR_RELEASE log_record_release
+#define DARRAY_DATA struct log_record*
#include <rsys/dynamic_array.h>
void
@@ -335,6 +322,18 @@ green_compute_1
*STD = (V > 0) ? sqrt(V / (double)green->counts.ok_count) : 0;
}
+static int
+cmp_records
+ (void const* r1, void const* r2)
+{
+ ASSERT(r1 && r2);
+ const struct log_record* record1 = *(struct log_record**)r1;
+ const struct log_record* record2 = *(struct log_record**)r2;
+ if(record1->line_num == record2->line_num)
+ return record1->var_num - record2->var_num;
+ return record1->line_num - record2->line_num;
+}
+
static void
do_log
(const char* file_name,
@@ -342,13 +341,20 @@ do_log
struct darray_logs* logs)
{
size_t i;
+ int prev_line_num = INT_MAX;
enum log_type log_type = LOG_WARNING;
ASSERT(file_name && green && logs);
if(darray_logs_size_get(logs) == 0) return;
+ /* Sort records by #line */
+ qsort(darray_logs_data_get(logs),
+ darray_logs_size_get(logs),
+ sizeof(*darray_logs_data_get(logs)),
+ cmp_records);
+
FOR_EACH(i, 0, darray_logs_size_get(logs)) {
- struct log_record* record = darray_logs_data_get(logs) + i;
+ struct log_record* record = darray_logs_data_get(logs)[i];
if(record->type & (RECORD_INVALID | RECORD_UNKNOWN)) {
log_type = LOG_ERROR;
break;
@@ -356,38 +362,71 @@ do_log
}
logger_print(green->logger, log_type, "In file '%s':\n", file_name);
FOR_EACH(i, 0, darray_logs_size_get(logs)) {
- struct log_record* record = darray_logs_data_get(logs) + i;
+ struct log_record* record = darray_logs_data_get(logs)[i];
switch (record->type) {
case RECORD_INVALID:
- logger_print(green->logger, LOG_ERROR,
- "In line '%s':\n\tInvalid data (missing name)\n",
- record->keep_line);
+ if(record->line_num != prev_line_num) {
+ logger_print(green->logger, LOG_ERROR,
+ "In line #%d: '%s':\n",
+ record->line_num, record->keep_line);
+ logger_print(green->logger, LOG_ERROR,
+ (str_is_empty(&record->name)
+ ? "Invalid data (missing name)\n" : "Invalid data (missing value)\n"));
+ } else
+ logger_print(green->logger, LOG_ERROR,
+ (str_is_empty(&record->name)
+ ? "Invalid data (missing name)\n" : "Invalid data (missing value)\n"));
break;
case RECORD_UNKNOWN:
- logger_print(green->logger, LOG_ERROR,
- "In line '%s':\n\tUnknown variable name: '%s'\n",
- record->keep_line, str_cget(&record->name));
+ if(record->line_num != prev_line_num) {
+ logger_print(green->logger, LOG_ERROR,
+ "In line #%d: '%s':\n",
+ record->line_num, record->keep_line);
+ logger_print(green->logger, LOG_ERROR,
+ "Unknown variable name: '%s'\n",
+ str_cget(&record->name));
+ } else
+ logger_print(green->logger, LOG_ERROR,
+ "\tUnknown variable name: '%s'\n",
+ str_cget(&record->name));
break;
case RECORD_UNUSED:
- logger_print(green->logger, LOG_WARNING,
- "In line '%s':\n\tAttempt to change unused variable '%s'.\n",
- record->keep_line, str_cget(&record->name));
+ if(record->line_num != prev_line_num) {
+ logger_print(green->logger, LOG_WARNING,
+ "In line #%d: '%s':\n",
+ record->line_num, record->keep_line);
+ logger_print(green->logger, LOG_WARNING,
+ "Attempt to change unused variable '%s'.\n",
+ str_cget(&record->name));
+ } else
+ logger_print(green->logger, LOG_WARNING,
+ "\tAttempt to change unused variable '%s'.\n",
+ str_cget(&record->name));
break;
case RECORD_DEFAULT:
- logger_print(green->logger, LOG_WARNING,
- "In line '%s':\n\tChange variable '%s' to its default value %g.\n",
- record->keep_line, str_cget(&record->name), record->default_value);
+ if(record->line_num != prev_line_num) {
+ logger_print(green->logger, LOG_WARNING,
+ "In line #%d: '%s':\n",
+ record->line_num, record->keep_line);
+ logger_print(green->logger, LOG_WARNING,
+ "Change variable '%s' to its default value %g.\n",
+ str_cget(&record->name), record->default_value);
+ } else
+ logger_print(green->logger, LOG_WARNING,
+ "Change variable '%s' to its default value %g.\n",
+ str_cget(&record->name), record->default_value);
break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
+ prev_line_num = record->line_num;
}
}
static res_T
parse_line
(const char* file_name,
- const int64_t idx,
+ const int idx,
struct green* green,
struct applied_settings_elt* settings,
struct darray_logs* logs)
@@ -395,11 +434,12 @@ parse_line
res_T res = RES_OK;
int name_count;
struct str name;
- char* tk = NULL;
+ char* tk_name = NULL;
+ char* tk_value = NULL;
char* tok_ctx = NULL;
const struct str* keep_line;
struct str line;
- ASSERT(file_name && green);
+ ASSERT(file_name && green && settings && logs && idx >= 0);
keep_line = darray_str_cdata_get(&green->settings) + idx;
str_init(green->allocator, &line);
@@ -410,66 +450,64 @@ parse_line
/* At least one name=value, no name without value */
for(name_count = 0; ; name_count++) {
struct variable_data* vd;
- struct log_record record;
+ struct log_record* record = NULL;
double prev;
if(res != RES_OK) goto error;
- record.keep_line = str_cget(keep_line); /* Just in case */
-
- tk = strtok_r(name_count ? NULL : str_get(&line), "=", &tok_ctx);
- if(tk) {
+ tk_name = strtok_r(name_count ? NULL : str_get(&line), "=", &tok_ctx);
+ if(tk_name) {
char* c;
- c = tk + strlen(tk) - 1;
- while(c >= tk && isspace(*tk)) tk++;
- while(c >= tk && isspace(*c)) {
+ c = tk_name + strlen(tk_name) - 1;
+ while(c >= tk_name && isspace(*tk_name)) tk_name++;
+ while(c >= tk_name && isspace(*c)) {
*c = '\0';
c--;
}
- if(c < tk) tk = NULL;
+ if(c < tk_name) tk_name = NULL;
}
- if(!tk) {
- if(name_count == 0) {
- /* At least 1 name */
- record.type = RECORD_INVALID;
- str_init(green->allocator, &record.name);
- res = RES_BAD_ARG;
- goto push_record;
- }
- else break;
+ tk_value = strtok_r(NULL, " \t", &tok_ctx);
+ if((tk_name == NULL) != (tk_value == NULL)) {
+ /* '<name> = <value>' or '' */
+ ERR(log_record_create(green->allocator, RECORD_INVALID, &record));
+ if(tk_name) ERR(str_set(&record->name, tk_name));
+ res = RES_BAD_ARG;
+ goto push_record;
}
- ERR(str_set(&name, tk));
- CHK_TOK(strtok_r(NULL, " \t", &tok_ctx), "value");
+ if(!tk_name) break; /* End of data */
+ /* Check name validity */
+ ERR(str_set(&name, tk_name));
vd = htable_variable_ptr_find(&green->variable_ptrs, &name);
if(!vd) {
- record.type = RECORD_UNKNOWN;
- str_init(green->allocator, &record.name);
- ERR(str_copy(&record.name, &name));
+ ERR(log_record_create(green->allocator, RECORD_UNKNOWN, &record));
+ ERR(str_set(&record->name, tk_name));
res = RES_BAD_ARG;
goto push_record;
}
if(!vd->used) {
- record.type = RECORD_UNUSED;
- str_init(green->allocator, &record.name);
- ERR(str_copy(&record.name, &name));
+ ERR(log_record_create(green->allocator, RECORD_UNUSED, &record));
+ ERR(str_set(&record->name, tk_name));
goto push_record;
}
/* Variable exists and is used in Green function: check if really changed */
prev = ((double*)settings)[vd->idx];
- ERR(cstr_to_double(tk, ((double*)settings) + vd->idx));
+ ERR(cstr_to_double(tk_value, ((double*)settings) + vd->idx));
if(prev == ((double*)settings)[vd->idx]) {
- record.type = RECORD_DEFAULT;
- str_init(green->allocator, &record.name);
- ERR(str_copy(&record.name, &name));
- record.default_value = prev;
+ ERR(log_record_create(green->allocator, RECORD_DEFAULT, &record));
+ ERR(str_set(&record->name, tk_name));
+ record->default_value = prev;
goto push_record;
}
continue;
push_record:
#pragma omp critical
{
- res_T tmp_res = darray_logs_push_back(logs, &record);
- str_release(&record.name);
+ res_T tmp_res;
+ ASSERT(record && record->type != RECORD_TYPES_UNDEF__);
+ record->line_num = idx;
+ record->var_num = name_count;
+ record->keep_line = str_cget(keep_line);
+ tmp_res = darray_logs_push_back(logs, &record);
if(res == RES_OK) res = tmp_res;
}
}
@@ -488,14 +526,14 @@ green_compute
const char* in_name)
{
res_T res = RES_OK;
- size_t sz;
- int64_t i;
+ size_t sz, n;
+ int i;
struct applied_settings_elt** settings = NULL;
struct darray_logs logs;
ASSERT(green && in_name);
sz = darray_str_size_get(&green->settings);
- ASSERT(sz < INT64_MAX);
+ ASSERT(sz < INT_MAX);
settings = MEM_CALLOC(green->allocator, green->nthreads, sizeof(*settings));
if(settings == NULL) {
@@ -506,7 +544,7 @@ green_compute
omp_set_num_threads((int)green->nthreads);
#pragma omp parallel for schedule(static)
- for(i = 0; i < (int64_t)sz; i++) {
+ for(i = 0; i < (int)sz; i++) {
struct result* result = darray_result_data_get(&green->results) + i;
res_T tmp_res = RES_OK;
int t = omp_get_thread_num();
@@ -538,9 +576,13 @@ green_compute
exit:
do_log(in_name, green, &logs);
if(settings) {
- FOR_EACH(i, 0, green->nthreads) MEM_RM(green->allocator, settings[i]);
+ FOR_EACH(n, 0, green->nthreads) MEM_RM(green->allocator, settings[n]);
MEM_RM(green->allocator, settings);
}
+ FOR_EACH(n, 0, darray_logs_size_get(&logs)) {
+ struct log_record* record = darray_logs_data_get(&logs)[n];
+ log_record_release(record);
+ }
darray_logs_release(&logs);
return res;
error: