static void run_remote_task (TaskLocalData *tld) { UfoRemoteNode *remote; guint n_remote_gpus; gboolean *alive; gboolean active = TRUE; g_assert (tld->n_inputs == 1); remote = UFO_REMOTE_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (tld->task))); n_remote_gpus = ufo_remote_node_get_num_gpus (remote); alive = g_new0 (gboolean, n_remote_gpus); /* * We launch a new thread for each incoming input data set because then we * can send as many items as we have remote GPUs available without waiting * for processing to stop. */ while (active) { for (guint i = 0; i < n_remote_gpus; i++) { UfoBuffer *input; if (get_inputs (tld, &input)) { ufo_remote_node_send_inputs (remote, &input); release_inputs (tld, &input); alive[i] = TRUE; } else { alive[i] = FALSE; } } for (guint i = 0; i < n_remote_gpus; i++) { UfoGroup *group; UfoBuffer *output; UfoRequisition requisition; if (!alive[i]) continue; ufo_remote_node_get_requisition (remote, &requisition); group = ufo_task_node_get_out_group (UFO_TASK_NODE (tld->task)); output = ufo_group_pop_output_buffer (group, &requisition); ufo_remote_node_get_result (remote, output); ufo_group_push_output_buffer (group, output); } active = any (alive, n_remote_gpus); } g_free (alive); ufo_group_finish (ufo_task_node_get_out_group (UFO_TASK_NODE (tld->task))); }
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))); } }
static gboolean ufo_null_task_process (UfoTask *task, UfoBuffer **inputs, UfoBuffer *output, UfoRequisition *requisition) { UfoNullTaskPrivate *priv; priv = UFO_NULL_TASK_GET_PRIVATE (task); if (priv->force_download) { gfloat *host_array; host_array = ufo_buffer_get_host_array (inputs[0], NULL); host_array[0] = 0.0; } if (priv->finish) { UfoGpuNode *gpu; gpu = UFO_GPU_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task))); UFO_RESOURCES_CHECK_CLERR (clFinish (ufo_gpu_node_get_cmd_queue (gpu))); } return TRUE; }
static UfoNode * ufo_task_node_copy (UfoNode *node, GError **error) { UfoTaskNode *orig; UfoTaskNode *copy; copy = UFO_TASK_NODE (UFO_NODE_CLASS (ufo_task_node_parent_class)->copy (node, error)); orig = UFO_TASK_NODE (node); copy->priv->pattern = orig->priv->pattern; for (guint i = 0; i < 16; i++) copy->priv->n_expected[i] = orig->priv->n_expected[i]; ufo_task_node_set_plugin_name (copy, orig->priv->plugin); return UFO_NODE (copy); }
gboolean ufo_task_process (UfoTask *task, UfoBuffer **inputs, UfoBuffer *output, UfoRequisition *requisition) { gboolean result; result = UFO_TASK_GET_IFACE (task)->process (task, inputs, output, requisition); ufo_signal_emit (task, signals[PROCESSED], 0); ufo_task_node_increase_processed (UFO_TASK_NODE (task)); return result; }
static gboolean expand_group_graph (UfoResources *resources, UfoGraph *graph, GError **error) { GList *nodes; GList *it; GList *gpu_nodes; guint n_gpus; gboolean success = TRUE; gpu_nodes = ufo_resources_get_gpu_nodes (resources); n_gpus = g_list_length (gpu_nodes); nodes = ufo_graph_get_nodes (graph); g_list_for (nodes, it) { TaskGroup *group; UfoTaskNode *node; group = ufo_node_get_label (UFO_NODE (it->data)); node = UFO_TASK_NODE (group->tasks->data); if (ufo_task_uses_gpu (UFO_TASK (node))) { ufo_task_node_set_proc_node (node, g_list_first (gpu_nodes)->data); for (guint i = 1; i < n_gpus; i++) { UfoTaskNode *copy; copy = UFO_TASK_NODE (ufo_node_copy (UFO_NODE (node), error)); if (copy == NULL) { success = FALSE; goto cleanup; } ufo_task_node_set_proc_node (copy, g_list_nth_data (gpu_nodes, i)); group->tasks = g_list_append (group->tasks, copy); } } }
static void release_inputs (TaskLocalData *tld, UfoBuffer **inputs) { UfoTaskNode *node = UFO_TASK_NODE (tld->task); for (guint i = 0; i < tld->n_inputs; i++) { UfoGroup *group; 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); } }
static gboolean get_inputs (TaskLocalData *tld, UfoBuffer **inputs) { UfoRequisition req; UfoTaskNode *node = UFO_TASK_NODE (tld->task); guint n_finished = 0; for (guint i = 0; i < tld->n_inputs; i++) { UfoGroup *group; if (!tld->finished[i]) { UfoBuffer *input; group = ufo_task_node_get_current_in_group (node, i); input = ufo_group_pop_input_buffer (group, tld->task); if (tld->strict && input != UFO_END_OF_STREAM) { ufo_buffer_get_requisition (input, &req); if (req.n_dims != tld->dims[i]) { g_warning ("%s: buffer from input %i provides %i dimensions but expect %i dimensions", G_OBJECT_TYPE_NAME (tld->task), i, req.n_dims, tld->dims[i]); return FALSE; } } if (input == UFO_END_OF_STREAM) { tld->finished[i] = TRUE; n_finished++; } else inputs[i] = input; } else n_finished++; } return (tld->n_inputs == 0) || (n_finished < tld->n_inputs); }
static gpointer run_task (TaskLocalData *tld) { UfoBuffer *inputs[tld->n_inputs]; UfoBuffer *output; UfoTaskNode *node; UfoTaskMode mode; UfoProfiler *profiler; UfoRequisition requisition; gboolean active; node = UFO_TASK_NODE (tld->task); active = TRUE; output = NULL; profiler = g_object_ref (ufo_task_node_get_profiler (node)); if (UFO_IS_REMOTE_TASK (tld->task)) { run_remote_task (tld); return NULL; } /* mode without CPU/GPU flag */ mode = tld->mode & UFO_TASK_MODE_TYPE_MASK; while (active) { UfoGroup *group; gboolean produces; group = ufo_task_node_get_out_group (node); /* Get input buffers */ active = get_inputs (tld, inputs); if (!active) { ufo_group_finish (group); break; } /* Get output buffers */ ufo_task_get_requisition (tld->task, inputs, &requisition); produces = requisition.n_dims > 0; if (produces) { output = ufo_group_pop_output_buffer (group, &requisition); g_assert (output != NULL); } if (output != NULL) ufo_buffer_discard_location (output); switch (mode) { case UFO_TASK_MODE_PROCESSOR: ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_PROCESS | UFO_TRACE_EVENT_BEGIN); active = ufo_task_process (tld->task, inputs, output, &requisition); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_PROCESS | UFO_TRACE_EVENT_END); ufo_task_node_increase_processed (UFO_TASK_NODE (tld->task)); break; case UFO_TASK_MODE_REDUCTOR: do { ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_PROCESS | UFO_TRACE_EVENT_BEGIN); ufo_task_process (tld->task, inputs, output, &requisition); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_PROCESS | UFO_TRACE_EVENT_END); ufo_task_node_increase_processed (UFO_TASK_NODE (tld->task)); release_inputs (tld, inputs); active = get_inputs (tld, inputs); } while (active); break; case UFO_TASK_MODE_GENERATOR: ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_GENERATE | UFO_TRACE_EVENT_BEGIN); active = ufo_task_generate (tld->task, output, &requisition); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_GENERATE | UFO_TRACE_EVENT_END); break; default: g_warning ("Invalid task mode: %i\n", mode); } if (active && produces && (mode != UFO_TASK_MODE_REDUCTOR)) ufo_group_push_output_buffer (group, output); /* Release buffers for further consumption */ if (active) release_inputs (tld, inputs); if (mode == UFO_TASK_MODE_REDUCTOR) { do { ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_GENERATE | UFO_TRACE_EVENT_BEGIN); active = ufo_task_generate (tld->task, output, &requisition); ufo_profiler_trace_event (profiler, UFO_TRACE_EVENT_GENERATE | UFO_TRACE_EVENT_END); if (active) { ufo_group_push_output_buffer (group, output); output = ufo_group_pop_output_buffer (group, &requisition); } } while (active); } if (!active) ufo_group_finish (group); } g_object_unref (profiler); return NULL; }