Skip to content

Commit

Permalink
Merge pull request #876 from Shivansh20128/12-parallelize-classival-v…
Browse files Browse the repository at this point in the history
…alue

Parallelize classical value in nonlocal games
  • Loading branch information
vprusso authored Dec 7, 2024
2 parents df15208 + c66cc8f commit 0cb040e
Showing 1 changed file with 41 additions and 13 deletions.
54 changes: 41 additions & 13 deletions toqito/nonlocal_games/nonlocal_game.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Two-player nonlocal game."""

import multiprocessing
from collections import defaultdict

import cvxpy
Expand Down Expand Up @@ -120,6 +121,29 @@ def from_bcs_game(cls, constraints: list[np.ndarray], reps: int = 1) -> "Nonloca

return cls(prob_mat, pred_mat, reps)

def process_iteration(i:int, num_bob_outputs:int, num_bob_inputs:int, pred_mat_copy:np.ndarray,
num_alice_outputs:int, num_alice_inputs:int)-> float:
"""Help the classical_value function as a helper method.
:return: A value between [0, 1] representing the tgval.
"""
number = i
base = num_bob_outputs
digits = num_bob_inputs
b_ind = np.zeros(digits)

for j in range(digits - 1, -1, -1):
number, remainder = divmod(number, base)
b_ind[j] = remainder

pred_alice = np.zeros((num_alice_outputs, num_alice_inputs))

for y_bob_in in range(num_bob_inputs):
pred_alice += pred_mat_copy[:, :, int(b_ind[y_bob_in]), y_bob_in]

tgval = np.sum(np.amax(pred_alice, axis=0))
return tgval

def classical_value(self) -> float:
"""Compute the classical value of the nonlocal game.
Expand Down Expand Up @@ -153,20 +177,24 @@ def classical_value(self) -> float:
) = pred_mat_copy.shape
pred_mat_copy = np.transpose(pred_mat_copy, (0, 2, 1, 3))

for i in range(num_alice_outputs**num_bob_inputs):
number = i
base = num_bob_outputs
digits = num_bob_inputs
b_ind = np.zeros(digits)
for j in range(digits):
b_ind[digits - j - 1] = np.mod(number, base)
number = np.floor(number / base)
pred_alice = np.zeros((num_alice_outputs, num_alice_inputs))
num_iterations = num_alice_outputs**num_bob_inputs

# we parallelize for large problems only
if num_iterations > 1000:
with multiprocessing.Pool() as pool: # Creating a pool of processes for parallelization
tgvals = pool.starmap(
NonlocalGame.process_iteration,
[(i, num_bob_outputs, num_bob_inputs, pred_mat_copy, num_alice_outputs, num_alice_inputs)
for i in range(num_iterations)]
)
p_win = max(tgvals)
# Using single core implementation for small problems
else:
for i in range(num_iterations):
tgval = NonlocalGame.process_iteration(i, num_bob_outputs, num_bob_inputs, pred_mat_copy,
num_alice_outputs, num_alice_inputs)
p_win = max(p_win, tgval)

for y_bob_in in range(num_bob_inputs):
pred_alice = pred_alice + pred_mat_copy[:, :, int(b_ind[y_bob_in]), y_bob_in]
tgval = np.sum(np.amax(pred_alice, axis=0))
p_win = max(p_win, tgval)
return p_win

def quantum_value_lower_bound(
Expand Down

0 comments on commit 0cb040e

Please sign in to comment.