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

Debug/energy #30

Merged
merged 35 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1e084ee
Debugging energy calculation
mxburns2022 Sep 11, 2024
dd52f86
Fixed amplitude input issue
mxburns2022 Sep 11, 2024
ddeee8f
debugging, removed extraneous terms
mxburns2022 Sep 27, 2024
ee6cb00
Fixed input amplitude I/O, added example problems
mxburns2022 Sep 27, 2024
72ee6e8
no symmetries
mxburns2022 Oct 8, 2024
72eb4b0
Make default value match with help in main.cpp
Firepanda415 Oct 18, 2024
8d24710
Much clearer callback and result summary
Firepanda415 Oct 18, 2024
9619834
More result summary information
Firepanda415 Oct 18, 2024
cd5935a
finialize printout for UCCSD
Firepanda415 Oct 22, 2024
f6560f3
Backup file for UCCSD without symmetry, for comparing with the symmet…
Firepanda415 Oct 22, 2024
5f3f38f
cleaning uccsd
mxburns2022 Oct 23, 2024
68109eb
Added symm flag
mxburns2022 Oct 23, 2024
9bd8a57
Added one extra level to symmetries
mxburns2022 Oct 23, 2024
151ed41
Symm=4 working
mxburns2022 Oct 24, 2024
f842566
Recreate Qiskit's scheme for UCCSD in NWQSim
Firepanda415 Oct 24, 2024
c5a46ee
Fixed the calculation on number of alpha-alpha and beta-beta doubles
Firepanda415 Oct 25, 2024
c9eecf8
Forgot to remove 2* on n_doubles after my previous fix
Firepanda415 Oct 25, 2024
be22bfb
more informative printouts
Firepanda415 Oct 27, 2024
0339bbb
not needed since we have symm 0
Firepanda415 Oct 28, 2024
26b4cea
Add full symmetries
Firepanda415 Oct 29, 2024
5211188
Add option for using qiskit-like ansatz
Firepanda415 Nov 4, 2024
3df0476
clearly a mistake in the past
Firepanda415 Nov 6, 2024
04bf242
Apply fixes on the symmetries for UCCSD ansatz in VQE and Adapt-VQE. …
Firepanda415 Dec 2, 2024
a1b0d3a
change uccsdqis to uccsdmin, and make it the default UCCSD. Matt's UC…
Firepanda415 Dec 5, 2024
15109a3
Add documents and Singlet GSD is working. This ones gives better appr…
Firepanda415 Dec 6, 2024
0654e72
quick correction on DUCC qubit indexing and singlet gsd
Firepanda415 Dec 6, 2024
a3dcf82
finish singlet gsd on adapt-vqe
Firepanda415 Dec 6, 2024
c8aac59
Fix doc and finalize some formats
Firepanda415 Dec 6, 2024
8367a08
slight adjustment on ADAPT-VQE
Firepanda415 Dec 9, 2024
a496866
clear up ansates
Firepanda415 Dec 10, 2024
ce70c66
fix for prev. commit and bounds for optimizer under mpi
Firepanda415 Dec 10, 2024
3ae87e8
fix mistake on the previous day on ansatz and pool, unify qflow.cpp a…
Firepanda415 Dec 11, 2024
57d352c
update docs
Firepanda415 Dec 11, 2024
6b288fe
Merge branch 'main' into debug/energy
Firepanda415 Dec 11, 2024
6b6b532
adjustments to main branch changes
Firepanda415 Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ if(CUDAToolkit_FOUND)
set(CMAKE_CUDA_ARCHITECTURES "${CUDA_ARCH}")
endif()

set(CMAKE_CUDA_FLAGS_DEBUG "-g -G")

# set(CMAKE_CUDA_FLAGS_DEBUG "-g -G")

set(CMAKE_CUDA_FLAGS_RELEASE "-O3")
set(CMAKE_CUDA_STANDARD 17)
Expand Down
55 changes: 1 addition & 54 deletions VERSION.txt
Original file line number Diff line number Diff line change
@@ -1,54 +1 @@
2.5.0
2^ 0 :: 4.860889e+00
3^ 0 :: 1.215927e+00
2^ 1 :: 6.037454e-02
3^ 1 :: 6.036514e+00
6^ 4 :: 3.630773e+00
7^ 4 :: 4.970384e+00
6^ 5 :: 2.304436e+00
7^ 5 :: 2.063374e-01
2^ 6^ 4 0 :: 4.449431e+00
2^ 6^ 5 0 :: 5.448004e+00
3^ 6^ 4 0 :: 2.592272e+00
3^ 6^ 5 0 :: 4.937449e+00
2^ 6^ 4 1 :: 5.097959e+00
2^ 6^ 5 1 :: 2.644317e+00
3^ 6^ 4 1 :: 5.000318e-01
3^ 6^ 5 1 :: 5.481111e+00
2^ 7^ 4 0 :: 5.924450e-01
2^ 7^ 5 0 :: 6.053923e+00
3^ 7^ 4 0 :: 2.939819e+00
3^ 7^ 5 0 :: 4.725854e+00
6^ 7^ 4 5 :: 5.227969e+00
2^ 3^ 0 1 :: 5.081496e+00
2^ 7^ 4 1 :: 5.406291e+00
2^ 7^ 5 1 :: 8.847376e-01
3^ 7^ 4 1 :: 5.689913e+00
3^ 7^ 5 1 :: 2.063626e+00

