Copilot commented on code in PR #824:
URL: https://github.com/apache/mahout/pull/824#discussion_r2693154704
##########
qdp/qdp-python/tests/test_numpy.py:
##########
@@ -24,118 +23,123 @@
from _qdp import QdpEngine
-def test_encode_from_numpy_basic():
- """Test basic NumPy file encoding"""
- engine = QdpEngine(device_id=0)
-
- # Create test data
- num_samples = 10
- num_qubits = 3
- sample_size = 2**num_qubits # 8
-
- # Generate normalized data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- # Normalize each row
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
-
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
-
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
-
- # Verify shape
- assert tensor.shape == (num_samples, sample_size), (
- f"Expected shape {(num_samples, sample_size)}, got {tensor.shape}"
- )
-
- # Verify it's on GPU
- assert tensor.is_cuda, "Tensor should be on CUDA device"
+def _verify_tensor(tensor, expected_shape, check_normalization=False):
+ """Helper function to verify tensor properties"""
+ assert tensor.shape == expected_shape, (
+ f"Expected shape {expected_shape}, got {tensor.shape}"
+ )
+ assert tensor.is_cuda, "Tensor should be on CUDA device"
- # Verify normalization (amplitude encoding normalizes)
+ if check_normalization:
norms = tensor.abs().pow(2).sum(dim=1).sqrt()
assert torch.allclose(norms, torch.ones_like(norms), atol=1e-5), (
"States should be normalized"
)
- print("✓ test_encode_from_numpy_basic passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
-
-
-def test_encode_from_numpy_large():
- """Test NumPy encoding with larger dataset"""
+def test_encode_from_numpy_file():
+ """Test NumPy file encoding"""
engine = QdpEngine(device_id=0)
Review Comment:
Missing `@pytest.mark.gpu` decorator. Other test files in this repository
use this marker for GPU-dependent tests (see test_bindings.py and
test_high_fidelity.py). All test functions in this file require GPU and should
be marked accordingly.
##########
qdp/qdp-python/tests/test_numpy.py:
##########
@@ -24,118 +23,123 @@
from _qdp import QdpEngine
-def test_encode_from_numpy_basic():
- """Test basic NumPy file encoding"""
- engine = QdpEngine(device_id=0)
-
- # Create test data
- num_samples = 10
- num_qubits = 3
- sample_size = 2**num_qubits # 8
-
- # Generate normalized data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- # Normalize each row
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
-
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
-
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
-
- # Verify shape
- assert tensor.shape == (num_samples, sample_size), (
- f"Expected shape {(num_samples, sample_size)}, got {tensor.shape}"
- )
-
- # Verify it's on GPU
- assert tensor.is_cuda, "Tensor should be on CUDA device"
+def _verify_tensor(tensor, expected_shape, check_normalization=False):
+ """Helper function to verify tensor properties"""
+ assert tensor.shape == expected_shape, (
+ f"Expected shape {expected_shape}, got {tensor.shape}"
+ )
+ assert tensor.is_cuda, "Tensor should be on CUDA device"
- # Verify normalization (amplitude encoding normalizes)
+ if check_normalization:
norms = tensor.abs().pow(2).sum(dim=1).sqrt()
assert torch.allclose(norms, torch.ones_like(norms), atol=1e-5), (
"States should be normalized"
)
- print("✓ test_encode_from_numpy_basic passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
-
-
-def test_encode_from_numpy_large():
- """Test NumPy encoding with larger dataset"""
+def test_encode_from_numpy_file():
+ """Test NumPy file encoding"""
engine = QdpEngine(device_id=0)
- num_samples = 100
- num_qubits = 6
- sample_size = 2**num_qubits # 64
-
- # Generate test data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
+ test_cases = [
+ (10, 3, True), # Basic: 10 samples, 3 qubits, check normalization
+ (100, 6, False), # Large: 100 samples, 6 qubits
+ (1, 4, False), # Single sample: 1 sample, 4 qubits
+ ]
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ for num_samples, num_qubits, check_norm in test_cases:
+ sample_size = 2**num_qubits
- try:
- np.save(npy_path, data)
+ # Generate normalized data
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
+ # Save to temporary .npy file
+ with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
+ npy_path = f.name
- # Verify
- assert tensor.shape == (num_samples, sample_size)
- assert tensor.is_cuda
+ try:
+ np.save(npy_path, data)
+ qtensor = engine.encode(npy_path, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
- print("✓ test_encode_from_numpy_large passed")
+ _verify_tensor(tensor, (num_samples, sample_size), check_norm)
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+ finally:
+ if os.path.exists(npy_path):
+ os.remove(npy_path)
-def test_encode_from_numpy_single_sample():
- """Test NumPy encoding with single sample"""
+def test_encode_numpy_array():
+ """Test NumPy array encoding (1D and 2D)"""
engine = QdpEngine(device_id=0)
Review Comment:
Missing `@pytest.mark.gpu` decorator. Other test files in this repository
use this marker for GPU-dependent tests (see test_bindings.py and
test_high_fidelity.py). All test functions in this file require GPU and should
be marked accordingly.
##########
qdp/qdp-python/tests/test_numpy.py:
##########
@@ -24,118 +23,123 @@
from _qdp import QdpEngine
-def test_encode_from_numpy_basic():
- """Test basic NumPy file encoding"""
- engine = QdpEngine(device_id=0)
-
- # Create test data
- num_samples = 10
- num_qubits = 3
- sample_size = 2**num_qubits # 8
-
- # Generate normalized data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- # Normalize each row
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
-
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
-
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
-
- # Verify shape
- assert tensor.shape == (num_samples, sample_size), (
- f"Expected shape {(num_samples, sample_size)}, got {tensor.shape}"
- )
-
- # Verify it's on GPU
- assert tensor.is_cuda, "Tensor should be on CUDA device"
+def _verify_tensor(tensor, expected_shape, check_normalization=False):
+ """Helper function to verify tensor properties"""
+ assert tensor.shape == expected_shape, (
+ f"Expected shape {expected_shape}, got {tensor.shape}"
+ )
+ assert tensor.is_cuda, "Tensor should be on CUDA device"
- # Verify normalization (amplitude encoding normalizes)
+ if check_normalization:
norms = tensor.abs().pow(2).sum(dim=1).sqrt()
assert torch.allclose(norms, torch.ones_like(norms), atol=1e-5), (
"States should be normalized"
)
- print("✓ test_encode_from_numpy_basic passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
-
-
-def test_encode_from_numpy_large():
- """Test NumPy encoding with larger dataset"""
+def test_encode_from_numpy_file():
+ """Test NumPy file encoding"""
engine = QdpEngine(device_id=0)
- num_samples = 100
- num_qubits = 6
- sample_size = 2**num_qubits # 64
-
- # Generate test data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
+ test_cases = [
+ (10, 3, True), # Basic: 10 samples, 3 qubits, check normalization
+ (100, 6, False), # Large: 100 samples, 6 qubits
+ (1, 4, False), # Single sample: 1 sample, 4 qubits
+ ]
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ for num_samples, num_qubits, check_norm in test_cases:
+ sample_size = 2**num_qubits
- try:
- np.save(npy_path, data)
+ # Generate normalized data
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
+ # Save to temporary .npy file
+ with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
+ npy_path = f.name
- # Verify
- assert tensor.shape == (num_samples, sample_size)
- assert tensor.is_cuda
+ try:
+ np.save(npy_path, data)
+ qtensor = engine.encode(npy_path, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
- print("✓ test_encode_from_numpy_large passed")
+ _verify_tensor(tensor, (num_samples, sample_size), check_norm)
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+ finally:
+ if os.path.exists(npy_path):
+ os.remove(npy_path)
-def test_encode_from_numpy_single_sample():
- """Test NumPy encoding with single sample"""
+def test_encode_numpy_array():
+ """Test NumPy array encoding (1D and 2D)"""
engine = QdpEngine(device_id=0)
- num_qubits = 4
- sample_size = 2**num_qubits # 16
+ # 1D arrays
+ for num_qubits in [1, 2, 3, 4]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(sample_size).astype(np.float64)
+ data = data / np.linalg.norm(data)
- # Single sample
- data = np.random.randn(1, sample_size).astype(np.float64)
- data = data / np.linalg.norm(data)
+ qtensor = engine.encode(data, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (1, sample_size), check_normalization=True)
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ # 2D arrays
+ for num_samples, num_qubits in [(5, 2), (10, 3)]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
+ qtensor = engine.encode(data, num_qubits)
tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (num_samples, sample_size),
check_normalization=True)
+
+
+def test_encode_numpy_configurations():
+ """Test different encoding methods and precision settings"""
+ num_qubits = 2
Review Comment:
Missing `@pytest.mark.gpu` decorator. Other test files in this repository
use this marker for GPU-dependent tests (see test_bindings.py and
test_high_fidelity.py). All test functions in this file require GPU and should
be marked accordingly.
##########
qdp/qdp-python/tests/test_numpy.py:
##########
@@ -24,118 +23,123 @@
from _qdp import QdpEngine
-def test_encode_from_numpy_basic():
- """Test basic NumPy file encoding"""
- engine = QdpEngine(device_id=0)
-
- # Create test data
- num_samples = 10
- num_qubits = 3
- sample_size = 2**num_qubits # 8
-
- # Generate normalized data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- # Normalize each row
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
-
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
-
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
-
- # Verify shape
- assert tensor.shape == (num_samples, sample_size), (
- f"Expected shape {(num_samples, sample_size)}, got {tensor.shape}"
- )
-
- # Verify it's on GPU
- assert tensor.is_cuda, "Tensor should be on CUDA device"
+def _verify_tensor(tensor, expected_shape, check_normalization=False):
+ """Helper function to verify tensor properties"""
+ assert tensor.shape == expected_shape, (
+ f"Expected shape {expected_shape}, got {tensor.shape}"
+ )
+ assert tensor.is_cuda, "Tensor should be on CUDA device"
- # Verify normalization (amplitude encoding normalizes)
+ if check_normalization:
norms = tensor.abs().pow(2).sum(dim=1).sqrt()
assert torch.allclose(norms, torch.ones_like(norms), atol=1e-5), (
"States should be normalized"
)
- print("✓ test_encode_from_numpy_basic passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
-
-
-def test_encode_from_numpy_large():
- """Test NumPy encoding with larger dataset"""
+def test_encode_from_numpy_file():
+ """Test NumPy file encoding"""
engine = QdpEngine(device_id=0)
- num_samples = 100
- num_qubits = 6
- sample_size = 2**num_qubits # 64
-
- # Generate test data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
+ test_cases = [
+ (10, 3, True), # Basic: 10 samples, 3 qubits, check normalization
+ (100, 6, False), # Large: 100 samples, 6 qubits
+ (1, 4, False), # Single sample: 1 sample, 4 qubits
+ ]
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ for num_samples, num_qubits, check_norm in test_cases:
+ sample_size = 2**num_qubits
- try:
- np.save(npy_path, data)
+ # Generate normalized data
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
+ # Save to temporary .npy file
+ with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
+ npy_path = f.name
- # Verify
- assert tensor.shape == (num_samples, sample_size)
- assert tensor.is_cuda
+ try:
+ np.save(npy_path, data)
+ qtensor = engine.encode(npy_path, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
- print("✓ test_encode_from_numpy_large passed")
+ _verify_tensor(tensor, (num_samples, sample_size), check_norm)
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+ finally:
+ if os.path.exists(npy_path):
+ os.remove(npy_path)
-def test_encode_from_numpy_single_sample():
- """Test NumPy encoding with single sample"""
+def test_encode_numpy_array():
+ """Test NumPy array encoding (1D and 2D)"""
engine = QdpEngine(device_id=0)
- num_qubits = 4
- sample_size = 2**num_qubits # 16
+ # 1D arrays
+ for num_qubits in [1, 2, 3, 4]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(sample_size).astype(np.float64)
+ data = data / np.linalg.norm(data)
- # Single sample
- data = np.random.randn(1, sample_size).astype(np.float64)
- data = data / np.linalg.norm(data)
+ qtensor = engine.encode(data, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (1, sample_size), check_normalization=True)
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ # 2D arrays
+ for num_samples, num_qubits in [(5, 2), (10, 3)]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
+ qtensor = engine.encode(data, num_qubits)
tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (num_samples, sample_size),
check_normalization=True)
+
+
+def test_encode_numpy_configurations():
+ """Test different encoding methods and precision settings"""
+ num_qubits = 2
+ sample_size = 2**num_qubits
+ data = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float64)
- assert tensor.shape == (1, sample_size)
- assert tensor.is_cuda
+ # Test encoding methods
+ # TODO: Add angle and basis encoding tests when implemented
+ engine = QdpEngine(device_id=0)
+ for method in ["amplitude"]:
+ qtensor = engine.encode(data, num_qubits, encoding_method=method)
+ tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (1, sample_size))
+
+ # Test precision settings
+ for precision, expected_dtype in [
+ ("float32", torch.complex64),
+ ("float64", torch.complex128),
+ ]:
+ engine = QdpEngine(device_id=0, precision=precision)
+ qtensor = engine.encode(data, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
+ assert tensor.dtype == expected_dtype, (
+ f"Expected {expected_dtype}, got {tensor.dtype}"
+ )
- print("✓ test_encode_from_numpy_single_sample passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+def test_encode_numpy_errors():
+ """Test error handling for invalid inputs"""
+ engine = QdpEngine(device_id=0)
Review Comment:
Missing `@pytest.mark.gpu` decorator. Other test files in this repository
use this marker for GPU-dependent tests (see test_bindings.py and
test_high_fidelity.py). All test functions in this file require GPU and should
be marked accordingly.
##########
qdp/qdp-python/tests/test_numpy.py:
##########
@@ -24,118 +23,123 @@
from _qdp import QdpEngine
-def test_encode_from_numpy_basic():
- """Test basic NumPy file encoding"""
- engine = QdpEngine(device_id=0)
-
- # Create test data
- num_samples = 10
- num_qubits = 3
- sample_size = 2**num_qubits # 8
-
- # Generate normalized data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- # Normalize each row
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
-
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
-
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
-
- # Verify shape
- assert tensor.shape == (num_samples, sample_size), (
- f"Expected shape {(num_samples, sample_size)}, got {tensor.shape}"
- )
-
- # Verify it's on GPU
- assert tensor.is_cuda, "Tensor should be on CUDA device"
+def _verify_tensor(tensor, expected_shape, check_normalization=False):
+ """Helper function to verify tensor properties"""
+ assert tensor.shape == expected_shape, (
+ f"Expected shape {expected_shape}, got {tensor.shape}"
+ )
+ assert tensor.is_cuda, "Tensor should be on CUDA device"
- # Verify normalization (amplitude encoding normalizes)
+ if check_normalization:
norms = tensor.abs().pow(2).sum(dim=1).sqrt()
assert torch.allclose(norms, torch.ones_like(norms), atol=1e-5), (
"States should be normalized"
)
- print("✓ test_encode_from_numpy_basic passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
-
-
-def test_encode_from_numpy_large():
- """Test NumPy encoding with larger dataset"""
+def test_encode_from_numpy_file():
+ """Test NumPy file encoding"""
engine = QdpEngine(device_id=0)
- num_samples = 100
- num_qubits = 6
- sample_size = 2**num_qubits # 64
-
- # Generate test data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
+ test_cases = [
+ (10, 3, True), # Basic: 10 samples, 3 qubits, check normalization
+ (100, 6, False), # Large: 100 samples, 6 qubits
+ (1, 4, False), # Single sample: 1 sample, 4 qubits
+ ]
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ for num_samples, num_qubits, check_norm in test_cases:
+ sample_size = 2**num_qubits
- try:
- np.save(npy_path, data)
+ # Generate normalized data
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
+ # Save to temporary .npy file
+ with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
+ npy_path = f.name
- # Verify
- assert tensor.shape == (num_samples, sample_size)
- assert tensor.is_cuda
+ try:
+ np.save(npy_path, data)
+ qtensor = engine.encode(npy_path, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
- print("✓ test_encode_from_numpy_large passed")
+ _verify_tensor(tensor, (num_samples, sample_size), check_norm)
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+ finally:
+ if os.path.exists(npy_path):
+ os.remove(npy_path)
-def test_encode_from_numpy_single_sample():
- """Test NumPy encoding with single sample"""
+def test_encode_numpy_array():
+ """Test NumPy array encoding (1D and 2D)"""
engine = QdpEngine(device_id=0)
- num_qubits = 4
- sample_size = 2**num_qubits # 16
+ # 1D arrays
+ for num_qubits in [1, 2, 3, 4]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(sample_size).astype(np.float64)
+ data = data / np.linalg.norm(data)
- # Single sample
- data = np.random.randn(1, sample_size).astype(np.float64)
- data = data / np.linalg.norm(data)
+ qtensor = engine.encode(data, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (1, sample_size), check_normalization=True)
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ # 2D arrays
+ for num_samples, num_qubits in [(5, 2), (10, 3)]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
+ qtensor = engine.encode(data, num_qubits)
tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (num_samples, sample_size),
check_normalization=True)
+
+
+def test_encode_numpy_configurations():
+ """Test different encoding methods and precision settings"""
+ num_qubits = 2
+ sample_size = 2**num_qubits
+ data = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float64)
- assert tensor.shape == (1, sample_size)
- assert tensor.is_cuda
+ # Test encoding methods
+ # TODO: Add angle and basis encoding tests when implemented
+ engine = QdpEngine(device_id=0)
+ for method in ["amplitude"]:
+ qtensor = engine.encode(data, num_qubits, encoding_method=method)
+ tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (1, sample_size))
+
+ # Test precision settings
+ for precision, expected_dtype in [
+ ("float32", torch.complex64),
+ ("float64", torch.complex128),
+ ]:
+ engine = QdpEngine(device_id=0, precision=precision)
+ qtensor = engine.encode(data, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
+ assert tensor.dtype == expected_dtype, (
+ f"Expected {expected_dtype}, got {tensor.dtype}"
+ )
- print("✓ test_encode_from_numpy_single_sample passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+def test_encode_numpy_errors():
+ """Test error handling for invalid inputs"""
+ engine = QdpEngine(device_id=0)
+ # Test wrong dtype
+ data_wrong_dtype = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+ try:
+ engine.encode(data_wrong_dtype, 2)
+ assert False, "Should have raised an error for wrong dtype"
+ except (RuntimeError, TypeError):
+ pass # Expected
Review Comment:
Use pytest.raises() instead of try-except with assert False. This is the
standard pytest pattern used elsewhere in test_bindings.py (lines 115, 214,
218, 223). Replace with: `with pytest.raises((RuntimeError, TypeError)):`
##########
qdp/qdp-python/tests/test_numpy.py:
##########
@@ -24,118 +23,123 @@
from _qdp import QdpEngine
-def test_encode_from_numpy_basic():
- """Test basic NumPy file encoding"""
- engine = QdpEngine(device_id=0)
-
- # Create test data
- num_samples = 10
- num_qubits = 3
- sample_size = 2**num_qubits # 8
-
- # Generate normalized data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- # Normalize each row
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
-
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
-
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
-
- # Verify shape
- assert tensor.shape == (num_samples, sample_size), (
- f"Expected shape {(num_samples, sample_size)}, got {tensor.shape}"
- )
-
- # Verify it's on GPU
- assert tensor.is_cuda, "Tensor should be on CUDA device"
+def _verify_tensor(tensor, expected_shape, check_normalization=False):
+ """Helper function to verify tensor properties"""
+ assert tensor.shape == expected_shape, (
+ f"Expected shape {expected_shape}, got {tensor.shape}"
+ )
+ assert tensor.is_cuda, "Tensor should be on CUDA device"
- # Verify normalization (amplitude encoding normalizes)
+ if check_normalization:
norms = tensor.abs().pow(2).sum(dim=1).sqrt()
assert torch.allclose(norms, torch.ones_like(norms), atol=1e-5), (
"States should be normalized"
)
- print("✓ test_encode_from_numpy_basic passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
-
-
-def test_encode_from_numpy_large():
- """Test NumPy encoding with larger dataset"""
+def test_encode_from_numpy_file():
+ """Test NumPy file encoding"""
engine = QdpEngine(device_id=0)
- num_samples = 100
- num_qubits = 6
- sample_size = 2**num_qubits # 64
-
- # Generate test data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
+ test_cases = [
+ (10, 3, True), # Basic: 10 samples, 3 qubits, check normalization
+ (100, 6, False), # Large: 100 samples, 6 qubits
+ (1, 4, False), # Single sample: 1 sample, 4 qubits
+ ]
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ for num_samples, num_qubits, check_norm in test_cases:
+ sample_size = 2**num_qubits
- try:
- np.save(npy_path, data)
+ # Generate normalized data
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
+ # Save to temporary .npy file
+ with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
+ npy_path = f.name
- # Verify
- assert tensor.shape == (num_samples, sample_size)
- assert tensor.is_cuda
+ try:
+ np.save(npy_path, data)
+ qtensor = engine.encode(npy_path, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
- print("✓ test_encode_from_numpy_large passed")
+ _verify_tensor(tensor, (num_samples, sample_size), check_norm)
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+ finally:
+ if os.path.exists(npy_path):
+ os.remove(npy_path)
-def test_encode_from_numpy_single_sample():
- """Test NumPy encoding with single sample"""
+def test_encode_numpy_array():
+ """Test NumPy array encoding (1D and 2D)"""
engine = QdpEngine(device_id=0)
- num_qubits = 4
- sample_size = 2**num_qubits # 16
+ # 1D arrays
+ for num_qubits in [1, 2, 3, 4]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(sample_size).astype(np.float64)
+ data = data / np.linalg.norm(data)
- # Single sample
- data = np.random.randn(1, sample_size).astype(np.float64)
- data = data / np.linalg.norm(data)
+ qtensor = engine.encode(data, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (1, sample_size), check_normalization=True)
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ # 2D arrays
+ for num_samples, num_qubits in [(5, 2), (10, 3)]:
+ sample_size = 2**num_qubits
+ data = np.random.randn(num_samples, sample_size).astype(np.float64)
+ norms = np.linalg.norm(data, axis=1, keepdims=True)
+ data = data / norms
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
+ qtensor = engine.encode(data, num_qubits)
tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (num_samples, sample_size),
check_normalization=True)
+
+
+def test_encode_numpy_configurations():
+ """Test different encoding methods and precision settings"""
+ num_qubits = 2
+ sample_size = 2**num_qubits
+ data = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float64)
- assert tensor.shape == (1, sample_size)
- assert tensor.is_cuda
+ # Test encoding methods
+ # TODO: Add angle and basis encoding tests when implemented
+ engine = QdpEngine(device_id=0)
+ for method in ["amplitude"]:
+ qtensor = engine.encode(data, num_qubits, encoding_method=method)
+ tensor = torch.from_dlpack(qtensor)
+ _verify_tensor(tensor, (1, sample_size))
+
+ # Test precision settings
+ for precision, expected_dtype in [
+ ("float32", torch.complex64),
+ ("float64", torch.complex128),
+ ]:
+ engine = QdpEngine(device_id=0, precision=precision)
+ qtensor = engine.encode(data, num_qubits)
+ tensor = torch.from_dlpack(qtensor)
+ assert tensor.dtype == expected_dtype, (
+ f"Expected {expected_dtype}, got {tensor.dtype}"
+ )
- print("✓ test_encode_from_numpy_single_sample passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
+def test_encode_numpy_errors():
+ """Test error handling for invalid inputs"""
+ engine = QdpEngine(device_id=0)
+ # Test wrong dtype
+ data_wrong_dtype = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+ try:
+ engine.encode(data_wrong_dtype, 2)
+ assert False, "Should have raised an error for wrong dtype"
+ except (RuntimeError, TypeError):
+ pass # Expected
-if __name__ == "__main__":
- test_encode_from_numpy_basic()
- test_encode_from_numpy_large()
- test_encode_from_numpy_single_sample()
- print("\n✅ All NumPy encoding tests passed!")
+ # Test unsupported dimensions (3D+)
+ data_3d = np.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=np.float64)
+ try:
+ engine.encode(data_3d, 1)
+ assert False, "Should have raised an error for 3D array"
+ except (RuntimeError, TypeError):
+ pass # Expected
Review Comment:
Use pytest.raises() instead of try-except with assert False. This is the
standard pytest pattern used elsewhere in test_bindings.py (lines 115, 214,
218, 223). Replace with: `with pytest.raises((RuntimeError, TypeError)):`
##########
qdp/qdp-python/tests/test_numpy.py:
##########
@@ -24,118 +23,123 @@
from _qdp import QdpEngine
-def test_encode_from_numpy_basic():
- """Test basic NumPy file encoding"""
- engine = QdpEngine(device_id=0)
-
- # Create test data
- num_samples = 10
- num_qubits = 3
- sample_size = 2**num_qubits # 8
-
- # Generate normalized data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- # Normalize each row
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
-
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
-
- try:
- np.save(npy_path, data)
-
- qtensor = engine.encode(npy_path, num_qubits)
- tensor = torch.from_dlpack(qtensor)
-
- # Verify shape
- assert tensor.shape == (num_samples, sample_size), (
- f"Expected shape {(num_samples, sample_size)}, got {tensor.shape}"
- )
-
- # Verify it's on GPU
- assert tensor.is_cuda, "Tensor should be on CUDA device"
+def _verify_tensor(tensor, expected_shape, check_normalization=False):
+ """Helper function to verify tensor properties"""
+ assert tensor.shape == expected_shape, (
+ f"Expected shape {expected_shape}, got {tensor.shape}"
+ )
+ assert tensor.is_cuda, "Tensor should be on CUDA device"
- # Verify normalization (amplitude encoding normalizes)
+ if check_normalization:
norms = tensor.abs().pow(2).sum(dim=1).sqrt()
assert torch.allclose(norms, torch.ones_like(norms), atol=1e-5), (
"States should be normalized"
)
- print("✓ test_encode_from_numpy_basic passed")
- finally:
- if os.path.exists(npy_path):
- os.remove(npy_path)
-
-
-def test_encode_from_numpy_large():
- """Test NumPy encoding with larger dataset"""
+def test_encode_from_numpy_file():
+ """Test NumPy file encoding"""
engine = QdpEngine(device_id=0)
- num_samples = 100
- num_qubits = 6
- sample_size = 2**num_qubits # 64
-
- # Generate test data
- data = np.random.randn(num_samples, sample_size).astype(np.float64)
- norms = np.linalg.norm(data, axis=1, keepdims=True)
- data = data / norms
+ test_cases = [
+ (10, 3, True), # Basic: 10 samples, 3 qubits, check normalization
+ (100, 6, False), # Large: 100 samples, 6 qubits
+ (1, 4, False), # Single sample: 1 sample, 4 qubits
+ ]
- # Save to temporary .npy file
- with tempfile.NamedTemporaryFile(suffix=".npy", delete=False) as f:
- npy_path = f.name
+ for num_samples, num_qubits, check_norm in test_cases:
Review Comment:
Consider using @pytest.mark.parametrize decorator instead of a manual for
loop over test_cases. This follows the pattern used in test_high_fidelity.py
and provides better test reporting, allowing individual test case failures to
be identified separately.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]