Skip to content

Commit 4c05892

Browse files
Streaming and debug
1 parent bff8e52 commit 4c05892

File tree

3 files changed

+109
-15
lines changed

3 files changed

+109
-15
lines changed

pyqrackising/maxcut_tfim_util.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,90 @@ def compute_cut_streaming(sample, G_func, nodes, n_qubits):
432432
return cut
433433

434434

435+
@njit
436+
def compute_energy_diff_streaming(u, sample, G_func, nodes, n_qubits):
437+
energy = 0.0
438+
u_bit = sample[u]
439+
for v in range(u):
440+
val = 2 * G_func(nodes[u], nodes[v])
441+
energy += val if u_bit == sample[v] else -val
442+
for v in range(u + 1, n_qubits):
443+
val = 2 * G_func(nodes[u], nodes[v])
444+
energy += val if u_bit == sample[v] else -val
445+
446+
return -energy
447+
448+
449+
@njit
450+
def compute_cut_diff_streaming(u, sample, G_func, nodes, n_qubits):
451+
energy = 0.0
452+
u_bit = sample[u]
453+
for v in range(u):
454+
val = G_func(nodes[u], nodes[v])
455+
energy += -val if u_bit == sample[v] else val
456+
for v in range(u + 1, n_qubits):
457+
val = G_func(nodes[u], nodes[v])
458+
energy += -val if u_bit == sample[v] else val
459+
460+
return energy
461+
462+
463+
@njit
464+
def compute_energy_diff_2_streaming(k, l, sample, G_func, nodes, n_qubits):
465+
if l < k:
466+
t = k
467+
k = l
468+
l = t
469+
energy = 0.0
470+
k_bit = sample[k]
471+
l_bit = sample[l]
472+
for v in range(k):
473+
val = 2 * G_func(nodes[k], nodes[v])
474+
energy += val if k_bit == sample[v] else -val
475+
val = 2 * G_func(nodes[l], nodes[v])
476+
energy += val if l_bit == sample[v] else -val
477+
for v in range(k + 1, l):
478+
val = 2 * G_func(nodes[k], nodes[v])
479+
energy += val if k_bit == sample[v] else -val
480+
val = 2 * G_func(nodes[l], nodes[v])
481+
energy += val if l_bit == sample[v] else -val
482+
for v in range(l + 1, n_qubits):
483+
val = 2 * G_func(nodes[k], nodes[v])
484+
energy += val if k_bit == sample[v] else -val
485+
val = 2 * G_func(nodes[l], nodes[v])
486+
energy += val if l_bit == sample[v] else -val
487+
488+
return -energy
489+
490+
491+
@njit
492+
def compute_cut_diff_2_streaming(k, l, sample, G_func, nodes, n_qubits):
493+
if l < k:
494+
t = k
495+
k = l
496+
l = t
497+
energy = 0.0
498+
k_bit = sample[k]
499+
l_bit = sample[l]
500+
for v in range(k):
501+
val = G_func(nodes[k], nodes[v])
502+
energy += -val if k_bit == sample[v] else val
503+
val = G_func(nodes[l], nodes[v])
504+
energy += -val if l_bit == sample[v] else val
505+
for v in range(k + 1, l):
506+
val = G_func(nodes[k], nodes[v])
507+
energy += -val if k_bit == sample[v] else val
508+
val = G_func(nodes[l], nodes[v])
509+
energy += -val if l_bit == sample[v] else val
510+
for v in range(l + 1, n_qubits):
511+
val = G_func(nodes[k], nodes[v])
512+
energy += -val if k_bit == sample[v] else val
513+
val = G_func(nodes[l], nodes[v])
514+
energy += -val if l_bit == sample[v] else val
515+
516+
return energy
517+
518+
435519
@njit
436520
def get_cut(solution, nodes, n):
437521
bit_string = ""

