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 operational modes #406

Merged
merged 75 commits into from
Sep 15, 2023
Merged

Add operational modes #406

merged 75 commits into from
Sep 15, 2023

Conversation

andrea-pasquale
Copy link
Contributor

@andrea-pasquale andrea-pasquale commented Jun 19, 2023

In this PR I propose to add different operational modes to split acquisition, fitting and report generation.
To achieve this I've added 3 new commands in qibocal:

  • qq acquire <runcard> which performs the data acquisition (without generating the report)
  • qq fit <output_folder> which performs the fitting/post-processing on a folder containing only the data acquisition
  • qq report <output_folder> which generates the html report from an output folder

qq is now an empty command. To run autocalibration the default command will be qq auto.

In this PR I still need to fix tests and coverage.

Things to be fixed before merging:

  • restore possibility to call qq fit (currently it is not possible because the task.run uses yield and the first output will always be the acquisition)
  • fix RB to work with the new layout
  • fix tune landscape
  • restore iterative dump
  • fix loading and saving of single shot classification with classifiers
  • check that everything works with all protocols
  • implement recursive deserialization

Let me know what you think.

Checklist:

  • Reviewers confirm new code works as expected.
  • Tests are passing.
  • Coverage does not decrease.
  • Documentation is updated.

pyproject.toml Outdated Show resolved Hide resolved
@andrea-pasquale andrea-pasquale mentioned this pull request Jun 26, 2023
4 tasks
src/qibocal/cli/builders.py Outdated Show resolved Hide resolved
src/qibocal/cli/builders.py Outdated Show resolved Hide resolved
src/qibocal/utils.py Outdated Show resolved Hide resolved
src/qibocal/utils.py Outdated Show resolved Hide resolved
src/qibocal/web/templates/template.html Outdated Show resolved Hide resolved
src/qibocal/protocols/characterization/allxy/allxy.py Outdated Show resolved Hide resolved
@andrea-pasquale
Copy link
Contributor Author

andrea-pasquale commented Jun 26, 2023

Since there are some conflicts and I'm modifying the base branch of this PR I would suggest you to wait to review this PR @stavros11 @alecandido.
After we merge #403 I will fix conflicts and then you can review.

EDIT: too late ahahah

Co-authored-by: Alessandro Candido <[email protected]>
@andrea-pasquale andrea-pasquale mentioned this pull request Jun 27, 2023
4 tasks
Base automatically changed from save_fit to main June 28, 2023 09:48
@alecandido
Copy link
Member

@andrea-pasquale now that you merged #403, this should be merged/rebased on current main.

@andrea-pasquale
Copy link
Contributor Author

@andrea-pasquale now that you merged #403, this should be merged/rebased on current main.

Done @alecandido.
I still need to address some of your previous comments.
All the commands work except from qq fit. The reason is that I'm not sure how to implement it following #403 (comment) (using a generator to yield first data and then resutls). It is a bit awkward now given that some users may want to perform post-processing on a folder which already contains data without re-acquiring data.

I know how to solve it by removing the yield. I don't know if there is some value in keeping this mechanism while finding a solution for qq fit. What do you suggest?

Copy link
Member

@alecandido alecandido left a comment

Choose a reason for hiding this comment

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

I still didn't review the routines, and I should take a second look at builders.py.

src/qibocal/auto/execute.py Outdated Show resolved Hide resolved
src/qibocal/auto/execute.py Outdated Show resolved Hide resolved
src/qibocal/auto/execute.py Outdated Show resolved Hide resolved
src/qibocal/auto/history.py Outdated Show resolved Hide resolved
src/qibocal/auto/history.py Outdated Show resolved Hide resolved
src/qibocal/auto/operation.py Outdated Show resolved Hide resolved
src/qibocal/auto/operation.py Outdated Show resolved Hide resolved
src/qibocal/auto/operation.py Outdated Show resolved Hide resolved
src/qibocal/utils.py Outdated Show resolved Hide resolved
src/qibocal/web/templates/template.html Show resolved Hide resolved
Copy link
Member

