Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
esitester.cpp
Go to the documentation of this file.
1//===- esitester.cpp - ESI accelerator test/example tool ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// DO NOT EDIT!
10// This file is distributed as part of an ESI runtime package. The source for
11// this file should always be modified within CIRCT
12// (lib/dialect/ESI/runtime/cpp/tools/esitester.cpp).
13//
14//===----------------------------------------------------------------------===//
15//
16// This application isn't a utility so much as a test driver for an ESI system.
17// It is also useful as an example of how to use the ESI C++ API. esiquery.cpp
18// is also useful as an example.
19//
20//===----------------------------------------------------------------------===//
21
22#include "esi/Accelerator.h"
23#include "esi/CLI.h"
24#include "esi/Manifest.h"
25#include "esi/Services.h"
26
27#include <chrono>
28#include <iostream>
29#include <map>
30#include <stdexcept>
31
32using namespace esi;
33
35static void hostmemTest(AcceleratorConnection *, Accelerator *, bool read,
36 bool write);
37static void dmaTest(AcceleratorConnection *, Accelerator *, bool read,
38 bool write);
40 uint32_t xferCount,
41 const std::vector<uint32_t> &widths, bool read,
42 bool write);
43
44int main(int argc, const char *argv[]) {
45 CliParser cli("esitester");
46 cli.description("Test an ESI system running the ESI tester image.");
47 cli.require_subcommand(1);
48
49 CLI::App *loopSub = cli.add_subcommand("loop", "Loop indefinitely");
50
51 CLI::App *waitSub =
52 cli.add_subcommand("wait", "Wait for a certain number of seconds");
53 uint32_t waitTime = 1;
54 waitSub->add_option("-t,--time", waitTime, "Number of seconds to wait");
55
56 CLI::App *hostmemtestSub =
57 cli.add_subcommand("hostmem", "Run the host memory test");
58 bool hmRead = false;
59 bool hmWrite = false;
60 hostmemtestSub->add_flag("-w,--write", hmWrite,
61 "Enable host memory write test");
62 hostmemtestSub->add_flag("-r,--read", hmRead, "Enable host memory read test");
63
64 CLI::App *dmatestSub = cli.add_subcommand("dma", "Run the DMA test");
65 bool dmaRead = false;
66 bool dmaWrite = false;
67 dmatestSub->add_flag("-w,--write", dmaWrite, "Enable dma write test");
68 dmatestSub->add_flag("-r,--read", dmaRead, "Enable dma read test");
69
70 CLI::App *bandwidthSub =
71 cli.add_subcommand("bandwidth", "Run the bandwidth test");
72 uint32_t xferCount = 1000;
73 bandwidthSub->add_option("-c,--count", xferCount,
74 "Number of transfers to perform");
75 bool bandwidthRead = false;
76 bool bandwidthWrite = false;
77 std::vector<uint32_t> widths = {32, 64, 128, 256, 384, 504, 512};
78 bandwidthSub->add_option("--widths", widths,
79 "Width of the transfers to perform (default: 32, "
80 "64, 128, 256, 384, 504, 512)");
81 bandwidthSub->add_flag("-w,--write", bandwidthWrite,
82 "Enable bandwidth write");
83 bandwidthSub->add_flag("-r,--read", bandwidthRead, "Enable bandwidth read");
84
85 if (int rc = cli.esiParse(argc, argv))
86 return rc;
87 if (!cli.get_help_ptr()->empty())
88 return 0;
89
90 Context &ctxt = cli.getContext();
91 try {
92 std::unique_ptr<AcceleratorConnection> acc = cli.connect();
93 const auto &info = *acc->getService<services::SysInfo>();
94 Manifest manifest(ctxt, info.getJsonManifest());
95 Accelerator *accel = manifest.buildAccelerator(*acc);
96 acc->getServiceThread()->addPoll(*accel);
97
98 if (*loopSub) {
99 registerCallbacks(acc.get(), accel);
100 while (true) {
101 std::this_thread::sleep_for(std::chrono::milliseconds(100));
102 }
103 } else if (*waitSub) {
104 registerCallbacks(acc.get(), accel);
105 std::this_thread::sleep_for(std::chrono::seconds(waitTime));
106 } else if (*hostmemtestSub) {
107 hostmemTest(acc.get(), accel, hmRead, hmWrite);
108 } else if (*dmatestSub) {
109 dmaTest(acc.get(), accel, dmaRead, dmaWrite);
110 } else if (*bandwidthSub) {
111 bandwidthTest(acc.get(), accel, xferCount, widths, bandwidthRead,
112 bandwidthWrite);
113 }
114
115 acc->disconnect();
116 std::cout << "Exiting successfully\n";
117 return 0;
118 } catch (std::exception &e) {
119 ctxt.getLogger().error("esitester", e.what());
120 return -1;
121 }
122}
123
125 auto ports = accel->getPorts();
126 auto f = ports.find(AppID("PrintfExample"));
127 if (f != ports.end()) {
128 auto callPort = f->second.getAs<services::CallService::Callback>();
129 if (callPort)
130 callPort->connect(
131 [conn](const MessageData &data) -> MessageData {
132 conn->getLogger().debug(
133 [&](std::string &subsystem, std::string &msg,
134 std::unique_ptr<std::map<std::string, std::any>> &details) {
135 subsystem = "ESITESTER";
136 msg = "Received PrintfExample message";
137 details = std::make_unique<std::map<std::string, std::any>>();
138 details->emplace("data", data);
139 });
140 std::cout << "PrintfExample: " << *data.as<uint32_t>() << std::endl;
141 return MessageData();
142 },
143 true);
144 else
145 std::cerr << "PrintfExample port is not a CallService::Callback"
146 << std::endl;
147 } else {
148 std::cerr << "No PrintfExample port found" << std::endl;
149 }
150}
151
152/// Initiate a test read.
154 esi::services::HostMem::HostMemRegion &region, uint32_t width,
155 void *devicePtr, bool read, bool write) {
156 std::cout << "Running hostmem test with width " << width << std::endl;
157 uint64_t *dataPtr = static_cast<uint64_t *>(region.getPtr());
158
159 if (read) {
160 auto readMemChildIter = acc->getChildren().find(AppID("readmem", width));
161 if (readMemChildIter == acc->getChildren().end())
162 throw std::runtime_error("hostmem test failed. No readmem child found");
163 auto &readMemPorts = readMemChildIter->second->getPorts();
164 auto readMemPortIter = readMemPorts.find(AppID("ReadMem"));
165 if (readMemPortIter == readMemPorts.end())
166 throw std::runtime_error("hostmem test failed. No ReadMem port found");
167 auto *readMem = readMemPortIter->second.getAs<services::MMIO::MMIORegion>();
168 if (!readMem)
169 throw std::runtime_error("hostmem test failed. ReadMem port is not MMIO");
170
171 for (size_t i = 0; i < 8; ++i) {
172 dataPtr[0] = 0x12345678 << i;
173 dataPtr[1] = 0xDEADBEEF << i;
174 region.flush();
175 readMem->write(8, reinterpret_cast<uint64_t>(devicePtr));
176
177 // Wait for the accelerator to read the correct value. Timeout and fail
178 // after 10ms.
179 uint64_t val = 0;
180 uint64_t expected = dataPtr[0];
181 if (width < 64)
182 expected &= ((1ull << width) - 1);
183 for (int i = 0; i < 100; ++i) {
184 val = readMem->read(0);
185 if (val == expected)
186 break;
187 std::this_thread::sleep_for(std::chrono::microseconds(100));
188 }
189
190 if (val != expected)
191 throw std::runtime_error("hostmem read test failed. Expected " +
192 esi::toHex(expected) + ", got " +
193 esi::toHex(val));
194 }
195 }
196
197 // Initiate a test write.
198 if (write) {
199 assert(width % 8 == 0);
200 auto check = [&](bool print) {
201 bool ret = true;
202 for (size_t i = 0; i < 8; ++i) {
203 if (print)
204 std::cout << "dataPtr[" << i << "] = 0x" << esi::toHex(dataPtr[i])
205 << std::endl;
206 if (i < (width + 63) / 64 && dataPtr[i] == 0xFFFFFFFFFFFFFFFFull)
207 ret = false;
208 }
209 return ret;
210 };
211
212 auto writeMemChildIter = acc->getChildren().find(AppID("writemem", width));
213 if (writeMemChildIter == acc->getChildren().end())
214 throw std::runtime_error("hostmem test failed. No writemem child found");
215 auto &writeMemPorts = writeMemChildIter->second->getPorts();
216 auto writeMemPortIter = writeMemPorts.find(AppID("WriteMem"));
217 if (writeMemPortIter == writeMemPorts.end())
218 throw std::runtime_error("hostmem test failed. No WriteMem port found");
219 auto *writeMem =
220 writeMemPortIter->second.getAs<services::MMIO::MMIORegion>();
221 if (!writeMem)
222 throw std::runtime_error(
223 "hostmem test failed. WriteMem port is not MMIO");
224
225 for (size_t i = 0, e = 8; i < e; ++i)
226 dataPtr[i] = 0xFFFFFFFFFFFFFFFFull;
227 region.flush();
228
229 auto telemetryPortIter = writeMemPorts.find(AppID("timesWritten"));
230 if (telemetryPortIter == writeMemPorts.end())
231 throw std::runtime_error("hostmem test failed. No telemetry child found");
233 telemetryPortIter->second
235 telemetry->connect();
236 uint64_t writeCount = *telemetry->read().get().as<uint64_t>();
237 std::cout << "Write count: " << writeCount << std::endl;
238
239 // Command the accelerator to write to 'devicePtr', the pointer which the
240 // device should use for 'dataPtr'.
241 writeMem->write(0, reinterpret_cast<uint64_t>(devicePtr));
242 // Wait for the accelerator to write. Timeout and fail after 10ms.
243 for (int i = 0; i < 100; ++i) {
244 if (check(false))
245 break;
246 std::this_thread::sleep_for(std::chrono::microseconds(100));
247 }
248 if (!check(true))
249 throw std::runtime_error("hostmem write test failed");
250
251 writeCount = *telemetry->read().get().as<uint64_t>();
252 std::cout << "Write count: " << writeCount << std::endl;
253
254 // Check that the accelerator didn't write too far.
255 size_t widthInBytes = width / 8;
256 uint8_t *dataPtr8 = reinterpret_cast<uint8_t *>(region.getPtr());
257 for (size_t i = widthInBytes; i < 64; ++i) {
258 std::cout << "endcheck dataPtr8[" << i << "] = 0x"
259 << esi::toHex(dataPtr8[i]) << std::endl;
260 if (dataPtr8[i] != 0xFF)
261 throw std::runtime_error(
262 "hostmem write test failed -- write went too far");
263 }
264 }
265}
266
268 bool write) {
269 // Enable the host memory service.
270 auto hostmem = conn->getService<services::HostMem>();
271 hostmem->start();
272 auto scratchRegion = hostmem->allocate(/*size(bytes)=*/512, /*memOpts=*/{});
273 uint64_t *dataPtr = static_cast<uint64_t *>(scratchRegion->getPtr());
274 for (size_t i = 0; i < scratchRegion->getSize() / 8; ++i)
275 dataPtr[i] = 0;
276 scratchRegion->flush();
277
278 for (size_t width : {32, 64, 128, 256, 384, 504, 512, 513})
279 hostmemTest(acc, *scratchRegion, width, scratchRegion->getDevicePtr(), read,
280 write);
281}
282
284 size_t width) {
285 Logger &logger = conn->getLogger();
286 logger.info("esitester",
287 "== Running DMA read test with width " + std::to_string(width));
288 AppIDPath lastPath;
289 BundlePort *toHostMMIOPort = acc->resolvePort(
290 {AppID("tohostdmatest", width), AppID("ToHostDMATest")}, lastPath);
291 if (!toHostMMIOPort)
292 throw std::runtime_error("dma read test failed. No tohostdmatest[" +
293 std::to_string(width) + "] found");
294 auto *toHostMMIO = toHostMMIOPort->getAs<services::MMIO::MMIORegion>();
295 if (!toHostMMIO)
296 throw std::runtime_error("dma read test failed. MMIO port is not MMIO");
297 lastPath.clear();
298 BundlePort *outPortBundle =
299 acc->resolvePort({AppID("tohostdmatest", width), AppID("out")}, lastPath);
300 ReadChannelPort &outPort = outPortBundle->getRawRead("data");
301 outPort.connect();
302
303 size_t xferCount = 24;
304 uint64_t last = 0;
305 MessageData data;
306 toHostMMIO->write(0, xferCount);
307 for (size_t i = 0; i < xferCount; ++i) {
308 outPort.read(data);
309 if (width == 64) {
310 uint64_t val = *data.as<uint64_t>();
311 if (val < last)
312 throw std::runtime_error("dma read test failed. Out of order data");
313 last = val;
314 }
315 logger.debug("esitester",
316 "Cycle count [" + std::to_string(i) + "] = 0x" + data.toHex());
317 }
318 outPort.disconnect();
319 logger.info("esitester", "== DMA read test complete");
320}
321
323 size_t width) {
324 Logger &logger = conn->getLogger();
325 logger.info("esitester",
326 "== Running DMA write test with width " + std::to_string(width));
327 AppIDPath lastPath;
328 BundlePort *fromHostMMIOPort = acc->resolvePort(
329 {AppID("fromhostdmatest", width), AppID("FromHostDMATest")}, lastPath);
330 if (!fromHostMMIOPort)
331 throw std::runtime_error("dma read test for " + toString(width) +
332 " bits failed. No fromhostdmatest[" +
333 std::to_string(width) + "] found");
334 auto *fromHostMMIO = fromHostMMIOPort->getAs<services::MMIO::MMIORegion>();
335 if (!fromHostMMIO)
336 throw std::runtime_error("dma write test for " + toString(width) +
337 " bits failed. MMIO port is not MMIO");
338 lastPath.clear();
339 BundlePort *outPortBundle = acc->resolvePort(
340 {AppID("fromhostdmatest", width), AppID("in")}, lastPath);
341 if (!outPortBundle)
342 throw std::runtime_error("dma write test for " + toString(width) +
343 " bits failed. No out port found");
344 WriteChannelPort &writePort = outPortBundle->getRawWrite("data");
346
347 size_t xferCount = 24;
348 uint8_t *data = new uint8_t[width];
349 for (size_t i = 0; i < width / 8; ++i)
350 data[i] = 0;
351 fromHostMMIO->read(8);
352 fromHostMMIO->write(0, xferCount);
353 for (size_t i = 1; i < xferCount + 1; ++i) {
354 data[0] = i;
355 bool successWrite;
356 size_t attempts = 0;
357 do {
358 successWrite = writePort.tryWrite(MessageData(data, width / 8));
359 if (!successWrite) {
360 std::this_thread::sleep_for(std::chrono::milliseconds(10));
361 }
362 } while (!successWrite && ++attempts < 100);
363 if (!successWrite)
364 throw std::runtime_error("dma write test for " + toString(width) +
365 " bits failed. Write failed");
366 uint64_t lastReadMMIO;
367 for (size_t a = 0; a < 20; ++a) {
368 lastReadMMIO = fromHostMMIO->read(8);
369 if (lastReadMMIO == i)
370 break;
371 std::this_thread::sleep_for(std::chrono::milliseconds(10));
372 if (a >= 19)
373 throw std::runtime_error("dma write for " + toString(width) +
374 " bits test failed. Read from MMIO failed");
375 }
376 }
377 writePort.disconnect();
378 delete[] data;
379 logger.info("esitester",
380 "== DMA write test for " + toString(width) + " bits complete");
381}
382
383static void dmaTest(AcceleratorConnection *conn, Accelerator *acc, bool read,
384 bool write) {
385 bool success = true;
386 if (write)
387 for (size_t width : {32, 64, 128, 256, 384, 504, 512})
388 try {
389 dmaWriteTest(conn, acc, width);
390 } catch (std::exception &e) {
391 success = false;
392 std::cerr << "DMA write test for " << width
393 << "bits failed: " << e.what() << std::endl;
394 }
395 if (read)
396 for (size_t width : {32, 64, 128, 256, 384, 504, 512})
397 dmaReadTest(conn, acc, width);
398 if (!success)
399 throw std::runtime_error("DMA test failed");
400}
401
403 size_t width, size_t xferCount) {
404
405 AppIDPath lastPath;
406 BundlePort *toHostMMIOPort = acc->resolvePort(
407 {AppID("tohostdmatest", width), AppID("ToHostDMATest")}, lastPath);
408 if (!toHostMMIOPort)
409 throw std::runtime_error("bandwidth test failed. No tohostdmatest[" +
410 std::to_string(width) + "] found");
411 auto *toHostMMIO = toHostMMIOPort->getAs<services::MMIO::MMIORegion>();
412 if (!toHostMMIO)
413 throw std::runtime_error("bandwidth test failed. MMIO port is not MMIO");
414 lastPath.clear();
415 BundlePort *outPortBundle =
416 acc->resolvePort({AppID("tohostdmatest", width), AppID("out")}, lastPath);
417 ReadChannelPort &outPort = outPortBundle->getRawRead("data");
418 outPort.connect();
419
420 Logger &logger = conn->getLogger();
421 logger.info("esitester", "Starting bandwidth test read with " +
422 std::to_string(xferCount) + " x " +
423 std::to_string(width) + " bit transfers");
424 MessageData data;
425 auto start = std::chrono::high_resolution_clock::now();
426 toHostMMIO->write(0, xferCount);
427 for (size_t i = 0; i < xferCount; ++i) {
428 outPort.read(data);
429 logger.debug(
430 [i, &data](std::string &subsystem, std::string &msg,
431 std::unique_ptr<std::map<std::string, std::any>> &details) {
432 subsystem = "esitester";
433 msg = "Cycle count [" + std::to_string(i) + "] = 0x" + data.toHex();
434 });
435 }
436 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
437 std::chrono::high_resolution_clock::now() - start);
438 logger.info("esitester",
439 " Bandwidth test: " + std::to_string(xferCount) + " x " +
440 std::to_string(width) + " bit transfers in " +
441 std::to_string(duration.count()) + " microseconds");
442 logger.info("esitester",
443 " bandwidth: " +
444 std::to_string((xferCount * (width / 8) * 1000000) /
445 duration.count() / 1024) +
446 " kbytes/sec");
447}
448
450 size_t width, size_t xferCount) {
451
452 AppIDPath lastPath;
453 BundlePort *fromHostMMIOPort = acc->resolvePort(
454 {AppID("fromhostdmatest", width), AppID("FromHostDMATest")}, lastPath);
455 if (!fromHostMMIOPort)
456 throw std::runtime_error("bandwidth test failed. No tohostdmatest[" +
457 std::to_string(width) + "] found");
458 auto *fromHostMMIO = fromHostMMIOPort->getAs<services::MMIO::MMIORegion>();
459 if (!fromHostMMIO)
460 throw std::runtime_error("bandwidth test failed. MMIO port is not MMIO");
461 lastPath.clear();
462 BundlePort *inPortBundle = acc->resolvePort(
463 {AppID("fromhostdmatest", width), AppID("in")}, lastPath);
464 WriteChannelPort &outPort = inPortBundle->getRawWrite("data");
465 outPort.connect();
466
467 Logger &logger = conn->getLogger();
468 logger.info("esitester", "Starting bandwidth write read with " +
469 std::to_string(xferCount) + " x " +
470 std::to_string(width) + " bit transfers");
471 std::vector<uint8_t> dataVec(width / 8);
472 for (size_t i = 0; i < width / 8; ++i)
473 dataVec[i] = i;
474 MessageData data(dataVec);
475 auto start = std::chrono::high_resolution_clock::now();
476 fromHostMMIO->write(0, xferCount);
477 for (size_t i = 0; i < xferCount; ++i) {
478 outPort.write(data);
479 logger.debug(
480 [i, &data](std::string &subsystem, std::string &msg,
481 std::unique_ptr<std::map<std::string, std::any>> &details) {
482 subsystem = "esitester";
483 msg = "Cycle count [" + std::to_string(i) + "] = 0x" + data.toHex();
484 });
485 }
486 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
487 std::chrono::high_resolution_clock::now() - start);
488 logger.info("esitester",
489 " Bandwidth test: " + std::to_string(xferCount) + " x " +
490 std::to_string(width) + " bit transfers in " +
491 std::to_string(duration.count()) + " microseconds");
492 logger.info("esitester",
493 " bandwidth: " +
494 std::to_string((xferCount * (width / 8) * 1000000) /
495 duration.count() / 1024) +
496 " kbytes/sec");
497}
498
500 uint32_t xferCount,
501 const std::vector<uint32_t> &widths, bool read,
502 bool write) {
503 if (read)
504 for (size_t width : widths)
505 bandwidthReadTest(conn, acc, width, xferCount);
506 if (write)
507 for (size_t width : widths)
508 bandwidthWriteTest(conn, acc, width, xferCount);
509}
assert(baseType &&"element must be base type")
static void print(TypedAttr val, llvm::raw_ostream &os)
static void writePort(uint16_t port)
Write the port number to a file.
Definition RpcServer.cpp:37
Abstract class representing a connection to an accelerator.
Definition Accelerator.h:79
ServiceClass * getService(AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Get a typed reference to a particular service type.
Logger & getLogger() const
Definition Accelerator.h:84
Top level accelerator class.
Definition Accelerator.h:60
Services provide connections to 'bundles' – collections of named, unidirectional communication channe...
Definition Ports.h:226
T * getAs() const
Cast this Bundle port to a subclass which is actually useful.
Definition Ports.h:254
ReadChannelPort & getRawRead(const std::string &name) const
Definition Ports.cpp:35
WriteChannelPort & getRawWrite(const std::string &name) const
Get access to the raw byte streams of a channel.
Definition Ports.cpp:25
Common options and code for ESI runtime tools.
Definition CLI.h:29
Context & getContext()
Get the context.
Definition CLI.h:63
std::unique_ptr< AcceleratorConnection > connect()
Connect to the accelerator using the specified backend and connection.
Definition CLI.h:58
int esiParse(int argc, const char **argv)
Run the parser.
Definition CLI.h:46
AcceleratorConnections, Accelerators, and Manifests must all share a context.
Definition Context.h:31
BundlePort * resolvePort(const AppIDPath &path, AppIDPath &lastLookup) const
Attempt to resolve a path to a port.
Definition Design.cpp:72
const std::map< AppID, BundlePort & > & getPorts() const
Access the module's ports by ID.
Definition Design.h:76
const std::map< AppID, Instance * > & getChildren() const
Access the module's children by ID.
Definition Design.h:67
virtual void info(const std::string &subsystem, const std::string &msg, const std::map< std::string, std::any > *details=nullptr)
Report an informational message.
Definition Logging.h:75
void debug(const std::string &subsystem, const std::string &msg, const std::map< std::string, std::any > *details=nullptr)
Report a debug message.
Definition Logging.h:83
Class to parse a manifest.
Definition Manifest.h:39
A logical chunk of data representing serialized data.
Definition Common.h:103
A ChannelPort which reads data from the accelerator.
Definition Ports.h:124
virtual void connect(std::function< bool(MessageData)> callback, std::optional< unsigned > bufferSize=std::nullopt)
Definition Ports.cpp:44
virtual void disconnect() override
Definition Ports.h:129
virtual void read(MessageData &outData)
Specify a buffer to read into.
Definition Ports.h:165
A ChannelPort which sends data to the accelerator.
Definition Ports.h:77
virtual void write(const MessageData &)=0
A very basic blocking write API.
virtual void connect(std::optional< unsigned > bufferSize=std::nullopt) override
Set up a connection to the accelerator.
Definition Ports.h:82
A function call which gets attached to a service port.
Definition Services.h:304
void connect(std::function< MessageData(const MessageData &)> callback, bool quick=false)
Connect a callback to code which will be executed when the accelerator invokes the callback.
Definition Services.cpp:244
virtual void start()
In cases where necessary, enable host memory services.
Definition Services.h:232
A "slice" of some parent MMIO space.
Definition Services.h:159
Information about the Accelerator system.
Definition Services.h:100
A telemetry port which gets attached to a service port.
Definition Services.h:353
std::future< MessageData > read()
Definition Services.cpp:313
void connect()
Connect to a particular telemetry port.
Definition Services.cpp:299
static void bandwidthReadTest(AcceleratorConnection *conn, Accelerator *acc, size_t width, size_t xferCount)
static void dmaWriteTest(AcceleratorConnection *conn, Accelerator *acc, size_t width)
static void bandwidthWriteTest(AcceleratorConnection *conn, Accelerator *acc, size_t width, size_t xferCount)
static void registerCallbacks(AcceleratorConnection *, Accelerator *)
static void bandwidthTest(AcceleratorConnection *, Accelerator *, uint32_t xferCount, const std::vector< uint32_t > &widths, bool read, bool write)
static void dmaReadTest(AcceleratorConnection *conn, Accelerator *acc, size_t width)
static void hostmemTest(AcceleratorConnection *, Accelerator *, bool read, bool write)
int main(int argc, const char *argv[])
Definition esitester.cpp:44
static void dmaTest(AcceleratorConnection *, Accelerator *, bool read, bool write)
Definition esi.py:1
std::string toString(const std::any &a)
'Stringify' a std::any. This is used to log std::any values by some loggers.
Definition Logging.cpp:132
std::string toHex(void *val)
Definition Common.cpp:37
RAII memory region for host memory.
Definition Services.h:208
virtual void * getPtr() const =0
Get a pointer to the host memory.
virtual void flush()
Flush the memory region to ensure that the device sees the latest contents.
Definition Services.h:222