Hitmap 1.3
 All Data Structures Namespaces Files Functions Variables Typedefs Friends Macros Groups Pages
hit_layout.c
Go to the documentation of this file.
1 
15 /*
16  * <license>
17  *
18  * Hitmap v1.2
19  *
20  * This software is provided to enhance knowledge and encourage progress in the scientific
21  * community. It should be used only for research and educational purposes. Any reproduction
22  * or use for commercial purpose, public redistribution, in source or binary forms, with or
23  * without modifications, is NOT ALLOWED without the previous authorization of the copyright
24  * holder. The origin of this software must not be misrepresented; you must not claim that you
25  * wrote the original software. If you use this software for any purpose (e.g. publication),
26  * a reference to the software package and the authors must be included.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY
29  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
31  * THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Copyright (c) 2007-2015, Trasgo Group, Universidad de Valladolid.
39  * All rights reserved.
40  *
41  * More information on http://trasgo.infor.uva.es/
42  *
43  * </license>
44 */
45 
46 #include <stdio.h>
47 #include <math.h>
48 
49 #include <hit_layout.h>
50 #include <hit_funcop.h>
51 
52 #include <hit_com.h>
53 
54 #include <hit_sshape.h>
55 #include <hit_cshape.h>
56 #include <hit_bshape.h>
57 
58 /* TOOL: EXTERN DECLARATION FOR vfor LOOPS */
60 
61 /* NULL SIGNATURE LAYOUT VALUE */
63 
64 /* NULL GROUP VALUE */
66 
67 /* NULL GROUP LAYOUT VALUE */
69 
70 /* NULL LAYOUT VALUE */
72 
73 
74 /* PREDEFINED LAYOUT FUNCTIONS */
75 
76 /* A.1. GENERIC SIGNATURE FUNCTIONS */
77 /* NOTE: AN INVERSE FUNCTION IS ALSO PROVIDED FOR EACH SIGNATURE */
78 
79 /* A.1.1. GENERIC SIGNATURES: COPY SIGNATURE -- NON-PARTITIONED DIMENSION */
80 int hit_layout_plug_layCopy_Sig(int procId, int procsCard, int blocksCard,
81  float* extraParameter,
82  HitSig input, HitSig *res ) {
83  HIT_NOT_USED( procId );
84  HIT_NOT_USED( procsCard );
85  HIT_NOT_USED( blocksCard );
86  HIT_NOT_USED( extraParameter );
87 
88  /* COPY SIGNATURE */
89  (*res) = input;
90  /* RETURN ACTIVE */
91  return 1;
92 }
93 int hit_layout_plug_layCopy_SigInv(int procId, int procsCard, int blocksCard,
94  float* extraParameter,
95  HitSig input,
96  int ind ) {
97  HIT_NOT_USED( procsCard );
98  HIT_NOT_USED( blocksCard );
99  HIT_NOT_USED( input );
100  HIT_NOT_USED( extraParameter );
101 
102  /* CHECK: THE INDEX SHOULD BE IN THE INPUT DOMAIN */
103  if ( ! hit_sigIn( input, ind ) ) return HIT_RANK_NULL;
104 
105  /* RETURN PROC ID: MYSELF */
106  return procId;
107 }
108 
109 /* A.1.2. GENERIC SIGNATURES: ALL IN ONE -- NON-PARTITIONED DIMENSION */
110 int hit_layout_plug_layAllInOne_Sig(int procId, int procsCard, int blocksCard,
111  float* extraParameter,
112  HitSig input, HitSig *res ) {
113  HIT_NOT_USED( procsCard );
114  HIT_NOT_USED( blocksCard );
115  HIT_NOT_USED( extraParameter );
116 
117  int active;
118 
119  /* COPY SIGNATURE */
120  if ( procId == 0 ) {
121  (*res) = input;
122  active = 1;
123  }
124  else {
125  (*res) = HIT_SIG_NULL;
126  active = 0;
127  }
128 
129  /* RETURN ACTIVE */
130  return active;
131 }
132 int hit_layout_plug_layAllInOne_SigInv(int procId, int procsCard, int blocksCard,
133  float* extraParameter,
134  HitSig input,
135  int ind ) {
136  HIT_NOT_USED( procsCard );
137  HIT_NOT_USED( blocksCard );
138  HIT_NOT_USED( input );
139  HIT_NOT_USED( extraParameter );
140 
141  /* CHECK: ONLY THE LEADER HAS SOMETHING */
142  if ( procId == 0 ) {
143  /* CHECK: THE INDEX SHOULD BE IN THE INPUT DOMAIN */
144  if ( ! hit_sigIn( input, ind ) ) return HIT_RANK_NULL;
145  return 0;
146  }
147  else return HIT_RANK_NULL;
148 }
149 
150 /* A.2 GENERIC MAX/MIN CARD FUNCTIONS */
151 /* A.2.1 GENERIC MAX CARD: COPY SIGNATURE -- NON-PARTITIONED DIMENSION */
152 int hit_layout_plug_layCopy_maxCard( int procsCard, int blocksCard, float* extraParameter ) {
153  HIT_NOT_USED( procsCard );
154  HIT_NOT_USED( extraParameter );
155 
156  return blocksCard;
157 }
158 
159 /* A.2.2. GENERIC MAX CARD: REGULAR (BLOCKING/CYCLIC) */
160 int hit_layout_plug_layRegular_maxCard( int procsCard, int blocksCard, float* extraParameter ) {
161  HIT_NOT_USED( extraParameter );
162 
163  return (int)ceil( (double)blocksCard / procsCard);
164 }
165 
166 /* A.2.3 GENERIC MIN CARD: COPY SIGNATURE -- NON-PARTITIONED DIMENSION */
167 int hit_layout_plug_layCopy_minCard( int procsCard, int blocksCard, float* extraParameter ) {
168  HIT_NOT_USED( procsCard );
169  HIT_NOT_USED( extraParameter );
170 
171  return blocksCard;
172 }
173 
174 /* A.2.4. GENERIC MIN CARD: REGULAR (BLOCKING/CYCLIC) */
175 int hit_layout_plug_layRegular_minCard( int procsCard, int blocksCard, float* extraParameter ) {
176  HIT_NOT_USED( extraParameter );
177 
178  return (int)floor( (double)blocksCard / procsCard);
179 }
180 
181 /* A.3 GENERIC NUM ACTIVES FUNCTIONS */
182 /* A.3.1. GENERIC NUM. ACTIVES: REGULAR (BLOCKING/CYCLIC) */
183 int hit_layout_plug_layRegular_numActives( int procsCard, int blocksCard, float* extraParameter ) {
184  HIT_NOT_USED( extraParameter );
185 
186 // printf("CTRL REGULAR_numActive: Rank: %d --- %d, %d, %f\n", hit_Rank, procsCard, blocksCard, extraParameter );
187  return hit_min( blocksCard, procsCard );
188 }
189 
190 /* A.3.2. GENERIC NUM. ACTIVES: WHOLE STRUCTURE IN ONE */
191 int hit_layout_plug_layAllInOne_numActives( int procsCard, int blocksCard, float* extraParameter ) {
192  HIT_NOT_USED( procsCard );
193  HIT_NOT_USED( blocksCard );
194  HIT_NOT_USED( extraParameter );
195 
196 // printf("CTRL ALL_IN_ONE_numActive: Rank: %d --- %d, %d, %f\n", hit_Rank, procsCard, blocksCard, extraParameter );
197  return 1;
198 }
199 
200 
201 /* A.4 GENERIC FUNCTIONS TO TRASNFORM TOPOLOGY RANKS TO ACTIVE RANKS AND VICEVERSA */
202 /* A.4.1. GENERIC REGULAR CONTIGUOUS: REGULAR (BLOCKING/CYCLIC) WITH NON-ACTIVE AT THE END */
204  int procId, int procsCard, int blocksCard, float* extraParameter ) {
205  HIT_NOT_USED( extraParameter );
206 
207  /* MODE: TOPO TO ACTIVE */
208  if ( topoActiveMode == HIT_LAY_RANKS_TOPO_TO_ACTIVE ) {
209  /* GET NUM ACTIVES, ASSERT: procId IS ACTIVE */
210  int actives = hit_min( blocksCard, procsCard );
211  if ( procId < 0 || procId > actives ) return HIT_RANK_NULL;
212  else return procId;
213  }
214  /* MODE: ACTIVE TO TOPO */
215  else return procId;
216 
217 }
218 
219 /* A.4.2. GENERIC REGULAR F: REGULAR (BLOCKING/CYCLIC) WITH GROUPS, FIRST IS LEADER */
220 int hit_layout_plug_layRegularF_ranks( char topoActiveMode,
221  int procId, int procsCard, int blocksCard, float* extraParameter ) {
222  HIT_NOT_USED( extraParameter );
223 
224  /* MODE INDEPENDENT */
225  if ( blocksCard >= procsCard ) {
226  if ( procId < 0 || procId > procsCard ) return HIT_RANK_NULL;
227  else return procId;
228  }
229 
230  /* MODE: TOPO TO ACTIVE */
231  if ( topoActiveMode == HIT_LAY_RANKS_TOPO_TO_ACTIVE )
232  return (int)(procId * (double)blocksCard / procsCard );
233  /* MODE: ACTIVE TO TOPO */
234  else return (int)ceil( procId * (double)procsCard / blocksCard );
235 }
236 
237 /* A.4.3. GENERIC REGULAR L: REGULAR (BLOCKING/CYCLIC) WITH GROUPS, LAST IS LEADER */
238 int hit_layout_plug_layRegularL_ranks( char topoActiveMode,
239  int procId, int procsCard, int blocksCard, float* extraParameter ) {
240  HIT_NOT_USED( extraParameter );
241 
242  /* MODE INDEPENDENT */
243  if ( blocksCard >= procsCard ) {
244  if ( procId < 0 || procId > procsCard ) return HIT_RANK_NULL;
245  else return procId;
246  }
247 
248  /* MODE: TOPO TO ACTIVE */
249  if ( topoActiveMode == HIT_LAY_RANKS_TOPO_TO_ACTIVE )
250  return (int)(procId * (double)blocksCard / procsCard );
251  /* MODE: ACTIVE TO TOPO */
252  else return (int)ceil( (procId+1) * (double)procsCard / blocksCard ) - 1;
253 }
254 
255 /* A.4.4. GENERIC ALL IN ONE: ONLY ONE ACTIVE (LEADER) */
256 int hit_layout_plug_layAllInOne_ranks( char topoActiveMode,
257  int procId, int procsCard, int blocksCard, float* extraParameter ) {
258  HIT_NOT_USED( topoActiveMode );
259  HIT_NOT_USED( procsCard );
260  HIT_NOT_USED( blocksCard );
261  HIT_NOT_USED( extraParameter );
262 
263  /* MODE: TOPO TO ACTIVE */
264  /* MODE: ACTIVE TO TOPO */
265  if ( procId != 0 ) return HIT_RANK_NULL;
266  else return 0;
267 }
268 
269 
270 
271 /* 1. LAYOUT (SIGNATURES): BLOCKS */
272 /* 1.1. BLOCKS: SIGNATURE */
273 int hit_layout_plug_layBlocks_Sig(int procId, int procsCard, int blocksCard,
274  float* extraParameter,
275  HitSig input, HitSig *res ) {
276  HIT_NOT_USED( extraParameter );
277 
278  /* REJECT EMPTY INPUT SIGNATURES */
279  if ( blocksCard == 0 ) {
280  (*res) = HIT_SIG_NULL;
281  return 0;
282  }
283 
284  int begin = procId * blocksCard / hit_min(blocksCard, procsCard);
285 
286  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
287  if ( begin >= blocksCard ) {
288  /* RETURN NUL SIGNATURE AND NON-ACTIVE */
289  (*res) = HIT_SIG_NULL;
290  return 0;
291  }
292  else {
293  /* BEGIN */
294  (*res).begin = begin * input.stride + input.begin;
295 
296  /* END */
297  (*res).end = ((( procId + 1 ) * blocksCard / hit_min(blocksCard, procsCard))-1)
298  * input.stride + input.begin;
299 
300  /* STRIDE */
301  (*res).stride = input.stride;
302  }
303 
304  /* RETURN ACTIVE */
305  return 1;
306 }
307 int hit_layout_plug_layBlocks_SigInv(int procId, int procsCard, int blocksCard,
308  float* extraParameter,
309  HitSig input,
310  int ind ) {
311  HIT_NOT_USED( procId );
312  HIT_NOT_USED( extraParameter );
313 
314  /* CHECK: THE INDEX SHOULD BE IN THE INPUT DOMAIN */
315  if ( ! hit_sigIn( input, ind ) ) return HIT_RANK_NULL;
316 
317  /* RETURN PROC ID */
318  int tileInd = (ind - input.begin) / input.stride;
319  int id = tileInd * hit_min(blocksCard, procsCard) / blocksCard;
320  if ( (id+1) * blocksCard / hit_min(blocksCard, procsCard) == tileInd ) return id+1;
321  else return id;
322 }
323 
324 
325 /* 1.4. BLOCKS: LAYOUT FUNCTION INTERFACE */
327  HitLayout res;
328  HitRanks group;
329  //float extraParameterValue = 0.0;
330 
331  /* ACTIVE */
332  res = hit_layout_wrapper(
333  topo,
334  shape,
337  NULL,
338  NULL,
340  NULL,
342  NULL,
344  NULL,
346  NULL,
347  NULL, //&extraParameterValue,
349  );
350 
351  res.type = HIT_LAYOUT_BLOCKS;
352 
353  if(! res.active){
354  // DEFAULT VALUES
355  //res.group = HIT_GROUP_ID_NULL;
356  //res.leaderRanks = HIT_RANKS_NULL;
357  //res.leader = 0;
358  return res;
359  }
360 
361  /* MY GROUP */
362  int dim;
363  for (dim=0; dim<hit_shapeDims(shape); dim++) {
364  if( res.active ){
365  group.rank[dim] = topo.self.rank[dim];
366  } else {
367  group.rank[dim] = -1;
368  }
369  }
370  res.group = hit_layActiveRanksId( res, group );
371 
372  /* MY LEADER */
373  //res.leader = topo.linearRank;
374  res.leaderRanks = group;
375  res.leader = 1;
376 
377  return res;
378 }
379 
380 
381 /* 1.4.S. BLOCKS IN A RESTRICTED DIMENSION: LAYOUT FUNCTION INTERFACE */
383  HitLayout res;
384  HitRanks group;
385  //float extraParameterValue = 0.0;
386 
387  /* ACTIVE */
388  res = hit_layout_wrapper(
389  topo,
390  shape,
403  NULL, //&extraParameterValue,
404  restrictDim
405  );
406 
408 
409  if(! res.active){
410  // DEFAULT VALUES
411  //res.group = HIT_GROUP_ID_NULL;
412  //res.leaderRanks = HIT_RANKS_NULL;
413  //res.leader = 0;
414  return res;
415  }
416 
417  /* MY GROUP */
418  int dim;
419  for (dim=0; dim<hit_shapeDims(shape); dim++) {
420  if( res.active ){
421  group.rank[dim] = topo.self.rank[dim];
422  } else {
423  group.rank[dim] = -1;
424  }
425  }
426  res.group = hit_layActiveRanksId( res, group );
427 
428  /* MY LEADER */
429  //res.leader = topo.linearRank;
430  res.leaderRanks = group;
431  res.leader = 1;
432 
433  return res;
434 }
435 
436 /* 1.2.1. BLOCKS WITH MINIMUM: SIGNATURE */
437 int hit_layout_plug_layMinBlocks_Sig(int procId, int procsCard, int blocksCard,
438  float* extraParameter,
439  HitSig input, HitSig *res ) {
440  int minimum = (int)*extraParameter;
441 
442  /* REJECT EMPTY INPUT SIGNATURES */
443  if ( blocksCard == 0 ) {
444  (*res) = HIT_SIG_NULL;
445  return 0;
446  }
447 
448  /* COMPUTE SIZE */
449  // INTEGER DIVISION: DETECT IF ANYONE COULD RECEIVE LESS THAN MINIMUM
450  int size = blocksCard / hit_min(blocksCard, procsCard);
451  if ( size < minimum ) {
452  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
453  int begin = procId * minimum;
454  if ( begin >= blocksCard ) {
455  /* RETURN NUL SIGNATURE AND NON-ACTIVE */
456  (*res) = HIT_SIG_NULL;
457  return 0;
458  }
459  /* COMPUTE SIGNATURE */
460  (*res).begin = begin * input.stride + input.begin;
461  (*res).end = ( begin + minimum ) * input.stride + input.begin;
462  (*res).stride = input.stride;
463  return 1;
464  }
465  else
466  //return hit_layout_plug_layBlocks_Sig(procId, procsCard, blocksCard, 0.0f, input, res );
467  return hit_layout_plug_layBlocks_Sig(procId, procsCard, blocksCard, NULL, input, res );
468 }
469 int hit_layout_plug_layMinBlocks_SigInv(int procId, int procsCard, int blocksCard,
470  float* extraParameter,
471  HitSig input,
472  int ind ) {
473  HIT_NOT_USED( procId );
474  int minimum = (int)*extraParameter;
475 
476  /* CHECK: THE INDEX SHOULD BE IN THE INPUT DOMAIN */
477  if ( ! hit_sigIn( input, ind ) ) return HIT_RANK_NULL;
478 
479  /* COMPUTE SIZE */
480  // INTEGER DIVISION: DETECT IF ANYONE CAN RECEIVE LESS THAN MINIMUM
481  int size = blocksCard / hit_min(blocksCard, procsCard);
482 
483  /* RETURN PROC ID */
484  int tileInd = (ind - input.begin) / input.stride;
485  if ( size < minimum )
486  return tileInd / minimum;
487  else
488  //return hit_layout_plug_layBlocks_SigInv(procId, procsCard, blocksCard, 0.0, input, ind );
489  return hit_layout_plug_layBlocks_SigInv(procId, procsCard, blocksCard, NULL, input, ind );
490 }
491 
492 /* 1.2.2. BLOCKS WITH MINIMUM: maxCard */
493 int hit_layout_plug_layMinBlocks_maxCard( int procsCard, int blocksCard, float* extraParameter ) {
494  int minimum = (int)*extraParameter;
495 
496  int regularMaxSize = hit_layout_plug_layRegular_maxCard( procsCard, blocksCard, extraParameter );
497  if ( regularMaxSize < minimum ) return minimum;
498  else return regularMaxSize;
499 }
500 /* 1.2.3. BLOCKS WITH MINIMUM: minCard */
501 int hit_layout_plug_layMinBlocks_minCard( int procsCard, int blocksCard, float* extraParameter ) {
502  int minimum = (int)*extraParameter;
503 
504  int regularMinSize = hit_layout_plug_layRegular_minCard( procsCard, blocksCard, extraParameter );
505  if ( regularMinSize < minimum ) return minimum;
506  else return regularMinSize;
507 }
508 /* 1.2.4. BLOCKS WITH MINIMUM: numActives */
509 int hit_layout_plug_layMinBlocks_numActives( int procsCard, int blocksCard, float* extraParameter ) {
510  int minimum = (int)*extraParameter;
511  return hit_min( procsCard, blocksCard/minimum );
512 }
513 /* 1.2.5. BLOCKS WITH MINIMUM: NON-ACTIVE AT THE END */
514 int hit_layout_plug_layMinBlocks_ranks( char topoActiveMode,
515  int procId, int procsCard, int blocksCard, float* extraParameter ) {
516  /* MODE: TOPO TO ACTIVE */
517  if ( topoActiveMode == HIT_LAY_RANKS_TOPO_TO_ACTIVE ) {
518  /* GET NUM ACTIVES, ASSERT: procId IS ACTIVE */
519  int actives = hit_layout_plug_layMinBlocks_numActives( procsCard, blocksCard, extraParameter );
520  if ( procId < 0 || procId > actives ) return HIT_RANK_NULL;
521  else return procId;
522  }
523  /* MODE: ACTIVE TO TOPO */
524  else return procId;
525 }
526 
527 
528 /* 1.4.M. BLOCKS WITH A MINIMUM SIZE: LAYOUT FUNCTION INTERFACE */
530  HitLayout res;
531  HitRanks group;
532  float extraParameterValue = (float)minElems;
533 
534  /* ACTIVE */
535  res = hit_layout_wrapper(
536  topo,
537  shape,
540  NULL,
541  NULL,
543  NULL,
545  NULL,
547  NULL,
549  NULL,
550  &extraParameterValue,
551  /* TODO: ?????? */
553  );
554 
556 
557  if(! res.active){
558  // DEFAULT VALUES
559  //res.group = HIT_GROUP_ID_NULL;
560  //res.leaderRanks = HIT_RANKS_NULL;
561  //res.leader = 0;
562  return res;
563  }
564 
565  /* MY GROUP */
566  int dim;
567  for (dim=0; dim<hit_shapeDims(shape); dim++) {
568  if( res.active ){
569  group.rank[dim] = topo.self.rank[dim];
570  } else {
571  group.rank[dim] = -1;
572  }
573  }
574  res.group = hit_layActiveRanksId( res, group );
575 
576  /* MY LEADER */
577  //res.leader = topo.linearRank;
578  res.leaderRanks = group;
579  res.leader = 1;
580 
581  return res;
582 }
583 
584 
585 /* 1.X LAYOUT (SIGNATURES): BLOCKS NO REPEATED, NON-ACTIVES AT THE END
586  * THIS IS AN ALTERNATIVE IMPLEMENTATION TO THE CURRENT BLOCKS LAYOUT */
587 /* 1.1. BLOCKS X: SIGNATURE */
588 int hit_layout_plug_layBlocksX_Sig(int procId, int procsCard, int blocksCard,
589  HitSig input, HitSig *res ) {
590  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
591  if ( blocksCard <= procsCard ) {
592  if ( procId >= blocksCard ) {
593  /* RETURN NUL SIGNATURE AND NON-ACTIVE */
594  (*res) = HIT_SIG_NULL;
595  return 0;
596  }
597  else {
598  /* ACTIVE ELEMENT */
599  (*res).begin = procId;
600  (*res).end = procId;
601  (*res).stride = 1;
602  }
603  }
604  /* MORE LOGICAL PROCESSES THAN VIRTUAL PROCESSORS */
605  else {
606  int begin = procId * blocksCard / hit_min(blocksCard, procsCard);
607 
608  /* BEGIN */
609  (*res).begin = begin * input.stride + input.begin;
610 
611  /* END */
612  (*res).end = ((( procId + 1 ) * blocksCard / hit_min(blocksCard, procsCard))-1)
613  * input.stride + input.begin;
614 
615  /* STRIDE */
616  (*res).stride = input.stride;
617  }
618 
619  /* RETURN ACTIVE */
620  return 1;
621 }
622 
623 
624 /* 1.4. BLOCKS: LAYOUT FUNCTION INTERFACE */
626 
627  /* CHECK IF ACTIVE */
628  HitLayout res;
629  HitRanks group = HIT_RANKS_NULL;
630  //float extraParameterValue = 0.0;
631 
632  /* ACTIVE */
633  res = hit_layout_wrapper(
634  topo,
635  shape,
638  NULL,
639  NULL,
641  NULL,
643  NULL,
645  NULL,
647  NULL,
648  NULL, //&extraParameterValue,
650  );
651 
652  res.type = HIT_LAYOUT_BLOCKSX;
653 
654  if(! res.active){
655  // DEFAULT VALUES
656  //res.group = HIT_GROUP_ID_NULL;
657  //res.leaderRanks = HIT_RANKS_NULL;
658  //res.leader = 0;
659  return res;
660  }
661 
662  /* MY GROUP */
663  int dim;
664  for (dim=0; dim<hit_shapeDims(shape); dim++) {
665  if( res.active ){
666  group.rank[dim] = topo.self.rank[dim];
667  } else {
668  group.rank[dim] = -1;
669  }
670  }
671 
672  // Transform ranks to process id
673  res.group = hit_layActiveRanksId(res,group);
674 
675  /* MY LEADER */
676  //res.leader = topo.linearRank;
677  res.leaderRanks = group;
678  res.leader = 1;
679 
680  return res;
681 }
682 
683 
684 /* 2. LAYOUT (SIGNATURES): BLOCK LOCATED ON GROUP LEADERS (First processor is leader) */
685 /* 2.1. BLOCKSF: SIGNATURE */
686 int hit_layout_plug_layBlocksF_Sig(int procId, int procsCard, int blocksCard,
687  float* extraParameter,
688  HitSig input, HitSig *res ) {
689  HIT_NOT_USED( extraParameter );
690 
691  /* COMPUTE BLOCK SIZE AND STARTING POINT */
692  double ratio = (double)blocksCard / procsCard;
693  double beginFrac = procId * ratio;
694  int begin = (int)beginFrac;
695 
696  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
697  if ( floor(beginFrac) == floor(beginFrac-ratio) ) {
698  /* RETURN NUL SIGNATURE AND NON-ACTIVE */
699  (*res) = HIT_SIG_NULL;
700  return 0;
701  }
702  else {
703  /* COMPUTE SIGNATURE */
704  /* BEGIN */
705  (*res).begin = begin * input.stride + input.begin;
706 
707  /* END */
708  int adjust = (blocksCard > procsCard) ? 1 : 0;
709  int end = ((procId + adjust) * blocksCard / procsCard ) - adjust;
710  (*res).end = end * input.stride + input.begin;
711 
712  /* STRIDE */
713  (*res).stride = input.stride;
714  }
715 
716  /* RETURN ACTIVE */
717  return 1;
718 }
719 
720 /* 2.4. BLOCKSF: LAYOUT FUNCTION INTERFACE */
722 
723  HitLayout res;
724  HitRanks group;
725  //HitRanks leader;
726  //float extraParameterValue = 0.0;
727 
728  res = hit_layout_wrapper(
729  topo,
730  shape,
733  NULL,
734  NULL,
736  NULL,
738  NULL,
740  NULL,
742  NULL,
743  NULL, //&extraParameterValue, //0.0,
745  );
746 
747  res.type = HIT_LAYOUT_BLOCKSF;
748 
749  if(! res.active ){
750  // DEFAULT VALUES
751  //res.group = HIT_GROUP_ID_NULL;
752  //res.leaderRanks = HIT_RANKS_NULL;
753  //res.leader = 0;
754  return res;
755  }
756 
757 
758  /* MY GROUP & MY LEADER */
759  int dim;
760  for (dim=0; dim<hit_shapeDims(shape); dim++) {
761  double ratio = (double) hit_sigCard(hit_shapeSig(shape,dim)) / topo.card[dim];
762  double ratioInv = (double) topo.card[dim] / hit_sigCard(hit_shapeSig(shape,dim));
763 
764  if( ratio >= 1 ){
765  group.rank[dim] = topo.self.rank[dim];
766  //leader.rank[dim] = group.rank[dim];
767  res.leaderRanks.rank[dim] = group.rank[dim];
768  } else {
769  group.rank[dim] = (int)(topo.self.rank[dim] * ratio);
770  //leader.rank[dim] = (int) ceil(ratioInv * group.rank[dim]);
771  res.leaderRanks.rank[dim] = (int) ceil(ratioInv * group.rank[dim]);
772  }
773  }
774 
775  res.group = hit_layActiveRanksId(res,group);
776  //res.leader = hit_topRankInternal(topo,leader);
777  // @arturo 2015/01/22
778  //res.leader = ( hit_topRankInternal(topo,res.leaderRanks) == topo.linearRank ) ? 1 : 0;
779  res.leader = ( hit_topRankInternal(topo,res.leaderRanks) ==
780  hit_topSelfRankInternal( topo ) ) ? 1 : 0 ;
781 
782  /* RETURN */
783  return res;
784 }
785 
786 
787 /* 3. LAYOUT (SIGNATURES): BLOCK LOCATED AT LAST ELEMENT OF GROUP (Last processor is leader) */
788 /* 3.1. BLOCKSL: SIGNATURE */
789 int hit_layout_plug_layBlocksL_Sig(int procId, int procsCard, int blocksCard,
790  float* extraParameter,
791  HitSig input, HitSig *res ) {
792  HIT_NOT_USED( extraParameter );
793 
794  /* COMPUTE BLOCK SIZE AND STARTING POINT */
795  double ratio = (double)blocksCard / procsCard;
796  double beginFrac = procId * ratio;
797  int begin = (int)beginFrac;
798 
799 #ifdef DEBUG_HITLIB
800  printf("CTRL procId: %d, procsCard %d, blocksCard: %d\n", procId, procsCard, blocksCard);
801  printf("CTRL Input[%d:%d:%d]\n",
802  input.begin,
803  input.end,
804  input.stride
805  );
806 #endif
807 
808 
809  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
810  //if ( (beginFrac+ratio) != floor(beginFrac+ratio) ) { // Old
811  //if( floor(beginFrac) == floor(beginFrac-ratio) ) { // BlocksF
812  if( floor(beginFrac) == floor(beginFrac+ratio) ) {
813  /* RETURN NUL SIGNATURE AND NON-ACTIVE */
814  (*res) = HIT_SIG_NULL;
815  return 0;
816  }
817  else {
818  /* COMPUTE SIGNATURE */
819  /* BEGIN */
820  (*res).begin = begin * input.stride + input.begin;
821 
822  /* END */
823  int adjust = (blocksCard > procsCard) ? 1 : 0;
824  int end = ((procId + adjust) * blocksCard / procsCard ) - adjust;
825  (*res).end = end * input.stride + input.begin;
826 
827  /* STRIDE */
828  (*res).stride = input.stride;
829  }
830 
831  /* RETURN ACTIVE */
832  return 1;
833 }
834 
835 
836 
837 /* 3.4. BLOCKSL: LAYOUT FUNCTION INTERFACE */
839 
840  HitLayout res;
841  HitRanks group;
842  //HitRanks leader;
843  //float extraParameterValue = 0.0;
844 
845  res = hit_layout_wrapper(
846  topo,
847  shape,
850  NULL,
851  NULL,
853  NULL,
855  NULL,
857  NULL,
859  NULL,
860  NULL, //&extraParameterValue, //0.0,
862  );
863 
864  res.type = HIT_LAYOUT_BLOCKSL;
865 
866  if(! res.active){
867  // DEFAULT VALUES
868  //res.group = HIT_GROUP_ID_NULL;
869  //res.leaderRanks = HIT_RANKS_NULL;
870  //res.leader = 0;
871  return res;
872  }
873 
874  /* MY GROUP & MY LEADER */
875  int dim;
876  for (dim=0; dim<hit_shapeDims(shape); dim++) {
877  double ratio = (double) hit_sigCard(hit_shapeSig(shape,dim)) / topo.card[dim];
878  double ratioInv = (double) topo.card[dim] / hit_sigCard(hit_shapeSig(shape,dim));
879 
880  if( ratio >= 1 ){
881  group.rank[dim] = topo.self.rank[dim];
882  //leader.rank[dim] = group.rank[dim];
883  res.leaderRanks.rank[dim] = group.rank[dim];
884  } else {
885  group.rank[dim] = (int)(topo.self.rank[dim] * ratio);
886  //leader.rank[dim] = ((int) ceil(ratioInv * (group.rank[dim]+1)) ) -1;
887  res.leaderRanks.rank[dim] = ((int) ceil(ratioInv * (group.rank[dim]+1)) ) -1;
888  }
889 
890  }
891  res.group = hit_layActiveRanksId(res,group);
892  //res.leader = hit_topRankInternal(topo,leader);
893  // @arturo 2015/01/22
894  //res.leader = ( hit_topRankInternal(topo,res.leaderRanks) == topo.linearRank ) ? 1 : 0;
895  res.leader = ( hit_topRankInternal(topo,res.leaderRanks) ==
896  hit_topSelfRankInternal( topo ) ) ? 1 : 0 ;
897 
898  /* RETURN */
899  return res;
900 }
901 
902 
903 /* 4. LAYOUT (SIGNATURES): CYCLIC */
904 /* 4.1. CYCLIC: SIGNATURE */
905 int hit_layout_plug_layCyclic_Sig(int procId, int procsCard, int blocksCard,
906  float* extraParameter,
907  HitSig input, HitSig *res ) {
908  HIT_NOT_USED( extraParameter );
909 
910  /* NOT ENOUGH INPUT DOMAIN ELEMENTS FOR THIS PROC ID */
911  if ( blocksCard <= procId ) {
912  (*res) = HIT_SIG_NULL;
913  return 0;
914  }
915 
916  /* BEGIN */
917  (*res).begin = input.begin + input.stride * procId;
918 
919  /* END */
920  int tmp = (blocksCard / procsCard - 1) * procsCard + procId;
921  if ( procId < blocksCard % procsCard ) tmp = tmp + procsCard;
922  (*res).end = input.begin + tmp * input.stride;
923 
924  /* STRIDE */
925  (*res).stride = input.stride * procsCard;
926 
927  /* RETURN ACTIVE */
928  return 1;
929 }
930 int hit_layout_plug_layCyclic_SigInv(int procId, int procsCard, int blocksCard,
931  float* extraParameter,
932  HitSig input,
933  int ind ) {
934  HIT_NOT_USED( procId );
935  HIT_NOT_USED( blocksCard );
936  HIT_NOT_USED( extraParameter );
937 
938  /* CHECK: THE INDEX SHOULD BE IN THE INPUT DOMAIN */
939  if ( ! hit_sigIn( input, ind ) ) return HIT_RANK_NULL;
940 
941  /* RETURN PROC ID */
942  int tileInd = (ind - input.begin) / input.stride;
943  return tileInd % procsCard;
944 }
945 
946 
947 /* 4.4. CYCLIC: LAYOUT FUNCTION INTERFACE */
949 
950  //float extraParameterValue = 0.0;
951 
953  topo,
954  shape,
967  NULL, //&extraParameterValue, //0.0,
968  restrictToDim
969  );
970 
971  lay.type = HIT_LAYOUT_CYCLIC;
972 
973  /* MY GROUP & MY LEADER */
974  if ( ! lay.active ){
975  // DEFAULT VALUES
976  //res.group = HIT_GROUP_ID_NULL;
977  //res.leaderRanks = HIT_RANKS_NULL;
978  //res.leader = 0;
979  return lay;
980  }
981 
982 
983  HitRanks group;
984  //HitRanks leader;
985 
986  int dim;
987  for (dim=0; dim<hit_shapeDims(shape); dim++) {
988  if ( restrictToDim != dim ) {
989  group.rank[dim] = 0;
990  //leader.rank[dim] = 0;
991  lay.leaderRanks.rank[dim] = 0;
992  }
993  else {
994  group.rank[dim] = topo.self.rank[dim];
995  //leader.rank[dim] = topo.self.rank[dim];
996  lay.leaderRanks.rank[dim] = topo.self.rank[dim];
997  }
998  }
999  lay.group = hit_layActiveRanksId(lay,group);
1000  //lay.leader = hit_topRankInternal(topo,leader);
1001  // @arturo 2015/01/22
1002  //lay.leader = ( hit_topRankInternal(topo,lay.leaderRanks) == topo.linearRank ) ? 1 : 0;
1003  lay.leader = ( hit_topRankInternal(topo,lay.leaderRanks) ==
1004  hit_topSelfRankInternal( topo ) ) ? 1 : 0;
1005 
1006  /* RETURN */
1007  return lay;
1008 }
1009 
1010 
1011 
1012 /* 5. ALL THE STRUCTURE IN THE LEADER: LAYOUT FUNCTION INTERFACE */
1014  HitLayout res;
1015  HitRanks group;
1016  //float extraParameterValue = 0.0;
1017 
1018  res = hit_layout_wrapper(
1019  topo,
1020  shape,
1023  NULL,
1024  NULL,
1026  NULL,
1028  NULL,
1030  NULL,
1032  NULL,
1033  NULL, //&extraParameterValue, //0.0,
1035  );
1036 
1038 
1039  if(! res.active) return res;
1040 
1041  /* MY GROUP */
1042  int dim;
1043  for (dim=0; dim<hit_shapeDims(shape); dim++) {
1044  group.rank[dim] = 0;
1045  }
1046  res.group = hit_layActiveRanksId( res, group );
1047 
1048  /* MY LEADER */
1049  res.leaderRanks = group;
1050  res.leader = 1;
1051 
1052  return res;
1053 }
1054 
1055 
1056 /* 10. LAYOUT (SIGNATURES): BLOCKS WITH LOAD BALANCE IN ONE DIMENSION */
1057 /* 10.1. BLOCKS BALANCE: SIGNATURE */
1058 int hit_layout_plug_layBlocksBalance_Sig(int procId, int procsCard, int blocksCard,
1059  float* extraParameter,
1060  HitSig input, HitSig *res ) {
1061 
1062  /* IF LESS THAN TWO PROCS. RETURN FULL SIGNATURE */
1063  if ( procsCard < 2 && procId == 0 ) {
1064  (*res) = input;
1065  return 1;
1066  }
1067 
1068  /* COMPUTE FIRST BLOCK OF ACTIVE PROCESSORS PART: PROPORTIONAL TO LOAD */
1069  int firstSize = (int)ceilf(*extraParameter * (float)blocksCard);
1070  /* COMPUTE LAST ACTIVE PROCESSOR PART: PROPORTIONAL TO INVERSE LOAD */
1071  int lastSize = blocksCard - firstSize;
1072 
1073  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
1074  int lastProc = hit_min( procsCard-1, firstSize );
1075  if ( procId > lastProc ) {
1076  /* RETURN NUL SIGNATURE AND NON-ACTIVE */
1077  (*res) = HIT_SIG_NULL;
1078  return 0;
1079  }
1080 
1081  /* LAST PROCESSOR */
1082  if ( procId == lastProc ) {
1083  if ( lastSize == 0 ) {
1084  (*res) = HIT_SIG_NULL;
1085  return 0;
1086  }
1087  else {
1088  (*res).begin = input.end - ( lastSize-1 ) * input.stride;
1089  (*res).end = input.end;
1090  (*res).stride = input.stride;
1091  }
1092  return 1;
1093  }
1094 
1095  /* REST OF PROCCESORS: CORRECT INPUT END */
1096  input.end = input.end - lastSize * input.stride;
1097 
1098  /* CALL TO REGULAR BLOCKS PLUG-IN */
1099  return hit_layout_plug_layBlocks_Sig( procId, lastProc, firstSize, extraParameter, input, res );
1100 }
1101 int hit_layout_plug_layBlocksBalance_SigInv(int procId, int procsCard, int blocksCard,
1102  float* extraParameter,
1103  HitSig input,
1104  int ind ) {
1105 
1106  /* CHECK: THE INDEX SHOULD BE IN THE INPUT DOMAIN */
1107  if ( ! hit_sigIn( input, ind ) ) return HIT_RANK_NULL;
1108 
1109  /* IF LESS THAN TWO PROCS. RETURN THE SAME Id */
1110  if ( procsCard < 2 && procId == 0 ) return 0;
1111 
1112  /* COMPUTE FIRST BLOCK OF ACTIVE PROCESSORS PART: PROPORTIONAL TO LOAD */
1113  int firstSize = (int)ceilf(*extraParameter * (float)blocksCard);
1114  /* COMPUTE LAST ACTIVE PROCESSOR PART: PROPORTIONAL TO INVERSE LOAD */
1115  int lastSize = blocksCard - firstSize;
1116  int lastProc = hit_min( procsCard-1, firstSize );
1117 
1118  /* REST OF PROCCESORS: CORRECT INPUT END */
1119  input.end = input.end - lastSize * input.stride;
1120 
1121  /* RETURN PROC ID */
1122  int tileInd = (ind - input.begin) / input.stride;
1123  if ( tileInd >= firstSize ) return procsCard-1;
1124  else return hit_layout_plug_layBlocks_SigInv( procId, lastProc, firstSize, extraParameter, input, ind );
1125 }
1126 
1127 
1128 /* 10.2. BLOCKS BALANCE: MAX CARDINALITY */
1129 int hit_layout_plug_layBlocksBalance_maxCard( int procsCard, int blocksCard, float* extraParameter ) {
1130  /* IF LESS THAN TWO PROCS. RETURN FULL SIGNATURE */
1131  if ( procsCard < 2 ) return blocksCard;
1132 
1133  /* COMPUTE FIRST BLOCK OF ACTIVE PROCESSORS PART: PROPORTIONAL TO LOAD */
1134  int firstSize = (int)ceilf(*extraParameter * (float)blocksCard);
1135  /* COMPUTE LAST ACTIVE PROCESSOR PART: PROPORTIONAL TO INVERSE LOAD */
1136  int lastSize = blocksCard - firstSize;
1137  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
1138  int lastProc = hit_min( procsCard-1, firstSize );
1139 
1140  /* COMPUTE MAX CARDS */
1141  int others = hit_layout_plug_layRegular_maxCard( lastProc, firstSize, extraParameter );
1142  return (lastSize > others) ? lastSize:others;
1143 }
1144 
1145 /* 10.2.b BLOCKS BALANCE: MIN CARDINALITY */
1146 int hit_layout_plug_layBlocksBalance_minCard( int procsCard, int blocksCard, float* extraParameter ) {
1147  /* IF LESS THAN TWO PROCS. RETURN FULL SIGNATURE */
1148  if ( procsCard < 2 ) return blocksCard;
1149 
1150  /* COMPUTE FIRST BLOCK OF ACTIVE PROCESSORS PART: PROPORTIONAL TO LOAD */
1151  int firstSize = (int)ceilf(*extraParameter * (float)blocksCard);
1152  /* COMPUTE LAST ACTIVE PROCESSOR PART: PROPORTIONAL TO INVERSE LOAD */
1153  int lastSize = blocksCard - firstSize;
1154  /* DETECT NON-ACTIVE VIRTUAL PROCESS (NOT ENOUGH LOGICAL PROCESSES) */
1155  int lastProc = hit_min( procsCard-1, firstSize );
1156 
1157  /* COMPUTE MAX CARDS */
1158  int others = hit_layout_plug_layRegular_minCard( lastProc, firstSize, extraParameter );
1159  return (lastSize < others) ? lastSize:others;
1160 }
1161 
1162 
1163 /* 10.3. BLOCKS BALANCE: NUM. ACTIVES */
1164 int hit_layout_plug_layBlocksBalance_numActives( int procsCard, int blocksCard, float* extraParameter ) {
1165  /* ASSERT: BLOCKS CARD BIGGER THAN 0 */
1166  if ( blocksCard < 1 ) return 0;
1167 
1168  /* IF LESS THAN TWO PROCS. RETURN ONE PROC. ACTIVE WITH THE FULL SIGNATURE */
1169  if ( procsCard < 2 ) return 1;
1170 
1171  /* COMPUTE FIRST BLOCK PART: PROPORTIONAL TO LOAD */
1172  int firstSize = (int)ceilf(*extraParameter * (float)blocksCard);
1173 
1174  /* DEGENERATED CASE */
1175  if ( firstSize == 0 ) return 1;
1176 
1177  /* GENERAL CASE FOR FIRST SIZE */
1178  int numActivesFirst = hit_layout_plug_layRegular_numActives( procsCard-1, firstSize, extraParameter );
1179 
1180  /* DEGENERATED CASE */
1181  if ( firstSize == blocksCard ) return numActivesFirst;
1182  else return numActivesFirst + 1;
1183 }
1184 
1185 /* 10.4. BLOCKS BALANCE: RANKS */
1186 int hit_layout_plug_layBlocksBalance_ranks( char topoActiveMode,
1187  int procId, int procsCard, int blocksCard, float* extraParameter ) {
1188 
1189  /* MODE: TOPO TO ACTIVE */
1190  if ( topoActiveMode == HIT_LAY_RANKS_TOPO_TO_ACTIVE ) {
1191  /* GET NUM ACTIVES, ASSERT: procId IS ACTIVE */
1192  int actives = hit_layout_plug_layBlocksBalance_numActives( procsCard, blocksCard, extraParameter );
1193  if ( procId < 0 || procId > actives ) return HIT_RANK_NULL;
1194  else return procId;
1195  }
1196  /* MODE: ACTIVE TO TOPO */
1197  else return procId;
1198 }
1199 
1200 
1201 /* 10.5. BLOCKS BALANCE: LAYOUT FUNCTION INTERFACE */
1202 HitLayout hit_layout_plug_layBlocksBalance(HitTopology topo, HitShape shape, int restrictToDim, float load ) {
1203 
1204  /* ASSERT: LOAD RANGE [0.0:1.0] */
1205  if ( load < 0.0 || load > 1.0 ) {
1206  hit_errInternal( __FUNCTION__, "Incorrect load parameter", "", __FILE__, __LINE__);
1207  }
1208 
1209  /* CHECK IF ACTIVE */
1210  HitLayout res;
1211  HitRanks group;
1212 
1213  /* ACTIVE */
1214  res = hit_layout_wrapper(
1215  topo,
1216  shape,
1229  &load, //load,
1230  restrictToDim
1231  );
1232 
1234 
1235  if( ! res.active){
1236  // DEFAULT VALUES
1237  //res.group = HIT_GROUP_ID_NULL;
1238  //res.leaderRanks = HIT_RANKS_NULL;
1239  //res.leader = 0;
1240  return res;
1241  }
1242 
1243  /* MY GROUP */
1244  int dim;
1245  for (dim=0; dim<hit_shapeDims(shape); dim++) {
1246  if( res.active ){
1247  group.rank[dim] = topo.self.rank[dim];
1248  } else {
1249  group.rank[dim] = -1;
1250  }
1251  }
1252  res.group = hit_layActiveRanksId(res,group);
1253 
1254  /* MY LEADER */
1255  //res.leader = topo.linearRank;
1256  res.leaderRanks = group;
1257  res.leader = 1;
1258 
1259  return res;
1260 }
1261 
1262 int perform_weighted_distribution(int procsCard, int blocksCard, float* weights, int* result){
1263 
1264  /*SUM WEIGHTS & SAFETY CHECK: NO NEGATIVE LOADS*/
1265  int i;
1266  float sumDimWeights = 0;
1267  for (i = 0; i < procsCard; i++)
1268  {
1269  if (weights[i] < 0.0)
1270  {hit_errInternal(__FUNCTION__,"Weight input data is incorrect (check workload expressions)","",__FILE__,__LINE__);}
1271  else
1272  {sumDimWeights += weights[i];}
1273  }
1274 
1275  //If normalization is not required, skip the block below until the END_SKIP comment
1276  double sumWeights = 0;
1277 
1278  for (i = 0; i < procsCard; i++)
1279  sumWeights += weights[i];
1280 
1281  /* SAFETY CHECK: CONSISTENCY OF INPUT DATA, TOTAL WEIGHT 0 */
1282  if (sumWeights == 0.0) sumWeights = 1.0; /* Avoid division by 0 */
1283  //END_SKIP
1284 
1285  double floatElemDimProcess[procsCard]; //Number of data elements assigned to process i for this dim
1286  double remElemDimProcess[procsCard]; //Fractional part of floatElemDimProcess assigned to process i
1287  int intElemDimProcess[procsCard]; //Integer part of floatElemDimProcess assigned to process i
1288  int sumIntElemDimProcess = 0;
1289 
1290  for (i = 0; i < procsCard; i++)
1291  {
1292  //Number of data elements that should be assigned to process i (float)
1293  floatElemDimProcess[i] = (weights[i] / sumWeights) * blocksCard;
1294  //If normalization is not required, use the line below instead
1295  // floatElemDimProcess[i] = weights[i] * blocksCard;
1296  //Since the number of data elements assigned must be an integer, truncate the previous number
1297  // This number of elements will be directly assigned.
1298  intElemDimProcess[i] = (int) floatElemDimProcess[i];
1299  //Get the fractional part of floatElemDimProcess for the process i. As the number of data elements
1300  // assigned to processes has to be an integer, this is the "part of a data element" unassigned for
1301  // process i
1302  remElemDimProcess[i] = floatElemDimProcess[i] - intElemDimProcess[i];
1303  //Sum the fractional parts of all floatElemDimProcess. Those are the total unassigned data elements.
1304  sumIntElemDimProcess += intElemDimProcess[i];
1305  }
1306 
1307  //Assign the remamining and unassigned fractional parts as whole data elements to the processors
1308  for (i = 0; i < (blocksCard - sumIntElemDimProcess); i++)
1309  {
1310  double maxRemElemDimProcessValue = remElemDimProcess[0];
1311  int maxRemElemDimProcessPosit = 0;
1312  int j;
1313  //Look for the maximum (unassigned) fractional part among all the processes for this dimension
1314  // Store the maximum value and its position in the array.
1315  for (j = 0; j < procsCard; j++)
1316  {
1317  if (remElemDimProcess[j] > maxRemElemDimProcessValue)
1318  {
1319  maxRemElemDimProcessValue = remElemDimProcess[j];
1320  maxRemElemDimProcessPosit = j;
1321  }
1322  }
1323  //Assign one more data element to the process with the highest fractional part
1324  intElemDimProcess[maxRemElemDimProcessPosit]++;
1325  //Substract one to the fractional part of the process which has been asigned one
1326  // more data element. This way, the fractional part for this process will be a
1327  // negative number and therefore will not be eligible for another assignation.
1328  remElemDimProcess[maxRemElemDimProcessPosit]--;
1329  }
1330 
1331  //TODO: This array copy seems somewhat absurd. There is a safety reason behind this that cannot be solved
1332  // this way. Find a way and delete this two lines below.
1333  for (i = 0; i < procsCard; i++)
1334  {result[i] = intElemDimProcess[i];}
1335  //TODO: This function should return 1 only when all was OK.
1336  return 1;
1337 
1338 }
1339 
1340 int hit_layout_plug_layWeighted_Sig(int procId, int procsCard, int blocksCard,
1341  float* extraParameter,
1342  HitSig input, HitSig *res ) {
1343  /* REJECT EMPTY INPUT SIGNATURES */
1344  if ( blocksCard == 0 ) {
1345  (*res) = HIT_SIG_NULL;
1346  return 0;
1347  }
1348 
1349  //nDimDataElements = blocksCard;//hit_sigCard(hit_shapeSig(shape, currDim));
1350  //nDimProcesses = procsCard;//topo.card[currDim];
1351  int weightedDistRes[procsCard];
1352  perform_weighted_distribution(procsCard, blocksCard, extraParameter, weightedDistRes);
1353 
1354  //If the number of data elements assigned to our process is zero, return null signature and non-active process
1355  if (weightedDistRes[procId] == 0.0)
1356  {
1357  (*res) = HIT_SIG_NULL;
1358  return 0;
1359  }
1360  else
1361  {
1362  //We are going to compute the signature for our process (procId). First let's compute the cumulative sum of all
1363  // assigned elements for each process, from (the zeroth process to the current process id) of our dimension.
1364  int j;
1365  int cumSumIntElemDimProcess = 0;
1366  for (j = 0; j < procId ; j++)
1367  cumSumIntElemDimProcess += weightedDistRes[j];
1368 
1369  /* BEGIN */
1370  (*res).begin = input.begin + (cumSumIntElemDimProcess * input.stride);
1371 
1372  /* END */
1373  //If our intElemDimProcess[procId] were zero, we would not have a problem here since
1374  // this condiction is avoided by the if block.
1375  (*res).end = (*res).begin + ((weightedDistRes[procId] - 1) * input.stride);
1376 
1377  /* STRIDE */
1378  (*res).stride = input.stride;
1379  }
1380 
1381  /* RETURN ACTIVE */
1382  return 1;
1383 }
1384 
1385 int hit_layout_plug_layWeighted_SigInv(int procId, int procsCard, int blocksCard,
1386  float* extraParameter,
1387  HitSig input,
1388  int ind ) {
1389  HIT_NOT_USED( procId );
1390 
1391  /* CHECK: THE INDEX SHOULD BE IN THE INPUT DOMAIN */
1392  if ( ! hit_sigIn( input, ind ) ) return HIT_RANK_NULL;
1393 
1394  //TODO: Quick & dirty solution. Do the weighted distribution and look for the index within the result.
1395  // It might be much faster to undo the equations of the distribution to directly compute the processor Id.
1396  // Marked as a pending job.
1397  //UPDATE: Improved, but there is still room for more improvements.
1398 
1399  int weightedDistRes[procsCard];
1400  perform_weighted_distribution(procsCard, blocksCard, extraParameter, weightedDistRes);//, HIT_LAYWEIGHT_NORMALIZE);
1401 
1402  //begin_of_the_ind_proces_block = input.begin + (cumSumIntElemDimProcess * input.stride);
1403  //Thus, we have ind = input.begin + ((cumSumIntElemDimProcess + k) * input.stride);, where k in {0 to the
1404  // weightedDistRes value attributed to that processor}
1405  //Therefore ((ind - input.begin) / input.stride) = (cumSumIntElemDimProcess + k);
1406  //For k = 0 (first element of the block assigned to the processor), we have
1407  // ((ind - input.begin) / input.stride) = (cumSumIntElemDimProcess);
1408  //Let's scan for its value
1409  int cumSumIntElemDimTARGETProcess = ((ind - input.begin) / input.stride);
1410 
1411  int i;
1412  int cumSumIntElemDimProcess = 0;
1413  for (i = 0; i < procsCard; i++){
1414  cumSumIntElemDimProcess += weightedDistRes[i];
1415  if (cumSumIntElemDimProcess >= cumSumIntElemDimTARGETProcess) break;
1416  }
1417 #ifdef DEBUG
1418  int begin, end;
1419  begin = input.begin + (cumSumIntElemDimProcess * input.stride);
1420  end = begin + ((weightedDistRes[i] - 1) * input.stride);
1421  if (! ((ind >= begin) && (ind <= end)))
1422  printf("Error @ %s:%i: index %i not within the bounds of block (%i, %i, %i) for processor %i", __FILE__,__LINE__, ind, input.begin, input.end, input.stride, i);
1423 #endif
1424 
1425  return i;
1426 }
1427 
1428 int hit_layout_plug_layWeighted_ranks( char topoActiveMode,
1429  int procId, int procsCard, int blocksCard, float* extraParameter ) {
1430 
1431  HIT_NOT_USED( extraParameter );
1432 
1433  //TODO: Hacer esta función
1434 
1435  /* MODE: TOPO TO ACTIVE */
1436  if ( topoActiveMode == HIT_LAY_RANKS_TOPO_TO_ACTIVE ) {
1437  /* GET NUM ACTIVES, ASSERT: procId IS ACTIVE */
1438  int actives = hit_min( blocksCard, procsCard );
1439  if ( procId < 0 || procId > actives ) return HIT_RANK_NULL;
1440  else return procId;
1441  }
1442  /* MODE: ACTIVE TO TOPO */
1443  else return procId;
1444 
1445 }
1446 
1447 int hit_layout_plug_layWeighted_maxCard( int procsCard, int blocksCard, float* extraParameter ) {
1448 
1449  int weightedDistRes[procsCard];
1450  perform_weighted_distribution(procsCard, blocksCard, extraParameter, weightedDistRes);
1451 
1452  int i = 0;
1453  int maxCard = weightedDistRes[0];
1454  for (i = 0; i < procsCard; i++)
1455  {if (weightedDistRes[i] > maxCard) maxCard = weightedDistRes[i];}
1456  return maxCard;
1457 }
1458 
1459 int hit_layout_plug_layWeighted_minCard( int procsCard, int blocksCard, float* extraParameter ) {
1460 
1461  int weightedDistRes[procsCard];
1462  perform_weighted_distribution(procsCard, blocksCard, extraParameter, weightedDistRes);
1463 
1464  int i = 0;
1465  int minCard = weightedDistRes[0];
1466  for (i = 0; i < procsCard; i++)
1467  {if (weightedDistRes[i] < minCard) minCard = weightedDistRes[i];}
1468  return minCard;
1469 }
1470 
1471 int hit_layout_plug_layWeighted_numActives( int procsCard, int blocksCard, float* extraParameter ) {
1472 
1473  int weightedDistRes[procsCard];
1474  perform_weighted_distribution(procsCard, blocksCard, extraParameter, weightedDistRes);
1475 
1476  int i;
1477  int numDimActiveLayProcesses = 0;
1478  for (i = 0; i < procsCard; i++)
1479  {if (weightedDistRes[i] != 0) numDimActiveLayProcesses++;}
1480  return numDimActiveLayProcesses;
1481 }
1482 
1483 /* 7.5 WEIGHTED: LAYOUT FUNCTION INTERFACE */
1484 HitLayout hit_layout_plug_layDimWeighted(HitTopology topo, HitShape shape, int restrictDim, float* weights) {
1485  HitLayout res;
1486  HitRanks group;
1487 
1488  /* ACTIVE */
1489  res = hit_layout_wrapper(
1490  topo,
1491  shape,
1497  &(hit_layout_plug_layRegularContiguos_ranks), //TODO: Ver a ver si hay que hacer esta función o qué
1504  weights,
1505  restrictDim
1506  );
1507 
1509 
1510  if(! res.active){
1511  // DEFAULT VALUES
1512  //res.group = HIT_GROUP_ID_NULL;
1513  //res.leaderRanks = HIT_RANKS_NULL;
1514  //res.leader = 0;
1515  return res;
1516  }
1517 
1518  /* MY GROUP */
1519  int dim;
1520  for (dim=0; dim<hit_shapeDims(shape); dim++) {
1521  if( res.active ){
1522  group.rank[dim] = topo.self.rank[dim];
1523  } else {
1524  group.rank[dim] = -1;
1525  }
1526  }
1527  res.group = hit_layActiveRanksId(res,group);
1528 
1529  /* MY LEADER */
1530  //res.leader = topo.linearRank;
1531  res.leaderRanks = group;
1532  res.leader = 1;
1533 
1534  return res;
1535 }
1536 
1537 /* 7.5 WEIGHTED: LAYOUT FUNCTION INTERFACE */
1539  HitLayout res;
1540  HitRanks group;
1541 
1542  /* ACTIVE */
1543  res = hit_layout_wrapper(
1544  topo,
1545  shape,
1548  NULL,
1549  NULL,
1550  &(hit_layout_plug_layRegularContiguos_ranks), //TODO: Ver a ver si hay que hacer esta función o qué
1551  NULL,
1553  NULL,
1555  NULL,
1557  NULL,
1558  weights,
1560  );
1561 
1562  res.type = HIT_LAYOUT_WEIGHTED;
1563 
1564  if(! res.active){
1565  // DEFAULT VALUES
1566  //res.group = HIT_GROUP_ID_NULL;
1567  //res.leaderRanks = HIT_RANKS_NULL;
1568  //res.leader = 0;
1569  return res;
1570  }
1571 
1572  /* MY GROUP */
1573  int dim;
1574  for (dim=0; dim<hit_shapeDims(shape); dim++) {
1575  if( res.active ){
1576  group.rank[dim] = topo.self.rank[dim];
1577  } else {
1578  group.rank[dim] = -1;
1579  }
1580  }
1581  res.group = hit_layActiveRanksId(res,group);
1582 
1583  /* MY LEADER */
1584  //res.leader = topo.linearRank;
1585  res.leaderRanks = group;
1586  res.leader = 1;
1587 
1588  return res;
1589 }
1590 
1591 /* 8. LAYOUT (SIGNATURES): WRAP/UNWRAP NEIGHBOURS */
1592 /* 8.1. WRAP ALL DIMENSIONS */
1594  /* FOR EACH DIMENSION, WRAP */
1595  int dim;
1596  for (dim=0; dim< hit_shapeDims( hit_layShape(*lay) ); dim++) {
1597  (*lay).wrap[dim] = HIT_WRAPPED;
1598  }
1599 }
1600 
1601 /* 8.2. WRAP GIVEN DIMENSION */
1603  (*lay).wrap[dim] = HIT_WRAPPED;
1604 }
1605 
1606 /* 8.3. UNWRAP ALL DIMENSIONS */
1608  /* FOR EACH DIMENSION, UNWRAP */
1609  int dim;
1610  for (dim=0; dim< hit_shapeDims(hit_layShape(*lay)); dim++) {
1611  (*lay).wrap[dim] = HIT_NOWRAPPED;
1612  }
1613 }
1614 
1615 /* 8.4. UNWRAP GIVEN DIMENSION */
1617  (*lay).wrap[dim] = HIT_NOWRAPPED;
1618 }
1619 
1620 
1621 
1622 /* 9.1. EXTENDED SHAPE TO CREATE MAXIMAL BUFFERS FOR DIFFERENT SIZED TILES ON THE LAYOUT */
1624 
1625  HitShape newShp = HIT_SHAPE_NULL;
1626 
1627  if(!lay.active) return newShp;
1628 
1630 
1631  /* 1A. COPY ORIGINAL SHAPE */
1632  newShp = hit_layShape(lay);
1633 
1634  /* 2A. EXTEND THE END TO ALLOW THE BIGGEST PIECES TO FIT */
1635  int i;
1636  for (i=0; i<hit_shapeDims(newShp); i++)
1637  hit_shapeSig(newShp,i).end = hit_shapeSig(newShp,i).begin +
1638  ( lay.maxSize[i] - 1 ) * hit_shapeSig(newShp,i).stride ;
1639 
1640  } else{
1641 
1642  /* 1B. MAKE A NEW SHAPE */
1643  return hit_shape(1,hit_sig(0,lay.maxSize[0],1));
1644  }
1645 
1646  /* RETURN EXTENDED SHAPE */
1647  return newShp;
1648 }
1649 
1651 
1652  HitShape newShp = HIT_SHAPE_NULL;
1653 
1654  if(!lay.active) return newShp;
1655 
1657 
1658  /* 1A. COPY ORIGINAL SHAPE */
1659  newShp = hit_layShape(lay);
1660 
1661  /* 2A. EXTEND THE END TO ALLOW THE BIGGEST PIECES TO FIT (ONLY FOR THE GIVEN DIMENSION) */
1662  hit_shapeSig(newShp,dim).end = hit_shapeSig(newShp,dim).begin +
1663  ( lay.maxSize[dim] - 1 ) * hit_shapeSig(newShp,dim).stride ;
1664 
1665  } else{
1666 
1667  /* 1B. MAKE A NEW SHAPE */
1668  return hit_shape(1,hit_sig(0,lay.maxSize[0],1));
1669  }
1670 
1671  /* RETURN EXTENDED SHAPE */
1672  return newShp;
1673 }
1674 
1675 
1676 /* 9.2. EXTENDED SHAPE TO CREATE MINIMAL BUFFERS FOR DIFFERENT SIZED TILES ON THE LAYOUT */
1678 
1679  HitShape newShp = HIT_SHAPE_NULL;
1680 
1681  if(!lay.active) return newShp;
1682 
1684 
1685  /* 1A. COPY ORIGINAL SHAPE */
1686  newShp = hit_layShape(lay);
1687 
1688  /* 2A. EXTEND THE END TO ALLOW THE BIGGEST PIECES TO FIT */
1689  int i;
1690  for (i=0; i<hit_shapeDims(newShp); i++)
1691  hit_shapeSig(newShp,i).end = hit_shapeSig(newShp,i).begin +
1692  ( lay.minSize[i] - 1 ) * hit_shapeSig(newShp,i).stride ;
1693 
1694  } else{
1695 
1696  /* 1B. MAKE A NEW SHAPE */
1697  return hit_shape(1,hit_sig(0,lay.minSize[0],1));
1698  }
1699 
1700  /* RETURN EXTENDED SHAPE */
1701  return newShp;
1702 }
1703 
1705 
1706  HitShape newShp = HIT_SHAPE_NULL;
1707 
1708  if(!lay.active) return newShp;
1709 
1711 
1712  /* 1A. COPY ORIGINAL SHAPE */
1713  newShp = hit_layShape(lay);
1714 
1715  /* 2A. EXTEND THE END TO ALLOW THE BIGGEST PIECES TO FIT (ONLY FOR THE GIVEN DIMENSION) */
1716  hit_shapeSig(newShp,dim).end = hit_shapeSig(newShp,dim).begin +
1717  ( lay.minSize[dim] - 1 ) * hit_shapeSig(newShp,dim).stride ;
1718 
1719  } else{
1720 
1721  /* 1B. MAKE A NEW SHAPE */
1722  return hit_shape(1,hit_sig(0,lay.minSize[0],1));
1723  }
1724 
1725  /* RETURN EXTENDED SHAPE */
1726  return newShp;
1727 }
1728 
1729 
1730 /* 10. INTERNAL: WRAPPERS FOR SIGNATURE LAYOUTS */
1731 /* 10.1. INTERNAL WRAPPER: SHAPE (1st TIME LAYOUT IS COMPUTED) */
1732 int hit_layout_wrapperShape( int topoNumDims,
1733  HitRanks proc,
1734  int card[HIT_MAXDIMS],
1735  HitShape shape,
1736  HitShape *newShape,
1737  HitLayoutSignatureFunction sigFunctionGeneric,
1738  HitLayoutSignatureFunction sigFunctionRestricted,
1739  float* extraParameter,
1740  int restrictToDim
1741  ) {
1742  HitShape res = HIT_SHAPE_NULL;
1743 
1744  /* FOR EACH DIMENSION IN THE SHAPE, COMPUTE LAYOUT */
1745  hit_shapeDimsSet(res, hit_shapeDims(shape));
1746  int active = ( hit_shapeDims(shape) > 0 );
1747  int dim;
1748  for (dim=0; dim<hit_shapeDims(shape); dim++) {
1749  /* NO TOPOLOGY DIMENSION, COPY ALL THE SIGNATURE */
1750  if ( dim >= topoNumDims ) {
1751  hit_shapeSig(res,dim) = hit_shapeSig(shape,dim);
1752  }
1753  /* COMPUTE SIGNATURE LAYOUT FOR TOPOLOGY CARDINALITY */
1754  else {
1755  int procId = proc.rank[dim];
1756 
1757  /* NULL RANK */
1758  if ( procId == HIT_RANK_NULL || procId < 0 || procId >= card[dim] ) {
1759  hit_shapeSig(res,dim) = HIT_SIG_NULL;
1760  active = 0;
1761  }
1762  /* NORMAL RANK */
1763  else {
1764  int procsCard = card[dim];
1765  int blocksCard = hit_sigCard(hit_shapeSig(shape,dim));
1766  int tmpActive;
1767 
1768  /* GENERIC vs. RESTRICTED DIMENSION: DIFFERENT SIGNATURE FUNCTION */
1769  if ( restrictToDim != HIT_LAYOUT_NODIM && dim == restrictToDim )
1770  tmpActive = sigFunctionRestricted(procId, procsCard, blocksCard,
1771  extraParameter,
1772  hit_shapeSig(shape,dim),
1773  &(hit_shapeSig(res,dim))
1774  );
1775  else
1776  tmpActive = sigFunctionGeneric(procId, procsCard, blocksCard,
1777  extraParameter,
1778  hit_shapeSig(shape,dim),
1779  &(hit_shapeSig(res,dim))
1780  );
1781  active = active && tmpActive;
1782  }
1783  }
1784  }
1785 
1786  /* RETURN ACTIVE */
1787  *newShape = res;
1788  return active;
1789 }
1790 
1791 /* 10.2. INTERNAL WRAPPER: SHAPE FOR GIVEN RANKS (LAYOUT ALREADY COMPUTED) */
1793  HitShape res;
1794 
1795  /* COMPUTE SHAPE */
1796  // @arturo 2015/01/07 Add check for non-active processors
1797  int active = hit_layout_wrapperShape(
1798  self.topo.numDims,
1799  ranks,
1800  self.topo.card,
1801  self.origShape,
1802  &(res),
1803  self.info.layoutSig.signatureGenericF,
1804  self.info.layoutSig.signatureRestrictedF,
1805  self.info.layoutSig.extraParameter,
1806  self.info.layoutSig.restrictToDim
1807  );
1808  if ( ! active ) return HIT_SHAPE_NULL;
1809 
1810  /* RETURN */
1811  return res;
1812 }
1813 
1814 /* 10.3. INTERNAL WRAPPER: SHAPE FOR NEIGHBORS (LAYOUT ALREADY COMPUTED) */
1816  HitShape res = HIT_SHAPE_NULL;
1817 
1818  /* FOR EACH DIMENSION IN THE SHAPE, COMPUTE LAYOUT */
1819  hit_shapeDimsSet(res, hit_shapeDims(self.origShape));
1820 
1821  int d;
1822  for (d=0; d<hit_layNumDims(self); d++) {
1823  /* SHIFTING IN NON-TOPOLOGY DIMENSIONS */
1824  if ( d == dim && d >= self.topo.numDims ) {
1825  /* FAKED SHIFT: THE SAME PROC SELECTED (SHIFT 0, OR WRAPPED LAYOUT) */
1826  if ( shift == 0 || self.wrap[d] == HIT_WRAPPED ) {
1827  hit_shapeSig(res,d) = hit_shapeSig(hit_layShape(self),d);
1828 
1829  if ( hit_sigCard(hit_shapeSig(res,d)) < 1 ) return HIT_SHAPE_NULL;
1830  }
1831  /* REAL SHIFT ALWAYS GOES OUTSIDE OF THE TOPOLOGY */
1832  else {
1833  return HIT_SHAPE_NULL;
1834  }
1835  }
1836  /* COPY SIGNATURES OF NON-SHIFTED DIMENSION */
1837  else if ( d != dim ) {
1838  hit_shapeSig(res,d) = hit_shapeSig(hit_layShape(self),d);
1839  if ( hit_sigCard(hit_shapeSig(res,d)) < 1 ) return HIT_SHAPE_NULL;
1840  }
1841 
1842  /* COMPUTE NEW SIGNATURE FOR THE SHIFTED DIMENSION */
1843  else {
1844  /* GET NEW PROC RANK */
1845  int newProcId = hit_layDimNeighbor( self, dim, shift );
1846 
1847  /* NULL RANK */
1848  if (newProcId == HIT_RANK_NULL || newProcId<0 || newProcId>=self.topo.card[d]) {
1849  return HIT_SHAPE_NULL;
1850  }
1851  /* NORMAL RANK */
1852  else {
1853  int tmpActive;
1854  if ( self.info.layoutSig.restrictToDim != HIT_LAYOUT_NODIM
1855  && self.info.layoutSig.restrictToDim == d ) {
1856  tmpActive = self.info.layoutSig.signatureRestrictedF( newProcId,
1857  self.topo.card[d],
1858  hit_sigCard( hit_shapeSig(self.origShape,d) ),
1859  self.info.layoutSig.extraParameter,
1860  hit_shapeSig(self.origShape,d),
1861  &(hit_shapeSig(res,d))
1862  );
1863  }
1864  else {
1865  tmpActive = self.info.layoutSig.signatureGenericF( newProcId,
1866  self.topo.card[d],
1867  hit_sigCard( hit_shapeSig(self.origShape,d) ),
1868  self.info.layoutSig.extraParameter,
1869  hit_shapeSig(self.origShape,d),
1870  &(hit_shapeSig(res,d))
1871  );
1872  }
1873  if(!tmpActive) return HIT_SHAPE_NULL;
1874 
1875  }
1876  }
1877  }
1878 
1879  /* RETURN */
1880  return res;
1881 }
1882 
1883 
1884 
1885 /* 10.8. TRANSLATE TOPOLOGY RANKS FROM/TO TOPOLOGY TO/FROM ACTIVE RANKS */
1886 HitRanks hit_layTransformRanks( char topoActiveMode, HitLayout self, HitRanks ranks ) {
1887  HitRanks active = HIT_RANKS_NULL;
1888 
1889  /* 0. NON-SIGNATURE LAYOUTS: RETURN THE SAME RANKS */
1890  if ( self.type != HIT_LAYOUT_SIG_CLASS ) return ranks;
1891 
1892  /* 1. ALIASES FOR LAYOUT INFORMATION (DIMENSION INDEPENDENT) */
1893  float* extraParameter = self.info.layoutSig.extraParameter;
1894  int restrictedDim = self.info.layoutSig.restrictToDim;
1895 
1896  /* 2. FOR EACH DIMENSION */
1897  int dim;
1898  for (dim = 0; dim < hit_shapeDims(self.shape); dim++) {
1899  /* 2.1. ALIASES FOR LAYOUT INFORMATION (DIMENSION DEPENDENT) */
1900  int procsCard = self.topo.card[dim];
1901  int blocksCard = hit_sigCard(hit_shapeSig(self.origShape,dim));
1902 
1903  /* 2.2. TOPO TO ACTIVE RANK */
1904  if ( restrictedDim == dim )
1905  active.rank[dim] = self.info.layoutSig.ranksRestrictedF( topoActiveMode, ranks.rank[dim], procsCard, blocksCard, extraParameter );
1906  else
1907  active.rank[dim] = self.info.layoutSig.ranksGenericF( topoActiveMode, ranks.rank[dim], procsCard, blocksCard, extraParameter );
1908  }
1909 
1910  /* 3. RETURN ACTIVE RANKS */
1911  return active;
1912 }
1913 
1914 
1915 /* 10.9. TRANSFORM MULTIDIMENSIONAL ACTIVE RANKS TO PROCESS IDENTIFIER (LINEAR RANK) */
1917 
1918  if ( hit_ranksCmp(ranks,HIT_RANKS_NULL) ) return HIT_RANK_NULL;
1919 
1920  int linear = 0;
1921  int acumCard = 1;
1922 
1923  int dim;
1924  for(dim=lay.topo.numDims-1; dim>=0; dim--) {
1925  linear = linear + acumCard * ranks.rank[dim];
1926  acumCard = acumCard * lay.numActives[dim];
1927  }
1928 
1929  return linear;
1930 }
1931 
1932 
1933 
1934 /* 10.10. TRANSFORM PROCESS IDENTIFIER (LINEAR RANK) IN MULTIDIMENSIONAL ACTIVE RANKS */
1936 
1937  HitRanks ranks = HIT_RANKS_NULL;
1938  int acumCard[HIT_MAXDIMS];
1939 
1940  acumCard[lay.topo.numDims-1] = 1;
1941 
1942  int dim;
1943  for(dim=lay.topo.numDims-2; dim>=0; dim--) acumCard[dim] = acumCard[dim+1] * lay.numActives[dim+1];
1944 
1945  for(dim=0;dim<lay.topo.numDims;dim++){
1946  ranks.rank[dim] = linear / acumCard[dim];
1947  linear %= acumCard[dim];
1948  }
1949 
1950  return ranks;
1951 }
1952 
1953 
1954 /* 10.4.1. GENERIC SHIFTED NEIGHBOUR: FROM ACTIVE RANK TO TOPOLOGY RANK */
1955 int hit_layNeighborFrom(HitLayout self, int source, int dim, int shift) {
1956  /* 1. ALIASES FOR LAYOUT INFORMATION */
1957  int procsCard = self.topo.card[dim];
1958  int blocksCard = hit_sigCard(hit_shapeSig(self.origShape,dim));
1959  float* extraParameter = self.info.layoutSig.extraParameter;
1960  int numActives = self.numActives[ dim ];
1961  int restrictedDim = self.info.layoutSig.restrictToDim;
1962 
1963  /* 2. SHIFT AND WRAP */
1964  int shiftedActive = source + shift;
1965  if ( self.wrap[dim] == HIT_NOWRAPPED ) {
1966  if ( shiftedActive < 0 || shiftedActive >= numActives ) return HIT_RANK_NULL;
1967  }
1968  else {
1969  shiftedActive = shiftedActive % numActives;
1970  if ( shiftedActive < 0 ) shiftedActive = shiftedActive + numActives;
1971  }
1972 
1973  /* 3. ACTIVE TO TOPO RANK */
1974  if ( restrictedDim == dim )
1975  return self.info.layoutSig.ranksRestrictedF( HIT_LAY_RANKS_ACTIVE_TO_TOPO, shiftedActive, procsCard, blocksCard, extraParameter );
1976  else
1977  return self.info.layoutSig.ranksGenericF( HIT_LAY_RANKS_ACTIVE_TO_TOPO, shiftedActive, procsCard, blocksCard, extraParameter );
1978 }
1979 
1980 
1981 /* 10.4.2. GENERIC SHIFTED NEIGHBOR: FROM TOPOLOGY RANK TO TOPOLOGY RANK */
1982 int hit_layNeighborFromTopoRank(HitLayout self, int source, int dim, int shift) {
1983  /* 1. ALIASES FOR LAYOUT INFORMATION */
1984  int procsCard = self.topo.card[dim];
1985  int blocksCard = hit_sigCard(hit_shapeSig(self.origShape,dim));
1986  float* extraParameter = self.info.layoutSig.extraParameter;
1987  int restrictedDim = self.info.layoutSig.restrictToDim;
1988 
1989  /* 2. TOPO TO ACTIVE RANK */
1990  int active;
1991  if ( restrictedDim == dim )
1992  active = self.info.layoutSig.ranksRestrictedF( HIT_LAY_RANKS_TOPO_TO_ACTIVE, source, procsCard, blocksCard, extraParameter );
1993  else
1994  active = self.info.layoutSig.ranksGenericF( HIT_LAY_RANKS_TOPO_TO_ACTIVE, source, procsCard, blocksCard, extraParameter );
1995 
1996  return hit_layNeighborFrom(self, active, dim, shift);
1997 }
1998 
1999 
2000 /* 10.5. INTERNAL WRAPPER: SHIFTED NEIGHBOUR DISTANCE */
2001 int hit_layNeighborDistance(HitLayout self, int dim, int shift) {
2002  int procId = self.topo.self.rank[dim];
2003  int neigh = hit_layNeighborFromTopoRank( self, procId, dim, shift );
2004  return neigh - procId;
2005 }
2006 
2007 /* 10.6.1. INTERNAL WRAPPER: GENERIC SHIFTED NEIGHBOUR RANKS */
2008 HitRanks hit_layNeighborRanksFrom(HitLayout self, HitRanks source, int dim, int shift) {
2009  HitRanks neighbor = HIT_RANKS_NULL;
2010 
2011  /* CHECK dim PARAMETER */
2012  if(dim < 0) return HIT_RANKS_NULL;
2013 
2014  /* NEIGHBORS IN LAYOUT DIMENSIONS WHICH ARE NOT IN THE TOPOLOGY, ONLY EXIST
2015  * WHEN WRAPPING IS ACTIVE FOR THAT DIMENSION. THE NEIGHBOR IS THE SAME
2016  * VIRTUAL PROCCESOR */
2017  if(dim >= self.topo.numDims ) {
2018  if ( self.wrap[dim] ) return self.topo.self;
2019  else return HIT_RANKS_NULL;
2020  }
2021 
2022  int d;
2023  for (d=0; d<hit_shapeDims(hit_layShape(self)); d++) {
2024  /* COPY RANK FOR NOT SELECTED DIM, OR DIM ABOVE THE DIMENSIONS IN THE TOPOLOGY */
2025  if (dim != d ) {
2026  neighbor.rank[d] = source.rank[d];
2027  }
2028  else neighbor.rank[d] = hit_layNeighborFrom( self, source.rank[d], d, shift );
2029 
2030  /* IF ANY RANK IS NULL, RETURN NULL RANKS */
2031  if ( neighbor.rank[d] == HIT_RANK_NULL ) return HIT_RANKS_NULL;
2032  }
2033 
2034  /* RETURN RESULT */
2035  return neighbor;
2036 }
2037 
2038 /* 10.6.2. INTERNAL WRAPPER: SHIFTED NEIGHBOUR RANKS */
2039 HitRanks hit_layNeighborRanks(HitLayout self, int dim, int shift) {
2040 
2041  HitRanks neighbor = HIT_RANKS_NULL;
2042 
2043  /* CHECK dim PARAMETER */
2044  if(dim < 0) return HIT_RANKS_NULL;
2045 
2046  /* NEIGHBORS IN LAYOUT DIMENSIONS WHICH ARE NOT IN THE TOPOLOGY, ONLY EXIST
2047  * WHEN WRAPPING IS ACTIVE FOR THAT DIMENSION. THE NEIGHBOR IS THE SAME
2048  * VIRTUAL PROCCESOR */
2049  if(dim >= self.topo.numDims ) {
2050  if ( self.wrap[dim] ) return self.topo.self;
2051  else return HIT_RANKS_NULL;
2052  }
2053 
2054  int d;
2055  for (d=0; d<hit_shapeDims(hit_layShape(self)); d++) {
2056  /* COPY RANK FOR NOT SELECTED DIM, OR DIM ABOVE THE DIMENSIONS IN THE TOPOLOGY */
2057  if (dim != d ) {
2058  neighbor.rank[d] = self.topo.self.rank[d];
2059  }
2060  else neighbor.rank[d] = hit_layDimNeighbor( self, d, shift );
2061 
2062  /* IF ANY RANK IS NULL, RETURN NULL RANKS */
2063  if ( neighbor.rank[d] == HIT_RANK_NULL ) return HIT_RANKS_NULL;
2064 
2065  }
2066 
2067  /* RETURN RESULT */
2068  return neighbor;
2069 }
2070 
2071 
2072 /* 10.7. INTERNAL WRAPPER: DO LAYOUT FOR ONE OR ALL DIMENSIONS */
2074  HitShape shape,
2075  HitLayoutSignatureFunction signatureGenericF,
2076  HitLayoutSignatureInvFunction signatureInvGenericF,
2077  HitLayoutSignatureFunction signatureRestrictedF,
2078  HitLayoutSignatureInvFunction signatureInvRestrictedF,
2079  HitLayoutRanksFunction ranksGenericF,
2080  HitLayoutRanksFunction ranksRestrictedF,
2081  HitLayoutSignatureMaxCardFunction maxCardGenericF,
2082  HitLayoutSignatureMaxCardFunction maxCardRestrictedF,
2083  HitLayoutSignatureMinCardFunction minCardGenericF,
2084  HitLayoutSignatureMinCardFunction minCardRestrictedF,
2085  HitLayoutSignatureNumActivesFunction activesGenericF,
2086  HitLayoutSignatureNumActivesFunction activesRestrictedF,
2087  float* extraParameter,
2088  int restrictToDim
2089  ) {
2090 
2091  /* 0. CHECK NULL TOPOLOGY */
2092  if ( hit_ptopoIsNull( topo.pTopology ) ) return HIT_LAYOUT_NULL;
2093 
2094  /* 1. INIT RESULT STRUCTURE */
2095  HitLayout res = HIT_LAYOUT_NULL;
2097 
2098  /* 2. COPY ORIGINAL SHAPE AND PARAMETERS FOR FUTURE REFERENCE */
2099  res.origShape = shape;
2100  res.topo = topo;
2101  res.info.layoutSig.restrictToDim = restrictToDim;
2102  res.info.layoutSig.extraParameter = extraParameter;
2103 
2104  /* 3. SKIP PROCCESSROS WHICH ARE NON-ACTIVE IN THE TOPOLOGY */
2105  int active = 0;
2106  // @arturo: 2015/01/06 Processors non-active in the topology should be able to
2107  // ask and answer about other processors which ARE active.
2108  // Used for Redistribution funtion with different topologies.
2109  // Thus, the pointers to compute layouts (in other procs.) should be set
2110  //if ( topo.active ) {
2111  /* 4. INITIALIZE POINTERS TO METHODS */
2112  res.info.layoutSig.signatureGenericF = signatureGenericF;
2113  res.info.layoutSig.signatureInvGenericF = signatureInvGenericF;
2114  res.info.layoutSig.signatureRestrictedF = signatureRestrictedF;
2115  res.info.layoutSig.signatureInvRestrictedF = signatureInvRestrictedF;
2116  //res.info.layoutSig.neighborGenericF = neighborGenericF;
2117  //res.info.layoutSig.neighborRestrictedF = neighborRestrictedF;
2118  res.info.layoutSig.ranksGenericF = ranksGenericF;
2119  res.info.layoutSig.ranksRestrictedF = ranksRestrictedF;
2120 
2121  /* 5. COMPUTE NUMBER OF ACTIVE PROCCESORS */
2122  int dim;
2123  for (dim=0; dim<hit_shapeDims(shape); dim++) {
2124  /* OLD: It works only for regular blocking/cyclic signatures */
2125  /*
2126  res.numActives[dim] =
2127  ( topo.card[dim] <= hit_sigCard(hit_shapeSig(shape,dim) ) ) ?
2128  topo.card[dim] :
2129  hit_sigCard(hit_shapeSig(shape,dim));
2130  */
2131 
2132  int blocksCard = hit_sigCard(hit_shapeSig(shape,dim));
2133  /* 5.1. DIMENSIONS OUT OF TOPOLOGY: ALL ACTIVE */
2134  if ( dim >= topo.numDims ) res.numActives[dim] = blocksCard;
2135  /* 5.2. DIMENSION RESTRICTED TO A SPECIFIC SIGNATURE FUNCTION */
2136  else if ( dim == restrictToDim )
2137  res.numActives[dim] = activesRestrictedF( topo.card[dim], blocksCard, extraParameter);
2138  /* 5.3. OTHER DIMENSIONS USE THE GENERIC SIGNATURE FUNCTION */
2139  else
2140  res.numActives[dim] = activesGenericF( topo.card[dim], blocksCard, extraParameter);
2141 
2142  // It can't be 0. TODO: REVISE THE FUNCTIONS TO COMPUTE numActives,
2143  // CHECK THAT THEY CANNONT RETURN 0 IF THE INPUT SHAPE IS NOT NULL
2144  // res.numActives[dim] = hit_max(1,res.numActives[dim]);
2145  }
2146 
2147  // @arturo 2015/01/06
2148  if ( topo.active ) {
2149 
2150  /* 6. COMPUTE BLOCK AND ACTIVE STATUS */
2151  active = hit_layout_wrapperShape(
2152  topo.numDims,
2153  topo.self,
2154  topo.card,
2155  shape,
2156  &(hit_layShape(res)),
2157  signatureGenericF,
2158  signatureRestrictedF,
2159  extraParameter,
2160  restrictToDim
2161  );
2162  res.active = active;
2163  if(! active) hit_layShape(res) = HIT_SHAPE_NULL;
2164 
2165  /* 7. COMPUTE MAX/MIN SIZES */
2166  for (dim=0; dim<hit_shapeDims(shape); dim++) {
2167  int blocksCard = hit_sigCard(hit_shapeSig(shape,dim));
2168  /* 7.1. DIMENSIONS OUT OF TOPOLOGY: NON-PARTITIONED, SIGNATURE COPIED IN ALL PROCS */
2169  if ( dim >= topo.numDims ) {
2170  res.maxSize[dim] = blocksCard;
2171  res.minSize[dim] = blocksCard;
2172  }
2173  /* 7.2. DIMENSION RESTRICTED TO A SPECIFIC SIGNATURE FUNCTION */
2174  else if ( dim == restrictToDim ) {
2175  res.maxSize[dim] = maxCardRestrictedF( topo.card[dim], blocksCard, extraParameter);
2176  res.minSize[dim] = minCardRestrictedF( topo.card[dim], blocksCard, extraParameter);
2177  }
2178  /* 7.3. OTHER DIMENSIONS USE THE GENERIC SIGNATURE FUNCTION */
2179  else {
2180  res.maxSize[dim] = maxCardGenericF( topo.card[dim], blocksCard, extraParameter);
2181  res.minSize[dim] = minCardGenericF( topo.card[dim], blocksCard, extraParameter);
2182  }
2183  }
2184  }
2185 
2186  /* 8. COMPUTE THE MPI COMUNICATOR FOR THE ACTIVE PROCESSORS */
2187  int allactive = 1;
2188  //int dim;
2189  for (dim=0; dim<topo.numDims; dim++) {
2190  if(topo.card[dim] > hit_sigCard(hit_shapeSig(shape,dim))) { allactive = 0; break; }
2191  }
2192 
2193  if( allactive ) {
2194  //if( active ) {
2195  res.pTopology[0] = hit_ptopDup( topo.pTopology );
2196  }
2197  else {
2198  // @arturo: Feb 2012, TODO: This check should not be needed any more.
2199  // else if( topo.pTopology.lowLevel != NULL ) {
2200 #ifdef DEBUG
2201  printf("Not all processes are active -> mpi communicator split\n");
2202 #endif
2203  /* @arturo: Feb 2012 Split physical topology communicators is embedded in a function */
2204  res.pTopology[0] = hit_ptopSplit( topo.pTopology, active );
2205  }
2206 
2207  /* 9. RETURN RESULT */
2208  return res;
2209 }
2210 
2211 
2212 /* COMPUTE THE TOTAL NUMBER OF ACTIVE PROCESSORS IN THE LAYOUT */
2214  int nProcs = 1;
2215  int i;
2216  for( i=0; i<lay.topo.numDims; i++ ) nProcs *= lay.numActives[i];
2217  return nProcs;
2218 }
2219 
2220 
2221 
2222 /* COMPUTE THE ACTIVE RANK OF THE OWNER OF A GIVEN INDEX */
2223 int hit_layDimOwner( HitLayout lay, int dim, int ind ) {
2224 
2225  /* 1. DIMENSIONS OUT OF TOPOLOGY */
2226  if ( dim >= lay.topo.numDims ) return HIT_RANK_NULL;
2227 
2228  /* 2. DIMENSION RESTRICTED TO A SPECIFIC SIGNATURE FUNCTION */
2229  if ( dim == lay.info.layoutSig.restrictToDim )
2231  hit_laySelfRanksDim( lay, dim ),
2232  lay.topo.card[dim],
2233  hit_shapeSigCard( lay.origShape, dim ),
2235  hit_shapeSig( lay.origShape, dim ),
2236  ind
2237  );
2238  /* 3. DIMENSION RESTRICTED TO A SPECIFIC SIGNATURE FUNCTION */
2239  else return lay.info.layoutSig.signatureInvGenericF(
2240  hit_laySelfRanksDim( lay, dim ),
2241  lay.topo.card[dim],
2242  hit_shapeSigCard( lay.origShape, dim ),
2244  hit_shapeSig( lay.origShape, dim ),
2245  ind
2246  );
2247 }
2248 
2249 
2250 /* FREE LAYOUT INTERNAL RESOURCES */
2252 
2253  int dim;
2254 
2256 
2257  // @arturo Mar 2013 CURRENTLY IT IS NOT A COPY, DO NOT FREE
2258  // Free the main topology
2259  // hit_topFree( lay.topo );
2260 
2261  // Free axis topologies if activated
2262  for( dim=0; dim < hit_layNumDims(lay); dim++ ) {
2263  // @arturo Mar 2013
2264  /*
2265  if(!hit_ptopoCmp(lay.pTopology[dim+1],HIT_PTOPOLOGY_NULL)){
2266  MPI_Comm_free( (MPI_Comm *) lay.pTopology[dim+1].lowLevel);
2267  free( lay.pTopology[dim+1].lowLevel );
2268  }
2269  */
2270  if ( lay.pTopology[dim+1] != NULL ) hit_ptopFree( &(lay.pTopology[dim+1]) );
2271  }
2272 
2273  } else if( hit_layout_class(lay) == HIT_LAYOUT_LIST_CLASS ){
2274 
2275  // Groups
2276  free(lay.info.layoutList.assignedGroups);
2277  free(lay.info.layoutList.groups);
2278 
2279  // Sparse
2280  hit_shapeFree( hit_layShape(lay) );
2281 
2282  }
2283 
2284  // Free the active pTopology
2285  // @arturo Mar 2013
2286  /*
2287  if( ! hit_ptopoCmp(lay.pTopology[0], lay.topo.pTopology) ){
2288  MPI_Comm_free( (MPI_Comm *) lay.pTopology[0].lowLevel);
2289  free( lay.pTopology[0].lowLevel );
2290  }
2291  */
2292  hit_ptopFree( &(lay.pTopology[0]) );
2293 
2294  // Free group topology if activated
2295  /*
2296  if( ! hit_ptopoCmp(lay.pTopologyGroup, HIT_PTOPOLOGY_NULL ) ){
2297  MPI_Comm_free( (MPI_Comm *) lay.pTopologyGroup.lowLevel);
2298  free( lay.pTopologyGroup.lowLevel );
2299  }
2300  */
2301  if( lay.pTopologyGroup != NULL ) hit_ptopFree( &(lay.pTopologyGroup) );
2302 }
2303 
2304 
2305 
2306 /* @arturo: Feb 2013
2307  * BUILD THE SUBTOPOLOGY OF A GIVEN GROUP */
2308 /* TODO:
2309  * Groups are those processors with the same part of the layout assigned.
2310  * NOTE: Most signature layouts, by definition, could not group processors. All active processors
2311  * have their own group, and inactive processors form a group without topology structure (they
2312  * are again a cloud or plain topology)
2313  * The exceptions are the layouts with Copy signature functions. For these layouts, forming
2314  * the groups is associated with rank indexes. It should be easy to provide functions to derive
2315  * groups.
2316  */
2317 /* TODO: Only works for list layouts, do implementation for Signature layouts */
2319  HitTopology newTopo = HIT_TOPOLOGY_NULL;
2320 
2321  /* 0.1. CHECK THAT IT IS A LIST LAYOUT */
2322  if ( lay.type < HIT_LAYOUT_LIST_FIRST ) {
2323  hit_warnInternal(__FUNCTION__, "Sorry. Implementation of Group topologies for signature layouts is not yey implemented.", "", __FILE__, __LINE__ );
2324  return HIT_TOPOLOGY_NULL;
2325  }
2326 
2327  /* 0.2. CHECK THAT THE GROUP INDEX EXIST IN THE LAYOUT */
2328  if ( groupId < 0 || groupId >= hit_lgr_numGroups(lay) ) {
2329  hit_warnInternal(__FUNCTION__, "Group Id does not exist", "", __FILE__, __LINE__ );
2330  return HIT_TOPOLOGY_NULL;
2331  }
2332 
2333  /* 1. IF NOT DONE BEFORE, GENERATE THE SUB-GROUP PTOPOLOGY */
2334  //if ( hit_ptopoIsNull( lay.pTopologyGroup ) ) {
2335  if ( lay.pTopologyGroup == NULL ) {
2336  /* 1.1. ONLY ONE GROUP, DUPLICATE THE ACTIVES PTOPOLOGY */
2337  if ( hit_lgr_numGroups( lay ) == 1 )
2338  lay.pTopologyGroup = hit_ptopDup( lay.pTopology[0] );
2339  /* 1.2. SEVERAL GROUPS, SPLIT THE TOPOLOGY, KEEP THE SAME RANK ORDER IN THE GROUPS */
2340  else
2341  lay.pTopologyGroup = hit_ptopSplit( lay.pTopology[0], lay.group );
2342  }
2343 
2344  /* 2. FILL COMMON TOPOLOGY FIELDS */
2345  newTopo.type = HIT_TOPOLOGY_PLAIN;
2346  // @arturo Mar 2013, Main pTopology field is not currently freed. Use a direct copy.
2347  // TODO: This field will get obsolete in the next refactorization.
2348  //newTopo.pTopology = hit_ptopDup( lay.pTopologyGroup );
2349  newTopo.pTopology = lay.pTopologyGroup;
2350  newTopo.numDims = 1;
2351 
2352  /* 3. IF THE LOCAL PROCESS IS IN THE GROUP */
2353  if ( groupId == lay.group ) {
2354  newTopo.card[0] = newTopo.pTopology->numProcs;
2355  newTopo.self.rank[0] = newTopo.pTopology->selfRank;
2356  //newTopo.linearRank = newTopo.self.rank[0];
2357  //newTopo.pTopology = hit_ptopDup( lay.pTopologyGroup );
2358  newTopo.active = 1;
2359  }
2360  /* 4. LOCAL PROCESS NOT IN THE GROUP */
2361  else {
2362  newTopo.card[0] = hit_lgr_groupNProcs( lay, groupId );
2363  }
2364 
2365  /* 4. RETURN */
2366  return newTopo;
2367 }
2368 
2369 
2370 /* @arturo Feb, 2013 */
2371 /* BUILD A TOPOLOGY OBJECT WITH THE ACTIVE PROCESSORS */
2373  HitTopology newTopo = HIT_TOPOLOGY_NULL;
2374 
2375  /* NON-ACTIVE PROCESSORS: RETURN NULL */
2376  if ( ! hit_layImActive( lay ) ) return newTopo;
2377 
2378  /* BUILD A PLAIN TOPOLOGY OBJECT */
2379  newTopo.pTopology = hit_ptopDup( lay.pTopology[0] );
2380  newTopo.type = HIT_TOPOLOGY_PLAIN;
2381  newTopo.numDims = 1;
2382  newTopo.card[0] = newTopo.pTopology->numProcs;
2383  newTopo.self.rank[0] = newTopo.pTopology->selfRank;
2384  //newTopo.linearRank = newTopo.pTopology->selfRank;
2385  newTopo.active = 1;
2386 
2387  /* RETURN */
2388  return newTopo;
2389 }
2390 
2391 /***************************************************************/
2392 /***************************************************************/
2393 /***************************************************************/
2394 
2395 
2396 
2397 /*
2398  * hit_layout_list_initGroups
2399  * Init the layout structure whit n elements
2400  */
2401 void hit_layout_list_initGroups(HitLayout * lay, int numElementsTotal) {
2402 
2403  lay->group = HIT_GROUP_ID_NULL;
2404 
2405  lay->info.layoutList.numGroups = 0;
2406  lay->info.layoutList.groups = NULL;
2407 
2408  lay->info.layoutList.numElementsTotal = numElementsTotal;
2409  // @arturo Ago 2015: New allocP interface
2410  // hit_calloc(lay->info.layoutList.assignedGroups, sizeof(int), (size_t)numElementsTotal,int*);
2411  hit_calloc(lay->info.layoutList.assignedGroups, int, numElementsTotal );
2412 
2413 }
2414 
2415 
2423 void hit_layout_list_addGroup(HitLayout * lay, int leader, int np) {
2424 
2425 
2426  // @arturo Ago 2015: New allocP interface
2427  // hit_realloc(lay->info.layoutList.groups,(size_t)sizeof(HitGroup)*((size_t)lay->info.layoutList.numGroups+1),HitGroup*);
2429 
2430  if(leader == -1){
2431  if(lay->info.layoutList.numGroups == 0){
2432  leader = 0;
2433  } else {
2434  leader = lay->info.layoutList.groups[lay->info.layoutList.numGroups-1].leader +
2436  }
2437  }
2438 
2439 #ifdef DEBUG
2440  printf("Adding group %d, leader: %d, nprocs: %d\n",lay->info.layoutList.numGroups,leader,np);
2441 #endif
2442 
2443  lay->info.layoutList.groups[lay->info.layoutList.numGroups].leader = leader;
2445 
2446  lay->info.layoutList.numGroups++;
2447 }
2448 
2449 
2450 
2451 /* List of the elements assigned to a group */
2452 void hit_lay_elements(HitLayout layout, int group, int ** els, int * nEls){
2453 
2454  HitLayout * layg = &layout;
2455  int i;
2456  int nElements = 0;
2457  int * elements = NULL;
2458 
2459  for( i=0; i<layg->info.layoutList.numElementsTotal; i++){
2460 
2461  if( layg->info.layoutList.assignedGroups[i] == group ){
2462  nElements++;
2463  // @arturo Ago 2015: New allocP interface
2464  // hit_realloc(elements,sizeof(int)*(size_t)nElements,int*);
2465  hit_realloc(elements, int, nElements);
2466  elements[ nElements -1 ] = i;
2467  }
2468  }
2469 
2470  (*els) = elements;
2471  (*nEls) = nElements;
2472 
2473 }
2474 
2475 
2476 /* Calculate the group number for a given processor */
2477 int hit_lay_procGroup(HitLayout layout, int processor){
2478 
2479  HitLayout * layg = &(layout);
2480  int i;
2481  int sum;
2482 
2483  sum = 0;
2484  for(i=0;i<layg->info.layoutList.numGroups;i++){
2485  sum += layg->info.layoutList.groups[i].numProcs;
2486  if(processor < sum) return i;
2487  }
2488 
2489  return -1;
2490 }
2491 
2492 
2493 
2494 /* SCHEDULING OF n INDEPENDENT BLOCKS TO m PROCS, ACCORDING TO BLOCK WEIGHTs */
2495 HitLayout hit_layout_plug_layIndependentLB( HitTopology topo , HitShape elements, const double *weights ) {
2496 
2498  double totWeight = 0.0;
2499  int i;
2500  int proc;
2501  int nElements;
2502  int totProcs;
2503  int numGroups;
2504  int nProcs;
2505 
2506 
2507  lay.topo = topo;
2508  lay.origShape = elements;
2509  // lay.pTopology[0] = topo.pTopology;
2510  lay.pTopology[0] = hit_ptopDup( topo.pTopology );
2512 
2513  /* NUMBER OF PROCESSORS */
2514  nProcs = 1;
2515  for(i=0;i<topo.numDims;i++){
2516  nProcs *= topo.card[i];
2517  lay.numActives[i] = topo.card[i];
2518  }
2519 
2520  /* CALCULATE NUMBER OF ELEMENTS */
2521  nElements = hit_sigCard(hit_shapeSig(elements,0));
2522 
2523  int numProcs[nElements];
2524  double normWeight[nElements];
2525  double normWeightPerGroup[nElements];
2526 
2527 #ifdef DEBUG
2528 double normW = 0.0;
2529 setbuf(stdout, NULL);
2530 #endif
2531 
2532  /* INIT SCHED STRUCTURE */
2533  hit_layout_list_initGroups(&lay, nElements);
2534 
2535  /* SAFETY CHECK: CONSISTENCY OF INPUT DATA, NO NEGATIVE LOADS */
2536 #ifndef Hit_UNSAFE
2537  for (i=0; i<nElements; i++) {
2538  if (weights[i]<0.0){
2539  hit_errInternal(__FUNCTION__,"Weight input data is incorrect (check workload expressions)","",__FILE__,__LINE__);
2540  }
2541  }
2542 #endif
2543 
2544  /* COMPUTE TOTAL WORKLOAD */
2545  totProcs = 0;
2546  for (i=0; i<nElements; i++) totWeight = totWeight + weights[i];
2547 #ifdef DEBUG
2548 printf("TotWeight-A %lf\n", totWeight);
2549 #endif
2550 
2551  /* SAFETY CHECK: CONSISTENCY OF INPUT DATA, TOTAL WEIGHT 0 */
2552  if (totWeight == 0.0) totWeight = 1.0; /* Avoid division by 0 */
2553 #ifdef DEBUG
2554 printf("TotWeight-B %lf\n", totWeight);
2555 #endif
2556 
2557  /* NORMALIZE THE NUMBER OF PROCESSOR PER ELEMENT, ROUND DOWN */
2558  for (i=0; i<nElements; i++) {
2559  normWeight[i] = nProcs * weights[i] / totWeight;
2560  numProcs[i] = (int)normWeight[i];
2561  normWeight[i] = normWeight[i] - numProcs[i];
2562  totProcs = totProcs + numProcs[i];
2563 #ifdef DEBUG
2564 printf("CTRL numProcs[%i] = %d . %lf\n", i, numProcs[i],normWeight[i]);
2565 normW = normW + numProcs[i] + normWeight[i];
2566 #endif
2567  }
2568 
2569 #ifdef DEBUG
2570 printf("CTRL Total norm. weight %lf\n", normW);
2571 #endif
2572 
2573  /* ASSIGN THE REST OF PROCESSORS */
2574  for (i=0; i<(nProcs-totProcs); i++) {
2575  /* ASSIGN IT TO THE ELEMENT WITH THE BIGGEST REST OF NORM. WEIGHT */
2576  double maxWeight = normWeight[0];
2577  int maxPos = 0;
2578  int j;
2579  for (j=1; j<nElements; j++) {
2580  if (normWeight[j]>maxWeight) {
2581  maxWeight = normWeight[j];
2582  maxPos = j;
2583  }
2584  }
2585  numProcs[maxPos]++;
2586  normWeight[maxPos]=normWeight[maxPos]-1;
2587  }
2588 
2589 #ifdef DEBUG
2590 for (i=0;i<nElements;i++) {
2591 printf("CTRL numProcs[%i] = %d . %lf\n", i, numProcs[i],normWeight[i]);
2592 }
2593 #endif
2594 
2595  /* CREATE PROCESSOR-GROUPS AND ASSIGN ELEMENTS */
2596  proc = 0;
2597  numGroups = 0;
2598  for (i=0; i<nElements; i++) {
2599  if ( numProcs[i] > 0 ) {
2600  hit_layout_list_addGroup(&lay, proc, numProcs[i]);
2601  proc = proc + numProcs[i];
2602 
2603  lay.info.layoutList.assignedGroups[i] = numGroups;
2604 
2605  normWeightPerGroup[numGroups]=normWeight[i];
2606  numGroups++;
2607  }
2608  }
2609 
2610  /* ELEMENTS WITH NO PROCCESSOR YET ASSIGNED */
2611  for (i=0; i<nElements; i++) {
2612  if (numProcs[i]==0) {
2613  /* ASSIGN IT TO THE LESS REST OF NORM. WEIGHT GROUP */
2614  double minWeight = normWeightPerGroup[0];
2615  int minPos = 0;
2616  int j;
2617  for (j=1; j<numGroups; j++) {
2618  if ( normWeightPerGroup[j] < minWeight) {
2619  minWeight = normWeightPerGroup[j];
2620  minPos = j;
2621  }
2622  }
2623  lay.info.layoutList.assignedGroups[i] = minPos;
2624  normWeightPerGroup[minPos] = normWeightPerGroup[minPos] + normWeight[i];
2625 #ifdef DEBUG
2626 printf("Block %d, assigned to group %d, new normWeight %lf\n",i,minPos,normWeightPerGroup[minPos]);
2627 #endif
2628  }
2629  }
2630 
2631  // @arturo 2015/01/22
2632  //int group = hit_lay_procGroup(lay,topo.linearRank);
2633  int group = hit_lay_procGroup(lay, hit_topSelfRankInternal( topo ) );
2634  lay.group = group;
2635 
2636  int leaderId = lay.info.layoutList.groups[group].leader;
2637  // @arturo 2015/01/22
2638  //lay.leader = (topo.linearRank == leaderId ) ? 1 : 0;
2639  lay.leader = ( hit_topSelfRankInternal( topo ) == leaderId ) ? 1 : 0;
2640 
2641  HitRanks leaderRanks = HIT_RANKS_NULL;
2642  leaderRanks.rank[0] = leaderId;
2643  lay.leaderRanks = leaderRanks;
2644 
2645  /* RETURN */
2646  return lay;
2647 }
2648 
2649 
2650 
2651 /* SCHEDULING OF n CONTIGUOUS BLOCKS TO m PROCS, ACCORDING TO BLOCK WEIGHTs like IS NAS benckmark */
2652 HitLayout hit_layout_plug_layContiguous(HitTopology topo, HitShape elements, const double *weights ) {
2653 
2655  double totWeight; // Total weight
2656  double avgWeight; // Average weight
2657  int i;
2658  int proc;
2659  int nElements;
2660  int nProcs;
2661 
2662  lay.topo = topo;
2663  lay.origShape = elements;
2664  lay.pTopology[0] = hit_ptopDup( topo.pTopology );
2666 
2667  /* NUMBER OF PROCESSORS */
2668  nProcs = 1;
2669  for(i=0;i<topo.numDims;i++){
2670  nProcs *= topo.card[i];
2671  lay.numActives[i] = topo.card[i];
2672  }
2673 
2674  /* CALCULATE NUMBER OF ELEMENTS */
2675  nElements = hit_shapeCard( elements );
2676 
2677  /* INIT STRUCTURE */
2678  hit_layout_list_initGroups(&lay, nElements);
2679 
2680  /* SAFETY CHECK: CONSISTENCY OF INPUT DATA, NO NEGATIVE LOADS */
2681 #ifndef Hit_UNSAFE
2682  for (i=0; i<nElements; i++) {
2683  if (weights[i]<0.0){
2684  hit_errInternal(__FUNCTION__,"Weight input data is incorrect (check workload expressions)","",__FILE__,__LINE__);
2685  }
2686  }
2687 #endif
2688 
2689  /* COMPUTE TOTAL WORKLOAD */
2690  totWeight = 0.0;
2691  for (i=0; i<nElements; i++) totWeight += weights[i];
2692 
2693  /* SAFETY CHECK: CONSISTENCY OF INPUT DATA, TOTAL WEIGHT 0 */
2694  if (totWeight == 0.0) totWeight = 1.0; /* Avoid division by 0 */
2695 
2696  /* AVERAGE WEIGHT */
2697  avgWeight = totWeight / nProcs;
2698 
2699 #ifdef DEBUG
2700  printf("[%d] plugContiguous CTRL totalWeight: %lf, nprocs: %d, avg: %lf\n", hit_Rank, totWeight, nProcs, avgWeight );
2701 #endif
2702 
2703  proc = 0;
2704  double localWeight = 0.0;
2705  double acumWeight = 0.0;
2706  int localElements = 0;
2707  int acumElements = 0;
2708 
2709  /* ASSIGN ELEMENTS TO PROCESSORS */
2710  for(i=0; i<nElements; i++) {
2711  localElements++;
2712  localWeight = localWeight + weights[i];
2713  lay.info.layoutList.assignedGroups[i] = proc;
2714 
2715  if ( acumWeight + localWeight >= avgWeight * (proc+1) ) {
2716  if ( proc == hit_topSelfRankInternal( topo ) ) {
2717  lay.ownLoad = localWeight;
2718  lay.predecessorsLoad[0] = acumWeight;
2719  lay.successorsLoad[0] = totWeight - acumWeight - localWeight;
2720  lay.info.layoutList.cardOwnElements = localElements;
2721  lay.info.layoutList.cardPredElements = acumElements;
2722  lay.info.layoutList.cardSuccElements = nElements - acumElements - localElements;
2723  }
2724  hit_layout_list_addGroup(&lay, proc, 1);
2725  proc++;
2726 
2727  acumWeight += localWeight;
2728  acumElements += localElements;
2729  localWeight = 0.0;
2730  localElements = 0;
2731  }
2732  }
2733  /* LAST ELEMENTS, IN CASE THAT ROUNDING ERRORS IN INNER COMPARISON LET THEM UNASSIGNED */
2734  if ( localWeight != 0.0 ) {
2735  hit_layout_list_addGroup(&lay, proc, 1);
2736  if ( proc == hit_topSelfRankInternal( topo ) ) {
2737  lay.ownLoad = localWeight;
2738  lay.predecessorsLoad[0] = acumWeight;
2739  lay.successorsLoad[0] = totWeight - acumWeight - localWeight;
2740  lay.info.layoutList.cardOwnElements = localElements;
2741  lay.info.layoutList.cardPredElements = acumElements;
2742  lay.info.layoutList.cardSuccElements = nElements - acumElements - localElements;
2743  }
2744  proc++;
2745  acumWeight += localWeight;
2746  acumElements += localElements;
2747  }
2748 
2749  /* ASSIGN FREE PROCESSORS */
2750  // @arturo: IS policy: EVERY PROC. HAS ITS OWN GROUP, THERE ARE GROUPS WITH NO LOAD
2751  for ( ; proc < nProcs; proc++ ) {
2752  hit_layout_list_addGroup(&lay, proc, 1);
2753  if ( proc == hit_topSelfRankInternal( topo ) ) {
2754  lay.ownLoad = 0.0;
2755  lay.predecessorsLoad[0] = acumWeight;
2756  }
2757  }
2758  /*
2759  nProcs -= (proc+1);
2760  while(nProcs > 0){
2761  int j, maxg = 0;
2762  double maxw = 0, current;
2763 
2764  for(i=0;i<lay.info.layoutList.numGroups;i++){
2765  current = 0;
2766  for(j=0;j<lay.info.layoutList.numElementsTotal;j++){
2767  if(lay.info.layoutList.assignedGroups[j] == i){
2768  current += weights[j];
2769  }
2770  }
2771 
2772  current /= lay.info.layoutList.groups[i].numProcs;
2773 
2774  if(current > maxw){
2775  maxw = current;
2776  maxg = i;
2777  }
2778  }
2779 
2780  lay.info.layoutList.groups[maxg].numProcs++;
2781  nProcs--;
2782  }
2783  */
2784 
2785  /* CALCULATE THE LEADERS */
2786  int act_leader = 0;
2787  for(i=0;i<lay.info.layoutList.numGroups;i++){
2788  lay.info.layoutList.groups[i].leader = act_leader;
2789  act_leader += lay.info.layoutList.groups[i].numProcs;
2790  }
2791  // @arturo 2015/01/22
2792  //int group = hit_lay_procGroup(lay,topo.linearRank);
2793  int group = hit_lay_procGroup(lay, hit_topSelfRankInternal( topo ) );
2794  lay.group = group;
2795  int leader = lay.info.layoutList.groups[group].leader;
2796  // @arturo 2015/01/22
2797  //lay.leader = (topo.linearRank == leader ) ? 1 : 0;
2798  lay.leader = ( hit_topSelfRankInternal( topo ) == leader ) ? 1 : 0;
2799 
2800  /* RETURN */
2801  return lay;
2802 }
2803 
2804 
2805 
2810 
2811  int ok;
2812  int cards[2];
2813  // @arturo Mar 2013
2814  //MPI_Comm comm = *((MPI_Comm *)topo.pTopology.lowLevel);
2815  MPI_Comm comm = topo.pTopology->comm;
2816 
2817  if(topo.pTopology->selfRank == 0){
2818  cards[0] = hit_bShapeCard(*shape,0);
2819  cards[1] = hit_bShapeCard(*shape,1);
2820  MPI_Bcast(cards, 2, MPI_INT, 0, comm);
2821  } else {
2822  MPI_Bcast(cards, 2, MPI_INT, 0, comm);
2823 
2824  HitShape newShp = hit_bitmapShapeMatrix(cards[0],cards[1]);
2825  *shape = newShp;
2826  }
2827 
2828  // Send the flag for names.
2829  ok = MPI_Bcast(&(hit_bShapeNameList(*shape,0).flagNames),1,MPI_INT,0,comm);
2830  hit_mpiTestError(ok,"Error in bitmap hit_bitmapShapeBcastInternal");
2831  ok = MPI_Bcast(&(hit_bShapeNameList(*shape,1).flagNames),1,MPI_INT,0,comm);
2832  hit_mpiTestError(ok,"Error in bitmap hit_bitmapShapeBcastInternal");
2833 
2834 
2835  if(topo.pTopology->selfRank != 0){
2836  if(hit_bShapeNameList(*shape,0).flagNames == HIT_SHAPE_NAMES_ARRAY)
2837  hit_bShapeNameList(*shape,0).flagNames = HIT_SHAPE_NAMES_NOARRAY;
2838  if(hit_bShapeNameList(*shape,1).flagNames == HIT_SHAPE_NAMES_ARRAY)
2839  hit_bShapeNameList(*shape,1).flagNames = HIT_SHAPE_NAMES_NOARRAY;
2840  }
2841 
2842  int nbits = cards[0] * cards[1];
2843  int ndata = (int)(hit_bitmapShapeIndex(nbits) + (hit_bitmapShapeOffset(nbits)==0 ? 0 : 1));
2844 
2845  ok = MPI_Bcast(hit_bShapeData(*shape),ndata,HIT_BITMAP_COMM_TYPE,0,comm);
2846  hit_mpiTestError(ok,"Error in bitmap hit_bitmapShapeBcastInternal");
2847 
2848  ok = MPI_Bcast(hit_cShapeNameList(*shape,0).names, cards[0], MPI_INT, 0, comm);
2849  hit_mpiTestError(ok,"Error in bitmap hit_bitmapShapeBcastInternal");
2850  ok = MPI_Bcast(hit_cShapeNameList(*shape,1).names, cards[1], MPI_INT, 0, comm);
2851  hit_mpiTestError(ok,"Error in bitmap hit_bitmapShapeBcastInternal");
2852 
2853  hit_cShapeNameList(*shape,0).nNames = cards[0];
2854  hit_cShapeNameList(*shape,1).nNames = cards[1];
2855 
2856 }
2857 
2858 
2860 
2861  // 0. Broadcast the sparse shape
2862  hit_bShapeBcastInternal(shapeP,topo);
2863 
2864  HitShape shape = *shapeP;
2865 
2866  // 1. Create the layout
2868  lay.topo = topo;
2869  lay.origShape = shape;
2870 
2871  // 2. Obtain the number of processors
2872  int procsCard = hit_topCard(topo);
2873  // @arturo 2015/01/22
2874  //int procId = topo.linearRank;
2875  int procId = hit_topSelfRankInternal( topo );
2876  HitSig input = hit_sig(0,hit_bShapeNvertices(shape),1);
2877  HitSig output;
2878 
2879  // Split the communicator
2880  // @javfres 2015-10-05 Split to support inactive processes
2881  //lay.active = hit_layout_plug_layBlocks_Sig(procId, procsCard,hit_bShapeNvertices(shape), 0.0, input, &output);
2882  lay.active = hit_layout_plug_layBlocks_Sig(procId, procsCard,hit_bShapeNvertices(shape), NULL, input, &output);
2883  lay.pTopology[0] = hit_ptopSplit(topo.pTopology, lay.active);
2884  int nactives = hit_min(hit_bShapeNvertices(shape), procsCard);
2885  lay.numActives[0] = nactives;
2886 
2888  int i;
2889  for(i=0;i<nactives;i++){
2890  hit_layout_list_addGroup(&lay, i, 1);
2891  HitSig part_i;
2892  //hit_layout_plug_layBlocks_Sig(i, nactives,hit_bShapeNvertices(shape), 0.0, input, &part_i);
2893  hit_layout_plug_layBlocks_Sig(i, nactives,hit_bShapeNvertices(shape), NULL, input, &part_i);
2894  int j;
2895  for(j=part_i.begin; j<=part_i.end; j++){
2896  lay.info.layoutList.assignedGroups[j] = i;
2897  }
2898 
2899  }
2900 
2901  int * names = hit_bShapeNameList(shape,0).names + output.begin;
2902  lay.shape = hit_bShapeSelect(shape, hit_sigCard(output), names);
2903 
2904  return lay;
2905 }
2906 
2907 
2908 
2909 
2911 
2912  int ok;
2913  int cards[2];
2914  int nz;
2915  // @arturo Mar 2013
2916  //MPI_Comm comm = *((MPI_Comm *)topo.pTopology.lowLevel);
2917  MPI_Comm comm = topo.pTopology->comm;
2918 
2919  if(topo.pTopology->selfRank == 0){
2920  cards[0] = hit_cShapeCard(*shape,0);
2921  cards[1] = hit_cShapeCard(*shape,1);
2922  nz = hit_cShapeNZElems(*shape);
2923  MPI_Bcast(cards, 2, MPI_INT, 0, comm);
2924  MPI_Bcast(&nz, 1, MPI_INT, 0, comm);
2925  } else {
2926  MPI_Bcast(cards, 2, MPI_INT, 0, comm);
2927  MPI_Bcast(&nz, 1, MPI_INT, 0, comm);
2928 
2929  HitShape newShp = hit_csrShapeMatrix(cards[0],cards[1],nz);
2930  *shape = newShp;
2931  }
2932 
2933  // Send the flag for names.
2934  ok = MPI_Bcast(&(hit_cShapeNameList(*shape,0).flagNames),1,MPI_INT,0,comm);
2935  hit_mpiTestError(ok,"Broadcast error hit_cShapeBcastInternal");
2936  ok = MPI_Bcast(&(hit_cShapeNameList(*shape,1).flagNames),1,MPI_INT,0,comm);
2937  hit_mpiTestError(ok,"Broadcast error hit_cShapeBcastInternal");
2938 
2939 
2940  if(topo.pTopology->selfRank != 0){
2941  if(hit_cShapeNameList(*shape,0).flagNames == HIT_SHAPE_NAMES_ARRAY)
2942  hit_cShapeNameList(*shape,0).flagNames = HIT_SHAPE_NAMES_NOARRAY;
2943  if(hit_cShapeNameList(*shape,1).flagNames == HIT_SHAPE_NAMES_ARRAY)
2944  hit_cShapeNameList(*shape,1).flagNames = HIT_SHAPE_NAMES_NOARRAY;
2945  }
2946 
2947  ok = MPI_Bcast(hit_cShapeXadj(*shape), cards[0]+1, MPI_INT, 0, comm);
2948  hit_mpiTestError(ok,"Error in sparseShapeBcast");
2949  ok = MPI_Bcast(hit_cShapeAdjncy(*shape), nz, MPI_INT, 0, comm);
2950  hit_mpiTestError(ok,"Error in sparseShapeBcast");
2951  ok = MPI_Bcast(hit_cShapeNameList(*shape,0).names, cards[0], MPI_INT, 0, comm);
2952  hit_mpiTestError(ok,"Error in sparseShapeBcast");
2953  ok = MPI_Bcast(hit_cShapeNameList(*shape,1).names, cards[1], MPI_INT, 0, comm);
2954  hit_mpiTestError(ok,"Error in sparseShapeBcast");
2955 
2956  hit_cShapeNameList(*shape,0).nNames = cards[0];
2957  hit_cShapeNameList(*shape,1).nNames = cards[1];
2958 
2959 }
2960 
2961 
2962 
2964 
2965  // 0. Broadcast the sparse shape
2966  hit_cShapeBcastInternal(shapeP,topo);
2967  HitShape shape = *shapeP;
2968 
2969  // 1. Create the layout
2971  lay.topo = topo;
2972  lay.origShape = shape;
2973 
2974  // 2. Obtain the number of processors
2975  int procsCard = hit_topCard(topo);
2976  // @arturo 2015/01/22
2977  //int procId = topo.linearRank;
2978  int procId = hit_topSelfRankInternal( topo );
2979  HitSig input = hit_sig(0,hit_cShapeNvertices(shape),1);
2980  HitSig output;
2981 
2982  // Split the communicator
2983  // @javfres 2015-10-05 Split to support inactive processes
2984  //lay.active = hit_layout_plug_layBlocks_Sig(procId, procsCard, hit_cShapeCard(shape,0), 0.0, input, &output);
2985  lay.active = hit_layout_plug_layBlocks_Sig(procId, procsCard, hit_cShapeCard(shape,0), NULL, input, &output);
2986  lay.pTopology[0] = hit_ptopSplit(topo.pTopology, lay.active);
2987  int nactives = hit_min(hit_cShapeCard(shape,0), procsCard);
2988  lay.numActives[0] = nactives;
2989 
2990  // @note @javfres Esto solo funciona para filas enteras.
2992 
2993  int i;
2994  for(i=0;i<procsCard;i++){
2995  hit_layout_list_addGroup(&lay, i, 1);
2996  HitSig part_i;
2997  //hit_layout_plug_layBlocks_Sig(i, procsCard,hit_cShapeCard(shape,0), 0.0, input, &part_i);
2998  hit_layout_plug_layBlocks_Sig(i, procsCard,hit_cShapeCard(shape,0), NULL, input, &part_i);
2999  int j;
3000  for(j=part_i.begin; j<=part_i.end; j++){
3001  lay.info.layoutList.assignedGroups[j] = i;
3002  }
3003 
3004  }
3005 
3006  int * names = hit_cShapeNameList(shape,0).names + output.begin;
3007  lay.shape = hit_cShapeSelectRows(shape, hit_sigCard(output), names);
3008 
3009  return lay;
3010 
3011 }
3012 
3013 
3014 
3016 
3017  // 0. Broadcast the sparse shape
3018  hit_bShapeBcastInternal(shapeP,topo);
3019  HitShape shape = *shapeP;
3020 
3021  // 1. Create the layout
3023  lay.topo = topo;
3024  lay.pTopology[0] = hit_ptopDup( topo.pTopology );
3025  lay.origShape = shape;
3026 
3027  // 2. Obtain the number of processors
3028  int procsCard = hit_topCard(topo);
3029  // @arturo 2015/01/22
3030  //int procId = topo.linearRank;
3031  int procId = hit_topSelfRankInternal( topo );
3032  HitSig input = hit_sig(0,hit_bShapeNvertices(shape),1);
3033  HitSig output;
3034 
3035  // @javfres 2015-10-19 Split to support inactive processes
3036  //lay.active = hit_layout_plug_layBlocks_Sig(procId, procsCard, hit_bShapeCard(shape,0), 0.0, input, &output);
3037  lay.active = hit_layout_plug_layBlocks_Sig(procId, procsCard, hit_bShapeCard(shape,0), NULL, input, &output);
3038  lay.pTopology[0] = hit_ptopSplit(topo.pTopology, lay.active);
3039  int nactives = hit_min(hit_bShapeCard(shape,0), procsCard);
3040  lay.numActives[0] = nactives;
3041 
3042 
3043  // @note @javfres Esto solo funciona para filas enteras.
3045 
3046  int i;
3047  for(i=0;i<procsCard;i++){
3048  hit_layout_list_addGroup(&lay, i, 1);
3049  HitSig part_i;
3050  //hit_layout_plug_layBlocks_Sig(i, procsCard,hit_bShapeCard(shape,0), 0.0, input, &part_i);
3051  hit_layout_plug_layBlocks_Sig(i, procsCard,hit_bShapeCard(shape,0), NULL, input, &part_i);
3052  int j;
3053  for(j=part_i.begin; j<=part_i.end; j++){
3054  lay.info.layoutList.assignedGroups[j] = i;
3055  }
3056  }
3057 
3058  int * names = hit_bShapeNameList(shape,0).names + output.begin;
3059  lay.shape = hit_bShapeSelectRows(shape, hit_sigCard(output), names);
3060 
3061  return lay;
3062 }
3063 
3064 
3065 
3066 
3067 
3068 
#define HIT_LAY_RANKS_TOPO_TO_ACTIVE
Definition: hit_layout.h:105
int hit_layout_plug_layBlocksBalance_SigInv(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, int ind)
Definition: hit_layout.c:1101
#define hit_cShapeAdjncy(shape)
#define hit_shape(nd,...)
Definition: hit_sshape.h:175
HitLayout hit_layout_plug_layCyclic(HitTopology topo, HitShape shape, int dim)
Definition: hit_layout.c:948
HitLayout HIT_LAYOUT_NULL
Definition: hit_layout.c:71
HitGroup * groups
Definition: hit_layout.h:225
#define hit_layShape(lay)
Definition: hit_layout.h:650
int hit_layDimOwner(HitLayout lay, int dim, int ind)
Definition: hit_layout.c:2223
HitLayoutSig HIT_LAYOUTSIG_NULL
Definition: hit_layout.c:62
int(* HitLayoutRanksFunction)(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParam)
Definition: hit_layout.h:106
HitShape hit_bShapeSelectRows(HitShape shape, int nNames, int *names)
Definition: hit_bshape.c:162
HitLayoutSignatureFunction signatureGenericF
Definition: hit_layout.h:158
int hit_layout_plug_layMinBlocks_numActives(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:509
HitLayoutSignatureInvFunction signatureInvRestrictedF
Definition: hit_layout.h:161
HitShape hit_bShapeSelect(HitShape shape, int nvertices, int *vertices)
Definition: hit_bshape.c:134
#define HIT_LAYOUT_MINBLOCKS
Definition: hit_layout.h:326
HitLayoutRanksFunction ranksGenericF
Definition: hit_layout.h:162
HitRanks leaderRanks
Definition: hit_layout.h:268
#define HIT_GROUP_NULL_STATIC
Definition: hit_layout.h:212
int hit_layout_plug_layMinBlocks_maxCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:493
HitPTopology * hit_ptopSplit(HitPTopology *in, int group)
Definition: hit_topology.c:80
int hit_layout_plug_layAllInOne_ranks(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:256
int perform_weighted_distribution(int procsCard, int blocksCard, float *weights, int *result)
Definition: hit_layout.c:1262
int hit_layNeighborDistance(HitLayout self, int dim, int shift)
Definition: hit_layout.c:2001
HitLayoutSignatureFunction signatureRestrictedF
Definition: hit_layout.h:160
#define hit_Rank
Definition: hit_com.h:140
int hit_topRankInternal(HitTopology topo, HitRanks ranks)
Definition: hit_topology.c:415
void hit_lay_elements(HitLayout layout, int group, int **elements, int *nElements)
Definition: hit_layout.c:2452
float * extraParameter
Definition: hit_layout.h:164
#define HIT_LAYOUT_LIST_FIRST
Definition: hit_layout.h:376
int rank[HIT_MAXDIMS]
Definition: hit_topology.h:135
int cardPredElements
Definition: hit_layout.h:229
HitTopology topo
Definition: hit_layout.h:255
#define hit_shapeDimsSet(shape, value)
Definition: hit_sshape.h:387
#define hit_bShapeCard(shape, dim)
Definition: hit_bshape.h:144
int hit_layout_plug_layBlocksL_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:789
#define hit_lgr_numGroups(lay)
Definition: hit_layout.h:897
HitPTopology * pTopology
Definition: hit_topology.h:253
int minSize[HIT_MAXDIMS]
Definition: hit_layout.h:261
HitLayout hit_layout_plug_layIndependentLB(HitTopology topo, HitShape elements, const double *weights)
Definition: hit_layout.c:2495
#define HIT_LAYOUT_NULL_STATIC
Definition: hit_layout.h:300
#define HIT_WRAPPED
Definition: hit_layout.h:191
int hit_layout_plug_layBlocks_SigInv(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, int ind)
Definition: hit_layout.c:307
int hit_layout_plug_layCopy_maxCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:152
HitShape hit_csrShapeMatrix(int n, int m, int nz)
Definition: hit_cshape.c:72
int hit_layout_plug_layBlocksBalance_minCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1146
int numElementsTotal
Definition: hit_layout.h:226
int hit_layout_plug_layCopy_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:80
#define HIT_NOWRAPPED
Definition: hit_layout.h:187
#define hit_bShapeNameList(shape, dim)
Definition: hit_bshape.h:171
HitShape hit_layMaxShape(HitLayout lay)
Definition: hit_layout.c:1623
#define HIT_LAYOUT_BLOCKSX
Definition: hit_layout.h:333
int hit_layout_plug_layWeighted_minCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1459
#define HIT_LAYOUT_BLOCKSL
Definition: hit_layout.h:343
HitTopology hit_layGroupTopo(HitLayout lay, int groupId)
Definition: hit_layout.c:2318
#define hit_calloc(ptr, type, nmemb)
Definition: hit_allocP.h:114
#define HIT_LAYOUT_DIMWEIGHTED
Definition: hit_layout.h:358
#define hit_lgr_groupNProcs(lay, group)
Definition: hit_layout.h:967
void hit_layUnwrapNeighbors(HitLayout *lay)
Definition: hit_layout.c:1607
HitLayout layout[k_num]
Definition: mg.c:150
int hit_layout_plug_layBlocksBalance_numActives(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1164
int hit_layout_plug_layWeighted_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:1340
HitRanks HIT_RANKS_NULL
Definition: hit_topology.c:68
#define hit_sigCard(sig)
Definition: hit_sig.h:162
Definition: hit_sig.h:79
int hit_layout_plug_layMinBlocks_minCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:501
#define hit_ranksCmp(a, b)
Definition: hit_topology.h:220
#define HIT_MAXDIMS
Definition: hit_shape.h:72
#define HIT_LAYOUT_ALLINLEADER
Definition: hit_layout.h:348
#define hit_bShapeData(shape)
Definition: hit_bshape.h:180
#define HIT_LAYOUT_BLOCKS
Definition: hit_layout.h:316
HitGroup HIT_GROUP_NULL
Definition: hit_layout.c:65
#define hit_cShapeCard(shape, dim)
Definition: hit_cshape.h:108
#define hit_sigIn(sig, ind)
Definition: hit_sig.h:186
int HIT_RANK_NULL
Definition: hit_topology.c:67
void hit_layout_list_addGroup(HitLayout *lay, int leader, int np)
Definition: hit_layout.c:2423
HitPTopology * hit_ptopDup(HitPTopology *in)
Definition: hit_topology.c:74
HitPTopology * pTopology[HIT_MAXDIMS+1]
Definition: hit_layout.h:278
int hit_layActiveRanksId(HitLayout lay, HitRanks ranks)
Definition: hit_layout.c:1916
HitShape hit_layDimMaxShape(HitLayout lay, int dim)
Definition: hit_layout.c:1650
int hit_layout_plug_layCyclic_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:905
int cardSuccElements
Definition: hit_layout.h:230
int hit_layout_plug_layBlocksBalance_ranks(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1186
int(* HitLayoutSignatureNumActivesFunction)(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.h:141
int restrictToDim
Definition: hit_layout.h:165
HitRanks self
Definition: hit_topology.h:249
int hit_layout_plug_layWeighted_SigInv(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, int ind)
Definition: hit_layout.c:1385
int nProcs
Definition: SWpar_ref.c:183
#define hit_laySelfRanksDim(lay, dim)
Definition: hit_layout.h:857
HitShape hit_layout_wrapperOtherShape(HitLayout self, HitRanks ranks)
Definition: hit_layout.c:1792
HitLayout hit_layout_plug_layInLeader(HitTopology topo, HitShape shape)
Definition: hit_layout.c:1013
int hit_layout_plug_layMinBlocks_SigInv(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, int ind)
Definition: hit_layout.c:469
#define HIT_GROUP_ID_NULL
Definition: hit_layout.h:408
double ownLoad
Definition: hit_layout.h:291
#define hit_layNumDims(lay)
Definition: hit_layout.h:655
int begin
Definition: hit_sig.h:80
int hit_layout_plug_layBlocksF_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:686
int hit_layNeighborFrom(HitLayout self, int source, int dim, int shift)
Definition: hit_layout.c:1955
#define HIT_LAYOUT_BLOCKSF
Definition: hit_layout.h:338
int cardOwnElements
Definition: hit_layout.h:228
double successorsLoad[HIT_MAXDIMS]
Definition: hit_layout.h:290
MPI_Comm comm
Definition: SWpar_ref.c:193
HitRanks hit_layTransformRanks(char topoActiveMode, HitLayout lay, HitRanks ranks)
Definition: hit_layout.c:1886
int hit_layout_plug_layRegular_maxCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:160
int hit_layout_plug_layBlocksX_Sig(int procId, int procsCard, int blocksCard, HitSig input, HitSig *res)
Definition: hit_layout.c:588
HitSig HIT_SIG_NULL
Definition: hit_sig.c:48
char leader
Definition: hit_layout.h:267
void hit_cShapeBcastInternal(HitShape *shape, HitTopology topo)
Definition: hit_layout.c:2910
#define hit_shapeDims(shape)
Definition: hit_sshape.h:364
HitLayout hit_layout_plug_layBlocksBalance(HitTopology topo, HitShape shape, int dim, float load)
Definition: hit_layout.c:1202
#define hit_cShapeXadj(shape)
#define hit_mpiTestError(ok, cad)
Definition: hit_com.h:62
int hit_layout_plug_layMinBlocks_ranks(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:514
#define HIT_LAYOUT_LIST_CLASS
Definition: hit_layout.h:311
#define hit_cShapeNvertices(shape)
int(* HitLayoutSignatureMinCardFunction)(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.h:130
int * assignedGroups
Definition: hit_layout.h:227
#define HIT_LAYOUT_DIMBLOCKS
Definition: hit_layout.h:321
HitLayoutList HIT_LAYOUTLIST_NULL
Definition: hit_layout.c:68
HitLayout hit_layout_wrapper(HitTopology topo, HitShape shape, HitLayoutSignatureFunction signatureGenericF, HitLayoutSignatureInvFunction signatureInvGenericF, HitLayoutSignatureFunction signatureRestrictedF, HitLayoutSignatureInvFunction signatureInvRestrictedF, HitLayoutRanksFunction ranksGenericF, HitLayoutRanksFunction ranksRestrictedF, HitLayoutSignatureMaxCardFunction maxCardGenericF, HitLayoutSignatureMaxCardFunction maxCardRestrictedF, HitLayoutSignatureMinCardFunction minCardGenericF, HitLayoutSignatureMinCardFunction minCardRestrictedF, HitLayoutSignatureNumActivesFunction activesGenericF, HitLayoutSignatureNumActivesFunction activesRestrictedF, float *extraParameter, int restrictToDim)
Definition: hit_layout.c:2073
int size[2]
Definition: SWcommon.c:57
int end
Definition: hit_sig.h:81
#define hit_cShapeNameList(shape, dim)
Definition: hit_cshape.h:162
HitRanks hit_layActiveIdRanks(HitLayout lay, int id)
Definition: hit_layout.c:1935
HitLayout hit_layout_plug_layBlocks(HitTopology topo, HitShape shape)
Definition: hit_layout.c:326
int hit_layout_plug_layRegular_numActives(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:183
HitLayout hit_layout_plug_laySparseRows(HitTopology topo, HitShape *shape)
Definition: hit_layout.c:2963
int hit_layout_plug_layBlocks_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:273
#define HIT_NOT_USED(x)
Definition: hit_error.h:50
int hit_layout_plug_layRegular_minCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:175
#define hit_cShapeNZElems(shape)
Definition: hit_cshape.h:126
#define HIT_LAY_RANKS_ACTIVE_TO_TOPO
Definition: hit_layout.h:104
void hit_layWrapNeighbors(HitLayout *lay)
Definition: hit_layout.c:1593
void hit_ptopFree(HitPTopology **in)
Definition: hit_topology.c:109
int leader
Definition: hit_layout.h:202
int hit_layout_plug_layRegularF_ranks(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:220
HitLayout hit_layout_plug_layMinBlocks(HitTopology topo, HitShape shape, int minElems)
Definition: hit_layout.c:529
int hit_layout_plug_layAllInOne_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:110
HitShape hit_layDimMinShape(HitLayout lay, int dim)
Definition: hit_layout.c:1704
HitShape hit_bitmapShapeMatrix(int n, int m)
Definition: hit_bshape.c:69
HitShape HIT_SHAPE_NULL
Definition: hit_shape.c:60
#define HIT_TOPOLOGY_PLAIN
Definition: hit_topology.h:261
HitShape shape
#define hit_layImActive(lay)
Definition: hit_layout.h:797
int card[HIT_MAXDIMS]
Definition: hit_topology.h:246
HitLayout hit_layout_plug_layBlocksX(HitTopology topo, HitShape shape)
Definition: hit_layout.c:625
int maxSize[HIT_MAXDIMS]
Definition: hit_layout.h:260
HitLayoutList layoutList
Definition: hit_layout.h:285
int hit_layout_plug_layAllInOne_SigInv(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, int ind)
Definition: hit_layout.c:132
HitLayout hit_layout_plug_layContiguous(HitTopology topo, HitShape elements, const double *weights)
Definition: hit_layout.c:2652
#define hit_bShapeNvertices(shape)
HitPTopology * pTopologyGroup
Definition: hit_layout.h:279
#define HIT_LAYOUT_BLOCKS_BALANCE
Definition: hit_layout.h:369
int hit_layout_plug_layCopy_SigInv(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, int ind)
Definition: hit_layout.c:93
#define HIT_LAYOUT_CONTIGUOUS
Definition: hit_layout.h:381
void hit_layWrapNeighborsDim(HitLayout *lay, int dim)
Definition: hit_layout.c:1602
int hit_topCard(HitTopology topo)
Definition: hit_topology.c:361
int hit_layout_plug_layCyclic_SigInv(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, int ind)
Definition: hit_layout.c:930
HitLayout hit_layout_plug_layBlocksL(HitTopology topo, HitShape shape)
Definition: hit_layout.c:838
int hit_layout_plug_layWeighted_numActives(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1471
HitLayout hit_layout_plug_layDimWeighted(HitTopology topo, HitShape shape, int restrictDim, float *weights)
Definition: hit_layout.c:1484
HitLayoutSig layoutSig
Definition: hit_layout.h:283
#define hit_shapeSigCard(shape, dim)
Definition: hit_sshape.h:412
int hit_layout_plug_layMinBlocks_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:437
#define HIT_LAYOUT_WEIGHTED
Definition: hit_layout.h:353
int hit_layout_plug_layCopy_minCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:167
void hit_layFree(HitLayout lay)
Definition: hit_layout.c:2251
HitShape hit_cShapeSelectRows(HitShape shape, int n, int *names)
Definition: hit_cshape.c:542
#define HIT_SIGLAYOUT_NULL_STATIC
Definition: hit_layout.h:181
HitShape shape
Definition: hit_layout.h:271
int hit_layNeighborFromTopoRank(HitLayout self, int source, int dim, int shift)
Definition: hit_layout.c:1982
int stride
Definition: hit_sig.h:82
#define HIT_LAYOUT_NODIM
Definition: hit_layout.h:173
int numProcs
Definition: hit_layout.h:203
int hit_layout_wrapperShape(int topoNumDims, HitRanks proc, int card[HIT_MAXDIMS], HitShape shape, HitShape *newShape, HitLayoutSignatureFunction sigFunctionGeneric, HitLayoutSignatureFunction sigFunctionRestricted, float *extraParameter, int restrictToDim)
Definition: hit_layout.c:1732
HitLayoutSignatureInvFunction signatureInvGenericF
Definition: hit_layout.h:159
#define HIT_LAYOUTLIST_NULL_STATIC
Definition: hit_layout.h:239
#define HIT_LAYOUT_INDEPENDENTLB
Definition: hit_layout.h:386
union HitLayout::@0 info
#define hit_realloc(ptr, type, nmemb)
Definition: hit_allocP.h:134
int hit_layout_plug_layRegularContiguos_ranks(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:203
HitShape hit_layMinShape(HitLayout lay)
Definition: hit_layout.c:1677
HitLayout hit_layout_plug_layWeighted(HitTopology topo, HitShape shape, float *weights)
Definition: hit_layout.c:1538
#define HIT_LAYOUT_CYCLIC
Definition: hit_layout.h:363
int hit_layout_plug_layAllInOne_numActives(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:191
HitShape origShape
Definition: hit_layout.h:274
#define HIT_LAYOUT_SIG_CLASS
Definition: hit_layout.h:306
int hit_layout_plug_layWeighted_maxCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1447
HitShape hit_layout_wrapperNeighborShape(HitLayout self, int dim, int shift)
Definition: hit_layout.c:1815
int(* HitLayoutSignatureFunction)(int procId, int procsCard, int blocksCard, float *extraParam, HitSig input, HitSig *res)
Definition: hit_layout.h:73
HitLayout hit_layout_plug_layBlocksF(HitTopology topo, HitShape shape)
Definition: hit_layout.c:721
int hit_layNumActives(HitLayout lay)
Definition: hit_layout.c:2213
int hit_layout_plug_layBlocksBalance_Sig(int procId, int procsCard, int blocksCard, float *extraParameter, HitSig input, HitSig *res)
Definition: hit_layout.c:1058
double predecessorsLoad[HIT_MAXDIMS]
Definition: hit_layout.h:289
HitRanks hit_layNeighborRanksFrom(HitLayout self, HitRanks source, int dim, int shift)
Definition: hit_layout.c:2008
int hit_layout_plug_layRegularL_ranks(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:238
HitTopology HIT_TOPOLOGY_NULL
Definition: hit_topology.c:64
int active
Definition: hit_layout.h:263
#define hit_topSelfRankInternal(topo)
Definition: hit_topology.h:439
#define hit_warnInternal(routine, text, extraParam, file, numLine)
Definition: hit_error.h:69
int numActives[HIT_MAXDIMS]
Definition: hit_layout.h:257
HitLayout lay
Definition: heat.c:107
#define hit_shapeSig(shape, dim)
Definition: hit_sshape.h:400
#define hit_layout_class(lay)
Definition: hit_layout.h:398
int(* HitLayoutSignatureMaxCardFunction)(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.h:119
#define hit_min(a, b)
Definition: hit_funcop.h:65
HitTopology hit_layActivesTopology(HitLayout lay)
Definition: hit_layout.c:2372
HitLayoutRanksFunction ranksRestrictedF
Definition: hit_layout.h:163
void hit_shapeFree(HitShape s)
Definition: hit_shape.c:84
#define hit_errInternal(routine, text, extraParam, file, numLine)
Definition: hit_error.h:63
#define hit_layDimNeighbor(lay, dim, shift)
Definition: hit_layout.h:712
HitLayout hit_layout_plug_layDimBlocks(HitTopology topo, HitShape shape, int restrictDim)
Definition: hit_layout.c:382
HitRanks hit_layNeighborRanks(HitLayout self, int dim, int shift)
Definition: hit_layout.c:2039
void hit_bShapeBcastInternal(HitShape *shape, HitTopology topo)
Definition: hit_layout.c:2809
int hit_layout_plug_layWeighted_ranks(char topoActiveMode, int procId, int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1428
HitLayout hit_layout_plug_layBitmap(HitTopology topo, HitShape *shape)
Definition: hit_layout.c:2859
void hit_layUnwrapNeighborsDim(HitLayout *lay, int dim)
Definition: hit_layout.c:1616
int(* HitLayoutSignatureInvFunction)(int procId, int procsCard, int blocksCard, float *extraParam, HitSig input, int ind)
Definition: hit_layout.h:89
HitLayout hit_layout_plug_laySparseBitmapRows(HitTopology topo, HitShape *shapeP)
Definition: hit_layout.c:3015
int hit_lay_procGroup(HitLayout layout, int processor)
Definition: hit_layout.c:2477
int hit_lsig_vfor_index[HIT_MAXDIMS]
Definition: hit_layout.c:59
int hit_layout_plug_layBlocksBalance_maxCard(int procsCard, int blocksCard, float *extraParameter)
Definition: hit_layout.c:1129
void hit_layout_list_initGroups(HitLayout *lay, int numElementsTotal)
Definition: hit_layout.c:2401