Skip to content

test the functions #298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
263 changes: 2 additions & 261 deletions pgml-extension/pgml_rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use std::path::Path;
use std::sync::Mutex;
use xgboost::{parameters, Booster, DMatrix};

pub mod vectors;

pg_module_magic!();

extension_sql_file!("../sql/schema.sql", name = "bootstrap_raw", bootstrap);
Expand Down Expand Up @@ -373,272 +375,11 @@ mod pgml_rust {
None => error!("Model with id = {} does not exist", model_id),
}
}

#[pg_extern(immutable, parallel_safe, strict, name="add")]
fn pgml_add_scalar_s(vector: Vec<f32>, addend: f32) -> Vec<f32> {
vector.as_slice().iter().map(|a| a + addend).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="add")]
fn pgml_add_scalar_d(vector: Vec<f64>, addend: f64) -> Vec<f64> {
vector.as_slice().iter().map(|a| a + addend).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="subtract")]
fn pgml_subtract_scalar_s(vector: Vec<f32>, subtahend: f32) -> Vec<f32> {
vector.as_slice().iter().map(|a| a - subtahend).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="subtract")]
fn pgml_subtract_scalar_d(vector: Vec<f64>, subtahend: f64) -> Vec<f64> {
vector.as_slice().iter().map(|a| a - subtahend).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="multiply")]
fn pgml_multiply_scalar_s(vector: Vec<f32>, multiplicand: f32) -> Vec<f32> {
vector.as_slice().iter().map(|a| a * multiplicand).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="multiply")]
fn pgml_multiply_scalar_d(vector: Vec<f64>, multiplicand: f64) -> Vec<f64> {
vector.as_slice().iter().map(|a| a * multiplicand).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="divide")]
fn pgml_divide_scalar_s(vector: Vec<f32>, dividend: f32) -> Vec<f32> {
vector.as_slice().iter().map(|a| a / dividend).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="divide")]
fn pgml_divide_scalar_d(vector: Vec<f64>, dividend: f64) -> Vec<f64> {
vector.as_slice().iter().map(|a| a / dividend).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="add")]
fn pgml_add_vector_s(vector: Vec<f32>, addend: Vec<f32>) -> Vec<f32> {
vector.as_slice().iter()
.zip(addend.as_slice().iter())
.map(|(a, b)| a + b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="add")]
fn pgml_add_vector_d(vector: Vec<f64>, addend: Vec<f64>) -> Vec<f64> {
vector.as_slice().iter()
.zip(addend.as_slice().iter())
.map(|(a, b)| a + b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="subtract")]
fn pgml_subtract_vector_s(vector: Vec<f32>, subtahend: Vec<f32>) -> Vec<f32> {
vector.as_slice().iter()
.zip(subtahend.as_slice().iter())
.map(|(a, b)| a - b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="subtract")]
fn pgml_subtract_vector_d(vector: Vec<f64>, subtahend: Vec<f64>) -> Vec<f64> {
vector.as_slice().iter()
.zip(subtahend.as_slice().iter())
.map(|(a, b)| a - b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="multiply")]
fn pgml_multiply_vector_s(vector: Vec<f32>, multiplicand: Vec<f32>) -> Vec<f32> {
vector.as_slice().iter()
.zip(multiplicand.as_slice().iter())
.map(|(a, b)| a * b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="multiply")]
fn pgml_multiply_vector_d(vector: Vec<f64>, multiplicand: Vec<f64>) -> Vec<f64> {
vector.as_slice().iter()
.zip(multiplicand.as_slice().iter())
.map(|(a, b)| a * b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="divide")]
fn pgml_divide_vector_s(vector: Vec<f32>, dividend: Vec<f32>) -> Vec<f32> {
vector.as_slice().iter()
.zip(dividend.as_slice().iter())
.map(|(a, b)| a / b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="divide")]
fn pgml_divide_vector_d(vector: Vec<f64>, dividend: Vec<f64>) -> Vec<f64> {
vector.as_slice().iter()
.zip(dividend.as_slice().iter())
.map(|(a, b)| a / b ).collect()
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_l0")]
fn pgml_norm_l0_s(vector: Vec<f32>) -> f32 {
vector.as_slice().iter().map(|a| if *a == 0.0 { 0.0 } else { 1.0 } ).sum()
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_l0")]
fn pgml_norm_l0_d(vector: Vec<f64>) -> f64 {
vector.as_slice().iter().map(|a| if *a == 0.0 { 0.0 } else { 1.0 } ).sum()
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_l1")]
fn pgml_norm_l1_s(vector: Vec<f32>) -> f32 {
unsafe {
blas::sasum(vector.len().try_into().unwrap(), vector.as_slice(), 1)
}
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_l1")]
fn pgml_norm_l1_d(vector: Vec<f64>) -> f64 {
unsafe {
blas::dasum(vector.len().try_into().unwrap(), vector.as_slice(), 1)
}
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_l2")]
fn pgml_norm_l2_s(vector: Vec<f32>) -> f32 {
unsafe {
blas::snrm2(vector.len().try_into().unwrap(), vector.as_slice(), 1)
}
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_l2")]
fn pgml_norm_l2_d(vector: Vec<f64>) -> f64 {
unsafe {
blas::dnrm2(vector.len().try_into().unwrap(), vector.as_slice(), 1)
}
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_max")]
fn pgml_norm_max_s(vector: Vec<f32>) -> f32 {
unsafe {
let index = blas::isamax(vector.len().try_into().unwrap(), vector.as_slice(), 1);
vector[index - 1]
}
}

#[pg_extern(immutable, parallel_safe, strict, name="norm_max")]
fn pgml_norm_max_d(vector: Vec<f64>) -> f64 {
unsafe {
let index = blas::idamax(vector.len().try_into().unwrap(), vector.as_slice(), 1);
vector[index - 1]
}
}

#[pg_extern(immutable, parallel_safe, strict, name="normalize_l1")]
fn pgml_normalize_l1_s(vector: Vec<f32>) -> Vec<f32> {
let norm: f32;
unsafe {
norm = blas::sasum(vector.len().try_into().unwrap(), vector.as_slice(), 1);
}
pgml_divide_scalar_s(vector, norm)
}

#[pg_extern(immutable, parallel_safe, strict, name="normalize_l1")]
fn pgml_normalize_l1_d(vector: Vec<f64>) -> Vec<f64> {
let norm: f64;
unsafe {
norm = blas::dasum(vector.len().try_into().unwrap(), vector.as_slice(), 1);
}
pgml_divide_scalar_d(vector, norm)
}

#[pg_extern(immutable, parallel_safe, strict, name="normalize_l2")]
fn pgml_normalize_l2_s(vector: Vec<f32>) -> Vec<f32> {
let norm: f32;
unsafe {
norm = blas::snrm2(vector.len().try_into().unwrap(), vector.as_slice(), 1);
}
pgml_divide_scalar_s(vector, norm)
}

#[pg_extern(immutable, parallel_safe, strict, name="normalize_l2")]
fn pgml_normalize_l2_d(vector: Vec<f64>) -> Vec<f64> {
let norm: f64;
unsafe {
norm = blas::dnrm2(vector.len().try_into().unwrap(), vector.as_slice(), 1);
}
pgml_divide_scalar_d(vector, norm)
}

#[pg_extern(immutable, parallel_safe, strict, name="normalize_max")]
fn pgml_normalize_max_s(vector: Vec<f32>) -> Vec<f32> {
let norm = vector.as_slice().iter().map(|a| a.abs()).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
pgml_divide_scalar_s(vector, norm)
}

#[pg_extern(immutable, parallel_safe, strict, name="normalize_max")]
fn pgml_normalize_max_d(vector: Vec<f64>) -> Vec<f64> {
let norm = vector.as_slice().iter().map(|a| a.abs()).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
pgml_divide_scalar_d(vector, norm)
}

#[pg_extern(immutable, parallel_safe, strict, name="distance_l1")]
fn pgml_distance_l1_s(vector: Vec<f32>, other: Vec<f32>) -> f32 {
vector.as_slice().iter()
.zip(other.as_slice().iter())
.map(|(a, b)| (a - b).abs() ).sum()
}

#[pg_extern(immutable, parallel_safe, strict, name="distance_l1")]
fn pgml_distance_l1_d(vector: Vec<f64>, other: Vec<f64>) -> f64 {
vector.as_slice().iter()
.zip(other.as_slice().iter())
.map(|(a, b)| (a - b).abs() ).sum()
}

#[pg_extern(immutable, parallel_safe, strict, name="distance_l2")]
fn pgml_distance_l2_s(vector: Vec<f32>, other: Vec<f32>) -> f32 {
vector.as_slice().iter()
.zip(other.as_slice().iter())
.map(|(a, b)| (a - b).powf(2.0) ).sum::<f32>().sqrt()
}

#[pg_extern(immutable, parallel_safe, strict, name="distance_l2")]
fn pgml_distance_l2_d(vector: Vec<f64>, other: Vec<f64>) -> f64 {
vector.as_slice().iter()
.zip(other.as_slice().iter())
.map(|(a, b)| (a - b).powf(2.0) ).sum::<f64>().sqrt()
}

#[pg_extern(immutable, parallel_safe, strict, name="dot_product")]
fn pgml_dot_product_s(vector: Vec<f32>, other: Vec<f32>) -> f32 {
unsafe {
blas::sdot(vector.len().try_into().unwrap(), vector.as_slice(), 1, other.as_slice(), 1)
}
}

#[pg_extern(immutable, parallel_safe, strict, name="dot_product")]
fn pgml_dot_product_d(vector: Vec<f64>, other: Vec<f64>) -> f64 {
unsafe {
blas::ddot(vector.len().try_into().unwrap(), vector.as_slice(), 1, other.as_slice(), 1)
}
}

#[pg_extern(immutable, parallel_safe, strict, name="cosine_similarity")]
fn pgml_cosine_similarity_s(vector: Vec<f32>, other: Vec<f32>) -> f32 {
unsafe {
let dot = blas::sdot(vector.len().try_into().unwrap(), vector.as_slice(), 1, other.as_slice(), 1);
let a_norm = blas::snrm2(vector.len().try_into().unwrap(), vector.as_slice(), 1);
let b_norm = blas::snrm2(other.len().try_into().unwrap(), other.as_slice(), 1);
dot / (a_norm * b_norm)
}
}

#[pg_extern(immutable, parallel_safe, strict, name="cosine_similarity")]
fn pgml_cosine_similarity_d(vector: Vec<f64>, other: Vec<f64>) -> f64 {
unsafe {
let dot = blas::ddot(vector.len().try_into().unwrap(), vector.as_slice(), 1, other.as_slice(), 1);
let a_norm = blas::dnrm2(vector.len().try_into().unwrap(), vector.as_slice(), 1);
let b_norm = blas::dnrm2(other.len().try_into().unwrap(), other.as_slice(), 1);
dot / (a_norm * b_norm)
}
}
}

#[cfg(any(test, feature = "pg_test"))]
#[pg_schema]
mod tests {
use pgx::*;
}

#[cfg(test)]
Expand Down
Loading