mirror of
https://github.com/ruvnet/RuVector.git
synced 2026-05-31 05:13:39 +00:00
feat(dag-wasm): add minimal WASM build for browser/embedded
- 130KB raw, 58KB gzipped WASM binary - 13-method API surface (add_node, add_edge, topo_sort, critical_path, attention) - 3 attention mechanisms (topological, critical path, uniform) - Binary and JSON serialization - wee_alloc feature for even smaller builds - TypeScript type definitions included Also updates ruvector-dag README with: - Design philosophy: MinCut as central control signal - Policy layer for attention mechanism selection - SONA state vector structure with per-operator LoRA weights - Predictive healing based on rising cut tension - External cost model trait for PostgreSQL/embedded/chip schedulers - QuDAG sync frequency bounds (1min-1hr adaptive) - End-to-end convergence example with logs
This commit is contained in:
parent
74e70e9eab
commit
c30dae72aa
5 changed files with 848 additions and 131 deletions
126
Cargo.lock
generated
126
Cargo.lock
generated
|
|
@ -39,7 +39,7 @@ version = "0.8.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"getrandom 0.3.4",
|
||||
"once_cell",
|
||||
"serde",
|
||||
|
|
@ -102,7 +102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d4bbb2296f2525e53a52680f5c2df6de9a83b8a94cc22a8cc629301a27b5e0b7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"cpu-time",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
|
|
@ -312,7 +312,7 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b29ec3788e96fb4fdb275ccb9d62811f2fa903d76c5eb4dd6fe7d09a7ed5871f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"rustc_version 0.3.3",
|
||||
]
|
||||
|
||||
|
|
@ -512,7 +512,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
|
|
@ -670,7 +670,7 @@ dependencies = [
|
|||
"arrayref",
|
||||
"arrayvec",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
|
|
@ -923,6 +923,12 @@ dependencies = [
|
|||
"nom 7.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
|
|
@ -1103,7 +1109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"itoa",
|
||||
"rustversion",
|
||||
"ryu",
|
||||
|
|
@ -1156,7 +1162,7 @@ version = "0.1.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
|
|
@ -1252,7 +1258,7 @@ version = "0.4.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1280,7 +1286,7 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1497,7 +1503,7 @@ version = "5.5.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"hashbrown 0.14.5",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
|
|
@ -1510,7 +1516,7 @@ version = "6.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"crossbeam-utils",
|
||||
"hashbrown 0.14.5",
|
||||
"lock_api",
|
||||
|
|
@ -1689,7 +1695,7 @@ version = "2.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
|
|
@ -1825,7 +1831,7 @@ version = "0.8.35"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2059,7 +2065,7 @@ version = "0.2.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys 0.60.2",
|
||||
|
|
@ -2579,7 +2585,7 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
|
|
@ -2592,7 +2598,7 @@ version = "0.3.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi",
|
||||
|
|
@ -2638,7 +2644,7 @@ version = "0.6.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"dashmap 5.5.3",
|
||||
"futures",
|
||||
"futures-timer",
|
||||
|
|
@ -2703,7 +2709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"crunchy",
|
||||
"num-traits",
|
||||
"rand 0.9.2",
|
||||
|
|
@ -2769,7 +2775,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "bdcd9b131fd67bb827b386d0dc63d3e74196a14616ef800acf87ca5fef741a10"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"hdf5-derive",
|
||||
"hdf5-sys",
|
||||
"hdf5-types",
|
||||
|
|
@ -2813,7 +2819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b47268c0dfb499b1ffe5638b6e7694e7a87fe49fb92eca998a4346e5483e428f"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"hdf5-sys",
|
||||
"libc",
|
||||
]
|
||||
|
|
@ -2918,7 +2924,7 @@ dependencies = [
|
|||
"anndists",
|
||||
"anyhow",
|
||||
"bincode 1.3.3",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"cpu-time",
|
||||
"env_logger",
|
||||
"hashbrown 0.15.5",
|
||||
|
|
@ -3439,7 +3445,7 @@ version = "0.1.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3657,7 +3663,7 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
|
@ -3667,7 +3673,7 @@ version = "0.8.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
|
|
@ -3825,7 +3831,7 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
|
|
@ -3835,7 +3841,7 @@ version = "0.10.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"digest",
|
||||
]
|
||||
|
||||
|
|
@ -3864,6 +3870,12 @@ dependencies = [
|
|||
"autocfg 1.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
|
|
@ -3940,7 +3952,7 @@ version = "0.13.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"downcast",
|
||||
"fragile",
|
||||
"mockall_derive",
|
||||
|
|
@ -3954,7 +3966,7 @@ version = "0.13.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
|
|
@ -4120,7 +4132,7 @@ version = "2.16.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"convert_case",
|
||||
"napi-derive-backend",
|
||||
"proc-macro2",
|
||||
|
|
@ -4226,7 +4238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"libc",
|
||||
"memoffset",
|
||||
"pin-utils",
|
||||
|
|
@ -4547,7 +4559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"foreign-types 0.3.2",
|
||||
"libc",
|
||||
"once_cell",
|
||||
|
|
@ -4707,7 +4719,7 @@ version = "0.8.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall 0.2.16",
|
||||
|
|
@ -4721,7 +4733,7 @@ version = "0.9.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"libc",
|
||||
"redox_syscall 0.5.18",
|
||||
"smallvec 1.15.1",
|
||||
|
|
@ -5173,7 +5185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ef5c97c51bd34c7e742402e216abdeb44d415fbe6ae41d56b114723e953711cb"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"criterion",
|
||||
"findshlibs",
|
||||
"inferno",
|
||||
|
|
@ -5329,7 +5341,7 @@ version = "0.13.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
|
|
@ -5425,7 +5437,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "96b86df24f0a7ddd5e4b95c94fc9ed8a98f1ca94d3b01bdce2824097e7835907"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"libm",
|
||||
"num-complex 0.4.6",
|
||||
"reborrow",
|
||||
|
|
@ -5737,7 +5749,7 @@ dependencies = [
|
|||
"av1-grain",
|
||||
"bitstream-io",
|
||||
"built",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"interpolate_name",
|
||||
"itertools 0.14.0",
|
||||
"libc",
|
||||
|
|
@ -6077,7 +6089,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"getrandom 0.2.16",
|
||||
"libc",
|
||||
"untrusted",
|
||||
|
|
@ -6528,6 +6540,18 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruvector-dag-wasm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode 1.3.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
"wee_alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruvector-filter"
|
||||
version = "0.1.29"
|
||||
|
|
@ -7488,7 +7512,7 @@ version = "0.10.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
|
@ -7499,7 +7523,7 @@ version = "0.10.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
|
@ -7870,7 +7894,7 @@ version = "0.30.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"ntapi",
|
||||
|
|
@ -8067,7 +8091,7 @@ version = "1.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -9011,7 +9035,7 @@ version = "0.2.106"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
|
|
@ -9024,7 +9048,7 @@ version = "0.4.56"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -9161,6 +9185,18 @@ dependencies = [
|
|||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.12"
|
||||
|
|
@ -9632,7 +9668,7 @@ version = "0.50.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.4",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ members = [
|
|||
"crates/rvlite",
|
||||
"crates/ruvector-nervous-system",
|
||||
"crates/ruvector-dag",
|
||||
"crates/ruvector-dag-wasm",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
|
|
|
|||
38
crates/ruvector-dag-wasm/Cargo.toml
Normal file
38
crates/ruvector-dag-wasm/Cargo.toml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
[package]
|
||||
name = "ruvector-dag-wasm"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["RuVector Contributors"]
|
||||
description = "Minimal WASM DAG library for browser and embedded systems"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
bincode = "1.3"
|
||||
|
||||
[dependencies.wee_alloc]
|
||||
version = "0.4"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
# Enable wee_alloc for ~10KB smaller WASM binary
|
||||
wee_alloc = ["dep:wee_alloc"]
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
strip = true
|
||||
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = false
|
||||
416
crates/ruvector-dag-wasm/src/lib.rs
Normal file
416
crates/ruvector-dag-wasm/src/lib.rs
Normal file
|
|
@ -0,0 +1,416 @@
|
|||
//! Minimal WASM DAG library optimized for browser and embedded systems
|
||||
//!
|
||||
//! Size optimizations:
|
||||
//! - u8/u32/f32 instead of larger types
|
||||
//! - Inline hot paths
|
||||
//! - Minimal error handling
|
||||
//! - No string operations in critical paths
|
||||
//! - Optional wee_alloc for smaller binary
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
// Use wee_alloc for smaller WASM binary (~10KB reduction)
|
||||
#[cfg(feature = "wee_alloc")]
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
/// Minimal DAG node - 9 bytes (u32 + u8 + f32)
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
struct WasmNode {
|
||||
id: u32,
|
||||
op: u8,
|
||||
cost: f32,
|
||||
}
|
||||
|
||||
/// Minimal DAG structure for WASM
|
||||
/// Self-contained with no external dependencies beyond wasm-bindgen
|
||||
#[wasm_bindgen]
|
||||
pub struct WasmDag {
|
||||
nodes: Vec<WasmNode>,
|
||||
edges: Vec<(u32, u32)>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WasmDag {
|
||||
/// Create new empty DAG
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
nodes: Vec::new(),
|
||||
edges: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a node with operator type and cost
|
||||
/// Returns node ID
|
||||
#[inline]
|
||||
pub fn add_node(&mut self, op: u8, cost: f32) -> u32 {
|
||||
let id = self.nodes.len() as u32;
|
||||
self.nodes.push(WasmNode { id, op, cost });
|
||||
id
|
||||
}
|
||||
|
||||
/// Add edge from -> to
|
||||
/// Returns false if creates cycle (simple check)
|
||||
#[inline]
|
||||
pub fn add_edge(&mut self, from: u32, to: u32) -> bool {
|
||||
// Basic validation - nodes must exist
|
||||
if from >= self.nodes.len() as u32 || to >= self.nodes.len() as u32 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Simple cycle check: to must not reach from
|
||||
if self.has_path(to, from) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.edges.push((from, to));
|
||||
true
|
||||
}
|
||||
|
||||
/// Get number of nodes
|
||||
#[inline]
|
||||
pub fn node_count(&self) -> u32 {
|
||||
self.nodes.len() as u32
|
||||
}
|
||||
|
||||
/// Get number of edges
|
||||
#[inline]
|
||||
pub fn edge_count(&self) -> u32 {
|
||||
self.edges.len() as u32
|
||||
}
|
||||
|
||||
/// Topological sort using Kahn's algorithm
|
||||
/// Returns node IDs in topological order
|
||||
pub fn topo_sort(&self) -> Vec<u32> {
|
||||
let n = self.nodes.len();
|
||||
let mut in_degree = vec![0u32; n];
|
||||
|
||||
// Calculate in-degrees
|
||||
for &(_, to) in &self.edges {
|
||||
in_degree[to as usize] += 1;
|
||||
}
|
||||
|
||||
// Find nodes with no incoming edges
|
||||
let mut queue: Vec<u32> = (0..n as u32)
|
||||
.filter(|&i| in_degree[i as usize] == 0)
|
||||
.collect();
|
||||
|
||||
let mut result = Vec::with_capacity(n);
|
||||
|
||||
while let Some(node) = queue.pop() {
|
||||
result.push(node);
|
||||
|
||||
// Reduce in-degree for neighbors
|
||||
for &(from, to) in &self.edges {
|
||||
if from == node {
|
||||
in_degree[to as usize] -= 1;
|
||||
if in_degree[to as usize] == 0 {
|
||||
queue.push(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Find critical path (longest path by cost)
|
||||
/// Returns JSON: {"path": [node_ids], "cost": total}
|
||||
pub fn critical_path(&self) -> JsValue {
|
||||
let topo = self.topo_sort();
|
||||
let n = self.nodes.len();
|
||||
|
||||
// dist[i] = (max_cost_to_i, predecessor)
|
||||
let mut dist = vec![(0.0f32, u32::MAX); n];
|
||||
|
||||
// Initialize starting nodes
|
||||
for &node in &topo {
|
||||
if !self.has_incoming(node) {
|
||||
dist[node as usize] = (self.nodes[node as usize].cost, u32::MAX);
|
||||
}
|
||||
}
|
||||
|
||||
// Relax edges in topological order
|
||||
for &from in &topo {
|
||||
let from_cost = dist[from as usize].0;
|
||||
|
||||
for &(f, to) in &self.edges {
|
||||
if f == from {
|
||||
let new_cost = from_cost + self.nodes[to as usize].cost;
|
||||
if new_cost > dist[to as usize].0 {
|
||||
dist[to as usize] = (new_cost, from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find node with maximum cost
|
||||
let (max_idx, (max_cost, _)) = dist.iter()
|
||||
.enumerate()
|
||||
.max_by(|(_, a), (_, b)| a.0.partial_cmp(&b.0).unwrap())
|
||||
.unwrap();
|
||||
|
||||
// Backtrack to build path
|
||||
let mut path = Vec::new();
|
||||
let mut current = max_idx as u32;
|
||||
|
||||
while current != u32::MAX {
|
||||
path.push(current);
|
||||
current = dist[current as usize].1;
|
||||
}
|
||||
|
||||
path.reverse();
|
||||
|
||||
// Convert to JSON manually to avoid serde_json dependency
|
||||
let path_str = path.iter()
|
||||
.map(|id| id.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
|
||||
let json = format!("{{\"path\":[{}],\"cost\":{}}}", path_str, max_cost);
|
||||
JsValue::from_str(&json)
|
||||
}
|
||||
|
||||
/// Compute attention scores for nodes
|
||||
/// mechanism: 0=topological, 1=critical_path, 2=uniform
|
||||
pub fn attention(&self, mechanism: u8) -> Vec<f32> {
|
||||
compute_attention(self, mechanism)
|
||||
}
|
||||
|
||||
/// Serialize to bytes (bincode format)
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
#[derive(Serialize)]
|
||||
struct SerDag<'a> {
|
||||
nodes: &'a [WasmNode],
|
||||
edges: &'a [(u32, u32)],
|
||||
}
|
||||
|
||||
let data = SerDag {
|
||||
nodes: &self.nodes,
|
||||
edges: &self.edges,
|
||||
};
|
||||
|
||||
bincode::serialize(&data).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Deserialize from bytes
|
||||
pub fn from_bytes(data: &[u8]) -> Result<WasmDag, JsValue> {
|
||||
#[derive(Deserialize)]
|
||||
struct SerDag {
|
||||
nodes: Vec<WasmNode>,
|
||||
edges: Vec<(u32, u32)>,
|
||||
}
|
||||
|
||||
bincode::deserialize::<SerDag>(data)
|
||||
.map(|d| WasmDag {
|
||||
nodes: d.nodes,
|
||||
edges: d.edges,
|
||||
})
|
||||
.map_err(|e| JsValue::from_str(&format!("Deserialize error: {}", e)))
|
||||
}
|
||||
|
||||
/// Serialize to JSON
|
||||
pub fn to_json(&self) -> String {
|
||||
#[derive(Serialize)]
|
||||
struct SerDag<'a> {
|
||||
nodes: &'a [WasmNode],
|
||||
edges: &'a [(u32, u32)],
|
||||
}
|
||||
|
||||
let data = SerDag {
|
||||
nodes: &self.nodes,
|
||||
edges: &self.edges,
|
||||
};
|
||||
|
||||
serde_json::to_string(&data).unwrap_or_else(|_| String::from("{}"))
|
||||
}
|
||||
|
||||
/// Deserialize from JSON
|
||||
pub fn from_json(json: &str) -> Result<WasmDag, JsValue> {
|
||||
#[derive(Deserialize)]
|
||||
struct SerDag {
|
||||
nodes: Vec<WasmNode>,
|
||||
edges: Vec<(u32, u32)>,
|
||||
}
|
||||
|
||||
serde_json::from_str::<SerDag>(json)
|
||||
.map(|d| WasmDag {
|
||||
nodes: d.nodes,
|
||||
edges: d.edges,
|
||||
})
|
||||
.map_err(|e| JsValue::from_str(&format!("JSON error: {}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
// Internal helper methods (not exported to WASM)
|
||||
impl WasmDag {
|
||||
/// Check if there's a path from 'from' to 'to' (for cycle detection)
|
||||
#[inline(always)]
|
||||
fn has_path(&self, from: u32, to: u32) -> bool {
|
||||
if from == to {
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut visited = vec![false; self.nodes.len()];
|
||||
let mut stack = Vec::with_capacity(8);
|
||||
stack.push(from);
|
||||
|
||||
while let Some(node) = stack.pop() {
|
||||
if visited[node as usize] {
|
||||
continue;
|
||||
}
|
||||
visited[node as usize] = true;
|
||||
|
||||
for &(f, t) in &self.edges {
|
||||
if f == node {
|
||||
if t == to {
|
||||
return true;
|
||||
}
|
||||
stack.push(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Check if node has incoming edges
|
||||
#[inline(always)]
|
||||
fn has_incoming(&self, node: u32) -> bool {
|
||||
self.edges.iter().any(|&(_, to)| to == node)
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute attention scores based on mechanism
|
||||
///
|
||||
/// Mechanisms:
|
||||
/// - 0: Topological (position in topo sort)
|
||||
/// - 1: Critical path (distance from critical path)
|
||||
/// - 2: Uniform (all equal)
|
||||
#[inline]
|
||||
fn compute_attention(dag: &WasmDag, mechanism: u8) -> Vec<f32> {
|
||||
let n = dag.nodes.len();
|
||||
|
||||
match mechanism {
|
||||
0 => {
|
||||
// Topological attention - earlier nodes get higher scores
|
||||
let topo = dag.topo_sort();
|
||||
let mut scores = vec![0.0f32; n];
|
||||
|
||||
for (i, &node_id) in topo.iter().enumerate() {
|
||||
scores[node_id as usize] = 1.0 - (i as f32 / n as f32);
|
||||
}
|
||||
|
||||
scores
|
||||
}
|
||||
|
||||
1 => {
|
||||
// Critical path attention - nodes on/near critical path get higher scores
|
||||
let topo = dag.topo_sort();
|
||||
let mut dist = vec![0.0f32; n];
|
||||
|
||||
// Forward pass - compute longest path to each node
|
||||
for &from in &topo {
|
||||
for &(f, to) in &dag.edges {
|
||||
if f == from {
|
||||
let new_dist = dist[from as usize] + dag.nodes[to as usize].cost;
|
||||
if new_dist > dist[to as usize] {
|
||||
dist[to as usize] = new_dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize to [0, 1]
|
||||
let max_dist = dist.iter().fold(0.0f32, |a, &b| a.max(b));
|
||||
if max_dist > 0.0 {
|
||||
dist.iter_mut().for_each(|d| *d /= max_dist);
|
||||
}
|
||||
|
||||
dist
|
||||
}
|
||||
|
||||
_ => {
|
||||
// Uniform attention
|
||||
vec![1.0f32 / n as f32; n]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_basic_dag() {
|
||||
let mut dag = WasmDag::new();
|
||||
|
||||
let n0 = dag.add_node(1, 1.0);
|
||||
let n1 = dag.add_node(2, 2.0);
|
||||
let n2 = dag.add_node(3, 3.0);
|
||||
|
||||
assert_eq!(dag.node_count(), 3);
|
||||
|
||||
assert!(dag.add_edge(n0, n1));
|
||||
assert!(dag.add_edge(n1, n2));
|
||||
assert_eq!(dag.edge_count(), 2);
|
||||
|
||||
// Should detect cycle
|
||||
assert!(!dag.add_edge(n2, n0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_topo_sort() {
|
||||
let mut dag = WasmDag::new();
|
||||
|
||||
let n0 = dag.add_node(0, 1.0);
|
||||
let n1 = dag.add_node(1, 1.0);
|
||||
let n2 = dag.add_node(2, 1.0);
|
||||
|
||||
dag.add_edge(n0, n1);
|
||||
dag.add_edge(n1, n2);
|
||||
|
||||
let topo = dag.topo_sort();
|
||||
assert_eq!(topo, vec![0, 1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_attention() {
|
||||
let mut dag = WasmDag::new();
|
||||
|
||||
dag.add_node(0, 1.0);
|
||||
dag.add_node(1, 2.0);
|
||||
dag.add_node(2, 3.0);
|
||||
|
||||
// Uniform
|
||||
let uniform = dag.attention(2);
|
||||
assert_eq!(uniform.len(), 3);
|
||||
assert!((uniform[0] - 0.333).abs() < 0.01);
|
||||
|
||||
// Topological
|
||||
let topo = dag.attention(0);
|
||||
assert_eq!(topo.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
let mut dag = WasmDag::new();
|
||||
|
||||
dag.add_node(1, 1.5);
|
||||
dag.add_node(2, 2.5);
|
||||
dag.add_edge(0, 1);
|
||||
|
||||
// Binary
|
||||
let bytes = dag.to_bytes();
|
||||
let restored = WasmDag::from_bytes(&bytes).unwrap();
|
||||
assert_eq!(restored.node_count(), 2);
|
||||
assert_eq!(restored.edge_count(), 1);
|
||||
|
||||
// JSON
|
||||
let json = dag.to_json();
|
||||
let from_json = WasmDag::from_json(&json).unwrap();
|
||||
assert_eq!(from_json.node_count(), 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,19 @@
|
|||
# RuVector DAG - Neural Self-Learning DAG
|
||||
|
||||
A high-performance neural DAG learning system for query optimization in RuVector.
|
||||
A production-grade neural DAG learning system for query optimization in RuVector. Not an optimizer—a control plane for learning systems.
|
||||
|
||||
## Features
|
||||
|
||||
- **7 DAG Attention Mechanisms**: Topological, Causal Cone, Critical Path, MinCut Gated, Hierarchical Lorentz, Parallel Branch, Temporal BTSP
|
||||
- **SONA Learning**: Self-Optimizing Neural Architecture with MicroLoRA adaptation
|
||||
- **Subpolynomial MinCut**: O(n^0.12) bottleneck detection
|
||||
- **Self-Healing**: Autonomous anomaly detection and repair
|
||||
- **QuDAG Integration**: Quantum-resistant distributed pattern learning
|
||||
- **SONA Learning**: Self-Optimizing Neural Architecture with MicroLoRA adaptation (<100μs)
|
||||
- **Subpolynomial MinCut**: O(n^0.12) bottleneck detection—the coherence boundary everything listens to
|
||||
- **Self-Healing**: Autonomous anomaly detection, reactive repair, and predictive intervention
|
||||
- **QuDAG Integration**: Quantum-resistant distributed pattern learning with bounded sync
|
||||
- **WASM Target**: 58KB gzipped for browser and embedded systems
|
||||
|
||||
## Design Philosophy
|
||||
|
||||
MinCut is not an optimization trick here. It is the coherence boundary that everything else listens to. Attention mechanisms, SONA learning, and self-healing all respond to MinCut stress signals—creating a unified nervous system for query optimization.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
|
@ -33,11 +38,11 @@ let scores = attention.forward(&dag).unwrap();
|
|||
## Modules
|
||||
|
||||
- `dag` - Core DAG data structures and algorithms
|
||||
- `attention` - 7 attention mechanisms for node importance scoring
|
||||
- `attention` - 7 attention mechanisms + policy-driven selection
|
||||
- `sona` - Self-Optimizing Neural Architecture with adaptive learning
|
||||
- `mincut` - Subpolynomial bottleneck detection and optimization
|
||||
- `healing` - Self-healing system with anomaly detection
|
||||
- `qudag` - QuDAG network integration for distributed learning
|
||||
- `mincut` - Subpolynomial bottleneck detection (the central control signal)
|
||||
- `healing` - Reactive + predictive self-healing
|
||||
- `qudag` - QuDAG network integration with bounded sync frequency
|
||||
|
||||
## Core Components
|
||||
|
||||
|
|
@ -54,96 +59,291 @@ let filter = dag.add_node(OperatorNode::filter(1, "age > 18"));
|
|||
dag.add_edge(scan, filter).unwrap();
|
||||
```
|
||||
|
||||
### Attention Mechanisms
|
||||
### Attention Mechanisms + Policy Layer
|
||||
|
||||
Seven different attention mechanisms to compute node importance:
|
||||
Seven attention mechanisms with dynamic policy-driven selection:
|
||||
|
||||
1. **Topological**: Position-based importance with depth decay
|
||||
2. **Causal Cone**: Focus on downstream dependencies
|
||||
3. **Critical Path**: Emphasize execution bottlenecks
|
||||
4. **MinCut Gated**: Flow-aware importance gating
|
||||
5. **Hierarchical Lorentz**: Hyperbolic geometry for hierarchies
|
||||
6. **Parallel Branch**: Multi-branch execution awareness
|
||||
7. **Temporal BTSP**: Temporal backward trajectory sampling
|
||||
| Mechanism | When to Use | Trigger |
|
||||
|-----------|-------------|---------|
|
||||
| Topological | Default baseline | Low variance |
|
||||
| Causal Cone | Downstream impact analysis | Write-heavy patterns |
|
||||
| Critical Path | Latency-bound queries | p99 > 2x p50 |
|
||||
| MinCut Gated | Bottleneck-aware weighting | Cut tension rising |
|
||||
| Hierarchical Lorentz | Deep hierarchical queries | Depth > 10 |
|
||||
| Parallel Branch | Wide parallel execution | Branch count > 3 |
|
||||
| Temporal BTSP | Time-series workloads | Temporal patterns |
|
||||
|
||||
```rust
|
||||
use ruvector_dag::attention::{TopologicalAttention, DagAttention};
|
||||
use ruvector_dag::attention::{AttentionSelector, SelectionPolicy};
|
||||
use ruvector_dag::mincut::DagMinCutEngine;
|
||||
|
||||
let attention = TopologicalAttention::new(Default::default());
|
||||
let scores = attention.forward(&dag)?;
|
||||
// Policy-driven attention selection based on MinCut stress
|
||||
let mut selector = AttentionSelector::new();
|
||||
let mut mincut = DagMinCutEngine::new(Default::default());
|
||||
|
||||
// Dynamic switching based on cut tension
|
||||
let analysis = mincut.analyze_bottlenecks(&dag)?;
|
||||
let policy = if analysis.max_tension > 0.7 {
|
||||
SelectionPolicy::MinCutGated // High stress: gate by flow
|
||||
} else if analysis.latency_variance > 2.0 {
|
||||
SelectionPolicy::CriticalPath // Variance: focus on bottlenecks
|
||||
} else {
|
||||
SelectionPolicy::Topological // Stable: use position-based
|
||||
};
|
||||
|
||||
let scores = selector.select_and_apply(policy, &dag)?;
|
||||
```
|
||||
|
||||
### SONA (Self-Optimizing Neural Architecture)
|
||||
|
||||
Adaptive learning engine that improves query optimization over time:
|
||||
Adaptive learning with explicit data structures. SONA runs post-query in background, never blocking execution.
|
||||
|
||||
**State Vector Structure:**
|
||||
```rust
|
||||
use ruvector_dag::sona::DagSonaEngine;
|
||||
/// SONA maintains per-DAG-pattern state vectors
|
||||
pub struct SonaState {
|
||||
/// Base embedding: pattern signature (256-dim)
|
||||
pub embedding: [f32; 256],
|
||||
|
||||
let mut sona = DagSonaEngine::new(256);
|
||||
/// MicroLoRA weights: scoped per operator type
|
||||
/// Shape: [num_operator_types, rank, rank] where rank=2
|
||||
pub lora_weights: HashMap<OperatorType, [[f32; 2]; 2]>,
|
||||
|
||||
// Pre-query: Get enhanced embedding
|
||||
let enhanced = sona.pre_query(&dag);
|
||||
/// Trajectory statistics for this pattern
|
||||
pub trajectory_stats: TrajectoryStats,
|
||||
}
|
||||
|
||||
// Execute query...
|
||||
|
||||
// Post-query: Record trajectory
|
||||
sona.post_query(&dag, execution_time, baseline_time, "topological");
|
||||
|
||||
// Background learning
|
||||
sona.background_learn();
|
||||
pub struct TrajectoryStats {
|
||||
pub count: u64,
|
||||
pub mean_improvement: f32, // vs baseline
|
||||
pub variance: f32,
|
||||
pub best_mechanism: AttentionType,
|
||||
}
|
||||
```
|
||||
|
||||
### MinCut Optimization
|
||||
```rust
|
||||
use ruvector_dag::sona::{DagSonaEngine, SonaConfig};
|
||||
|
||||
Subpolynomial bottleneck detection:
|
||||
let config = SonaConfig {
|
||||
embedding_dim: 256,
|
||||
lora_rank: 2, // Rank-2 for <100μs updates
|
||||
ewc_lambda: 5000.0, // Catastrophic forgetting prevention
|
||||
trajectory_capacity: 10_000,
|
||||
};
|
||||
let mut sona = DagSonaEngine::new(config);
|
||||
|
||||
// Pre-query: Get enhanced embedding (fast path)
|
||||
let enhanced = sona.pre_query(&dag);
|
||||
|
||||
// Execute query... (SONA doesn't block here)
|
||||
let execution_time = execute_query(&dag);
|
||||
|
||||
// Post-query: Record trajectory (async, background)
|
||||
sona.post_query(&dag, execution_time, baseline_time, "topological");
|
||||
|
||||
// Background learning (runs in separate thread)
|
||||
sona.background_learn(); // Updates LoRA weights, EWC consolidation
|
||||
```
|
||||
|
||||
### MinCut Optimization (Central Control Signal)
|
||||
|
||||
The MinCut engine is the coherence boundary. Rising cut tension triggers attention switching, SONA re-weighting, and predictive healing.
|
||||
|
||||
```rust
|
||||
use ruvector_dag::mincut::{DagMinCutEngine, MinCutConfig};
|
||||
|
||||
let mut engine = DagMinCutEngine::new(MinCutConfig::default());
|
||||
let mut engine = DagMinCutEngine::new(MinCutConfig {
|
||||
update_complexity: 0.12, // O(n^0.12) amortized
|
||||
tension_threshold: 0.7,
|
||||
emit_signals: true, // Broadcast to other subsystems
|
||||
});
|
||||
|
||||
let analysis = engine.analyze_bottlenecks(&dag)?;
|
||||
|
||||
// Tension signal drives the whole system
|
||||
if analysis.max_tension > 0.7 {
|
||||
// High tension: trigger predictive healing
|
||||
healing.predict_and_prepare(&analysis);
|
||||
|
||||
// Switch attention to MinCut-aware mechanism
|
||||
selector.force_mechanism(AttentionType::MinCutGated);
|
||||
|
||||
// Accelerate SONA learning for this pattern
|
||||
sona.boost_learning_rate(2.0);
|
||||
}
|
||||
|
||||
for bottleneck in &analysis.bottlenecks {
|
||||
println!("Bottleneck at nodes {:?}: capacity {}",
|
||||
bottleneck.cut_nodes, bottleneck.capacity);
|
||||
println!("Bottleneck at nodes {:?}: capacity {}, tension {}",
|
||||
bottleneck.cut_nodes, bottleneck.capacity, bottleneck.tension);
|
||||
}
|
||||
```
|
||||
|
||||
### Self-Healing
|
||||
### Self-Healing (Reactive + Predictive)
|
||||
|
||||
Autonomous anomaly detection and repair:
|
||||
Self-healing responds to anomalies (reactive) and rising MinCut tension (predictive).
|
||||
|
||||
```rust
|
||||
use ruvector_dag::healing::{HealingOrchestrator, AnomalyConfig};
|
||||
use ruvector_dag::healing::{HealingOrchestrator, AnomalyConfig, PredictiveConfig};
|
||||
|
||||
let mut orchestrator = HealingOrchestrator::new();
|
||||
|
||||
// Reactive: Z-score anomaly detection
|
||||
orchestrator.add_detector("query_latency", AnomalyConfig {
|
||||
z_threshold: 3.0,
|
||||
window_size: 100,
|
||||
min_samples: 10,
|
||||
});
|
||||
|
||||
// Predictive: Rising cut tension triggers early intervention
|
||||
orchestrator.enable_predictive(PredictiveConfig {
|
||||
tension_threshold: 0.6, // Intervene before 0.7 crisis
|
||||
variance_threshold: 1.5, // Rising variance = trouble coming
|
||||
lookahead_window: 50, // Predict 50 queries ahead
|
||||
});
|
||||
|
||||
// Observe metrics
|
||||
orchestrator.observe("query_latency", latency);
|
||||
orchestrator.observe_mincut(&mincut_analysis);
|
||||
|
||||
// Run healing cycle
|
||||
// Healing cycle: reactive + predictive
|
||||
let result = orchestrator.run_cycle();
|
||||
println!("Detected: {}, Repaired: {}",
|
||||
result.anomalies_detected, result.repairs_succeeded);
|
||||
println!("Reactive repairs: {}, Predictive interventions: {}",
|
||||
result.reactive_repairs, result.predictive_interventions);
|
||||
```
|
||||
|
||||
### External Cost Model Trait
|
||||
|
||||
Plug in cost models for PostgreSQL, embedded, or chip-level schedulers without forking logic.
|
||||
|
||||
```rust
|
||||
/// Trait for external cost estimation
|
||||
pub trait CostModel: Send + Sync {
|
||||
/// Estimate execution cost for an operator
|
||||
fn estimate_cost(&self, op: &OperatorNode, context: &CostContext) -> f64;
|
||||
|
||||
/// Estimate cardinality (row count) for an operator
|
||||
fn estimate_cardinality(&self, op: &OperatorNode, context: &CostContext) -> u64;
|
||||
|
||||
/// Platform-specific overhead factor
|
||||
fn platform_overhead(&self) -> f64 { 1.0 }
|
||||
}
|
||||
|
||||
/// PostgreSQL cost model (uses pg_catalog statistics)
|
||||
pub struct PostgresCostModel { /* ... */ }
|
||||
|
||||
/// Embedded systems cost model (memory-bound)
|
||||
pub struct EmbeddedCostModel {
|
||||
pub ram_kb: u32,
|
||||
pub flash_latency_ns: u32,
|
||||
}
|
||||
|
||||
/// Chip-level cost model (cycle-accurate)
|
||||
pub struct ChipCostModel {
|
||||
pub clock_mhz: u32,
|
||||
pub pipeline_depth: u8,
|
||||
pub cache_line_bytes: u8,
|
||||
}
|
||||
|
||||
// Plug into DAG analysis
|
||||
let mut dag = QueryDag::with_cost_model(Box::new(EmbeddedCostModel {
|
||||
ram_kb: 512,
|
||||
flash_latency_ns: 100,
|
||||
}));
|
||||
```
|
||||
|
||||
### QuDAG Integration (Bounded Sync)
|
||||
|
||||
Quantum-resistant distributed learning with explicit sync frequency bounds.
|
||||
|
||||
```rust
|
||||
use ruvector_dag::qudag::{QuDagClient, SyncConfig};
|
||||
|
||||
let client = QuDagClient::new(SyncConfig {
|
||||
// Sync frequency bounds (critical for distributed scale)
|
||||
min_sync_interval: Duration::from_secs(60), // At least 1 min apart
|
||||
max_sync_interval: Duration::from_secs(3600), // At most 1 hour
|
||||
adaptive_backoff: true, // Backoff under network pressure
|
||||
|
||||
// Batch settings
|
||||
max_patterns_per_sync: 100,
|
||||
pattern_age_threshold: Duration::from_secs(300), // 5 min maturity
|
||||
|
||||
// Privacy
|
||||
differential_privacy_epsilon: 0.1,
|
||||
noise_mechanism: NoiseMechanism::Laplace,
|
||||
});
|
||||
|
||||
// Sync only mature, validated patterns
|
||||
client.sync_patterns(
|
||||
sona.get_mature_patterns(),
|
||||
&crypto_identity,
|
||||
).await?;
|
||||
|
||||
// Receive network-learned patterns (also bounded)
|
||||
let network_patterns = client.receive_patterns().await?;
|
||||
sona.merge_network_patterns(network_patterns);
|
||||
```
|
||||
|
||||
## End-to-End Example: Query Convergence
|
||||
|
||||
A slow query converges over several runs. One file, no prose, just logs.
|
||||
|
||||
```text
|
||||
$ cargo run --example convergence_demo
|
||||
|
||||
[run 1] query: SELECT * FROM vectors WHERE embedding <-> $1 < 0.5
|
||||
dag: 4 nodes, 3 edges
|
||||
attention: topological (default)
|
||||
mincut_tension: 0.23
|
||||
latency: 847ms (baseline: 850ms, improvement: 0.4%)
|
||||
sona: recorded trajectory, pattern_id=0x7a3f
|
||||
|
||||
[run 2] same query, different params
|
||||
attention: topological
|
||||
mincut_tension: 0.31 (rising)
|
||||
latency: 812ms (improvement: 4.5%)
|
||||
sona: pattern match, applying lora_weights
|
||||
|
||||
[run 3]
|
||||
attention: topological
|
||||
mincut_tension: 0.58 (approaching threshold)
|
||||
latency: 623ms (improvement: 26.7%)
|
||||
sona: lora adaptation complete, ewc consolidating
|
||||
|
||||
[run 4]
|
||||
mincut_tension: 0.71 > 0.7 (THRESHOLD)
|
||||
--> switching attention: topological -> mincut_gated
|
||||
--> healing: predictive intervention queued
|
||||
attention: mincut_gated
|
||||
latency: 412ms (improvement: 51.5%)
|
||||
sona: boosting learning rate 2x for this pattern
|
||||
|
||||
[run 5]
|
||||
attention: mincut_gated (sticky after tension spike)
|
||||
mincut_tension: 0.45 (stabilizing)
|
||||
latency: 398ms (improvement: 53.2%)
|
||||
healing: predictive reindex completed in background
|
||||
|
||||
[run 10]
|
||||
attention: mincut_gated
|
||||
mincut_tension: 0.22 (stable)
|
||||
latency: 156ms (improvement: 81.6%)
|
||||
sona: pattern mature, queued for qudag sync
|
||||
|
||||
[qudag sync] pattern 0x7a3f synced to network
|
||||
peers learning from our optimization
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
The `examples/` directory contains comprehensive examples:
|
||||
The `examples/` directory contains:
|
||||
|
||||
- `basic_usage.rs` - DAG creation and basic operations
|
||||
- `attention_selection.rs` - Using different attention mechanisms
|
||||
- `learning_workflow.rs` - SONA learning workflow
|
||||
- `self_healing.rs` - Self-healing system demonstration
|
||||
- `attention_selection.rs` - Policy-driven attention switching
|
||||
- `learning_workflow.rs` - SONA learning with explicit state vectors
|
||||
- `self_healing.rs` - Reactive and predictive healing
|
||||
- `convergence_demo.rs` - End-to-end query convergence logs
|
||||
|
||||
Run examples with:
|
||||
```bash
|
||||
cargo run --example basic_usage
|
||||
cargo run --example attention_selection
|
||||
|
|
@ -151,65 +351,91 @@ cargo run --example learning_workflow
|
|||
cargo run --example self_healing
|
||||
```
|
||||
|
||||
## WASM Target
|
||||
|
||||
Minimal WASM build for browser and embedded systems.
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Raw size | 130 KB |
|
||||
| Gzipped | 58 KB |
|
||||
| API surface | 13 methods |
|
||||
|
||||
```bash
|
||||
# Build WASM
|
||||
wasm-pack build crates/ruvector-dag-wasm --target web --release
|
||||
|
||||
# With wee_alloc for even smaller size
|
||||
wasm-pack build crates/ruvector-dag-wasm --target web --release -- --features wee_alloc
|
||||
```
|
||||
|
||||
## Performance Targets
|
||||
|
||||
| Component | Target |
|
||||
|-----------|--------|
|
||||
| Attention (100 nodes) | <100μs |
|
||||
| MicroLoRA adaptation | <100μs |
|
||||
| Pattern search (10K) | <2ms |
|
||||
| MinCut update | O(n^0.12) |
|
||||
| Anomaly detection | <50μs |
|
||||
| Component | Target | Notes |
|
||||
|-----------|--------|-------|
|
||||
| Attention (100 nodes) | <100μs | All 7 mechanisms |
|
||||
| MicroLoRA adaptation | <100μs | Rank-2, per-operator |
|
||||
| Pattern search (10K) | <2ms | K-means++ indexing |
|
||||
| MinCut update | O(n^0.12) | Subpolynomial amortized |
|
||||
| Anomaly detection | <50μs | Z-score, streaming |
|
||||
| Predictive healing | <1ms | Tension-based lookahead |
|
||||
| QuDAG sync | Bounded | 1min-1hr adaptive |
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ Query DAG Layer │
|
||||
│ (Operators, Edges, Topological Sort) │
|
||||
└──────────────────┬──────────────────────────────┘
|
||||
│
|
||||
┌──────────┴──────────┐
|
||||
│ │
|
||||
┌───────▼─────────┐ ┌──────▼──────────┐
|
||||
│ Attention │ │ MinCut │
|
||||
│ Mechanisms │ │ Optimization │
|
||||
│ (7 types) │ │ (Bottlenecks) │
|
||||
└───────┬─────────┘ └──────┬──────────┘
|
||||
│ │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
┌──────────▼──────────┐
|
||||
│ SONA Engine │
|
||||
│ (Neural Learning) │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
┌──────────▼──────────┐
|
||||
│ Self-Healing │
|
||||
│ (Orchestrator) │
|
||||
└─────────────────────┘
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Query DAG Layer │
|
||||
│ (Operators, Edges, Topological Sort) │
|
||||
│ + External Cost Model Trait │
|
||||
└───────────────────────────┬─────────────────────────────────┘
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
┌──────────▼──────────┐ ┌─────────▼─────────┐
|
||||
│ Attention Layer │ │ MinCut Engine │
|
||||
│ (7 mechanisms) │◄────│ (Control Signal) │
|
||||
│ + Policy Selector │ │ O(n^0.12) │
|
||||
└──────────┬──────────┘ └─────────┬─────────┘
|
||||
│ │
|
||||
│ ┌─────────────────────┤
|
||||
│ │ │
|
||||
┌──────────▼────▼─────┐ ┌─────────▼─────────┐
|
||||
│ SONA Engine │ │ Self-Healing │
|
||||
│ (Post-Query Learn) │ │ (Reactive + Pred) │
|
||||
│ MicroLoRA + EWC │ │ Tension-Driven │
|
||||
└──────────┬──────────┘ └─────────┬─────────┘
|
||||
│ │
|
||||
└────────────┬────────────┘
|
||||
│
|
||||
┌────────────▼────────────┐
|
||||
│ QuDAG Sync Layer │
|
||||
│ (Bounded Frequency) │
|
||||
│ ML-KEM + Differential │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
cargo test
|
||||
cargo test -p ruvector-dag
|
||||
|
||||
# Run benchmarks
|
||||
cargo bench
|
||||
cargo bench -p ruvector-dag
|
||||
|
||||
# Check documentation
|
||||
cargo doc --open
|
||||
cargo doc -p ruvector-dag --open
|
||||
```
|
||||
|
||||
## Integration with RuVector
|
||||
|
||||
This crate is part of the RuVector ecosystem and integrates with:
|
||||
This crate is part of the RuVector ecosystem:
|
||||
|
||||
- `ruvector-core` - Core vector operations
|
||||
- `ruvector-qudag` - Quantum-resistant distributed learning
|
||||
- `ruvector-hooks` - Intelligence hooks for adaptive behavior
|
||||
- `ruvector-dag-wasm` - Browser/embedded WASM target (58KB gzipped)
|
||||
- `ruvector-postgres` - PostgreSQL extension with 50+ SQL functions
|
||||
- `ruvector-qudag` - Full QuDAG consensus client
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue