26 #include "pips_config.h"
51 #define SIGMAC_INSTANTIATE(a, b) " agent " a " = new " b ";\n"
52 #define SIGMAC_CONNECT(a, b) " connect (" a ", " b ");\n"
53 #define REPLICATION_AGENT "rep"
105 for (i = 0; i < strlen(s); i++)
146 &k[5], &k[6], &k[7], &k[8]);
148 for (
int i = 0; i < 8; i++)
149 sb_prf(sb_par,
"%d, ", k[i]);
150 sb_prf(sb_par,
"%d }", k[8]);
165 &k[4], &k[5], &k[6], &k[7], &k[8]);
167 string row[3] = {
"olid",
"clid",
"ilid"};
171 "#define %s_%d(OPR)\t\t\t\t\\\n",
173 for (i = 0; i < 3; i++)
174 for (j = 0; j < 3; j++)
176 string neighbor =
strdup(
cat(
"buffer[", row[i],
"][i+",
i2a(j),
"]"));
177 sb_prf(sb_morpho,
"ret = PIXEL_ ## OPR(ret, %s);\t\\\n", neighbor,
180 sb_prf(sb_morpho,
"\nCUSTOM_MORPHO_AGENT(%s_%d, " PIXEL_T ")\n"
228 sb_prf(sb_par,
"// nb args for type %s : %d/%d, in %d, out %d\n",
230 gen_length(vtx_param_vars),
f->arg_misc_in,
f->arg_misc_out);
252 if (!dynamic_agent) {
263 sb_cat(sb_par,
"[9]",
" = ");
288 sb_cat(sbinst,
f->sigmac.agent_name);
293 sb_prf(sbinst,
"(%s",
f->sigmac.agent_arg);
296 if ((
f->arg_misc_in +
f->arg_misc_out) && hparams) {
298 sb_cat(sbinst,
", height");
309 sb_cat(sbinst,
", ", miscparams);
320 sb_cat(sbinst,
"dilate_");
322 sb_cat(sbinst,
"convole_");
354 int i, l = strlen(title);
358 for (i = 0; i < columns; i++)
364 int a = (columns - l - 2) / 2;
365 for (i = 0; i < a; i++)
371 for (i = 0; i < a; i++)
377 for (i = 0; i < columns; i++)
389 int n_imgs_input,
int n_imgs_output,
390 int n_params_input,
int n_params_output) {
391 sb_prf(
sb,
"subgraph\n%s\n", subgraph_name);
392 sb_cat(
sb,
"(char pipein[255],\n char pipeout[255],\n",
393 " int width,\n int height,\n size_t sizeMax,\n"
394 " char pipeparin[255],\n char pipeparout[255])\n"
400 if (n_imgs_input > 0) {
407 sb_cat(
sb,
" SigmaC_agent_setUnitType(strin,\"k1-I/O\");\n");
410 if (n_imgs_output > 0) {
412 "Launcher_Out(pipeout, %d, width, height)"),
417 sb_cat(
sb,
" SigmaC_agent_setUnitType(strout,\"k1-I/O\");\n");
421 if (n_params_input > 0) {
427 sb_prf(
sb,
" SigmaC_agent_setUnitType(sp,\"k1-I/O\");\n");
431 if (n_params_output > 0) {
437 sb_prf(
sb,
" SigmaC_agent_setUnitType(jo,\"k1-I/O\");\n");
446 static int dagvtx_sigmac_priority(
const dagvtx *pv1,
const dagvtx *pv2) {
447 const dagvtx v1 = *pv1, v2 = *pv2;
455 static int is_vtx_compound(
dagvtx vtx,
list lcomponents) {
456 unsigned int n_connex = 0;
464 return (n_connex ==
gen_length(lcomponents)) ? -1 : (
int)n_connex;
467 static list sigmac_get_component_outputs(
list lconnex,
dag dg) {
483 static list sigmac_get_component_inputs(
list lconnex,
dag dg) {
500 list inputs = sigmac_get_component_inputs(lconnex,
dg);
511 static list sigmac_get_mergeable_ops(
dag dg) {
527 hash_put(ht_merge, vtx, (
void *)nb_cc);
531 unsigned int min_thr = 2;
536 set set_connex[nb_cc];
537 for (
int i = 0; i < nb_cc; i++)
547 for (
int i = 0; i < nb_cc; i++) {
548 unsigned int p =
set_size(set_connex[i]);
549 unsigned int g = (p + max_thr - 1) / max_thr;
550 unsigned int thr = (g > 0) ? p / g + (p % g > 0) : 0;
551 thr = (thr > 1) ? thr : max_thr;
558 lresult =
CONS(
list, lconnex, lresult);
565 lresult =
CONS(
list, lconnex, lresult);
571 static int ncompound = 0;
574 int n_connex,
dag dg) {
575 list outputs = sigmac_get_component_outputs(lconnex,
dg);
576 list ext_inputs = sigmac_get_in_channels(lconnex,
dg);
577 unsigned int n_inputs =
gen_length(ext_inputs);
579 sb_prf(
sb,
"AGENT_MERGE_ARITH(agent_compound_%d_%d, " PIXEL_T, ncompound,
581 sb_prf(
sb,
", %d, %d, \n", n_inputs, n_outputs);
585 for (i = 0; i < n_inputs; i++)
618 if (i < api->arg_misc_in - 1)
646 int vtxconnex = is_vtx_compound(vtx, lcomponents);
650 _int succconnex = is_vtx_compound(succ, lcomponents);
651 if (vtxconnex != -1 && succconnex == vtxconnex)
654 else if (succconnex == -1) {
660 else if (succconnex != -1) {
663 used_components =
CONS(
int, succconnex, used_components);
679 sb_prf(succ_inst,
"strout.input[%d] /* %s */",
689 static void sigmac_compile_subgraph(
string module,
dag dg,
string fname,
690 int n_split, FILE *helper) {
691 fprintf(helper,
"// code module=%s fname=%s split=%d\n",
module, fname,
719 lcomponents = sigmac_get_mergeable_ops(
dg);
723 sigmac_generate_compound_agent(sb_cpd, lconnex, n_connex++,
dg);
734 int split_port_n = 0;
748 n_connex = is_vtx_compound(v, lcomponents);
755 if (n_connex == -1) {
758 sc_inst(sb_new, v, htid, NULL, NULL, dynamic_agent);
760 sc_inst(sb_new, v, htid, hparams, NULL, dynamic_agent);
765 n_connex, ncompound, n_connex);
766 lcomponents_inst =
CONS(
int, n_connex, lcomponents_inst);
774 sb_prf(sb_instoutp,
"strin.output[%d] /* %s */",
777 else if (n_connex == -1)
780 list comp_outps = sigmac_get_component_outputs(
782 sb_prf(sb_instoutp,
"cpd%d.output[%d]", n_connex,
791 if (
f->arg_misc_out == 1)
794 else if (
f->arg_misc_out > 1)
795 for (i = 0; i <
f->arg_misc_out; i++)
803 for (i = 0; i <
f->arg_misc_in; i++) {
813 list succ_insts = get_succ_insts(v, lcomponents,
dg, htid);
815 FOREACH(
string, inst, succ_insts) {
825 FOREACH(
string, inst, succ_insts) {
832 string subgraph_name =
strdup(
cat(fname,
"_",
i2a(n_split)));
846 sb_cat(
sb,
"\n // parameters declaration...\n");
850 sb_cat(sb_new,
" // instantiations...\n");
856 sb_cat(sb_conn,
" // connections...\n");
892 #define SIGMAC_HELPER "freia_mppa_launch"
897 static void sigmac_call_helper(
dag d,
int helper) {
954 bool call_inserted =
false;
967 call_inserted =
true;
979 #define N_PREDEFINED_CONTROLLERS 5
981 static void print_subgraph_calls(
string fname,
int n_split,
int n_dags) {
985 sb_prf(subg_calls,
" new %s_%d\n"
986 " (pipes[%d], pipes[%d],\n"
987 " width, height, sizeMax,\n"
988 " pipes[%d], pipes[%d]);\n"
996 #define MAIN_PATH "cd .. && ./main"
1002 static void sc_subgraph_root(FILE *sigmac_helper,
int n_graphs) {
1008 " int width = %d, height = %d;\n"
1009 " size_t sizeMax = width * height * sizeof(" PIXEL_T ");\n"
1015 sb_cat(
sb,
" char cmd[255] = \"", exec_path,
"\";\n");
1022 sb_prf(
sb,
" int i, n_pipes = %d;\n", n_pipes);
1023 sb_cat(
sb,
" char pipes[n_pipes][255];\n"
1024 " for (i=0; i<n_pipes; i++)\n"
1025 " tmpnam(pipes[i]);\n"
1028 " agent pp = new Pipes(cmd, n_pipes, pipes);\n"
1029 " agent sk = new Sink<char>(1);\n"
1030 " SigmaC_agent_setUnitType(sk, \"native\");\n"
1031 " connect(pp.output, sk.input);\n\n"
1036 " new Malloc(pipes[0], pipes[1]);\n"
1037 " new Free(pipes[2], pipes[3]);\n"
1038 " new MCopy(pipes[4], pipes[5]);\n"
1039 " new SendDataToMPPA(pipes[6], pipes[7], sizeMax);\n"
1040 " new SendDataToHost(pipes[8], pipes[9], sizeMax);\n"
1062 const set output_images,
1066 int number,
int n_calls) {
1072 FILE *sigmac_file =
safe_fopen(sigmac_file_name,
"a");
1114 sigmac_compile_subgraph(
module, d, fname_fulldag, n_split, sigmac_file);
1115 print_subgraph_calls(fname_fulldag, n_split,
n_dags);
1116 sigmac_call_helper(d,
n_dags);
1123 if (number == n_calls - 1)
1124 sc_subgraph_root(sigmac_file,
n_dags);
1142 fclose(sigmac_file);
1143 free(sigmac_file_name);
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
int get_int_property(const string)
call make_call(entity a1, list a2)
void const char const char const int
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
_int dagvtx_optype(const dagvtx v)
list dag_vertex_preds(const dag d, const dagvtx target)
return target predecessor vertices as a list.
_int dagvtx_number(const dagvtx v)
returns the vertex number, i.e.
void dagvtx_nb_dump(FILE *out, const string what, const list l)
bool dag_no_image_operation(dag d)
tell whether we have something to do with images ??? hmmm...
list dag_split_on_scalars(const dag initial, bool(*alone_only)(const dagvtx), dagvtx(*choose_vertex)(const list, bool), gen_cmp_func_t priority, void(*priority_update)(const dag), const set output_images)
split a dag on scalar dependencies only, with a greedy heuristics.
list dag_fix_image_reuse(dag d, hash_table init, const hash_table occs)
fix intermediate image reuse in dag
bool dagvtx_is_measurement_p(const dagvtx v)
returns whether the vertex is an image measurement operation.
entity dagvtx_image(const dagvtx v)
return the produced image or NULL
void dag_dump(FILE *out, const string what, const dag d)
for dag debug
void freia_dag_optimize(dag d, hash_table exchanges, list *lbefore, list *lafter)
remove dead image operations.
string dagvtx_operation(const dagvtx v)
statement dagvtx_statement(const dagvtx v)
return statement if any, or NULL (for input nodes).
_int dagvtx_opid(const dagvtx v)
void dag_statements(set stats, const dag d)
build the set of actual statements in d
void dag_dot_dump_prefix(const string module, const string prefix, int number, const dag d, const list lb, const list la)
FILE * safe_fopen(const char *filename, const char *what)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
entity freia_create_helper_function(const string function_name, list lparams)
string helper_file_name(string func_name, string suffix)
return malloc'ed "foo.database/Src/%{module}_helper_functions.c" should it depend on the target?...
list freia_get_vertex_params(const dagvtx v)
list freia_extract_params(const int napi, list args, string_buffer head, string_buffer head2, hash_table params, int *nparams)
returns an allocated expression list of the parameters only (i.e.
list freia_allocate_new_images_if_needed(list ls, list images, const hash_table occs, const hash_table init, const hash_table signatures)
insert image allocation if needed, for intermediate image inserted before if an image is used only tw...
void freia_migrate_statements(sequence sq, const set stats, const set before)
void hwac_replace_statement(statement s, call newc, bool kill)
replace statement contents with call to c, or continue if kill
bool freia_convolution_p(dagvtx v)
is it the convolution special case?
bool freia_extract_kernel_vtx(dagvtx v, bool strict, intptr_t *k00, intptr_t *k10, intptr_t *k20, intptr_t *k01, intptr_t *k11, intptr_t *k21, intptr_t *k02, intptr_t *k12, intptr_t *k22)
vertex-based version
call freia_ok(void)
build all is well freia constant
call freia_statement_to_call(const statement s)
return the actual function call from a statement, dealing with assign and returns....
void freia_insert_added_stats(list ls, list stats, bool before)
insert statements to actual code sequence in "ls" BEWARE that ls is assumed to be in reverse order....
const freia_api_t * get_freia_api_vtx(dagvtx v)
static void sc_delimiter(string_buffer sb, const string title)
Generate a 3 lines commented code delimiter with a centered title.
static void sigmac_params_decl(string_buffer sb_par, dag dg, hash_table hparams, int *pnparams)
Generates the constant parameters declaration.
#define N_PREDEFINED_CONTROLLERS
static void sc_kernel_specific_agent(string_buffer sb_morpho, hash_table hparams, const dag dg)
static bool sc_print_kernel(string_buffer sb_par, dagvtx v)
Print the value of a morphological kernel extracted from a dagvtx.
static bool has_vtx_dynamic_params(dagvtx v)
Determine if a dagvtx has at least one dynamic parameter.
#define SIGMAC_INSTANTIATE(a, b)
static void sigmac_name_instances(dag dg, hash_table htid)
Populates the hash table htid: one dagvtx is linked to an unique id depending on its freia_api_t.
static bool is_param_dynamic(expression arg)
Determine if an argument contains references to other variables (dirty hack based on isalpha)
static list sc_get_params_values(dagvtx vtx, hash_table hparams, int *nparams)
Returns a list of values of one dagvtx misc input parameters.
static int sc_get_port_id(dagvtx current_vtx, dagvtx succ, dag dg)
Helper function determine the input port of the succ dagvtx to be connected to the output port of cur...
#define SIGMAC_CONNECT(a, b)
static string sc_vtx_tostring(const dagvtx v, const hash_table htid)
Generate a unique string per dagvtx consisting in.
#define REPLICATION_AGENT
static void sc_inst(string_buffer sb, const dagvtx v, const hash_table htid, const hash_table hparams, string miscparams, bool is_dynamic)
Generate the instanciation of an agent in the forme "agent instname = new agentname (parameters)".
static bool sc_kernel_compute_loop(string_buffer sb_morpho, const dagvtx vtx, string kname)
Print a kernel customized inner loop from a morphological kernel.
#define FREIA_SIGMAC_SC_INCLUDES
#define dagvtx_content(x)
#define pstatement_statement(x)
#define vtxcontent_source(x)
list gen_make_list(int domain,...)
list gen_nreverse(list cp)
reverse a list in place
int gen_position(const void *item, const list l)
Element ranks are strictly positive as for first, second, and so on.
#define NIL
The empty list (nil in Lisp)
size_t gen_length(const list l)
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
void gen_free_list(list l)
free the spine of the list
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
list gen_full_copy_list(list l)
Copy a list structure with element copy.
hash_table hash_table_make(hash_key_type key_type, size_t size)
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
list freia_sigmac_compile_calls(string, dag, sequence, list, const hash_table, hash_table, const set, FILE *, set, int, int)
freia_sigmac.c
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
string strupper(string, const char *)
#define HASH_FOREACH(key_type, k, value_type, v, ht)
#define same_string_p(s1, s2)
int set_size(const set)
returns the number of items in s.
bool set_belong_p(const set, const void *)
set set_union(set, const set, const set)
set set_make(set_type)
Create an empty set of any type but hash_private.
set set_add_element(set, const set, const void *)
string string_buffer_to_string(const string_buffer)
return malloc'ed string from string buffer sb
void string_buffer_to_file(const string_buffer, FILE *)
put string buffer into file.
void string_buffer_free(string_buffer *)
free string buffer structure, also free string contents according to the dup field
void string_buffer_reset(string_buffer)
remove stack contents
string_buffer string_buffer_make(bool dup)
allocate a new string buffer
bool string_buffer_empty_p(const string_buffer)
return whether string_buffer sb is empty.
string string_buffer_to_string_reverse(const string_buffer)
return malloc'ed string from string buffer sb going from bottom to top
int(* gen_cmp_func_t)(const void *, const void *)
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
string expression_to_string(expression e)
list lparams
Array bounds.
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
static int init
Maximal value set for Fortran 77.
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
#define expression_domain
newgen_execution_domain_defined
#define EXPRESSION(x)
EXPRESSION.
#define entity_undefined_p(x)
#define call_arguments(x)
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
internally defined structure.
FI: I do not understand why the type is duplicated at the set level.
The structure used to build lists in NewGen.
FREIA API function name -> SPoC hardware description (and others?)