|
| enum class | LogType {
Resource
, Execution
, Internal
, All
,
NumLogType = All
} |
| |
| enum class | LogLevel { Error
, Info
, Debug
} |
| |
| enum class | LogDetail { None
, TimeStamp
, CodeLocation
, All
} |
| |
| enum class | LogOutput { Stdout
, Stderr
, File
} |
| |
| enum class | ArgDir : unsigned char { InOut
, Input
, Output
} |
| |
| enum class | ExecuteStatus {
Idle = 0
, HostInit
, DeviceInit
, Request
,
Waiting
, DeviceFinalize
, HostFinalize
, Fail
,
Cancelled
, Completed
, Max
} |
| |
| enum class | ArgType { Constant
, DeviceMemory
, NDArray
} |
| |
| enum class | Result {
Success = 0
, Failure
, Pending
, InvalidArgument
,
DeviceError
, NotFound
, Timeout
, NotSupported
,
NotInitialized
, Cancelled
, Internal
, Count
} |
| |
| enum class | DeviceAttr {
InfiniteMemory
, NumClusterPerSub
, NumMuCorePerCluster
, TotalSubCount
,
CxlMemoryCapacity
, MappingGranularity
} |
| |
| enum class | LocalityMode : uint32_t { CompactMode = 0
, SpreadMode
} |
| |
|
| void | enableLog (const LogType &type, const LogLevel &level=LogLevel::Error, const LogDetail &detail=LogDetail::None) |
| | Configures logging settings for a specific log type. More...
|
| |
| void | disableLog (const LogType &type) |
| | Disables logging for a specific log type. More...
|
| |
| void | setOutput (const LogOutput &outputType, const char *filename=nullptr) |
| | Sets the output destination for log messages. More...
|
| |
| void | registerSignalHandler (int32_t signalType) |
| | Registers a signal handler for a specific signal type. More...
|
| |
| void | registerSignalHandler (const std::initializer_list< int32_t > &signalLists) |
| | Registers signal handlers for multiple signal types. More...
|
| |
| void | flushHostCache (void *hostVirtualPtr, size_t size, bool opt=true) |
| | Flushes the host CPU cache for the specified memory range and records the range as written. More...
|
| |
| void | flushHostCacheUntracked (void *hostVirtualPtr, size_t size, bool opt=true) |
| | Flushes the host CPU cache, and nothing else. More...
|
| |
| void | invalidateHostCache (void *hostVirtualPtr, size_t size) |
| | Drops host cache lines over the range so a later read sees what the device wrote. More...
|
| |
| uint32_t | getNumDevice () |
| | Retrieves the number of available devices. More...
|
| |
| uint32_t | availableSubCount (uint32_t deviceId) |
| | Returns the number of currently available compute resources (Subs) on a device, without creating a Context. More...
|
| |
| std::optional< uint32_t > | getDefaultDeviceId () |
| | Returns the current process-wide default device ID. More...
|
| |
| void | clearDefaultDeviceId () |
| | Clears the cached default device ID. More...
|
| |
| Context * | createContext () |
| | Creates a context. Defaults to the first available device. More...
|
| |
| Context * | createContext (uint32_t deviceId) |
| | Creates a context for the specified device ID. More...
|
| |
| void | destroyContext (Context *context) |
| | Destroys the specified context. More...
|
| |
| Module * | createModule (const char *muBinaryPath) |
| | Creates a Module object from the specified MU binary path. More...
|
| |
| Module * | createModule (const void *image) |
| | Creates a Module object from the specified MU binary image. More...
|
| |
| Module * | createModule () |
| | Creates a Module from the embedded kernel binary. More...
|
| |
| void | destroyModule (Module *module) |
| | Destroys the specified Module object. More...
|
| |
| void | registerKernelBinary (const void *start, const void *end) |
| | Registers an embedded kernel binary for automatic loading. More...
|
| |
| bool | enableProfiling (const xpti::ProfileConfig &cfg) |
| |
| void | disableProfiling () |
| |
| bool | isProfilingEnabled () |
| |
| Stream * | createStream () |
| | Creates a stream. More...
|
| |
| void | destroyStream (Stream *stream) |
| | Destroys a stream. More...
|
| |
| const char * | resultString (Result result) noexcept |
| |
| void pxl::destroyContext |
( |
Context * |
context | ) |
|
Destroys the specified context.
- Parameters
-
| context | Pointer to the context to be destroyed. |
Teardown waits for every Job's outstanding work. When called from a Map callback or createJobForceAsync() callback, this function cannot safely wait for that work. Instead, it retains the context and returns without destroying it.
A retained context keeps its Jobs, Subs, device memory, and stream slot. Its in-flight work continues, and callbacks may still run after this function returns. Keep all callback state alive until every Map has completed.
To release the context deterministically, call destroyContext() again from a thread that can wait. Otherwise, the next createContext() or destroyContext() call resumes the deferred teardown. If neither is called, library teardown resumes it. Do not use the context in the meantime. A call that resumes teardown may block until all of the retained context's work has completed.
- Warning
- Library teardown cannot defer retained contexts again. When it runs on a callback-delivery thread, it skips all Context and device cleanup and leaves those resources allocated until process exit.
Example usage:
void destroyContext(Context *context)
Destroys the specified context.
| void pxl::destroyStream |
( |
Stream * |
stream | ) |
|
Destroys a stream.
- Parameters
-
| stream | Pointer to the stream to be destroyed. |
This function detaches the stream's consumer thread instead of joining it when the join would wait for work that the calling thread itself must deliver. This applies when called from the consumer thread, where this Stream's Map completion and error callbacks run, or from a frame that delivers a callback without publishing its own completion: a Map message callback or a createJobForceAsync() callback. All other callers join the consumer. This includes a completion or error callback that destroys a different Stream and an error callback invoked on the caller's thread when execute() fails to start.
After a detach, work already in the queue continues, and its callbacks may run after this function returns. The stream ID becomes available for reuse immediately, so createStream() may assign the same ID to a new Stream while the detached consumer is still draining. Creating another Stream before every Map on the destroyed Stream has completed is not supported. Keep callback state alive until all of that work has completed.
Example usage:
void destroyStream(Stream *stream)
Destroys a stream.
| void pxl::flushHostCacheUntracked |
( |
void * |
hostVirtualPtr, |
|
|
size_t |
size, |
|
|
bool |
opt = true |
|
) |
| |
Flushes the host CPU cache, and nothing else.
The same cache operation as flushHostCache() without the record it keeps.
- Note
- On real hardware this is the variant a signal handler may call. flushHostCache() reaches a process-wide registry to note the range, and that registry is mutex-protected – taking a lock from a handler can deadlock against the code the signal interrupted. This one skips the registry and reduces to a CLFLUSHOPT loop plus a fence, and it is deliberately left out of the public-API tracing, because that tracing takes a lock and allocates when it is switched on.
- Warning
- Under the emulator the cache operation is an ioctl instead, and the host address has to be translated for it. That translation goes through MemoryLibrary::isManaged(), which takes the allocation map's mutex on every call – not just the first. A handler that calls this while the interrupted code was inside that lookup re-acquires a non-recursive mutex on its own thread and sleeps forever.
Measured on the emulator: it deadlocks, and it does so whatever the range is – the lock sits in front of the managed/unmanaged decision, so even an address this library never allocated hangs. So there is no signal-safe way to publish a host write there yet, and the warm-up below does not create one; it only removes the first-call cost. This is tracked, not settled: see issue #580. Do not read the paragraph above as the intended end state.
Call it once on the normal path before relying on it from a handler. This is not an emulator-only step: the platform check in front of the cache operation resolves a singleton on first use, and that construction reads a sysfs file through std::ifstream, so the first call allocates on real hardware too. Every call after it is the CLFLUSHOPT loop alone.
Also the one to prefer on any path that runs repeatedly, for a second reason: flushHostCache()'s record is removed only when a Map::execute() claims it as covering an argument, so a caller that flushes in a loop without executing again grows that registry for the life of the process.
- Parameters
-
| hostVirtualPtr | Pointer to the start of the memory range. |
| size | Size of the memory range in bytes. |
| opt | Enable optimized flushing (default: true). |
- Note
- This recipe assumes your own handler. registerSignalHandler() installs one that reports and exits instead of setting a flag, and std::signal keeps one handler per signal, so registering it for the same signal replaces this.
Example usage:
control->stop = 1;
void flushHostCacheUntracked(void *hostVirtualPtr, size_t size, bool opt=true)
Flushes the host CPU cache, and nothing else.
| std::optional<uint32_t> pxl::getDefaultDeviceId |
( |
| ) |
|
Returns the current process-wide default device ID.
The default device is updated implicitly by successful explicit-device API calls (e.g. allocateMemory(deviceId, ...), createContext(deviceId), Launcher(deviceId)) and consumed by auto-device API calls (allocateMemory(size_t), createContext(), Launcher()).
- Returns
- The current default device ID, or std::nullopt if none has been set.
| void pxl::invalidateHostCache |
( |
void * |
hostVirtualPtr, |
|
|
size_t |
size |
|
) |
| |
Drops host cache lines over the range so a later read sees what the device wrote.
The counterpart to flushHostCache(): that one publishes host writes to the device, this one lets the host observe device writes. Needed to read a value the device produced — a completion counter the kernel bumps, for instance. A flush is not a substitute: on the QEMU device model the two are different ioctls, and flushing there leaves the host reading its own stale line.
- Warning
- The range must hold no dirty host lines — either the device is its only writer, or the host flushed it and has not touched it since. On x86 CLFLUSHOPT writes a dirty line back before invalidating it, so a dirty line here overwrites the device's data.
The operation is widened to whole cache lines, so keep a device-written field on its own cache line if the host writes anything adjacent. A size of 0 is a no-op for the same reason: widening an empty range would reach a line the caller asked nothing about, and the warning above applies to that line too.
- Note
- Returns void, like the two flushes beside it, and on real hardware that loses nothing: the call is a CLFLUSHOPT loop with no failure mode. Under the emulator it can be skipped whole — /dev/xcena_cache not open, or the address not one this library allocated — and the caller then reads a stale line with no way to tell from the call. The error log is the only signal there, so check it before trusting a device-written value read back under the emulator.
- Parameters
-
| hostVirtualPtr | Pointer to the start of the memory range. |
| size | Size of the memory range in bytes. |
Example usage:
const uint32_t done = control->doneCount;
void invalidateHostCache(void *hostVirtualPtr, size_t size)
Drops host cache lines over the range so a later read sees what the device wrote.