FilterScopeVisitor.java

Go to the documentation of this file.
00001 package edu.rice.cs.hpc.data.experiment.scope.visitors;
00002 
00003 import edu.rice.cs.hpc.data.experiment.BaseExperiment;
00004 import edu.rice.cs.hpc.data.experiment.Experiment;
00005 import edu.rice.cs.hpc.data.experiment.metric.BaseMetric;
00006 import edu.rice.cs.hpc.data.experiment.metric.MetricType;
00007 import edu.rice.cs.hpc.data.experiment.metric.MetricValue;
00008 import edu.rice.cs.hpc.data.experiment.scope.CallSiteScope;
00009 import edu.rice.cs.hpc.data.experiment.scope.FileScope;
00010 import edu.rice.cs.hpc.data.experiment.scope.GroupScope;
00011 import edu.rice.cs.hpc.data.experiment.scope.LineScope;
00012 import edu.rice.cs.hpc.data.experiment.scope.LoadModuleScope;
00013 import edu.rice.cs.hpc.data.experiment.scope.LoopScope;
00014 import edu.rice.cs.hpc.data.experiment.scope.ProcedureScope;
00015 import edu.rice.cs.hpc.data.experiment.scope.RootScope;
00016 import edu.rice.cs.hpc.data.experiment.scope.RootScopeType;
00017 import edu.rice.cs.hpc.data.experiment.scope.Scope;
00018 import edu.rice.cs.hpc.data.experiment.scope.ScopeVisitType;
00019 import edu.rice.cs.hpc.data.experiment.scope.StatementRangeScope;
00020 import edu.rice.cs.hpc.data.experiment.scope.TreeNode;
00021 import edu.rice.cs.hpc.data.filter.FilterAttribute;
00022 import edu.rice.cs.hpc.data.filter.IFilterData;
00023 
00024 
00025 /******************************************************************
00026  * 
00027  * Visitor class to filter a CCT tree and generate a new filtered tree
00028  * This class is designed only for CCT, and it definitely doesn't work
00029  * with callers tree and flat tree.<br/>
00030  * <br/>
00031  * To generate a filtered caller tree (or flat tree) one need to 
00032  * create first a filtered CCT and then transform it to callers tree
00033  * (or flat tree) 
00034  *
00035  ******************************************************************/
00036 public class FilterScopeVisitor implements IScopeVisitor 
00037 {
00038     private final IFilterData filter;
00039     private final MetricValue []rootMetricValues;
00040     //private final HashMap<Integer, ScopeToRemove> listScopesToRemove;
00041     private final BaseExperiment experiment;
00042     private BaseMetric []metrics = null;
00043     
00044     /**** flag to allow the dfs to continue to go deeper or not.  
00045           For inclusive filter, we should stop going deeper      *****/
00046     private boolean need_to_continue;
00047     
00048     /***********
00049      * Constructor to filter a cct
00050      * 
00051      * @param rootFilter : the main root for filter tree 
00052      * @param rootOriginalCCT : the original cct tree
00053      * @param filter : filter map to filter a string
00054      */
00055     public FilterScopeVisitor(RootScope rootOriginalCCT, IFilterData filter)
00056     {
00057         this.filter           = filter;
00058         this.rootMetricValues = rootOriginalCCT.getMetricValues();
00059         
00060         need_to_continue = true;
00061         
00062         experiment = rootOriginalCCT.getExperiment();
00063         if (experiment instanceof Experiment)
00064         {
00065             metrics = ((Experiment)experiment).getMetrics();
00066         }
00067         //listScopesToRemove = new HashMap<>();
00068     }
00069     
00070     /**************
00071      * return a flag whether the caller needs to dig deeper to their descendants or not
00072      * 
00073      * @return true if one needs to continue to walk into the descendant, false otherwise.
00074      */
00075     public boolean needToContinue()
00076     {
00077         return need_to_continue;
00078     }
00079     
00080     //----------------------------------------------------
00081     // visitor pattern instantiations for each Scope type
00082     //----------------------------------------------------
00083     public void visit(RootScope scope,              ScopeVisitType vt) { 
00084         if (scope.getType() != RootScopeType.Invisible) 
00085             mergeInsert(scope, vt);
00086     }
00087     public void visit(LoadModuleScope scope,        ScopeVisitType vt) { mergeInsert(scope, vt); }
00088     public void visit(FileScope scope,              ScopeVisitType vt) { mergeInsert(scope, vt); }
00089     public void visit(GroupScope scope,             ScopeVisitType vt) { mergeInsert(scope, vt); }
00090     public void visit(Scope scope,                  ScopeVisitType vt) { mergeInsert(scope, vt); }
00091     public void visit(CallSiteScope scope,          ScopeVisitType vt) { mergeInsert(scope, vt); }
00092     public void visit(ProcedureScope scope,         ScopeVisitType vt) { mergeInsert(scope, vt); }
00093     public void visit(LoopScope scope,              ScopeVisitType vt) { mergeInsert(scope, vt); }
00094     public void visit(StatementRangeScope scope,    ScopeVisitType vt) { mergeInsert(scope, vt); }
00095     public void visit(LineScope scope,              ScopeVisitType vt) { mergeInsert(scope, vt); }
00096 
00097     
00098     private void mergeInsert(Scope scope, ScopeVisitType vt) {
00099         
00100         if (vt == ScopeVisitType.PreVisit) {
00101             // Previsit
00102             Scope parent = scope.getParentScope();
00103             
00104             FilterAttribute filterAttribute = filter.getFilterAttribute(scope.getName());
00105             if (filterAttribute != null)
00106             {
00107                 // the scope needs to be excluded
00108                 need_to_continue = (filterAttribute.filterType == FilterAttribute.Type.Exclusive);
00109                 if (metrics  != null)
00110                 {
00111                     if (scope instanceof LineScope)
00112                     {
00113                         // no need to merge metric if the filtered child is a line statement.
00114                         // in this case, the parent (PF) already includes the exclusive value.
00115                     } else {
00116                         mergeMetrics(parent, scope);
00117                     }
00118                 }
00119                 removeChild(scope, filterAttribute.filterType);
00120                 // mark that we will remove this scope
00121                 // listScopesToRemove.put(scope.getCCTIndex(), new ScopeToRemove(scope, filterAttribute.filterType));
00122             } else 
00123             {
00124                 // filter is not needed, we can surely continue to investigate the descendants
00125                 need_to_continue = true;
00126             }           
00127         } else 
00128         { // PostVisit
00129         }
00130     }
00131     
00132     
00133     private void removeChild(Scope childToRemove, FilterAttribute.Type filterType)
00134     {
00135         Scope parent = childToRemove.getParentScope();
00136         parent.remove(childToRemove);
00137         
00138         if (filterType == FilterAttribute.Type.Exclusive)
00139         {
00140             Object []children = childToRemove.getChildren();
00141             if (children != null)
00142             {
00143                 for(Object child : children)
00144                 {
00145                     parent.add((TreeNode) child);
00146                     ((TreeNode)child).setParent(parent);
00147                 }
00148             }
00149         }
00150     }
00151     /******
00152      * Merging metrics
00153      * X : exclusive metric value
00154      * I : Inclusive metric value
00155      * 
00156      * Exclusive filter
00157      * Xp <- For all filtered i, sum Xi
00158      * Ip <- Ip (no change)
00159      * 
00160      * Inclusive filter
00161      * Xp <- For all filtered i, sum Ii
00162      * Ip <- Ip (no change)
00163      *
00164      * @param parent : the parent scope
00165      * @param child  : the child scope to be excluded  
00166      */
00167     private void mergeMetrics(Scope parent, Scope child)
00168     {
00169         // we need to merge the metric values
00170         MetricValue []values = child.getMetricValues();
00171         for (int i=0; i<metrics.length; i++)
00172         {
00173             if (need_to_continue && metrics[i].getMetricType() == MetricType.EXCLUSIVE)
00174             {
00175                 MetricValue value = parent.getMetricValue(i).duplicate();
00176                 parent.setMetricValue(i, value);
00177                 
00178                 // exclusive filter: merge the exclusive metrics to the parent's exclusive
00179                 mergeMetricToParent(parent, i, values[i]);
00180                 
00181             } else if (!need_to_continue && metrics[i].getMetricType() == MetricType.INCLUSIVE)
00182             {
00183                 // inclusive filter: merge the inclusive metrics to the parent's exclusive
00184                 int index_exclusive_metric = metrics[i].getPartner();
00185 
00186                 // this is tricky: the original index of the metric is the same as the short name
00187                 // however, when we ask getMetric(), it requires the metric index in the array (which is 0..n)
00188                 // we can cheat this by converting the index into "short name" and get the metric.
00189                 BaseMetric metric_exc = ((Experiment)experiment).getMetric(String.valueOf(index_exclusive_metric));
00190                 mergeMetricToParent(parent, metric_exc.getIndex(), values[i]);
00191             }
00192         }
00193     }
00194     
00195     /*******
00196      * merge a metric value to the parent 
00197      *
00198      * @param root
00199      * @param target
00200      * @param metric_exclusive_index
00201      * @param mvChild
00202      */
00203     private void mergeMetricToParent(Scope target, 
00204             int metric_exclusive_index, MetricValue mvChild)
00205     {
00206         MetricValue mvParentExc = target.getMetricValue(metric_exclusive_index);
00207         float value = 0;
00208         if (mvParentExc.getValue() >= 0) {
00209             // Initialize with the original value if it has a value (otherwise the value is -1)
00210             value = mvParentExc.getValue();
00211         }
00212         // update the filtered value
00213         value             += mvChild.getValue();
00214         float rootValue   = rootMetricValues[metric_exclusive_index].getValue();
00215         float annotation  = value / rootValue;
00216         
00217         MetricValue mv    = new MetricValue(value, annotation);
00218         target.setMetricValue(metric_exclusive_index, mv);
00219     }
00220 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1