32#include "debug/SpatterGen.hh"
33#include "debug/SpatterKernel.hh"
34#include "enums/SpatterKernelType.hh"
35#include "enums/SpatterProcessingMode.hh"
43using enums::SpatterKernelTypeStrings;
44using enums::SpatterProcessingMode;
49 requestorId(params.
system->getRequestorId(this)),
50 numPendingMemRequests(0),
52 mode(params.processing_mode),
53 port(this,
name() +
".port"),
54 intRegFileSize(params.int_regfile_size), intRegUsed(0),
55 fpRegFileSize(params.fp_regfile_size), fpRegUsed(0),
56 requestGenLatency(params.request_gen_latency),
57 requestGenRate(params.request_gen_rate),
58 firstGeneratorAvailableTime(0),
60 requestBufferEntries(params.request_buffer_entries),
61 requestBuffer(clockPeriod()),
62 sendRate(params.send_rate),
63 firstPortAvailableTime(0),
64 nextSendEvent([
this](){ processNextSendEvent(); },
name() +
".SendEvent"),
65 receiveBuffer(clockPeriod())
67 fatal_if(fpRegFileSize < requestBufferEntries,
68 "fp_regfile_size should be >= request_buffer_entries."
69 "if request_buffer_entries is bigger than fp_regfile_size,"
70 "it may result in inaccuracies in your simulation."
71 "Ideally: fp_regfile_size >> request_buffer_entries."
73 generatorBusyUntil.resize(requestGenRate, 0);
74 portBusyUntil.resize(sendRate, 0);
80 if (if_name ==
"port") {
101 "%s: Port blocked when sending %s.\n",
102 __func__, pkt->
print()
112 blockedPacket ==
nullptr,
113 "Received reqRetry with no blocked packet."
115 if (!sendTimingReq(blockedPacket)) {
118 "%s: Port blocked when sending %s.\n",
119 __func__, blockedPacket->print()
122 blockedPacket =
nullptr;
123 owner->recvReqRetry();
138 return owner->recvTimingResp(pkt);
153 int trips_left = spatter_access->
tripsLeft();
154 assert(trips_left >= 0);
155 if (trips_left > 0) {
167 if (spatter_access->
type() == SpatterKernelType::gather) {
171 }
else if (spatter_access->
type() == SpatterKernelType::scatter) {
176 panic(
"Unknown kernel type.");
189 delete spatter_access;
206 uint32_t
id, uint32_t delta, uint32_t
count,
208 size_t index_size,
Addr base_index_addr,
209 size_t value_size,
Addr base_value_addr,
215 "%s: Adding kernel with id: %d, delta: %d, count: %d, type: %s.\n",
216 __func__,
id, delta,
count, SpatterKernelTypeStrings[
type]
221 index_size, base_index_addr,
222 value_size, base_value_addr
231 assert(
mode == SpatterProcessingMode::synchronous);
247 if (!can_do_init && !can_do_mid && !can_do_ult && no_pending && no_queued)
250 (
mode == SpatterProcessingMode::synchronous) &&
253 mode == SpatterProcessingMode::asynchronous
257 csprintf(
"%s received all expected responses.",
name()),
267 bool have_int_reg = int_regs > 0;
274 return have_kernel && have_int_reg;
280 bool have_int_reg = int_regs > 0;
282 bool mid_idx = have_index && (
receiveBuffer.front()->tripsLeft() > 1);
283 return mid_idx && have_int_reg;
289 bool have_fp_reg = fp_regs > 0;
291 bool val_idx = have_index && (
receiveBuffer.front()->tripsLeft() == 1);
292 return val_idx && have_fp_reg;
319 int int_used_now = 0;
333 "%s: AGU[%d] is busy this cycle.\n", __func__,
i
361 "%s: Pushed pkt: %s to requestBuffer.\n",
362 __func__, pkt->
print()
384 "%s: Pushed pkt: %s to requestBuffer.\n",
385 __func__, pkt->
print()
405 "%s: Pushed pkt: %s to requestBuffer.\n",
406 __func__, pkt->
print()
412 "%s: Done with kernel %d type: %s.\n",
413 __func__, front.
id(),
414 SpatterKernelTypeStrings[front.
type()]
420 if (
mode == SpatterProcessingMode::synchronous) {
428 "%s: Nothing more could be done this cycle.\n", __func__
431 "{KERNELS_REMAIN: %d, INDEXES_REMAIN: %d, INT_REG_USED: %d, "
432 "FP_REG_USED: %d, REQ_BUFF_SIZE: %d}.\n",
482 "%s: Port[%d] is busy this cycle.\n", __func__,
i
489 "%s: No packets to send this cycle.\n", __func__
496 "%s: Packet at front of requestBuffer not ready this cycle.\n",
504 "%s: Sending pkt: %s to port[%d].\n",
546 statistics::
Group(spatter_gen), spatterGen(spatter_gen),
547 ADD_STAT(numIndexReads, statistics::units::Count::get(),
548 "Number of reads from the indexer array."),
549 ADD_STAT(indexBytesRead, statistics::units::Byte::get(),
550 "Number of bytes read from the indexer array."),
551 ADD_STAT(totalIndexReadLatency, statistics::units::
Tick::get(),
552 "Total latency for reading from the indexer array."),
553 ADD_STAT(numValueReads, statistics::units::Count::get(),
554 "Number of reads from the values array."),
555 ADD_STAT(numValueWrites, statistics::units::Count::get(),
556 "Number of writes to the values array."),
557 ADD_STAT(valueBytesRead, statistics::units::Byte::get(),
558 "Number of bytes read from the values array."),
559 ADD_STAT(valueBytesWritten, statistics::units::Byte::get(),
560 "Number of bytes written to the values array."),
561 ADD_STAT(totalValueReadLatency, statistics::units::
Tick::get(),
562 "Total latency for reading from the values array."),
563 ADD_STAT(totalValueWriteLatency, statistics::units::
Tick::get(),
564 "Total latency for writing to the values array."),
565 ADD_STAT(indexAccessLatency, statistics::units::
Tick::get(),
566 "Distribution of latency for accessing the indexer array."),
567 ADD_STAT(valueAccessLatency, statistics::units::
Tick::get(),
568 "Distribution of latency for accessing the values array."),
569 ADD_STAT(totalIndirectAccessLatency, statistics::units::
Tick::get(),
570 "Distribution of total latency for indirect accesses.")
576 using namespace statistics;
577 indexAccessLatency.init(8);
578 valueAccessLatency.init(16);
579 totalIndirectAccessLatency.init(16);
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
ClockedObjectParams Params
Parameters of ClockedObject.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
Cycles is a wrapper class for representing cycle counts, i.e.
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
T * findNextSenderState() const
Go through the sender state stack and return the first instance that is of type T (as determined by a...
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
RequestPtr req
A pointer to the original request.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
virtual void recvReqRetry() override
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
void sendPacket(PacketPtr pkt)
virtual bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool initAccessOk(int int_regs, int fp_regs, Tick when) const
bool recvTimingResp(PacketPtr pkt)
TimedQueue< SpatterAccess * > receiveBuffer
void processNextGenEvent()
SpatterProcessingMode mode
std::vector< Tick > portBusyUntil
bool ultAccessOk(int int_regs, int fp_regs, Tick when) const
SpatterGenEvent nextSendEvent
void processNextSendEvent()
SpatterGen(const Params ¶ms)
enums::SpatterKernelType SpatterKernelType
Tick firstGeneratorAvailableTime
virtual void startup() override
startup() is the final initialization call before simulation.
void proceedPastSyncPoint()
void addKernel(uint32_t id, uint32_t delta, uint32_t count, SpatterKernelType type, size_t index_size, Addr base_index_addr, size_t value_size, Addr base_value_addr, const std::vector< uint32_t > &indices)
bool interAccessOk(int int_regs, int fp_regs, Tick when) const
SpatterGenEvent nextGenEvent
Tick firstPortAvailableTime
std::queue< SpatterKernel > kernels
std::unordered_map< RequestPtr, Tick > requestDepartureTime
TimedQueue< PacketPtr > requestBuffer
std::vector< Tick > generatorBusyUntil
void scheduleNextSendEvent(Tick when)
void scheduleNextGenEvent(Tick when)
int numPendingMemRequests
void setIndices(const std::vector< uint32_t > &pattern)
SpatterAccess * nextSpatterAccess()
SpatterKernelType type() const
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
uint64_t Tick
Tick count type.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
std::string csprintf(const char *format, const Args &...args)
Declaration of the Packet class.
SpatterKernelType type() const
Tick tripTimeSoFar() const
void recordTripTime(Tick trip_time)
statistics::Scalar valueBytesRead
statistics::Scalar numIndexReads
statistics::Scalar totalValueWriteLatency
virtual void regStats() override
Callback to set stat parameters.
statistics::Histogram totalIndirectAccessLatency
statistics::Histogram valueAccessLatency
statistics::Scalar totalValueReadLatency
statistics::Scalar indexBytesRead
statistics::Scalar numValueWrites
statistics::Histogram indexAccessLatency
statistics::Scalar valueBytesWritten
statistics::Scalar totalIndexReadLatency
statistics::Scalar numValueReads
SpatterGenStats(SpatterGen *spatter_gen)
const std::string & name()