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

Add capability to output task graph #1099

Merged
merged 30 commits into from
Jun 17, 2024
Merged

Conversation

lroberts36
Copy link
Collaborator

@lroberts36 lroberts36 commented Jun 7, 2024

PR Summary

This PR adds the functionality to output the graph of a TaskList, TaskRegion, or TaskCollection in the Graphviz format. I do not explicitly add the connectivity between TaskRegions, so they show up as disconnected graphs. It is pretty trivial to pull out the graph because of #917. Initially, I used the nameof library for writing out function names, but I am not actually convinced this is necessary. I think we get everything we want with

#define TF(...) std::string(#__VA_ARGS__), __VA_ARGS__

Let me know if you have thoughts on this. After reading the internet for a while, I am pretty sure that there is no way to get the names of tasks within task lists themselves since they are effectively function pointers and no name information is available (hence the need to allow passing a string naming the task).

Results look like (from the sparse advection test without refinement and a single block):
Screen Shot 2024-06-07 at 1 51 18 PM

PR Checklist

  • Code passes cpplint
  • New features are documented.
  • Adds a test for any bugs fixed. Adds tests for new features.
  • Code is formatted
  • Changes are summarized in CHANGELOG.md
  • Change is breaking (API, behavior, ...)
    • Change is additionally added to CHANGELOG.md in the breaking section
    • PR is marked as breaking
    • Short summary API changes at the top of the PR (plus optionally with an automated update/fix script)
  • CI has been triggered on Darwin for performance regression tests.
  • Docs build
  • (@lanl.gov employees) Update copyright on changed files

@lroberts36 lroberts36 requested a review from jdolence June 7, 2024 19:53
@lroberts36 lroberts36 changed the title WIP: Add capability to output task graph Add capability to output task graph Jun 10, 2024
@lroberts36 lroberts36 linked an issue Jun 10, 2024 that may be closed by this pull request
Copy link
Collaborator

@pdmullen pdmullen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really cool and a powerful debugging tool. My approval comes from testing this utility in various downstream applications. All looks good to me. It even appears to be working with the iterative tasking infrastructure. And it has already uncovered various issues that needed addressing! 😬

My only comment is a non-blocker but for a future PR: It would be cool to thread these graphs through outputs so that they could be dumped to file, e.g., at the beginning of a simulation. In the meantime, however, as a debugging tool, calling std::cout << my_task_collection should be sufficient.

Copy link
Collaborator

@Yurlungur Yurlungur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Looks like now the user has to call WriteTaskGraph by hand? That's probably for the best.

If I interpret this correctly, the task graph appending is optional--and this doesn't break downstream?

Also could we support

PARTHENON_ADDTASK(tasklist, dependency, _VA_ARGS_)

as sugar for the call around TF?

example/sparse_advection/sparse_advection_driver.cpp Outdated Show resolved Hide resolved
src/tasks/tasks.hpp Outdated Show resolved Hide resolved
src/tasks/tasks.hpp Outdated Show resolved Hide resolved
src/tasks/tasks.hpp Show resolved Hide resolved
@lroberts36
Copy link
Collaborator Author

lroberts36 commented Jun 17, 2024

LGTM. Looks like now the user has to call WriteTaskGraph by hand? That's probably for the best.

Yeah, currently the user has to do something like std::cout << tc; to write the graph to screen. Patrick suggested having an option in the driver that would write the task graph to file on the first step.

If I interpret this correctly, the task graph appending is optional--and this doesn't break downstream?

Yes, this should have no impact on downstream codes. Although there is a label attached to all tasks now, it has no impact unless you call the output stream operator on a TaskCollection, TaskRegion, or TaskList. If you do call the output stream operator before completely building the task list, it is possible that it could break things since the output operator calls the graph completion task (which is required so that all the edges are correctly set before printing).

The vector of tasks that gets appended to for output of the graph is a temporary and has no impact on the internal task lists of Task*. Aside from the issue of calling the output operator to early and finalizing the graph to early, you should be able to write the task graph to file and then execute the task graph with no side effects.

Also could we support

PARTHENON_ADDTASK(tasklist, dependency, _VA_ARGS_)

as sugar for the call around TF?

I don't quite see what this would buy us?

@Yurlungur
Copy link
Collaborator

Yeah, currently the user has to do something like std::cout << tc; to write the graph to screen. Patrick suggested having an option in the driver that would write the task graph to file on the first step.

👍 would be kind of nice to have the driver do it automatically.

Yes, this should have no impact on downstream codes. Although there is a label attached to all tasks now, it has no impact unless you call the output stream operator on a TaskCollection, TaskRegion, or TaskList. If you do call the output stream operator before completely building the task list, it is possible that it could break things since the output operator calls the graph completion task (which is required so that all the edges are correctly set before printing).

Not super important... but can we add guard rails for that?

The vector of tasks that gets appended to for output of the graph is a temporary and has no impact on the internal task lists of Task*. Aside from the issue of calling the output operator to early and finalizing the graph to early, you should be able to write the task graph to file and then execute the task graph with no side effects.

👍

I don't quite see what this would buy us?

I just find TF a little ugly and I like that macro better. But it's a taste thing. No need to add it.

@lroberts36
Copy link
Collaborator Author

Yeah, currently the user has to do something like std::cout << tc; to write the graph to screen. Patrick suggested having an option in the driver that would write the task graph to file on the first step.

👍 would be kind of nice to have the driver do it automatically.

Yeah, agreed, but let's leave for a future PR.

Yes, this should have no impact on downstream codes. Although there is a label attached to all tasks now, it has no impact unless you call the output stream operator on a TaskCollection, TaskRegion, or TaskList. If you do call the output stream operator before completely building the task list, it is possible that it could break things since the output operator calls the graph completion task (which is required so that all the edges are correctly set before printing).

Not super important... but can we add guard rails for that?

I just included a check in AddTask that the task region containing it hasn't had BuildGraph called.

I just find TF a little ugly and I like that macro better. But it's a taste thing. No need to add it.

Josh and I thought this sort of pattern was a quick to implement, minimally invasive way to update old task list building code, but I agree that it can be a little obscure (which partially inspired the task function acronym choice...).

@Yurlungur
Copy link
Collaborator

Yeah, agreed, but let's leave for a future PR.

👍

I just included a check in AddTask that the task region containing it hasn't had BuildGraph called.

👍

Josh and I thought this sort of pattern was a quick to implement, minimally invasive way to update old task list building code, but I agree that it can be a little obscure (which partially inspired the task function acronym choice...).

Yeah. That's fine. Like I said it's a taste thing.

@lroberts36 lroberts36 merged commit 5c339a7 into develop Jun 17, 2024
49 of 50 checks passed
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

Successfully merging this pull request may close these issues.

Flowchart for tasks
3 participants