gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
gpu_wavefront.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
35 
36 #include "debug/ProtocolTest.hh"
37 
39  : TesterThread(p), cuId(p.cu_id)
40 {
41  threadName = "GpuWavefront(TesterThread ID = " + std::to_string(threadId) +
42  ", CU ID = " + std::to_string(cuId) + ")";
43  threadEvent.setDesc("GpuWavefront tick");
44 }
45 
47 {
48 
49 }
50 
51 void
53 {
54  assert(curAction);
56  // we should not have any outstanding fence or atomic op at this point
57  assert(pendingFenceCount == 0);
58  assert(pendingAtomicCount == 0);
59 
60  for (int lane = 0; lane < numLanes; ++lane) {
61  Location location = curAction->getLocation(lane);
62  assert(location >= AddressManager::INVALID_LOCATION);
63 
64  // Make a request if we do not get an INVALID_LOCATION for this lane.
65  if (location >= 0) {
66  Addr address = addrManager->getAddress(location);
67  DPRINTF(ProtocolTest, "%s Episode %d: Issuing Load - Addr %s\n",
68  this->getName(), curEpisode->getEpisodeId(),
69  printAddress(address));
70 
71  int load_size = sizeof(Value);
72 
73  // for now, assert address is 4-byte aligned
74  assert(address % load_size == 0);
75 
76  auto req = std::make_shared<Request>(address, load_size,
77  0, tester->requestorId(),
78  0, threadId, nullptr);
79  req->setPaddr(address);
80  req->setReqInstSeqNum(tester->getActionSeqNum());
81  // set protocol-specific flags
83 
84  PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
85  uint8_t* data = new uint8_t[load_size];
86  pkt->dataDynamic(data);
88 
89  // increment the number of outstanding ld_st requests
91 
92  if (!port->sendTimingReq(pkt)) {
93  panic("Not expected failed sendTimingReq\n");
94  }
95 
96  // insert an outstanding load
97  addOutstandingReqs(outstandingLoads, address, lane, location);
98  }
99  }
100 }
101 
102 void
104 {
105  assert(curAction);
107  // we should not have any outstanding fence or atomic op at this point
108  assert(pendingFenceCount == 0);
109  assert(pendingAtomicCount == 0);
110 
111  for (int lane = 0; lane < numLanes; ++lane) {
112  Location location = curAction->getLocation(lane);
113  assert(location >= AddressManager::INVALID_LOCATION);
114 
115  // Make a request if we do not get an INVALID_LOCATION for this lane.
116  if (location >= 0) {
117  // prepare the next value to store
118  Value new_value = addrManager->getLoggedValue(location) + 1;
119 
120  Addr address = addrManager->getAddress(location);
121  // must be aligned with store size
122  assert(address % sizeof(Value) == 0);
123 
124  DPRINTF(ProtocolTest, "%s Episode %d: Issuing Store - Addr %s - "
125  "Value %d\n", this->getName(),
126  curEpisode->getEpisodeId(), printAddress(address),
127  new_value);
128 
129  auto req = std::make_shared<Request>(address, sizeof(Value),
130  0, tester->requestorId(), 0,
131  threadId, nullptr);
132  req->setPaddr(address);
133  req->setReqInstSeqNum(tester->getActionSeqNum());
134  // set protocol-specific flags
136 
137  PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
138  uint8_t *writeData = new uint8_t[sizeof(Value)];
139  for (int j = 0; j < sizeof(Value); ++j) {
140  writeData[j] = ((uint8_t*)&new_value)[j];
141  }
142  pkt->dataDynamic(writeData);
143  pkt->senderState = new ProtocolTester::SenderState(this);
144 
145  // increment the number of outstanding ld_st requests
147 
148  if (!port->sendTimingReq(pkt)) {
149  panic("Not expecting a failed sendTimingReq\n");
150  }
151 
152  // add an outstanding store
153  addOutstandingReqs(outstandingStores, address, lane, location,
154  new_value);
155  }
156  }
157 }
158 
159 void
161 {
162  assert(curAction);
164  // we should not have any outstanding ops at this point
165  assert(pendingFenceCount == 0);
166  assert(pendingLdStCount == 0);
167  assert(pendingAtomicCount == 0);
168 
169  // we use atomic_inc in the tester
171 
172  for (int lane = 0; lane < numLanes; ++lane) {
173  Location location = curAction->getLocation(lane);
174  assert(location >= 0);
175 
176  Addr address = addrManager->getAddress(location);
177 
178  DPRINTF(ProtocolTest, "%s Episode %d: Issuing Atomic_Inc - Addr %s\n",
179  this->getName(), curEpisode->getEpisodeId(),
180  printAddress(address));
181 
182  // must be aligned with store size
183  assert(address % sizeof(Value) == 0);
184  AtomicOpFunctor *amo_op = new AtomicOpInc<Value>();
185  auto req = std::make_shared<Request>(address, sizeof(Value),
186  flags, tester->requestorId(),
187  0, threadId,
188  AtomicOpFunctorPtr(amo_op));
189  req->setPaddr(address);
190  req->setReqInstSeqNum(tester->getActionSeqNum());
191  // set protocol-specific flags
193 
194  PacketPtr pkt = new Packet(req, MemCmd::SwapReq);
195  uint8_t* data = new uint8_t[sizeof(Value)];
196  pkt->dataDynamic(data);
197  pkt->senderState = new ProtocolTester::SenderState(this);
198 
199  if (!port->sendTimingReq(pkt)) {
200  panic("Not expecting failed sendTimingReq\n");
201  }
202 
203  // increment the number of outstanding atomic ops
205 
206  // add an outstanding atomic
207  addOutstandingReqs(outstandingAtomics, address, lane, location);
208  }
209 }
210 
211 void
213 {
214  DPRINTF(ProtocolTest, "%s Episode %d: Issuing Acquire\n", this->getName(),
216 
217  assert(curAction);
219  // we should not have any outstanding ops at this point
220  assert(pendingFenceCount == 0);
221  assert(pendingLdStCount == 0);
222  assert(pendingAtomicCount == 0);
223 
224  auto acq_req = std::make_shared<Request>(0, 0, 0,
225  tester->requestorId(), 0,
226  threadId, nullptr);
227  acq_req->setPaddr(0);
228  acq_req->setReqInstSeqNum(tester->getActionSeqNum());
229  acq_req->setCacheCoherenceFlags(Request::INV_L1);
230  // set protocol-specific flags
231  setExtraRequestFlags(acq_req);
232 
233  PacketPtr pkt = new Packet(acq_req, MemCmd::MemSyncReq);
234  pkt->senderState = new ProtocolTester::SenderState(this);
235 
236  // increment the number of outstanding fence requests
238 
239  if (!port->sendTimingReq(pkt)) {
240  panic("Not expecting failed sendTimingReq\n");
241  }
242 }
243 
244 void
246 {
247  DPRINTF(ProtocolTest, "%s Episode %d: Issuing Release\n", this->getName(),
249 
250  // A release fence simply waits for all previous stores to complete. All
251  // previous loads and stores were done before this release operation is
252  // issued, so issueReleaseOp is just a no-op in this tester.
253 
254  // we may be able to issue an action. Let's check
255  if (!threadEvent.scheduled()) {
256  scheduleWakeup();
257  }
258 }
259 
260 void
262 {
263  assert(pkt);
264  MemCmd resp_cmd = pkt->cmd;
265  Addr addr = (resp_cmd == MemCmd::WriteCompleteResp) ? 0 : pkt->getAddr();
266 
267  DPRINTF(ProtocolTest, "%s Episode %d: hitCallback - Command %s - "
268  "Addr %s\n", this->getName(),
269  curEpisode->getEpisodeId(), resp_cmd.toString(),
270  printAddress(addr));
271 
272  // whether the transaction is done after this hitCallback
273  bool isTransactionDone = true;
274 
275  if (resp_cmd == MemCmd::MemSyncResp) {
276  // response to a pending fence
277  // no validation needed for fence responses
278  assert(pendingFenceCount > 0);
279  assert(pendingLdStCount == 0);
280  assert(pendingAtomicCount == 0);
282  } else if (resp_cmd == MemCmd::ReadResp) {
283  // response to a pending read
284  assert(pendingLdStCount > 0);
285  assert(pendingAtomicCount == 0);
286  assert(outstandingLoads.count(addr) > 0);
287 
288  // get return data
289  Value value = *(pkt->getPtr<Value>());
291  validateLoadResp(req.origLoc, req.lane, value);
292 
293  // this Read is done
295  } else if (resp_cmd == MemCmd::WriteResp) {
296  // response to a pending write
297  assert(pendingLdStCount > 0);
298  assert(pendingAtomicCount == 0);
299 
300  // no need to validate Write response
301  // just pop it from the outstanding req table so that subsequent
302  // requests dependent on this write can proceed
303  // note that we don't decrement pendingLdStCount here yet since
304  // the write is not yet completed in downstream memory. Instead, we
305  // decrement the counter when we receive the write completion ack
306  assert(outstandingStores.count(addr) > 0);
309 
310  // update log table
313  req.storedValue,
314  curTick(),
315  cuId);
316 
317  // the transaction is not done yet. Waiting for write completion ack
318  isTransactionDone = false;
319  } else if (resp_cmd == MemCmd::SwapResp) {
320  // response to a pending atomic
321  assert(pendingAtomicCount > 0);
322  assert(pendingLdStCount == 0);
323  assert(outstandingAtomics.count(addr) > 0);
324 
325  // get return data
326  Value value = *(pkt->getPtr<Value>());
327 
328  // validate atomic op return
330  validateAtomicResp(req.origLoc, req.lane, value);
331 
332  // update log table
334  curEpisode->getEpisodeId(), value,
335  curTick(),
336  cuId);
337 
338  // this Atomic is done
340  } else if (resp_cmd == MemCmd::WriteCompleteResp) {
341  // write completion ACK
342  assert(pendingLdStCount > 0);
343  assert(pendingAtomicCount == 0);
344 
345  // the Write is now done
347  } else {
348  panic("Unsupported MemCmd response type");
349  }
350 
351  if (isTransactionDone) {
352  // no need to keep senderState and request around
353  delete pkt->senderState;
354  }
355 
356  delete pkt;
357 
358  // record the last active cycle to check for deadlock
360 
361  // we may be able to issue an action. Let's check
362  if (!threadEvent.scheduled()) {
363  scheduleWakeup();
364  }
365 }
366 
367 void
369 {
370  // No extra request flag is set
371 }
Episode::Action::getLocation
Location getLocation(int lane) const
Definition: episode.cc:288
ProtocolTester::requestorId
RequestorID requestorId()
Definition: protocol_tester.hh:121
TesterThread::outstandingStores
OutstandingReqTable outstandingStores
Definition: tester_thread.hh:172
AtomicOpFunctorPtr
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:239
Request::INV_L1
@ INV_L1
mem_sync_op flags
Definition: request.hh:295
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:462
TesterThread::pendingFenceCount
int pendingFenceCount
Definition: tester_thread.hh:161
data
const char data[]
Definition: circlebuf.test.cc:47
GpuWavefront::Value
AddressManager::Value Value
Definition: gpu_wavefront.hh:49
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:755
GpuWavefront::~GpuWavefront
virtual ~GpuWavefront()
Definition: gpu_wavefront.cc:46
Flags< FlagsType >
TesterThread::TesterThreadEvent::setDesc
void setDesc(std::string _description)
Definition: tester_thread.hh:92
AtomicOpInc
Definition: amo.hh:187
TesterThread
Definition: tester_thread.hh:48
AddressManager::getAddress
Addr getAddress(Location loc)
Definition: address_manager.cc:87
sc_dt::to_string
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:91
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:83
TesterThread::numLanes
int numLanes
Definition: tester_thread.hh:137
Episode::Action::Type::LOAD
@ LOAD
TesterThread::OutstandingReq::origLoc
Location origLoc
Definition: tester_thread.hh:122
Request::ATOMIC_RETURN_OP
@ ATOMIC_RETURN_OP
The request is an atomic that returns data.
Definition: request.hh:166
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:86
TesterThread::pendingAtomicCount
int pendingAtomicCount
Definition: tester_thread.hh:162
GpuWavefront::setExtraRequestFlags
virtual void setExtraRequestFlags(RequestPtr req)
Definition: gpu_wavefront.cc:368
Packet::dataDynamic
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Definition: packet.hh:1146
TesterThread::addrManager
AddressManager * addrManager
Definition: tester_thread.hh:143
Episode::Action::getType
Type getType() const
Definition: episode.hh:63
GpuWavefront::Params
GpuWavefrontParams Params
Definition: gpu_wavefront.hh:44
TesterThread::OutstandingReq::lane
int lane
Definition: tester_thread.hh:121
GpuWavefront::hitCallback
virtual void hitCallback(PacketPtr pkt)
Definition: gpu_wavefront.cc:261
GpuWavefront::issueStoreOps
void issueStoreOps()
Definition: gpu_wavefront.cc:103
TesterThread::outstandingLoads
OutstandingReqTable outstandingLoads
Definition: tester_thread.hh:171
ProtocolTester::getActionSeqNum
int getActionSeqNum()
Definition: protocol_tester.hh:136
AtomicOpFunctor
Definition: amo.hh:40
GpuWavefront::issueReleaseOp
virtual void issueReleaseOp()
Definition: gpu_wavefront.cc:245
MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:86
MemCmd::WriteCompleteResp
@ WriteCompleteResp
Definition: packet.hh:88
TesterThread::OutstandingReq
Definition: tester_thread.hh:119
ArmISA::j
Bitfield< 24 > j
Definition: miscregs_types.hh:54
TesterThread::threadName
std::string threadName
Definition: tester_thread.hh:139
MemCmd::SwapReq
@ SwapReq
Definition: packet.hh:112
GpuWavefront::cuId
int cuId
Definition: gpu_wavefront.hh:65
AddressManager::getLoggedValue
Value getLoggedValue(Location loc) const
Definition: address_manager.cc:420
RequestPort::sendTimingReq
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition: port.hh:492
MemCmd::toString
const std::string & toString() const
Return the string to a cmd given by idx.
Definition: packet.hh:240
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
GpuWavefront::issueAcquireOp
virtual void issueAcquireOp()
Definition: gpu_wavefront.cc:212
SenderState
RubyTester::SenderState SenderState
Definition: Check.cc:37
MemCmd
Definition: packet.hh:72
TesterThread::curEpisode
Episode * curEpisode
Definition: tester_thread.hh:155
Clocked::curCycle
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Definition: clocked_object.hh:192
MemCmd::SwapResp
@ SwapResp
Definition: packet.hh:113
Episode::Action::Type::ACQUIRE
@ ACQUIRE
TesterThread::lastActiveCycle
Cycles lastActiveCycle
Definition: tester_thread.hh:165
TesterThread::curAction
const Episode::Action * curAction
Definition: tester_thread.hh:157
TesterThread::popOutstandingReq
OutstandingReq popOutstandingReq(OutstandingReqTable &req_table, Addr address)
Definition: tester_thread.cc:307
GpuWavefront::Location
AddressManager::Location Location
Definition: gpu_wavefront.hh:48
gpu_wavefront.hh
ProbePoints::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:103
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
TesterThread::validateAtomicResp
void validateAtomicResp(Location loc, int lane, Value ret_val)
Definition: tester_thread.cc:333
MemCmd::MemSyncResp
@ MemSyncResp
Definition: packet.hh:117
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
Packet::cmd
MemCmd cmd
The command field of the packet.
Definition: packet.hh:336
TesterThread::threadId
int threadId
Definition: tester_thread.hh:135
GpuWavefront::issueLoadOps
void issueLoadOps()
Definition: gpu_wavefront.cc:52
TesterThread::outstandingAtomics
OutstandingReqTable outstandingAtomics
Definition: tester_thread.hh:173
Episode::Action::Type::STORE
@ STORE
TesterThread::OutstandingReq::storedValue
Value storedValue
Definition: tester_thread.hh:123
MemCmd::WriteResp
@ WriteResp
Definition: packet.hh:87
TesterThread::scheduleWakeup
void scheduleWakeup()
Definition: tester_thread.cc:111
MemCmd::MemSyncReq
@ MemSyncReq
Definition: packet.hh:116
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
GpuWavefront::issueAtomicOps
void issueAtomicOps()
Definition: gpu_wavefront.cc:160
TesterThread::threadEvent
TesterThreadEvent threadEvent
Definition: tester_thread.hh:97
Packet::getPtr
T * getPtr()
get a pointer to the data ptr.
Definition: packet.hh:1158
MemCmd::ReadResp
@ ReadResp
Definition: packet.hh:84
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
TesterThread::pendingLdStCount
int pendingLdStCount
Definition: tester_thread.hh:160
Packet::senderState
SenderState * senderState
This packet's sender state.
Definition: packet.hh:509
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
TesterThread::addOutstandingReqs
void addOutstandingReqs(OutstandingReqTable &req_table, Addr addr, int lane, Location loc, Value stored_val=AddressManager::INVALID_VALUE)
Definition: tester_thread.cc:290
TesterThread::getName
const std::string & getName() const
Definition: tester_thread.hh:69
AddressManager::updateLogTable
void updateLogTable(Location loc, int threadId, int episodeId, Value new_value, Tick curTick, int cuId=-1)
Definition: address_manager.cc:412
AddressManager::INVALID_LOCATION
static const int INVALID_LOCATION
Definition: address_manager.hh:151
GpuWavefront::GpuWavefront
GpuWavefront(const Params &p)
Definition: gpu_wavefront.cc:38
TesterThread::tester
ProtocolTester * tester
Definition: tester_thread.hh:141
Episode::getEpisodeId
int getEpisodeId() const
Definition: episode.hh:82
printAddress
std::string printAddress(Addr addr)
Definition: Address.cc:74
TesterThread::port
ProtocolTester::SeqPort * port
Definition: tester_thread.hh:145
TesterThread::validateLoadResp
void validateLoadResp(Location loc, int lane, Value ret_val)
Definition: tester_thread.cc:357
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
Episode::Action::Type::ATOMIC
@ ATOMIC
AddressManager::INVALID_VALUE
static const int INVALID_VALUE
Definition: address_manager.hh:150

Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17