gem5 v24.0.0.0
Loading...
Searching...
No Matches
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 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
33
34#include <algorithm>
35#include <ctime>
36#include <fstream>
37
38#include "base/random.hh"
43#include "debug/ProtocolTest.hh"
44#include "mem/request.hh"
45#include "sim/sim_exit.hh"
46#include "sim/system.hh"
47
48namespace gem5
49{
50
53 _requestorId(p.system->getRequestorId(this)),
54 numCpuPorts(p.port_cpu_ports_connection_count),
55 numDmaPorts(p.port_dma_ports_connection_count),
56 numVectorPorts(p.port_cu_vector_ports_connection_count),
57 numSqcPorts(p.port_cu_sqc_ports_connection_count),
58 numScalarPorts(p.port_cu_scalar_ports_connection_count),
59 numTokenPorts(p.port_cu_token_ports_connection_count),
60 numCusPerSqc(p.cus_per_sqc),
61 numCusPerScalar(p.cus_per_scalar),
62 numWfsPerCu(p.wavefronts_per_cu),
63 numWisPerWf(p.workitems_per_wavefront),
64 numCuTokens(p.max_cu_tokens),
65 numAtomicLocs(p.num_atomic_locations),
66 numNormalLocsPerAtomic(p.num_normal_locs_per_atomic),
67 episodeLength(p.episode_length),
68 maxNumEpisodes(p.max_num_episodes),
69 debugTester(p.debug_tester),
70 cpuThreads(p.cpu_threads),
71 dmaThreads(p.dma_threads),
72 wfs(p.wavefronts)
73{
74 int idx = 0; // global port index
75
76 numCpus = numCpuPorts; // 1 cpu port per CPU
77 numDmas = numDmaPorts; // 1 dma port per DMA
78 numCus = numVectorPorts; // 1 vector port per CU
79
80 // create all physical cpu's data ports
81 for (int i = 0; i < numCpuPorts; ++i) {
82 DPRINTF(ProtocolTest, "Creating %s\n",
83 csprintf("%s-cpuPort%d", name(), i));
84 cpuPorts.push_back(new SeqPort(csprintf("%s-cpuPort%d", name(), i),
85 this, i, idx));
86 idx++;
87 }
88
89 // create all physical DMA data ports
90 for (int i = 0; i < numDmaPorts; ++i) {
91 DPRINTF(ProtocolTest, "Creating %s\n",
92 csprintf("%s-dmaPort%d", name(), i));
93 dmaPorts.push_back(new SeqPort(csprintf("%s-dmaPort%d", name(), i),
94 this, i, idx));
95 idx++;
96 }
97
98 // create all physical gpu's data ports
99 for (int i = 0; i < numVectorPorts; ++i) {
100 DPRINTF(ProtocolTest, "Creating %s\n",
101 csprintf("%s-cuVectorPort%d", name(), i));
102 cuVectorPorts.push_back(new SeqPort(csprintf("%s-cuVectorPort%d",
103 name(), i),
104 this, i, idx));
105 idx++;
106 }
107
108 for (int i = 0; i < numScalarPorts; ++i) {
109 DPRINTF(ProtocolTest, "Creating %s\n",
110 csprintf("%s-cuScalarPort%d", name(), i));
111 cuScalarPorts.push_back(new SeqPort(csprintf("%s-cuScalarPort%d",
112 name(), i),
113 this, i, idx));
114 idx++;
115 }
116
117 for (int i = 0; i < numSqcPorts; ++i) {
118 DPRINTF(ProtocolTest, "Creating %s\n",
119 csprintf("%s-cuSqcPort%d", name(), i));
120 cuSqcPorts.push_back(new SeqPort(csprintf("%s-cuSqcPort%d",
121 name(), i),
122 this, i, idx));
123 idx++;
124 }
125
126 for (int i = 0; i < numTokenPorts; ++i) {
127 cuTokenPorts.push_back(new GMTokenPort(csprintf("%s-cuTokenPort%d",
128 name(), i),
129 this, i));
131 cuTokenPorts[i]->setTokenManager(cuTokenManagers[i]);
132 }
133
134 // create an address manager
137 nextEpisodeId = 0;
138
139 if (!debugTester)
140 warn("Data race check is not enabled\n");
141
142 sentExitSignal = false;
143
144 // set random seed number, if specified.
145 // Note: random_m5 will use a fixed key if random_seed is not set.
146 // This ensures a reproducable.
147 if (p.random_seed != 0) {
148 random_mt.init(p.random_seed);
149 } else {
150 warn(
151 "If `random_seed == 0` (or `random_seed` is unset) "
152 "ProtocolTester does not seed the RNG. This will NOT result in "
153 "the RNG generating different results each run. In this case the "
154 "RNG is seeded by a default value. This differs from behavior in "
155 "previous versions of gem5. Setting `random_seed` to a non-zero "
156 "value is strongly recommended."
157 );
158 }
159
160 actionCount = 0;
161
162 // create a new log file
163 logFile = simout.create(p.log_file);
164 assert(logFile);
165
166 // print test configs
167 std::stringstream ss;
168 ss << "GPU Ruby test's configurations" << std::endl
169 << "\tNumber of CPUs: " << numCpus << std::endl
170 << "\tNumber of DMAs: " << numDmas << std::endl
171 << "\tNumber of CUs: " << numCus << std::endl
172 << "\tNumber of wavefronts per CU: " << numWfsPerCu << std::endl
173 << "\tWavefront size: " << numWisPerWf << std::endl
174 << "\tNumber of atomic locations: " << numAtomicLocs << std::endl
175 << "\tNumber of non-atomic locations: "
176 << numNormalLocsPerAtomic * numAtomicLocs << std::endl
177 << "\tEpisode length: " << episodeLength << std::endl
178 << "\tTest length (max number of episodes): " << maxNumEpisodes
179 << std::endl
180 << "\tRandom seed: " << p.random_seed
181 << std::endl;
182
183 ccprintf(*(logFile->stream()), "%s", ss.str());
184 logFile->stream()->flush();
185}
186
188{
189 for (int i = 0; i < cpuPorts.size(); ++i)
190 delete cpuPorts[i];
191 for (int i = 0; i < dmaPorts.size(); ++i)
192 delete dmaPorts[i];
193 for (int i = 0; i < cuVectorPorts.size(); ++i)
194 delete cuVectorPorts[i];
195 for (int i = 0; i < cuScalarPorts.size(); ++i)
196 delete cuScalarPorts[i];
197 for (int i = 0; i < cuSqcPorts.size(); ++i)
198 delete cuSqcPorts[i];
199 delete addrManager;
200
201 // close the log file
203}
204
205void
207{
208 DPRINTF(ProtocolTest, "Attach threads to ports\n");
209
210 // connect cpu threads to cpu's ports
211 for (int cpu_id = 0; cpu_id < numCpus; ++cpu_id) {
212 cpuThreads[cpu_id]->attachTesterThreadToPorts(this,
213 static_cast<SeqPort*>(cpuPorts[cpu_id]));
214 cpuThreads[cpu_id]->scheduleWakeup();
215 cpuThreads[cpu_id]->scheduleDeadlockCheckEvent();
216 }
217
218 // connect dma threads to dma's ports
219 for (int dma_id = 0; dma_id < numDmas; ++dma_id) {
220 dmaThreads[dma_id]->attachTesterThreadToPorts(this,
221 static_cast<SeqPort*>(dmaPorts[dma_id]));
222 dmaThreads[dma_id]->scheduleWakeup();
223 dmaThreads[dma_id]->scheduleDeadlockCheckEvent();
224 }
225
226 // connect gpu wavefronts to gpu's ports
227 int wfId = 0;
228 int vectorPortId = 0;
229 int sqcPortId = 0;
230 int scalarPortId = 0;
231
232 for (int cu_id = 0; cu_id < numCus; ++cu_id) {
233 vectorPortId = cu_id;
234 sqcPortId = cu_id/numCusPerSqc;
235 scalarPortId = cu_id/numCusPerScalar;
236
237 for (int i = 0; i < numWfsPerCu; ++i) {
238 wfId = cu_id * numWfsPerCu + i;
239 wfs[wfId]->attachTesterThreadToPorts(this,
240 static_cast<SeqPort*>(cuVectorPorts[vectorPortId]),
241 cuTokenPorts[vectorPortId],
242 static_cast<SeqPort*>(cuSqcPorts[sqcPortId]),
243 static_cast<SeqPort*>(cuScalarPorts[scalarPortId]));
244 wfs[wfId]->scheduleWakeup();
245 wfs[wfId]->scheduleDeadlockCheckEvent();
246 }
247 }
248}
249
250Port&
251ProtocolTester::getPort(const std::string &if_name, PortID idx)
252{
253 if (if_name != "cpu_ports" && if_name != "dma_ports" &&
254 if_name != "cu_vector_ports" && if_name != "cu_sqc_ports" &&
255 if_name != "cu_scalar_ports" && if_name != "cu_token_ports") {
256 // pass along to super class
257 return ClockedObject::getPort(if_name, idx);
258 } else {
259 if (if_name == "cpu_ports") {
260 if (idx > numCpuPorts)
261 panic("ProtocolTester: unknown cpu port %d\n", idx);
262 return *cpuPorts[idx];
263 } else if (if_name == "dma_ports") {
264 if (idx > numDmaPorts)
265 panic("ProtocolTester: unknown dma port %d\n", idx);
266 return *dmaPorts[idx];
267 } else if (if_name == "cu_vector_ports") {
268 if (idx > numVectorPorts)
269 panic("ProtocolTester: unknown cu vect port %d\n", idx);
270 return *cuVectorPorts[idx];
271 } else if (if_name == "cu_sqc_ports") {
272 if (idx > numSqcPorts)
273 panic("ProtocolTester: unknown cu sqc port %d\n", idx);
274 return *cuSqcPorts[idx];
275 } else if (if_name == "cu_token_ports") {
276 if (idx > numTokenPorts)
277 panic("ProtocolTester: unknown cu token port %d\n", idx);
278 return *cuTokenPorts[idx];
279 } else {
280 assert(if_name == "cu_scalar_ports");
281 if (idx > numScalarPorts)
282 panic("ProtocolTester: unknown cu scal port %d\n", idx);
283 return *cuScalarPorts[idx];
284 }
285 }
286
287 assert(false);
288}
289
290bool
292{
294 if (!sentExitSignal) {
295 // all done
296 inform("Total completed episodes: %d\n", nextEpisodeId - 1);
297 exitSimLoop("GPU Ruby Tester: Passed!");
298 sentExitSignal = true;
299 }
300 return true;
301 }
302 return false;
303}
304
305bool
307 Location loc, bool isStore) const
308{
309 if (debugTester) {
310 // go through all active episodes in all threads
311 for (const TesterThread* th : wfs) {
312 if (!th->checkDRF(atomic_loc, loc, isStore))
313 return false;
314 }
315
316 for (const TesterThread* th : cpuThreads) {
317 if (!th->checkDRF(atomic_loc, loc, isStore))
318 return false;
319 }
320
321 for (const TesterThread* th : dmaThreads) {
322 if (!th->checkDRF(atomic_loc, loc, isStore))
323 return false;
324 }
325 }
326
327 return true;
328}
329
330void
332{
333 if (!sentExitSignal) {
334 // go through all threads and dump their outstanding requests
335 for (auto t : cpuThreads) {
336 t->printAllOutstandingReqs(ss);
337 }
338
339 for (auto t : dmaThreads) {
340 t->printAllOutstandingReqs(ss);
341 }
342
343 for (auto t : wfs) {
344 t->printAllOutstandingReqs(ss);
345 }
346
347 // dump error log into a file
348 assert(logFile);
349 ccprintf(*(logFile->stream()), "%s", ss.str());
350 logFile->stream()->flush();
351
352 sentExitSignal = true;
353 // terminate the simulation
354 panic("GPU Ruby Tester: Failed!\n");
355 }
356}
357
358bool
360{
361 // get the requesting thread from the original sender state
362 ProtocolTester::SenderState* senderState =
364 TesterThread *th = senderState->th;
365
366 th->hitCallback(pkt);
367
368 return true;
369}
370
371} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
virtual std::string name() const
Definition named.hh:47
void close(OutputStream *file)
Closes an output file and free the corresponding OutputFile.
Definition output.cc:147
OutputStream * create(const std::string &name, bool binary=false, bool no_gz=false)
Creates a file in this directory (optionally compressed).
Definition output.cc:210
std::ostream * stream() const
Get the output underlying output stream.
Definition output.hh:62
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
SenderState * senderState
This packet's sender state.
Definition packet.hh:545
Ports are used to interface objects to each other.
Definition port.hh:62
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
ProtocolTester(const Params &p)
std::vector< GpuWavefront * > wfs
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::vector< RequestPort * > cuVectorPorts
AddressManager * addrManager
AddressManager::Location Location
std::vector< RequestPort * > cuSqcPorts
ProtocolTesterParams Params
std::vector< DmaThread * > dmaThreads
bool checkDRF(Location atomic_loc, Location loc, bool isStore) const
std::vector< GMTokenPort * > cuTokenPorts
std::vector< CpuThread * > cpuThreads
std::vector< RequestPort * > cuScalarPorts
std::vector< RequestPort * > dmaPorts
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
std::vector< TokenManager * > cuTokenManagers
std::vector< RequestPort * > cpuPorts
void dumpErrorLog(std::stringstream &ss)
void init(uint32_t s)
Definition random.cc:67
virtual void hitCallback(PacketPtr pkt)=0
Random random_mt
Definition random.cc:99
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
#define warn(...)
Definition logging.hh:256
#define inform(...)
Definition logging.hh:257
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 21 > ss
Definition misc_types.hh:60
Bitfield< 0 > p
Bitfield< 15 > system
Definition misc.hh:1032
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
T safe_cast(U &&ref_or_ptr)
Definition cast.hh:74
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
OutputDirectory simout
Definition output.cc:62
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:88
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
Declaration of a request, the overall memory request consisting of the parts of the request that are ...

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0