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

[WIP] Introduce partitioned_contract #97

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

Conversation

LinjianMa
Copy link
Contributor

@LinjianMa LinjianMa commented Jul 6, 2023

This PR is mainly used for discussion. We need to break it into pieces to merge.

APIs:

Given a partition par and its partial contraction tree contraction_tree, the function below performs the approximate contraction based on given parameters:

  • ansatz: can be mps or comb
  • approx_itensornetwork_alg: can be density_matrix or ttn_svd
  • linear_ordering_alg: can be top_down or bottom_up. This denotes the heuristic used to choose the MPS site ordering.
function partitioned_contract(
  par::DataGraph,
  contraction_tree::NamedDiGraph;
  ansatz="mps",
  approx_itensornetwork_alg="density_matrix",
  cutoff=1e-15,
  maxdim=10000,
  swap_size=1,
  contraction_sequence_alg,
  contraction_sequence_kwargs,
  linear_ordering_alg,
)

Instead of passing a partition and a contraction tree, one can also passing a contraction_sequence, which is a nested vector of ITensors. par and contraction_tree will then be produced internally.

function partitioned_contract(contraction_sequence::Vector; kwargs...)

One can also choose to let the package generate the partition and the contraction tree automatically. Given tn, the function below will generate a par and contraction_tree based on the recursive bisection algorithm, with each partition having approximately nvertices_per_partition number of vertices.

function contract(
  alg::Algorithm"partitioned_contract",
  tn::AbstractITensorNetwork;
  nvertices_per_partition::Integer=2,
  backend::String="KaHyPar",
  kwargs...,
)

Organization of the PR

  • examples/partitioned_contract contains codes to benchmark the algorithm. The implementations contain experiments on top of 3D grids, random regular graphs, and random quantum circuits.
  • src/contract.jl includes the new API for contract.
  • src/mincut.jl includes a new algorithm/heuristic for generating the binary tree structure and path graph structure. In particular, the existing algorithm is a bottom-up greedy algorithm, and another greedy top-down algorithm based on recursive bisection is added. The top-down algorithm is standard since recursive bisection is a common algorithm. For now it is unclear which one is better.
  • src/partitioned_contract/partitioned_contract.jl includes the implementations of partitioned_contract

@codecov-commenter
Copy link

codecov-commenter commented Jul 19, 2023

Codecov Report

Merging #97 (7e9ce10) into main (d1e9ba6) will decrease coverage by 10.89%.
The diff coverage is 13.39%.

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

@@             Coverage Diff             @@
##             main      #97       +/-   ##
===========================================
- Coverage   79.64%   68.75%   -10.89%     
===========================================
  Files          64       69        +5     
  Lines        3507     4276      +769     
===========================================
+ Hits         2793     2940      +147     
- Misses        714     1336      +622     
Impacted Files Coverage Δ
src/ITensorNetworks.jl 77.77% <ø> (ø)
src/approx_itensornetwork/ttn_svd.jl 100.00% <ø> (ø)
src/approx_itensornetwork/utils.jl 94.11% <ø> (ø)
src/contract.jl 36.84% <0.00%> (-63.16%) ⬇️
src/partitioned_contract/adjacency_tree.jl 0.00% <0.00%> (ø)
src/partitioned_contract/constrained_ordering.jl 0.00% <0.00%> (ø)
src/partitioned_contract/partitioned_contract.jl 0.00% <0.00%> (ø)
src/partitioned_contract/utils.jl 0.00% <0.00%> (ø)
src/mincut.jl 82.52% <62.79%> (-11.93%) ⬇️
src/approx_itensornetwork/density_matrix.jl 91.24% <65.71%> (-8.76%) ⬇️
... and 2 more

... and 9 files with indirect coverage changes

@@ -335,6 +328,97 @@ function _rem_vertex!(
return U
end

function _update_cache_w_low_rank_projector!(
::Algorithm"direct_eigen",
alg_graph::_DensityMartrixAlgGraph,
Copy link
Member

Choose a reason for hiding this comment

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

Just noticed this should be _DensityMatrixAlgGraph, not _DensityMartrixAlgGraph. Also I think it's best to remove the underscore.

@@ -22,6 +22,8 @@ function approx_itensornetwork(
partition_wo_deltas = _contract_deltas_ignore_leaf_partitions(
binary_tree_partition; root=root
)
density_matrix_alg =
alg isa Algorithm"density_matrix_direct_eigen" ? "direct_eigen" : "qr_svd"
Copy link
Member

Choose a reason for hiding this comment

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

It seems like the main use for Algorithm"density_matrix_direct_eigen" is this selection of the density_matrix_alg. Maybe simpler to just make density_matrix_alg a keyword argument directly and remove Algorithm"density_matrix_direct_eigen".

@@ -5,7 +5,7 @@ with the same binary tree structure. `root` is the root vertex of the
pre-order depth-first-search traversal used to perform the truncations.
"""
function approx_itensornetwork(
Copy link
Member

Choose a reason for hiding this comment

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

I forget why this was called approx_itensornetwork. Can this just be contract? It seems like it is just called from contract anyway.

kwargs...,
)
sequence = _partitioned_contraction_sequence(
tn; nvertices_per_partition=nvertices_per_partition, backend=backend
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
tn; nvertices_per_partition=nvertices_per_partition, backend=backend
tn; nvertices_per_partition, backend

In the more recent versions of Julia, you don't have to repeat the argument if it has the same name as the keyword in a keyword argument.

@mtfishman
Copy link
Member

Sorry for the very long delay in reviewing this, finally finding some time to take a look.

In terms of the API, instead of the partitioned_contract you propose above, what if it was the following:

function contract(
  alg::Algorithm"partitioned_contract",
  tn::AbstractITensorNetwork;
  sequence,
  backend::String="KaHyPar",
  kwargs...,
)

sequence would be a partial contraction sequence, by which I mean if the vertices are 1:10, it could be something like:

[[[1, 2, 3], [4, 5, 6]], [7, 8, 9, 10]]

This would complement the version that accepts nvertices_per_partition::Integer, which would generate a sequence with that format.

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.

3 participants