diff --git a/src/qc_compiler/batching.py b/src/qc_compiler/batching.py index ebd2829..8b1e969 100644 --- a/src/qc_compiler/batching.py +++ b/src/qc_compiler/batching.py @@ -20,6 +20,7 @@ same device, maximizing qubit utilization. """ +import hashlib from dataclasses import dataclass, field from qiskit import QuantumCircuit @@ -302,7 +303,7 @@ def _compute_core_hash(self, circuit: QuantumCircuit) -> int: ) core_gates.append((gate_name, qubits, params)) - return hash(tuple(core_gates)) + return int(hashlib.sha256(str(tuple(core_gates)).encode()).hexdigest(), 16) def _detect_measurement_basis( self, circuit: QuantumCircuit diff --git a/tests/test_batching.py b/tests/test_batching.py index 3cea4da..78a1d30 100644 --- a/tests/test_batching.py +++ b/tests/test_batching.py @@ -352,4 +352,28 @@ def test_circuits_exceeding_device_capacity_split_into_batches(self): qc.cx(0, 1) plan = batcher.create_batch_plan(circuits, strategy="structural") assert plan.total_circuits == 4 - assert plan.num_batches >= 2 \ No newline at end of file + assert plan.num_batches >= 2 + + +class TestDeterministicCoreHash: + """Regression test for deterministic hashing (issue #51).""" + + def test_core_hash_is_deterministic_across_calls(self): + batcher = CircuitBatcher(cost_model=CostModel()) + qc = QuantumCircuit(2) + qc.h(0) + qc.cx(0, 1) + hash1 = batcher._compute_core_hash(qc) + hash2 = batcher._compute_core_hash(qc) + assert hash1 == hash2 + + def test_core_hash_differs_for_different_circuits(self): + batcher = CircuitBatcher(cost_model=CostModel()) + qc1 = QuantumCircuit(2) + qc1.h(0) + qc1.cx(0, 1) + qc2 = QuantumCircuit(2) + qc2.x(0) + hash1 = batcher._compute_core_hash(qc1) + hash2 = batcher._compute_core_hash(qc2) + assert hash1 != hash2 \ No newline at end of file