Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Adding new functionalities.
[mapping.git] / src / and / Mapping / FT_AIAC_QM.java
1 package and.Mapping ;
2
3
4 import java.io.Serializable;
5 import java.util.ArrayList;
6 import java.util.Random;
7
8
9 /**
10  * Implementation of the Fault Tolerant AIAC Quick Quality Map (FT-AIAC-QM) algorithm
11  * @author Sébastien Miquée
12  * @version 1.0
13  */
14 public class FT_AIAC_QM extends Algo
15 {
16         private static final long serialVersionUID = 1L;
17         
18         
19         private ArrayList<GTask2> atraiter ;
20         private ArrayList<GNode> archi ;
21         private double f ; // search factor
22         
23         
24         /**
25          * Default constructor.
26          */
27         public FT_AIAC_QM()
28         {
29                 super() ;
30                 name = "AIAC-QM" ;
31         }
32         
33
34         /**
35          * Constructor
36          * @param _gr Application graph to be mapped on
37          * @param _gd Grid graph
38          * @param _f Search factor
39          */
40         public FT_AIAC_QM( Graph _gr, Grid _gd, double _f )
41         {
42                 super( _gr, _gd ) ;
43                 
44                 f = _f ;
45                 name = "AIAC-QM" ;
46         }
47         
48         /**
49          * 
50          * @return
51          */
52         private ArrayList<GNode> sortInitGNode() 
53         {
54                 ArrayList<GNode> grn = null ;
55                 
56                 if( gl != null )
57                 {
58                         grn = new ArrayList<GNode>() ;
59                         
60                         ArrayList<GNode> tmp = gl.getGNodes() ;
61         
62                         grn.add( tmp.get( 0 ) ) ;
63                         
64                         boolean ok ;
65                 
66                         for( int i = 1 ; i < tmp.size() ; i++ )
67                         {
68                                 ok = false ;
69                                 
70                                 for( int j = 0 ; j < grn.size() ; j++ )
71                                 {
72                                         if( tmp.get( i ).getPower() > grn.get( j ).getPower() )
73                                         {
74                                                 grn.add( j, tmp.get( i ) ) ;
75                                                 ok = true ;
76                                                 break ;
77                                         }
78                                 }
79                                 
80                                 if( ok == false )
81                                 {
82                                         grn.add( tmp.get( i ) ) ;
83                                 }
84                         }
85                 }
86
87                 return grn ;
88         }
89
90
91         private ArrayList<GTask2> listToGTask2( Graph _gr ) 
92         {
93                 ArrayList<GTask2> gr2 = null ;
94                 
95                 if( _gr != null )
96                 {
97                         gr2 = new ArrayList<GTask2>() ;
98                 
99                         for( int i = 0 ; i < _gr.getNbGTask() ; i++ )
100                         {
101                                 gr2.add( new GTask2( _gr.getGraph().get( i ) ) ) ;
102                         }
103                 }
104                 
105                 return gr2 ;
106         }
107
108
109         @Override
110         public void map() 
111         {
112                 /* If the mapping is possible ... */
113                 if( gr.getNbGTask() <= gl.getNbGNode() )
114                 {
115                         atraiter = listToGTask2( gr ) ;
116                         archi = sortInitGNode() ;
117                         
118                         /** Local Variables **/
119                         GNode nc = null ;
120                         double yc = -1 ;
121                         GNode nb = null ;
122                         double yb = -1 ;
123                         GNode nr = null ;
124                         double yr = -1 ;
125                         double ynb = -1 ;
126
127                         
128                         System.out.println( "**********************************************" ) ;
129                         System.out.println( "* Launching the FT-AIAC-QM Mapping algorithm *" ) ;
130                         System.out.println( "**********************************************\n\n" ) ;
131                         
132                         /** Initial values **/
133                         int r = 1 ; // Number of rounds
134                         int n = gr.getNbGTask() ; // Number of tasks
135                         
136                         /** Initial mapping **/
137                         initMapping() ;
138                         
139                         /** Main loop **/
140                         while( isOneMoveable() )
141                         {
142                                 for( int ti = 0 ; ti < atraiter.size() ; ti++ )
143                                 {
144                                         if( atraiter.get( ti ).isMoveable() )
145                                         {
146                                                 nc = atraiter.get( ti ).getMapedOn() ;
147                                                 yc = atraiter.get( ti ).getExecTime() ;
148                                                 nb = nc ;
149                                                 yb = yc ;
150                                                 
151                                                 /** Search a node to map on **/
152                                                 for( int k = 0 ; k < ( f * n / r ) ; k++ )
153                                                 {
154                                                         nr = selectRandomGNode( n, r ) ;
155                                                         yr = execTimeOn( atraiter.get( ti ).clone(), nr ) ;
156                                                         
157                                                         if( yr < yb )
158                                                         {
159                                                                 nb = nr ;
160                                                                 yb = yr ;
161                                                         }
162                                                 }
163                                                 
164                                                 /** Research of the neighbours' nodes **/
165                                                 ArrayList<GNode> neighbours = researchNeighbours( atraiter.get( ti ), 1 ) ;
166                                                 
167                                                 for( int ni = 0 ; ni < neighbours.size() ; ni++ )
168                                                 {
169                                                         ynb = execTimeOn( atraiter.get( ti ).clone(), neighbours.get( ni ) ) ;
170                                                 
171                                                         if( ynb < yb )
172                                                         {
173                                                                 nb = neighbours.get( ni ) ;
174                                                                 yb = ynb ;
175                                                         }
176                                                 }
177                                                 
178                                                 
179                                                 /** Mapping of the task **/
180                                                 if( ! nb.equals( nc ) )
181                                                 {
182                                                         GTask2 t_ = taskOn( nb ) ;
183                                                         if( t_ != null && t_.isMoveable() )
184                                                         {
185                                                                 t_.setGNode( null ) ;
186                                                         } 
187                                                         
188                                                         atraiter.get( ti ).setGNode( nb ) ;
189                                                         
190                                                         updateExecTimeNeighbours( atraiter.get( ti ) ) ;
191                                                 }
192                                         }
193                                         
194                                         /** The task is fixed on this node **/
195                                         atraiter.get( ti ).setMoveable( false ) ;
196                                         
197                                         /** If all tasks have been considered **/
198                                         if( ti == atraiter.size() - 1 )
199                                         {
200                                                 r++ ;
201                                         }
202                                 }
203                         }
204                         
205                         /** Save the Mapping **/
206                         for( int i = 0 ; i < atraiter.size() ; i++ )
207                         {
208                                 mp.addMapping( new Association( atraiter.get( i ).getMapedOn(), atraiter.get( i ).getGTask() ) ) ;
209                         }
210                 
211                 } else {
212                         System.err.println( "\n\n!!! Unable to map application !\n\n" ) ;
213                 }
214         }
215         
216         /**
217          * 
218          * @param _nb
219          * @return
220          */
221         private GTask2 taskOn( GNode _nb ) 
222         {
223                 for( int i = 0 ; i < atraiter.size() ; i++ )
224                 {
225                         if( atraiter.get( i ).getMapedOn().equals( _nb ) )
226                         {
227                                 return atraiter.get( i ) ;
228                         }
229                 }
230                 
231                 return null;
232         }
233
234         /**
235          * 
236          * @param _g
237          * @param _deep
238          * @return
239          */
240         private ArrayList<GNode> researchNeighbours( GTask2 _g, double _deep) 
241         {
242                 ArrayList<GNode> nb = new ArrayList<GNode>() ;
243                 ArrayList<GTask2> neighbours = new ArrayList<GTask2>() ;
244                 
245                 for( int i = 0 ; i < _g.getGTask().getNbDep() ; i++ )
246                 {
247                         neighbours.add( atraiter.get( _g.getGTask().getDependencies().get( i ).getNum() ) ) ;
248                 }
249                 
250                 for( int i = 0 ; i < archi.size() ; i++ )
251                 {
252                         for( int j = 0 ; j < neighbours.size() ; j++ )
253                         {
254                                 GNode tmp = neighbours.get( j ).getMapedOn() ;
255                         
256                                 if( gl.getDistance( tmp, archi.get( i ) ) <= _deep && ! nb.contains( tmp ) )
257                                 {
258                                         nb.add( tmp ) ;
259                                 }
260                         }
261                 }
262                 
263                 return nb ;
264         }
265
266
267         /**
268          * Initialization of the mapping. Each task is mapped on computing
269          * nodes in order of their rank.
270          */
271         private void initMapping() 
272         {
273                 for( int i = 0 ; i < atraiter.size() ; i++ )
274                 {
275                         atraiter.get( i ).setGNode( archi.get( i ) ) ;
276                 }
277         }
278
279
280         /**
281          * 
282          * @param _g
283          * @param _n
284          * @return
285          */
286         private double execTimeOn( GTask2 _g, GNode _n ) 
287         {               
288                 _g.setGNode( _n ) ;
289                         
290                 return calcExecTime( _g ) ;
291         }
292
293         /**
294          * 
295          * @param _n
296          * @param _r
297          * @return
298          */
299         private GNode selectRandomGNode( int _n, int _r ) 
300         {
301                 GNode g = null ;
302                 
303                 Random rand = new Random() ;
304                 
305                 g = archi.get( rand.nextInt( _n / _r ) ) ;
306                 
307                 while( isTaskNotMoveableOn( g ) )
308                 {
309                         g = archi.get( rand.nextInt( _n / _r ) ) ;
310                 }
311                 
312                 return g ;
313         }
314
315
316         /**
317          * 
318          * @param _g
319          * @return
320          */
321         private boolean isTaskNotMoveableOn( GNode _g ) 
322         {
323                 for( int i = 0 ; i < atraiter.size() ; i++ )
324                 {
325                         if( atraiter.get( i ).getMapedOn().equals( _g ) && ! atraiter.get( i ).isMoveable() )
326                         {
327                                 return true ;
328                         }
329                 }
330         
331                 return false ;
332         }
333
334
335         /**
336          * 
337          * @return
338          */
339         private boolean isOneMoveable() 
340         {
341                 if( atraiter != null && atraiter.size() > 0 )
342                 {
343                         for( int i = 0 ; i < atraiter.size() ; i++ )
344                         {
345                                 if( atraiter.get( i ).isMoveable() )
346                                 {
347                                         return true ;
348                                 }
349                         }
350                 }
351                 
352                 return false ;
353         }
354         
355         
356         /**
357          * 
358          * @param _g
359          * @return
360          */
361         private double calcExecTime( GTask2 _g )
362         {
363                 double w = -1 ;
364                 
365                 if( _g != null )
366                 {       
367                         // Weight of computation
368                         w = ( _g.getGTask().getWeight() / _g.mappedOn.getPower() ) ;
369                         
370                         // Weight of communications
371                         int tab[] = new int[ _g.getGTask().getNbDep() ] ;
372                         for( int i = 0 ; i < _g.getGTask().getNbDep() ; i++ )
373                         {
374                                 tab[ i ] = _g.getGTask().getDependencies().get( i ).getNum() ;
375                         }
376                         
377                         for( int i = 0 ; i < tab.length ; i++ )
378                         {
379                                 double tmp = gl.getDistance( _g.getMapedOn(), atraiter.get( tab[i] ).getMapedOn() ) ;
380                                 
381                                 if( tmp >= 0 )
382                                 {
383                                         w += tmp ;
384                                 }               
385                         }
386                 }
387                 
388                 return w ;
389         }
390
391
392         /**
393          * 
394          * @param _g
395          */
396         private void updateExecTime( GTask2 _g )
397         {
398                 double w = calcExecTime( _g ) ;
399                 
400                 if( w >= 0 )
401                 {
402                         if( w > _g.getExecTime() )
403                         {
404                                 _g.setMoveable( true ) ;
405                         }
406                         
407                         _g.setExecTime( w ) ;
408                 }
409         }
410         
411         
412         /**
413          * 
414          * @param _g
415          */
416         private void updateExecTimeNeighbours( GTask2 _g )
417         {
418                 int tab[] = new int[ _g.getGTask().getNbDep() ] ;
419                 for( int i = 0 ; i < _g.getGTask().getNbDep() ; i++ )
420                 {
421                         tab[ i ] = _g.getGTask().getDependencies().get( i ).getNum() ;
422                 }
423                 
424                 for( int i = 0 ; i < tab.length ; i++ )
425                 {
426                         updateExecTime( atraiter.get( tab[i] ) ) ;                      
427                 }
428         }
429         
430         
431         
432         /** Intern class **/
433         /**
434          * Temporary class.
435          */
436         private class GTask2 implements Serializable
437         {
438                 private static final long serialVersionUID = 1L;
439                 
440                 private GTask g ;
441                 private boolean moveable ;
442                 private double execTime ;
443                 private GNode mappedOn ;
444                 
445                 public GTask2()
446                 {
447                         g = null ;
448                         moveable = false ;
449                         execTime = -1 ;
450                         mappedOn = null ;
451                 }
452                 
453                 public GTask2( GTask _g )
454                 {
455                         g = _g ;
456                         moveable = false ;
457                         execTime = -1 ;
458                         mappedOn = null ;
459                 }
460                 
461                 public boolean isMoveable()
462                 {
463                         return moveable ;
464                 }
465                 
466                 public void setMoveable( boolean b )
467                 {
468                         moveable = b ;
469                 }
470                 
471                 public void setGNode( GNode _g )
472                 {
473                         mappedOn = _g ;
474                 }
475                 
476                 
477                 public GTask getGTask()
478                 {
479                         return g ;
480                 }
481                 
482                 
483                 public double getExecTime()
484                 {
485                         return execTime ;
486                 }
487                 
488                 
489                 public void setExecTime( double _d )
490                 {
491                         execTime = _d ;
492                 }
493                 
494                 public GNode getMapedOn()
495                 {
496                         return mappedOn ;
497                 }
498                 
499                 
500                 public GTask2 clone()
501                 {
502                         GTask2 g_new = new GTask2() ;
503                         g_new.execTime = this.execTime ;
504                         g_new.g = this.g ;
505                         g_new.mappedOn = this.mappedOn ;
506                         g_new.moveable = this.moveable ;
507                         
508                         return g_new ;
509                 }
510         }
511
512
513
514         @Override
515         public GNode replaceNode( GNode _dead, ArrayList<GNode> _ag ) 
516         {
517                 GNode ret = null ;
518                 
519                 /** If something has to be done **/
520                 if( _dead != null )
521                 {
522                         ArrayList<GNode> ac = new ArrayList<GNode>() ;
523                         GNode tmp = null ;
524                 
525                         /** Searching if clusters have some free nodes **/
526                         for( int i = 0 ; i < gl.getNbCluster() ; i++ )
527                         {
528                                 if( gl.getClusters().get( i ).getNbFreeNodes() > 0 )
529                                 {
530                                         tmp = gl.getClusters().get( i ).nextGNode() ;
531                                         
532                                         if( tmp != null )
533                                         {
534                                                 ac.add( tmp ) ;
535                                         }
536                                 }
537                         }
538                         
539                         /** If there some nodes in clusters **/
540                         if( ac.size() > 0 )
541                         {
542                                 double power = -1, best = -1 ;
543                                 int bestNode = -1 ;
544                                 
545                                 /** Searching the replacing node with the higher 
546                                  * computing power
547                                  */
548                                 for( int i = 0 ; i < ac.size() ; i++ )
549                                 {
550                                         power = ac.get( i ).getPower() ;
551                                         
552                                         if( best == -1 )
553                                         {
554                                                 best = power ;
555                                                 bestNode = i ;
556                                         } else {
557                                                 if( power > best )
558                                                 {
559                                                         best = power ;
560                                                         bestNode = i ;
561                                                 }
562                                         }
563                                 }
564                                 
565                                 /** Is there any node candidate ? **/
566                                 if( bestNode != -1 )
567                                 {
568                                         ret = ac.get( bestNode ) ;
569                                 }
570                         }               
571                         
572                         nb_fault++ ;
573                 }
574                 
575                 return ret ;
576         }
577
578
579         @Override
580         public GNode getOtherGNode( ArrayList<GNode> _ag ) 
581         {
582                 GNode ret = null ;
583                 
584                 int free[] = new int[ gl.getNbCluster() ] ;
585                 
586                 /** Searching if clusters have some free nodes **/
587                 for( int i = 0 ; i < gl.getNbCluster() ; i++ )
588                 {
589                         free[ i ] = gl.getClusters().get( i ).getNbFreeNodes() ;
590                 }
591                 
592                 /** Returning a node from the cluster which has the most
593                  * available nodes
594                  */
595                 int most = -1, max = 0 ;
596                 
597                 for( int i = 0 ; i < free.length ; i++ )
598                 {
599                         if( free[ i ] > max )
600                         {
601                                 max = free[ i ] ;
602                                 most = i ;
603                         }
604                 }
605                 
606                 /** Is there any cluster candidate ? **/
607                 if( most != -1 )
608                 {
609                         ret = gl.getClusters().get( most ).nextGNode() ;
610                 }
611                 
612                 
613                 return ret ;
614         }
615
616
617         @Override
618         public boolean setParams(Object[] _params) {
619                 return true ;
620         }
621 }
622
623
624
625 /** La programmation est un art, respectons ceux qui la pratiquent !! **/