Skip to content

feat: Merge program set task results#1254

Open
speller26 wants to merge 2 commits into
splitfrom
merge
Open

feat: Merge program set task results#1254
speller26 wants to merge 2 commits into
splitfrom
merge

Conversation

@speller26
Copy link
Copy Markdown
Member

Introduce merge method to ProgramSetQuantumTaskResult that combines multiple results into one.

Issue #, if available:

Description of changes:

Testing done:

Merge Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your pull request.

General

Tests

  • I have added tests that prove my fix is effective or that my feature works (if appropriate)
  • I have checked that my tests are not configured for a specific region or account (if appropriate)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Introduce `merge` method to `ProgramSetQuantumTaskResult` that combines multiple results into one.
@speller26 speller26 requested a review from a team as a code owner May 10, 2026 21:47
@speller26 speller26 mentioned this pull request May 10, 2026
5 tasks
@speller26
Copy link
Copy Markdown
Member Author

If this is approved before #1249, we can merge this cleanly into the split branch and assume the files are reviewed in that PR.

Comment thread src/braket/tasks/program_set_quantum_task_result.py Outdated
return binding.to_ir()


def _count_executables(binding: CircuitBinding | Circuit) -> int:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Surprised CircuitBinding doesn't actually have a simple .executables property here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Mainly because there isn't really a class that encapsulates a single executable, so such a method would just return a list of tuples

return num_ps * num_obs


def _buffer_result(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we add a description to this function? The other ones are straightforward but this has more complexity and _buffer_result is a bit vague.

for composite in result.entries:
for entry in composite.entries:
if j >= len(map_k):
raise ValueError(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can this realistically happen? I guess if you have two programsets, where each one has the same total number of different numbers in the constituents?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, if you pass in the wrong merge list; this is just defensive, like the if j != len(parent_indices) below.

return ProgramSetQuantumTaskResult(
entries=entries,
task_metadata=ProgramSetTaskMetadata(
id=";".join(meta.id for meta in metas), # Better way to do this?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if there is a way to denote that this is just synthetic metadata, or an aggregate, and these are just convenience attributes. Unfortunately the best way for that would probably be a new schema, which seems excessive.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Or if task_metadata could have a union type with Sequence[ProgramSetTaskMetadata]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I can add a flag that triggers a warning the first time the metadata is accessed.

def _buffer_result(
k: int,
result: ProgramSetQuantumTaskResult,
map_k: list[int],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is like the composite_entry_map?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Map to the parent program set index

)
orig_idx = map_k[j]
binding_idx, ps_idx, obs_idx = executable_indices[orig_idx]
buffer[orig_idx] = _convert_measured_entry(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So map_k is some contiguous list between [0] and the composite entry number of executables, right? j is essentially a subindex, or the rank-2 index. So why is the buffer at along this index when the original buffer is len(total_executables), i.e. unfolded?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No, map_k's sublist actually starts where the previous sublist ended; it's the index in the parent program set. I'll rename accordingly.

Comment thread src/braket/tasks/program_set_quantum_task_result.py Outdated
And other minor changes
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.

2 participants