summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Vogelgesang <matthias.vogelgesang@kit.edu>2012-12-04 18:23:18 +0100
committerMatthias Vogelgesang <matthias.vogelgesang@kit.edu>2012-12-04 18:23:18 +0100
commit9d7478bf103b36f244283c82d80a11b303217432 (patch)
treeb2a80358925482baa2be45c9192d7ae5f6f513bd
parenta21147c0a5d9a7eff9e8c02865ac7dc62f0213fb (diff)
First integration step of the prototype
This is introducing better multi GPU handling and cluster processing using zmq.
-rw-r--r--CMakeLists.txt11
-rw-r--r--docs/Ufo-sections.txt.in333
-rw-r--r--docs/scangobj.sh.in2
-rw-r--r--src/CMakeLists.txt96
-rw-r--r--src/Ufo.types16
-rw-r--r--src/ufo-arch-graph.c204
-rw-r--r--src/ufo-arch-graph.h57
-rw-r--r--src/ufo-aux.c55
-rw-r--r--src/ufo-aux.h16
-rw-r--r--src/ufo-buffer.c773
-rw-r--r--src/ufo-buffer.h87
-rw-r--r--src/ufo-channel.c259
-rw-r--r--src/ufo-channel.h62
-rw-r--r--src/ufo-config.c (renamed from src/ufo-configuration.c)113
-rw-r--r--src/ufo-config.h47
-rw-r--r--src/ufo-configurable.c10
-rw-r--r--src/ufo-configuration.h47
-rw-r--r--src/ufo-cpu-node.c93
-rw-r--r--src/ufo-cpu-node.h49
-rw-r--r--src/ufo-cpu-task-iface.c31
-rw-r--r--src/ufo-cpu-task-iface.h35
-rw-r--r--src/ufo-filter-reduce.c136
-rw-r--r--src/ufo-filter-reduce.h79
-rw-r--r--src/ufo-filter-repeater.c112
-rw-r--r--src/ufo-filter-repeater.h45
-rw-r--r--src/ufo-filter-sink-direct.c112
-rw-r--r--src/ufo-filter-sink-direct.h50
-rw-r--r--src/ufo-filter-sink.c85
-rw-r--r--src/ufo-filter-sink.h63
-rw-r--r--src/ufo-filter-source-direct.c127
-rw-r--r--src/ufo-filter-source-direct.h50
-rw-r--r--src/ufo-filter-source.c101
-rw-r--r--src/ufo-filter-source.h62
-rw-r--r--src/ufo-filter-splitter.c155
-rw-r--r--src/ufo-filter-splitter.h45
-rw-r--r--src/ufo-filter.c640
-rw-r--r--src/ufo-filter.h183
-rw-r--r--src/ufo-gpu-node.c78
-rw-r--r--src/ufo-gpu-node.h49
-rw-r--r--src/ufo-gpu-task-iface.c32
-rw-r--r--src/ufo-gpu-task-iface.h37
-rw-r--r--src/ufo-graph.c906
-rw-r--r--src/ufo-graph.h71
-rw-r--r--src/ufo-group.c233
-rw-r--r--src/ufo-group.h62
-rw-r--r--src/ufo-input-task.c216
-rw-r--r--src/ufo-input-task.h54
-rw-r--r--src/ufo-node.c88
-rw-r--r--src/ufo-node.h57
-rw-r--r--src/ufo-output-task.c184
-rw-r--r--src/ufo-output-task.h53
-rw-r--r--src/ufo-plugin-manager.c79
-rw-r--r--src/ufo-plugin-manager.h12
-rw-r--r--src/ufo-profiler.c8
-rw-r--r--src/ufo-profiler.h1
-rw-r--r--src/ufo-relation.c454
-rw-r--r--src/ufo-relation.h82
-rw-r--r--src/ufo-remote-node.c231
-rw-r--r--src/ufo-remote-node.h80
-rw-r--r--src/ufo-remote-task.c160
-rw-r--r--src/ufo-remote-task.h48
-rw-r--r--src/ufo-resource-manager.c846
-rw-r--r--src/ufo-resource-manager.h100
-rw-r--r--src/ufo-resources.c665
-rw-r--r--src/ufo-resources.h84
-rw-r--r--src/ufo-scheduler.c918
-rw-r--r--src/ufo-scheduler.h12
-rw-r--r--src/ufo-task-graph.c135
-rw-r--r--src/ufo-task-graph.h60
-rw-r--r--src/ufo-task-iface.c59
-rw-r--r--src/ufo-task-iface.h62
-rw-r--r--src/ufo-task-node.c114
-rw-r--r--src/ufo-task-node.h70
73 files changed, 4457 insertions, 6384 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82eb779..39db0e9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ set(UFO_VERSION_PATCH "0")
set(UFO_GIR_VERSION "${UFO_VERSION_MAJOR}.${UFO_VERSION_MINOR}")
# increase UFO_SO_VERSION on each version that breaks ABI compatibility
-set(UFO_SO_VERSION "2")
+set(UFO_SO_VERSION "3")
set(UFO_DESCRIPTION "UFO high-speed image processing core library")
set(UFO_DESCRIPTION_SUMMARY "UFO high-speed image processing core library")
@@ -55,6 +55,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}
)
add_definitions("-std=c99 -pedantic -Wall -Wextra -fPIC")
+
if (CMAKE_COMPILER_IS_GNUCC)
add_definitions("-Wmissing-prototypes -Wmissing-declarations -Wshadow
-Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Wcast-qual
@@ -66,10 +67,10 @@ endif()
add_definitions(-DG_LOG_DOMAIN=\"Ufo\")
add_subdirectory(src)
-add_subdirectory(docs)
-add_subdirectory(python)
-add_subdirectory(tests)
-add_subdirectory(tools)
+#add_subdirectory(docs)
+#add_subdirectory(python)
+#add_subdirectory(tests)
+#add_subdirectory(tools)
# --- Package generation ------------------------------------------------------
diff --git a/docs/Ufo-sections.txt.in b/docs/Ufo-sections.txt.in
index abb7853..b518754 100644
--- a/docs/Ufo-sections.txt.in
+++ b/docs/Ufo-sections.txt.in
@@ -1,19 +1,19 @@
<SECTION>
-<FILE>ufo-configuration</FILE>
-<TITLE>UfoConfiguration</TITLE>
-UfoConfiguration
-ufo_configuration_new
-ufo_configuration_get_paths
+<FILE>ufo-config</FILE>
+<TITLE>UfoConfig</TITLE>
+UfoConfig
+ufo_config_new
+ufo_config_get_paths
<SUBSECTION Standard>
-UFO_CONFIGURATION
-UFO_CONFIGURATION_CLASS
-UFO_CONFIGURATION_GET_CLASS
-UFO_IS_CONFIGURATION
-UFO_IS_CONFIGURATION_CLASS
-UFO_TYPE_CONFIGURATION
-ufo_configuration_get_type
+UFO_CONFIG
+UFO_CONFIG_CLASS
+UFO_CONFIG_GET_CLASS
+UFO_IS_CONFIG
+UFO_IS_CONFIG_CLASS
+UFO_TYPE_CONFIG
+ufo_config_get_type
<SUBSECTION Private>
-UfoConfigurationPrivate
+UfoConfigPrivate
</SECTION>
<SECTION>
@@ -38,8 +38,8 @@ UfoConfigurableIface
UfoPluginManagerError
UfoPluginManager
ufo_plugin_manager_new
-ufo_plugin_manager_get_filter
-ufo_plugin_manager_get_all_filter_names
+ufo_plugin_manager_get_task
+ufo_plugin_manager_get_all_task_names
<SUBSECTION Standard>
UFO_PLUGIN_MANAGER
UFO_IS_PLUGIN_MANAGER
@@ -56,82 +56,27 @@ ufo_plugin_manager_error_quark
<SECTION>
<FILE>ufo-resource-manager</FILE>
-<TITLE>UfoResourceManager</TITLE>
-CHECK_OPENCL_ERROR
-UfoResourceManagerError
-UfoResourceManager
-ufo_resource_manager_new
-ufo_resource_manager_get_kernel
-ufo_resource_manager_get_kernel_from_source
-ufo_resource_manager_get_context
-ufo_resource_manager_get_command_queues
-ufo_resource_manager_get_command_queue
-ufo_resource_manager_get_number_of_devices
-ufo_resource_manager_memdup
-ufo_resource_manager_memalloc
-ufo_resource_manager_request_buffer
-ufo_resource_manager_get_queue_number
-<SUBSECTION Standard>
-UFO_RESOURCE_MANAGER
-UFO_IS_RESOURCE_MANAGER
-UFO_TYPE_RESOURCE_MANAGER
-ufo_resource_manager_get_type
-UFO_RESOURCE_MANAGER_CLASS
-UFO_IS_RESOURCE_MANAGER_CLASS
-UFO_RESOURCE_MANAGER_GET_CLASS
-<SUBSECTION Private>
-UFO_RESOURCE_MANAGER_ERROR
-UfoResourceManagerClass
-UfoResourceManagerPrivate
+<TITLE>UfoResources</TITLE>
+UfoResourcesError
+UfoResources
+ufo_resources_new
+ufo_resources_get_kernel
+ufo_resources_get_kernel_from_source
+ufo_resources_get_context
+<SUBSECTION Standard>
+UFO_RESOURCES
+UFO_IS_RESOURCES
+UFO_TYPE_RESOURCES
+ufo_resources_get_type
+UFO_RESOURCES_CLASS
+UFO_IS_RESOURCES_CLASS
+UFO_RESOURCES_GET_CLASS
+<SUBSECTION Private>
+UFO_RESOURCES_ERROR
+UfoResourcesClass
+UfoResourcesPrivate
opencl_map_error
-ufo_resource_manager_error_quark
-</SECTION>
-
-<SECTION>
-<FILE>ufo-filter</FILE>
-<TITLE>UfoFilter</TITLE>
-UfoFilterError
-UfoFilter
-UfoFilterClass
-UfoFilterConditionFunc
-UfoInputParameter
-UfoOutputParameter
-UFO_FILTER_INFINITE_INPUT
-ufo_filter_initialize
-ufo_filter_process_cpu
-ufo_filter_process_gpu
-ufo_filter_register_inputs
-ufo_filter_register_outputs
-ufo_filter_get_num_inputs
-ufo_filter_get_num_outputs
-ufo_filter_get_input_parameters
-ufo_filter_get_output_parameters
-ufo_filter_set_plugin_name
-ufo_filter_get_plugin_name
-ufo_filter_get_unique_name
-ufo_filter_set_resource_manager
-ufo_filter_get_resource_manager
-ufo_filter_set_command_queue
-ufo_filter_get_command_queue
-ufo_filter_set_profiler
-ufo_filter_get_profiler
-ufo_filter_set_input_channel
-ufo_filter_get_input_channel
-ufo_filter_set_output_channel
-ufo_filter_get_output_channel
-ufo_filter_wait_until
-<SUBSECTION Standard>
-UFO_FILTER
-UFO_IS_FILTER
-UFO_TYPE_FILTER
-ufo_filter_get_type
-UFO_FILTER_CLASS
-UFO_IS_FILTER_CLASS
-UFO_FILTER_GET_CLASS
-<SUBSECTION Private>
-UFO_FILTER_ERROR
-UfoFilterPrivate
-ufo_filter_error_quark
+ufo_resources_error_quark
</SECTION>
<SECTION>
@@ -161,204 +106,10 @@ UfoProfilerPrivate
</SECTION>
<SECTION>
-<FILE>ufo-filter-sink</FILE>
-<TITLE>UfoFilterSink</TITLE>
-UfoFilterSink
-UfoFilterSinkClass
-ufo_filter_sink_initialize
-ufo_filter_sink_consume
-<SUBSECTION Standard>
-UFO_TYPE_FILTER_SINK
-UFO_FILTER_SINK
-UFO_FILTER_SINK_CLASS
-UFO_FILTER_SINK_GET_CLASS
-UFO_IS_FILTER_SINK
-UFO_IS_FILTER_SINK_CLASS
-ufo_filter_sink_get_type
-<SUBSECTION Private>
-UfoFilterSinkPrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-filter-sink-direct</FILE>
-<TITLE>UfoFilterSinkDirect</TITLE>
-UfoFilterSinkDirect
-ufo_filter_sink_direct_pop
-ufo_filter_sink_direct_release
-<SUBSECTION Standard>
-UfoFilterSinkDirectClass
-UFO_TYPE_FILTER_SINK_DIRECT
-UFO_FILTER_SINK_DIRECT
-UFO_FILTER_SINK_DIRECT_CLASS
-UFO_FILTER_SINK_DIRECT_GET_CLASS
-UFO_IS_FILTER_SINK_DIRECT
-UFO_IS_FILTER_SINK_DIRECT_CLASS
-ufo_filter_sink_direct_get_type
-<SUBSECTION Private>
-UfoFilterSinkDirectPrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-filter-source</FILE>
-<TITLE>UfoFilterSource</TITLE>
-UfoFilterSource
-UfoFilterSourceClass
-ufo_filter_source_initialize
-ufo_filter_source_generate
-<SUBSECTION Standard>
-UFO_TYPE_FILTER_SOURCE
-UFO_FILTER_SOURCE
-UFO_FILTER_SOURCE_CLASS
-UFO_FILTER_SOURCE_GET_CLASS
-UFO_IS_FILTER_SOURCE
-UFO_IS_FILTER_SOURCE_CLASS
-ufo_filter_source_get_type
-<SUBSECTION Private>
-UfoFilterSourcePrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-filter-source-direct</FILE>
-<TITLE>UfoFilterSourceDirect</TITLE>
-UfoFilterSourceDirect
-ufo_filter_source_direct_push
-ufo_filter_source_direct_stop
-<SUBSECTION Standard>
-UfoFilterSourceDirectClass
-UFO_FILTER_SOURCE_DIRECT
-UFO_FILTER_SOURCE_DIRECT_CLASS
-UFO_FILTER_SOURCE_DIRECT_GET_CLASS
-UFO_IS_FILTER_SOURCE_DIRECT
-UFO_IS_FILTER_SOURCE_DIRECT_CLASS
-UFO_TYPE_FILTER_SOURCE_DIRECT
-ufo_filter_source_direct_get_type
-<SUBSECTION Private>
-UfoFilterSourceDirectPrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-filter-reduce</FILE>
-<TITLE>UfoFilterReduce</TITLE>
-UfoFilterReduce
-UfoFilterReduceClass
-ufo_filter_reduce_initialize
-ufo_filter_reduce_collect
-ufo_filter_reduce_reduce
-<SUBSECTION Standard>
-UFO_TYPE_FILTER_REDUCE
-UFO_FILTER_REDUCE
-UFO_FILTER_REDUCE_CLASS
-UFO_FILTER_REDUCE_GET_CLASS
-UFO_IS_FILTER_REDUCE
-UFO_IS_FILTER_REDUCE_CLASS
-ufo_filter_reduce_get_type
-<SUBSECTION Private>
-UfoFilterReducePrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-filter-repeater</FILE>
-<TITLE>UfoFilterRepeater</TITLE>
-UfoFilterRepeater
-UfoFilterRepeaterClass
-<SUBSECTION Standard>
-UFO_FILTER_REPEATER
-UFO_FILTER_REPEATER_CLASS
-UFO_FILTER_REPEATER_GET_CLASS
-UFO_IS_FILTER_REPEATER
-UFO_IS_FILTER_REPEATER_CLASS
-UFO_TYPE_FILTER_REPEATER
-ufo_filter_repeater_get_type
-<SUBSECTION Private>
-UfoFilterRepeaterPrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-filter-splitter</FILE>
-<TITLE>UfoFilterSplitter</TITLE>
-UfoFilterSplitter
-UfoFilterSplitterClass
-<SUBSECTION Standard>
-UFO_TYPE_FILTER_SPLITTER
-UFO_FILTER_SPLITTER
-UFO_FILTER_SPLITTER_CLASS
-UFO_FILTER_SPLITTER_GET_CLASS
-UFO_IS_FILTER_SPLITTER
-UFO_IS_FILTER_SPLITTER_CLASS
-ufo_filter_splitter_get_type
-<SUBSECTION Private>
-UfoFilterSplitterPrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-relation</FILE>
-<TITLE>UfoRelation</TITLE>
-UfoRelation
-UfoRelationMode
-ufo_relation_new
-ufo_relation_add_consumer
-ufo_relation_get_producer
-ufo_relation_get_consumers
-ufo_relation_get_consumer_port
-ufo_relation_get_producer_port
-ufo_relation_get_consumer_queues
-ufo_relation_get_producer_queues
-ufo_relation_has_consumer
-ufo_relation_push_poison_pill
-<SUBSECTION Standard>
-UFO_TYPE_RELATION
-UFO_RELATION
-UFO_RELATION_CLASS
-UFO_RELATION_GET_CLASS
-UFO_IS_RELATION
-UFO_IS_RELATION_CLASS
-ufo_relation_get_type
-<SUBSECTION Private>
-UfoRelationPrivate
-</SECTION>
-
-<SECTION>
-<FILE>ufo-channel</FILE>
-<TITLE>UfoChannel</TITLE>
-UfoChannel
-ufo_channel_new
-ufo_channel_ref
-ufo_channel_insert
-ufo_channel_fetch_input
-ufo_channel_release_input
-ufo_channel_fetch_output
-ufo_channel_release_output
-ufo_channel_daisy_chain
-ufo_channel_finish
-ufo_channel_finish_next
-<SUBSECTION Standard>
-UFO_CHANNEL
-UFO_IS_CHANNEL
-UFO_TYPE_CHANNEL
-ufo_channel_get_type
-UFO_CHANNEL_CLASS
-UFO_IS_CHANNEL_CLASS
-UFO_CHANNEL_GET_CLASS
-<SUBSECTION Private>
-UfoChannelClass
-UfoChannelPrivate
-</SECTION>
-
-<SECTION>
<FILE>ufo-graph</FILE>
<TITLE>UfoGraph</TITLE>
-UfoGraphError
UfoGraph
-UfoTransferMode
ufo_graph_new
-ufo_graph_connect_filters
-ufo_graph_connect_filters_full
-ufo_graph_read_from_json
-ufo_graph_save_to_json
-ufo_graph_get_filters
-ufo_graph_get_roots
-ufo_graph_get_children
-ufo_graph_get_num_filters
<SUBSECTION Standard>
UFO_GRAPH
UFO_IS_GRAPH
@@ -382,25 +133,11 @@ UfoBuffer
UFO_BUFFER_MAX_NDIMS
ufo_buffer_new
ufo_buffer_copy
-ufo_buffer_alloc_host_mem
-ufo_buffer_transfer_id
ufo_buffer_get_size
-ufo_buffer_get_id
-ufo_buffer_get_dimensions
ufo_buffer_get_2d_dimensions
ufo_buffer_resize
-ufo_buffer_reinterpret
-ufo_buffer_fill_with_value
-ufo_buffer_set_host_array
ufo_buffer_get_host_array
-ufo_buffer_swap_host_arrays
ufo_buffer_get_device_array
-ufo_buffer_set_cl_mem
-ufo_buffer_invalidate_gpu_data
-ufo_buffer_get_transfer_timer
-ufo_buffer_attach_event
-ufo_buffer_get_events
-ufo_buffer_clear_events
<SUBSECTION>UfoBufferParamSpec</SUBSECTION>
UfoBufferParamSpec
ufo_buffer_param_spec
diff --git a/docs/scangobj.sh.in b/docs/scangobj.sh.in
index 5a208c2..aedf3f0 100644
--- a/docs/scangobj.sh.in
+++ b/docs/scangobj.sh.in
@@ -1 +1 @@
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${CMAKE_CURRENT_BINARY_DIR}" CFLAGS="${GTK_DOC_CFLAGS}" LDFLAGS="${GTK_DOC_LDFLAGS} -L${CMAKE_CURRENT_BINARY_DIR} -lufo" gtkdoc-scangobj --types=${CMAKE_CURRENT_SOURCE_DIR}/Ufo.types --module=Ufo
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${CMAKE_CURRENT_BINARY_DIR}" CFLAGS="${GTK_DOC_CFLAGS}" LDFLAGS="${GTK_DOC_LDFLAGS} -L${CMAKE_CURRENT_BINARY_DIR} -lufo" gtkdoc-scangobj --module=Ufo
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7f0c427..ded3b95 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,52 +2,55 @@ cmake_minimum_required(VERSION 2.6)
# --- Set sources -------------------------------------------------------------
set(ufocore_SRCS
- ufo-scheduler.c
- ufo-channel.c
+ ufo-arch-graph.c
+ ufo-buffer.c
ufo-configurable.c
- ufo-configuration.c
+ ufo-config.c
+ ufo-cpu-node.c
+ ufo-cpu-task-iface.c
+ ufo-gpu-node.c
+ ufo-gpu-task-iface.c
ufo-graph.c
- ufo-buffer.c
- ufo-filter.c
- ufo-filter-source.c
- ufo-filter-source-direct.c
- ufo-filter-sink.c
- ufo-filter-sink-direct.c
- ufo-filter-reduce.c
- ufo-filter-repeater.c
- ufo-filter-splitter.c
+ ufo-group.c
+ ufo-input-task.c
+ ufo-node.c
+ ufo-output-task.c
ufo-plugin-manager.c
ufo-profiler.c
- ufo-resource-manager.c
+ ufo-remote-node.c
+ ufo-remote-task.c
+ ufo-resources.c
+ ufo-scheduler.c
+ ufo-task-iface.c
+ ufo-task-graph.c
+ ufo-task-node.c
)
set(ufocore_HDRS
- ufo-scheduler.h
- ufo-channel.h
+ ufo-arch-graph.h
+ ufo-buffer.h
ufo-configurable.h
- ufo-configuration.h
+ ufo-config.h
+ ufo-cpu-node.h
+ ufo-cpu-task-iface.h
+ ufo-gpu-node.h
+ ufo-gpu-task-iface.h
ufo-graph.h
- ufo-buffer.h
- ufo-filter.h
- ufo-filter-source.h
- ufo-filter-source-direct.h
- ufo-filter-sink.h
- ufo-filter-sink-direct.h
- ufo-filter-reduce.h
- ufo-filter-repeater.h
- ufo-filter-splitter.h
+ ufo-group.h
+ ufo-input-task.h
+ ufo-node.h
+ ufo-output-task.h
ufo-plugin-manager.h
ufo-profiler.h
- ufo-resource-manager.h
- )
-
-set(ufocore_NODOC_SRCS
- ufo-aux.c
+ ufo-remote-node.h
+ ufo-remote-task.h
+ ufo-resources.h
+ ufo-scheduler.h
+ ufo-task-iface.h
+ ufo-task-graph.h
+ ufo-task-node.h
)
-set(ufocore_NODOC_HDRS
- ufo-aux.h
- )
# --- Find packages and libraries ---------------------------------------------
find_program(INTROSPECTION_SCANNER "g-ir-scanner")
@@ -57,6 +60,7 @@ find_program(GLIB2_MKENUMS glib-mkenums REQUIRED)
pkg_check_modules(GMODULE2 gmodule-2.0>=2.22 REQUIRED)
pkg_check_modules(GTHREAD2 gthread-2.0>=2.22 REQUIRED)
pkg_check_modules(JSON_GLIB json-glib-1.0 REQUIRED)
+pkg_check_modules(ZMQ libzmq>=3.2 REQUIRED)
set(ufocore_LIBS
${OPENCL_LIBRARIES}
@@ -65,6 +69,7 @@ set(ufocore_LIBS
${GMODULE2_LIBRARIES}
${GTHREAD2_LIBRARIES}
${JSON_GLIB_LIBRARIES}
+ ${ZMQ_LIBRARIES}
)
# --- Add enum generation targets ---------------------------------------------
@@ -98,7 +103,7 @@ set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${JSON_GLIB_INCLUDE_DIRS}
- )
+ ${ZMQ_INCLUDE_DIRS})
if(CMAKE_BUILD_TYPE MATCHES "Release")
add_definitions(-DG_DISABLE_ASSERT)
@@ -164,7 +169,9 @@ if (INTROSPECTION_SCANNER AND INTROSPECTION_COMPILER)
--no-libtool
--include=GObject-2.0
--include=GModule-2.0
+ --include=GLib-2.0
-I${OPENCL_INCLUDE_DIRS}
+ -I${CMAKE_CURRENT_SOURCE_DIR}
--output ${GIR_XML}
--warn-all
${_gir_input}
@@ -225,28 +232,10 @@ if(GTK_DOC_FOUND)
endforeach()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../docs/Ufo-docs.xml.in" "${docs_out}/Ufo-docs.xml")
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../docs/Ufo-sections.txt.in" "${docs_out}/Ufo-sections.txt")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../docs/scangobj.sh.in" "${docs_out}/scangobj.sh")
set(reference_files
"${docs_out}/index.html"
- "${docs_out}/annotation-glossary.html"
- "${docs_out}/api-index-full.html"
- "${docs_out}/ch01.html"
- "${docs_out}/UfoBuffer.html"
- "${docs_out}/UfoChannel.html"
- "${docs_out}/UfoConfigurable.html"
- "${docs_out}/UfoConfiguration.html"
- "${docs_out}/UfoFilter.html"
- "${docs_out}/UfoFilterReduce.html"
- "${docs_out}/UfoFilterSink.html"
- "${docs_out}/UfoFilterSinkDirect.html"
- "${docs_out}/UfoFilterSource.html"
- "${docs_out}/UfoFilterSourceDirect.html"
- "${docs_out}/UfoGraph.html"
- "${docs_out}/UfoPluginManager.html"
- "${docs_out}/UfoProfiler.html"
- "${docs_out}/UfoResourceManager.html"
"${docs_out}/UfoScheduler.html"
"${docs_out}/style.css"
"${docs_out}/Ufo.devhelp2"
@@ -264,13 +253,12 @@ if(GTK_DOC_FOUND)
COMMAND ${GTK_DOC_SCAN}
--module=Ufo
--source-dir=${CMAKE_CURRENT_SOURCE_DIR}/../src
- --ignore-headers="${ufocore_NODOC_HDRS}"
DEPENDS ${ufocore_SRCS}
WORKING_DIRECTORY ${docs_out})
add_custom_command(OUTPUT ${docs_out}/Ufo.args
COMMAND sh scangobj.sh
- DEPENDS ${ufocore_SRCS} ${docs_out}/Ufo-decl.txt ${CMAKE_CURRENT_SOURCE_DIR}/Ufo.types
+ DEPENDS ${ufocore_SRCS} ${docs_out}/Ufo-decl.txt
WORKING_DIRECTORY ${docs_out})
add_custom_command(OUTPUT ${docs_out}/sgml.stamp
diff --git a/src/Ufo.types b/src/Ufo.types
index 1c60b5a..e69de29 100644
--- a/src/Ufo.types
+++ b/src/Ufo.types
@@ -1,16 +0,0 @@
-ufo_scheduler_get_type
-ufo_buffer_get_type
-ufo_channel_get_type
-ufo_configurable_get_type
-ufo_configuration_get_type
-ufo_filter_get_type
-ufo_filter_source_get_type
-ufo_filter_source_direct_get_type
-ufo_filter_sink_get_type
-ufo_filter_sink_direct_get_type
-ufo_filter_reduce_get_type
-ufo_filter_splitter_get_type
-ufo_graph_get_type
-ufo_plugin_manager_get_type
-ufo_profiler_get_type
-ufo_resource_manager_get_type
diff --git a/src/ufo-arch-graph.c b/src/ufo-arch-graph.c
new file mode 100644
index 0000000..e0d2232
--- /dev/null
+++ b/src/ufo-arch-graph.c
@@ -0,0 +1,204 @@
+/**
+ * SECTION:ufo-arch-graph
+ * @Short_description: Describe and hold #UfoGpuNode, #UfoCpuNode and
+ * #UfoRemoteNode
+ * @Title: UfoArchGraph
+ */
+
+#define _GNU_SOURCE
+#include <sys/sysinfo.h>
+#include <sched.h>
+#include <ufo-arch-graph.h>
+#include <ufo-cpu-node.h>
+#include <ufo-gpu-node.h>
+#include <ufo-remote-node.h>
+
+G_DEFINE_TYPE (UfoArchGraph, ufo_arch_graph, UFO_TYPE_GRAPH)
+
+#define UFO_ARCH_GRAPH_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_ARCH_GRAPH, UfoArchGraphPrivate))
+
+struct _UfoArchGraphPrivate {
+ gpointer zmq_context;
+ gpointer ocl_context;
+ guint n_cpus;
+ guint n_gpus;
+};
+
+/**
+ * ufo_arch_graph_new:
+ * @zmq_context: Context created with zmq_context_new().
+ * @remote_addresses: (element-type utf8): A #GList containing address strings.
+ * @resources: An initialized #UfoResources object
+ *
+ * Returns: A new #UfoArchGraph.
+ */
+UfoGraph *
+ufo_arch_graph_new (gpointer zmq_context,
+ GList *remote_addresses,
+ UfoResources *resources)
+{
+ UfoArchGraph *graph;
+ UfoArchGraphPrivate *priv;
+ GList *cmd_queues;
+ UfoNode **cpu_nodes;
+ UfoNode **gpu_nodes;
+ cpu_set_t mask;
+ UfoNode **remote_nodes = NULL;
+ guint n_remotes = 0;
+
+ graph = UFO_ARCH_GRAPH (g_object_new (UFO_TYPE_ARCH_GRAPH, NULL));
+ priv = graph->priv;
+ priv->ocl_context = ufo_resources_get_context (resources);
+ priv->zmq_context = zmq_context;
+
+ /* Create CPU nodes */
+ priv->n_cpus = (guint) get_nprocs ();
+ cpu_nodes = g_new0 (UfoNode *, priv->n_cpus);
+
+ for (guint i = 0; i < priv->n_cpus; i++) {
+ CPU_ZERO (&mask);
+ CPU_SET (i, &mask);
+ cpu_nodes[i] = ufo_cpu_node_new (&mask);
+ }
+
+ /* Create GPU nodes, each one is associated with its own command queue. */
+ cmd_queues = ufo_resources_get_cmd_queues (resources);
+ priv->n_gpus = g_list_length (cmd_queues);
+ gpu_nodes = g_new0 (UfoNode *, priv->n_gpus);
+
+ for (guint i = 0; i < priv->n_gpus; i++) {
+ gpu_nodes[i] = ufo_gpu_node_new (g_list_nth_data (cmd_queues, i));
+ }
+
+ /* Create remote nodes */
+ if (zmq_context) {
+ n_remotes = g_list_length (remote_addresses);
+ remote_nodes = g_new0 (UfoNode *, n_remotes);
+
+ for (guint i = 0; i < n_remotes; i++)
+ remote_nodes[i] = ufo_remote_node_new (zmq_context,
+ (gchar *) g_list_nth_data (remote_addresses, i));
+ }
+
+ /*
+ * Connect all CPUs to all GPUs. In the future this is the place for a
+ * NUMA-specific mapping.
+ */
+ for (guint i = 0; i < priv->n_cpus; i++) {
+ for (guint j = 0; j < priv->n_gpus; j++) {
+ ufo_graph_connect_nodes (UFO_GRAPH (graph),
+ cpu_nodes[i],
+ gpu_nodes[j],
+ NULL);
+ }
+
+ for (guint j = 0; j < n_remotes; j++) {
+ ufo_graph_connect_nodes (UFO_GRAPH (graph),
+ cpu_nodes[i],
+ remote_nodes[j],
+ NULL);
+ }
+ }
+
+ g_free (cpu_nodes);
+ g_free (gpu_nodes);
+ g_free (remote_nodes);
+ g_list_free (cmd_queues);
+ return UFO_GRAPH (graph);
+}
+
+/**
+ * ufo_arch_graph_get_context:
+ * @graph: A #UfoArchGraph object
+ *
+ * Returns: OpenCL context associated with @graph.
+ */
+gpointer
+ufo_arch_graph_get_context (UfoArchGraph *graph)
+{
+ g_return_val_if_fail (UFO_IS_ARCH_GRAPH (graph), NULL);
+ return graph->priv->ocl_context;
+}
+
+/**
+ * ufo_arch_graph_get_num_cpus:
+ * @graph: A #UfoArchGraph object
+ *
+ * Returns: Number of CPU nodes in @graph.
+ */
+guint
+ufo_arch_graph_get_num_cpus (UfoArchGraph *graph)
+{
+ g_return_val_if_fail (UFO_IS_ARCH_GRAPH (graph), 0);
+ return graph->priv->n_cpus;
+}
+
+/**
+ * ufo_arch_graph_get_num_gpus:
+ * @graph: A #UfoArchGraph object
+ *
+ * Returns: Number of GPU nodes in @graph.
+ */
+guint
+ufo_arch_graph_get_num_gpus (UfoArchGraph *graph)
+{
+ g_return_val_if_fail (UFO_IS_ARCH_GRAPH (graph), 0);
+ return graph->priv->n_gpus;
+}
+
+static gboolean
+is_gpu_node (UfoNode *node)
+{
+ return UFO_IS_GPU_NODE (node);
+}
+
+/**
+ * ufo_arch_graph_get_gpu_nodes:
+ * @graph: A #UfoArchGraph
+ *
+ * Returns: (element-type UfoGpuNode) (transfer container): A list of
+ * #UfoGpuNode elements in @graph.
+ */
+GList *
+ufo_arch_graph_get_gpu_nodes (UfoArchGraph *graph)
+{
+ return ufo_graph_get_nodes_filtered (UFO_GRAPH (graph),
+ is_gpu_node);
+}
+
+static gboolean
+is_remote_node (UfoNode *node)
+{
+ return UFO_IS_REMOTE_NODE (node);
+}
+
+/**
+ * ufo_arch_graph_get_remote_nodes:
+ * @graph: A #UfoArchGraph
+ *
+ * Returns: (element-type UfoGpuNode) (transfer container): A list of
+ * #UfoRemoteNode elements in @graph.
+ */
+GList *
+ufo_arch_graph_get_remote_nodes (UfoArchGraph *graph)
+{
+ return ufo_graph_get_nodes_filtered (UFO_GRAPH (graph),
+ is_remote_node);
+}
+
+static void
+ufo_arch_graph_class_init (UfoArchGraphClass *klass)
+{
+ g_type_class_add_private(klass, sizeof(UfoArchGraphPrivate));
+}
+
+static void
+ufo_arch_graph_init (UfoArchGraph *self)
+{
+ UfoArchGraphPrivate *priv;
+ self->priv = priv = UFO_ARCH_GRAPH_GET_PRIVATE (self);
+
+ ufo_graph_register_node_type (UFO_GRAPH (self), UFO_TYPE_CPU_NODE);
+ ufo_graph_register_node_type (UFO_GRAPH (self), UFO_TYPE_GPU_NODE);
+ ufo_graph_register_node_type (UFO_GRAPH (self), UFO_TYPE_REMOTE_NODE);
+}
diff --git a/src/ufo-arch-graph.h b/src/ufo-arch-graph.h
new file mode 100644
index 0000000..7ffef31
--- /dev/null
+++ b/src/ufo-arch-graph.h
@@ -0,0 +1,57 @@
+#ifndef __UFO_ARCH_GRAPH_H
+#define __UFO_ARCH_GRAPH_H
+
+#include <glib-object.h>
+#include <ufo-graph.h>
+#include <ufo-resources.h>
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_ARCH_GRAPH (ufo_arch_graph_get_type())
+#define UFO_ARCH_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_ARCH_GRAPH, UfoArchGraph))
+#define UFO_IS_ARCH_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_ARCH_GRAPH))
+#define UFO_ARCH_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_ARCH_GRAPH, UfoArchGraphClass))
+#define UFO_IS_ARCH_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_ARCH_GRAPH))
+#define UFO_ARCH_GRAPH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_ARCH_GRAPH, UfoArchGraphClass))
+
+typedef struct _UfoArchGraph UfoArchGraph;
+typedef struct _UfoArchGraphClass UfoArchGraphClass;
+typedef struct _UfoArchGraphPrivate UfoArchGraphPrivate;
+
+/**
+ * UfoArchGraph:
+ *
+ * Graph structure that describes the relation between hardware nodes. The
+ * contents of the #UfoArchGraph structure are private and should only be
+ * accessed via the provided API.
+ */
+struct _UfoArchGraph {
+ /*< private >*/
+ UfoGraph parent_instance;
+
+ UfoArchGraphPrivate *priv;
+};
+
+/**
+ * UfoArchGraphClass:
+ *
+ * #UfoArchGraph class
+ */
+struct _UfoArchGraphClass {
+ /*< private >*/
+ UfoGraphClass parent_class;
+};
+
+UfoGraph *ufo_arch_graph_new (gpointer zmq_context,
+ GList *remote_addresses,
+ UfoResources *resources);
+gpointer ufo_arch_graph_get_context (UfoArchGraph *graph);
+guint ufo_arch_graph_get_num_cpus (UfoArchGraph *graph);
+guint ufo_arch_graph_get_num_gpus (UfoArchGraph *graph);
+GList *ufo_arch_graph_get_gpu_nodes (UfoArchGraph *graph);
+GList *ufo_arch_graph_get_remote_nodes (UfoArchGraph *graph);
+GType ufo_arch_graph_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-aux.c b/src/ufo-aux.c
deleted file mode 100644
index de4959e..0000000
--- a/src/ufo-aux.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-#include "ufo-aux.h"
-
-/**
- * ufo_set_property_object:
- * @storage: A place to store @object
- * @object: An object that should be stored and referenced or %NULL
- *
- * Tries to store @object in @storage and references if @object is not %NULL. In
- * case @storage contains already an object, the existing object is unreffed
- * with g_object_unref().
- */
-void
-ufo_set_property_object (GObject **storage, GObject *object)
-{
- if (*storage != NULL)
- g_object_unref (*storage);
-
- *storage = object;
-
- if (object != NULL)
- g_object_ref (object);
-}
-
-/**
- * ufo_unref_stored_object:
- * @storage: A place that could contain an object.
- *
- * If @storage contains an object it is unreffed with %NULL and the storage set
- * to %NULL.
- */
-void
-ufo_unref_stored_object (GObject **storage)
-{
- if (*storage != NULL) {
- g_object_unref (*storage);
- *storage = NULL;
- }
-}
-
-void
-ufo_debug_cl (const gchar *format, ...)
-{
- va_list args;
-
- va_start (args, format);
- g_logv ("ocl", G_LOG_LEVEL_MESSAGE, format, args);
- va_end (args);
-}
-
-
diff --git a/src/ufo-aux.h b/src/ufo-aux.h
deleted file mode 100644
index 1e5ef0b..0000000
--- a/src/ufo-aux.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __UFO_AUX_H
-#define __UFO_AUX_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-void ufo_set_property_object (GObject **storage,
- GObject *object);
-void ufo_unref_stored_object (GObject **object);
-void ufo_debug_cl (const gchar *format,
- ...);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-buffer.c b/src/ufo-buffer.c
index 34a0f02..655b413 100644
--- a/src/ufo-buffer.c
+++ b/src/ufo-buffer.c
@@ -11,19 +11,13 @@
#include <CL/cl.h>
#endif
-#include "config.h"
-#include "ufo-buffer.h"
-#include "ufo-aux.h"
-#include "ufo-resource-manager.h"
-#include "ufo-enums.h"
+#include <ufo-buffer.h>
+#include <ufo-resources.h>
G_DEFINE_TYPE(UfoBuffer, ufo_buffer, G_TYPE_OBJECT)
#define UFO_BUFFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_BUFFER, UfoBufferPrivate))
-#define UFO_BUFFER_ERROR ufo_buffer_error_quark()
-
-
enum {
PROP_0,
PROP_ID,
@@ -31,15 +25,6 @@ enum {
N_PROPERTIES
};
-static GParamSpec *buffer_properties[N_PROPERTIES] = { NULL, };
-
-
-typedef enum {
- NO_DATA = 0,
- HOST_ARRAY_VALID,
- DEVICE_ARRAY_VALID
-} data_location;
-
typedef struct {
guint num_dims;
gfloat *data;
@@ -48,574 +33,360 @@ typedef struct {
} nd_array;
struct _UfoBufferPrivate {
- nd_array host_array;
- cl_mem device_array;
- data_location location;
-
- gint id; /**< unique id that is passed to the transformed buffer */
- gsize size; /**< size of buffer in bytes */
-
- cl_event *events;
- cl_uint current_event_index; /**< index of currently available event position */
- cl_uint num_total_events; /**< total amount of events we can keep */
-
- GTimer *timer; /**< holds elapsed time for up/download */
- cl_ulong time_upload;
- cl_ulong time_download;
+ nd_array host_array;
+ cl_mem device_array;
+ cl_context context;
+ cl_command_queue last_queue;
+ gsize size; /**< size of buffer in bytes */
+ UfoMemLocation location;
+ GTimer *timer;
};
-/**
- * UfoBufferError:
- * @UFO_BUFFER_ERROR_WRONG_SIZE: Wrongly sized array passed to the buffer
- *
- * Possible errors when using a UfoBuffer.
- */
-GQuark ufo_buffer_error_quark(void)
-{
- return g_quark_from_static_string("ufo-buffer-error-quark");
-}
-
static void
-ufo_buffer_set_dimensions(UfoBuffer *buffer, guint num_dims, const guint *dim_size)
+alloc_mem (UfoBufferPrivate *priv,
+ UfoRequisition *requisition)
{
- g_return_if_fail (UFO_IS_BUFFER(buffer));
- g_return_if_fail ((num_dims > 0) && (num_dims <= UFO_BUFFER_MAX_NDIMS));
- g_return_if_fail (dim_size != NULL);
+ cl_int err;
+
+ if (priv->host_array.data != NULL)
+ g_free (priv->host_array.data);
+
+ if (priv->device_array != NULL)
+ clReleaseMemObject (priv->device_array);
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE(buffer);
priv->size = sizeof(gfloat);
- priv->host_array.num_dims = num_dims;
+ priv->host_array.num_dims = requisition->n_dims;
- for (guint i = 0; i < num_dims; i++) {
- priv->host_array.dim_size[i] = dim_size[i];
- priv->size *= dim_size[i];
+ for (guint i = 0; i < requisition->n_dims; i++) {
+ priv->host_array.dim_size[i] = requisition->dims[i];
+ priv->size *= requisition->dims[i];
}
+
+ priv->host_array.data = g_malloc0 (priv->size);
+ priv->device_array = clCreateBuffer (priv->context,
+ CL_MEM_READ_WRITE, /* XXX: we _should_ evaluate USE_HOST_PTR */
+ priv->size,
+ NULL,
+ &err);
+ UFO_RESOURCES_CHECK_CLERR (err);
+ priv->location = UFO_LOCATION_HOST;
}
/**
* ufo_buffer_new:
- * @num_dims: (in): Number of dimensions
- * @dim_size: (in) (array): Size of each dimension
- *
- * Create a new buffer with the given dimensions.
+ * @requisition: (in): size requisition
+ * @context: (in): cl_context to use for creating the device array
*
* Return value: A new #UfoBuffer with the given dimensions.
*/
UfoBuffer *
-ufo_buffer_new (guint num_dims, const guint *dim_size)
+ufo_buffer_new (UfoRequisition *requisition,
+ gpointer context)
{
- g_return_val_if_fail ((num_dims <= UFO_BUFFER_MAX_NDIMS) && (dim_size != NULL), NULL);
- UfoBuffer *buffer = UFO_BUFFER (g_object_new (UFO_TYPE_BUFFER, NULL));
- ufo_buffer_set_dimensions (buffer, num_dims, dim_size);
+ UfoBuffer *buffer;
+
+ g_return_val_if_fail ((requisition->n_dims <= UFO_BUFFER_MAX_NDIMS), NULL);
+ buffer = UFO_BUFFER (g_object_new (UFO_TYPE_BUFFER, NULL));
+ buffer->priv->context = context;
+
+ alloc_mem (buffer->priv, requisition);
return buffer;
}
-/**
- * ufo_buffer_alloc_host_mem:
- * @buffer: A #UfoBuffer object
- *
- * Allocate host memory for dimensions specified in ufo_buffer_new().
- *
- * Since: 0.2
- */
-void
-ufo_buffer_alloc_host_mem (UfoBuffer *buffer)
+gsize
+ufo_buffer_get_size (UfoBuffer *buffer)
{
- UfoBufferPrivate *priv;
-
- g_return_if_fail (UFO_IS_BUFFER (buffer));
- priv = UFO_BUFFER_GET_PRIVATE (buffer);
-
- if (priv->host_array.data != NULL)
- g_free (priv->host_array.data);
-
- priv->host_array.data = g_malloc0(priv->size);
+ g_return_val_if_fail (UFO_IS_BUFFER (buffer), 0);
+ return buffer->priv->size;
}
-/**
- * ufo_buffer_copy:
- * @src: Source #UfoBuffer
- * @dst: Destination #UfoBuffer
- *
- * Copy the contents of %src into %dst.
- *
- * Since: 0.2
- */
-void
-ufo_buffer_copy (UfoBuffer *src, UfoBuffer *dst)
+static void
+copy_host_to_host (UfoBufferPrivate *src_priv,
+ UfoBufferPrivate *dst_priv)
{
- g_return_if_fail (UFO_IS_BUFFER (src) && UFO_IS_BUFFER (dst));
- g_return_if_fail (src->priv->size == dst->priv->size);
+ g_memmove (dst_priv->host_array.data,
+ src_priv->host_array.data,
+ src_priv->size);
+}
- if (src->priv->location != HOST_ARRAY_VALID) {
- g_warning ("Copying source buffers with invalid or device memory not yet supported");
- return;
- }
+static void
+copy_device_to_device (UfoBufferPrivate *src_priv,
+ UfoBufferPrivate *dst_priv)
+{
+ cl_event event;
- if (dst->priv->host_array.data == NULL)
- ufo_buffer_alloc_host_mem (dst);
+ clEnqueueCopyBuffer (NULL,
+ src_priv->device_array,
+ dst_priv->device_array,
+ 0, 0, /* offsets */
+ src_priv->size,
+ 0, NULL, &event);
- g_memmove (dst->priv->host_array.data, src->priv->host_array.data, src->priv->size);
- dst->priv->location = HOST_ARRAY_VALID;
+ clWaitForEvents (1, &event);
+ clReleaseEvent (event);
}
-/**
- * ufo_buffer_resize:
- * @buffer: A #UfoBuffer
- * @num_dims: New number of dimensions
- * @dim_size: New dimension sizes
- *
- * Resize an existing buffer.
- * Since: 0.2
- */
-void
-ufo_buffer_resize (UfoBuffer *buffer, guint num_dims, const guint *dim_size)
+static void
+ufo_buffer_to_host (UfoBuffer *buffer, gpointer cmd_queue)
{
UfoBufferPrivate *priv;
+ cl_int cl_err;
+ cl_command_queue queue;
- g_return_if_fail ((num_dims <= UFO_BUFFER_MAX_NDIMS) && (dim_size != NULL));
+ g_return_if_fail (UFO_IS_BUFFER (buffer));
+ priv = buffer->priv;
- ufo_buffer_set_dimensions (buffer, num_dims, dim_size);
- priv = UFO_BUFFER_GET_PRIVATE (buffer);
+ if (priv->location == UFO_LOCATION_HOST)
+ return;
- if (priv->host_array.data != NULL) {
- g_free (priv->host_array.data);
- priv->host_array.data = NULL;
- }
+ queue = cmd_queue == NULL ? priv->last_queue : cmd_queue;
+ priv->last_queue = cmd_queue;
- if (priv->device_array != NULL) {
- CHECK_OPENCL_ERROR (clReleaseMemObject (priv->device_array));
- priv->device_array = NULL;
- }
+ cl_err = clEnqueueReadBuffer (queue,
+ priv->device_array,
+ CL_TRUE,
+ 0, priv->size,
+ priv->host_array.data,
+ 0, NULL, NULL);
+
+ priv->location = UFO_LOCATION_HOST;
+ UFO_RESOURCES_CHECK_CLERR (cl_err);
}
-/**
- * ufo_buffer_get_dimensions:
- * @buffer: A #UfoBuffer
- * @num_dims: (out): Location to store the number of dimensions.
- * @dim_size: (out): Location to store the dimensions. If *dim_size is NULL
- * enough space is allocated to hold num_dims elements and should be freed
- * with g_free(). If *dim_size is NULL, the caller must provide enough
- * memory.
- *
- * Retrieve dimensions of buffer.
- */
-void
-ufo_buffer_get_dimensions(UfoBuffer *buffer, guint *num_dims, guint **dim_size)
+static void
+ufo_buffer_to_device (UfoBuffer *buffer, gpointer cmd_queue)
{
- g_return_if_fail(UFO_IS_BUFFER(buffer) || (num_dims == NULL) || (dim_size == NULL));
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE(buffer);
+ UfoBufferPrivate *priv;
+ cl_int cl_err;
+ cl_command_queue queue;
- *num_dims = priv->host_array.num_dims;
+ g_return_if_fail (UFO_IS_BUFFER (buffer));
+ priv = buffer->priv;
- if (*dim_size == NULL)
- *dim_size = g_malloc0(sizeof(guint) * (*num_dims));
+ if (priv->location == UFO_LOCATION_DEVICE)
+ return;
- g_memmove(*dim_size, priv->host_array.dim_size, sizeof(guint) * (*num_dims));
-}
+ queue = cmd_queue == NULL ? priv->last_queue : cmd_queue;
+ priv->last_queue = cmd_queue;
-/**
- * ufo_buffer_get_size:
- * @buffer: A #UfoBuffer
- *
- * Get size of internal data in bytes.
- *
- * Return value: Size of data
- */
-gsize
-ufo_buffer_get_size(UfoBuffer *buffer)
-{
- g_return_val_if_fail(UFO_IS_BUFFER(buffer), 0);
- return buffer->priv->size;
-}
+ cl_err = clEnqueueWriteBuffer ((cl_command_queue) queue,
+ priv->device_array,
+ CL_TRUE,
+ 0, priv->size,
+ priv->host_array.data,
+ 0, NULL, NULL);
-/**
- * ufo_buffer_get_id:
- * @buffer: A #UfoBuffer
- *
- * Get internal identification.
- *
- * Return value: unique and monotone id
- */
-gint
-ufo_buffer_get_id(UfoBuffer *buffer)
-{
- g_return_val_if_fail(UFO_IS_BUFFER(buffer), -1);
- return buffer->priv->id;
+ priv->location = UFO_LOCATION_DEVICE;
+ UFO_RESOURCES_CHECK_CLERR (cl_err);
}
/**
- * ufo_buffer_transfer_id:
- * @from: A #UfoBuffer whose id is copied.
- * @to: UfoBuffer who gets this id
+ * ufo_buffer_copy:
+ * @src: Source #UfoBuffer
+ * @dst: Destination #UfoBuffer
*
- * Transfer id from one buffer to another.
+ * Copy contents of @src to @dst. The final memory location is determined by the
+ * destination buffer.
*/
void
-ufo_buffer_transfer_id(UfoBuffer *from, UfoBuffer *to)
+ufo_buffer_copy (UfoBuffer *src, UfoBuffer *dst)
{
- g_return_if_fail(UFO_IS_BUFFER(from) || (UFO_IS_BUFFER(to)));
- to->priv->id = from->priv->id;
-}
+ g_return_if_fail (UFO_IS_BUFFER (src) && UFO_IS_BUFFER (dst));
+ g_return_if_fail (src->priv->size == dst->priv->size);
-/**
- * ufo_buffer_get_2d_dimensions:
- * @buffer: A #UfoBuffer.
- * @width: (out): Location to store the width of the buffer
- * @height: (out): Location to store the height of the buffer
- *
- * Convenience function to retrieve dimension of buffer.
- */
-void
-ufo_buffer_get_2d_dimensions(UfoBuffer *buffer, guint *width, guint *height)
-{
- g_return_if_fail(UFO_IS_BUFFER(buffer) || (width != NULL) || (height != NULL));
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE(buffer);
- *width = priv->host_array.dim_size[0];
- *height = priv->host_array.dim_size[1];
+ /* Copy depending on location */
+ if (src->priv->location == dst->priv->location) {
+ switch (src->priv->location) {
+ case UFO_LOCATION_HOST:
+ copy_host_to_host (src->priv, dst->priv);
+ break;
+ case UFO_LOCATION_DEVICE:
+ copy_device_to_device (src->priv, dst->priv);
+ break;
+ default:
+ g_warning ("oops, we should not copy invalid data");
+ }
+ }
+ else {
+ if (dst->priv->location == UFO_LOCATION_HOST) {
+ ufo_buffer_to_host (src, NULL);
+ copy_host_to_host (src->priv, dst->priv);
+ }
+ else {
+ ufo_buffer_to_device (src, NULL);
+ copy_device_to_device (src->priv, src->priv);
+ }
+ }
}
/**
- * ufo_buffer_invalidate_gpu_data:
- * @buffer: A #UfoBuffer.
+ * ufo_buffer_dup:
+ * @buffer: A #UfoBuffer
*
- * Invalidate state of a buffer so that Data won't be synchronized between CPU
- * and GPU and must be re-set again with ufo_buffer_set_cpu_data.
- */
-void
-ufo_buffer_invalidate_gpu_data(UfoBuffer *buffer)
-{
- g_return_if_fail(UFO_IS_BUFFER(buffer));
- buffer->priv->location = HOST_ARRAY_VALID;
-}
-
-/**
- * ufo_buffer_reinterpret:
- * @buffer: A #UfoBuffer.
- * @source_depth: The number of bits that make up the original integer data type.
- * @num_pixels: Number of pixels to consider
- * @normalize: Normalize image data to range [0.0, 1.0]
+ * Create a new buffer with the same requisition as @buffer. Note, that this is
+ * not a copy of @buffer!
*
- * The fundamental data type of a UfoBuffer is one single-precision floating
- * point per pixel. To increase performance it is possible to load arbitrary
- * integer into the host array returned by ufo_buffer_get_host_array() and
- * convert that data with this method.
+ * Returns: A #UfoBuffer with the same size as @buffer.
*/
-void
-ufo_buffer_reinterpret(UfoBuffer *buffer, gsize source_depth, gsize num_pixels, gboolean normalize)
+UfoBuffer *
+ufo_buffer_dup (UfoBuffer *buffer)
{
- g_return_if_fail (UFO_IS_BUFFER(buffer));
- gfloat *dst = buffer->priv->host_array.data;
-
- /* To save a memory allocation and several copies, we process data from back
- * to front. This is possible if src bit depth is at most half as wide as
- * the 32-bit target buffer. The processor cache should not be a problem. */
- if (source_depth == 8) {
- guint8 *src = (guint8 *) buffer->priv->host_array.data;
- const float scale = normalize ? 255.0f : 1.0f;
-
- for (gint index = (((gint) num_pixels) - 1); index >= 0; index--)
- dst[index] = ((gfloat) src[index]) / scale;
- }
- else if (source_depth == 16) {
- guint16 *src = (guint16 *) buffer->priv->host_array.data;
- const float scale = normalize ? 65535.0f : 1.0f;
+ UfoBuffer *copy;
+ UfoRequisition requisition;
- for (gint index = (((gint) num_pixels) - 1); index >= 0; index--)
- dst[index] = ((gfloat) src[index]) / scale;
- }
+ ufo_buffer_get_requisition (buffer, &requisition);
+ copy = ufo_buffer_new (&requisition, buffer->priv->context);
+ return copy;
}
/**
- * ufo_buffer_fill_with_value:
- * @buffer: A #UfoBuffer.
- * @value: Buffer is filled with this value
+ * ufo_buffer_resize:
+ * @buffer: A #UfoBuffer
+ * @requisition: A #UfoRequisition structure
*
- * Fill buffer with the same value.
+ * Resize an existing buffer. If the new requisition has the same size as
+ * before, resizing is a no-op.
+ *
+ * Since: 0.2
*/
-void ufo_buffer_fill_with_value (UfoBuffer* buffer, gfloat value)
+void
+ufo_buffer_resize (UfoBuffer *buffer,
+ UfoRequisition *requisition)
{
UfoBufferPrivate *priv;
- gfloat *data;
- guint n_elements = 1;
- g_return_if_fail (UFO_IS_BUFFER(buffer));
+ g_return_if_fail (UFO_IS_BUFFER (buffer));
priv = UFO_BUFFER_GET_PRIVATE (buffer);
- data = ufo_buffer_get_host_array (buffer, NULL);
- for (guint i = 0; i < priv->host_array.num_dims; i++)
- n_elements *= priv->host_array.dim_size[i];
+ if (priv->host_array.data != NULL) {
+ g_free (priv->host_array.data);
+ priv->host_array.data = NULL;
+ }
- for (guint i = 0; i < n_elements; i++)
- data[i] = value;
+ if (priv->device_array != NULL) {
+ UFO_RESOURCES_CHECK_CLERR (clReleaseMemObject (priv->device_array));
+ priv->device_array = NULL;
+ }
- priv->location = HOST_ARRAY_VALID;
+ alloc_mem (priv, requisition);
}
/**
- * ufo_buffer_set_cl_mem:
- * @buffer: A #UfoBuffer.
- * @mem: A cl_mem object.
+ * ufo_buffer_cmp_dimensions:
+ * @buffer: A #UfoBuffer
+ * @requisition: #UfoRequisition
*
- * Set OpenCL memory object that is used to up and download data.
+ * Compare the size of @buffer with a given @requisition.
+ *
+ * Returns: value < 0, 0 or > 0 if requisition is smaller, equal or larger.
*/
-void
-ufo_buffer_set_cl_mem(UfoBuffer *buffer, gpointer mem)
+gint
+ufo_buffer_cmp_dimensions (UfoBuffer *buffer,
+ UfoRequisition *requisition)
{
- g_return_if_fail (UFO_IS_BUFFER(buffer) || (mem != NULL));
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE (buffer);
- cl_mem mem_object = (cl_mem) mem;
- gsize mem_size;
+ gint result;
+ g_return_val_if_fail (UFO_IS_BUFFER(buffer), FALSE);
- CHECK_OPENCL_ERROR (clGetMemObjectInfo (mem_object, CL_MEM_SIZE, sizeof(gsize), &mem_size, NULL));
+ result = 0;
- if (mem_size != priv->size)
- g_warning ("Buffer size is different from OpenCL memory object size");
-
- priv->device_array = (cl_mem) mem_object;
-}
-
-/**
- * ufo_buffer_attach_event:
- * @buffer: A #UfoBuffer.
- * @event: A cl_event object.
- *
- * Attach an OpenCL event to a buffer that must be finished before anything else
- * can be done with this buffer.
- */
-void
-ufo_buffer_attach_event(UfoBuffer *buffer, gpointer event)
-{
- g_return_if_fail(UFO_IS_BUFFER(buffer) || (event != NULL));
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE(buffer);
- priv->events[priv->current_event_index++] = (cl_event) event;
-
- if (priv->current_event_index == priv->num_total_events) {
- priv->num_total_events *= 2;
- priv->events = g_realloc(priv->events, priv->num_total_events * sizeof(cl_event));
- g_debug("Reallocated event array to %i elements\n", priv->num_total_events);
+ for (guint i = 0; i < buffer->priv->host_array.num_dims; i++) {
+ gint req_dim = (gint) requisition->dims[i];
+ gint host_dim = (gint) buffer->priv->host_array.dim_size[i];
+ result += req_dim - host_dim;
}
-}
-/**
- * ufo_buffer_get_events:
- * @buffer: A #UfoBuffer.
- * @events: (out) (transfer none): Location to store pointer of events.
- * @num_events: (out): Location to store the length of the event array.
- *
- * Return events currently associated with a buffer but don't release them from
- * this buffer.
- */
-void
-ufo_buffer_get_events(UfoBuffer *buffer, gpointer **events, guint *num_events)
-{
- g_return_if_fail(UFO_IS_BUFFER(buffer) || (events != NULL) || (num_events != NULL));
- *num_events = buffer->priv->current_event_index;
- *events = (gpointer *) buffer->priv->events;
+ return result;
}
/**
- * ufo_buffer_clear_events:
- * @buffer: A #UfoBuffer.
+ * ufo_buffer_get_requisition:
+ * @buffer: A #UfoBuffer
+ * @requisition: (out): A location to store the requisition of @buffer
*
- * Clear and release events associated with a buffer
+ * Return the size of @buffer.
*/
void
-ufo_buffer_clear_events(UfoBuffer *buffer)
+ufo_buffer_get_requisition (UfoBuffer *buffer,
+ UfoRequisition *requisition)
{
- g_return_if_fail(UFO_IS_BUFFER(buffer));
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE(buffer);
+ UfoBufferPrivate *priv;
- for (guint i = 0; i < priv->current_event_index; i++)
- clReleaseEvent(priv->events[i]);
+ g_return_if_fail (UFO_IS_BUFFER (buffer) && (requisition != NULL));
+ priv = buffer->priv;
+ requisition->n_dims = priv->host_array.num_dims;
- priv->current_event_index = 0;
-}
-
-/**
- * ufo_buffer_get_transfer_timer: (skip)
- * @buffer: A #UfoBuffer.
- *
- * Each buffer has a timer object that measures time spent for transfering data
- * between host and device.
- *
- * Returns: A #GTimer associated with this buffer
- */
-GTimer *
-ufo_buffer_get_transfer_timer(UfoBuffer *buffer)
-{
- g_return_val_if_fail(UFO_IS_BUFFER(buffer), NULL);
- return buffer->priv->timer;
+ for (guint i = 0; i < priv->host_array.num_dims; i++)
+ requisition->dims[i] = priv->host_array.dim_size[i];
}
/**
- * ufo_buffer_set_host_array:
+ * ufo_buffer_get_2d_dimensions:
* @buffer: A #UfoBuffer.
- * @data: User supplied data
- * @num_bytes: Size of data in bytes
- * @error: Pointer to GError*
+ * @width: (out): Location to store the width of the buffer
+ * @height: (out): Location to store the height of the buffer
*
- * Fill buffer with data. This method does not take ownership of data, it just
- * copies the data off of it because we never know if there is enough memory to
- * hold floats of that data.
+ * Convenience function to retrieve dimension of buffer.
*/
void
-ufo_buffer_set_host_array(UfoBuffer *buffer, gfloat *data, gsize num_bytes, GError **error)
+ufo_buffer_get_2d_dimensions (UfoBuffer *buffer,
+ guint *width,
+ guint *height)
{
- g_return_if_fail(UFO_IS_BUFFER(buffer) || (data != NULL));
- UfoBufferPrivate *priv = buffer->priv;
-
- if (num_bytes > priv->size) {
- if (error != NULL) {
- g_set_error(error,
- UFO_BUFFER_ERROR,
- UFO_BUFFER_ERROR_WRONG_SIZE,
- "Trying to set more data than buffer dimensions allow");
- }
-
- return;
- }
-
- if (priv->host_array.data == NULL)
- ufo_buffer_alloc_host_mem (buffer);
-
- g_memmove(priv->host_array.data, data, num_bytes);
- priv->location = HOST_ARRAY_VALID;
+ g_return_if_fail (UFO_IS_BUFFER(buffer) || (width != NULL) || (height != NULL));
+ *width = buffer->priv->host_array.dim_size[0];
+ *height = buffer->priv->host_array.dim_size[1];
}
/**
* ufo_buffer_get_host_array:
* @buffer: A #UfoBuffer.
- * @command_queue: A cl_command_queue object.
+ * @cmd_queue: (allow-none): A cl_command_queue object or %NULL.
*
* Returns a flat C-array containing the raw float data.
*
- * Return value: Float array.
+ * Returns: Float array.
*/
gfloat *
-ufo_buffer_get_host_array(UfoBuffer *buffer, gpointer command_queue)
+ufo_buffer_get_host_array (UfoBuffer *buffer, gpointer cmd_queue)
{
- g_return_val_if_fail(UFO_IS_BUFFER(buffer), NULL);
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE(buffer);
-
- switch (priv->location) {
- case HOST_ARRAY_VALID:
- /* This can be the case, when a buffer's device memory was invalidated
- * but no host memory has been allocated before. */
- if (priv->host_array.data == NULL)
- ufo_buffer_alloc_host_mem (buffer);
-
- break;
-
- case DEVICE_ARRAY_VALID:
- if (priv->host_array.data == NULL)
- ufo_buffer_alloc_host_mem (buffer);
-
- g_timer_start(priv->timer);
- CHECK_OPENCL_ERROR(clEnqueueReadBuffer(command_queue,
- priv->device_array,
- CL_TRUE,
- 0, priv->size,
- priv->host_array.data,
- 0, NULL, NULL));
- g_timer_stop(priv->timer);
- /* TODO: Can we release the events here? */
- priv->current_event_index = 0;
- priv->location = HOST_ARRAY_VALID;
- break;
-
- case NO_DATA:
- ufo_buffer_alloc_host_mem (buffer);
- priv->location = HOST_ARRAY_VALID;
- break;
- }
-
- return priv->host_array.data;
+ g_return_val_if_fail (UFO_IS_BUFFER (buffer), NULL);
+ ufo_buffer_to_host (buffer, cmd_queue);
+ return buffer->priv->host_array.data;
}
/**
- * ufo_buffer_get_device_array: (skip)
- * @buffer: A #UfoBuffer
- * @command_queue: A cl_command_queue object that is used to access the device
- * memory.
+ * ufo_buffer_get_device_array:
+ * @buffer: A #UfoBuffer.
+ * @cmd_queue: (allow-none): A cl_command_queue object or %NULL.
*
- * Get OpenCL memory object that is used to up and download data.
+ * Return the current cl_mem object of @buffer. If the data is not yet in device
+ * memory, it is transfered via @cmd_queue to the object. If @cmd_queue is %NULL
+ * @cmd_queue, the last used command queue is used.
*
- * Return value: OpenCL memory object associated with this #UfoBuffer.
+ * Returns: A cl_mem object associated with @buffer.
*/
gpointer
-ufo_buffer_get_device_array(UfoBuffer *buffer, gpointer command_queue)
+ufo_buffer_get_device_array (UfoBuffer *buffer, gpointer cmd_queue)
{
- g_return_val_if_fail(UFO_IS_BUFFER(buffer) || (command_queue != NULL), NULL);
- UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE(buffer);
- cl_event event;
- cl_int cl_err = CL_SUCCESS;
-
- switch (priv->location) {
- case HOST_ARRAY_VALID:
- if (priv->device_array == NULL)
- priv->device_array = clCreateBuffer(NULL, CL_MEM_READ_WRITE, priv->size, NULL, &cl_err);
-
- CHECK_OPENCL_ERROR (cl_err);
-
- g_timer_start(priv->timer);
- CHECK_OPENCL_ERROR(clEnqueueWriteBuffer((cl_command_queue) command_queue,
- priv->device_array,
- CL_TRUE,
- 0, priv->size,
- priv->host_array.data,
- 0, NULL, &event));
- g_timer_stop(priv->timer);
- priv->location = DEVICE_ARRAY_VALID;
- break;
-
- case DEVICE_ARRAY_VALID:
- break;
-
- case NO_DATA:
- if (priv->device_array) {
- priv->location = DEVICE_ARRAY_VALID;
- break;
- }
-
- return NULL;
- }
-
- return priv->device_array;
+ g_return_val_if_fail (UFO_IS_BUFFER (buffer), NULL);
+ ufo_buffer_to_device (buffer, cmd_queue);
+ return buffer->priv->device_array;
}
/**
- * ufo_buffer_swap_host_arrays:
- * @a: A #UfoBuffer
- * @b: A #UfoBuffer
+ * ufo_buffer_discard_location:
+ * @buffer: A #UfoBuffer
+ * @location: Location to discard
*
- * Swap host array pointers of @a and @b and mark host arrays valid.
+ * Discard @location and use "other" location without copying to it first.
*/
void
-ufo_buffer_swap_host_arrays(UfoBuffer *a, UfoBuffer *b)
+ufo_buffer_discard_location (UfoBuffer *buffer,
+ UfoMemLocation location)
{
- g_return_if_fail(UFO_IS_BUFFER(a) && UFO_IS_BUFFER(b));
-
- UfoBufferPrivate *pa = a->priv;
- UfoBufferPrivate *pb = b->priv;
-
- /* TODO: also check size of dimensions? */
- g_return_if_fail(pa->host_array.num_dims == pb->host_array.num_dims);
- g_return_if_fail((pa->host_array.data != NULL) || (pb->host_array.data != NULL));
-
- if (pa->host_array.data == NULL)
- ufo_buffer_alloc_host_mem (a);
-
- if (pb->host_array.data == NULL)
- ufo_buffer_alloc_host_mem (b);
-
- gfloat *tmp = pa->host_array.data;
- pa->host_array.data = pb->host_array.data;
- pb->host_array.data = tmp;
-
- pa->location = HOST_ARRAY_VALID;
- pb->location = HOST_ARRAY_VALID;
+ g_return_if_fail (UFO_IS_BUFFER (buffer));
+ buffer->priv->location = location == UFO_LOCATION_HOST ? UFO_LOCATION_DEVICE : UFO_LOCATION_HOST;
}
/**
@@ -644,98 +415,54 @@ ufo_buffer_param_spec(const gchar *name, const gchar *nick, const gchar *blurb,
return G_PARAM_SPEC(bspec);
}
-
-static void
-ufo_filter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- UfoBuffer *buffer = UFO_BUFFER(object);
-
- switch (property_id) {
- case PROP_ID:
- buffer->priv->id = g_value_get_int(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_filter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- UfoBuffer *buffer = UFO_BUFFER(object);
-
- switch (property_id) {
- case PROP_ID:
- g_value_set_int(value, buffer->priv->id);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
static void
-ufo_buffer_finalize(GObject *gobject)
+ufo_buffer_finalize (GObject *gobject)
{
UfoBuffer *buffer = UFO_BUFFER (gobject);
UfoBufferPrivate *priv = UFO_BUFFER_GET_PRIVATE (buffer);
- if (priv->host_array.data != NULL)
+ if (priv->host_array.data != NULL) {
g_free (priv->host_array.data);
+ priv->host_array.data = NULL;
+ }
- if (priv->device_array != NULL)
- CHECK_OPENCL_ERROR (clReleaseMemObject (priv->device_array));
-
- priv->host_array.data = NULL;
- priv->device_array = NULL;
+ if (priv->device_array != NULL) {
+ UFO_RESOURCES_CHECK_CLERR (clReleaseMemObject (priv->device_array));
+ priv->device_array = NULL;
+ }
- g_timer_destroy(priv->timer);
- g_free(priv->events);
+ if (priv->timer != NULL) {
+ g_timer_destroy (priv->timer);
+ priv->timer = NULL;
+ }
G_OBJECT_CLASS(ufo_buffer_parent_class)->finalize(gobject);
}
static void
-ufo_buffer_class_init(UfoBufferClass *klass)
+ufo_buffer_class_init (UfoBufferClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->set_property = ufo_filter_set_property;
- gobject_class->get_property = ufo_filter_get_property;
gobject_class->finalize = ufo_buffer_finalize;
- buffer_properties[PROP_ID] =
- g_param_spec_int("id",
- "ID of this buffer",
- "ID of this buffer",
- -1, G_MAXINT, 0,
- G_PARAM_READWRITE);
-
- g_object_class_install_property(gobject_class, PROP_ID, buffer_properties[PROP_ID]);
-
g_type_class_add_private(klass, sizeof(UfoBufferPrivate));
}
static void
-ufo_buffer_init(UfoBuffer *buffer)
+ufo_buffer_init (UfoBuffer *buffer)
{
UfoBufferPrivate *priv;
buffer->priv = priv = UFO_BUFFER_GET_PRIVATE(buffer);
- priv->id = -1;
+ priv->last_queue = NULL;
priv->device_array = NULL;
priv->host_array.data = NULL;
priv->host_array.num_dims = 0;
- priv->location = NO_DATA;
- priv->current_event_index = 0;
- priv->num_total_events = 8;
- priv->events = g_malloc0(priv->num_total_events * sizeof(cl_event));
- priv->time_upload = 0;
- priv->time_download = 0;
- priv->timer = g_timer_new();
+ priv->timer = g_timer_new ();
+ g_timer_stop (priv->timer);
}
static void
-ufo_buffer_param_init(GParamSpec *pspec)
+ufo_buffer_param_init (GParamSpec *pspec)
{
UfoBufferParamSpec *bspec = UFO_BUFFER_PARAM_SPEC(pspec);
@@ -743,7 +470,7 @@ ufo_buffer_param_init(GParamSpec *pspec)
}
static void
-ufo_buffer_param_set_default(GParamSpec *pspec, GValue *value)
+ufo_buffer_param_set_default (GParamSpec *pspec, GValue *value)
{
UfoBufferParamSpec *bspec = UFO_BUFFER_PARAM_SPEC(pspec);
diff --git a/src/ufo-buffer.h b/src/ufo-buffer.h
index c9faeed..d0d504e 100644
--- a/src/ufo-buffer.h
+++ b/src/ufo-buffer.h
@@ -17,14 +17,22 @@ G_BEGIN_DECLS
#define UFO_BUFFER_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_CAST((pspec), UFO_TYPE_PARAM_BUFFER, UfoBufferParamSpec))
#define UFO_BUFFER_ERROR ufo_buffer_error_quark()
+
typedef enum {
UFO_BUFFER_ERROR_WRONG_SIZE
} UfoBufferError;
+typedef enum {
+ UFO_LOCATION_INVALID,
+ UFO_LOCATION_HOST,
+ UFO_LOCATION_DEVICE
+} UfoMemLocation;
+
typedef struct _UfoBuffer UfoBuffer;
typedef struct _UfoBufferClass UfoBufferClass;
typedef struct _UfoBufferPrivate UfoBufferPrivate;
typedef struct _UfoBufferParamSpec UfoBufferParamSpec;
+typedef struct _UfoRequisition UfoRequisition;
/**
* UfoBuffer:
@@ -46,7 +54,7 @@ struct _UfoBuffer {
* of const variable because of <ulink
* url="http://c-faq.com/ansi/constasconst.html">C constraints</ulink>.
*/
-#define UFO_BUFFER_MAX_NDIMS 32
+#define UFO_BUFFER_MAX_NDIMS 8
/**
* UfoBufferClass:
@@ -59,6 +67,18 @@ struct _UfoBufferClass {
};
/**
+ * UfoRequisition:
+ * @n_dims: Number of dimensions
+ * @dims: Size of dimension
+ *
+ * Used to specify buffer size requirements.
+ */
+struct _UfoRequisition {
+ guint n_dims;
+ guint dims[UFO_BUFFER_MAX_NDIMS];
+};
+
+/**
* UfoBufferParamSpec:
*
* UfoBufferParamSpec class
@@ -70,50 +90,27 @@ struct _UfoBufferParamSpec {
UfoBuffer *default_value;
};
-UfoBuffer* ufo_buffer_new (guint num_dims,
- const guint *dim_size);
-void ufo_buffer_alloc_host_mem (UfoBuffer *buffer);
-void ufo_buffer_resize (UfoBuffer *buffer,
- guint num_dims,
- const guint *dim_size);
-void ufo_buffer_copy (UfoBuffer *src,
- UfoBuffer *dst);
-void ufo_buffer_transfer_id (UfoBuffer *from,
- UfoBuffer *to);
-gsize ufo_buffer_get_size (UfoBuffer *buffer);
-gint ufo_buffer_get_id (UfoBuffer *buffer);
-void ufo_buffer_get_dimensions (UfoBuffer *buffer,
- guint* num_dims,
- guint** dim_size);
-void ufo_buffer_get_2d_dimensions (UfoBuffer* buffer,
- guint* width,
- guint* height);
-void ufo_buffer_reinterpret (UfoBuffer* buffer,
- gsize source_depth,
- gsize num_pixels,
- gboolean normalize);
-void ufo_buffer_fill_with_value (UfoBuffer* buffer,
- gfloat value);
-void ufo_buffer_set_host_array (UfoBuffer* buffer,
- gfloat* data,
- gsize num_bytes,
- GError** error);
-gfloat* ufo_buffer_get_host_array (UfoBuffer *buffer,
- gpointer command_queue);
-GTimer* ufo_buffer_get_transfer_timer (UfoBuffer *buffer);
-void ufo_buffer_swap_host_arrays (UfoBuffer *a,
- UfoBuffer *b);
-gpointer ufo_buffer_get_device_array (UfoBuffer *buffer,
- gpointer command_queue);
-void ufo_buffer_invalidate_gpu_data (UfoBuffer* buffer);
-void ufo_buffer_set_cl_mem (UfoBuffer* buffer,
- gpointer mem);
-void ufo_buffer_attach_event (UfoBuffer* buffer,
- gpointer event);
-void ufo_buffer_get_events (UfoBuffer* buffer,
- gpointer** events,
- guint* num_events);
-void ufo_buffer_clear_events (UfoBuffer* buffer);
+UfoBuffer* ufo_buffer_new (UfoRequisition *requisition,
+ gpointer context);
+void ufo_buffer_resize (UfoBuffer *buffer,
+ UfoRequisition *requisition);
+gint ufo_buffer_cmp_dimensions (UfoBuffer *buffer,
+ UfoRequisition *requisition);
+void ufo_buffer_get_requisition (UfoBuffer *buffer,
+ UfoRequisition *requisition);
+gsize ufo_buffer_get_size (UfoBuffer *buffer);
+void ufo_buffer_get_2d_dimensions (UfoBuffer *buffer,
+ guint *width,
+ guint *height);
+void ufo_buffer_copy (UfoBuffer *src,
+ UfoBuffer *dst);
+UfoBuffer *ufo_buffer_dup (UfoBuffer *buffer);
+gfloat* ufo_buffer_get_host_array (UfoBuffer *buffer,
+ gpointer cmd_queue);
+gpointer ufo_buffer_get_device_array (UfoBuffer *buffer,
+ gpointer cmd_queue);
+void ufo_buffer_discard_location (UfoBuffer *buffer,
+ UfoMemLocation location);
GType ufo_buffer_get_type (void);
GQuark ufo_buffer_error_quark (void);
diff --git a/src/ufo-channel.c b/src/ufo-channel.c
deleted file mode 100644
index df5d0d6..0000000
--- a/src/ufo-channel.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/**
- * SECTION:ufo-channel
- * @Short_description: Data transport between two UfoFilters
- * @Title: UfoChannel
- *
- * A channel encapsulates the data transfer from one filter that outputs data to
- * one that receives that as an input. Channels can be daisy-chained so that the
- * second channel receives the same data as the first one.
- */
-
-#include <string.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-resource-manager.h"
-#include "ufo-channel.h"
-
-G_DEFINE_TYPE(UfoChannel, ufo_channel, G_TYPE_OBJECT)
-
-#define UFO_CHANNEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_CHANNEL, UfoChannelPrivate))
-
-struct _UfoChannelPrivate {
- gint ref_count;
- GAsyncQueue *input_queue;
- GAsyncQueue *output_queue;
- UfoChannel *next;
-};
-
-/**
- * ufo_channel_new:
- *
- * Creates a new #UfoChannel.
- *
- * Return value: A new #UfoChannel
- */
-UfoChannel *
-ufo_channel_new (void)
-{
- UfoChannel *channel = UFO_CHANNEL (g_object_new (UFO_TYPE_CHANNEL, NULL));
- return channel;
-}
-
-/**
- * ufo_channel_ref:
- * @channel: A #UfoChannel
- *
- * Reference a channel if to be used as an output.
- */
-void
-ufo_channel_ref (UfoChannel *channel)
-{
- g_return_if_fail (UFO_IS_CHANNEL (channel));
- g_atomic_int_inc (&channel->priv->ref_count);
-}
-
-/**
- * ufo_channel_finish:
- * @channel: A #UfoChannel
- *
- * Finish using this channel and notify subsequent filters that no more
- * data can be expected.
- */
-void
-ufo_channel_finish (UfoChannel *channel)
-{
- UfoChannelPrivate *priv;
-
- g_return_if_fail (UFO_IS_CHANNEL (channel));
- priv = UFO_CHANNEL_GET_PRIVATE (channel);
-
- for (gint i = 0; i < priv->ref_count; i++)
- g_async_queue_push (priv->input_queue, GINT_TO_POINTER (1));
-}
-
-/**
- * ufo_channel_finish_next:
- * @channel: A #UfoChannel
- *
- * Finish using this channel. If @channel has a daisy-chained channel, it will
- * also be finished.
- */
-void
-ufo_channel_finish_next (UfoChannel *channel)
-{
- UfoChannelPrivate *priv;
-
- g_return_if_fail (UFO_IS_CHANNEL (channel));
- priv = UFO_CHANNEL_GET_PRIVATE (channel);
-
- ufo_channel_finish (channel);
-
- if (priv->next != NULL)
- ufo_channel_finish (priv->next);
-}
-
-/**
- * ufo_channel_insert:
- * @channel: A #UfoChannel
- * @buffer: A #UfoBuffer to be inserted
- *
- * Inserts an initial @buffer that can be consumed with
- * ufo_channel_fetch_output().
- */
-void
-ufo_channel_insert (UfoChannel *channel,
- UfoBuffer *buffer)
-{
- g_return_if_fail (UFO_IS_CHANNEL (channel));
-
- if (channel->priv->next != NULL) {
- UfoChannel *next = channel->priv->next;
-
- while (next->priv->next != NULL)
- next = next->priv->next;
-
- g_async_queue_push (next->priv->output_queue, buffer);
- }
- else
- g_async_queue_push (channel->priv->output_queue, buffer);
-}
-
-/**
- * ufo_channel_fetch_input: (skip)
- * @channel: A #UfoChannel
- *
- * Get a new buffer from the channel that can be consumed as an input. This
- * method blocks execution as long as no new input buffer the available from the
- * preceding filter. Use ufo_channel_release_input() to return the buffer to the
- * channel.
- *
- * Return value: The next #UfoBuffer input
- */
-UfoBuffer *
-ufo_channel_fetch_input (UfoChannel *channel)
-{
- g_return_val_if_fail (UFO_IS_CHANNEL (channel), NULL);
- return g_async_queue_pop (channel->priv->input_queue);
-}
-
-/**
- * ufo_channel_release_input:
- * @channel: A #UfoChannel
- * @buffer: A #UfoBuffer acquired with ufo_channel_fetch_input()
- *
- * Release a buffer that was acquired with ufo_channel_fetch_input().
- */
-void
-ufo_channel_release_input (UfoChannel *channel, UfoBuffer *buffer)
-{
- g_return_if_fail (UFO_IS_CHANNEL (channel));
-
- if (channel->priv->next != NULL)
- g_async_queue_push (channel->priv->next->priv->input_queue, buffer);
- else
- g_async_queue_push (channel->priv->output_queue, buffer);
-}
-
-/**
- * ufo_channel_fetch_output: (skip)
- * @channel: A #UfoChannel
- *
- * Get a new buffer from the channel that can be consumed as an output. This
- * method blocks execution as long as no new input buffer the available from the
- * successing filter. Use ufo_channel_release_output() to return the buffer to
- * the channel.
- *
- * Return value: The next #UfoBuffer for output
- */
-UfoBuffer *
-ufo_channel_fetch_output (UfoChannel *channel)
-{
- UfoChannel *next;
-
- g_return_val_if_fail (UFO_IS_CHANNEL (channel), NULL);
-
- next = channel->priv->next;
-
- if (next == NULL) {
- return g_async_queue_pop (channel->priv->output_queue);
- }
- else {
- while (next->priv->next != NULL)
- next = next->priv->next;
-
- return g_async_queue_pop (next->priv->output_queue);
- }
-}
-
-/**
- * ufo_channel_release_output:
- * @channel: A #UfoChannel
- * @buffer: A #UfoBuffer acquired with ufo_channel_fetch_output()
- *
- * Release a buffer that was acquired with ufo_channel_fetch_output().
- */
-void
-ufo_channel_release_output (UfoChannel *channel, UfoBuffer *buffer)
-{
- g_return_if_fail (UFO_IS_CHANNEL (channel) && UFO_IS_BUFFER (buffer));
- g_async_queue_push (channel->priv->input_queue, buffer);
-}
-
-/**
- * ufo_channel_daisy_chain:
- * @channel: A #UfoChannel
- * @next: A #UfoChannel that is appended to @channel
- *
- * Appends @next to @channel, so that both become siblings and share the same
- * input. You should not use this function directly as it makes most sense for
- * the scheduler when connecting to filters.
- */
-void ufo_channel_daisy_chain (UfoChannel *channel,
- UfoChannel *next)
-{
- g_return_if_fail (UFO_IS_CHANNEL (channel) && UFO_IS_CHANNEL (next));
- channel->priv->next = next;
-}
-
-static void
-ufo_channel_dispose (GObject *object)
-{
- G_OBJECT_CLASS (ufo_channel_parent_class)->dispose (object);
-}
-
-static void
-ufo_channel_finalize (GObject *object)
-{
- UfoChannelPrivate *priv = UFO_CHANNEL_GET_PRIVATE (object);
-
- g_async_queue_unref (priv->input_queue);
- g_async_queue_unref (priv->output_queue);
-
- G_OBJECT_CLASS (ufo_channel_parent_class)->finalize (object);
-}
-
-static void
-ufo_channel_class_init (UfoChannelClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->dispose = ufo_channel_dispose;
- gobject_class->finalize = ufo_channel_finalize;
- g_type_class_add_private (klass, sizeof (UfoChannelPrivate));
-}
-
-static void
-ufo_channel_init (UfoChannel *channel)
-{
- UfoChannelPrivate *priv;
- channel->priv = priv = UFO_CHANNEL_GET_PRIVATE (channel);
-
- priv->ref_count = 0;
- priv->input_queue = g_async_queue_new ();
- priv->output_queue = g_async_queue_new ();
- priv->next = NULL;
-}
diff --git a/src/ufo-channel.h b/src/ufo-channel.h
deleted file mode 100644
index 2d14b1b..0000000
--- a/src/ufo-channel.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __UFO_CHANNEL_H
-#define __UFO_CHANNEL_H
-
-#include <glib-object.h>
-#include "ufo-buffer.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_CHANNEL (ufo_channel_get_type())
-#define UFO_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_CHANNEL, UfoChannel))
-#define UFO_IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_CHANNEL))
-#define UFO_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_CHANNEL, UfoChannelClass))
-#define UFO_IS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_CHANNEL))
-#define UFO_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_CHANNEL, UfoChannelClass))
-
-typedef struct _UfoChannel UfoChannel;
-typedef struct _UfoChannelClass UfoChannelClass;
-typedef struct _UfoChannelPrivate UfoChannelPrivate;
-
-/**
- * UfoChannel:
- *
- * Data transport channel between two #UfoFilter objects. The contents of the
- * #UfoChannel structure are private and should only be accessed via the
- * provided API.
- */
-struct _UfoChannel {
- /*< private >*/
- GObject parent_instance;
-
- UfoChannelPrivate *priv;
-};
-
-/**
- * UfoChannelClass:
- *
- * #UfoChannel class
- */
-struct _UfoChannelClass {
- /*< private >*/
- GObjectClass parent_class;
-};
-
-UfoChannel *ufo_channel_new (void);
-void ufo_channel_ref (UfoChannel *channel);
-void ufo_channel_finish (UfoChannel *channel);
-void ufo_channel_finish_next (UfoChannel *channel);
-void ufo_channel_insert (UfoChannel *channel,
- UfoBuffer *buffer);
-UfoBuffer * ufo_channel_fetch_input (UfoChannel *channel);
-void ufo_channel_release_input (UfoChannel *channel,
- UfoBuffer *buffer);
-UfoBuffer * ufo_channel_fetch_output (UfoChannel *channel);
-void ufo_channel_release_output (UfoChannel *channel,
- UfoBuffer *buffer);
-void ufo_channel_daisy_chain (UfoChannel *channel,
- UfoChannel *next);
-GType ufo_channel_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-configuration.c b/src/ufo-config.c
index cf5c766..fac2e32 100644
--- a/src/ufo-configuration.c
+++ b/src/ufo-config.c
@@ -1,23 +1,22 @@
/**
- * SECTION:ufo-configuration
+ * SECTION:ufo-config
* @Short_description: Access run-time specific settings
- * @Title: UfoConfiguration
+ * @Title: UfoConfig
*
- * A #UfoConfiguration object is used to keep settings that affect the run-time
+ * A #UfoConfig object is used to keep settings that affect the run-time
* rather than the parameters of the filter graph. Each object that implements
- * the #UfoConfigurable interface can receive a #UfoConfiguration object and use
+ * the #UfoConfigurable interface can receive a #UfoConfig object and use
* the information stored in it.
*/
-#include "ufo-configuration.h"
-#include "ufo-profiler.h"
-#include "ufo-enums.h"
+#include <ufo-config.h>
+#include <ufo-profiler.h>
+#include <ufo-enums.h>
#include "config.h"
+G_DEFINE_TYPE(UfoConfig, ufo_config, G_TYPE_OBJECT)
-G_DEFINE_TYPE(UfoConfiguration, ufo_configuration, G_TYPE_OBJECT)
-
-#define UFO_CONFIGURATION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_CONFIGURATION, UfoConfigurationPrivate))
+#define UFO_CONFIG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_CONFIG, UfoConfigPrivate))
enum {
PROP_0,
@@ -27,7 +26,7 @@ enum {
N_PROPERTIES
};
-struct _UfoConfigurationPrivate {
+struct _UfoConfigPrivate {
GValueArray *path_array;
UfoProfilerLevel profile_level;
gchar *profile_output_prefix;
@@ -36,21 +35,21 @@ struct _UfoConfigurationPrivate {
static GParamSpec *config_properties[N_PROPERTIES] = { NULL, };
/**
- * ufo_configuration_new:
+ * ufo_config_new:
*
- * Create a configuration object.
+ * Create a config object.
*
- * Return value: A new configuration object.
+ * Return value: A new config object.
*/
-UfoConfiguration *
-ufo_configuration_new (void)
+UfoConfig *
+ufo_config_new (void)
{
- return UFO_CONFIGURATION (g_object_new (UFO_TYPE_CONFIGURATION, NULL));
+ return UFO_CONFIG (g_object_new (UFO_TYPE_CONFIG, NULL));
}
/**
- * ufo_configuration_get_paths:
- * @config: A #UfoConfiguration object
+ * ufo_config_get_paths:
+ * @config: A #UfoConfig object
*
* Get an array of path strings.
*
@@ -59,13 +58,13 @@ ufo_configuration_new (void)
* g_strfreev() to free it.
*/
gchar **
-ufo_configuration_get_paths (UfoConfiguration *config)
+ufo_config_get_paths (UfoConfig *config)
{
GValueArray *path_array;
gchar **paths;
guint n_paths;
- g_return_val_if_fail (UFO_IS_CONFIGURATION (config), NULL);
+ g_return_val_if_fail (UFO_IS_CONFIG (config), NULL);
path_array = config->priv->path_array;
n_paths = path_array->n_values;
@@ -79,20 +78,20 @@ ufo_configuration_get_paths (UfoConfiguration *config)
}
/**
- * ufo_configuration_add_path:
- * @config: A #UfoConfiguration object
+ * ufo_config_add_path:
+ * @config: A #UfoConfig object
* @path: A %NULL-terminated string denoting a path
*
* Add a path to the list of paths that are searched by #UfoPluginManager and
* #UfoResourceManager.
*/
static void
-ufo_configuration_add_path (UfoConfiguration *config,
+ufo_config_add_path (UfoConfig *config,
const gchar *path)
{
GValue path_value = {0};
- g_return_if_fail (UFO_IS_CONFIGURATION (config));
+ g_return_if_fail (UFO_IS_CONFIG (config));
g_value_init (&path_value, G_TYPE_STRING);
g_value_set_string (&path_value, path);
@@ -101,12 +100,12 @@ ufo_configuration_add_path (UfoConfiguration *config,
}
static void
-ufo_configuration_set_property(GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+ufo_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- UfoConfigurationPrivate *priv = UFO_CONFIGURATION_GET_PRIVATE (object);
+ UfoConfigPrivate *priv = UFO_CONFIG_GET_PRIVATE (object);
switch (property_id) {
case PROP_PATHS:
@@ -139,12 +138,12 @@ ufo_configuration_set_property(GObject *object,
}
static void
-ufo_configuration_get_property(GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+ufo_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- UfoConfigurationPrivate *priv = UFO_CONFIGURATION_GET_PRIVATE (object);
+ UfoConfigPrivate *priv = UFO_CONFIG_GET_PRIVATE (object);
switch (property_id) {
case PROP_PATHS:
@@ -166,34 +165,34 @@ ufo_configuration_get_property(GObject *object,
}
static void
-ufo_configuration_dispose (GObject *object)
+ufo_config_dispose (GObject *object)
{
- G_OBJECT_CLASS (ufo_configuration_parent_class)->finalize (object);
- g_message ("UfoConfiguration: disposed");
+ G_OBJECT_CLASS (ufo_config_parent_class)->finalize (object);
+ g_message ("UfoConfig: disposed");
}
static void
-ufo_configuration_finalize (GObject *object)
+ufo_config_finalize (GObject *object)
{
- UfoConfigurationPrivate *priv = UFO_CONFIGURATION_GET_PRIVATE (object);
+ UfoConfigPrivate *priv = UFO_CONFIG_GET_PRIVATE (object);
g_value_array_free (priv->path_array);
- G_OBJECT_CLASS (ufo_configuration_parent_class)->finalize (object);
- g_message ("UfoConfiguration: finalized");
+ G_OBJECT_CLASS (ufo_config_parent_class)->finalize (object);
+ g_message ("UfoConfig: finalized");
}
static void
-ufo_configuration_class_init (UfoConfigurationClass *klass)
+ufo_config_class_init (UfoConfigClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->set_property = ufo_configuration_set_property;
- gobject_class->get_property = ufo_configuration_get_property;
- gobject_class->dispose = ufo_configuration_dispose;
- gobject_class->finalize = ufo_configuration_finalize;
+ gobject_class->set_property = ufo_config_set_property;
+ gobject_class->get_property = ufo_config_get_property;
+ gobject_class->dispose = ufo_config_dispose;
+ gobject_class->finalize = ufo_config_finalize;
/**
- * UfoConfiguration:paths:
+ * UfoConfig:paths:
*
* An array of strings with paths pointing to possible filter and kernel
* file locations.
@@ -210,7 +209,7 @@ ufo_configuration_class_init (UfoConfigurationClass *klass)
G_PARAM_READWRITE);
/**
- * UfoConfiguration:profile-level:
+ * UfoConfig:profile-level:
*
* Controls the amount of profiling.
*
@@ -235,20 +234,20 @@ ufo_configuration_class_init (UfoConfigurationClass *klass)
g_object_class_install_property (gobject_class, PROP_PROFILE_LEVEL, config_properties[PROP_PROFILE_LEVEL]);
g_object_class_install_property (gobject_class, PROP_PROFILE_OUTPUT_PREFIX, config_properties[PROP_PROFILE_OUTPUT_PREFIX]);
- g_type_class_add_private(klass, sizeof (UfoConfigurationPrivate));
+ g_type_class_add_private(klass, sizeof (UfoConfigPrivate));
}
static void
-ufo_configuration_init (UfoConfiguration *config)
+ufo_config_init (UfoConfig *config)
{
- config->priv = UFO_CONFIGURATION_GET_PRIVATE (config);
+ config->priv = UFO_CONFIG_GET_PRIVATE (config);
config->priv->path_array = g_value_array_new (0);
config->priv->profile_level = UFO_PROFILER_LEVEL_NONE;
config->priv->profile_output_prefix = NULL;
- ufo_configuration_add_path (config, LIB_FILTER_DIR);
- ufo_configuration_add_path (config, "/usr/lib/ufo");
- ufo_configuration_add_path (config, "/usr/lib64/ufo");
- ufo_configuration_add_path (config, "/usr/local/lib/ufo");
- ufo_configuration_add_path (config, "/usr/local/lib64/ufo");
+ ufo_config_add_path (config, LIB_FILTER_DIR);
+ ufo_config_add_path (config, "/usr/lib/ufo");
+ ufo_config_add_path (config, "/usr/lib64/ufo");
+ ufo_config_add_path (config, "/usr/local/lib/ufo");
+ ufo_config_add_path (config, "/usr/local/lib64/ufo");
}
diff --git a/src/ufo-config.h b/src/ufo-config.h
new file mode 100644
index 0000000..caeeeca
--- /dev/null
+++ b/src/ufo-config.h
@@ -0,0 +1,47 @@
+#ifndef __UFO_CONFIG_H
+#define __UFO_CONFIG_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_CONFIG (ufo_config_get_type())
+#define UFO_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_CONFIG, UfoConfig))
+#define UFO_IS_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_CONFIG))
+#define UFO_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_CONFIG, UfoConfigClass))
+#define UFO_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_CONFIG))
+#define UFO_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_CONFIG, UfoConfigClass))
+
+typedef struct _UfoConfig UfoConfig;
+typedef struct _UfoConfigClass UfoConfigClass;
+typedef struct _UfoConfigPrivate UfoConfigPrivate;
+
+/**
+ * UfoConfig:
+ *
+ * A #UfoConfig provides access to run-time specific settings.
+ */
+struct _UfoConfig {
+ /*< private >*/
+ GObject parent_instance;
+
+ UfoConfigPrivate *priv;
+};
+
+/**
+ * UfoConfigClass:
+ *
+ * #UfoConfig class
+ */
+struct _UfoConfigClass {
+ /*< private >*/
+ GObjectClass parent_class;
+};
+
+UfoConfig * ufo_config_new (void);
+gchar ** ufo_config_get_paths (UfoConfig *config);
+GType ufo_config_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-configurable.c b/src/ufo-configurable.c
index fad31da..129af07 100644
--- a/src/ufo-configurable.c
+++ b/src/ufo-configurable.c
@@ -8,7 +8,7 @@
*/
#include "ufo-configurable.h"
-#include "ufo-configuration.h"
+#include "ufo-config.h"
typedef UfoConfigurableIface UfoConfigurableInterface;
@@ -25,10 +25,10 @@ ufo_configurable_default_init (UfoConfigurableInterface *iface)
* The #UfoConfiguration object that can be passed to all objects that
* implement the #UfoConfigurable interface.
*/
- config_spec = g_param_spec_object ("configuration",
- "A UfoConfiguration object",
- "A UfoConfiguration object",
- UFO_TYPE_CONFIGURATION,
+ config_spec = g_param_spec_object ("config",
+ "A UfoConfig object",
+ "A UfoConfig object",
+ UFO_TYPE_CONFIG,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_interface_install_property (iface, config_spec);
diff --git a/src/ufo-configuration.h b/src/ufo-configuration.h
deleted file mode 100644
index 97df392..0000000
--- a/src/ufo-configuration.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __UFO_CONFIGURATION_H
-#define __UFO_CONFIGURATION_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_CONFIGURATION (ufo_configuration_get_type())
-#define UFO_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_CONFIGURATION, UfoConfiguration))
-#define UFO_IS_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_CONFIGURATION))
-#define UFO_CONFIGURATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_CONFIGURATION, UfoConfigurationClass))
-#define UFO_IS_CONFIGURATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_CONFIGURATION))
-#define UFO_CONFIGURATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_CONFIGURATION, UfoConfigurationClass))
-
-typedef struct _UfoConfiguration UfoConfiguration;
-typedef struct _UfoConfigurationClass UfoConfigurationClass;
-typedef struct _UfoConfigurationPrivate UfoConfigurationPrivate;
-
-/**
- * UfoConfiguration:
- *
- * A #UfoConfiguration provides access to run-time specific settings.
- */
-struct _UfoConfiguration {
- /*< private >*/
- GObject parent_instance;
-
- UfoConfigurationPrivate *priv;
-};
-
-/**
- * UfoConfigurationClass:
- *
- * #UfoConfiguration class
- */
-struct _UfoConfigurationClass {
- /*< private >*/
- GObjectClass parent_class;
-};
-
-UfoConfiguration * ufo_configuration_new (void);
-gchar ** ufo_configuration_get_paths (UfoConfiguration *config);
-GType ufo_configuration_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-cpu-node.c b/src/ufo-cpu-node.c
new file mode 100644
index 0000000..05bb358
--- /dev/null
+++ b/src/ufo-cpu-node.c
@@ -0,0 +1,93 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include <ufo-cpu-node.h>
+
+G_DEFINE_TYPE (UfoCpuNode, ufo_cpu_node, UFO_TYPE_NODE)
+
+#define UFO_CPU_NODE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_CPU_NODE, UfoCpuNodePrivate))
+
+
+struct _UfoCpuNodePrivate {
+ cpu_set_t *mask;
+};
+
+UfoNode *
+ufo_cpu_node_new (gpointer mask)
+{
+ UfoCpuNode *node;
+
+ g_return_val_if_fail (mask != NULL, NULL);
+ node = UFO_CPU_NODE (g_object_new (UFO_TYPE_CPU_NODE, NULL));
+ node->priv->mask = g_memdup (mask, sizeof(cpu_set_t));
+ return UFO_NODE (node);
+}
+
+gpointer
+ufo_cpu_node_get_affinity (UfoCpuNode *cpu_node)
+{
+ g_return_val_if_fail (UFO_IS_CPU_NODE (cpu_node), NULL);
+ return cpu_node->priv->mask;
+}
+
+static void
+ufo_cpu_node_finalize (GObject *object)
+{
+ UfoCpuNodePrivate *priv;
+
+ priv = UFO_CPU_NODE_GET_PRIVATE (object);
+
+ if (priv->mask) {
+ g_free (priv->mask);
+ priv->mask = NULL;
+ }
+
+ G_OBJECT_CLASS (ufo_cpu_node_parent_class)->finalize (object);
+}
+
+static UfoNode *
+ufo_cpu_node_copy_real (UfoNode *node,
+ GError **error)
+{
+ return UFO_NODE (ufo_cpu_node_new (UFO_CPU_NODE (node)->priv->mask));
+}
+
+static gboolean
+ufo_cpu_node_equal_real (UfoNode *n1,
+ UfoNode *n2)
+{
+ UfoCpuNodePrivate *priv1;
+ UfoCpuNodePrivate *priv2;
+ const gsize MAX_CPUS = MIN (16, CPU_SETSIZE);
+
+ g_return_val_if_fail (UFO_IS_CPU_NODE (n1) && UFO_IS_CPU_NODE (n2), FALSE);
+ priv1 = UFO_CPU_NODE_GET_PRIVATE (n1);
+ priv2 = UFO_CPU_NODE_GET_PRIVATE (n2);
+
+ for (gsize i = 0; i < MAX_CPUS; i++) {
+ if (CPU_ISSET (i, priv1->mask) != CPU_ISSET (i, priv2->mask))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+ufo_cpu_node_class_init (UfoCpuNodeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ UfoNodeClass *node_class = UFO_NODE_CLASS (klass);
+
+ object_class->finalize = ufo_cpu_node_finalize;
+ node_class->copy = ufo_cpu_node_copy_real;
+ node_class->equal = ufo_cpu_node_equal_real;
+
+ g_type_class_add_private(klass, sizeof(UfoCpuNodePrivate));
+}
+
+static void
+ufo_cpu_node_init (UfoCpuNode *self)
+{
+ UfoCpuNodePrivate *priv;
+ self->priv = priv = UFO_CPU_NODE_GET_PRIVATE (self);
+ priv->mask = NULL;
+}
diff --git a/src/ufo-cpu-node.h b/src/ufo-cpu-node.h
new file mode 100644
index 0000000..673c1ec
--- /dev/null
+++ b/src/ufo-cpu-node.h
@@ -0,0 +1,49 @@
+#ifndef __UFO_CPU_NODE_H
+#define __UFO_CPU_NODE_H
+
+#include <glib-object.h>
+#include <ufo-node.h>
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_CPU_NODE (ufo_cpu_node_get_type())
+#define UFO_CPU_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_CPU_NODE, UfoCpuNode))
+#define UFO_IS_CPU_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_CPU_NODE))
+#define UFO_CPU_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_CPU_NODE, UfoCpuNodeClass))
+#define UFO_IS_CPU_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_CPU_NODE))
+#define UFO_CPU_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_CPU_NODE, UfoCpuNodeClass))
+
+typedef struct _UfoCpuNode UfoCpuNode;
+typedef struct _UfoCpuNodeClass UfoCpuNodeClass;
+typedef struct _UfoCpuNodePrivate UfoCpuNodePrivate;
+
+/**
+ * UfoCpuNode:
+ *
+ * Main object for organizing filters. The contents of the #UfoCpuNode structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoCpuNode {
+ /*< private >*/
+ UfoNode parent_instance;
+
+ UfoCpuNodePrivate *priv;
+};
+
+/**
+ * UfoCpuNodeClass:
+ *
+ * #UfoCpuNode class
+ */
+struct _UfoCpuNodeClass {
+ /*< private >*/
+ UfoNodeClass parent_class;
+};
+
+UfoNode *ufo_cpu_node_new (gpointer mask);
+gpointer ufo_cpu_node_get_affinity (UfoCpuNode *cpu_node);
+GType ufo_cpu_node_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-cpu-task-iface.c b/src/ufo-cpu-task-iface.c
new file mode 100644
index 0000000..d0b6e38
--- /dev/null
+++ b/src/ufo-cpu-task-iface.c
@@ -0,0 +1,31 @@
+#include "ufo-cpu-task-iface.h"
+
+typedef UfoCpuTaskIface UfoCpuTaskInterface;
+
+G_DEFINE_INTERFACE (UfoCpuTask, ufo_cpu_task, UFO_TYPE_TASK)
+
+
+gboolean
+ufo_cpu_task_process (UfoCpuTask *task,
+ UfoBuffer **inputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition)
+{
+ return UFO_CPU_TASK_GET_IFACE (task)->process (task, inputs, output, requisition);
+}
+
+static gboolean
+ufo_cpu_task_process_real (UfoCpuTask *task,
+ UfoBuffer **inputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition)
+{
+ g_warning ("`process' of UfoCpuTaskInterface not implemented");
+ return FALSE;
+}
+
+static void
+ufo_cpu_task_default_init (UfoCpuTaskInterface *iface)
+{
+ iface->process = ufo_cpu_task_process_real;
+}
diff --git a/src/ufo-cpu-task-iface.h b/src/ufo-cpu-task-iface.h
new file mode 100644
index 0000000..3aa8712
--- /dev/null
+++ b/src/ufo-cpu-task-iface.h
@@ -0,0 +1,35 @@
+#ifndef UFO_CPU_TASK_IFACE_H
+#define UFO_CPU_TASK_IFACE_H
+
+#include <glib-object.h>
+#include "ufo-task-iface.h"
+#include "ufo-buffer.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_CPU_TASK (ufo_cpu_task_get_type())
+#define UFO_CPU_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_CPU_TASK, UfoCpuTask))
+#define UFO_CPU_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_CPU_TASK, UfoCpuTaskIface))
+#define UFO_IS_CPU_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_CPU_TASK))
+#define UFO_IS_CPU_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_CPU_TASK))
+#define UFO_CPU_TASK_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), UFO_TYPE_CPU_TASK, UfoCpuTaskIface))
+
+typedef struct _UfoCpuTask UfoCpuTask;
+typedef struct _UfoCpuTaskIface UfoCpuTaskIface;
+
+struct _UfoCpuTaskIface {
+ UfoTaskIface parent_iface;
+
+ gboolean (*process) (UfoCpuTask *task, UfoBuffer **inputs, UfoBuffer *output, UfoRequisition *requisition);
+};
+
+gboolean ufo_cpu_task_process (UfoCpuTask *task,
+ UfoBuffer **inputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition);
+
+GType ufo_cpu_task_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-filter-reduce.c b/src/ufo-filter-reduce.c
deleted file mode 100644
index a577c6c..0000000
--- a/src/ufo-filter-reduce.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * SECTION:ufo-filter-reduce
- * @Short_description: A reduction filter accumulates one output from all inputs
- * @Title: UfoFilterReduce
- *
- * A reduction filter takes an arbitrary number of data input and produces one
- * output when the stream has finished. This scheme is useful for averaging the
- * data stream or producing a volume from a series of projections.
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-filter-reduce.h"
-
-G_DEFINE_TYPE (UfoFilterReduce, ufo_filter_reduce, UFO_TYPE_FILTER)
-
-#define UFO_FILTER_REDUCE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_REDUCE, UfoFilterReducePrivate))
-
-/**
- * ufo_filter_reduce_initialize:
- * @filter: A #UfoFilter.
- * @input: An array of buffers for each input port
- * @output_dims: The size of each dimension for each output
- * @default_value: The value to fill the output buffer
- * @error: Location for #GError.
- *
- * This function calls the implementation for the virtual initialize method. The
- * filter can use the input buffers as a hint to setup its own internal
- * structures. Moreover, it needs to return size of each output dimension in
- * each port as specified with ufo_filter_register_outputs():
- * <programlisting>
- * // register a 1-dimensional and a 2-dimensional output in object::init
- * ufo_filter_register_outputs (self, 1, 2, NULL);
- *
- * // specify sizes in object::initialize
- * output_dim_sizes[0][0] = 1024;
- *
- * output_dim_sizes[1][0] = 640;
- * output_dim_sizes[1][1] = 480;
- * </programlisting>
- *
- * It also has to set a valid default value with which the output buffer is
- * initialized.
- *
- * Since: 0.2
- */
-void
-ufo_filter_reduce_initialize (UfoFilterReduce *filter, UfoBuffer *input[], guint **output_dims, gfloat *default_value, GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER_REDUCE (filter));
- UFO_FILTER_REDUCE_GET_CLASS (filter)->initialize (filter, input, output_dims, default_value, error);
-}
-
-/**
- * ufo_filter_reduce_collect:
- * @filter: A #UfoFilter.
- * @input: An array of buffers for each input port
- * @output: An array of buffers for each output port
- * @error: Location for #GError.
- *
- * Process input data. The output buffer array contains the same buffers on each
- * method invocation and can be used to store accumulated values.
- *
- * Since: 0.2
- */
-void
-ufo_filter_reduce_collect (UfoFilterReduce *filter, UfoBuffer *input[], UfoBuffer *output[], GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER_REDUCE (filter));
- UFO_FILTER_REDUCE_GET_CLASS (filter)->collect (filter, input, output, error);
-}
-
-/**
- * ufo_filter_reduce_reduce:
- * @filter: A #UfoFilter.
- * @output: An array of buffers for each output port
- * @error: Location for #GError.
- *
- * This method calls the virtual reduce method and is called itself, when the
- * input data stream has finished. The reduce method can be used to finalize
- * work on the output buffers.
- *
- * Returns: TRUE if data is produced or FALSE if reduction has stopped
- *
- * Since: 0.2
- */
-gboolean
-ufo_filter_reduce_reduce (UfoFilterReduce *filter, UfoBuffer *output[], GError **error)
-{
- g_return_val_if_fail (UFO_IS_FILTER_REDUCE (filter), FALSE);
- return UFO_FILTER_REDUCE_GET_CLASS (filter)->reduce (filter, output, error);
-}
-
-static void
-ufo_filter_reduce_initialize_real (UfoFilterReduce *filter, UfoBuffer *input[], guint **output_dims, gfloat *default_value, GError **error)
-{
- g_debug ("%s->initialize not implemented", ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-}
-
-static void
-ufo_filter_reduce_collect_real (UfoFilterReduce *filter, UfoBuffer *input[], UfoBuffer *output[], GError **error)
-{
- g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_METHOD_NOT_IMPLEMENTED,
- "Virtual method `collect' of %s is not implemented",
- ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-}
-
-static gboolean
-ufo_filter_reduce_reduce_real (UfoFilterReduce *filter, UfoBuffer *output[], GError **error)
-{
- g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_METHOD_NOT_IMPLEMENTED,
- "Virtual method `reduce' of %s is not implemented",
- ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-
- return FALSE;
-}
-
-static void
-ufo_filter_reduce_class_init (UfoFilterReduceClass *klass)
-{
- klass->initialize = ufo_filter_reduce_initialize_real;
- klass->collect = ufo_filter_reduce_collect_real;
- klass->reduce = ufo_filter_reduce_reduce_real;
-}
-
-static void
-ufo_filter_reduce_init (UfoFilterReduce *self)
-{
-}
diff --git a/src/ufo-filter-reduce.h b/src/ufo-filter-reduce.h
deleted file mode 100644
index 9d01b71..0000000
--- a/src/ufo-filter-reduce.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef __UFO_FILTER_REDUCE_H
-#define __UFO_FILTER_REDUCE_H
-
-#include <glib-object.h>
-
-#include "ufo-buffer.h"
-#include "ufo-filter.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER_REDUCE (ufo_filter_reduce_get_type())
-#define UFO_FILTER_REDUCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER_REDUCE, UfoFilterReduce))
-#define UFO_IS_FILTER_REDUCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER_REDUCE))
-#define UFO_FILTER_REDUCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER_REDUCE, UfoFilterReduceClass))
-#define UFO_IS_FILTER_REDUCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER_REDUCE))
-#define UFO_FILTER_REDUCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER_REDUCE, UfoFilterReduceClass))
-
-typedef struct _UfoFilterReduce UfoFilterReduce;
-typedef struct _UfoFilterReduceClass UfoFilterReduceClass;
-typedef struct _UfoFilterReducePrivate UfoFilterReducePrivate;
-
-/**
- * UfoFilterReduce:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilterReduce {
- /*< private >*/
- UfoFilter parent;
-};
-
-/**
- * UfoFilterReduceClass:
- * @parent: the parent class
- * @initialize: the @initialize function is called by an UfoBaseScheduler to set
- * up a filter before actual execution happens. It receives the first input
- * data to which the filter can get adjust. The reduce filter should return
- * the default value that is used to fill the output buffer.
- * @collect: the @collect function is called for each new input. The output
- * buffer will be the same for all invocations and can be used to
- * accumulate results.
- * @reduce: the @reduce function is called after the data stream end. It is used
- * to finish any remaining work on the output.
- */
-struct _UfoFilterReduceClass {
- UfoFilterClass parent;
-
- /* overridable */
- void (*initialize) (UfoFilterReduce *filter,
- UfoBuffer *input[],
- guint **output_dims,
- gfloat *default_value,
- GError **error);
- void (*collect) (UfoFilterReduce *filter,
- UfoBuffer *input[],
- UfoBuffer *output[],
- GError **error);
- gboolean (*reduce) (UfoFilterReduce *filter,
- UfoBuffer *output[],
- GError **error);
-};
-
-void ufo_filter_reduce_initialize (UfoFilterReduce *filter,
- UfoBuffer *input[],
- guint **output_dims,
- gfloat *default_value,
- GError **error);
-void ufo_filter_reduce_collect (UfoFilterReduce *filter,
- UfoBuffer *input[],
- UfoBuffer *output[],
- GError **error);
-gboolean ufo_filter_reduce_reduce (UfoFilterReduce *filter,
- UfoBuffer *output[],
- GError **error);
-GType ufo_filter_reduce_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-filter-repeater.c b/src/ufo-filter-repeater.c
deleted file mode 100644
index 8b57942..0000000
--- a/src/ufo-filter-repeater.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * SECTION:ufo-filter-repeater
- * @Short_description: The repeater filter repeats its input on the output
- * @Title: UfoFilterRepeater
- *
- * In case you want to subtract a constant image from a series of input images,
- * you would need to repeat the constant image as often as you have other
- * images.
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-filter-repeater.h"
-
-G_DEFINE_TYPE (UfoFilterRepeater, ufo_filter_repeater, UFO_TYPE_FILTER)
-
-#define UFO_FILTER_REPEATER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_REPEATER, UfoFilterRepeaterPrivate))
-
-struct _UfoFilterRepeaterPrivate {
- guint count;
-};
-
-enum {
- PROP_0,
- PROP_COUNT,
- N_PROPERTIES
-};
-
-static GParamSpec *repeater_properties[N_PROPERTIES] = { NULL, };
-
-static void
-ufo_filter_repeater_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- UfoFilterRepeaterPrivate *priv = UFO_FILTER_REPEATER_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_COUNT:
- priv->count = g_value_get_uint (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_filter_repeater_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- UfoFilterRepeaterPrivate *priv = UFO_FILTER_REPEATER_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_COUNT:
- g_value_set_uint (value, priv->count);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_filter_repeater_class_init (UfoFilterRepeaterClass *klass)
-{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (klass);
- oclass->set_property = ufo_filter_repeater_set_property;
- oclass->get_property = ufo_filter_repeater_get_property;
-
- repeater_properties[PROP_COUNT] =
- g_param_spec_uint ("count",
- "Number of repetitions",
- "Number of repetitions",
- 1, G_MAXUINT, 1,
- G_PARAM_READWRITE);
-
- g_object_class_install_property (oclass, PROP_COUNT, repeater_properties[PROP_COUNT]);
- g_type_class_add_private (klass, sizeof (UfoFilterRepeaterPrivate));
-}
-
-static void
-ufo_filter_repeater_init (UfoFilterRepeater *self)
-{
- UfoInputParameter input_param;
- UfoOutputParameter output_params;
-
- self->priv = UFO_FILTER_REPEATER_GET_PRIVATE (self);
- self->priv->count = 1;
-
- input_param.n_dims = 2;
- input_param.n_expected_items = 1;
- output_params.n_dims = 2;
-
- ufo_filter_register_inputs (UFO_FILTER (self), 1, &input_param);
- ufo_filter_register_outputs (UFO_FILTER (self), 1, &output_params);
- ufo_filter_set_plugin_name (UFO_FILTER (self), "repeater");
-}
diff --git a/src/ufo-filter-repeater.h b/src/ufo-filter-repeater.h
deleted file mode 100644
index 63ab1dd..0000000
--- a/src/ufo-filter-repeater.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __UFO_FILTER_REPEATER_H
-#define __UFO_FILTER_REPEATER_H
-
-#include <glib-object.h>
-
-#include "ufo-filter.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER_REPEATER (ufo_filter_repeater_get_type())
-#define UFO_FILTER_REPEATER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER_REPEATER, UfoFilterRepeater))
-#define UFO_IS_FILTER_REPEATER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER_REPEATER))
-#define UFO_FILTER_REPEATER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER_REPEATER, UfoFilterRepeaterClass))
-#define UFO_IS_FILTER_REPEATER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER_REPEATER))
-#define UFO_FILTER_REPEATER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER_REPEATER, UfoFilterRepeaterClass))
-
-typedef struct _UfoFilterRepeater UfoFilterRepeater;
-typedef struct _UfoFilterRepeaterClass UfoFilterRepeaterClass;
-typedef struct _UfoFilterRepeaterPrivate UfoFilterRepeaterPrivate;
-
-/**
- * UfoFilterRepeater:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilterRepeater {
- /*< private >*/
- UfoFilter parent;
-
- UfoFilterRepeaterPrivate *priv;
-};
-
-/**
- * UfoFilterRepeaterClass:
- * @parent: the parent class
- */
-struct _UfoFilterRepeaterClass {
- UfoFilterClass parent;
-};
-
-GType ufo_filter_repeater_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-filter-sink-direct.c b/src/ufo-filter-sink-direct.c
deleted file mode 100644
index d3cf239..0000000
--- a/src/ufo-filter-sink-direct.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * SECTION:ufo-filter-sink-direct
- * @Short_description: A direct sink filter outputs data coming from a processing pipeline
- * @Title: UfoFilterSinkDirect
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-filter-sink-direct.h"
-
-G_DEFINE_TYPE (UfoFilterSinkDirect, ufo_filter_sink_direct, UFO_TYPE_FILTER_SINK)
-
-#define UFO_FILTER_SINK_DIRECT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_SINK_DIRECT, UfoFilterSinkDirectPrivate))
-
-struct _UfoFilterSinkDirectPrivate {
- GAsyncQueue *outgoing_queue;
- GAsyncQueue *incoming_queue;
-};
-
-static void
-ufo_filter_sink_direct_initialize (UfoFilterSink *filter, UfoBuffer *input[], GError **error)
-{
- g_debug ("Virtual method `initialize' of %s not implemented",
- ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-}
-
-static void
-ufo_filter_sink_direct_consume (UfoFilterSink *filter, UfoBuffer *input[], GError **error)
-{
- UfoFilterSinkDirectPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER_SINK_DIRECT (filter));
-
- priv = UFO_FILTER_SINK_DIRECT_GET_PRIVATE (filter);
- g_async_queue_push (priv->outgoing_queue, input[0]);
- g_async_queue_pop (priv->incoming_queue);
-}
-
-/**
- * ufo_filter_sink_direct_pop:
- * @filter: A #UfoFilterSinkDirect object
- *
- * Get the buffer from this node. After processing the data, the buffer needs to
- * be released with ufo_filter_sink_direct_release().
- *
- * Returns: (transfer none): A #UfoBuffer to be processed directly.
- */
-UfoBuffer *
-ufo_filter_sink_direct_pop (UfoFilterSinkDirect *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER_SINK_DIRECT (filter), NULL);
- return g_async_queue_pop (filter->priv->outgoing_queue);
-}
-
-/**
- * ufo_filter_sink_direct_release:
- * @filter: A #UfoFilterSinkDirect object
- * @buffer: A #UfoBuffer acquired with ufo_filter_sink_direct_pop().
- *
- * Release a buffer acquired with ufo_filter_sink_direct_pop().
- *
- * Note: If the buffer is not released, the processing pipeline will dead-lock.
- */
-void
-ufo_filter_sink_direct_release (UfoFilterSinkDirect *filter, UfoBuffer *buffer)
-{
- g_return_if_fail (UFO_IS_FILTER_SINK_DIRECT (filter));
- g_async_queue_push (filter->priv->incoming_queue, buffer);
-}
-
-static void
-ufo_filter_sink_direct_finalize (GObject *object)
-{
- UfoFilterSinkDirectPrivate *priv;
-
- priv = UFO_FILTER_SINK_DIRECT_GET_PRIVATE (object);
- g_async_queue_unref (priv->outgoing_queue);
- g_async_queue_unref (priv->incoming_queue);
-}
-
-static void
-ufo_filter_sink_direct_class_init (UfoFilterSinkDirectClass *klass)
-{
- GObjectClass *oclass = G_OBJECT_CLASS (klass);
- UfoFilterSinkClass *filter_class = UFO_FILTER_SINK_CLASS (klass);
-
- filter_class->initialize = ufo_filter_sink_direct_initialize;
- filter_class->consume = ufo_filter_sink_direct_consume;
- oclass->finalize = ufo_filter_sink_direct_finalize;
-
- g_type_class_add_private (klass, sizeof (UfoFilterSinkDirectPrivate));
-}
-
-static void
-ufo_filter_sink_direct_init (UfoFilterSinkDirect *self) {
- UfoFilterSinkDirectPrivate *priv;
- UfoInputParameter input_params[] = {{2, UFO_FILTER_INFINITE_INPUT}};
-
- self->priv = priv = UFO_FILTER_SINK_DIRECT_GET_PRIVATE (self);
- priv->outgoing_queue = g_async_queue_new ();
- priv->incoming_queue = g_async_queue_new ();
-
- ufo_filter_set_plugin_name (UFO_FILTER (self), "direct-sink");
- ufo_filter_register_inputs (UFO_FILTER (self), 1, input_params);
-}
diff --git a/src/ufo-filter-sink-direct.h b/src/ufo-filter-sink-direct.h
deleted file mode 100644
index ff394ec..0000000
--- a/src/ufo-filter-sink-direct.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef __UFO_FILTER_SINK_DIRECT_H
-#define __UFO_FILTER_SINK_DIRECT_H
-
-#include <glib-object.h>
-
-#include "ufo-buffer.h"
-#include "ufo-filter-sink.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER_SINK_DIRECT (ufo_filter_sink_direct_get_type())
-#define UFO_FILTER_SINK_DIRECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER_SINK_DIRECT, UfoFilterSinkDirect))
-#define UFO_IS_FILTER_SINK_DIRECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER_SINK_DIRECT))
-#define UFO_FILTER_SINK_DIRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER_SINK_DIRECT, UfoFilterSinkDirectClass))
-#define UFO_IS_FILTER_SINK_DIRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER_SINK_DIRECT))
-#define UFO_FILTER_SINK_DIRECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER_SINK_DIRECT, UfoFilterSinkDirectClass))
-
-typedef struct _UfoFilterSinkDirect UfoFilterSinkDirect;
-typedef struct _UfoFilterSinkDirectClass UfoFilterSinkDirectClass;
-typedef struct _UfoFilterSinkDirectPrivate UfoFilterSinkDirectPrivate;
-
-/**
- * UfoFilterSinkDirect:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilterSinkDirect {
- /*< private >*/
- UfoFilterSink parent;
-
- UfoFilterSinkDirectPrivate *priv;
-};
-
-/**
- * UfoFilterSinkDirectClass:
- *
- * @parent: the parent class
- */
-struct _UfoFilterSinkDirectClass {
- UfoFilterSinkClass parent;
-};
-
-UfoBuffer * ufo_filter_sink_direct_pop (UfoFilterSinkDirect *filter);
-void ufo_filter_sink_direct_release (UfoFilterSinkDirect *filter,
- UfoBuffer *buffer);
-GType ufo_filter_sink_direct_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-filter-sink.c b/src/ufo-filter-sink.c
deleted file mode 100644
index cd44890..0000000
--- a/src/ufo-filter-sink.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * SECTION:ufo-filter-sink
- * @Short_description: A sink filter consumes data only
- * @Title: UfoFilterSink
- *
- * A sink does not produce an output from its inputs. This kind of filter is
- * necessary to implement file writers or display nodes.
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-filter-sink.h"
-
-G_DEFINE_TYPE (UfoFilterSink, ufo_filter_sink, UFO_TYPE_FILTER)
-
-#define UFO_FILTER_SINK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_SINK, UfoFilterSinkPrivate))
-
-/**
- * ufo_filter_sink_initialize:
- * @filter: A #UfoFilter.
- * @input: An array of buffers for each input port
- * @error: Location for #GError.
- *
- * This function calls the implementation for the virtual initialize method. The
- * filter can use the input buffers as a hint to setup its own internal
- * structures.
- *
- * Since: 0.2
- */
-void
-ufo_filter_sink_initialize (UfoFilterSink *filter, UfoBuffer *input[], GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER_SINK (filter));
- UFO_FILTER_SINK_GET_CLASS (filter)->initialize (filter, input, error);
-}
-
-/**
- * ufo_filter_sink_consume:
- * @filter: A #UfoFilter.
- * @input: An array of buffers for each input port
- * @error: Location for #GError.
- *
- * Process input data from a buffer array.
- *
- * Since: 0.2
- */
-void
-ufo_filter_sink_consume (UfoFilterSink *filter, UfoBuffer *input[], GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER_SINK (filter));
- UFO_FILTER_SINK_GET_CLASS (filter)->consume (filter, input, error);
-}
-
-static void
-ufo_filter_sink_initialize_real (UfoFilterSink *filter, UfoBuffer *input[], GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER_SINK (filter));
-}
-
-static void
-ufo_filter_sink_consume_real (UfoFilterSink *filter, UfoBuffer *input[], GError **error)
-{
- g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_METHOD_NOT_IMPLEMENTED,
- "Virtual method `consume' of %s is not implemented",
- ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-}
-
-static void
-ufo_filter_sink_class_init (UfoFilterSinkClass *klass)
-{
- klass->initialize = ufo_filter_sink_initialize_real;
- klass->consume = ufo_filter_sink_consume_real;
-}
-
-static void
-ufo_filter_sink_init (UfoFilterSink *self)
-{
-}
diff --git a/src/ufo-filter-sink.h b/src/ufo-filter-sink.h
deleted file mode 100644
index b3f2bc5..0000000
--- a/src/ufo-filter-sink.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef __UFO_FILTER_SINK_H
-#define __UFO_FILTER_SINK_H
-
-#include <glib-object.h>
-
-#include "ufo-buffer.h"
-#include "ufo-filter.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER_SINK (ufo_filter_sink_get_type())
-#define UFO_FILTER_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER_SINK, UfoFilterSink))
-#define UFO_IS_FILTER_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER_SINK))
-#define UFO_FILTER_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER_SINK, UfoFilterSinkClass))
-#define UFO_IS_FILTER_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER_SINK))
-#define UFO_FILTER_SINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER_SINK, UfoFilterSinkClass))
-
-typedef struct _UfoFilterSink UfoFilterSink;
-typedef struct _UfoFilterSinkClass UfoFilterSinkClass;
-typedef struct _UfoFilterSinkPrivate UfoFilterSinkPrivate;
-
-/**
- * UfoFilterSink:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilterSink {
- /*< private >*/
- UfoFilter parent;
-};
-
-/**
- * UfoFilterSinkClass:
- * @parent: the parent class
- * @initialize: the @initialize function is called by an UfoBaseScheduler to set
- * up a filter before actual execution happens. It receives the first input
- * data to which the filter can get adjust.
- * @consume: the @consume function implements what is going to happen with the
- * input.
- */
-struct _UfoFilterSinkClass {
- UfoFilterClass parent;
-
- /* overridable methods */
- void (*initialize) (UfoFilterSink *filter,
- UfoBuffer *input[],
- GError **error);
- void (*consume) (UfoFilterSink *filter,
- UfoBuffer *input[],
- GError **error);
-};
-
-void ufo_filter_sink_initialize (UfoFilterSink *filter,
- UfoBuffer *input[],
- GError **error);
-void ufo_filter_sink_consume (UfoFilterSink *filter,
- UfoBuffer *input[],
- GError **error);
-GType ufo_filter_sink_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-filter-source-direct.c b/src/ufo-filter-source-direct.c
deleted file mode 100644
index 0b295e4..0000000
--- a/src/ufo-filter-source-direct.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * SECTION:ufo-filter-source-direct
- * @Short_description: A source filter provides in-process data but does not consume any
- * @Title: UfoFilterSourceDirect
- *
- * A direct source filter pushes in-process data into the processing pipeline to
- * interface with modules that are not part of the pipeline.
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-filter-source-direct.h"
-
-G_DEFINE_TYPE (UfoFilterSourceDirect, ufo_filter_source_direct, UFO_TYPE_FILTER_SOURCE)
-
-#define UFO_FILTER_SOURCE_DIRECT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_SOURCE_DIRECT, UfoFilterSourceDirectPrivate))
-
-static UfoBuffer *END_OF_STREAM = GINT_TO_POINTER (1);
-
-struct _UfoFilterSourceDirectPrivate {
- GAsyncQueue *incoming_queue;
- GAsyncQueue *outgoing_queue;
-};
-
-static void
-ufo_filter_source_direct_initialize (UfoFilterSource *filter, guint **output_dim_sizes, GError **error)
-{
- g_debug ("Virtual method `initialize' of %s not implemented",
- ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-}
-
-static gboolean
-ufo_filter_source_direct_generate (UfoFilterSource *filter, UfoBuffer *output[], GError **error)
-{
- UfoFilterSourceDirectPrivate *priv;
- UfoBuffer *buffer;
-
- g_return_val_if_fail (UFO_IS_FILTER_SOURCE_DIRECT (filter), FALSE);
-
- priv = UFO_FILTER_SOURCE_DIRECT_GET_PRIVATE (filter);
-
- g_async_queue_push (priv->outgoing_queue, output[0]);
- buffer = g_async_queue_pop (priv->incoming_queue);
-
- return buffer == END_OF_STREAM;
-}
-
-/**
- * ufo_filter_source_direct_push:
- * @filter: A #UfoFilterSourceDirect object
- * @buffer: A #UfoBuffer to be pushed into this node
- *
- * Pushes a #UfoBuffer into this node to be processed by subsequent, connected
- * filters. To stop iterating, call ufo_filter_source_direct_stop().
- */
-void
-ufo_filter_source_direct_push (UfoFilterSourceDirect *filter,
- UfoBuffer *buffer)
-{
- UfoFilterSourceDirectPrivate *priv;
- UfoBuffer *output;
-
- g_return_if_fail (UFO_IS_FILTER_SOURCE_DIRECT (filter));
-
- priv = UFO_FILTER_SOURCE_DIRECT_GET_PRIVATE (filter);
- output = g_async_queue_pop (priv->outgoing_queue);
- ufo_buffer_copy (buffer, output);
- g_async_queue_push (priv->incoming_queue, output);
-}
-
-/**
- * ufo_filter_source_direct_stop:
- * @filter: A #UfoFilterSourceDirect object
- *
- * Stop execution. This node cannot accept anymore and subsequent nodes will be
- * notified, that data generation has stopped.
- */
-void
-ufo_filter_source_direct_stop (UfoFilterSourceDirect *filter)
-{
- g_return_if_fail (UFO_IS_FILTER_SOURCE_DIRECT (filter));
- g_async_queue_push (filter->priv->incoming_queue, END_OF_STREAM);
-}
-
-static void
-ufo_filter_source_direct_finalize (GObject *object)
-{
- UfoFilterSourceDirectPrivate *priv;
-
- priv = UFO_FILTER_SOURCE_DIRECT_GET_PRIVATE (object);
- g_async_queue_unref (priv->outgoing_queue);
- g_async_queue_unref (priv->incoming_queue);
-}
-
-static void
-ufo_filter_source_direct_class_init (UfoFilterSourceDirectClass *klass)
-{
- GObjectClass *oclass = G_OBJECT_CLASS (klass);
- UfoFilterSourceClass *source_class = UFO_FILTER_SOURCE_CLASS (klass);
-
- source_class->initialize = ufo_filter_source_direct_initialize;
- source_class->generate = ufo_filter_source_direct_generate;
- oclass->finalize = ufo_filter_source_direct_finalize;
-
- g_type_class_add_private (klass, sizeof (UfoFilterSourceDirectPrivate));
-}
-
-static void
-ufo_filter_source_direct_init (UfoFilterSourceDirect *self)
-{
- UfoFilterSourceDirectPrivate *priv;
- UfoOutputParameter output_params[] = {{2}};
-
- self->priv = priv = UFO_FILTER_SOURCE_DIRECT_GET_PRIVATE (self);
- priv->incoming_queue = g_async_queue_new ();
- priv->outgoing_queue = g_async_queue_new ();
-
- ufo_filter_set_plugin_name (UFO_FILTER (self), "direct-source");
- ufo_filter_register_outputs (UFO_FILTER (self), 1, output_params);
-}
diff --git a/src/ufo-filter-source-direct.h b/src/ufo-filter-source-direct.h
deleted file mode 100644
index 7a0ba37..0000000
--- a/src/ufo-filter-source-direct.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef __UFO_FILTER_SOURCE_DIRECT_H
-#define __UFO_FILTER_SOURCE_DIRECT_H
-
-#include <glib-object.h>
-
-#include "ufo-buffer.h"
-#include "ufo-filter-source.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER_SOURCE_DIRECT (ufo_filter_source_direct_get_type())
-#define UFO_FILTER_SOURCE_DIRECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER_SOURCE_DIRECT, UfoFilterSourceDirect))
-#define UFO_IS_FILTER_SOURCE_DIRECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER_SOURCE_DIRECT))
-#define UFO_FILTER_SOURCE_DIRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER_SOURCE_DIRECT, UfoFilterSourceDirectClass))
-#define UFO_IS_FILTER_SOURCE_DIRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER_SOURCE_DIRECT))
-#define UFO_FILTER_SOURCE_DIRECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER_SOURCE_DIRECT, UfoFilterSourceDirectClass))
-
-typedef struct _UfoFilterSourceDirect UfoFilterSourceDirect;
-typedef struct _UfoFilterSourceDirectClass UfoFilterSourceDirectClass;
-typedef struct _UfoFilterSourceDirectPrivate UfoFilterSourceDirectPrivate;
-
-/**
- * UfoFilterSourceDirect:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilterSourceDirect {
- /*< private >*/
- UfoFilterSource parent;
-
- UfoFilterSourceDirectPrivate *priv;
-};
-
-/**
- * UfoFilterSourceDirectClass:
- *
- * @parent: the parent class
- */
-struct _UfoFilterSourceDirectClass {
- UfoFilterSourceClass parent;
-};
-
-void ufo_filter_source_direct_push (UfoFilterSourceDirect *filter,
- UfoBuffer *buffer);
-void ufo_filter_source_direct_stop (UfoFilterSourceDirect *filter);
-GType ufo_filter_source_direct_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-filter-source.c b/src/ufo-filter-source.c
deleted file mode 100644
index 29ce454..0000000
--- a/src/ufo-filter-source.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * SECTION:ufo-filter-source
- * @Short_description: A source filter provides data but does not consume any
- * @Title: UfoFilterSource
- *
- * A source filter produces data but does not accept any inputs. This can be
- * used to implement file readers or acquisition devices.
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-filter-source.h"
-
-G_DEFINE_TYPE (UfoFilterSource, ufo_filter_source, UFO_TYPE_FILTER)
-
-#define UFO_FILTER_SOURCE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_SOURCE, UfoFilterSourcePrivate))
-
-/**
- * ufo_filter_source_initialize:
- * @filter: A #UfoFilter.
- * @output_dim_sizes: The size of each dimension for each output
- * @error: Location for #GError.
- *
- * This function calls the implementation for the virtual initialize method. It
- * needs to return size of each output dimension in each port as specified with
- * ufo_filter_register_outputs():
- * <programlisting>
- * // register a 1-dimensional and a 2-dimensional output in object::init
- * ufo_filter_register_outputs (self, 1, 2, NULL);
- *
- * // specify sizes in object::initialize
- * output_dim_sizes[0][0] = 1024;
- *
- * output_dim_sizes[1][0] = 640;
- * output_dim_sizes[1][1] = 480;
- * </programlisting>
- *
- * Since: 0.2
- */
-void
-ufo_filter_source_initialize (UfoFilterSource *filter, guint **output_dim_sizes, GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER_SOURCE (filter));
- UFO_FILTER_SOURCE_GET_CLASS (filter)->initialize (filter, output_dim_sizes, error);
-}
-
-/**
- * ufo_filter_source_generate:
- * @filter: A #UfoFilter.
- * @output: An array of buffers for each output port
- * @error: Location for #GError.
- *
- * This function calls the implementation for the virtual generate method. It
- * should produce one set of outputs for each time it is called. If no more data
- * is produced it must return %FALSE.
- *
- * Returns: %TRUE if data is produced, otherwise %FALSE.
- * Since: 0.2
- */
-gboolean
-ufo_filter_source_generate (UfoFilterSource *filter, UfoBuffer *output[], GError **error)
-{
- g_return_val_if_fail (UFO_IS_FILTER_SOURCE (filter), FALSE);
- return UFO_FILTER_SOURCE_GET_CLASS (filter)->generate (filter, output, error);
-}
-
-static void
-ufo_filter_source_initialize_real (UfoFilterSource *filter, guint **output_dim_sizes, GError **error)
-{
- g_debug ("Virtual method `initialize' of %s not implemented",
- ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-}
-
-static gboolean
-ufo_filter_source_generate_real (UfoFilterSource *filter, UfoBuffer *output[], GError **error)
-{
- g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_METHOD_NOT_IMPLEMENTED,
- "Virtual method `generate' of %s is not implemented",
- ufo_filter_get_plugin_name (UFO_FILTER (filter)));
-
- return FALSE;
-}
-
-static void
-ufo_filter_source_class_init (UfoFilterSourceClass *klass)
-{
- klass->initialize = ufo_filter_source_initialize_real;
- klass->generate = ufo_filter_source_generate_real;
-}
-
-static void
-ufo_filter_source_init (UfoFilterSource *self)
-{
-}
diff --git a/src/ufo-filter-source.h b/src/ufo-filter-source.h
deleted file mode 100644
index 1d6f15d..0000000
--- a/src/ufo-filter-source.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __UFO_FILTER_SOURCE_H
-#define __UFO_FILTER_SOURCE_H
-
-#include <glib-object.h>
-
-#include "ufo-buffer.h"
-#include "ufo-filter.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER_SOURCE (ufo_filter_source_get_type())
-#define UFO_FILTER_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER_SOURCE, UfoFilterSource))
-#define UFO_IS_FILTER_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER_SOURCE))
-#define UFO_FILTER_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER_SOURCE, UfoFilterSourceClass))
-#define UFO_IS_FILTER_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER_SOURCE))
-#define UFO_FILTER_SOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER_SOURCE, UfoFilterSourceClass))
-
-typedef struct _UfoFilterSource UfoFilterSource;
-typedef struct _UfoFilterSourceClass UfoFilterSourceClass;
-typedef struct _UfoFilterSourcePrivate UfoFilterSourcePrivate;
-
-/**
- * UfoFilterSource:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilterSource {
- /*< private >*/
- UfoFilter parent;
-};
-
-/**
- * UfoFilterSourceClass:
- * @parent: the parent class
- * @initialize: the @initialize function is called by an UfoBaseScheduler to set
- * up a filter before actual execution happens.
- * @generate: the @generate function produces data for subsequent filters. It
- * returns TRUE if is produced.
- */
-struct _UfoFilterSourceClass {
- UfoFilterClass parent;
-
- /* overridable */
- void (*initialize) (UfoFilterSource *filter,
- guint **output_dim_sizes,
- GError **error);
- gboolean (*generate) (UfoFilterSource *filter,
- UfoBuffer *output[],
- GError **error);
-};
-
-void ufo_filter_source_initialize (UfoFilterSource *filter,
- guint **output_dim_sizes,
- GError **error);
-gboolean ufo_filter_source_generate (UfoFilterSource *filter,
- UfoBuffer *output[],
- GError **error);
-GType ufo_filter_source_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-filter-splitter.c b/src/ufo-filter-splitter.c
deleted file mode 100644
index f4524a4..0000000
--- a/src/ufo-filter-splitter.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * SECTION:ufo-filter-splitter
- * @Short_description: Splitter filters control diverging data flows
- * @Title: UfoFilterSplitter
- *
- * The splitter filter is used to split the incoming data stream into
- * consecutive, linear sub-streams. For example, this allows you to to route
- * the first ten items to the first node, the next to items to the second and
- * the remaining to the last node.
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-filter-splitter.h"
-
-G_DEFINE_TYPE (UfoFilterSplitter, ufo_filter_splitter, UFO_TYPE_FILTER)
-
-#define UFO_FILTER_SPLITTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_SPLITTER, UfoFilterSplitterPrivate))
-
-struct _UfoFilterSplitterPrivate {
- guint n_splits;
- guint *splits;
- GValueArray *counts;
-};
-
-enum {
- PROP_0,
- PROP_COUNTS,
- N_PROPERTIES
-};
-
-static GParamSpec *splitter_properties[N_PROPERTIES] = { NULL, };
-
-static void
-ufo_filter_splitter_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- UfoFilterSplitterPrivate *priv = UFO_FILTER_SPLITTER_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_COUNTS:
- {
- GValueArray *array;
-
- if (priv->counts != NULL)
- g_value_array_free (priv->counts);
-
- array = g_value_get_boxed (value);
-
- if (array != NULL) {
- priv->counts = g_value_array_copy (array);
- priv->n_splits = priv->counts->n_values;
- }
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_filter_splitter_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- UfoFilterSplitterPrivate *priv = UFO_FILTER_SPLITTER_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_COUNTS:
- g_value_set_boxed (value, priv->counts);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_filter_splitter_constructed (GObject *object)
-{
- UfoInputParameter input_param;
- UfoOutputParameter *output_params;
- UfoFilterSplitter *splitter;
- UfoFilterSplitterPrivate *priv;
- guint n_outputs;
-
- splitter = UFO_FILTER_SPLITTER (object);
- priv = splitter->priv;
-
- input_param.n_dims = 2;
- input_param.n_expected_items = UFO_FILTER_INFINITE_INPUT;
- ufo_filter_register_inputs (UFO_FILTER (splitter), 1, &input_param);
-
- n_outputs = priv->n_splits + 1;
- output_params = g_new0 (UfoOutputParameter, n_outputs);
-
- for (guint i = 0; i < n_outputs; i++)
- output_params[i].n_dims = 2;
-
- ufo_filter_register_outputs (UFO_FILTER (splitter), n_outputs, output_params);
- g_free (output_params);
-
- if (G_OBJECT_CLASS (ufo_filter_splitter_parent_class)->constructed != NULL)
- G_OBJECT_CLASS (ufo_filter_splitter_parent_class)->constructed (object);
-}
-
-static void
-ufo_filter_splitter_class_init (UfoFilterSplitterClass *klass)
-{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (klass);
- oclass->set_property = ufo_filter_splitter_set_property;
- oclass->get_property = ufo_filter_splitter_get_property;
- oclass->constructed = ufo_filter_splitter_constructed;
-
- splitter_properties[PROP_COUNTS] =
- g_param_spec_value_array ("counts",
- "Array of counts for splitting the stream",
- "Array of counts for splitting the stream",
- g_param_spec_int ("count",
- "Number of items to push",
- "Number of items to push",
- -G_MAXINT, G_MAXINT, -1,
- G_PARAM_READWRITE),
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (oclass, PROP_COUNTS, splitter_properties[PROP_COUNTS]);
-
- g_type_class_add_private (klass, sizeof (UfoFilterSplitterPrivate));
-}
-
-static void
-ufo_filter_splitter_init (UfoFilterSplitter *self)
-{
- self->priv = UFO_FILTER_SPLITTER_GET_PRIVATE (self);
-
- self->priv->n_splits = 0;
- self->priv->counts = NULL;
-
- ufo_filter_set_plugin_name (UFO_FILTER (self), "splitter");
-}
diff --git a/src/ufo-filter-splitter.h b/src/ufo-filter-splitter.h
deleted file mode 100644
index 2764a1f..0000000
--- a/src/ufo-filter-splitter.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __UFO_FILTER_SPLITTER_H
-#define __UFO_FILTER_SPLITTER_H
-
-#include <glib-object.h>
-
-#include "ufo-filter.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER_SPLITTER (ufo_filter_splitter_get_type())
-#define UFO_FILTER_SPLITTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER_SPLITTER, UfoFilterSplitter))
-#define UFO_IS_FILTER_SPLITTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER_SPLITTER))
-#define UFO_FILTER_SPLITTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER_SPLITTER, UfoFilterSplitterClass))
-#define UFO_IS_FILTER_SPLITTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER_SPLITTER))
-#define UFO_FILTER_SPLITTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER_SPLITTER, UfoFilterSplitterClass))
-
-typedef struct _UfoFilterSplitter UfoFilterSplitter;
-typedef struct _UfoFilterSplitterClass UfoFilterSplitterClass;
-typedef struct _UfoFilterSplitterPrivate UfoFilterSplitterPrivate;
-
-/**
- * UfoFilterSplitter:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilterSplitter {
- /*< private >*/
- UfoFilter parent;
-
- UfoFilterSplitterPrivate *priv;
-};
-
-/**
- * UfoFilterSplitterClass:
- * @parent: the parent class
- */
-struct _UfoFilterSplitterClass {
- UfoFilterClass parent;
-};
-
-GType ufo_filter_splitter_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-filter.c b/src/ufo-filter.c
deleted file mode 100644
index d27bf25..0000000
--- a/src/ufo-filter.c
+++ /dev/null
@@ -1,640 +0,0 @@
-/**
- * SECTION:ufo-filter
- * @Short_description: Single unit of computation
- * @Title: UfoFilter
- *
- * The base class for processing nodes.
- */
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-#include <string.h>
-
-#include "config.h"
-#include "ufo-filter.h"
-#include "ufo-filter-source.h"
-#include "ufo-filter-sink.h"
-
-G_DEFINE_TYPE(UfoFilter, ufo_filter, G_TYPE_OBJECT)
-
-#define UFO_FILTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER, UfoFilterPrivate))
-
-struct _UfoFilterPrivate {
- gchar *plugin_name;
- gchar *unique_name;
-
- guint n_inputs;
- guint n_outputs;
-
- UfoResourceManager *manager;
- UfoProfiler *profiler;
- UfoInputParameter *input_parameters;
- UfoOutputParameter *output_parameters;
- UfoChannel **input_channels;
- UfoChannel **output_channels;
-
- cl_command_queue command_queue;
- gboolean finished;
-};
-
-/**
- * UfoFilterError:
- * @UFO_FILTER_ERROR_INSUFFICIENTINPUTS: Filter does not provide enough inputs.
- * @UFO_FILTER_ERROR_INSUFFICIENTOUTPUTS: Filter does not provide enough
- * outputs.
- * @UFO_FILTER_ERROR_NUMDIMSMISMATCH: Mismatch between number of dimensions of
- * given input and output.
- * @UFO_FILTER_ERROR_NOSUCHINPUT: Filter does not provide an input with that
- * name.
- * @UFO_FILTER_ERROR_NOSUCHOUTPUT: Filter does not provide an output with that
- * name.
- * @UFO_FILTER_ERROR_INITIALIZATION: Filter could not be initialized.
- * @UFO_FILTER_ERROR_METHOD_NOT_IMPLEMENTED: A method, further specified in the
- * message, is not implemented.
- *
- * Possible errors that ufo_filter_connect_to() and ufo_filter_connect_by_name()
- * can return.
- */
-GQuark
-ufo_filter_error_quark(void)
-{
- return g_quark_from_static_string ("ufo-filter-error-quark");
-}
-
-/**
- * ufo_filter_initialize:
- * @filter: A #UfoFilter.
- * @input: An array of buffers for each input port
- * @output_dim_sizes: The size of each dimension for each output
- * @error: Location for #GError.
- *
- * This function calls the implementation for the virtual initialize method. The
- * filter can use the input buffers as a hint to setup its own internal
- * structures. Moreover, it needs to return size of each output dimension in
- * each port as specified with ufo_filter_register_outputs():
- * <programlisting>
- * // register a 1-dimensional and a 2-dimensional output in object::init
- * ufo_filter_register_outputs (self, 1, 2, NULL);
- *
- * // specify sizes in object::initialize
- * output_dim_sizes[0][0] = 1024;
- *
- * output_dim_sizes[1][0] = 640;
- * output_dim_sizes[1][1] = 480;
- * </programlisting>
- *
- * Since: 0.2
- */
-void
-ufo_filter_initialize (UfoFilter *filter, UfoBuffer *input[], guint **output_dim_sizes, GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER (filter));
- UFO_FILTER_GET_CLASS (filter)->initialize (filter, input, output_dim_sizes, error);
-}
-
-/**
- * ufo_filter_set_resource_manager:
- * @filter: A #UfoFilter.
- * @manager: A #UfoResourceManager
- *
- * Set the resource manager that this filter uses for requesting resources.
- *
- * Since: 0.2
- */
-void ufo_filter_set_resource_manager (UfoFilter *filter,
- UfoResourceManager *manager)
-{
- UfoFilterPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER (filter) && UFO_IS_RESOURCE_MANAGER (manager));
- priv = filter->priv;
- priv->manager = manager;
-}
-
-/**
- * ufo_filter_get_resource_manager:
- * @filter: A #UfoFilter.
- *
- * Get the resource manager that this filter uses for requesting resources.
- *
- * Returns: (transfer full): A #UfoResourceManager
- * Since: 0.2
- */
-UfoResourceManager *ufo_filter_get_resource_manager (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- return filter->priv->manager;
-}
-
-/**
- * ufo_filter_set_profiler:
- * @filter: A #UfoFilter.
- * @profiler: A #UfoProfiler
- *
- * Set this filter's profiler.
- *
- * Since: 0.2
- */
-void ufo_filter_set_profiler (UfoFilter *filter,
- UfoProfiler *profiler)
-{
- UfoFilterPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER (filter) && UFO_IS_PROFILER (profiler));
- priv = filter->priv;
-
- if (priv->profiler != NULL)
- g_object_unref (priv->profiler);
-
- g_object_ref (profiler);
- priv->profiler = profiler;
-}
-
-/**
- * ufo_filter_get_profiler:
- * @filter: A #UfoFilter.
- *
- * Get this filter's profiler.
- *
- * Returns: (transfer full): A #UfoProfiler
- * Since: 0.2
- */
-UfoProfiler *ufo_filter_get_profiler (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- return filter->priv->profiler;
-}
-
-/**
- * ufo_filter_process_cpu:
- * @filter: A #UfoFilter.
- * @input: An array of buffers for each input port
- * @output: An array of buffers for each output port
- * @error: Location for #GError.
- *
- * Process input data from a buffer array on the CPU and put the results into
- * buffers in the #output array.
- *
- * Since: 0.2
- */
-void
-ufo_filter_process_cpu (UfoFilter *filter, UfoBuffer *input[], UfoBuffer *output[], GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER (filter));
- UFO_FILTER_GET_CLASS (filter)->process_cpu (filter, input, output, error);
-}
-
-/**
- * ufo_filter_process_gpu: (skip)
- * @filter: A #UfoFilter.
- * @input: An array of buffers for each input port
- * @output: An array of buffers for each output port
- * @error: Location for an error.
- *
- * Process input data from a buffer array on the GPU and put the results into
- * buffers in the #output array. For each enqueue command, a %cl_event object
- * should be created and put into a #UfoEventList that is returned at the end:
- * <programlisting>
- * UfoEventList *event_list = ufo_event_list_new (2);
- * cl_event *events = ufo_event_list_get_event_array (event_list);
- *
- * clEnqueueNDRangeKernel(..., 0, NULL, &events[0]);
- *
- * return event_list;
- * </programlisting>
- *
- * Since: 0.2
- */
-void
-ufo_filter_process_gpu (UfoFilter *filter, UfoBuffer *input[], UfoBuffer *output[], GError **error)
-{
- g_return_if_fail (UFO_IS_FILTER (filter));
- UFO_FILTER_GET_CLASS (filter)->process_gpu (filter, input, output, error);
-}
-
-/**
- * ufo_filter_set_plugin_name:
- * @filter: A #UfoFilter.
- * @plugin_name: The name of this filter.
- *
- * Set the name of filter.
- */
-void
-ufo_filter_set_plugin_name (UfoFilter *filter, const gchar *plugin_name)
-{
- UfoFilterPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER (filter));
-
- priv = filter->priv;
- priv->plugin_name = g_strdup (plugin_name);
- priv->unique_name = g_strdup_printf ("%s-%p",
- plugin_name,
- (gpointer) filter);
-}
-
-/**
- * ufo_filter_register_inputs: (skip)
- * @filter: A #UfoFilter.
- * @n_inputs: Number of inputs
- * @input_parameters: An array of #UfoInputParameter structures
- *
- * Specifies the number of dimensions and expected number of data elements for
- * each input.
- *
- * Since: 0.2
- */
-void
-ufo_filter_register_inputs (UfoFilter *filter, guint n_inputs, UfoInputParameter *parameters)
-{
- UfoFilterPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER (filter));
- g_return_if_fail (parameters != NULL);
-
- priv = UFO_FILTER_GET_PRIVATE (filter);
-
- if (UFO_IS_FILTER_SOURCE (filter)) {
- g_warning ("%s is a source filter and cannot receive any inputs",
- priv->plugin_name);
- return;
- }
-
- priv->n_inputs = n_inputs;
- priv->input_channels = g_new0 (UfoChannel *, n_inputs);
- priv->input_parameters = g_new0 (UfoInputParameter, n_inputs);
- g_memmove (priv->input_parameters, parameters, n_inputs * sizeof(UfoInputParameter));
-}
-
-/**
- * ufo_filter_register_outputs: (skip)
- * @filter: A #UfoFilter.
- * @n_outputs: Number of outputs
- * @output_parameters: An array of #UfoOutputParameter structures
- *
- * Specifies the number of dimensions for each output.
- *
- * Since: 0.2
- */
-void
-ufo_filter_register_outputs (UfoFilter *filter, guint n_outputs, UfoOutputParameter *parameters)
-{
- UfoFilterPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER (filter));
- g_return_if_fail (parameters != NULL);
-
- priv = UFO_FILTER_GET_PRIVATE (filter);
-
- if (UFO_IS_FILTER_SINK (filter)) {
- g_warning ("%s is a sink filter and cannnot output any data",
- priv->plugin_name);
- return;
- }
-
- priv->n_outputs = n_outputs;
- priv->output_channels = g_new0 (UfoChannel *, n_outputs);
- priv->output_parameters = g_new0 (UfoOutputParameter, n_outputs);
- g_memmove (priv->output_parameters, parameters, n_outputs * sizeof(UfoOutputParameter));
-}
-
-/**
- * ufo_filter_get_input_parameters: (skip)
- * @filter: A #UfoFilter.
- *
- * Get input parameters.
- *
- * Return: An array of #UfoInputParameter structures. This array must not be
- * freed.
- */
-UfoInputParameter *
-ufo_filter_get_input_parameters (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- return filter->priv->input_parameters;
-}
-
-/**
- * ufo_filter_get_output_parameters: (skip)
- * @filter: A #UfoFilter.
- *
- * Get ouput parameters.
- *
- * Return: An array of #UfoOuputParameter structures. This array must not be
- * freed.
- */
-UfoOutputParameter *
-ufo_filter_get_output_parameters (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- return filter->priv->output_parameters;
-}
-
-/**
- * ufo_filter_get_num_inputs:
- * @filter: A #UfoFilter.
- *
- * Return the number of input ports.
- *
- * Returns: Number of input ports.
- * Since: 0.2
- */
-guint
-ufo_filter_get_num_inputs (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), 0);
- return filter->priv->n_inputs;
-}
-
-/**
- * ufo_filter_get_num_outputs:
- * @filter: A #UfoFilter.
- *
- * Return the number of output ports.
- *
- * Returns: Number of output ports.
- * Since: 0.2
- */
-guint
-ufo_filter_get_num_outputs (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), 0);
- return filter->priv->n_outputs;
-}
-
-/**
- * ufo_filter_get_plugin_name:
- * @filter: A #UfoFilter.
- *
- * Get canonical name of @filter.
- *
- * Returns: (transfer none): %NULL-terminated string owned by the filter.
- */
-const gchar *
-ufo_filter_get_plugin_name (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- return filter->priv->plugin_name;
-}
-
-/**
- * ufo_filter_get_unique_name:
- * @filter: A #UfoFilter
- *
- * Get unique filter name consisting of the plugin name as returned by
- * ufo_filter_get_plugin_name(), a dash `-' and the address of the filter
- * object. This can be useful to differentiate between several instances of the
- * same filter.
- *
- * Returns: (transfer none): %NULL-terminated string owned by the filter.
- */
-const gchar*
-ufo_filter_get_unique_name (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- return filter->priv->unique_name;
-}
-
-/**
- * ufo_filter_set_output_channel:
- * @filter: A #UfoFilter.
- * @port: Output port number
- * @channel: A #UfoChannel.
- *
- * Set a filter's output channel for a certain output port.
- *
- * Since: 0.2
- */
-void
-ufo_filter_set_output_channel (UfoFilter *filter, guint port, UfoChannel *channel)
-{
- UfoFilterPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER (filter) && UFO_IS_CHANNEL (channel));
- g_return_if_fail (port < filter->priv->n_outputs);
-
- priv = filter->priv;
-
- if (priv->output_channels[port] != NULL)
- g_object_unref (priv->output_channels[port]);
-
- g_object_ref (channel);
- priv->output_channels[port] = channel;
-}
-
-/**
- * ufo_filter_get_output_channel:
- * @filter: A #UfoFilter.
- * @port: Output port number
- *
- * Return a filter's output channel for a certain output port.
- *
- * Returns: (transfer none) (allow-none): The associated output channel.
- * Since: 0.2
- */
-UfoChannel *
-ufo_filter_get_output_channel (UfoFilter *filter, guint port)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- g_return_val_if_fail (port < filter->priv->n_outputs, NULL);
- return filter->priv->output_channels[port];
-}
-
-/**
- * ufo_filter_set_input_channel:
- * @filter: A #UfoFilter.
- * @port: input port number
- * @channel: A #UfoChannel.
- *
- * Set a filter's input channel for a certain input port.
- *
- * Since: 0.2
- */
-void
-ufo_filter_set_input_channel (UfoFilter *filter, guint port, UfoChannel *channel)
-{
- UfoFilterPrivate *priv;
-
- g_return_if_fail (UFO_IS_FILTER (filter) && UFO_IS_CHANNEL (channel));
- g_return_if_fail (port < filter->priv->n_inputs);
-
- priv = filter->priv;
-
- if (priv->input_channels[port] != NULL)
- g_object_unref (priv->input_channels[port]);
-
- g_object_ref (channel);
- filter->priv->input_channels[port] = channel;
-}
-
-/**
- * ufo_filter_get_input_channel:
- * @filter: A #UfoFilter.
- * @port: input port number
- *
- * Return a filter's input channel for a certain input port.
- *
- * Returns: (transfer none) (allow-none): The associated input channel.
- * Since: 0.2
- */
-UfoChannel *
-ufo_filter_get_input_channel (UfoFilter *filter, guint port)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
-
- if (port >= filter->priv->n_inputs) {
- g_warning ("Requested port %i of `%s' but has only %i inputs\n",
- port, ufo_filter_get_plugin_name (filter),
- filter->priv->n_inputs);
- return NULL;
- }
-
- return filter->priv->input_channels[port];
-}
-
-/**
- * ufo_filter_set_command_queue:
- * @filter: A #UfoFilter.
- * @cmd_queue: A %cl_command_queue to be used for computation and data transfer
- *
- * Set the associated command queue.
- * Since: 0.2
- */
-void
-ufo_filter_set_command_queue (UfoFilter *filter,
- gpointer cmd_queue)
-{
- g_return_if_fail (UFO_IS_FILTER (filter));
- filter->priv->command_queue = cmd_queue;
-}
-
-/**
- * ufo_filter_get_command_queue:
- * @filter: A #UfoFilter.
- *
- * Get the associated command queue.
- *
- * Returns: (transfer none): A %cl_command_queue or %NULL
- * Since: 0.2
- */
-gpointer
-ufo_filter_get_command_queue (UfoFilter *filter)
-{
- g_return_val_if_fail (UFO_IS_FILTER (filter), NULL);
- return filter->priv->command_queue;
-}
-
-/**
- * ufo_filter_wait_until: (skip)
- * @filter: A #UfoFilter
- * @pspec: The specification of the property
- * @condition: A condition function to wait until it is satisfied
- * @user_data: User data passed to the condition func
- *
- * Wait until a property specified by @pspec fulfills @condition.
- */
-void
-ufo_filter_wait_until (UfoFilter *filter, GParamSpec *pspec, UfoFilterConditionFunc condition, gpointer user_data)
-{
- GValue val = {0,};
- g_value_init (&val, pspec->value_type);
-
- while (1) {
- g_object_get_property (G_OBJECT (filter), pspec->name, &val);
-
- if (condition (&val, user_data))
- break;
-
- g_usleep (10000);
- }
-
- g_value_unset (&val);
-}
-
-static void
-ufo_filter_initialize_real (UfoFilter *filter, UfoBuffer *input[], guint **output_dim_sizes, GError **error)
-{
- g_debug ("Virtual method `initialize' of %s not implemented\n",
- filter->priv->plugin_name);
-}
-
-static void
-ufo_filter_dispose (GObject *object)
-{
- UfoFilterPrivate *priv;
-
- priv = UFO_FILTER_GET_PRIVATE (object);
-
- if (priv->profiler != NULL) {
- g_object_unref (priv->profiler);
- priv->profiler = NULL;
- }
-
- for (guint port = 0; port < priv->n_inputs; port++) {
- if (priv->input_channels[port] != NULL)
- g_object_unref (priv->input_channels[port]);
- }
-
- for (guint port = 0; port < priv->n_outputs; port++) {
- if (priv->output_channels[port] != NULL)
- g_object_unref (priv->output_channels[port]);
- }
-
- G_OBJECT_CLASS (ufo_filter_parent_class)->dispose(object);
- g_message ("UfoFilter (%p): disposed", (gpointer) object);
-}
-
-static void
-ufo_filter_finalize (GObject *object)
-{
- UfoFilterPrivate *priv = UFO_FILTER_GET_PRIVATE (object);
-
- g_free (priv->input_parameters);
- g_free (priv->output_parameters);
- g_free (priv->input_channels);
- g_free (priv->output_channels);
- g_free (priv->plugin_name);
- g_free (priv->unique_name);
-
- G_OBJECT_CLASS (ufo_filter_parent_class)->finalize (object);
- g_message ("UfoFilter (%p): finalized", (gpointer) object);
-}
-
-static void
-ufo_filter_class_init (UfoFilterClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = ufo_filter_finalize;
- gobject_class->dispose = ufo_filter_dispose;
-
- klass->initialize = ufo_filter_initialize_real;
- klass->process_cpu = NULL;
- klass->process_gpu = NULL;
-
- g_type_class_add_private (klass, sizeof (UfoFilterPrivate));
-}
-
-static void
-ufo_filter_init (UfoFilter *self)
-{
- UfoFilterPrivate *priv;
- self->priv = priv = UFO_FILTER_GET_PRIVATE (self);
- priv->finished = FALSE;
- priv->n_inputs = 0;
- priv->n_outputs = 0;
- priv->input_parameters = NULL;
- priv->output_parameters = NULL;
- priv->input_channels = NULL;
- priv->output_channels = NULL;
- priv->profiler = NULL;
- priv->command_queue = NULL;
- priv->plugin_name = NULL;
- priv->unique_name = NULL;
-}
-
diff --git a/src/ufo-filter.h b/src/ufo-filter.h
deleted file mode 100644
index b9da081..0000000
--- a/src/ufo-filter.h
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef __UFO_FILTER_H
-#define __UFO_FILTER_H
-
-#include <glib-object.h>
-
-#include "ufo-profiler.h"
-#include "ufo-resource-manager.h"
-#include "ufo-buffer.h"
-#include "ufo-channel.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_FILTER (ufo_filter_get_type())
-#define UFO_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FILTER, UfoFilter))
-#define UFO_IS_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FILTER))
-#define UFO_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FILTER, UfoFilterClass))
-#define UFO_IS_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FILTER))
-#define UFO_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FILTER, UfoFilterClass))
-
-/**
- * UFO_FILTER_INFINITE_INPUT:
- *
- * Use this to specify that you accept an infinite data stream on an input for
- * #UfoInputParameter and ufo_filter_register_inputs().
- */
-#define UFO_FILTER_INFINITE_INPUT -1
-
-#define UFO_FILTER_ERROR ufo_filter_error_quark()
-GQuark ufo_filter_error_quark(void);
-
-typedef enum {
- UFO_FILTER_ERROR_INSUFFICIENTINPUTS,
- UFO_FILTER_ERROR_INSUFFICIENTOUTPUTS,
- UFO_FILTER_ERROR_NUMDIMSMISMATCH,
- UFO_FILTER_ERROR_NOSUCHINPUT,
- UFO_FILTER_ERROR_NOSUCHOUTPUT,
- UFO_FILTER_ERROR_INITIALIZATION,
- UFO_FILTER_ERROR_METHOD_NOT_IMPLEMENTED
-} UfoFilterError;
-
-typedef struct _UfoFilter UfoFilter;
-typedef struct _UfoFilterClass UfoFilterClass;
-typedef struct _UfoFilterPrivate UfoFilterPrivate;
-typedef struct _UfoInputParameter UfoInputParameter;
-typedef struct _UfoOutputParameter UfoOutputParameter;
-
-/**
- * UfoFilterConditionFunc:
- * @value: Property value that should be checked
- * @user_data: user data passed to the function
- *
- * A function that returns a boolean value depending on the input property.
- *
- * Returns: %TRUE if property satisfies condition else %FALSE
- *
- * Since: 0.2
- */
-typedef gboolean (*UfoFilterConditionFunc) (GValue *value, gpointer user_data);
-
-/**
- * UfoInputParameter:
- * @n_dims: Number of dimension the input accept
- * @n_expected_items: Number of expected items. Use UFO_FILTER_INFINITE_INPUT to
- * accept a data stream.
- * @n_fetched_items: Number of fetched items.
- *
- * Data structure for describing the parameters of an input as used by
- * ufo_filter_register_inputs().
- */
-struct _UfoInputParameter {
- /* To be initialized by filter implementation */
- guint n_dims;
- gint n_expected_items;
-
- /* Do not have to be set */
- gint n_fetched_items;
-};
-
-/**
- * UfoOutputParameter:
- * @n_dims: Number of dimension the input accept
- *
- * Data structure for describing the parameters of an output as used by
- * ufo_filter_register_outputs().
- */
-struct _UfoOutputParameter {
- guint n_dims;
-};
-
-/**
- * UfoFilter:
- *
- * The contents of this object is opaque to the user.
- */
-struct _UfoFilter {
- /*< private >*/
- GObject parent;
-
- UfoFilterPrivate *priv;
-};
-
-/**
- * UfoFilterClass:
- * @parent: the parent class
- * @initialize: the @initialize function is called by an UfoBaseScheduler to set
- * up a filter before actual execution happens. It receives the first input
- * data to which the filter can get adjust.
- * @process_cpu: this method implements data processing on CPU.
- * @process_gpu: this method implements data processing on GPU.
- *
- * The class structure for the UfoFilter type.
- */
-struct _UfoFilterClass {
- GObjectClass parent;
-
- void (*initialize) (UfoFilter *filter,
- UfoBuffer *input[],
- guint **output_dim_sizes,
- GError **error);
- void (*process_cpu) (UfoFilter *filter,
- UfoBuffer *input[],
- UfoBuffer *output[],
- GError **error);
- void (*process_gpu) (UfoFilter *filter,
- UfoBuffer *input[],
- UfoBuffer *output[],
- GError **error);
-};
-
-void ufo_filter_initialize (UfoFilter *filter,
- UfoBuffer *input[],
- guint **output_dim_sizes,
- GError **error);
-void ufo_filter_set_resource_manager (UfoFilter *filter,
- UfoResourceManager *manager);
-UfoResourceManager *ufo_filter_get_resource_manager (UfoFilter *filter);
-void ufo_filter_set_profiler (UfoFilter *filter,
- UfoProfiler *profiler);
-UfoProfiler * ufo_filter_get_profiler (UfoFilter *filter);
-void ufo_filter_process_cpu (UfoFilter *filter,
- UfoBuffer *input[],
- UfoBuffer *output[],
- GError **error);
-void ufo_filter_process_gpu (UfoFilter *filter,
- UfoBuffer *input[],
- UfoBuffer *output[],
- GError **error);
-void ufo_filter_set_plugin_name (UfoFilter *filter,
- const gchar *plugin_name);
-const gchar* ufo_filter_get_plugin_name (UfoFilter *filter);
-const gchar* ufo_filter_get_unique_name (UfoFilter *filter);
-void ufo_filter_register_inputs (UfoFilter *filter,
- guint n_inputs,
- UfoInputParameter *input_parameters);
-void ufo_filter_register_outputs (UfoFilter *filter,
- guint n_outputs,
- UfoOutputParameter *output_parameters);
-UfoInputParameter *ufo_filter_get_input_parameters (UfoFilter *filter);
-UfoOutputParameter *ufo_filter_get_output_parameters (UfoFilter *filter);
-guint ufo_filter_get_num_inputs (UfoFilter *filter);
-guint ufo_filter_get_num_outputs (UfoFilter *filter);
-void ufo_filter_set_output_channel (UfoFilter *filter,
- guint port,
- UfoChannel *channel);
-UfoChannel * ufo_filter_get_output_channel (UfoFilter *filter,
- guint port);
-void ufo_filter_set_input_channel (UfoFilter *filter,
- guint port,
- UfoChannel *channel);
-void ufo_filter_set_command_queue (UfoFilter *filter,
- gpointer cmd_queue);
-gpointer ufo_filter_get_command_queue (UfoFilter *filter);
-UfoChannel * ufo_filter_get_input_channel (UfoFilter *filter,
- guint port);
-void ufo_filter_wait_until (UfoFilter *filter,
- GParamSpec *pspec,
- UfoFilterConditionFunc condition,
- gpointer user_data);
-GType ufo_filter_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-gpu-node.c b/src/ufo-gpu-node.c
new file mode 100644
index 0000000..b0d377d
--- /dev/null
+++ b/src/ufo-gpu-node.c
@@ -0,0 +1,78 @@
+#include <CL/cl.h>
+#include "ufo-gpu-node.h"
+
+G_DEFINE_TYPE (UfoGpuNode, ufo_gpu_node, UFO_TYPE_NODE)
+
+#define UFO_GPU_NODE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_GPU_NODE, UfoGpuNodePrivate))
+
+
+struct _UfoGpuNodePrivate {
+ gpointer cmd_queue;
+};
+
+UfoNode *
+ufo_gpu_node_new (gpointer cmd_queue)
+{
+ UfoGpuNode *node;
+
+ g_return_val_if_fail (cmd_queue != NULL, NULL);
+ node = UFO_GPU_NODE (g_object_new (UFO_TYPE_GPU_NODE, NULL));
+ node->priv->cmd_queue = cmd_queue;
+ clRetainCommandQueue (cmd_queue);
+
+ return UFO_NODE (node);
+}
+
+gpointer
+ufo_gpu_node_get_cmd_queue (UfoGpuNode *node)
+{
+ g_return_val_if_fail (UFO_IS_GPU_NODE (node), NULL);
+ return node->priv->cmd_queue;
+}
+
+static UfoNode *
+ufo_gpu_node_copy_real (UfoNode *node,
+ GError **error)
+{
+ return UFO_NODE (ufo_gpu_node_new (UFO_GPU_NODE (node)->priv->cmd_queue));
+}
+
+static gboolean
+ufo_gpu_node_equal_real (UfoNode *n1,
+ UfoNode *n2)
+{
+ g_return_val_if_fail (UFO_IS_GPU_NODE (n1) && UFO_IS_GPU_NODE (n2), FALSE);
+ return UFO_GPU_NODE (n1)->priv->cmd_queue == UFO_GPU_NODE (n2)->priv->cmd_queue;
+}
+
+static void
+ufo_gpu_node_dispose (GObject *object)
+{
+ UfoGpuNodePrivate *priv;
+
+ priv = UFO_GPU_NODE_GET_PRIVATE (object);
+ clReleaseCommandQueue (priv->cmd_queue);
+ priv->cmd_queue = NULL;
+ G_OBJECT_CLASS (ufo_gpu_node_parent_class)->dispose (object);
+}
+
+static void
+ufo_gpu_node_class_init (UfoGpuNodeClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+ UfoNodeClass *node_class = UFO_NODE_CLASS (klass);
+
+ oclass->dispose = ufo_gpu_node_dispose;
+ node_class->copy = ufo_gpu_node_copy_real;
+ node_class->equal = ufo_gpu_node_equal_real;
+
+ g_type_class_add_private (klass, sizeof (UfoGpuNodePrivate));
+}
+
+static void
+ufo_gpu_node_init (UfoGpuNode *self)
+{
+ UfoGpuNodePrivate *priv;
+ self->priv = priv = UFO_GPU_NODE_GET_PRIVATE (self);
+ priv->cmd_queue = NULL;
+}
diff --git a/src/ufo-gpu-node.h b/src/ufo-gpu-node.h
new file mode 100644
index 0000000..4e65520
--- /dev/null
+++ b/src/ufo-gpu-node.h
@@ -0,0 +1,49 @@
+#ifndef __UFO_GPU_NODE_H
+#define __UFO_GPU_NODE_H
+
+#include <glib-object.h>
+#include "ufo-node.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_GPU_NODE (ufo_gpu_node_get_type())
+#define UFO_GPU_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_GPU_NODE, UfoGpuNode))
+#define UFO_IS_GPU_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_GPU_NODE))
+#define UFO_GPU_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_GPU_NODE, UfoGpuNodeClass))
+#define UFO_IS_GPU_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_GPU_NODE))
+#define UFO_GPU_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_GPU_NODE, UfoGpuNodeClass))
+
+typedef struct _UfoGpuNode UfoGpuNode;
+typedef struct _UfoGpuNodeClass UfoGpuNodeClass;
+typedef struct _UfoGpuNodePrivate UfoGpuNodePrivate;
+
+/**
+ * UfoGpuNode:
+ *
+ * Main object for organizing filters. The contents of the #UfoGpuNode structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoGpuNode {
+ /*< private >*/
+ UfoNode parent_instance;
+
+ UfoGpuNodePrivate *priv;
+};
+
+/**
+ * UfoGpuNodeClass:
+ *
+ * #UfoGpuNode class
+ */
+struct _UfoGpuNodeClass {
+ /*< private >*/
+ UfoNodeClass parent_class;
+};
+
+UfoNode *ufo_gpu_node_new (gpointer cmd_queue);
+gpointer ufo_gpu_node_get_cmd_queue (UfoGpuNode *gpu_node);
+GType ufo_gpu_node_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-gpu-task-iface.c b/src/ufo-gpu-task-iface.c
new file mode 100644
index 0000000..d830dfa
--- /dev/null
+++ b/src/ufo-gpu-task-iface.c
@@ -0,0 +1,32 @@
+#include "ufo-gpu-task-iface.h"
+
+typedef UfoGpuTaskIface UfoGpuTaskInterface;
+
+G_DEFINE_INTERFACE (UfoGpuTask, ufo_gpu_task, UFO_TYPE_TASK)
+
+gboolean
+ufo_gpu_task_process (UfoGpuTask *task,
+ UfoBuffer **inputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition,
+ UfoGpuNode *node)
+{
+ return UFO_GPU_TASK_GET_IFACE (task)->process (task, inputs, output, requisition, node);
+}
+
+static gboolean
+ufo_gpu_task_process_real (UfoGpuTask *task,
+ UfoBuffer **inputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition,
+ UfoGpuNode *node)
+{
+ g_warning ("`process' of UfoGpuTaskInterface not implemented");
+ return FALSE;
+}
+
+static void
+ufo_gpu_task_default_init (UfoGpuTaskInterface *iface)
+{
+ iface->process = ufo_gpu_task_process_real;
+}
diff --git a/src/ufo-gpu-task-iface.h b/src/ufo-gpu-task-iface.h
new file mode 100644
index 0000000..9a718f4
--- /dev/null
+++ b/src/ufo-gpu-task-iface.h
@@ -0,0 +1,37 @@
+#ifndef UFO_GPU_TASK_IFACE_H
+#define UFO_GPU_TASK_IFACE_H
+
+#include <glib-object.h>
+#include "ufo-gpu-node.h"
+#include "ufo-task-iface.h"
+#include "ufo-buffer.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_GPU_TASK (ufo_gpu_task_get_type())
+#define UFO_GPU_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_GPU_TASK, UfoGpuTask))
+#define UFO_GPU_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_GPU_TASK, UfoGpuTaskIface))
+#define UFO_IS_GPU_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_GPU_TASK))
+#define UFO_IS_GPU_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_GPU_TASK))
+#define UFO_GPU_TASK_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), UFO_TYPE_GPU_TASK, UfoGpuTaskIface))
+
+typedef struct _UfoGpuTask UfoGpuTask;
+typedef struct _UfoGpuTaskIface UfoGpuTaskIface;
+
+struct _UfoGpuTaskIface {
+ UfoTaskIface parent_iface;
+
+ gboolean (*process) (UfoGpuTask *task, UfoBuffer **inputs, UfoBuffer *output, UfoRequisition *requisition, UfoGpuNode *node);
+};
+
+gboolean ufo_gpu_task_process (UfoGpuTask *task,
+ UfoBuffer **inputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition,
+ UfoGpuNode *node);
+
+GType ufo_gpu_task_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-graph.c b/src/ufo-graph.c
index 549fea3..bffdbb1 100644
--- a/src/ufo-graph.c
+++ b/src/ufo-graph.c
@@ -1,70 +1,21 @@
-/**
- * SECTION:ufo-graph
- * @Short_description: Organize filters
- * @Title: UfoGraph
- *
- * A graph object represents the logical relationship between different filter
- * nodes, i.e. how they are connected. Graphs can be constructed from
- * free-standing #UfoFilter objects with ufo_graph_connect_filters() and
- * ufo_graph_connect_filters_full() or load from a JSON description via
- * ufo_graph_read_from_json().
- *
- * A #UfoScheduler object is then used to "execute" the graph.
- */
-
-#include <glib.h>
-#include <json-glib/json-glib.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-graph.h"
-#include "ufo-aux.h"
-#include "ufo-filter-source.h"
-#include "ufo-plugin-manager.h"
+#include <stdio.h>
+#include <ufo-node.h>
+#include <ufo-graph.h>
G_DEFINE_TYPE (UfoGraph, ufo_graph, G_TYPE_OBJECT)
#define UFO_GRAPH_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_GRAPH, UfoGraphPrivate))
-/**
- * UfoTransferMode:
- * @UFO_TRANSFER_MODE_DISTRIBUTE: Distribute data among connected filters.
- * @UFO_TRANSFER_MODE_COPY: Re-use the same input data for all connected
- * filters.
- *
- * The transfer mode specifies how the data is moved from one source filter to
- * multiple sink filters when using ufo_graph_connect_filters_full().
- */
-
-/**
- * UfoGraphError:
- * @UFO_GRAPH_ERROR_ALREADY_LOAD: Graph is already loaded
- * @UFO_GRAPH_ERROR_JSON_KEY: Specified key not found in JSON file
- *
- * Possible errors when loading the graph from JSON.
- */
-GQuark
-ufo_graph_error_quark(void)
-{
- return g_quark_from_static_string("ufo-graph-error-quark");
-}
-
typedef struct {
- UfoFilter *to;
- guint to_port;
- guint from_port;
-} Connection;
+ UfoNode *target;
+ gpointer label;
+} UfoEdge;
struct _UfoGraphPrivate {
- UfoPluginManager *plugin_manager;
- GHashTable *prop_sets; /**< maps from gchar* to JsonNode */
- GHashTable *connections;
- GHashTable *filters;
- GHashTable *json_filters;
+ GHashTable *adjacency;
+ GList *node_types;
+ GList *nodes;
+ guint n_edges;
};
enum {
@@ -72,657 +23,494 @@ enum {
N_PROPERTIES
};
-/* static GParamSpec *graph_properties[N_PROPERTIES] = { NULL, }; */
+UfoGraph *
+ufo_graph_new (void)
+{
+ return UFO_GRAPH (g_object_new (UFO_TYPE_GRAPH, NULL));
+}
-static void
-handle_json_prop_set (JsonObject *object,
- const gchar *name,
- JsonNode *node,
- gpointer user)
+void
+ufo_graph_register_node_type (UfoGraph *graph,
+ GType type)
{
UfoGraphPrivate *priv;
- JsonObject *properties;
- priv = (UfoGraphPrivate *) user;
- properties = json_object_get_object_member (object, name);
- json_object_ref (properties);
- g_hash_table_insert (priv->prop_sets, g_strdup (name), properties);
+ g_return_if_fail (UFO_IS_GRAPH (graph));
+
+ /* Make sure type is at least a node type */
+ g_return_if_fail (g_type_is_a (type, UFO_TYPE_NODE));
+
+ priv = graph->priv;
+ priv->node_types = g_list_append (priv->node_types, GINT_TO_POINTER (type));
}
-static void
-handle_json_single_prop (JsonObject *object,
- const gchar *name,
- JsonNode *node,
- gpointer user)
+/**
+ * ufo_graph_get_registered_node_types:
+ * @graph: A #UfoGraph
+ *
+ * Returns: (element-type GType) (transfer container): A list of #GType
+ * identifiers that can be added to @graph.
+ */
+GList *
+ufo_graph_get_registered_node_types (UfoGraph *graph)
{
- GValue val = {0,};
- json_node_get_value (node, &val);
- g_object_set_property (G_OBJECT(user), name, &val);
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
+ return g_list_copy (graph->priv->node_types);
}
-static gboolean
-handle_json_filter_node (JsonNode *element,
- UfoGraphPrivate *priv,
- GError **error)
+gboolean
+ufo_graph_is_connected (UfoGraph *graph,
+ UfoNode *from,
+ UfoNode *to)
{
- UfoFilter *plugin;
- JsonObject *object;
- GError *tmp_error = NULL;
- const gchar *name;
- const gchar *plugin_name;
-
- object = json_node_get_object (element);
-
- if (!json_object_has_member (object, "plugin") ||
- !json_object_has_member (object, "name")) {
- g_set_error (error, UFO_GRAPH_ERROR, UFO_GRAPH_ERROR_JSON_KEY,
- "Node does not have `plugin' or `name' key");
- return FALSE;
- }
-
- plugin_name = json_object_get_string_member (object, "plugin");
- plugin = ufo_plugin_manager_get_filter (priv->plugin_manager, plugin_name, &tmp_error);
-
- if (tmp_error != NULL) {
- g_propagate_error (error, tmp_error);
- return FALSE;
- }
-
- name = json_object_get_string_member (object, "name");
-
- if (g_hash_table_lookup (priv->json_filters, name) != NULL)
- g_error ("Duplicate name `%s' found", name);
-
- g_hash_table_insert (priv->json_filters, g_strdup (name), plugin);
-
- if (json_object_has_member (object, "properties")) {
- JsonObject *prop_object = json_object_get_object_member (object, "properties");
- json_object_foreach_member (prop_object, handle_json_single_prop, plugin);
- }
+ UfoGraphPrivate *priv;
+ GList *successors;
+ gboolean found = FALSE;
- if (json_object_has_member (object, "prop-refs")) {
- JsonArray *prop_refs;
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), FALSE);
- prop_refs = json_object_get_array_member (object, "prop-refs");
+ priv = graph->priv;
+ successors = g_hash_table_lookup (priv->adjacency, from);
- for (guint i = 0; i < json_array_get_length (prop_refs); i++) {
- const gchar *ref_name = json_array_get_string_element (prop_refs, i);
- JsonObject *prop_set = g_hash_table_lookup (priv->prop_sets, ref_name);
+ for (GList *it = g_list_first (successors); it != NULL; it = g_list_next (it)) {
+ UfoEdge *edge = (UfoEdge *) it->data;
- if (prop_set == NULL) {
- g_warning ("No property set `%s' found in `prop-sets'", ref_name);
- }
- else {
- json_object_foreach_member (prop_set,
- handle_json_single_prop,
- plugin);
- }
+ if (edge->target == to) {
+ found = TRUE;
+ break;
}
}
- return TRUE;
+ return found;
}
-static void
-handle_json_filter_edge (JsonArray *array,
- guint index,
- JsonNode *element,
- gpointer user)
+static gboolean
+is_valid_node_type (UfoGraphPrivate *priv,
+ UfoNode *node)
{
- UfoGraph *graph = user;
- UfoGraphPrivate *priv = graph->priv;
- JsonObject *edge;
- UfoFilter *from_filter, *to_filter;
- JsonObject *from_object, *to_object;
- guint from_port, to_port;
- const gchar *from_name;
- const gchar *to_name;
- GError *error = NULL;
-
- edge = json_node_get_object (element);
-
- if (!json_object_has_member (edge, "from") ||
- !json_object_has_member (edge, "to")) {
- g_error ("Edge does not have `from' or `to' key");
- return;
- }
-
- /* Get from details */
- from_object = json_object_get_object_member (edge, "from");
-
- if (!json_object_has_member (from_object, "name")) {
- g_error ("From node does not have `name' key");
- return;
- }
-
- from_name = json_object_get_string_member (from_object, "name");
- from_port = 0;
-
- if (json_object_has_member (from_object, "output"))
- from_port = (guint) json_object_get_int_member (from_object, "output");
-
- /* Get to details */
- to_object = json_object_get_object_member (edge, "to");
+ for (GList *it = g_list_first (priv->node_types); it != NULL; it = g_list_next (it)) {
+ GType type = (GType) GPOINTER_TO_INT (it->data);
- if (!json_object_has_member (to_object, "name")) {
- g_error ("To node does not have `name' key");
- return;
+ if (G_TYPE_CHECK_INSTANCE_TYPE (node, type))
+ return TRUE;
}
- to_name = json_object_get_string_member (to_object, "name");
- to_port = 0;
-
- if (json_object_has_member (to_object, "input"))
- to_port = (guint) json_object_get_int_member (to_object, "input");
-
- /* Get actual filters and connect them */
- from_filter = g_hash_table_lookup (priv->json_filters, from_name);
- to_filter = g_hash_table_lookup (priv->json_filters, to_name);
-
- ufo_graph_connect_filters_full (graph,
- from_filter, from_port,
- to_filter, to_port,
- UFO_TRANSFER_MODE_DISTRIBUTE,
- &error);
-
- if (error != NULL)
- g_warning ("%s", error->message);
+ return FALSE;
}
static void
-graph_build (UfoGraph *graph, JsonNode *root, GError **error)
+add_node_if_not_found (UfoGraphPrivate *priv,
+ UfoNode *node)
{
- JsonObject *root_object = json_node_get_object(root);
+ if (!g_list_find (priv->nodes, node))
+ priv->nodes = g_list_append (priv->nodes, node);
+}
- if (json_object_has_member(root_object, "prop-sets")) {
- JsonObject *sets = json_object_get_object_member (root_object, "prop-sets");
- json_object_foreach_member (sets, handle_json_prop_set, graph->priv);
- }
+void
+ufo_graph_connect_nodes (UfoGraph *graph,
+ UfoNode *source,
+ UfoNode *target,
+ gpointer edge_label)
+{
+ UfoGraphPrivate *priv;
+ UfoEdge *edge;
+ GList *successors;
- if (json_object_has_member (root_object, "nodes")) {
- JsonArray *nodes = json_object_get_array_member (root_object, "nodes");
- GList *elements = json_array_get_elements (nodes);
+ g_return_if_fail (UFO_IS_GRAPH (graph));
+ priv = graph->priv;
- for (GList *it = g_list_first (elements); it != NULL; it = g_list_next (it)) {
- if (!handle_json_filter_node (it->data, graph->priv, error)) {
- g_list_free (elements);
- return;
- }
- }
+ g_return_if_fail (is_valid_node_type (priv, source) && is_valid_node_type (priv, target));
- g_list_free (elements);
+ edge = g_new0 (UfoEdge, 1);
+ edge->target = target;
+ edge->label = edge_label;
- /*
- * We only check edges if we have nodes, anything else doesn't make much
- * sense.
- */
- if (json_object_has_member (root_object, "edges")) {
- JsonArray *edges = json_object_get_array_member (root_object, "edges");
- json_array_foreach_element (edges, handle_json_filter_edge, graph);
- }
- }
-}
+ successors = g_hash_table_lookup (priv->adjacency, source);
+ successors = g_list_append (successors, edge);
+ g_hash_table_insert (priv->adjacency, source, successors);
-static JsonObject *
-json_object_from_ufo_filter (UfoFilter *filter)
-{
- JsonObject *object = json_object_new ();
+ add_node_if_not_found (priv, source);
+ add_node_if_not_found (priv, target);
- json_object_set_string_member (object, "name", ufo_filter_get_unique_name (filter));
- return object;
+ priv->n_edges++;
}
-static void
-graph_add_filter_to_json_array(gpointer data, gpointer user_data)
+guint
+ufo_graph_get_num_nodes (UfoGraph *graph)
{
- g_return_if_fail (UFO_IS_FILTER (data));
-
- UfoFilter *filter = UFO_FILTER (data);
- JsonArray *array = (JsonArray *) user_data;
- JsonObject *node_object = json_object_new ();
-
- const gchar *plugin_name = ufo_filter_get_plugin_name (filter);
- json_object_set_string_member (node_object, "plugin", plugin_name);
-
- json_object_set_string_member (node_object, "name", ufo_filter_get_unique_name (filter));
-
- JsonNode *prop_node = json_gobject_serialize (G_OBJECT (filter));
- json_object_set_member (node_object, "properties", prop_node);
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), 0);
+ return g_list_length (graph->priv->nodes);
+}
- json_array_add_object_element (array, node_object);
+guint
+ufo_graph_get_num_edges (UfoGraph *graph)
+{
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), 0);
+ return graph->priv->n_edges;
}
/**
- * ufo_graph_new:
- *
- * Create a new #UfoGraph.
+ * ufo_graph_get_nodes:
+ * @graph: A #UfoGraph
*
- * Return value: A #UfoGraph.
+ * Returns: (element-type UfoNode) (transfer container): A list of all nodes
+ * added to @graph.
*/
-UfoGraph *
-ufo_graph_new (void)
+GList *
+ufo_graph_get_nodes (UfoGraph *graph)
{
- return UFO_GRAPH (g_object_new (UFO_TYPE_GRAPH, NULL));
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
+ return graph->priv->nodes;
}
/**
- * ufo_graph_read_from_json:
- * @graph: A #UfoGraph.
- * @manager: A #UfoPluginManager used to load the filters
- * @filename: Path and filename to the JSON file
- * @error: Indicates error in case of failed file loading or parsing
+ * ufo_graph_get_nodes_filtered:
+ * @graph: A #UfoGraph
+ * @func: Predicate function to filter out nodes
*
- * Read a JSON configuration file to fill the filter structure of @graph.
+ * Returns: (element-type UfoNode) (transfer container): A list of all nodes
+ * that are marked as true by the predicate function @func.
*/
-void
-ufo_graph_read_from_json (UfoGraph *graph, UfoPluginManager *manager, const gchar *filename, GError **error)
+GList *
+ufo_graph_get_nodes_filtered (UfoGraph *graph,
+ UfoFilterPredicate func)
{
- g_return_if_fail (UFO_IS_GRAPH(graph) && UFO_IS_PLUGIN_MANAGER (manager) && (filename != NULL));
- JsonParser *json_parser = json_parser_new ();
- GError *tmp_error = NULL;
+ UfoGraphPrivate *priv;
+ GList *result = NULL;
- if (!json_parser_load_from_file (json_parser, filename, &tmp_error)) {
- g_propagate_prefixed_error (error, tmp_error, "Parsing JSON: ");
- return;
- }
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
+ priv = graph->priv;
- graph->priv->plugin_manager = manager;
- g_object_ref (manager);
+ for (GList *it = g_list_first (priv->nodes); it != NULL; it = g_list_next (it)) {
+ UfoNode *node = UFO_NODE (it->data);
+
+ if (func (node))
+ result = g_list_append (result, node);
+ }
- graph_build (graph, json_parser_get_root (json_parser), error);
- g_object_unref (json_parser);
+ return result;
}
-/**
- * ufo_graph_save_to_json:
- * @graph: A #UfoGraph.
- * @filename: Path and filename to the JSON file
- * @error: Indicates error in case of failed file saving
- *
- * Save a JSON configuration file with the filter structure of @graph.
- */
void
-ufo_graph_save_to_json (UfoGraph *graph, const gchar *filename, GError **error)
+ufo_graph_remove_edge (UfoGraph *graph,
+ UfoNode *source,
+ UfoNode *target)
{
UfoGraphPrivate *priv;
- GList *filters;
- GList *sources;
- GError *tmp_error = NULL;
-
- g_return_if_fail (UFO_IS_GRAPH (graph) && (filename != NULL));
+ GList *edges;
- priv = UFO_GRAPH_GET_PRIVATE (graph);
-
- JsonGenerator *json_generator = json_generator_new ();
- JsonNode *root_node = json_node_new (JSON_NODE_OBJECT);
- JsonObject *root_object = json_object_new ();
- JsonArray *nodes = json_array_new ();
- JsonArray *edges = json_array_new ();
+ g_return_if_fail (UFO_IS_GRAPH (graph));
+ priv = graph->priv;
- filters = g_hash_table_get_keys (priv->filters);
- g_list_foreach (filters, graph_add_filter_to_json_array, nodes);
- g_list_free (filters);
+ edges = g_hash_table_lookup (priv->adjacency, source);
- sources = g_hash_table_get_keys (priv->connections);
+ if (edges != NULL) {
+ UfoEdge *edge = NULL;
- for (GList *it = g_list_first (sources); it != NULL; it = g_list_next (it)) {
- UfoFilter *from;
- GList *connections;
+ for (GList *it = g_list_first (edges); it != NULL; it = g_list_next (it)) {
+ UfoEdge *candidate = (UfoEdge *) it->data;
- from = UFO_FILTER (it->data);
- connections = g_hash_table_lookup (priv->connections, from);
+ if (candidate->target == target) {
+ edge = candidate;
+ break;
+ }
+ }
- for (GList *jt = g_list_first (connections); jt != NULL; jt = g_list_next (jt)) {
- Connection *c = (Connection *) jt->data;
+ if (edge != NULL) {
+ priv->nodes = g_list_remove (priv->nodes, source);
+ g_object_unref (source);
- JsonObject *to_object = json_object_from_ufo_filter (c->to);
- JsonObject *from_object = json_object_from_ufo_filter (from);
- JsonObject *edge_object = json_object_new ();
+ priv->nodes = g_list_remove (priv->nodes, edge->target);
+ g_object_unref (edge->target);
- json_object_set_int_member (to_object, "input", c->to_port);
- json_object_set_int_member (from_object, "output", c->from_port);
- json_object_set_object_member (edge_object, "to", to_object);
- json_object_set_object_member (edge_object, "from", from_object);
- json_array_add_object_element (edges, edge_object);
+ edges = g_list_remove (edges, edge);
+ g_hash_table_insert (priv->adjacency, source, edges);
}
-
- g_list_free (connections);
}
- g_list_free (sources);
+ priv->n_edges--;
+}
- json_object_set_array_member(root_object, "nodes", nodes);
- json_object_set_array_member(root_object, "edges", edges);
- json_node_set_object(root_node, root_object);
- json_generator_set_root(json_generator, root_node);
+gpointer
+ufo_graph_get_edge_label (UfoGraph *graph,
+ UfoNode *source,
+ UfoNode *target)
+{
+ UfoGraphPrivate *priv;
+ GList *edges;
- if (!json_generator_to_file(json_generator, filename, &tmp_error)) {
- g_propagate_error(error, tmp_error);
- return;
- }
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
+ priv = graph->priv;
+ edges = g_hash_table_lookup (priv->adjacency, source);
- g_object_unref(json_generator);
-}
+ for (GList *it = g_list_first (edges); it != NULL; it = g_list_next (it)) {
+ UfoEdge *edge = (UfoEdge *) it->data;
-/**
- * ufo_graph_connect_filters:
- * @graph: A #UfoGraph
- * @from: Source filter
- * @to: Destination filter
- * @error: return location for error
- *
- * Connect to filters using their default input and output ports.
- */
-void
-ufo_graph_connect_filters (UfoGraph *graph, UfoFilter *from, UfoFilter *to, GError **error)
-{
- ufo_graph_connect_filters_full (graph, from, 0, to, 0, UFO_TRANSFER_MODE_DISTRIBUTE, error);
-}
+ if (edge->target == target) {
+ gpointer label = edge->label;
+ return label;
+ }
+ }
-static void
-add_connection (UfoGraphPrivate *priv,
- UfoFilter *from,
- guint from_port,
- UfoFilter *to,
- guint to_port)
-{
- GList *connections;
- Connection *c;
-
- c = g_new0 (Connection, 1);
- c->from_port = from_port;
- c->to = to;
- c->to_port = to_port;
-
- connections = g_hash_table_lookup (priv->connections, from);
- connections = g_list_append (connections, c);
- g_hash_table_insert (priv->connections, from, connections);
- g_hash_table_insert (priv->filters, from, NULL);
- g_hash_table_insert (priv->filters, to, NULL);
+ g_warning ("target not found");
+ return NULL;
}
-static GList *
-get_connected_set (UfoGraphPrivate *priv,
- UfoFilter *from,
- guint from_port)
+static gboolean
+has_predecessor (UfoGraph *graph,
+ UfoNode *node)
{
- GList *connections;
- GList *set = NULL;
-
- connections = g_hash_table_lookup (priv->connections, from);
-
- for (GList *it = g_list_first (connections); it != NULL; it = g_list_next (it)) {
- Connection *c = (Connection *) it->data;
+ for (GList *it = g_list_first (graph->priv->nodes); it != NULL; it = g_list_next (it)) {
+ UfoNode *source = (UfoNode *) it->data;
- if (c->from_port == from_port)
- set = g_list_append (set, c);
+ if (ufo_graph_is_connected (graph, source, node))
+ return TRUE;
}
- return set;
+ return FALSE;
}
/**
- * ufo_graph_connect_filters_full:
+ * ufo_graph_get_roots:
* @graph: A #UfoGraph
- * @from: Source filter
- * @from_port: Source output port
- * @to: Destination filter
- * @to_port: Destination input port
- * @mode: Transfer mode for multiple sinks
- * @error: return location for error
*
- * Connect two filters with the specified input and output ports.
+ * Returns: (element-type UfoNode) (transfer container): A list of all nodes
+ * that do not have a predessor node.
*/
-void
-ufo_graph_connect_filters_full (UfoGraph *graph,
- UfoFilter *from,
- guint from_port,
- UfoFilter *to,
- guint to_port,
- UfoTransferMode mode,
- GError **error)
+GList *
+ufo_graph_get_roots (UfoGraph *graph)
{
UfoGraphPrivate *priv;
- UfoChannel *channel;
+ GList *result;
- g_return_if_fail (UFO_IS_GRAPH (graph) && UFO_IS_FILTER (from) && UFO_IS_FILTER (to));
+ g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
priv = graph->priv;
+ result = NULL;
- channel = ufo_filter_get_input_channel (to, to_port);
-
- if (channel != NULL) {
- g_warning ("Input %s:%i is already in use.",
- ufo_filter_get_unique_name (to),
- to_port);
- }
-
- channel = ufo_filter_get_output_channel (from, from_port);
-
- if (mode == UFO_TRANSFER_MODE_DISTRIBUTE) {
- if (channel == NULL) {
- channel = ufo_filter_get_input_channel (to, to_port);
-
- if (channel == NULL)
- channel = ufo_channel_new ();
- }
-
- ufo_filter_set_output_channel (from, from_port, channel);
- ufo_filter_set_input_channel (to, to_port, channel);
- ufo_channel_ref (channel);
- }
- else if (mode == UFO_TRANSFER_MODE_COPY) {
- if (channel == NULL) {
- channel = ufo_filter_get_input_channel (to, to_port);
-
- if (channel == NULL)
- channel = ufo_channel_new ();
+ for (GList *it = g_list_first (priv->nodes); it != NULL; it = g_list_next (it)) {
+ UfoNode *node = (UfoNode *) it->data;
- ufo_filter_set_output_channel (from, from_port, channel);
- ufo_filter_set_input_channel (to, to_port, channel);
- ufo_channel_ref (channel);
- }
- else {
- GList *set;
- GList *last;
- Connection *connection;
- UfoChannel *new_channel;
-
- set = get_connected_set (priv, from, from_port);
- last = g_list_last (set);
- g_assert (last != NULL);
-
- connection = (Connection *) last->data;
- channel = ufo_filter_get_input_channel (connection->to, connection->to_port);
- g_assert (channel != NULL);
-
- new_channel = ufo_channel_new ();
- ufo_channel_ref (new_channel);
- ufo_channel_daisy_chain (channel, new_channel);
- ufo_filter_set_input_channel (to, to_port, new_channel);
- }
+ if (!has_predecessor (graph, node))
+ result = g_list_append (result, node);
}
- add_connection (priv, from, from_port, to, to_port);
- g_debug ("Connected %s:%i and %s:%i",
- ufo_filter_get_unique_name (from), from_port,
- ufo_filter_get_unique_name (to), to_port);
+ return result;
}
/**
- * ufo_graph_get_filters:
+ * ufo_graph_get_successors:
* @graph: A #UfoGraph
*
- * Return a list of all filter nodes of @graph.
- *
- * Returns: (element-type UfoFilter) (transfer full): List of filter nodes. Use
- * g_list_free() when done using the list.
+ * Returns: (element-type UfoNode) (transfer container): All succeeding nodes of
+ * @node.
*/
GList *
-ufo_graph_get_filters (UfoGraph *graph)
+ufo_graph_get_successors (UfoGraph *graph,
+ UfoNode *node)
{
+ UfoGraphPrivate *priv;
+ GList *edges;
+ GList *result;
+
g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
- return g_hash_table_get_keys (graph->priv->filters);
+ priv = graph->priv;
+ edges = g_hash_table_lookup (priv->adjacency, node);
+ result = NULL;
+
+ for (GList *it = g_list_first (edges); it != NULL; it = g_list_next (it)) {
+ UfoEdge *edge = (UfoEdge *) it->data;
+ result = g_list_prepend (result, edge->target);
+ }
+
+ return result;
}
/**
- * ufo_graph_get_num_filters:
+ * ufo_graph_split:
* @graph: A #UfoGraph
+ * @path: (element-type UfoNode): A path of nodes, preferably created with
+ * ufo_graph_get_paths().
*
- * Return the number of filters connected in the graph.
- *
- * Returns: Number of filters.
+ * Duplicate nodes between head and tail of path and insert at the exact the
+ * position of where path started and ended.
*/
-guint
-ufo_graph_get_num_filters (UfoGraph *graph)
+void
+ufo_graph_split (UfoGraph *graph,
+ GList *path)
{
- GList *filters;
- guint n_filters;
+ GList *head;
+ GList *tail;
+ UfoNode *orig;
+ UfoNode *current;
+ GError *error = NULL;
+
+ g_return_if_fail (UFO_IS_GRAPH (graph));
+
+ head = g_list_first (path);
+ tail = g_list_last (path);
+ g_assert (head != tail);
+
+ orig = UFO_NODE (head->data);
- filters = ufo_graph_get_filters (graph);
- n_filters = g_list_length (filters);
- g_list_free (filters);
- return n_filters;
+ /* The first link goes from the original head */
+ current = orig;
+
+ for (GList *it = g_list_next (head); it != tail; it = g_list_next (it)) {
+ UfoNode *next;
+ UfoNode *copy;
+ gpointer label;
+
+ next = UFO_NODE (it->data);
+ copy = ufo_node_copy (next, &error);
+ label = ufo_graph_get_edge_label (graph, orig, next);
+ ufo_graph_connect_nodes (graph, current, copy, label);
+ current = copy;
+ orig = next;
+ }
+
+ if (tail->data != NULL) {
+ ufo_graph_connect_nodes (graph, current, UFO_NODE (tail->data),
+ ufo_graph_get_edge_label (graph, orig, UFO_NODE (tail->data)));
+ }
}
-/**
- * ufo_graph_get_roots:
- * @graph: A #UfoGraph
- *
- * Return a list of #UfoFilterSource nodes in @graph that do not have any
- * parents.
- *
- * Returns: (element-type UfoFilter) (transfer none): List of filter nodes. Use
- * g_list_free() when done using the list.
- */
-GList *
-ufo_graph_get_roots (UfoGraph *graph)
+static void
+pickup_paths (UfoGraph *graph,
+ UfoFilterPredicate pred,
+ UfoNode *current,
+ UfoNode *last,
+ GList *current_path,
+ GList **paths)
{
- GList *filters;
- GList *roots = NULL;
+ GList *successors;
- g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
- filters = ufo_graph_get_filters (graph);
+ if (pred (current)) {
+ if (!pred (last))
+ current_path = g_list_append (current_path, last);
+
+ current_path = g_list_append (current_path, current);
+ }
+ else {
+ if (current_path != NULL) {
+ current_path = g_list_append (current_path, current);
+ *paths = g_list_append (*paths, current_path);
+ }
- for (GList *it = g_list_first (filters); it != NULL; it = g_list_next (it)) {
- if (UFO_IS_FILTER_SOURCE (it->data))
- roots = g_list_append (roots, it->data);
+ current_path = NULL;
}
- g_list_free (filters);
- return roots;
+ successors = ufo_graph_get_successors (graph, current);
+
+ for (GList *it = g_list_first (successors); it != NULL; it = g_list_next (it))
+ pickup_paths (graph, pred, it->data, current, g_list_copy (current_path), paths);
+
+ g_list_free (successors);
}
/**
- * ufo_graph_get_children:
+ * ufo_graph_get_paths:
* @graph: A #UfoGraph
- * @filter: A #UfoFilter
+ * @pred: A predicate function
*
- * Return a list of nodes in @graph that @filter connects to.
+ * Compute a list of lists that contain complete paths with nodes that match a
+ * predicate function.
*
- * Returns: (element-type UfoFilter) (transfer none): List of filter nodes. Use g_list_free()
- * when done using the list.
+ * Returns: (element-type GLib.GList) (transfer full): A list of lists with paths
+ * that match @pred.
*/
GList *
-ufo_graph_get_children (UfoGraph *graph,
- UfoFilter *filter)
+ufo_graph_get_paths (UfoGraph *graph,
+ UfoFilterPredicate pred)
{
- UfoGraphPrivate *priv;
- GList *connections;
- GList *result = NULL;
+ GList *roots;
+ GList *paths = NULL;
- g_return_val_if_fail (UFO_IS_GRAPH (graph), NULL);
- priv = graph->priv;
- connections = g_hash_table_lookup (priv->connections, filter);
+ roots = ufo_graph_get_roots (graph);
- for (GList *it = g_list_first (connections); it != NULL; it = g_list_next (it)) {
- Connection *c = (Connection *) it->data;
- result = g_list_append (result, c->to);
+ for (GList *it = g_list_first (roots); it != NULL; it = g_list_next (it)) {
+ UfoNode *node = UFO_NODE (it->data);
+ pickup_paths (graph, pred, node, node, NULL, &paths);
}
- return result;
+ g_list_free (roots);
+ return paths;
}
-static void
-unref_list_elements (GList *l)
+void
+ufo_graph_dump_dot (UfoGraph *graph,
+ const gchar *filename)
{
- g_list_foreach (l, (GFunc) g_object_unref, NULL);
-}
+ FILE *fp;
+ GList *nodes;
-static void
-ufo_graph_dispose(GObject *object)
-{
- UfoGraph *graph = UFO_GRAPH (object);
- UfoGraphPrivate *priv = UFO_GRAPH_GET_PRIVATE (graph);
+ fp = fopen (filename, "w");
+ fprintf (fp, "digraph foo {\n");
- unref_list_elements (g_hash_table_get_values (priv->json_filters));
+ nodes = ufo_graph_get_nodes (graph);
- ufo_unref_stored_object ((GObject **) &priv->plugin_manager);
+ for (GList *it = g_list_first (nodes); it != NULL; it = g_list_next (it)) {
+ UfoNode *source;
+ GList *successors;
- G_OBJECT_CLASS (ufo_graph_parent_class)->dispose (object);
- g_message ("UfoGraph: disposed");
-}
+ source = UFO_NODE (it->data);
+ successors = ufo_graph_get_successors (graph, source);
-static void
-ufo_graph_finalize (GObject *object)
-{
- UfoGraph *self = UFO_GRAPH (object);
- UfoGraphPrivate *priv = UFO_GRAPH_GET_PRIVATE (self);
+ for (GList *jt = g_list_first (successors); jt != NULL; jt = g_list_next (jt)) {
+ UfoNode *target;
- g_hash_table_destroy (priv->prop_sets);
- g_hash_table_destroy (priv->json_filters);
- g_hash_table_destroy (priv->filters);
- g_hash_table_destroy (priv->connections);
+ target = UFO_NODE (jt->data);
- priv->connections = NULL;
- priv->prop_sets = NULL;
+ fprintf (fp, " %s_%p -> %s_%p;\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (source)), (gpointer) source,
+ g_type_name (G_TYPE_FROM_INSTANCE (target)), (gpointer) target);
+ }
- G_OBJECT_CLASS (ufo_graph_parent_class)->finalize (object);
- g_message ("UfoGraph: finalized");
-}
+ g_list_free (successors);
+ }
-static void
-ufo_graph_constructed (GObject *object)
-{
- if (G_OBJECT_CLASS (ufo_graph_parent_class)->constructed != NULL)
- G_OBJECT_CLASS (ufo_graph_parent_class)->constructed (object);
+ fprintf (fp, "}\n");
+ fclose (fp);
}
static void
-ufo_graph_set_property(GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+ufo_graph_dispose (GObject *object)
{
- switch (property_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
+ UfoGraphPrivate *priv;
+
+ priv = UFO_GRAPH_GET_PRIVATE (object);
+
+ if (priv->adjacency != NULL) {
+ g_hash_table_destroy (priv->adjacency);
+ priv->adjacency = NULL;
}
+
+ g_list_foreach (priv->nodes, (GFunc) g_object_unref, NULL);
+
+ G_OBJECT_CLASS (ufo_graph_parent_class)->dispose (object);
}
static void
-ufo_graph_get_property(GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+ufo_graph_finalize (GObject *object)
{
- switch (property_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
+ UfoGraphPrivate *priv;
+
+ priv = UFO_GRAPH_GET_PRIVATE (object);
+
+ if (priv->nodes) {
+ g_list_free (priv->nodes);
+ priv->nodes = NULL;
}
+
+ G_OBJECT_CLASS (ufo_graph_parent_class)->finalize (object);
}
static void
ufo_graph_class_init (UfoGraphClass *klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
- gobject_class->set_property = ufo_graph_set_property;
- gobject_class->get_property = ufo_graph_get_property;
- gobject_class->dispose = ufo_graph_dispose;
- gobject_class->finalize = ufo_graph_finalize;
- gobject_class->constructed = ufo_graph_constructed;
+ oclass->dispose = ufo_graph_dispose;
+ oclass->finalize = ufo_graph_finalize;
g_type_class_add_private(klass, sizeof(UfoGraphPrivate));
}
@@ -732,16 +520,8 @@ ufo_graph_init (UfoGraph *self)
{
UfoGraphPrivate *priv;
self->priv = priv = UFO_GRAPH_GET_PRIVATE (self);
-
- priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, NULL);
- priv->filters = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, NULL);
- priv->prop_sets = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify) json_object_unref);
- priv->json_filters = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, NULL);
-
- g_thread_init (NULL);
+ priv->adjacency = g_hash_table_new (g_direct_hash, g_direct_equal);
+ priv->node_types = NULL;
+ priv->nodes = NULL;
+ priv->n_edges = 0;
}
-
diff --git a/src/ufo-graph.h b/src/ufo-graph.h
index 8067b2b..a8b6f89 100644
--- a/src/ufo-graph.h
+++ b/src/ufo-graph.h
@@ -2,8 +2,7 @@
#define __UFO_GRAPH_H
#include <glib-object.h>
-#include "ufo-plugin-manager.h"
-#include "ufo-filter.h"
+#include "ufo-node.h"
G_BEGIN_DECLS
@@ -14,21 +13,12 @@ G_BEGIN_DECLS
#define UFO_IS_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_GRAPH))
#define UFO_GRAPH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_GRAPH, UfoGraphClass))
-#define UFO_GRAPH_ERROR ufo_graph_error_quark()
-typedef enum {
- UFO_GRAPH_ERROR_ALREADY_LOAD,
- UFO_GRAPH_ERROR_JSON_KEY
-} UfoGraphError;
-
-typedef enum {
- UFO_TRANSFER_MODE_DISTRIBUTE,
- UFO_TRANSFER_MODE_COPY
-} UfoTransferMode;
-
typedef struct _UfoGraph UfoGraph;
typedef struct _UfoGraphClass UfoGraphClass;
typedef struct _UfoGraphPrivate UfoGraphPrivate;
+typedef gboolean (*UfoFilterPredicate) (UfoNode *node);
+
/**
* UfoGraph:
*
@@ -53,31 +43,38 @@ struct _UfoGraphClass {
};
UfoGraph *ufo_graph_new (void);
-void ufo_graph_read_from_json (UfoGraph *graph,
- UfoPluginManager *manager,
- const gchar *filename,
- GError **error);
-void ufo_graph_save_to_json (UfoGraph *graph,
- const gchar *filename,
- GError **error);
-void ufo_graph_connect_filters (UfoGraph *graph,
- UfoFilter *from,
- UfoFilter *to,
- GError **error);
-void ufo_graph_connect_filters_full (UfoGraph *graph,
- UfoFilter *from,
- guint from_port,
- UfoFilter *to,
- guint to_port,
- UfoTransferMode mode,
- GError **error);
-GList *ufo_graph_get_filters (UfoGraph *graph);
-guint ufo_graph_get_num_filters (UfoGraph *graph);
-GList *ufo_graph_get_roots (UfoGraph *graph);
-GList *ufo_graph_get_children (UfoGraph *graph,
- UfoFilter *filter);
+void ufo_graph_register_node_type (UfoGraph *graph,
+ GType type);
+GList *ufo_graph_get_registered_node_types
+ (UfoGraph *graph);
+void ufo_graph_connect_nodes (UfoGraph *graph,
+ UfoNode *source,
+ UfoNode *target,
+ gpointer edge_label);
+gboolean ufo_graph_is_connected (UfoGraph *graph,
+ UfoNode *from,
+ UfoNode *to);
+void ufo_graph_remove_edge (UfoGraph *graph,
+ UfoNode *source,
+ UfoNode *target);
+gpointer ufo_graph_get_edge_label (UfoGraph *graph,
+ UfoNode *source,
+ UfoNode *target);
+guint ufo_graph_get_num_nodes (UfoGraph *graph);
+guint ufo_graph_get_num_edges (UfoGraph *graph);
+GList *ufo_graph_get_nodes (UfoGraph *graph);
+GList *ufo_graph_get_nodes_filtered (UfoGraph *graph,
+ UfoFilterPredicate func);
+GList *ufo_graph_get_roots (UfoGraph *graph);
+GList *ufo_graph_get_successors (UfoGraph *graph,
+ UfoNode *node);
+GList *ufo_graph_get_paths (UfoGraph *graph,
+ UfoFilterPredicate pred);
+void ufo_graph_split (UfoGraph *graph,
+ GList *path);
+void ufo_graph_dump_dot (UfoGraph *graph,
+ const gchar *filename);
GType ufo_graph_get_type (void);
-GQuark ufo_graph_error_quark (void);
G_END_DECLS
diff --git a/src/ufo-group.c b/src/ufo-group.c
new file mode 100644
index 0000000..25b08fa
--- /dev/null
+++ b/src/ufo-group.c
@@ -0,0 +1,233 @@
+#include <CL/cl.h>
+#include "ufo-group.h"
+#include "ufo-task-node.h"
+
+G_DEFINE_TYPE (UfoGroup, ufo_group, G_TYPE_OBJECT)
+
+#define UFO_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_GROUP, UfoGroupPrivate))
+
+typedef struct {
+ GAsyncQueue *queues[2];
+ guint capacity;
+} UfoQueue;
+
+struct _UfoGroupPrivate {
+ GList *targets;
+ guint n_targets;
+ UfoQueue **queues;
+ gboolean *ready;
+ UfoSendPattern pattern;
+ guint current;
+ cl_context context;
+ GList *buffers;
+};
+
+enum {
+ PROP_0,
+ N_PROPERTIES
+};
+
+typedef enum {
+ UFO_QUEUE_PRODUCER = 0,
+ UFO_QUEUE_CONSUMER = 1
+} UfoQueueAccess;
+
+static UfoQueue *ufo_queue_new (void);
+static gpointer ufo_queue_pop (UfoQueue *queue, UfoQueueAccess access);
+static void ufo_queue_push (UfoQueue *queue, UfoQueueAccess access, gpointer data);
+static void ufo_queue_insert (UfoQueue *queue, UfoQueueAccess access, gpointer data);
+static guint ufo_queue_get_capacity (UfoQueue *queue);
+
+/**
+ * ufo_group_new:
+ * @targets: (element-type UfoNode): A list of #UfoNode targets
+ * @context: A cl_context on which the targets should operate on.
+ *
+ * Returns: A new #UfoGroup.
+ */
+UfoGroup *
+ufo_group_new (GList *targets,
+ gpointer context)
+{
+ UfoGroup *group;
+ UfoGroupPrivate *priv;
+
+ group = UFO_GROUP (g_object_new (UFO_TYPE_GROUP, NULL));
+ priv = group->priv;
+
+ priv->targets = targets;
+ priv->n_targets = g_list_length (targets);
+ priv->queues = g_new0 (UfoQueue *, priv->n_targets);
+ priv->pattern = UFO_SEND_SCATTER;
+ priv->current = 0;
+ priv->context = context;
+
+ for (guint i = 0; i < priv->n_targets; i++)
+ priv->queues[i] = ufo_queue_new ();
+
+ return group;
+}
+
+UfoBuffer *
+ufo_group_pop_output_buffer (UfoGroup *group,
+ UfoRequisition *requisition)
+{
+ UfoBuffer *output;
+ UfoGroupPrivate *priv;
+
+ priv = group->priv;
+
+ if (ufo_queue_get_capacity (priv->queues[priv->current]) < priv->n_targets) {
+ output = ufo_buffer_new (requisition, priv->context);
+ priv->buffers = g_list_append (priv->buffers, output);
+ ufo_queue_insert (priv->queues[priv->current],
+ UFO_QUEUE_PRODUCER,
+ output);
+ }
+
+ output = ufo_queue_pop (priv->queues[priv->current],
+ UFO_QUEUE_PRODUCER);
+
+ if (!ufo_buffer_cmp_dimensions (output, requisition))
+ ufo_buffer_resize (output, requisition);
+
+ return output;
+}
+
+void
+ufo_group_push_output_buffer (UfoGroup *group,
+ UfoBuffer *buffer)
+{
+ UfoGroupPrivate *priv;
+
+ priv = group->priv;
+
+ /* Copy or not depending on the send pattern */
+ if (priv->pattern == UFO_SEND_SCATTER) {
+ ufo_queue_push (priv->queues[priv->current],
+ UFO_QUEUE_PRODUCER,
+ buffer);
+
+ priv->current = (priv->current + 1) % priv->n_targets;
+ }
+ else
+ g_print ("Other send methods are not yet supported\n");
+}
+
+UfoBuffer *
+ufo_group_pop_input_buffer (UfoGroup *group,
+ UfoTask *target)
+{
+ UfoGroupPrivate *priv;
+ UfoBuffer *input;
+ gint pos;
+
+ priv = group->priv;
+ pos = g_list_index (priv->targets, target);
+ input = pos >= 0 ? ufo_queue_pop (priv->queues[pos], UFO_QUEUE_CONSUMER) : NULL;
+
+ return input;
+}
+
+void
+ufo_group_push_input_buffer (UfoGroup *group,
+ UfoTask *target,
+ UfoBuffer *input)
+{
+ UfoGroupPrivate *priv;
+ gint pos;
+
+ priv = group->priv;
+ pos = g_list_index (priv->targets, target);
+
+ if (pos >= 0)
+ ufo_queue_push (priv->queues[pos], UFO_QUEUE_CONSUMER, input);
+}
+
+void
+ufo_group_finish (UfoGroup *group)
+{
+ UfoGroupPrivate *priv;
+
+ priv = group->priv;
+
+ for (guint i = 0; i < priv->n_targets; i++) {
+ ufo_queue_push (priv->queues[i],
+ UFO_QUEUE_PRODUCER,
+ UFO_END_OF_STREAM);
+ }
+}
+
+static UfoQueue *
+ufo_queue_new (void)
+{
+ UfoQueue *queue = g_new0 (UfoQueue, 1);
+ queue->queues[0] = g_async_queue_new ();
+ queue->queues[1] = g_async_queue_new ();
+ queue->capacity = 0;
+ return queue;
+}
+
+static gpointer
+ufo_queue_pop (UfoQueue *queue, UfoQueueAccess access)
+{
+ return g_async_queue_pop (queue->queues[access]);
+}
+
+static void
+ufo_queue_push (UfoQueue *queue, UfoQueueAccess access, gpointer data)
+{
+ g_async_queue_push (queue->queues[1-access], data);
+}
+
+static void
+ufo_queue_insert (UfoQueue *queue, UfoQueueAccess access, gpointer data)
+{
+ g_async_queue_push (queue->queues[access], data);
+ queue->capacity++;
+}
+
+static guint
+ufo_queue_get_capacity (UfoQueue *queue)
+{
+ return queue->capacity;
+}
+
+static void
+ufo_group_dispose(GObject *object)
+{
+ UfoGroupPrivate *priv;
+
+ priv = UFO_GROUP_GET_PRIVATE (object);
+ g_list_foreach (priv->buffers, (GFunc) g_object_unref, NULL);
+ G_OBJECT_CLASS (ufo_group_parent_class)->dispose (object);
+}
+
+static void
+ufo_group_finalize (GObject *object)
+{
+ UfoGroupPrivate *priv;
+
+ priv = UFO_GROUP_GET_PRIVATE (object);
+ g_list_free (priv->buffers);
+ G_OBJECT_CLASS (ufo_group_parent_class)->finalize (object);
+}
+
+static void
+ufo_group_class_init (UfoGroupClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = ufo_group_dispose;
+ gobject_class->finalize = ufo_group_finalize;
+
+ g_type_class_add_private(klass, sizeof(UfoGroupPrivate));
+}
+
+static void
+ufo_group_init (UfoGroup *self)
+{
+ UfoGroupPrivate *priv;
+ self->priv = priv = UFO_GROUP_GET_PRIVATE (self);
+ priv->buffers = NULL;
+}
diff --git a/src/ufo-group.h b/src/ufo-group.h
new file mode 100644
index 0000000..124e0b7
--- /dev/null
+++ b/src/ufo-group.h
@@ -0,0 +1,62 @@
+#ifndef __UFO_GROUP_H
+#define __UFO_GROUP_H
+
+#include <glib-object.h>
+#include "ufo-task-iface.h"
+#include "ufo-buffer.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_GROUP (ufo_group_get_type())
+#define UFO_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_GROUP, UfoGroup))
+#define UFO_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_GROUP))
+#define UFO_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_GROUP, UfoGroupClass))
+#define UFO_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_GROUP))
+#define UFO_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_GROUP, UfoGroupClass))
+
+typedef struct _UfoGroup UfoGroup;
+typedef struct _UfoGroupClass UfoGroupClass;
+typedef struct _UfoGroupPrivate UfoGroupPrivate;
+
+#define UFO_END_OF_STREAM (GINT_TO_POINTER(1))
+
+/**
+ * UfoGroup:
+ *
+ * Main object for organizing filters. The contents of the #UfoGroup structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoGroup {
+ /*< private >*/
+ GObject parent_instance;
+
+ UfoGroupPrivate *priv;
+};
+
+/**
+ * UfoGroupClass:
+ *
+ * #UfoGroup class
+ */
+struct _UfoGroupClass {
+ /*< private >*/
+ GObjectClass parent_class;
+};
+
+UfoGroup * ufo_group_new (GList *targets,
+ gpointer context);
+UfoBuffer * ufo_group_pop_output_buffer (UfoGroup *group,
+ UfoRequisition *requisition);
+void ufo_group_push_output_buffer (UfoGroup *group,
+ UfoBuffer *buffer);
+UfoBuffer * ufo_group_pop_input_buffer (UfoGroup *group,
+ UfoTask *target);
+void ufo_group_push_input_buffer (UfoGroup *group,
+ UfoTask *target,
+ UfoBuffer *input);
+void ufo_group_finish (UfoGroup *group);
+GType ufo_group_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-input-task.c b/src/ufo-input-task.c
new file mode 100644
index 0000000..516f566
--- /dev/null
+++ b/src/ufo-input-task.c
@@ -0,0 +1,216 @@
+/**
+ * SECTION:ufo-input-task
+ * @Short_description: Write TIFF files
+ * @Title: Input task
+ *
+ * The writer node writes each incoming image as a TIFF using libtiff to disk.
+ * Each file is prefixed with #UfoInputTask:prefix and written into
+ * #UfoInputTask:path.
+ */
+
+#ifdef __APPLE__
+#include <OpenCL/cl.h>
+#else
+#include <CL/cl.h>
+#endif
+#include <gmodule.h>
+#include <tiffio.h>
+#include <ufo-input-task.h>
+#include <ufo-cpu-task-iface.h>
+#include <ufo-gpu-task-iface.h>
+#include <ufo-gpu-node.h>
+
+struct _UfoInputTaskPrivate {
+ GAsyncQueue **in_queues;
+ GAsyncQueue **out_queues;
+ UfoTask *wrapped;
+ UfoInputParameter *in_params;
+ gboolean active;
+ guint n_inputs;
+ UfoBuffer **inputs;
+};
+
+static void ufo_task_interface_init (UfoTaskIface *iface);
+static void ufo_cpu_task_interface_init (UfoCpuTaskIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UfoInputTask, ufo_input_task, UFO_TYPE_TASK_NODE,
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
+ ufo_task_interface_init)
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_CPU_TASK,
+ ufo_cpu_task_interface_init))
+
+#define UFO_INPUT_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_INPUT_TASK, UfoInputTaskPrivate))
+
+enum {
+ PROP_0,
+ N_PROPERTIES
+};
+
+UfoNode *
+ufo_input_task_new (UfoTask *wrapped)
+{
+ UfoInputTask *task;
+ UfoInputTaskPrivate *priv;
+
+ task = UFO_INPUT_TASK (g_object_new (UFO_TYPE_INPUT_TASK, NULL));
+ priv = task->priv;
+ priv->wrapped = wrapped;
+
+ /* TODO: free in_params and queues */
+ ufo_task_get_structure (wrapped, &priv->n_inputs, &priv->in_params);
+ priv->in_queues = g_new0 (GAsyncQueue *, priv->n_inputs);
+ priv->out_queues = g_new0 (GAsyncQueue *, priv->n_inputs);
+ priv->inputs = g_new0 (UfoBuffer *, priv->n_inputs);
+
+ for (guint i = 0; i < priv->n_inputs; i++) {
+ priv->in_queues[i] = g_async_queue_new ();
+ priv->out_queues[i] = g_async_queue_new ();
+ }
+
+ return UFO_NODE (task);
+}
+
+void
+ufo_input_task_stop (UfoInputTask *task)
+{
+ g_return_if_fail (UFO_IS_INPUT_TASK (task));
+ task->priv->active = FALSE;
+}
+
+void
+ufo_input_task_release_input_buffer (UfoInputTask *task,
+ guint input,
+ UfoBuffer *buffer)
+{
+ g_return_if_fail (UFO_IS_INPUT_TASK (task));
+ g_async_queue_push (task->priv->in_queues[input], buffer);
+}
+
+UfoBuffer *
+ufo_input_task_get_input_buffer (UfoInputTask *task,
+ gint input)
+{
+ g_return_val_if_fail (UFO_IS_INPUT_TASK (task), NULL);
+ return g_async_queue_pop (task->priv->out_queues[input]);
+}
+
+static void
+pop_all_inputs (UfoInputTaskPrivate *priv)
+{
+ for (guint i = 0; i < priv->n_inputs; i++)
+ priv->inputs[i] = g_async_queue_pop (priv->in_queues[i]);
+}
+
+static void
+push_all_inputs (UfoInputTaskPrivate *priv)
+{
+ for (guint i = 0; i < priv->n_inputs; i++)
+ g_async_queue_push (priv->out_queues[i], priv->inputs[i]);
+}
+
+static void
+ufo_input_task_setup (UfoTask *task, GError **error)
+{
+}
+
+static void
+ufo_input_task_get_requisition (UfoTask *task,
+ UfoBuffer **inputs,
+ UfoRequisition *requisition)
+{
+ UfoInputTaskPrivate *priv;
+
+ priv = UFO_INPUT_TASK_GET_PRIVATE (task);
+ pop_all_inputs (priv);
+ ufo_task_get_requisition (priv->wrapped, priv->inputs, requisition);
+}
+
+static void
+ufo_input_task_get_structure (UfoTask *task,
+ guint *n_inputs,
+ UfoInputParameter **in_params)
+{
+ *n_inputs = 0;
+}
+
+static gboolean
+ufo_input_task_process (UfoCpuTask *task,
+ UfoBuffer **none,
+ UfoBuffer *output,
+ UfoRequisition *requisition)
+{
+ UfoInputTaskPrivate *priv;
+ gboolean active;
+
+ g_return_val_if_fail (UFO_IS_INPUT_TASK (task), FALSE);
+
+ priv = UFO_INPUT_TASK_GET_PRIVATE (task);
+
+ if (UFO_IS_CPU_TASK (priv->wrapped)) {
+ active = ufo_cpu_task_process (UFO_CPU_TASK (priv->wrapped),
+ priv->inputs, output,
+ requisition);
+ }
+ else if (UFO_IS_GPU_TASK (priv->wrapped)) {
+ UfoGpuNode *gpu;
+
+ gpu = UFO_GPU_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task)));
+ active = ufo_gpu_task_process (UFO_GPU_TASK (priv->wrapped),
+ priv->inputs, output,
+ requisition, gpu);
+ }
+
+ push_all_inputs (priv);
+ return active;
+}
+
+static void
+ufo_input_task_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_input_task_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_task_interface_init (UfoTaskIface *iface)
+{
+ iface->setup = ufo_input_task_setup;
+ iface->get_structure = ufo_input_task_get_structure;
+ iface->get_requisition = ufo_input_task_get_requisition;
+}
+
+static void
+ufo_cpu_task_interface_init (UfoCpuTaskIface *iface)
+{
+ iface->process = ufo_input_task_process;
+}
+
+static void
+ufo_input_task_class_init (UfoInputTaskClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->set_property = ufo_input_task_set_property;
+ gobject_class->get_property = ufo_input_task_get_property;
+
+ g_type_class_add_private (gobject_class, sizeof(UfoInputTaskPrivate));
+}
+
+static void
+ufo_input_task_init(UfoInputTask *self)
+{
+ self->priv = UFO_INPUT_TASK_GET_PRIVATE(self);
+}
diff --git a/src/ufo-input-task.h b/src/ufo-input-task.h
new file mode 100644
index 0000000..c259c3e
--- /dev/null
+++ b/src/ufo-input-task.h
@@ -0,0 +1,54 @@
+#ifndef __UFO_INPUT_TASK_H
+#define __UFO_INPUT_TASK_H
+
+#include <glib-object.h>
+#include "ufo-task-node.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_INPUT_TASK (ufo_input_task_get_type())
+#define UFO_INPUT_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_INPUT_TASK, UfoInputTask))
+#define UFO_IS_INPUT_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_INPUT_TASK))
+#define UFO_INPUT_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_INPUT_TASK, UfoInputTaskClass))
+#define UFO_IS_INPUT_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_INPUT_TASK))
+#define UFO_INPUT_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_INPUT_TASK, UfoInputTaskClass))
+
+typedef struct _UfoInputTask UfoInputTask;
+typedef struct _UfoInputTaskClass UfoInputTaskClass;
+typedef struct _UfoInputTaskPrivate UfoInputTaskPrivate;
+
+/**
+ * UfoInputTask:
+ *
+ * Main object for organizing filters. The contents of the #UfoInputTask structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoInputTask {
+ /*< private >*/
+ UfoTaskNode parent_instance;
+
+ UfoInputTaskPrivate *priv;
+};
+
+/**
+ * UfoInputTaskClass:
+ *
+ * #UfoInputTask class
+ */
+struct _UfoInputTaskClass {
+ /*< private >*/
+ UfoTaskNodeClass parent_class;
+};
+
+UfoNode * ufo_input_task_new (UfoTask *wrapped);
+void ufo_input_task_stop (UfoInputTask *task);
+void ufo_input_task_release_input_buffer (UfoInputTask *task,
+ guint input,
+ UfoBuffer *buffer);
+UfoBuffer * ufo_input_task_get_input_buffer (UfoInputTask *task,
+ gint input);
+GType ufo_input_task_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-node.c b/src/ufo-node.c
new file mode 100644
index 0000000..f586c89
--- /dev/null
+++ b/src/ufo-node.c
@@ -0,0 +1,88 @@
+#include "ufo-node.h"
+
+G_DEFINE_TYPE (UfoNode, ufo_node, G_TYPE_OBJECT)
+
+#define UFO_NODE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_NODE, UfoNodePrivate))
+
+struct _UfoNodePrivate {
+ UfoNode *copied_from;
+ gpointer label;
+};
+
+enum {
+ PROP_0,
+ N_PROPERTIES
+};
+
+UfoNode *
+ufo_node_new (gpointer label)
+{
+ UfoNode *node;
+
+ node = UFO_NODE (g_object_new (UFO_TYPE_NODE, NULL));
+ node->priv->label = label;
+ return node;
+}
+
+gpointer
+ufo_node_get_label (UfoNode *node)
+{
+ g_return_val_if_fail (UFO_IS_NODE (node), NULL);
+ return node->priv->label;
+}
+
+static UfoNode *
+ufo_node_copy_real (UfoNode *node,
+ GError **error)
+{
+ return ufo_node_new (node->priv->label);
+}
+
+static gboolean
+ufo_node_equal_real (UfoNode *n1,
+ UfoNode *n2)
+{
+ g_return_val_if_fail (UFO_IS_NODE (n1) && UFO_IS_NODE (n2), FALSE);
+
+ /* FIXME: When done we should just check if the types match */
+ return n1 == n2 ||
+ n1->priv->copied_from == n2 ||
+ n2->priv->copied_from == n1;
+}
+
+UfoNode *
+ufo_node_copy (UfoNode *node,
+ GError **error)
+{
+ UfoNode *offspring;
+
+ offspring = UFO_NODE_GET_CLASS (node)->copy (node, error);
+ offspring->priv->copied_from = node;
+ return offspring;
+}
+
+gboolean
+ufo_node_equal (UfoNode *n1,
+ UfoNode *n2)
+{
+ return UFO_NODE_GET_CLASS (n1)->equal (n1, n2);
+}
+
+static void
+ufo_node_class_init (UfoNodeClass *klass)
+{
+ klass->copy = ufo_node_copy_real;
+ klass->equal = ufo_node_equal_real;
+
+ g_type_class_add_private(klass, sizeof(UfoNodePrivate));
+}
+
+static void
+ufo_node_init (UfoNode *self)
+{
+ UfoNodePrivate *priv;
+ self->priv = priv = UFO_NODE_GET_PRIVATE (self);
+
+ priv->copied_from = NULL;
+ priv->label = NULL;
+}
diff --git a/src/ufo-node.h b/src/ufo-node.h
new file mode 100644
index 0000000..b9ee3b3
--- /dev/null
+++ b/src/ufo-node.h
@@ -0,0 +1,57 @@
+#ifndef __UFO_NODE_H
+#define __UFO_NODE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_NODE (ufo_node_get_type())
+#define UFO_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_NODE, UfoNode))
+#define UFO_IS_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_NODE))
+#define UFO_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_NODE, UfoNodeClass))
+#define UFO_IS_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_NODE))
+#define UFO_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_NODE, UfoNodeClass))
+
+typedef struct _UfoNode UfoNode;
+typedef struct _UfoNodeClass UfoNodeClass;
+typedef struct _UfoNodePrivate UfoNodePrivate;
+
+/**
+ * UfoNode:
+ *
+ * Main object for organizing filters. The contents of the #UfoNode structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoNode {
+ /*< private >*/
+ GObject parent_instance;
+
+ UfoNodePrivate *priv;
+};
+
+/**
+ * UfoNodeClass:
+ *
+ * #UfoNode class
+ */
+struct _UfoNodeClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ UfoNode * (*copy) (UfoNode *node,
+ GError **error);
+ gboolean (*equal) (UfoNode *n1,
+ UfoNode *n2);
+};
+
+UfoNode *ufo_node_new (gpointer label);
+gpointer ufo_node_get_label (UfoNode *node);
+UfoNode *ufo_node_copy (UfoNode *node,
+ GError **error);
+gboolean ufo_node_equal (UfoNode *n1,
+ UfoNode *n2);
+GType ufo_node_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-output-task.c b/src/ufo-output-task.c
new file mode 100644
index 0000000..4cc8c77
--- /dev/null
+++ b/src/ufo-output-task.c
@@ -0,0 +1,184 @@
+/**
+ * SECTION:ufo-output-task
+ * @Short_description: Output task
+ * @Title: Output task
+ */
+
+#include <gmodule.h>
+#include <tiffio.h>
+#ifdef __APPLE__
+#include <OpenCL/cl.h>
+#else
+#include <CL/cl.h>
+#endif
+
+#include <ufo-output-task.h>
+#include <ufo-cpu-task-iface.h>
+
+struct _UfoOutputTaskPrivate {
+ GAsyncQueue *out_queue;
+ GAsyncQueue *in_queue;
+ guint n_dims;
+ guint n_copies;
+};
+
+static void ufo_task_interface_init (UfoTaskIface *iface);
+static void ufo_cpu_task_interface_init (UfoCpuTaskIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UfoOutputTask, ufo_output_task, UFO_TYPE_TASK_NODE,
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
+ ufo_task_interface_init)
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_CPU_TASK,
+ ufo_cpu_task_interface_init))
+
+#define UFO_OUTPUT_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_OUTPUT_TASK, UfoOutputTaskPrivate))
+
+enum {
+ PROP_0,
+ N_PROPERTIES
+};
+
+UfoNode *
+ufo_output_task_new (guint n_dims)
+{
+ UfoOutputTask *task = UFO_OUTPUT_TASK (g_object_new (UFO_TYPE_OUTPUT_TASK, NULL));
+
+ task->priv->n_dims = n_dims;
+ return UFO_NODE (task);
+}
+
+void
+ufo_output_task_get_output_requisition (UfoOutputTask *task,
+ UfoRequisition *requisition)
+{
+ UfoBuffer *buffer;
+ UfoOutputTaskPrivate *priv;
+
+ g_return_if_fail (UFO_IS_OUTPUT_TASK (task));
+ priv = task->priv;
+ buffer = g_async_queue_pop (priv->out_queue);
+ ufo_buffer_get_requisition (buffer, requisition);
+ g_async_queue_push (priv->out_queue, buffer);
+}
+
+UfoBuffer *
+ufo_output_task_get_output_buffer (UfoOutputTask *task)
+{
+ g_return_val_if_fail (UFO_IS_OUTPUT_TASK (task), NULL);
+ return g_async_queue_pop (task->priv->out_queue);
+}
+
+void
+ufo_output_task_release_output_buffer (UfoOutputTask *task,
+ UfoBuffer *buffer)
+{
+ g_return_if_fail (UFO_IS_OUTPUT_TASK (task));
+ g_async_queue_push (task->priv->in_queue, buffer);
+}
+
+static void
+ufo_output_task_setup (UfoTask *task, GError **error)
+{
+}
+
+static void
+ufo_output_task_get_requisition (UfoTask *task,
+ UfoBuffer **inputs,
+ UfoRequisition *requisition)
+{
+ (*requisition).n_dims = 0;
+}
+
+static void
+ufo_output_task_get_structure (UfoTask *task,
+ guint *n_inputs,
+ UfoInputParameter **in_params)
+{
+ UfoOutputTaskPrivate *priv = UFO_OUTPUT_TASK_GET_PRIVATE (task);
+
+ *n_inputs = 1;
+ *in_params = g_new0 (UfoInputParameter, 1);
+ (*in_params)[0].n_dims = priv->n_dims;
+ (*in_params)[0].n_expected_items = -1;
+}
+
+static gboolean
+ufo_output_task_process (UfoCpuTask *task,
+ UfoBuffer **outputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition)
+{
+ UfoOutputTaskPrivate *priv;
+ UfoRequisition req;
+ UfoBuffer *copy;
+
+ g_return_val_if_fail (UFO_IS_OUTPUT_TASK (task), FALSE);
+ ufo_buffer_get_requisition (outputs[0], &req);
+
+ priv = UFO_OUTPUT_TASK_GET_PRIVATE (task);
+
+ if (priv->n_copies == 0) {
+ copy = ufo_buffer_dup (outputs[0]);
+ g_async_queue_push (priv->in_queue, copy);
+ priv->n_copies++;
+ }
+
+ copy = g_async_queue_pop (priv->in_queue);
+ ufo_buffer_copy (outputs[0], copy);
+ g_async_queue_push (priv->out_queue, copy);
+ return TRUE;
+}
+
+static void
+ufo_output_task_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_output_task_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_task_interface_init (UfoTaskIface *iface)
+{
+ iface->setup = ufo_output_task_setup;
+ iface->get_structure = ufo_output_task_get_structure;
+ iface->get_requisition = ufo_output_task_get_requisition;
+}
+
+static void
+ufo_cpu_task_interface_init (UfoCpuTaskIface *iface)
+{
+ iface->process = ufo_output_task_process;
+}
+
+static void
+ufo_output_task_class_init (UfoOutputTaskClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->set_property = ufo_output_task_set_property;
+ gobject_class->get_property = ufo_output_task_get_property;
+
+ g_type_class_add_private (gobject_class, sizeof(UfoOutputTaskPrivate));
+}
+
+static void
+ufo_output_task_init(UfoOutputTask *self)
+{
+ self->priv = UFO_OUTPUT_TASK_GET_PRIVATE(self);
+ self->priv->out_queue = g_async_queue_new ();
+ self->priv->in_queue = g_async_queue_new ();
+ self->priv->n_copies = 0;
+}
diff --git a/src/ufo-output-task.h b/src/ufo-output-task.h
new file mode 100644
index 0000000..68a8e66
--- /dev/null
+++ b/src/ufo-output-task.h
@@ -0,0 +1,53 @@
+#ifndef __UFO_OUTPUT_TASK_H
+#define __UFO_OUTPUT_TASK_H
+
+#include <glib-object.h>
+#include "ufo-task-node.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_OUTPUT_TASK (ufo_output_task_get_type())
+#define UFO_OUTPUT_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_OUTPUT_TASK, UfoOutputTask))
+#define UFO_IS_OUTPUT_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_OUTPUT_TASK))
+#define UFO_OUTPUT_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_OUTPUT_TASK, UfoOutputTaskClass))
+#define UFO_IS_OUTPUT_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_OUTPUT_TASK))
+#define UFO_OUTPUT_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_OUTPUT_TASK, UfoOutputTaskClass))
+
+typedef struct _UfoOutputTask UfoOutputTask;
+typedef struct _UfoOutputTaskClass UfoOutputTaskClass;
+typedef struct _UfoOutputTaskPrivate UfoOutputTaskPrivate;
+
+/**
+ * UfoOutputTask:
+ *
+ * Main object for organizing filters. The contents of the #UfoOutputTask structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoOutputTask {
+ /*< private >*/
+ UfoTaskNode parent_instance;
+
+ UfoOutputTaskPrivate *priv;
+};
+
+/**
+ * UfoOutputTaskClass:
+ *
+ * #UfoOutputTask class
+ */
+struct _UfoOutputTaskClass {
+ /*< private >*/
+ UfoTaskNodeClass parent_class;
+};
+
+UfoNode * ufo_output_task_new (guint n_dims);
+void ufo_output_task_get_output_requisition (UfoOutputTask *task,
+ UfoRequisition *requisition);
+UfoBuffer * ufo_output_task_get_output_buffer (UfoOutputTask *task);
+void ufo_output_task_release_output_buffer (UfoOutputTask *task,
+ UfoBuffer *buffer);
+GType ufo_output_task_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-plugin-manager.c b/src/ufo-plugin-manager.c
index 931710e..201e68d 100644
--- a/src/ufo-plugin-manager.c
+++ b/src/ufo-plugin-manager.c
@@ -11,21 +11,21 @@
*/
#include <gmodule.h>
#include <glob.h>
+#include <ufo-plugin-manager.h>
+#include <ufo-configurable.h>
#include "config.h"
-#include "ufo-plugin-manager.h"
-#include "ufo-configurable.h"
G_DEFINE_TYPE_WITH_CODE (UfoPluginManager, ufo_plugin_manager, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (UFO_TYPE_CONFIGURABLE, NULL))
#define UFO_PLUGIN_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_PLUGIN_MANAGER, UfoPluginManagerPrivate))
-typedef UfoFilter* (* GetFilterFunc) (void);
+typedef UfoNode* (* NewFunc) (void);
struct _UfoPluginManagerPrivate {
GSList *search_paths;
GSList *modules;
- GHashTable *filter_funcs; /**< maps from gchar* to GetFilterFunc* */
+ GHashTable *new_funcs; /**< maps from gchar* to NewFunc* */
};
enum {
@@ -64,7 +64,7 @@ plugin_manager_get_path (UfoPluginManagerPrivate *priv, const gchar *name)
GSList *p = g_slist_nth (priv->search_paths, 0);
while (p != NULL) {
- gchar *path = g_strdup_printf ("%s%c%s", (gchar *) p->data, G_DIR_SEPARATOR, name);
+ gchar *path = g_build_filename ((gchar *) p->data, name, NULL);
if (g_file_test (path, G_FILE_TEST_EXISTS))
return path;
@@ -77,11 +77,11 @@ plugin_manager_get_path (UfoPluginManagerPrivate *priv, const gchar *name)
}
static void
-copy_config_paths (UfoPluginManagerPrivate *priv, UfoConfiguration *config)
+copy_config_paths (UfoPluginManagerPrivate *priv, UfoConfig *config)
{
gchar **paths;
- paths = ufo_configuration_get_paths (config);
+ paths = ufo_config_get_paths (config);
for (guint i = 0; paths[i] != NULL; i++)
priv->search_paths = g_slist_prepend (priv->search_paths, g_strdup (paths[i]));
@@ -91,7 +91,7 @@ copy_config_paths (UfoPluginManagerPrivate *priv, UfoConfiguration *config)
/**
* ufo_plugin_manager_new:
- * @config: (allow-none): A #UfoConfiguration object or %NULL.
+ * @config: (allow-none): A #UfoConfig object or %NULL.
*
* Create a plugin manager object to instantiate filter objects. When a config
* object is passed to the constructor, its search-path property is added to the
@@ -100,7 +100,7 @@ copy_config_paths (UfoPluginManagerPrivate *priv, UfoConfiguration *config)
* Return value: A new plugin manager object.
*/
UfoPluginManager *
-ufo_plugin_manager_new (UfoConfiguration *config)
+ufo_plugin_manager_new (UfoConfig *config)
{
UfoPluginManager *manager;
@@ -124,27 +124,28 @@ ufo_plugin_manager_new (UfoConfiguration *config)
*
* Since: 0.2, the error parameter is available
*/
-UfoFilter *
-ufo_plugin_manager_get_filter (UfoPluginManager *manager, const gchar *name, GError **error)
+UfoNode *
+ufo_plugin_manager_get_task (UfoPluginManager *manager, const gchar *name, GError **error)
{
g_return_val_if_fail (UFO_IS_PLUGIN_MANAGER (manager) && (name != NULL), NULL);
UfoPluginManagerPrivate *priv = UFO_PLUGIN_MANAGER_GET_PRIVATE (manager);
- UfoFilter *filter;
- GetFilterFunc *func = NULL;
- GModule *module = NULL;
+ UfoNode *node;
+ NewFunc *func;
+ GModule *module;
gchar *module_name = NULL;
+
const gchar *entry_symbol_name = "ufo_filter_plugin_new";
- func = g_hash_table_lookup (priv->filter_funcs, name);
+ func = g_hash_table_lookup (priv->new_funcs, name);
if (func == NULL) {
/* No suitable function found, let's find the module */
- module_name = g_strdup_printf ("libufofilter%s.so", name);
+ module_name = g_strdup_printf ("libufotask%s.so", name);
gchar *path = plugin_manager_get_path (priv, module_name);
if (path == NULL) {
g_set_error (error, UFO_PLUGIN_MANAGER_ERROR, UFO_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND,
- "Module %s not found", module_name);
+ "Module %s not found", module_name);
goto handle_error;
}
@@ -153,15 +154,15 @@ ufo_plugin_manager_get_filter (UfoPluginManager *manager, const gchar *name, GEr
if (!module) {
g_set_error (error, UFO_PLUGIN_MANAGER_ERROR, UFO_PLUGIN_MANAGER_ERROR_MODULE_OPEN,
- "Module %s could not be opened: %s", module_name, g_module_error ());
+ "Module %s could not be opened: %s", module_name, g_module_error ());
goto handle_error;
}
- func = g_malloc0 (sizeof (GetFilterFunc));
+ func = g_malloc0 (sizeof (NewFunc));
if (!g_module_symbol (module, entry_symbol_name, (gpointer *) func)) {
g_set_error (error, UFO_PLUGIN_MANAGER_ERROR, UFO_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND,
- "%s is not exported by module %s: %s", entry_symbol_name, module_name, g_module_error ());
+ "%s is not exported by module %s: %s", entry_symbol_name, module_name, g_module_error ());
g_free (func);
if (!g_module_close (module))
@@ -171,15 +172,15 @@ ufo_plugin_manager_get_filter (UfoPluginManager *manager, const gchar *name, GEr
}
priv->modules = g_slist_append (priv->modules, module);
- g_hash_table_insert (priv->filter_funcs, g_strdup (name), func);
+ g_hash_table_insert (priv->new_funcs, g_strdup (name), func);
g_free (module_name);
}
- filter = (*func) ();
- ufo_filter_set_plugin_name (filter, name);
- g_message ("UfoPluginManager: Created %s-%p", name, (gpointer) filter);
+ node = (*func) ();
+ /* ufo_filter_set_plugin_name (filter, name); */
+ g_message ("UfoPluginManager: Created %s-%p", name, (gpointer) node);
- return filter;
+ return node;
handle_error:
g_free (module_name);
@@ -187,7 +188,7 @@ handle_error:
}
/**
- * ufo_plugin_manager_get_all_filter_names:
+ * ufo_plugin_manager_get_all_task_names:
* @manager: A #UfoPluginManager
*
* Return a list with potential filter names that match shared objects in all
@@ -196,21 +197,23 @@ handle_error:
* Return value: (element-type utf8) (transfer full): List of strings with filter names
*/
GList *
-ufo_plugin_manager_get_all_filter_names (UfoPluginManager *manager)
+ufo_plugin_manager_get_all_task_names (UfoPluginManager *manager)
{
g_return_val_if_fail (UFO_IS_PLUGIN_MANAGER (manager), NULL);
UfoPluginManagerPrivate *priv = UFO_PLUGIN_MANAGER_GET_PRIVATE (manager);
GList *result = NULL;
GSList *path;
- GRegex *regex = g_regex_new ("libufofilter([A-Za-z]+).so", 0, 0, NULL);
+ GRegex *regex = g_regex_new ("libufotask([A-Za-z]+).so", 0, 0, NULL);
GMatchInfo *match_info = NULL;
path = g_slist_nth (priv->search_paths, 0);
while (path != NULL) {
glob_t glob_vector;
- gchar *pattern = g_strdup_printf ("%s%clibufofilter*.so", (gchar *) path->data, G_DIR_SEPARATOR);
+ gchar *pattern;
+
+ pattern = g_build_filename ((gchar *) path->data, "libufotask*.so", NULL);
glob (pattern, GLOB_MARK | GLOB_TILDE, NULL, &glob_vector);
g_free (pattern);
gsize i = 0;
@@ -255,9 +258,9 @@ ufo_plugin_manager_set_property (GObject *object, guint property_id, const GValu
value_object = g_value_get_object (value);
if (value_object != NULL) {
- UfoConfiguration *config;
+ UfoConfig *config;
- config = UFO_CONFIGURATION (value_object);
+ config = UFO_CONFIG (value_object);
copy_config_paths (UFO_PLUGIN_MANAGER_GET_PRIVATE (object), config);
}
}
@@ -275,7 +278,7 @@ ufo_plugin_manager_constructed (GObject *object)
UfoPluginManagerPrivate *priv = UFO_PLUGIN_MANAGER_GET_PRIVATE (object);
if (priv->search_paths == NULL) {
- UfoConfiguration *config = ufo_configuration_new ();
+ UfoConfig *config = ufo_config_new ();
copy_config_paths (priv, config);
g_object_unref (config);
}
@@ -305,7 +308,7 @@ ufo_plugin_manager_finalize (GObject *gobject)
g_slist_foreach (priv->search_paths, (GFunc) g_free, NULL);
g_slist_free (priv->search_paths);
- g_hash_table_destroy (priv->filter_funcs);
+ g_hash_table_destroy (priv->new_funcs);
G_OBJECT_CLASS (ufo_plugin_manager_parent_class)->finalize (gobject);
g_message ("UfoPluginManager: finalized");
}
@@ -320,7 +323,7 @@ ufo_plugin_manager_class_init (UfoPluginManagerClass *klass)
gobject_class->dispose = ufo_plugin_manager_dispose;
gobject_class->finalize = ufo_plugin_manager_finalize;
- g_object_class_override_property (gobject_class, PROP_CONFIG, "configuration");
+ g_object_class_override_property (gobject_class, PROP_CONFIG, "config");
g_type_class_add_private (klass, sizeof (UfoPluginManagerPrivate));
}
@@ -331,8 +334,8 @@ ufo_plugin_manager_init (UfoPluginManager *manager)
UfoPluginManagerPrivate *priv;
manager->priv = priv = UFO_PLUGIN_MANAGER_GET_PRIVATE (manager);
- priv->modules = NULL;
- priv->search_paths = NULL;
- priv->filter_funcs = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_free);
+ priv->modules = NULL;
+ priv->search_paths = NULL;
+ priv->new_funcs = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
}
diff --git a/src/ufo-plugin-manager.h b/src/ufo-plugin-manager.h
index 6bd47fb..48c0ccb 100644
--- a/src/ufo-plugin-manager.h
+++ b/src/ufo-plugin-manager.h
@@ -2,8 +2,8 @@
#define __UFO_PLUGIN_MANAGER_H
#include <glib-object.h>
-#include "ufo-configuration.h"
-#include "ufo-filter.h"
+#include <ufo-config.h>
+#include <ufo-node.h>
G_BEGIN_DECLS
@@ -51,11 +51,11 @@ struct _UfoPluginManagerClass {
GObjectClass parent_class;
};
-UfoPluginManager *ufo_plugin_manager_new (UfoConfiguration *config);
-UfoFilter *ufo_plugin_manager_get_filter (UfoPluginManager *manager,
- const gchar *name,
+UfoPluginManager * ufo_plugin_manager_new (UfoConfig *config);
+UfoNode * ufo_plugin_manager_get_task (UfoPluginManager *manager,
+ const gchar *name,
GError **error);
-GList *ufo_plugin_manager_get_all_filter_names (UfoPluginManager *manager);
+GList * ufo_plugin_manager_get_all_task_names (UfoPluginManager *manager);
GType ufo_plugin_manager_get_type (void);
G_END_DECLS
diff --git a/src/ufo-profiler.c b/src/ufo-profiler.c
index d5e353b..41bef23 100644
--- a/src/ufo-profiler.c
+++ b/src/ufo-profiler.c
@@ -24,9 +24,9 @@
#endif
#include <gmodule.h>
#include <glob.h>
-#include "config.h"
-#include "ufo-profiler.h"
-#include "ufo-aux.h"
+
+#include <ufo-profiler.h>
+#include <ufo-resources.h>
G_DEFINE_TYPE(UfoProfiler, ufo_profiler, G_TYPE_OBJECT)
@@ -147,7 +147,7 @@ ufo_profiler_call (UfoProfiler *profiler,
global_work_size,
local_work_size,
0, NULL, event_loc);
- CHECK_OPENCL_ERROR (cl_err);
+ UFO_RESOURCES_CHECK_CLERR (cl_err);
if (priv->level & UFO_PROFILER_LEVEL_OPENCL) {
row.event = event;
diff --git a/src/ufo-profiler.h b/src/ufo-profiler.h
index b12eaaf..292fb5e 100644
--- a/src/ufo-profiler.h
+++ b/src/ufo-profiler.h
@@ -2,7 +2,6 @@
#define __UFO_PROFILER_H
#include <glib-object.h>
-#include "ufo-resource-manager.h"
G_BEGIN_DECLS
diff --git a/src/ufo-relation.c b/src/ufo-relation.c
deleted file mode 100644
index 01a64e7..0000000
--- a/src/ufo-relation.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/**
- * SECTION:ufo-relation
- * @Short_description: Data transport between two UfoFilters
- * @Title: UfoRelation
- */
-
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-relation.h"
-#include "ufo-enums.h"
-
-G_DEFINE_TYPE(UfoRelation, ufo_relation, G_TYPE_OBJECT)
-
-#define UFO_RELATION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_RELATION, UfoRelationPrivate))
-
-struct _UfoRelationPrivate {
- UfoRelationMode mode;
-
- UfoFilter *producer;
- guint output_port;
- GAsyncQueue *producer_pop_queue;
- GAsyncQueue *producer_push_queue;
- GList *consumers; /* contains UfoFilter * */
- GHashTable *consumer_ports; /* maps from UfoFilter* to input port */
- GHashTable *consumer_pop_queues; /* maps from UfoFilter* to GAsyncQueue */
- GHashTable *consumer_push_queues; /* maps from UfoFilter* to GAsyncQueue */
-};
-
-enum {
- PROP_0,
- PROP_PRODUCER,
- PROP_OUTPUT_PORT,
- PROP_MODE,
- N_PROPERTIES
-};
-
-static GParamSpec *relation_properties[N_PROPERTIES] = { NULL, };
-
-/**
- * ufo_relation_new:
- * @producer: A #UfoFilter
- * @output_port: The outgoing port number of the producer
- * @mode: The relation mode that determines how data is forwarded
- *
- * Creates a new #UfoRelation that represents a 1:m relationship between a
- * @producer and an arbitrary number of consumers..
- *
- * Return value: A new #UfoRelation
- * Since: 0.2
- */
-UfoRelation *
-ufo_relation_new (UfoFilter *producer, guint output_port, UfoRelationMode mode)
-{
- UfoRelation *relation;
-
- relation = UFO_RELATION (g_object_new (UFO_TYPE_RELATION,
- "producer", producer,
- "output-port", output_port,
- "mode", mode,
- NULL));
-
- g_object_ref (producer);
- return relation;
-}
-
-/**
- * ufo_relation_get_producer: (skip)
- * @relation: A #UfoRelation object
- *
- * Get the producer associated with the relation.
- *
- * Returns: A #UfoFilter
- * Since: 0.2
- */
-UfoFilter *
-ufo_relation_get_producer (UfoRelation *relation)
-{
- g_return_val_if_fail (UFO_IS_RELATION (relation), NULL);
- return relation->priv->producer;
-}
-
-/**
- * ufo_relation_add_consumer:
- * @relation: A #UfoRelation object
- * @consumer: The consumer that takes input from the #relation
- * @input_port: The input port number of the consumer
- * @error: Location for #GError
- *
- * Add a consumer to this relation.
- *
- * Since: 0.2
- */
-void
-ufo_relation_add_consumer (UfoRelation *relation, UfoFilter *consumer, guint input_port, GError **error)
-{
- UfoRelationPrivate *priv;
- UfoInputParameter *input_params;
- UfoOutputParameter *output_params;
- guint num_input_ports;
- guint input_num_dims;
- guint output_num_dims;
-
- g_return_if_fail (UFO_IS_RELATION (relation));
-
- priv = UFO_RELATION_GET_PRIVATE (relation);
-
- num_input_ports = ufo_filter_get_num_inputs (consumer);
- input_params = ufo_filter_get_input_parameters (consumer);
- output_params = ufo_filter_get_output_parameters (priv->producer);
-
- if (input_port >= num_input_ports) {
- g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_INSUFFICIENTINPUTS,
- "%s has only %i input ports, but port %i was specified\n",
- ufo_filter_get_plugin_name (consumer), num_input_ports, input_port);
- return;
- }
-
- input_num_dims = input_params[input_port].n_dims;
- output_num_dims = output_params[priv->output_port].n_dims;
-
- if (input_num_dims != output_num_dims) {
- g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_NUMDIMSMISMATCH,
- "%i dimensions at output port %i != %i dimensions at input port %i\n",
- output_num_dims, priv->output_port, input_num_dims, input_port);
- return;
- }
-
- g_hash_table_insert (priv->consumer_ports, consumer, GINT_TO_POINTER (input_port));
-
- if (priv->producer_pop_queue == NULL)
- priv->producer_pop_queue = g_async_queue_new ();
-
- if (priv->producer_push_queue == NULL)
- priv->producer_push_queue = g_async_queue_new ();
-
- if (priv->mode == UFO_RELATION_MODE_DISTRIBUTE) {
- /*
- * In distribute mode, each consumer consumes from the same input queue and
- * has to push it back to the same used output queue.
- */
- g_hash_table_insert (priv->consumer_push_queues, consumer, priv->producer_pop_queue);
- g_hash_table_insert (priv->consumer_pop_queues, consumer, priv->producer_push_queue);
- }
- else {
- /*
- * In copy mode, we daisy chain pop-push-queues and transfer the
- * produced buffer from one consumer to the next until it is placed back
- * again in the producers pop queue.
- */
- GList *last_element = g_list_last (priv->consumers);
-
- if (last_element == NULL) {
- g_hash_table_insert (priv->consumer_push_queues, consumer, priv->producer_pop_queue);
- g_hash_table_insert (priv->consumer_pop_queues, consumer, priv->producer_push_queue);
- }
- else {
- UfoFilter *last_consumer = UFO_FILTER (last_element->data);
- GAsyncQueue *queue = g_async_queue_new ();
- g_hash_table_insert (priv->consumer_push_queues, last_consumer, queue);
- g_hash_table_insert (priv->consumer_pop_queues, consumer, queue);
- g_hash_table_insert (priv->consumer_push_queues, consumer, priv->producer_pop_queue);
- }
- }
-
- g_object_ref (consumer);
- priv->consumers = g_list_append (priv->consumers, consumer);
-}
-
-/**
- * ufo_relation_get_consumers: (skip)
- * @relation: A #UfoRelation object
- *
- * Get the consumers associated with this relation
- *
- * Returns: (transfer none) (element-type UfoFilter): A list with #UfoFilter consumers
- * Since: 0.2
- */
-GList *
-ufo_relation_get_consumers (UfoRelation *relation)
-{
- g_return_val_if_fail (UFO_IS_RELATION (relation), NULL);
- return relation->priv->consumers;
-}
-
-/**
- * ufo_relation_get_producer_port:
- * @relation: A #UfoRelation object
- *
- * Get the producer's output port number
- *
- * Returns: The producer's output port number
- * Since: 0.2
- */
-guint
-ufo_relation_get_producer_port (UfoRelation *relation)
-{
- g_return_val_if_fail (UFO_IS_RELATION (relation), 0);
- return relation->priv->output_port;
-}
-
-/**
- * ufo_relation_get_consumer_port:
- * @relation: A #UfoRelation object
- * @consumer: A consumer that is
- *
- * Get the #consumer's input port number
- *
- * Returns: The consumer's output port number
- * Since: 0.2
- */
-guint
-ufo_relation_get_consumer_port (UfoRelation *relation, UfoFilter *consumer)
-{
- if (!ufo_relation_has_consumer (relation, consumer))
- g_warning ("Consumer is not part of this relation. Expect wrong port 0.");
-
- return (guint) GPOINTER_TO_INT (g_hash_table_lookup (relation->priv->consumer_ports, consumer));
-}
-
-/**
- * ufo_relation_get_producer_queues:
- * @relation: A #UfoRelation object
- * @push_queue: A location for the queue into which to push fresh output data
- * @pop_queue: A location for the queue from which to pop used output buffers
- *
- * Get queues for the producer.
- *
- * Since: 0.2
- */
-void
-ufo_relation_get_producer_queues (UfoRelation *relation, GAsyncQueue **push_queue, GAsyncQueue **pop_queue)
-{
- g_return_if_fail (UFO_IS_RELATION (relation));
- g_return_if_fail (push_queue != NULL && pop_queue != NULL);
-
- UfoRelationPrivate *priv = UFO_RELATION_GET_PRIVATE (relation);
- *push_queue = priv->producer_push_queue;
- *pop_queue = priv->producer_pop_queue;
-}
-
-/**
- * ufo_relation_get_consumer_queues:
- * @relation: A #UfoRelation object
- * @consumer: The #UfoFilter for which to get the queues
- * @push_queue: A location for the queue into which to push used input data
- * @pop_queue: A location for the queue from which to pop fresh input buffers
- *
- * Get queues for #consumer.
- *
- * Since: 0.2
- */
-void
-ufo_relation_get_consumer_queues (UfoRelation *relation, UfoFilter *consumer, GAsyncQueue **push_queue, GAsyncQueue **pop_queue)
-{
- g_return_if_fail (UFO_IS_RELATION (relation) && UFO_IS_FILTER (consumer));
- g_return_if_fail (push_queue != NULL && pop_queue != NULL);
-
- UfoRelationPrivate *priv = UFO_RELATION_GET_PRIVATE (relation);
- *push_queue = g_hash_table_lookup (priv->consumer_push_queues, consumer);
- *pop_queue = g_hash_table_lookup (priv->consumer_pop_queues, consumer);
-}
-
-/**
- * ufo_relation_has_consumer:
- * @relation: A #UfoRelation object
- * @consumer: A #UfoFilter consumer
- *
- * Check if #consumer is part of #relation.
- *
- * Returns: %TRUE if #consumer is part of #relation, otherwise %FALSE.
- * Since: 0.2
- */
-gboolean
-ufo_relation_has_consumer (UfoRelation *relation, UfoFilter *consumer)
-{
- g_return_val_if_fail (UFO_IS_RELATION (relation), FALSE);
- return g_hash_table_lookup_extended (relation->priv->consumer_ports, consumer, NULL, NULL);
-}
-
-/**
- * ufo_relation_push_poison_pill:
- * @relation: A #UfoRelation object
- *
- * Tell all consumers that the producer does not provide any more data.
- *
- * Since: 0.2
- */
-void
-ufo_relation_push_poison_pill (UfoRelation *relation)
-{
- g_return_if_fail (UFO_IS_RELATION (relation));
-
- UfoRelationPrivate *priv = UFO_RELATION_GET_PRIVATE (relation);
-
- /*
- * The mode doesn't matter here. If it is distributed, pop_queue will be the
- * same for each consumer thus pushing the pill n times. If copy mode is
- * enable, the pill will be inserted into each consumer's pop queue.
- */
- for (GList *it = g_list_first (priv->consumers); it != NULL; it = g_list_next (it)) {
- UfoFilter *consumer = UFO_FILTER (it->data);
- GAsyncQueue *pop_queue = g_hash_table_lookup (priv->consumer_pop_queues, consumer);
- g_async_queue_push (pop_queue, GINT_TO_POINTER (1));
- }
-}
-
-static void
-ufo_relation_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- UfoRelationPrivate *priv = UFO_RELATION_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_PRODUCER:
- priv->producer = g_value_get_object (value);
- break;
- case PROP_OUTPUT_PORT:
- priv->output_port = g_value_get_uint (value);
- break;
- case PROP_MODE:
- priv->mode = g_value_get_enum (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_relation_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- UfoRelationPrivate *priv = UFO_RELATION_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_PRODUCER:
- g_value_set_object (value, priv->producer);
- break;
- case PROP_OUTPUT_PORT:
- g_value_set_uint (value, priv->output_port);
- break;
- case PROP_MODE:
- g_value_set_enum (value, priv->mode);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-g_async_queue_safe_unref (GAsyncQueue *queue)
-{
- if (queue)
- g_async_queue_unref (queue);
-}
-
-static void
-ufo_relation_dispose (GObject *object)
-{
- UfoRelationPrivate *priv = UFO_RELATION_GET_PRIVATE (object);
-
- g_list_foreach (priv->consumers, (GFunc) g_object_unref, NULL);
-
- /*
- * FIXME: if we enable the following unref, the unref will segfault with a
- * certain number of filters. Why, this is, I don't know :(
- */
- /* g_object_unref (priv->producer); */
-
- G_OBJECT_CLASS (ufo_relation_parent_class)->dispose (object);
-}
-
-static void
-ufo_relation_finalize (GObject *object)
-{
- UfoRelationPrivate *priv = UFO_RELATION_GET_PRIVATE (object);
-
- if (priv->mode == UFO_RELATION_MODE_DISTRIBUTE) {
- g_async_queue_safe_unref (priv->producer_pop_queue);
- g_async_queue_safe_unref (priv->producer_push_queue);
- }
- else {
- for (GList *it = g_list_first (priv->consumers); it != NULL; it = g_list_next (it)) {
- UfoFilter *consumer = UFO_FILTER (it->data);
- GAsyncQueue *pop_queue = g_hash_table_lookup (priv->consumer_pop_queues, consumer);
- g_async_queue_safe_unref (pop_queue);
- }
-
- g_async_queue_safe_unref (priv->producer_pop_queue);
- }
-
- g_list_free (priv->consumers);
- g_hash_table_destroy (priv->consumer_push_queues);
- g_hash_table_destroy (priv->consumer_pop_queues);
- g_hash_table_destroy (priv->consumer_ports);
-
- G_OBJECT_CLASS (ufo_relation_parent_class)->finalize (object);
-}
-
-static void
-ufo_relation_class_init (UfoRelationClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->get_property = ufo_relation_get_property;
- gobject_class->set_property = ufo_relation_set_property;
- gobject_class->dispose = ufo_relation_dispose;
- gobject_class->finalize = ufo_relation_finalize;
-
- relation_properties[PROP_PRODUCER] =
- g_param_spec_object ("producer",
- "An UfoFilter",
- "An UfoFilter",
- UFO_TYPE_FILTER,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- relation_properties[PROP_OUTPUT_PORT] =
- g_param_spec_uint ("output-port",
- "Number of the producer output port",
- "Number of the producer output port",
- 0, 256, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- relation_properties[PROP_MODE] =
- g_param_spec_enum ("mode",
- "Work item mode",
- "Work item mode",
- UFO_TYPE_RELATION_MODE, UFO_RELATION_MODE_DISTRIBUTE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
- g_object_class_install_property (gobject_class, i, relation_properties[i]);
-
- g_type_class_add_private (klass, sizeof (UfoRelationPrivate));
-}
-
-static void
-ufo_relation_init (UfoRelation *relation)
-{
- UfoRelationPrivate *priv;
- relation->priv = priv = UFO_RELATION_GET_PRIVATE (relation);
- priv->producer = NULL;
- priv->output_port = 0;
- priv->consumers = NULL;
- priv->consumer_ports = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- priv->producer_push_queue= NULL;
- priv->producer_pop_queue = NULL;
- priv->consumer_pop_queues = g_hash_table_new (g_direct_hash, g_direct_equal);
- priv->consumer_push_queues = g_hash_table_new (g_direct_hash, g_direct_equal);
-}
diff --git a/src/ufo-relation.h b/src/ufo-relation.h
deleted file mode 100644
index 54a9f12..0000000
--- a/src/ufo-relation.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef __UFO_RELATION_H
-#define __UFO_RELATION_H
-
-#include <glib-object.h>
-#include "ufo-filter.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_RELATION (ufo_relation_get_type())
-#define UFO_RELATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_RELATION, UfoRelation))
-#define UFO_IS_RELATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_RELATION))
-#define UFO_RELATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_RELATION, UfoRelationClass))
-#define UFO_IS_RELATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_RELATION))
-#define UFO_RELATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_RELATION, UfoRelationClass))
-
-typedef struct _UfoRelation UfoRelation;
-typedef struct _UfoRelationClass UfoRelationClass;
-typedef struct _UfoRelationPrivate UfoRelationPrivate;
-
-/**
- * UfoRelationMode:
- * @UFO_RELATION_MODE_DISTRIBUTE: Data from the producer is distributed in a
- * non-predictable way to one consumer.
- * @UFO_RELATION_MODE_COPY: The data from the producer is copied and send to all
- * producers.
- */
-typedef enum {
- UFO_RELATION_MODE_DISTRIBUTE,
- UFO_RELATION_MODE_COPY
-} UfoRelationMode;
-
-/**
- * UfoRelation:
- *
- * Data transport channel between two #UfoFilter objects. The contents of the
- * #UfoRelation structure are private and should only be accessed via the
- * provided API.
- */
-struct _UfoRelation {
- /*< private >*/
- GObject parent_instance;
-
- UfoRelationPrivate *priv;
-};
-
-/**
- * UfoRelationClass:
- *
- * #UfoRelation class
- */
-struct _UfoRelationClass {
- /*< private >*/
- GObjectClass parent_class;
-};
-
-UfoRelation *ufo_relation_new (UfoFilter *producer,
- guint output_port,
- UfoRelationMode mode);
-UfoFilter *ufo_relation_get_producer (UfoRelation *relation);
-GList *ufo_relation_get_consumers (UfoRelation *relation);
-void ufo_relation_add_consumer (UfoRelation *relation,
- UfoFilter *consumer,
- guint input_port,
- GError **error);
-gboolean ufo_relation_has_consumer (UfoRelation *relation,
- UfoFilter *consumer);
-guint ufo_relation_get_producer_port (UfoRelation *relation);
-guint ufo_relation_get_consumer_port (UfoRelation *relation,
- UfoFilter *consumer);
-void ufo_relation_get_producer_queues (UfoRelation *relation,
- GAsyncQueue **push_queue,
- GAsyncQueue **pop_queue);
-void ufo_relation_get_consumer_queues (UfoRelation *relation,
- UfoFilter *consumer,
- GAsyncQueue **push_queue,
- GAsyncQueue **pop_queue);
-void ufo_relation_push_poison_pill (UfoRelation *relation);
-GType ufo_relation_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-remote-node.c b/src/ufo-remote-node.c
new file mode 100644
index 0000000..fd72ad7
--- /dev/null
+++ b/src/ufo-remote-node.c
@@ -0,0 +1,231 @@
+#include <zmq.h>
+#include <string.h>
+#include "ufo-remote-node.h"
+
+G_DEFINE_TYPE (UfoRemoteNode, ufo_remote_node, UFO_TYPE_NODE)
+
+#define UFO_REMOTE_NODE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_REMOTE_NODE, UfoRemoteNodePrivate))
+
+static void ufo_msg_send (UfoMessage *msg, gpointer socket, gint flags);
+
+struct _UfoRemoteNodePrivate {
+ gpointer context;
+ gpointer socket;
+ guint n_inputs;
+};
+
+UfoNode *
+ufo_remote_node_new (gpointer zmq_context,
+ const gchar *address)
+{
+ UfoRemoteNode *node;
+ UfoRemoteNodePrivate *priv;
+
+ g_return_val_if_fail (zmq_context != NULL && address != NULL, NULL);
+ node = UFO_REMOTE_NODE (g_object_new (UFO_TYPE_REMOTE_NODE, NULL));
+ priv = node->priv;
+ priv->context = zmq_context;
+ priv->socket = zmq_socket (zmq_context, ZMQ_REQ);
+ zmq_connect (priv->socket, address);
+
+ return UFO_NODE (node);
+}
+
+void
+ufo_remote_node_request_setup (UfoRemoteNode *node)
+{
+ UfoRemoteNodePrivate *priv;
+ UfoMessage request;
+ zmq_msg_t reply_msg;
+
+ g_return_if_fail (UFO_IS_REMOTE_NODE (node));
+
+ priv = node->priv;
+ request.type = UFO_MESSAGE_SETUP;
+ ufo_msg_send (&request, priv->socket, 0);
+
+ /* Receive reply */
+ zmq_msg_init (&reply_msg);
+ zmq_msg_recv (&reply_msg, priv->socket, 0);
+ zmq_msg_close (&reply_msg);
+}
+
+void
+ufo_remote_node_get_structure (UfoRemoteNode *node,
+ guint *n_inputs,
+ UfoInputParameter **in_params)
+{
+ UfoRemoteNodePrivate *priv;
+ UfoMessage request;
+ UfoMessage *header;
+ UfoInputParameter *payload;
+ zmq_msg_t header_msg;
+ zmq_msg_t payload_msg;
+ gsize payload_size;
+
+ g_return_if_fail (UFO_IS_REMOTE_NODE (node));
+
+ priv = node->priv;
+ request.type = UFO_MESSAGE_GET_STRUCTURE;
+ ufo_msg_send (&request, priv->socket, 0);
+
+ /* Receive header */
+ zmq_msg_init (&header_msg);
+ zmq_msg_recv (&header_msg, priv->socket, 0);
+ header = (UfoMessage *) zmq_msg_data (&header_msg);
+
+ /* Receive payload */
+ zmq_msg_init (&payload_msg);
+ zmq_msg_recv (&payload_msg, priv->socket, 0);
+ payload_size = header->n_inputs * sizeof (UfoInputParameter);
+ g_assert (zmq_msg_size (&payload_msg) >= payload_size);
+ payload = zmq_msg_data (&payload_msg);
+
+ priv->n_inputs = header->n_inputs;
+ *n_inputs = header->n_inputs;
+ *in_params = g_new0 (UfoInputParameter, header->n_inputs);
+ memcpy (*in_params, payload, payload_size);
+
+ zmq_msg_close (&header_msg);
+ zmq_msg_close (&payload_msg);
+}
+
+void
+ufo_remote_node_send_inputs (UfoRemoteNode *node,
+ UfoBuffer **inputs)
+{
+ UfoRemoteNodePrivate *priv;
+ UfoMessage request;
+ zmq_msg_t reply_msg;
+
+ g_return_if_fail (UFO_IS_REMOTE_NODE (node));
+
+ priv = node->priv;
+ request.type = UFO_MESSAGE_SEND_INPUTS;
+ ufo_msg_send (&request, priv->socket, ZMQ_SNDMORE);
+
+ /*
+ * For each of the input data items send two frames: the first one contains
+ * the size as an UfoRequisition struct and the second one the raw byte
+ * data.
+ */
+ for (guint i = 0; i < priv->n_inputs; i++) {
+ UfoRequisition requisition;
+ zmq_msg_t requisition_msg;
+ zmq_msg_t data_msg;
+ gsize size;
+ gint flags;
+
+ ufo_buffer_get_requisition (inputs[i], &requisition);
+ size = ufo_buffer_get_size (inputs[i]);
+
+ zmq_msg_init_size (&requisition_msg, sizeof (UfoRequisition));
+ zmq_msg_init_size (&data_msg, size);
+
+ memcpy (zmq_msg_data (&requisition_msg), &requisition, sizeof (UfoRequisition));
+ memcpy (zmq_msg_data (&data_msg), ufo_buffer_get_host_array (inputs[i], NULL), size);
+
+ flags = i == priv->n_inputs - 1 ? 0 : ZMQ_SNDMORE;
+ zmq_msg_send (&requisition_msg, priv->socket, ZMQ_SNDMORE);
+ zmq_msg_send (&data_msg, priv->socket, flags);
+
+ zmq_msg_close (&requisition_msg);
+ zmq_msg_close (&data_msg);
+ }
+
+ /* Receive final ACK */
+ zmq_msg_init (&reply_msg);
+ zmq_msg_recv (&reply_msg, priv->socket, 0);
+ zmq_msg_close (&reply_msg);
+}
+
+void
+ufo_remote_node_get_result (UfoRemoteNode *node,
+ UfoBuffer *buffer)
+{
+ UfoRemoteNodePrivate *priv;
+ UfoMessage request;
+ zmq_msg_t reply_msg;
+ gpointer host_array;
+
+ g_return_if_fail (UFO_IS_REMOTE_NODE (node));
+
+ priv = node->priv;
+ request.type = UFO_MESSAGE_GET_RESULT;
+ ufo_msg_send (&request, priv->socket, 0);
+
+ /* Get the remote data and put it into our buffer */
+ zmq_msg_init (&reply_msg);
+ zmq_msg_recv (&reply_msg, priv->socket, 0);
+
+ ufo_buffer_discard_location (buffer, UFO_LOCATION_DEVICE);
+ host_array = ufo_buffer_get_host_array (buffer, NULL);
+ g_assert (ufo_buffer_get_size (buffer) == zmq_msg_size (&reply_msg));
+ memcpy (host_array, zmq_msg_data (&reply_msg), ufo_buffer_get_size (buffer));
+
+ zmq_msg_close (&reply_msg);
+}
+
+void
+ufo_remote_node_get_requisition (UfoRemoteNode *node,
+ UfoRequisition *requisition)
+{
+ UfoRemoteNodePrivate *priv;
+ UfoMessage request;
+ zmq_msg_t reply_msg;
+
+ g_return_if_fail (UFO_IS_REMOTE_NODE (node));
+
+ priv = node->priv;
+ request.type = UFO_MESSAGE_GET_REQUISITION;
+ ufo_msg_send (&request, priv->socket, 0);
+
+ zmq_msg_init (&reply_msg);
+ zmq_msg_recv (&reply_msg, priv->socket, 0);
+ g_assert (zmq_msg_size (&reply_msg) >= sizeof (UfoRequisition));
+ memcpy (requisition, zmq_msg_data (&reply_msg), sizeof (UfoRequisition));
+ zmq_msg_close (&reply_msg);
+}
+
+static void ufo_msg_send (UfoMessage *msg,
+ gpointer socket,
+ gint flags)
+{
+ zmq_msg_t request;
+
+ zmq_msg_init_size (&request, sizeof (UfoMessage));
+ memcpy (zmq_msg_data (&request), msg, sizeof (UfoMessage));
+ zmq_msg_send (&request, socket, flags);
+ zmq_msg_close (&request);
+}
+
+static void
+ufo_remote_node_finalize (GObject *object)
+{
+ UfoRemoteNodePrivate *priv;
+
+ priv = UFO_REMOTE_NODE_GET_PRIVATE (object);
+ zmq_close (priv->socket);
+ G_OBJECT_CLASS (ufo_remote_node_parent_class)->finalize (object);
+}
+
+static void
+ufo_remote_node_class_init (UfoRemoteNodeClass *klass)
+{
+ GObjectClass *oclass;
+
+ oclass = G_OBJECT_CLASS (klass);
+ oclass->finalize = ufo_remote_node_finalize;
+
+ g_type_class_add_private (klass, sizeof(UfoRemoteNodePrivate));
+}
+
+static void
+ufo_remote_node_init (UfoRemoteNode *self)
+{
+ UfoRemoteNodePrivate *priv;
+ self->priv = priv = UFO_REMOTE_NODE_GET_PRIVATE (self);
+ priv->context = NULL;
+ priv->socket = NULL;
+ priv->n_inputs = 0;
+}
diff --git a/src/ufo-remote-node.h b/src/ufo-remote-node.h
new file mode 100644
index 0000000..7f131c4
--- /dev/null
+++ b/src/ufo-remote-node.h
@@ -0,0 +1,80 @@
+#ifndef __UFO_REMOTE_NODE_H
+#define __UFO_REMOTE_NODE_H
+
+#include <glib-object.h>
+#include "ufo-node.h"
+#include "ufo-buffer.h"
+#include "ufo-task-iface.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_REMOTE_NODE (ufo_remote_node_get_type())
+#define UFO_REMOTE_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_REMOTE_NODE, UfoRemoteNode))
+#define UFO_IS_REMOTE_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_REMOTE_NODE))
+#define UFO_REMOTE_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_REMOTE_NODE, UfoRemoteNodeClass))
+#define UFO_IS_REMOTE_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_REMOTE_NODE))
+#define UFO_REMOTE_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_REMOTE_NODE, UfoRemoteNodeClass))
+
+typedef struct _UfoRemoteNode UfoRemoteNode;
+typedef struct _UfoRemoteNodeClass UfoRemoteNodeClass;
+typedef struct _UfoRemoteNodePrivate UfoRemoteNodePrivate;
+typedef struct _UfoMessage UfoMessage;
+
+/**
+ * UfoRemoteNode:
+ *
+ * Main object for organizing filters. The contents of the #UfoRemoteNode structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoRemoteNode {
+ /*< private >*/
+ UfoNode parent_instance;
+
+ UfoRemoteNodePrivate *priv;
+};
+
+/**
+ * UfoRemoteNodeClass:
+ *
+ * #UfoRemoteNode class
+ */
+struct _UfoRemoteNodeClass {
+ /*< private >*/
+ UfoNodeClass parent_class;
+};
+
+typedef enum {
+ UFO_MESSAGE_SETUP = 0,
+ UFO_MESSAGE_GET_STRUCTURE,
+ UFO_MESSAGE_STRUCTURE,
+ UFO_MESSAGE_GET_REQUISITION,
+ UFO_MESSAGE_REQUISITION,
+ UFO_MESSAGE_SEND_INPUTS,
+ UFO_MESSAGE_GET_RESULT,
+ UFO_MESSAGE_RESULT,
+ UFO_MESSAGE_ACK
+} UfoMessageType;
+
+struct _UfoMessage {
+ UfoMessageType type;
+
+ guint n_inputs;
+};
+
+UfoNode *ufo_remote_node_new (gpointer zmq_context,
+ const gchar *address);
+void ufo_remote_node_request_setup (UfoRemoteNode *node);
+void ufo_remote_node_get_structure (UfoRemoteNode *node,
+ guint *n_inputs,
+ UfoInputParameter **in_params);
+void ufo_remote_node_send_inputs (UfoRemoteNode *node,
+ UfoBuffer **inputs);
+void ufo_remote_node_get_result (UfoRemoteNode *node,
+ UfoBuffer *result);
+void ufo_remote_node_get_requisition (UfoRemoteNode *node,
+ UfoRequisition *requisition);
+GType ufo_remote_node_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-remote-task.c b/src/ufo-remote-task.c
new file mode 100644
index 0000000..603f6ee
--- /dev/null
+++ b/src/ufo-remote-task.c
@@ -0,0 +1,160 @@
+/**
+ * SECTION:ufo-remote-task
+ * @Short_description: Encapsulate remote task
+ * @Title: Remote task
+ */
+
+#include <gmodule.h>
+#include <tiffio.h>
+#ifdef __APPLE__
+#include <OpenCL/cl.h>
+#else
+#include <CL/cl.h>
+#endif
+
+#include <ufo-remote-task.h>
+#include <ufo-remote-node.h>
+#include <ufo-cpu-task-iface.h>
+
+struct _UfoRemoteTaskPrivate {
+ UfoRemoteNode *remote;
+};
+
+static void ufo_task_interface_init (UfoTaskIface *iface);
+static void ufo_cpu_task_interface_init (UfoCpuTaskIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UfoRemoteTask, ufo_remote_task, UFO_TYPE_TASK_NODE,
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
+ ufo_task_interface_init)
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_CPU_TASK,
+ ufo_cpu_task_interface_init))
+
+#define UFO_REMOTE_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_REMOTE_TASK, UfoRemoteTaskPrivate))
+
+enum {
+ PROP_0,
+ N_PROPERTIES
+};
+
+UfoNode *
+ufo_remote_task_new (void)
+{
+ return UFO_NODE (g_object_new (UFO_TYPE_REMOTE_TASK, NULL));
+}
+
+static void
+ufo_remote_task_setup (UfoTask *task, GError **error)
+{
+ UfoRemoteTaskPrivate *priv;
+
+ priv = UFO_REMOTE_TASK_GET_PRIVATE (UFO_REMOTE_TASK (task));
+ priv->remote = UFO_REMOTE_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task)));
+ g_assert (priv->remote != NULL);
+ g_object_ref (priv->remote);
+ ufo_remote_node_request_setup (priv->remote);
+}
+
+static void
+ufo_remote_task_get_requisition (UfoTask *task,
+ UfoBuffer **inputs,
+ UfoRequisition *requisition)
+{
+ UfoRemoteTaskPrivate *priv;
+
+ priv = UFO_REMOTE_TASK_GET_PRIVATE (UFO_REMOTE_TASK (task));
+
+ /*
+ * We send our input to the remote node which will execute immediately.
+ * After remote execution, we will know the requisition of the _last_ remote
+ * task node and can get it back.
+ */
+ ufo_remote_node_send_inputs (priv->remote, inputs);
+ ufo_remote_node_get_requisition (priv->remote, requisition);
+}
+
+static void
+ufo_remote_task_get_structure (UfoTask *task,
+ guint *n_inputs,
+ UfoInputParameter **in_params)
+{
+ UfoRemoteTaskPrivate *priv;
+
+ priv = UFO_REMOTE_TASK_GET_PRIVATE (UFO_REMOTE_TASK (task));
+ ufo_remote_node_get_structure (priv->remote, n_inputs, in_params);
+}
+
+static gboolean
+ufo_remote_task_process (UfoCpuTask *task,
+ UfoBuffer **inputs,
+ UfoBuffer *output,
+ UfoRequisition *requisition)
+{
+ UfoRemoteTaskPrivate *priv;
+ priv = UFO_REMOTE_TASK_GET_PRIVATE (UFO_REMOTE_TASK (task));
+
+ ufo_remote_node_get_result (priv->remote, output);
+ return TRUE;
+}
+
+static void
+ufo_remote_task_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_remote_task_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_remote_task_dispose (GObject *object)
+{
+ UfoRemoteTaskPrivate *priv;
+
+ priv = UFO_REMOTE_TASK_GET_PRIVATE (object);
+ g_object_unref (priv->remote);
+ priv->remote = NULL;
+ G_OBJECT_CLASS (ufo_remote_task_parent_class)->dispose (object);
+}
+
+static void
+ufo_task_interface_init (UfoTaskIface *iface)
+{
+ iface->setup = ufo_remote_task_setup;
+ iface->get_structure = ufo_remote_task_get_structure;
+ iface->get_requisition = ufo_remote_task_get_requisition;
+}
+
+static void
+ufo_cpu_task_interface_init (UfoCpuTaskIface *iface)
+{
+ iface->process = ufo_remote_task_process;
+}
+
+static void
+ufo_remote_task_class_init (UfoRemoteTaskClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ oclass->set_property = ufo_remote_task_set_property;
+ oclass->get_property = ufo_remote_task_get_property;
+ oclass->dispose = ufo_remote_task_dispose;
+
+ g_type_class_add_private (oclass, sizeof(UfoRemoteTaskPrivate));
+}
+
+static void
+ufo_remote_task_init(UfoRemoteTask *self)
+{
+ self->priv = UFO_REMOTE_TASK_GET_PRIVATE(self);
+}
diff --git a/src/ufo-remote-task.h b/src/ufo-remote-task.h
new file mode 100644
index 0000000..12e8d64
--- /dev/null
+++ b/src/ufo-remote-task.h
@@ -0,0 +1,48 @@
+#ifndef __UFO_REMOTE_TASK_H
+#define __UFO_REMOTE_TASK_H
+
+#include <glib-object.h>
+#include <ufo-task-node.h>
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_REMOTE_TASK (ufo_remote_task_get_type())
+#define UFO_REMOTE_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_REMOTE_TASK, UfoRemoteTask))
+#define UFO_IS_REMOTE_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_REMOTE_TASK))
+#define UFO_REMOTE_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_REMOTE_TASK, UfoRemoteTaskClass))
+#define UFO_IS_REMOTE_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_REMOTE_TASK))
+#define UFO_REMOTE_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_REMOTE_TASK, UfoRemoteTaskClass))
+
+typedef struct _UfoRemoteTask UfoRemoteTask;
+typedef struct _UfoRemoteTaskClass UfoRemoteTaskClass;
+typedef struct _UfoRemoteTaskPrivate UfoRemoteTaskPrivate;
+
+/**
+ * UfoRemoteTask:
+ *
+ * Main object for organizing filters. The contents of the #UfoRemoteTask structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoRemoteTask {
+ /*< private >*/
+ UfoTaskNode parent_instance;
+
+ UfoRemoteTaskPrivate *priv;
+};
+
+/**
+ * UfoRemoteTaskClass:
+ *
+ * #UfoRemoteTask class
+ */
+struct _UfoRemoteTaskClass {
+ /*< private >*/
+ UfoTaskNodeClass parent_class;
+};
+
+UfoNode *ufo_remote_task_new (void);
+GType ufo_remote_task_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-resource-manager.c b/src/ufo-resource-manager.c
deleted file mode 100644
index cc916ec..0000000
--- a/src/ufo-resource-manager.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/**
- * SECTION:ufo-resource-manager
- * @Short_description: Manage OpenCL resources
- * @Title: UfoResourceManager
- *
- * The #UfoResourceManager creates the OpenCL environment and loads OpenCL
- * kernels from text files.
- */
-
-#include <glib.h>
-#include <stdio.h>
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#include "config.h"
-#include "ufo-resource-manager.h"
-#include "ufo-configurable.h"
-#include "ufo-aux.h"
-
-G_DEFINE_TYPE_WITH_CODE (UfoResourceManager, ufo_resource_manager, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (UFO_TYPE_CONFIGURABLE, NULL))
-
-#define UFO_RESOURCE_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_RESOURCE_MANAGER, UfoResourceManagerPrivate))
-
-/**
- * UfoResourceManagerError:
- * @UFO_RESOURCE_MANAGER_ERROR_LOAD_PROGRAM: Could not load the OpenCL file
- * @UFO_RESOURCE_MANAGER_ERROR_CREATE_PROGRAM: Could not create a program from
- * the sources
- * @UFO_RESOURCE_MANAGER_ERROR_BUILD_PROGRAM: Could not build program from
- * sources
- * @UFO_RESOURCE_MANAGER_ERROR_CREATE_KERNEL: Could not create kernel
- *
- * OpenCL related errors.
- */
-GQuark ufo_resource_manager_error_quark (void)
-{
- return g_quark_from_static_string ("ufo-resource-manager-error-quark");
-}
-
-struct _UfoResourceManagerPrivate {
- UfoConfiguration *config;
-
- cl_uint num_platforms;
- cl_platform_id *opencl_platforms;
- cl_context opencl_context;
- cl_uint *num_devices; /**< Number of OpenCL devices per platform id */
- cl_device_id **opencl_devices; /**< Array of OpenCL devices per platform id */
- cl_command_queue *command_queues; /**< Array of command queues per device */
-
- GList *kernel_paths; /**< Colon-separated string with paths to kernel files */
- GHashTable *opencl_programs; /**< Map from filename to cl_program */
- GList *opencl_kernels;
- GString *opencl_build_options;
- GString *include_paths; /**< List of include paths "-I/foo/bar" built from added paths */
-
- guint current_id; /**< current non-assigned buffer id */
-};
-
-enum {
- PROP_0,
- PROP_CONFIG,
- N_PROPERTIES
-};
-
-const gchar *opencl_error_msgs[] = {
- "CL_SUCCESS",
- "CL_DEVICE_NOT_FOUND",
- "CL_DEVICE_NOT_AVAILABLE",
- "CL_COMPILER_NOT_AVAILABLE",
- "CL_MEM_OBJECT_ALLOCATION_FAILURE",
- "CL_OUT_OF_RESOURCES",
- "CL_OUT_OF_HOST_MEMORY",
- "CL_PROFILING_INFO_NOT_AVAILABLE",
- "CL_MEM_COPY_OVERLAP",
- "CL_IMAGE_FORMAT_MISMATCH",
- "CL_IMAGE_FORMAT_NOT_SUPPORTED",
- "CL_BUILD_PROGRAM_FAILURE",
- "CL_MAP_FAILURE",
- "CL_MISALIGNED_SUB_BUFFER_OFFSET",
- "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST",
-
- /* next IDs start at 30! */
- "CL_INVALID_VALUE",
- "CL_INVALID_DEVICE_TYPE",
- "CL_INVALID_PLATFORM",
- "CL_INVALID_DEVICE",
- "CL_INVALID_CONTEXT",
- "CL_INVALID_QUEUE_PROPERTIES",
- "CL_INVALID_COMMAND_QUEUE",
- "CL_INVALID_HOST_PTR",
- "CL_INVALID_MEM_OBJECT",
- "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR",
- "CL_INVALID_IMAGE_SIZE",
- "CL_INVALID_SAMPLER",
- "CL_INVALID_BINARY",
- "CL_INVALID_BUILD_OPTIONS",
- "CL_INVALID_PROGRAM",
- "CL_INVALID_PROGRAM_EXECUTABLE",
- "CL_INVALID_KERNEL_NAME",
- "CL_INVALID_KERNEL_DEFINITION",
- "CL_INVALID_KERNEL",
- "CL_INVALID_ARG_INDEX",
- "CL_INVALID_ARG_VALUE",
- "CL_INVALID_ARG_SIZE",
- "CL_INVALID_KERNEL_ARGS",
- "CL_INVALID_WORK_DIMENSION",
- "CL_INVALID_WORK_GROUP_SIZE",
- "CL_INVALID_WORK_ITEM_SIZE",
- "CL_INVALID_GLOBAL_OFFSET",
- "CL_INVALID_EVENT_WAIT_LIST",
- "CL_INVALID_EVENT",
- "CL_INVALID_OPERATION",
- "CL_INVALID_GL_OBJECT",
- "CL_INVALID_BUFFER_SIZE",
- "CL_INVALID_MIP_LEVEL",
- "CL_INVALID_GLOBAL_WORK_SIZE"
-};
-
-const gchar *
-opencl_map_error (int error)
-{
- static const gchar *invalid = "Invalid error code";
- const gint array_size = sizeof opencl_error_msgs/sizeof(gchar*);
- gint index;
-
- index = error >= -14 ? -error : -error-15;
-
- if (index >= 0 && index < array_size)
- return opencl_error_msgs[index];
-
- return invalid;
-}
-
-static gchar *
-resource_manager_load_opencl_program (const gchar *filename)
-{
- FILE *fp = fopen (filename, "r");
-
- if (fp == NULL)
- return NULL;
-
- fseek (fp, 0, SEEK_END);
- const gsize length = (gsize) ftell (fp);
- rewind (fp);
- gchar *buffer = (gchar *) g_malloc0(length + 1);
-
- if (buffer == NULL) {
- fclose (fp);
- return NULL;
- }
-
- size_t buffer_length = fread (buffer, 1, length, fp);
- fclose (fp);
-
- if (buffer_length != length) {
- g_free (buffer);
- return NULL;
- }
-
- return buffer;
-}
-
-static void
-resource_manager_release_kernel (gpointer data, gpointer user_data)
-{
- cl_kernel kernel = (cl_kernel) data;
- CHECK_OPENCL_ERROR (clReleaseKernel (kernel));
- ufo_debug_cl ("Released kernel %p", (gpointer) kernel);
-}
-
-static void
-resource_manager_release_program (gpointer data)
-{
- cl_program program = (cl_program) data;
- CHECK_OPENCL_ERROR (clReleaseProgram (program));
- ufo_debug_cl ("Released program %p", (gpointer) program);
-}
-
-static gchar *
-resource_manager_find_path (UfoResourceManagerPrivate *priv, const gchar *filename)
-{
- /* Check first if filename is already a path */
- if (g_path_is_absolute (filename)) {
- if (g_file_test (filename, G_FILE_TEST_EXISTS))
- return g_strdup (filename);
- else
- return NULL;
- }
-
- /* If it is not a path, search in all paths that were added */
- GList *elem = g_list_first (priv->kernel_paths);
-
- while (elem != NULL) {
- gchar *path = g_strdup_printf ("%s%c%s", (gchar *) elem->data, G_DIR_SEPARATOR, filename);
-
- if (g_file_test (path, G_FILE_TEST_EXISTS))
- return path;
-
- g_free (path);
- elem = g_list_next (elem);
- }
-
- return NULL;
-}
-
-/**
- * ufo_resource_manager_new:
- * @config: A #UfoConfiguration object or %NULL
- *
- * Create a new #UfoResourceManager instance.
- *
- * Returns: (transfer none): A new #UfoResourceManager
- */
-UfoResourceManager *
-ufo_resource_manager_new (UfoConfiguration *config)
-{
- return UFO_RESOURCE_MANAGER (g_object_new (UFO_TYPE_RESOURCE_MANAGER,
- "configuration", config,
- NULL));
-}
-
-static void
-add_paths (UfoResourceManagerPrivate *priv, gchar *paths[])
-{
- if (paths == NULL)
- return;
-
- for (guint i = 0; paths[i] != NULL; i++) {
- priv->kernel_paths = g_list_append (priv->kernel_paths, g_strdup (paths[i]));
- g_string_append_printf (priv->include_paths, "-I%s ", paths[i]);
- }
-}
-
-static cl_program
-add_program_from_source (UfoResourceManagerPrivate *priv,
- const gchar *source,
- const gchar *options,
- GError **error)
-{
- cl_program program;
- gchar *build_options = NULL;
- cl_int errcode = CL_SUCCESS;
-
- program = clCreateProgramWithSource (priv->opencl_context,
- 1, &source, NULL, &errcode);
- ufo_debug_cl ("Created program %p with error code %i", (gpointer) program, errcode);
-
- if (errcode != CL_SUCCESS) {
- g_set_error (error,
- UFO_RESOURCE_MANAGER_ERROR,
- UFO_RESOURCE_MANAGER_ERROR_CREATE_PROGRAM,
- "Failed to create OpenCL program: %s", opencl_map_error (errcode));
- return NULL;
- }
-
- if (options != NULL)
- build_options = g_strdup_printf ("%s %s %s", priv->opencl_build_options->str, priv->include_paths->str, options);
- else
- build_options = g_strdup_printf ("%s %s", priv->opencl_build_options->str, priv->include_paths->str);
-
- errcode = clBuildProgram (program,
- priv->num_devices[0],
- priv->opencl_devices[0],
- build_options,
- NULL, NULL);
-
- ufo_debug_cl ("Build program %p with error code %i", (gpointer) program, errcode);
- g_free (build_options);
-
- if (errcode != CL_SUCCESS) {
- g_set_error (error,
- UFO_RESOURCE_MANAGER_ERROR,
- UFO_RESOURCE_MANAGER_ERROR_BUILD_PROGRAM,
- "Failed to build OpenCL program: %s", opencl_map_error (errcode));
-
- const gsize LOG_SIZE = 4096;
- gchar *log = (gchar *) g_malloc0(LOG_SIZE * sizeof (char));
- CHECK_OPENCL_ERROR (clGetProgramBuildInfo (program,
- priv->opencl_devices[0][0],
- CL_PROGRAM_BUILD_LOG,
- LOG_SIZE, (void *) log, NULL));
- g_print ("\n=== Build log for s===%s\n\n", log);
- g_free (log);
- return NULL;
- }
-
- return program;
-}
-
-static cl_program
-resource_manager_add_program (UfoResourceManager *manager, const gchar *filename, const gchar *options, GError **error)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager) || (filename != NULL), FALSE);
- UfoResourceManagerPrivate *priv = manager->priv;
-
- /* Programs might be added multiple times if this is not locked */
- static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- g_static_mutex_lock (&mutex);
-
- /* Don't process the kernel file again, if already load */
- cl_program program = g_hash_table_lookup (priv->opencl_programs, filename);
-
- if (program != NULL) {
- g_static_mutex_unlock (&mutex);
- return program;
- }
-
- gchar *path = resource_manager_find_path (priv, filename);
-
- if (path == NULL) {
- g_set_error (error,
- UFO_RESOURCE_MANAGER_ERROR,
- UFO_RESOURCE_MANAGER_ERROR_LOAD_PROGRAM,
- "Could not find `%s'. Maybe you forgot to pass a configuration?", filename);
- g_static_mutex_unlock (&mutex);
- return NULL;
- }
-
- gchar *buffer = resource_manager_load_opencl_program (path);
- g_free (path);
-
- if (buffer == NULL) {
- g_set_error (error,
- UFO_RESOURCE_MANAGER_ERROR,
- UFO_RESOURCE_MANAGER_ERROR_LOAD_PROGRAM,
- "Could not open `%s'", filename);
- g_static_mutex_unlock (&mutex);
- return NULL;
- }
-
- program = add_program_from_source (priv, buffer, options, error);
- g_message ("Added program %p from `%s`", (gpointer) program, filename);
-
- if (program != NULL)
- g_hash_table_insert (priv->opencl_programs, g_strdup (filename), program);
-
- g_static_mutex_unlock (&mutex);
- g_free (buffer);
- return program;
-}
-
-static cl_kernel
-resource_manager_get_kernel (UfoResourceManagerPrivate *priv, cl_program program, const gchar *kernel_name, GError **error)
-{
- cl_int errcode = CL_SUCCESS;
- cl_kernel kernel = clCreateKernel (program, kernel_name, &errcode);
-
- ufo_debug_cl ("Created kernel `%s` from program %p", kernel_name, (gpointer) program);
-
- if (kernel == NULL || errcode != CL_SUCCESS) {
- g_set_error (error,
- UFO_RESOURCE_MANAGER_ERROR,
- UFO_RESOURCE_MANAGER_ERROR_CREATE_KERNEL,
- "Failed to create kernel `%s`: %s", kernel_name, opencl_map_error (errcode));
- return NULL;
- }
-
- priv->opencl_kernels = g_list_append (priv->opencl_kernels, kernel);
- CHECK_OPENCL_ERROR (clRetainKernel (kernel));
- return kernel;
-}
-
-/**
- * ufo_resource_manager_get_kernel: (skip)
- * @manager: A #UfoResourceManager
- * @filename: Name of the .cl kernel file
- * @kernel_name: Name of a kernel
- * @error: Return location for a GError from #UfoResourceManagerError, or NULL
- *
- * Loads a and builds a kernel from a file. The file is searched in the current
- * working directory and all paths added through
- * ufo_resource_manager_add_paths ().
- *
- * Returns: a cl_kernel object that is load from @filename or %NULL on error
- */
-gpointer
-ufo_resource_manager_get_kernel (UfoResourceManager *manager, const gchar *filename, const gchar *kernel_name, GError **error)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager) &&
- (filename != NULL) && (kernel_name != NULL), NULL);
-
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (manager);
- GError *tmp_error = NULL;
-
- cl_program program = resource_manager_add_program (manager, filename, "", &tmp_error);
-
- if (program == NULL) {
- g_propagate_error (error, tmp_error);
- return NULL;
- }
-
- return resource_manager_get_kernel (priv, program, kernel_name, error);
-}
-
-/**
- * ufo_resource_manager_get_kernel_from_source: (skip)
- * @manager: A #UfoResourceManager
- * @source: OpenCL source string
- * @kernel_name: Name of a kernel
- * @error: Return location for a GError from #UfoResourceManagerError, or NULL
- *
- * Loads and builds a kernel from a string.
- *
- * Returns: a cl_kernel object that is load from @filename
- */
-gpointer
-ufo_resource_manager_get_kernel_from_source (UfoResourceManager *manager, const gchar *source, const gchar *kernel_name, GError **error)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager) && (source != NULL) && (kernel_name != NULL), NULL);
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (manager);
- cl_program program = add_program_from_source (priv, source, NULL, error);
-
- /*
- * We add the program under a fake file name. This looks very brittle to me
- * (kernel name could be the same as a source filename) but it should work
- * in most cases.
- */
- if (program != NULL)
- g_hash_table_insert (priv->opencl_programs, g_strdup (kernel_name), program);
- else
- return NULL;
-
- return resource_manager_get_kernel (priv, program, kernel_name, error);
-}
-
-/* void ufo_resource_manager_call(UfoResourceManager *manager, */
-/* const gchar *kernel_name, */
-/* void *command_queue, */
-/* uint32_t work_dim, */
-/* size_t *global_work_size, */
-/* size_t *local_work_size, */
-/* ...) */
-/* { */
-/* cl_kernel kernel = (cl_kernel) g_hash_table_lookup(manager->priv->opencl_kernels, kernel_name); */
-
-/* if (kernel == NULL) */
-/* return; */
-
-/* cl_uint num_args = 0; */
-/* clGetKernelInfo(kernel, CL_KERNEL_NUM_ARGS, sizeof(cl_uint), &num_args, NULL); */
-/* void *ptr = NULL; */
-/* size_t size = 0; */
-/* va_list ap; */
-/* va_start(ap, local_work_size); */
-/* g_message("parsing arguments"); */
-
-/* for (guint i = 0; i < num_args; i++) { */
-/* size = va_arg(ap, size_t); */
-/* ptr = va_arg(ap, void *); */
-/* clSetKernelArg(kernel, i, size, ptr); */
-/* } */
-
-/* va_end(ap); */
-/* clEnqueueNDRangeKernel(command_queue, kernel, */
-/* work_dim, NULL, global_work_size, local_work_size, */
-/* 0, NULL, NULL); */
-/* } */
-
-/**
- * ufo_resource_manager_get_context: (skip)
- * @manager: A #UfoResourceManager
- *
- * Returns the OpenCL context object that is used by the resource manager. This
- * context can be used to initialize othe third-party libraries.
- *
- * Return value: A cl_context object.
- */
-gpointer
-ufo_resource_manager_get_context (UfoResourceManager *manager)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager), NULL);
- return manager->priv->opencl_context;
-}
-
-/**
- * ufo_resource_manager_request_buffer: (skip)
- * @manager: A #UfoResourceManager
- * @num_dims: (in): Number of dimensions
- * @dim_size: (in) (array): Size of each dimension
- * @data: (in) (allow-none): Data used to initialize the buffer with, or NULL
- * @cmd_queue: (in) (allow-none): If data should be copied onto the device,
- * a cl_command_queue must be provide, or %NULL
- *
- * Creates a new #UfoBuffer and initializes it with data on demand. If
- * non-floating point data have to be uploaded, use ufo_buffer_set_host_array()
- * and ufo_buffer_reinterpret() on the #UfoBuffer.
- *
- * Return value: A new #UfoBuffer with the given dimensions
- */
-UfoBuffer *
-ufo_resource_manager_request_buffer (UfoResourceManager *manager,
- guint num_dims,
- const guint *dim_size,
- gfloat *data,
- gpointer cmd_queue)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager), NULL);
- g_return_val_if_fail ((num_dims > UFO_BUFFER_MAX_NDIMS) || (dim_size != NULL), NULL);
-
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (manager);
- UfoBuffer *buffer = ufo_buffer_new (num_dims, dim_size);
- const gsize num_bytes = ufo_buffer_get_size (buffer);
- cl_mem_flags mem_flags = CL_MEM_READ_WRITE;
-
- if ((data != NULL) && (cmd_queue != NULL))
- mem_flags |= CL_MEM_COPY_HOST_PTR;
-
- cl_int errcode;
- cl_mem buffer_mem = clCreateBuffer (priv->opencl_context,
- mem_flags,
- num_bytes,
- data, &errcode);
- CHECK_OPENCL_ERROR (errcode);
- ufo_buffer_set_cl_mem (buffer, buffer_mem);
-
- if ((data) && (cmd_queue == NULL))
- ufo_buffer_set_host_array (buffer, data, num_bytes, NULL);
-
- return buffer;
-}
-
-/**
- * ufo_resource_manager_memalloc: (skip)
- * @manager: A #UfoResourceManager
- * @size: Size of cl_mem in bytes
- *
- * Allocates a new cl_mem object with the given size.
- *
- * Return value: A cl_mem object
- */
-gpointer
-ufo_resource_manager_memalloc (UfoResourceManager *manager, gsize size)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager) || (size == 0), NULL);
- cl_int errcode = CL_SUCCESS;
- cl_mem mem = clCreateBuffer (manager->priv->opencl_context, CL_MEM_READ_WRITE, size, NULL, &errcode);
- CHECK_OPENCL_ERROR (errcode);
- return mem;
-}
-
-/**
- * ufo_resource_manager_memdup: (skip)
- * @manager: A #UfoResourceManager
- * @memobj: A cl_mem object
- *
- * Creates a new cl_mem object with the same size and content as a given cl_mem
- * object.
- *
- * Return value: A new cl_mem object
- */
-gpointer
-ufo_resource_manager_memdup (UfoResourceManager *manager, gpointer memobj)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager) || (memobj == NULL), NULL);
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (manager);
- cl_int errcode;
- cl_event event;
- cl_mem mem, dup;
- size_t size;
-
- mem = (cl_mem) memobj;
- CHECK_OPENCL_ERROR (clGetMemObjectInfo (mem, CL_MEM_SIZE, sizeof (size_t), &size, NULL));
- dup = clCreateBuffer (priv->opencl_context, CL_MEM_READ_WRITE, size, NULL, &errcode);
- CHECK_OPENCL_ERROR (errcode);
-
- CHECK_OPENCL_ERROR (clEnqueueCopyBuffer (priv->command_queues[0],
- mem, dup, 0, 0, size, 0, NULL, &event));
-
- CHECK_OPENCL_ERROR (clWaitForEvents (1, &event));
- CHECK_OPENCL_ERROR (clReleaseEvent (event));
-
- return dup;
-}
-
-/**
- * ufo_resource_manager_get_command_queues:
- * @manager: A #UfoResourceManager
- * @cmd_queues: (out): Sets pointer to command_queues array
- * @num_queues: (out): Number of queues
- *
- * Return the number and actual command queues.
- */
-void ufo_resource_manager_get_command_queues (UfoResourceManager *manager, gpointer *cmd_queues, guint *num_queues)
-{
- g_return_if_fail (UFO_IS_RESOURCE_MANAGER (manager) || (cmd_queues != NULL) || (num_queues != NULL));
- /* FIXME: Use only first platform */
- *num_queues = manager->priv->num_devices[0];
- *cmd_queues= manager->priv->command_queues;
-}
-
-/**
- * ufo_resource_manager_get_command_queue: (skip)
- * @manager: A #UfoResourceManager
- * @queue: The number of the queue which must be less than the number returned
- * by ufo_resource_manager_get_number_of_devices ().
- *
- * Return a specific command queue.
- *
- * Return value: The ith cl_command_queue
- * Since: 0.2
- */
-gpointer
-ufo_resource_manager_get_command_queue (UfoResourceManager *manager, guint queue)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager), NULL);
- g_return_val_if_fail (queue >= manager->priv->num_devices[0], NULL);
- return manager->priv->command_queues[queue];
-}
-
-/**
- * ufo_resource_manager_get_queue_number:
- * @manager: A #UfoResourceManager
- * @cmd_queue: A %cl_command_queue
- *
- * Translate a %cl_command_queue pointer into a numerical representation.
- *
- * Returns: The numeral position of %cmd_queue or -1 if it is not found.
- * Since: 0.2
- */
-gint
-ufo_resource_manager_get_queue_number (UfoResourceManager *manager,
- gpointer cmd_queue)
-{
- UfoResourceManagerPrivate *priv;
-
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager), -1);
- priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (manager);
-
- for (guint i = 0; i < priv->num_devices[0]; i++)
- if (priv->command_queues[i] == cmd_queue)
- return (gint) i;
-
- return -1;
-}
-
-/**
- * ufo_resource_manager_get_number_of_devices:
- * @manager: A #UfoResourceManager
- *
- * Get number of acceleration devices such as GPUs.
- *
- * Return value: Number of acceleration devices.
- */
-guint ufo_resource_manager_get_number_of_devices (UfoResourceManager *manager)
-{
- g_return_val_if_fail (UFO_IS_RESOURCE_MANAGER (manager), 0);
- return manager->priv->num_devices[0];
-}
-
-static void
-ufo_resource_manager_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_CONFIG:
- {
- UfoConfiguration *config;
- gchar **paths;
- GObject *value_object = g_value_get_object (value);
-
- ufo_set_property_object ((GObject **) &priv->config, value_object);
-
- if (value_object != NULL) {
- config = UFO_CONFIGURATION (value_object);
- paths = ufo_configuration_get_paths (config);
- add_paths (priv, paths);
- g_strfreev (paths);
- }
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_resource_manager_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_CONFIG:
- g_value_set_object (value, priv->config);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void
-ufo_resource_manager_dispose (GObject *object)
-{
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (object);
-
- ufo_unref_stored_object ((GObject **) &priv->config);
-
- G_OBJECT_CLASS (ufo_resource_manager_parent_class)->finalize (object);
- g_message ("UfoResourceManager: disposed");
-}
-
-static void
-ufo_resource_manager_finalize (GObject *object)
-{
- UfoResourceManagerPrivate *priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (object);
-
- g_hash_table_destroy (priv->opencl_programs);
- g_list_foreach (priv->kernel_paths, (GFunc) g_free, NULL);
- g_list_free (priv->kernel_paths);
- g_list_foreach (priv->opencl_kernels, resource_manager_release_kernel, NULL);
- g_list_free (priv->opencl_kernels);
-
- for (guint i = 0; i < priv->num_devices[0]; i++)
- CHECK_OPENCL_ERROR (clReleaseCommandQueue (priv->command_queues[i]));
-
- CHECK_OPENCL_ERROR (clReleaseContext (priv->opencl_context));
- g_string_free (priv->opencl_build_options, TRUE);
- g_string_free (priv->include_paths, TRUE);
-
- for (guint i = 0; i < priv->num_platforms; i ++)
- g_free (priv->opencl_devices[i]);
-
- g_free (priv->num_devices);
- g_free (priv->opencl_devices);
- g_free (priv->opencl_platforms);
- g_free (priv->command_queues);
- priv->num_devices = NULL;
- priv->opencl_kernels = NULL;
- priv->opencl_devices = NULL;
- priv->opencl_platforms = NULL;
-
- G_OBJECT_CLASS (ufo_resource_manager_parent_class)->finalize (object);
- g_message ("UfoResourceManager: finalized");
-}
-
-static void
-ufo_resource_manager_class_init (UfoResourceManagerClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->set_property = ufo_resource_manager_set_property;
- gobject_class->get_property = ufo_resource_manager_get_property;
- gobject_class->dispose = ufo_resource_manager_dispose;
- gobject_class->finalize = ufo_resource_manager_finalize;
-
- g_object_class_override_property (gobject_class, PROP_CONFIG, "configuration");
-
- g_type_class_add_private (klass, sizeof (UfoResourceManagerPrivate));
-}
-
-static void
-ufo_resource_manager_init (UfoResourceManager *self)
-{
- UfoResourceManagerPrivate *priv;
- self->priv = priv = UFO_RESOURCE_MANAGER_GET_PRIVATE (self);
- priv->current_id = 0;
-
- priv->config = NULL;
- priv->opencl_programs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, resource_manager_release_program);
- priv->kernel_paths = g_list_append (NULL, g_strdup ("."));
- priv->opencl_kernels = NULL;
- priv->opencl_platforms = NULL;
- priv->opencl_build_options = g_string_new ("-cl-mad-enable ");
- priv->include_paths = g_string_new ("-I. ");
-
- /* initialize OpenCL subsystem */
- int errcode = CL_SUCCESS;
- CHECK_OPENCL_ERROR (clGetPlatformIDs (0, NULL, &priv->num_platforms));
- priv->opencl_platforms = g_malloc0(priv->num_platforms * sizeof (cl_platform_id));
-
- CHECK_OPENCL_ERROR (clGetPlatformIDs (priv->num_platforms, priv->opencl_platforms, NULL));
- priv->num_devices = g_malloc0(priv->num_platforms * sizeof (cl_uint));
- priv->opencl_devices = g_malloc0(priv->num_platforms * sizeof (cl_device_id *));
-
- ufo_debug_cl ("Number of OpenCL platforms: %i", priv->num_platforms);
-
- /* Get devices for each available platform */
- gchar *info_buffer = g_malloc0(256);
-
- for (guint i = 0; i < priv->num_platforms; i++) {
- cl_uint num_devices;
- cl_platform_id platform = priv->opencl_platforms[i];
-
- CHECK_OPENCL_ERROR (clGetPlatformInfo (platform, CL_PLATFORM_NAME, 256, info_buffer, NULL));
- ufo_debug_cl ("--- %s ---", info_buffer);
- CHECK_OPENCL_ERROR (clGetPlatformInfo (platform, CL_PLATFORM_VENDOR, 256, info_buffer, NULL));
- ufo_debug_cl (" Vendor : %s", info_buffer);
-
- if (g_str_has_prefix (info_buffer, "NVIDIA"))
- g_string_append (priv->opencl_build_options, "-cl-nv-verbose -DVENDOR=NVIDIA");
- else if (g_str_has_prefix (info_buffer, "Advanced Micro Devices"))
- g_string_append (priv->opencl_build_options, "-DVENDOR=AMD");
-
- CHECK_OPENCL_ERROR (clGetPlatformInfo (platform, CL_PLATFORM_VERSION, 256, info_buffer, NULL));
- ufo_debug_cl (" Version : %s", info_buffer);
-
- CHECK_OPENCL_ERROR (clGetDeviceIDs (platform,
- CL_DEVICE_TYPE_ALL,
- 0, NULL,
- &num_devices));
- priv->opencl_devices[i] = g_malloc0(num_devices * sizeof (cl_device_id));
-
- CHECK_OPENCL_ERROR (clGetDeviceIDs (platform,
- CL_DEVICE_TYPE_ALL,
- num_devices, priv->opencl_devices[i],
- NULL));
- priv->num_devices[i] = num_devices;
-
- ufo_debug_cl (" Device count : %i", num_devices);
- ufo_debug_cl (" Build options : %s", priv->opencl_build_options->str);
- }
-
- g_free (info_buffer);
- cl_command_queue_properties queue_properties = CL_QUEUE_PROFILING_ENABLE;
-
- /* XXX: create context for each platform?! */
- if (priv->num_platforms > 0) {
- priv->opencl_context = clCreateContext (NULL,
- priv->num_devices[0],
- priv->opencl_devices[0],
- NULL, NULL, &errcode);
- CHECK_OPENCL_ERROR (errcode);
- priv->command_queues = g_malloc0(priv->num_devices[0] * sizeof (cl_command_queue));
-
- for (guint i = 0; i < priv->num_devices[0]; i++) {
- priv->command_queues[i] = clCreateCommandQueue (priv->opencl_context,
- priv->opencl_devices[0][i],
- queue_properties, &errcode);
- CHECK_OPENCL_ERROR (errcode);
- }
- }
-}
diff --git a/src/ufo-resource-manager.h b/src/ufo-resource-manager.h
deleted file mode 100644
index 0fed200..0000000
--- a/src/ufo-resource-manager.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __UFO_RESOURCE_MANAGER_H
-#define __UFO_RESOURCE_MANAGER_H
-
-#include <glib-object.h>
-#include "ufo-configuration.h"
-#include "ufo-buffer.h"
-
-G_BEGIN_DECLS
-
-#define UFO_TYPE_RESOURCE_MANAGER (ufo_resource_manager_get_type())
-#define UFO_RESOURCE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_RESOURCE_MANAGER, UfoResourceManager))
-#define UFO_IS_RESOURCE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_RESOURCE_MANAGER))
-#define UFO_RESOURCE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_RESOURCE_MANAGER, UfoResourceManagerClass))
-#define UFO_IS_RESOURCE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_RESOURCE_MANAGER))
-#define UFO_RESOURCE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_RESOURCE_MANAGER, UfoResourceManagerClass))
-
-typedef struct _UfoResourceManager UfoResourceManager;
-typedef struct _UfoResourceManagerClass UfoResourceManagerClass;
-typedef struct _UfoResourceManagerPrivate UfoResourceManagerPrivate;
-
-#define UFO_RESOURCE_MANAGER_ERROR ufo_resource_manager_error_quark()
-typedef enum {
- UFO_RESOURCE_MANAGER_ERROR_LOAD_PROGRAM,
- UFO_RESOURCE_MANAGER_ERROR_CREATE_PROGRAM,
- UFO_RESOURCE_MANAGER_ERROR_BUILD_PROGRAM,
- UFO_RESOURCE_MANAGER_ERROR_CREATE_KERNEL
-} UfoResourceManagerError;
-
-
-/**
- * opencl_map_error: (skip)
- */
-const gchar *opencl_map_error(int error);
-
-/**
- * CHECK_OPENCL_ERROR:
- * @error: OpenCL error code
- *
- * Check the return value of OpenCL functions and issue a warning with file and
- * line number if an error occured.
- */
-#define CHECK_OPENCL_ERROR(error) { \
- if ((error) != CL_SUCCESS) g_log("ocl", G_LOG_LEVEL_CRITICAL, "Error <%s:%i>: %s", __FILE__, __LINE__, opencl_map_error((error))); }
-
-/**
- * UfoResourceManager:
- *
- * Manages OpenCL resources. The contents of the #UfoResourceManager structure
- * are private and should only be accessed via the provided API.
- */
-struct _UfoResourceManager {
- /*< private >*/
- GObject parent_instance;
-
- UfoResourceManagerPrivate *priv;
-};
-
-/**
- * UfoResourceManagerClass:
- *
- * #UfoResourceManager class
- */
-struct _UfoResourceManagerClass {
- /*< private >*/
- GObjectClass parent_class;
-};
-
-UfoResourceManager *ufo_resource_manager_new (UfoConfiguration *config);
-gpointer ufo_resource_manager_get_kernel (UfoResourceManager *manager,
- const gchar *filename,
- const gchar *kernel_name,
- GError **error);
-gpointer ufo_resource_manager_get_kernel_from_source (UfoResourceManager *manager,
- const gchar *source,
- const gchar *kernel_name,
- GError **error);
-gpointer ufo_resource_manager_get_context (UfoResourceManager *manager);
-void ufo_resource_manager_get_command_queues (UfoResourceManager *manager,
- gpointer *cmd_queues,
- guint *num_queues);
-gint ufo_resource_manager_get_queue_number (UfoResourceManager *manager,
- gpointer cmd_queue);
-gpointer ufo_resource_manager_get_command_queue (UfoResourceManager *manager,
- guint queue);
-guint ufo_resource_manager_get_number_of_devices (UfoResourceManager *manager);
-gpointer ufo_resource_manager_memdup (UfoResourceManager *manager,
- gpointer memobj);
-gpointer ufo_resource_manager_memalloc (UfoResourceManager *manager,
- gsize size);
-UfoBuffer *ufo_resource_manager_request_buffer (UfoResourceManager *manager,
- guint num_dims,
- const guint *dim_size,
- gfloat *data,
- gpointer cmd_queue);
-GType ufo_resource_manager_get_type (void);
-GQuark ufo_resource_manager_error_quark (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ufo-resources.c b/src/ufo-resources.c
new file mode 100644
index 0000000..ea3ac0a
--- /dev/null
+++ b/src/ufo-resources.c
@@ -0,0 +1,665 @@
+/**
+ * SECTION:ufo-resources
+ * @Short_description: Manage OpenCL resources
+ * @Title: UfoResources
+ *
+ * The #UfoResources creates the OpenCL environment and loads OpenCL
+ * kernels from text files.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#ifdef __APPLE__
+#include <OpenCL/cl.h>
+#else
+#include <CL/cl.h>
+#endif
+
+#include "ufo-resources.h"
+#include "ufo-configurable.h"
+
+G_DEFINE_TYPE_WITH_CODE (UfoResources, ufo_resources, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_CONFIGURABLE, NULL))
+
+#define UFO_RESOURCES_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_RESOURCES, UfoResourcesPrivate))
+
+/**
+ * UfoResourcesError:
+ * @UFO_RESOURCES_ERROR_LOAD_PROGRAM: Could not load the OpenCL file
+ * @UFO_RESOURCES_ERROR_CREATE_PROGRAM: Could not create a program from
+ * the sources
+ * @UFO_RESOURCES_ERROR_BUILD_PROGRAM: Could not build program from
+ * sources
+ * @UFO_RESOURCES_ERROR_CREATE_KERNEL: Could not create kernel
+ *
+ * OpenCL related errors.
+ */
+GQuark
+ufo_resources_error_quark (void)
+{
+ return g_quark_from_static_string ("ufo-resource-resources-error-quark");
+}
+
+struct _UfoResourcesPrivate {
+ UfoConfig *config;
+
+ cl_uint num_platforms;
+ cl_platform_id *opencl_platforms;
+ cl_context opencl_context;
+ cl_uint *num_devices; /**< Number of OpenCL devices per platform id */
+ cl_device_id **opencl_devices; /**< Array of OpenCL devices per platform id */
+ cl_command_queue *command_queues; /**< Array of command queues per device */
+
+ GList *kernel_paths; /**< Colon-separated string with paths to kernel files */
+ GHashTable *opencl_programs; /**< Map from filename to cl_program */
+ GList *opencl_kernels;
+ GString *opencl_build_options;
+ GString *include_paths; /**< List of include paths "-I/foo/bar" built from added paths */
+};
+
+enum {
+ PROP_0,
+ PROP_CONFIG,
+ N_PROPERTIES
+};
+
+const gchar *opencl_error_msgs[] = {
+ "CL_SUCCESS",
+ "CL_DEVICE_NOT_FOUND",
+ "CL_DEVICE_NOT_AVAILABLE",
+ "CL_COMPILER_NOT_AVAILABLE",
+ "CL_MEM_OBJECT_ALLOCATION_FAILURE",
+ "CL_OUT_OF_RESOURCES",
+ "CL_OUT_OF_HOST_MEMORY",
+ "CL_PROFILING_INFO_NOT_AVAILABLE",
+ "CL_MEM_COPY_OVERLAP",
+ "CL_IMAGE_FORMAT_MISMATCH",
+ "CL_IMAGE_FORMAT_NOT_SUPPORTED",
+ "CL_BUILD_PROGRAM_FAILURE",
+ "CL_MAP_FAILURE",
+ "CL_MISALIGNED_SUB_BUFFER_OFFSET",
+ "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST",
+
+ /* next IDs start at 30! */
+ "CL_INVALID_VALUE",
+ "CL_INVALID_DEVICE_TYPE",
+ "CL_INVALID_PLATFORM",
+ "CL_INVALID_DEVICE",
+ "CL_INVALID_CONTEXT",
+ "CL_INVALID_QUEUE_PROPERTIES",
+ "CL_INVALID_COMMAND_QUEUE",
+ "CL_INVALID_HOST_PTR",
+ "CL_INVALID_MEM_OBJECT",
+ "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR",
+ "CL_INVALID_IMAGE_SIZE",
+ "CL_INVALID_SAMPLER",
+ "CL_INVALID_BINARY",
+ "CL_INVALID_BUILD_OPTIONS",
+ "CL_INVALID_PROGRAM",
+ "CL_INVALID_PROGRAM_EXECUTABLE",
+ "CL_INVALID_KERNEL_NAME",
+ "CL_INVALID_KERNEL_DEFINITION",
+ "CL_INVALID_KERNEL",
+ "CL_INVALID_ARG_INDEX",
+ "CL_INVALID_ARG_VALUE",
+ "CL_INVALID_ARG_SIZE",
+ "CL_INVALID_KERNEL_ARGS",
+ "CL_INVALID_WORK_DIMENSION",
+ "CL_INVALID_WORK_GROUP_SIZE",
+ "CL_INVALID_WORK_ITEM_SIZE",
+ "CL_INVALID_GLOBAL_OFFSET",
+ "CL_INVALID_EVENT_WAIT_LIST",
+ "CL_INVALID_EVENT",
+ "CL_INVALID_OPERATION",
+ "CL_INVALID_GL_OBJECT",
+ "CL_INVALID_BUFFER_SIZE",
+ "CL_INVALID_MIP_LEVEL",
+ "CL_INVALID_GLOBAL_WORK_SIZE"
+};
+
+const gchar *
+ufo_resources_clerr (int error)
+{
+ static const gchar *invalid = "Invalid error code";
+ const gint array_size = sizeof opencl_error_msgs/sizeof(gchar*);
+ gint index;
+
+ index = error >= -14 ? -error : -error-15;
+
+ if (index >= 0 && index < array_size)
+ return opencl_error_msgs[index];
+
+ return invalid;
+}
+
+static gchar *
+resources_load_opencl_program (const gchar *filename)
+{
+ FILE *fp = fopen (filename, "r");
+
+ if (fp == NULL)
+ return NULL;
+
+ fseek (fp, 0, SEEK_END);
+ const gsize length = (gsize) ftell (fp);
+ rewind (fp);
+ gchar *buffer = (gchar *) g_malloc0(length + 1);
+
+ if (buffer == NULL) {
+ fclose (fp);
+ return NULL;
+ }
+
+ size_t buffer_length = fread (buffer, 1, length, fp);
+ fclose (fp);
+
+ if (buffer_length != length) {
+ g_free (buffer);
+ return NULL;
+ }
+
+ return buffer;
+}
+
+static void
+resources_release_kernel (gpointer data, gpointer user_data)
+{
+ cl_kernel kernel = (cl_kernel) data;
+ UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (kernel));
+}
+
+static void
+resources_release_program (gpointer data)
+{
+ cl_program program = (cl_program) data;
+ UFO_RESOURCES_CHECK_CLERR (clReleaseProgram (program));
+}
+
+static gchar *
+resources_find_path (UfoResourcesPrivate *priv, const gchar *filename)
+{
+ /* Check first if filename is already a path */
+ if (g_path_is_absolute (filename)) {
+ if (g_file_test (filename, G_FILE_TEST_EXISTS))
+ return g_strdup (filename);
+ else
+ return NULL;
+ }
+
+ /* If it is not a path, search in all paths that were added */
+ GList *elem = g_list_first (priv->kernel_paths);
+
+ while (elem != NULL) {
+ gchar *path = g_strdup_printf ("%s%c%s", (gchar *) elem->data, G_DIR_SEPARATOR, filename);
+
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ return path;
+
+ g_free (path);
+ elem = g_list_next (elem);
+ }
+
+ return NULL;
+}
+
+/**
+ * ufo_resources_new:
+ * @config: A #UfoConfiguration object or %NULL
+ *
+ * Create a new #UfoResources instance.
+ *
+ * Returns: (transfer none): A new #UfoResources
+ */
+UfoResources *
+ufo_resources_new (UfoConfig *config)
+{
+ return UFO_RESOURCES (g_object_new (UFO_TYPE_RESOURCES,
+ "configuration", config,
+ NULL));
+}
+
+static void
+add_paths (UfoResourcesPrivate *priv, gchar *paths[])
+{
+ if (paths == NULL)
+ return;
+
+ for (guint i = 0; paths[i] != NULL; i++) {
+ priv->kernel_paths = g_list_append (priv->kernel_paths, g_strdup (paths[i]));
+ g_string_append_printf (priv->include_paths, "-I%s ", paths[i]);
+ }
+}
+
+static cl_program
+add_program_from_source (UfoResourcesPrivate *priv,
+ const gchar *source,
+ const gchar *options,
+ GError **error)
+{
+ cl_program program;
+ gchar *build_options = NULL;
+ cl_int errcode = CL_SUCCESS;
+
+ program = clCreateProgramWithSource (priv->opencl_context,
+ 1, &source, NULL, &errcode);
+
+ if (errcode != CL_SUCCESS) {
+ g_set_error (error,
+ UFO_RESOURCES_ERROR,
+ UFO_RESOURCES_ERROR_CREATE_PROGRAM,
+ "Failed to create OpenCL program: %s", ufo_resources_clerr (errcode));
+ return NULL;
+ }
+
+ if (options != NULL)
+ build_options = g_strdup_printf ("%s %s %s", priv->opencl_build_options->str, priv->include_paths->str, options);
+ else
+ build_options = g_strdup_printf ("%s %s", priv->opencl_build_options->str, priv->include_paths->str);
+
+ errcode = clBuildProgram (program,
+ priv->num_devices[0],
+ priv->opencl_devices[0],
+ build_options,
+ NULL, NULL);
+
+ g_free (build_options);
+
+ if (errcode != CL_SUCCESS) {
+ g_set_error (error,
+ UFO_RESOURCES_ERROR,
+ UFO_RESOURCES_ERROR_BUILD_PROGRAM,
+ "Failed to build OpenCL program: %s", ufo_resources_clerr (errcode));
+
+ const gsize LOG_SIZE = 4096;
+ gchar *log = (gchar *) g_malloc0(LOG_SIZE * sizeof (char));
+ UFO_RESOURCES_CHECK_CLERR (clGetProgramBuildInfo (program,
+ priv->opencl_devices[0][0],
+ CL_PROGRAM_BUILD_LOG,
+ LOG_SIZE, (void *) log, NULL));
+ g_print ("\n=== Build log for s===%s\n\n", log);
+ g_free (log);
+ return NULL;
+ }
+
+ return program;
+}
+
+static cl_program
+resources_add_program (UfoResources *resources, const gchar *filename, const gchar *options, GError **error)
+{
+ g_return_val_if_fail (UFO_IS_RESOURCES (resources) || (filename != NULL), FALSE);
+ UfoResourcesPrivate *priv = resources->priv;
+
+ /* Programs might be added multiple times if this is not locked */
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+ g_static_mutex_lock (&mutex);
+
+ /* Don't process the kernel file again, if already load */
+ cl_program program = g_hash_table_lookup (priv->opencl_programs, filename);
+
+ if (program != NULL) {
+ g_static_mutex_unlock (&mutex);
+ return program;
+ }
+
+ gchar *path = resources_find_path (priv, filename);
+
+ if (path == NULL) {
+ g_set_error (error,
+ UFO_RESOURCES_ERROR,
+ UFO_RESOURCES_ERROR_LOAD_PROGRAM,
+ "Could not find `%s'. Maybe you forgot to pass a configuration?", filename);
+ g_static_mutex_unlock (&mutex);
+ return NULL;
+ }
+
+ gchar *buffer = resources_load_opencl_program (path);
+ g_free (path);
+
+ if (buffer == NULL) {
+ g_set_error (error,
+ UFO_RESOURCES_ERROR,
+ UFO_RESOURCES_ERROR_LOAD_PROGRAM,
+ "Could not open `%s'", filename);
+ g_static_mutex_unlock (&mutex);
+ return NULL;
+ }
+
+ program = add_program_from_source (priv, buffer, options, error);
+ g_message ("Added program %p from `%s`", (gpointer) program, filename);
+
+ if (program != NULL)
+ g_hash_table_insert (priv->opencl_programs, g_strdup (filename), program);
+
+ g_static_mutex_unlock (&mutex);
+ g_free (buffer);
+ return program;
+}
+
+static cl_kernel
+resources_get_kernel (UfoResourcesPrivate *priv,
+ cl_program program,
+ const gchar *kernel_name,
+ GError **error)
+{
+ cl_int errcode = CL_SUCCESS;
+ cl_kernel kernel = clCreateKernel (program, kernel_name, &errcode);
+
+ if (kernel == NULL || errcode != CL_SUCCESS) {
+ g_set_error (error,
+ UFO_RESOURCES_ERROR,
+ UFO_RESOURCES_ERROR_CREATE_KERNEL,
+ "Failed to create kernel `%s`: %s", kernel_name, ufo_resources_clerr (errcode));
+ return NULL;
+ }
+
+ priv->opencl_kernels = g_list_append (priv->opencl_kernels, kernel);
+ UFO_RESOURCES_CHECK_CLERR (clRetainKernel (kernel));
+ return kernel;
+}
+
+/**
+ * ufo_resources_get_kernel:
+ * @resources: A #UfoResources object
+ * @filename: Name of the .cl kernel file
+ * @kernel: Name of a kernel
+ * @error: Return location for a GError from #UfoResourcesError, or NULL
+ *
+ * Loads a and builds a kernel from a file. The file is searched in the current
+ * working directory and all paths added through
+ * ufo_resources_add_paths ().
+ *
+ * Returns: a cl_kernel object that is load from @filename or %NULL on error
+ */
+gpointer
+ufo_resources_get_kernel (UfoResources *resources,
+ const gchar *filename,
+ const gchar *kernel,
+ GError **error)
+{
+ UfoResourcesPrivate *priv;
+ cl_program program;
+ GError *tmp_error = NULL;
+
+ g_return_val_if_fail (UFO_IS_RESOURCES (resources) &&
+ (filename != NULL) &&
+ (kernel != NULL), NULL);
+
+ priv = resources->priv;
+ program = resources_add_program (resources, filename, "", &tmp_error);
+
+ if (program == NULL) {
+ g_propagate_error (error, tmp_error);
+ return NULL;
+ }
+
+ return resources_get_kernel (priv, program, kernel, error);
+}
+
+/**
+ * ufo_resources_get_kernel_from_source: (skip)
+ * @resources: A #UfoResources
+ * @source: OpenCL source string
+ * @kernel_name: Name of a kernel
+ * @error: Return location for a GError from #UfoResourcesError, or NULL
+ *
+ * Loads and builds a kernel from a string.
+ *
+ * Returns: a cl_kernel object that is load from @filename
+ */
+gpointer
+ufo_resources_get_kernel_from_source (UfoResources *resources,
+ const gchar *source,
+ const gchar *kernel,
+ GError **error)
+{
+ UfoResourcesPrivate *priv;
+ cl_program program;
+
+ g_return_val_if_fail (UFO_IS_RESOURCES (resources) &&
+ (source != NULL) &&
+ (kernel != NULL), NULL);
+
+ priv = UFO_RESOURCES_GET_PRIVATE (resources);
+ program = add_program_from_source (priv, source, NULL, error);
+
+ /*
+ * We add the program under a fake file name. This looks very brittle to me
+ * (kernel name could be the same as a source filename) but it should work
+ * in most cases.
+ */
+ if (program != NULL)
+ g_hash_table_insert (priv->opencl_programs, g_strdup (kernel), program);
+ else
+ return NULL;
+
+ return resources_get_kernel (priv, program, kernel, error);
+}
+
+/**
+ * ufo_resources_get_context: (skip)
+ * @resources: A #UfoResources
+ *
+ * Returns the OpenCL context object that is used by the resource resources. This
+ * context can be used to initialize othe third-party libraries.
+ *
+ * Return value: A cl_context object.
+ */
+gpointer
+ufo_resources_get_context (UfoResources *resources)
+{
+ g_return_val_if_fail (UFO_IS_RESOURCES (resources), NULL);
+ return resources->priv->opencl_context;
+}
+
+/**
+ * ufo_resources_get_cmd_queues:
+ * @resources: A #UfoResources
+ *
+ * Returns: (element-type gpointer) (transfer container): List with
+ * cl_command_queue objects.
+ */
+GList *
+ufo_resources_get_cmd_queues (UfoResources *resources)
+{
+ UfoResourcesPrivate *priv;
+ GList *result = NULL;
+
+ g_return_val_if_fail (UFO_IS_RESOURCES (resources), NULL);
+ priv = resources->priv;
+
+ for (guint i = 0; i < priv->num_devices[0]; i++)
+ result = g_list_append (result, priv->command_queues[i]);
+
+ return result;
+}
+
+static void
+ufo_resources_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ UfoResourcesPrivate *priv = UFO_RESOURCES_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_CONFIG:
+ {
+ UfoConfig *config;
+ gchar **paths;
+ GObject *value_object = g_value_get_object (value);
+
+ if (priv->config)
+ g_object_unref (priv->config);
+
+
+ if (value_object != NULL) {
+ config = UFO_CONFIG (value_object);
+ paths = ufo_config_get_paths (config);
+ add_paths (priv, paths);
+ g_strfreev (paths);
+ g_object_ref (config);
+ priv->config = config;
+ }
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_resources_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ UfoResourcesPrivate *priv = UFO_RESOURCES_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_CONFIG:
+ g_value_set_object (value, priv->config);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_resources_dispose (GObject *object)
+{
+ UfoResourcesPrivate *priv = UFO_RESOURCES_GET_PRIVATE (object);
+
+ if (priv->config) {
+ g_object_unref (priv->config);
+ priv->config = NULL;
+ }
+
+ G_OBJECT_CLASS (ufo_resources_parent_class)->finalize (object);
+}
+
+static void
+ufo_resources_finalize (GObject *object)
+{
+ UfoResourcesPrivate *priv = UFO_RESOURCES_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->opencl_programs);
+ g_list_foreach (priv->kernel_paths, (GFunc) g_free, NULL);
+ g_list_free (priv->kernel_paths);
+ g_list_foreach (priv->opencl_kernels, resources_release_kernel, NULL);
+ g_list_free (priv->opencl_kernels);
+
+ for (guint i = 0; i < priv->num_devices[0]; i++)
+ UFO_RESOURCES_CHECK_CLERR (clReleaseCommandQueue (priv->command_queues[i]));
+
+ UFO_RESOURCES_CHECK_CLERR (clReleaseContext (priv->opencl_context));
+
+ g_string_free (priv->opencl_build_options, TRUE);
+ g_string_free (priv->include_paths, TRUE);
+
+ for (guint i = 0; i < priv->num_platforms; i ++)
+ g_free (priv->opencl_devices[i]);
+
+ g_free (priv->num_devices);
+ g_free (priv->opencl_devices);
+ g_free (priv->opencl_platforms);
+ g_free (priv->command_queues);
+
+ priv->num_devices = NULL;
+ priv->opencl_kernels = NULL;
+ priv->opencl_devices = NULL;
+ priv->opencl_platforms = NULL;
+
+ G_OBJECT_CLASS (ufo_resources_parent_class)->finalize (object);
+ g_message ("UfoResources: finalized");
+}
+
+static void
+ufo_resources_class_init (UfoResourcesClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->set_property = ufo_resources_set_property;
+ gobject_class->get_property = ufo_resources_get_property;
+ gobject_class->dispose = ufo_resources_dispose;
+ gobject_class->finalize = ufo_resources_finalize;
+
+ g_object_class_override_property (gobject_class, PROP_CONFIG, "config");
+
+ g_type_class_add_private (klass, sizeof (UfoResourcesPrivate));
+}
+
+static void
+ufo_resources_init (UfoResources *self)
+{
+ UfoResourcesPrivate *priv;
+ self->priv = priv = UFO_RESOURCES_GET_PRIVATE (self);
+
+ priv->config = NULL;
+ priv->opencl_programs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, resources_release_program);
+ priv->kernel_paths = g_list_append (NULL, g_strdup ("."));
+ priv->opencl_kernels = NULL;
+ priv->opencl_platforms = NULL;
+ priv->opencl_build_options = g_string_new ("-cl-mad-enable ");
+ priv->include_paths = g_string_new ("-I. ");
+
+ /* initialize OpenCL subsystem */
+ int errcode = CL_SUCCESS;
+ UFO_RESOURCES_CHECK_CLERR (clGetPlatformIDs (0, NULL, &priv->num_platforms));
+ priv->opencl_platforms = g_malloc0(priv->num_platforms * sizeof (cl_platform_id));
+
+ UFO_RESOURCES_CHECK_CLERR (clGetPlatformIDs (priv->num_platforms, priv->opencl_platforms, NULL));
+ priv->num_devices = g_malloc0(priv->num_platforms * sizeof (cl_uint));
+ priv->opencl_devices = g_malloc0(priv->num_platforms * sizeof (cl_device_id *));
+
+ /* Get devices for each available platform */
+ gchar *info_buffer = g_malloc0 (256);
+
+ for (guint i = 0; i < priv->num_platforms; i++) {
+ cl_uint num_devices;
+ cl_platform_id platform = priv->opencl_platforms[i];
+
+ UFO_RESOURCES_CHECK_CLERR (clGetPlatformInfo (platform, CL_PLATFORM_VENDOR, 256, info_buffer, NULL));
+
+ if (g_str_has_prefix (info_buffer, "NVIDIA"))
+ g_string_append (priv->opencl_build_options, "-cl-nv-verbose -DVENDOR=NVIDIA");
+ else if (g_str_has_prefix (info_buffer, "Advanced Micro Devices"))
+ g_string_append (priv->opencl_build_options, "-DVENDOR=AMD");
+
+ UFO_RESOURCES_CHECK_CLERR (clGetDeviceIDs (platform,
+ CL_DEVICE_TYPE_ALL,
+ 0, NULL,
+ &num_devices));
+ priv->opencl_devices[i] = g_malloc0 (num_devices * sizeof (cl_device_id));
+
+ UFO_RESOURCES_CHECK_CLERR (clGetDeviceIDs (platform,
+ CL_DEVICE_TYPE_ALL,
+ num_devices, priv->opencl_devices[i],
+ NULL));
+ priv->num_devices[i] = num_devices;
+ }
+
+ g_free (info_buffer);
+ cl_command_queue_properties queue_properties = CL_QUEUE_PROFILING_ENABLE;
+
+ /* XXX: create context for each platform?! */
+ if (priv->num_platforms > 0) {
+ priv->opencl_context = clCreateContext (NULL,
+ priv->num_devices[0],
+ priv->opencl_devices[0],
+ NULL, NULL, &errcode);
+ UFO_RESOURCES_CHECK_CLERR (errcode);
+ priv->command_queues = g_malloc0 (priv->num_devices[0] * sizeof (cl_command_queue));
+
+ for (guint i = 0; i < priv->num_devices[0]; i++) {
+ priv->command_queues[i] = clCreateCommandQueue (priv->opencl_context,
+ priv->opencl_devices[0][i],
+ queue_properties, &errcode);
+ UFO_RESOURCES_CHECK_CLERR (errcode);
+ }
+ }
+}
diff --git a/src/ufo-resources.h b/src/ufo-resources.h
new file mode 100644
index 0000000..0744434
--- /dev/null
+++ b/src/ufo-resources.h
@@ -0,0 +1,84 @@
+#ifndef __UFO_RESOURCES_H
+#define __UFO_RESOURCES_H
+
+#include <glib-object.h>
+#include "ufo-config.h"
+#include "ufo-buffer.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_RESOURCES (ufo_resources_get_type())
+#define UFO_RESOURCES(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_RESOURCES, UfoResources))
+#define UFO_IS_RESOURCES(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_RESOURCES))
+#define UFO_RESOURCES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_RESOURCES, UfoResourcesClass))
+#define UFO_IS_RESOURCES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_RESOURCES))
+#define UFO_RESOURCES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_RESOURCES, UfoResourcesClass))
+
+typedef struct _UfoResources UfoResources;
+typedef struct _UfoResourcesClass UfoResourcesClass;
+typedef struct _UfoResourcesPrivate UfoResourcesPrivate;
+
+#define UFO_RESOURCES_ERROR ufo_resources_error_quark()
+typedef enum {
+ UFO_RESOURCES_ERROR_LOAD_PROGRAM,
+ UFO_RESOURCES_ERROR_CREATE_PROGRAM,
+ UFO_RESOURCES_ERROR_BUILD_PROGRAM,
+ UFO_RESOURCES_ERROR_CREATE_KERNEL
+} UfoResourcesError;
+
+
+/**
+ * opencl_map_error: (skip)
+ */
+
+/**
+ * UFO_RESOURCES_CHECK_CLERR:
+ * @error: OpenCL error code
+ *
+ * Check the return value of OpenCL functions and issue a warning with file and
+ * line number if an error occured.
+ */
+#define UFO_RESOURCES_CHECK_CLERR(error) { \
+ if ((error) != CL_SUCCESS) g_log("ocl", G_LOG_LEVEL_CRITICAL, "Error <%s:%i>: %s", __FILE__, __LINE__, ufo_resources_clerr((error))); }
+
+/**
+ * UfoResources:
+ *
+ * Manages OpenCL resources. The contents of the #UfoResources structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoResources {
+ /*< private >*/
+ GObject parent_instance;
+
+ UfoResourcesPrivate *priv;
+};
+
+/**
+ * UfoResourcesClass:
+ *
+ * #UfoResources class
+ */
+struct _UfoResourcesClass {
+ /*< private >*/
+ GObjectClass parent_class;
+};
+
+UfoResources * ufo_resources_new (UfoConfig *config);
+gpointer ufo_resources_get_kernel (UfoResources *resources,
+ const gchar *filename,
+ const gchar *kernel,
+ GError **error);
+gpointer ufo_resources_get_kernel_from_source (UfoResources *resources,
+ const gchar *source,
+ const gchar *kernel,
+ GError **error);
+gpointer ufo_resources_get_context (UfoResources *resources);
+GList * ufo_resources_get_cmd_queues (UfoResources *resources);
+const gchar * ufo_resources_clerr (int error);
+GType ufo_resources_get_type (void);
+GQuark ufo_resources_error_quark (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-scheduler.c b/src/ufo-scheduler.c
index eeb98b5..2edfd0b 100644
--- a/src/ufo-scheduler.c
+++ b/src/ufo-scheduler.c
@@ -15,803 +15,244 @@
#include <stdio.h>
#include <string.h>
-#include "config.h"
-#include "ufo-aux.h"
#include "ufo-scheduler.h"
-#include "ufo-configurable.h"
-#include "ufo-filter.h"
-#include "ufo-filter-source.h"
-#include "ufo-filter-sink.h"
-#include "ufo-filter-reduce.h"
-#include "ufo-filter-repeater.h"
-#include "ufo-filter-splitter.h"
+#include "ufo-buffer.h"
+#include "ufo-task-node.h"
+#include "ufo-task-iface.h"
+#include "ufo-cpu-task-iface.h"
+#include "ufo-gpu-task-iface.h"
-G_DEFINE_TYPE_WITH_CODE (UfoScheduler, ufo_scheduler, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (UFO_TYPE_CONFIGURABLE, NULL))
+G_DEFINE_TYPE (UfoScheduler, ufo_scheduler, G_TYPE_OBJECT)
#define UFO_SCHEDULER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_SCHEDULER, UfoSchedulerPrivate))
typedef struct {
- UfoFilter *filter;
- UfoProfiler *profiler;
- guint num_inputs;
- guint num_outputs;
- UfoInputParameter *input_params;
- UfoOutputParameter *output_params;
- guint **output_dims;
- UfoBuffer **work;
- UfoBuffer **result;
- guint num_children;
- GError *error;
- GAsyncQueue *return_queue;
-} ThreadInfo;
+ UfoTask *task;
+ guint n_inputs;
+ UfoInputParameter
+ *in_params;
+} ThreadLocalData;
struct _UfoSchedulerPrivate {
- UfoConfiguration *config;
- UfoResourceManager *manager;
- GAsyncQueue *return_queue;
+ guint foo;
};
enum {
PROP_0,
- PROP_CONFIG,
- PROP_RESOURCE_MANAGER,
N_PROPERTIES
};
-static GParamSpec *scheduler_properties[N_PROPERTIES] = { NULL, };
-
-static gpointer NO_ERROR = GINT_TO_POINTER (1);
-
/**
* ufo_scheduler_new:
- * @config: (allow-none): A #UfoConfiguration or %NULL
- * @manager: (allow-none): A #UfoResourceManager or %NULL
*
* Creates a new #UfoScheduler.
*
* Return value: A new #UfoScheduler
*/
UfoScheduler *
-ufo_scheduler_new (UfoConfiguration *config,
- UfoResourceManager *manager)
+ufo_scheduler_new (void)
{
- UfoScheduler *scheduler;
-
- scheduler = UFO_SCHEDULER (g_object_new (UFO_TYPE_SCHEDULER,
- "configuration", config,
- "resource-manager", manager,
- NULL));
-
- return scheduler;
+ return UFO_SCHEDULER (g_object_new (UFO_TYPE_SCHEDULER, NULL));
}
-static void
-alloc_output_buffers (ThreadInfo *info,
- gboolean use_default_value,
- gfloat default_value)
+static gpointer
+run_task (ThreadLocalData *tld)
{
- UfoFilter *filter;
- UfoOutputParameter *output_params;
- UfoResourceManager *manager;
- guint num_outputs;
- guint num_buffers;
-
- filter = info->filter;
- output_params = ufo_filter_get_output_parameters (filter);
- manager = ufo_filter_get_resource_manager (filter);
- num_outputs = ufo_filter_get_num_outputs (filter);
- num_buffers = 2 * info->num_children * num_outputs;
-
- for (guint port = 0; port < num_outputs; port++) {
- UfoChannel *channel;
- guint num_dims;
-
- num_dims = output_params[port].n_dims;
- channel = ufo_filter_get_output_channel (filter, port);
-
- for (guint i = 0; i < num_buffers; i++) {
- UfoBuffer *buffer;
-
- buffer = ufo_resource_manager_request_buffer (manager, num_dims, info->output_dims[port], NULL, NULL);
-
- /*
- * For some reason, if we don't reference the buffer again,
- * it is returned by ufo_buffer_new() for other filters as
- * well, thus sharing the buffer which is not what we want.
- *
- * TODO: remove the reference in a meaningful way, or find
- * out what the problem is.
- */
- g_object_ref (buffer);
-
- if (use_default_value)
- ufo_buffer_fill_with_value (buffer, default_value);
-
- ufo_channel_insert (channel, buffer);
+ UfoBuffer *inputs[tld->n_inputs];
+ UfoBuffer *output;
+ UfoTaskNode *node;
+ UfoRequisition requisition;
+ gboolean active;
+
+ node = UFO_TASK_NODE (tld->task);
+ active = TRUE;
+ output = NULL;
+
+ while (active) {
+ /* Get input buffers */
+ for (guint i = 0; i < tld->n_inputs; i++) {
+ UfoGroup *group = ufo_task_node_get_current_in_group (node, i);
+
+ inputs[i] = ufo_group_pop_input_buffer (group, tld->task);
+
+ if (inputs[i] == UFO_END_OF_STREAM) {
+ active = FALSE;
+ break;
+ }
}
- }
-}
-static gboolean
-expected_number_of_items_fetched (UfoInputParameter *param)
-{
- return param->n_expected_items != UFO_FILTER_INFINITE_INPUT &&
- param->n_fetched_items >= param->n_expected_items;
-}
-
-static void
-cleanup_fetched (ThreadInfo *info)
-{
- for (guint port = 0; port < info->num_inputs; port++) {
- if (expected_number_of_items_fetched (&info->input_params[port])) {
- UfoChannel *channel = ufo_filter_get_input_channel (info->filter, port);
- ufo_channel_release_input (channel, info->work[port]);
+ if (!active) {
+ ufo_group_finish (ufo_task_node_get_out_group (node));
+ break;
}
- }
-}
-
-static gboolean
-fetch_work (ThreadInfo *info)
-{
- const gpointer POISON_PILL = GINT_TO_POINTER (1);
- gboolean success = TRUE;
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_FETCH);
+ /* Get output buffers */
+ ufo_task_get_requisition (tld->task, inputs, &requisition);
- for (guint port = 0; port < info->num_inputs; port++) {
- UfoChannel *channel = ufo_filter_get_input_channel (info->filter, port);
+ if (requisition.n_dims > 0) {
+ UfoGroup *group;
- if (!expected_number_of_items_fetched (&info->input_params[port])) {
- info->work[port] = ufo_channel_fetch_input (channel);
- info->input_params[port].n_fetched_items++;
+ group = ufo_task_node_get_out_group (node);
+ output = ufo_group_pop_output_buffer (group, &requisition);
+ g_assert (output != NULL);
}
- if (info->work[port] == POISON_PILL) {
- ufo_channel_finish_next (channel);
- success = FALSE;
- }
- }
-
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_FETCH);
- return success;
-}
-
-static void
-push_work (ThreadInfo *info)
-{
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_RELEASE);
+ /* Process */
+ if (UFO_IS_CPU_TASK (tld->task)) {
+ if (output != NULL)
+ ufo_buffer_discard_location (output, UFO_LOCATION_DEVICE);
- for (guint port = 0; port < info->num_inputs; port++) {
- if (!expected_number_of_items_fetched (&info->input_params[port])) {
- UfoChannel *channel = ufo_filter_get_input_channel (info->filter, port);
- ufo_channel_release_input (channel, info->work[port]);
+ active = ufo_cpu_task_process (UFO_CPU_TASK (tld->task), inputs, output, &requisition);
}
- }
-
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_RELEASE);
-}
-
-static void
-fetch_result (ThreadInfo *info)
-{
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_FETCH);
-
- for (guint port = 0; port < info->num_outputs; port++) {
- UfoChannel *channel = ufo_filter_get_output_channel (info->filter, port);
- info->result[port] = ufo_channel_fetch_output (channel);
- }
-
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_FETCH);
-}
-
-static void
-push_result (ThreadInfo *info)
-{
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_RELEASE);
-
- for (guint port = 0; port < info->num_outputs; port++) {
- UfoChannel *channel = ufo_filter_get_output_channel (info->filter, port);
- ufo_channel_release_output (channel, info->result[port]);
- }
-
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_RELEASE);
-}
-
-static GError *
-process_source_filter (ThreadInfo *info)
-{
- UfoFilter *filter = UFO_FILTER (info->filter);
- GError *error = NULL;
- gboolean cont = TRUE;
-
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- ufo_filter_source_initialize (UFO_FILTER_SOURCE (filter), info->output_dims, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
-
- alloc_output_buffers (info, FALSE, 0.0);
-
- while (cont) {
- fetch_result (info);
-
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- cont = ufo_filter_source_generate (UFO_FILTER_SOURCE (filter), info->result, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
-
- if (cont)
- push_result (info);
- }
-
- return NULL;
-}
-
-static GError *
-process_synchronous_filter (ThreadInfo *info)
-{
- UfoFilter *filter = UFO_FILTER (info->filter);
- UfoFilterClass *filter_class = UFO_FILTER_GET_CLASS (filter);
- GError *error = NULL;
- gboolean cont = TRUE;
- guint iteration = 0;
-
- /*
- * Initialize
- */
- if (fetch_work (info)) {
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- ufo_filter_initialize (filter, info->work, info->output_dims, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL) {
- g_error ("%s", error->message);
- return error;
+ else if (UFO_IS_GPU_TASK (tld->task)) {
+ if (output != NULL)
+ ufo_buffer_discard_location (output, UFO_LOCATION_HOST);
+
+ active = ufo_gpu_task_process (UFO_GPU_TASK (tld->task),
+ inputs, output,
+ &requisition,
+ UFO_GPU_NODE (ufo_task_node_get_proc_node (node)));
}
- alloc_output_buffers (info, FALSE, 0.0);
- }
- else {
- return NULL;
- }
-
- fetch_result (info);
-
- while (cont) {
- g_message ("%-25s processing % 5i",
- ufo_filter_get_unique_name (filter),
- iteration++);
-
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (filter_class->process_gpu != NULL)
- ufo_filter_process_gpu (filter, info->work, info->result, &error);
- else
- ufo_filter_process_cpu (filter, info->work, info->result, &error);
-
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
-
- push_work (info);
- push_result (info);
-
- fetch_result (info);
- cont = fetch_work (info);
- }
-
- /*
- * In case this buffer keeps some of its inputs (if n_expected_items <
- * UFO_FILTER_INPUT_INFINITE), then we need to return those buffers to the
- * preceding filter. Otherwise we get stuck.
- */
- cleanup_fetched (info);
-
- return NULL;
-}
-
-static GError *
-process_sink_filter (ThreadInfo *info)
-{
- UfoFilter *filter = UFO_FILTER (info->filter);
- UfoFilterSink *sink_filter = UFO_FILTER_SINK (filter);
- GError *error = NULL;
- gboolean cont = TRUE;
-
- if (fetch_work (info)) {
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- ufo_filter_sink_initialize (sink_filter, info->work, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
- }
- else
- return NULL;
-
- while (cont) {
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- ufo_filter_sink_consume (sink_filter, info->work, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
-
- push_work (info);
- cont = fetch_work (info);
- }
-
- return NULL;
-}
-
-static GError *
-process_reduce_filter (ThreadInfo *info)
-{
- UfoFilter *filter = UFO_FILTER (info->filter);
- GError *error = NULL;
- gboolean cont;
- gfloat default_value = 0.0f;
-
- if (fetch_work (info)) {
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- ufo_filter_reduce_initialize (UFO_FILTER_REDUCE (filter), info->work, info->output_dims, &default_value, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
-
- alloc_output_buffers (info, TRUE, default_value);
- }
- else {
- return NULL;
- }
-
- /*
- * Fetch the first result buffers and initialize them with the requested
- * default value. These buffer will be used throughout the collection phase.
- */
- fetch_result (info);
-
- for (guint i = 0; i < info->num_outputs; i++)
- ufo_buffer_fill_with_value (info->result[i], default_value);
-
- /*
- * Collect until no more data is available for consumption. The filter is
- * given the same result buffers, so that results can be accumulated.
- */
- cont = TRUE;
-
- while (cont) {
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- ufo_filter_reduce_collect (UFO_FILTER_REDUCE (filter), info->work, info->result, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
-
- push_work (info);
- cont = fetch_work (info);
- }
-
- /*
- * Calculate reduction results until the filter finishes.
- */
- cont = TRUE;
-
- while (cont) {
- ufo_profiler_start (info->profiler, UFO_PROFILER_TIMER_CPU);
- cont = ufo_filter_reduce_reduce (UFO_FILTER_REDUCE (filter), info->result, &error);
- ufo_profiler_stop (info->profiler, UFO_PROFILER_TIMER_CPU);
-
- if (error != NULL)
- return error;
-
- if (cont) {
- push_result (info);
- fetch_result (info);
+ /* Release buffers for further consumption */
+ for (guint i = 0; i < tld->n_inputs; i++) {
+ UfoGroup *group = ufo_task_node_get_current_in_group (node, i);
+ ufo_group_push_input_buffer (group, tld->task, inputs[i]);
+ ufo_task_node_switch_in_group (node, i);
}
- }
-
- return error;
-}
-
-static GError *
-process_splitter_filter (ThreadInfo *info)
-{
- GValueArray *counts;
- UfoChannel *channel;
- gint max_count;
- gint count;
- guint output;
- gboolean cont;
-
- g_object_get (info->filter, "counts", &counts, NULL);
-
- if (counts == NULL) {
- GError *error;
- g_set_error (&error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_INSUFFICIENTINPUTS,
- "`splitter's \"counts\" property must be set");
- return error;
- }
-
- cont = fetch_work (info);
- count = 0;
- output = 0;
- max_count = g_value_get_int (g_value_array_get_nth (counts, output));
+ if (requisition.n_dims > 0) {
+ UfoGroup *group = ufo_task_node_get_out_group (node);
- while (cont) {
- if ((max_count >= 0) && (count == max_count) && (output < counts->n_values - 1)) {
- output++;
- count = 0;
- max_count = g_value_get_int (g_value_array_get_nth (counts, output));
+ if (active)
+ ufo_group_push_output_buffer (group, output);
+ else
+ ufo_group_finish (group);
}
-
- channel = ufo_filter_get_output_channel (info->filter, output);
- ufo_channel_release_output (channel, info->work[0]);
- ufo_channel_fetch_output (channel);
- push_work (info);
-
- count++;
- cont = fetch_work (info);
}
return NULL;
}
-static GError *
-process_repeater_filter (ThreadInfo *info)
-{
- UfoChannel *channel;
- gboolean cont;
- guint count;
-
- g_object_get (G_OBJECT (info->filter), "count", &count, NULL);
-
- channel = ufo_filter_get_output_channel (info->filter, 0);
- cont = fetch_work (info);
-
- if (!cont) {
- g_warning ("`%s': didn't receive work\n", ufo_filter_get_unique_name (info->filter));
- return NULL;
- }
-
- for (guint i = 0; i < count; i++) {
- ufo_channel_release_output (channel, info->work[0]);
- ufo_channel_fetch_output (channel);
- }
-
- push_work (info);
-
- return NULL;
-}
-
-static gpointer
-process_thread (gpointer data)
-{
- ThreadInfo *info = (ThreadInfo *) data;
- UfoFilter *filter = info->filter;
- GError *error = NULL;
-
- g_assert (ufo_filter_get_command_queue (filter) != NULL);
-
- UfoOutputParameter *output_params = ufo_filter_get_output_parameters (filter);
-
- info->num_inputs = ufo_filter_get_num_inputs (filter);
- info->num_outputs = ufo_filter_get_num_outputs (filter);
- info->input_params = ufo_filter_get_input_parameters (filter);
- info->output_params = ufo_filter_get_output_parameters (filter);
- info->work = g_malloc (info->num_inputs * sizeof (UfoBuffer *));
- info->result = g_malloc (info->num_outputs * sizeof (UfoBuffer *));
- info->output_dims = g_malloc0(info->num_outputs * sizeof (guint *));
-
- for (guint i = 0; i < info->num_inputs; i++)
- info->input_params[i].n_fetched_items = 0;
-
- for (guint i = 0; i < info->num_outputs; i++)
- info->output_dims[i] = g_malloc0 (output_params[i].n_dims * sizeof(guint));
-
- if (UFO_IS_FILTER_SOURCE (filter))
- error = process_source_filter (info);
- else if (UFO_IS_FILTER_SINK (filter))
- error = process_sink_filter (info);
- else if (UFO_IS_FILTER_REDUCE (filter))
- error = process_reduce_filter (info);
- else if (UFO_IS_FILTER_SPLITTER (filter))
- error = process_splitter_filter (info);
- else if (UFO_IS_FILTER_REPEATER (filter))
- error = process_repeater_filter (info);
- else
- error = process_synchronous_filter (info);
-
- g_async_queue_ref (info->return_queue);
-
- if (error != NULL) {
- GError *prefixed;
-
- g_propagate_prefixed_error (&prefixed, error, "%s: ", ufo_filter_get_plugin_name (info->filter));
- g_async_queue_push (info->return_queue, prefixed);
- }
- else
- g_async_queue_push (info->return_queue, NO_ERROR);
-
- g_async_queue_unref (info->return_queue);
-
- for (guint port = 0; port < info->num_outputs; port++) {
- UfoChannel *channel = ufo_filter_get_output_channel (info->filter, port);
-
- if (channel != NULL)
- ufo_channel_finish (channel);
- }
-
- g_message ("UfoScheduler: %s finished", ufo_filter_get_unique_name (filter));
-
- g_free (info->output_dims);
- g_free (info->work);
- g_free (info->result);
- g_free (info);
-
- return NULL;
-}
-
-static void
-print_row (const gchar *row, FILE *fp)
-{
- fprintf (fp, "%s\n", row);
-}
-
-static void
-pass_queue (UfoGraph *graph, UfoFilter *filter, guint queue, guint n_queues, cl_command_queue *queues)
-{
- GList *children;
- guint i = queue;
-
- children = ufo_graph_get_children (graph, filter);
-
- for (GList *it = g_list_first (children); it != NULL; it = g_list_next (it), i++) {
- UfoFilter *successor;
- guint new_queue;
-
- successor = UFO_FILTER (it->data);
- new_queue = i % n_queues;
- ufo_filter_set_command_queue (successor, queues[new_queue]);
- pass_queue (graph, successor, new_queue, n_queues, queues);
- }
-}
-
-static void
-init_filter_queues (UfoSchedulerPrivate *priv,
- UfoGraph *graph)
-{
- cl_command_queue *queues;
- GList *roots;
- guint n_queues;
- guint i = 0;
-
- ufo_resource_manager_get_command_queues (priv->manager, (gpointer *) &queues, &n_queues);
-
- roots = ufo_graph_get_roots (graph);
-
- for (GList *it = g_list_first (roots); it != NULL; it = g_list_next (it), i++) {
- UfoFilter *root;
- guint queue;
-
- root = UFO_FILTER (it->data);
- queue = i % n_queues;
- ufo_filter_set_command_queue (root, queues[queue]);
- pass_queue (graph, root, queue, n_queues, queues);
- }
-
- g_list_free (roots);
-}
-
-static GThread *
-start_filter_thread (UfoSchedulerPrivate *priv,
- UfoFilter *filter,
- UfoGraph *graph,
- GError **error)
-{
- UfoProfilerLevel profile_level;
- GList *children;
- ThreadInfo *info;
-
- g_object_get (G_OBJECT (priv->config),
- "profile-level", &profile_level,
- NULL);
-
- info = g_new0 (ThreadInfo, 1);
- info->filter = filter;
-
- info->return_queue = priv->return_queue;
- info->profiler = ufo_profiler_new (profile_level);
- ufo_filter_set_profiler (filter, info->profiler);
- ufo_filter_set_resource_manager (filter, priv->manager);
-
- children = ufo_graph_get_children (graph, filter);
- info->num_children = g_list_length (children);
- g_list_free (children);
-
- return g_thread_create (process_thread, info, TRUE, error);
-}
-
-static FILE *
-open_prefixed_file (const gchar *prefix, const gchar *suffix)
-{
- gchar *filename;
- FILE *fp;
-
- filename = g_strdup_printf ("%s.%s", prefix, suffix);
- fp = fopen (filename, "w");
- g_free (filename);
- return fp;
-}
-
-static void
-print_profile_information (UfoSchedulerPrivate *priv, UfoGraph *graph)
+void
+ufo_scheduler_run (UfoScheduler *scheduler,
+ UfoArchGraph *arch_graph,
+ UfoTaskGraph *task_graph,
+ GError **error)
{
- GList *filters;
- UfoProfilerLevel profile_level;
- gchar *profile_prefix;
- FILE *opencl_fp = stdout;
- FILE *io_fp = stdout;
- FILE *sync_fp = stdout;
- FILE *cpu_fp = stdout;
-
- g_object_get (G_OBJECT (priv->config),
- "profile-level", &profile_level,
- "profile-output-prefix", &profile_prefix,
- NULL);
-
- if (profile_prefix != NULL) {
- if (profile_level & UFO_PROFILER_LEVEL_OPENCL)
- opencl_fp = open_prefixed_file (profile_prefix, "cl.stat");
-
- if (profile_level & UFO_PROFILER_LEVEL_IO)
- io_fp = open_prefixed_file (profile_prefix, "io.stat");
-
- if (profile_level & UFO_PROFILER_LEVEL_SYNC)
- sync_fp = open_prefixed_file (profile_prefix, "sync.stat");
-
- if (profile_level & UFO_PROFILER_LEVEL_CPU)
- cpu_fp = open_prefixed_file (profile_prefix, "cpu.stat");
- }
-
- filters = ufo_graph_get_filters (graph);
+ GList *nodes;
+ guint n_nodes;
+ GThread **threads;
+ ThreadLocalData **tlds;
+ GTimer *timer;
+ gpointer context;
- for (GList *it = filters; it != NULL; it = g_list_next (it)) {
- UfoProfiler *profiler;
- UfoFilter *filter;
-
- filter = (UfoFilter *) it->data;
- profiler = ufo_filter_get_profiler (filter);
+ g_return_if_fail (UFO_IS_SCHEDULER (scheduler));
- if (profile_level & UFO_PROFILER_LEVEL_OPENCL)
- ufo_profiler_foreach (profiler, (UfoProfilerFunc) print_row, opencl_fp);
+ ufo_task_graph_split (task_graph, arch_graph);
+ ufo_task_graph_map (task_graph, arch_graph);
- if (profile_level & UFO_PROFILER_LEVEL_IO)
- fprintf (io_fp, "%-16s %f\n",
- ufo_filter_get_plugin_name (filter),
- ufo_profiler_elapsed (profiler, UFO_PROFILER_TIMER_IO));
+ timer = g_timer_new ();
+ context = ufo_arch_graph_get_context (arch_graph);
+ n_nodes = ufo_graph_get_num_nodes (UFO_GRAPH (task_graph));
+ nodes = ufo_graph_get_nodes (UFO_GRAPH (task_graph));
+ threads = g_new0 (GThread *, n_nodes);
+ tlds = g_new0 (ThreadLocalData *, n_nodes);
- if (profile_level & UFO_PROFILER_LEVEL_SYNC)
- fprintf (sync_fp, "%-16s %f %f\n",
- ufo_filter_get_plugin_name (filter),
- ufo_profiler_elapsed (profiler, UFO_PROFILER_TIMER_FETCH),
- ufo_profiler_elapsed (profiler, UFO_PROFILER_TIMER_RELEASE));
+ if (error && (*error != NULL))
+ return;
- if (profile_level & UFO_PROFILER_LEVEL_CPU)
- fprintf (cpu_fp, "%-16s %f\n",
- ufo_filter_get_plugin_name (filter),
- ufo_profiler_elapsed (profiler, UFO_PROFILER_TIMER_CPU));
+ for (guint i = 0; i < n_nodes; i++) {
+ UfoNode *node;
+ UfoGroup *group;
+ ThreadLocalData *tld;
- g_object_unref (profiler);
- }
-}
+ node = g_list_nth_data (nodes, i);
-static GError *
-spawn_threads (UfoSchedulerPrivate *priv, UfoGraph *graph)
-{
- GList *filters;
- GList *threads = NULL;
- GError *error = NULL;
+ /* Setup thread data */
+ tld = g_new0 (ThreadLocalData, 1);
+ tld->task = UFO_TASK (node);
+ tlds[i] = tld;
- filters = ufo_graph_get_filters (graph);
+ ufo_task_setup (UFO_TASK (node), error);
+ ufo_task_get_structure (UFO_TASK (node),
+ &tld->n_inputs,
+ &tld->in_params);
- /* Start each filter in its own thread */
- for (GList *it = filters; it != NULL; it = g_list_next (it)) {
- UfoFilter *filter;
- GThread *thread;
+ group = ufo_group_new (ufo_graph_get_successors (UFO_GRAPH (task_graph), node),
+ context);
- filter = (UfoFilter *) it->data;
- thread = start_filter_thread (priv, filter, graph, &error);
+ ufo_task_node_set_out_group (UFO_TASK_NODE (node), group);
- if (error != NULL)
- return error;
+ /* TODO: cleanup */
+ if (error && *error != NULL)
+ return;
- threads = g_list_append (threads, thread);
+ g_object_set_data (G_OBJECT (node), "thread-local-data", tld);
}
- g_list_free (filters);
- g_list_free (threads);
-
- return NULL;
-}
+ /* Connect group references */
+ for (guint i = 0; i < n_nodes; i++) {
+ UfoNode *node;
+ UfoGroup *group;
+ GList *successors;
-static GError *
-join_threads (UfoSchedulerPrivate *priv, UfoGraph *graph)
-{
- guint n_threads;
- guint n_finished;
+ node = g_list_nth_data (nodes, i);
+ group = ufo_task_node_get_out_group (UFO_TASK_NODE (node));
+ successors = ufo_graph_get_successors (UFO_GRAPH (task_graph), node);
- n_threads = ufo_graph_get_num_filters (graph);
+ for (GList *it = g_list_first (successors); it != NULL; it = g_list_next (it)) {
+ UfoNode *target;
+ UfoTaskGraphConnection *conn;
- for (n_finished = 0; n_finished < n_threads; n_finished++) {
- gpointer val = g_async_queue_pop (priv->return_queue);
+ target = UFO_NODE (it->data);
+ conn = ufo_graph_get_edge_label (UFO_GRAPH (task_graph), node, target);
+ ufo_task_node_add_in_group (UFO_TASK_NODE (target),
+ conn->target_input,
+ group);
+ }
- if (val != NO_ERROR)
- return val;
+ g_list_free (successors);
}
- return NULL;
-}
-
-/**
- * ufo_scheduler_run:
- * @scheduler: A #UfoScheduler object
- * @graph: A #UfoGraph object whose filters are scheduled
- * @error: return location for a GError with error codes from
- * #UfoPluginManagerError or %NULL
- *
- * Start executing all filters from the @filters list in their own threads.
- */
-void
-ufo_scheduler_run (UfoScheduler *scheduler,
- UfoGraph *graph,
- GError **error)
-{
- UfoSchedulerPrivate *priv;
-
- GTimer *timer;
- GError *tmp_error = NULL;
-
- g_return_if_fail (UFO_IS_SCHEDULER (scheduler));
-
- priv = scheduler->priv;
+ g_timer_stop (timer);
+ g_print ("Preparation took %fs\n", g_timer_elapsed (timer, NULL));
- if (priv->config == NULL)
- priv->config = ufo_configuration_new ();
+ g_timer_start (timer);
- if (priv->manager == NULL) {
- priv->manager = ufo_resource_manager_new (priv->config);
+ /* Spawn threads */
+ for (guint i = 0; i < n_nodes; i++) {
+ threads[i] = g_thread_create ((GThreadFunc) run_task,
+ tlds[i],
+ TRUE, error);
+ if (error && (*error != NULL))
+ return;
}
- init_filter_queues (priv, graph);
+ /* Wait for threads to finish */
+ for (guint i = 0; i < n_nodes; i++)
+ g_thread_join (threads[i]);
- timer = g_timer_new ();
- tmp_error = spawn_threads (priv, graph);
+ g_timer_stop (timer);
+ g_print ("Processing finished after %3.5fs\n",
+ g_timer_elapsed (timer, NULL));
+ g_timer_destroy (timer);
- if (tmp_error != NULL) {
- g_propagate_error (error, tmp_error);
- return;
- }
+ /* Cleanup */
+ for (guint i = 0; i < n_nodes; i++) {
+ UfoNode *node;
+ UfoGroup *group;
+ ThreadLocalData *tld;
- tmp_error = join_threads (priv, graph);
+ node = g_list_nth_data (nodes, i);
+ group = ufo_task_node_get_out_group (UFO_TASK_NODE (node));
+ g_object_unref (group);
- if (tmp_error != NULL) {
- g_propagate_error (error, tmp_error);
- return;
+ tld = tlds[i];
+ g_free (tld);
}
- g_timer_stop (timer);
- g_message ("Processing finished after %3.5f seconds", g_timer_elapsed (timer, NULL));
- g_timer_destroy (timer);
-
- print_profile_information (priv, graph);
+ g_free (tlds);
}
static void
@@ -820,17 +261,7 @@ ufo_scheduler_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- UfoSchedulerPrivate *priv = UFO_SCHEDULER_GET_PRIVATE(object);
-
switch (property_id) {
- case PROP_CONFIG:
- ufo_set_property_object ((GObject **) &priv->config, g_value_get_object (value));
- break;
-
- case PROP_RESOURCE_MANAGER:
- ufo_set_property_object ((GObject **) &priv->manager, g_value_get_object (value));
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -843,17 +274,7 @@ ufo_scheduler_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- UfoSchedulerPrivate *priv = UFO_SCHEDULER_GET_PRIVATE(object);
-
switch (property_id) {
- case PROP_CONFIG:
- g_value_set_object (value, priv->config);
- break;
-
- case PROP_RESOURCE_MANAGER:
- g_value_set_object (value, priv->manager);
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -863,22 +284,13 @@ ufo_scheduler_get_property (GObject *object,
static void
ufo_scheduler_dispose (GObject *object)
{
- UfoSchedulerPrivate *priv = UFO_SCHEDULER_GET_PRIVATE (object);
-
- ufo_unref_stored_object ((GObject **) &priv->config);
- ufo_unref_stored_object ((GObject **) &priv->manager);
-
- g_async_queue_unref (priv->return_queue);
-
G_OBJECT_CLASS (ufo_scheduler_parent_class)->dispose (object);
- g_message ("UfoScheduler: disposed");
}
static void
ufo_scheduler_finalize (GObject *object)
{
G_OBJECT_CLASS (ufo_scheduler_parent_class)->finalize (object);
- g_message ("UfoScheduler: finalized");
}
static void
@@ -890,16 +302,6 @@ ufo_scheduler_class_init (UfoSchedulerClass *klass)
gobject_class->dispose = ufo_scheduler_dispose;
gobject_class->finalize = ufo_scheduler_finalize;
- scheduler_properties[PROP_RESOURCE_MANAGER] =
- g_param_spec_object ("resource-manager",
- "A UfoResourceManager",
- "A UfoResourceManager",
- UFO_TYPE_RESOURCE_MANAGER,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- g_object_class_install_property (gobject_class, PROP_RESOURCE_MANAGER, scheduler_properties[PROP_RESOURCE_MANAGER]);
- g_object_class_override_property (gobject_class, PROP_CONFIG, "configuration");
-
g_type_class_add_private (klass, sizeof (UfoSchedulerPrivate));
}
@@ -907,6 +309,6 @@ static void
ufo_scheduler_init (UfoScheduler *scheduler)
{
UfoSchedulerPrivate *priv;
+
scheduler->priv = priv = UFO_SCHEDULER_GET_PRIVATE (scheduler);
- priv->return_queue = g_async_queue_new ();
}
diff --git a/src/ufo-scheduler.h b/src/ufo-scheduler.h
index 1a7122a..6102474 100644
--- a/src/ufo-scheduler.h
+++ b/src/ufo-scheduler.h
@@ -2,10 +2,8 @@
#define __UFO_SCHEDULER_H
#include <glib-object.h>
-#include "ufo-configuration.h"
-#include "ufo-graph.h"
-#include "ufo-resource-manager.h"
-#include "ufo-filter.h"
+#include "ufo-arch-graph.h"
+#include "ufo-task-graph.h"
G_BEGIN_DECLS
@@ -44,10 +42,10 @@ struct _UfoSchedulerClass {
GObjectClass parent_class;
};
-UfoScheduler* ufo_scheduler_new (UfoConfiguration *config,
- UfoResourceManager *manager);
+UfoScheduler* ufo_scheduler_new (void);
void ufo_scheduler_run (UfoScheduler *scheduler,
- UfoGraph *graph,
+ UfoArchGraph *arch_graph,
+ UfoTaskGraph *task_graph,
GError** error);
GType ufo_scheduler_get_type (void);
diff --git a/src/ufo-task-graph.c b/src/ufo-task-graph.c
new file mode 100644
index 0000000..5dcf59a
--- /dev/null
+++ b/src/ufo-task-graph.c
@@ -0,0 +1,135 @@
+#include "ufo-task-graph.h"
+#include "ufo-task-node.h"
+#include "ufo-cpu-task-iface.h"
+#include "ufo-gpu-task-iface.h"
+#include "ufo-remote-task.h"
+#include "ufo-input-task.h"
+
+G_DEFINE_TYPE (UfoTaskGraph, ufo_task_graph, UFO_TYPE_GRAPH)
+
+#define UFO_TASK_GRAPH_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_TASK_GRAPH, UfoTaskGraphPrivate))
+
+struct _UfoTaskGraphPrivate {
+ gint foo;
+};
+
+UfoGraph *
+ufo_task_graph_new (void)
+{
+ UfoTaskGraph *graph;
+ graph = UFO_TASK_GRAPH (g_object_new (UFO_TYPE_TASK_GRAPH, NULL));
+ return UFO_GRAPH (graph);
+}
+
+static gboolean
+is_gpu_task (UfoNode *node)
+{
+ return UFO_IS_GPU_TASK (node);
+}
+
+void
+ufo_task_graph_split (UfoTaskGraph *task_graph,
+ UfoArchGraph *arch_graph)
+{
+ GList *paths;
+ guint n_gpus;
+
+ paths = ufo_graph_get_paths (UFO_GRAPH (task_graph), is_gpu_task);
+ n_gpus = ufo_arch_graph_get_num_gpus (arch_graph);
+
+ for (GList *it = g_list_first (paths); it != NULL; it = g_list_next (it)) {
+ GList *path = (GList *) it->data;
+
+ for (guint i = 1; i < n_gpus; i++)
+ ufo_graph_split (UFO_GRAPH (task_graph), path);
+
+ g_list_free (path);
+ }
+
+ g_list_free (paths);
+}
+
+void
+ufo_task_graph_fuse (UfoTaskGraph *task_graph)
+{
+}
+
+static void
+map_proc_node (UfoGraph *graph,
+ UfoNode *node,
+ guint proc_index,
+ GList *gpu_nodes,
+ GList *remote_nodes)
+{
+ GList *successors;
+ guint index;
+ guint n_gpus;
+
+ n_gpus = g_list_length (gpu_nodes);
+ successors = ufo_graph_get_successors (graph, node);
+ index = 0;
+
+ if (UFO_IS_GPU_TASK (node)) {
+ ufo_task_node_set_proc_node (UFO_TASK_NODE (node),
+ g_list_nth_data (gpu_nodes, proc_index));
+ }
+
+ if (UFO_IS_INPUT_TASK (node)) {
+ ufo_task_node_set_proc_node (UFO_TASK_NODE (node),
+ g_list_nth_data (gpu_nodes, proc_index));
+ }
+
+ if (UFO_IS_REMOTE_TASK (node)) {
+ ufo_task_node_set_proc_node (UFO_TASK_NODE (node),
+ g_list_nth_data (remote_nodes, 0));
+ }
+
+ for (GList *it = g_list_first (successors); it != NULL; it = g_list_next (it)) {
+ map_proc_node (graph, UFO_NODE (it->data), proc_index + index, gpu_nodes, remote_nodes);
+ index = (index + 1) % n_gpus;
+ }
+
+ g_list_free (successors);
+}
+
+
+/**
+ * ufo_task_graph_map:
+ *
+ * Map task nodes of a task graph to the processing nodes of an architecture
+ * graph.
+ */
+void
+ufo_task_graph_map (UfoTaskGraph *task_graph,
+ UfoArchGraph *arch_graph)
+{
+ GList *gpu_nodes;
+ GList *remote_nodes;
+ GList *roots;
+
+ gpu_nodes = ufo_arch_graph_get_gpu_nodes (arch_graph);
+ remote_nodes = ufo_arch_graph_get_remote_nodes (arch_graph);
+ roots = ufo_graph_get_roots (UFO_GRAPH (task_graph));
+
+ for (GList *it = g_list_first (roots); it != NULL; it = g_list_next (it))
+ map_proc_node (UFO_GRAPH (task_graph), UFO_NODE (it->data), 0, gpu_nodes, remote_nodes);
+
+ g_list_free (roots);
+}
+
+static void
+ufo_task_graph_class_init (UfoTaskGraphClass *klass)
+{
+ g_type_class_add_private(klass, sizeof(UfoTaskGraphPrivate));
+}
+
+static void
+ufo_task_graph_init (UfoTaskGraph *self)
+{
+ UfoTaskGraphPrivate *priv;
+ self->priv = priv = UFO_TASK_GRAPH_GET_PRIVATE (self);
+
+ /* Maybe we should define a specific task node type from which all tasks
+ * must inherit */
+ ufo_graph_register_node_type (UFO_GRAPH (self), UFO_TYPE_NODE);
+}
diff --git a/src/ufo-task-graph.h b/src/ufo-task-graph.h
new file mode 100644
index 0000000..4c79aa2
--- /dev/null
+++ b/src/ufo-task-graph.h
@@ -0,0 +1,60 @@
+#ifndef __UFO_TASK_GRAPH_H
+#define __UFO_TASK_GRAPH_H
+
+#include <glib-object.h>
+#include "ufo-graph.h"
+#include "ufo-arch-graph.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_TASK_GRAPH (ufo_task_graph_get_type())
+#define UFO_TASK_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_TASK_GRAPH, UfoTaskGraph))
+#define UFO_IS_TASK_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_TASK_GRAPH))
+#define UFO_TASK_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_TASK_GRAPH, UfoTaskGraphClass))
+#define UFO_IS_TASK_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_TASK_GRAPH))
+#define UFO_TASK_GRAPH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_TASK_GRAPH, UfoTaskGraphClass))
+
+typedef struct _UfoTaskGraph UfoTaskGraph;
+typedef struct _UfoTaskGraphClass UfoTaskGraphClass;
+typedef struct _UfoTaskGraphPrivate UfoTaskGraphPrivate;
+typedef struct _UfoTaskGraphConnection UfoTaskGraphConnection;
+
+struct _UfoTaskGraphConnection {
+ guint source_output;
+ guint target_input;
+};
+
+/**
+ * UfoTaskGraph:
+ *
+ * Main object for organizing filters. The contents of the #UfoTaskGraph structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoTaskGraph {
+ /*< private >*/
+ UfoGraph parent_instance;
+
+ UfoTaskGraphPrivate *priv;
+};
+
+/**
+ * UfoTaskGraphClass:
+ *
+ * #UfoTaskGraph class
+ */
+struct _UfoTaskGraphClass {
+ /*< private >*/
+ UfoGraphClass parent_class;
+};
+
+UfoGraph *ufo_task_graph_new (void);
+void ufo_task_graph_map (UfoTaskGraph *task_graph,
+ UfoArchGraph *arch_graph);
+void ufo_task_graph_split (UfoTaskGraph *task_graph,
+ UfoArchGraph *arch_graph);
+void ufo_task_graph_fuse (UfoTaskGraph *task_graph);
+GType ufo_task_graph_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-task-iface.c b/src/ufo-task-iface.c
new file mode 100644
index 0000000..7d2b61a
--- /dev/null
+++ b/src/ufo-task-iface.c
@@ -0,0 +1,59 @@
+#include "ufo-task-iface.h"
+
+typedef UfoTaskIface UfoTaskInterface;
+
+G_DEFINE_INTERFACE (UfoTask, ufo_task, G_TYPE_OBJECT)
+
+void
+ufo_task_setup (UfoTask *task,
+ GError **error)
+{
+ UFO_TASK_GET_IFACE (task)->setup (task, error);
+}
+
+void
+ufo_task_get_requisition (UfoTask *task,
+ UfoBuffer **inputs,
+ UfoRequisition *requisition)
+{
+ UFO_TASK_GET_IFACE (task)->get_requisition (task, inputs, requisition);
+}
+
+void
+ufo_task_get_structure (UfoTask *task,
+ guint *n_inputs,
+ UfoInputParameter **in_params)
+{
+ UFO_TASK_GET_IFACE (task)->get_structure (task, n_inputs, in_params);
+}
+
+static void
+ufo_task_setup_real (UfoTask *task,
+ GError **error)
+{
+ g_warning ("`setup' not implemented");
+}
+
+static void
+ufo_task_get_requisition_real (UfoTask *task,
+ UfoBuffer **inputs,
+ UfoRequisition *requisition)
+{
+ g_warning ("`get_allocation' not implemented");
+}
+
+static void
+ufo_task_get_structure_real (UfoTask *task,
+ guint *n_inputs,
+ UfoInputParameter **in_params)
+{
+ g_warning ("`get_structure' not implemented");
+}
+
+static void
+ufo_task_default_init (UfoTaskInterface *iface)
+{
+ iface->setup = ufo_task_setup_real;
+ iface->get_requisition = ufo_task_get_requisition_real;
+ iface->get_structure = ufo_task_get_structure_real;
+}
diff --git a/src/ufo-task-iface.h b/src/ufo-task-iface.h
new file mode 100644
index 0000000..c9e7671
--- /dev/null
+++ b/src/ufo-task-iface.h
@@ -0,0 +1,62 @@
+#ifndef UFO_TASK_IFACE_H
+#define UFO_TASK_IFACE_H
+
+#include <glib-object.h>
+#include "ufo-buffer.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_TASK (ufo_task_get_type())
+#define UFO_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_TASK, UfoTask))
+#define UFO_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_TASK, UfoTaskIface))
+#define UFO_IS_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_TASK))
+#define UFO_IS_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_TASK))
+#define UFO_TASK_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), UFO_TYPE_TASK, UfoTaskIface))
+
+typedef struct _UfoTask UfoTask;
+typedef struct _UfoTaskIface UfoTaskIface;
+typedef struct _UfoInputParameter UfoInputParameter;
+typedef struct _UfoOutputParameter UfoOutputParameter;
+
+/**
+ * UfoInputParameter:
+ * @n_dims: Number of dimension the input accept
+ * @n_expected_items: Number of expected items. Use UFO_FILTER_INFINITE_INPUT to
+ * accept a data stream.
+ *
+ * Data structure for describing the parameters of an input as used by
+ * ufo_filter_register_inputs().
+ */
+struct _UfoInputParameter {
+ guint n_dims;
+ gint n_expected_items;
+};
+
+struct _UfoTaskIface {
+ GTypeInterface parent_iface;
+
+ void (*setup) (UfoTask *task,
+ GError **error);
+ void (*get_structure) (UfoTask *task,
+ guint *n_inputs,
+ UfoInputParameter **in_params);
+ void (*get_requisition) (UfoTask *task,
+ UfoBuffer **inputs,
+ UfoRequisition *requisition);
+};
+
+void ufo_task_setup (UfoTask *task,
+ GError **error);
+void ufo_task_get_requisition (UfoTask *task,
+ UfoBuffer **inputs,
+ UfoRequisition *requisition);
+void ufo_task_get_structure (UfoTask *task,
+ guint *n_inputs,
+ UfoInputParameter
+ **in_params);
+
+GType ufo_task_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ufo-task-node.c b/src/ufo-task-node.c
new file mode 100644
index 0000000..648c0d0
--- /dev/null
+++ b/src/ufo-task-node.c
@@ -0,0 +1,114 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include "ufo-task-node.h"
+
+G_DEFINE_TYPE (UfoTaskNode, ufo_task_node, UFO_TYPE_NODE)
+
+#define UFO_TASK_NODE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_TASK_NODE, UfoTaskNodePrivate))
+
+
+struct _UfoTaskNodePrivate {
+ UfoSendPattern pattern;
+ UfoNode *proc_node;
+ UfoGroup *out_group;
+ GList *in_groups[16];
+ GList *current[16];
+};
+
+void
+ufo_task_node_set_send_pattern (UfoTaskNode *node,
+ UfoSendPattern pattern)
+{
+ g_return_if_fail (UFO_IS_TASK_NODE (node));
+ node->priv->pattern = pattern;
+}
+
+UfoSendPattern
+ufo_task_node_get_send_pattern (UfoTaskNode *node)
+{
+ g_return_val_if_fail (UFO_IS_TASK_NODE (node), 0);
+ return node->priv->pattern;
+}
+
+void
+ufo_task_node_set_out_group (UfoTaskNode *node,
+ UfoGroup *group)
+{
+ g_return_if_fail (UFO_IS_TASK_NODE (node));
+ node->priv->out_group = group;
+}
+
+UfoGroup *
+ufo_task_node_get_out_group (UfoTaskNode *node)
+{
+ g_return_val_if_fail (UFO_IS_TASK_NODE (node), NULL);
+ return node->priv->out_group;
+}
+
+void
+ufo_task_node_add_in_group (UfoTaskNode *node,
+ guint pos,
+ UfoGroup *group)
+{
+ g_return_if_fail (UFO_IS_TASK_NODE (node));
+ /* TODO: check out-of-bounds condition */
+ node->priv->in_groups[pos] = g_list_prepend (node->priv->in_groups[pos], group);
+ node->priv->current[pos] = node->priv->in_groups[pos];
+}
+
+UfoGroup *
+ufo_task_node_get_current_in_group (UfoTaskNode *node,
+ guint pos)
+{
+ g_return_val_if_fail (UFO_IS_TASK_NODE (node), NULL);
+ return UFO_GROUP (node->priv->current[pos]->data);
+}
+
+void
+ufo_task_node_switch_in_group (UfoTaskNode *node,
+ guint pos)
+{
+ UfoTaskNodePrivate *priv;
+
+ g_return_if_fail (UFO_IS_TASK_NODE (node));
+ priv = node->priv;
+ priv->current[pos] = g_list_next (priv->current[pos]);
+
+ if (priv->current[pos] == NULL)
+ priv->current[pos] = g_list_first (priv->in_groups[pos]);
+}
+
+void
+ufo_task_node_set_proc_node (UfoTaskNode *task_node,
+ UfoNode *proc_node)
+{
+ g_return_if_fail (UFO_IS_TASK_NODE (task_node) && UFO_IS_NODE (proc_node));
+ task_node->priv->proc_node = proc_node;
+}
+
+UfoNode *
+ufo_task_node_get_proc_node (UfoTaskNode *node)
+{
+ g_return_val_if_fail (UFO_IS_TASK_NODE (node), NULL);
+ return node->priv->proc_node;
+}
+
+static void
+ufo_task_node_class_init (UfoTaskNodeClass *klass)
+{
+ g_type_class_add_private (klass, sizeof(UfoTaskNodePrivate));
+}
+
+static void
+ufo_task_node_init (UfoTaskNode *self)
+{
+ self->priv = UFO_TASK_NODE_GET_PRIVATE (self);
+ self->priv->pattern = UFO_SEND_BROADCAST;
+ self->priv->proc_node = NULL;
+ self->priv->out_group = NULL;
+
+ for (guint i = 0; i < 16; i++) {
+ self->priv->in_groups[i] = NULL;
+ self->priv->current[i] = NULL;
+ }
+}
diff --git a/src/ufo-task-node.h b/src/ufo-task-node.h
new file mode 100644
index 0000000..a08fa7f
--- /dev/null
+++ b/src/ufo-task-node.h
@@ -0,0 +1,70 @@
+#ifndef __UFO_TASK_NODE_H
+#define __UFO_TASK_NODE_H
+
+#include <glib-object.h>
+#include <sched.h>
+#include "ufo-node.h"
+#include "ufo-group.h"
+
+G_BEGIN_DECLS
+
+#define UFO_TYPE_TASK_NODE (ufo_task_node_get_type())
+#define UFO_TASK_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_TASK_NODE, UfoTaskNode))
+#define UFO_IS_TASK_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_TASK_NODE))
+#define UFO_TASK_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_TASK_NODE, UfoTaskNodeClass))
+#define UFO_IS_TASK_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_TASK_NODE))
+#define UFO_TASK_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_TASK_NODE, UfoTaskNodeClass))
+
+typedef struct _UfoTaskNode UfoTaskNode;
+typedef struct _UfoTaskNodeClass UfoTaskNodeClass;
+typedef struct _UfoTaskNodePrivate UfoTaskNodePrivate;
+
+typedef enum {
+ UFO_SEND_BROADCAST,
+ UFO_SEND_SCATTER
+} UfoSendPattern;
+
+/**
+ * UfoTaskNode:
+ *
+ * Main object for organizing filters. The contents of the #UfoTaskNode structure
+ * are private and should only be accessed via the provided API.
+ */
+struct _UfoTaskNode {
+ /*< private >*/
+ UfoNode parent_instance;
+
+ UfoTaskNodePrivate *priv;
+};
+
+/**
+ * UfoTaskNodeClass:
+ *
+ * #UfoTaskNode class
+ */
+struct _UfoTaskNodeClass {
+ /*< private >*/
+ UfoNodeClass parent_class;
+};
+
+void ufo_task_node_set_send_pattern (UfoTaskNode *task_node,
+ UfoSendPattern pattern);
+UfoSendPattern ufo_task_node_get_send_pattern (UfoTaskNode *task_node);
+void ufo_task_node_set_out_group (UfoTaskNode *task_node,
+ UfoGroup *group);
+UfoGroup *ufo_task_node_get_out_group (UfoTaskNode *task_node);
+void ufo_task_node_add_in_group (UfoTaskNode *task_node,
+ guint pos,
+ UfoGroup *group);
+UfoGroup *ufo_task_node_get_current_in_group (UfoTaskNode *task_node,
+ guint pos);
+void ufo_task_node_switch_in_group (UfoTaskNode *task_node,
+ guint pos);
+void ufo_task_node_set_proc_node (UfoTaskNode *task_node,
+ UfoNode *proc_node);
+UfoNode *ufo_task_node_get_proc_node (UfoTaskNode *task_node);
+GType ufo_task_node_get_type (void);
+
+G_END_DECLS
+
+#endif