[((0,), (2,)),
((0,), (3,)),
((1,), (2,)),
((1,), (3,)),
((4,), (6,)),
((4,), (7,)),
((5,), (6,)),
((5,), (7,)),
((0, 1), (2, 3)),
((0, 4), (2, 6)),
((0, 4), (2, 7)),
((0, 5), (2, 6)),
((0, 5), (2, 7)),
((0, 4), (3, 6)),
((0, 4), (3, 7)),
((0, 5), (3, 6)),
((0, 5), (3, 7)),
((1, 4), (2, 6)),
((1, 4), (2, 7)),
((1, 5), (2, 6)),
((1, 5), (2, 7)),
((1, 4), (3, 6)),
((1, 4), (3, 7)),
((1, 5), (3, 6)),
((1, 5), (3, 7)),
((4, 5), (6, 7))]
2.5.0
114 changes: 64 additions & 50 deletions vqe/README.md

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions vqe/docs/components/adapt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ADAPT-VQE

Note that `state->optimize()` (the VQE subroutine) is override in `vqe/include/vqe_state.hpp`, `vqe/include/svsim_vqe/sv_mpi_vqe.hpp`, and `vqe/include/svsim_vqe/sv_cuda_mpi_vqe.cuh`

Current termination flags for ADAPT-VQE:
```shell
0 -> Reach the gradient norm tolerance
1 -> Reach the function tolerance
2 -> Reach the maximum number of ADAPT iterations
9 -> ADAPT iteration is not run successfully
```
39 changes: 18 additions & 21 deletions vqe/docs/components/circuits.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ansatzë
# Ansätze
Here we describe the `Ansatz` base class and its core data structures, as well as the `UCCSD` subclass.

