PIPS
remapping.c
Go to the documentation of this file.
1 /*
2 
3  $Id: remapping.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* HPFC module by Fabien COELHO
28  *
29  * generates a remapping code.
30  * debug controlled with HPFC_REMAPPING_DEBUG_LEVEL.
31  * ??? should drop the renaming domain?
32  */
33 
34 #include "defines-local.h"
35 
36 #include "prettyprint.h" // for sc_syst_debug()
37 #include "conversion.h"
38 #include "resources.h"
39 #include "pipsdbm.h"
40 
41 /* linearize the processor arrangement on which array is distributed
42  * or replicated (driven by distributed). The variables are those created
43  * or returned by the create_var function. var is set as the linearization
44  * result, if not NULL. *psize the the extent of the returned array.
45  * Special care is taken about the declaration shifts.
46  */
47 static Pcontrainte
49  entity array, /* array variable */
50  bool distributed, /* distributed or replicated dimensions lin. */
51  entity var, /* assigned variable if desired */
52  int *psize, /* returned array extent */
53  entity (*create_var)(int)) /* dimension variable builder */
54 {
56  int dim = NumberOfDimension(proc), low, up, size;
58 
59  for(*psize=1; dim>0; dim--)
60  if (distributed ^ processors_dim_replicated_p(proc, array, dim))
61  {
62  get_entity_dimensions(proc, dim, &low, &up);
63  size = up - low + 1;
64  *psize *= size;
65  v = vect_multiply(v, int_to_value(size));
66  vect_add_elem(&v, (Variable) create_var(dim), VALUE_ONE);
67  vect_add_elem(&v, TCST, int_to_value(-low));
68  }
69 
70  if (var) vect_add_elem(&v, (Variable) var, VALUE_MONE);
71 
72  return contrainte_make(v);
73 }
74 
75 /* builds a linarization equation of the dimensions of obj.
76  * var is set to the result. *psize returns the size of obj.
77  * Done the Fortran way, or the other way around...
78  */
81  entity obj, /* array being lin. */
82  entity var, /* assigned variable if desired */
83  int *psize, /* returned array extent */
84  entity (*create_var)(int), /* dimension variable builder */
85  bool fortran_way, /* Fortran/C linearization way */
86  int initial_offset) /* initial offset if desired */
87 {
88  int dim = NumberOfDimension(obj), low, up, size, i;
90 
91  for(*psize=1, i=fortran_way ? dim : 1 ;
92  fortran_way ? i>0 : i<=dim;
93  i+= fortran_way ? -1 : 1)
94  {
95  get_entity_dimensions(obj, i, &low, &up);
96  size = up - low + 1;
97  *psize *= size;
98  v = vect_multiply(v, int_to_value(size));
99  vect_add_elem(&v, (Variable) create_var(i), VALUE_ONE);
100  vect_add_elem(&v, TCST, int_to_value(-low));
101  }
102 
103  if (var) vect_add_elem(&v, (Variable) var, VALUE_MONE);
104  if (initial_offset)
105  vect_add_elem(&v, TCST,
106  int_to_value(initial_offset));
107 
108  return contrainte_make(v);
109 }
110 
111 /* load-balancing equation as suggested in the A-274 report.
112  * here some choices are quite arbitrary:
113  * - the dimension order linearization of both source and target procs.
114  * - the initial offset
115  * some clever choice could be suggested so as to minimize the required
116  * communications by maximizing the local copies, knowing the actual
117  * hpf processors to real processors affectation...
118  *
119  * should allow a stupid system with some property?
120  */
121 static Psysteme
123  entity src, /* source array */
124  entity trg) /* target array */
125 {
126  entity psi_r = get_ith_temporary_dummy(1),
127  psi_d = get_ith_temporary_dummy(2),
128  delta = get_ith_temporary_dummy(3);
129  int size_r, size_d;
130  Psysteme sharing = sc_new();
131 
132  sc_add_egalite(sharing, partial_linearization(src, false, psi_r, &size_r,
134  sc_add_egalite(sharing, partial_linearization(trg, true, psi_d, &size_d,
136 
137  /* psi_d = psi_r + |psi_r| delta
138  */
140  (VECTEUR_NUL, psi_d, VALUE_MONE,
141  psi_r, VALUE_ONE,
142  delta, int_to_value(size_r),
143  TCST, VALUE_ZERO)));
144 
145  if (size_d > size_r)
146  {
147  /* 0 <= delta (there are cycles)
148  */
151 
152  /* delta <= -((size_d-1)/size_r) // not really necessary, but may help.
153  */
155  (vect_make(VECTEUR_NUL, delta, VALUE_ONE,
156  TCST, int_to_value(-((size_d-1)/size_r)))));
157  }
158  else
159  {
160  /* delta == 0
161  */
162  sc_add_egalite(sharing,
164  }
165 
166  sc_creer_base(sharing);
167 
168  return sharing;
169 }
170 
171 /* returns the full remapping system, including the source and target
172  * mappings systems, the link and the work sharing system
173  */
174 static Psysteme
176  entity src, /* source array for the remapping */
177  entity trg) /* target array */
178 {
179  int ndim = variable_entity_dimension(src);
180  Psysteme
181  result,
187  s_shr = generate_work_sharing_system(src, trg);
188 
189  DEBUG_SYST(6, concatenate("source ", entity_name(src), NULL), s_src);
190  DEBUG_SYST(6, concatenate("target ", entity_name(trg), NULL), s_trg);
191  DEBUG_SYST(6, "link", s_equ);
192  DEBUG_SYST(6, "sharing", s_shr);
193 
194  result = s_src;
195  result = sc_append(result, s_trg), sc_rm(s_trg);
196  result = sc_append(result, s_equ), sc_rm(s_equ);
197  result = sc_append(result, s_shr), sc_rm(s_shr);
198 
199  return result;
200 }
201 
202 /* ??? assumes that there are no parameters. what should be the case...
203  * generates the list of variables needed by the code generation.
204  */
205 static void
207  Psysteme s, /* full remapping system */
208  entity a1, /* source array */
209  entity a2, /* target array */
210  list *pl, /* P */
211  list *plp, /* P' */
212  list *pll, /* locals */
213  list *plrm, /* to remove */
214  list *pld, /* diffusion processor variables */
215  list *plo) /* others */
216 {
217  entity
218  t1 = array_to_template(a1),
219  p1 = template_to_processors(t1),
220  t2 = array_to_template(a2),
221  p2 = template_to_processors(t2);
222  int
223  a1dim = variable_entity_dimension(a1),
224  a2dim = variable_entity_dimension(a2),
225  t1dim = variable_entity_dimension(t1),
226  t2dim = variable_entity_dimension(t2),
227  p1dim = variable_entity_dimension(p1),
228  p2dim = variable_entity_dimension(p2), i;
229 
230  /* processors.
231  */
233  *plp = NIL; add_to_list_of_vars(*plp, get_ith_processor_prime, p2dim);
234 
235  *pld = NIL;
236  for (i=p2dim; i>0; i--)
237  if (processors_dim_replicated_p(p2, a2, i))
238  *pld = CONS(ENTITY, get_ith_processor_prime(i), *pld);
239 
240  /* to be removed.
241  */
242  *plrm = NIL;
247 
248  /* corresponding equations generated in the sharing system
249  */
251 
252 
253  /* Replicated dimensions associated variables must be removed.
254  * A nicer approach would have been not to generate them, but
255  * it's not so hard to remove them, and the equation generation is
256  * kept simpler this way. At least in my own opinion:-)
257  */
258  for (i=p1dim; i>0; i--)
259  if (processors_dim_replicated_p(p1, a1, i))
260  *plrm = CONS(ENTITY, get_ith_block_dummy(i),
261  CONS(ENTITY, get_ith_cycle_dummy(i), *plrm));
262 
263  for (i=p2dim; i>0; i--)
264  if (processors_dim_replicated_p(p2, a2, i))
265  *plrm = CONS(ENTITY, get_ith_block_prime(i),
266  CONS(ENTITY, get_ith_cycle_prime(i), *plrm));
267 
268  /* locals.
269  */
270  *pll = NIL;
273 
274  /* others.
275  */
276  *plo = base_to_list(sc_base(s));
277  gen_remove(plo, (entity) TCST);
278 
279  MAP(ENTITY, e, gen_remove(plo, e), *pl);
280  MAP(ENTITY, e, gen_remove(plo, e), *plp);
281  MAP(ENTITY, e, gen_remove(plo, e), *plrm);
282  MAP(ENTITY, e, gen_remove(plo, e), *pll);
283 
284  DEBUG_ELST(7, "P", *pl);
285  DEBUG_ELST(7, "P'", *plp);
286  DEBUG_ELST(7, "RM", *plrm);
287  DEBUG_ELST(7, "LOCALS", *pll);
288  DEBUG_ELST(7, "DIFFUSION", *pld);
289  DEBUG_ELST(7, "OTHERS", *plo);
290 }
291 
292 /* to be generated:
293  * ??? the Proc cycle should be deduce directly in some case...
294  *
295  * PSI_i's definitions
296  * [ IF (I AM IN S(PSI_i)) THEN ]
297  * DO OTH_i's in S(OTH_i's)[PSI_i's]
298  * LID computation(OTH_i's) // if LID is not NULL!
299  * body
300  * ENDDO
301  * [ ENDIF ]
302  */
303 static statement
305  Psysteme s, /* system of comm. couples of processors */
306  _UNUSED_ list /* of entities */ l_psi, /* processor local dimensions */
307  list /* of entities */ l_oth, /* communicating proc. dimensions */
308  entity psi, /* local processor arrangement */
309  entity oth, /* communicating processor arrangement */
310  entity lid, /* variable for the comm. proc local id */
311  entity array, /* array being remapped */
312  entity (*create_psi)(), /* to create a local proc. dim. */
313  entity (*create_oth)(), /* to create a comm. proc. dim. */
314  statement body, /* loop body */
315  bool sh) /* whether to shift the psi's */
316 {
318  Psysteme condition, enumeration, known, simpler;
319  statement define_psis, compute_lid, oth_loop, if_guard;
320 
321  define_psis = define_node_processor_id(psi, create_psi);
322 
323  /* the lid computation is delayed in the body for broadcasts.
324  */
325  compute_lid = (lid) ?
326  hpfc_compute_lid(lid, oth, create_oth, array) :
328 
329  /* simplifies the processor arrangement for the condition
330  */
331  known = sc_dup(entity_to_declaration_constraints(psi, 2));
332  if (sh) known = shift_system_to_prime_variables(known);
333 
334  DEBUG_SYST(7, "initial system", s);
335  DEBUG_ELST(7, "loop indexes", l_oth);
336 
337  hpfc_algorithm_row_echelon(s, l_oth, &condition, &enumeration);
338 
339  DEBUG_SYST(7, "P condition", condition);
340 
341  simpler = extract_nredund_subsystem(condition, known);
342  sc_rm(condition), sc_rm(known);
343 
344  /* the processor must be in the psi processor arrangement
345  */
346  sc_add_inegalite(simpler,
353 
354  DEBUG_SYST(5, "P simpler", simpler);
355  DEBUG_SYST(5, "P enumeration", enumeration);
356 
357  /* target processors enumeration loop
358  */
359  oth_loop = systeme_to_loop_nest(enumeration, l_oth,
360  make_block_statement(CONS(STATEMENT, compute_lid,
361  CONS(STATEMENT, body,
362  NIL))), divide);
363 
364  if_guard = generate_optional_if(simpler, oth_loop);
365 
366  sc_rm(simpler); sc_rm(enumeration);
367 
368  return make_block_statement(CONS(STATEMENT, define_psis,
369  CONS(STATEMENT, if_guard,
370  NIL)));
371 }
372 
373 /* to be generated:
374  *
375  * DO ll's in S(ll)[...]
376  * DEDUCABLES(ld)
377  * body
378  * ENDDO
379  */
380 static statement
382  Psysteme s, /* triangular bounds on ll */
383  list /* of entities */ ll, /* loop indexes */
384  list /* of expressions */ ld, /* deduced scalars */
385  statement body) /* loop body */
386 {
387  return systeme_to_loop_nest(s, ll,
389  CONS(STATEMENT, body,
390  NIL))),
392 }
393 
394 static expression
396 {
398  entity_to_expression(lid));
399 }
400 
401 /* to be generated:
402  * IF (MYLID.NE.LID[.AND.NOT.HPFC_TWIN_P(an, LID)])
403  * THEN true
404  * ELSE false
405  * ENDIF
406  */
407 static statement
409  entity src, /* source array processor */
410  entity lid, /* process local id variable */
411  statement strue, /* then statement */
412  statement sfalse) /* else statement */
413 {
414  expression cond = mylid_ne_lid(lid);
415 
416  if (get_bool_property("HPFC_GUARDED_TWINS") && replicated_p(src))
417  {
418  list /* of expression */ largs;
419  expression not_twin;
420 
425 
426  cond = and_expression(cond, not_twin);
427  }
428 
429  return test_to_statement(make_test(cond, strue, sfalse));
430 }
431 
432 /* builds the diffusion loop.
433  *
434  * [ IF (LAZY_SEND) THEN ]
435  * DO ldiff in sr
436  * LID computation(...)
437  * IF (MYLID.NE.LID) send to LID
438  * ENDDO
439  * [ ENDIF ]
440  */
441 static statement
443  entity src, /* source array */
444  entity lid, /* variable to store the target local id */
445  entity proc, /* target processors for the broadcast */
446  Psysteme sr, /* broadcast polyhedron */
447  list /* of entity */ ldiff, /* dimension variables for the broadcast */
448  bool lazy) /* whether to send empty messages */
449 {
450  statement cmp_lid, body, nest;
451 
452  cmp_lid = hpfc_compute_lid(lid, proc, (entity(*)())get_ith_processor_prime, NULL);
453  body = make_block_statement
454  (CONS(STATEMENT, cmp_lid,
456  (src, lid, hpfc_generate_message(lid, true, false),
458  NIL)));
459 
460  nest = systeme_to_loop_nest(sr, ldiff, body, hpfc_name_to_entity(IDIVIDE));
461 
462  return lazy ? hpfc_lazy_guard(true, nest) : nest ;
463 }
464 
465 /* in the following functions tag t controls the code generation,
466  * depending of what is to be generated (send, receive, copy, broadcast)...
467  * tag t may have the following values:
468  */
469 
470 #define CPY 0
471 #define SND 1
472 #define RCV 2
473 #define BRD 3
474 
475 #define PRE 0
476 #define INL 4
477 #define PST 8
478 
479 #define NLZ 0
480 #define LZY 16
481 
482 #define NBF 0
483 #define BUF 32
484 
485 /* I have to deal with a 4D space to generate some code:
486  *
487  * buffer/nobuf
488  * lazy/nolazy
489  *
490  * pre/in/post
491  * cpy/snd/rcv/brd
492  */
493 
494 #define ret(name) result = name; break
495 
496 /* arguments: all that may be useful to generate some code */
497 static statement
498 gen(int what,
499  entity src, entity trg, entity lid, entity proc,
500  entity (*create_src)(), entity (*create_trg)(),
501  Psysteme sr, list /* of entity */ ldiff)
502 {
503  statement result;
504  bool is_lazy = what & LZY,
505  is_buff = what & BUF;
506 
507  switch (what)
508  {
509  /* cpy pre/post
510  * rcv post nbuf
511  */
512  case CPY+PRE:
513  case CPY+PST:
514  case CPY+PRE+LZY:
515  case CPY+PST+LZY:
516  case CPY+PRE+BUF:
517  case CPY+PST+BUF:
518  case CPY+PRE+LZY+BUF:
519  case CPY+PST+LZY+BUF:
520  case RCV+PST:
521  case RCV+PST+LZY:
522  case RCV+PST+BUF:
523  case RCV+PST+LZY+BUF:
525 
526  /* snd.brd pre nbuf
527  */
528  case SND+PRE:
529  case BRD+PRE:
530  case SND+PRE+LZY:
531  case BRD+PRE+LZY:
532  ret(hpfc_initsend(is_lazy));
533 
534  case RCV+PRE+LZY:
536 
537  case RCV+PRE:
538  ret(hpfc_generate_message(lid, false, false));
539 
540  /* cpy inl
541  */
542  case CPY+INL:
543  case CPY+INL+LZY:
544  case CPY+INL+BUF:
545  case CPY+INL+LZY+BUF:
547  make_reference_expression(src, create_src)));
548 
549  /* snd/brd inl nbf
550  */
551  case SND+INL:
552  case BRD+INL:
553  case SND+INL+LZY:
554  case BRD+INL+LZY:
555  ret(hpfc_lazy_packing(src, lid, create_src, true, is_lazy));
556 
557  case SND+INL+BUF:
558  case SND+INL+LZY+BUF:
559  case BRD+INL+BUF:
560  case BRD+INL+LZY+BUF:
561  ret(hpfc_lazy_buffer_packing(src, trg, lid, proc, create_src,
562  true /* send! */, is_lazy));
563  case RCV+INL+BUF:
564  case RCV+INL+LZY+BUF:
565  ret(hpfc_lazy_buffer_packing(src, trg, lid, proc, create_trg,
566  false /* receive! */, is_lazy));
567  case RCV+INL:
568  case RCV+INL+LZY:
569  ret(hpfc_lazy_packing(trg, lid, create_trg, false, is_lazy));
570 
571  case SND+PST:
572  case SND+PST+LZY:
573  ret(hpfc_generate_message(lid, true, is_lazy));
574 
575  case BRD+PST:
576  case BRD+PST+LZY:
577  ret(broadcast(src, lid, proc, sr, ldiff, is_lazy));
578 
579  case SND+PST+BUF:
580  case SND+PST+LZY+BUF:
581  case BRD+PST+BUF:
582  case BRD+PST+LZY+BUF:
583  ret(hpfc_broadcast_if_necessary(src, trg, lid, proc, is_lazy));
584 
585  /* snd/rcv pre buf
586  */
587  case SND+PRE+BUF:
588  case SND+PRE+LZY+BUF:
589  case BRD+PRE+BUF:
590  case BRD+PRE+LZY+BUF:
591  ret(hpfc_buffer_initialization(true /* send! */, is_lazy, true));
592  case RCV+PRE+BUF:
593  case RCV+PRE+LZY+BUF:
594  ret(hpfc_buffer_initialization(false /* receive! */, is_lazy, true));
595 
596  /* default is a forgotten case, I guess
597  */
598  default:
599  pips_internal_error("invalid tag %d", what);
600  ret(statement_undefined); /* to avoid a gcc warning */
601  }
602 
603  pips_debug(7, "tag is %d (%s, %s)\n", what,
604  is_lazy ? "lazy" : "not lazy",
605  is_buff ? "bufferized" : "not bufferized");
606  DEBUG_STAT(7, "returning", result);
607 
608  return result;
609 }
610 
611 /* generates a remapping loop nest (copy/send/receive/broadcast)
612  * basically a loop on elements with pre/in/post statements...
613  */
614 static statement
616  int t, /* tag: CPY/SND/RCV/BRD */
617  Psysteme s, /* elements polyhedron */
618  Psysteme sr, /* broadcast polyhedron */
619  list /* of entity */ ll, /* indexes for element loops */
620  list /* of entity */ ldiff, /* indexes for broadcasts */
621  list /* of expressions */ ld, /* deducable elements */
622  entity lid, /* lid variable to be used */
623  entity src, /* source array */
624  entity trg) /* target array */
625 {
626  entity proc = array_to_processors(trg);
627  statement inner, prel, postl, result;
628  bool is_buffer, is_lazy;
629  int what;
630 
631  is_lazy = get_bool_property(LAZY_MESSAGES);
632  is_buffer = get_bool_property(USE_BUFFERS);
633  what = (is_lazy ? LZY : NLZ) + (is_buffer ? BUF : NBF) + t;
634 
635  prel = gen(what+PRE, src, trg, lid, proc,
637  inner = gen(what+INL, src, trg, lid, proc,
639  postl = gen(what+PST, src, trg, lid, proc,
641 
642  result = make_block_statement
643  (CONS(STATEMENT, prel,
644  CONS(STATEMENT, elements_loop(s, ll, ld, inner),
645  CONS(STATEMENT, postl,
646  NIL))));
647 
648  {
649  /* comments are added to help understand the generated code
650  */
651  string comment = strdup(concatenate("! - ", (what & LZY) ? "lazy " : "",
652  t==CPY ? "copy" : t==SND ? "send" : t==RCV ? "receiv" :
653  t==BRD ? "broadcast" : "?", "ing\n", NULL));
655  free(comment);
656  }
657  return result;
658 }
659 
660 
661 /* generates a full remapping code, given the systems and indexes
662  * to be used in the different loops. that is complementary send/broadcast
663  * and receive/copy. The distribution of target onto source processors
664  * may require special care if lambda.
665  *
666  * output:
667  * AS a source
668  * DO target
669  * DO element
670  * PACK
671  * SEND/BROADCAST to target(s)
672  * AS a target
673  * DO source
674  * DO element RECEIVE/UNPACK
675  * OR
676  * DO element COPY
677  */
678 static statement
680  entity src, /* source array */
681  entity trg, /* target array */
682  Psysteme procs, /* communicating processors polyhedron */
683  Psysteme locals, /* elements polyhedron */
684  list /* of entity */ l, /* source processor indexes */
685  list lp, /* target processor indexes */
686  list ll, /* element indexes */
687  list ldiff, /* broadcast target processor indexes */
688  list /* of expression */ ld, /* deducable elements */
689  bool dist_p) /* true if must take care of lambda */
690 {
692  p_src = array_to_processors(src),
693  p_trg = array_to_processors(trg),
694  lambda = get_ith_temporary_dummy(3),
695  primary = load_primary_entity(src);
696  statement copy, recv, send, receive, cont, result;
697  bool is_buffer = get_bool_property(USE_BUFFERS);
698 
699  pips_debug(3, "%s taking care of processor cyclic distribution\n",
700  dist_p ? "actually" : "not");
701 
702  copy = remapping_stats(CPY, locals, SC_EMPTY, ll, NIL, ld, lid, src, trg);
703  recv = remapping_stats(RCV, locals, SC_EMPTY, ll, NIL, ld, lid, src, trg);
704 
705  if (dist_p) lp = CONS(ENTITY, lambda, lp);
706 
707  /* the send is different for diffusions
708  */
709  if (ENDP(ldiff))
710  {
711  statement rp_send;
712 
713  rp_send =
714  remapping_stats(SND, locals, SC_EMPTY, ll, NIL, ld, lid, src, trg);
715 
716  send = processor_loop
717  (procs, l, lp, p_src, p_trg, lid, NULL,
719  if_different_pe_and_not_twin(src, lid, rp_send,
720  make_empty_statement()), false);
721  }
722  else
723  {
724  Pbase b = entity_list_to_base(ldiff);
725  list lpproc = gen_copy_seq(lp);
726  statement diff;
727  Psysteme
728  sd /* distributed */,
729  sr /* replicated */;
730 
731  MAP(ENTITY, e, gen_remove(&lpproc, e), ldiff);
732 
733  /* polyhedron separation to extract the diffusions.
734  */
735  sc_separate_on_vars(procs, b, &sr, &sd);
736  base_rm(b);
737 
738  diff = remapping_stats(BRD, locals, sr, ll, ldiff, ld, lid, src, trg);
739 
740  send = processor_loop
741  (sd, l, lpproc, p_src, p_trg, lid, is_buffer ? trg : NULL,
743  diff, false);
744 
745  gen_free_list(lpproc); sc_rm(sd); sc_rm(sr);
746  }
747 
748  if (dist_p)
749  {
750  gen_remove(&lp, lambda);
751  l = gen_nconc(l, CONS(ENTITY, lambda, NIL)); /* ??? to be deduced */
752  }
753 
754  receive = processor_loop
755  (procs, lp, l, p_trg, p_src, lid, NULL,
757  if_different_pe_and_not_twin(src, lid, recv, copy), true);
758 
759  if (dist_p) gen_remove(&l, lambda);
760 
761  cont = make_empty_statement();
762 
763  result = make_block_statement(CONS(STATEMENT, send,
764  CONS(STATEMENT, receive,
765  CONS(STATEMENT, cont,
766  NIL))));
767 
768  /* some comments to help understand the generated code
769  */
770  {
771  char *buffer;
772 
773  asprintf(&buffer, "! remapping %s[%"PRIdPTR"]: %s[%"PRIdPTR"] -> %s[%"PRIdPTR"]\n",
774  entity_local_name(primary), load_hpf_number(primary),
777 
779  free(buffer);
780  insert_comments_to_statement(send, "! send part\n");
781  insert_comments_to_statement(receive, "! receive part\n");
782  insert_comments_to_statement(cont, "! end of remapping\n");
783  }
784 
785  DEBUG_STAT(3, "result", result);
786 
787  return result;
788 }
789 
790 /* returns LIVEMAPPING(index)
791  */
792 static expression
794 {
795  entity live_status = hpfc_name_to_entity(LIVEMAPPING);
797  (live_status, CONS(EXPRESSION, int_to_expression(index), NIL)));
798 }
799 
800 static statement
802 {
803  int trg_n = load_hpf_number(trg),
804  prm_n = load_hpf_number(load_primary_entity(trg));
805  entity m_status = hpfc_name_to_entity(MSTATUS); /* mapping status */
806  expression m_stat_ref;
807 
808  /* MSTATUS(primary_n) */
809  m_stat_ref =
811  (make_reference(m_status,
812  CONS(EXPRESSION, int_to_expression(prm_n), NIL)));
813 
814  return make_assign_statement(m_stat_ref, int_to_expression(trg_n));
815 }
816 
817 static statement
819  entity trg,
820  _UNUSED_ bool val)
821 {
822  int trg_n = load_hpf_number(load_similar_mapping(trg));
823 
825  bool_to_expression(true));
826 }
827 
828 static statement
830 {
831  statement s = set_live_status(trg, true);
832 
833  {
834  string comment =
835  strdup(concatenate("! direct remapping for ",
836  entity_local_name(load_primary_entity(trg)), "\n", NULL));
838  free(comment);
839  }
840 
841  return make_block_statement
842  (CONS(STATEMENT, s,
844 }
845 
846 /* Runtime descriptors management around the remapping code.
847  * performs the remapping if reaching mapping is ok, and update the
848  * mapping status.
849  *
850  * IF (MSTATUS(primary_number).eq.src_number) THEN
851  * [ IF (.not.LIVEMAPPING(target_number)]) THEN ]
852  * the_code
853  * [ ENDIF ]
854  * [ LIVEMAPPING(target_number) = .TRUE. ]
855  * MSTATUS(primary_number) = trg_number
856  * ENDDIF
857  */
858 static statement
860  entity src, /* source array */
861  entity trg, /* target array */
862  statement the_code) /* remapping code */
863 {
864  int src_n = load_hpf_number(src), /* source, target and primary numbers */
865  trg_n = load_hpf_number(trg),
867  entity m_status = hpfc_name_to_entity(MSTATUS); /* mapping status */
868  expression m_stat_ref, cond;
869  statement result;
870  list /* of statement */ l = NIL;
871 
872  /* MSTATUS(primary_n) */
873  m_stat_ref =
875  (make_reference(m_status,
876  CONS(EXPRESSION, int_to_expression(prm_n), NIL)));
877 
878  /* MSTATUS(primary_number) = trg_number */
880 
881  /* MSTATUS(primary_number).eq.src_number */
882  cond = eq_expression(m_stat_ref, int_to_expression(src_n));
883 
884  /* checks whether alive or not */
885  if (get_bool_property("HPFC_DYNAMIC_LIVENESS"))
886  {
887  expression live_cond =
889 
890  the_code = test_to_statement(make_test
891  (live_cond, the_code, make_empty_statement()));
892 
893  l = CONS(STATEMENT,
895  bool_to_expression(true)), l);
896  }
897 
898  result = test_to_statement(make_test(cond,
899  make_block_statement(CONS(STATEMENT, the_code, l)),
901 
902  return result;
903 }
904 
905 static statement
907  entity primary,
908  bool val,
909  entity butthisone)
910 {
911  statement result;
912  list /* of statement */ ls = NIL;
913 
914  MAP(ENTITY, array,
915  {
916  /* LIVEMAPPING(array) = val (.TRUE. or .FALSE.)
917  */
918  if (array != butthisone)
919  ls = CONS(STATEMENT,
922  bool_to_expression(val)), ls);
923  },
924  entities_list(load_dynamic_hpf(primary)));
925 
926  /* commented result
927  */
928  result = make_block_statement(ls);
929  {
930  string comment =
931  strdup(concatenate("! all livenesss for ",
932  entity_local_name(primary), "\n", NULL));
934  free(comment);
935  }
936  return result;
937 }
938 
939 statement
941  entity primary,
942  bool val)
943 {
944  return generate_all_liveness_but(primary, val, entity_undefined);
945 }
946 
947 static statement
949  entity primary,
950  list /* of entity */ tokeep)
951 {
952  statement result;
953  list /* of statement */ ls = NIL;
954 
955  /* clean not maybeuseful instances of the primary
956  */
957  MAP(ENTITY, array,
958  {
959  if (!gen_in_list_p(array, tokeep))
960  {
961  /* LIVEMAPPING(array) = .FALSE.
962  */
963  ls = CONS(STATEMENT,
966  bool_to_expression(false)), ls);
967  }
968  },
969  entities_list(load_dynamic_hpf(primary)));
970 
971  /* commented result
972  */
973  result = make_block_statement(ls);
974  if (ls) {
975  string comment =
976  strdup(concatenate("! clean live set for ",
977  entity_local_name(primary), "\n", NULL));
979  free(comment);
980  }
981  return result;
982 }
983 
984 static statement
986 {
987  statement result;
988  list /* of entity */ already_seen = NIL,
990  /* of statement */ ls;
991 
992  result = make_empty_statement();
993  {
994  string comment =
995  strdup(concatenate("! end of liveness management\n", NULL));
997  free(comment);
998  }
999  ls = CONS(STATEMENT, result, NIL);
1000 
1001  /* for each primary remapped at s, generate the management code.
1002  */
1003  MAP(ENTITY, array,
1004  {
1005  entity primary = load_primary_entity(array);
1006 
1007  if (!gen_in_list_p(primary, already_seen))
1008  {
1009  ls = CONS(STATEMENT,
1010  generate_dynamic_liveness_for_primary(primary, tokeep),
1011  ls);
1012  already_seen = CONS(ENTITY, primary, already_seen);
1013  }
1014  },
1015  tokeep);
1016 
1017  /* commented result
1018  */
1019  result = make_block_statement(ls);
1020  {
1021  string comment =
1022  strdup(concatenate("! liveness management\n", NULL));
1024  free(comment);
1025  }
1026  return result;
1027 }
1028 
1029 /* remaps src to trg.
1030  * first builds the equation and needed lists of indexes,
1031  * then call the actual code generation phase.
1032  */
1033 static statement
1035  entity src,
1036  entity trg)
1037 {
1038  Psysteme p, proc, enume;
1039  statement s;
1040  entity lambda = get_ith_temporary_dummy(3) ; /* P cycle */
1041  bool proc_distribution_p;
1042  list /* of entities */ l, lp, ll, lrm, ld, lo, left, scanners,
1043  /* of expressions */ lddc;
1044  bool time_remapping = get_bool_property("HPFC_TIME_REMAPPINGS");
1045 
1046  pips_debug(1, "%s -> %s\n", entity_name(src), entity_name(trg));
1047 
1048  if (src==trg) /* (optimization:-) */
1049  return make_empty_statement();
1050 
1051  if (time_remapping) push_performance_spy();
1052 
1053  /* builds and simplifies the systems.
1054  */
1055  p = generate_remapping_system(src, trg);
1057 
1058  remapping_variables(p, src, trg, &l, &lp, &ll, &lrm, &ld, &lo);
1059 
1060  /* it is not obvious to decide where to place
1061  * the cleaning, the equalities detection and the deducables...
1062  */
1063 
1064  clean_the_system(&p, &lrm, &lo);
1065  DEBUG_SYST(4, "cleaned system", p);
1066 
1067  if (get_bool_property("HPFC_EXTRACT_EQUALITIES"))
1068  {
1069  sc_find_equalities(&p);
1070  DEBUG_SYST(4, "more equalities", p);
1071  }
1072 
1073  lddc = simplify_deducable_variables(p, ll, &left);
1074  gen_free_list(ll);
1075  DEBUG_SYST(4, "without deducables system", p);
1076 
1077  /* the P cycle ?
1078  */
1079  proc_distribution_p = gen_in_list_p(lambda, lo);
1080  if (proc_distribution_p) gen_remove(&lo, lambda);
1081  scanners = gen_nconc(lo, left);
1082 
1083  DEBUG_ELST(4, "scanners", scanners);
1084 
1085  /* processors/array elements separation.
1086  *
1087  * ??? why row echelon? why not... it is not too bad a projection!
1088  * actually, what I want is to separate processors and elements.
1089  * Then I would like to perform some manipulations on the systems
1090  * to improve them, extracting deducables and lattices...
1091  * but the conservation of the optimized order is not obvious...
1092  * May/should I give it up in some cases? Well, I guess so.
1093  *
1094  * What's missing:
1095  * - extraction of the lattice if equalities remain in a system.
1096  * 1 Hermite transformation + variable list update...
1097  * - also some deducables could be extracted once the code is transformed.
1098  * - Q: what about variables which were kept althought not desired?
1099  */
1100  hpfc_algorithm_row_echelon(p, scanners, &proc, &enume);
1101  sc_rm(p);
1102 
1104  sc_transform_ineg_in_eg(enume);
1105 
1106  if (sc_egalites(proc))
1107  hpfc_warning("lattice extraction not implemented (proc)\n");
1108  /* {
1109  list ns = NIL;
1110  extract_lattice(proc, lp, &ns, &lp.. */
1111 
1112 
1113  if (sc_egalites(enume))
1114  {
1115  list ns = NIL;
1116  extract_lattice(enume, scanners, &ns, &lddc);
1117  gen_free_list(scanners), scanners=ns;
1118  }
1119 
1120  DEBUG_SYST(3, "proc", proc);
1121  DEBUG_SYST(3, "enum", enume);
1122 
1123  /* generates the code.
1124  */
1126  (src, trg, proc, enume, l, lp, scanners, ld, lddc, proc_distribution_p));
1127 
1128  /* clean.
1129  */
1130  sc_rm(proc), sc_rm(enume);
1131  gen_free_list(scanners);
1133  gen_map((gen_iter_func_t)gen_free, lddc), gen_free_list(lddc); /* ??? */
1134 
1136 
1137  if (time_remapping)
1138  pop_performance_spy(stderr,
1139  concatenate("remapping ",
1140  entity_name(src), " -> ",
1141  entity_name(trg), NULL));
1142 
1143  DEBUG_STAT(6, "result", s);
1144 
1145  return s;
1146 }
1147 
1148 /* file name for storing the remapping code.
1149  * {module}_{array}_{src}_{trg}_node.h
1150  */
1151 static string
1153  renaming remap)
1154 {
1155  char *buffer;
1156  entity src = renaming_old(remap), trg = renaming_new(remap);
1157  string module, array;
1158 
1161 
1162  asprintf(&buffer, "%s_%s_%"PRIdPTR"_%"PRIdPTR"_node.h", module, array,
1164 
1165  free(module);
1166  free(array);
1167 
1168  return buffer;
1169 }
1170 
1171 /* quick recursion to find the entities referenced in a statement.
1172  * the list is allocated and returned.
1173  */
1174 static list /* of entity */ l_found;
1175 static void loop_rwt(loop l)
1177 static void reference_rwt(reference r)
1179 
1180 static list
1182 {
1183  l_found = NIL;
1186  return l_found;
1187 }
1188 
1189 static text
1191 {
1192  text t;
1193  debug_on("PRETTYPRINT_DEBUG_LEVEL");
1194  t = Text_Statement(entity_undefined, 0, s);
1195  debug_off();
1196  return t;
1197 }
1198 
1199 static void
1201 {
1202  string file_name, dir;
1203  FILE * f;
1204  statement remap;
1205  text t;
1206  list /* of entity */ l;
1207  entity src = renaming_old(r), trg = renaming_new(r);
1208 
1209  pips_debug(1, "%s -> %s\n",
1210  entity_name(src), entity_name(trg));
1211 
1212  /* generates the remapping code and text
1213  * !!! generated between similar arrays...
1214  */
1216  load_similar_mapping(trg));
1218  t = protected_text_statement(remap);
1219 
1220  /* stores the remapping as computed
1221  */
1222  l = list_of_referenced_entities(remap);
1224 
1225  /* put it in a file
1226  */
1228  string rfn = remapping_file_name(r);
1229  asprintf(&file_name,"%s/%s",dir,rfn);
1230  free(rfn);
1231  free(dir);
1232 
1233  f = hpfc_fopen(file_name);
1234  print_text(f, t);
1236 
1237  free_text(t);
1238  free(file_name);
1239  free_statement(remap);
1240  gen_free_list(l);
1241 }
1242 
1243 /* just a hack because pips does not have 'include'
1244  */
1245 static statement
1247 {
1248  statement result;
1249 
1250  result = make_empty_statement();
1251  {
1252  string comment =
1253  strdup(concatenate(" include '",
1254  remapping_file_name(r), "'\n", NULL));
1256  free(comment);
1257  }
1258  return result;
1259 }
1260 
1261 /* returns the initialization statement:
1262  * must initialize the status and liveness of arrays
1263  */
1264 statement
1266  statement root)
1267 {
1268  list /* of statement */ ls = NIL;
1269  list /* of entity */ le =
1271 
1272  /* LIVENESS(...) = .TRUE.
1273  * STATUS(...) = ...
1274  */
1275  MAP(RENAMING, r,
1277  load_renamings(root));
1278 
1279  /* LIVENESS(...) = .FALSE.
1280  */
1281  MAP(ENTITY, array,
1283  ls = CONS(STATEMENT, generate_all_liveness(array, false), ls),
1284  le);
1285 
1286  gen_free_list(le), le = NIL;
1287 
1288  return make_block_statement(ls);
1289 }
1290 
1291 /* void remapping_compile(s, hsp, nsp)
1292  * statement s, *hsp, *nsp;
1293  *
1294  * what: generates the remapping code for s.
1295  * how: polyhedron technique.
1296  * input: s, the statement.
1297  * output: statements *hsp and *nsp, the host and SPMD node code.
1298  * side effects: (none?)
1299  * bugs or features:
1300  */
1301 void
1303  statement s, /* initial statement in the source code */
1304  statement *hsp, /* Host Statement Pointer */
1305  statement *nsp) /* idem Node */
1306 {
1307  statement tmp;
1308  list /* of statements */ l = NIL;
1309 
1310  debug_on("HPFC_REMAPPING_DEBUG_LEVEL");
1311  what_stat_debug(1, s);
1312 
1313  *hsp = make_empty_statement(); /* nothing for host */
1314 
1315  /* comment at the end
1316  */
1317  tmp = make_empty_statement();
1318  {
1319  string comment = strdup(concatenate("! end remappings\n", NULL));
1321  free(comment);
1322  }
1323  l = CONS(STATEMENT, tmp, l);
1324 
1325  /* dynamic liveness management if required
1326  */
1327  if (get_bool_property("HPFC_DYNAMIC_LIVENESS"))
1328  {
1330  }
1331 
1332  /* remapping codes (indirect thru include)
1333  */
1334  MAP(RENAMING, r,
1335  {
1336  pips_debug(7, "remapping %s -> %s\n", entity_name(renaming_old(r)),
1338  if (renaming_old(r)==renaming_new(r)) /* KILL => status update */
1340  l);
1341  else
1342  {
1345 
1348  }
1349  },
1350  load_renamings(s));
1351 
1352  /* comment at the beginning
1353  */
1354  tmp = make_empty_statement();
1355  {
1356  string comment = strdup(concatenate("! begin remappings\n", NULL));
1358  free(comment);
1359  }
1360  l = CONS(STATEMENT, tmp, l);
1361 
1362  *nsp = make_block_statement(l); /* block of remaps for the nodes */
1363  DEBUG_STAT(8, "result", *nsp);
1364 
1365  debug_off();
1366 }
1367 
1368 /* that is all
1369  */
call make_call(entity a1, list a2)
Definition: ri.c:269
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
void free_statement(statement p)
Definition: ri.c:2189
void free_text(text p)
Definition: text.c:74
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
#define VALUE_ZERO
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
#define VALUE_MONE
#define divide(a, b)
#define VALUE_ONE
Psysteme entity_to_declaration_constraints(entity e, tag what)
gives back the constraints due to the declarations.
Definition: build-system.c:285
Psysteme generate_system_for_equal_variables(int n, entity(*gen1)(int), entity(*gen2)(int))
Definition: build-system.c:751
Psysteme shift_system_to_prime_variables(Psysteme s)
Definition: build-system.c:173
Psysteme generate_system_for_distributed_variable(entity v)
Psysteme generate_system_for_variable(v) entity v;.
Definition: build-system.c:789
entity node_module
Definition: compiler.c:47
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
void reset_information_for_code_optimizations(void)
statement systeme_to_loop_nest(Psysteme, list, statement, entity)
sc is used to generate the loop nest bounds for variables vars.
void set_information_for_code_optimizations(Psysteme)
I could keep the system for further optimizations...
statement generate_optional_if(Psysteme, statement)
statement generate_optional_if(sc, stat)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
void gen_free(gen_chunk *obj)
version without shared_pointers.
Definition: genClib.c:992
statement hpfc_compute_lid(entity lid, entity proc, entity(*creation)(), entity array)
statement st_compute_lid(proc)
statement hpfc_lazy_guard(bool snd, statement then)
returns if (LAZY_{SEND,RECV}) then
statement generate_deducables(list le)
statement generate_deducables(list le)
Definition: generate-util.c:83
statement hpfc_lazy_packing(entity array, entity lid, entity(*creation)(), bool pack, bool lazy)
the lazy issues.
statement define_node_processor_id(entity proc, entity(*creation)(int))
builds a statement VAR_i = MYPOS(i, proc_number) // i=1 to proc dimension
Definition: generate-util.c:49
statement hpfc_generate_message(entity ld, bool send, bool lazy)
expression make_reference_expression(entity e, entity(*creation)())
statement hpfc_initsend(bool lazy)
statement hpfc_buffer_initialization(bool is_send, _UNUSED_ bool is_lazy, bool job_was_done)
statement hpfc_broadcast_if_necessary(entity array, entity trg, entity lid, entity proc, bool is_lazy)
lazy or not...
statement hpfc_lazy_buffer_packing(entity src, entity trg, entity lid, entity proc, entity(*array_dim)(), bool is_send, bool is_lazy)
lazy in actually sending or not the packed buffer immediatly...
void free(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_map(gen_iter_func_t fp, const list l)
Definition: list.c:172
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
statement make_assign_statement(expression, expression)
Definition: statement.c:583
void insert_comments_to_statement(statement, const char *)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
Definition: statement.c:1916
void update_object_for_module(void *obj, entity module)
#define renaming_old(x)
Definition: hpf_private.h:969
#define entities_list(x)
Definition: hpf_private.h:414
#define renaming_new(x)
Definition: hpf_private.h:971
#define RENAMING(x)
RENAMING.
Definition: hpf_private.h:939
void get_entity_dimensions(entity e, int dim, int *plow, int *pup)
Definition: hpfc-util.c:651
bool replicated_p(entity e)
replicated_p
Definition: hpfc-util.c:96
bool processors_dim_replicated_p(_UNUSED_ entity p, entity a, int i)
true if array a is replicated on processors p i-th dimension.
Definition: hpfc-util.c:143
#define src(name, suf)
HPFC by Fabien Coelho, May 1993 and later...
Definition: compile.c:41
FILE * hpfc_fopen(string name)
Definition: compile.c:329
void hpfc_fclose(FILE *f, string name)
Definition: compile.c:341
list list_of_distributed_arrays_for_module(entity module)
returns the list of entities that are 'local' to module
Definition: declarations.c:72
#define array_to_template(array)
#define DEBUG_SYST(D, W, S)
#define array_to_processors(array)
#define TWIN_P
#define IDIVIDE
#define LAZY_MESSAGES
#define what_stat_debug(level, stat)
#define DEBUG_ELST(D, W, L)
#define LIVEMAPPING
#define template_to_processors(template)
#define MYLID
#define MSTATUS
#define LAZY_RECV
#define hpfc_warning
WARNING.
#define DEBUG_STAT(D, W, S)
#define primary_entity_p(a)
#define T_LID
Variables.
#define add_to_list_of_vars(l, fun, n)
list of variables...
Definition: defines-local.h:89
#define USE_BUFFERS
list base_to_list(Pbase base)
Most includes are centralized here.
#define set_logical(var, b)
void add_remapping_as_computed(renaming r, list vars)
variables to be declared
Definition: hpfc.c:121
void add_remapping_as_used(renaming x)
Definition: hpfc.c:135
bool remapping_already_computed_p(renaming x)
list of already computed remappings...
Definition: hpfc.c:105
entity get_ith_array_prime(int)
entities load_dynamic_hpf(entity)
entity hpfc_name_to_entity(const char *)
Definition: run-time.c:817
entity get_ith_template_dummy(int)
entity load_similar_mapping(entity)
entity get_ith_cycle_dummy(int)
void clean_the_system(Psysteme *, list *, list *)
Definition: io-compile.c:360
list load_renamings(statement)
entity get_ith_processor_prime(int)
entity get_ith_array_dummy(int)
entity get_ith_template_prime(int)
entity load_primary_entity(entity)
entity get_ith_cycle_prime(int)
entity get_ith_local_prime(int)
entity get_ith_block_dummy(int)
entity get_ith_processor_dummy(int)
void hpfc_algorithm_row_echelon(Psysteme, list, Psysteme *, Psysteme *)
io-compile.c
Definition: io-compile.c:127
entity get_ith_local_dummy(int)
bool bound_dynamic_hpf_p(entity)
list simplify_deducable_variables(Psysteme, list, list *)
list simplify_deducable_variables(syst, vars, pleftvars) Psysteme syst; list vars,...
Definition: io-compile.c:562
entity get_ith_block_prime(int)
entity get_ith_temporary_dummy(int)
intptr_t load_hpf_number(entity)
entities load_maybeuseful_mappings(statement)
void extract_lattice(Psysteme, list, list *, list *)
lattice_extraction.c
string db_get_directory_name_for_module(const char *name)
returns the allocated and mkdir'ed directory for module name
Definition: lowlevel.c:150
#define debug_on(env)
Definition: misc-local.h:157
#define _UNUSED_
Definition: misc-local.h:232
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define asprintf
Definition: misc-local.h:225
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
void push_performance_spy(void)
perf_spy.c
Definition: perf_spy.c:89
void pop_performance_spy(FILE *, string)
Definition: perf_spy.c:97
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
void(* gen_iter_func_t)(void *)
Definition: newgen_types.h:116
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
#define WORKSPACE_SRC_SPACE
Definition: pipsdbm-local.h:32
text Text_Statement(entity, int, statement)
static hash_table pl
properties are stored in this hash table (string -> property) for fast accesses.
Definition: properties.c:783
static statement if_different_pe_and_not_twin(entity src, entity lid, statement strue, statement sfalse)
to be generated: IF (MYLID.NE.LID[.AND.NOT.HPFC_TWIN_P(an, LID)]) THEN true ELSE false ENDIF
Definition: remapping.c:408
static Pcontrainte partial_linearization(entity array, bool distributed, entity var, int *psize, entity(*create_var)(int))
HPFC module by Fabien COELHO.
Definition: remapping.c:48
static statement generate_remapping_guard(entity src, entity trg, statement the_code)
Runtime descriptors management around the remapping code.
Definition: remapping.c:859
statement generate_all_liveness(entity primary, bool val)
Definition: remapping.c:940
static statement update_runtime_for_remapping(entity trg)
Definition: remapping.c:829
#define LZY
Definition: remapping.c:480
#define NLZ
Definition: remapping.c:479
static statement generate_dynamic_liveness_management(statement s)
Definition: remapping.c:985
static expression live_mapping_expression(int index)
returns LIVEMAPPING(index)
Definition: remapping.c:793
#define BUF
Definition: remapping.c:483
#define NBF
Definition: remapping.c:482
static Psysteme generate_remapping_system(entity src, entity trg)
returns the full remapping system, including the source and target mappings systems,...
Definition: remapping.c:175
#define PRE
Definition: remapping.c:475
#define RCV
Definition: remapping.c:472
#define CPY
in the following functions tag t controls the code generation, depending of what is to be generated (...
Definition: remapping.c:470
static statement generate_all_liveness_but(entity primary, bool val, entity butthisone)
Definition: remapping.c:906
static text protected_text_statement(statement s)
Definition: remapping.c:1190
static statement broadcast(entity src, entity lid, entity proc, Psysteme sr, list ldiff, bool lazy)
builds the diffusion loop.
Definition: remapping.c:442
static Psysteme generate_work_sharing_system(entity src, entity trg)
load-balancing equation as suggested in the A-274 report.
Definition: remapping.c:122
static string remapping_file_name(renaming remap)
file name for storing the remapping code.
Definition: remapping.c:1152
static statement remapping_stats(int t, Psysteme s, Psysteme sr, list ll, list ldiff, list ld, entity lid, entity src, entity trg)
generates a remapping loop nest (copy/send/receive/broadcast) basically a loop on elements with pre/i...
Definition: remapping.c:615
static statement set_live_status(entity trg, _UNUSED_ bool val)
Definition: remapping.c:818
static statement generate_dynamic_liveness_for_primary(entity primary, list tokeep)
Definition: remapping.c:948
static statement generate_remapping_include(renaming r)
just a hack because pips does not have 'include'
Definition: remapping.c:1246
static void loop_rwt(loop l)
Definition: remapping.c:1175
#define PST
Definition: remapping.c:477
static void generate_hpf_remapping_file(renaming r)
Definition: remapping.c:1200
static list list_of_referenced_entities(statement s)
Definition: remapping.c:1181
#define SND
Definition: remapping.c:471
static expression mylid_ne_lid(entity lid)
Definition: remapping.c:395
static statement gen(int what, entity src, entity trg, entity lid, entity proc, entity(*create_src)(), entity(*create_trg)(), Psysteme sr, list ldiff)
arguments: all that may be useful to generate some code
Definition: remapping.c:498
statement root_statement_remapping_inits(statement root)
returns the initialization statement: must initialize the status and liveness of arrays
Definition: remapping.c:1265
static void remapping_variables(Psysteme s, entity a1, entity a2, list *pl, list *plp, list *pll, list *plrm, list *pld, list *plo)
??? assumes that there are no parameters.
Definition: remapping.c:206
static statement generate_remapping_code(entity src, entity trg, Psysteme procs, Psysteme locals, list l, list lp, list ll, list ldiff, list ld, bool dist_p)
generates a full remapping code, given the systems and indexes to be used in the different loops.
Definition: remapping.c:679
#define BRD
Definition: remapping.c:473
static list l_found
quick recursion to find the entities referenced in a statement.
Definition: remapping.c:1174
static statement processor_loop(Psysteme s, _UNUSED_ list l_psi, list l_oth, entity psi, entity oth, entity lid, entity array, entity(*create_psi)(), entity(*create_oth)(), statement body, bool sh)
to be generated: ??? the Proc cycle should be deduce directly in some case...
Definition: remapping.c:304
void remapping_compile(statement s, statement *hsp, statement *nsp)
void remapping_compile(s, hsp, nsp) statement s, *hsp, *nsp;
Definition: remapping.c:1302
#define INL
Definition: remapping.c:476
static void reference_rwt(reference r)
Definition: remapping.c:1177
static statement hpf_remapping(entity src, entity trg)
remaps src to trg.
Definition: remapping.c:1034
static statement elements_loop(Psysteme s, list ll, list ld, statement body)
to be generated:
Definition: remapping.c:381
Pcontrainte full_linearization(entity obj, entity var, int *psize, entity(*create_var)(int), bool fortran_way, int initial_offset)
builds a linarization equation of the dimensions of obj.
Definition: remapping.c:80
static statement set_array_status_to_target(entity trg)
Definition: remapping.c:801
#define ret(name)
I have to deal with a 4D space to generate some code:
Definition: remapping.c:494
#define test_to_statement(t)
#define and_expression(e1, e2)
#define ne_expression(e1, e2)
#define eq_expression(e1, e2)
#define not_expression(e)
#define make_empty_statement
An alias for make_empty_block_statement.
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
Pbase entity_list_to_base(list l)
Definition: entity.c:2860
expression reference_to_expression(reference r)
Definition: expression.c:196
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression bool_to_expression(bool b)
Definition: expression.c:1238
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
int element_number(basic, list)
END_EOLE.
Definition: size.c:391
int NumberOfDimension(entity)
Definition: size.c:588
int variable_entity_dimension(entity)
variable_entity_dimension(entity v): returns the dimension of variable v; scalar have dimension 0.
Definition: variable.c:1293
#define reference_variable(x)
Definition: ri.h:2326
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_variable(x)
Definition: ri.h:2949
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792
#define loop_index(x)
Definition: ri.h:1640
#define variable_basic(x)
Definition: ri.h:3120
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
void sc_separate_on_vars(Psysteme s, Pbase b, Psysteme *pwith, Psysteme *pwithout)
Definition: sc.c:418
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Psysteme extract_nredund_subsystem(Psysteme s1, Psysteme s2)
Psysteme extract_nredund_subsystem(s1, s2) Psysteme s1, s2;.
Psysteme sc_append(Psysteme s1, Psysteme s2)
Psysteme sc_append(Psysteme s1, Psysteme s2): calcul de l'intersection des polyedres definis par s1 e...
char * strdup()
void sc_find_equalities(Psysteme *ps)
void sc_transform_ineg_in_eg(Psysteme sc)
Transform the two constraints A.x <= b and -A.x <= -b of system sc into an equality A....
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
static entity array
static string buffer
Definition: string.c:113
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
void print_text(FILE *fd, text t)
Definition: print.c:195
static string file_name
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define base_rm(b)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
Pvecteur vect_make(Pvecteur v, Variable var, Value val,...)
Pvecteur vect_make(v, [var, val,]* 0, val) Pvecteur v; // may be NULL, use assigne anyway Variable va...
Definition: alloc.c:165
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72