@alecandido alecandido left a comment

Choose a reason for hiding this comment

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

If you want to merge, just do it.
Everything else could be solved in separate issues.

However, I believe that the current priority of Qibocal is to reduce and simplify the infrastructure. We should try to what we are doing with the minimal (as reasonable amount of) code.

In particular, I would not care too much about what is inside protocols/, but attempt to polish everything else (eventually, I'd also like to review protocols, and improve the code in there, but in a sense we could start considering protocols as plugins, and actually expose a Plugin API for extending Qibocal).

@dataclass
class Completed:
"""A completed task."""
def add_timings_to_meta(meta, history):
Copy link
Member

Choose a reason for hiding this comment

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

The merge function can be arbitrarily improved, e.g.

  • we can make a deep merge, recursively
  • we can decide which one overwrites the other in case of duplicates

However, if these two are the conditions, or something similar, we could make a simpler and reusable function, rather than spelling out the condition for each field.

The principle is to try to adopt a broader perspective (for simplicity, thus maintainability, and reusability of solutions), instead of solving problems case by case.

Anyhow, it's definite not the uttermost relevant piece of code. So, if merging is more relevant, keep going.

# FIXME: I'm not too sure why but the code doesn't work anymore
# with this line. We can postpone it when we will have the
# ExceptionalFlow.
# completed.task.iteration += 1
Copy link
Member

Choose a reason for hiding this comment

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

I agree on the conclusion that we should take a deeper look in a separate PR.

However, the idea should be relatively simple: tasks are nodes of the original graph, unique in there, and they all start with zero iterations each.
Since you can pass more than once from each node, multiple completions are possible. Every time you complete a node, you create a completion (Completed instance) with the task id and the current iterations, while you increase the iteration number.

Of course, the task has no path on its own, since data are associated to completions. A completion instead has a path, and it's unique (because tasks are unique in the graph, and each completion of a given task has a unique incremental) and associated to uid = (id, iteration).

If all the assumptions are satisfied, there should be no problem. My guess is that at the moment maximum one iteration is happening, because loops are absent, and the Task is abused in place of the Completed. But I haven't inspected the code.

@dataclass
class Completed:
"""A completed task."""
def add_timings_to_meta(meta, history):
Copy link
Member

Choose a reason for hiding this comment

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

Even better: Completed contains a whole Task, and most likely it is not deeply copied, so it keeps being mutated under the hood.

The easiest is simplifying Completed storing only the task id, such that it could still get access to the task if strictly needed, but with less moving parts.

)


def autocalibrate(card, folder, force, update):
Copy link
Member

Choose a reason for hiding this comment

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

For the time being, it is fine like this, at least the classes have been simplified.

However, autocalibrate should be the concatenation of the other three actions (composing them gives us fewer cases), so the function should be call the others.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know. Potentially the autocalibrate will become more complicated than a simple acquisition followed by a fitting. But for sure we could recover some parts from acquire and fit. Let's do it in a separate PR as you suggested.

runcard = Runcard.load(yaml.safe_load((path / RUNCARD).read_text()))
executor = Executor.load(
runcard, path, update=update, platform=runcard.platform_obj
)
Copy link
Member

Choose a reason for hiding this comment

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

These operations are also repeated, so we might consider splitting them.

Not needed now, but keep in mind to reexamine later on.

@andrea-pasquale andrea-pasquale changed the base branch from main to twpa_again September 12, 2023 09:14
Copy link
Contributor

@Edoardo-Pedicillo Edoardo-Pedicillo left a comment

Choose a reason for hiding this comment

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

runcards/actions_qq.yml Outdated Show resolved Hide resolved
Base automatically changed from twpa_again to main September 15, 2023 13:29
@andrea-pasquale andrea-pasquale added this pull request to the merge queue Sep 15, 2023
Merged via the queue into main with commit aabc7f0 Sep 15, 2023
20 checks passed
@andrea-pasquale andrea-pasquale deleted the report_from_file branch September 15, 2023 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants