00001 // Copyright 2009-2010 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-2010, 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 00013 #ifndef SST_CORE_INTROSPECTOR_H 00014 #define SST_CORE_INTROSPECTOR_H 00015 00016 #include "sst/core/introspectedComponent.h" 00017 #include "sst/core/simulation.h" 00018 #include "sst/core/clock.h" 00019 #include "sst/core/timeConverter.h" 00020 00021 namespace SST { 00022 00023 #if DBG_INTROSPECTOR 00024 #define _INTROSPECTOR_DBG( fmt, args...) \ 00025 printf( "%d:Introspector::%s():%d: "fmt, _debug_rank, __FUNCTION__,__LINE__, ## args ) 00026 #else 00027 #define _INTROSPECTOR_DBG( fmt, args...) 00028 #endif 00029 00030 00031 /** 00032 * Main introspector object for the simulation. 00033 * All models inherit from this. 00034 * Introspection interface is a unified way to gather statistics and arbitrary data from components. 00035 */ 00036 class Introspector { 00037 public: 00038 typedef std::multimap<int, IntrospectedComponent*> Database_t; 00039 00040 /** Types of boost MPI collective operations that introspector can perform.*/ 00041 enum collect_type { GATHER, ALLGATHER, BROADCAST, REDUCE, ALLREDUCE}; 00042 /** Types of funciton objects for the reduce collective.*/ 00043 enum mpi_operation { 00044 MINIMUM, 00045 MAXIMUM, 00046 SUM, 00047 NOT_APPLICABLE 00048 }; 00049 00050 /** Constructor. Generally only called by the factory class. 00051 @param id Unique introspector ID*/ 00052 Introspector(); 00053 virtual ~Introspector() = 0; 00054 00055 /** Called after all components/introspectors have been constructed, but before 00056 simulation time has begun. */ 00057 virtual int Setup( ) { return 0; } 00058 /** Called after simulation completes, but before objects are 00059 destroyed. A good place to print out statistics. */ 00060 virtual int Finish( ) { return 0; } 00061 00062 /** Get component of a certain type indicated by CompType on this rank. 00063 If CompType is blank, a list of all local components is returned. 00064 This function is usually used in Introspector::Setup(). 00065 @param CompType Component's type*/ 00066 std::list<IntrospectedComponent*> getModels(const std::string CompType); 00067 /** Declare that this introspector will be monitoring a given component. 00068 The information of the introspector is also stored in the component's MyIntroList. 00069 This function is usually used in Introspector::Setup(). 00070 @param c Pointer to the component that will be monitored*/ 00071 void monitorComponent(IntrospectedComponent* c); 00072 /** Store pointer to the component and the data ID of the integer data of interest in a local map. 00073 This function is usually used in Introspector::Setup(). 00074 @param c Pointer to the component that is monitored by this introspector 00075 @param dataID ID of the integer data */ 00076 void addToIntDatabase(IntrospectedComponent* c, int dataID); 00077 /** Store pointer to the component and the data ID of the double data of interest in a local map. 00078 This function is usually used in Introspector::Setup(). 00079 @param c Pointer to the component that is monitored by this introspector 00080 @param dataID ID of the double data */ 00081 void addToDoubleDatabase(IntrospectedComponent* c, int dataID); 00082 /** Query the components it is moniroting at regular intervals to retrieve components' statistics & data. 00083 Introspector-writers will implement their own pullData function. This function calls Component::getIntData() 00084 or Component::getDoubleData() to retrieve components' data, and is a good place to manipulate the data 00085 (print to screen, MPI collective communication, etc). 00086 This function can be invoked by an event handler triggered by a clock.*/ 00087 virtual bool pullData( Cycle_t ) { return false; } 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 /** Database of the integer data monitored by this introspector available through Introspector::pullData().*/ 00113 Database_t DatabaseInt; 00114 /** Database of the double data monitored by this introspector available through Introspector::pullData().*/ 00115 Database_t DatabaseDouble; 00116 /** Minimum value of the integer values collected from all introspectors by Introspector::collectInt().*/ 00117 uint64_t minvalue; 00118 /** Maximum value of the integer values collected from all introspectors by Introspector::collectInt().*/ 00119 uint64_t maxvalue; 00120 /** Result value of the reduction operation in Introspector::collectInt().*/ 00121 uint64_t value; 00122 /** Data vector that holds data collected from all introspectors by Introspector::collectInt().*/ 00123 std::vector<uint64_t> arrayvalue; 00124 00125 /** Registers a clock for this component. 00126 @param freq Frequency for the clock in SI units 00127 @param handler Pointer to Clock::HandlerBase which is to be invoked 00128 at the specified interval 00129 @param regAll Should this clock perioud be used as the default 00130 time base for all of the links connected to this component 00131 */ 00132 TimeConverter* registerClock( std::string freq, Clock::HandlerBase* handler); 00133 void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler); 00134 00135 SimTime_t getFreq() {return defaultTimeBase->getFactor();} 00136 00137 protected: 00138 /** Timebase used if no other timebase is specified for calls like 00139 Component::getCurrentSimTime(). Often set by Component::registerClock() 00140 function */ 00141 TimeConverter* defaultTimeBase; 00142 00143 private: 00144 friend class boost::serialization::access; 00145 template<class Archive> 00146 void serialize(Archive& ar, const unsigned int version); 00147 }; 00148 00149 00150 } //end namespace 00151 00152 BOOST_CLASS_EXPORT_KEY(SST::Introspector) 00153 00154 #endif