def test_init_tensor_from_backend_array(backend, dtype): """ Creates an instance of the backend's array class, initializes a Tensor from it, and checks that all its members have been correctly initialized. """ shape = (2, 3, 1) if backend == "pytorch": if dtype not in testing_utils.torch_supported_dtypes: with pytest.raises(TypeError): dtype = testing_utils.np_dtype_to_backend(backend, dtype) return dtype = testing_utils.np_dtype_to_backend(backend, dtype) init = torch.zeros(shape, dtype=dtype) elif backend == "numpy": dtype = testing_utils.np_dtype_to_backend(backend, dtype) init = np.zeros(shape, dtype=dtype) elif backend == "jax": dtype = testing_utils.np_dtype_to_backend(backend, dtype) init = jnp.zeros(shape, dtype=dtype) elif backend == "tensorflow": dtype = testing_utils.np_dtype_to_backend(backend, dtype) init = tf.zeros(shape, dtype=dtype) else: raise ValueError("Unexpected backend ", backend) A = tensornetwork.Tensor(init, backend=backend) assert A.backend.name == backend np.testing.assert_allclose(A.array, init) assert A.shape == init.shape assert A.size == np.prod(init.shape) assert A.ndim == init.ndim
def test_outer_invalid_backends(dtype, backend): backend_names = set(["jax", "numpy", "tensorflow", "pytorch"]) this_name = set([backend]) other_backend_names = list(backend_names - this_name) shape = (4, 3) dtype1 = testing_utils.np_dtype_to_backend(backend, dtype) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype1) for other_backend in other_backend_names: dtype2 = testing_utils.np_dtype_to_backend(other_backend, dtype) tensor2 = tensornetwork.ones(shape, backend=other_backend, dtype=dtype2) with pytest.raises(ValueError): _ = tensornetwork.outer(tensor1, tensor2)
def test_inv_vs_backend(backend, dtype): shape = 6 dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.eye(shape, backend=backend, dtype=dtype) tn_result = linalg.inv(tensor) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.inv(tensor.array) np.testing.assert_allclose(tn_result.array, backend_result)
def test_norm_vs_backend(backend, dtype): shape = (6, 2, 6) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype) tn_result = linalg.norm(tensor) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.norm(tensor.array) assert backend_result == tn_result
def test_sqrt_vs_backend(backend, dtype): shape = (4, 5, 6) dtype_b = testing_utils.np_dtype_to_backend(backend, dtype) backend_obj = backends.backend_factory.get_backend(backend) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype_b) if (backend == "pytorch" and dtype == np.float16): pytest.skip("Prod not supported with this dtype and backend.") else: backend_result = backend_obj.sqrt(tensor.array) tn_result = tensornetwork.sqrt(tensor).array np.testing.assert_allclose(backend_result, tn_result)
def test_reshape_vs_backend(backend, dtype): """ Tests that reshape yields the same result as the backend equivalent. """ shape = (3, 2, 4) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype) result = tensornetwork.reshape(tensor, (6, 4)) backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.reshape(tensor.array, (6, 4)) assert result.shape == backend_result.shape
def test_inv_vs_backend(backend, dtype): np.random.seed(10) shape = (4, 4) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = initialize_hermitian_matrix(backend, shape, dtype) tn_result = linalg.inv(tensor) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.inv(tensor.array) testing_utils.assert_allclose(tn_result.array, backend_result, backend_obj)
def test_rq_default(backend, dtype): shape = (3, 6, 4, 2) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype) split_axis = 1 tn_result = linalg.rq(tensor, split_axis) result2 = linalg.rq(tensor, split_axis, non_negative_diagonal=False) tn_arrays = [t.array for t in tn_result] arrays2 = [t.array for t in result2] for tn_arr, arr2 in zip(tn_arrays, arrays2): np.testing.assert_allclose(tn_arr, arr2)
def test_norm_vs_backend(backend, dtype): np.random.seed(10) shape = (6, 8, 6) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = initialize_tensor('randn', backend, shape, dtype) tn_result = linalg.norm(tensor) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.norm(tensor.array) assert backend_result == tn_result
def test_outer_vs_backend(dtype, backend): shape = (4, 3) dtype = testing_utils.np_dtype_to_backend(backend, dtype) testing_utils.check_contraction_dtype(backend, dtype) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensor2 = tensornetwork.ones(shape, backend=backend, dtype=dtype) result = tensornetwork.outer(tensor1, tensor2) backend_obj = backends.backend_factory.get_backend(backend) arrays = [t.array for t in [tensor1, tensor2]] backend_result = backend_obj.outer_product(*arrays) np.testing.assert_allclose(backend_result, result.array)
def test_tensordot_invalid_backend_raises_value_error(backend, dtype): """ Tests that tensordot raises ValueError when fed Tensors with different backends. Other failure modes are tested at the backend level. """ backend_names = set(["jax", "numpy", "tensorflow", "pytorch"]) this_name = set([backend]) other_backend_names = list(backend_names - this_name) shape = (4, 4, 4) dtype1 = testing_utils.np_dtype_to_backend(backend, dtype) testing_utils.check_contraction_dtype(backend, dtype1) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype1) for other_backend in other_backend_names: dtype2 = testing_utils.np_dtype_to_backend(other_backend, dtype) testing_utils.check_contraction_dtype(other_backend, dtype2) tensor2 = tensornetwork.ones(shape, backend=other_backend, dtype=dtype2) with pytest.raises(ValueError): _ = tensornetwork.tensordot(tensor1, tensor2, [[2, 0, 1], [1, 2, 0]])
def test_eigh_vs_backend(backend, dtype): shape = (3, 6, 4, 4) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype) tn_result = linalg.eigh(tensor) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.eigh(tensor.array) tn_arrays = [t.array for t in tn_result] for tn_arr, backend_arr in zip(tn_arrays, backend_result): np.testing.assert_allclose(tn_arr, backend_arr)
def test_rq_default(backend, dtype): np.random.seed(10) shape = (3, 6, 4, 2) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = initialize_tensor('randn', backend, shape, dtype) split_axis = 1 tn_result = linalg.rq(tensor, split_axis) result2 = linalg.rq(tensor, split_axis, non_negative_diagonal=False) tn_arrays = [t.array for t in tn_result] arrays2 = [t.array for t in result2] backend_obj = backends.backend_factory.get_backend(backend) for tn_arr, arr2 in zip(tn_arrays, arrays2): testing_utils.assert_allclose(tn_arr, arr2, backend_obj)
def test_rq_vs_backend(backend, dtype): shape = (3, 6, 4, 2) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype) split_axis = 1 tn_result = linalg.rq(tensor, split_axis, non_negative_diagonal=False) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.rq(tensor.array, split_axis) tn_arrays = [t.array for t in tn_result] for tn_arr, backend_arr in zip(tn_arrays, backend_result): np.testing.assert_allclose(tn_arr, backend_arr)
def test_eigh_vs_backend(backend, dtype): np.random.seed(10) shape = (4, 4) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = initialize_hermitian_matrix(backend, shape, dtype) tn_result = linalg.eigh(tensor) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.eigh(tensor.array) tn_arrays = [t.array for t in tn_result] for tn_arr, backend_arr in zip(tn_arrays, backend_result): testing_utils.assert_allclose(tn_arr, backend_arr, backend_obj)
def test_ncon_vs_backend(dtype, backend): shape = (4, 3) dtype = testing_utils.np_dtype_to_backend(backend, dtype) testing_utils.check_contraction_dtype(backend, dtype) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensor2 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensor3 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensors = [tensor1, tensor2, tensor3] arrays = [tensor1.array, tensor2.array, tensor3.array] idxs = [[1, -1], [1, 2], [-2, 2]] result = ncon(tensors, idxs, backend=backend) old_result = tensornetwork.ncon(arrays, idxs, backend=backend) np.testing.assert_allclose(old_result, result.array)
def test_ncon_invalid_backends(dtype, backend): backend_names = set(["jax", "numpy", "tensorflow", "pytorch"]) this_name = set([backend]) other_backend_names = list(backend_names - this_name) shape = (4, 3) dtype1 = testing_utils.np_dtype_to_backend(backend, dtype) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype1) for other_backend in other_backend_names: dtype2 = testing_utils.np_dtype_to_backend(other_backend, dtype) tensor2 = tensornetwork.ones(shape, backend=other_backend, dtype=dtype2) for other_other_backend in backend_names: dtype3 = testing_utils.np_dtype_to_backend(other_other_backend, dtype) tensor3 = tensornetwork.zeros(shape, backend=other_other_backend, dtype=dtype3) tensors = [tensor1, tensor2, tensor3] idxs = [[1, -1], [1, 2], [-2, 2]] with pytest.raises(ValueError): _ = ncon(tensors, idxs)
def test_take_slice_vs_backend(backend, dtype): """ Tests that take_slice yields the same result as the backend equivalent. """ shape = (5, 6, 7) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype) start_indices = (1, 2, 3) slice_sizes = (2, 3, 3) result = tensornetwork.take_slice(tensor, start_indices, slice_sizes) backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.slice(tensor.array, start_indices, slice_sizes) assert result.shape == backend_result.shape
def test_rq_vs_backend(backend, dtype): np.random.seed(10) shape = (3, 6, 4, 2) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = initialize_tensor('randn', backend, shape, dtype) split_axis = 1 tn_result = linalg.rq(tensor, split_axis, non_negative_diagonal=False) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.rq(tensor.array, split_axis) tn_arrays = [t.array for t in tn_result] for tn_arr, backend_arr in zip(tn_arrays, backend_result): testing_utils.assert_allclose(tn_arr, backend_arr, backend_obj)
def test_einsum_invalid_backends(dtype, backend): backend_names = set(["jax", "numpy", "tensorflow", "pytorch"]) this_name = set([backend]) other_backend_names = list(backend_names - this_name) shape = (4, 3) dtype1 = testing_utils.np_dtype_to_backend(backend, dtype) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype1) for other_backend in other_backend_names: dtype2 = testing_utils.np_dtype_to_backend(other_backend, dtype) tensor2 = tensornetwork.ones(shape, backend=other_backend, dtype=dtype2) for other_other_backend in backend_names: dtype3 = testing_utils.np_dtype_to_backend(other_other_backend, dtype) tensor3 = tensornetwork.zeros(shape, backend=other_other_backend, dtype=dtype3) with pytest.raises(ValueError): _ = tensornetwork.einsum("ba, bc, dc", tensor1, tensor2, tensor3, optimize=True)
def test_unary_ops_vs_backend(backend, dtype, fname): shape = (4, 5, 6) dtype_b = testing_utils.np_dtype_to_backend(backend, dtype) backend_obj = backends.backend_factory.get_backend(backend) backend_func = getattr(backend_obj, fname) tn_func = getattr(tensornetwork.linalg.operations, fname) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype_b) if backend == "pytorch" and fname in ["sin", "log", "exp", "cos"]: with pytest.raises(NotImplementedError): backend_result = backend_func(tensor.array) with pytest.raises(NotImplementedError): tn_result = tn_func(tensor).array else: backend_result = backend_func(tensor.array) tn_result = tn_func(tensor).array np.testing.assert_allclose(backend_result, tn_result)
def test_tensordot_int_vs_backend(backend, dtype): """ Tests that tensordot yields the same result as the backend equivalent. """ shape = (4, 4, 4) dtype = testing_utils.np_dtype_to_backend(backend, dtype) testing_utils.check_contraction_dtype(backend, dtype) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensor2 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensors = [tensor1, tensor2] dim = 1 result = tensornetwork.tensordot(*tensors, dim) backend_obj = backends.backend_factory.get_backend(backend) arrays = [t.array for t in tensors] backend_result = backend_obj.tensordot(*arrays, axes=dim) np.testing.assert_allclose(backend_result, result.array)
def test_einsum_vs_backend(dtype, backend): shape = (4, 3) dtype = testing_utils.np_dtype_to_backend(backend, dtype) testing_utils.check_contraction_dtype(backend, dtype) tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensor2 = tensornetwork.ones(shape, backend=backend, dtype=dtype) tensor3 = tensornetwork.ones(shape, backend=backend, dtype=dtype) result = tensornetwork.einsum("ba, bc, dc", tensor1, tensor2, tensor3, optimize=True) backend_obj = backends.backend_factory.get_backend(backend) arrays = [t.array for t in [tensor1, tensor2, tensor3]] backend_result = backend_obj.einsum("ba, bc, dc", *arrays, optimize=True) np.testing.assert_allclose(backend_result, result.array)
def test_expm_vs_backend(backend, dtype): shape = 6 dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.eye(shape, backend=backend, dtype=dtype) if backend in ["pytorch"]: with pytest.raises(NotImplementedError): tn_result = linalg.expm(tensor) else: tn_result = linalg.expm(tensor) backend_obj = backends.backend_factory.get_backend(backend) if backend in ["pytorch"]: with pytest.raises(NotImplementedError): backend_result = backend_obj.expm(tensor.array) else: backend_result = backend_obj.expm(tensor.array) np.testing.assert_allclose(tn_result.array, backend_result)
def test_matvec_cache(sparse_backend, dtype): shape = (4, 4) dtype = testing_utils.np_dtype_to_backend(sparse_backend, dtype) A = tensornetwork.linalg.initialization.ones(shape, backend=sparse_backend, dtype=dtype) B = -1.3 * tensornetwork.linalg.initialization.ones( shape, backend=sparse_backend, dtype=dtype) def matvec(B, A): return A @ B def matvec_array(B, A): return A.array @ B.array matvec_cache = tensornetwork.linalg.krylov.MatvecCache() mv = matvec_cache.retrieve(sparse_backend, matvec) result = mv(B.array, A.array) test = matvec_array(B, A) assert np.all(np.isfinite(np.ravel(result))) np.testing.assert_allclose(result, test)
def test_eigsh_lanczos_with_args(sparse_backend, dtype): """ Compares linalg.krylov.eigsh_lanczos with backend.eigsh_lanczos. """ n = 2 shape = (n, n) dtype = testing_utils.np_dtype_to_backend(sparse_backend, dtype) A = tensornetwork.linalg.initialization.ones(shape, backend=sparse_backend, dtype=dtype) x0 = tensornetwork.linalg.initialization.ones((n, 1), backend=sparse_backend, dtype=dtype) def matvec(B): return A @ B def matvec_args(B, A): return A @ B result = tensornetwork.linalg.krylov.eigsh_lanczos(matvec, backend=A.backend, x0=x0, num_krylov_vecs=n - 1) test = tensornetwork.linalg.krylov.eigsh_lanczos(matvec_args, backend=A.backend, x0=x0, num_krylov_vecs=n - 1, args=[ A, ]) rev, reV = result tev, teV = test assert np.all(np.isfinite(np.ravel(np.array(rev)))) np.testing.assert_allclose(np.array(rev), np.array(tev)) for r, t in zip(reV, teV): assert np.all(np.isfinite(np.ravel(r.array))) np.testing.assert_allclose(r.array, t.array)
def test_svd_vs_backend(backend, dtype): np.random.seed(10) shape = (3, 6, 4, 6) dtype = testing_utils.np_dtype_to_backend(backend, dtype) tensor = initialize_tensor('randn', backend, shape, dtype) split_axis = 1 max_singular_values = 5 max_trunc_error = 0.1 relative = True tn_result = linalg.svd(tensor, split_axis, max_singular_values=max_singular_values, max_truncation_error=max_trunc_error, relative=relative) if backend is None: backend = backend_contextmanager.get_default_backend() backend_obj = backends.backend_factory.get_backend(backend) backend_result = backend_obj.svd(tensor.array, split_axis, max_singular_values=max_singular_values, max_truncation_error=max_trunc_error, relative=relative) tn_arrays = [t.array for t in tn_result] for tn_arr, backend_arr in zip(tn_arrays, backend_result): testing_utils.assert_allclose(tn_arr, backend_arr, backend_obj)
def test_shape(backend, dtype): shape = (4, 5, 6) dtype_b = testing_utils.np_dtype_to_backend(backend, dtype) tensor = tensornetwork.ones(shape, backend=backend, dtype=dtype_b) tn_result = tensornetwork.shape(tensor) assert tensor.shape == tn_result