17#ifdef CIRCT_LIBFST_ENABLED
25#include <system_error>
36 const char *args,
ArcState *mutableState)
44 std::cout <<
"[ArcRuntime] "
48 std::cout <<
"[ArcRuntime] Model \"" <<
getModelName() <<
"\"";
49 if (hasTraceInstrumentation)
50 std::cout <<
" has trace instrumentation." << std::endl;
52 std::cout <<
" does not have trace instrumentation." << std::endl;
57 <<
"[ArcRuntime] WARNING: "
58 <<
"Tracing has been requested but model \"" <<
getModelName()
59 <<
"\" contains no instrumentation."
60 <<
" No trace will be produced.\n\t\tMake sure to compile the model"
61 " with tracing enabled and that it contains observed signals."
64 if (hasTraceInstrumentation) {
68 std::make_unique<DummyTraceEncoder>(
modelInfo, mutableState);
75#ifdef CIRCT_LIBFST_ENABLED
79 std::cerr <<
"[ArcRuntime] ERROR: FST tracing was requested but CIRCT "
80 "was not built with FST support (CIRCT_LIBFST_ENABLED=OFF)."
83 std::make_unique<DummyTraceEncoder>(
modelInfo, mutableState);
94 std::cout <<
"[ArcRuntime] "
95 <<
"Deleting instance"
98 <<
" step(s)" << std::endl;
100 assert(
state->
impl ==
static_cast<void *
>(
this) &&
"Inconsistent ArcState");
108 if (it !=
arguments.end() && it->second.has_value())
109 return workDir / std::filesystem::path(*it->second);
111 std::string saneName;
114 for (
auto &c : saneName) {
115 if (c ==
' ' || c ==
'/' || c ==
'\\')
121 return workDir / std::filesystem::path(saneName);
137 std::cout <<
"[ArcRuntime] "
138 <<
"Instance with ID " <<
instanceID <<
" initialized"
146 "swapTraceBuffer called on model without trace instrumentation");
148 std::cout <<
"[ArcRuntime] Consuming trace buffer of size "
159static std::map<std::string, std::optional<std::string>>
161 std::map<std::string, std::optional<std::string>> result;
163 enum class State { Key, AfterEq, Unquoted, Quoted, Escape, AfterQuote, Skip };
164 State state = State::Key;
168 bool hasValue =
false;
170 auto warn = [&](
const char *msg) {
171 std::cerr <<
"[ArcRuntime] WARNING: Malformed runtime argument: " << msg;
173 std::cerr <<
" for key \"" << key <<
"\"";
174 std::cerr <<
", ignoring\n";
178 result[std::move(key)] =
179 hasValue ? std::optional(std::move(value)) : std::nullopt;
186 auto skipToNext = [&] {
193 for (
size_t i = 0; i <= argStr.size(); ++i) {
194 const bool atEnd = (i == argStr.size());
195 const char c = atEnd ?
'\0' : argStr[i];
199 if (atEnd || c ==
';') {
202 }
else if (std::isgraph(
static_cast<unsigned char>(c)) && c !=
'"' &&
205 }
else if (c ==
'=' && !key.empty()) {
207 state = State::AfterEq;
215 if (c ==
'"' && !atEnd) {
216 state = State::Quoted;
217 }
else if (atEnd || c ==
';') {
221 state = State::Unquoted;
225 case State::Unquoted:
226 if (atEnd || c ==
';') {
228 }
else if (c ==
'"') {
229 warn(
"Unquoted value contains forbidden character '\"'");
238 warn(
"Unterminated quoted value");
240 }
else if (c ==
'"') {
241 state = State::AfterQuote;
242 }
else if (c ==
'\\') {
243 state = State::Escape;
251 warn(
"Truncated escape sequence in quoted value");
253 }
else if (c ==
'"' || c ==
'\\') {
255 state = State::Quoted;
257 warn(
"Invalid escape sequence in quoted value");
262 case State::AfterQuote:
263 if (atEnd || c ==
';') {
266 warn(
"Unexpected content after closing quote");
272 if (!atEnd && c ==
';')
284 auto argStr = std::string_view(args);
291 std::cout <<
"[ArcRuntime] Argument string for instance ID " <<
instanceID
292 <<
": " << argStr << std::endl;
293 std::cout <<
"[ArcRuntime] Parsed argument(s):" << std::endl;
294 for (
const auto &[key, value] :
arguments) {
295 std::cout <<
"[ArcRuntime] " << key;
296 if (value.has_value())
297 std::cout <<
" = \"" << *value <<
"\"";
298 std::cout << std::endl;
305 workDir = std::filesystem::current_path(ec);
307 std::cerr <<
"[ArcRuntime] WARNING: Could not determine current working "
309 << ec.message() << std::endl;
313 if (workDirIt !=
arguments.end() && workDirIt->second.has_value()) {
318 std::filesystem::create_directories(
workDir, ec);
320 std::cerr <<
"[ArcRuntime] WARNING: Could not create working directory \""
321 <<
workDir.string() <<
"\": " << ec.message() << std::endl;
325 std::cout <<
"[ArcRuntime] Working directory for instance ID " <<
instanceID
326 <<
": " <<
workDir.string() << std::endl;
assert(baseType &&"element must be base type")
std::filesystem::path getTraceFilePath(const std::string &suffix)
Get the path to the output trace file.
static const std::string kArgKeyTraceFile
Workdir-relative or absolute path to trace file.
void onEval(ArcState *mutableState)
void parseArgs(const char *args)
Parse and initialize the instance settings from the given argument string.
static const std::string kArgKeyDebug
Enable verbose debug output.
static const std::string kArgKeyVcd
Select VCD trace mode.
std::unique_ptr< TraceEncoder > traceEncoder
std::map< std::string, std::optional< std::string > > arguments
std::filesystem::path workDir
The path to the instance's working directory.
const ArcState *const state
const uint64_t instanceID
static const std::string kArgKeyFst
Select FST trace mode.
void onInitialized(ArcState *mutableState)
static const std::string kArgKeyWorkDir
Instance's working directory. Absolute or relative to process workdir.
const char * getModelName() const
uint64_t * swapTraceBuffer()
const ArcRuntimeModelInfo *const modelInfo
static std::map< std::string, std::optional< std::string > > parseArgsToMap(std::string_view argStr)
static void fatalError(const char *message)
Raise an irrecoverable error.
static uint64_t instanceIDsGlobal
Static information for a compiled hardware model, generated by the MLIR lowering.
struct ArcModelTraceInfo * traceInfo
Signal tracing information. NULL iff the model is not trace instrumented.
const char * modelName
Name of the compiled model.
Combined runtime and model state for a hardware model instance.
void * impl
Runtime implementation specific data. Usually points to a custom struct.
uint32_t traceBufferSize
Number of valid elements in the active trace buffer.