cuda: Add methods to enable stream ordered allocation

Adding prefer-stream-ordered-alloc property to GstCudaContext.
If stream ordered allocation buffer pool option is not configured
and this property is enabled, buffer pool will enable the stream
ordered allocation. Otherwise it will follow default behavior.

If GST_CUDA_ENABLE_STREAM_ORDERED_ALLOC env is set,
default behavior is enabling the stream ordered allocation.
Otherwise sync alloc/free method will be used.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7427>
This commit is contained in:
Seungha Yang 2024-09-10 19:29:44 +09:00 committed by GStreamer Marge Bot
parent d5d17d804e
commit cdaa798ac7
4 changed files with 80 additions and 7 deletions

View file

@ -23,3 +23,12 @@ Example: `GST_CUDA_CRITICAL_ERRORS=2,700`
As a result of the above example, if `CUDA_ERROR_OUT_OF_MEMORY(2)` or As a result of the above example, if `CUDA_ERROR_OUT_OF_MEMORY(2)` or
`CUDA_ERROR_ILLEGAL_ADDRESS(700)` error is detected in GStreamer CUDA library, `CUDA_ERROR_ILLEGAL_ADDRESS(700)` error is detected in GStreamer CUDA library,
the process will be aborted. the process will be aborted.
**`GST_CUDA_ENABLE_STREAM_ORDERED_ALLOC`. (Since: 1.26)**
As of 1.26, GStreamer CUDA library supports stream ordered CUDA allocation
(e.g., cuMemAllocAsync). The new allocation method is disabled by default
unless it's explicitly requested via buffer pool option.
This environment variable can be used to change the default behavior
so that the stream ordered allocation can be used by default.

View file