pyqrackising/spin_glass_solver.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,16 +464,21 @@ def spin_glass_solver(
464464
improved = True
465465
continue
466466

467+
if max_energy == float("inf"):
468+
# We no way to compare for improvement.
469+
break
470+
467471
# Post-reheat phase
468472
reheat_theta = state
473+
reheat_energy = energy
469474

470475
# Single bit flips with O(n^2)
471476
if is_opencl:
472477
theta_buf = make_best_theta_buf(reheat_theta)
473478
energy, state = run_bit_flips_opencl(False, n_qubits, single_bit_flips_kernel, reheat_theta, theta_buf, G_m_buf, is_segmented, *opencl_args)
474479
else:
475480
energy, state = run_single_bit_flips(reheat_theta, is_spin_glass, G_m)
476-
if energy > 0.0:
481+
if energy > (max_energy - reheat_energy):
477482
max_energy += energy
478483
best_theta = state
479484
improved = True
@@ -485,7 +490,7 @@ def spin_glass_solver(
485490
energy, state = run_bit_flips_opencl(True, n_qubits, double_bit_flips_kernel, reheat_theta, theta_buf, G_m_buf, is_segmented, *opencl_args)
486491
else:
487492
energy, state = run_double_bit_flips(reheat_theta, is_spin_glass, G_m, thread_count)
488-
if energy > 0.0:
493+
if energy > (max_energy - reheat_energy):
489494
max_energy += energy
490495
best_theta = state
491496
improved = True

pyqrackising/spin_glass_solver_streaming.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .maxcut_tfim_streaming import maxcut_tfim_streaming
2-
from .maxcut_tfim_util import compute_cut_streaming, compute_energy_streaming, get_cut, get_cut_base, gray_code_next, gray_mutation, heuristic_threshold, int_to_bitstring, opencl_context
2+
from .maxcut_tfim_util import compute_cut_streaming, compute_cut_diff_streaming, compute_cut_diff_2_streaming, compute_energy_streaming, compute_energy_diff_streaming, compute_energy_diff_2_streaming, get_cut, get_cut_base, gray_code_next, gray_mutation, heuristic_threshold, int_to_bitstring, opencl_context
33
import networkx as nx
44
import numpy as np
55
from numba import njit, prange
@@ -19,12 +19,12 @@ def run_single_bit_flips(best_theta, is_spin_glass, G_func, nodes):
1919
for i in prange(n):
2020
state = best_theta.copy()
2121
state[i] = not state[i]
22-
energies[i] = compute_energy_streaming(state, G_func, nodes, n)
22+
energies[i] = compute_energy_diff_streaming(i, state, G_func, nodes, n)
2323
else:
2424
for i in prange(n):
2525
state = best_theta.copy()
2626
state[i] = not state[i]
27-
energies[i] = compute_cut_streaming(state, G_func, nodes, n)
27+
energies[i] = compute_cut_diff_streaming(i, state, G_func, nodes, n)
2828

2929
best_index = np.argmax(energies)
3030
best_energy = energies[best_index]
@@ -62,7 +62,7 @@ def run_double_bit_flips(best_theta, is_spin_glass, G_func, nodes, thread_count)
6262
state[i] = not state[i]
6363
state[j] = not state[j]
6464

65-
states[t], energies[t] = state, compute_energy_streaming(state, G_func, nodes, n)
65+
states[t], energies[t] = state, compute_energy_diff_2_streaming(i, j, state, G_func, nodes, n)
6666

6767
s += thread_batch
6868
else:
@@ -84,7 +84,7 @@ def run_double_bit_flips(best_theta, is_spin_glass, G_func, nodes, thread_count)
8484
state[i] = not state[i]
8585
state[j] = not state[j]
8686

87-
states[t], energies[t] = state, compute_cut_streaming(state, G_func, nodes, n)
87+
states[t], energies[t] = state, compute_cut_diff_2_streaming(i, j, state, G_func, nodes, n)
8888

8989
s += thread_batch
9090

@@ -247,16 +247,16 @@ def spin_glass_solver_streaming(
247247

248248
# Single bit flips with O(n^2)
249249
energy, state = run_single_bit_flips(best_theta, is_spin_glass, G_func, nodes)
250-
if energy > max_energy:
251-
max_energy = energy
250+
if energy > 0.0:
251+
max_energy += energy
252252
best_theta = state
253253
improved = True
254254
continue
255255

256256
# Double bit flips with O(n^3)
257257
energy, state = run_double_bit_flips(best_theta, is_spin_glass, G_func, nodes, thread_count)
258-
if energy > max_energy:
259-
max_energy = energy
258+
if energy > 0.0:
259+
max_energy += energy
260260
best_theta = state
261261
improved = True
262262
continue
@@ -277,21 +277,26 @@ def spin_glass_solver_streaming(
277277
improved = True
278278
continue
279279

280+
if max_energy == float("inf"):
281+
# We no way to compare for improvement.
282+
break
283+
280284
# Post-reheat phase
281285
reheat_theta = state
286+
reheat_energy = energy
282287

283288
# Single bit flips with O(n^2)
284289
energy, state = run_single_bit_flips(reheat_theta, is_spin_glass, G_func, nodes)
285-
if energy > max_energy:
286-
max_energy = energy
290+
if energy > (max_energy - reheat_energy):
291+
max_energy += energy
287292
best_theta = state
288293
improved = True
289294
continue
290295

291296
# Double bit flips with O(n^3)
292297
energy, state = run_double_bit_flips(reheat_theta, is_spin_glass, G_func, nodes, thread_count)
293-
if energy > max_energy:
294-
max_energy = energy
298+
if energy > (max_energy - reheat_energy):
299+
max_energy += energy
295300
best_theta = state
296301
improved = True
297302

0 commit comments

Comments
 (0)