Skip to content

Commit c35febc

Browse files
Gray code search by cut/energy differential
1 parent 4c05892 commit c35febc

File tree

3 files changed

+28
-25
lines changed

3 files changed

+28
-25
lines changed

pyqrackising/maxcut_tfim_util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,4 +744,5 @@ def gray_mutation(index, seed_bits, offset):
744744
bits = seed_bits.copy()
745745
for i in range(n):
746746
bits[n - offset - 1 - i] ^= (gray >> i) & 1
747+
747748
return bits

pyqrackising/spin_glass_solver.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -141,41 +141,42 @@ def pick_gray_seeds(best_theta, thread_count, gray_seed_multiple, G_m, n, is_spi
141141
return best_seeds, best_energies
142142

143143
@njit(parallel=True)
144-
def run_gray_optimization(best_theta, iterators, energies, gray_iterations, thread_count, is_spin_glass, G_m):
144+
def run_gray_optimization(best_theta, iterators, gray_iterations, thread_count, is_spin_glass, G_m):
145145
n = len(best_theta)
146146
thread_iterations = (gray_iterations + thread_count - 1) // thread_count
147147
blocks = (n + 63) >> 6
148+
energies = np.empty(thread_count, dtype=dtype)
148149

149150
if is_spin_glass:
150151
for i in prange(thread_count):
151152
iterator = iterators[i]
152-
best_energy = energies[i]
153+
best_energy = 0.0
153154
for curr_idx in range(thread_iterations):
154155
for block in range(blocks):
155156
flip_bit = gray_code_next(iterator, curr_idx, block << 6)
156-
energy = compute_energy(iterator, G_m, n)
157+
energy = compute_energy_diff(flip_bit, iterator, G_m, n)
157158
if energy > best_energy:
158159
best_energy = energy
159160
else:
160161
# Revert iterator
161162
iterator[flip_bit] = not iterator[flip_bit]
162-
if best_energy > energies[i]:
163-
energies[i] = best_energy
163+
if best_energy > 0.0:
164+
energies[i] += best_energy
164165
else:
165166
for i in prange(thread_count):
166167
iterator = iterators[i]
167-
best_energy = energies[i]
168+
best_energy = 0.0
168169
for curr_idx in range(thread_iterations):
169170
for block in range(blocks):
170171
flip_bit = gray_code_next(iterator, curr_idx, block << 6)
171-
energy = compute_cut(iterator, G_m, n)
172+
energy = compute_cut_diff(flip_bit, iterator, G_m, n)
172173
if energy > best_energy:
173174
best_energy = energy
174175
else:
175176
# Revert iterator
176177
iterator[flip_bit] = not iterator[flip_bit]
177-
if best_energy > energies[i]:
178-
energies[i] = best_energy
178+
if best_energy > 0.0:
179+
energies[i] += best_energy
179180

180181
best_index = np.argmax(energies)
181182
best_energy = energies[best_index]
@@ -295,9 +296,7 @@ def run_gray_search_opencl(n, kernel, best_energy, theta, theta_buf, G_m_buf, is
295296

296297
if energy <= 0.0:
297298
# No improvement: we can exit early
298-
return best_energy, theta
299-
300-
energy += best_energy
299+
return 0.0, theta
301300

302301
# We need the best index
303302
queue.finish()
@@ -457,9 +456,10 @@ def spin_glass_solver(
457456
improved = True
458457
continue
459458

460-
energy, state = run_gray_optimization(best_theta, iterators, energies, gray_iterations, thread_count, is_spin_glass, G_m)
461-
if energy > max_energy:
462-
max_energy = energy
459+
energies = None
460+
energy, state = run_gray_optimization(best_theta, iterators, gray_iterations, thread_count, is_spin_glass, G_m)
461+
if energy > 0.0:
462+
max_energy += energy
463463
best_theta = state
464464
improved = True
465465
continue

pyqrackising/spin_glass_solver_streaming.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,11 @@ def pick_gray_seeds(best_theta, thread_count, gray_seed_multiple, G_func, nodes,
132132
return best_seeds, best_energies
133133

134134
@njit(parallel=True)
135-
def run_gray_optimization(best_theta, iterators, energies, gray_iterations, thread_count, is_spin_glass, G_func, nodes):
135+
def run_gray_optimization(best_theta, iterators, gray_iterations, thread_count, is_spin_glass, G_func, nodes):
136136
n = len(best_theta)
137137
thread_iterations = (gray_iterations + thread_count - 1) // thread_count
138138
blocks = (n + 63) >> 6
139+
energies = np.empty(thread_count, dtype=dtype)
139140

140141
if is_spin_glass:
141142
for i in prange(thread_count):
@@ -144,29 +145,29 @@ def run_gray_optimization(best_theta, iterators, energies, gray_iterations, thre
144145
for curr_idx in range(thread_iterations):
145146
for block in range(blocks):
146147
flip_bit = gray_code_next(iterator, curr_idx, block << 6)
147-
energy = compute_energy_streaming(iterator, G_func, nodes, n)
148+
energy = compute_energy_diff_streaming(flip_bit, iterator, G_func, nodes, n)
148149
if energy > best_energy:
149150
best_energy = energy
150151
else:
151152
# Revert iterator
152153
iterator[flip_bit] = not iterator[flip_bit]
153-
if best_energy > energies[i]:
154-
energies[i] = best_energy
154+
if best_energy > 0.0:
155+
energies[i] += best_energy
155156
else:
156157
for i in prange(thread_count):
157158
iterator = iterators[i]
158159
best_energy = energies[i]
159160
for curr_idx in range(thread_iterations):
160161
for block in range(blocks):
161162
flip_bit = gray_code_next(iterator, curr_idx, block << 6)
162-
energy = compute_cut_streaming(iterator, G_func, nodes, n)
163+
energy = compute_cut_diff_streaming(flip_bit, iterator, G_func, nodes, n)
163164
if energy > best_energy:
164165
best_energy = energy
165166
else:
166167
# Revert iterator
167168
iterator[flip_bit] = not iterator[flip_bit]
168-
if best_energy > energies[i]:
169-
energies[i] = best_energy
169+
if best_energy > 0.0:
170+
energies[i] += best_energy
170171

171172
best_index = np.argmax(energies)
172173
best_energy = energies[best_index]
@@ -270,9 +271,10 @@ def spin_glass_solver_streaming(
270271
improved = True
271272
continue
272273

273-
energy, state = run_gray_optimization(best_theta, iterators, energies, gray_iterations, thread_count, is_spin_glass, G_func, nodes)
274-
if energy > max_energy:
275-
max_energy = energy
274+
energies = None
275+
energy, state = run_gray_optimization(best_theta, iterators, gray_iterations, thread_count, is_spin_glass, G_func, nodes)
276+
if energy > 0.0:
277+
max_energy += energy
276278
best_theta = state
277279
improved = True
278280
continue

0 commit comments

Comments
 (0)