hipDNN backend C API#
2026-03-31
16 min read time
hipDNN Backend C API
This file defines the public C API for hipDNN backend operations. The backend provides handle management, descriptor operations, and execution of computational graphs.
Basic Usage#
Create a handle:
hipdnnHandle_t handle; hipdnnCreate(&handle);
Create and configure descriptors:
hipdnnBackendDescriptor_t graphDesc; hipdnnBackendCreateAndDeserializeGraph_ext(&graphDesc, serializedGraph, size);
Execute operations:
hipdnnBackendExecute(handle, executionPlan, variantPack);
Clean up:
hipdnnBackendDestroyDescriptor(graphDesc); hipdnnDestroy(handle);
See also
hipdnn_frontend.hpp for the C++ frontend API
Typedefs
-
typedef struct hipdnnHandle *hipdnnHandle_t#
Creates the hipdnnHandle_t type.
-
typedef struct HipdnnBackendDescriptor *hipdnnBackendDescriptor_t#
Creates the hipdnnBackendDescriptor_t type.
Enums
Functions
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnCreate (hipdnnHandle_t *handle)
Creates a hipdnnHandle_t.
- Parameters:
handle – [in] An instance of hipdnnHandle_t
- Return values:
HIPDNN_STATUS_SUCCESS – The creation was successful
HIPDNN_STATUS_BAD_PARAM – The descriptor is not a valid (NULL) descriptor.
HIPDNN_STATUS_ALLOC_FAILED – The memory allocation failed when creating handle object.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnDestroy (hipdnnHandle_t handle)
Destroyes hipdnnHandle_t.
- Parameters:
handle – [in] An instance of hipdnnHandle_t
- Return values:
HIPDNN_STATUS_BAD_PARAM – The descriptor is not a valid (NULL) descriptor.
HIPDNN_STATUS_SUCCESS – The destruction was successful
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnSetStream (hipdnnHandle_t handle, hipStream_t streamId)
Sets the stream for the hipdnnHandle_t.
- Parameters:
handle – [in] An instance of hipdnnHandle_t
streamId – [in] The stream to be set
- Return values:
HIPDNN_STATUS_BAD_PARAM – invalid (NULL) handle.
HIPDNN_STATUS_SUCCESS – The creation was successful
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnGetStream (hipdnnHandle_t handle, hipStream_t *streamId)
Retrieves the HIP stream associated with the specified hipDNN handle.
Note
The handle must be valid and initialized before calling this function.
The streamId pointer must not be null.
This function uses a try-catch mechanism to handle exceptions internally.
- Parameters:
handle – [in] The hipDNN handle whose associated stream is to be retrieved.
streamId – [out] Pointer to a hipStream_t where the associated stream ID will be stored upon successful execution.
- Return values:
HIPDNN_STATUS_BAD_PARAM – invalid (NULL) handle.
HIPDNN_STATUS_SUCCESS – The creation was successful
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendCreateDescriptor (hipdnnBackendDescriptorType_t descriptorType, hipdnnBackendDescriptor_t *descriptor)
Creates a backend descriptor.
Allocates memory for a given descriptorType at the location pointed by the descriptor
- Parameters:
descriptorType – [in] One among the enumerated hipdnnBackendDescriptor_t
descriptor – [out] Pointer to a descriptor
- Return values:
HIPDNN_STATUS_SUCCESS – The creation was successful
HIPDNN_STATUS_NOT_SUPPORTED – Creating a descriptor of a given type is not supported.
HIPDNN_STATUS_ALLOC_FAILED – The memory allocation failed.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendDestroyDescriptor (hipdnnBackendDescriptor_t descriptor)
Destroys an instance of hipdnnBackendDescriptor_t.
Destroys instances of hipdnnBackendDescriptor_t that were previously created using hipdnnBackendCreateDescriptor(). The value pointed by the descriptor will be undefined after the memory is free and done.
Undefined Behavior if the descriptor was altered between the ‘Create’ and ‘Destroy Descriptor’
- Parameters:
descriptor – [in] Instance of hipdnnBackendDescriptor_t previously created by hipdnnBackendCreateDescriptor()
- Return values:
HIPDNN_STATUS_SUCCESS – The memory was destroyed successfully
HIPDNN_STATUS_ALLOC_FAILED – The destruction of memory failed.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendExecute (hipdnnHandle_t handle, hipdnnBackendDescriptor_t executionPlan, hipdnnBackendDescriptor_t variantPack)
Executes a graph.
Executes the given engine_configuration_plan on the variantPack and the finalized executionPlan on the data. The data and the working space are encapsulated in the variantPack.
- Parameters:
handle – [in] An instance of hipdnnHandle_t
executionPlan – [in] Descriptor of the finalized executionPlan
variantPack – [in] Descriptor of the finalized variantPack consisting of:
Data pointer for each non-virtual pointer of the operation set in the execution plan.
Pointer to user-allocated workspace in global memory at least as large as the size queried
- Return values:
HIPDNN_STATUS_SUCCESS – The executionPlan was executed successfully
HIPDNN_STATUS_BAD_PARAM – An incorrect or inconsistent value is encountered. For example, a required data pointer is invalid.
HIPDNN_STATUS_INTERNAL_ERROR – Some internal errors were encountered.
HIPDNN_STATUS_EXECUTION_FAILED – An error was encountered executing the plan with the variantPack.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendFinalize (hipdnnBackendDescriptor_t descriptor)
Finalizes a backend descriptor.
Finalizes the memory pointed to by the descriptor. The type of finalization is done depending on the descriptor_type argument with which the descriptor was created using hipdnnBackendCreateDescriptor() or initialized using hipdnnBackendInitialize().
- Parameters:
descriptor – [in] Instance of hipdnnBackendDescriptor_t to finalize
- Return values:
HIPDNN_STATUS_SUCCESS – The descriptor was finalized successfully
HIPDNN_STATUS_BAD_PARAM – Invalid descriptor attribute values or combination thereof is encountered.
HIPDNN_STATUS_NOT_SUPPORTED – Descriptor attribute values or combinations therefore not supported by the current version of hipDNN are encountered.
HIPDNN_STATUS_INTERNAL_ERROR – Some internal errors are encountered.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendGetAttribute (hipdnnBackendDescriptor_t descriptor, hipdnnBackendAttributeName_t attributeName, hipdnnBackendAttributeType_t attributeType, int64_t requestedElementCount, int64_t *elementCount, void *arrayOfElements)
Retrieves backend descriptor’s attribute.
This function retrieves the values of an attribute of a descriptor. attributeName is the name of the attribute whose value is requested. attributeType is the type of attribute. requestedElementCount is the number of elements to be potentially retrieved. The number of elements for the requested attribute is stored in elementCount. The retrieved values are stored in arrayOfElements. When the attribute is expected to have a single value, arrayOfElements can be pointer to the output value. This function will return HIPDNN_STATUS_NOT_INTIALIZED if the descriptor has not been successfully finalized using hipdnnBackendFinalize()
- Parameters:
descriptor – [in] Instance of hipdnnBackendDescriptor_t whose attribute to retrieve
attributeName – [in] The name of the attribute being get from the descriptor
attributeType – [in] The type of attribute
requestedElementCount – [in] Number of elements to output to arrayOfElements
elementCount – [out] Output pointer for the number of elements the descriptor attribute has. Note that hipdnnBackendGetAttribute() will only write the least of this and requestedElementCount elements to arrayOfElements
arrayOfElements – [out] Array of elements of the datatype of the attributeType. The data type of the attributeType is listed in the mapping table of hipdnnBackendAttributeType_t
- Return values:
HIPDNN_STATUS_SUCCESS – The attributeName was retrieved from the descriptor successfully
HIPDNN_STATUS_BAD_PARAM – One or more invalid or inconsistent argument values were encountered. Some examples include: attributeName is not a valid attribute for the descriptor. attributeType is not one of the valid types for the attribute.
HIPDNN_STATUS_NOT_INITIALIZED – The descriptor has not been successfully finalized using hipdnnBackendFinalize().
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendSetAttribute (hipdnnBackendDescriptor_t descriptor, hipdnnBackendAttributeName_t attributeName, hipdnnBackendAttributeType_t attributeType, int64_t elementCount, const void *arrayOfElements)
Sets an attribute of a descriptor.
This function sets an attribute of a descriptor to values provided as a pointer. descriptor is the descriptor to be set. attributeName is the name of the attribute to be set. attributeType is the type of attribute. The value to which the attribute is set, is pointed by the arrayOfElements. The number of elements is given by elementCount. This function will return HIPDNN_STATUS_NOT_INITIALIZED if the descriptor is already successfully finalized using hipdnnBackendFinalize().
- Parameters:
descriptor – [in] Instance of hipdnnBackendDescriptor_t whose attribute is being set
attributeName – [in] The name of the attribute being set on the descriptor
attributeType – [in] The type of attribute
elementCount – [in] Number of elements being set
arrayOfElements – [in] The starting location for an array from where to read the values from. The elements of the array are expected to be of the datatype of the attributeType. The datatype of the attributeType is listed in the mapping table of hipdnnBackendAttributeType_t.
- Return values:
HIPDNN_STATUS_SUCCESS – The attributeName was set to the descriptor
HIPDNN_STATUS_NOT_INITIALIZED – The backend descriptor pointed to by the descriptor is already in the finalized state.
HIPDNN_STATUS_BAD_PARAM – The function is called with arguments that correspond to invalid values. Some examples include: attributeName is not a settable attribute of descriptor. attributeType is incorrect for this attributeName. elementCount value is unexpected. arrayOfElements contains values invalid for the attributeType.
HIPDNN_STATUS_NOT_SUPPORTED – The values to which the attributes are being set are not supported by the current version of hipDNN.
- HIPDNN_BACKEND_EXPORT const char * hipdnnGetErrorString (hipdnnStatus_t status)
Converts the hipDNN status code to a NULL terminated static string.
This function takes a hipdnnStatus_t status code and returns a pointer to a static, NULL-terminated string describing the error or status.
- Parameters:
status – The hipDNN status code to convert.
- Returns:
A pointer to a static, NULL-terminated string describing the status.
- HIPDNN_BACKEND_EXPORT void hipdnnGetLastErrorString (char *message, size_t maxSize)
Retrieves the last error message for the calling thread.
This function copies the last error message associated with the calling thread into the provided message buffer, up to max_size bytes (including the null terminator). Note the max size for an error message is HIPDNN_ERROR_STRING_MAX_LENGTH characters.
After retrieving the error message, this function clears the internal error state. Use hipdnnPeekLastErrorString_ext() if you need to retrieve the error without clearing it.
- Parameters:
message – [out] Pointer to a character buffer where the error message will be copied.
maxSize – [in] Maximum number of bytes to copy, including the null terminator.
- HIPDNN_BACKEND_EXPORT void hipdnnPeekLastErrorString_ext (char *message, size_t maxSize)
Retrieves the last error message for the calling thread without clearing it.
This function copies the last error message associated with the calling thread into the provided message buffer, up to max_size bytes (including the null terminator). Note the max size for an error message is HIPDNN_ERROR_STRING_MAX_LENGTH characters.
Unlike hipdnnGetLastErrorString(), this function does NOT clear the internal error state after retrieval. This preserves the pre-existing behavior for cases where the error needs to be queried multiple times.
- Parameters:
message – [out] Pointer to a character buffer where the error message will be copied.
maxSize – [in] Maximum number of bytes to copy, including the null terminator.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendCreateAndDeserializeGraph_ext (hipdnnBackendDescriptor_t *descriptor, const uint8_t *serializedGraph, size_t graphByteSize)
Creates and deserializes a graph into a backend descriptor.
This function creates a backend descriptor and deserializes a graph from a serialized byte array into the descriptor. The serialized graph is provided as an input byte array, and the size of the graph in bytes is specified. The created descriptor will encapsulate the deserialized graph.
IMPORTANT: Hipdnn expects that the serialized graph is sorted in topological order, has no cycles, and is fully connected (no orphan nodes). Additionally, all tensors in the graph must have unique uids.
- Parameters:
descriptor – [out] Pointer to a backend descriptor where the deserialized graph will be stored.
serializedGraph – [in] Pointer to the serialized graph data in a byte array.
graphByteSize – [in] Size of the serialized graph in bytes.
- Return values:
HIPDNN_STATUS_SUCCESS – The graph was successfully deserialized and stored in the descriptor.
HIPDNN_STATUS_BAD_PARAM – Invalid or inconsistent parameter values were encountered, such as:
descriptor is null.
serializedGraph is null.
graphByteSize is zero.
HIPDNN_STATUS_ALLOC_FAILED – Memory allocation for the descriptor or graph failed.
HIPDNN_STATUS_INTERNAL_ERROR – An internal error occurred during deserialization.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendGetSerializedBinaryGraph_ext (hipdnnBackendDescriptor_t descriptor, size_t requestedByteSize, size_t *graphByteSize, uint8_t *serializedGraph)
Retrieves the binary-serialized graph from a finalized operation graph descriptor.
Uses the standard two-call pattern: call first with
serializedGraphset tonullptrto query the required buffer size, then call again with a caller-allocated buffer to receive the data. The descriptor must be of type HIPDNN_BACKEND_OPERATIONGRAPH_DESCRIPTOR and must be finalized.- Parameters:
descriptor – [in] A finalized operation graph descriptor.
requestedByteSize – [in] Size of the caller-allocated buffer in bytes. Ignored when
serializedGraphisnullptr.graphByteSize – [out] Pointer to receive the size of the serialized graph in bytes. Always written on success.
serializedGraph – [out] Caller-allocated buffer to receive the serialized graph data, or
nullptrto query the required size only.
- Return values:
HIPDNN_STATUS_SUCCESS – The serialized graph was successfully retrieved, or the size query completed successfully.
HIPDNN_STATUS_BAD_PARAM_NULL_POINTER – descriptor or graphByteSize is null.
HIPDNN_STATUS_BAD_PARAM – The descriptor is not an operation graph descriptor.
HIPDNN_STATUS_BAD_PARAM_NOT_FINALIZED – The descriptor is not finalized.
HIPDNN_STATUS_BAD_PARAM_SIZE_INSUFFICIENT – The requestedByteSize is smaller than the serialized graph size.
HIPDNN_STATUS_INTERNAL_ERROR – An internal error occurred during serialization.
- HIPDNN_BACKEND_EXPORT void hipdnnLoggingCallback_ext (hipdnnSeverity_t severity, const char *msg)
Callback function for logging messages.
This function is called by the hipDNN library to log messages. The severity level of the message is provided along with the message itself.
- Parameters:
severity – [in] The severity level of the message.
msg – [in] The message to be logged.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnSetEnginePluginPaths_ext (size_t numPaths, const char *const *pluginPaths, hipdnnPluginLoadingMode_ext_t loadingMode)
Sets the search paths for hipDNN engine plugins.
This function configures the search paths for engine plugins and must be called before creating a hipDNN handle, as plugins are loaded during handle creation.
Paths can be either directories or specific plugin files. Relative paths are resolved from the location of the libhipdnn_backend.so file. The backend can resolve platform-agnostic names, allowing users to omit prefixes like
liband extensions like.soor.dll.- Parameters:
numPaths – [in] The number of paths in the
pluginPathsarray.pluginPaths – [in] An array of relative or absolute path strings.
loadingMode – [in] Specifies whether to add paths to or replace the default search paths.
- Return values:
HIPDNN_STATUS_SUCCESS – The operation was successful.
HIPDNN_STATUS_BAD_PARAM_NULL_POINTER –
pluginPathsis nullptr whennumPathsis greater than 0.HIPDNN_STATUS_NOT_SUPPORTED – Called with active handle.
HIPDNN_STATUS_INTERNAL_ERROR – An internal error occurred.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnSetPluginUnloadMode_ext (hipdnnPluginUnloadingMode_ext_t unloadingMode)
Sets the plugin unloading mode for hipDNN.
This function controls when plugins are unloaded from memory. By default, lazy unloading (HIPDNN_PLUGIN_UNLOAD_LAZY) is used, which keeps plugins loaded until the application exits or until hipdnnSetEnginePluginPaths_ext is called. This avoids expensive plugin reloading when handles are frequently created and destroyed.
This function can be called at any time. When switching from lazy to eager mode (HIPDNN_PLUGIN_UNLOAD_EAGER) while no handles exist, plugins will be unloaded immediately.
- Parameters:
unloadingMode – [in] Specifies when plugins should be unloaded from memory.
- Return values:
HIPDNN_STATUS_SUCCESS – The operation was successful.
HIPDNN_STATUS_BAD_PARAM – An invalid unloading mode was specified.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnGetLoadedEnginePluginPaths_ext (hipdnnHandle_t handle, size_t *numPluginPaths, char **pluginPaths, size_t *maxStringLen)
Gets file paths of loaded engine plugins for a given handle.
This function must be called twice:
First call: Pass
pluginPathsasnullptrto query the number of plugins and required buffer size.Sets
numPluginPathsto the total number of loaded pluginsSets
maxStringLento the maximum string length needed (including null terminator)
Second call: Pass allocated buffers to retrieve the actual plugin paths.
Allocate an array of
numPluginPathschar pointersEach char pointer should point to a buffer of at least
maxStringLencharactersThe function will populate these buffers with the plugin paths
- Parameters:
handle – [in] A valid hipDNN handle
numPluginPaths – [inout] Pointer to number of plugins; updated with actual count.
pluginPaths – [out] Array of character pointers for plugin paths, or
nullptrto query sizes.maxStringLen – [inout] Pointer to max string length; updated with required length.
- Return values:
HIPDNN_STATUS_SUCCESS – Success.
HIPDNN_STATUS_BAD_PARAM – Invalid handle, null pointers, or insufficient buffer sizes.
HIPDNN_STATUS_INTERNAL_ERROR – Internal error.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnSetUserLogCallback_ext (hipdnnUserLogCallback_t callback, hipdnnSeverity_t minLevel, hipdnnLogCallbackMode_t mode, hipdnnUserLogCallbackHandle_t userHandle)
Set or update a user log callback.
This API allows registering multiple user callbacks with individual log levels and sync/async modes. Each callback is uniquely identified by the composite key (callback, userHandle).
Behavior:
If (callback, userHandle) already registered: UPDATES settings (level and/or sync/async mode)
If (callback, userHandle) new: ADDS new registration
If minLevel == SEV_OFF: REMOVES registration
userHandle must be non-null
Callback Removal (minLevel == SEV_OFF):
No further logs will be received on the callback.
Any pending async logs for this callback will be abandoned
After this function returns, user can safely destroy data referenced by userHandle
Note
When a synchronous callback is registered, the synchronous callbacks will delay hipDNN until the callback returns, regardless of any async log callbacks also being registered. Synchronous callbacks are recommended only for debugging or testing purposes due to their blocking nature. Use async callbacks for production workloads.
- Parameters:
callback – [in] The callback function to invoke
minLevel – [in] Minimum severity level (SEV_OFF removes the callback). Note that the logs produced on this callback will be limited by the global log level set either by the HIPDNN_LOG_LEVEL environment variable or the setGlobalLogLevel() API function.
mode – [in] Sync or async invocation mode
userHandle – [in] Non-null user data (also serves as unique callback ID)
- Return values:
HIPDNN_STATUS_SUCCESS – The callback was set/updated/removed successfully
HIPDNN_STATUS_BAD_PARAM – callback is NULL, userHandle is NULL, invalid mode, or attempting to remove non-existent callback
HIPDNN_STATUS_NOT_INITIALIZED – Logging system not initialized
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendSetGlobalLogLevel_ext (hipdnnSeverity_t level)
Set the global log level for the backend.
This controls which log messages are output to console/file AND to the global backend log output callback. Valid levels: HIPDNN_SEV_INFO, HIPDNN_SEV_WARN, HIPDNN_SEV_ERROR, HIPDNN_SEV_FATAL, HIPDNN_SEV_OFF.
- Parameters:
level – [in] The severity level to set
- Return values:
HIPDNN_STATUS_SUCCESS – The log level was set successfully
HIPDNN_STATUS_BAD_PARAM – Invalid log level
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnBackendGetGlobalLogLevel_ext (hipdnnSeverity_t *level)
Get the global log level for the backend.
- Parameters:
level – [out] Pointer to store the current log level
- Return values:
HIPDNN_STATUS_SUCCESS – The log level was retrieved successfully
HIPDNN_STATUS_BAD_PARAM – level pointer is NULL
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnGetEngineCount_ext (hipdnnHandle_t handle, size_t *numEngines)
Gets the number of loaded engines for a given handle.
- Parameters:
handle – [in] A valid hipDNN handle.
numEngines – [out] Pointer where the engine count will be stored.
- Return values:
HIPDNN_STATUS_SUCCESS – Success.
HIPDNN_STATUS_BAD_PARAM – Invalid handle or null pointer.
HIPDNN_STATUS_INTERNAL_ERROR – Internal error.
- HIPDNN_BACKEND_EXPORT hipdnnStatus_t hipdnnGetEngineInfo_ext (hipdnnHandle_t handle, size_t engineIndex, int64_t *engineId, char *engineName, size_t *engineNameLen, char *pluginName, size_t *pluginNameLen, char *version, size_t *versionLen, char *type, size_t *typeLen)
Gets information about a loaded engine by index.
Retrieves the id, name, version, type, and plugin name of the engine at the given index. Valid indices are 0 to numEngines-1 as returned by hipdnnGetEngineCount_ext. Engines are sorted alphabetically by name.
This function uses a two-call pattern for string fields:
First call: Pass all string buffers as
nullptrto query required sizes.Sets
nameLen,versionLen,typeLen, andpluginNameLento the required buffer sizes (including null terminator). Note: if any string buffer is null, all sizes are updated.
Second call: Pass allocated buffers with sizes set from the first call.
- Parameters:
handle – [in] A valid hipDNN handle.
engineIndex – [in] Zero-based index of the engine to query.
engineId – [out] Pointer where the engine ID will be stored, or
nullptrto skip.engineName – [out] Buffer for the engine name, or
nullptrto query size.engineNameLen – [inout] Pointer to buffer size; updated with required size.
pluginName – [out] Buffer for the plugin name, or
nullptrto query size.pluginNameLen – [inout] Pointer to buffer size; updated with required size.
version – [out] Buffer for the engine version, or
nullptrto query size.versionLen – [inout] Pointer to buffer size; updated with required size.
type – [out] Buffer for the engine type string, or
nullptrto query size.typeLen – [inout] Pointer to buffer size; updated with required size.
- Return values:
HIPDNN_STATUS_SUCCESS – Success.
HIPDNN_STATUS_BAD_PARAM – Invalid handle, null pointers, or out-of-range index.
HIPDNN_STATUS_INTERNAL_ERROR – Internal error.
- HIPDNN_BACKEND_DEPRECATED_EXPORT hipdnnStatus_t hipdnnGetVersion_ext (const char **version)
Returns hipdnn backend version string. Returns an error if nullptr is passed.
- Deprecated:
Use hipdnnVersionString_ext instead
- Parameters:
version – [out] pointer to where version string will be written
- Return values:
HIPDNN_STATUS_SUCCESS – Success
HIPDNN_STATUS_BAD_PARAM_NULL_POINTER – If version parameter is nullptr
- HIPDNN_BACKEND_EXPORT const char * hipdnnVersionString_ext ()
Returns hipdnn backend version string.
- Returns:
A string in the format “MAJOR.MINOR.PATCH.TWEAK”. The returned value has a static lifetime