Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
b4ae4d7
Working BP Commit
JoeyT1994 Oct 2, 2025
d77d063
BP Code
JoeyT1994 Oct 23, 2025
b80e36e
Express BP in terms of `SweepIterator` interface
jack-dunham Oct 28, 2025
fe44b80
Add method for `setmessages!` that allows messages from one cache to …
jack-dunham Oct 31, 2025
3ce0898
Network is now passed to `forest_cover_edge_sequence` directly.
jack-dunham Nov 10, 2025
f6e4fd0
test file formatting
jack-dunham Nov 25, 2025
63840a9
Add `DataGraphsPartitionedGraphsExt` glue for `TensorNetwork` type
jack-dunham Nov 25, 2025
ba22ab5
Make abstract tensor network interface more generic.
jack-dunham Nov 25, 2025
49b0870
BP Caching overhauls
jack-dunham Nov 25, 2025
db46c04
Remove dead deps
jack-dunham Nov 25, 2025
400e373
Fix merge
jack-dunham Nov 25, 2025
b9aafe8
Fix type inference in TensorNetwork construction
jack-dunham Nov 25, 2025
4090e61
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 25, 2025
be0750e
Remove `ITensorBase` dep
jack-dunham Nov 25, 2025
b971b89
`forest_cover_edge_sequence` now constructs a temporary `NamedGraph` …
jack-dunham Dec 1, 2025
9ebf031
[LazyNamedDimsArrays] Fix `parenttype` method
jack-dunham Jan 6, 2026
16fe303
BP Cache now uses new `DataGraphs`interface
jack-dunham Jan 6, 2026
24a4335
Adjust `default_message` to take a `message` type as its first argument
jack-dunham Jan 6, 2026
c43884e
Remove unnecessary code and fix ambiguities in `AbstractTensorNetwork`
jack-dunham Jan 6, 2026
dd6f645
`TensorNetwork` type now uses new DataGraphs interface
jack-dunham Jan 6, 2026
7bb579c
Sweeping algorithms based on AlgorithmsInterface.jl (#30)
mtfishman Dec 19, 2025
032447a
Upgrade to NamedDimsArrays.jl v0.11 (#38)
mtfishman Dec 23, 2025
b256d79
[LazyNamedDimsArrays] New `symnameddims` method that pulls out indice…
jack-dunham Jan 9, 2026
b2da9d8
The function `region_scalar` should now return a scalar, rather than …
jack-dunham Jan 9, 2026
8506e26
Fix double counting in `edge_scalars` function
jack-dunham Jan 9, 2026
938180a
Minor code formatting
jack-dunham Jan 9, 2026
4461967
Expressed belief propagation in terms of AlgorithmsInterface
jack-dunham Jan 9, 2026
d68860a
Fixes to TensorNetwork construction from tensor list
jack-dunham Jan 9, 2026
2f5c783
Minor simplifications to `contract_network` interface.
jack-dunham Jan 9, 2026
9a45a5b
Merge branch 'main' into bp
jack-dunham Feb 13, 2026
4eec9b6
Upgrade DataGraphs and NamedGraphs dependencies
jack-dunham Feb 10, 2026
202724c
[AlgorithmsInterfaceExtensions] Allowing mapping over a generic itera…
jack-dunham Feb 10, 2026
69542e3
Upgrade serial BP to use own `<:Algorithm` structs.
jack-dunham Feb 11, 2026
9925069
Simplify BP cache to only store factors
jack-dunham Feb 13, 2026
292f2fa
Upgrade to DataGraphs v0.3.1 and NamedGraphs v0.10
jack-dunham Feb 13, 2026
9d937aa
Fix compat
jack-dunham Feb 13, 2026
5432fe2
Fix broken merge
jack-dunham Feb 13, 2026
c916c84
Bug fix; upgrade tests
jack-dunham Feb 19, 2026
4a511a1
Add 2D TN test
jack-dunham Feb 24, 2026
5b97af3
Formatting
jack-dunham Feb 24, 2026
f2f9011
Refactor `NestedAlgorithm` hooks: `initialize_subsolve` + `finalize_s…
mtfishman May 19, 2026
314c294
Strip AIE down to minimal NestedAlgorithm + abstract scaffolding
mtfishman May 19, 2026
e35b1a2
Drop AIE `Problem` / `Algorithm` / `State` / `DefaultState` scaffolding
mtfishman May 19, 2026
b1821ce
Refactor BP into three problem/algorithm/state triples
mtfishman May 19, 2026
fdb3c04
Reorder BP source top-to-bottom
mtfishman May 19, 2026
56b2d82
Move StopWhenConverged + iterate_diff verb into AIE
mtfishman May 19, 2026
4fd8a47
Move `edge` field from `SimpleMessageUpdateAlgorithm` to `MessageUpda…
mtfishman May 19, 2026
81f7b4f
Move BP edge ordering from `BeliefPropagationProblem` to `BeliefPropa…
mtfishman May 19, 2026
6dbf365
Store edges on `BeliefPropagationAlgorithm`, not the sweep algorithm
mtfishman May 19, 2026
0d871c2
Index per-edge BP algorithms by edge; drop `AbstractVector` constraints
mtfishman May 19, 2026
e5a58d0
Rename `beliefpropagationproblem.jl` to `beliefpropagation.jl`
mtfishman May 19, 2026
2e8ee3b
Simplify BP API: single child algorithms + select_* selectors
mtfishman May 20, 2026
c8cafb9
Minor reorg and line-collapse cleanup in `beliefpropagation`
mtfishman May 20, 2026
b0a1e90
Collapse BP message-update AI layer; introduce `MessageUpdateAlgorith…
mtfishman May 20, 2026
cba3785
Merge branch 'main' into bp
jack-dunham May 20, 2026
e2220fe
Working Parallel BP
jack-dunham Feb 13, 2026
13f717c
Remove basic `Distributed.jl` implementation.
jack-dunham Feb 26, 2026
be1bfb1
Fix imports.
jack-dunham Feb 26, 2026
e715e15
Fix Project.toml
jack-dunham Feb 26, 2026
c1c73a3
Simplify parallel code.
jack-dunham Mar 2, 2026
7110108
for merge
jack-dunham May 21, 2026
d62feed
Merge branch 'main' into parallel-bp
jack-dunham May 26, 2026
c6d5a30
Delete legacy files.
jack-dunham Jun 1, 2026
cce227f
Add partitioned from of BP; define generic algorithm state objects.
jack-dunham Jun 1, 2026
49a4981
Refactor parallel and simplify code for parallelization.
jack-dunham Jun 1, 2026
b242e03
Merge branch 'main' into parallel-bp
jack-dunham Jun 1, 2026
798d344
Fix algorithms interface using legacy `finalize_substate` signature.
jack-dunham Jun 1, 2026
38004ad
Add Dagger.jl compat entry.
jack-dunham Jun 1, 2026
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: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,19 @@ WrappedUnions = "325db55a-9c6c-5b90-b1a2-ec87e7a38c44"

[weakdeps]
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"
Dagger = "d58978e5-989f-55fb-8d15-ea34adc7bf54"

[extensions]
ITensorNetworksNextTensorOperationsExt = "TensorOperations"
ITensorNetworksNextDaggerExt = "Dagger"

[compat]
AbstractTrees = "0.4.5"
Adapt = "4.3"
AlgorithmsInterface = "0.1"
BackendSelection = "0.1.6"
Combinatorics = "1"
Dagger = "0.19.0"
DataGraphs = "0.4"
DiagonalArrays = "0.3.31"
Dictionaries = "0.4.5"
Expand Down
84 changes: 84 additions & 0 deletions ext/ITensorNetworksNextDaggerExt/ITensorNetworksNextDaggerExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module ITensorNetworksNextDaggerExt

import AlgorithmsInterface as AI
import ITensorNetworksNext.AlgorithmsInterfaceExtensions as AIE
import ITensorNetworksNext.ITensorNetworksNextParallel as ITNNP
using Dagger
using Dictionaries: Dictionary, set!

@kwdef mutable struct DaggerState{Chunk <: Dagger.Chunk} <: AI.State
chunk::Chunk # A chunk living on the host worker.
futures = Dictionary{Int, Dagger.DTask}() # the futures from the remote steps.
end

function Base.getproperty(state::DaggerState, name::Symbol)
if name in (:chunk, :futures)
return getfield(state, name)
end
return getproperty(fetch(state.chunk), name)
end
function Base.setproperty!(state::DaggerState, name::Symbol, val)
if name === (:chunk, :futures)
return setfield!(state, name, val)
end
fetch(Dagger.@spawn setproperty!(state.chunk, name, val))
return state
end

# ====================================== overloads ======================================= #

function ITNNP.default_workers(::AI.Algorithm, ::ITNNP.AbstractDaggerStrategy)
return Dagger.Distributed.workers()
end

function ITNNP.initialize_parallel_state(
problem::AI.Problem, algorithm::AI.Algorithm,
_strategy::ITNNP.GenericDaggerStrategy; kwargs...
)
chunk = Dagger.@mutable AI.initialize_state(problem, algorithm; iterate, kwargs...)

return DaggerState(; chunk)
end

function AI.step!(problem::AI.Problem, algorithm::ITNNP.Parallelized, state::DaggerState)
worker_list = algorithm.workers
algorithm = algorithm.parent

function remote_solve(state)
subsolve = AIE.initialize_subsolve(problem, algorithm, state)

subproblem, subalgorithm, substate = subsolve
AI.solve!(subproblem, subalgorithm, substate)

return subsolve
end

worker = worker_list[mod(state.iteration, 1:length(worker_list))]

dtask = Dagger.@spawn scope = Dagger.scope(; worker) remote_solve(fetch(state.chunk))

# Spawns on the host only (as we do not fetch the chunk before hand.)
dtask = Dagger.spawn(dtask, state.chunk) do subsolve, state
subproblem, subalgorithm, substate = subsolve

AIE.finalize_substate!(subproblem, subalgorithm, substate, state)
return state
end

set!(state.futures, state.iteration, dtask)

return state
end
function AI.finalize_state!(::AI.Problem, ::AI.Algorithm, state::DaggerState)
foreach(fetch, state.futures)
return state.iterate
end

function AIE.finalize_substate!(
problem::AI.Problem, algorithm::AI.Algorithm, substate::DaggerState, state::AI.State
)
AIE.finalize_substate!(problem, algorithm, fetch(substate.chunk), state)
return state
end

end # ITensorNetworksNextDaggerExt
41 changes: 39 additions & 2 deletions src/AlgorithmsInterfaceExtensions/AlgorithmsInterfaceExtensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,37 @@ module AlgorithmsInterfaceExtensions

import AlgorithmsInterface as AI

@kwdef mutable struct GenericAlgorithmState{Iterate, StoppingCriterionState} <: AI.State
iterate::Iterate
iteration::Int = 0
stopping_criterion_state::StoppingCriterionState
end

function AI.initialize_state(
problem::AI.Problem,
algorithm::AI.Algorithm;
iterate,
iteration = 0
)
stopping_criterion_state = AI.initialize_state(
problem, algorithm, algorithm.stopping_criterion; iterate
)
return GenericAlgorithmState(; iterate, iteration, stopping_criterion_state)
end

function AI.initialize_state!(
problem::AI.Problem,
algorithm::AI.Algorithm,
state::AI.State;
iteration = 0
)
state.iteration = iteration
AI.initialize_state!(
problem, algorithm, algorithm.stopping_criterion, state.stopping_criterion_state
)
return state
end

# ============================ NestedAlgorithm =============================================

abstract type NestedAlgorithm <: AI.Algorithm end
Expand All @@ -18,7 +49,7 @@ function initialize_subsolve(
end

function finalize_substate!(
problem::AI.Problem, algorithm::AI.Algorithm, state::AI.State, substate::AI.State
::AI.Problem, ::AI.Algorithm, substate::AI.State, state::AI.State
)
state.iterate = substate.iterate
return state
Expand All @@ -27,7 +58,7 @@ end
function AI.step!(problem::AI.Problem, algorithm::NestedAlgorithm, state::AI.State)
subproblem, subalgorithm, substate = initialize_subsolve(problem, algorithm, state)
AI.solve!(subproblem, subalgorithm, substate)
finalize_substate!(problem, algorithm, state, substate)
finalize_substate!(subproblem, subalgorithm, substate, state)
return state
end

Expand All @@ -38,6 +69,12 @@ end
# state. Subtypes must store the inner state as a field named `substate`.
abstract type NestedState <: AI.State end

@kwdef mutable struct GenericNestedState{Substate, StoppingCriterionState} <: NestedState
substate::Substate
iteration::Int = 0
stopping_criterion_state::StoppingCriterionState
end

# Use `getfield` on the right-hand side so future edits to this forwarder
# can't accidentally recurse through the overload.
function Base.getproperty(state::NestedState, name::Symbol)
Expand Down
4 changes: 4 additions & 0 deletions src/ITensorNetworksNext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ include("contract_network.jl")

include("beliefpropagation/messagecache.jl")
include("beliefpropagation/beliefpropagation.jl")
include("beliefpropagation/partitioned.jl")

# lib
include("ITensorNetworksNextParallel/ITensorNetworksNextParallel.jl")

end
60 changes: 60 additions & 0 deletions src/ITensorNetworksNextParallel/ITensorNetworksNextParallel.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module ITensorNetworksNextParallel

import ..ITensorNetworksNext.AlgorithmsInterfaceExtensions as AIE
import AlgorithmsInterface as AI

abstract type AbstractParallelizationStrategy end

function default_workers end
function initialize_parallel_state end

@kwdef struct Parallelized{Strategy, Workers, Algorithm <: AI.Algorithm} <: AI.Algorithm
parent::Algorithm
strategy::Strategy
workers::Workers = default_workers(parent, strategy)
end

function Base.getproperty(algorithm::Parallelized, name::Symbol)
if name in (:parent, :strategy, :workers)
return getfield(algorithm, name)
end
return getproperty(getfield(algorithm, :parent), name)
end

function AI.initialize_state(problem::AI.Problem, algorithm::Parallelized; kwargs...)
return initialize_parallel_state(
problem,
algorithm.parent,
algorithm.strategy;
kwargs...
)
end

# ====================================== Dagger.jl ======================================= #

abstract type AbstractDaggerStrategy <: AbstractParallelizationStrategy end
struct GenericDaggerStrategy <: AbstractDaggerStrategy end

function initialize_parallel_state(
_problem,
_algorithm,
strategy::AbstractDaggerStrategy;
_kwargs...
)
throw(
ArgumentError(
"package Dagger.jl not loaded; please install and load Dagger.jl to use \
strategy of type $(typeof(strategy))."
)
)
end

function default_workers(algorithm, strategy::AbstractDaggerStrategy)
@warn(
"package Dagger.jl may not be loaded; please install and load Dagger.jl to use \
strategy of type `$(typeof(strategy))`"
)
throw(MethodError(default_workers, (algorithm, strategy)))
end

end # ITensorNetworksNextParallel
3 changes: 3 additions & 0 deletions src/LazyNamedDimsArrays/symbolicnameddimsarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const SymbolicNamedDimsArray{T, N, Parent <: SymbolicArray{T, N}, DimNames} =
function symnameddims(symname, dims)
return lazy(nameddims(SymbolicArray(symname, denamed.(dims)), name.(dims)))
end
function symnameddims(name, ndarray::AbstractNamedDimsArray)
return symnameddims(name, Tuple(inds(ndarray)))
end
symnameddims(name) = symnameddims(name, ())
using AbstractTrees: AbstractTrees
function AbstractTrees.printnode(io::IO, a::SymbolicNamedDimsArray)
Expand Down
1 change: 1 addition & 0 deletions src/abstracttensornetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Base.copy(::AbstractTensorNetwork) = not_implemented()

# Iteration
Base.iterate(tn::AbstractTensorNetwork, args...) = iterate(vertex_data(tn), args...)

Base.keys(tn::AbstractTensorNetwork) = vertices(tn)

# TODO: This contrasts with the `DataGraphs.AbstractDataGraph` definition,
Expand Down
Loading
Loading