## Ansatz Base Class
Expand All @@ -14,9 +14,9 @@ class Ansatz: public Circuit {
std::unordered_map<std::string, IdxType> excitation_index_map;
```

The Ansatz constructor only requires the number of qubits: `Ansatz(IdxType n_qubits)`. However, after construction the Ansatz requires a call to `buildAnsatz`. For example:
The Ansatz constructor only requires the number of qubits: `Ansatz(IdxType n_qubits)`. However, after construction, the Ansatz requires a call to `buildAnsatz`. For example:
```c++
UCCSD test_ansatz(10); // 10 qubit UCCSD
UCCSD test_ansatz(10); // 10 qubit UCCSD
test_ansatz.buildAnsatz();
```
The separate call is used by some Ansatz subclasses (namely `DynamicAnsatz`) to build the circuit after some initial step, such as setting the operator pool.
Expand All @@ -39,9 +39,9 @@ This is how symmetry groups are explicitly implemented, explained in the UCCSD s
5. `std::unordered_map<std::string, IdxType> excitation_index_map`: Used to map between Fermionic operator strings and parameter indices. Used for explicit parameter inputs for `QFlow`.

### Functions
The `Ansatz` class implements the following functions.
The `Ansatz` class implements the following functions:

The first two implement parameterized circuit modification:
The first two implement parameterized circuit modification:
1. `void assignGateParam(IdxType gate_index, ValType param)`: Assign a single gate angle
2. `virtual void setParams(const std::vector<ValType>& params)`: Update the parameter vector and all gate angles

Expand All @@ -51,15 +51,11 @@ The next two are general circuit utilities found to be useful
3. `std::string toQASM3()` (Work in Progress): Return the parameterized circuit as a OpenQASM3 formatted string. QASM3 is required for unbound parameters, otherwise the circuit would need to fix the gate angles.
4. `void compose(const Circuit& other, std::vector<IdxType>& qubit_mapping)`: Compose the Ansatz with another circuit (e.g. for measurement). Also just a generally useful utility for circuit construction

The following two are used for ansatz construction using Pauli operators


5. `void OneParamGate(enum OP _op_name...)`: Construct a single parameterized gate and update the associated data structures. Called by ExponentialGate, by default assumed to be an `RZ` gate. NOTE: To use with DMSim this would have to be modified to support the gate type as an input to match arbitrary bases.
The following two are used for ansatz construction using Pauli operators:
5. `void OneParamGate(enum OP _op_name...)`: Construct a single parameterized gate and update the associated data structures. Called by ExponentialGate, by default assumed to be an `RZ` gate. NOTE: To use with DMSim, this would have to be modified to support the gate type as an input to match arbitrary bases
6. `void ExponentialGate(const PauliOperator& pauli_op...)`: Construct an operator evolving $e^{pauli_op}$. Here we assume `pauli_op` already has the appropriate phase/coefficients. The circuit constructs a basic CNOT ladder terminating at the first non-identity qubit. NOTE: Room for optimization via Paulihedral or Tetris for 2-qubit gate cancellation

The following three functions are non implemented in the base class, and require overloading:


The following three functions are not implemented in the base class and require overloading:
7. `std::vector<std::string> getFermionicOperatorStrings()`: Return the string representations of the operators used to construct the Ansatz. Despite the name, these may also be Pauli operators in the case of Qubit-ADAPT
8. `std::vector<std::pair<std::string, ValType> > getFermionicOperatorParameters()`: Return the string representations of the Fermionic operators used to construct the Ansatz along with their associated excitations. Note that there are more strings returned than parameters, as we print all members of a symmetry group and their spin-reversed forms.

Expand Down Expand Up @@ -112,21 +108,25 @@ symmetries[1] = {{0, 1.0}};
fermion_ops_to_params[0] = 0;
```

A symmetry is further used to reduce the number of parameters required for both single and double excitations, in general there are two cases:
1. When two operators only differ in the spin but not spin-orbital index: $t_{I(\alpha)}^{A(\alpha)} = t_{I(\beta)}^{A(\beta)}$ and $t_{I(\alpha)J(\alpha)}^{A(\alpha)B(\alpha)} = t_{I(\beta)J(\beta)}^{A(\beta)B(\beta)}$
2. For double exicitations, when the order of indices flipped for creation and annihilation operators: $t_{I(\alpha)J(\beta)}^{A(\alpha)B(\beta)} = t_{J(\alpha)I(\beta)}^{B(\alpha)A(\beta)}$

<--
However, the number of double excitations requires a bit more combinatorics. We can delineate *mixed terms* (where all spatial orbitals are unique) from *degenerate terms* (where either the annihilation or creation operators share a spatial orbital). These two groups have different symmetry expressions:

Using bars to denote spin orientation ($\alpha_i$ for a spin up annihilation, $\beta_i$ for spin down), we can express the symmetries for mixed excitations as follows:

$$
```math
\alpha_i^\dagger\alpha_j^\dagger\alpha_r\alpha_s=\beta_i^\dagger\beta_j^\dagger\beta_r\beta_s=\alpha_i^\dagger\beta_j^\dagger\beta_r\alpha_s+\alpha_i^\dagger\beta_j^\dagger\alpha_r\beta_s=\beta_i^\dagger\alpha_j^\dagger\alpha_r\beta_s+\beta_i^\dagger\alpha_j^\dagger\beta_r\alpha_s
$$
```

whereas degenerate excitations have the symmetry:
$$
```math
\beta_i^\dagger\alpha_j^\dagger\alpha_r\beta_r=\beta_j^\dagger\alpha_i^\dagger\alpha_r\beta_r
$$
with a similar form for degenerate virtual orbitals.

```
with a similar form for degenerate virtual orbitals.)
-->


### Construction
Expand Down Expand Up @@ -175,6 +175,3 @@ for (auto& fermionic_group: pauli_oplist) {
}
```
The same step is repeated if multiple Trotter steps are requested. The UCCSD Ansatz is now ready for simulation.



12 changes: 6 additions & 6 deletions vqe/docs/components/expectation_values.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
Here we discuss the method of computing expectation values in NWQ-Sim, starting with the relevant data structures and then discussing simulation details.

For an operator in the diagonal basis of the form:
$$
```math
P_i=c_i\bigotimes_{j}Z_j
$$
```
where identity operators are implicit between the qubits $j$. The expectation value with respect to a statevector $\vert \psi\rangle$ can be computed as:
$$
```math
\langle \psi\vert P_i\vert \psi\rangle=\sum_{j=1}^{2^N}c_jParity(j, P_i)|\psi_{j}|^2
$$
```
where $Parity(j, P_i)$ measures the bitwise parity between the Z stabilizer array of $P_i$ and the binary representation of index $j$. For example, $IZZI$ yields the stabilizer $0110$, which has an even parity with $6=0110$ (+1) and an odd parity with $5=0101$ (-1). To compute each expectation value, we need to:
1. Diagonalize the Pauli operator with a measurement circuit
2. Compute and store the summation above
3. Reverse the diagonalization to return to the previous statevector.
3. Reverse the diagonalization to return to the previous statevector


## ObservableLists
Expand All @@ -30,4 +30,4 @@ struct ObservableList {
- `coeffs` stores the Pauli coefficients
- `numterms` stores the number of Pauli terms to compute for which we compute the expectation value (equivalently, the size of `zmasks` and `coeffs`)

Each `ObservableList` object and its fields are allocated either in the `fill_obslist` or ``
Each `ObservableList` object and its fields are allocated in the `fill_obslist` funtction.
Loading