File size: 2,723 Bytes
47709ed | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #!/usr/bin/env python3
import json
import sys
from pathlib import Path
import torch
PROJECT_DIR = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_DIR / "code/src"))
from quantum_qwen38.quantum_residual import NativeStatevectorVQC
def main() -> None:
torch.manual_seed(20260828)
device = torch.device("cuda:0")
angles = (torch.rand(32, 8, device=device) * 2.0 - 1.0).requires_grad_(True)
analytic_circuit = NativeStatevectorVQC(n_qubits=8, depth=0).to(device)
measured = analytic_circuit(angles)
expected = torch.cos(angles)
forward_max_abs_error = float((measured - expected).abs().max())
measured.sum().backward()
gradient_max_abs_error = float((angles.grad - (-torch.sin(angles.detach()))).abs().max())
trainable_circuit = NativeStatevectorVQC(n_qubits=8, depth=1).to(device)
fixed_angles = torch.randn(16, 8, device=device)
loss = trainable_circuit(fixed_angles).square().mean()
loss.backward()
autograd_value = float(trainable_circuit.theta.grad[0, 0, 0])
epsilon = 1.0e-3
with torch.no_grad():
original = trainable_circuit.theta[0, 0, 0].clone()
trainable_circuit.theta[0, 0, 0] = original + epsilon
plus = float(trainable_circuit(fixed_angles).square().mean())
trainable_circuit.theta[0, 0, 0] = original - epsilon
minus = float(trainable_circuit(fixed_angles).square().mean())
trainable_circuit.theta[0, 0, 0] = original
finite_difference_value = (plus - minus) / (2.0 * epsilon)
finite_difference_abs_error = abs(autograd_value - finite_difference_value)
finite_difference_relative_error = finite_difference_abs_error / max(
abs(autograd_value), abs(finite_difference_value), 1.0e-12
)
result = {
"status": "ok",
"device": torch.cuda.get_device_name(0),
"analytic_forward_max_abs_error": forward_max_abs_error,
"analytic_input_gradient_max_abs_error": gradient_max_abs_error,
"trainable_gate_autograd": autograd_value,
"trainable_gate_finite_difference": finite_difference_value,
"trainable_gate_abs_error": finite_difference_abs_error,
"trainable_gate_relative_error": finite_difference_relative_error,
"passes": {
"forward": forward_max_abs_error < 1.0e-5,
"input_gradient": gradient_max_abs_error < 1.0e-5,
"trainable_gate_gradient": finite_difference_relative_error < 2.0e-2,
},
}
if not all(result["passes"].values()):
result["status"] = "failed"
print(json.dumps(result, ensure_ascii=False, indent=2))
if result["status"] != "ok":
raise SystemExit(1)
if __name__ == "__main__":
main()
|