diff --git a/Cargo.lock b/Cargo.lock index 4c1449a1..eacd7238 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "ascii-canvas" version = "3.0.0" @@ -305,6 +314,13 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "externfns" +version = "0.1.0" +dependencies = [ + "nalgebra", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -521,6 +537,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libredox" version = "0.1.3" @@ -616,6 +638,7 @@ name = "nac3core" version = "0.1.0" dependencies = [ "crossbeam", + "externfns", "indexmap 2.2.6", "indoc", "inkwell", @@ -664,12 +687,64 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "nalgebra" +version = "0.32.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" +dependencies = [ + "approx", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -699,6 +774,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "petgraph" version = "0.6.5" @@ -1070,6 +1151,18 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "simba" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", +] + [[package]] name = "similar" version = "2.5.0" @@ -1230,6 +1323,12 @@ dependencies = [ "crunchy", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unic-char-property" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 765ab391..3b15c464 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "nac3ast", "nac3parser", "nac3core", + "nac3core/src/codegen/externfns", "nac3standalone", "nac3artiq", "runkernel", diff --git a/nac3core/Cargo.toml b/nac3core/Cargo.toml index 724e0c8c..2659ddc4 100644 --- a/nac3core/Cargo.toml +++ b/nac3core/Cargo.toml @@ -11,6 +11,7 @@ indexmap = "2.2" parking_lot = "0.12" rayon = "1.8" nac3parser = { path = "../nac3parser" } +externfns = { path = "src/codegen/externfns" } strum = "0.26.2" strum_macros = "0.26.4" diff --git a/nac3core/src/codegen/externfns/Cargo.toml b/nac3core/src/codegen/externfns/Cargo.toml new file mode 100644 index 00000000..9d4592b4 --- /dev/null +++ b/nac3core/src/codegen/externfns/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "externfns" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +nalgebra = {version = "0.32.6", default-features = false, features = ["libm", "alloc"]} diff --git a/nac3core/src/codegen/externfns/src/lib.rs b/nac3core/src/codegen/externfns/src/lib.rs new file mode 100644 index 00000000..504aa670 --- /dev/null +++ b/nac3core/src/codegen/externfns/src/lib.rs @@ -0,0 +1,30 @@ +use core::slice; +use nalgebra::{linalg, DMatrix}; + +/// # Safety +/// +/// `data` must point to an array with `dim0`x`dim1` elements in row-major order +#[no_mangle] +pub unsafe extern "C" fn linalg_try_invert_to(dim0: usize, dim1: usize, data: *mut f64) -> i8 { + let data_slice = unsafe { slice::from_raw_parts_mut(data, dim0 * dim1) }; + let matrix = DMatrix::from_row_slice(dim0, dim1, data_slice); + let mut inverted_matrix = DMatrix::::zeros(dim0, dim1); + + if linalg::try_invert_to(matrix, &mut inverted_matrix) { + data_slice.copy_from_slice(inverted_matrix.transpose().as_slice()); + 1 + } else { + 0 + } +} + +/// # Safety +/// +/// `data` must point to an array of 4 elements in row-major order +#[no_mangle] +pub unsafe extern "C" fn linalg_wilkinson_shift(dim0: usize, dim1: usize, data: *mut f64) -> f64 { + let data_slice = unsafe { slice::from_raw_parts_mut(data, dim0 * dim1) }; + let matrix = DMatrix::from_row_slice(dim0, dim1, data_slice); + + linalg::wilkinson_shift(matrix[(0, 0)], matrix[(1, 1)], matrix[(0, 1)]) +}