Skip to content

Commit 6644248

Browse files
committed
Fix tfq_simulate_ops_cuda op test.
1 parent 23dd880 commit 6644248

File tree

1 file changed

+29
-74
lines changed

1 file changed

+29
-74
lines changed

tensorflow_quantum/core/ops/tfq_simulate_ops_cuda_test.py

Lines changed: 29 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,23 @@
2424
from tensorflow_quantum.core.ops import tfq_simulate_ops_cuda
2525
from tensorflow_quantum.python import util
2626

27+
def measure_average_runtime(fn, tag, num_samples=10):
28+
avg_time = []
29+
for _ in range(num_samples):
30+
begin_time = time.time()
31+
result = fn()
32+
duration = time.time() - begin_time
33+
avg_time.append(duration)
34+
avg_time = sum(avg_time) / float(num_samples)
35+
print(f"\n\t{tag} time: {avg_time}\n")
36+
return avg_time, result
37+
2738

2839
class SimulateExpectationTest(tf.test.TestCase):
2940
"""Tests tfq_simulate_expectation."""
3041

31-
def test_simulate_expectation_diff(self):
32-
"""Make sure that cpu & gpu ops have the same results."""
33-
# TF 2
34-
# gpus = tf.config.list_physical_devices('GPU')
35-
# self.assertLess(len(gpus), 1)
36-
# if len(gpus) < 1:
37-
# self.skipTest("Expected at least 1 GPU but found {} GPUs".format(
38-
# len(gpus)))
42+
def test_simulate_expectation_cpu_vs_cuda(self):
43+
"""Make sure that cpu & gpu(cuda) ops have the same results."""
3944
n_qubits = 20
4045
batch_size = 5
4146
symbol_names = ['alpha']
@@ -54,77 +59,27 @@ def test_simulate_expectation_diff(self):
5459
pauli_sums = util.random_pauli_sums(qubits, 3, batch_size)
5560
pauli_sums_tensor = util.convert_to_tensor([[x] for x in pauli_sums])
5661

57-
cpu_avg_time = []
58-
for _ in range(10):
59-
cpu_time = time.time()
60-
res_cpu = tfq_simulate_ops.tfq_simulate_expectation(
62+
cpu_avg_time, res_cpu = measure_average_runtime(
63+
lambda: tfq_simulate_ops.tfq_simulate_expectation(
6164
circuit_batch_tensor,
6265
symbol_names, symbol_values_array.astype(np.float64),
63-
pauli_sums_tensor)
64-
cpu_time = time.time() - cpu_time
65-
cpu_avg_time.append(cpu_time)
66-
cpu_avg_time = sum(cpu_avg_time) / 10.0
67-
print("\n\tCPU time: ", cpu_avg_time, "\n")
68-
69-
avg_cpu_with_gpu_time = []
70-
for _ in range(10):
71-
cpu_with_gpu_time = time.time()
72-
with tf.device("/device:GPU:0"):
73-
res_cpu_with_gpu = tfq_simulate_ops_cuda.tfq_simulate_expectation(
74-
circuit_batch_tensor,
75-
symbol_names, symbol_values_array.astype(np.float64),
76-
pauli_sums_tensor)
77-
cpu_with_gpu_time = time.time() - cpu_with_gpu_time
78-
avg_cpu_with_gpu_time.append(cpu_with_gpu_time)
79-
avg_cpu_with_gpu_time = sum(avg_cpu_with_gpu_time) / 10.0
80-
81-
# Both are CPU devices.
82-
self.assertEqual(res_cpu.device, res_cpu_with_gpu.device)
83-
np.testing.assert_allclose(res_cpu, res_cpu_with_gpu)
84-
print("\n\tCPU with GPU device time: ", avg_cpu_with_gpu_time, "\n")
85-
86-
@tf.function
87-
def cpu_with_gpu_fn():
88-
with tf.device("/device:GPU:0"):
89-
return tfq_simulate_ops_cuda.tfq_simulate_expectation(
90-
circuit_batch_tensor,
91-
symbol_names, symbol_values_array.astype(np.float64),
92-
pauli_sums_tensor)
66+
pauli_sums_tensor),
67+
"CPU"
68+
)
9369

94-
avg_fn_cpu_with_gpu_time = []
95-
for _ in range(10):
96-
fn_cpu_with_gpu_time = time.time()
97-
res_fn_cpu_with_gpu = cpu_with_gpu_fn()
98-
fn_cpu_with_gpu_time = time.time() - fn_cpu_with_gpu_time
99-
avg_fn_cpu_with_gpu_time.append(fn_cpu_with_gpu_time)
100-
avg_fn_cpu_with_gpu_time = sum(avg_fn_cpu_with_gpu_time) / 10.0
101-
102-
# CPU & GPU devices.
103-
self.assertNotEqual(res_cpu.device, res_fn_cpu_with_gpu.device)
104-
np.testing.assert_allclose(res_cpu, res_fn_cpu_with_gpu)
105-
print("\n\ttf.function, CPU with GPU device time: ",
106-
avg_fn_cpu_with_gpu_time, "\n")
107-
108-
# avg_gpu_time = []
109-
# for _ in range(10):
110-
# gpu_time = time.time()
111-
# res_gpu = tfq_simulate_ops_gpu_cpu.tfq_simulate_expectation(
112-
# circuit_batch_tensor,
113-
# symbol_names, symbol_values_array.astype(np.float64),
114-
# pauli_sums_tensor)
115-
# gpu_time = time.time() - gpu_time
116-
# avg_gpu_time.append(gpu_time)
117-
# avg_gpu_time = sum(avg_gpu_time) / 10.0
118-
# print("\n\tGPU version time: ", avg_gpu_time, "\n")
70+
cuda_avg_time, res_cuda = measure_average_runtime(
71+
lambda: tfq_simulate_ops_cuda.tfq_simulate_expectation(
72+
circuit_batch_tensor,
73+
symbol_names, symbol_values_array.astype(np.float64),
74+
pauli_sums_tensor),
75+
"CUDA"
76+
)
11977

78+
# The result should be the similar within a tolerance.
79+
np.testing.assert_allclose(res_cpu, res_cuda, atol=1e-5)
12080

121-
# # This guarantees that both tensors are not in the same devices
122-
# # (e.g. CPU vs GPU)
123-
# # self.assertNotEqual(res.device, res_gpu.device)
124-
# # -> this doesn't work anymore because TFQ op itself is in CPU.
125-
# # only qsim::SimulatorCUDA is in GPU
126-
# np.testing.assert_allclose(res_cpu, res_gpu)
127-
# self.assertGreater(cpu_avg_time, avg_gpu_time)
81+
# CUDA op should be faster than CPU op.
82+
self.assertGreater(cpu_avg_time, cuda_avg_time)
12883

12984

13085
if __name__ == "__main__":

0 commit comments

Comments
 (0)