diff --git a/Earthfile b/Earthfile index 5233567a..d5559ef4 100644 --- a/Earthfile +++ b/Earthfile @@ -56,7 +56,7 @@ build: # This target formats the project. fmt: FROM +chef-cook - RUN cargo fmt --all --all-features -- --check && rye fmt --all --check + RUN cargo fmt --all -- --check && rye fmt --all --check # This target lints the project. lint: @@ -77,7 +77,7 @@ fix: # This target runs the tests. test: FROM +chef-cook - RUN cargo test --release --lib --bins --examples --tests --all-features + RUN cargo test -r # TODO: switch to --all, blocked on https://github.com/astral-sh/rye/issues/853 RUN rye test --package abd-distances diff --git a/crates/abd-clam/Cargo.toml b/crates/abd-clam/Cargo.toml index 3fb90200..a44988bd 100644 --- a/crates/abd-clam/Cargo.toml +++ b/crates/abd-clam/Cargo.toml @@ -10,7 +10,7 @@ authors = [ "Oliver McLaughlin ", ] edition = "2021" -rust-version = "1.79" +rust-version = "1.83" description = "Clustering, Learning and Approximation with Manifolds" license = "MIT" readme = "./README.md" @@ -43,8 +43,7 @@ ndarray-npy = { workspace = true, optional = true } # For: # - CHAODA -smartcore = { git = "https://github.com/smartcorelib/smartcore.git", rev = "239c00428f7448d30b78bf8653923f6bc0e2c29b", features = ["serde"], optional = true } -ordered-float = { version = "4.2.2", optional = true } +smartcore = { version = "0.4", features = ["serde"], optional = true } # For: # - MSA @@ -58,20 +57,18 @@ flate2 = { workspace = true, optional = true } [dev-dependencies] symagen = { workspace = true } bitcode = { workspace = true } -criterion = { version = "0.5.1", features = ["html_reports"] } +criterion = { version = "0.5", features = ["html_reports"] } tempdir = "0.3.7" float-cmp = "0.10.0" test-case = "3.2.1" statistical = "1.0.0" [features] -csv = ["dep:csv"] -bitcode = ["dep:bitcode", "dep:flate2"] -ndarray-bindings = ["dep:ndarray", "dep:ndarray-npy"] -chaoda = ["dep:smartcore", "dep:ordered-float", "bitcode"] +disk-io = ["dep:csv", "dep:bitcode", "dep:flate2", "dep:ndarray", "dep:ndarray-npy"] +chaoda = ["dep:smartcore"] mbed = ["chaoda"] msa = ["dep:stringzilla"] -all = ["csv", "bitcode", "ndarray-bindings", "chaoda", "mbed", "msa"] +all = ["disk-io", "chaoda", "mbed", "msa"] [[bench]] name = "vector_search" diff --git a/crates/abd-clam/src/cakes/cluster/permuted_ball.rs b/crates/abd-clam/src/cakes/cluster/permuted_ball.rs index cb7afa4d..aead65d8 100644 --- a/crates/abd-clam/src/cakes/cluster/permuted_ball.rs +++ b/crates/abd-clam/src/cakes/cluster/permuted_ball.rs @@ -21,8 +21,8 @@ use crate::{ /// - `T`: The type of the distance values. /// - `S`: The `Cluster` type that the `PermutedBall` is based on. #[derive(Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] -#[cfg_attr(feature = "bitcode", bitcode(recursive))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", bitcode(recursive))] pub struct PermutedBall> { /// The `Cluster` type that the `PermutedBall` is based on. source: S, @@ -155,7 +155,7 @@ impl> ParCluster for PermutedBall { /// Parameters for adapting the `PermutedBall`. #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] pub struct Offset { /// The offset of the slice of indices of the `Cluster` in the reordered /// dataset. @@ -271,7 +271,7 @@ impl + Permutable, S: ParCluster> } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl> crate::cluster::Csv for PermutedBall { fn header(&self) -> Vec { let mut header = self.source.header(); @@ -290,13 +290,13 @@ impl> crate::cluster::Csv for PermutedBa } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl> crate::cluster::ParCsv for PermutedBall {} -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl> crate::cluster::ClusterIO for PermutedBall {} -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl> crate::cluster::ParClusterIO for PermutedBall {} #[cfg(test)] diff --git a/crates/abd-clam/src/chaoda/graph/mod.rs b/crates/abd-clam/src/chaoda/graph/mod.rs index 03b27177..9f0cb1be 100644 --- a/crates/abd-clam/src/chaoda/graph/mod.rs +++ b/crates/abd-clam/src/chaoda/graph/mod.rs @@ -3,13 +3,12 @@ use core::cmp::Reverse; -use std::collections::{BinaryHeap, HashMap}; +use std::collections::HashMap; use distances::Number; -use ordered_float::OrderedFloat; use rayon::prelude::*; -use crate::{cluster::ParCluster, dataset::ParDataset, metric::ParMetric, Cluster, Dataset, Metric}; +use crate::{cluster::ParCluster, dataset::ParDataset, metric::ParMetric, Cluster, Dataset, Metric, SizedHeap}; use super::Vertex; @@ -90,10 +89,10 @@ impl<'a, T: Number, S: Cluster> Graph<'a, T, S> { // `Vertex`es are selected by highest score and then by shallowest depth. let mut candidates = clusters .into_iter() - .zip(scores.into_iter().map(OrderedFloat)) + .zip(scores) .filter(|(c, _)| c.is_leaf() || c.depth() >= min_depth) .map(|(c, s)| (s, Reverse(c))) - .collect::>(); + .collect::>(); let mut clusters = vec![]; while let Some((_, Reverse(v))) = candidates.pop() { @@ -239,10 +238,10 @@ impl<'a, T: Number, S: ParCluster> Graph<'a, T, S> { // `Vertex`es are selected by highest score and then by shallowest depth. let mut candidates = clusters .into_iter() - .zip(scores.into_iter().map(OrderedFloat)) + .zip(scores) .filter(|(c, _)| c.is_leaf() || c.depth() >= min_depth) .map(|(c, s)| (s, Reverse(c))) - .collect::>(); + .collect::>(); let mut clusters = vec![]; while let Some((_, Reverse(v))) = candidates.pop() { diff --git a/crates/abd-clam/src/core/cluster/ball.rs b/crates/abd-clam/src/core/cluster/ball.rs index c0e5d86c..3c26926a 100644 --- a/crates/abd-clam/src/core/cluster/ball.rs +++ b/crates/abd-clam/src/core/cluster/ball.rs @@ -19,8 +19,8 @@ use super::{partition::ParPartition, Cluster, ParCluster, Partition, LFD}; /// A metric-`Ball` is a collection of items that are within a certain distance /// of a center. #[derive(Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] -#[cfg_attr(feature = "bitcode", bitcode(recursive))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", bitcode(recursive))] pub struct Ball { /// Parameters used for creating the `Ball`. depth: usize, @@ -268,7 +268,7 @@ impl ParPartition for Ball { } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl super::Csv for Ball { fn header(&self) -> Vec { vec![ @@ -295,13 +295,13 @@ impl super::Csv for Ball { } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl super::ParCsv for Ball {} -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl super::ClusterIO for Ball {} -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl super::ParClusterIO for Ball {} #[cfg(test)] diff --git a/crates/abd-clam/src/core/cluster/io.rs b/crates/abd-clam/src/core/cluster/io.rs index 18afed63..6dc8a9dd 100644 --- a/crates/abd-clam/src/core/cluster/io.rs +++ b/crates/abd-clam/src/core/cluster/io.rs @@ -7,7 +7,7 @@ use rayon::prelude::*; use super::{Cluster, ParCluster}; -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] /// Write a tree to a CSV file. pub trait Csv: Cluster { /// Returns the names of the columns in the CSV file. @@ -45,7 +45,7 @@ pub trait Csv: Cluster { } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] /// Parallel version of `Csv`. pub trait ParCsv: Csv + ParCluster { /// Parallel version of `Csv::write_to_csv`. @@ -84,7 +84,7 @@ pub trait ParCsv: Csv + ParCluster { } } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] /// Reading and writing `Cluster` trees to disk using `bitcode`. pub trait ClusterIO: Cluster { /// Writes the `Cluster` to disk in binary format using `bitcode`. @@ -116,7 +116,7 @@ pub trait ClusterIO: Cluster { } } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] /// Parallel version of `ClusterIO`. pub trait ParClusterIO: ParCluster + ClusterIO { /// Parallel version of `ClusterIO::write_to`. diff --git a/crates/abd-clam/src/core/cluster/mod.rs b/crates/abd-clam/src/core/cluster/mod.rs index 1e2bdb1b..1193f373 100644 --- a/crates/abd-clam/src/core/cluster/mod.rs +++ b/crates/abd-clam/src/core/cluster/mod.rs @@ -11,7 +11,6 @@ use super::{ pub mod adapter; mod balanced_ball; mod ball; -mod io; mod lfd; mod partition; @@ -20,12 +19,12 @@ pub use ball::Ball; pub use lfd::LFD; pub use partition::{ParPartition, Partition}; -#[cfg(feature = "csv")] -pub use io::{Csv, ParCsv}; +#[cfg(feature = "disk-io")] +mod io; -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] #[allow(clippy::module_name_repetitions)] -pub use io::{ClusterIO, ParClusterIO}; +pub use io::{ClusterIO, Csv, ParClusterIO, ParCsv}; /// A `Cluster` is a collection of "similar" items in a dataset. /// diff --git a/crates/abd-clam/src/core/dataset/flat_vec.rs b/crates/abd-clam/src/core/dataset/flat_vec.rs index 1ebca1e4..91c38da8 100644 --- a/crates/abd-clam/src/core/dataset/flat_vec.rs +++ b/crates/abd-clam/src/core/dataset/flat_vec.rs @@ -11,8 +11,8 @@ use super::{AssociatesMetadata, AssociatesMetadataMut, Dataset, ParDataset, Perm /// - `I`: The type of the items in the dataset. /// - `Me`: The type of the metadata associated with the items. #[derive(Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] -#[cfg_attr(feature = "bitcode", bitcode(recursive))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", bitcode(recursive))] pub struct FlatVec { /// The items in the dataset. items: Vec, @@ -223,13 +223,13 @@ impl Permutable for FlatVec { } } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl super::DatasetIO for FlatVec {} -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl super::ParDatasetIO for FlatVec {} -#[cfg(feature = "ndarray-bindings")] +#[cfg(feature = "disk-io")] impl FlatVec, usize> { /// Reads a `FlatVec` from a `.npy` file. /// @@ -250,7 +250,7 @@ impl FlatVec, usize> { } } -#[cfg(feature = "ndarray-bindings")] +#[cfg(feature = "disk-io")] impl FlatVec, usize> { /// Writes the `FlatVec` to a `.npy` file in the given directory. /// @@ -282,7 +282,7 @@ impl FlatVec, usize> { } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl FlatVec, usize> { /// Reads a `FlatVec` from a `.csv` file. /// @@ -321,7 +321,7 @@ impl FlatVec, usize> { } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl FlatVec, M> { /// Writes the `FlatVec` to a `.csv` file with the given path. /// @@ -376,7 +376,7 @@ mod tests { Ok(()) } - #[cfg(feature = "ndarray-bindings")] + #[cfg(feature = "disk-io")] #[test] fn npy_io() -> Result<(), String> { let items = vec![vec![1, 2], vec![3, 4], vec![5, 6]]; diff --git a/crates/abd-clam/src/core/dataset/io.rs b/crates/abd-clam/src/core/dataset/io.rs index 7d5f6659..913241d9 100644 --- a/crates/abd-clam/src/core/dataset/io.rs +++ b/crates/abd-clam/src/core/dataset/io.rs @@ -2,7 +2,7 @@ use super::{Dataset, ParDataset}; -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] /// For writing and reading datasets to and from disk. pub trait DatasetIO: Dataset { /// Writes the `Dataset` to disk in binary format using `bitcode`. @@ -34,7 +34,7 @@ pub trait DatasetIO: Dataset { } } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] /// Parallel version of `DatasetIO`. pub trait ParDatasetIO: DatasetIO + ParDataset { /// Parallel version of `DatasetIO::write_to`. @@ -45,7 +45,6 @@ pub trait ParDatasetIO: DatasetIO + ParDataset { /// /// - If the dataset cannot be encoded. /// - If the file cannot be written. - #[cfg(feature = "bitcode")] fn par_write_to>(&self, path: &P) -> Result<(), String> where Self: bitcode::Encode, @@ -61,7 +60,6 @@ pub trait ParDatasetIO: DatasetIO + ParDataset { /// /// - If the file cannot be read. /// - If the dataset cannot be decoded. - #[cfg(feature = "bitcode")] fn par_read_from>(path: &P) -> Result where Self: bitcode::Decode, diff --git a/crates/abd-clam/src/core/dataset/mod.rs b/crates/abd-clam/src/core/dataset/mod.rs index f86acd25..368e99af 100644 --- a/crates/abd-clam/src/core/dataset/mod.rs +++ b/crates/abd-clam/src/core/dataset/mod.rs @@ -8,7 +8,6 @@ use super::{metric::ParMetric, Metric}; mod associates_metadata; mod flat_vec; -mod io; mod permutable; mod sized_heap; @@ -17,7 +16,10 @@ pub use flat_vec::FlatVec; pub use permutable::Permutable; pub use sized_heap::SizedHeap; -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] +mod io; + +#[cfg(feature = "disk-io")] #[allow(clippy::module_name_repetitions)] pub use io::{DatasetIO, ParDatasetIO}; diff --git a/crates/abd-clam/src/core/dataset/sized_heap.rs b/crates/abd-clam/src/core/dataset/sized_heap.rs index 7a40c496..8b27e7ea 100644 --- a/crates/abd-clam/src/core/dataset/sized_heap.rs +++ b/crates/abd-clam/src/core/dataset/sized_heap.rs @@ -12,6 +12,16 @@ pub struct SizedHeap { k: usize, } +impl FromIterator for SizedHeap { + fn from_iter>(iter: I) -> Self { + let mut heap = Self::new(None); + for item in iter { + heap.push(item); + } + heap + } +} + impl SizedHeap { /// Creates a new `SizedHeap` with a fixed size. #[must_use] @@ -86,6 +96,11 @@ impl SizedHeap { self.push(item.0); } } + + /// Retains only the elements that satisfy the predicate. + pub fn retain bool>(&mut self, f: F) { + self.heap.retain(|MaxItem(x)| f(x)); + } } impl SizedHeap { @@ -116,6 +131,6 @@ impl PartialOrd for MaxItem { impl Ord for MaxItem { fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.0.partial_cmp(&other.0).unwrap_or(core::cmp::Ordering::Greater) + self.0.partial_cmp(&other.0).unwrap_or(core::cmp::Ordering::Less) } } diff --git a/crates/abd-clam/src/pancakes/cluster/squishy_ball.rs b/crates/abd-clam/src/pancakes/cluster/squishy_ball.rs index 3eb608d0..03d77da2 100644 --- a/crates/abd-clam/src/pancakes/cluster/squishy_ball.rs +++ b/crates/abd-clam/src/pancakes/cluster/squishy_ball.rs @@ -18,16 +18,16 @@ use crate::{ use super::super::{CodecData, Compressible, Decodable, Decompressible, Encodable, ParCompressible, ParDecompressible}; -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] use std::io::{Read, Write}; -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] use flate2::{read::GzDecoder, write::GzEncoder, Compression}; /// A `Cluster` for use in compressive search. #[derive(Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] -#[cfg_attr(feature = "bitcode", bitcode(recursive))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", bitcode(recursive))] pub struct SquishyBall> { /// The `Cluster` type that the `OffsetBall` is based on. source: PermutedBall, @@ -237,7 +237,7 @@ impl> ParCluster for SquishyBall { /// Parameters for the `OffsetBall`. #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] pub struct SquishCosts { /// Expected memory cost of recursive compression. recursive: T, @@ -375,7 +375,7 @@ impl> core::hash::Hash for SquishyBall { } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl> crate::cluster::Csv for SquishyBall { fn header(&self) -> Vec { let mut header = self.source.header(); @@ -400,10 +400,10 @@ impl> crate::cluster::Csv for SquishyBal } } -#[cfg(feature = "csv")] +#[cfg(feature = "disk-io")] impl> crate::cluster::ParCsv for SquishyBall {} -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl> crate::cluster::ClusterIO for SquishyBall { fn write_to>(&self, path: &P) -> Result<(), String> where @@ -427,5 +427,5 @@ impl> crate::cluster::ClusterIO fo } } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl> crate::cluster::ParClusterIO for SquishyBall {} diff --git a/crates/abd-clam/src/pancakes/dataset/codec_data.rs b/crates/abd-clam/src/pancakes/dataset/codec_data.rs index ef387050..53cbb8b4 100644 --- a/crates/abd-clam/src/pancakes/dataset/codec_data.rs +++ b/crates/abd-clam/src/pancakes/dataset/codec_data.rs @@ -20,10 +20,10 @@ use super::{ decompression::{Decodable, Decompressible, ParDecompressible}, }; -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] use std::io::{Read, Write}; -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] use flate2::{read::GzDecoder, write::GzEncoder, Compression}; /// A compressed dataset, that can be partially decompressed for search and @@ -34,7 +34,7 @@ use flate2::{read::GzDecoder, write::GzEncoder, Compression}; /// - `I`: The type of the items in the dataset. /// - `Me`: The type of the metadata associated with the items. #[derive(Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] pub struct CodecData { /// The cardinality of the dataset. cardinality: usize, @@ -341,7 +341,7 @@ impl AssociatesMetadataMut(item: T) -> Result, String> { encoder.finish().map_err(|e| e.to_string()) } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] /// Decompresses using Gzip and decodes using bitcode. /// /// # Errors @@ -369,7 +369,7 @@ fn decompress_and_decode(bytes: &[u8]) -> Result bitcode::decode(&buf).map_err(|e| e.to_string()) } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl crate::dataset::DatasetIO for CodecData { fn write_to>(&self, path: &P) -> Result<(), String> where @@ -441,7 +441,7 @@ impl crate::dataset::Datase } } -#[cfg(feature = "bitcode")] +#[cfg(feature = "disk-io")] impl crate::dataset::ParDatasetIO for CodecData { diff --git a/crates/abd-clam/src/pancakes/dataset/mod.rs b/crates/abd-clam/src/pancakes/dataset/mod.rs index 464029eb..3d7b8cd1 100644 --- a/crates/abd-clam/src/pancakes/dataset/mod.rs +++ b/crates/abd-clam/src/pancakes/dataset/mod.rs @@ -4,7 +4,6 @@ mod codec_data; mod compression; mod decompression; -#[allow(clippy::module_name_repetitions)] pub use codec_data::CodecData; pub use compression::{Compressible, Encodable, ParCompressible}; pub use decompression::{Decodable, Decompressible, ParDecompressible}; diff --git a/crates/abd-clam/src/pancakes/sequence/mod.rs b/crates/abd-clam/src/pancakes/sequence/mod.rs index bb15d74e..343d3f21 100644 --- a/crates/abd-clam/src/pancakes/sequence/mod.rs +++ b/crates/abd-clam/src/pancakes/sequence/mod.rs @@ -7,7 +7,7 @@ use super::{Decodable, Encodable}; /// A sequence of 'omic data. #[derive(Clone, Debug, Serialize, Deserialize, Default)] -#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] +#[cfg_attr(feature = "disk-io", derive(bitcode::Encode, bitcode::Decode))] pub struct Sequence(String); impl Sequence { diff --git a/crates/results/cakes/Cargo.toml b/crates/results/cakes/Cargo.toml index a32e656b..9321ae2f 100644 --- a/crates/results/cakes/Cargo.toml +++ b/crates/results/cakes/Cargo.toml @@ -10,7 +10,7 @@ distances = { workspace = true } stringzilla = "3.9.5" bio = { workspace = true } rand = { workspace = true } -abd-clam = { workspace = true, features = ["csv", "bitcode"] } +abd-clam = { workspace = true, features = ["disk-io"] } hdf5 = { package = "hdf5-metno", version = "0.9.0" } serde = { workspace = true } serde_json = "1.0" diff --git a/crates/results/chaoda/Cargo.toml b/crates/results/chaoda/Cargo.toml index 27ee7bab..53d0867d 100644 --- a/crates/results/chaoda/Cargo.toml +++ b/crates/results/chaoda/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] clap = { version = "4.5.16", features = ["derive"] } -abd-clam = { workspace = true, features = ["chaoda", "ndarray-bindings"] } +abd-clam = { workspace = true, features = ["chaoda", "disk-io"] } distances = { workspace = true } rand = { workspace = true } ndarray = { workspace = true } diff --git a/crates/results/msa/Cargo.toml b/crates/results/msa/Cargo.toml index 165236d5..d4980495 100644 --- a/crates/results/msa/Cargo.toml +++ b/crates/results/msa/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" clap = { workspace = true } ftlog = { workspace = true } results-cakes = { path = "../cakes" } -abd-clam = { workspace = true, features = ["msa", "bitcode"] } +abd-clam = { workspace = true, features = ["msa", "disk-io"] } distances = { workspace = true } bio = { workspace = true } rayon = { workspace = true }