gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
protocol_tester.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 <algorithm>
37 #include <ctime>
38 #include <fstream>
39 #include <random>
40 
45 #include "debug/ProtocolTest.hh"
46 #include "mem/request.hh"
47 #include "sim/sim_exit.hh"
48 #include "sim/system.hh"
49 
51  : ClockedObject(p),
52  _requestorId(p.system->getRequestorId(this)),
53  numCpuPorts(p.port_cpu_ports_connection_count),
54  numDmaPorts(p.port_dma_ports_connection_count),
55  numVectorPorts(p.port_cu_vector_ports_connection_count),
56  numSqcPorts(p.port_cu_sqc_ports_connection_count),
57  numScalarPorts(p.port_cu_scalar_ports_connection_count),
58  numTokenPorts(p.port_cu_token_ports_connection_count),
59  numCusPerSqc(p.cus_per_sqc),
60  numCusPerScalar(p.cus_per_scalar),
61  numWfsPerCu(p.wavefronts_per_cu),
62  numWisPerWf(p.workitems_per_wavefront),
63  numCuTokens(p.max_cu_tokens),
64  numAtomicLocs(p.num_atomic_locations),
65  numNormalLocsPerAtomic(p.num_normal_locs_per_atomic),
66  episodeLength(p.episode_length),
67  maxNumEpisodes(p.max_num_episodes),
68  debugTester(p.debug_tester),
69  cpuThreads(p.cpu_threads),
70  dmaThreads(p.dma_threads),
71  wfs(p.wavefronts)
72 {
73  int idx = 0; // global port index
74 
75  numCpus = numCpuPorts; // 1 cpu port per CPU
76  numDmas = numDmaPorts; // 1 dma port per DMA
77  numCus = numVectorPorts; // 1 vector port per CU
78 
79  // create all physical cpu's data ports
80  for (int i = 0; i < numCpuPorts; ++i) {
81  DPRINTF(ProtocolTest, "Creating %s\n",
82  csprintf("%s-cpuPort%d", name(), i));
83  cpuPorts.push_back(new SeqPort(csprintf("%s-cpuPort%d", name(), i),
84  this, i, idx));
85  idx++;
86  }
87 
88  // create all physical DMA data ports
89  for (int i = 0; i < numDmaPorts; ++i) {
90  DPRINTF(ProtocolTest, "Creating %s\n",
91  csprintf("%s-dmaPort%d", name(), i));
92  dmaPorts.push_back(new SeqPort(csprintf("%s-dmaPort%d", name(), i),
93  this, i, idx));
94  idx++;
95  }
96 
97  // create all physical gpu's data ports
98  for (int i = 0; i < numVectorPorts; ++i) {
99  DPRINTF(ProtocolTest, "Creating %s\n",
100  csprintf("%s-cuVectorPort%d", name(), i));
101  cuVectorPorts.push_back(new SeqPort(csprintf("%s-cuVectorPort%d",
102  name(), i),
103  this, i, idx));
104  idx++;
105  }
106 
107  for (int i = 0; i < numScalarPorts; ++i) {
108  DPRINTF(ProtocolTest, "Creating %s\n",
109  csprintf("%s-cuScalarPort%d", name(), i));
110  cuScalarPorts.push_back(new SeqPort(csprintf("%s-cuScalarPort%d",
111  name(), i),
112  this, i, idx));
113  idx++;
114  }
115 
116  for (int i = 0; i < numSqcPorts; ++i) {
117  DPRINTF(ProtocolTest, "Creating %s\n",
118  csprintf("%s-cuSqcPort%d", name(), i));
119  cuSqcPorts.push_back(new SeqPort(csprintf("%s-cuSqcPort%d",
120  name(), i),
121  this, i, idx));
122  idx++;
123  }
124 
125  for (int i = 0; i < numTokenPorts; ++i) {
126  cuTokenPorts.push_back(new GMTokenPort(csprintf("%s-cuTokenPort%d",
127  name(), i),
128  this, i));
129  cuTokenManagers.push_back(new TokenManager(numCuTokens));
130  cuTokenPorts[i]->setTokenManager(cuTokenManagers[i]);
131  }
132 
133  // create an address manager
136  nextEpisodeId = 0;
137 
138  if (!debugTester)
139  warn("Data race check is not enabled\n");
140 
141  sentExitSignal = false;
142 
143  // set random seed number
144  if (p.random_seed != 0) {
145  srand(p.random_seed);
146  } else {
147  srand(time(NULL));
148  }
149 
150  actionCount = 0;
151 
152  // create a new log file
153  logFile = simout.create(p.log_file);
154  assert(logFile);
155 
156  // print test configs
157  std::stringstream ss;
158  ss << "GPU Ruby test's configurations" << std::endl
159  << "\tNumber of CPUs: " << numCpus << std::endl
160  << "\tNumber of DMAs: " << numDmas << std::endl
161  << "\tNumber of CUs: " << numCus << std::endl
162  << "\tNumber of wavefronts per CU: " << numWfsPerCu << std::endl
163  << "\tWavefront size: " << numWisPerWf << std::endl
164  << "\tNumber of atomic locations: " << numAtomicLocs << std::endl
165  << "\tNumber of non-atomic locations: "
166  << numNormalLocsPerAtomic * numAtomicLocs << std::endl
167  << "\tEpisode length: " << episodeLength << std::endl
168  << "\tTest length (max number of episodes): " << maxNumEpisodes
169  << std::endl
170  << "\tRandom seed: " << p.random_seed
171  << std::endl;
172 
173  ccprintf(*(logFile->stream()), "%s", ss.str());
174  logFile->stream()->flush();
175 }
176 
178 {
179  for (int i = 0; i < cpuPorts.size(); ++i)
180  delete cpuPorts[i];
181  for (int i = 0; i < dmaPorts.size(); ++i)
182  delete dmaPorts[i];
183  for (int i = 0; i < cuVectorPorts.size(); ++i)
184  delete cuVectorPorts[i];
185  for (int i = 0; i < cuScalarPorts.size(); ++i)
186  delete cuScalarPorts[i];
187  for (int i = 0; i < cuSqcPorts.size(); ++i)
188  delete cuSqcPorts[i];
189  delete addrManager;
190 
191  // close the log file
193 }
194 
195 void
197 {
198  DPRINTF(ProtocolTest, "Attach threads to ports\n");
199 
200  // connect cpu threads to cpu's ports
201  for (int cpu_id = 0; cpu_id < numCpus; ++cpu_id) {
202  cpuThreads[cpu_id]->attachTesterThreadToPorts(this,
203  static_cast<SeqPort*>(cpuPorts[cpu_id]));
204  cpuThreads[cpu_id]->scheduleWakeup();
205  cpuThreads[cpu_id]->scheduleDeadlockCheckEvent();
206  }
207 
208  // connect dma threads to dma's ports
209  for (int dma_id = 0; dma_id < numDmas; ++dma_id) {
210  dmaThreads[dma_id]->attachTesterThreadToPorts(this,
211  static_cast<SeqPort*>(dmaPorts[dma_id]));
212  dmaThreads[dma_id]->scheduleWakeup();
213  dmaThreads[dma_id]->scheduleDeadlockCheckEvent();
214  }
215 
216  // connect gpu wavefronts to gpu's ports
217  int wfId = 0;
218  int vectorPortId = 0;
219  int sqcPortId = 0;
220  int scalarPortId = 0;
221 
222  for (int cu_id = 0; cu_id < numCus; ++cu_id) {
223  vectorPortId = cu_id;
224  sqcPortId = cu_id/numCusPerSqc;
225  scalarPortId = cu_id/numCusPerScalar;
226 
227  for (int i = 0; i < numWfsPerCu; ++i) {
228  wfId = cu_id * numWfsPerCu + i;
229  wfs[wfId]->attachTesterThreadToPorts(this,
230  static_cast<SeqPort*>(cuVectorPorts[vectorPortId]),
231  cuTokenPorts[vectorPortId],
232  static_cast<SeqPort*>(cuSqcPorts[sqcPortId]),
233  static_cast<SeqPort*>(cuScalarPorts[scalarPortId]));
234  wfs[wfId]->scheduleWakeup();
235  wfs[wfId]->scheduleDeadlockCheckEvent();
236  }
237  }
238 }
239 
240 Port&
241 ProtocolTester::getPort(const std::string &if_name, PortID idx)
242 {
243  if (if_name != "cpu_ports" && if_name != "dma_ports" &&
244  if_name != "cu_vector_ports" && if_name != "cu_sqc_ports" &&
245  if_name != "cu_scalar_ports" && if_name != "cu_token_ports") {
246  // pass along to super class
247  return ClockedObject::getPort(if_name, idx);
248  } else {
249  if (if_name == "cpu_ports") {
250  if (idx > numCpuPorts)
251  panic("ProtocolTester: unknown cpu port %d\n", idx);
252  return *cpuPorts[idx];
253  } else if (if_name == "dma_ports") {
254  if (idx > numDmaPorts)
255  panic("ProtocolTester: unknown dma port %d\n", idx);
256  return *dmaPorts[idx];
257  } else if (if_name == "cu_vector_ports") {
258  if (idx > numVectorPorts)
259  panic("ProtocolTester: unknown cu vect port %d\n", idx);
260  return *cuVectorPorts[idx];
261  } else if (if_name == "cu_sqc_ports") {
262  if (idx > numSqcPorts)
263  panic("ProtocolTester: unknown cu sqc port %d\n", idx);
264  return *cuSqcPorts[idx];
265  } else if (if_name == "cu_token_ports") {
266  if (idx > numTokenPorts)
267  panic("ProtocolTester: unknown cu token port %d\n", idx);
268  return *cuTokenPorts[idx];
269  } else {
270  assert(if_name == "cu_scalar_ports");
271  if (idx > numScalarPorts)
272  panic("ProtocolTester: unknown cu scal port %d\n", idx);
273  return *cuScalarPorts[idx];
274  }
275  }
276 
277  assert(false);
278 }
279 
280 bool
282 {
284  if (!sentExitSignal) {
285  // all done
286  inform("Total completed episodes: %d\n", nextEpisodeId - 1);
287  exitSimLoop("GPU Ruby Tester: Passed!");
288  sentExitSignal = true;
289  }
290  return true;
291  }
292  return false;
293 }
294 
295 bool
297  Location loc, bool isStore) const
298 {
299  if (debugTester) {
300  // go through all active episodes in all threads
301  for (const TesterThread* th : wfs) {
302  if (!th->checkDRF(atomic_loc, loc, isStore))
303  return false;
304  }
305 
306  for (const TesterThread* th : cpuThreads) {
307  if (!th->checkDRF(atomic_loc, loc, isStore))
308  return false;
309  }
310 
311  for (const TesterThread* th : dmaThreads) {
312  if (!th->checkDRF(atomic_loc, loc, isStore))
313  return false;
314  }
315  }
316 
317  return true;
318 }
319 
320 void
321 ProtocolTester::dumpErrorLog(std::stringstream& ss)
322 {
323  if (!sentExitSignal) {
324  // go through all threads and dump their outstanding requests
325  for (auto t : cpuThreads) {
326  t->printAllOutstandingReqs(ss);
327  }
328 
329  for (auto t : dmaThreads) {
330  t->printAllOutstandingReqs(ss);
331  }
332 
333  for (auto t : wfs) {
334  t->printAllOutstandingReqs(ss);
335  }
336 
337  // dump error log into a file
338  assert(logFile);
339  ccprintf(*(logFile->stream()), "%s", ss.str());
340  logFile->stream()->flush();
341 
342  sentExitSignal = true;
343  // terminate the simulation
344  panic("GPU Ruby Tester: Failed!\n");
345  }
346 }
347 
348 bool
350 {
351  // get the requesting thread from the original sender state
352  ProtocolTester::SenderState* senderState =
353  safe_cast<ProtocolTester::SenderState*>(pkt->senderState);
354  TesterThread *th = senderState->th;
355 
356  th->hitCallback(pkt);
357 
358  return true;
359 }
ProtocolTester::SenderState
Definition: protocol_tester.hh:99
ProtocolTester::debugTester
bool debugTester
Definition: protocol_tester.hh:164
warn
#define warn(...)
Definition: logging.hh:239
ProtocolTester::numSqcPorts
int numSqcPorts
Definition: protocol_tester.hh:148
system.hh
ProtocolTester::numCusPerSqc
int numCusPerSqc
Definition: protocol_tester.hh:151
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
ProtocolTester::cuSqcPorts
std::vector< RequestPort * > cuSqcPorts
Definition: protocol_tester.hh:170
ProtocolTester::checkDRF
bool checkDRF(Location atomic_loc, Location loc, bool isStore) const
Definition: protocol_tester.cc:296
ProtocolTester::numCuTokens
int numCuTokens
Definition: protocol_tester.hh:155
TesterThread
Definition: tester_thread.hh:48
OutputDirectory::create
OutputStream * create(const std::string &name, bool binary=false, bool no_gz=false)
Creates a file in this directory (optionally compressed).
Definition: output.cc:207
PortID
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:243
ProtocolTester::numTokenPorts
int numTokenPorts
Definition: protocol_tester.hh:150
ProtocolTester::SeqPort
Definition: protocol_tester.hh:71
ProtocolTester::cpuThreads
std::vector< CpuThread * > cpuThreads
Definition: protocol_tester.hh:175
ProtocolTester::~ProtocolTester
~ProtocolTester()
Definition: protocol_tester.cc:177
ProtocolTester::sentExitSignal
bool sentExitSignal
Definition: protocol_tester.hh:196
ProtocolTester::cuScalarPorts
std::vector< RequestPort * > cuScalarPorts
Definition: protocol_tester.hh:171
sim_exit.hh
request.hh
ProtocolTester::cuTokenPorts
std::vector< GMTokenPort * > cuTokenPorts
Definition: protocol_tester.hh:173
ClockedObject
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Definition: clocked_object.hh:231
ProtocolTester::SenderState::th
TesterThread * th
Definition: protocol_tester.hh:101
ProtocolTester::episodeLength
int episodeLength
Definition: protocol_tester.hh:160
dma_thread.hh
ProtocolTester::SeqPort::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Definition: protocol_tester.cc:349
ProtocolTester::maxNumEpisodes
int maxNumEpisodes
Definition: protocol_tester.hh:162
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
ProtocolTester::numDmas
int numDmas
Definition: protocol_tester.hh:186
ProtocolTester::numCus
int numCus
Definition: protocol_tester.hh:187
AddressManager
Definition: address_manager.hh:119
ArmISA::ss
Bitfield< 21 > ss
Definition: miscregs_types.hh:56
ProtocolTester::checkExit
bool checkExit()
Definition: protocol_tester.cc:281
ProtocolTester::addrManager
AddressManager * addrManager
Definition: protocol_tester.hh:182
SimObject::getPort
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:120
OutputStream::stream
std::ostream * stream() const
Get the output underlying output stream.
Definition: output.hh:59
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
ProtocolTester::numWisPerWf
int numWisPerWf
Definition: protocol_tester.hh:154
ProtocolTester::numScalarPorts
int numScalarPorts
Definition: protocol_tester.hh:149
Port
Ports are used to interface objects to each other.
Definition: port.hh:56
tester_thread.hh
ProtocolTester::cuTokenManagers
std::vector< TokenManager * > cuTokenManagers
Definition: protocol_tester.hh:172
ProtocolTester::Location
AddressManager::Location Location
Definition: protocol_tester.hh:117
OutputDirectory::close
void close(OutputStream *file)
Closes an output file and free the corresponding OutputFile.
Definition: output.cc:144
exitSimLoop
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 (...
Definition: sim_events.cc:85
ProtocolTester::wfs
std::vector< GpuWavefront * > wfs
Definition: protocol_tester.hh:177
ProtocolTester::logFile
OutputStream * logFile
Definition: protocol_tester.hh:198
cpu_thread.hh
gpu_wavefront.hh
ProtocolTester::numCusPerScalar
int numCusPerScalar
Definition: protocol_tester.hh:152
TesterThread::hitCallback
virtual void hitCallback(PacketPtr pkt)=0
ProtocolTester::numDmaPorts
int numDmaPorts
Definition: protocol_tester.hh:146
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:182
ProtocolTester::numAtomicLocs
int numAtomicLocs
Definition: protocol_tester.hh:157
ProtocolTester::ProtocolTester
ProtocolTester(const Params &p)
Definition: protocol_tester.cc:50
ProtocolTester::numVectorPorts
int numVectorPorts
Definition: protocol_tester.hh:147
ProtocolTester::numWfsPerCu
int numWfsPerCu
Definition: protocol_tester.hh:153
inform
#define inform(...)
Definition: logging.hh:240
ProtocolTester::dumpErrorLog
void dumpErrorLog(std::stringstream &ss)
Definition: protocol_tester.cc:321
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
ProtocolTester::actionCount
int actionCount
Definition: protocol_tester.hh:193
ProtocolTester::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: protocol_tester.cc:241
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
ProtocolTester::Params
ProtocolTesterParams Params
Definition: protocol_tester.hh:113
protocol_tester.hh
ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
ProtocolTester::nextEpisodeId
int nextEpisodeId
Definition: protocol_tester.hh:189
ProtocolTester::numNormalLocsPerAtomic
int numNormalLocsPerAtomic
Definition: protocol_tester.hh:158
ProtocolTester::dmaPorts
std::vector< RequestPort * > dmaPorts
Definition: protocol_tester.hh:168
TokenManager
Definition: token_port.hh:129
Packet::senderState
SenderState * senderState
This packet's sender state.
Definition: packet.hh:509
simout
OutputDirectory simout
Definition: output.cc:59
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
ProtocolTester::GMTokenPort
Definition: protocol_tester.hh:85
ProtocolTester::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: protocol_tester.cc:196
ProtocolTester::numCpus
int numCpus
Definition: protocol_tester.hh:185
ProtocolTester::cpuPorts
std::vector< RequestPort * > cpuPorts
Definition: protocol_tester.hh:167
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
ProtocolTester::dmaThreads
std::vector< DmaThread * > dmaThreads
Definition: protocol_tester.hh:176
ProtocolTester::cuVectorPorts
std::vector< RequestPort * > cuVectorPorts
Definition: protocol_tester.hh:169
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
ProtocolTester::numCpuPorts
int numCpuPorts
Definition: protocol_tester.hh:145

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