00001 #ifndef DISTRIBUTEDINCOMINGANALOGMSGDISPATCHER_H_ 00002 #define DISTRIBUTEDINCOMINGANALOGMSGDISPATCHER_H_ 00003 00004 00005 #include <vector> 00006 #include <string> 00007 #include <utility> 00008 00009 #include "SimObject.h" 00010 #include "DistIncomingAnalogSources2BufPosMap.h" 00011 #include "MPIInputBuffer.h" 00012 #include "AnalogDelayObject.h" 00013 00014 using std::vector; 00015 using std::string; 00016 using std::pair; 00017 using std::make_pair; 00018 00019 class DistributedIncomingAnalogMsgDispatcher 00020 { 00021 public: 00022 00023 DistributedIncomingAnalogMsgDispatcher(delay_t minimumDelay, MPIInputBuffer *mpiInputBuffer, DistIncomingAnalogSources2BufPosMap *bufferPositionsOfIncomingSources); 00024 00025 virtual ~DistributedIncomingAnalogMsgDispatcher(); 00026 00027 /*template<typename AnalogSrcType> 00028 void addDirectIncAnalogMessage(SimObject::ID &src, AnalogSrcType srcFieldOrPort, SimObject *dest, string destfield); 00029 00030 template<typename AnalogSrcType> 00031 void addDirectIncAnalogMessage(SimObject::ID &src, AnalogSrcType srcFieldOrPort, SimObject *dest, analog_port_id_t dest_port);*/ 00032 00033 00034 //void dispatchMPIIncomingAnalogMsgs(int step); 00035 00036 void dispatchDelayerCycledIncomingAnalogMsgs(); 00037 00038 void initialize(); 00039 00040 void reset(double dt); 00041 00042 template <typename AnalogSrcType> 00043 inline IncomingAnalogDelayObject* 00044 addDelayerCycledIncomingAnalogMessage(const SimObject::ID &src, AnalogSrcType srcFieldOrPort); 00045 00046 protected: 00047 00048 int nNodes; 00049 00050 delay_t minDelay; 00051 00052 /* typedef vector< vector< pair<SimObject*,analog_port_id_t> > > port_incoming_analog_msgs_type; 00053 port_incoming_analog_msgs_type port_analog_msgs; 00054 00055 typedef vector< vector<double *> > field_incoming_analog_msgs_type; 00056 field_incoming_analog_msgs_type field_analog_msgs; 00057 00058 vector< unsigned > port_msgs_buff_pos; 00059 vector< unsigned > field_msgs_buff_pos; 00060 00061 vector< unsigned > *port_buf_pos_source_eng_ids; 00062 00063 vector< unsigned > *field_buf_pos_source_eng_ids; 00064 */ 00065 // Sources and destinations for the (mpi input buffer) -> (incoming delayers) transfer 00066 // (cycled incoming analog msgs) 00067 vector< unsigned > cycled_inc_msgs_src_buff_pos; 00068 00069 vector< engineid_t > *cycled_buf_pos_source_eng_ids; 00070 00071 vector< IncomingAnalogDelayObject *> cycled_inc_msgs_delayer_destinations; 00072 00073 /* typedef hash_map< unsigned, unsigned > buff_pos2msglist_pos_type; 00074 00075 buff_pos2msglist_pos_type *field_msgs_positions; 00076 00077 buff_pos2msglist_pos_type *port_msgs_positions; */ 00078 00079 // [simobject][port/field] -> buffer position or NULL 00080 DistIncomingAnalogSources2BufPosMap * bufPosOfIncomingSources; 00081 00082 MPIInputBuffer *inputBuffer; 00083 00084 double * mpiBufferPtr; 00085 00086 bool initialized; 00087 }; 00088 00089 template <typename AnalogSrcType> 00090 inline IncomingAnalogDelayObject* 00091 DistributedIncomingAnalogMsgDispatcher::addDelayerCycledIncomingAnalogMessage(const SimObject::ID &src, const AnalogSrcType srcFieldOrPort) 00092 { 00093 typename DistIncomingAnalogSources2BufPosMap::type<AnalogSrcType>::iterator iter = bufPosOfIncomingSources->find(src, srcFieldOrPort); 00094 if (iter == bufPosOfIncomingSources->end(srcFieldOrPort)) { 00095 /* there is no position for this source so we need to register one */ 00096 unsigned buf_position = inputBuffer->getAnalogMsgCounter(src.eng)++; 00097 IncomingAnalogDelayObject *ado = new IncomingAnalogDelayObject(minDelay); 00098 bufPosOfIncomingSources->insert(src, srcFieldOrPort, buf_position, ado); 00099 cycled_inc_msgs_src_buff_pos.push_back(buf_position); 00100 cycled_buf_pos_source_eng_ids->push_back(src.eng); 00101 cycled_inc_msgs_delayer_destinations.push_back(ado); 00102 00103 return ado; 00104 } else 00105 if (!iter->second.second) { 00106 /* there is a position but no incoming analog delay object */ 00107 IncomingAnalogDelayObject *ado = new IncomingAnalogDelayObject(minDelay); 00108 iter->second.second = ado; 00109 cycled_inc_msgs_src_buff_pos.push_back(iter->second.first); 00110 cycled_buf_pos_source_eng_ids->push_back(src.eng); 00111 cycled_inc_msgs_delayer_destinations.push_back(ado); 00112 return ado; 00113 } else { 00114 return iter->second.second ; // return the delayer object 00115 } 00116 return NULL; 00117 } 00118 00119 #endif /*DISTRIBUTEDINCOMINGANALOGMSGDISPATCHER_H_*/