From 72da5a8703efb0182d94f0f9849e78e713f33572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20de=20Kok?= Date: Mon, 9 Sep 2019 10:35:02 +0200 Subject: [PATCH] Add tests for reading/mmaping quantized embeddings Fixes #56. --- tests/conftest.py | 10 ++++++++++ tests/similarity-pq.fifu | Bin 0 -> 15610 bytes tests/test_embeddings.py | 14 ++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 tests/similarity-pq.fifu diff --git a/tests/conftest.py b/tests/conftest.py index 0e46ed4..385a4d7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,6 +25,16 @@ def similarity_fifu(tests_root): yield finalfusion.Embeddings(os.path.join(tests_root, "similarity.fifu")) +@pytest.fixture +def similarity_pq(tests_root): + yield finalfusion.Embeddings(os.path.join(tests_root, "similarity-pq.fifu")) + + +@pytest.fixture +def similarity_pq_mmap(tests_root): + yield finalfusion.Embeddings(os.path.join(tests_root, "similarity-pq.fifu"), mmap=True) + + @pytest.fixture def subword_fifu(tests_root): yield finalfusion.Embeddings(os.path.join(tests_root, "subword.fifu")) diff --git a/tests/similarity-pq.fifu b/tests/similarity-pq.fifu new file mode 100644 index 0000000000000000000000000000000000000000..5104426ba57b3ea7a722b534006472b70f08c482 GIT binary patch literal 15610 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