From 3c02c0f8162d9056cf3558f27a900a98575ee6ba Mon Sep 17 00:00:00 2001 From: Ameya Date: Fri, 30 Dec 2016 21:08:38 +0530 Subject: [PATCH 01/35] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2595cdba..9aa1724d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ BookSim Interconnection Network Simulator ========================================= +Added features for CHIPPER (Bufferless routing strategy) + +========================================= + BookSim is a cycle-accurate interconnection network simulator. Originally developed for and introduced with the [Principles and Practices of Interconnection Networks](http://cva.stanford.edu/books/ppin/) book, its functionality has since been continuously extended. The current major release, BookSim 2.0, supports a wide range of topologies such as mesh, torus and flattened butterfly networks, provides diverse routing algorithms and includes numerous options for customizing the network's router microarchitecture. @@ -9,4 +13,4 @@ The current major release, BookSim 2.0, supports a wide range of topologies such If you use BookSim in your research, we would appreciate the following citation in any publications to which it has contributed: -Nan Jiang, Daniel U. Becker, George Michelogiannakis, James Balfour, Brian Towles, John Kim and William J. Dally. A Detailed and Flexible Cycle-Accurate Network-on-Chip Simulator. In *Proceedings of the 2013 IEEE International Symposium on Performance Analysis of Systems and Software*, 2013. \ No newline at end of file +Nan Jiang, Daniel U. Becker, George Michelogiannakis, James Balfour, Brian Towles, John Kim and William J. Dally. A Detailed and Flexible Cycle-Accurate Network-on-Chip Simulator. In *Proceedings of the 2013 IEEE International Symposium on Performance Analysis of Systems and Software*, 2013. From 08aaec7ef0f823ba24bd33441c49f8a1799559c0 Mon Sep 17 00:00:00 2001 From: Ameya Date: Fri, 30 Dec 2016 21:09:42 +0530 Subject: [PATCH 02/35] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 9aa1724d..51ad8de6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ BookSim Interconnection Network Simulator ========================================= Added features for CHIPPER (Bufferless routing strategy) - ========================================= BookSim is a cycle-accurate interconnection network simulator. From a9db8ff794a9599b19c37e1b85ea6e3acb91af5c Mon Sep 17 00:00:00 2001 From: Ameya Date: Sat, 31 Dec 2016 02:09:38 +0530 Subject: [PATCH 03/35] Added basic skeleton for chipper --- src/routers/chipper.cpp | 93 +++++++++++++++++++++++++++++++++++++++++ src/routers/chipper.hpp | 49 ++++++++++++++++++++++ src/routers/router.cpp | 3 ++ 3 files changed, 145 insertions(+) create mode 100644 src/routers/chipper.cpp create mode 100644 src/routers/chipper.hpp diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp new file mode 100644 index 00000000..a352b97e --- /dev/null +++ b/src/routers/chipper.cpp @@ -0,0 +1,93 @@ +// Ameya: Remove redundancies +#include +#include +#include +#include +#include + +#include "chipper.hpp" +#include "stats.hpp" +#include "globals.hpp" + +Chipper::Chipper( const Configuration& config, + Module *parent, const string & name, int id, + int inputs, int outputs ) + : Router( config, + parent, name, + id, + inputs, outputs ) +{ + ostringstream module_name; + + // Routing + + string rf = config.GetStr("routing_function") + "_" + config.GetStr("topology"); + map::iterator rf_iter = gRoutingFunctionMap.find(rf); + if(rf_iter == gRoutingFunctionMap.end()) { + Error("Invalid routing function: " + rf); + } + _rf = rf_iter->second; + + assert(_inputs == _outputs); + + _input_buffer.resize(_inputs); + _output_buffer.resize(_outputs); + + _stage_1.resize(_inputs); + _stage_2.resize(_inputs); +} + +Chipper::~Chipper() +{ + for ( int i = 0; i < _inputs; ++i ) { + while (!_input_buffer[i].empty()) + { + (_input_buffer[i].begin()->second)->Free(); + _input_buffer[i].erase(_input_buffer[i].begin()); + } + } + + for ( int i = 0; i < _inputs; ++i ) { + while (!_stage_1[i].empty()) + { + (_stage_1[i].begin()->second)->Free(); + _stage_1.erase(_stage_1.begin()); + } + } + + for ( int i = 0; i < _inputs; ++i ) { + while (!_stage_2[i].empty()) + { + (_stage_2[i].begin()->second)->Free(); + _stage_2.erase(_stage_2.begin()); + } + } + + for ( int o = 0; o < _outputs; ++o ) { + while (!_output_buffer[o].empty()) + { + (_output_buffer[o].begin()->second)->Free(); + _output_buffer[o].erase(_output_buffer[o].begin()); + } + } +} + +void Chipper::Display( ostream & os ) const +{ + os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func +} + +void Chipper::ReadInputs() +{ + cout << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func +} + +void Chipper::WriteOutputs() +{ + cout << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func +} + +void Chipper::_InternalStep() +{ + cout << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func +} \ No newline at end of file diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp new file mode 100644 index 00000000..30134602 --- /dev/null +++ b/src/routers/chipper.hpp @@ -0,0 +1,49 @@ +#ifndef _CHIPPER_HPP_ +#define _CHIPPER_HPP_ + +#include +#include +#include + +#include "module.hpp" +#include "router.hpp" +#include "routefunc.hpp" + +class Chipper : public Router { + // Each stage buffer is maintained as a map of + // but the length should not exceed 2 flit widths + // This is necessary to allow for code to depict + // segments working in parallel + vector > _input_buffer; + vector > _output_buffer; + vector > _stage_1; + vector > _stage_2; + // No need for extra flags showing occupancy as each buffer is timed + + tRoutingFunction _rf; // Temporary (check necessity later) Ameya + + virtual void _InternalStep(); + +public: + Chipper( const Configuration& config, + Module *parent, const string & name, int id, + int inputs, int outputs ); + virtual ~Chipper(); + + virtual void ReadInputs(); + // virtual void Evaluate( ); + virtual void WriteOutputs(); + + // Ameya: Just for sake of avoiding pure virual func + virtual int GetUsedCredit(int o) const {return 0;} + virtual int GetBufferOccupancy(int i) const {return 0;} + + virtual vector UsedCredits() const { return vector(); } + virtual vector FreeCredits() const { return vector(); } + virtual vector MaxCredits() const { return vector(); } + + // Ameya: Just for sake of avoiding pure virual func + virtual void Display( ostream & os = cout ) const; // Recheck implementation +}; + +#endif diff --git a/src/routers/router.cpp b/src/routers/router.cpp index 49b46dc9..cc68687f 100644 --- a/src/routers/router.cpp +++ b/src/routers/router.cpp @@ -47,6 +47,7 @@ #include "iq_router.hpp" #include "event_router.hpp" #include "chaos_router.hpp" +#include "chipper.hpp" // Ameya /////////////////////////////////////////////////////// int const Router::STALL_BUFFER_BUSY = -2; @@ -138,6 +139,8 @@ Router *Router::NewRouter( const Configuration& config, r = new EventRouter( config, parent, name, id, inputs, outputs ); } else if ( type == "chaos" ) { r = new ChaosRouter( config, parent, name, id, inputs, outputs ); + } else if ( type == "chipper" ) { // Ameya + r = new Chipper( config, parent, name, id, inputs, outputs ); } else { cerr << "Unknown router type: " << type << endl; } From 3a6ccaf5ca597a40d93c194f87ee51d13cf7f228 Mon Sep 17 00:00:00 2001 From: sabersword Date: Sat, 31 Dec 2016 03:18:31 +0530 Subject: [PATCH 04/35] Added config options for CHIPPER --- src/booksim_config.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/booksim_config.hpp | 1 + src/config_utils.hpp | 8 ++++---- src/main.cpp | 17 ++++++++++------- src/routers/chipper.cpp | 15 +++++++++++++++ src/routers/chipper.hpp | 3 +++ 6 files changed, 71 insertions(+), 11 deletions(-) mode change 100644 => 100755 src/routers/chipper.hpp diff --git a/src/booksim_config.cpp b/src/booksim_config.cpp index 6f403962..d853322a 100644 --- a/src/booksim_config.cpp +++ b/src/booksim_config.cpp @@ -35,6 +35,8 @@ #include "booksim.hpp" #include "booksim_config.hpp" +#include + BookSimConfig::BookSimConfig( ) { //======================================================== @@ -94,6 +96,9 @@ BookSimConfig::BookSimConfig( ) // enable next-hop-output queueing _int_map["noq"] = 0; + // Ameya: enable bufferless simulation + _int_map["bufferless"] = 0; + //==== Input-queued ====================================== // Control of virtual channel speculation @@ -347,3 +352,36 @@ PowerConfig::PowerConfig( ) _float_map["wire_length"] = 0; } + +void BookSimConfig::CheckConsistency() // Ameya +{ + int bufferless = this->GetInt("bufferless"); + if(bufferless) + { + if(this->GetInt("num_vcs")!=1) + { + cerr << "Setting num_vcs to 1 from original value of " << this->GetInt("num_vcs") << endl; + this->Assign("num_vcs", 1); + } + if(this->GetInt("vc_buf_size")!=1) + { + cerr << "Setting vc_buf_size to 1 from original value of " << this->GetInt("vc_buf_size") << endl; + this->Assign("vc_buf_size", 1); + } + if(this->GetInt("buf_size")!=1) + { + cerr << "Setting buf_size to 1 from original value of " << this->GetInt("buf_size") << endl; + this->Assign("buf_size", 1); + } + if(this->GetStr("topology") != "mesh") + { + cerr << "Bufferless only supported for mesh" << endl; + assert(this->GetStr("topology") == "mesh"); + } + if(this->GetStr("routing_function") != "dor") + { + cerr << "Bufferless only supported for dor" << endl; + assert(this->GetStr("routing_function") == "dor"); + } + } +} \ No newline at end of file diff --git a/src/booksim_config.hpp b/src/booksim_config.hpp index e5589dcf..df9ae94f 100644 --- a/src/booksim_config.hpp +++ b/src/booksim_config.hpp @@ -35,6 +35,7 @@ class BookSimConfig : public Configuration { public: BookSimConfig( ); + void CheckConsistency(); // Ameya }; #endif diff --git a/src/config_utils.hpp b/src/config_utils.hpp index e7343443..7b4045de 100644 --- a/src/config_utils.hpp +++ b/src/config_utils.hpp @@ -30,10 +30,10 @@ #include "booksim.hpp" -#include -#include -#include -#include +#include +#include +#include +#include extern "C" int yyparse(); diff --git a/src/main.cpp b/src/main.cpp index ef16a944..a0de8264 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,7 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or @@ -15,7 +15,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; @@ -110,7 +110,7 @@ bool Simulate( BookSimConfig const & config ) } /*tcc and characterize are legacy - *not sure how to use them + *not sure how to use them */ assert(trafficManager == NULL); @@ -160,16 +160,19 @@ int main( int argc, char **argv ) if ( !ParseArgs( &config, argc, argv ) ) { cerr << "Usage: " << argv[0] << " configfile... [param=value...]" << endl; return 0; - } + } - + + /*basic consistency chcks for bufferless + */ + config.CheckConsistency(); // Ameya /*initialize routing, traffic, injection functions */ InitializeRoutingMap( config ); gPrintActivity = (config.GetInt("print_activity") > 0); gTrace = (config.GetInt("viewer_trace") > 0); - + string watch_out_file = config.GetStr( "watch_out" ); if(watch_out_file == "") { gWatchOut = NULL; @@ -178,7 +181,7 @@ int main( int argc, char **argv ) } else { gWatchOut = new ofstream(watch_out_file.c_str()); } - + /*configure and run the simulator */ diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index a352b97e..18e09717 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -72,6 +72,21 @@ Chipper::~Chipper() } } +void Chipper::AddInputChannel( FlitChannel *channel, CreditChannel * ignored) +{ + // Ameya: credit channel ignored + _input_channels.push_back( channel ); + channel->SetSink( this, _input_channels.size() - 1 ) ; +} + +void Chipper::AddOutputChannel(FlitChannel * channel, CreditChannel * ignored) +{ + // Ameya: credit channel ignored + _output_channels.push_back( channel ); + _channel_faults.push_back( false ); + channel->SetSource( this, _output_channels.size() - 1 ) ; +} + void Chipper::Display( ostream & os ) const { os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp old mode 100644 new mode 100755 index 30134602..cacf9be2 --- a/src/routers/chipper.hpp +++ b/src/routers/chipper.hpp @@ -30,6 +30,9 @@ class Chipper : public Router { int inputs, int outputs ); virtual ~Chipper(); + virtual void AddInputChannel( FlitChannel *channel, CreditChannel * ignored); + virtual void AddOutputChannel(FlitChannel * channel, CreditChannel * ignored); + virtual void ReadInputs(); // virtual void Evaluate( ); virtual void WriteOutputs(); From 039ddaf0f2c4898110cf265b9110a0917a054529 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 4 Jan 2017 00:44:16 +0530 Subject: [PATCH 05/35] Added traffic manager for bufferless networks --- src/config_utils.cpp | 60 +++---- src/flitchannel.hpp | 5 + src/networks/network.cpp | 6 + src/networks/network.hpp | 1 + src/routers/chipper.hpp | 6 +- src/trafficmanager.cpp | 354 ++++++++++++++++++++------------------- src/trafficmanager.hpp | 6 +- 7 files changed, 228 insertions(+), 210 deletions(-) diff --git a/src/config_utils.cpp b/src/config_utils.cpp index 04f76343..96bc9966 100644 --- a/src/config_utils.cpp +++ b/src/config_utils.cpp @@ -6,7 +6,7 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or @@ -14,7 +14,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; @@ -26,7 +26,7 @@ /*config_utils.cpp * - *The configuration object which contained the parsed data from the + *The configuration object which contained the parsed data from the *configuration file */ @@ -55,7 +55,7 @@ void Configuration::AddStrField(string const & field, string const & value) void Configuration::Assign(string const & field, string const & value) { map::const_iterator match; - + match = _str_map.find(field); if(match != _str_map.end()) { _str_map[field] = value; @@ -67,7 +67,7 @@ void Configuration::Assign(string const & field, string const & value) void Configuration::Assign(string const & field, int value) { map::const_iterator match; - + match = _int_map.find(field); if(match != _int_map.end()) { _int_map[field] = value; @@ -79,7 +79,7 @@ void Configuration::Assign(string const & field, int value) void Configuration::Assign(string const & field, double value) { map::const_iterator match; - + match = _float_map.find(field); if(match != _float_map.end()) { _float_map[field] = value; @@ -115,7 +115,7 @@ int Configuration::GetInt(string const & field) const } double Configuration::GetFloat(string const & field) const -{ +{ map::const_iterator match; match = _float_map.find(field); @@ -239,9 +239,9 @@ bool ParseArgs(Configuration * cf, int argc, char * * argv) ifstream in(argv[i]); cout << "BEGIN Configuration File: " << argv[i] << endl; while (!in.eof()) { - char c; - in.get(c); - cout << c ; + char c; + in.get(c); + cout << c ; } cout << "END Configuration File: " << argv[i] << endl; rc = true; @@ -260,11 +260,11 @@ bool ParseArgs(Configuration * cf, int argc, char * * argv) //However, it can't and won't write out empty strings since the booksim yacc //parser won't be abled to parse blank strings void Configuration::WriteFile(string const & filename) { - + ostream *config_out= new ofstream(filename.c_str()); - - - for(map::const_iterator i = _str_map.begin(); + + + for(map::const_iterator i = _str_map.begin(); i!=_str_map.end(); i++){ //the parser won't read empty strings @@ -272,15 +272,15 @@ void Configuration::WriteFile(string const & filename) { *config_out<first<<" = "<second<<";"<::const_iterator i = _int_map.begin(); + + for(map::const_iterator i = _int_map.begin(); i!=_int_map.end(); i++){ *config_out<first<<" = "<second<<";"<::const_iterator i = _float_map.begin(); + for(map::const_iterator i = _float_map.begin(); i!=_float_map.end(); i++){ *config_out<first<<" = "<second<<";"<flush(); delete config_out; - + } void Configuration::WriteMatlabFile(ostream * config_out) const { - - - for(map::const_iterator i = _str_map.begin(); + + + for(map::const_iterator i = _str_map.begin(); i!=_str_map.end(); i++){ //the parser won't read blanks lolz @@ -305,15 +305,15 @@ void Configuration::WriteMatlabFile(ostream * config_out) const { *config_out<<"%"<first<<" = \'"<second<<"\';"<::const_iterator i = _int_map.begin(); + + for(map::const_iterator i = _int_map.begin(); i!=_int_map.end(); i++){ *config_out<<"%"<first<<" = "<second<<";"<::const_iterator i = _float_map.begin(); + for(map::const_iterator i = _float_map.begin(); i!=_float_map.end(); i++){ *config_out<<"%"<first<<" = "<second<<";"< tokenize_str(string const & data) } // doesn't start with an opening brace --> treat as single element - // note that this element can potentially contain nested lists + // note that this element can potentially contain nested lists if(data[0] != '{') { values.push_back(data); return values; @@ -345,7 +345,7 @@ vector tokenize_str(string const & data) size_t curr = start; while(string::npos != (curr = data.find_first_of("{,}", curr))) { - + if(data[curr] == '{') { ++nested; } else if((data[curr] == '}') && nested) { @@ -374,7 +374,7 @@ vector tokenize_int(string const & data) } // doesn't start with an opening brace --> treat as single element - // note that this element can potentially contain nested lists + // note that this element can potentially contain nested lists if(data[0] != '{') { values.push_back(atoi(data.c_str())); return values; @@ -386,7 +386,7 @@ vector tokenize_int(string const & data) size_t curr = start; while(string::npos != (curr = data.find_first_of("{,}", curr))) { - + if(data[curr] == '{') { ++nested; } else if((data[curr] == '}') && nested) { @@ -415,7 +415,7 @@ vector tokenize_float(string const & data) } // doesn't start with an opening brace --> treat as single element - // note that this element can potentially contain nested lists + // note that this element can potentially contain nested lists if(data[0] != '{') { values.push_back(atof(data.c_str())); return values; @@ -427,7 +427,7 @@ vector tokenize_float(string const & data) size_t curr = start; while(string::npos != (curr = data.find_first_of("{,}", curr))) { - + if(data[curr] == '{') { ++nested; } else if((data[curr] == '}') && nested) { diff --git a/src/flitchannel.hpp b/src/flitchannel.hpp index f4406097..71952b71 100644 --- a/src/flitchannel.hpp +++ b/src/flitchannel.hpp @@ -72,6 +72,11 @@ class FlitChannel : public Channel { return _active; } + // Ameya + inline int GetInjectStatus() const { + return ( _input == 0 ); + } + // Send flit virtual void Send(Flit * flit); diff --git a/src/networks/network.cpp b/src/networks/network.cpp index ec44835c..59771fac 100644 --- a/src/networks/network.cpp +++ b/src/networks/network.cpp @@ -212,6 +212,12 @@ void Network::WriteFlit( Flit *f, int source ) _inject[source]->Send(f); } +int Network::CheckInject( int source ) +{ + assert( ( source >= 0 ) && ( source < _nodes ) ); + return ( _inject[source]->GetInjectStatus() ); +} + Flit *Network::ReadFlit( int dest ) { assert( ( dest >= 0 ) && ( dest < _nodes ) ); diff --git a/src/networks/network.hpp b/src/networks/network.hpp index b3dfb440..e9bc33ff 100644 --- a/src/networks/network.hpp +++ b/src/networks/network.hpp @@ -93,6 +93,7 @@ class Network : public TimedModule { virtual void ReadInputs( ); virtual void Evaluate( ); virtual void WriteOutputs( ); + int CheckInject( int source ); // Ameya void Display( ostream & os = cout ) const; void DumpChannelMap( ostream & os = cout, string const & prefix = "" ) const; diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp index cacf9be2..df37d53d 100755 --- a/src/routers/chipper.hpp +++ b/src/routers/chipper.hpp @@ -41,9 +41,9 @@ class Chipper : public Router { virtual int GetUsedCredit(int o) const {return 0;} virtual int GetBufferOccupancy(int i) const {return 0;} - virtual vector UsedCredits() const { return vector(); } - virtual vector FreeCredits() const { return vector(); } - virtual vector MaxCredits() const { return vector(); } + virtual vector UsedCredits() const { return vector(); } + virtual vector FreeCredits() const { return vector(); } + virtual vector MaxCredits() const { return vector(); } // Ameya: Just for sake of avoiding pure virual func virtual void Display( ostream & os = cout ) const; // Recheck implementation diff --git a/src/trafficmanager.cpp b/src/trafficmanager.cpp index 3963188b..188d895b 100644 --- a/src/trafficmanager.cpp +++ b/src/trafficmanager.cpp @@ -7,7 +7,7 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or @@ -15,7 +15,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; @@ -36,7 +36,8 @@ #include "booksim_config.hpp" #include "trafficmanager.hpp" #include "batchtrafficmanager.hpp" -#include "random_utils.hpp" +#include "blesstrafficmanager.hpp" // Ameya +#include "random_utils.hpp" #include "vc.hpp" #include "packet_reply_info.hpp" @@ -45,13 +46,17 @@ TrafficManager * TrafficManager::New(Configuration const & config, { TrafficManager * result = NULL; string sim_type = config.GetStr("sim_type"); + int tbufferless = config.GetInt("bufferless"); if((sim_type == "latency") || (sim_type == "throughput")) { - result = new TrafficManager(config, net); + if(tbufferless) + result = new BlessTrafficManager(config, net); + else + result = new TrafficManager(config, net); // Ameya } else if(sim_type == "batch") { result = new BatchTrafficManager(config, net); } else { cerr << "Unknown simulation type: " << sim_type << endl; - } + } return result; } @@ -64,14 +69,14 @@ TrafficManager::TrafficManager( const Configuration &config, const vector::const_iterator rf_iter = gRoutingFunctionMap.find(rf); @@ -103,7 +108,7 @@ TrafficManager::TrafficManager( const Configuration &config, const vectorsecond; - + _lookahead_routing = !config.GetInt("routing_delay"); _noq = config.GetInt("noq"); if(_noq) { @@ -112,7 +117,7 @@ TrafficManager::TrafficManager( const Configuration &config, const vector(1, (_read_request_size[c] + _read_reply_size[c] + _write_request_size[c] + _write_reply_size[c]) / 2); _packet_size_rate[c] = vector(1, 1); @@ -200,7 +205,7 @@ TrafficManager::TrafficManager( const Configuration &config, const vector watch_packets = config.GetIntArray("watch_packets"); for(size_t i = 0; i < watch_packets.size(); ++i) { _packets_to_watch.insert(watch_packets[i]); @@ -380,7 +385,7 @@ TrafficManager::TrafficManager( const Configuration &config, const vector(_nodes, 0)); _ejected_flits.resize(_classes, vector(_nodes, 0)); @@ -449,7 +454,7 @@ TrafficManager::TrafficManager( const Configuration &config, const vectorcl].count(f->id) > 0); _total_in_flight_flits[f->cl].erase(f->id); - + if(f->record) { assert(_measured_in_flight_flits[f->cl].count(f->id) > 0); _measured_in_flight_flits[f->cl].erase(f->id); } - if ( f->watch ) { + if ( f->watch ) { *gWatchOut << GetSimTime() << " | " << "node" << dest << " | " - << "Retiring flit " << f->id + << "Retiring flit " << f->id << " (packet " << f->pid - << ", src = " << f->src + << ", src = " << f->src << ", dest = " << f->dest << ", hops = " << f->hops << ", flat = " << f->atime - f->itime @@ -669,7 +674,7 @@ void TrafficManager::_RetireFlit( Flit *f, int dest ) err << "Flit " << f->id << " arrived at incorrect output " << dest; Error( err.str( ) ); } - + if((_slowest_flit[f->cl] < 0) || (_flat_stats[f->cl]->Max() < (f->atime - f->itime))) _slowest_flit[f->cl] = f->id; @@ -677,7 +682,7 @@ void TrafficManager::_RetireFlit( Flit *f, int dest ) if(_pair_stats){ _pair_flat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - f->itime ); } - + if ( f->tail ) { Flit * head; if(f->head) { @@ -690,14 +695,14 @@ void TrafficManager::_RetireFlit( Flit *f, int dest ) assert(head->head); assert(f->pid == head->pid); } - if ( f->watch ) { + if ( f->watch ) { *gWatchOut << GetSimTime() << " | " << "node" << dest << " | " - << "Retiring packet " << f->pid + << "Retiring packet " << f->pid << " (plat = " << f->atime - head->ctime << ", nlat = " << f->atime - head->itime << ", frag = " << (f->atime - head->atime) - (f->id - head->id) // NB: In the spirit of solving problems using ugly hacks, we compute the packet length by taking advantage of the fact that the IDs of flits within a packet are contiguous. - << ", src = " << head->src + << ", src = " << head->src << ", dest = " << head->dest << ")." << endl; } @@ -716,13 +721,13 @@ void TrafficManager::_RetireFlit( Flit *f, int dest ) } else if(f->type == Flit::ANY_TYPE) { _requestsOutstanding[f->src]--; } - + } // Only record statistics once per packet (at tail) // and based on the simulation state if ( ( _sim_state == warming_up ) || f->record ) { - + _hop_stats[f->cl]->AddSample( f->hops ); if((_slowest_packet[f->cl] < 0) || @@ -731,19 +736,19 @@ void TrafficManager::_RetireFlit( Flit *f, int dest ) _plat_stats[f->cl]->AddSample( f->atime - head->ctime); _nlat_stats[f->cl]->AddSample( f->atime - head->itime); _frag_stats[f->cl]->AddSample( (f->atime - head->atime) - (f->id - head->id) ); - + if(_pair_stats){ _pair_plat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->ctime ); _pair_nlat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->itime ); } } - + if(f != head) { head->Free(); } - + } - + if(f->head && !f->tail) { _retired_packets[f->cl].insert(make_pair(f->pid, f)); } else { @@ -762,33 +767,33 @@ int TrafficManager::_IssuePacket( int source, int cl ) result = -1; } } else { - + //produce a packet if(_injection_process[cl]->test(source)) { - + //coin toss to determine request type. result = (RandomFloat() < _write_fraction[cl]) ? 2 : 1; - + _requestsOutstanding[source]++; } } } else { //normal mode result = _injection_process[cl]->test(source) ? 1 : 0; _requestsOutstanding[source]++; - } + } if(result != 0) { _packet_seq_no[source]++; } return result; } -void TrafficManager::_GeneratePacket( int source, int stype, +void TrafficManager::_GeneratePacket( int source, int stype, int cl, int time ) { assert(stype!=0); Flit::FlitType packet_type = Flit::ANY_TYPE; - int size = _GetNextPacketSize(cl); //input size + int size = _GetNextPacketSize(cl); //input size int pid = _cur_pid++; assert(_cur_pid); int packet_destination = _traffic_pattern[cl]->dest(source); @@ -840,18 +845,18 @@ void TrafficManager::_GeneratePacket( int source, int stype, record = _measure_stats[cl]; } - int subnetwork = ((packet_type == Flit::ANY_TYPE) ? + int subnetwork = ((packet_type == Flit::ANY_TYPE) ? RandomInt(_subnets-1) : _subnet[packet_type]); - - if ( watch ) { + + if ( watch ) { *gWatchOut << GetSimTime() << " | " << "node" << source << " | " << "Enqueuing packet " << pid << " at time " << time << "." << endl; } - + for ( int i = 0; i < size; ++i ) { Flit * f = Flit::New(); f->id = _cur_id++; @@ -868,7 +873,7 @@ void TrafficManager::_GeneratePacket( int source, int stype, if(record) { _measured_in_flight_flits[f->cl].insert(make_pair(f->id, f)); } - + if(gTrace){ cout<<"New Flit "<src<tail = false; } - + f->vc = -1; - if ( f->watch ) { + if ( f->watch ) { *gWatchOut << GetSimTime() << " | " << "node" << source << " | " << "Enqueuing flit " << f->id @@ -929,10 +934,10 @@ void TrafficManager::_Inject(){ bool generated = false; while( !generated && ( _qtime[input][c] <= _time ) ) { int stype = _IssuePacket( input, c ); - + if ( stype != 0 ) { //generate a packet - _GeneratePacket( input, stype, c, - _include_queuing==1 ? + _GeneratePacket( input, stype, c, + _include_queuing==1 ? _qtime[input][c] : _time ); generated = true; } @@ -941,8 +946,8 @@ void TrafficManager::_Inject(){ ++_qtime[input][c]; } } - - if ( ( _sim_state == draining ) && + + if ( ( _sim_state == draining ) && ( _qtime[input][c] > _drain_time ) ) { _qdrained[input][c] = true; } @@ -963,7 +968,7 @@ void TrafficManager::_Step( ) } vector > flits(_subnets); - + for ( int subnet = 0; subnet < _subnets; ++subnet ) { for ( int n = 0; n < _nodes; ++n ) { Flit * const f = _net[subnet]->ReadFlit( n ); @@ -1003,7 +1008,7 @@ void TrafficManager::_Step( ) } _net[subnet]->ReadInputs( ); } - + if ( !_empty_network ) { _Inject(); } @@ -1022,12 +1027,12 @@ void TrafficManager::_Step( ) if(_hold_switch_for_packet) { list const & pp = _partial_packets[n][last_class]; - if(!pp.empty() && !pp.front()->head && + if(!pp.empty() && !pp.front()->head && !dest_buf->IsFullFor(pp.front()->vc)) { f = pp.front(); assert(f->vc == _last_vc[n][subnet][last_class]); - // if we're holding the connection, we don't need to check that class + // if we're holding the connection, we don't need to check that class // again in the for loop --class_limit; } @@ -1046,7 +1051,7 @@ void TrafficManager::_Step( ) Flit * const cf = pp.front(); assert(cf); assert(cf->cl == c); - + if(cf->subnetwork != subnet) { continue; } @@ -1056,7 +1061,7 @@ void TrafficManager::_Step( ) } if(cf->head && cf->vc == -1) { // Find first available VC - + OutputSet route_set; _rf(NULL, cf, -1, &route_set, true); set const & os = route_set.GetSet(); @@ -1073,8 +1078,8 @@ void TrafficManager::_Step( ) assert(router); int in_channel = inject->GetSinkPort(); - // NOTE: Because the lookahead is not for injection, but for the - // first hop, we have to temporarily set cf's VC to be non-negative + // NOTE: Because the lookahead is not for injection, but for the + // first hop, we have to temporarily set cf's VC to be non-negative // in order to avoid seting of an assertion in the routing function. cf->vc = vc_start; _rf(router, cf, in_channel, &cf->la_route_set, false); @@ -1130,7 +1135,7 @@ void TrafficManager::_Step( ) } } } - + if(cf->vc == -1) { if(cf->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " @@ -1158,7 +1163,7 @@ void TrafficManager::_Step( ) int const c = f->cl; if(f->head) { - + if (_lookahead_routing) { if(!_noq) { const FlitChannel * inject = _net[subnet]->GetInject(n); @@ -1185,7 +1190,7 @@ void TrafficManager::_Step( ) dest_buf->TakeBuffer(f->vc); _last_vc[n][subnet][c] = f->vc; } - + _last_class[n][subnet] = c; _partial_packets[n][c].pop_front(); @@ -1196,12 +1201,12 @@ void TrafficManager::_Step( ) #endif dest_buf->SendingFlit(f); - + if(_pri_type == network_age_based) { f->pri = numeric_limits::max() - _time; assert(f->pri >= 0); } - + if(f->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " @@ -1218,20 +1223,20 @@ void TrafficManager::_Step( ) Flit * const nf = _partial_packets[n][c].front(); nf->vc = f->vc; } - + if((_sim_state == warming_up) || (_sim_state == running)) { ++_sent_flits[c][n]; if(f->head) { ++_sent_packets[c][n]; } } - + #ifdef TRACK_FLOWS ++_injected_flits[c][n]; #endif - + _net[subnet]->WriteFlit(f, n); - + } } } @@ -1246,18 +1251,18 @@ void TrafficManager::_Step( ) if(f->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " - << "Injecting credit for VC " << f->vc - << " into subnet " << subnet + << "Injecting credit for VC " << f->vc + << " into subnet " << subnet << "." << endl; } Credit * const c = Credit::New(); c->vc.insert(f->vc); _net[subnet]->WriteCredit(c, n); - + #ifdef TRACK_FLOWS ++_ejected_flits[f->cl][n]; #endif - + _RetireFlit(f, n); } } @@ -1273,13 +1278,13 @@ void TrafficManager::_Step( ) } } - + bool TrafficManager::_PacketsOutstanding( ) const { for ( int c = 0; c < _classes; ++c ) { if ( _measure_stats[c] ) { if ( _measured_in_flight_flits[c].empty() ) { - + for ( int s = 0; s < _nodes; ++s ) { if ( !_qdrained[s][c] ) { #ifdef DEBUG_DRAIN @@ -1341,7 +1346,7 @@ void TrafficManager::_ClearStats( ) _reset_time = _time; } -void TrafficManager::_ComputeStats( const vector & stats, int *sum, int *min, int *max, int *min_pos, int *max_pos ) const +void TrafficManager::_ComputeStats( const vector & stats, int *sum, int *min, int *max, int *min_pos, int *max_pos ) const { int const count = stats.size(); assert(count > 0); @@ -1380,7 +1385,7 @@ void TrafficManager::_ComputeStats( const vector & stats, int *sum, int *mi } } -void TrafficManager::_DisplayRemaining( ostream & os ) const +void TrafficManager::_DisplayRemaining( ostream & os ) const { for(int c = 0; c < _classes; ++c) { @@ -1397,9 +1402,9 @@ void TrafficManager::_DisplayRemaining( ostream & os ) const } if(_total_in_flight_flits[c].size() > 10) os << "[...] "; - + os << "(" << _total_in_flight_flits[c].size() << " flits)" << endl; - + os << "Measured flits: "; for ( iter = _measured_in_flight_flits[c].begin( ), i = 0; ( iter != _measured_in_flight_flits[c].end( ) ) && ( i < 10 ); @@ -1408,45 +1413,46 @@ void TrafficManager::_DisplayRemaining( ostream & os ) const } if(_measured_in_flight_flits[c].size() > 10) os << "[...] "; - + os << "(" << _measured_in_flight_flits[c].size() << " flits)" << endl; - + } } bool TrafficManager::_SingleSim( ) { int converged = 0; - - //once warmed up, we require 3 converging runs to end the simulation + + //once warmed up, we require 3 converging runs to end the simulation vector prev_latency(_classes, 0.0); vector prev_accepted(_classes, 0.0); bool clear_last = false; int total_phases = 0; - while( ( total_phases < _max_samples ) && - ( ( _sim_state != running ) || + while( ( total_phases < _max_samples ) && + ( ( _sim_state != running ) || ( converged < 3 ) ) ) { - + if ( clear_last || (( ( _sim_state == warming_up ) && ( ( total_phases % 2 ) == 0 ) )) ) { clear_last = false; _ClearStats( ); } - - + + for ( int iter = 0; iter < _sample_period; ++iter ) _Step( ); - + + //cout << _sim_state << endl; UpdateStats(); DisplayStats(); - + int lat_exc_class = -1; int lat_chg_exc_class = -1; int acc_chg_exc_class = -1; - + for(int c = 0; c < _classes; ++c) { - + if(_measure_stats[c] == 0) { continue; } @@ -1466,21 +1472,21 @@ bool TrafficManager::_SingleSim( ) double latency = (double)_plat_stats[c]->Sum(); double count = (double)_plat_stats[c]->NumSamples(); - + map::const_iterator iter; - for(iter = _total_in_flight_flits[c].begin(); - iter != _total_in_flight_flits[c].end(); + for(iter = _total_in_flight_flits[c].begin(); + iter != _total_in_flight_flits[c].end(); iter++) { latency += (double)(_time - iter->second->ctime); count++; } - + if((lat_exc_class < 0) && (_latency_thres[c] >= 0.0) && ((latency / count) > _latency_thres[c])) { lat_exc_class = c; } - + cout << "latency change = " << latency_change << endl; if(lat_chg_exc_class < 0) { if((_sim_state == warming_up) && @@ -1493,7 +1499,7 @@ bool TrafficManager::_SingleSim( ) lat_chg_exc_class = c; } } - + cout << "throughput change = " << accepted_change << endl; if(acc_chg_exc_class < 0) { if((_sim_state == warming_up) && @@ -1506,25 +1512,25 @@ bool TrafficManager::_SingleSim( ) acc_chg_exc_class = c; } } - + } - + // Fail safe for latency mode, throughput will ust continue if ( _measure_latency && ( lat_exc_class >= 0 ) ) { - + cout << "Average latency for class " << lat_exc_class << " exceeded " << _latency_thres[lat_exc_class] << " cycles. Aborting simulation." << endl; - converged = 0; + converged = 0; _sim_state = draining; _drain_time = _time; if(_stats_out) { WriteStats(*_stats_out); } break; - + } - + if ( _sim_state == warming_up ) { - if ( ( _warmup_periods > 0 ) ? + if ( ( _warmup_periods > 0 ) ? ( total_phases + 1 >= _warmup_periods ) : ( ( !_measure_latency || ( lat_chg_exc_class < 0 ) ) && ( acc_chg_exc_class < 0 ) ) ) { @@ -1542,69 +1548,69 @@ bool TrafficManager::_SingleSim( ) } ++total_phases; } - + if ( _sim_state == running ) { ++converged; - + _sim_state = draining; _drain_time = _time; if ( _measure_latency ) { cout << "Draining all recorded packets ..." << endl; int empty_steps = 0; - while( _PacketsOutstanding( ) ) { - _Step( ); - + while( _PacketsOutstanding( ) ) { + _Step( ); + ++empty_steps; - + if ( empty_steps % 1000 == 0 ) { - + int lat_exc_class = -1; - + for(int c = 0; c < _classes; c++) { - + double threshold = _latency_thres[c]; - + if(threshold < 0.0) { continue; } - + double acc_latency = _plat_stats[c]->Sum(); double acc_count = (double)_plat_stats[c]->NumSamples(); - + map::const_iterator iter; - for(iter = _total_in_flight_flits[c].begin(); - iter != _total_in_flight_flits[c].end(); + for(iter = _total_in_flight_flits[c].begin(); + iter != _total_in_flight_flits[c].end(); iter++) { acc_latency += (double)(_time - iter->second->ctime); acc_count++; } - + if((acc_latency / acc_count) > threshold) { lat_exc_class = c; break; } } - + if(lat_exc_class >= 0) { cout << "Average latency for class " << lat_exc_class << " exceeded " << _latency_thres[lat_exc_class] << " cycles. Aborting simulation." << endl; - converged = 0; + converged = 0; _sim_state = warming_up; if(_stats_out) { WriteStats(*_stats_out); } break; } - - _DisplayRemaining( ); - + + _DisplayRemaining( ); + } } } } else { cout << "Too many sample periods needed to converge" << endl; } - + return ( converged > 0 ); } @@ -1634,7 +1640,7 @@ bool TrafficManager::Run( ) // converge // draing, wait until all packets finish _sim_state = warming_up; - + _ClearStats( ); for(int c = 0; c < _classes; ++c) { @@ -1657,15 +1663,15 @@ bool TrafficManager::Run( ) packets_left |= !_total_in_flight_flits[c].empty(); } - while( packets_left ) { - _Step( ); + while( packets_left ) { + _Step( ); ++empty_steps; if ( empty_steps % 1000 == 0 ) { - _DisplayRemaining( ); + _DisplayRemaining( ); } - + packets_left = false; for(int c = 0; c < _classes; ++c) { packets_left |= !_total_in_flight_flits[c].empty(); @@ -1673,35 +1679,35 @@ bool TrafficManager::Run( ) } //wait until all the credits are drained as well while(Credit::OutStanding()!=0){ - _Step(); + _Step( ); } _empty_network = false; //for the love of god don't ever say "Time taken" anywhere else //the power script depend on it - cout << "Time taken is " << _time << " cycles" <Min(); _overall_avg_plat[c] += _plat_stats[c]->Average(); _overall_max_plat[c] += _plat_stats[c]->Max(); @@ -1711,7 +1717,7 @@ void TrafficManager::_UpdateOverallStats() { _overall_min_flat[c] += _flat_stats[c]->Min(); _overall_avg_flat[c] += _flat_stats[c]->Average(); _overall_max_flat[c] += _flat_stats[c]->Max(); - + _overall_min_frag[c] += _frag_stats[c]->Min(); _overall_avg_frag[c] += _frag_stats[c]->Average(); _overall_max_frag[c] += _frag_stats[c]->Max(); @@ -1782,15 +1788,15 @@ void TrafficManager::_UpdateOverallStats() { } void TrafficManager::WriteStats(ostream & os) const { - + os << "%=================================" << endl; for(int c = 0; c < _classes; ++c) { - + if(_measure_stats[c] == 0) { continue; } - + //c+1 due to matlab array starting at 1 os << "plat(" << c+1 << ") = " << _plat_stats[c]->Average() << ";" << endl << "plat_hist(" << c+1 << ",:) = " << *_plat_stats[c] << ";" << endl @@ -1913,7 +1919,7 @@ void TrafficManager::UpdateStats() { for(int router = 0; router < _routers; ++router) { Router * const r = _router[subnet][router]; #ifdef TRACK_FLOWS - char trail_char = + char trail_char = ((router == _routers - 1) && (subnet == _subnets - 1) && (c == _classes - 1)) ? '\n' : ','; if(_received_flits_out) *_received_flits_out << r->GetReceivedFlits(c) << trail_char; if(_stored_flits_out) *_stored_flits_out << r->GetStoredFlits(c) << trail_char; @@ -1956,7 +1962,7 @@ void TrafficManager::UpdateStats() { } for(int r = 0; r < _routers; ++r) { Router const * const rtr = _router[s][r]; - char trail_char = + char trail_char = ((r == _routers - 1) && (s == _subnets - 1)) ? '\n' : ','; if(_used_credits_out) *_used_credits_out << rtr->UsedCredits() << trail_char; if(_free_credits_out) *_free_credits_out << rtr->FreeCredits() << trail_char; @@ -1971,16 +1977,16 @@ void TrafficManager::UpdateStats() { } void TrafficManager::DisplayStats(ostream & os) const { - + for(int c = 0; c < _classes; ++c) { - + if(_measure_stats[c] == 0) { continue; } - + cout << "Class " << c << ":" << endl; - - cout + + cout << "Packet latency average = " << _plat_stats[c]->Average() << endl << "\tminimum = " << _plat_stats[c]->Min() << endl << "\tmaximum = " << _plat_stats[c]->Max() << endl @@ -1995,7 +2001,7 @@ void TrafficManager::DisplayStats(ostream & os) const { << "Fragmentation average = " << _frag_stats[c]->Average() << endl << "\tminimum = " << _frag_stats[c]->Min() << endl << "\tmaximum = " << _frag_stats[c]->Max() << endl; - + int count_sum, count_min, count_max; double rate_sum, rate_min, rate_max; double rate_avg; @@ -2009,7 +2015,7 @@ void TrafficManager::DisplayStats(ostream & os) const { rate_avg = rate_sum / (double)_nodes; sent_packets = count_sum; cout << "Injected packet rate average = " << rate_avg << endl - << "\tminimum = " << rate_min + << "\tminimum = " << rate_min << " (at node " << min_pos << ")" << endl << "\tmaximum = " << rate_max << " (at node " << max_pos << ")" << endl; @@ -2020,7 +2026,7 @@ void TrafficManager::DisplayStats(ostream & os) const { rate_avg = rate_sum / (double)_nodes; accepted_packets = count_sum; cout << "Accepted packet rate average = " << rate_avg << endl - << "\tminimum = " << rate_min + << "\tminimum = " << rate_min << " (at node " << min_pos << ")" << endl << "\tmaximum = " << rate_max << " (at node " << max_pos << ")" << endl; @@ -2031,7 +2037,7 @@ void TrafficManager::DisplayStats(ostream & os) const { rate_avg = rate_sum / (double)_nodes; sent_flits = count_sum; cout << "Injected flit rate average = " << rate_avg << endl - << "\tminimum = " << rate_min + << "\tminimum = " << rate_min << " (at node " << min_pos << ")" << endl << "\tmaximum = " << rate_max << " (at node " << max_pos << ")" << endl; @@ -2042,18 +2048,18 @@ void TrafficManager::DisplayStats(ostream & os) const { rate_avg = rate_sum / (double)_nodes; accepted_flits = count_sum; cout << "Accepted flit rate average= " << rate_avg << endl - << "\tminimum = " << rate_min + << "\tminimum = " << rate_min << " (at node " << min_pos << ")" << endl << "\tmaximum = " << rate_max << " (at node " << max_pos << ")" << endl; - + cout << "Injected packet length average = " << (double)sent_flits / (double)sent_packets << endl << "Accepted packet length average = " << (double)accepted_flits / (double)accepted_packets << endl; cout << "Total in-flight flits = " << _total_in_flight_flits[c].size() << " (" << _measured_in_flight_flits[c].size() << " measured)" << endl; - + #ifdef TRACK_STALLS _ComputeStats(_buffer_busy_stalls[c], &count_sum); rate_sum = (double)count_sum / time_delta; @@ -2076,7 +2082,7 @@ void TrafficManager::DisplayStats(ostream & os) const { rate_avg = rate_sum / (double)(_subnets*_routers); os << "Crossbar conflict stall rate = " << rate_avg << endl; #endif - + } } @@ -2090,7 +2096,7 @@ void TrafficManager::DisplayOverallStats( ostream & os ) const { } os << "====== Traffic class " << c << " ======" << endl; - + os << "Packet latency average = " << _overall_avg_plat[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; os << "\tminimum = " << _overall_min_plat[c] / (double)_total_sims @@ -2125,7 +2131,7 @@ void TrafficManager::DisplayOverallStats( ostream & os ) const { << " (" << _total_sims << " samples)" << endl; os << "\tmaximum = " << _overall_max_sent_packets[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; - + os << "Accepted packet rate average = " << _overall_avg_accepted_packets[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; os << "\tminimum = " << _overall_min_accepted_packets[c] / (double)_total_sims @@ -2139,23 +2145,23 @@ void TrafficManager::DisplayOverallStats( ostream & os ) const { << " (" << _total_sims << " samples)" << endl; os << "\tmaximum = " << _overall_max_sent[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; - + os << "Accepted flit rate average = " << _overall_avg_accepted[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; os << "\tminimum = " << _overall_min_accepted[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; os << "\tmaximum = " << _overall_max_accepted[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; - + os << "Injected packet size average = " << _overall_avg_sent[c] / _overall_avg_sent_packets[c] << " (" << _total_sims << " samples)" << endl; os << "Accepted packet size average = " << _overall_avg_accepted[c] / _overall_avg_accepted_packets[c] << " (" << _total_sims << " samples)" << endl; - + os << "Hops average = " << _overall_hop_stats[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; - + #ifdef TRACK_STALLS os << "Buffer busy stall rate = " << (double)_overall_buffer_busy_stalls[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl @@ -2168,9 +2174,9 @@ void TrafficManager::DisplayOverallStats( ostream & os ) const { << "Crossbar conflict stall rate = " << (double)_overall_crossbar_conflict_stalls[c] / (double)_total_sims << " (" << _total_sims << " samples)" << endl; #endif - + } - + } string TrafficManager::_OverallStatsCSV(int c) const @@ -2228,7 +2234,7 @@ void TrafficManager::DisplayOverallStatsCSV(ostream & os) const { void TrafficManager::_LoadWatchList(const string & filename){ ifstream watch_list; watch_list.open(filename.c_str()); - + string line; if(watch_list.is_open()) { while(!watch_list.eof()) { @@ -2241,7 +2247,7 @@ void TrafficManager::_LoadWatchList(const string & filename){ } } } - + } else { Error("Unable to open flit watch file: " + filename); } diff --git a/src/trafficmanager.hpp b/src/trafficmanager.hpp index 986d8b4a..5e91fdc1 100644 --- a/src/trafficmanager.hpp +++ b/src/trafficmanager.hpp @@ -265,12 +265,12 @@ class TrafficManager : public Module { virtual void _RetireFlit( Flit *f, int dest ); void _Inject(); - void _Step( ); - + virtual void _Step( ); + bool _PacketsOutstanding( ) const; virtual int _IssuePacket( int source, int cl ); - void _GeneratePacket( int source, int size, int cl, int time ); + virtual void _GeneratePacket( int source, int size, int cl, int time ); virtual void _ClearStats( ); From f12f1565873104d76e878b4a2aa4572bee390d92 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 4 Jan 2017 01:03:17 +0530 Subject: [PATCH 06/35] Added traffic manager for bufferless networks --- src/blesstrafficmanager.cpp | 276 ++++++++++++++++++++++++++++++++++++ src/blesstrafficmanager.hpp | 36 +++++ src/examples/meshbless | 73 ++++++++++ 3 files changed, 385 insertions(+) create mode 100644 src/blesstrafficmanager.cpp create mode 100644 src/blesstrafficmanager.hpp create mode 100644 src/examples/meshbless diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp new file mode 100644 index 00000000..290e0175 --- /dev/null +++ b/src/blesstrafficmanager.cpp @@ -0,0 +1,276 @@ +/* Ameya: new traffic manager to handle bufferless networks +*/ +#include +#include +#include +#include +#include +#include + +#include "blesstrafficmanager.hpp" +#include "random_utils.hpp" +#include "packet_reply_info.hpp" + +BlessTrafficManager::BlessTrafficManager( const Configuration &config, + const vector & net ) +: TrafficManager(config, net) {} + +BlessTrafficManager::~BlessTrafficManager( ) {} + +void BlessTrafficManager::_Step( ) +{ + bool flits_in_flight = false; + for(int c = 0; c < _classes; ++c) { + flits_in_flight |= !_total_in_flight_flits[c].empty(); + } + if(flits_in_flight && (_deadlock_timer++ >= _deadlock_warn_timeout)){ + _deadlock_timer = 0; + cout << "WARNING: Possible network deadlock.\n"; + } + + vector > flits(_subnets); + + for ( int subnet = 0; subnet < _subnets; ++subnet ) + { + for ( int n = 0; n < _nodes; ++n ) + { + Flit * const f = _net[subnet]->ReadFlit( n ); + if ( f ) + { + if(f->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << n << " | " + << "Ejecting flit " << f->id + << " (packet " << f->pid << ")" + << " from VC " << f->vc + << "." << endl; + } + flits[subnet].insert(make_pair(n, f)); + if((_sim_state == warming_up) || (_sim_state == running)) + { + ++_accepted_flits[f->cl][n]; + if(f->tail) + { + ++_accepted_packets[f->cl][n]; + } + } + } + } + _net[subnet]->ReadInputs( ); + } + + if ( !_empty_network ) { + _Inject(); + } + + for(int subnet = 0; subnet < _subnets; ++subnet) { + for(int n = 0; n < _nodes; ++n) { + Flit * f = NULL; + + int const last_class = _last_class[n][subnet]; + + int class_limit = _classes; + + for(int i = 1; i <= class_limit; ++i) + { + int const c = (last_class + i) % _classes; + + list & pp = _partial_packets[n][c]; + + if(pp.empty()) { + continue; + } + + f = pp.front(); + if( _net[subnet]->CheckInject(n) ) + { + f->itime = _time; + + _last_class[n][subnet] = f->cl; + + if(f->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << n << " | " + << "Injecting flit " << f->id + << " into subnet " << subnet + << " at time " << _time + << " with priority " << f->pri + << "." << endl; + } +#ifdef TRACK_FLOWS + ++_injected_flits[f->cl][n]; +#endif + + _net[subnet]->WriteFlit(f, n); + + pp.pop_front(); + } + } + } + } + + for(int subnet = 0; subnet < _subnets; ++subnet) + { + for(int n = 0; n < _nodes; ++n) + { + map::const_iterator iter = flits[subnet].find(n); + if(iter != flits[subnet].end()) + { + Flit * const f = iter->second; + + f->atime = _time; + +#ifdef TRACK_FLOWS + ++_ejected_flits[f->cl][n]; +#endif + + _RetireFlit(f, n); + } + } + flits[subnet].clear(); + _net[subnet]->Evaluate( ); + _net[subnet]->WriteOutputs( ); + } + + ++_time; + assert(_time); + if(gTrace) + { + cout<<"TIME "<<_time<dest(source); + bool record = false; + bool watch = gWatchOut && (_packets_to_watch.count(pid) > 0); + if(_use_read_write[cl]){ + if(stype > 0) { + if (stype == 1) { + packet_type = Flit::READ_REQUEST; + size = _read_request_size[cl]; + } else if (stype == 2) { + packet_type = Flit::WRITE_REQUEST; + size = _write_request_size[cl]; + } else { + ostringstream err; + err << "Invalid packet type: " << packet_type; + Error( err.str( ) ); + } + } else { + PacketReplyInfo* rinfo = _repliesPending[source].front(); + if (rinfo->type == Flit::READ_REQUEST) {//read reply + size = _read_reply_size[cl]; + packet_type = Flit::READ_REPLY; + } else if(rinfo->type == Flit::WRITE_REQUEST) { //write reply + size = _write_reply_size[cl]; + packet_type = Flit::WRITE_REPLY; + } else { + ostringstream err; + err << "Invalid packet type: " << rinfo->type; + Error( err.str( ) ); + } + packet_destination = rinfo->source; + time = rinfo->time; + record = rinfo->record; + _repliesPending[source].pop_front(); + rinfo->Free(); + } + } + + if ((packet_destination <0) || (packet_destination >= _nodes)) { + ostringstream err; + err << "Incorrect packet destination " << packet_destination + << " for stype " << packet_type; + Error( err.str( ) ); + } + + if ( ( _sim_state == running ) || + ( ( _sim_state == draining ) && ( time < _drain_time ) ) ) { + record = _measure_stats[cl]; + } + + int subnetwork = ((packet_type == Flit::ANY_TYPE) ? + RandomInt(_subnets-1) : + _subnet[packet_type]); + + if ( watch ) { + *gWatchOut << GetSimTime() << " | " + << "node" << source << " | " + << "Enqueuing packet " << pid + << " at time " << time + << "." << endl; + } + + for ( int i = 0; i < size; ++i ) { + Flit * f = Flit::New(); + f->id = _cur_id++; + assert(_cur_id); + f->pid = pid; + f->watch = watch | (gWatchOut && (_flits_to_watch.count(f->id) > 0)); + f->subnetwork = subnetwork; + f->src = source; + f->ctime = time; + f->record = record; + f->cl = cl; + + _total_in_flight_flits[f->cl].insert(make_pair(f->id, f)); + if(record) { + _measured_in_flight_flits[f->cl].insert(make_pair(f->id, f)); + } + + if(gTrace){ + cout<<"New Flit "<src<type = packet_type; + f->dest = packet_destination; + if ( i == 0 ) { // Head flit + f->head = true; + } else { + f->head = false; + } + // switch( _pri_type ) { + // case class_based: + // f->pri = _class_priority[cl]; + // assert(f->pri >= 0); + // break; + // case age_based: + // f->pri = numeric_limits::max() - time; + // assert(f->pri >= 0); + // break; + // case sequence_based: + // f->pri = numeric_limits::max() - _packet_seq_no[source]; + // assert(f->pri >= 0); + // break; + // default: + // f->pri = 0; + // } + f->pri = size - i; + if ( i == ( size - 1 ) ) { // Tail flit + f->tail = true; + } else { + f->tail = false; + } + + f->vc = -1; + + if ( f->watch ) { + *gWatchOut << GetSimTime() << " | " + << "node" << source << " | " + << "Enqueuing flit " << f->id + << " (packet " << f->pid + << ") at time " << time + << "." << endl; + } + + _partial_packets[source][cl].push_back( f ); + } +} \ No newline at end of file diff --git a/src/blesstrafficmanager.hpp b/src/blesstrafficmanager.hpp new file mode 100644 index 00000000..30da02cd --- /dev/null +++ b/src/blesstrafficmanager.hpp @@ -0,0 +1,36 @@ +/* Ameya: new traffic manager to handle bufferless networks +*/ + +#ifndef _BLESSTRAFFICMANAGER_HPP_ +#define _BLESSTRAFFICMANAGER_HPP_ + +#include + +#include "config_utils.hpp" +#include "stats.hpp" +#include "trafficmanager.hpp" + +class BlessTrafficManager : public TrafficManager { + +protected: + // virtual void _RetireFlit( Flit *f, int dest ); + + // virtual void _ClearStats( ); + virtual void _Step( ); + void _GeneratePacket( int source, int stype, int cl, int time ); + // virtual void _UpdateOverallStats( ); + + // virtual string _OverallStatsCSV(int c = 0) const; + +public: + + BlessTrafficManager( const Configuration &config, const vector & net ); + virtual ~BlessTrafficManager( ); + + // virtual void WriteStats( ostream & os = cout ) const; + // virtual void DisplayStats( ostream & os = cout ) const; + // virtual void DisplayOverallStats( ostream & os = cout ) const; + +}; + +#endif \ No newline at end of file diff --git a/src/examples/meshbless b/src/examples/meshbless new file mode 100644 index 00000000..dd5694a5 --- /dev/null +++ b/src/examples/meshbless @@ -0,0 +1,73 @@ +// $Id$ + +// Copyright (c) 2007-2015, Trustees of The Leland Stanford Junior University +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +//8X8 mesh with 20 flits per packet under injection mode +//injection rate here is packet per cycle, NOT flit per cycle + +// Topology + +topology = mesh; +k = 8; +n = 2; + +// Routing +routing_function = dor; + +// Flow control +num_vcs = 1; +vc_buf_size = 1; +wait_for_tail_credit = 0; + +// Router architecture +vc_allocator = islip; +sw_allocator = islip; +alloc_iters = 1; + +credit_delay = 2; +routing_delay = 0; +vc_alloc_delay = 1; +sw_alloc_delay = 1; + +input_speedup = 2; +output_speedup = 1; +internal_speedup = 1.0; + + +// Traffic +traffic = transpose; +packet_size = 4; + + +// Simulation +sim_type = latency; + +injection_rate = 0.005; + +//watch_file = /home/ameya/ProjectU/booksim2-master/tempwatch; + +bufferless = 1; + +router = chipper; From d4faac38f24f153dc3364ee7baaa0a553ebab0db Mon Sep 17 00:00:00 2001 From: sabersword Date: Mon, 9 Jan 2017 20:01:29 +0530 Subject: [PATCH 07/35] Added Golden packet functionality --- src/blesstrafficmanager.cpp | 169 ++++++++++++++++++++++++++++++++++-- src/blesstrafficmanager.hpp | 21 ++--- src/examples/mesh88_lat | 10 ++- src/examples/meshbless | 3 + src/examples/torus88 | 3 + src/flit.hpp | 2 + 6 files changed, 188 insertions(+), 20 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index 290e0175..b7d67195 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -13,7 +13,8 @@ BlessTrafficManager::BlessTrafficManager( const Configuration &config, const vector & net ) -: TrafficManager(config, net) {} +: TrafficManager(config, net), _golden_turn(0), _golden_in_flight(0) +{} BlessTrafficManager::~BlessTrafficManager( ) {} @@ -253,11 +254,24 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, // default: // f->pri = 0; // } - f->pri = size - i; - if ( i == ( size - 1 ) ) { // Tail flit - f->tail = true; - } else { - f->tail = false; + // f->pri = size - i; + // if ( i == ( size - 1 ) ) { // Tail flit + // f->tail = true; + // } else { + // f->tail = false; + // } + + f->pri = numeric_limits::max() - time; + assert(f->pri >= 0); + + if(!_IsGoldenInFlight() && _IsGoldenTurn(source)) + { + f->golden = 1; + _golden_flits.push_back(f->id); + } + else + { + f->golden = 0; } f->vc = -1; @@ -268,9 +282,152 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, << "Enqueuing flit " << f->id << " (packet " << f->pid << ") at time " << time + << " with golden status " << f->golden << "." << endl; } _partial_packets[source][cl].push_back( f ); } + + if(!_IsGoldenInFlight() && _IsGoldenTurn(source)) + { + assert(!_golden_flits.empty()); + _UpdateGoldenStatus(source); + } +} + +void BlessTrafficManager::_UpdateGoldenStatus( int source ) +{ + _golden_in_flight = 1; + _golden_turn = (source + 1)%_nodes; +} + +void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) +{ + _deadlock_timer = 0; + + assert(_total_in_flight_flits[f->cl].count(f->id) > 0); + _total_in_flight_flits[f->cl].erase(f->id); + + if(f->record) { + assert(_measured_in_flight_flits[f->cl].count(f->id) > 0); + _measured_in_flight_flits[f->cl].erase(f->id); + } + + if ( f->watch ) { + *gWatchOut << GetSimTime() << " | " + << "node" << dest << " | " + << "Retiring flit " << f->id + << " (packet " << f->pid + << ", src = " << f->src + << ", dest = " << f->dest + << ", golden = " << f->golden + << ", hops = " << f->hops + << ", flat = " << f->atime - f->itime + << ")." << endl; + } + + if ( f->dest != dest ) { + ostringstream err; + err << "Flit " << f->id << " arrived at incorrect output " << dest; + Error( err.str( ) ); + } + + if((_slowest_flit[f->cl] < 0) || + (_flat_stats[f->cl]->Max() < (f->atime - f->itime))) + _slowest_flit[f->cl] = f->id; + _flat_stats[f->cl]->AddSample( f->atime - f->itime); + if(_pair_stats){ + _pair_flat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - f->itime ); + } + + if ( f->tail ) { + Flit * head; + if(f->head) { + head = f; + } else { + map::iterator iter = _retired_packets[f->cl].find(f->pid); + assert(iter != _retired_packets[f->cl].end()); + head = iter->second; + _retired_packets[f->cl].erase(iter); + assert(head->head); + assert(f->pid == head->pid); + } + if ( f->watch ) { + *gWatchOut << GetSimTime() << " | " + << "node" << dest << " | " + << "Retiring packet " << f->pid + << " (plat = " << f->atime - head->ctime + << ", nlat = " << f->atime - head->itime + << ", frag = " << (f->atime - head->atime) - (f->id - head->id) // NB: In the spirit of solving problems using ugly hacks, we compute the packet length by taking advantage of the fact that the IDs of flits within a packet are contiguous. + << ", src = " << head->src + << ", dest = " << head->dest + << ", golden = " << head->golden + << ")." << endl; + } + + //code the source of request, look carefully, its tricky ;) + if (f->type == Flit::READ_REQUEST || f->type == Flit::WRITE_REQUEST) { + PacketReplyInfo* rinfo = PacketReplyInfo::New(); + rinfo->source = f->src; + rinfo->time = f->atime; + rinfo->record = f->record; + rinfo->type = f->type; + _repliesPending[dest].push_back(rinfo); + } else { + if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY ){ + _requestsOutstanding[dest]--; + } else if(f->type == Flit::ANY_TYPE) { + _requestsOutstanding[f->src]--; + } + + } + + // Only record statistics once per packet (at tail) + // and based on the simulation state + if ( ( _sim_state == warming_up ) || f->record ) { + + _hop_stats[f->cl]->AddSample( f->hops ); + + if((_slowest_packet[f->cl] < 0) || + (_plat_stats[f->cl]->Max() < (f->atime - head->itime))) + _slowest_packet[f->cl] = f->pid; + _plat_stats[f->cl]->AddSample( f->atime - head->ctime); + _nlat_stats[f->cl]->AddSample( f->atime - head->itime); + _frag_stats[f->cl]->AddSample( (f->atime - head->atime) - (f->id - head->id) ); + + if(_pair_stats){ + _pair_plat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->ctime ); + _pair_nlat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->itime ); + } + } + + if(f != head) { + head->Free(); + } + + } + + if(f->golden) + { + if ( _golden_flits.empty() ) + { + ostringstream err; + err << "Flit " << f->id << " claiming to be golden at " << dest; + Error( err.str( ) ); + } + vector::iterator it = find( _golden_flits.begin(), _golden_flits.end(), f->id ); + assert( it != _golden_flits.end()); + _golden_flits.erase(it); + if( _golden_flits.empty() ) + { + _golden_in_flight = 0; + } + } + + if(f->head && !f->tail) { + _retired_packets[f->cl].insert(make_pair(f->pid, f)); + } else { + f->Free(); + } } \ No newline at end of file diff --git a/src/blesstrafficmanager.hpp b/src/blesstrafficmanager.hpp index 30da02cd..61297877 100644 --- a/src/blesstrafficmanager.hpp +++ b/src/blesstrafficmanager.hpp @@ -5,32 +5,33 @@ #define _BLESSTRAFFICMANAGER_HPP_ #include +#include +#include #include "config_utils.hpp" #include "stats.hpp" #include "trafficmanager.hpp" class BlessTrafficManager : public TrafficManager { +private: + int _golden_turn; + int _golden_in_flight; + vector _golden_flits; protected: - // virtual void _RetireFlit( Flit *f, int dest ); - // virtual void _ClearStats( ); + int _IsGoldenTurn( int source ) { return (_golden_turn == source);} + int _IsGoldenInFlight() { return _golden_in_flight; } + void _UpdateGoldenStatus( int source ); + void _RetireFlit( Flit *f, int dest ); virtual void _Step( ); void _GeneratePacket( int source, int stype, int cl, int time ); - // virtual void _UpdateOverallStats( ); - - // virtual string _OverallStatsCSV(int c = 0) const; - + public: BlessTrafficManager( const Configuration &config, const vector & net ); virtual ~BlessTrafficManager( ); - // virtual void WriteStats( ostream & os = cout ) const; - // virtual void DisplayStats( ostream & os = cout ) const; - // virtual void DisplayOverallStats( ostream & os = cout ) const; - }; #endif \ No newline at end of file diff --git a/src/examples/mesh88_lat b/src/examples/mesh88_lat index 0faf45bd..43a90d81 100644 --- a/src/examples/mesh88_lat +++ b/src/examples/mesh88_lat @@ -37,9 +37,9 @@ n = 2; routing_function = dor; // Flow control -num_vcs = 8; -vc_buf_size = 8; -wait_for_tail_credit = 1; +num_vcs = 1; +vc_buf_size = 1; +wait_for_tail_credit = 0; // Router architecture vc_allocator = islip; @@ -58,7 +58,7 @@ internal_speedup = 1.0; // Traffic traffic = transpose; -packet_size = 20; +packet_size = 4; // Simulation @@ -66,3 +66,5 @@ sim_type = latency; injection_rate = 0.005; +watch_file=tempwatch; +watch_out=tempout; diff --git a/src/examples/meshbless b/src/examples/meshbless index dd5694a5..eab60fa4 100644 --- a/src/examples/meshbless +++ b/src/examples/meshbless @@ -71,3 +71,6 @@ injection_rate = 0.005; bufferless = 1; router = chipper; + +watch_file=tempwatch; +watch_out=tempout; diff --git a/src/examples/torus88 b/src/examples/torus88 index bfe61ad9..c75f6f17 100644 --- a/src/examples/torus88 +++ b/src/examples/torus88 @@ -38,3 +38,6 @@ num_vcs = 2; // Traffic traffic = uniform; injection_rate = 0.15; + +watch_file=tempwatch; +watch_out=tempout; diff --git a/src/flit.hpp b/src/flit.hpp index a28d6ac0..ad220180 100644 --- a/src/flit.hpp +++ b/src/flit.hpp @@ -66,6 +66,8 @@ class Flit { int dest; int pri; + // Ameya: For bufferless routing + int golden; int hops; bool watch; From ba94cc2e0d61ebd32bfcea2926c00ee500547f57 Mon Sep 17 00:00:00 2001 From: nandanbedekar Date: Mon, 9 Jan 2017 15:24:10 -0100 Subject: [PATCH 08/35] Add files via upload --- src/routers/chipper.cpp | 119 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 112 insertions(+), 7 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 18e09717..3e65640b 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -92,17 +92,122 @@ void Chipper::Display( ostream & os ) const os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func } -void Chipper::ReadInputs() +void Chipper::ReadInputs() // HH : Performs the function of reading flits from channel into input buffer { - cout << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func + // HH : Receiving flits from channel into input buffer, no credits received, as in event_router } -void Chipper::WriteOutputs() +// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time +int Chipper::_IncomingFlits( ) { - cout << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func + Flit *f; + map< int,Flit* > buffer_timed; + receive_time = GetSimTime(); + for ( int input = 0; input < _inputs; ++input ) { + f = _input_channels[input]->Receive(); + if ( f ) { + _input_buffer[input].insert( pair(receive_time,f) ); + } + } } -void Chipper::_InternalStep() +void Chipper::WriteOutputs() // HH : Performs the function of sending flits from output buffer into channel { - cout << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func -} \ No newline at end of file + _SendFlits( ); //HH : Sending flits from output buffer into input channel, no credits sent, as in event_router +} + +// HH Definition of _Sendflits in Chipper class same as that in class event_router +void Chipper::_SendFlits( int pair_time) +{ + map buffer_timed; + Flit *f; + for ( int output = 0; output < _outputs; ++output ) { + //if ( !_output_buffer[output].empty( ) ) { + //Flit *f = _output_buffer[output].front( ); + //_output_buffer[output].pop( ); + //_output_channels[output]->Send( f ); + buffer_timed = _output_buffer.back; + f = buffer_timed.find( pair_time); + if(f){ + _output_channels[output]->Send( f ); + } + } + } + +void Chipper::_InternalStep( ) +{ + // Receive incoming flits + int pair_time = _IncomingFlits( ); + //HH : Need to make the time the flits are received global in order to know when the input flits were +// were paired into the map + //Have to pass this onto subsequent functions to find the correct flit from each buffer + // I am thinking pair_time should be updated at each stage with GetSimTime and then passed onto next stage + // Eject flits which have reached their desitnation + _EjectFlits(); + + _Buffer_to_stage1(); + + _stage1_to_stage2(); + + + +} + +// Added by HH + void _EjectFlits(){ + Flit *f; + + for ( int input = 0; input < _inputs; ++input ) { + // f = _input_buffer[input].pop; + + if ( f->dest == GetID() ) { + ; + } + else if { + + } + else + } + } + + void Chipper::_Buffer_to_stage1() +{ + map intermediate_1; + int input = 0; + for ( int input = 0; input < _inputs; ++input ){ + intermediate = _input_buffer[input]; + for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe + if(pair_time == it->first){ + it->first = it->first + delay_pipe_1; + } + } + stage_1[input] = _input_buffer[input]; + } +} + +void Chipper::_stage1_to_stage2() +{ + msp intermediate_2; + int input = 0; + for ( int input = 0; input < _inputs; ++input ){ // Nandan: Adding the delay associated with the pipe + intermediate = _stage_1[input]; + for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ + if(pair_time == it->first){ + it->first = it->first + delay_pipe_2; + } + } + stage_2[input] = _stage_1[input]; + } +} +// Added by HH : scheme for determining Golden_packet as in chipper paper(not exactly) +// Returning the packet id that is to be made golden by just dividing time_elapsed by L instead of +// keeping track of all the packets in the network. (I don't know if a maximum number of packets is available) +// Instead of iterating over all possible packet ids called "transaction ids" from all nodes, just iterate over +// packet ids which uniquely identifies each packet +int Chipper::Golden_Packet(int L) // Parameter L is obtained from before from another function +{ + int time_elapsed = GetSimTime(); + int epoch_no = time_elapsed/L; // L is the golden epoch, needs to be defined as the upper + //bound of the maximum time taken by a golden packet to reach its destination + return epoch_no; +} From fe8ae3b2c970640e951c0b783ac221ec79d1cca5 Mon Sep 17 00:00:00 2001 From: sabersword Date: Tue, 10 Jan 2017 11:35:46 +0530 Subject: [PATCH 09/35] Updated flit priority at inject --- src/blesstrafficmanager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index b7d67195..08126b35 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -86,6 +86,8 @@ void BlessTrafficManager::_Step( ) if( _net[subnet]->CheckInject(n) ) { f->itime = _time; + f->pri = numeric_limits::max() - f->itime; + assert(f->pri >= 0); _last_class[n][subnet] = f->cl; From d74212d4da47f5abcfb5aaa293ff4d6b830ffe40 Mon Sep 17 00:00:00 2001 From: hariharan-n Date: Thu, 12 Jan 2017 22:27:13 +0530 Subject: [PATCH 10/35] Add files via upload Added eject flits function in chipper.cpp along with other minor functions Add permute routes --- chipper .cpp | 378 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 chipper .cpp diff --git a/chipper .cpp b/chipper .cpp new file mode 100644 index 00000000..5a944a3f --- /dev/null +++ b/chipper .cpp @@ -0,0 +1,378 @@ +// Ameya: Remove redundancies +#include +#include +#include +#include +#include + +#include "chipper.hpp" +#include "stats.hpp" +#include "globals.hpp" +#include "routefunc.hpp" + +int retire_index = 4; // HH : For mesh, ejection is through _output_channels[4]; + +Chipper::Chipper( const Configuration& config, + Module *parent, const string & name, int id, + int inputs, int outputs ) + : Router( config, + parent, name, + id, + inputs, outputs ) +{ + ostringstream module_name; + + // Routing + + string rf = config.GetStr("routing_function") + "_" + config.GetStr("topology"); + map::iterator rf_iter = gRoutingFunctionMap.find(rf); + if(rf_iter == gRoutingFunctionMap.end()) { + Error("Invalid routing function: " + rf); + } + _rf = rf_iter->second; + + assert(_inputs == _outputs); + + _input_buffer.resize(_inputs-1); + _output_buffer.resize(_outputs-1); + + _stage_1.resize(_inputs-1); + _stage_2.resize(_inputs-1); +} + +Chipper::~Chipper() +{ + for ( int i = 0; i < _inputs; ++i ) { + while (!_input_buffer[i].empty()) + { + (_input_buffer[i].begin()->second)->Free(); + _input_buffer[i].erase(_input_buffer[i].begin()); + } + } + + for ( int i = 0; i < _inputs; ++i ) { + while (!_stage_1[i].empty()) + { + (_stage_1[i].begin()->second)->Free(); + _stage_1.erase(_stage_1.begin()); + } + } + + for ( int i = 0; i < _inputs; ++i ) { + while (!_stage_2[i].empty()) + { + (_stage_2[i].begin()->second)->Free(); + _stage_2.erase(_stage_2.begin()); + } + } + + for ( int o = 0; o < _outputs; ++o ) { + while (!_output_buffer[o].empty()) + { + (_output_buffer[o].begin()->second)->Free(); + _output_buffer[o].erase(_output_buffer[o].begin()); + } + } +} + +void Chipper::AddInputChannel( FlitChannel *channel, CreditChannel * ignored) +{ + // Ameya: credit channel ignored + _input_channels.push_back( channel ); + channel->SetSink( this, _input_channels.size() - 1 ) ; +} + +void Chipper::AddOutputChannel(FlitChannel * channel, CreditChannel * ignored) +{ + // Ameya: credit channel ignored + _output_channels.push_back( channel ); + _channel_faults.push_back( false ); + channel->SetSource( this, _output_channels.size() - 1 ) ; +} + +void Chipper::Display( ostream & os ) const +{ + os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func +} + +void Chipper::ReadInputs() // HH : Performs the function of reading flits from channel into input buffer +{ + // HH : Receiving flits from channel into input buffer, no credits received, as in event_router +} + +// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time +int Chipper::_IncomingFlits( ) +{ + Flit *f; + map< int,Flit* > buffer_timed; + receive_time = GetSimTime(); + for ( int input = 0; input < _inputs; ++input ) { + f = _input_channels[input]->Receive(); + if ( f ) { + _input_buffer[input].insert( pair(receive_time,f) ); + } + } +} + +void Chipper::WriteOutputs() // HH : Performs the function of sending flits from output buffer into channel +{ + _SendFlits( ); //HH : Sending flits from output buffer into input channel, no credits sent, as in event_router +} + +// HH Definition of _Sendflits in Chipper class same as that in class event_router +void Chipper::_SendFlits( int pair_time) +{ + map buffer_timed; + Flit *f; + for ( int output = 0; output < _outputs; ++output ) { + //if ( !_output_buffer[output].empty( ) ) { + //Flit *f = _output_buffer[output].front( ); + //_output_buffer[output].pop( ); + //_output_channels[output]->Send( f ); + buffer_timed = _output_buffer.back; + f = buffer_timed.find( pair_time); + if(f){ + _output_channels[output]->Send( f ); + } + } + } + +void Chipper::_InternalStep( ) +{ + // Receive incoming flits + int pair_time = _IncomingFlits( ); + //HH : Need to make the time the flits are received global in order to know when the input flits were +// were paired into the map + //Have to pass this onto subsequent functions to find the correct flit from each buffer + // I am thinking pair_time should be updated at each stage with GetSimTime and then passed onto next stage + // Eject flits which have reached their desitnation + _EjectFlits(); + + _Buffer_to_stage1(); + + _stage1_to_stage2(); + + + +} + +// Added by HH + void _EjectFlits(){ + array Flit *f received_flits[_inputs]; // To keep track of all the flits that need to be ejected + int flit_to_eject = -1; + int golden_cnt = 0; + for ( int input = 0; input < _inputs-1; ++input ) { + // One input channel is for the router + // f = _input_buffer[input].pop; + + if ( f->dest == GetID() ) { + received_flits[input] = f; + // Check for golden status and golden tie + if(f->golden == 1 && !golden_cnt) + { + flit_to_eject = input; + golden_cnt++; + } + else if(f->golden == 1) + { + if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit + { + flit_to_eject = input; + break; + } + } + } + else{ + received_flits[input] = NULL; // Flit not at destination + } + if(flit_to_eject == -1){ + for( int input = 0; input < _inputs-1; ++input ){ + // Iterating through the array of stored flits that need to be ejected + // to find the oldest flit and consequently retiring that flit + int oldest_flit_index; + int high_pri = -1; + if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) + { + high_pri = received_flits[input]->pri; + oldest_flit_index = input; + } + if(high_pri > -1) + { + flit_to_eject = oldest_flit_index; + _output_channels[retire_index] = received_flits[flit_to_eject]; + // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit + } + } + } + } + + + void Chipper::_Buffer_to_stage1() +{ + // map intermediate_1; + int input = 0; + map::iterator it; + for ( int input = 0; input < _inputs; ++input ){ + // intermediate = _input_buffer[input]; + // for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe + // if(pair_time == it->first){ + // it->first = it->first + 1; + // } + // } + it =_input_buffer[input].find(GetSimTime()); + if(it == _input_buffer[input].end()) + continue; + _stage_1[input].insert(make_pair(it->first+1, it->second)); + _input_buffer[input].erase(it); + } +} + +void Chipper::_stage1_to_stage2() +{ + // msp intermediate_2; + int input = 0; + for ( int input = 0; input < _inputs; ++input ){ // Nandan: Adding the delay associated with the pipe + // intermediate = _stage_1[input]; + // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ + // if(pair_time == it->first){ + // it->first = it->first + 1; + // } + // } + it = _stage_1[input].find(GetSimTime()); + if(it == _stage_1[input].end()) + continue; + _stage_2[input].insert(make_pair(it->first+1, it->second)); + _stage_1[input].erase(it); + } +} + +void Chipper::Permute() +{ + // int router_number = GetID(); + // int west = _LeftNode(router_number, 0); + // int east = _RightNode(router_number, 0); + // int north = _LeftNode(router_number, 1); + // int south = _RightNode(router_number, 1); + // vector direction; + // vector priority; + // vector golden; + // direction.resize(_inputs-1); + // priority.resize(_inputs-1); + // for(input = 0; input < _inputs; ++input) + // { + + // if(golden[input] == true) + Partial_Permute(2,0,1); + Partial_Permute(3,1,1); + Partial_Permute(3,2,2); + Partial_Permute(1,0,0); + // } +} + +void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) +{ + Flit *f1; + Flit *f2; + map iterator it1,it2; + it1 = _stage_2[dir1].find(GetSimTime()); + it2 = _stage_2[dir2].find(GetSimTime()); + *f1 = it1->second; + *f2 = it2->second; + if((f1->golden == 1)&&(f2->golden == 1)) + { + if(f1->pri >= f2->pri) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + } + else if((f1->golden == 1)) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else if((f2->golden == 1)) + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + else + { + if(f1->pri >= f2->pri) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + + } +} +// Added by HH : scheme for determining Golden_packet as in chipper paper(not exactly) +// Returning the packet id that is to be made golden by just dividing time_elapsed by L instead of +// keeping track of all the packets in the network. (I don't know if a maximum number of packets is available) +// Instead of iterating over all possible packet ids called "transaction ids" from all nodes, just iterate over +// packet ids which uniquely identifies each packet + From 1ad7a80230337748e113333a2baba4df41f501bc Mon Sep 17 00:00:00 2001 From: hariharan-n Date: Fri, 13 Jan 2017 20:52:52 +0530 Subject: [PATCH 11/35] Add files via upload Added eject flits and some minor changes Add permute routes --- chipper.cpp | 378 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 chipper.cpp diff --git a/chipper.cpp b/chipper.cpp new file mode 100644 index 00000000..5a944a3f --- /dev/null +++ b/chipper.cpp @@ -0,0 +1,378 @@ +// Ameya: Remove redundancies +#include +#include +#include +#include +#include + +#include "chipper.hpp" +#include "stats.hpp" +#include "globals.hpp" +#include "routefunc.hpp" + +int retire_index = 4; // HH : For mesh, ejection is through _output_channels[4]; + +Chipper::Chipper( const Configuration& config, + Module *parent, const string & name, int id, + int inputs, int outputs ) + : Router( config, + parent, name, + id, + inputs, outputs ) +{ + ostringstream module_name; + + // Routing + + string rf = config.GetStr("routing_function") + "_" + config.GetStr("topology"); + map::iterator rf_iter = gRoutingFunctionMap.find(rf); + if(rf_iter == gRoutingFunctionMap.end()) { + Error("Invalid routing function: " + rf); + } + _rf = rf_iter->second; + + assert(_inputs == _outputs); + + _input_buffer.resize(_inputs-1); + _output_buffer.resize(_outputs-1); + + _stage_1.resize(_inputs-1); + _stage_2.resize(_inputs-1); +} + +Chipper::~Chipper() +{ + for ( int i = 0; i < _inputs; ++i ) { + while (!_input_buffer[i].empty()) + { + (_input_buffer[i].begin()->second)->Free(); + _input_buffer[i].erase(_input_buffer[i].begin()); + } + } + + for ( int i = 0; i < _inputs; ++i ) { + while (!_stage_1[i].empty()) + { + (_stage_1[i].begin()->second)->Free(); + _stage_1.erase(_stage_1.begin()); + } + } + + for ( int i = 0; i < _inputs; ++i ) { + while (!_stage_2[i].empty()) + { + (_stage_2[i].begin()->second)->Free(); + _stage_2.erase(_stage_2.begin()); + } + } + + for ( int o = 0; o < _outputs; ++o ) { + while (!_output_buffer[o].empty()) + { + (_output_buffer[o].begin()->second)->Free(); + _output_buffer[o].erase(_output_buffer[o].begin()); + } + } +} + +void Chipper::AddInputChannel( FlitChannel *channel, CreditChannel * ignored) +{ + // Ameya: credit channel ignored + _input_channels.push_back( channel ); + channel->SetSink( this, _input_channels.size() - 1 ) ; +} + +void Chipper::AddOutputChannel(FlitChannel * channel, CreditChannel * ignored) +{ + // Ameya: credit channel ignored + _output_channels.push_back( channel ); + _channel_faults.push_back( false ); + channel->SetSource( this, _output_channels.size() - 1 ) ; +} + +void Chipper::Display( ostream & os ) const +{ + os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func +} + +void Chipper::ReadInputs() // HH : Performs the function of reading flits from channel into input buffer +{ + // HH : Receiving flits from channel into input buffer, no credits received, as in event_router +} + +// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time +int Chipper::_IncomingFlits( ) +{ + Flit *f; + map< int,Flit* > buffer_timed; + receive_time = GetSimTime(); + for ( int input = 0; input < _inputs; ++input ) { + f = _input_channels[input]->Receive(); + if ( f ) { + _input_buffer[input].insert( pair(receive_time,f) ); + } + } +} + +void Chipper::WriteOutputs() // HH : Performs the function of sending flits from output buffer into channel +{ + _SendFlits( ); //HH : Sending flits from output buffer into input channel, no credits sent, as in event_router +} + +// HH Definition of _Sendflits in Chipper class same as that in class event_router +void Chipper::_SendFlits( int pair_time) +{ + map buffer_timed; + Flit *f; + for ( int output = 0; output < _outputs; ++output ) { + //if ( !_output_buffer[output].empty( ) ) { + //Flit *f = _output_buffer[output].front( ); + //_output_buffer[output].pop( ); + //_output_channels[output]->Send( f ); + buffer_timed = _output_buffer.back; + f = buffer_timed.find( pair_time); + if(f){ + _output_channels[output]->Send( f ); + } + } + } + +void Chipper::_InternalStep( ) +{ + // Receive incoming flits + int pair_time = _IncomingFlits( ); + //HH : Need to make the time the flits are received global in order to know when the input flits were +// were paired into the map + //Have to pass this onto subsequent functions to find the correct flit from each buffer + // I am thinking pair_time should be updated at each stage with GetSimTime and then passed onto next stage + // Eject flits which have reached their desitnation + _EjectFlits(); + + _Buffer_to_stage1(); + + _stage1_to_stage2(); + + + +} + +// Added by HH + void _EjectFlits(){ + array Flit *f received_flits[_inputs]; // To keep track of all the flits that need to be ejected + int flit_to_eject = -1; + int golden_cnt = 0; + for ( int input = 0; input < _inputs-1; ++input ) { + // One input channel is for the router + // f = _input_buffer[input].pop; + + if ( f->dest == GetID() ) { + received_flits[input] = f; + // Check for golden status and golden tie + if(f->golden == 1 && !golden_cnt) + { + flit_to_eject = input; + golden_cnt++; + } + else if(f->golden == 1) + { + if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit + { + flit_to_eject = input; + break; + } + } + } + else{ + received_flits[input] = NULL; // Flit not at destination + } + if(flit_to_eject == -1){ + for( int input = 0; input < _inputs-1; ++input ){ + // Iterating through the array of stored flits that need to be ejected + // to find the oldest flit and consequently retiring that flit + int oldest_flit_index; + int high_pri = -1; + if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) + { + high_pri = received_flits[input]->pri; + oldest_flit_index = input; + } + if(high_pri > -1) + { + flit_to_eject = oldest_flit_index; + _output_channels[retire_index] = received_flits[flit_to_eject]; + // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit + } + } + } + } + + + void Chipper::_Buffer_to_stage1() +{ + // map intermediate_1; + int input = 0; + map::iterator it; + for ( int input = 0; input < _inputs; ++input ){ + // intermediate = _input_buffer[input]; + // for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe + // if(pair_time == it->first){ + // it->first = it->first + 1; + // } + // } + it =_input_buffer[input].find(GetSimTime()); + if(it == _input_buffer[input].end()) + continue; + _stage_1[input].insert(make_pair(it->first+1, it->second)); + _input_buffer[input].erase(it); + } +} + +void Chipper::_stage1_to_stage2() +{ + // msp intermediate_2; + int input = 0; + for ( int input = 0; input < _inputs; ++input ){ // Nandan: Adding the delay associated with the pipe + // intermediate = _stage_1[input]; + // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ + // if(pair_time == it->first){ + // it->first = it->first + 1; + // } + // } + it = _stage_1[input].find(GetSimTime()); + if(it == _stage_1[input].end()) + continue; + _stage_2[input].insert(make_pair(it->first+1, it->second)); + _stage_1[input].erase(it); + } +} + +void Chipper::Permute() +{ + // int router_number = GetID(); + // int west = _LeftNode(router_number, 0); + // int east = _RightNode(router_number, 0); + // int north = _LeftNode(router_number, 1); + // int south = _RightNode(router_number, 1); + // vector direction; + // vector priority; + // vector golden; + // direction.resize(_inputs-1); + // priority.resize(_inputs-1); + // for(input = 0; input < _inputs; ++input) + // { + + // if(golden[input] == true) + Partial_Permute(2,0,1); + Partial_Permute(3,1,1); + Partial_Permute(3,2,2); + Partial_Permute(1,0,0); + // } +} + +void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) +{ + Flit *f1; + Flit *f2; + map iterator it1,it2; + it1 = _stage_2[dir1].find(GetSimTime()); + it2 = _stage_2[dir2].find(GetSimTime()); + *f1 = it1->second; + *f2 = it2->second; + if((f1->golden == 1)&&(f2->golden == 1)) + { + if(f1->pri >= f2->pri) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + } + else if((f1->golden == 1)) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else if((f2->golden == 1)) + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + else + { + if(f1->pri >= f2->pri) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + + } +} +// Added by HH : scheme for determining Golden_packet as in chipper paper(not exactly) +// Returning the packet id that is to be made golden by just dividing time_elapsed by L instead of +// keeping track of all the packets in the network. (I don't know if a maximum number of packets is available) +// Instead of iterating over all possible packet ids called "transaction ids" from all nodes, just iterate over +// packet ids which uniquely identifies each packet + From 4adb5eff5a472b1d805c2eb21d0b88414f329579 Mon Sep 17 00:00:00 2001 From: hariharan-n Date: Fri, 13 Jan 2017 22:03:58 +0530 Subject: [PATCH 12/35] Add files via upload From 29f69337252baac4581bc093f5e1a9fe0f05966d Mon Sep 17 00:00:00 2001 From: hariharan-n Date: Fri, 13 Jan 2017 22:08:32 +0530 Subject: [PATCH 13/35] Delete chipper .cpp --- chipper .cpp | 378 --------------------------------------------------- 1 file changed, 378 deletions(-) delete mode 100644 chipper .cpp diff --git a/chipper .cpp b/chipper .cpp deleted file mode 100644 index 5a944a3f..00000000 --- a/chipper .cpp +++ /dev/null @@ -1,378 +0,0 @@ -// Ameya: Remove redundancies -#include -#include -#include -#include -#include - -#include "chipper.hpp" -#include "stats.hpp" -#include "globals.hpp" -#include "routefunc.hpp" - -int retire_index = 4; // HH : For mesh, ejection is through _output_channels[4]; - -Chipper::Chipper( const Configuration& config, - Module *parent, const string & name, int id, - int inputs, int outputs ) - : Router( config, - parent, name, - id, - inputs, outputs ) -{ - ostringstream module_name; - - // Routing - - string rf = config.GetStr("routing_function") + "_" + config.GetStr("topology"); - map::iterator rf_iter = gRoutingFunctionMap.find(rf); - if(rf_iter == gRoutingFunctionMap.end()) { - Error("Invalid routing function: " + rf); - } - _rf = rf_iter->second; - - assert(_inputs == _outputs); - - _input_buffer.resize(_inputs-1); - _output_buffer.resize(_outputs-1); - - _stage_1.resize(_inputs-1); - _stage_2.resize(_inputs-1); -} - -Chipper::~Chipper() -{ - for ( int i = 0; i < _inputs; ++i ) { - while (!_input_buffer[i].empty()) - { - (_input_buffer[i].begin()->second)->Free(); - _input_buffer[i].erase(_input_buffer[i].begin()); - } - } - - for ( int i = 0; i < _inputs; ++i ) { - while (!_stage_1[i].empty()) - { - (_stage_1[i].begin()->second)->Free(); - _stage_1.erase(_stage_1.begin()); - } - } - - for ( int i = 0; i < _inputs; ++i ) { - while (!_stage_2[i].empty()) - { - (_stage_2[i].begin()->second)->Free(); - _stage_2.erase(_stage_2.begin()); - } - } - - for ( int o = 0; o < _outputs; ++o ) { - while (!_output_buffer[o].empty()) - { - (_output_buffer[o].begin()->second)->Free(); - _output_buffer[o].erase(_output_buffer[o].begin()); - } - } -} - -void Chipper::AddInputChannel( FlitChannel *channel, CreditChannel * ignored) -{ - // Ameya: credit channel ignored - _input_channels.push_back( channel ); - channel->SetSink( this, _input_channels.size() - 1 ) ; -} - -void Chipper::AddOutputChannel(FlitChannel * channel, CreditChannel * ignored) -{ - // Ameya: credit channel ignored - _output_channels.push_back( channel ); - _channel_faults.push_back( false ); - channel->SetSource( this, _output_channels.size() - 1 ) ; -} - -void Chipper::Display( ostream & os ) const -{ - os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func -} - -void Chipper::ReadInputs() // HH : Performs the function of reading flits from channel into input buffer -{ - // HH : Receiving flits from channel into input buffer, no credits received, as in event_router -} - -// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time -int Chipper::_IncomingFlits( ) -{ - Flit *f; - map< int,Flit* > buffer_timed; - receive_time = GetSimTime(); - for ( int input = 0; input < _inputs; ++input ) { - f = _input_channels[input]->Receive(); - if ( f ) { - _input_buffer[input].insert( pair(receive_time,f) ); - } - } -} - -void Chipper::WriteOutputs() // HH : Performs the function of sending flits from output buffer into channel -{ - _SendFlits( ); //HH : Sending flits from output buffer into input channel, no credits sent, as in event_router -} - -// HH Definition of _Sendflits in Chipper class same as that in class event_router -void Chipper::_SendFlits( int pair_time) -{ - map buffer_timed; - Flit *f; - for ( int output = 0; output < _outputs; ++output ) { - //if ( !_output_buffer[output].empty( ) ) { - //Flit *f = _output_buffer[output].front( ); - //_output_buffer[output].pop( ); - //_output_channels[output]->Send( f ); - buffer_timed = _output_buffer.back; - f = buffer_timed.find( pair_time); - if(f){ - _output_channels[output]->Send( f ); - } - } - } - -void Chipper::_InternalStep( ) -{ - // Receive incoming flits - int pair_time = _IncomingFlits( ); - //HH : Need to make the time the flits are received global in order to know when the input flits were -// were paired into the map - //Have to pass this onto subsequent functions to find the correct flit from each buffer - // I am thinking pair_time should be updated at each stage with GetSimTime and then passed onto next stage - // Eject flits which have reached their desitnation - _EjectFlits(); - - _Buffer_to_stage1(); - - _stage1_to_stage2(); - - - -} - -// Added by HH - void _EjectFlits(){ - array Flit *f received_flits[_inputs]; // To keep track of all the flits that need to be ejected - int flit_to_eject = -1; - int golden_cnt = 0; - for ( int input = 0; input < _inputs-1; ++input ) { - // One input channel is for the router - // f = _input_buffer[input].pop; - - if ( f->dest == GetID() ) { - received_flits[input] = f; - // Check for golden status and golden tie - if(f->golden == 1 && !golden_cnt) - { - flit_to_eject = input; - golden_cnt++; - } - else if(f->golden == 1) - { - if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit - { - flit_to_eject = input; - break; - } - } - } - else{ - received_flits[input] = NULL; // Flit not at destination - } - if(flit_to_eject == -1){ - for( int input = 0; input < _inputs-1; ++input ){ - // Iterating through the array of stored flits that need to be ejected - // to find the oldest flit and consequently retiring that flit - int oldest_flit_index; - int high_pri = -1; - if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) - { - high_pri = received_flits[input]->pri; - oldest_flit_index = input; - } - if(high_pri > -1) - { - flit_to_eject = oldest_flit_index; - _output_channels[retire_index] = received_flits[flit_to_eject]; - // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit - } - } - } - } - - - void Chipper::_Buffer_to_stage1() -{ - // map intermediate_1; - int input = 0; - map::iterator it; - for ( int input = 0; input < _inputs; ++input ){ - // intermediate = _input_buffer[input]; - // for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe - // if(pair_time == it->first){ - // it->first = it->first + 1; - // } - // } - it =_input_buffer[input].find(GetSimTime()); - if(it == _input_buffer[input].end()) - continue; - _stage_1[input].insert(make_pair(it->first+1, it->second)); - _input_buffer[input].erase(it); - } -} - -void Chipper::_stage1_to_stage2() -{ - // msp intermediate_2; - int input = 0; - for ( int input = 0; input < _inputs; ++input ){ // Nandan: Adding the delay associated with the pipe - // intermediate = _stage_1[input]; - // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ - // if(pair_time == it->first){ - // it->first = it->first + 1; - // } - // } - it = _stage_1[input].find(GetSimTime()); - if(it == _stage_1[input].end()) - continue; - _stage_2[input].insert(make_pair(it->first+1, it->second)); - _stage_1[input].erase(it); - } -} - -void Chipper::Permute() -{ - // int router_number = GetID(); - // int west = _LeftNode(router_number, 0); - // int east = _RightNode(router_number, 0); - // int north = _LeftNode(router_number, 1); - // int south = _RightNode(router_number, 1); - // vector direction; - // vector priority; - // vector golden; - // direction.resize(_inputs-1); - // priority.resize(_inputs-1); - // for(input = 0; input < _inputs; ++input) - // { - - // if(golden[input] == true) - Partial_Permute(2,0,1); - Partial_Permute(3,1,1); - Partial_Permute(3,2,2); - Partial_Permute(1,0,0); - // } -} - -void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) -{ - Flit *f1; - Flit *f2; - map iterator it1,it2; - it1 = _stage_2[dir1].find(GetSimTime()); - it2 = _stage_2[dir2].find(GetSimTime()); - *f1 = it1->second; - *f2 = it2->second; - if((f1->golden == 1)&&(f2->golden == 1)) - { - if(f1->pri >= f2->pri) - { - if(_rf(GetID(), f1->dest, true) > perm_num) - { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - } - else - { - if(_rf(GetID(), f2->dest, true) > perm_num) - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - else - { - - } - } - } - else if((f1->golden == 1)) - { - if(_rf(GetID(), f1->dest, true) > perm_num) - { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - } - else if((f2->golden == 1)) - { - if(_rf(GetID(), f2->dest, true) > perm_num) - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - else - { - - } - } - else - { - if(f1->pri >= f2->pri) - { - if(_rf(GetID(), f1->dest, true) > perm_num) - { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - } - else - { - if(_rf(GetID(), f2->dest, true) > perm_num) - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - else - { - - } - } - - } -} -// Added by HH : scheme for determining Golden_packet as in chipper paper(not exactly) -// Returning the packet id that is to be made golden by just dividing time_elapsed by L instead of -// keeping track of all the packets in the network. (I don't know if a maximum number of packets is available) -// Instead of iterating over all possible packet ids called "transaction ids" from all nodes, just iterate over -// packet ids which uniquely identifies each packet - From 74cd6d25a04a0298cf5c723ff5fc75d4c82bbd21 Mon Sep 17 00:00:00 2001 From: hariharan-n Date: Fri, 13 Jan 2017 22:10:50 +0530 Subject: [PATCH 14/35] Delete chipper.cpp --- chipper.cpp | 378 ---------------------------------------------------- 1 file changed, 378 deletions(-) delete mode 100644 chipper.cpp diff --git a/chipper.cpp b/chipper.cpp deleted file mode 100644 index 5a944a3f..00000000 --- a/chipper.cpp +++ /dev/null @@ -1,378 +0,0 @@ -// Ameya: Remove redundancies -#include -#include -#include -#include -#include - -#include "chipper.hpp" -#include "stats.hpp" -#include "globals.hpp" -#include "routefunc.hpp" - -int retire_index = 4; // HH : For mesh, ejection is through _output_channels[4]; - -Chipper::Chipper( const Configuration& config, - Module *parent, const string & name, int id, - int inputs, int outputs ) - : Router( config, - parent, name, - id, - inputs, outputs ) -{ - ostringstream module_name; - - // Routing - - string rf = config.GetStr("routing_function") + "_" + config.GetStr("topology"); - map::iterator rf_iter = gRoutingFunctionMap.find(rf); - if(rf_iter == gRoutingFunctionMap.end()) { - Error("Invalid routing function: " + rf); - } - _rf = rf_iter->second; - - assert(_inputs == _outputs); - - _input_buffer.resize(_inputs-1); - _output_buffer.resize(_outputs-1); - - _stage_1.resize(_inputs-1); - _stage_2.resize(_inputs-1); -} - -Chipper::~Chipper() -{ - for ( int i = 0; i < _inputs; ++i ) { - while (!_input_buffer[i].empty()) - { - (_input_buffer[i].begin()->second)->Free(); - _input_buffer[i].erase(_input_buffer[i].begin()); - } - } - - for ( int i = 0; i < _inputs; ++i ) { - while (!_stage_1[i].empty()) - { - (_stage_1[i].begin()->second)->Free(); - _stage_1.erase(_stage_1.begin()); - } - } - - for ( int i = 0; i < _inputs; ++i ) { - while (!_stage_2[i].empty()) - { - (_stage_2[i].begin()->second)->Free(); - _stage_2.erase(_stage_2.begin()); - } - } - - for ( int o = 0; o < _outputs; ++o ) { - while (!_output_buffer[o].empty()) - { - (_output_buffer[o].begin()->second)->Free(); - _output_buffer[o].erase(_output_buffer[o].begin()); - } - } -} - -void Chipper::AddInputChannel( FlitChannel *channel, CreditChannel * ignored) -{ - // Ameya: credit channel ignored - _input_channels.push_back( channel ); - channel->SetSink( this, _input_channels.size() - 1 ) ; -} - -void Chipper::AddOutputChannel(FlitChannel * channel, CreditChannel * ignored) -{ - // Ameya: credit channel ignored - _output_channels.push_back( channel ); - _channel_faults.push_back( false ); - channel->SetSource( this, _output_channels.size() - 1 ) ; -} - -void Chipper::Display( ostream & os ) const -{ - os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func -} - -void Chipper::ReadInputs() // HH : Performs the function of reading flits from channel into input buffer -{ - // HH : Receiving flits from channel into input buffer, no credits received, as in event_router -} - -// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time -int Chipper::_IncomingFlits( ) -{ - Flit *f; - map< int,Flit* > buffer_timed; - receive_time = GetSimTime(); - for ( int input = 0; input < _inputs; ++input ) { - f = _input_channels[input]->Receive(); - if ( f ) { - _input_buffer[input].insert( pair(receive_time,f) ); - } - } -} - -void Chipper::WriteOutputs() // HH : Performs the function of sending flits from output buffer into channel -{ - _SendFlits( ); //HH : Sending flits from output buffer into input channel, no credits sent, as in event_router -} - -// HH Definition of _Sendflits in Chipper class same as that in class event_router -void Chipper::_SendFlits( int pair_time) -{ - map buffer_timed; - Flit *f; - for ( int output = 0; output < _outputs; ++output ) { - //if ( !_output_buffer[output].empty( ) ) { - //Flit *f = _output_buffer[output].front( ); - //_output_buffer[output].pop( ); - //_output_channels[output]->Send( f ); - buffer_timed = _output_buffer.back; - f = buffer_timed.find( pair_time); - if(f){ - _output_channels[output]->Send( f ); - } - } - } - -void Chipper::_InternalStep( ) -{ - // Receive incoming flits - int pair_time = _IncomingFlits( ); - //HH : Need to make the time the flits are received global in order to know when the input flits were -// were paired into the map - //Have to pass this onto subsequent functions to find the correct flit from each buffer - // I am thinking pair_time should be updated at each stage with GetSimTime and then passed onto next stage - // Eject flits which have reached their desitnation - _EjectFlits(); - - _Buffer_to_stage1(); - - _stage1_to_stage2(); - - - -} - -// Added by HH - void _EjectFlits(){ - array Flit *f received_flits[_inputs]; // To keep track of all the flits that need to be ejected - int flit_to_eject = -1; - int golden_cnt = 0; - for ( int input = 0; input < _inputs-1; ++input ) { - // One input channel is for the router - // f = _input_buffer[input].pop; - - if ( f->dest == GetID() ) { - received_flits[input] = f; - // Check for golden status and golden tie - if(f->golden == 1 && !golden_cnt) - { - flit_to_eject = input; - golden_cnt++; - } - else if(f->golden == 1) - { - if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit - { - flit_to_eject = input; - break; - } - } - } - else{ - received_flits[input] = NULL; // Flit not at destination - } - if(flit_to_eject == -1){ - for( int input = 0; input < _inputs-1; ++input ){ - // Iterating through the array of stored flits that need to be ejected - // to find the oldest flit and consequently retiring that flit - int oldest_flit_index; - int high_pri = -1; - if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) - { - high_pri = received_flits[input]->pri; - oldest_flit_index = input; - } - if(high_pri > -1) - { - flit_to_eject = oldest_flit_index; - _output_channels[retire_index] = received_flits[flit_to_eject]; - // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit - } - } - } - } - - - void Chipper::_Buffer_to_stage1() -{ - // map intermediate_1; - int input = 0; - map::iterator it; - for ( int input = 0; input < _inputs; ++input ){ - // intermediate = _input_buffer[input]; - // for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe - // if(pair_time == it->first){ - // it->first = it->first + 1; - // } - // } - it =_input_buffer[input].find(GetSimTime()); - if(it == _input_buffer[input].end()) - continue; - _stage_1[input].insert(make_pair(it->first+1, it->second)); - _input_buffer[input].erase(it); - } -} - -void Chipper::_stage1_to_stage2() -{ - // msp intermediate_2; - int input = 0; - for ( int input = 0; input < _inputs; ++input ){ // Nandan: Adding the delay associated with the pipe - // intermediate = _stage_1[input]; - // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ - // if(pair_time == it->first){ - // it->first = it->first + 1; - // } - // } - it = _stage_1[input].find(GetSimTime()); - if(it == _stage_1[input].end()) - continue; - _stage_2[input].insert(make_pair(it->first+1, it->second)); - _stage_1[input].erase(it); - } -} - -void Chipper::Permute() -{ - // int router_number = GetID(); - // int west = _LeftNode(router_number, 0); - // int east = _RightNode(router_number, 0); - // int north = _LeftNode(router_number, 1); - // int south = _RightNode(router_number, 1); - // vector direction; - // vector priority; - // vector golden; - // direction.resize(_inputs-1); - // priority.resize(_inputs-1); - // for(input = 0; input < _inputs; ++input) - // { - - // if(golden[input] == true) - Partial_Permute(2,0,1); - Partial_Permute(3,1,1); - Partial_Permute(3,2,2); - Partial_Permute(1,0,0); - // } -} - -void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) -{ - Flit *f1; - Flit *f2; - map iterator it1,it2; - it1 = _stage_2[dir1].find(GetSimTime()); - it2 = _stage_2[dir2].find(GetSimTime()); - *f1 = it1->second; - *f2 = it2->second; - if((f1->golden == 1)&&(f2->golden == 1)) - { - if(f1->pri >= f2->pri) - { - if(_rf(GetID(), f1->dest, true) > perm_num) - { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - } - else - { - if(_rf(GetID(), f2->dest, true) > perm_num) - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - else - { - - } - } - } - else if((f1->golden == 1)) - { - if(_rf(GetID(), f1->dest, true) > perm_num) - { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - } - else if((f2->golden == 1)) - { - if(_rf(GetID(), f2->dest, true) > perm_num) - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - else - { - - } - } - else - { - if(f1->pri >= f2->pri) - { - if(_rf(GetID(), f1->dest, true) > perm_num) - { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - } - else - { - if(_rf(GetID(), f2->dest, true) > perm_num) - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - } - else - { - - } - } - - } -} -// Added by HH : scheme for determining Golden_packet as in chipper paper(not exactly) -// Returning the packet id that is to be made golden by just dividing time_elapsed by L instead of -// keeping track of all the packets in the network. (I don't know if a maximum number of packets is available) -// Instead of iterating over all possible packet ids called "transaction ids" from all nodes, just iterate over -// packet ids which uniquely identifies each packet - From 37940b25e6b29c74659a811ad549c4834ad3d02b Mon Sep 17 00:00:00 2001 From: hariharan-n Date: Fri, 13 Jan 2017 22:11:30 +0530 Subject: [PATCH 15/35] Add files via upload --- src/routers/chipper.cpp | 235 ++++++++++++++++++++++++++++++++++------ 1 file changed, 200 insertions(+), 35 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 3e65640b..5a944a3f 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -8,6 +8,9 @@ #include "chipper.hpp" #include "stats.hpp" #include "globals.hpp" +#include "routefunc.hpp" + +int retire_index = 4; // HH : For mesh, ejection is through _output_channels[4]; Chipper::Chipper( const Configuration& config, Module *parent, const string & name, int id, @@ -30,11 +33,11 @@ Chipper::Chipper( const Configuration& config, assert(_inputs == _outputs); - _input_buffer.resize(_inputs); - _output_buffer.resize(_outputs); + _input_buffer.resize(_inputs-1); + _output_buffer.resize(_outputs-1); - _stage_1.resize(_inputs); - _stage_2.resize(_inputs); + _stage_1.resize(_inputs-1); + _stage_2.resize(_inputs-1); } Chipper::~Chipper() @@ -155,59 +158,221 @@ void Chipper::_InternalStep( ) // Added by HH void _EjectFlits(){ - Flit *f; - - for ( int input = 0; input < _inputs; ++input ) { + array Flit *f received_flits[_inputs]; // To keep track of all the flits that need to be ejected + int flit_to_eject = -1; + int golden_cnt = 0; + for ( int input = 0; input < _inputs-1; ++input ) { + // One input channel is for the router // f = _input_buffer[input].pop; if ( f->dest == GetID() ) { - ; + received_flits[input] = f; + // Check for golden status and golden tie + if(f->golden == 1 && !golden_cnt) + { + flit_to_eject = input; + golden_cnt++; + } + else if(f->golden == 1) + { + if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit + { + flit_to_eject = input; + break; + } + } } - else if { - + else{ + received_flits[input] = NULL; // Flit not at destination } - else - } + if(flit_to_eject == -1){ + for( int input = 0; input < _inputs-1; ++input ){ + // Iterating through the array of stored flits that need to be ejected + // to find the oldest flit and consequently retiring that flit + int oldest_flit_index; + int high_pri = -1; + if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) + { + high_pri = received_flits[input]->pri; + oldest_flit_index = input; + } + if(high_pri > -1) + { + flit_to_eject = oldest_flit_index; + _output_channels[retire_index] = received_flits[flit_to_eject]; + // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit + } + } + } } + void Chipper::_Buffer_to_stage1() { - map intermediate_1; + // map intermediate_1; int input = 0; + map::iterator it; for ( int input = 0; input < _inputs; ++input ){ - intermediate = _input_buffer[input]; - for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe - if(pair_time == it->first){ - it->first = it->first + delay_pipe_1; - } - } - stage_1[input] = _input_buffer[input]; + // intermediate = _input_buffer[input]; + // for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe + // if(pair_time == it->first){ + // it->first = it->first + 1; + // } + // } + it =_input_buffer[input].find(GetSimTime()); + if(it == _input_buffer[input].end()) + continue; + _stage_1[input].insert(make_pair(it->first+1, it->second)); + _input_buffer[input].erase(it); } } void Chipper::_stage1_to_stage2() { - msp intermediate_2; + // msp intermediate_2; int input = 0; for ( int input = 0; input < _inputs; ++input ){ // Nandan: Adding the delay associated with the pipe - intermediate = _stage_1[input]; - for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ - if(pair_time == it->first){ - it->first = it->first + delay_pipe_2; - } - } - stage_2[input] = _stage_1[input]; + // intermediate = _stage_1[input]; + // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ + // if(pair_time == it->first){ + // it->first = it->first + 1; + // } + // } + it = _stage_1[input].find(GetSimTime()); + if(it == _stage_1[input].end()) + continue; + _stage_2[input].insert(make_pair(it->first+1, it->second)); + _stage_1[input].erase(it); } } + +void Chipper::Permute() +{ + // int router_number = GetID(); + // int west = _LeftNode(router_number, 0); + // int east = _RightNode(router_number, 0); + // int north = _LeftNode(router_number, 1); + // int south = _RightNode(router_number, 1); + // vector direction; + // vector priority; + // vector golden; + // direction.resize(_inputs-1); + // priority.resize(_inputs-1); + // for(input = 0; input < _inputs; ++input) + // { + + // if(golden[input] == true) + Partial_Permute(2,0,1); + Partial_Permute(3,1,1); + Partial_Permute(3,2,2); + Partial_Permute(1,0,0); + // } +} + +void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) +{ + Flit *f1; + Flit *f2; + map iterator it1,it2; + it1 = _stage_2[dir1].find(GetSimTime()); + it2 = _stage_2[dir2].find(GetSimTime()); + *f1 = it1->second; + *f2 = it2->second; + if((f1->golden == 1)&&(f2->golden == 1)) + { + if(f1->pri >= f2->pri) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + } + else if((f1->golden == 1)) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else if((f2->golden == 1)) + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + else + { + if(f1->pri >= f2->pri) + { + if(_rf(GetID(), f1->dest, true) > perm_num) + { + + } + else + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + } + else + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].make_pair(it1->first, it1->second); + _stage_2[dir1].make_pair(it2->first, it2->second); + _stage_2[dir1].erase(it1); + _stage_2[dir2].erase(it2); + } + else + { + + } + } + + } +} // Added by HH : scheme for determining Golden_packet as in chipper paper(not exactly) // Returning the packet id that is to be made golden by just dividing time_elapsed by L instead of // keeping track of all the packets in the network. (I don't know if a maximum number of packets is available) // Instead of iterating over all possible packet ids called "transaction ids" from all nodes, just iterate over // packet ids which uniquely identifies each packet -int Chipper::Golden_Packet(int L) // Parameter L is obtained from before from another function -{ - int time_elapsed = GetSimTime(); - int epoch_no = time_elapsed/L; // L is the golden epoch, needs to be defined as the upper - //bound of the maximum time taken by a golden packet to reach its destination - return epoch_no; -} + From 1feef9f81dc4197a8fa3d9782196ff33e228b98c Mon Sep 17 00:00:00 2001 From: sabersword Date: Fri, 13 Jan 2017 22:46:47 +0530 Subject: [PATCH 16/35] Fix compilation errors and fix logic in chipper.cpp:Permute() --- src/blesstrafficmanager.cpp | 1 - src/flitchannel.hpp | 6 +- src/main.cpp | 1 - src/networks/network.cpp | 2 +- src/routefunc.cpp | 4 + src/routefunc.hpp | 2 + src/routers/chipper.cpp | 378 +++++++++++++++++++++--------------- src/routers/chipper.hpp | 17 +- src/routers/router.hpp | 5 + src/trafficmanager.cpp | 4 +- 10 files changed, 258 insertions(+), 162 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index 08126b35..8c96fd24 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -134,7 +134,6 @@ void BlessTrafficManager::_Step( ) _net[subnet]->Evaluate( ); _net[subnet]->WriteOutputs( ); } - ++_time; assert(_time); if(gTrace) diff --git a/src/flitchannel.hpp b/src/flitchannel.hpp index 71952b71..e98ab2f4 100644 --- a/src/flitchannel.hpp +++ b/src/flitchannel.hpp @@ -73,9 +73,9 @@ class FlitChannel : public Channel { } // Ameya - inline int GetInjectStatus() const { - return ( _input == 0 ); - } + // inline int GetInjectStatus() const { + // return ( _input == 0 ); + // } // Send flit virtual void Send(Flit * flit); diff --git a/src/main.cpp b/src/main.cpp index a0de8264..0bd80f39 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -112,7 +112,6 @@ bool Simulate( BookSimConfig const & config ) /*tcc and characterize are legacy *not sure how to use them */ - assert(trafficManager == NULL); trafficManager = TrafficManager::New( config, net ) ; diff --git a/src/networks/network.cpp b/src/networks/network.cpp index 59771fac..169171cb 100644 --- a/src/networks/network.cpp +++ b/src/networks/network.cpp @@ -215,7 +215,7 @@ void Network::WriteFlit( Flit *f, int source ) int Network::CheckInject( int source ) { assert( ( source >= 0 ) && ( source < _nodes ) ); - return ( _inject[source]->GetInjectStatus() ); + return ( _routers[source]->GetInjectStatus() ); } Flit *Network::ReadFlit( int dest ) diff --git a/src/routefunc.cpp b/src/routefunc.cpp index 0fd210fa..cb9b9e12 100644 --- a/src/routefunc.cpp +++ b/src/routefunc.cpp @@ -53,6 +53,7 @@ map gRoutingFunctionMap; +map cRoutingFunctionMap; /* Global information used by routing functions */ @@ -1996,4 +1997,7 @@ void InitializeRoutingMap( const Configuration & config ) gRoutingFunctionMap["chaos_mesh"] = &chaos_mesh; gRoutingFunctionMap["chaos_torus"] = &chaos_torus; + + // Ameya + cRoutingFunctionMap["dor_next_mesh"] = &dor_next_mesh; } diff --git a/src/routefunc.hpp b/src/routefunc.hpp index 2340a928..7ee061bf 100644 --- a/src/routefunc.hpp +++ b/src/routefunc.hpp @@ -34,10 +34,12 @@ #include "config_utils.hpp" typedef void (*tRoutingFunction)( const Router *, const Flit *, int in_channel, OutputSet *, bool ); +typedef int (*cRoutingFunction)( int router, int dest, bool descending ); void InitializeRoutingMap( const Configuration & config ); extern map gRoutingFunctionMap; +extern map cRoutingFunctionMap; extern int gNumVCs; extern int gReadReqBeginVC, gReadReqEndVC; diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 5a944a3f..94079938 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -10,8 +10,6 @@ #include "globals.hpp" #include "routefunc.hpp" -int retire_index = 4; // HH : For mesh, ejection is through _output_channels[4]; - Chipper::Chipper( const Configuration& config, Module *parent, const string & name, int id, int inputs, int outputs ) @@ -24,9 +22,9 @@ Chipper::Chipper( const Configuration& config, // Routing - string rf = config.GetStr("routing_function") + "_" + config.GetStr("topology"); - map::iterator rf_iter = gRoutingFunctionMap.find(rf); - if(rf_iter == gRoutingFunctionMap.end()) { + string rf = "dor_next_mesh"; + map::iterator rf_iter = cRoutingFunctionMap.find(rf); + if(rf_iter == cRoutingFunctionMap.end()) { Error("Invalid routing function: " + rf); } _rf = rf_iter->second; @@ -38,6 +36,10 @@ Chipper::Chipper( const Configuration& config, _stage_1.resize(_inputs-1); _stage_2.resize(_inputs-1); + + _time = 0; + _inject_slot = -1; + last_channel = _inputs-1; } Chipper::~Chipper() @@ -95,44 +97,71 @@ void Chipper::Display( ostream & os ) const os << "Nothing to display" << endl; // Ameya: Just for sake of avoiding pure virual func } -void Chipper::ReadInputs() // HH : Performs the function of reading flits from channel into input buffer +// Ameya: Returns 1 if there is empty slot in _stage_1 +int Chipper::GetInjectStatus() { - // HH : Receiving flits from channel into input buffer, no credits received, as in event_router + for ( int input = 0; input < _inputs - 1; ++input ) + { + map::iterator f = _stage_1[input].find(GetSimTime()); + if(f == _stage_1[input].end()) + { + _inject_slot = input; + return 1; + } + } + _inject_slot = -1; + return 0; } -// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time -int Chipper::_IncomingFlits( ) +// Ameya : Performs the function of reading flits from channel into input buffer +void Chipper::ReadInputs() { - Flit *f; - map< int,Flit* > buffer_timed; - receive_time = GetSimTime(); - for ( int input = 0; input < _inputs; ++input ) { - f = _input_channels[input]->Receive(); - if ( f ) { - _input_buffer[input].insert( pair(receive_time,f) ); - } - } + int time = GetSimTime(); + Flit *f; + for ( int input = 0; input < _inputs - 1; ++input ) // Avoid _inject channel + { + f = _input_channels[input]->Receive(); + + if ( f ) + { + _input_buffer[input].insert( pair(time, f) ); + } + } } -void Chipper::WriteOutputs() // HH : Performs the function of sending flits from output buffer into channel +// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time +// void Chipper::_IncomingFlits( ) +// { +// Flit *f; +// map< int,Flit* > buffer_timed; +// int receive_time = GetSimTime(); +// for ( int input = 0; input < _inputs; ++input ) { +// f = _input_channels[input]->Receive(); +// if ( f ) { +// _input_buffer[input].insert( pair(receive_time,f) ); +// } +// } +// } + +// HH : Performs the function of sending flits from output buffer into channel +void Chipper::WriteOutputs() { _SendFlits( ); //HH : Sending flits from output buffer into input channel, no credits sent, as in event_router } // HH Definition of _Sendflits in Chipper class same as that in class event_router -void Chipper::_SendFlits( int pair_time) +void Chipper::_SendFlits( ) { - map buffer_timed; - Flit *f; - for ( int output = 0; output < _outputs; ++output ) { - //if ( !_output_buffer[output].empty( ) ) { - //Flit *f = _output_buffer[output].front( ); - //_output_buffer[output].pop( ); - //_output_channels[output]->Send( f ); - buffer_timed = _output_buffer.back; - f = buffer_timed.find( pair_time); - if(f){ - _output_channels[output]->Send( f ); + int time = GetSimTime(); + map::iterator f; + for ( int output = 0; output < _outputs - 1; ++output ) // Avoid _eject channel + { + map & buffer_timed = _output_buffer[output]; + f = buffer_timed.find( time ); + if(f != buffer_timed.end() ) + { + _output_channels[output]->Send( f->second ); + buffer_timed.erase(f); } } } @@ -140,86 +169,106 @@ void Chipper::_SendFlits( int pair_time) void Chipper::_InternalStep( ) { // Receive incoming flits - int pair_time = _IncomingFlits( ); + // int pair_time = _IncomingFlits( ); //HH : Need to make the time the flits are received global in order to know when the input flits were // were paired into the map //Have to pass this onto subsequent functions to find the correct flit from each buffer // I am thinking pair_time should be updated at each stage with GetSimTime and then passed onto next stage // Eject flits which have reached their desitnation + _time = GetSimTime(); + _EjectFlits(); - _Buffer_to_stage1(); + _input_to_stage1(); _stage1_to_stage2(); + Permute(); - + _stage2_to_output(); } // Added by HH - void _EjectFlits(){ - array Flit *f received_flits[_inputs]; // To keep track of all the flits that need to be ejected - int flit_to_eject = -1; - int golden_cnt = 0; - for ( int input = 0; input < _inputs-1; ++input ) { - // One input channel is for the router - // f = _input_buffer[input].pop; - - if ( f->dest == GetID() ) { - received_flits[input] = f; - // Check for golden status and golden tie - if(f->golden == 1 && !golden_cnt) - { - flit_to_eject = input; - golden_cnt++; - } - else if(f->golden == 1) - { - if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit - { - flit_to_eject = input; - break; - } - } +void Chipper::_EjectFlits(){ + Flit * received_flits[_inputs-1]; // To keep track of all the flits that need to be ejected + Flit *f; // Ameya: syntax edits + map::iterator it; + int flit_to_eject = -1; + int golden_cnt = 0; + for ( int input = 0; input < _inputs-1; ++input ) + { + it = _input_buffer[input].find(_time); + if(it == _input_buffer[input].end()) + { + received_flits[input] = NULL; + continue; + } + f = it->second; + if ( f->dest == GetID() ) + { + received_flits[input] = f; + // Check for golden status and golden tie + if(f->golden == 1 && !golden_cnt) + { + flit_to_eject = input; + golden_cnt++; + } + else if(f->golden == 1) + { + if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit + { + flit_to_eject = input; + break; + } + } } - else{ + else + { received_flits[input] = NULL; // Flit not at destination } - if(flit_to_eject == -1){ - for( int input = 0; input < _inputs-1; ++input ){ - // Iterating through the array of stored flits that need to be ejected - // to find the oldest flit and consequently retiring that flit - int oldest_flit_index; - int high_pri = -1; - if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) - { - high_pri = received_flits[input]->pri; - oldest_flit_index = input; - } - if(high_pri > -1) - { - flit_to_eject = oldest_flit_index; - _output_channels[retire_index] = received_flits[flit_to_eject]; - // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit - } - } - } } + if(flit_to_eject == -1) + { + int oldest_flit_index; + int high_pri = -1; + for( int input = 0; input < _inputs-1; ++input ) + { + // Iterating through the array of stored flits that need to be ejected + // to find the oldest flit and consequently retiring that flit + if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) + { + high_pri = received_flits[input]->pri; + oldest_flit_index = input; + } + } + if(high_pri > -1) + { + flit_to_eject = oldest_flit_index; + _output_channels[last_channel]->Send(received_flits[flit_to_eject]); + _input_buffer[flit_to_eject].erase(_input_buffer[flit_to_eject].find(_time)); + // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit + } + } + else + { + // Ameya: Eject golden flit + _output_channels[last_channel]->Send(received_flits[flit_to_eject]); + _input_buffer[flit_to_eject].erase(_input_buffer[flit_to_eject].find(_time)); + } +} - void Chipper::_Buffer_to_stage1() +void Chipper::_input_to_stage1() { - // map intermediate_1; - int input = 0; map::iterator it; - for ( int input = 0; input < _inputs; ++input ){ + for ( int input = 0; input < _inputs-1; ++input ){ // intermediate = _input_buffer[input]; // for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe // if(pair_time == it->first){ // it->first = it->first + 1; // } // } - it =_input_buffer[input].find(GetSimTime()); + it =_input_buffer[input].find(_time); if(it == _input_buffer[input].end()) continue; _stage_1[input].insert(make_pair(it->first+1, it->second)); @@ -228,24 +277,47 @@ void Chipper::_InternalStep( ) } void Chipper::_stage1_to_stage2() -{ - // msp intermediate_2; - int input = 0; - for ( int input = 0; input < _inputs; ++input ){ // Nandan: Adding the delay associated with the pipe - // intermediate = _stage_1[input]; - // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ - // if(pair_time == it->first){ - // it->first = it->first + 1; - // } - // } - it = _stage_1[input].find(GetSimTime()); - if(it == _stage_1[input].end()) - continue; - _stage_2[input].insert(make_pair(it->first+1, it->second)); - _stage_1[input].erase(it); +{ + map::iterator it; + for ( int input = 0; input < _inputs-1; ++input ){ // Nandan: Adding the delay associated with the pipe + // intermediate = _stage_1[input]; + // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ + // if(pair_time == it->first){ + // it->first = it->first + 1; + // } + // } + it = _stage_1[input].find(_time); + if(it == _stage_1[input].end()) + continue; + _stage_2[input].insert(make_pair(it->first+1, it->second)); + _stage_1[input].erase(it); + } + + if(_inject_slot > -1) + { + assert(_inject_slot < _inputs - 1); + Flit *f = _input_channels[last_channel]->Receive(); + if(f) + { + _stage_2[_inject_slot].insert(make_pair(_time+1, it->second)); + _inject_slot = -1; + } } } +void Chipper::_stage2_to_output() +{ + map::iterator it; + for ( int input = 0; input < _inputs-1; ++input ){ + it = _stage_2[input].find(_time); + if(it == _stage_2[input].end()) + continue; + _output_buffer[input].insert(make_pair(it->first+1, it->second)); + _stage_2[input].erase(it); + } +} + +// Nandan: Routing stage of CHIPPER void Chipper::Permute() { // int router_number = GetID(); @@ -261,118 +333,120 @@ void Chipper::Permute() // for(input = 0; input < _inputs; ++input) // { - // if(golden[input] == true) Partial_Permute(2,0,1); Partial_Permute(3,1,1); Partial_Permute(3,2,2); Partial_Permute(1,0,0); - // } + } void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { Flit *f1; Flit *f2; - map iterator it1,it2; - it1 = _stage_2[dir1].find(GetSimTime()); - it2 = _stage_2[dir2].find(GetSimTime()); - *f1 = it1->second; - *f2 = it2->second; + map::iterator it1,it2; + it1 = _stage_2[dir1].find(_time); + if(it1 == _stage_2[dir1].end()) + { + f1 = NULL; + } + else + { + f1 = it1->second; + } + it2 = _stage_2[dir2].find(_time); + if(it2 == _stage_2[dir2].end()) + { + f2 = NULL; + } + else + { + f2 = it2->second; + } + if((f1 == NULL)&&(f2 == NULL)) + return; + if((f1 == NULL)) + { + if(_rf(GetID(), f2->dest, true) > perm_num) + { + _stage_2[dir2].erase(it2); + _stage_2[dir1].insert(pair(_time, f2) ); + } + return; + } + if((f2 == NULL)) + { + if(_rf(GetID(), f1->dest, true) < perm_num) + { + _stage_2[dir1].erase(it1); + _stage_2[dir2].insert(pair(_time, f1) ); + } + return; + } if((f1->golden == 1)&&(f2->golden == 1)) { if(f1->pri >= f2->pri) { - if(_rf(GetID(), f1->dest, true) > perm_num) + if(_rf(GetID(), f1->dest, true) < perm_num) { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); + _stage_2[dir2].insert( pair(_time, f1) ); + _stage_2[dir1].insert( pair(_time, f2) ); } } else { if(_rf(GetID(), f2->dest, true) > perm_num) { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); - } - else - { - + _stage_2[dir2].insert( pair(_time, f1) ); + _stage_2[dir1].insert( pair(_time, f2) ); } } } else if((f1->golden == 1)) { - if(_rf(GetID(), f1->dest, true) > perm_num) + if(_rf(GetID(), f1->dest, true) < perm_num) { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); + _stage_2[dir2].insert( pair(_time, f1) ); + _stage_2[dir1].insert( pair(_time, f2) ); } } else if((f2->golden == 1)) { if(_rf(GetID(), f2->dest, true) > perm_num) { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); - } - else - { - + _stage_2[dir2].insert( pair(_time, f1) ); + _stage_2[dir1].insert( pair(_time, f2) ); } } else { if(f1->pri >= f2->pri) { - if(_rf(GetID(), f1->dest, true) > perm_num) + if(_rf(GetID(), f1->dest, true) < perm_num) { - - } - else - { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); + _stage_2[dir2].insert( pair(_time, f1) ); + _stage_2[dir1].insert( pair(_time, f2) ); } } else { if(_rf(GetID(), f2->dest, true) > perm_num) { - _stage_2[dir2].make_pair(it1->first, it1->second); - _stage_2[dir1].make_pair(it2->first, it2->second); _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); - } - else - { - + _stage_2[dir2].insert( pair(_time, f1) ); + _stage_2[dir1].insert( pair(_time, f2) ); } } - } -} -// Added by HH : scheme for determining Golden_packet as in chipper paper(not exactly) -// Returning the packet id that is to be made golden by just dividing time_elapsed by L instead of -// keeping track of all the packets in the network. (I don't know if a maximum number of packets is available) -// Instead of iterating over all possible packet ids called "transaction ids" from all nodes, just iterate over -// packet ids which uniquely identifies each packet - +} \ No newline at end of file diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp index df37d53d..23226c2c 100755 --- a/src/routers/chipper.hpp +++ b/src/routers/chipper.hpp @@ -20,9 +20,21 @@ class Chipper : public Router { vector > _stage_2; // No need for extra flags showing occupancy as each buffer is timed - tRoutingFunction _rf; // Temporary (check necessity later) Ameya + int _time; + int _inject_slot; + int last_channel; - virtual void _InternalStep(); + cRoutingFunction _rf; // Temporary (check necessity later) Ameya + + virtual void _InternalStep(); + void _IncomingFlits( ); + void _SendFlits( ); + void _EjectFlits(); + void _input_to_stage1(); + void _stage1_to_stage2(); + void Permute(); + void _stage2_to_output(); + void Partial_Permute(int dir1, int dir2, int perm_num); public: Chipper( const Configuration& config, @@ -33,6 +45,7 @@ class Chipper : public Router { virtual void AddInputChannel( FlitChannel *channel, CreditChannel * ignored); virtual void AddOutputChannel(FlitChannel * channel, CreditChannel * ignored); + int GetInjectStatus(); virtual void ReadInputs(); // virtual void Evaluate( ); virtual void WriteOutputs(); diff --git a/src/routers/router.hpp b/src/routers/router.hpp index 65bdac83..821bff52 100644 --- a/src/routers/router.hpp +++ b/src/routers/router.hpp @@ -111,6 +111,11 @@ class Router : public TimedModule { return _output_channels[output]; } + virtual int GetInjectStatus() + { + return 0; + } + virtual void ReadInputs( ) = 0; virtual void Evaluate( ); virtual void WriteOutputs( ) = 0; diff --git a/src/trafficmanager.cpp b/src/trafficmanager.cpp index 188d895b..111568b7 100644 --- a/src/trafficmanager.cpp +++ b/src/trafficmanager.cpp @@ -49,9 +49,9 @@ TrafficManager * TrafficManager::New(Configuration const & config, int tbufferless = config.GetInt("bufferless"); if((sim_type == "latency") || (sim_type == "throughput")) { if(tbufferless) - result = new BlessTrafficManager(config, net); + result = new BlessTrafficManager(config, net); // Ameya else - result = new TrafficManager(config, net); // Ameya + result = new TrafficManager(config, net); } else if(sim_type == "batch") { result = new BatchTrafficManager(config, net); } else { From e6e980dcbc87b5edd279c4e5958760c70b9cadea Mon Sep 17 00:00:00 2001 From: sabersword Date: Sat, 14 Jan 2017 19:06:56 +0530 Subject: [PATCH 17/35] Add CheckSanity() in chipper.cpp and flit track statements --- src/routers/chipper.cpp | 68 ++++++++++++++++++++++++++++++++++++----- src/routers/chipper.hpp | 1 + 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 94079938..225fad07 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -44,7 +44,7 @@ Chipper::Chipper( const Configuration& config, Chipper::~Chipper() { - for ( int i = 0; i < _inputs; ++i ) { + for ( int i = 0; i < _inputs-1; ++i ) { while (!_input_buffer[i].empty()) { (_input_buffer[i].begin()->second)->Free(); @@ -52,7 +52,7 @@ Chipper::~Chipper() } } - for ( int i = 0; i < _inputs; ++i ) { + for ( int i = 0; i < _inputs-1; ++i ) { while (!_stage_1[i].empty()) { (_stage_1[i].begin()->second)->Free(); @@ -60,7 +60,7 @@ Chipper::~Chipper() } } - for ( int i = 0; i < _inputs; ++i ) { + for ( int i = 0; i < _inputs-1; ++i ) { while (!_stage_2[i].empty()) { (_stage_2[i].begin()->second)->Free(); @@ -68,7 +68,7 @@ Chipper::~Chipper() } } - for ( int o = 0; o < _outputs; ++o ) { + for ( int o = 0; o < _outputs-1; ++o ) { while (!_output_buffer[o].empty()) { (_output_buffer[o].begin()->second)->Free(); @@ -105,11 +105,11 @@ int Chipper::GetInjectStatus() map::iterator f = _stage_1[input].find(GetSimTime()); if(f == _stage_1[input].end()) { - _inject_slot = input; + // _inject_slot = input; return 1; } } - _inject_slot = -1; + // _inject_slot = -1; return 0; } @@ -186,6 +186,8 @@ void Chipper::_InternalStep( ) Permute(); _stage2_to_output(); + + CheckSanity(); } // Added by HH @@ -288,7 +290,11 @@ void Chipper::_stage1_to_stage2() // } it = _stage_1[input].find(_time); if(it == _stage_1[input].end()) + { + if(_inject_slot == -1) + _inject_slot = input; continue; + } _stage_2[input].insert(make_pair(it->first+1, it->second)); _stage_1[input].erase(it); } @@ -299,7 +305,16 @@ void Chipper::_stage1_to_stage2() Flit *f = _input_channels[last_channel]->Receive(); if(f) { - _stage_2[_inject_slot].insert(make_pair(_time+1, it->second)); + if(f->watch) { + *gWatchOut << GetSimTime() << " | " + << "router" << GetID() << " | " + << "Receiving flit " << f->id + << " at time " << _time + << " with priority " << f->pri + << " and golden status " << f->golden + << "." << endl; + } + _stage_2[_inject_slot].insert(make_pair(_time+1, f)); _inject_slot = -1; } } @@ -449,4 +464,43 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) } } } +} + +void Chipper::CheckSanity() +{ + for ( int i = 0; i < _inputs-1; ++i ) { + if(_input_buffer[i].size() > 2) + { + ostringstream err; + err << "Flit pile up at input buffer of router: " << GetID(); + Error( err.str( ) ); + } + } + + for ( int i = 0; i < _inputs-1; ++i ) { + if(_stage_1[i].size() > 2) + { + ostringstream err; + err << "Flit pile up at _stage_1 of router: " << GetID(); + Error( err.str( ) ); + } + } + + for ( int i = 0; i < _inputs-1; ++i ) { + if(_stage_2[i].size() > 2) + { + ostringstream err; + err << "Flit pile up at _stage_2 of router: " << GetID(); + Error( err.str( ) ); + } + } + + for ( int o = 0; o < _outputs-1; ++o ) { + if(_output_buffer[o].size() > 2) + { + ostringstream err; + err << "Flit pile up at output buffer of router: " << GetID(); + Error( err.str( ) ); + } + } } \ No newline at end of file diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp index 23226c2c..8d9950d2 100755 --- a/src/routers/chipper.hpp +++ b/src/routers/chipper.hpp @@ -35,6 +35,7 @@ class Chipper : public Router { void Permute(); void _stage2_to_output(); void Partial_Permute(int dir1, int dir2, int perm_num); + void CheckSanity(); public: Chipper( const Configuration& config, From 479f57286a89e3831b771793a1014f15bbc12163 Mon Sep 17 00:00:00 2001 From: sabersword Date: Sun, 15 Jan 2017 14:29:31 +0530 Subject: [PATCH 18/35] Clean unnecesarry comments in chipper.cpp --- src/routers/chipper.cpp | 47 ----------------------------------------- 1 file changed, 47 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 225fad07..7f117893 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -129,20 +129,6 @@ void Chipper::ReadInputs() } } -// HH Definition of _ReceiveFlits: inserts flit into buffer from channel corresponding to current sim time -// void Chipper::_IncomingFlits( ) -// { -// Flit *f; -// map< int,Flit* > buffer_timed; -// int receive_time = GetSimTime(); -// for ( int input = 0; input < _inputs; ++input ) { -// f = _input_channels[input]->Receive(); -// if ( f ) { -// _input_buffer[input].insert( pair(receive_time,f) ); -// } -// } -// } - // HH : Performs the function of sending flits from output buffer into channel void Chipper::WriteOutputs() { @@ -168,13 +154,6 @@ void Chipper::_SendFlits( ) void Chipper::_InternalStep( ) { - // Receive incoming flits - // int pair_time = _IncomingFlits( ); - //HH : Need to make the time the flits are received global in order to know when the input flits were -// were paired into the map - //Have to pass this onto subsequent functions to find the correct flit from each buffer - // I am thinking pair_time should be updated at each stage with GetSimTime and then passed onto next stage - // Eject flits which have reached their desitnation _time = GetSimTime(); _EjectFlits(); @@ -264,12 +243,6 @@ void Chipper::_input_to_stage1() { map::iterator it; for ( int input = 0; input < _inputs-1; ++input ){ - // intermediate = _input_buffer[input]; - // for( map::iterator it = intermediate_1.begin() ; it = intermediate_1.end() ; ++it ){ //Nandan: Adding the delay associated with the pipe - // if(pair_time == it->first){ - // it->first = it->first + 1; - // } - // } it =_input_buffer[input].find(_time); if(it == _input_buffer[input].end()) continue; @@ -282,12 +255,6 @@ void Chipper::_stage1_to_stage2() { map::iterator it; for ( int input = 0; input < _inputs-1; ++input ){ // Nandan: Adding the delay associated with the pipe - // intermediate = _stage_1[input]; - // for( map::iterator it = intermediate_2.begin() ; it = intermediate_2.end() ; ++it ){ - // if(pair_time == it->first){ - // it->first = it->first + 1; - // } - // } it = _stage_1[input].find(_time); if(it == _stage_1[input].end()) { @@ -335,24 +302,10 @@ void Chipper::_stage2_to_output() // Nandan: Routing stage of CHIPPER void Chipper::Permute() { - // int router_number = GetID(); - // int west = _LeftNode(router_number, 0); - // int east = _RightNode(router_number, 0); - // int north = _LeftNode(router_number, 1); - // int south = _RightNode(router_number, 1); - // vector direction; - // vector priority; - // vector golden; - // direction.resize(_inputs-1); - // priority.resize(_inputs-1); - // for(input = 0; input < _inputs; ++input) - // { - Partial_Permute(2,0,1); Partial_Permute(3,1,1); Partial_Permute(3,2,2); Partial_Permute(1,0,0); - } void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) From a7f4b0eb4a75e793df2b172ee8d696302347f9eb Mon Sep 17 00:00:00 2001 From: sabersword Date: Sun, 15 Jan 2017 15:36:47 +0530 Subject: [PATCH 19/35] Add flit watch statements in chipper.cpp --- src/routers/chipper.cpp | 81 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 7f117893..6ba925c1 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -187,6 +187,15 @@ void Chipper::_EjectFlits(){ f = it->second; if ( f->dest == GetID() ) { + if(f->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << f->id + << " waiting for eject at " << f->dest + << " with priority " << f->pri + << " and golden status " << f->golden + << "." << endl; + } received_flits[input] = f; // Check for golden status and golden tie if(f->golden == 1 && !golden_cnt) @@ -196,10 +205,20 @@ void Chipper::_EjectFlits(){ } else if(f->golden == 1) { - if(received_flits[flit_to_eject]->pri > f->pri) // Resolve golden tie based on older flit + if(received_flits[flit_to_eject]->pri < f->pri) // Resolve golden tie based on older flit { flit_to_eject = input; - break; + } + else + { + if(f->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << f->id + << " trying to eject at " << f->dest + << " lost golden tie at time " << _time + << "." << endl; + } } } } @@ -211,7 +230,7 @@ void Chipper::_EjectFlits(){ if(flit_to_eject == -1) { - int oldest_flit_index; + int oldest_flit_index = -1; int high_pri = -1; for( int input = 0; input < _inputs-1; ++input ) { @@ -219,6 +238,19 @@ void Chipper::_EjectFlits(){ // to find the oldest flit and consequently retiring that flit if(received_flits[input] != NULL && received_flits[input]->pri > high_pri) { + if(oldest_flit_index != -1) + { + if(received_flits[input]->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << received_flits[input]->id + << " waiting for eject at " << received_flits[input]->dest + << " with priority " << received_flits[input]->pri + << " beat flit " << received_flits[oldest_flit_index]->id + << " with priority " << high_pri + << "." << endl; + } + } high_pri = received_flits[input]->pri; oldest_flit_index = input; } @@ -226,6 +258,14 @@ void Chipper::_EjectFlits(){ if(high_pri > -1) { flit_to_eject = oldest_flit_index; + if(received_flits[flit_to_eject]->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << received_flits[flit_to_eject]->id + << " accepted for eject at " << received_flits[flit_to_eject]->dest + << " | golden status " << received_flits[flit_to_eject]->golden + << "." << endl; + } _output_channels[last_channel]->Send(received_flits[flit_to_eject]); _input_buffer[flit_to_eject].erase(_input_buffer[flit_to_eject].find(_time)); // HH : Receive flit with oldest_flit_index -> Need to apply the function that handles retire flit @@ -234,6 +274,14 @@ void Chipper::_EjectFlits(){ else { // Ameya: Eject golden flit + if(f->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << f->id + << " accepted for eject at " << f->dest + << " | golden status " << f->golden + << "." << endl; + } _output_channels[last_channel]->Send(received_flits[flit_to_eject]); _input_buffer[flit_to_eject].erase(_input_buffer[flit_to_eject].find(_time)); } @@ -246,6 +294,15 @@ void Chipper::_input_to_stage1() it =_input_buffer[input].find(_time); if(it == _input_buffer[input].end()) continue; + if((it->second)->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << (it->second)->id + << " headed for " << (it->second)->dest + << " written from _input_buffer to _stage_1 in slot " + << input + << "." << endl; + } _stage_1[input].insert(make_pair(it->first+1, it->second)); _input_buffer[input].erase(it); } @@ -262,6 +319,15 @@ void Chipper::_stage1_to_stage2() _inject_slot = input; continue; } + if((it->second)->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << (it->second)->id + << " headed for " << (it->second)->dest + << " written from _stage_1 to _stage_2 in slot " + << input + << "." << endl; + } _stage_2[input].insert(make_pair(it->first+1, it->second)); _stage_1[input].erase(it); } @@ -294,6 +360,15 @@ void Chipper::_stage2_to_output() it = _stage_2[input].find(_time); if(it == _stage_2[input].end()) continue; + if((it->second)->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << (it->second)->id + << " headed for " << (it->second)->dest + << " written from _stage_2 to _output_buffer in slot " + << input + << "." << endl; + } _output_buffer[input].insert(make_pair(it->first+1, it->second)); _stage_2[input].erase(it); } From 00f51833b178d1d06762efff98e47f2d599a2661 Mon Sep 17 00:00:00 2001 From: sabersword Date: Sun, 15 Jan 2017 15:54:04 +0530 Subject: [PATCH 20/35] Add additional flit watch statements in chipper.cpp --- src/routers/chipper.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 6ba925c1..75fafd4c 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -124,7 +124,15 @@ void Chipper::ReadInputs() if ( f ) { - _input_buffer[input].insert( pair(time, f) ); + if(f->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << f->id + << " arrived at input " << input << " | " + << "destination " << f->dest + << "." << endl; + } + _input_buffer[input].insert( pair(time, f) ); } } } @@ -146,6 +154,14 @@ void Chipper::_SendFlits( ) f = buffer_timed.find( time ); if(f != buffer_timed.end() ) { + if((f->second)->watch) { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << (f->second)->id + << " sent from output " << output << " | " + << "destination " << (f->second)->dest + << "." << endl; + } _output_channels[output]->Send( f->second ); buffer_timed.erase(f); } From bfa86d79b9d50f9116e6e578f6ddebdb2dd46e70 Mon Sep 17 00:00:00 2001 From: sabersword Date: Sun, 15 Jan 2017 23:06:28 +0530 Subject: [PATCH 21/35] Correct permute logic and update flit watch statements in chipper.cpp --- src/routers/chipper.cpp | 91 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 75fafd4c..1764283a 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -397,6 +397,42 @@ void Chipper::Permute() Partial_Permute(3,1,1); Partial_Permute(3,2,2); Partial_Permute(1,0,0); + for(int i=0;i < _inputs-1;++i) + { + Flit *f; + map::iterator it; + it = _stage_2[i].find(_time); + if(it == _stage_2[i].end()) + { + continue; + } + else + { + f = it->second; + } + if(!(f->watch)) + continue; + if(_rf(GetID(), f->dest, true) == i) + { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << f->id + << " headed for " << f->dest + << " optimally routed" + << " to node "<< (_output_channels[i]->GetSink())->GetID() + << "." << endl; + } + else + { + *gWatchOut << GetSimTime() << " | " + << "node" << GetID() << " | " + << "Flit " << f->id + << " headed for " << f->dest + << " sub-optimally routed" + << " to node "<< (_output_channels[i]->GetSink())->GetID() + << "." << endl; + } + } } void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) @@ -424,34 +460,77 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) } if((f1 == NULL)&&(f2 == NULL)) return; - if((f1 == NULL)) + if(f1 == NULL) { if(_rf(GetID(), f2->dest, true) > perm_num) { _stage_2[dir2].erase(it2); _stage_2[dir1].insert(pair(_time, f2) ); } + // if(f2->watch) { + // *gWatchOut << GetSimTime() << " | " + // << "node" << GetID() << " | " + // << "Flit " << f2->id + // << " headed for " << f2->dest + // << " optimally routed (no contention) " + // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" + // << "." << endl; + // } return; } - if((f2 == NULL)) + if(f2 == NULL) { - if(_rf(GetID(), f1->dest, true) < perm_num) + if(_rf(GetID(), f1->dest, true) <= perm_num) { _stage_2[dir1].erase(it1); _stage_2[dir2].insert(pair(_time, f1) ); } + // if(f1->watch) { + // *gWatchOut << GetSimTime() << " | " + // << "node" << GetID() << " | " + // << "Flit " << f1->id + // << " headed for " << f1->dest + // << " optimally routed (no contention) " + // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" + // << "." << endl; + // } return; } + // if((f1->watch)||(f2->watch)) { + // *gWatchOut << GetSimTime() << " | " + // << "node" << GetID() << " | " + // << " f1 " << f1->id << " dest1 " << f1->dest + // << " f2 " << f2->id << " dest2 " << f2->dest + // <golden == 1)&&(f2->golden == 1)) { if(f1->pri >= f2->pri) { - if(_rf(GetID(), f1->dest, true) < perm_num) + if(_rf(GetID(), f1->dest, true) <= perm_num) { _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); _stage_2[dir2].insert( pair(_time, f1) ); _stage_2[dir1].insert( pair(_time, f2) ); + // if(f1->watch) { + // *gWatchOut << GetSimTime() << " | " + // << "node" << GetID() << " | " + // << "Flit " << f1->id + // << " headed for " << f1->dest + // << " optimally routed (no contention) " + // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" + // << "." << endl; + // } + // if(f1->watch) { + // *gWatchOut << GetSimTime() << " | " + // << "node" << GetID() << " | " + // << "Flit " << f1->id + // << " headed for " << f1->dest + // << " optimally routed (no contention) " + // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" + // << "." << endl; + // } } } else @@ -467,7 +546,7 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) } else if((f1->golden == 1)) { - if(_rf(GetID(), f1->dest, true) < perm_num) + if(_rf(GetID(), f1->dest, true) <= perm_num) { _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); @@ -489,7 +568,7 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { if(f1->pri >= f2->pri) { - if(_rf(GetID(), f1->dest, true) < perm_num) + if(_rf(GetID(), f1->dest, true) <= perm_num) { _stage_2[dir1].erase(it1); _stage_2[dir2].erase(it2); From 94fd2da304972a0af77afbd706f388b21c817dbb Mon Sep 17 00:00:00 2001 From: sabersword Date: Sun, 15 Jan 2017 23:09:27 +0530 Subject: [PATCH 22/35] Clean unnecesarry comments in chipper.cpp --- src/routers/chipper.cpp | 43 ----------------------------------------- 1 file changed, 43 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 1764283a..c6d2f1fd 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -467,15 +467,6 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) _stage_2[dir2].erase(it2); _stage_2[dir1].insert(pair(_time, f2) ); } - // if(f2->watch) { - // *gWatchOut << GetSimTime() << " | " - // << "node" << GetID() << " | " - // << "Flit " << f2->id - // << " headed for " << f2->dest - // << " optimally routed (no contention) " - // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" - // << "." << endl; - // } return; } if(f2 == NULL) @@ -485,24 +476,8 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) _stage_2[dir1].erase(it1); _stage_2[dir2].insert(pair(_time, f1) ); } - // if(f1->watch) { - // *gWatchOut << GetSimTime() << " | " - // << "node" << GetID() << " | " - // << "Flit " << f1->id - // << " headed for " << f1->dest - // << " optimally routed (no contention) " - // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" - // << "." << endl; - // } return; } - // if((f1->watch)||(f2->watch)) { - // *gWatchOut << GetSimTime() << " | " - // << "node" << GetID() << " | " - // << " f1 " << f1->id << " dest1 " << f1->dest - // << " f2 " << f2->id << " dest2 " << f2->dest - // <golden == 1)&&(f2->golden == 1)) { if(f1->pri >= f2->pri) @@ -513,24 +488,6 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) _stage_2[dir2].erase(it2); _stage_2[dir2].insert( pair(_time, f1) ); _stage_2[dir1].insert( pair(_time, f2) ); - // if(f1->watch) { - // *gWatchOut << GetSimTime() << " | " - // << "node" << GetID() << " | " - // << "Flit " << f1->id - // << " headed for " << f1->dest - // << " optimally routed (no contention) " - // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" - // << "." << endl; - // } - // if(f1->watch) { - // *gWatchOut << GetSimTime() << " | " - // << "node" << GetID() << " | " - // << "Flit " << f1->id - // << " headed for " << f1->dest - // << " optimally routed (no contention) " - // << "in step " <<(perm_num == 1 ? 1 : 2)<< " of permute" - // << "." << endl; - // } } } else From fc5b1fa82120389e7f8591d1a2a6a8b7b9016d10 Mon Sep 17 00:00:00 2001 From: sabersword Date: Mon, 16 Jan 2017 23:57:43 +0530 Subject: [PATCH 23/35] Correct cause of segmentation fault in chipper.cpp --- src/routers/chipper.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index c6d2f1fd..5c601f89 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -48,31 +48,31 @@ Chipper::~Chipper() while (!_input_buffer[i].empty()) { (_input_buffer[i].begin()->second)->Free(); - _input_buffer[i].erase(_input_buffer[i].begin()); + _input_buffer[i].erase(_input_buffer[i].begin()); } } - + for ( int i = 0; i < _inputs-1; ++i ) { while (!_stage_1[i].empty()) { (_stage_1[i].begin()->second)->Free(); - _stage_1.erase(_stage_1.begin()); + _stage_1[i].erase(_stage_1[i].begin()); } } - + for ( int i = 0; i < _inputs-1; ++i ) { while (!_stage_2[i].empty()) { (_stage_2[i].begin()->second)->Free(); - _stage_2.erase(_stage_2.begin()); + _stage_2[i].erase(_stage_2[i].begin()); } } - + for ( int o = 0; o < _outputs-1; ++o ) { while (!_output_buffer[o].empty()) { (_output_buffer[o].begin()->second)->Free(); - _output_buffer[o].erase(_output_buffer[o].begin()); + _output_buffer[o].erase(_output_buffer[o].begin()); } } } From 2093437deb61ee67e221ad9593883554b28581ba Mon Sep 17 00:00:00 2001 From: sabersword Date: Mon, 16 Jan 2017 22:55:01 +0530 Subject: [PATCH 24/35] Correct stats for blesstrafficmanager --- src/blesstrafficmanager.cpp | 201 +++++++++++++++++++++++++----------- src/blesstrafficmanager.hpp | 8 ++ src/flit.cpp | 3 + src/flit.hpp | 1 + 4 files changed, 150 insertions(+), 63 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index 8c96fd24..b3869e77 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -14,7 +14,9 @@ BlessTrafficManager::BlessTrafficManager( const Configuration &config, const vector & net ) : TrafficManager(config, net), _golden_turn(0), _golden_in_flight(0) -{} +{ + _retire_stats.resize(config.GetInt("classes")); +} BlessTrafficManager::~BlessTrafficManager( ) {} @@ -97,7 +99,8 @@ void BlessTrafficManager::_Step( ) << "Injecting flit " << f->id << " into subnet " << subnet << " at time " << _time - << " with priority " << f->pri + << " with priority " << f->pri << " | " + << " Destination " << f->dest << "." << endl; } #ifdef TRACK_FLOWS @@ -223,6 +226,7 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, f->ctime = time; f->record = record; f->cl = cl; + f->size = size; _total_in_flight_flits[f->cl].insert(make_pair(f->id, f)); if(record) { @@ -305,6 +309,8 @@ void BlessTrafficManager::_UpdateGoldenStatus( int source ) void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) { + int first = 0; + _deadlock_timer = 0; assert(_total_in_flight_flits[f->cl].count(f->id) > 0); @@ -342,72 +348,143 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) _pair_flat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - f->itime ); } - if ( f->tail ) { - Flit * head; - if(f->head) { - head = f; - } else { - map::iterator iter = _retired_packets[f->cl].find(f->pid); - assert(iter != _retired_packets[f->cl].end()); - head = iter->second; - _retired_packets[f->cl].erase(iter); - assert(head->head); - assert(f->pid == head->pid); - } - if ( f->watch ) { - *gWatchOut << GetSimTime() << " | " - << "node" << dest << " | " - << "Retiring packet " << f->pid - << " (plat = " << f->atime - head->ctime - << ", nlat = " << f->atime - head->itime - << ", frag = " << (f->atime - head->atime) - (f->id - head->id) // NB: In the spirit of solving problems using ugly hacks, we compute the packet length by taking advantage of the fact that the IDs of flits within a packet are contiguous. - << ", src = " << head->src - << ", dest = " << head->dest - << ", golden = " << head->golden - << ")." << endl; - } - - //code the source of request, look carefully, its tricky ;) - if (f->type == Flit::READ_REQUEST || f->type == Flit::WRITE_REQUEST) { - PacketReplyInfo* rinfo = PacketReplyInfo::New(); - rinfo->source = f->src; - rinfo->time = f->atime; - rinfo->record = f->record; - rinfo->type = f->type; - _repliesPending[dest].push_back(rinfo); - } else { - if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY ){ - _requestsOutstanding[dest]--; - } else if(f->type == Flit::ANY_TYPE) { - _requestsOutstanding[f->src]--; + map::iterator iter = _retire_stats[f->cl].find(f->pid); + if( iter != _retire_stats[f->cl].end() ) + { + Stat_Util *prime = iter->second; + prime->pending--; + if(prime->pending == 0) + { + // Entire packet has arrived + Flit * head = prime->f; + free(prime); + _retire_stats[f->cl].erase(iter); + if ( f->watch ) { + *gWatchOut << GetSimTime() << " | " + << "node" << dest << " | " + << "Retiring packet " << f->pid + << " (plat = " << f->atime - head->ctime + << ", nlat = " << f->atime - head->itime + << ", frag = " << (f->atime - head->atime) - (f->id - head->id) // NB: In the spirit of solving problems using ugly hacks, we compute the packet length by taking advantage of the fact that the IDs of flits within a packet are contiguous. + << ", src = " << head->src + << ", dest = " << head->dest + << ", golden = " << head->golden + << ")." << endl; + } + // code the source of request, look carefully, its tricky ;) + if (f->type == Flit::READ_REQUEST || f->type == Flit::WRITE_REQUEST) { + PacketReplyInfo* rinfo = PacketReplyInfo::New(); + rinfo->source = f->src; + rinfo->time = f->atime; + rinfo->record = f->record; + rinfo->type = f->type; + _repliesPending[dest].push_back(rinfo); + } else { + if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY ){ + _requestsOutstanding[dest]--; + } else if(f->type == Flit::ANY_TYPE) { + _requestsOutstanding[f->src]--; + } } - } - - // Only record statistics once per packet (at tail) - // and based on the simulation state - if ( ( _sim_state == warming_up ) || f->record ) { + // Only record statistics once per packet (at tail) + // and based on the simulation state + if ( ( _sim_state == warming_up ) || f->record ) { - _hop_stats[f->cl]->AddSample( f->hops ); + _hop_stats[f->cl]->AddSample( f->hops ); - if((_slowest_packet[f->cl] < 0) || - (_plat_stats[f->cl]->Max() < (f->atime - head->itime))) - _slowest_packet[f->cl] = f->pid; - _plat_stats[f->cl]->AddSample( f->atime - head->ctime); - _nlat_stats[f->cl]->AddSample( f->atime - head->itime); - _frag_stats[f->cl]->AddSample( (f->atime - head->atime) - (f->id - head->id) ); + if((_slowest_packet[f->cl] < 0) || + (_plat_stats[f->cl]->Max() < (f->atime - head->itime))) + _slowest_packet[f->cl] = f->pid; + _plat_stats[f->cl]->AddSample( f->atime - head->ctime); + _nlat_stats[f->cl]->AddSample( f->atime - head->itime); + _frag_stats[f->cl]->AddSample( (f->atime - head->atime) - (f->id - head->id) ); - if(_pair_stats){ - _pair_plat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->ctime ); - _pair_nlat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->itime ); + if(_pair_stats){ + _pair_plat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->ctime ); + _pair_nlat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->itime ); + } } + if(f != head) { + head->Free(); + } } - - if(f != head) { - head->Free(); - } - } + else + { + // First flit of packet is being retired + first = 1; + Stat_Util *s = new Stat_Util; + s->f = f; + s->pending = (f->size) - 1; + _retire_stats[f->cl].insert(make_pair(f->pid, s)); + } + // if ( f->tail ) { + // Flit * head; + // if(f->head) { + // head = f; + // } else { + // map::iterator iter = _retired_packets[f->cl].find(f->pid); + // assert(iter != _retired_packets[f->cl].end()); + // head = iter->second; + // _retired_packets[f->cl].erase(iter); + // assert(head->head); + // assert(f->pid == head->pid); + // } + // if ( f->watch ) { + // *gWatchOut << GetSimTime() << " | " + // << "node" << dest << " | " + // << "Retiring packet " << f->pid + // << " (plat = " << f->atime - head->ctime + // << ", nlat = " << f->atime - head->itime + // << ", frag = " << (f->atime - head->atime) - (f->id - head->id) // NB: In the spirit of solving problems using ugly hacks, we compute the packet length by taking advantage of the fact that the IDs of flits within a packet are contiguous. + // << ", src = " << head->src + // << ", dest = " << head->dest + // << ", golden = " << head->golden + // << ")." << endl; + // } + + // //code the source of request, look carefully, its tricky ;) + // if (f->type == Flit::READ_REQUEST || f->type == Flit::WRITE_REQUEST) { + // PacketReplyInfo* rinfo = PacketReplyInfo::New(); + // rinfo->source = f->src; + // rinfo->time = f->atime; + // rinfo->record = f->record; + // rinfo->type = f->type; + // _repliesPending[dest].push_back(rinfo); + // } else { + // if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY ){ + // _requestsOutstanding[dest]--; + // } else if(f->type == Flit::ANY_TYPE) { + // _requestsOutstanding[f->src]--; + // } + + // } + + // // Only record statistics once per packet (at tail) + // // and based on the simulation state + // if ( ( _sim_state == warming_up ) || f->record ) { + + // _hop_stats[f->cl]->AddSample( f->hops ); + + // if((_slowest_packet[f->cl] < 0) || + // (_plat_stats[f->cl]->Max() < (f->atime - head->itime))) + // _slowest_packet[f->cl] = f->pid; + // _plat_stats[f->cl]->AddSample( f->atime - head->ctime); + // _nlat_stats[f->cl]->AddSample( f->atime - head->itime); + // _frag_stats[f->cl]->AddSample( (f->atime - head->atime) - (f->id - head->id) ); + + // if(_pair_stats){ + // _pair_plat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->ctime ); + // _pair_nlat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->itime ); + // } + // } + + // if(f != head) { + // head->Free(); + // } + + // } if(f->golden) { @@ -426,9 +503,7 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) } } - if(f->head && !f->tail) { - _retired_packets[f->cl].insert(make_pair(f->pid, f)); - } else { + if(!first) { f->Free(); } } \ No newline at end of file diff --git a/src/blesstrafficmanager.hpp b/src/blesstrafficmanager.hpp index 61297877..9a22cc4a 100644 --- a/src/blesstrafficmanager.hpp +++ b/src/blesstrafficmanager.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "config_utils.hpp" #include "stats.hpp" @@ -17,6 +18,13 @@ class BlessTrafficManager : public TrafficManager { int _golden_turn; int _golden_in_flight; vector _golden_flits; + + struct Stat_Util{ + Flit * f; + int pending; + }; + + vector > _retire_stats; protected: diff --git a/src/flit.cpp b/src/flit.cpp index 5bf99a58..c8ac9350 100644 --- a/src/flit.cpp +++ b/src/flit.cpp @@ -77,6 +77,9 @@ void Flit::Reset() src = -1; dest = -1; pri = 0; + // Ameya + golden = 0; + size = 0; intm =-1; ph = -1; data = 0; diff --git a/src/flit.hpp b/src/flit.hpp index ad220180..17770a91 100644 --- a/src/flit.hpp +++ b/src/flit.hpp @@ -68,6 +68,7 @@ class Flit { int pri; // Ameya: For bufferless routing int golden; + int size; int hops; bool watch; From 2bfa3f174169e54f25b900f3598ef9aba52634de Mon Sep 17 00:00:00 2001 From: sabersword Date: Mon, 16 Jan 2017 23:51:14 +0530 Subject: [PATCH 25/35] Fix packet length stats in blesstrafficmanager --- src/blesstrafficmanager.cpp | 16 +++++++++++----- src/main.cpp | 1 - src/routers/chipper.cpp | 3 +-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index b3869e77..18073a6d 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -52,10 +52,7 @@ void BlessTrafficManager::_Step( ) if((_sim_state == warming_up) || (_sim_state == running)) { ++_accepted_flits[f->cl][n]; - if(f->tail) - { - ++_accepted_packets[f->cl][n]; - } + // Update of _accepted_packets[f->cl][n] moved to _RetireFlit } } } @@ -103,6 +100,14 @@ void BlessTrafficManager::_Step( ) << " Destination " << f->dest << "." << endl; } + + if((_sim_state == warming_up) || (_sim_state == running)) { + ++_sent_flits[f->cl][n]; + if(f->head) { + ++_sent_packets[f->cl][n]; + } + } + #ifdef TRACK_FLOWS ++_injected_flits[f->cl][n]; #endif @@ -407,7 +412,8 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) } if(f != head) { head->Free(); - } + } + ++_accepted_packets[f->cl][dest]; // Ameya: Moved here from _Step() } } else diff --git a/src/main.cpp b/src/main.cpp index 0bd80f39..57345d97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,7 +55,6 @@ #include "power_module.hpp" - /////////////////////////////////////////////////////////////////////////////// //Global declarations ////////////////////// diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 5c601f89..2a1fd02a 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -18,10 +18,9 @@ Chipper::Chipper( const Configuration& config, id, inputs, outputs ) { - ostringstream module_name; + ostringstream module_name; // Routing - string rf = "dor_next_mesh"; map::iterator rf_iter = cRoutingFunctionMap.find(rf); if(rf_iter == cRoutingFunctionMap.end()) { From b703a1417a47e26b6dd0dad2d3f7a8ef9f8189b3 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 18 Jan 2017 23:38:13 +0530 Subject: [PATCH 26/35] Fix routing to invalid channels in chipper.cpp --- src/routers/chipper.cpp | 94 +++++++++++++++++++++++++++++++++++++---- src/routers/chipper.hpp | 3 ++ 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 2a1fd02a..e9510851 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -39,6 +39,8 @@ Chipper::Chipper( const Configuration& config, _time = 0; _inject_slot = -1; last_channel = _inputs-1; + + router_type = Find_Edge_Router(id, config.GetInt("k") ); } Chipper::~Chipper() @@ -101,14 +103,31 @@ int Chipper::GetInjectStatus() { for ( int input = 0; input < _inputs - 1; ++input ) { + if( !IsChannelValid( input ) ) + continue; map::iterator f = _stage_1[input].find(GetSimTime()); if(f == _stage_1[input].end()) { - // _inject_slot = input; return 1; } } - // _inject_slot = -1; + return 0; +} + +int Chipper::IsChannelValid( int input ) +{ + if(input == 0) + if((router_type == 0)||(router_type == 1)||(router_type == 4)||(router_type == 5)||(router_type == 6)||(router_type == 7)) + return 1; + if(input == 1) + if((router_type == 1)||(router_type == 2)||(router_type == 3)||(router_type == 4)||(router_type == 7)||(router_type == 8)) + return 1; + if(input == 2) + if((router_type == 0)||(router_type == 1)||(router_type == 2)||(router_type == 3)||(router_type == 4)||(router_type == 5)) + return 1; + if(input == 3) + if((router_type == 3)||(router_type == 4)||(router_type == 5)||(router_type == 6)||(router_type == 7)||(router_type == 8)) + return 1; return 0; } @@ -330,7 +349,7 @@ void Chipper::_stage1_to_stage2() it = _stage_1[input].find(_time); if(it == _stage_1[input].end()) { - if(_inject_slot == -1) + if((_inject_slot == -1)&&(IsChannelValid(input))) _inject_slot = input; continue; } @@ -355,9 +374,10 @@ void Chipper::_stage1_to_stage2() { if(f->watch) { *gWatchOut << GetSimTime() << " | " - << "router" << GetID() << " | " + << "node" << GetID() << " | " << "Receiving flit " << f->id << " at time " << _time + << " at slot " << _inject_slot << " with priority " << f->pri << " and golden status " << f->golden << "." << endl; @@ -392,10 +412,47 @@ void Chipper::_stage2_to_output() // Nandan: Routing stage of CHIPPER void Chipper::Permute() { - Partial_Permute(2,0,1); - Partial_Permute(3,1,1); - Partial_Permute(3,2,2); - Partial_Permute(1,0,0); + if(router_type == 0) + Partial_Permute(2,0,1); + else if(router_type == 1) + { + Partial_Permute(2,0,1); + Partial_Permute(2,1,1); + Partial_Permute(1,0,0); + } + else if(router_type == 2) + Partial_Permute(2,1,1); + else if(router_type == 3) + { + Partial_Permute(3,1,1); + Partial_Permute(2,1,1); + Partial_Permute(3,2,2); + } + else if(router_type == 4) + { + Partial_Permute(2,0,1); + Partial_Permute(3,1,1); + Partial_Permute(3,2,2); + Partial_Permute(1,0,0); + } + else if(router_type == 5) + { + Partial_Permute(2,0,1); + Partial_Permute(3,0,1); + Partial_Permute(3,2,2); + } + else if(router_type == 6) + Partial_Permute(3,0,2); + else if(router_type == 7) + { + Partial_Permute(3,1,1); + Partial_Permute(3,0,1); + Partial_Permute(1,0,0); + } + else if (router_type == 8) + Partial_Permute(3,1,2); + // end permute part + for(int i=0;i < _inputs-1;++i) { Flit *f; @@ -545,6 +602,27 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) } } +int Chipper::Find_Edge_Router(int router_number, int k) +{ + if(router_number == 0) + return 0; + else if(router_number == (k-1) ) + return 2; + else if(router_number == ((k*k)-1) ) + return 8; + else if(router_number == ((k*k)-1-k) ) + return 6; + else if(router_number > ((k*k)-1-k) && (router_number < ((k*k)-1) ) ) + return 7; + else if( (router_number%k) == 0 ) + return 5; + else if( (router_number/k) == 0 ) + return 1; + else if( (router_number%k) == (k-1) ) + return 3; + else return 4; +} + void Chipper::CheckSanity() { for ( int i = 0; i < _inputs-1; ++i ) { diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp index 8d9950d2..f8477542 100755 --- a/src/routers/chipper.hpp +++ b/src/routers/chipper.hpp @@ -20,6 +20,7 @@ class Chipper : public Router { vector > _stage_2; // No need for extra flags showing occupancy as each buffer is timed + int router_type; int _time; int _inject_slot; int last_channel; @@ -36,6 +37,8 @@ class Chipper : public Router { void _stage2_to_output(); void Partial_Permute(int dir1, int dir2, int perm_num); void CheckSanity(); + int Find_Edge_Router(int id, int k); + int IsChannelValid( int input ); public: Chipper( const Configuration& config, From 4d02f0a4f9e8d7e9a559db3a468f8979493651b0 Mon Sep 17 00:00:00 2001 From: sabersword Date: Thu, 19 Jan 2017 01:46:41 +0530 Subject: [PATCH 27/35] Fix flit overwriting at inject --- src/routers/chipper.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index e9510851..bab3cf72 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -344,13 +344,25 @@ void Chipper::_input_to_stage1() void Chipper::_stage1_to_stage2() { - map::iterator it; - for ( int input = 0; input < _inputs-1; ++input ){ // Nandan: Adding the delay associated with the pipe + map::iterator it,it1; + for ( int input = 0; input < _inputs-1; ++input ) // Nandan: Adding the delay associated with the pipe + { it = _stage_1[input].find(_time); if(it == _stage_1[input].end()) { if((_inject_slot == -1)&&(IsChannelValid(input))) + { _inject_slot = input; + // Precaution (possibly redundant) + it1 = _stage_2[_inject_slot].find(_time+1); + if(!(it1 == _stage_2[_inject_slot].end())) + { + ostringstream err; + err << GetSimTime() << " | Magic flit: " << GetID(); + Error( err.str( ) ); + } + // End precaution + } continue; } if((it->second)->watch) { @@ -369,6 +381,15 @@ void Chipper::_stage1_to_stage2() if(_inject_slot > -1) { assert(_inject_slot < _inputs - 1); + // Precaution (possibly redundant) + it1 = _stage_2[_inject_slot].find(_time+1); + if(!(it1 == _stage_2[_inject_slot].end())) + { + ostringstream err; + err << GetSimTime() << " | Flit pile up at inject stage of router: " << GetID(); + Error( err.str( ) ); + } + // End precaution Flit *f = _input_channels[last_channel]->Receive(); if(f) { @@ -376,6 +397,7 @@ void Chipper::_stage1_to_stage2() *gWatchOut << GetSimTime() << " | " << "node" << GetID() << " | " << "Receiving flit " << f->id + << " headed for " << f->dest << " at time " << _time << " at slot " << _inject_slot << " with priority " << f->pri @@ -383,8 +405,8 @@ void Chipper::_stage1_to_stage2() << "." << endl; } _stage_2[_inject_slot].insert(make_pair(_time+1, f)); - _inject_slot = -1; } + _inject_slot = -1; } } @@ -610,9 +632,9 @@ int Chipper::Find_Edge_Router(int router_number, int k) return 2; else if(router_number == ((k*k)-1) ) return 8; - else if(router_number == ((k*k)-1-k) ) + else if(router_number == ((k*k)-k) ) return 6; - else if(router_number > ((k*k)-1-k) && (router_number < ((k*k)-1) ) ) + else if(router_number > ((k*k)-k) && (router_number < ((k*k)-1) ) ) return 7; else if( (router_number%k) == 0 ) return 5; From 4c465dd164d32d20d8284d27bdc57e9822529eee Mon Sep 17 00:00:00 2001 From: sabersword Date: Thu, 19 Jan 2017 01:57:26 +0530 Subject: [PATCH 28/35] Fix 'hops' statistic in chipper.cpp --- src/routers/chipper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index bab3cf72..a4f4da7e 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -180,6 +180,7 @@ void Chipper::_SendFlits( ) << "destination " << (f->second)->dest << "." << endl; } + (f->second)->hops++; _output_channels[output]->Send( f->second ); buffer_timed.erase(f); } From c23a57a106a189c9ea83161c3b04991b3d9b4f3b Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 25 Jan 2017 10:37:13 +0530 Subject: [PATCH 29/35] Changed injection process in chipper.cpp (Project not functioning) --- src/blesstrafficmanager.cpp | 12 +++++++----- src/routers/chipper.cpp | 19 +++++++------------ src/routers/chipper.hpp | 4 +++- src/routers/router.hpp | 3 +++ 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index 18073a6d..8f94a715 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -83,9 +83,10 @@ void BlessTrafficManager::_Step( ) f = pp.front(); if( _net[subnet]->CheckInject(n) ) - { - f->itime = _time; - f->pri = numeric_limits::max() - f->itime; + { + // Operation moved to chipper.cpp to note correct inject time + // f->itime = _time; + // f->pri = numeric_limits::max() - f->itime; assert(f->pri >= 0); _last_class[n][subnet] = f->cl; @@ -111,8 +112,9 @@ void BlessTrafficManager::_Step( ) #ifdef TRACK_FLOWS ++_injected_flits[f->cl][n]; #endif - - _net[subnet]->WriteFlit(f, n); + // Edit 25/01/17 + // _net[subnet]->WriteFlit(f, n); + _router[subnet][n]->QueueFlit(f); pp.pop_front(); } diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index a4f4da7e..5a3a0d33 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -101,17 +101,7 @@ void Chipper::Display( ostream & os ) const // Ameya: Returns 1 if there is empty slot in _stage_1 int Chipper::GetInjectStatus() { - for ( int input = 0; input < _inputs - 1; ++input ) - { - if( !IsChannelValid( input ) ) - continue; - map::iterator f = _stage_1[input].find(GetSimTime()); - if(f == _stage_1[input].end()) - { - return 1; - } - } - return 0; + return ( _inject_queue.empty() ); } int Chipper::IsChannelValid( int input ) @@ -185,7 +175,12 @@ void Chipper::_SendFlits( ) buffer_timed.erase(f); } } - } +} + +void Chipper::QueueFlit( Flit * f ) +{ + _inject_queue.push(f); +} void Chipper::_InternalStep( ) { diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp index f8477542..030f26a8 100755 --- a/src/routers/chipper.hpp +++ b/src/routers/chipper.hpp @@ -20,6 +20,8 @@ class Chipper : public Router { vector > _stage_2; // No need for extra flags showing occupancy as each buffer is timed + queue< Flit * > _inject_queue; + int router_type; int _time; int _inject_slot; @@ -50,8 +52,8 @@ class Chipper : public Router { virtual void AddOutputChannel(FlitChannel * channel, CreditChannel * ignored); int GetInjectStatus(); + void QueueFlit( Flit * f ); virtual void ReadInputs(); - // virtual void Evaluate( ); virtual void WriteOutputs(); // Ameya: Just for sake of avoiding pure virual func diff --git a/src/routers/router.hpp b/src/routers/router.hpp index 821bff52..e6f7abde 100644 --- a/src/routers/router.hpp +++ b/src/routers/router.hpp @@ -202,6 +202,9 @@ class Router : public TimedModule { inline int NumInputs() const {return _inputs;} inline int NumOutputs() const {return _outputs;} + + // Ameya + virtual void QueueFlit( Flit * f ) {}; }; #endif From 0c7261d434b82520859cbd0ddd3900038e8a9313 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 25 Jan 2017 11:48:02 +0530 Subject: [PATCH 30/35] Fix CHIPPER structure in chipper.cpp --- src/blesstrafficmanager.cpp | 4 - src/routers/chipper.cpp | 155 ++++++++++++++---------------------- src/routers/chipper.hpp | 5 +- 3 files changed, 63 insertions(+), 101 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index 8f94a715..cb7b3e06 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -84,9 +84,6 @@ void BlessTrafficManager::_Step( ) f = pp.front(); if( _net[subnet]->CheckInject(n) ) { - // Operation moved to chipper.cpp to note correct inject time - // f->itime = _time; - // f->pri = numeric_limits::max() - f->itime; assert(f->pri >= 0); _last_class[n][subnet] = f->cl; @@ -113,7 +110,6 @@ void BlessTrafficManager::_Step( ) ++_injected_flits[f->cl][n]; #endif // Edit 25/01/17 - // _net[subnet]->WriteFlit(f, n); _router[subnet][n]->QueueFlit(f); pp.pop_front(); diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index 5a3a0d33..e0642642 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "chipper.hpp" #include "stats.hpp" @@ -34,7 +35,6 @@ Chipper::Chipper( const Configuration& config, _output_buffer.resize(_outputs-1); _stage_1.resize(_inputs-1); - _stage_2.resize(_inputs-1); _time = 0; _inject_slot = -1; @@ -61,14 +61,6 @@ Chipper::~Chipper() } } - for ( int i = 0; i < _inputs-1; ++i ) { - while (!_stage_2[i].empty()) - { - (_stage_2[i].begin()->second)->Free(); - _stage_2[i].erase(_stage_2[i].begin()); - } - } - for ( int o = 0; o < _outputs-1; ++o ) { while (!_output_buffer[o].empty()) { @@ -190,11 +182,9 @@ void Chipper::_InternalStep( ) _input_to_stage1(); - _stage1_to_stage2(); - Permute(); - _stage2_to_output(); + _stage1_to_output(); CheckSanity(); } @@ -317,41 +307,21 @@ void Chipper::_EjectFlits(){ } } +// Ameya: Incorporates inject void Chipper::_input_to_stage1() -{ - map::iterator it; - for ( int input = 0; input < _inputs-1; ++input ){ - it =_input_buffer[input].find(_time); - if(it == _input_buffer[input].end()) - continue; - if((it->second)->watch) { - *gWatchOut << GetSimTime() << " | " - << "node" << GetID() << " | " - << "Flit " << (it->second)->id - << " headed for " << (it->second)->dest - << " written from _input_buffer to _stage_1 in slot " - << input - << "." << endl; - } - _stage_1[input].insert(make_pair(it->first+1, it->second)); - _input_buffer[input].erase(it); - } -} - -void Chipper::_stage1_to_stage2() { map::iterator it,it1; for ( int input = 0; input < _inputs-1; ++input ) // Nandan: Adding the delay associated with the pipe { - it = _stage_1[input].find(_time); - if(it == _stage_1[input].end()) + it = _input_buffer[input].find(_time); + if(it == _input_buffer[input].end()) { if((_inject_slot == -1)&&(IsChannelValid(input))) { _inject_slot = input; // Precaution (possibly redundant) - it1 = _stage_2[_inject_slot].find(_time+1); - if(!(it1 == _stage_2[_inject_slot].end())) + it1 = _stage_1[_inject_slot].find(_time+1); + if(!(it1 == _stage_1[_inject_slot].end())) { ostringstream err; err << GetSimTime() << " | Magic flit: " << GetID(); @@ -366,27 +336,32 @@ void Chipper::_stage1_to_stage2() << "node" << GetID() << " | " << "Flit " << (it->second)->id << " headed for " << (it->second)->dest - << " written from _stage_1 to _stage_2 in slot " + << " written from _input_buffer to _stage_1 in slot " << input << "." << endl; } - _stage_2[input].insert(make_pair(it->first+1, it->second)); - _stage_1[input].erase(it); + _stage_1[input].insert(make_pair(it->first+1, it->second)); + _input_buffer[input].erase(it); } - if(_inject_slot > -1) + if((_inject_slot > -1)&&(!_inject_queue.empty())) { assert(_inject_slot < _inputs - 1); // Precaution (possibly redundant) - it1 = _stage_2[_inject_slot].find(_time+1); - if(!(it1 == _stage_2[_inject_slot].end())) + it1 = _stage_1[_inject_slot].find(_time+1); + if(!(it1 == _stage_1[_inject_slot].end())) { ostringstream err; err << GetSimTime() << " | Flit pile up at inject stage of router: " << GetID(); Error( err.str( ) ); } // End precaution - Flit *f = _input_channels[last_channel]->Receive(); + Flit *f = _inject_queue.front(); + _inject_queue.pop(); + + f->itime = _time; + f->pri = numeric_limits::max() - f->itime; + if(f) { if(f->watch) { @@ -400,30 +375,31 @@ void Chipper::_stage1_to_stage2() << " and golden status " << f->golden << "." << endl; } - _stage_2[_inject_slot].insert(make_pair(_time+1, f)); + _stage_1[_inject_slot].insert(make_pair(_time+1, f)); } - _inject_slot = -1; } + + _inject_slot = -1; } -void Chipper::_stage2_to_output() +void Chipper::_stage1_to_output() { map::iterator it; for ( int input = 0; input < _inputs-1; ++input ){ - it = _stage_2[input].find(_time); - if(it == _stage_2[input].end()) + it = _stage_1[input].find(_time); + if(it == _stage_1[input].end()) continue; if((it->second)->watch) { *gWatchOut << GetSimTime() << " | " << "node" << GetID() << " | " << "Flit " << (it->second)->id << " headed for " << (it->second)->dest - << " written from _stage_2 to _output_buffer in slot " + << " written from _stage_1 to _output_buffer in slot " << input << "." << endl; } _output_buffer[input].insert(make_pair(it->first+1, it->second)); - _stage_2[input].erase(it); + _stage_1[input].erase(it); } } @@ -475,8 +451,8 @@ void Chipper::Permute() { Flit *f; map::iterator it; - it = _stage_2[i].find(_time); - if(it == _stage_2[i].end()) + it = _stage_1[i].find(_time); + if(it == _stage_1[i].end()) { continue; } @@ -514,8 +490,8 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) Flit *f1; Flit *f2; map::iterator it1,it2; - it1 = _stage_2[dir1].find(_time); - if(it1 == _stage_2[dir1].end()) + it1 = _stage_1[dir1].find(_time); + if(it1 == _stage_1[dir1].end()) { f1 = NULL; } @@ -523,8 +499,8 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { f1 = it1->second; } - it2 = _stage_2[dir2].find(_time); - if(it2 == _stage_2[dir2].end()) + it2 = _stage_1[dir2].find(_time); + if(it2 == _stage_1[dir2].end()) { f2 = NULL; } @@ -538,8 +514,8 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { if(_rf(GetID(), f2->dest, true) > perm_num) { - _stage_2[dir2].erase(it2); - _stage_2[dir1].insert(pair(_time, f2) ); + _stage_1[dir2].erase(it2); + _stage_1[dir1].insert(pair(_time, f2) ); } return; } @@ -547,8 +523,8 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { if(_rf(GetID(), f1->dest, true) <= perm_num) { - _stage_2[dir1].erase(it1); - _stage_2[dir2].insert(pair(_time, f1) ); + _stage_1[dir1].erase(it1); + _stage_1[dir2].insert(pair(_time, f1) ); } return; } @@ -558,20 +534,20 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { if(_rf(GetID(), f1->dest, true) <= perm_num) { - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - _stage_2[dir2].insert( pair(_time, f1) ); - _stage_2[dir1].insert( pair(_time, f2) ); + _stage_1[dir1].erase(it1); + _stage_1[dir2].erase(it2); + _stage_1[dir2].insert( pair(_time, f1) ); + _stage_1[dir1].insert( pair(_time, f2) ); } } else { if(_rf(GetID(), f2->dest, true) > perm_num) { - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - _stage_2[dir2].insert( pair(_time, f1) ); - _stage_2[dir1].insert( pair(_time, f2) ); + _stage_1[dir1].erase(it1); + _stage_1[dir2].erase(it2); + _stage_1[dir2].insert( pair(_time, f1) ); + _stage_1[dir1].insert( pair(_time, f2) ); } } } @@ -579,20 +555,20 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { if(_rf(GetID(), f1->dest, true) <= perm_num) { - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - _stage_2[dir2].insert( pair(_time, f1) ); - _stage_2[dir1].insert( pair(_time, f2) ); + _stage_1[dir1].erase(it1); + _stage_1[dir2].erase(it2); + _stage_1[dir2].insert( pair(_time, f1) ); + _stage_1[dir1].insert( pair(_time, f2) ); } } else if((f2->golden == 1)) { if(_rf(GetID(), f2->dest, true) > perm_num) { - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - _stage_2[dir2].insert( pair(_time, f1) ); - _stage_2[dir1].insert( pair(_time, f2) ); + _stage_1[dir1].erase(it1); + _stage_1[dir2].erase(it2); + _stage_1[dir2].insert( pair(_time, f1) ); + _stage_1[dir1].insert( pair(_time, f2) ); } } else @@ -601,20 +577,20 @@ void Chipper::Partial_Permute(int dir1, int dir2, int perm_num) { if(_rf(GetID(), f1->dest, true) <= perm_num) { - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - _stage_2[dir2].insert( pair(_time, f1) ); - _stage_2[dir1].insert( pair(_time, f2) ); + _stage_1[dir1].erase(it1); + _stage_1[dir2].erase(it2); + _stage_1[dir2].insert( pair(_time, f1) ); + _stage_1[dir1].insert( pair(_time, f2) ); } } else { if(_rf(GetID(), f2->dest, true) > perm_num) { - _stage_2[dir1].erase(it1); - _stage_2[dir2].erase(it2); - _stage_2[dir2].insert( pair(_time, f1) ); - _stage_2[dir1].insert( pair(_time, f2) ); + _stage_1[dir1].erase(it1); + _stage_1[dir2].erase(it2); + _stage_1[dir2].insert( pair(_time, f1) ); + _stage_1[dir1].insert( pair(_time, f2) ); } } } @@ -661,15 +637,6 @@ void Chipper::CheckSanity() } } - for ( int i = 0; i < _inputs-1; ++i ) { - if(_stage_2[i].size() > 2) - { - ostringstream err; - err << "Flit pile up at _stage_2 of router: " << GetID(); - Error( err.str( ) ); - } - } - for ( int o = 0; o < _outputs-1; ++o ) { if(_output_buffer[o].size() > 2) { diff --git a/src/routers/chipper.hpp b/src/routers/chipper.hpp index 030f26a8..1d38ca5d 100755 --- a/src/routers/chipper.hpp +++ b/src/routers/chipper.hpp @@ -17,7 +17,7 @@ class Chipper : public Router { vector > _input_buffer; vector > _output_buffer; vector > _stage_1; - vector > _stage_2; + // vector > _stage_2; // No need for extra flags showing occupancy as each buffer is timed queue< Flit * > _inject_queue; @@ -34,9 +34,8 @@ class Chipper : public Router { void _SendFlits( ); void _EjectFlits(); void _input_to_stage1(); - void _stage1_to_stage2(); void Permute(); - void _stage2_to_output(); + void _stage1_to_output(); void Partial_Permute(int dir1, int dir2, int perm_num); void CheckSanity(); int Find_Edge_Router(int id, int k); From 9622b6d0438c53436874a0f065e681fc8144ad04 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 25 Jan 2017 22:55:44 +0530 Subject: [PATCH 31/35] Fix wrong/extra channel delay in chipper.cpp --- src/routers/chipper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/routers/chipper.cpp b/src/routers/chipper.cpp index e0642642..91ff1200 100644 --- a/src/routers/chipper.cpp +++ b/src/routers/chipper.cpp @@ -164,6 +164,7 @@ void Chipper::_SendFlits( ) } (f->second)->hops++; _output_channels[output]->Send( f->second ); + _output_channels[output]->ReadInputs(); buffer_timed.erase(f); } } @@ -187,6 +188,8 @@ void Chipper::_InternalStep( ) _stage1_to_output(); CheckSanity(); + + WriteOutputs(); } // Added by HH From 697741c3b5aa6010ae9096dd6d51aec328ff21e3 Mon Sep 17 00:00:00 2001 From: sabersword Date: Tue, 7 Mar 2017 23:26:17 +0530 Subject: [PATCH 32/35] Fix stats for 1 flit packet case --- src/blesstrafficmanager.cpp | 148 +++++++++++++++++------------------- src/examples/mesh88_lat | 2 +- src/examples/meshbless | 2 +- 3 files changed, 72 insertions(+), 80 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index cb7b3e06..e714e5fb 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -352,6 +352,73 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) } map::iterator iter = _retire_stats[f->cl].find(f->pid); + if( iter == _retire_stats[f->cl].end() ) + { + // First flit of packet is being retired + first = 1; + Stat_Util *s = new Stat_Util; + s->f = f; + s->pending = (f->size) - 1; + if(s->pending==0) + { + if ( f->watch ) { + *gWatchOut << GetSimTime() << " | " + << "node" << dest << " | " + << "Retiring packet " << f->pid + << " (plat = " << f->atime - f->ctime + << ", nlat = " << f->atime - f->itime + << ", frag = 0" + << ", src = " << f->src + << ", dest = " << f->dest + << ", golden = " << f->golden + << ")." << endl; + } + + // code the source of request, look carefully, its tricky ;) + if (f->type == Flit::READ_REQUEST || f->type == Flit::WRITE_REQUEST) { + PacketReplyInfo* rinfo = PacketReplyInfo::New(); + rinfo->source = f->src; + rinfo->time = f->atime; + rinfo->record = f->record; + rinfo->type = f->type; + _repliesPending[dest].push_back(rinfo); + } else { + if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY ){ + _requestsOutstanding[dest]--; + } else if(f->type == Flit::ANY_TYPE) { + _requestsOutstanding[f->src]--; + } + } + + // Only record statistics once per packet (at tail) + // and based on the simulation state + if ( ( _sim_state == warming_up ) || f->record ) { + + _hop_stats[f->cl]->AddSample( f->hops ); + + if((_slowest_packet[f->cl] < 0) || + (_plat_stats[f->cl]->Max() < (f->atime - f->itime))) + _slowest_packet[f->cl] = f->pid; + _plat_stats[f->cl]->AddSample( f->atime - f->ctime); + _nlat_stats[f->cl]->AddSample( f->atime - f->itime); + _frag_stats[f->cl]->AddSample( 0 ); + + if(_pair_stats){ + _pair_plat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - f->ctime ); + _pair_nlat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - f->itime ); + } + } + + ++_accepted_packets[f->cl][dest]; // Ameya: Moved here from _Step() + + // To ensure flit is freed + first = 0; + } + else + { + _retire_stats[f->cl].insert(make_pair(f->pid, s)); + } + } if( iter != _retire_stats[f->cl].end() ) { Stat_Util *prime = iter->second; @@ -368,7 +435,7 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) << "Retiring packet " << f->pid << " (plat = " << f->atime - head->ctime << ", nlat = " << f->atime - head->itime - << ", frag = " << (f->atime - head->atime) - (f->id - head->id) // NB: In the spirit of solving problems using ugly hacks, we compute the packet length by taking advantage of the fact that the IDs of flits within a packet are contiguous. + << ", frag = " << (f->atime - head->atime) - (f->size) << ", src = " << head->src << ", dest = " << head->dest << ", golden = " << head->golden @@ -414,82 +481,7 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) ++_accepted_packets[f->cl][dest]; // Ameya: Moved here from _Step() } } - else - { - // First flit of packet is being retired - first = 1; - Stat_Util *s = new Stat_Util; - s->f = f; - s->pending = (f->size) - 1; - _retire_stats[f->cl].insert(make_pair(f->pid, s)); - } - // if ( f->tail ) { - // Flit * head; - // if(f->head) { - // head = f; - // } else { - // map::iterator iter = _retired_packets[f->cl].find(f->pid); - // assert(iter != _retired_packets[f->cl].end()); - // head = iter->second; - // _retired_packets[f->cl].erase(iter); - // assert(head->head); - // assert(f->pid == head->pid); - // } - // if ( f->watch ) { - // *gWatchOut << GetSimTime() << " | " - // << "node" << dest << " | " - // << "Retiring packet " << f->pid - // << " (plat = " << f->atime - head->ctime - // << ", nlat = " << f->atime - head->itime - // << ", frag = " << (f->atime - head->atime) - (f->id - head->id) // NB: In the spirit of solving problems using ugly hacks, we compute the packet length by taking advantage of the fact that the IDs of flits within a packet are contiguous. - // << ", src = " << head->src - // << ", dest = " << head->dest - // << ", golden = " << head->golden - // << ")." << endl; - // } - - // //code the source of request, look carefully, its tricky ;) - // if (f->type == Flit::READ_REQUEST || f->type == Flit::WRITE_REQUEST) { - // PacketReplyInfo* rinfo = PacketReplyInfo::New(); - // rinfo->source = f->src; - // rinfo->time = f->atime; - // rinfo->record = f->record; - // rinfo->type = f->type; - // _repliesPending[dest].push_back(rinfo); - // } else { - // if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY ){ - // _requestsOutstanding[dest]--; - // } else if(f->type == Flit::ANY_TYPE) { - // _requestsOutstanding[f->src]--; - // } - - // } - - // // Only record statistics once per packet (at tail) - // // and based on the simulation state - // if ( ( _sim_state == warming_up ) || f->record ) { - - // _hop_stats[f->cl]->AddSample( f->hops ); - - // if((_slowest_packet[f->cl] < 0) || - // (_plat_stats[f->cl]->Max() < (f->atime - head->itime))) - // _slowest_packet[f->cl] = f->pid; - // _plat_stats[f->cl]->AddSample( f->atime - head->ctime); - // _nlat_stats[f->cl]->AddSample( f->atime - head->itime); - // _frag_stats[f->cl]->AddSample( (f->atime - head->atime) - (f->id - head->id) ); - - // if(_pair_stats){ - // _pair_plat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->ctime ); - // _pair_nlat[f->cl][f->src*_nodes+dest]->AddSample( f->atime - head->itime ); - // } - // } - - // if(f != head) { - // head->Free(); - // } - - // } - + if(f->golden) { if ( _golden_flits.empty() ) @@ -506,7 +498,7 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) _golden_in_flight = 0; } } - + // cout<pid<Free(); } diff --git a/src/examples/mesh88_lat b/src/examples/mesh88_lat index 43a90d81..1f546c7a 100644 --- a/src/examples/mesh88_lat +++ b/src/examples/mesh88_lat @@ -58,7 +58,7 @@ internal_speedup = 1.0; // Traffic traffic = transpose; -packet_size = 4; +packet_size = 1; // Simulation diff --git a/src/examples/meshbless b/src/examples/meshbless index eab60fa4..ade96358 100644 --- a/src/examples/meshbless +++ b/src/examples/meshbless @@ -64,7 +64,7 @@ packet_size = 4; // Simulation sim_type = latency; -injection_rate = 0.005; +injection_rate = 0.05; //watch_file = /home/ameya/ProjectU/booksim2-master/tempwatch; From 5679c83cd14bf7ceaeccc4d66424b24d799add33 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 8 Mar 2017 01:40:59 +0530 Subject: [PATCH 33/35] Fix Golden Packet scheme --- src/blesstrafficmanager.cpp | 105 +++++++++++++++--------------------- src/blesstrafficmanager.hpp | 9 ++-- 2 files changed, 48 insertions(+), 66 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index e714e5fb..9f9434e3 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -13,9 +13,11 @@ BlessTrafficManager::BlessTrafficManager( const Configuration &config, const vector & net ) -: TrafficManager(config, net), _golden_turn(0), _golden_in_flight(0) +: TrafficManager(config, net), _golden_turn(0), _golden_packet(-1) { + _golden_epoch = config.GetInt("k")*config.GetInt("n"); _retire_stats.resize(config.GetInt("classes")); + _router_flits_in_flight.resize(_routers); } BlessTrafficManager::~BlessTrafficManager( ) {} @@ -33,6 +35,9 @@ void BlessTrafficManager::_Step( ) vector > flits(_subnets); + if(GetSimTime()%_golden_epoch == 0) + _UpdateGoldenStatus(); + for ( int subnet = 0; subnet < _subnets; ++subnet ) { for ( int n = 0; n < _nodes; ++n ) @@ -218,6 +223,8 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, << "." << endl; } + // For fast location of golden flits + vector pkt; for ( int i = 0; i < size; ++i ) { Flit * f = Flit::New(); f->id = _cur_id++; @@ -230,8 +237,11 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, f->record = record; f->cl = cl; f->size = size; + f->golden = 0; _total_in_flight_flits[f->cl].insert(make_pair(f->id, f)); + pkt.push_back( f ); + if(record) { _measured_in_flight_flits[f->cl].insert(make_pair(f->id, f)); } @@ -246,42 +256,10 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, } else { f->head = false; } - // switch( _pri_type ) { - // case class_based: - // f->pri = _class_priority[cl]; - // assert(f->pri >= 0); - // break; - // case age_based: - // f->pri = numeric_limits::max() - time; - // assert(f->pri >= 0); - // break; - // case sequence_based: - // f->pri = numeric_limits::max() - _packet_seq_no[source]; - // assert(f->pri >= 0); - // break; - // default: - // f->pri = 0; - // } - // f->pri = size - i; - // if ( i == ( size - 1 ) ) { // Tail flit - // f->tail = true; - // } else { - // f->tail = false; - // } f->pri = numeric_limits::max() - time; assert(f->pri >= 0); - - if(!_IsGoldenInFlight() && _IsGoldenTurn(source)) - { - f->golden = 1; - _golden_flits.push_back(f->id); - } - else - { - f->golden = 0; - } - + f->vc = -1; if ( f->watch ) { @@ -290,24 +268,29 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, << "Enqueuing flit " << f->id << " (packet " << f->pid << ") at time " << time - << " with golden status " << f->golden << "." << endl; } _partial_packets[source][cl].push_back( f ); } - if(!_IsGoldenInFlight() && _IsGoldenTurn(source)) - { - assert(!_golden_flits.empty()); - _UpdateGoldenStatus(source); - } + _router_flits_in_flight[source].insert(make_pair(pid, pkt)); } -void BlessTrafficManager::_UpdateGoldenStatus( int source ) +void BlessTrafficManager::_UpdateGoldenStatus( ) { - _golden_in_flight = 1; - _golden_turn = (source + 1)%_nodes; + assert(GetSimTime()%_golden_epoch == 0); + map >::iterator iter = _router_flits_in_flight[_golden_turn].find(_golden_packet); + _golden_turn = (_golden_turn + 1)%_routers; + if(!_router_flits_in_flight[_golden_turn].empty()) + { + iter = _router_flits_in_flight[_golden_turn].begin(); + _golden_packet = iter->first; + vector& pkt = iter->second; + vector::iterator flt; + for(flt = pkt.begin(); flt != pkt.end(); ++flt) + (*flt)->golden = 1; + } } void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) @@ -318,6 +301,23 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) assert(_total_in_flight_flits[f->cl].count(f->id) > 0); _total_in_flight_flits[f->cl].erase(f->id); + + assert(_router_flits_in_flight[f->src].count(f->pid) > 0); + map >::iterator iter1 = _router_flits_in_flight[f->src].find(f->pid); + vector& pkt = iter1->second; + vector::iterator flt; + for(flt = pkt.begin(); flt != pkt.end(); ++flt) + { + if( (*flt)->id == f->id) + { + pkt.erase(flt); + break; + } + } + if(pkt.empty()) + { + _router_flits_in_flight[f->src].erase(iter1); + } if(f->record) { assert(_measured_in_flight_flits[f->cl].count(f->id) > 0); @@ -481,24 +481,7 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) ++_accepted_packets[f->cl][dest]; // Ameya: Moved here from _Step() } } - - if(f->golden) - { - if ( _golden_flits.empty() ) - { - ostringstream err; - err << "Flit " << f->id << " claiming to be golden at " << dest; - Error( err.str( ) ); - } - vector::iterator it = find( _golden_flits.begin(), _golden_flits.end(), f->id ); - assert( it != _golden_flits.end()); - _golden_flits.erase(it); - if( _golden_flits.empty() ) - { - _golden_in_flight = 0; - } - } - // cout<pid<Free(); } diff --git a/src/blesstrafficmanager.hpp b/src/blesstrafficmanager.hpp index 9a22cc4a..e83c400b 100644 --- a/src/blesstrafficmanager.hpp +++ b/src/blesstrafficmanager.hpp @@ -16,8 +16,8 @@ class BlessTrafficManager : public TrafficManager { private: int _golden_turn; - int _golden_in_flight; - vector _golden_flits; + int _golden_packet; + int _golden_epoch; struct Stat_Util{ Flit * f; @@ -25,12 +25,11 @@ class BlessTrafficManager : public TrafficManager { }; vector > _retire_stats; + vector > > _router_flits_in_flight; protected: - int _IsGoldenTurn( int source ) { return (_golden_turn == source);} - int _IsGoldenInFlight() { return _golden_in_flight; } - void _UpdateGoldenStatus( int source ); + void _UpdateGoldenStatus( ); void _RetireFlit( Flit *f, int dest ); virtual void _Step( ); void _GeneratePacket( int source, int stype, int cl, int time ); From b10bf675e5bc59fc911b44bb7ae6824a9307f8e7 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 8 Mar 2017 09:40:40 +0530 Subject: [PATCH 34/35] Fix golden epoch to prevent multiple simultaneous golden packets --- src/blesstrafficmanager.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index 9f9434e3..b5d0f0c6 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -15,7 +15,7 @@ BlessTrafficManager::BlessTrafficManager( const Configuration &config, const vector & net ) : TrafficManager(config, net), _golden_turn(0), _golden_packet(-1) { - _golden_epoch = config.GetInt("k")*config.GetInt("n"); + _golden_epoch = config.GetInt("k")*config.GetInt("n")*3; // 3 -> 3-cycle router _retire_stats.resize(config.GetInt("classes")); _router_flits_in_flight.resize(_routers); } @@ -281,6 +281,10 @@ void BlessTrafficManager::_UpdateGoldenStatus( ) { assert(GetSimTime()%_golden_epoch == 0); map >::iterator iter = _router_flits_in_flight[_golden_turn].find(_golden_packet); + + if((iter->second).size()>0) + getchar(); + _golden_turn = (_golden_turn + 1)%_routers; if(!_router_flits_in_flight[_golden_turn].empty()) { @@ -289,7 +293,20 @@ void BlessTrafficManager::_UpdateGoldenStatus( ) vector& pkt = iter->second; vector::iterator flt; for(flt = pkt.begin(); flt != pkt.end(); ++flt) + { (*flt)->golden = 1; + if ( (*flt)->watch ) { + *gWatchOut << GetSimTime() << " | " + << " BlessTrafficManager | " + << "Updating priority to golden for flit" << (*flt)->id + << " (packet " << (*flt)->pid + << ", src = " << (*flt)->src + << ", dest = " << (*flt)->dest + << ", golden = " << (*flt)->golden + << ", hops = " << (*flt)->hops + << ")." << endl; + } + } } } From 105b061fe760326419c273b8947b0edb59fc4533 Mon Sep 17 00:00:00 2001 From: sabersword Date: Wed, 15 Mar 2017 23:57:24 +0530 Subject: [PATCH 35/35] Add facility to inject packet according to trace file --- src/blesstrafficmanager.cpp | 123 ++++++++++++++++++++++++++++++++++-- src/blesstrafficmanager.hpp | 20 +++++- src/booksim_config.cpp | 2 + src/examples/meshbless | 2 +- 4 files changed, 139 insertions(+), 8 deletions(-) diff --git a/src/blesstrafficmanager.cpp b/src/blesstrafficmanager.cpp index b5d0f0c6..4a116938 100644 --- a/src/blesstrafficmanager.cpp +++ b/src/blesstrafficmanager.cpp @@ -13,17 +13,31 @@ BlessTrafficManager::BlessTrafficManager( const Configuration &config, const vector & net ) -: TrafficManager(config, net), _golden_turn(0), _golden_packet(-1) +: TrafficManager(config, net), _golden_turn(0), _golden_packet(-1), position(0) { _golden_epoch = config.GetInt("k")*config.GetInt("n")*3; // 3 -> 3-cycle router _retire_stats.resize(config.GetInt("classes")); _router_flits_in_flight.resize(_routers); + + _file_inject = config.GetInt("file_inject"); + _eoif = 1; + if(_file_inject) + { + _eoif = 0; + _inject_file = config.GetStr("inject_file"); + assert(_inject_file != ""); + } } BlessTrafficManager::~BlessTrafficManager( ) {} void BlessTrafficManager::_Step( ) { + if((_time == 0)&&(_file_inject)) + { + _Read_File(position); + } + bool flits_in_flight = false; for(int c = 0; c < _classes; ++c) { flits_in_flight |= !_total_in_flight_flits[c].empty(); @@ -162,7 +176,7 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, int size = _GetNextPacketSize(cl); //input size int pid = _cur_pid++; assert(_cur_pid); - int packet_destination = _traffic_pattern[cl]->dest(source); + int packet_destination = ((_file_inject==1)? f_dest : _traffic_pattern[cl]->dest(source)); // Nandan bool record = false; bool watch = gWatchOut && (_packets_to_watch.count(pid) > 0); if(_use_read_write[cl]){ @@ -275,6 +289,10 @@ void BlessTrafficManager::_GeneratePacket( int source, int stype, } _router_flits_in_flight[source].insert(make_pair(pid, pkt)); + + // Nandan + if(_file_inject) + _Read_File(position); } void BlessTrafficManager::_UpdateGoldenStatus( ) @@ -282,8 +300,9 @@ void BlessTrafficManager::_UpdateGoldenStatus( ) assert(GetSimTime()%_golden_epoch == 0); map >::iterator iter = _router_flits_in_flight[_golden_turn].find(_golden_packet); - if((iter->second).size()>0) - getchar(); + // Ameya: check exclusion + // if((iter->second).size()>0) + // getchar(); _golden_turn = (_golden_turn + 1)%_routers; if(!_router_flits_in_flight[_golden_turn].empty()) @@ -502,4 +521,100 @@ void BlessTrafficManager::_RetireFlit( Flit *f, int dest ) if(!first) { f->Free(); } +} + +void BlessTrafficManager::_Inject() +{ + if(_file_inject) + { + for ( int input = 0; input < _nodes; ++input ) { + for ( int c = 0; c < _classes; ++c ) { + int stype = _IssuePacket( input, request_type, c ); + + if ( stype != 0 ) { //generate a packet + _GeneratePacket( input, stype, c, _time); + } + + if ( ( _sim_state == draining ) && + ( _qtime[input][c] > _drain_time ) ) { + _qdrained[input][c] = true; + } + } + } + } + else + { + TrafficManager::_Inject(); + } +} + +int BlessTrafficManager::_IssuePacket( int source, char request_type, int cl) +{ + assert(_file_inject==1); + int result = 0; + if((_time == f_time)&&(source == f_source)) + { + if(request_type == 'r') // READ_REQUEST + { + result = 1; + _requestsOutstanding[source]++; + } + else // assume WRITE_REQUEST + { + result = 2; + _requestsOutstanding[source]++; + } + } + else if(_use_read_write[cl]){ // no allocated packet in inject file + if (!_repliesPending[source].empty()) { + if(_repliesPending[source].front()->time <= _time) { + result = -1; + } + } + } + + if(result != 0) { + _packet_seq_no[source]++; + } + return result; +} + +void BlessTrafficManager::_Read_File( int position ) +{ + ifstream spec; + spec.open(_inject_file.c_str(), std::ios::in); + string a; + // string b; + int j; + spec.seekg(position); + for(j = 0; j < 4; j++) + { + if(j == 0) + spec >> f_time; + if(j == 1) + spec >> a; + if(j == 2) + spec >> request_type; + if(j == 3) + spec >> f_source; + } + position = spec.tellg(); + if( spec.eof() ) + { + // check + _eoif = 1; + } + // string::iterator itb = b.begin(); + // for (string::iterator ita=a.begin() + 2; ita!=a.end(); ++ita) + // { + // *itb = *ita; + // itb++; + // } + f_dest = Calculate_Dest( a ); // check this + spec.close(); +} + +int BlessTrafficManager::Calculate_Dest( string address ) +{ + return 0; } \ No newline at end of file diff --git a/src/blesstrafficmanager.hpp b/src/blesstrafficmanager.hpp index e83c400b..11ecf531 100644 --- a/src/blesstrafficmanager.hpp +++ b/src/blesstrafficmanager.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "config_utils.hpp" #include "stats.hpp" @@ -18,7 +19,17 @@ class BlessTrafficManager : public TrafficManager { int _golden_turn; int _golden_packet; int _golden_epoch; - + // Ameya + int _file_inject; + int _eoif; + string _inject_file; + //Nandan + int f_source; + int f_time; + int f_dest; + char request_type; + int position; + struct Stat_Util{ Flit * f; int pending; @@ -33,12 +44,15 @@ class BlessTrafficManager : public TrafficManager { void _RetireFlit( Flit *f, int dest ); virtual void _Step( ); void _GeneratePacket( int source, int stype, int cl, int time ); - + void _Read_File( int position ); + int _IssuePacket( int source, char request_type, int cl); + void _Inject(); + int Calculate_Dest( string address ); + public: BlessTrafficManager( const Configuration &config, const vector & net ); virtual ~BlessTrafficManager( ); - }; #endif \ No newline at end of file diff --git a/src/booksim_config.cpp b/src/booksim_config.cpp index d853322a..1a5b4185 100644 --- a/src/booksim_config.cpp +++ b/src/booksim_config.cpp @@ -157,6 +157,8 @@ BookSimConfig::BookSimConfig( ) _int_map["alloc_iters"] = 1; //==== Traffic ======================================== + _int_map["file_inject"] = 0; // Ameya: option for getting inject data from benchmark files + AddStrField("inject_file", ""); _int_map["classes"] = 1; diff --git a/src/examples/meshbless b/src/examples/meshbless index ade96358..fd1d23d5 100644 --- a/src/examples/meshbless +++ b/src/examples/meshbless @@ -58,7 +58,7 @@ internal_speedup = 1.0; // Traffic traffic = transpose; -packet_size = 4; +packet_size = 1; // Simulation