00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #ifndef _H_SST_CORE_HISTOGRAM_STATISTIC_
00014 #define _H_SST_CORE_HISTOGRAM_STATISTIC_
00015 
00016 #include <sst/core/sst_types.h>
00017 #include <sst/core/serialization.h>
00018 
00019 #include <sst/core/statapi/statbase.h>
00020 
00021 namespace SST {
00022 namespace Statistics {
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 #define CountType   uint64_t
00039 #define NumBinsType uint32_t
00040 
00041 template<class BinDataType>
00042 class HistogramStatistic : public Statistic<BinDataType> 
00043 {
00044 private:
00045     friend class SST::Simulation;
00046     
00047     HistogramStatistic(Component* comp, std::string& statName, std::string& statSubId, Params& statParams)
00048                 : Statistic<BinDataType>(comp, statName, statSubId, statParams)
00049     {
00050         
00051         Params::KeySet_t allowedKeySet;
00052         allowedKeySet.insert("minvalue");
00053         allowedKeySet.insert("binwidth");
00054         allowedKeySet.insert("numbins");
00055         allowedKeySet.insert("dumpbinsonoutput");
00056         allowedKeySet.insert("includeoutofbounds");
00057         statParams.pushAllowedKeys(allowedKeySet);
00058         
00059         
00060         m_minValue = statParams.find_integer("minvalue", 0);
00061         m_binWidth = statParams.find_integer("binwidth", 5000);
00062         m_numBins = statParams.find_integer("numbins", 100);
00063         m_dumpBinsOnOutput = statParams.find_integer("dumpbinsonoutput", 1);
00064         m_includeOutOfBounds = statParams.find_integer("includeoutofbounds", 1);
00065         
00066         
00067         m_totalSummed = 0;
00068         m_totalSummedSqr = 0;
00069         m_OOBMinCount = 0;
00070         m_OOBMaxCount = 0;
00071         m_itemsBinnedCount = 0;
00072         this->setCollectionCount(0);
00073 
00074         
00075         this->setStatisticTypeName("Histogram");
00076     }
00077 
00078     ~HistogramStatistic() {}
00079 
00080 protected:    
00081 
00082 
00083 
00084 
00085     void addData_impl(BinDataType value) 
00086     {
00087         
00088         if (value < getBinsMinValue()) {   
00089             m_OOBMinCount++;
00090             return; 
00091         }
00092         if (value > getBinsMaxValue()) {
00093             m_OOBMaxCount++;
00094             return; 
00095         } 
00096 
00097         
00098         
00099         m_totalSummed += value;
00100         m_totalSummedSqr += (value * value);
00101         
00102         
00103         m_itemsBinnedCount++;
00104         
00105         
00106         
00107         
00108         
00109         double calc1 = (double)value / (double)m_binWidth;  
00110         double calc2 = floor(calc1);             
00111         double calc3 = m_binWidth * calc2;
00112         BinDataType  bin_start = (BinDataType)calc3;
00113 
00114 
00115         HistoMapItr_t bin_itr = m_binsMap.find(bin_start);
00116         
00117         
00118         if(bin_itr == m_binsMap.end()) {
00119             
00120             m_binsMap.insert(std::pair<BinDataType, CountType>(bin_start, (CountType) 1));
00121         } else {
00122             
00123             bin_itr->second++;
00124         }
00125     }
00126 
00127 private:    
00128 
00129     NumBinsType getActiveBinCount() 
00130     {
00131         return m_binsMap.size();
00132     }
00133 
00134 
00135     NumBinsType getNumBins() 
00136     {
00137         return m_numBins;
00138     }
00139 
00140 
00141     NumBinsType getBinWidth() 
00142     {
00143         return m_binWidth;
00144     }
00145 
00146 
00147 
00148 
00149 
00150     CountType getBinCountByBinStart(BinDataType binStartValue) 
00151     {
00152         
00153         HistoMapItr_t bin_itr = m_binsMap.find(binStartValue);
00154 
00155         
00156         if(bin_itr == m_binsMap.end()) {
00157             
00158             return (CountType) 0;
00159         } else {
00160             
00161             return m_binsMap[binStartValue];
00162         }
00163     }
00164 
00165 
00166 
00167 
00168     BinDataType getBinsMinValue() 
00169     {
00170         return m_minValue;
00171     }
00172 
00173 
00174 
00175 
00176     BinDataType getBinsMaxValue() 
00177     {
00178         
00179         return (m_binWidth * m_numBins) + m_minValue - 1;
00180     }
00181 
00182 
00183 
00184 
00185 
00186     uint64_t getStatCollectionCount() 
00187     {
00188         
00189         return this->getCollectionCount();
00190     }
00191 
00192 
00193 
00194 
00195 
00196     CountType getItemsBinnedCount() 
00197     {
00198         
00199         return m_itemsBinnedCount;
00200     }
00201 
00202 
00203 
00204 
00205 
00206     BinDataType getValuesSummed() 
00207     {
00208         return m_totalSummed;
00209     }
00210 
00211 
00212 
00213 
00214 
00215     BinDataType getValuesSquaredSummed() {
00216         return m_totalSummedSqr;
00217     }
00218 
00219     void clearStatisticData()
00220     {
00221         m_totalSummed = 0;
00222         m_totalSummedSqr = 0;
00223         m_OOBMinCount = 0;
00224         m_OOBMaxCount = 0;
00225         m_itemsBinnedCount = 0;
00226         m_binsMap.clear();
00227         this->setCollectionCount(0);
00228     }
00229     
00230     void registerOutputFields(StatisticOutput* statOutput)
00231     {
00232         
00233         m_Fields.push_back(statOutput->registerField<BinDataType>("BinsMinValue"));
00234         m_Fields.push_back(statOutput->registerField<BinDataType>("BinsMaxValue"));  
00235         m_Fields.push_back(statOutput->registerField<NumBinsType>("BinWidth"));  
00236         m_Fields.push_back(statOutput->registerField<NumBinsType>("TotalNumBins"));  
00237         m_Fields.push_back(statOutput->registerField<BinDataType>("Sum"));
00238         m_Fields.push_back(statOutput->registerField<BinDataType>("SumSQ"));
00239         m_Fields.push_back(statOutput->registerField<NumBinsType>("NumActiveBins"));  
00240         m_Fields.push_back(statOutput->registerField<CountType>  ("NumItemsCollected"));
00241         m_Fields.push_back(statOutput->registerField<CountType>  ("NumItemsBinned"));
00242 
00243         if (true == m_includeOutOfBounds) {
00244                 m_Fields.push_back(statOutput->registerField<CountType>("NumOutOfBounds-MinValue"));
00245                 m_Fields.push_back(statOutput->registerField<CountType>("NumOutOfBounds-MaxValue"));
00246         }
00247 
00248         
00249         if (true == m_dumpBinsOnOutput) {
00250             BinDataType binLL;
00251             BinDataType binUL;
00252             
00253             for (uint32_t y = 0; y < getNumBins(); y++) {
00254                 
00255                 binLL = (y * getBinWidth()) + getBinsMinValue();
00256                 binUL = binLL + getBinWidth() - 1;
00257                 
00258                 std::stringstream ss;
00259                 ss << "Bin" << y << ":" << binLL << "-" << binUL;
00260                 m_Fields.push_back(statOutput->registerField<CountType>(ss.str().c_str()));
00261             }
00262         }
00263     }
00264 
00265     void outputStatisticData(StatisticOutput* statOutput, bool EndOfSimFlag)
00266     {
00267         uint32_t x = 0;
00268         statOutput->outputField(m_Fields[x++], getBinsMinValue());
00269         statOutput->outputField(m_Fields[x++], getBinsMaxValue());
00270         statOutput->outputField(m_Fields[x++], getBinWidth());
00271         statOutput->outputField(m_Fields[x++], getNumBins());
00272         statOutput->outputField(m_Fields[x++], getValuesSummed());
00273         statOutput->outputField(m_Fields[x++], getValuesSquaredSummed());
00274         statOutput->outputField(m_Fields[x++], getActiveBinCount());
00275         statOutput->outputField(m_Fields[x++], getStatCollectionCount());
00276         statOutput->outputField(m_Fields[x++], getItemsBinnedCount());
00277         
00278         if (true == m_includeOutOfBounds) {
00279             statOutput->outputField(m_Fields[x++], m_OOBMinCount);
00280             statOutput->outputField(m_Fields[x++], m_OOBMaxCount);
00281         }
00282 
00283         
00284         if (true == m_dumpBinsOnOutput) {
00285             BinDataType currentBinValue = getBinsMinValue();
00286             for (uint32_t y = 0; y < getNumBins(); y++) {
00287                 statOutput->outputField(m_Fields[x++], getBinCountByBinStart(currentBinValue));
00288                 
00289                 currentBinValue += getBinWidth();
00290             }
00291         }
00292     }
00293 
00294     bool isStatModeSupported(StatisticBase::StatMode_t mode) const 
00295     {
00296         if (mode == StatisticBase::STAT_MODE_COUNT) {
00297             return true;
00298         }
00299         if (mode == StatisticBase::STAT_MODE_PERIODIC) {
00300             return true;
00301         }
00302         return false;
00303     }
00304     
00305 private:
00306     
00307     typedef std::map<BinDataType, CountType> HistoMap_t;
00308 
00309     
00310     typedef typename HistoMap_t::iterator HistoMapItr_t;
00311 
00312     
00313     BinDataType m_minValue;
00314 
00315     
00316     NumBinsType m_binWidth;
00317     
00318     
00319     NumBinsType m_numBins;
00320 
00321     
00322     CountType m_OOBMinCount;
00323     CountType m_OOBMaxCount;
00324 
00325     
00326     
00327     CountType m_itemsBinnedCount;
00328 
00329     
00330     
00331     BinDataType m_totalSummed;
00332 
00333     
00334         
00335     BinDataType m_totalSummedSqr;
00336 
00337     
00338     HistoMap_t m_binsMap;
00339     
00340     
00341     std::vector<uint32_t> m_Fields;
00342     bool                  m_dumpBinsOnOutput;
00343     bool                  m_includeOutOfBounds;
00344 
00345     friend class boost::serialization::access;
00346     template<class Archive>
00347     void serialize(Archive & ar, const unsigned int version)
00348     {
00349         ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Statistic<BinDataType>);
00350         ar & BOOST_SERIALIZATION_NVP(m_minValue);
00351         ar & BOOST_SERIALIZATION_NVP(m_binWidth); 
00352         ar & BOOST_SERIALIZATION_NVP(m_numBins); 
00353         ar & BOOST_SERIALIZATION_NVP(m_OOBMinCount); 
00354         ar & BOOST_SERIALIZATION_NVP(m_OOBMaxCount); 
00355         ar & BOOST_SERIALIZATION_NVP(m_itemsBinnedCount); 
00356         ar & BOOST_SERIALIZATION_NVP(m_totalSummed);
00357         ar & BOOST_SERIALIZATION_NVP(m_totalSummedSqr);
00358         ar & BOOST_SERIALIZATION_NVP(m_binsMap);
00359         ar & BOOST_SERIALIZATION_NVP(m_Fields);
00360         ar & BOOST_SERIALIZATION_NVP(m_dumpBinsOnOutput);
00361         ar & BOOST_SERIALIZATION_NVP(m_includeOutOfBounds);
00362     }
00363 };
00364 
00365 } 
00366 } 
00367 
00368 
00369 
00370 #endif