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

State synthesis for quantum devices #2291

Open
wants to merge 44 commits into
base: main
Choose a base branch
from

Conversation

annagrin
Copy link
Collaborator

@annagrin annagrin commented Oct 17, 2024

Synthesize state pointer for quantum devices:

SimulationState:

  • Add hasData API that returns true iff the vector data exists on the state or can be computed.
  • Add getKernelInfo API that returns optional kernel name and a list of arguments for the kernel that generated the state.

QuantumState:

  • Add QuantumState class that inherits from simulation state and keeps kernel information only.

ArgumentConversion:

  • Substitute state pointer argument with quake.get_state "callee.num_qubits_N" "callee.init_N" instruction.
  • Add callee.num_qubits_N and callee.init_N functions that are created from the callee code and compute allocation size and initialize the allocation, respectively.
  • Add a list of converters for the callees in ArgumentConverter.
  • Generate substitutions for modified callee functions, recursively.

Passes:

  • Add a post-synthesis ReplaceStateWithKernel pass that
    • replaces quake.get_num_qubits instructions by a call to callee.num_qubits_N()
    • replaces quake.init_state instructions by a call to callee.init_N()

Synthesis:

  • Collect all substitutions for the call tree at the synthesis time for quantum devices.

Tests:

  • Add fake quantum state and a test for quantum state argument conversion to test_argument_conversion
  • Add quake tests for ReplaceStateWithKernel pass
  • Add quake tests for ArgumentSynthesis pass with state pointer substitutions
  • Add targettests/execution/qvector_init_from_state.cpp test that runs for various quantum backends emulation

Notes

Currently state pointer synthesis is only supported for kernels implemented as operator() inside a struct.

TODO (in subsequent PRs)

  • c++ tests for quantum backend integration
  • Use cudaq::qkernel to support c-like kernels in state pointer synthesis
  • Tests for synthesis of vectors of pauli words (needs rework of pauli word support)
  • python tests for quantum platforms (needs support for new synthesis in python)

Requires: #2354

bmhowe23 and others added 4 commits October 17, 2024 14:33
I, Ben Howe <bhowe@nvidia.com>, hereby add my Signed-off-by to this commit: 86681ef

Signed-off-by: Ben Howe <bhowe@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
@annagrin annagrin force-pushed the quantum-device-state branch from 4517712 to 7969a75 Compare October 17, 2024 21:38
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Copy link
Collaborator

@1tnguyen 1tnguyen left a comment

Choose a reason for hiding this comment

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

LGTM 👍

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Copy link
Collaborator

@schweitzpgi schweitzpgi left a comment

Choose a reason for hiding this comment

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

Still reviewing...

include/cudaq/Optimizer/Builder/Intrinsics.h Outdated Show resolved Hide resolved
include/cudaq/Optimizer/Transforms/Passes.td Outdated Show resolved Hide resolved
include/cudaq/Optimizer/Transforms/Passes.td Outdated Show resolved Hide resolved
include/cudaq/Optimizer/Transforms/Passes.td Outdated Show resolved Hide resolved
include/cudaq/Optimizer/Transforms/Passes.td Outdated Show resolved Hide resolved
Copy link
Collaborator

@schweitzpgi schweitzpgi left a comment

Choose a reason for hiding this comment

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

Still reviewing...

lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateInitialization.cpp Outdated Show resolved Hide resolved
lib/Optimizer/Transforms/StateValidation.cpp Outdated Show resolved Hide resolved
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…antum-device-state

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…ate-ops

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…ate-ops

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
@annagrin annagrin marked this pull request as draft November 5, 2024 18:03
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…ate-ops

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…antum-device-state

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…antum-device-state

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…antum-device-state

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
I, Anna Gringauze <agringauze@nvidia.com>, hereby add my Signed-off-by to this commit: 9563371

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
…antum-device-state

Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
@annagrin annagrin marked this pull request as ready for review January 22, 2025 17:37
@annagrin annagrin requested a review from schweitzpgi January 22, 2025 17:37
Comment on lines +1487 to +1488
StrAttr:$numQubitsFuncName,
StrAttr:$initFuncName
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
StrAttr:$numQubitsFuncName,
StrAttr:$initFuncName
FlatSymbolRefAttr:$numQubitsFuncName,
FlatSymbolRefAttr:$initFuncName

If these are truly artifacts that shall be present in the IR, let's make them Symbol attrs.

Copy link
Collaborator Author

@annagrin annagrin Jan 23, 2025

Choose a reason for hiding this comment

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

If the signatures of those functions are changed by the synthesis, would this instruction get updated with symbols with new signatures during application of the substitution? I can try that and see if the synthesis works.

let arguments = (ins
StrAttr:$numQubitsFuncName,
StrAttr:$initFuncName
);
let results = (outs cc_PointerType:$result);
Copy link
Collaborator

@schweitzpgi schweitzpgi Jan 23, 2025

Choose a reason for hiding this comment

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

We probably want to force this to be a ptr<state>, no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do, thanks

Comment on lines +65 to +66
createArgumentSynthesisPass(const std::vector<std::string> &funcNames,
const std::vector<std::string> &substitutions);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need this? ArrayRef should subsume rigid std::vector here. I don't think we need this overload?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

std::vector<string> does not get auto-converted to ArrayRef<StringRef>... I can try ArrayRef<std::string> instead

return calleeConverters;
}

std::pair<std::vector<std::string>, std::vector<std::string>>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use SmallVector.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think i tried and something went wrong, will try again

llvm::raw_string_ostream ss(substBuff);
ss << argCon.getSubstitutionModule();
mlir::SmallVector<mlir::StringRef> substs = {substBuff};
auto [kernels, substs] = argCon.collectAllSubstitutions();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like you got in trouble here by moving the strings into another function, where they go out of scope and vanish.

Let's leave the string creation here, where it is. To change it might look a little nicer, but it is far less efficient. Instead of a single copy of the data, we're building vectors of copies of the data and passing those around. The LLVM Way (tm) is preferred in the compiler code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The nested argument converters (for kernels used in get_state calls) have their new kernel names, created during state argument conversion, so I moved the kernel name storage to the ArgumentConverter for the kernel.

I thought about an alternative of having a special "storage" for the new names collection and passing that storage by reference to ArgumentConverter and its children, but that does not seem to solve the problem of efficiency of copying the name for the entry kernel. I appreciate any ideas here!

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.

4 participants