Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task comparison function or 'same dependency added twice to no-op' #558

Open
doocman opened this issue Feb 29, 2024 · 3 comments
Open

Task comparison function or 'same dependency added twice to no-op' #558

doocman opened this issue Feb 29, 2024 · 3 comments

Comments

@doocman
Copy link
Contributor

doocman commented Feb 29, 2024

I want to set up a small framework in which I automatically create graph dependencies depending on the output of a certain task, but it became problematic when one task (say task 'A') had more than one output and another task ('B') wanted to use more than one of the 'A':s outputs: cudaGraph gave an error when the same dependency was added twice and without an comparison function or operator I can't really get around the issue myself. Both Taskflow's Task and cudaFlows cudaTask are lightweight proxy objects. They could easily have a comparison operator that just checks if the underlying pointers points to the same object. Would that be a reasonable fix?

@tsung-wei-huang
Copy link
Member

Can you provide a more specific code snippet to demonstrate this problem?

@doocman
Copy link
Contributor Author

doocman commented Mar 14, 2024

Sure. Say we have a task foo and a task bar that has been modularised like this:

// TTaskType here could also be a cudaTask or something...
template <typename T, typename TTaskType = tf::Task>
struct task_result {
  T value;
  TTaskType task;
}

struct foo_task {
  struct my_task_result {
  task_result<std::span<int>, tf::Task> result1;
  task_result<std::span<int>, tf::Task> result2;
};
  std::vector<int> result1;
  std::vector<int> result2;
  foo_task(...) {...}
  my_task_result add_tasks(tf::Taskflow& destination) {
    auto task = destination.emplace([this]{ // do something that populates both result1 and result2});
    return {{result1, task}, {result2, task}};
}
};

struct bar_task {
...members
  struct my_task_result{...};
  my_task_result add_tasks(tf::Taskflow& destination, task_result<int> const& dep1, task_result<int> const& dep2) {
    // here, I'd either like the "succeed"-thing to take care of duplicated dependencies, or at least give me the ability to compare dep1.task and dep2.task to see if they refer to the same task.
    auto task = destination.emplace([vals1 = dep1.value, vals2 = dep2.value] {...}).succeed(dep1.task, dep2.task);
   retur {...};
}

void foo_bar() {
 tf::Taskflow tasks;
 auto foo = foo_task(...);
 auto bar = bar_task(...);
 auto [foo_res1, foo_res2] = foo_task.add_tasks(tasks);
 auto [bar_res...] = bar_task.add_tasks(tasks, foo_res1, foo_res2);
 ...
}

@doocman
Copy link
Contributor Author

doocman commented May 7, 2024

I realised that the functionality I want exists (more or less) for the regular Task-object (the operator==), but I'd like something similar for the cudaTask as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants