Skip to content

Commit

Permalink
refactor: move pgvecto.rs base to this repo
Browse files Browse the repository at this point in the history
Signed-off-by: usamoi <[email protected]>
  • Loading branch information
usamoi committed Jan 6, 2025
1 parent 9b70fb7 commit ed7b12e
Show file tree
Hide file tree
Showing 87 changed files with 7,981 additions and 963 deletions.
167 changes: 101 additions & 66 deletions Cargo.lock

Large diffs are not rendered by default.

54 changes: 32 additions & 22 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "vchord"
version = "0.0.0"
edition = "2021"
version.workspace = true
edition.workspace = true

[lib]
name = "vchord"
Expand All @@ -20,46 +20,56 @@ pg16 = ["pgrx/pg16", "pgrx-catalog/pg16"]
pg17 = ["pgrx/pg17", "pgrx-catalog/pg17"]

[dependencies]
base = { git = "https://github.com/tensorchord/pgvecto.rs.git", rev = "9d87afd75ca3dd6819da2a0a38d9fefdfb5b1c74" }

# lock algebra version forever so that the QR decomposition never changes for same input
nalgebra = "=0.33.0"
algorithm = { path = "./crates/algorithm" }
always_equal = { path = "./crates/always_equal" }
distance = { path = "./crates/distance" }
rabitq = { path = "./crates/rabitq" }
random_orthogonal_matrix = { path = "./crates/random_orthogonal_matrix" }
simd = { path = "./crates/simd" }
vector = { path = "./crates/vector" }

# lock rkyv version forever so that data is always compatible
rkyv = { version = "=0.7.45", features = ["validation"] }

half = { version = "2.4.1", features = ["rkyv"] }
half.workspace = true
log = "0.4.22"
paste = "1"
pgrx = { version = "=0.12.9", default-features = false, features = ["cshim"] }
pgrx-catalog = "0.1.0"
rand = "0.8.5"
rand_chacha = "0.3.1"
rand_distr = "0.4.3"
rand.workspace = true
rayon = "1.10.0"
serde = "1"
serde.workspace = true
toml = "0.8.19"
validator = { version = "0.19.0", features = ["derive"] }

[patch.crates-io]
half = { git = "https://github.com/tensorchord/half-rs.git" }

[lints]
rust.fuzzy_provenance_casts = "deny"
rust.unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(feature, values("pg12"))',
'cfg(pgrx_embed)',
] }
workspace = true

[workspace]
resolver = "2"
members = ["crates/*"]

[workspace.package]
version = "0.0.0"
edition = "2021"

[workspace.dependencies]
half = { version = "2.4.1", features = ["rkyv", "serde"] }
rand = "0.8.5"
serde = "1"

[workspace.lints]
clippy.identity_op = "allow"
clippy.int_plus_one = "allow"
clippy.needless_range_loop = "allow"
clippy.nonminimal_bool = "allow"
rust.unsafe_op_in_unsafe_fn = "deny"
rust.unused_lifetimes = "warn"
rust.unused_qualifications = "warn"

[profile.opt]
debug-assertions = false
inherits = "dev"
opt-level = 3
overflow-checks = false

[profile.release]
codegen-units = 1
debug = true
Expand Down
4 changes: 4 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
println!(r#"cargo::rustc-check-cfg=cfg(pgrx_embed)"#);
println!(r#"cargo::rustc-check-cfg=cfg(feature, values("pg12"))"#);
}
7 changes: 7 additions & 0 deletions crates/algorithm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "algorithm"
version.workspace = true
edition.workspace = true

[lints]
workspace = true
40 changes: 40 additions & 0 deletions crates/algorithm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::ops::{Deref, DerefMut};

#[repr(C, align(8))]
pub struct Opaque {
pub next: u32,
pub skip: u32,
}

pub trait Page: Sized {
fn get_opaque(&self) -> &Opaque;
fn get_opaque_mut(&mut self) -> &mut Opaque;
fn len(&self) -> u16;
fn get(&self, i: u16) -> Option<&[u8]>;
fn get_mut(&mut self, i: u16) -> Option<&mut [u8]>;
fn alloc(&mut self, data: &[u8]) -> Option<u16>;
fn free(&mut self, i: u16);
fn reconstruct(&mut self, removes: &[u16]);
fn freespace(&self) -> u16;
}

pub trait PageGuard {
fn id(&self) -> u32;
}

pub trait RelationRead {
type Page: Page;
type ReadGuard<'a>: PageGuard + Deref<Target = Self::Page>
where
Self: 'a;
fn read(&self, id: u32) -> Self::ReadGuard<'_>;
}

pub trait RelationWrite: RelationRead {
type WriteGuard<'a>: PageGuard + DerefMut<Target = Self::Page>
where
Self: 'a;
fn write(&self, id: u32, tracking_freespace: bool) -> Self::WriteGuard<'_>;
fn extend(&self, tracking_freespace: bool) -> Self::WriteGuard<'_>;
fn search(&self, freespace: usize) -> Option<Self::WriteGuard<'_>>;
}
7 changes: 7 additions & 0 deletions crates/always_equal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "always_equal"
version.workspace = true
edition.workspace = true

[lints]
workspace = true
30 changes: 30 additions & 0 deletions crates/always_equal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::cmp::Ordering;
use std::hash::Hash;

#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct AlwaysEqual<T>(pub T);

impl<T> PartialEq for AlwaysEqual<T> {
fn eq(&self, _: &Self) -> bool {
true
}
}

impl<T> Eq for AlwaysEqual<T> {}

impl<T> PartialOrd for AlwaysEqual<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl<T> Ord for AlwaysEqual<T> {
fn cmp(&self, _: &Self) -> Ordering {
Ordering::Equal
}
}

impl<T> Hash for AlwaysEqual<T> {
fn hash<H: std::hash::Hasher>(&self, _: &mut H) {}
}
7 changes: 7 additions & 0 deletions crates/distance/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "distance"
version.workspace = true
edition.workspace = true

[lints]
workspace = true
79 changes: 79 additions & 0 deletions crates/distance/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Distance(i32);

impl Distance {
pub const ZERO: Self = Distance::from_f32(0.0f32);
pub const INFINITY: Self = Distance::from_f32(f32::INFINITY);
pub const NEG_INFINITY: Self = Distance::from_f32(f32::NEG_INFINITY);

#[inline(always)]
pub const fn from_f32(value: f32) -> Self {
let bits = value.to_bits() as i32;
let mask = ((bits >> 31) as u32) >> 1;
let res = bits ^ (mask as i32);
Self(res)
}

#[inline(always)]
pub const fn to_f32(self) -> f32 {
let bits = self.0;
let mask = ((bits >> 31) as u32) >> 1;
let res = bits ^ (mask as i32);
f32::from_bits(res as u32)
}

#[inline(always)]
pub const fn to_i32(self) -> i32 {
self.0
}
}

impl From<f32> for Distance {
#[inline(always)]
fn from(value: f32) -> Self {
Distance::from_f32(value)
}
}

impl From<Distance> for f32 {
#[inline(always)]
fn from(value: Distance) -> Self {
Distance::to_f32(value)
}
}

#[test]
fn distance_conversions() {
assert_eq!(Distance::from(0.0f32), Distance::ZERO);
assert_eq!(Distance::from(f32::INFINITY), Distance::INFINITY);
assert_eq!(Distance::from(f32::NEG_INFINITY), Distance::NEG_INFINITY);
for i in -100..100 {
let val = (i as f32) * 0.1;
assert_eq!(f32::from(Distance::from(val)).to_bits(), val.to_bits());
}
assert_eq!(
f32::from(Distance::from(0.0f32)).to_bits(),
0.0f32.to_bits()
);
assert_eq!(
f32::from(Distance::from(-0.0f32)).to_bits(),
(-0.0f32).to_bits()
);
assert_eq!(
f32::from(Distance::from(f32::NAN)).to_bits(),
f32::NAN.to_bits()
);
assert_eq!(
f32::from(Distance::from(-f32::NAN)).to_bits(),
(-f32::NAN).to_bits()
);
assert_eq!(
f32::from(Distance::from(f32::INFINITY)).to_bits(),
f32::INFINITY.to_bits()
);
assert_eq!(
f32::from(Distance::from(-f32::INFINITY)).to_bits(),
(-f32::INFINITY).to_bits()
);
}
11 changes: 11 additions & 0 deletions crates/rabitq/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "rabitq"
version.workspace = true
edition.workspace = true

[dependencies]
distance = { path = "../distance" }
simd = { path = "../simd" }

[lints]
workspace = true
Loading

0 comments on commit ed7b12e

Please sign in to comment.