From f0a067e93124e05327ad8888b9d5bbd4ebe2b85e Mon Sep 17 00:00:00 2001 From: ploc <ploc@garoche.net> Date: Fri, 15 Mar 2019 14:14:18 -0700 Subject: [PATCH] Better production of trace files. By default traces are not produced. Requires the option -t to produce them --- include/io_frontend.c | 25 +++------- include/io_frontend.h | 14 +++--- include/io_frontend.hpp | 25 +++------- src/backends/C/c_backend_common.ml | 77 +++++++++++++++++++++++------- src/backends/C/c_backend_main.ml | 77 +++++++++++++++++++++++------- src/plugins/scopes/scopes.ml | 34 ++++++++----- 6 files changed, 163 insertions(+), 89 deletions(-) diff --git a/include/io_frontend.c b/include/io_frontend.c index 8984b3ce..1ea3db2c 100644 --- a/include/io_frontend.c +++ b/include/io_frontend.c @@ -6,7 +6,7 @@ int ISATTY; /* Standard Input procedures **************/ -_Bool _get_bool(FILE* file, char* n){ +_Bool _get_bool(char* n){ char b[512]; int r = 0; int s = 1; @@ -22,11 +22,10 @@ _Bool _get_bool(FILE* file, char* n){ if((c == '0') || (c == 'f') || (c == 'F')) r = 0; if((c == '1') || (c == 't') || (c == 'T')) r = 1; } while((s != 1) || (r == -1)); - fprintf(file, "%i\n",r); return (_Bool)r; } -int _get_int(FILE* file, char* n){ +int _get_int(char* n){ char b[512]; int r; int s = 1; @@ -38,11 +37,10 @@ int _get_int(FILE* file, char* n){ if(scanf("%s", b)==EOF) exit(0); s = sscanf(b, "%d", &r); } while(s != 1); - fprintf(file, "%d\n", r); return r; } -double _get_double(FILE* file, char* n){ +double _get_double(char* n){ char b[512]; double r; int s = 1; @@ -54,11 +52,10 @@ double _get_double(FILE* file, char* n){ if(scanf("%s", b)==EOF) exit(0); s = sscanf(b, "%lf", &r); } while(s != 1); - fprintf(file, "%f\n", r); return r; } /* Standard Output procedures **************/ -void _put_bool(FILE* file, char* n, _Bool _V){ +void _put_bool(char* n, _Bool _V){ if(ISATTY) { printf("%s = ", n); } else { @@ -66,10 +63,8 @@ void _put_bool(FILE* file, char* n, _Bool _V){ }; printf("'%i' ", (_V)? 1 : 0); printf("\n"); - fprintf(file, "%i\n", _V); - fflush(file); } -void _put_int(FILE* file, char* n, int _V){ +void _put_int(char* n, int _V){ if(ISATTY) { printf("%s = ", n); } else { @@ -77,11 +72,9 @@ void _put_int(FILE* file, char* n, int _V){ }; printf("'%d' ", _V); printf("\n"); - fprintf(file, "%d\n", _V); - fflush(file); } -void _put_float(FILE* file, char* n, float _V, int PREC){ +void _put_float(char* n, float _V, int PREC){ if(ISATTY) { printf("%s = ", n); } else { @@ -89,11 +82,9 @@ void _put_float(FILE* file, char* n, float _V, int PREC){ }; printf("'%.*f' ", PREC, _V); printf("\n"); - fprintf(file, "%.*f\n", PREC, _V); - fflush(file); } -void _put_double(FILE* file, char* n, double _V, int PREC){ +void _put_double(char* n, double _V, int PREC){ if(ISATTY) { printf("%s = ", n); } else { @@ -101,6 +92,4 @@ void _put_double(FILE* file, char* n, double _V, int PREC){ }; printf("'%.*f' ", PREC, _V); printf("\n"); - fprintf(file, "%.*f\n", PREC, _V); - fflush(file); } diff --git a/include/io_frontend.h b/include/io_frontend.h index 09084965..a7b75519 100644 --- a/include/io_frontend.h +++ b/include/io_frontend.h @@ -7,25 +7,25 @@ extern int ISATTY; /* Standard Input procedures **************/ /*@ assigns *n; */ -extern _Bool _get_bool(FILE* file, char* n); +extern _Bool _get_bool(char* n); /*@ assigns *n; */ -extern int _get_int(FILE* file, char* n); +extern int _get_int(char* n); /*@ assigns *n; */ -extern double _get_double(FILE* file, char* n); +extern double _get_double(char* n); /* Standard Output procedures **************/ /*@ assigns \nothing; */ -extern void _put_bool(FILE* file, char* n, _Bool _V); +extern void _put_bool(char* n, _Bool _V); /*@ assigns \nothing; */ -extern void _put_int(FILE* file, char* n, int _V); +extern void _put_int(char* n, int _V); /*@ assigns \nothing; */ -extern void _put_float(FILE* file, char* n, float _V, int PREC); +extern void _put_float(char* n, float _V, int PREC); /*@ assigns \nothing; */ -extern void _put_double(FILE* file, char* n, double _V, int PREC); +extern void _put_double(char* n, double _V, int PREC); #endif diff --git a/include/io_frontend.hpp b/include/io_frontend.hpp index b02385e2..3c15747e 100644 --- a/include/io_frontend.hpp +++ b/include/io_frontend.hpp @@ -8,7 +8,7 @@ int ISATTY; /* Standard Input procedures **************/ -bool _get_bool(FILE* file, char* n){ +bool _get_bool(char* n){ char b[512]; bool r = 0; int s = 1; @@ -24,11 +24,10 @@ bool _get_bool(FILE* file, char* n){ if((c == '0') || (c == 'f') || (c == 'F')) r = 0; if((c == '1') || (c == 't') || (c == 'T')) r = 1; } while((s != 1) || (r == -1)); - fprintf(file, "%i\n",r); return r; } -int _get_int(FILE* file, char* n){ +int _get_int(char* n){ char b[512]; int r; int s = 1; @@ -40,11 +39,10 @@ int _get_int(FILE* file, char* n){ if(scanf("%s", b)==EOF) exit(0); s = sscanf(b, "%d", &r); } while(s != 1); - fprintf(file, "%d\n", r); return r; } -double _get_double(FILE* file, char* n){ +double _get_double(char* n){ char b[512]; double r; int s = 1; @@ -56,32 +54,27 @@ double _get_double(FILE* file, char* n){ if(scanf("%s", b)==EOF) exit(0); s = sscanf(b, "%lf", &r); } while(s != 1); - fprintf(file, "%f\n", r); return r; } /* Standard Output procedures **************/ -void _put_bool(FILE* file, char* n, bool _V){ +void _put_bool(char* n, bool _V){ if(ISATTY) { printf("%s = ", n); } else { printf("'%s': ", n); }; printf("'%i' ", (_V)? 1 : 0); - printf("\n"); - fprintf(file, "%i\n", _V); } -void _put_int(FILE* file, char* n, int _V){ +void _put_int(char* n, int _V){ if(ISATTY) { printf("%s = ", n); } else { printf("'%s': ", n); }; printf("'%d' ", _V); - printf("\n"); - fprintf(file, "%d\n", _V); } -void _put_float(FILE* file, char* n, float _V, int PREC){ +void _put_float(char* n, float _V, int PREC){ if(ISATTY) { printf("%s = ", n); } else { @@ -89,11 +82,9 @@ void _put_float(FILE* file, char* n, float _V, int PREC){ }; printf("'%.*f' ", PREC, _V); printf("\n"); - fprintf(file, "%.*f\n", PREC, _V); - fflush(file); } -void _put_double(FILE* file, char* n, double _V, int PREC){ +void _put_double(char* n, double _V, int PREC){ if(ISATTY) { printf("%s = ", n); } else { @@ -101,8 +92,6 @@ void _put_double(FILE* file, char* n, double _V, int PREC){ }; printf("'%.*f' ", PREC, _V); printf("\n"); - fprintf(file, "%.*f\n", PREC, _V); - fflush(file); } diff --git a/src/backends/C/c_backend_common.ml b/src/backends/C/c_backend_common.ml index 11e823e1..fbeade98 100644 --- a/src/backends/C/c_backend_common.ml +++ b/src/backends/C/c_backend_common.ml @@ -705,34 +705,57 @@ let pp_instance_call m self fmt i (inputs: Machine_code_types.value_t list) (out (*** Common functions for main ***) +let pp_print_file file_suffix fmt typ arg = + fprintf fmt "@[<v 2>if (traces) {@ "; + fprintf fmt "fprintf(f_%s, \"%%%s\\n\", %s);@ " file_suffix typ arg; + fprintf fmt "fflush(f_%s);@ " file_suffix; + fprintf fmt "@]}@ " + let print_put_var fmt file_suffix name var_type var_id = + let pp_file = pp_print_file ("out" ^ file_suffix) in let unclocked_t = Types.unclock_type var_type in - if Types.is_int_type unclocked_t then - fprintf fmt "_put_int(f_out%s, \"%s\", %s)" file_suffix name var_id - else if Types.is_bool_type unclocked_t then - fprintf fmt "_put_bool(f_out%s, \"%s\", %s)" file_suffix name var_id + if Types.is_int_type unclocked_t then ( + fprintf fmt "_put_int(\"%s\", %s);@ " name var_id; + pp_file fmt "d" var_id + ) + else if Types.is_bool_type unclocked_t then ( + fprintf fmt "_put_bool(\"%s\", %s);@ " name var_id; + pp_file fmt "i" var_id + ) else if Types.is_real_type unclocked_t then - if !Options.mpfr then - fprintf fmt "_put_double(f_out%s, \"%s\", mpfr_get_d(%s, %s), %i)" file_suffix name var_id (Mpfr.mpfr_rnd ()) !Options.print_prec_double - else - fprintf fmt "_put_double(f_out%s, \"%s\", %s, %i)" file_suffix name var_id !Options.print_prec_double + let _ = + if !Options.mpfr then + fprintf fmt "_put_double(\"%s\", mpfr_get_d(%s, %s), %i);@ " name var_id (Mpfr.mpfr_rnd ()) !Options.print_prec_double + else + fprintf fmt "_put_double(\"%s\", %s, %i);@ " name var_id !Options.print_prec_double + in + pp_file fmt ".*f" ((string_of_int !Options.print_prec_double) ^ ", " ^ var_id) else (Format.eprintf "Impossible to print the _put_xx for type %a@.@?" Types.print_ty var_type; assert false) let print_get_inputs fmt m = let pi fmt (id, v', v) = - + let pp_file = pp_print_file ("in" ^ (string_of_int id)) in let unclocked_t = Types.unclock_type v.var_type in - if Types.is_int_type unclocked_t then - fprintf fmt "%s = _get_int(f_in%i, \"%s\")" v.var_id id v'.var_id - else if Types.is_bool_type unclocked_t then - fprintf fmt "%s = _get_bool(f_in%i, \"%s\")" v.var_id id v'.var_id + if Types.is_int_type unclocked_t then ( + fprintf fmt "%s = _get_int(\"%s\");@ " v.var_id v'.var_id; + pp_file fmt "d" v.var_id + ) + else if Types.is_bool_type unclocked_t then ( + fprintf fmt "%s = _get_bool(\"%s\");@ " v.var_id v'.var_id; + pp_file fmt "i" v.var_id + ) else if Types.is_real_type unclocked_t then - if !Options.mpfr then - fprintf fmt "mpfr_set_d(%s, _get_double(f_in%i, \"%s\"), %i)" v.var_id id v'.var_id (Mpfr.mpfr_prec ()) - else - fprintf fmt "%s = _get_double(f_in%i, \"%s\")" v.var_id id v'.var_id + if !Options.mpfr then ( + fprintf fmt "double %s_tmp = _get_double(\"%s\");@ " v.var_id v'.var_id; + pp_file fmt "f" (v.var_id ^ "_tmp"); + fprintf fmt "mpfr_set_d(%s, %s_tmp, %i);" v.var_id v.var_id (Mpfr.mpfr_prec ()) + ) + else ( + fprintf fmt "%s = _get_double(\"%s\");@ " v.var_id v'.var_id; + pp_file fmt "f" v.var_id + ) else begin Global.main_node := !Options.main_node; @@ -743,10 +766,28 @@ let print_get_inputs fmt m = end in Utils.List.iteri2 (fun idx v' v -> - fprintf fmt "@ %a;" pi ((idx+1), v', v); + fprintf fmt "@ %a" pi ((idx+1), v', v); ) m.mname.node_inputs m.mstep.step_inputs +let pp_file_decl fmt inout idx = + let idx = idx + 1 in (* we start from 1: in1, in2, ... *) + fprintf fmt "FILE *f_%s%i;@ " inout idx + +let pp_file_open fmt inout idx = + let idx = idx + 1 in (* we start from 1: in1, in2, ... *) + fprintf fmt "const char* cst_char_suffix_%s%i = \"_simu.%s%i\";@ " inout idx inout idx; + fprintf fmt "size_t l%s%i = strlen(dir) + strlen(prefix) + strlen(cst_char_suffix_%s%i);@ " inout idx inout idx; + fprintf fmt "char* f_%s%i_name = malloc((l%s%i+2) * sizeof(char));@ " inout idx inout idx; + fprintf fmt "strcpy (f_%s%i_name, dir);@ " inout idx; + fprintf fmt "strcat(f_%s%i_name, \"/\");@ " inout idx; + fprintf fmt "strcat(f_%s%i_name, prefix);@ " inout idx; + fprintf fmt "strcat(f_%s%i_name, cst_char_suffix_%s%i);@ " inout idx inout idx; + fprintf fmt "f_%s%i = fopen(f_%s%i_name, \"w\");@ " inout idx inout idx; + fprintf fmt "free(f_%s%i_name);@ " inout idx; + "f_" ^ inout ^ (string_of_int idx) + + (* Local Variables: *) (* compile-command:"make -C ../../.." *) (* End: *) diff --git a/src/backends/C/c_backend_main.ml b/src/backends/C/c_backend_main.ml index 90f3862e..6d8bf847 100644 --- a/src/backends/C/c_backend_main.ml +++ b/src/backends/C/c_backend_main.ml @@ -40,24 +40,25 @@ let print_put_outputs fmt m = in List.iteri2 (fun idx v' v -> fprintf fmt "@ %a;" po ((idx+1), v', v)) m.mname.node_outputs m.mstep.step_outputs -let print_main_inout_declaration basename fmt m = - let mname = m.mname.node_id in - (* TODO: find a proper way to shorthen long names. This causes segfault in the binary when trying to fprintf in them *) - let mname = if String.length mname > 50 then string_of_int (Hashtbl.hash mname) else mname in + +let print_main_inout_declaration m fmt = fprintf fmt "/* Declaration of inputs/outputs variables */@ "; - List.iteri - (fun idx v -> + List.iteri (fun idx v -> fprintf fmt "%a;@ " (pp_c_type v.var_id) v.var_type; - fprintf fmt "FILE *f_in%i;@ " (idx+1); (* we start from 1: in1, in2, ... *) - fprintf fmt "f_in%i = fopen(\"%s_%s_simu.in%i\", \"w\");@ " (idx+1) basename mname (idx+1); + ignore (pp_file_decl fmt "in" idx) ) m.mstep.step_inputs; - List.iteri - (fun idx v -> + List.iteri (fun idx v -> fprintf fmt "%a;@ " (pp_c_type v.var_id) v.var_type; - fprintf fmt "FILE *f_out%i;@ " (idx+1); (* we start from 1: in1, in2, ... *) - fprintf fmt "f_out%i = fopen(\"%s_%s_simu.out%i\", \"w\");@ " (idx+1) basename mname (idx+1); - ) m.mstep.step_outputs - + ignore (pp_file_decl fmt "out" idx) + ) m.mstep.step_outputs; + fprintf fmt "@[<v 2>if (traces) {@ "; + List.iteri (fun idx _ -> + ignore (pp_file_open fmt "in" idx) + ) m.mstep.step_inputs; + List.iteri (fun idx _ -> + ignore (pp_file_open fmt "out" idx) + ) m.mstep.step_outputs; + fprintf fmt "@]}@ " let print_main_memory_allocation mname main_mem fmt m = @@ -122,22 +123,66 @@ let print_main_loop mname main_mem fmt m = fprintf fmt "@ /* Infinite loop */@ "; fprintf fmt "@[<v 2>while(1){@ "; fprintf fmt "fflush(stdout);@ "; + fprintf fmt "@[<v 2>if (traces) {@ "; List.iteri (fun idx _ -> fprintf fmt "fflush(f_in%i);@ " (idx+1)) m.mstep.step_inputs; List.iteri (fun idx _ -> fprintf fmt "fflush(f_out%i);@ " (idx+1)) m.mstep.step_outputs; + fprintf fmt "@]}@ "; fprintf fmt "%a@ %t%a" print_get_inputs m (fun fmt -> pp_main_call mname main_mem fmt m input_values m.mstep.step_outputs) print_put_outputs m end +let print_usage fmt = + fprintf fmt "@[<v 2>void usage(char *argv[]) {@ "; + fprintf fmt "printf(\"Usage: %%s\\n\", argv[0]);@ "; + fprintf fmt "printf(\" -t: produce trace files for input/output flows\\n\");@ "; + fprintf fmt "printf(\" -d<dir>: directory containing traces (default: _traces)\\n\");@ "; + fprintf fmt "printf(\" -p<prefix>: prefix_simu.scope<id> (default: file_node)\\n\");@ "; + fprintf fmt "exit (8);@ "; + fprintf fmt "@]}@ " + +let print_options fmt name = + fprintf fmt "int traces = 0;@ "; + fprintf fmt "char* prefix = \"%s\";@ " name; + fprintf fmt "char* dir = \".\";@ "; + fprintf fmt "@[<v 2>while ((argc > 1) && (argv[1][0] == '-')) {@ "; + fprintf fmt "@[<v 2>switch (argv[1][1]) {@ "; + fprintf fmt "@[<v 2>case 't':@ "; + fprintf fmt "traces = 1;@ "; + fprintf fmt "break;@ "; + fprintf fmt "@]@ "; + fprintf fmt "@[<v 2>case 'd':@ "; + fprintf fmt "dir = &argv[1][2];@ "; + fprintf fmt "break;@ "; + fprintf fmt "@]@ "; + fprintf fmt "@[<v 2>case 'p':@ "; + fprintf fmt "prefix = &argv[1][2];@ "; + fprintf fmt "break;@ "; + fprintf fmt "@]@ "; + fprintf fmt "@[<v 2>default:@ "; + fprintf fmt "printf(\"Wrong Argument: %%s\\n\", argv[1]);@ "; + fprintf fmt "usage(argv);@ "; + fprintf fmt "@]@ "; + fprintf fmt "@]}@ "; + fprintf fmt "++argv;@ "; + fprintf fmt "--argc;@ "; + fprintf fmt "@]}@ " + let print_main_code fmt basename m = let mname = m.mname.node_id in + (* TODO: find a proper way to shorthen long names. This causes segfault in the binary when trying to fprintf in them *) + let mname = if String.length mname > 50 then string_of_int (Hashtbl.hash mname) else mname in + let main_mem = if (!Options.static_mem && !Options.main_node <> "") then "&main_mem" else "main_mem" in + print_usage fmt; + fprintf fmt "@[<v 2>int main (int argc, char *argv[]) {@ "; - print_main_inout_declaration basename fmt m; + print_options fmt (basename ^ "_" ^ mname); + print_main_inout_declaration m fmt; Plugins.c_backend_main_loop_body_prefix basename mname fmt (); print_main_memory_allocation mname main_mem fmt m; if !Options.mpfr then @@ -158,7 +203,7 @@ let print_main_code fmt basename m = fprintf fmt "@]@ }@." let print_main_header fmt = - fprintf fmt (if !Options.cpp then "#include <stdio.h>@.#include <unistd.h>@.#include \"%s/io_frontend.hpp\"@." else "#include <stdio.h>@.#include <unistd.h>@.#include \"%s/io_frontend.h\"@.") + fprintf fmt (if !Options.cpp then "#include <stdio.h>@.#include <unistd.h>@.#include \"%s/io_frontend.hpp\"@." else "#include <stdio.h>@.#include <unistd.h>@.#include <string.h>@.#include \"%s/io_frontend.h\"@.") (Options_management.core_dependency "io_frontend") let print_main_c main_fmt main_machine basename prog machines _ (*dependencies*) = diff --git a/src/plugins/scopes/scopes.ml b/src/plugins/scopes/scopes.ml index a51196d9..2846911c 100644 --- a/src/plugins/scopes/scopes.ml +++ b/src/plugins/scopes/scopes.ml @@ -175,7 +175,7 @@ par ex main_mem->n8->n9->_reg.flow let extract_scopes_defs scopes = let rec scope_path_name (path, flow) accu = match path with - | [] -> accu ^ "_reg." ^ (scope_var_name flow.var_id), flow.var_type + | [] -> accu ^ "_reg." ^ (scope_var_name flow.var_id), flow | (_, _, Some instance_id)::tl -> scope_path_name (tl, flow) ( accu ^ instance_id ^ "->" ) | _ -> assert false in @@ -189,22 +189,32 @@ let extract_scopes_defs scopes = let pp_scopes_files basename mname fmt scopes = let scopes_vars = extract_scopes_defs scopes in - List.iteri (fun idx _ (* (id, (var, typ)) *) -> - Format.fprintf fmt "FILE *f_out_scopes_%i;@ " (idx+1); - (* we start from 1: in1, in2, ... *) - Format.fprintf fmt - "f_out_scopes_%i = fopen(\"%s_%s_simu.scope%i\", \"w\");@ " - (idx+1) basename mname (idx+1); - ) scopes_vars - + List.iteri (fun idx _(*(id, (var_path, var))*) -> + C_backend_common.pp_file_decl fmt "out_scopes" idx) + scopes_vars; + Format.fprintf fmt "@[<v 2>if (traces) {@ "; + List.iteri (fun idx (id, (var_path, var)) -> + let file = C_backend_common.pp_file_open fmt "out_scopes" idx in + Format.fprintf fmt + "fprintf(%s, \"# scope: %s\\n\");@ " + file id; + Format.fprintf fmt + "fprintf(%s, \"# node: %s\\n\");@ " + file (Utils.desome var.var_parent_nodeid); + Format.fprintf fmt + "fprintf(%s, \"# variable: %s\\n\");@ " + file var.var_id + ) scopes_vars; + Format.fprintf fmt "@]}@ " + let pp_scopes fmt scopes = let scopes_vars = extract_scopes_defs scopes in - List.iteri (fun idx (id, (var, typ)) -> + List.iteri (fun idx (id, (var_path, var)) -> Format.fprintf fmt "@ %t;" (fun fmt -> C_backend_common.print_put_var fmt - ("_scopes_" ^ string_of_int (idx+1)) - id (*var*) typ var) + ("_scopes" ^ string_of_int (idx+1)) + id (*var*) var.var_type var_path) ) scopes_vars (**********************************************************************) -- GitLab