Skip to content
Draft
Show file tree
Hide file tree
Changes from 139 commits
Commits
Show all changes
149 commits
Select commit Hold shift + click to select a range
16e9309
Adding in crosstalk-free GST eDesigns.
dhothem Jan 20, 2025
c483ebb
Merge branch 'master' of https://github.com/sandialabs/pyGSTi into fe…
dhothem Jan 20, 2025
56242ee
style
rileyjmurray Jan 21, 2025
d249c80
restore commented-out line with update to function name
rileyjmurray Jan 23, 2025
dc964ad
whitespace and docstring
rileyjmurray Jan 23, 2025
8018e69
add some utility functions to CircuitList class
rileyjmurray Jan 23, 2025
1d29ddb
bugfixes in stich_circuits_by_germ_power_only. Remove HasProcessorSpe…
rileyjmurray Jan 23, 2025
19fcf3c
undo changes to CircuitList. Add tqdm logging. Fix crosstalkfreeexper…
rileyjmurray Jan 24, 2025
35e35fa
add PermutationOperator class. Remove outdated part of a docstring.
rileyjmurray Jan 27, 2025
3e3210f
update ProcessorSpec.compute_2Q_connectivity() so it can handle idle …
rileyjmurray Jan 28, 2025
1253ee5
undo imposition of certain connectivity structure for idle gates (now…
rileyjmurray Jan 28, 2025
99392bf
ready for 3qubit xfgst
rileyjmurray Jan 30, 2025
6b6b69e
replace assertion with warning
rileyjmurray Feb 4, 2025
c54c4d0
switch to try MOSEK if available, falling back on Clarabel and then C…
rileyjmurray Feb 4, 2025
a875d44
add ability to skip named sections in construct_standard_report. Alwa…
rileyjmurray Feb 4, 2025
eef4b44
make computing some report quantities more robust to degenerate input…
rileyjmurray Feb 4, 2025
689ffa7
make sure that circuits produced in crosstalk free experiment design …
rileyjmurray Feb 4, 2025
1d66e1c
style
rileyjmurray Feb 4, 2025
028e961
use separate 2q idle label
rileyjmurray Feb 5, 2025
9d2890a
methods for (de)serialization of PermutationOperator
rileyjmurray Feb 5, 2025
5644b20
tweak meaning of force=True in ModelMember.unlink_parent
rileyjmurray Feb 5, 2025
e96df9f
leave a TODO
rileyjmurray Feb 5, 2025
021fbf3
Clean up convert_members_inplace by adding two tiny helper classes to…
rileyjmurray Feb 5, 2025
1821244
add create_explicit method to LocalNoiseModel class
rileyjmurray Feb 5, 2025
35d0353
add option to change threshold at which customsolve is used. Updated …
rileyjmurray Feb 18, 2025
5a90e5c
comment where changes might be incorporated for faster forward sim
rileyjmurray Feb 18, 2025
4f3ba4d
logging
rileyjmurray Feb 21, 2025
5f96a16
argument check
rileyjmurray Feb 21, 2025
dd86821
move LocalNoiseModel.create_explicit to ImplicitOpModel. Add comments…
rileyjmurray Feb 24, 2025
7f0d9dd
add features to create_explicit
rileyjmurray Feb 24, 2025
a9b01a0
complete merge
rileyjmurray Feb 24, 2025
6c6fb53
add option to SimplerLMOptimizer and simplish_leastsq to terminate ba…
rileyjmurray Feb 27, 2025
284bbf9
Make the matrix forward simulator respect the lanes present in the st…
nkoskelo Jun 17, 2025
2abdfa6
save the lane information if the circuit is built from tensor products
nkoskelo Jun 20, 2025
a018714
Preliminary spatially homogeneous qubits.
nkoskelo Jul 1, 2025
646c5d1
Save
nkoskelo Jul 8, 2025
f2035ba
Merge branch 'develop' of https://github.com/sandialabs/pyGSTi into p…
nkoskelo Jul 8, 2025
ced6d46
Lanes collapsed by looking through the qubits used and building up a …
nkoskelo Jul 10, 2025
e7bb3c7
revert me, probably
rileyjmurray Jul 10, 2025
2f143f0
hopefully complete merge
rileyjmurray Jul 10, 2025
70843b4
Compute dense process matrix not with function in EvalTreeLCS.
nkoskelo Jul 10, 2025
3581769
deactivate test
rileyjmurray Jul 10, 2025
12723be
rename another test file
rileyjmurray Jul 10, 2025
56b8004
remove unused class
rileyjmurray Jul 10, 2025
6003f75
Regions in evaltree.
nkoskelo Jul 10, 2025
1ca3b2d
inline a function
rileyjmurray Jul 10, 2025
6f43b2a
whitespace
rileyjmurray Jul 11, 2025
613379a
Get the dense operator in the minimal space required for a gate opera…
nkoskelo Jul 11, 2025
5de4bff
Extract LCS work.
nkoskelo Jul 11, 2025
abb94ad
Add in test cases for sequencetools
nkoskelo Jul 11, 2025
81e805a
tiny simplification
rileyjmurray Jul 11, 2025
23c6a3a
add more test cases
nkoskelo Jul 11, 2025
2ea2a6d
Simplify
nkoskelo Jul 11, 2025
eb2ce64
Add padded idles into the circuit as necessary.
nkoskelo Jul 14, 2025
27167a3
bugfix for ExplicitLayerRules.get_dense_process_matrix_represention_f…
rileyjmurray Jul 14, 2025
7d9f9b2
Error out when there is an implicit idle.
nkoskelo Jul 15, 2025
17294bc
Make tests easier.
nkoskelo Jul 15, 2025
06dbc64
Improve the circuit splitting test.
nkoskelo Jul 15, 2025
7ad7b6d
change Circuit.replace_gatename_inplace to handle the common situatio…
rileyjmurray Jul 15, 2025
f158ebf
Make the matrix forward simulator respect the lanes present in the st…
nkoskelo Jun 17, 2025
3115499
save the lane information if the circuit is built from tensor products
nkoskelo Jun 20, 2025
6cad8d3
Preliminary spatially homogeneous qubits.
nkoskelo Jul 1, 2025
24930fb
Save
nkoskelo Jul 8, 2025
e8be458
Lanes collapsed by looking through the qubits used and building up a …
nkoskelo Jul 10, 2025
e991f6c
Compute dense process matrix not with function in EvalTreeLCS.
nkoskelo Jul 10, 2025
2616ae3
deactivate test
rileyjmurray Jul 10, 2025
1f4d05b
rename another test file
rileyjmurray Jul 10, 2025
3f82746
remove unused class
rileyjmurray Jul 10, 2025
0f560f7
Regions in evaltree.
nkoskelo Jul 10, 2025
248fa7e
inline a function
rileyjmurray Jul 10, 2025
c9b1adf
whitespace
rileyjmurray Jul 11, 2025
75bb798
Get the dense operator in the minimal space required for a gate opera…
nkoskelo Jul 11, 2025
6ff9e05
Extract LCS work.
nkoskelo Jul 11, 2025
5ff9873
Add in test cases for sequencetools
nkoskelo Jul 11, 2025
fc80874
tiny simplification
rileyjmurray Jul 11, 2025
51474fd
add more test cases
nkoskelo Jul 11, 2025
338f8cf
Simplify
nkoskelo Jul 11, 2025
9f8faad
Add padded idles into the circuit as necessary.
nkoskelo Jul 14, 2025
4b9b10a
bugfix for ExplicitLayerRules.get_dense_process_matrix_represention_f…
rileyjmurray Jul 14, 2025
40d6460
Error out when there is an implicit idle.
nkoskelo Jul 15, 2025
cbb090f
Make tests easier.
nkoskelo Jul 15, 2025
650fd59
Improve the circuit splitting test.
nkoskelo Jul 15, 2025
2025949
change Circuit.replace_gatename_inplace to handle the common situatio…
rileyjmurray Jul 15, 2025
58c9c2b
Merge branch 'psaap_3_2025_si' of https://github.com/nkoskelo/pyGSTi …
nkoskelo Jul 15, 2025
8cf274c
Helper classes
rileyjmurray Jul 15, 2025
e9f4576
add ECR to standard unitaries
rileyjmurray Jul 16, 2025
1dcc580
Update crosstalk free generator to add explicit idles to single qubit…
nkoskelo Jul 16, 2025
2180de6
Append idling layers
nkoskelo Jul 16, 2025
b037fab
edesign seems to work now
rileyjmurray Jul 16, 2025
8cec2d2
port a change from Nicks last commit
rileyjmurray Jul 16, 2025
45c0317
Revert "Append idling layers"
rileyjmurray Jul 16, 2025
60d23ed
Merge branch 'parallel-work-with-nick' into psaap_3_2025_si
rileyjmurray Jul 16, 2025
eb85393
Implicit op models work with opfactories that return embeddedops.
nkoskelo Jul 16, 2025
1d31a65
Add more tests for the forward simulator on implicit op models.
nkoskelo Jul 16, 2025
61ab0a1
Cache the split circuits if desired.
nkoskelo Jul 16, 2025
e18e7dd
Sim cost estimates
nkoskelo Jul 16, 2025
fe062e7
simplify switch_circuits_by_germ_power_only by introducing a new help…
rileyjmurray Jul 16, 2025
53b4eaa
Merge branch 'parallel-work-with-nick' into psaap_3_2025_si
rileyjmurray Jul 16, 2025
c2a2393
WIP resolution to the problem of implicit idle gates when circuits do…
rileyjmurray Jul 17, 2025
68937ef
type annotation
rileyjmurray Jul 17, 2025
806a78f
raise an error when we should
rileyjmurray Jul 17, 2025
0cc9464
nicks changes.
nkoskelo Jul 17, 2025
421b690
type annotations, type alias, and slight renaming
rileyjmurray Jul 17, 2025
ea49417
more typing
rileyjmurray Jul 17, 2025
4cc5ba2
type annotations
rileyjmurray Jul 17, 2025
91d2d96
resolve left over merge conflict
rileyjmurray Jul 17, 2025
6e6dde0
tests with smq1Q_XY pass (again ...)
rileyjmurray Jul 17, 2025
7d639bb
typing and compute a 16-by-16 matrix rather than having it written ex…
rileyjmurray Jul 17, 2025
3a413ca
Error out if we encounter an ExplicitOp Model.
nkoskelo Jul 17, 2025
773184e
Use the tensor product matrix multiplication trick.
nkoskelo Jul 18, 2025
c8c3bd0
Adding more typechecking
nkoskelo Jul 18, 2025
f4b989c
Debugging setting a single parameter directly.
nkoskelo Jul 18, 2025
e438351
Update flop cost.
nkoskelo Jul 22, 2025
0fcf1d8
Update after talking with Corey and Erik
nkoskelo Jul 22, 2025
eb9d122
Add dprobs test cases.
nkoskelo Jul 22, 2025
80ecba9
Fix formatting issues
nkoskelo Jul 22, 2025
ea18d5b
Add a cache for LCS external matches and collapse the sequences inter…
nkoskelo Jul 24, 2025
96c97f2
update test to have the metadata information for caching.
nkoskelo Jul 25, 2025
fa859ac
Collapse lanes internally first.
nkoskelo Jul 29, 2025
d73e251
Update LCS tree to track which cache indexes need to get recomputed i…
nkoskelo Jul 30, 2025
a233602
Caching so that you only need to compute probs if something will chan…
nkoskelo Aug 2, 2025
ec00225
Cache collapse is missing something.
nkoskelo Aug 2, 2025
656bff3
Invalidate the cache for all labels and those numerical values which …
nkoskelo Aug 6, 2025
661aa37
Caching for dprobs passes.
nkoskelo Aug 7, 2025
2fa4ad5
Working on storing only the updates we need to compute when doing the…
nkoskelo Aug 9, 2025
25af0e7
Works if not testing in bulk.
nkoskelo Aug 13, 2025
282cb59
bulk works with independent gates
nkoskelo Aug 13, 2025
74b6433
Attempt to handle identical gates.
nkoskelo Aug 14, 2025
821e532
Attempting to speed up by only replacing part of the KronStructured d…
nkoskelo Aug 15, 2025
9bb7a59
Add in a flops estimate for dprobs LCS tree.
nkoskelo Aug 19, 2025
84b5356
merge develop
rileyjmurray Aug 19, 2025
7992a6b
Merge made memo set twice.
nkoskelo Aug 19, 2025
8226079
finish actually changing Circuit.from_cirq from a classmethod to a st…
rileyjmurray Aug 19, 2025
5a29f4b
Revert "finish actually changing Circuit.from_cirq from a classmethod…
rileyjmurray Aug 19, 2025
d4e5db6
Move daydic kron op to tools.
nkoskelo Aug 19, 2025
b3a226c
Remove permutation op.
nkoskelo Aug 19, 2025
72303c3
Remove unused_xfgst.py
nkoskelo Aug 19, 2025
19d43d5
Reactivate test_errgenproptools.py
nkoskelo Aug 19, 2025
525373e
Remove unused code and commented out code.
nkoskelo Aug 19, 2025
bb78983
Revert changes to mapforward_calc_generic
nkoskelo Aug 19, 2025
d0152d1
No actually though.
nkoskelo Aug 19, 2025
58d97e0
Matrix layout update.
nkoskelo Aug 19, 2025
30ee59f
Types for sequencetools
nkoskelo Aug 19, 2025
dd402cf
Add licensing info.
nkoskelo Aug 19, 2025
3431730
Remove code not needed for the PR.
nkoskelo Aug 19, 2025
b4f7044
Extract eval tree to new file.
nkoskelo Aug 19, 2025
413ac67
Finish the split.
nkoskelo Aug 19, 2025
3bd478e
Add a description for EvalTreeBasedUponLongestCommonSubstring
nkoskelo Aug 19, 2025
8f57778
CollectionLCS Eval Tree documentation.
nkoskelo Aug 19, 2025
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
6 changes: 5 additions & 1 deletion pygsti/baseobjs/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import itertools as _itertools
import numbers as _numbers
import sys as _sys
import copy as _copy
import numpy as _np


Expand Down Expand Up @@ -138,7 +139,8 @@ def __new__(cls, name, state_space_labels=None, time=None, args=None):
return LabelStr.init(name, time)

else:
if args is not None: return LabelTupWithArgs.init(name, state_space_labels, time, args)
if args is not None:
return LabelTupWithArgs.init(name, state_space_labels, time, args)
else:
if time == 0.0:
return LabelTup.init(name, state_space_labels)
Expand Down Expand Up @@ -200,6 +202,8 @@ def is_simple(self):

return self.IS_SIMPLE

def copy(self):
return _copy.deepcopy(self)


class LabelTup(Label, tuple):
Expand Down
6 changes: 6 additions & 0 deletions pygsti/baseobjs/statespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,12 @@ def __getstate__(self):
def __setstate__(self, state_dict):
for k, v in state_dict.items():
self.__dict__[k] = v
try:
_ = self.__getattribute__(k)
except AttributeError:
_ = self.__dict__.pop(k)
self.__dict__['_' + k] = v
_ = self.__getattribute__(k)
Comment on lines +686 to +691
Copy link
Contributor

Choose a reason for hiding this comment

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

I remember making this change but I don't remember why. We should revert unless we have a good reason to keep as-is.

#reinitialize the hash
self._hash = hash((self.tensor_product_blocks_labels,
self.tensor_product_blocks_dimensions,
Expand Down
170 changes: 135 additions & 35 deletions pygsti/circuits/circuit.py

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions pygsti/circuits/circuitlist.py
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tensor circuit construction should retain knowledge of original lane structure.

Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@ def __setstate__(self, state_dict):
self.__dict__.update(state_dict)
if 'uuid' not in state_dict: # backward compatibility
self.uuid = _uuid.uuid4() # create a new uuid

def tensor_circuits(self, other_circuitlist, new_name=None):
assert len(self) == len(other_circuitlist)
circuits = []
for c1,c2 in zip(self._circuits, other_circuitlist._circuits):
circuits.append(c1.tensor_circuit(c2))
out = CircuitList(circuits, name=new_name)
return out

def elementvec_to_array(self, elementvec, layout, mergeop="sum"):
"""
Expand Down
186 changes: 186 additions & 0 deletions pygsti/circuits/split_circuits_into_lanes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import numpy as _np

from typing import Sequence, Dict, Tuple, Optional, Set
from pygsti.circuits import Circuit as Circuit
from pygsti.baseobjs.label import Label, LabelTupTup


def compute_qubit_to_lane_and_lane_to_qubits_mappings_for_circuit(circuit: Circuit) -> tuple[dict[int, int],
dict[int, tuple[int]]]:
"""
Parameters:
------------
circuit: Circuit - the circuit to compute qubit to lanes mapping for

num_qubits: int - The total number of qubits expected in the circuit.

Returns
--------
Dictionary mapping qubit number to lane number in the circuit.
"""

qubits_to_potentially_entangled_others = {i: set((i,)) for i in range(circuit.num_lines)}
num_layers = circuit.num_layers
for layer_ind in range(num_layers):
layer = circuit.layer(layer_ind)
for op in layer:
qubits_used = op.qubits
for qb in qubits_used:
qubits_to_potentially_entangled_others[qb].update(set(qubits_used))

lanes = {}
lan_num = 0
visited: dict[int, int] = {}
def reachable_nodes(starting_point: int,
graph_qubits_to_neighbors: dict[int, set[int]],
visited: dict[int, set[int]]):
"""
Find which nodes are reachable from this starting point.
"""
if starting_point in visited:
return visited[starting_point]
else:
assert starting_point in graph_qubits_to_neighbors
visited[starting_point] = graph_qubits_to_neighbors[starting_point]
output = set(visited[starting_point])
for child in graph_qubits_to_neighbors[starting_point]:
if child != starting_point:
output.update(output, reachable_nodes(child, graph_qubits_to_neighbors, visited))
visited[starting_point] = output
return output

available_starting_points = list(sorted(qubits_to_potentially_entangled_others.keys()))
while available_starting_points:
sp = available_starting_points[0]
nodes = reachable_nodes(sp, qubits_to_potentially_entangled_others, visited)
for node in nodes:
available_starting_points.remove(node)
lanes[lan_num] = nodes
lan_num += 1

def compute_qubits_to_lanes(lanes_to_qubits: dict[int, set[int]]) -> dict[int, int]:
"""
Determine a mapping from qubit to the lane it is in for this specific circuit.
"""
out = {}
for key, val in lanes_to_qubits.items():
for qb in val:
out[qb] = key
return out

return compute_qubits_to_lanes(lanes), lanes


def compute_subcircuits(circuit: Circuit,
qubit_to_lanes: dict[int, int],
lane_to_qubits: dict[int, tuple[int, ...]],
cache_lanes_in_circuit: bool = False) -> list[list[LabelTupTup]]:
"""
Split a circuit into multiple subcircuits which do not talk across lanes.
"""

if "lanes" in circuit.saved_auxinfo:
# Check if the lane info matches and I can just return that set up.
if len(lane_to_qubits) == len(circuit.saved_auxinfo["lanes"]):
# We may have this already in cache.

lanes_to_gates = [[] for _ in range(len(lane_to_qubits))]
for i, key in lane_to_qubits.items():
if tuple(sorted(key)) in circuit.saved_auxinfo["lanes"]:
lanes_to_gates[i] = circuit.saved_auxinfo["lanes"][tuple(sorted(key))]

else:
raise ValueError(f"lbl cache miss: {key} in circuit {circuit}")
return lanes_to_gates

lanes_to_gates = [[] for _ in range(_np.unique(list(qubit_to_lanes.values())).shape[0])]

num_layers = circuit.num_layers
for layer_ind in range(num_layers):
layer = circuit.layer_with_idles(layer_ind)
group = []
group_lane = None
sorted_layer = sorted(layer, key=lambda x: x.qubits[0])

for op in sorted_layer:
# We need this to be sorted by the qubit number so we do not get that a lane was split Q1 Q3 Q2 in the layer where Q1 and Q2 are in the same lane.
qubits_used = op.qubits # This will be a list of qubits used.
# I am assuming that the qubits are indexed numerically and not by strings.
lane = qubit_to_lanes[qubits_used[0]]

if group_lane is None:
group_lane = lane
group.append(op)
elif group_lane == lane:
group.append(op)
else:
lanes_to_gates[group_lane].append(LabelTupTup(tuple(group)))
group_lane = lane
group = [op]

if len(group) > 0:
# We have a left over group.
lanes_to_gates[group_lane].append(LabelTupTup(tuple(group)))

if cache_lanes_in_circuit:
circuit = circuit._cache_tensor_lanes(lanes_to_gates, lane_to_qubits)

if num_layers == 0:
return lanes_to_gates

return lanes_to_gates


@staticmethod
def batch_tensor(
circuits : Sequence[Circuit],
layer_mappers: Dict[int, Dict],
global_line_order: Optional[Tuple[int,...]] = None,
target_lines : Optional[Sequence[Tuple[int,...]]] = None
) -> Circuit:
"""
"""
assert len(circuits) > 0

if target_lines is None:
target_lines = []
total_lines = 0
max_cir_len = 0
for c in circuits:
target_lines.append(tuple(range(total_lines, total_lines + c.num_lines)))
total_lines += c.num_lines
max_cir_len = max(max_cir_len, len(c))
else:
total_lines = sum([c.num_lines for c in circuits])
max_cir_len = max(*[len(c) for c in circuits])

s : Set[int] = set()
for c, t in zip(circuits, target_lines):
assert not s.intersection(t)
assert len(t) == c.num_lines
s.update(t)

if global_line_order is None:
global_line_order = tuple(sorted(list(s)))

c = circuits[0].copy(editable=True)
c._append_idling_layers_inplace(max_cir_len - len(c))
c.done_editing()
# ^ That changes the format of c._labels. We need to edit c while in this format,
# so the next line sets c._static = False. (We repeat this pattern in the loop below.)
c._static = False
c._labels = [layer_mappers[c.num_lines][ell] for ell in c._labels]
c.map_state_space_labels_inplace({k:v for k,v in zip(c.line_labels, target_lines[0])})
c.done_editing()
for i, c2 in enumerate(circuits[1:]):
c2 = c2.copy(editable=True)
c2._append_idling_layers_inplace(max_cir_len - len(c2))
c2.done_editing()
c2._static = False
c2._labels = [layer_mappers[c2.num_lines][ell] for ell in c2._labels]
c2.map_state_space_labels_inplace({k:v for k,v in zip(c2.line_labels, target_lines[i+1])})
c2.done_editing()
c = c.tensor_circuit(c2)

c = c.reorder_lines(global_line_order)
return c
11 changes: 7 additions & 4 deletions pygsti/forwardsims/forwardsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
from pygsti.baseobjs.resourceallocation import ResourceAllocation as _ResourceAllocation
from pygsti.baseobjs.nicelyserializable import NicelySerializable as _NicelySerializable
from pygsti.tools import slicetools as _slct
from typing import Union, Callable, Literal
from typing import Union, Callable, Literal, TYPE_CHECKING

if TYPE_CHECKING:
from pygsti.models.model import OpModel


class ForwardSimulator(_NicelySerializable):
Expand Down Expand Up @@ -96,7 +99,7 @@ def _array_types_for_method(cls, method_name):
return ('ep', 'ep') + cls._array_types_for_method('_bulk_fill_dprobs_block')
return ()

def __init__(self, model=None):
def __init__(self, model: OpModel=None):
super().__init__()
#self.dim = model.dim
self.model = model
Expand Down Expand Up @@ -128,11 +131,11 @@ def __getstate__(self):
return state_dict

@property
def model(self):
def model(self) -> OpModel:
return self._model

@model.setter
def model(self, val):
def model(self, val: OpModel):
self._model = val
try:
evotype = None if val is None else self._model.evotype
Expand Down
8 changes: 6 additions & 2 deletions pygsti/forwardsims/mapforwardsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import numpy as _np
from numpy import linalg as _nla
import time

from pygsti.forwardsims.distforwardsim import DistributableForwardSimulator as _DistributableForwardSimulator
from pygsti.forwardsims.forwardsim import ForwardSimulator as _ForwardSimulator
Expand Down Expand Up @@ -360,13 +361,16 @@ def create_copa_layout_circuit_cache(circuits, model, dataset=None):

def _bulk_fill_probs_atom(self, array_to_fill, layout_atom, resource_alloc):
# Note: *don't* set dest_indices arg = layout.element_slice, as this is already done by caller
resource_alloc.check_can_allocate_memory(layout_atom.cache_size * self.model.dim)
# resource_alloc.check_can_allocate_memory(layout_atom.cache_size * self.model.dim)
start_time = time.time()
self.calclib.mapfill_probs_atom(self, array_to_fill, slice(0, array_to_fill.shape[0]), # all indices
layout_atom, resource_alloc)
end_time = time.time()
print("Time to compute forward probs with map Forward after fixed layout (s): ", end_time - start_time)

def _bulk_fill_dprobs_atom(self, array_to_fill, dest_param_slice, layout_atom, param_slice, resource_alloc):
# Note: *don't* set dest_indices arg = layout.element_slice, as this is already done by caller
resource_alloc.check_can_allocate_memory(layout_atom.cache_size * self.model.dim * _slct.length(param_slice))
# resource_alloc.check_can_allocate_memory(layout_atom.cache_size * self.model.dim * _slct.length(param_slice))
self.calclib.mapfill_dprobs_atom(self, array_to_fill, slice(0, array_to_fill.shape[0]), dest_param_slice,
layout_atom, param_slice, resource_alloc, self.derivative_eps)

Expand Down
2 changes: 2 additions & 0 deletions pygsti/forwardsims/mapforwardsim_calc_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ def mapfill_dprobs_atom(fwdsim, mx_to_fill, dest_indices, dest_param_indices, la
iFinal = iParamToFinal[param_indices[i]]
fwdsim.model.set_parameter_values([param_indices[i-1], param_indices[i]],
[orig_vec[param_indices[i-1]], orig_vec[param_indices[i]]+eps])
vec = fwdsim.model.to_vector()
assert _np.allclose(_np.where(vec != 0), [i])
#mapfill_probs_atom(fwdsim, probs2, slice(0, nEls), layout_atom, resource_alloc)
cond_update_probs_atom(fwdsim, probs2, slice(0, nEls), layout_atom, param_indices[i], resource_alloc)
#assert _np.linalg.norm(probs2_test-probs2) < 1e-10
Expand Down
Loading
Loading