00001 // Copyright 2009-2015 Sandia Corporation. Under the terms 00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 00003 // Government retains certain rights in this software. 00004 // 00005 // Copyright (c) 2009-2015, Sandia Corporation 00006 // All rights reserved. 00007 // 00008 // This file is part of the SST software package. For license 00009 // information, see the LICENSE file in the top level directory of the 00010 // distribution. 00011 00012 #ifndef SST_CORE_INTROSPECTOR_H 00013 #define SST_CORE_INTROSPECTOR_H 00014 00015 #include <sst/core/serialization.h> 00016 00017 #include "sst/core/clock.h" 00018 #include "sst/core/introspectedComponent.h" 00019 //#include "sst/core/simulation.h" 00020 //#include "sst/core/timeConverter.h" 00021 00022 namespace SST { 00023 00024 #if DBG_INTROSPECTOR 00025 #define _INTROSPECTOR_DBG( fmt, args...) \ 00026 printf( "%d:Introspector::%s():%d: " fmt, _debug_rank, __FUNCTION__,__LINE__, ## args ) 00027 #else 00028 #define _INTROSPECTOR_DBG( fmt, args...) 00029 #endif 00030 00031 00032 /** 00033 * Main introspector object for the simulation. 00034 * All models inherit from this. 00035 * Introspection interface is a unified way to gather statistics and arbitrary data from components. 00036 */ 00037 00038 class Introspector { 00039 public: 00040 00041 /** Types of boost MPI collective operations that introspector can perform.*/ 00042 enum collect_type { GATHER, ALLGATHER, BROADCAST, REDUCE, ALLREDUCE}; 00043 /** Types of funciton objects for the reduce collective.*/ 00044 enum mpi_operation { 00045 MINIMUM, 00046 MAXIMUM, 00047 SUM, 00048 NOT_APPLICABLE 00049 }; 00050 00051 /** Constructor. Generally only called by the factory class. 00052 @param id Unique introspector ID*/ 00053 Introspector(); 00054 virtual ~Introspector() {} 00055 00056 /** Called after all components/introspectors have been constructed, but before 00057 simulation time has begun. */ 00058 virtual void setup( ) { } 00059 /** Called after simulation completes, but before objects are 00060 destroyed. A good place to print out statistics. */ 00061 virtual void finish( ) { } 00062 00063 /** Get component of a certain type indicated by CompName on this rank. 00064 Name is unique so the fuction actually returns a list with only one component. 00065 This function is usually used in Introspector::setup(). 00066 @param CompName Component's name*/ 00067 std::list<IntrospectedComponent*> getModelsByName(const std::string CompName); 00068 /** Get component of a certain type indicated by CompType on this rank. 00069 If CompType is blank, a list of all local components is returned. 00070 This function is usually used in Introspector::setup(). 00071 @param CompType Component's type*/ 00072 std::list<IntrospectedComponent*> getModelsByType(const std::string CompType); 00073 00074 /** Query the components indicated by "c" to retrieve components' statistics & data. 00075 Return the value of the data indicated by "dataname". 00076 The function is usually called by introspector-pull mechanism in Introspector::triggeredUpdate(). 00077 @param c Pointer to the component 00078 @param dataname Name of the data */ 00079 template <typename typeT> 00080 typeT getData(IntrospectedComponent* c, std::string dataname); 00081 /** Introspector-writers will implement their own triggeredUpdate function. 00082 This function calls Introspector::getData() to retrieve components' data, 00083 and is a good place to manipulate the data 00084 (print to screen, MPI collective communication, etc). */ 00085 virtual bool triggeredUpdate() { return false; } 00086 00087 00088 /** Introspectors communicate among themselves with Boost MPI to exchange their integer data, invalue. 00089 This function initiates a specific type of collective communicaiton indicated by ctype. The data 00090 are operated based on ctype and on the MPI operation, op. An introspector type can have periodic 00091 collective communication by calling this function in a member function registered with an event handler that is 00092 triggered by a clock. 00093 @param ctype Types of collective communication. Currently supported options are Broadcast, (all)gather, 00094 and (all)reduce 00095 @param invalue The local value to be communicated 00096 @param op Types of the MPI operations for the (all)reduce algorithm to combine the values. Currently 00097 supported options are summarize, minimum and maximum. Default is set to none 00098 @param rank The rank where the introspector resides. Default is set to 0. If ctype is broadcast, 00099 rank here indicates the rank that will transmitting the value*/ 00100 void collectInt(collect_type ctype, uint64_t invalue, mpi_operation op=NOT_APPLICABLE, int rank=0); 00101 /** One time introspectors collective communication. The event handling functors that calls a given member 00102 communication function is inserted into the queue and will be triggered at time specified by, time. 00103 The introspector-write implements their own communication function if they want something other than 00104 the basic collective operations, broadcast, (all)reduce and (all)gather. 00105 @param time The simulation time when the introspectors will communicate among themselves 00106 @param functor Event handling functor that invokes member communication function*/ 00107 void oneTimeCollect(SimTime_t time, Event::HandlerBase* functor); 00108 00109 00110 /** List of components that this introspector is monitoring.*/ 00111 std::list<IntrospectedComponent*> MyCompList; 00112 /** Minimum value of the integer values collected from all introspectors by Introspector::collectInt().*/ 00113 uint64_t minvalue; 00114 /** Maximum value of the integer values collected from all introspectors by Introspector::collectInt().*/ 00115 uint64_t maxvalue; 00116 /** Result value of the reduction operation in Introspector::collectInt().*/ 00117 uint64_t value; 00118 /** Data vector that holds data collected from all introspectors by Introspector::collectInt().*/ 00119 /* std::vector<uint64_t> arrayvalue; */ 00120 uint64_t* arrayvalue; 00121 00122 /** Registers a clock for this component. 00123 @param freq Frequency for the clock in SI units 00124 @param handler Pointer to Clock::HandlerBase which is to be invoked 00125 at the specified interval 00126 @param regAll Should this clock perioud be used as the default 00127 time base for all of the links connected to this component 00128 */ 00129 TimeConverter* registerClock( std::string freq, Clock::HandlerBase* handler); 00130 void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler); 00131 00132 SimTime_t getFreq() {return defaultTimeBase->getFactor();} 00133 00134 protected: 00135 /** Timebase used if no other timebase is specified for calls like 00136 Component::getCurrentSimTime(). Often set by Component::registerClock() 00137 function */ 00138 TimeConverter* defaultTimeBase; 00139 00140 private: 00141 friend class boost::serialization::access; 00142 template<class Archive> 00143 void serialize(Archive& ar, const unsigned int version); 00144 }; 00145 00146 template <typename typeT> 00147 typeT Introspector::getData(IntrospectedComponent* c, std::string dataname) 00148 { 00149 IntrospectedComponent::MonitorBase* monitor; 00150 std::pair<bool, IntrospectedComponent::MonitorBase*> p; 00151 00152 p = c->getMonitor(dataname); 00153 00154 //check if the component cares about this data 00155 if (p.first){ 00156 monitor = p.second; 00157 return any_cast<typeT>( (*monitor)()); 00158 } 00159 else 00160 return (-9999); //return an unreasonable number for now 00161 } 00162 00163 } // namespace SST 00164 00165 BOOST_CLASS_EXPORT_KEY(SST::Introspector) 00166 00167 #endif // SST_CORE_INTROSPECTOR_H