-
Notifications
You must be signed in to change notification settings - Fork 0
Embeddings npyfile read
Development build. This page describes
main, not a released package. The latest published Lodestar.Embeddings is 0.4.0 — read its documentation.
Reads a .npy file into a block and the shape it was stored under.
public static NpyBlock Read(Stream source, ArtifactLoadOptions options = null)
public static NpyBlock Read(ReadOnlyMemory<byte> npy, ArtifactLoadOptions options = null)
public static NpyBlock Read(string path, ArtifactLoadOptions options = null)Parameters — source is the file's bytes, never disposed here; npy is the whole file
already in memory, which must outlive the block and must not change while it is read; path is
the file, whose stream this method owns. options bounds what will be accepted and defaults to
ArtifactLoadOptions's own defaults.
Returns — NpyBlock: the elements in C order, and the shape. Read from a
stream or a path, the block also carries the array it filled; read from memory it carries none,
because it borrowed instead of allocating.
Exceptions — ArgumentNullException for a null source or path. InvalidDataException when
the file does not open with numpy's magic, declares a version this does not read, declares a
header longer than this reader accepts (65 536 bytes), holds a dtype or layout this does not read,
is truncated against its own shape, declares more elements than one block can hold, or exceeds a
bound in options.
Example — reading what numpy wrote.
using Lodestar.Embeddings.Persistence;
using Lodestar.Embeddings.Search;
NpyBlock block = NpyFile.Read("vectors.npy");
var index = new EmbeddingIndex(block.Shape[1], normalize: true);Example — the same file already in memory, read without copying it.
using Lodestar.Embeddings.Persistence;
using var written = new MemoryStream();
NpyFile.Write(written, [1f, 0f, 0f, 1f], 2, 2);
NpyBlock borrowedBlock = NpyFile.Read(written.GetBuffer().AsMemory(0, (int)written.Length));
int rank = borrowedBlock.Shape.Count; // => 2
bool borrowed = borrowedBlock.OwnedArray is null; // => TrueRemarks — the three overloads differ in what they cost and in what they ask of you.
Read(Stream) and Read(string) read the payload straight into the array the block carries —
one copy on net10.0, and two on netstandard2.0, where Stream.Read(Span<byte>) does not exist and
the payload stages through a chunk on its way in. Nothing is asked of the caller in return, and
OwnedArray names that array so
EmbeddingIndex.FromOwnedBlock can adopt it rather
than copy it a second time.
Read(ReadOnlyMemory<byte>) copies nothing on either target, and that is the overload with a
contract: the block's values alias the bytes you passed, so those bytes must outlive the block
and must not change while it is read — what
EmbeddingIndex.Load already asks of a caller who hands it an
artifact it holds. OwnedArray is null on a block read this way, because a borrowed block has no
array to hand over, which is what keeps adoption out of reach from here.
Decision 0057
has why there are two contracts rather than one.
The header is never evaluated. numpy's header is a Python dict literal, and this accepts a fixed grammar out of it rather than parsing Python: three known keys, each with one of a closed set of values.
descr: '|O' is refused by name and first. That is numpy's object dtype and its payload is a
pickle — arbitrary code, the thing
decision 0011 rules out for artifacts. The refusal
happens on the header, before the payload is touched.
Refused with what they held, rather than read approximately: >f4 (big-endian), <f8 (float64),
fortran_order: True (column-major), a scalar shape (), and anything past two dimensions.
(0, 4) is legal and reads as empty.
Non-finite values are carried, not refused. EmbeddingIndex.Save
refuses a NaN because a non-finite component poisons every later score of an index this library
owns. A .npy is somebody else's data; changing it on the way in would be the worse failure.
Applies to — net10.0, netstandard2.0.
See also — NpyFile, NpyFile.Write,
NpyBlock, the persistence index.
- 0001-target-framework
- 0002-unicode-comparison-unit
- 0003-provenance-and-licensing
- 0004-levenshtein-myers-backlog
- 0005-hamming-jellyfish-divergence
- 0006-ratcliff-autojunk
- 0007-metaphone-scope
- 0008-italian-enza-nltk-divergence
- 0009-sample-consumes-a-local-feed
- 0010-stop-word-list-provenance
- 0011-persistence-format
- 0012-per-package-versioning
- 0013-sentencepiece-parity-scope
- 0014-precompiled-normalizer
- 0015-sonar-rules-in-the-build
- 0016-metrics-package-placement
- 0017-bpe-parity-scope
- 0018-multiclass-roc-auc-parallelism-is-opt-in
- 0019-the-net-analysers-run-in-the-build-too
- 0020-normalize-is-a-projection-not-a-parameter
- 0021-multioutput-is-a-method-not-an-enum
- 0022-added-token-matching-flags
- 0023-byte-level-decode-substitutes
- 0024-weighted-median-averages-within-scikit-learns-epsilon
- 0025-quickselect-replaces-a-full-sort-for-the-median
- 0026-r2-and-explainedvariance-split-their-undefined-cases-differently
- 0027-r2-and-explainedvariance-vectorize-only-a-single-output
- 0028-log1p-is-kahans-identity-not-math-log-1-plus-x
- 0029-balanced-accuracy-adjusted-is-left-to-ieee-754-at-the-edge
- 0030-cohen-kappa-keeps-scikit-learns-expected-matrix-orientation
- 0031-nosamplecorrect-mirrors-numpys-float64-upcast
- 0032-fbeta-substitutes-tp-predicted-and-support-algebraically
- 0033-compensated-sum-is-neumaiers-variant
- 0034-dropout-is-refused-for-want-of-a-user
- 0035-a-null-pre-split-is-removed-with-invert-not-isolated
- 0036-a-member-may-ship-without-an-oracle-if-it-says-so
- 0037-the-guards-run-before-the-commit
- 0038-the-gate-confronts-an-exception-tag-with-the-page-that-documents-it
- 0039-mutual-information-returns-zero-on-an-empty-input
- 0040-a-curve-is-a-sealed-class-per-curve
- 0041-one-sample-file-per-public-class
- 0042-phonetic-encoders-refuse-a-null-word
- 0043-the-equality-table-is-sized-to-the-pattern
- 0044-compression-belongs-to-the-caller
- 0045-a-console-call-carries-its-reason-on-the-line
- 0046-check-adr-immutable-runs-in-ci-only
- 0047-one-gate-per-kernel-not-one-per-alphabet
- 0048-the-gate-depends-on-the-kernel-and-the-alphabet
- 0049-two-gates-per-kernel-tested-where-the-width-is-known
- 0050-the-sentencepiece-bpe-lineage-stays-a-bpe-model
- 0051-the-save-paths-cost-is-the-buffer-not-the-encoding
- 0052-pre-sizing-the-artifact-file-buys-nothing-on-a-delayed-allocation-filesystem
- 0053-the-payload-buffer-is-not-pooled-because-residency-outlives-the-load
- 0054-the-payload-buffer-is-pooled-after-all-because-the-collection-is-the-cost
- 0055-the-artifact-gets-a-binary-sidecar-once-a-block-can-be-ingested-whole
- 0056-a-block-may-be-adopted-and-the-invariant-is-the-callers-to-keep
- 0057-the-npy-read-serves-a-stream-and-a-buffer-differently
- benchmark_latest
- decisions
- equivalence
- matplotlib
- migration
- nightly_run
- numpy
- pandas
- performance
- pytorch
- seaborn
- sklearn
- statsmodels