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;
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()
113 "Received reqRetry with no blocked packet."
118 "%s: Port blocked when sending %s.\n",
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) {
156 stats.numIndexReads++;
158 stats.totalIndexReadLatency += trip_time;
160 stats.indexAccessLatency.sample(trip_time);
163 stats.valueAccessLatency.sample(trip_time);
164 stats.totalIndirectAccessLatency.sample(
167 if (spatter_access->
type() == SpatterKernelType::gather) {
168 stats.numValueReads++;
170 stats.totalValueReadLatency += trip_time;
171 }
else if (spatter_access->
type() == SpatterKernelType::scatter) {
172 stats.numValueWrites++;
174 stats.totalValueWriteLatency += trip_time;
176 panic(
"Unknown kernel type.");
189 delete spatter_access;
206 uint32_t
id, uint32_t delta, uint32_t
count,
208 uint32_t base_index, uint32_t indices_per_stride, uint32_t
stride,
209 size_t index_size,
Addr base_index_addr,
210 size_t value_size,
Addr base_value_addr,
216 "%s: Adding kernel with id: %d, delta: %d, count: %d, type: %s.\n",
217 __func__,
id, delta,
count, SpatterKernelTypeStrings[type]
221 id, delta,
count, type,
222 base_index, indices_per_stride,
stride,
223 index_size, base_index_addr,
224 value_size, base_value_addr
233 assert(
mode == SpatterProcessingMode::synchronous);
249 if (!can_do_init && !can_do_mid && !can_do_ult && no_pending && no_queued)
252 (
mode == SpatterProcessingMode::synchronous) &&
255 mode == SpatterProcessingMode::asynchronous
259 csprintf(
"%s received all expected responses.",
name()),
269 bool have_int_reg = int_regs > 0;
276 return have_kernel && have_int_reg;
282 bool have_int_reg = int_regs > 0;
284 bool mid_idx = have_index && (
receiveBuffer.front()->tripsLeft() > 1);
285 return mid_idx && have_int_reg;
291 bool have_fp_reg = fp_regs > 0;
293 bool val_idx = have_index && (
receiveBuffer.front()->tripsLeft() == 1);
294 return val_idx && have_fp_reg;
321 int int_used_now = 0;
335 "%s: AGU[%d] is busy this cycle.\n", __func__,
i
363 "%s: Pushed pkt: %s to requestBuffer.\n",
364 __func__, pkt->
print()
386 "%s: Pushed pkt: %s to requestBuffer.\n",
387 __func__, pkt->
print()
407 "%s: Pushed pkt: %s to requestBuffer.\n",
408 __func__, pkt->
print()
414 "%s: Done with kernel %d type: %s.\n",
415 __func__, front.
id(),
416 SpatterKernelTypeStrings[front.
type()]
422 if (
mode == SpatterProcessingMode::synchronous) {
430 "%s: Nothing more could be done this cycle.\n", __func__
433 "{KERNELS_REMAIN: %d, INDEXES_REMAIN: %d, INT_REG_USED: %d, "
434 "FP_REG_USED: %d, REQ_BUFF_SIZE: %d}.\n",
484 "%s: Port[%d] is busy this cycle.\n", __func__,
i
491 "%s: No packets to send this cycle.\n", __func__
498 "%s: Packet at front of requestBuffer not ready this cycle.\n",
506 "%s: Sending pkt: %s to port[%d].\n",
511 port.sendPacket(pkt);
519 if (
port.blocked()) {
550 "Number of reads from the indexer array."),
552 "Number of bytes read from the indexer array."),
554 "Total latency for reading from the indexer array."),
556 "Number of reads from the values array."),
558 "Number of writes to the values array."),
560 "Number of bytes read from the values array."),
562 "Number of bytes written to the values array."),
564 "Total latency for reading from the values array."),
566 "Total latency for writing to the values array."),
568 "Distribution of latency for accessing the indexer array."),
570 "Distribution of latency for accessing the values array."),
572 "Distribution of total latency for indirect accesses.")
ClockedObject(const ClockedObjectParams &p)
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
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.
Ports are used to interface objects to each other.
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
void addKernel(uint32_t id, uint32_t delta, uint32_t count, SpatterKernelType type, uint32_t base_index, uint32_t indices_per_stride, uint32_t stride, size_t index_size, Addr base_index_addr, size_t value_size, Addr base_value_addr, const std::vector< uint32_t > &indices)
virtual void startup() override
startup() is the final initialization call before simulation.
void proceedPastSyncPoint()
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
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
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...
const Params & params() const
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Bitfield< 21, 20 > stride
Copyright (c) 2024 Arm Limited 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.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
The "old style" exitSimLoop functions.
uint64_t Tick
Tick count type.
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()