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

QCQMC notebook refactor #356

Merged
merged 40 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3e38a11
Add some tests for unit test.
fdmalone Jun 28, 2024
bcb3d4f
Tidy up.
fdmalone Jun 28, 2024
aa622a5
Converters.
fdmalone Jun 28, 2024
9285e4d
Test slow test solution.
fdmalone Jun 28, 2024
b5d88a0
Add tests for qubit_maps.
fdmalone Jun 28, 2024
a50a58f
Update tests.
fdmalone Jun 28, 2024
9a29bc2
Add trial tests.
fdmalone Jun 28, 2024
b60599e
Add generators test.
fdmalone Jun 28, 2024
caa0046
Add missing changes.
fdmalone Jun 28, 2024
4330f42
Remove debug code.
fdmalone Jun 28, 2024
7817f73
Remove prints.
fdmalone Jun 28, 2024
64017f8
Remove redundant test docstrings.
fdmalone Jun 28, 2024
58fadff
Add blueprint.
fdmalone Jun 20, 2024
08dd528
Skip slow test.
fdmalone Jun 29, 2024
7ddae81
Move conftest and skip another slow test.
fdmalone Jun 29, 2024
33ed0cd
Fix serialization.
fdmalone Jun 29, 2024
7227dfc
Fix _json_dict_.
fdmalone Jun 29, 2024
2585997
Merge branch 'master' into qcqmc-6
fdmalone Jul 1, 2024
d66c1e1
Remove comparator.
fdmalone Jul 1, 2024
fa71795
Fix merge errors.
fdmalone Jul 1, 2024
825af2e
Add experiment class.
fdmalone Jun 29, 2024
4fc0425
Fix fixture.
fdmalone Jun 29, 2024
9736332
Add check for serialization.
fdmalone Jun 29, 2024
9011803
Add experiment.
fdmalone Jun 29, 2024
2a1d750
Add overlap analysis.
fdmalone Jun 29, 2024
c27c0e7
Add missing file!
fdmalone Jun 29, 2024
def9ea8
Add code for integration with ipie.
fdmalone Jul 1, 2024
083f217
Merge branch 'master' into qcqmc-notebook-refactor
fdmalone Jul 2, 2024
395deb2
Update paths.
fdmalone Jul 2, 2024
712f545
Merge fix.
fdmalone Jul 2, 2024
b29776a
Fix merge.
fdmalone Jul 2, 2024
cf7fec7
Remove print.
fdmalone Jul 2, 2024
657d82f
Format.
fdmalone Jul 2, 2024
e1283df
Format.
fdmalone Jul 2, 2024
291ff49
Move dot to path_prefix.
fdmalone Jul 3, 2024
19003f9
Fix path for tests.
fdmalone Jul 3, 2024
2a09376
Add missing license.
fdmalone Jul 3, 2024
eb0f9c2
Add missing index.
fdmalone Jul 3, 2024
f199092
Address review comments.
fdmalone Jul 11, 2024
f6493df
Merge branch 'master' into qcqmc-notebook-refactor
fdmalone Jul 12, 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
77 changes: 70 additions & 7 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Tuple
import pathlib
from typing import Dict, Tuple

import numpy as np
import pytest

