/* * Copyright (C) 2011-2013 Karlsruhe Institute of Technology * * This file is part of Ufo. * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include #include /** * SECTION:ufo-task-iface * @Short_description: Base interface of all tasks * @Title: UfoTaskIface * * Interface that defines the behaviour of all tasks. Each scheduler uses the * same policy to run a task: First, ufo_task_setup(), ufo_task_get_num_inputs() * and ufo_task_get_num_dimensions() is called for each tasks. Then in each * iteration the task is asked about its size requirements using * ufo_task_get_requisition() and then executed using ufo_task_process() and/or * ufo_task_generate(). */ typedef UfoTaskIface UfoTaskInterface; G_DEFINE_INTERFACE (UfoTask, ufo_task, G_TYPE_OBJECT) enum { PROCESSED, GENERATED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; /** * UfoTaskError: * @UFO_TASK_ERROR_SETUP: Error during setup of a task. */ GQuark ufo_task_error_quark () { return g_quark_from_static_string ("ufo-task-error-quark"); } void ufo_task_setup (UfoTask *task, UfoResources *resources, GError **error) { GError *tmp_error = NULL; ufo_task_node_setup (UFO_TASK_NODE (task)); UFO_TASK_GET_IFACE (task)->setup (task, resources, &tmp_error); if (tmp_error != NULL) { g_propagate_prefixed_error (error, tmp_error, "%s: ", ufo_task_node_get_plugin_name (UFO_TASK_NODE (task))); } } void ufo_task_get_requisition (UfoTask *task, UfoBuffer **inputs, UfoRequisition *requisition) { UFO_TASK_GET_IFACE (task)->get_requisition (task, inputs, requisition); } guint ufo_task_get_num_inputs (UfoTask *task) { return UFO_TASK_GET_IFACE (task)->get_num_inputs (task); } guint ufo_task_get_num_dimensions (UfoTask *task, guint input) { return UFO_TASK_GET_IFACE (task)->get_num_dimensions (task, input); } UfoTaskMode ufo_task_get_mode (UfoTask *task) { return UFO_TASK_GET_IFACE (task)->get_mode (task); } void ufo_task_set_json_object_property (UfoTask *task, const gchar *prop_name, JsonObject *object) { UFO_TASK_GET_IFACE (task)->set_json_object_property (task, prop_name, object); } static void emit_signal (gpointer instance, guint signal_id, GQuark detail) { #ifdef WITH_PYTHON if (Py_IsInitialized ()) { PyGILState_STATE state = PyGILState_Ensure (); #endif g_signal_emit (instance, signal_id, detail, G_TYPE_NONE); #ifdef WITH_PYTHON PyGILState_Release (state); } #endif } gboolean ufo_task_process (UfoTask *task, UfoBuffer **inputs, UfoBuffer *output, UfoRequisition *requisition) { UfoProfiler *profiler; gboolean result; profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task)); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_PROCESS | UFO_TRACE_EVENT_BEGIN); result = UFO_TASK_GET_IFACE (task)->process (task, inputs, output, requisition); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_PROCESS | UFO_TRACE_EVENT_END); emit_signal (task, signals[PROCESSED], 0); ufo_task_node_increase_processed (UFO_TASK_NODE (task)); return result; } gboolean ufo_task_generate (UfoTask *task, UfoBuffer *output, UfoRequisition *requisition) { UfoProfiler *profiler; gboolean result; profiler = ufo_task_node_get_profiler (UFO_TASK_NODE(task)); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_GENERATE | UFO_TRACE_EVENT_BEGIN); result = UFO_TASK_GET_IFACE (task)->generate (task, output, requisition); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_GENERATE | UFO_TRACE_EVENT_END); emit_signal (task, signals[GENERATED], 0); return result; } gboolean ufo_task_uses_gpu (UfoTask *task) { return ufo_task_get_mode (task) & UFO_TASK_MODE_GPU; } gboolean ufo_task_uses_cpu (UfoTask *task) { return ufo_task_get_mode (task) & UFO_TASK_MODE_CPU; } static void warn_unimplemented (UfoTask *task, const gchar *func) { g_warning ("%s: `%s' not implemented", G_OBJECT_TYPE_NAME (task), func); } static void ufo_task_set_json_object_property_real (UfoTask *task, const gchar *prop_name, JsonObject *object) { warn_unimplemented (task, "set_json_object_property"); } static void ufo_task_setup_real (UfoTask *task, UfoResources *resources, GError **error) { warn_unimplemented (task, "setup"); } static void ufo_task_get_requisition_real (UfoTask *task, UfoBuffer **inputs, UfoRequisition *requisition) { warn_unimplemented (task, "get_allocation"); } static guint ufo_task_get_num_inputs_real (UfoTask *task) { warn_unimplemented (task, "get_num_inputs"); return 0; } static guint ufo_task_get_num_dimensions_real (UfoTask *task, guint input) { warn_unimplemented (task, "get_num_dimensions"); return 0; } static UfoTaskMode ufo_task_get_mode_real (UfoTask *task) { warn_unimplemented (task, "get_mode"); return 0; } static gboolean ufo_task_process_real (UfoTask *task, UfoBuffer **inputs, UfoBuffer *output, UfoRequisition *requisition) { warn_unimplemented (task, "process"); return FALSE; } static gboolean ufo_task_generate_real (UfoTask *task, UfoBuffer *output, UfoRequisition *requisition) { warn_unimplemented (task, "generate"); return FALSE; } static void ufo_task_default_init (UfoTaskInterface *iface) { iface->setup = ufo_task_setup_real; iface->get_requisition = ufo_task_get_requisition_real; iface->get_num_inputs = ufo_task_get_num_inputs_real; iface->get_num_dimensions = ufo_task_get_num_dimensions_real; iface->get_mode = ufo_task_get_mode_real; iface->set_json_object_property = ufo_task_set_json_object_property_real; iface->process = ufo_task_process_real; iface->generate = ufo_task_generate_real; signals[PROCESSED] = g_signal_new ("processed", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[GENERATED] = g_signal_new ("generated", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); }