@@ -40,7 +40,11 @@ def jw_molecule_compare_hamiltonians_test(xyz):
4040 of_hamiltonian , data = cudaq .chemistry .create_molecular_hamiltonian (
4141 xyz , 'sto-3g' , 1 , 0 )
4242
43- # Compute energy using CUDA-QX
43+ # Compute energy using CUDA-QX. Note you must run with
44+ # OMP_NUM_THREADS=1 if you want this to be bit-for-bit repeatable.
45+ # This is a PySCF limitation. With OMP_NUM_THREADS>1, the Hamiltonian
46+ # coefficients will randomly toggle their signs, but the resulting
47+ # eigenvalues of the Hamiltonian will still be correct.
4448 molecule = solvers .create_molecule (xyz , 'sto-3g' , 0 , 0 , casci = True )
4549 cqx_op = solvers .jordan_wigner (
4650 molecule .hpq ,
@@ -57,7 +61,12 @@ def jw_molecule_compare_hamiltonians_test(xyz):
5761 assert (k in of_hamiltonian_dict .keys ())
5862
5963 for k in of_hamiltonian_dict .keys ():
60- np .isclose (of_hamiltonian_dict [k ], cqx_op_dict [k ], 1e-12 )
64+ # Use abs() checks because the sign can mismatch and still keep the same
65+ # eigenvalues. Also, see OMP_NUM_THREADS note above.
66+ assert np .isclose (abs (np .real (of_hamiltonian_dict [k ])),
67+ abs (np .real (cqx_op_dict [k ])), 1e-12 )
68+ assert np .isclose (abs (np .imag (of_hamiltonian_dict [k ])),
69+ abs (np .imag (cqx_op_dict [k ])), 1e-12 )
6170
6271
6372def jw_molecule_test (xyz ):
@@ -73,15 +82,19 @@ def jw_molecule_test(xyz):
7382 of_energy = np .min (np .linalg .eigvals (of_hamiltonian .to_matrix ()))
7483 print (f'OpenFermion energy: { of_energy .real } ' )
7584
76- # Compute energy using CUDA-QX
85+ # Compute energy using CUDA-QX. Note you must run with
86+ # OMP_NUM_THREADS=1 if you want this to be bit-for-bit repeatable.
87+ # This is a PySCF limitation. With OMP_NUM_THREADS>1, the Hamiltonian
88+ # coefficients will randomly toggle their signs, but the resulting
89+ # eigenvalues of the Hamiltonian will still be correct.
7790 molecule = solvers .create_molecule (xyz , 'sto-3g' , 0 , 0 , casci = True )
7891 op = solvers .jordan_wigner (molecule .hpq ,
7992 molecule .hpqrs ,
80- core_energy = molecule .energies ['nuclear_energy' ])
93+ core_energy = molecule .energies ['nuclear_energy' ],
94+ tol = 1e-12 )
8195 assert op == molecule .hamiltonian
8296 assert of_hamiltonian == molecule .hamiltonian
8397
84- # FIXME - why do we need to call eigvals again if we can just assert the equality checks above?
8598 cudaqx_eig = np .min (np .linalg .eigvals (op .to_matrix ()))
8699 print (f'CUDA-QX energy: { cudaqx_eig .real } ' )
87100 assert np .isclose (cudaqx_eig , of_energy .real , atol = 1e-4 )
0 commit comments