from recirq.qcqmc import blueprint, qubit_maps
from recirq.qcqmc import analysis, blueprint, data, experiment, qubit_maps
from recirq.qcqmc.hamiltonian import (
HamiltonianData,
HamiltonianFileParams,
Expand All @@ -30,9 +31,18 @@


@pytest.fixture(scope="package")
def fixture_4_qubit_ham() -> HamiltonianData:
def package_tmp_path(tmp_path_factory: pytest.TempPathFactory) -> pathlib.Path:
return tmp_path_factory.mktemp("data", numbered=True)


@pytest.fixture(scope="package")
def fixture_4_qubit_ham(package_tmp_path) -> HamiltonianData:
params = HamiltonianFileParams(
name="test hamiltonian 4 qubits", integral_key="fh_sto3g", n_orb=2, n_elec=2
name="test hamiltonian 4 qubits",
integral_key="fh_sto3g",
n_orb=2,
n_elec=2,
path_prefix=str(package_tmp_path),
)

hamiltonian_data = build_hamiltonian_from_file(params)
Expand All @@ -41,9 +51,13 @@ def fixture_4_qubit_ham() -> HamiltonianData:


@pytest.fixture(scope="package")
def fixture_8_qubit_ham() -> HamiltonianData:
def fixture_8_qubit_ham(package_tmp_path) -> HamiltonianData:
params = HamiltonianFileParams(
name="test hamiltonian 8 qubits", integral_key="h4_sto3g", n_orb=4, n_elec=4
name="test hamiltonian 8 qubits",
integral_key="h4_sto3g",
n_orb=4,
n_elec=4,
path_prefix=str(package_tmp_path),
)

hamiltonian_data = build_hamiltonian_from_file(params)
Expand All @@ -52,13 +66,14 @@ def fixture_8_qubit_ham() -> HamiltonianData:


@pytest.fixture(scope="package")
def fixture_12_qubit_ham() -> HamiltonianData:
def fixture_12_qubit_ham(package_tmp_path) -> HamiltonianData:
params = HamiltonianFileParams(
name="test hamiltonian 12 qubits",
integral_key="diamond_dzvp/cas66",
n_orb=6,
n_elec=6,
do_eri_restore=True,
path_prefix=str(package_tmp_path),
)

hamiltonian_data = build_hamiltonian_from_file(params)
Expand All @@ -76,6 +91,7 @@ def fixture_4_qubit_ham_and_trial_wf(
heuristic_layers=tuple(),
do_pp=True,
restricted=True,
path_prefix=fixture_4_qubit_ham.params.path_prefix,
)

trial_wf = build_pp_plus_trial_wavefunction(
Expand All @@ -96,6 +112,7 @@ def fixture_8_qubit_ham_and_trial_wf(
initial_orbital_rotation=None,
initial_two_body_qchem_amplitudes=np.asarray([0.3, 0.4]),
do_optimization=False,
path_prefix=fixture_8_qubit_ham.params.path_prefix,
)

trial_wf = build_pp_plus_trial_wavefunction(
Expand All @@ -120,6 +137,7 @@ def fixture_4_qubit_ham_trial_wf_and_blueprint(
tuple(qubit_maps.get_qubits_a_b_reversed(n_orb=trial_wf_params.n_orb)),
),
seed=1,
path_prefix=ham_data.params.path_prefix,
)

bp = blueprint.BlueprintData.build_blueprint_from_dependencies(
Expand All @@ -129,6 +147,51 @@ def fixture_4_qubit_ham_trial_wf_and_blueprint(
return ham_data, trial_wf_data, bp


@pytest.fixture(scope="package")
def fixture_4_qubit_ham_trial_wf_and_overlap_analysis(
fixture_4_qubit_ham_trial_wf_and_blueprint,
) -> Tuple[HamiltonianData, TrialWavefunctionData, analysis.OverlapAnalysisData]:
"""Construct fixtures for the hamiltonian, trial wavefunction and overlap analysis.

Returns:
ham_data: The hamiltonian for the 4 qubit test system.
trial_wf_data: The trial wavefunction data for the 4 qubit system.
ovlp_analysis: The overlap analysis data used to reconstruct the
wavefunction via shadow tomography.
"""
ham_data, trial_wf_data, bp_data = fixture_4_qubit_ham_trial_wf_and_blueprint
simulated_experiment_params = experiment.SimulatedExperimentParams(
name="test_1",
blueprint_params=bp_data.params,
noise_model_name="None",
noise_model_params=(0,),
n_samples_per_clifford=10,
seed=1,
path_prefix=ham_data.params.path_prefix,
)
exp = experiment.ExperimentData.build_experiment_from_dependencies(
params=simulated_experiment_params, dependencies={bp_data.params: bp_data}
)

analysis_params = analysis.OverlapAnalysisParams(
"TEST_analysis",
experiment_params=exp.params,
k_to_calculate=(1,),
path_prefix=ham_data.params.path_prefix,
)
all_dependencies: Dict[data.Params, data.Data] = {
ham_data.params: ham_data,
trial_wf_data.params: trial_wf_data,
bp_data.params: bp_data,
simulated_experiment_params: exp,
}
ovlp_analysis = analysis.OverlapAnalysisData.build_analysis_from_dependencies(
analysis_params, dependencies=all_dependencies
)

return ham_data, trial_wf_data, ovlp_analysis


def pytest_addoption(parser):
parser.addoption("--skipslow", action="store_true", help="skips slow tests")

Expand Down
26 changes: 26 additions & 0 deletions docs/qcqmc/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# QCQMC

Notebooks outlining how to reproduce the results of [Unbiasing fermionic quantum Monte Carlo with a quantum computer](https://www.nature.com/articles/s41586-021-04351-z).
Quantum Monte Carlo methods are a class of classical algorithms that can offer
an efficient solution to the many-electron schroedinger equation but are plagued
by the `fermion sign problem`. Typically, a constraint is introduced to overcome
this problem at the cost of introducing an uncontrolled bias in the results. In
this paper, it was shown that a quantum computer could be used to prepare
complicated trial wavefunctions in order to unbias the classical results.

## Code Overview
The [Code Overview](./high-level.ipynb) notebook introduces the basic structure
of the code provided in recirq to generate the trial wavefunction's prepare in the [QCQMC paper](https://www.nature.com/articles/s41586-021-04351-z).

## End-to-End
The [End-to-End](./full_workflow.ipynb) notebook provides and end-to-end example
for the H4 molecule and interfaces with ipie to produce numbers similar to those
reported in the [QCQMC](https://www.nature.com/articles/s41586-021-04351-z)
paper.


## Experimental Wavefunctions

The [Experimental Wavefunctions](./experimental_wavefunctions.ipynb) notebook demonstrates
how to download and analyze the experimental wavefunctions, which can reproduce
the results in [QCQMC](https://www.nature.com/articles/s41586-021-04351-z).
5 changes: 5 additions & 0 deletions recirq/qcqmc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ def _resolve_json(cirq_type: str) -> Optional[ObjectFactory]:
PyscfHamiltonianParams,
SimulatedExperimentParams,
TrialWavefunctionData,
BlueprintParamsTrialWf,
BlueprintParamsRobustShadow,
BlueprintData,
ExperimentData,
SimulatedExperimentParams,
]
}.get(cirq_type, None)

Expand Down
2 changes: 1 addition & 1 deletion recirq/qcqmc/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class OverlapAnalysisParams(data.Params):
name: str
experiment_params: experiment.SimulatedExperimentParams
k_to_calculate: Tuple[int, ...] = attrs.field(converter=tuple)
path_prefix: str = ""
path_prefix: str = "."

def __attrs_post_init__(self):
if not isinstance(
Expand Down
5 changes: 3 additions & 2 deletions recirq/qcqmc/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import numpy as np
import quaff

from recirq.qcqmc import config, data, trial_wf, for_refactor
from recirq.qcqmc import config, data, for_refactor, trial_wf

BlueprintParams = Union["BlueprintParamsTrialWf", "BlueprintParamsRobustShadow"]

Expand Down Expand Up @@ -132,7 +132,7 @@ class BlueprintParamsTrialWf(data.Params):
)
seed: int = 0
optimizer_suite: int = 0
path_prefix: str = ""
path_prefix: str = "."

@property
def path_string(self) -> str:
Expand Down Expand Up @@ -190,6 +190,7 @@ class BlueprintData(data.Data):
def _json_dict_(self):
simple_dict = attrs.asdict(self)
simple_dict["params"] = self.params
return simple_dict

@property
def resolved_clifford_circuits(self) -> Iterator[Tuple[cirq.Circuit, ...]]:
Expand Down
10 changes: 4 additions & 6 deletions recirq/qcqmc/blueprint_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
import pytest
import quaff

from recirq.qcqmc.blueprint import (
BlueprintParamsTrialWf,
_get_truncated_cliffords,
BlueprintData
)
from recirq.qcqmc.blueprint import (BlueprintData, BlueprintParamsTrialWf,
_get_truncated_cliffords)
from recirq.qcqmc.hamiltonian import HamiltonianData, HamiltonianFileParams
from recirq.qcqmc.qubit_maps import get_qubits_a_b_reversed
from recirq.qcqmc.trial_wf import TrialWavefunctionData, TrialWavefunctionParams
from recirq.qcqmc.trial_wf import (TrialWavefunctionData,
TrialWavefunctionParams)


class FakeTrialWfParams(TrialWavefunctionParams):
Expand Down
12 changes: 6 additions & 6 deletions recirq/qcqmc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
class OutputDirectories:
"""Default output directories for qcqmc data."""

DEFAULT_HAMILTONIAN_DIRECTORY: str = "./data/hamiltonians/"
DEFAULT_TRIAL_WAVEFUNCTION_DIRECTORY: str = "./data/trial_wfs/"
DEFAULT_QMC_DIRECTORY: str = "./data/afqmc/"
DEFAULT_BLUEPRINT_DIRECTORY: str = "./data/blueprints/"
DEFAULT_EXPERIMENT_DIRECTORY: str = "./data/experiments/"
DEFAULT_ANALYSIS_DIRECTORY: str = "./data/analyses/"
DEFAULT_HAMILTONIAN_DIRECTORY: str = "/data/hamiltonians/"
DEFAULT_TRIAL_WAVEFUNCTION_DIRECTORY: str = "/data/trial_wfs/"
DEFAULT_QMC_DIRECTORY: str = "/data/afqmc/"
DEFAULT_BLUEPRINT_DIRECTORY: str = "/data/blueprints/"
DEFAULT_EXPERIMENT_DIRECTORY: str = "/data/experiments/"
DEFAULT_ANALYSIS_DIRECTORY: str = "/data/analyses/"

def make_output_directories(self) -> None:
"""Make the output directories given in OUTDIRS"""
Expand Down
Loading
Loading