diff --git a/configs/example/ruby_network_test.py b/configs/example/garnet_synth_traffic.py similarity index 73% rename from configs/example/ruby_network_test.py rename to configs/example/garnet_synth_traffic.py index f0e075055..a4c44efbc 100644 --- a/configs/example/ruby_network_test.py +++ b/configs/example/garnet_synth_traffic.py @@ -1,5 +1,4 @@ -# Copyright (c) 2006-2007 The Regents of The University of Michigan -# Copyright (c) 2010 Advanced Micro Devices, Inc. +# Copyright (c) 2016 Georgia Institute of Technology # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,8 +24,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Authors: Ron Dreslinski -# Tushar Krishna +# Author: Tushar Krishna import m5 from m5.objects import * @@ -48,9 +46,10 @@ m5_root = os.path.dirname(config_root) parser = optparse.OptionParser() Options.addCommonOptions(parser) -parser.add_option("--synthetic", type="int", default=0, - help="Synthetic Traffic type. 0 = Uniform Random,\ - 1 = Tornado, 2 = Bit Complement") +parser.add_option("--synthetic", type="choice", default="uniform_random", + choices=['uniform_random', 'tornado', 'bit_complement', \ + 'bit_reverse', 'bit_rotation', 'neighbor', \ + 'shuffle', 'transpose']) parser.add_option("-i", "--injectionrate", type="float", default=0.1, metavar="I", @@ -65,12 +64,22 @@ parser.add_option("--precision", type="int", default=3, parser.add_option("--sim-cycles", type="int", default=1000, help="Number of simulation cycles") -parser.add_option("--fixed-pkts", action="store_true", - help="Network_test: inject --maxpackets and stop") +parser.add_option("--num-packets-max", type="int", default=-1, + help="Stop injecting after --num-packets-max.\ + Set to -1 to disable.") -parser.add_option("--maxpackets", type="int", default=1, - help="Stop injecting after --maxpackets. \ - Works only with --fixed-pkts") +parser.add_option("--single-sender-id", type="int", default=-1, + help="Only inject from this sender.\ + Set to -1 to disable.") + +parser.add_option("--single-dest-id", type="int", default=-1, + help="Only send to this destination.\ + Set to -1 to disable.") + +parser.add_option("--inj-vnet", type="int", default=-1, + help="Only inject in this vnet (0, 1 or 2).\ + 0 and 1 are 1-flit, 2 is 5-flit.\ + Set to -1 to inject randomly in all vnets.") # # Add the ruby specific and protocol specific options @@ -85,21 +94,24 @@ if args: print "Error: script doesn't take any positional arguments" sys.exit(1) -block_size = 64 -if options.num_cpus > block_size: - print "Error: Number of cores %d limited to %d because of false sharing" \ - % (options.num_cpus, block_size) - sys.exit(1) +if options.inj_vnet > 2: + print "Error: Injection vnet %d should be 0 (1-flit), 1 (1-flit) \ + or 2 (5-flit) or -1 (random)"\ + % (options.inj_vnet) + sys.exit(1) -cpus = [ NetworkTest(fixed_pkts=options.fixed_pkts, - max_packets=options.maxpackets, +cpus = [ GarnetSyntheticTraffic( + num_packets_max=options.num_packets_max, + single_sender=options.single_sender_id, + single_dest=options.single_dest_id, sim_cycles=options.sim_cycles, traffic_type=options.synthetic, inj_rate=options.injectionrate, + inj_vnet=options.inj_vnet, precision=options.precision, - num_memories=options.num_dirs) \ + num_dest=options.num_dirs) \ for i in xrange(options.num_cpus) ] # create the desired simulated system diff --git a/src/cpu/testers/networktest/networktest.cc b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc similarity index 56% rename from src/cpu/testers/networktest/networktest.cc rename to src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc index 6ad26077c..f5a718697 100644 --- a/src/cpu/testers/networktest/networktest.cc +++ b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2016 Georgia Institute of Technology * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,8 +37,8 @@ #include "base/misc.hh" #include "base/random.hh" #include "base/statistics.hh" -#include "cpu/testers/networktest/networktest.hh" -#include "debug/NetworkTest.hh" +#include "cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh" +#include "debug/GarnetSyntheticTraffic.hh" #include "mem/mem_object.hh" #include "mem/packet.hh" #include "mem/port.hh" @@ -52,20 +52,20 @@ using namespace std; int TESTER_NETWORK=0; bool -NetworkTest::CpuPort::recvTimingResp(PacketPtr pkt) +GarnetSyntheticTraffic::CpuPort::recvTimingResp(PacketPtr pkt) { - networktest->completeRequest(pkt); + tester->completeRequest(pkt); return true; } void -NetworkTest::CpuPort::recvReqRetry() +GarnetSyntheticTraffic::CpuPort::recvReqRetry() { - networktest->doRetry(); + tester->doRetry(); } void -NetworkTest::sendPkt(PacketPtr pkt) +GarnetSyntheticTraffic::sendPkt(PacketPtr pkt) { if (!cachePort.sendTimingReq(pkt)) { retryPkt = pkt; // RubyPort will retry sending @@ -73,34 +73,43 @@ NetworkTest::sendPkt(PacketPtr pkt) numPacketsSent++; } -NetworkTest::NetworkTest(const Params *p) +GarnetSyntheticTraffic::GarnetSyntheticTraffic(const Params *p) : MemObject(p), tickEvent(this), - cachePort("network-test", this), + cachePort("GarnetSyntheticTraffic", this), retryPkt(NULL), size(p->memory_size), blockSizeBits(p->block_offset), - numMemories(p->num_memories), + numDestinations(p->num_dest), simCycles(p->sim_cycles), - fixedPkts(p->fixed_pkts), - maxPackets(p->max_packets), + numPacketsMax(p->num_packets_max), numPacketsSent(0), + singleSender(p->single_sender), + singleDest(p->single_dest), trafficType(p->traffic_type), injRate(p->inj_rate), + injVnet(p->inj_vnet), precision(p->precision), + responseLimit(p->response_limit), masterId(p->system->getMasterId(name())) { // set up counters noResponseCycles = 0; schedule(tickEvent, 0); + initTrafficType(); + if (trafficStringToEnum.count(trafficType) == 0) { + fatal("Unknown Traffic Type: %s!\n", traffic); + } + traffic = trafficStringToEnum[trafficType]; + id = TESTER_NETWORK++; - DPRINTF(NetworkTest,"Config Created: Name = %s , and id = %d\n", + DPRINTF(GarnetSyntheticTraffic,"Config Created: Name = %s , and id = %d\n", name(), id); } BaseMasterPort & -NetworkTest::getMasterPort(const std::string &if_name, PortID idx) +GarnetSyntheticTraffic::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "test") return cachePort; @@ -109,18 +118,19 @@ NetworkTest::getMasterPort(const std::string &if_name, PortID idx) } void -NetworkTest::init() +GarnetSyntheticTraffic::init() { numPacketsSent = 0; } void -NetworkTest::completeRequest(PacketPtr pkt) +GarnetSyntheticTraffic::completeRequest(PacketPtr pkt) { Request *req = pkt->req; - DPRINTF(NetworkTest, "Completed injection of %s packet for address %x\n", + DPRINTF(GarnetSyntheticTraffic, + "Completed injection of %s packet for address %x\n", pkt->isWrite() ? "write" : "read\n", req->getPaddr()); @@ -132,34 +142,36 @@ NetworkTest::completeRequest(PacketPtr pkt) void -NetworkTest::tick() +GarnetSyntheticTraffic::tick() { - if (++noResponseCycles >= 500000) { - cerr << name() << ": deadlocked at cycle " << curTick() << endl; - fatal(""); + if (++noResponseCycles >= responseLimit) { + fatal("%s deadlocked at cycle %d\n", name(), curTick()); } // make new request based on injection rate // (injection rate's range depends on precision) // - generate a random number between 0 and 10^precision // - send pkt if this number is < injRate*(10^precision) - bool send_this_cycle; + bool sendAllowedThisCycle; double injRange = pow((double) 10, (double) precision); unsigned trySending = random_mt.random(0, (int) injRange); if (trySending < injRate*injRange) - send_this_cycle = true; + sendAllowedThisCycle = true; else - send_this_cycle = false; + sendAllowedThisCycle = false; - // always generatePkt unless fixedPkts is enabled - if (send_this_cycle) { - if (fixedPkts) { - if (numPacketsSent < maxPackets) { - generatePkt(); - } - } else { + // always generatePkt unless fixedPkts or singleSender is enabled + if (sendAllowedThisCycle) { + bool senderEnable = true; + + if (numPacketsMax >= 0 && numPacketsSent >= numPacketsMax) + senderEnable = false; + + if (singleSender >= 0 && id != singleSender) + senderEnable = false; + + if (senderEnable) generatePkt(); - } } // Schedule wakeup @@ -172,30 +184,64 @@ NetworkTest::tick() } void -NetworkTest::generatePkt() +GarnetSyntheticTraffic::generatePkt() { + int num_destinations = numDestinations; + int radix = (int) sqrt(num_destinations); unsigned destination = id; - if (trafficType == 0) { // Uniform Random - destination = random_mt.random(0, numMemories - 1); - } else if (trafficType == 1) { // Tornado - int networkDimension = (int) sqrt(numMemories); - int my_x = id%networkDimension; - int my_y = id/networkDimension; + int dest_x = -1; + int dest_y = -1; + int source = id; + int src_x = id%radix; + int src_y = id/radix; - int dest_x = my_x + (int) ceil(networkDimension/2) - 1; - dest_x = dest_x%networkDimension; - int dest_y = my_y; + if (singleDest >= 0) + { + destination = singleDest; + } else if (traffic == UNIFORM_RANDOM_) { + destination = random_mt.random(0, num_destinations - 1); + } else if (traffic == BIT_COMPLEMENT_) { + dest_x = radix - src_x - 1; + dest_y = radix - src_y - 1; + destination = dest_y*radix + dest_x; + } else if (traffic == BIT_REVERSE_) { + unsigned int straight = source; + unsigned int reverse = source & 1; // LSB - destination = dest_y*networkDimension + dest_x; - } else if (trafficType == 2) { // Bit Complement - int networkDimension = (int) sqrt(numMemories); - int my_x = id%networkDimension; - int my_y = id/networkDimension; + int num_bits = (int) log2(num_destinations); - int dest_x = networkDimension - my_x - 1; - int dest_y = networkDimension - my_y - 1; - - destination = dest_y*networkDimension + dest_x; + for (int i = 1; i < num_bits; i++) + { + reverse <<= 1; + straight >>= 1; + reverse |= (straight & 1); // LSB + } + destination = reverse; + } else if (traffic == BIT_ROTATION_) { + if (source%2 == 0) + destination = source/2; + else // (source%2 == 1) + destination = ((source/2) + (num_destinations/2)); + } else if (traffic == NEIGHBOR_) { + dest_x = (src_x + 1) % radix; + dest_y = src_y; + destination = dest_y*radix + dest_x; + } else if (traffic == SHUFFLE_) { + if (source < num_destinations/2) + destination = source*2; + else + destination = (source*2 - num_destinations + 1); + } else if (traffic == TRANSPOSE_) { + dest_x = src_y; + dest_y = src_x; + destination = dest_y*radix + dest_x; + } else if (traffic == TORNADO_) { + dest_x = (src_x + (int) ceil(radix/2) - 1) % radix; + dest_y = src_y; + destination = dest_y*radix + dest_x; + } + else { + fatal("Unknown Traffic Type: %s!\n", traffic); } // The source of the packets is a cache. @@ -207,7 +253,7 @@ NetworkTest::generatePkt() // Modeling different coherence msg types over different msg classes. // - // networktest assumes the Network_test coherence protocol + // GarnetSyntheticTraffic assumes the Garnet_standalone coherence protocol // which models three message classes/virtual networks. // These are: request, forward, response. // requests and forwards are "control" packets (typically 8 bytes), @@ -234,18 +280,28 @@ NetworkTest::generatePkt() Request *req = nullptr; Request::Flags flags; - unsigned randomReqType = random_mt.random(0, 2); - if (randomReqType == 0) { + // Inject in specific Vnet + // Vnet 0 and 1 are for control packets (1-flit) + // Vnet 2 is for data packets (5-flit) + int injReqType = injVnet; + + if (injReqType < 0 || injReqType > 2) + { + // randomly inject in any vnet + injReqType = random_mt.random(0, 2); + } + + if (injReqType == 0) { // generate packet for virtual network 0 requestType = MemCmd::ReadReq; req = new Request(paddr, access_size, flags, masterId); - } else if (randomReqType == 1) { + } else if (injReqType == 1) { // generate packet for virtual network 1 requestType = MemCmd::ReadReq; flags.set(Request::INST_FETCH); req = new Request(0, 0x0, access_size, flags, masterId, 0x0, 0); req->setPaddr(paddr); - } else { // if (randomReqType == 2) + } else { // if (injReqType == 2) // generate packet for virtual network 2 requestType = MemCmd::WriteReq; req = new Request(paddr, access_size, flags, masterId); @@ -256,7 +312,7 @@ NetworkTest::generatePkt() //No need to do functional simulation //We just do timing simulation of the network - DPRINTF(NetworkTest, + DPRINTF(GarnetSyntheticTraffic, "Generated packet with destination %d, embedded in address %x\n", destination, req->getPaddr()); @@ -268,7 +324,20 @@ NetworkTest::generatePkt() } void -NetworkTest::doRetry() +GarnetSyntheticTraffic::initTrafficType() +{ + trafficStringToEnum["bit_complement"] = BIT_COMPLEMENT_; + trafficStringToEnum["bit_reverse"] = BIT_REVERSE_; + trafficStringToEnum["bit_rotation"] = BIT_ROTATION_; + trafficStringToEnum["neighbor"] = NEIGHBOR_; + trafficStringToEnum["shuffle"] = SHUFFLE_; + trafficStringToEnum["tornado"] = TORNADO_; + trafficStringToEnum["transpose"] = TRANSPOSE_; + trafficStringToEnum["uniform_random"] = UNIFORM_RANDOM_; +} + +void +GarnetSyntheticTraffic::doRetry() { if (cachePort.sendTimingReq(retryPkt)) { retryPkt = NULL; @@ -276,14 +345,14 @@ NetworkTest::doRetry() } void -NetworkTest::printAddr(Addr a) +GarnetSyntheticTraffic::printAddr(Addr a) { cachePort.printAddr(a); } -NetworkTest * -NetworkTestParams::create() +GarnetSyntheticTraffic * +GarnetSyntheticTrafficParams::create() { - return new NetworkTest(this); + return new GarnetSyntheticTraffic(this); } diff --git a/src/cpu/testers/networktest/networktest.hh b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh similarity index 66% rename from src/cpu/testers/networktest/networktest.hh rename to src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh index 572097a09..94eee44d7 100644 --- a/src/cpu/testers/networktest/networktest.hh +++ b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2016 Georgia Institute of Technology * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,26 +28,36 @@ * Authors: Tushar Krishna */ -#ifndef __CPU_NETWORKTEST_NETWORKTEST_HH__ -#define __CPU_NETWORKTEST_NETWORKTEST_HH__ +#ifndef __CPU_GARNET_SYNTHETIC_TRAFFIC_HH__ +#define __CPU_GARNET_SYNTHETIC_TRAFFIC_HH__ #include #include "base/statistics.hh" #include "mem/mem_object.hh" #include "mem/port.hh" -#include "params/NetworkTest.hh" +#include "params/GarnetSyntheticTraffic.hh" #include "sim/eventq.hh" #include "sim/sim_exit.hh" #include "sim/sim_object.hh" #include "sim/stats.hh" +enum TrafficType {BIT_COMPLEMENT_ = 0, + BIT_REVERSE_ = 1, + BIT_ROTATION_ = 2, + NEIGHBOR_ = 3, + SHUFFLE_ = 4, + TORNADO_ = 5, + TRANSPOSE_ = 6, + UNIFORM_RANDOM_ = 7, + NUM_TRAFFIC_PATTERNS_}; + class Packet; -class NetworkTest : public MemObject +class GarnetSyntheticTraffic : public MemObject { public: - typedef NetworkTestParams Params; - NetworkTest(const Params *p); + typedef GarnetSyntheticTrafficParams Params; + GarnetSyntheticTraffic(const Params *p); virtual void init(); @@ -67,24 +77,27 @@ class NetworkTest : public MemObject class TickEvent : public Event { private: - NetworkTest *cpu; + GarnetSyntheticTraffic *cpu; public: - TickEvent(NetworkTest *c) : Event(CPU_Tick_Pri), cpu(c) {} + TickEvent(GarnetSyntheticTraffic *c) : Event(CPU_Tick_Pri), cpu(c) {} void process() { cpu->tick(); } - virtual const char *description() const { return "NetworkTest tick"; } + virtual const char *description() const + { + return "GarnetSyntheticTraffic tick"; + } }; TickEvent tickEvent; class CpuPort : public MasterPort { - NetworkTest *networktest; + GarnetSyntheticTraffic *tester; public: - CpuPort(const std::string &_name, NetworkTest *_networktest) - : MasterPort(_name, _networktest), networktest(_networktest) + CpuPort(const std::string &_name, GarnetSyntheticTraffic *_tester) + : MasterPort(_name, _tester), tester(_tester) { } protected: @@ -96,11 +109,11 @@ class NetworkTest : public MemObject CpuPort cachePort; - class NetworkTestSenderState : public Packet::SenderState + class GarnetSyntheticTrafficSenderState : public Packet::SenderState { public: /** Constructor. */ - NetworkTestSenderState(uint8_t *_data) + GarnetSyntheticTrafficSenderState(uint8_t *_data) : data(_data) { } @@ -112,33 +125,41 @@ class NetworkTest : public MemObject unsigned size; int id; + std::map trafficStringToEnum; + unsigned blockSizeBits; Tick noResponseCycles; - int numMemories; + int numDestinations; Tick simCycles; - bool fixedPkts; - int maxPackets; + int numPacketsMax; int numPacketsSent; + int singleSender; + int singleDest; - int trafficType; + std::string trafficType; // string + TrafficType traffic; // enum from string double injRate; + int injVnet; int precision; + const Cycles responseLimit; + MasterID masterId; void completeRequest(PacketPtr pkt); void generatePkt(); void sendPkt(PacketPtr pkt); + void initTrafficType(); void doRetry(); friend class MemCompleteEvent; }; -#endif // __CPU_NETWORKTEST_NETWORKTEST_HH__ +#endif // __CPU_GARNET_SYNTHETIC_TRAFFIC_HH__ diff --git a/src/cpu/testers/networktest/NetworkTest.py b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.py similarity index 62% rename from src/cpu/testers/networktest/NetworkTest.py rename to src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.py index 25b2bb690..261e643c1 100644 --- a/src/cpu/testers/networktest/NetworkTest.py +++ b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.py @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Advanced Micro Devices, Inc. +# Copyright (c) 2016 Georgia Institute of Technology # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -30,17 +30,28 @@ from MemObject import MemObject from m5.params import * from m5.proxy import * -class NetworkTest(MemObject): - type = 'NetworkTest' - cxx_header = "cpu/testers/networktest/networktest.hh" +class GarnetSyntheticTraffic(MemObject): + type = 'GarnetSyntheticTraffic' + cxx_header = \ + "cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh" block_offset = Param.Int(6, "block offset in bits") - num_memories = Param.Int(1, "Num Memories") + num_dest = Param.Int(1, "Number of Destinations") memory_size = Param.Int(65536, "memory size") sim_cycles = Param.Int(1000, "Number of simulation cycles") - fixed_pkts = Param.Bool(False, "Send fixed number of packets") - max_packets = Param.Counter(0, "Number of packets to send when in fixed_pkts mode") - traffic_type = Param.Counter(0, "Traffic type: uniform random, tornado, bit complement") + num_packets_max = Param.Int(-1, "Max number of packets to send. \ + Default is to keep sending till simulation ends") + single_sender = Param.Int(-1, "Send only from this node. \ + By default every node sends") + single_dest = Param.Int(-1, "Send only to this dest. \ + Default depends on traffic_type") + traffic_type = Param.String("uniform_random", "Traffic type") inj_rate = Param.Float(0.1, "Packet injection rate") - precision = Param.Int(3, "Number of digits of precision after decimal point") + inj_vnet = Param.Int(-1, "Vnet to inject in. \ + 0 and 1 are 1-flit, 2 is 5-flit. \ + Default is to inject in all three vnets") + precision = Param.Int(3, "Number of digits of precision \ + after decimal point") + response_limit = Param.Cycles(5000000, "Cycles before exiting \ + due to lack of progress") test = MasterPort("Port to the memory system to test") system = Param.System(Parent.any, "System we belong to") diff --git a/src/cpu/testers/networktest/SConscript b/src/cpu/testers/garnet_synthetic_traffic/SConscript similarity index 90% rename from src/cpu/testers/networktest/SConscript rename to src/cpu/testers/garnet_synthetic_traffic/SConscript index 06ab0f2aa..f1624b05e 100644 --- a/src/cpu/testers/networktest/SConscript +++ b/src/cpu/testers/garnet_synthetic_traffic/SConscript @@ -1,6 +1,6 @@ # -*- mode:python -*- -# Copyright (c) 2009 Advanced Micro Devices, Inc. +# Copyright (c) 2016 Georgia Institute of Technology. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ Import('*') -SimObject('NetworkTest.py') +SimObject('GarnetSyntheticTraffic.py') -Source('networktest.cc') +Source('GarnetSyntheticTraffic.cc') -DebugFlag('NetworkTest') +DebugFlag('GarnetSyntheticTraffic')