@ -86,6 +86,19 @@ gst_cuda_buffer_pool_update_alloc_prop (GstCudaBufferPool * self)
return TRUE; return TRUE;
} }
static gboolean
default_stream_ordered_alloc_enabled (void)
{
static gboolean enabled = FALSE;
GST_CUDA_CALL_ONCE_BEGIN {
if (g_getenv ("GST_CUDA_ENABLE_STREAM_ORDERED_ALLOC"))
enabled = TRUE;
}
GST_CUDA_CALL_ONCE_END;
return enabled;
}
static gboolean static gboolean
gst_cuda_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) gst_cuda_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
{ {
@ -133,8 +146,25 @@ gst_cuda_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
priv->alloc = gst_cuda_pool_allocator_new_for_virtual_memory (self->context, priv->alloc = gst_cuda_pool_allocator_new_for_virtual_memory (self->context,
priv->stream, &info, &priv->prop, CU_MEM_ALLOC_GRANULARITY_MINIMUM); priv->stream, &info, &priv->prop, CU_MEM_ALLOC_GRANULARITY_MINIMUM);
} else { } else {
gboolean stream_ordered = gboolean stream_ordered = FALSE;
gst_buffer_pool_config_get_cuda_stream_ordered_alloc (config); if (!gst_buffer_pool_config_get_cuda_stream_ordered_alloc (config,
&stream_ordered)) {
gboolean prefer_stream_ordered = FALSE;
g_object_get (self->context, "prefer-stream-ordered-alloc",
&prefer_stream_ordered, nullptr);
if (prefer_stream_ordered) {
GST_DEBUG_OBJECT (self, "Stream ordered alloc was enabled in context");
stream_ordered = TRUE;
} else {
stream_ordered = default_stream_ordered_alloc_enabled ();
GST_DEBUG_OBJECT (self, "Use default stream ordered alloc: %d",
stream_ordered);
}
} else {
GST_DEBUG_OBJECT (self,
"stream ordered alloc by config: %d", stream_ordered);
}
GstStructure *alloc_config = gst_structure_new ("alloc-config", GstStructure *alloc_config = gst_structure_new ("alloc-config",
GST_CUDA_ALLOCATOR_OPT_STREAM_ORDERED, G_TYPE_BOOLEAN, stream_ordered, GST_CUDA_ALLOCATOR_OPT_STREAM_ORDERED, G_TYPE_BOOLEAN, stream_ordered,
nullptr); nullptr);
@ -343,13 +373,15 @@ gst_buffer_pool_config_set_cuda_alloc_method (GstStructure * config,
/** /**
* gst_buffer_pool_config_get_cuda_stream_ordered_alloc: * gst_buffer_pool_config_get_cuda_stream_ordered_alloc:
* @config: a buffer pool config * @config: a buffer pool config
* @enabled: (out): whether stream ordered allocation was requested or not
* *
* Returns: %TRUE if stream ordered allocation is enabled * Returns: %TRUE stream ordered allocation option was specified
* *
* Since: 1.26 * Since: 1.26
*/ */
gboolean gboolean
gst_buffer_pool_config_get_cuda_stream_ordered_alloc (GstStructure * config) gst_buffer_pool_config_get_cuda_stream_ordered_alloc (GstStructure * config,
gboolean * enabled)
{ {
gboolean stream_ordered = FALSE; gboolean stream_ordered = FALSE;
@ -357,11 +389,13 @@ gst_buffer_pool_config_get_cuda_stream_ordered_alloc (GstStructure * config)
if (!gst_structure_get_boolean (config, if (!gst_structure_get_boolean (config,
"cuda-stream-ordered-alloc", &stream_ordered)) { "cuda-stream-ordered-alloc", &stream_ordered)) {
/* Disable stream-ordered alloc by default */
return FALSE; return FALSE;
} }
return stream_ordered; if (enabled)
*enabled = stream_ordered;
return TRUE;
} }
/** /**

View file

@ -87,7 +87,8 @@ void gst_buffer_pool_config_set_cuda_alloc_method (GstStruct
GstCudaMemoryAllocMethod method); GstCudaMemoryAllocMethod method);
GST_CUDA_API GST_CUDA_API
gboolean gst_buffer_pool_config_get_cuda_stream_ordered_alloc (GstStructure * config); gboolean gst_buffer_pool_config_get_cuda_stream_ordered_alloc (GstStructure * config,
gboolean * enabled);
GST_CUDA_API GST_CUDA_API
void gst_buffer_pool_config_set_cuda_stream_ordered_alloc (GstStructure * config, void gst_buffer_pool_config_set_cuda_stream_ordered_alloc (GstStructure * config,

View file

@ -55,6 +55,7 @@ enum
PROP_VIRTUAL_MEMORY, PROP_VIRTUAL_MEMORY,
PROP_OS_HANDLE, PROP_OS_HANDLE,
PROP_STREAM_ORDERED_ALLOC, PROP_STREAM_ORDERED_ALLOC,
PROP_PREFER_STREAM_ORDERED_ALLLOC,
}; };
struct _GstCudaContextPrivate struct _GstCudaContextPrivate
@ -66,11 +67,14 @@ struct _GstCudaContextPrivate
gboolean virtual_memory_supported; gboolean virtual_memory_supported;
gboolean os_handle_supported; gboolean os_handle_supported;
gboolean stream_ordered_alloc_supported; gboolean stream_ordered_alloc_supported;
gboolean prefer_stream_ordered_alloc;
gint tex_align; gint tex_align;
GHashTable *accessible_peer; GHashTable *accessible_peer;
gboolean owns_context; gboolean owns_context;
GMutex lock;
}; };
#define gst_cuda_context_parent_class parent_class #define gst_cuda_context_parent_class parent_class
@ -152,6 +156,17 @@ gst_cuda_context_class_init (GstCudaContextClass * klass)
"Device supports stream ordered allocation", FALSE, "Device supports stream ordered allocation", FALSE,
(GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
/**
* GstCudaContext:prefer-stream-ordered-alloc:
*
* Since: 1.26
*/
g_object_class_install_property (gobject_class,
PROP_PREFER_STREAM_ORDERED_ALLLOC,
g_param_spec_boolean ("prefer-stream-ordered-alloc",
"Prefer Stream Ordered Alloc", "Prefers stream ordered allocation",
FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
gst_cuda_memory_init_once (); gst_cuda_memory_init_once ();
} }
@ -162,6 +177,7 @@ gst_cuda_context_init (GstCudaContext * context)
gst_cuda_context_get_instance_private (context); gst_cuda_context_get_instance_private (context);
priv->accessible_peer = g_hash_table_new (g_direct_hash, g_direct_equal); priv->accessible_peer = g_hash_table_new (g_direct_hash, g_direct_equal);
g_mutex_init (&priv->lock);
context->priv = priv; context->priv = priv;
} }
@ -173,10 +189,16 @@ gst_cuda_context_set_property (GObject * object, guint prop_id,
GstCudaContext *context = GST_CUDA_CONTEXT (object); GstCudaContext *context = GST_CUDA_CONTEXT (object);
GstCudaContextPrivate *priv = context->priv; GstCudaContextPrivate *priv = context->priv;
switch (prop_id) { switch (prop_id) {
case PROP_DEVICE_ID: case PROP_DEVICE_ID:
priv->device_id = g_value_get_uint (value); priv->device_id = g_value_get_uint (value);
break; break;
case PROP_PREFER_STREAM_ORDERED_ALLLOC:
g_mutex_lock (&priv->lock);
priv->prefer_stream_ordered_alloc = g_value_get_boolean (value);
g_mutex_unlock (&priv->lock);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -206,6 +228,11 @@ gst_cuda_context_get_property (GObject * object, guint prop_id,
case PROP_STREAM_ORDERED_ALLOC: case PROP_STREAM_ORDERED_ALLOC:
g_value_set_boolean (value, priv->stream_ordered_alloc_supported); g_value_set_boolean (value, priv->stream_ordered_alloc_supported);
break; break;
case PROP_PREFER_STREAM_ORDERED_ALLLOC:
g_mutex_lock (&priv->lock);
g_value_set_boolean (value, priv->prefer_stream_ordered_alloc);
g_mutex_unlock (&priv->lock);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -419,6 +446,8 @@ gst_cuda_context_finalize (GObject * object)
gst_cuda_result (CuCtxDestroy (priv->context)); gst_cuda_result (CuCtxDestroy (priv->context));
} }
g_mutex_clear (&priv->lock);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }