diff --git a/Cargo.lock b/Cargo.lock index a43261e..d504e2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" @@ -52,22 +43,13 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] -[[package]] -name = "aligned" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" -dependencies = [ - "as-slice", -] - [[package]] name = "aligned-vec" version = "0.6.4" @@ -79,9 +61,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.21" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "android_system_properties" @@ -94,9 +76,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -109,44 +91,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.11" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.101" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "approx" @@ -159,9 +140,12 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.4.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "arg_enum_proc_macro" @@ -171,42 +155,15 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] -[[package]] -name = "arimaa_engine_step" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c6726d7896a539a62e157b05fa4b7308ffb7872f2b4a2a592d5adb19837861" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "log", - "regex", -] - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "as-slice" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "ash" version = "0.38.0+1.3.281" @@ -218,9 +175,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.5.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", "event-listener-strategy", @@ -228,12 +185,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "atomic_float" version = "1.1.0" @@ -242,121 +193,31 @@ checksum = "628d228f918ac3b82fe590352cc719d30664a0c13ca3a60266fe02c7132d480a" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "av-scenechange" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394" -dependencies = [ - "aligned", - "anyhow", - "arg_enum_proc_macro", - "arrayvec 0.7.6", - "log", - "num-rational", - "num-traits", - "pastey", - "rayon", - "thiserror 2.0.18", - "v_frame", - "y4m", -] +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "av1-grain" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" +checksum = "4f3efb2ca85bc610acfa917b5aaa36f3fcbebed5b3182d7f877b02531c4b80c8" dependencies = [ "anyhow", - "arrayvec 0.7.6", + "arrayvec", "log", - "nom 8.0.0", + "nom", "num-rational", "v_frame", ] [[package]] name = "avif-serialize" -version = "0.8.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f" +checksum = "98922d6a4cfbcb08820c69d8eeccc05bb1f29bfa06b4f5b1dbfe9a868bd7608e" dependencies = [ - "arrayvec 0.7.6", -] - -[[package]] -name = "axum" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" -dependencies = [ - "axum-core", - "base64 0.22.1", - "bytes", - "form_urlencoded", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "serde_core", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sha1", - "sync_wrapper", - "tokio", - "tokio-tungstenite", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "axum-core" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "sync_wrapper", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link 0.2.1", + "arrayvec", ] [[package]] @@ -373,9 +234,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bincode" @@ -396,26 +257,6 @@ dependencies = [ "unty", ] -[[package]] -name = "bindgen" -version = "0.71.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 2.1.1", - "shlex", - "syn 2.0.114", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -433,9 +274,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bit_field" -version = "0.10.3" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" [[package]] name = "bitflags" @@ -445,21 +286,18 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ - "serde_core", + "serde", ] [[package]] name = "bitstream-io" -version = "4.9.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757" -dependencies = [ - "core2", -] +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" [[package]] name = "block" @@ -477,33 +315,25 @@ dependencies = [ ] [[package]] -name = "board-game" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647fc8459363368aae04df3d21da37094430c57dd993d09be2792133d5365e3e" +name = "bot" +version = "0.1.0" dependencies = [ - "arimaa_engine_step", - "cast_trait", - "chess", - "decorum", - "internal-iterator", - "itertools 0.10.5", - "lazy_static", - "nohash-hasher", - "nom 7.1.3", - "num-traits", - "once_cell", + "burn", + "burn-rl", + "env_logger 0.10.0", + "log", + "pretty_assertions", "rand 0.8.5", - "rand_xoshiro", - "rayon", - "static_assertions", + "serde", + "serde_json", + "store", ] [[package]] name = "bstr" -version = "1.12.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "regex-automata", @@ -512,35 +342,29 @@ dependencies = [ [[package]] name = "built" -version = "0.8.0" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" +checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" [[package]] name = "burn" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b78ff10ed98b73e1d477ea6e6e1ec1b9cf9f71a17afc3fea9f4dca482d43dcd4" +checksum = "ec639306f45bd663957465e840cfb07bcd2ae18f7c045dd9aba8cb7a69c0654a" dependencies = [ "burn-autodiff", "burn-candle", - "burn-collective", "burn-core", - "burn-cpu", "burn-cuda", "burn-ndarray", - "burn-nn", - "burn-optim", - "burn-remote", "burn-rocm", "burn-router", - "burn-store", "burn-tch", "burn-train", "burn-wgpu", @@ -548,331 +372,225 @@ dependencies = [ [[package]] name = "burn-autodiff" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f04955e9b4acd5e6a6229f80217dae79742975a97dc2253003f226333ad307" +checksum = "a178966322ab7ce71405f1324cdc14f79256d85a47138bbd2c8c4f0056148601" dependencies = [ - "burn-backend", - "burn-std", - "derive-new", - "hashbrown 0.16.1", + "burn-common", + "burn-tensor", + "derive-new 0.7.0", + "hashbrown 0.15.4", "log", "num-traits", - "parking_lot", "portable-atomic", - "spin", - "tracing", -] - -[[package]] -name = "burn-backend" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a724a5d8d5865a1f6b304f629eb19f51489760689501c583b3e1f4209f067357" -dependencies = [ - "burn-std", - "bytemuck", - "cubecl", - "derive-new", - "hashbrown 0.16.1", - "num-traits", - "rand 0.9.2", - "rand_distr", - "serde", - "thiserror 2.0.18", + "spin 0.10.0", ] [[package]] name = "burn-candle" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21c752d5008923eb9299783da5edae3242b94afdb956e88d2b37b025244b5071" +checksum = "9ed0981b3c1d07e9df0f5bef1042921b6db6e88b5d91916fa5dbdd7f0ca921c3" dependencies = [ - "burn-backend", - "burn-std", + "burn-tensor", "candle-core", - "derive-new", + "derive-new 0.7.0", + "half", ] [[package]] -name = "burn-collective" -version = "0.20.1" +name = "burn-common" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5b2199984291a0f3828d5ac04039fb864c56c3bdd9ee4172a63e457b668e4c" +checksum = "1c3fae76798ea4dd14e6290b6753eb6235ac28c6ceaf6da35ff8396775d5494d" dependencies = [ - "burn-communication", - "burn-std", - "burn-tensor", - "bytes", - "futures", - "log", - "rmp-serde", + "cubecl-common", + "rayon", "serde", - "tokio", - "tokio-util", -] - -[[package]] -name = "burn-communication" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585526cd672adc35918d8aea9bcb50669067904f36090caaffa9573d22fc7ade" -dependencies = [ - "axum", - "burn-std", - "burn-tensor", - "bytes", - "derive-new", - "futures", - "futures-util", - "log", - "rmp-serde", - "serde", - "serde_bytes", - "tokio", - "tokio-tungstenite", - "tokio-util", - "tracing", - "tracing-core", - "tracing-subscriber", ] [[package]] name = "burn-core" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3634c3ba84397bcf2977ce746954d7e0a40e2d862e92362dd694c29e18df62" +checksum = "2afa81c868c1a9b3fad25c31176945d0cc5181ba7b77c0456bc05cf57fca975c" dependencies = [ "ahash", "bincode 2.0.1", + "burn-common", "burn-dataset", "burn-derive", - "burn-std", "burn-tensor", "data-encoding", - "derive-new", + "derive-new 0.7.0", "flate2", "half", - "hashbrown 0.16.1", + "hashbrown 0.15.4", "log", "num-traits", - "portable-atomic", "portable-atomic-util", - "rand 0.9.2", - "regex", + "rand 0.9.1", "rmp-serde", "serde", "serde_json", - "spin", + "spin 0.10.0", "uuid", ] -[[package]] -name = "burn-cpu" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60aa53c4536719f1c91c250d4b4348daca473c44cf0c45b81096785f5510c192" -dependencies = [ - "burn-backend", - "burn-cubecl", - "burn-fusion", - "cubecl", -] - [[package]] name = "burn-cubecl" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6d13aff03fec966da4300459688883f8a1d741dddbf19d1bfc2562656a9a9b" +checksum = "c547cbe414274ab4022abcc85993e1e41aa7cdccc92395ba5658acfdac285e07" dependencies = [ - "burn-backend", + "burn-common", "burn-cubecl-fusion", "burn-fusion", "burn-ir", - "burn-std", + "burn-tensor", + "bytemuck", "cubecl", - "cubek", - "derive-new", + "cubecl-std", + "derive-new 0.7.0", "futures-lite", + "half", + "hashbrown 0.15.4", "log", + "num-traits", + "rand 0.9.1", "serde", + "spin 0.10.0", "text_placeholder", ] [[package]] name = "burn-cubecl-fusion" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d25b2e9fb805931401f79782aabd92462d65e60bc207035a3e554de8d7cd9f" +checksum = "c98a5cf4d17f2db71f68c44bda21bb85fe8fe06166ea83fdd2eaff557da7fc86" dependencies = [ - "burn-backend", + "burn-common", "burn-fusion", "burn-ir", - "burn-std", + "burn-tensor", "cubecl", - "cubek", - "derive-new", + "derive-new 0.7.0", + "half", "serde", ] [[package]] name = "burn-cuda" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0c68cf653eb9c27dcbe046bb7b04cc18c6b33afda4c09317c102e6f4ae7cb6" +checksum = "995bd0b3f52a4cfe0cfe47c16b40b3fd33285d17a086dd583e5b432074857e02" dependencies = [ - "burn-backend", "burn-cubecl", "burn-fusion", + "burn-tensor", + "bytemuck", "cubecl", + "derive-new 0.7.0", + "half", + "log", ] [[package]] name = "burn-dataset" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e87741e2ff9015845ed2b41b47f9e82795cf274bf2328a29619a2e6f662495c" +checksum = "136c784dfc474c822f34d69e865f88a5675e9de9803ef38cee4ce14cdba34d54" dependencies = [ "csv", - "derive-new", - "dirs", + "derive-new 0.7.0", + "dirs 6.0.0", "gix-tempfile", "image", "r2d2", "r2d2_sqlite", - "rand 0.9.2", + "rand 0.9.1", "rmp-serde", "rusqlite", - "sanitize-filename", + "sanitize-filename 0.6.0", "serde", "serde_json", "serde_rusqlite", - "strum 0.27.2", + "strum 0.27.1", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.12", ] [[package]] name = "burn-derive" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102d7e2f705b0cda2f89dd0e55e9bbfc6184029929d53487beb606c3303b29a5" +checksum = "12e9f07ccc658ef072bce2e996f0c38c80ee4c241598b6557afe1877dd87ae98" dependencies = [ - "derive-new", + "derive-new 0.7.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "burn-fusion" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea83d7f8574bcc07967291c5bb679ddc0a655c8db0642eca62755e2fffc8047" +checksum = "f9ed8e016795ec066c1028fc0d395a00bd5459922b4fa0eeae839b4d4ec58c45" dependencies = [ - "burn-backend", + "burn-common", "burn-ir", - "derive-new", - "hashbrown 0.16.1", + "burn-tensor", + "derive-new 0.7.0", + "half", + "hashbrown 0.15.4", "log", "serde", - "spin", - "tracing", + "spin 0.10.0", ] [[package]] name = "burn-ir" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd2b1b37a7289bd85438800deaaebde50507336429b80f96a71730794db5bc31" +checksum = "d63629f2c8b82ee52dbb9c18becded5117c2faf57365dc271a55c16d139cd91a" dependencies = [ - "burn-backend", - "hashbrown 0.16.1", + "burn-tensor", + "hashbrown 0.15.4", + "portable-atomic-util", "serde", ] [[package]] name = "burn-ndarray" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96be578991cecef163e41a73bf985d8d7eb7fb8ef7bececf8d48523c481ecddf" +checksum = "7e883846578e6915e1dbaeeb5bce32cc04cff03e7cb79c5836e1e888bbce974f" dependencies = [ "atomic_float", "burn-autodiff", - "burn-backend", + "burn-common", "burn-ir", - "burn-std", + "burn-tensor", "bytemuck", - "const-random", + "derive-new 0.7.0", "itertools 0.14.0", "libm", "macerator", "matrixmultiply", - "ndarray 0.17.2", + "ndarray", "num-traits", "paste", - "portable-atomic", "portable-atomic-util", - "rand 0.9.2", - "rayon", + "rand 0.9.1", "seq-macro", -] - -[[package]] -name = "burn-nn" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b8c6c14b94e5b1dddd68f8e6d669f20bac8f99fcb2e4f1a480212d1b598133" -dependencies = [ - "burn-core", - "num-traits", -] - -[[package]] -name = "burn-optim" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a8c376d835d92ea363c05c6f48ac19bb687b683c7958c310a716ef8d5d77ba3" -dependencies = [ - "burn-core", - "derive-new", - "hashbrown 0.16.1", - "log", - "num-traits", - "serde", -] - -[[package]] -name = "burn-remote" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7238df1d59dcbb6880fe92ca0aa7b02b64d02394815e618da3d7933950bdaf39" -dependencies = [ - "async-channel", - "axum", - "burn-communication", - "burn-ir", - "burn-router", - "burn-std", - "burn-tensor", - "bytes", - "derive-new", - "futures-util", - "log", - "rmp-serde", - "serde", - "serde_bytes", - "tokio", - "tokio-tungstenite", - "tokio-util", - "tracing-core", - "tracing-subscriber", + "spin 0.10.0", ] [[package]] name = "burn-rl" version = "0.1.0" -source = "git+https://github.com/yunjhongwu/burn-rl-examples.git#bf76ba61fdc89837cbf259a6f554a1fcec238690" +source = "git+https://github.com/yunjhongwu/burn-rl-examples.git#4d59261f26429f9df16dabd2b183f7fccd27ff9a" dependencies = [ "burn", "gym-rs", @@ -883,72 +601,43 @@ dependencies = [ [[package]] name = "burn-rocm" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e2abda6ee63bdcb730f1a335349a9ff83f03048130d405b6ecdccd2df3ff23" +checksum = "bd39d58202558b65b575921b57bff933845e6171296e2b8faf6a9d3610a344c5" dependencies = [ - "burn-backend", "burn-cubecl", "burn-fusion", + "burn-tensor", + "bytemuck", "cubecl", + "derive-new 0.7.0", + "half", + "log", ] [[package]] name = "burn-router" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "823ccb88484736a2861d53dc7f67db375ef050b0446bb02dd7cb8783ac6b69a2" +checksum = "22ed8614e180f7a58f77e658bd52e206d2f4a1ee37fcb4665c635ea9da90ea8b" dependencies = [ - "burn-backend", + "burn-common", "burn-ir", - "burn-std", - "hashbrown 0.16.1", - "log", - "spin", -] - -[[package]] -name = "burn-std" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a9ed8e34a4a49d3754586f306075d6b55a5e08343ac75c06f47e7d9f825271" -dependencies = [ - "bytemuck", - "bytes", - "cubecl", - "cubecl-common", - "half", - "num-traits", - "serde", -] - -[[package]] -name = "burn-store" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be80a7b084a19901dc1d0a2e9b77e226c5c575879fe66de891c67062db41a6d" -dependencies = [ - "burn-core", - "burn-nn", "burn-tensor", - "byteorder", - "bytes", - "half", - "hashbrown 0.16.1", - "memmap2", - "regex", - "safetensors 0.7.0", - "textdistance", + "hashbrown 0.15.4", + "log", + "spin 0.10.0", ] [[package]] name = "burn-tch" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061cd3df7b4126949561185454b9b67623f6885657361cad2a07a2340b3b3108" +checksum = "cacd39695f87086360a6457fa912062b2bbc04deacb281361539cf1bf6dcfac5" dependencies = [ - "burn-backend", + "burn-tensor", "cc", + "half", "libc", "log", "tch", @@ -957,37 +646,41 @@ dependencies = [ [[package]] name = "burn-tensor" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3720e52e00ed0155ced4f8681d0e8a362e699cee36494ec5b97ad44fcc5194c0" +checksum = "2a70d1562c0d00083939e34daad61dabebb0f8bc8c250d1ef2f5efc31eb93aaf" dependencies = [ - "burn-backend", - "burn-std", + "burn-common", + "bytemuck", "colored", - "derive-new", + "cubecl", + "derive-new 0.7.0", + "half", + "hashbrown 0.15.4", "num-traits", + "rand 0.9.1", + "rand_distr", "serde", + "serde_bytes", ] [[package]] name = "burn-train" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c3128c7571992c382a5ad057c72654c1048ea4dcf138d1f394313047e69803a" +checksum = "140182cf5f1255d60e1d8c677fa45c6f71018c3c3c66aad093a9e4c3c222cf1c" dependencies = [ "async-channel", "burn-core", "burn-ndarray", - "burn-optim", - "derive-new", + "derive-new 0.7.0", "log", "nvml-wrapper", - "ratatui", + "ratatui 0.29.0", "rstest", "serde", - "sysinfo 0.37.2", + "sysinfo", "systemstat", - "thiserror 2.0.18", "tracing-appender", "tracing-core", "tracing-subscriber", @@ -995,34 +688,34 @@ dependencies = [ [[package]] name = "burn-wgpu" -version = "0.20.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df78d62afc9b9fbb8ee4e49b72006485bb64f778a790e185a2d919479bcfc008" +checksum = "215bf0e641a27e17bcd3941a11867dcda411c9cb009488c6b6650c8206437c30" dependencies = [ - "burn-backend", "burn-cubecl", "burn-fusion", + "burn-tensor", "cubecl", ] [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -1039,12 +732,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" -dependencies = [ - "portable-atomic", -] +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "bytesize" @@ -1080,34 +770,24 @@ checksum = "fdd7a427adc0135366d99db65b36dae9237130997e560ed61118041fb72be6e8" [[package]] name = "candle-core" -version = "0.9.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15b675b80d994b2eadb20a4bbe434eabeb454eac3ee5e2b4cf6f147ee9be091" +checksum = "06ccf5ee3532e66868516d9b315f73aec9f34ea1a37ae98514534d458915dbf1" dependencies = [ "byteorder", - "float8 0.6.1", - "gemm", + "gemm 0.17.1", "half", - "libm", "memmap2", "num-traits", "num_cpus", - "rand 0.9.2", + "rand 0.9.1", "rand_distr", "rayon", - "safetensors 0.7.0", - "thiserror 2.0.18", + "safetensors 0.4.5", + "thiserror 1.0.69", + "ug", "yoke", - "zip 7.4.0", -] - -[[package]] -name = "caseless" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6fd507454086c8edfd769ca6ada439193cdb209c7681712ef6275cccbfe5d8" -dependencies = [ - "unicode-normalization", + "zip 1.1.4", ] [[package]] @@ -1116,47 +796,41 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" -[[package]] -name = "cast_trait" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f8d981c476baadf74cd52897866a1d279d3e14e2d5e2d9af045210e0ae6128" - [[package]] name = "castaway" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" dependencies = [ "rustversion", ] [[package]] name = "cc" -version = "1.2.55" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ - "find-msvc-tools", "jobserver", "libc", "shlex", ] [[package]] -name = "cexpr" -version = "0.6.0" +name = "cfg-expr" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ - "nom 7.1.3", + "smallvec", + "target-lexicon", ] [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" @@ -1188,18 +862,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "chess" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ed299b171ec34f372945ad6726f7bc1d2afd5f59fb8380f64f48e2bab2f0ec8" -dependencies = [ - "arrayvec 0.5.2", - "failure", - "nodrop", - "rand 0.7.3", -] - [[package]] name = "cipher" version = "0.4.4" @@ -1212,47 +874,37 @@ dependencies = [ ] [[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +name = "client_cli" +version = "0.1.0" dependencies = [ - "glob", - "libc", - "libloading", + "anyhow", + "bincode 1.3.3", + "bot", + "env_logger 0.11.6", + "itertools 0.13.0", + "log", + "pico-args", + "pretty_assertions", + "renet", + "store", ] [[package]] -name = "clap" -version = "4.5.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +name = "client_tui" +version = "0.1.0" dependencies = [ - "clap_builder", + "anyhow", + "bincode 1.3.3", + "crossterm", + "ratatui 0.28.1", + "store", ] -[[package]] -name = "clap_builder" -version = "4.5.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" -dependencies = [ - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_lex" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" - [[package]] name = "cmake" -version = "0.1.57" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] @@ -1265,18 +917,7 @@ checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ "serde", "termcolor", - "unicode-width 0.2.0", -] - -[[package]] -name = "codespan-reporting" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" -dependencies = [ - "serde", - "termcolor", - "unicode-width 0.2.0", + "unicode-width 0.1.14", ] [[package]] @@ -1287,24 +928,24 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" -version = "3.1.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] name = "compact_str" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" dependencies = [ "castaway", "cfg-if", @@ -1314,20 +955,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "comrak" -version = "0.39.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fefab951771fc3beeed0773ce66a4f7b706273fc6c4c95b08dd1615744abcf5" -dependencies = [ - "caseless", - "entities", - "memchr", - "slug", - "typed-arena", - "unicode_categories", -] - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -1337,73 +964,17 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "confy" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29222b549d4e3ded127989d523da9e928918d0d0d7f7c1690b439d0d538bae9" -dependencies = [ - "directories", - "serde", - "thiserror 2.0.18", - "toml 0.8.23", -] - -[[package]] -name = "const-random" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" -dependencies = [ - "const-random-macro", -] - -[[package]] -name = "const-random-macro" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" -dependencies = [ - "getrandom 0.2.17", - "once_cell", - "tiny-keccak", -] - [[package]] name = "constant_time_eq" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "constcat" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d3e02915a2cea4d74caa8681e2d44b1c3254bdbf17d11d41d587ff858832c" - -[[package]] -name = "convert_case" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "convert_case" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "core-foundation" -version = "0.10.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -1417,48 +988,33 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-graphics-types" -version = "0.2.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ - "bitflags 2.10.0", + "bitflags 1.3.2", "core-foundation", "libc", ] -[[package]] -name = "core2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" -dependencies = [ - "memchr", -] - [[package]] name = "cpufeatures" -version = "0.2.17" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] -[[package]] -name = "critical-section" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -1499,12 +1055,12 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "crossterm_winapi", "mio", "parking_lot", - "rustix 0.38.44", - "signal-hook 0.3.18", + "rustix 0.38.37", + "signal-hook", "signal-hook-mio", "winapi", ] @@ -1520,15 +1076,15 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -1537,36 +1093,36 @@ dependencies = [ [[package]] name = "csv" -version = "1.4.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", "ryu", - "serde_core", + "serde", ] [[package]] name = "csv-core" -version = "0.1.13" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" dependencies = [ "memchr", ] [[package]] name = "cubecl" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053856efd5436224775b9423d43d86f53d5b1d3af9a6b9983d9a313a0922638f" +checksum = "b1e438056cf7c25b3adde38240b89842e1c924b8e914731c82ad81161d23e6ff" dependencies = [ "cubecl-core", - "cubecl-cpu", "cubecl-cuda", "cubecl-hip", - "cubecl-ir", + "cubecl-linalg", + "cubecl-reduce", "cubecl-runtime", "cubecl-std", "cubecl-wgpu", @@ -1575,132 +1131,90 @@ dependencies = [ [[package]] name = "cubecl-common" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60bf8aaeb572c8cf2f2ffd07fa9bb1a2cf9336d1aa11ecd4d9a2f2e30c4be706" +checksum = "79251bfc7f067ac9038232fe38a317adc2f31cb2fc3800e69fd409ccac7abc1f" dependencies = [ - "backtrace", "bytemuck", - "bytes", - "cfg-if", - "cfg_aliases", - "derive-new", + "derive-new 0.6.0", "derive_more", - "dirs", + "dirs 5.0.1", "embassy-futures", - "embassy-time", - "float4", - "float8 0.4.2", "futures-lite", "half", - "hashbrown 0.15.5", + "hashbrown 0.14.5", "log", "num-traits", - "parking_lot", "portable-atomic", - "portable-atomic-util", - "rand 0.9.2", - "sanitize-filename", + "rand 0.9.1", + "sanitize-filename 0.5.0", "serde", - "serde_bytes", "serde_json", - "spin", - "tracing", - "wasm-bindgen-futures", - "web-time", + "spin 0.9.8", ] [[package]] name = "cubecl-core" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98374a31d2b68b55709891169832ccf205408c201c5e023964482441f213d0b9" +checksum = "b03bf4211cdbd68bb0fb8291e0ed825c13da0d1ac01b7c02dce3cee44a6138be" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "bytemuck", "cubecl-common", "cubecl-ir", "cubecl-macros", "cubecl-runtime", - "derive-new", + "derive-new 0.6.0", "derive_more", - "enumset", - "float-ord", "half", - "hashbrown 0.15.5", + "hashbrown 0.14.5", "log", "num-traits", "paste", "serde", "serde_json", - "tracing", "variadics_please", ] [[package]] name = "cubecl-cpp" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb24d96c1ff84ab4def0a529e384311a15cb771310aaf2b640c312384c3bca23" +checksum = "a5eef85cbcc34be7e25fc9d39edf99ed68559862dbf25c1877ebdf4a9595d31b" dependencies = [ "bytemuck", "cubecl-common", "cubecl-core", - "cubecl-opt", "cubecl-runtime", - "derive-new", - "half", - "itertools 0.14.0", - "log", -] - -[[package]] -name = "cubecl-cpu" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "152588a6e16b6bda5e8216af7a6fad3d7de4697294b6ce0f6acbe3a9029ff674" -dependencies = [ - "bytemuck", - "cubecl-common", - "cubecl-core", - "cubecl-opt", - "cubecl-runtime", - "cubecl-std", - "derive-new", + "derive-new 0.6.0", "half", "log", - "paste", - "serde", - "sysinfo 0.36.1", - "tracel-llvm", - "tracel-llvm-bundler", ] [[package]] name = "cubecl-cuda" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f74a5750c45090d1fc5ddf6a19fea9a099aa1f6800b78f1167a2d60182d1d96" +checksum = "71e091e4e3a3900faff440aec4053805ec4456f94f4acc4afe8e6b27519c6d16" dependencies = [ "bytemuck", "cubecl-common", "cubecl-core", "cubecl-cpp", "cubecl-runtime", - "cubecl-zspace", "cudarc", - "derive-new", + "derive-new 0.6.0", "half", "log", "serde", - "tracing", ] [[package]] name = "cubecl-hip" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbae9bc7ee6093d0d7a549c05873dff3478f9087b59eb09b223a97d642c849aa" +checksum = "0c2f8c00207517de61cccdc4ca2724bc1db9dab94840beaf4329e43cead3bc4a" dependencies = [ "bytemuck", "cubecl-common", @@ -1708,40 +1222,34 @@ dependencies = [ "cubecl-cpp", "cubecl-hip-sys", "cubecl-runtime", - "cubecl-zspace", - "derive-new", + "derive-new 0.6.0", "half", "log", "paste", - "serde", - "tracing", ] [[package]] name = "cubecl-hip-sys" -version = "7.0.5183101" +version = "6.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ef087b59445fda47d2177370886351eb923ad1a541086d4919268574cd9558" +checksum = "9f7557762176858fa0357504025f09ae6e979c3547776ff8b6a1025ef0702450" dependencies = [ "libc", - "regex", ] [[package]] name = "cubecl-ir" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361b608ff9f05024c7a7e381852689acd95b6af5af956d68734692b27d5f75ef" +checksum = "e096d77646590f0180ed4ce1aa7df4ecc7219f3c4616e9fe72d93ab63a352855" dependencies = [ "cubecl-common", "cubecl-macros-internal", - "derive-new", "derive_more", - "enumset", "float-ord", "fnv", "half", - "hashbrown 0.15.5", + "hashbrown 0.14.5", "num-traits", "portable-atomic", "serde", @@ -1749,56 +1257,67 @@ dependencies = [ ] [[package]] -name = "cubecl-macros" -version = "0.9.0" +name = "cubecl-linalg" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9a872d16207c6a27ed45942fd311a281394dd384b14a21f72131db1556a977" +checksum = "75aacf86f6004c274e63589aed55c5edcbcdf1b292eaf4ce2c1688c04c41a194" +dependencies = [ + "bytemuck", + "cubecl-common", + "cubecl-core", + "cubecl-reduce", + "cubecl-runtime", + "cubecl-std", + "half", + "serde", +] + +[[package]] +name = "cubecl-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd74622b5c8cb161e3f7fa0b2b751784ef89ab45acfa355f511eb2219dde337e" dependencies = [ "cubecl-common", - "darling 0.21.3", - "derive-new", + "darling", + "derive-new 0.6.0", "ident_case", "prettyplease", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "cubecl-macros-internal" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa3fa0626cdf28b9c49084c2bb51493bfde44378e22d90624aacaafb81da3588" +checksum = "6a89898212c1eaba0e2f0dffcadc9790b20b75d2ec8836da084370b043be2623" dependencies = [ - "darling 0.21.3", + "darling", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] -name = "cubecl-opt" -version = "0.9.0" +name = "cubecl-reduce" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdcff25fdcbd82ea4277c30a81e162722859f57c6ae105c0a3c53f8bb91154f6" +checksum = "7afbdfe03e7e3ca71f61890ebebc6b4390494204b545e6f6bf51a43755449073" dependencies = [ - "cubecl-common", "cubecl-core", - "cubecl-ir", - "float-ord", - "log", - "num", - "petgraph", - "smallvec", - "stable-vec", - "type-map", + "cubecl-runtime", + "cubecl-std", + "num-traits", + "serde", ] [[package]] name = "cubecl-runtime" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b02e28997a8d75311afae4d2cea7b593eb125312f845874118a59d78c7a6b34c" +checksum = "385234520c9e392382737f32ad372b05f345656eb798ba00b72d2722c68b698c" dependencies = [ "async-channel", "bytemuck", @@ -1806,48 +1325,34 @@ dependencies = [ "cfg_aliases", "cubecl-common", "cubecl-ir", - "derive-new", - "derive_more", - "dirs", - "enumset", - "foldhash 0.1.5", - "hashbrown 0.15.5", + "derive-new 0.6.0", + "hashbrown 0.14.5", "log", "md5", "serde", "serde_json", - "spin", - "thiserror 2.0.18", - "toml 0.9.11+spec-1.1.0", - "tracing", + "spin 0.9.8", "variadics_please", "wasm-bindgen-futures", - "web-time", ] [[package]] name = "cubecl-std" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ff5741c98b7a7a5944b4afb0b67dd7f5e0be41ce7f303b587f8b0d6430b29b" +checksum = "38868eea6fdc183feb3c46bcf5e666c78e6cf0ddca2c4f3a877785cc0eabd71e" dependencies = [ - "cubecl-common", "cubecl-core", "cubecl-runtime", - "foldhash 0.1.5", "half", - "num-traits", - "paste", "serde", - "spin", - "variadics_please", ] [[package]] name = "cubecl-wgpu" -version = "0.9.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29787364632fc7ec6a11cf3d95187f82f6fcce17d6bb4f0fb0dde580b837631d" +checksum = "77fa2dcfaa6d75cfbc5ff05cafe99ec4a7fb7c0fa7197917e0fd20f5b90979fe" dependencies = [ "async-channel", "bytemuck", @@ -1855,221 +1360,32 @@ dependencies = [ "cfg_aliases", "cubecl-common", "cubecl-core", - "cubecl-ir", "cubecl-runtime", - "derive-new", + "derive-new 0.6.0", "derive_more", - "half", - "hashbrown 0.15.5", + "hashbrown 0.14.5", "log", - "sanitize-filename", - "tracing", + "web-time", "wgpu", ] -[[package]] -name = "cubecl-zspace" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0f819071413b19a00b7105497e0f6d2cf3e7e9d65cbb8d4ecf1ddb29c61dc2" - -[[package]] -name = "cubek" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb1cce47db02017925301bedec92ae84628493df3f9761ea7ac42a60c6146f8" -dependencies = [ - "cubecl", - "cubek-attention", - "cubek-convolution", - "cubek-matmul", - "cubek-quant", - "cubek-random", - "cubek-reduce", -] - -[[package]] -name = "cubek-attention" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7278bd122b2428af479f9af05285160613733c33c93b63ab3c6d25cd0460c18b" -dependencies = [ - "bytemuck", - "cubecl", - "cubecl-common", - "cubek-matmul", - "cubek-random", - "half", - "serde", -] - -[[package]] -name = "cubek-convolution" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18eb04bca4ae104d62a56def04b04f3d079c42fe49aac62202c96876f90fa28b" -dependencies = [ - "bytemuck", - "cubecl", - "cubecl-common", - "cubek-matmul", - "derive-new", - "enumset", - "half", - "serde", -] - -[[package]] -name = "cubek-matmul" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28f3b04b113760e97c65a8a4dca9afc220744031eeecd5ad6cd0e3be91ba3a9" -dependencies = [ - "bytemuck", - "cubecl", - "cubecl-common", - "half", - "serde", -] - -[[package]] -name = "cubek-quant" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ec3ae04af324df2d615c2b394e270d58d6f08cb833d67633e2ba794de75916" -dependencies = [ - "cubecl", - "cubecl-common", - "half", - "serde", -] - -[[package]] -name = "cubek-random" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65a34844d8b7f739185c1d24896137dcb73f458830444103b45f678585ad983e" -dependencies = [ - "cubecl", - "cubecl-common", - "half", - "num-traits", - "rand 0.9.2", - "serde", -] - -[[package]] -name = "cubek-reduce" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42397d9ed85bb3084dfb56ed26de75690b5b07caf42a32f4006b57eb23d5b6d6" -dependencies = [ - "cubecl", - "half", - "num-traits", - "serde", - "thiserror 2.0.18", -] - [[package]] name = "cudarc" -version = "0.18.2" +version = "0.13.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa12038120eb13347a6ae2ffab1d34efe78150125108627fd85044dd4d6ff1e" +checksum = "486c221362668c63a1636cfa51463b09574433b39029326cff40864b3ba12b6e" dependencies = [ "libloading", ] -[[package]] -name = "cxx" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d8437319e3a2f43d93b341c137927ca70c0f5dabeea7a005a73665e247c7e" -dependencies = [ - "cc", - "cxx-build", - "cxxbridge-cmd", - "cxxbridge-flags", - "cxxbridge-macro", - "foldhash 0.2.0", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f4697d190a142477b16aef7da8a99bfdc41e7e8b1687583c0d23a79c7afc1e" -dependencies = [ - "cc", - "codespan-reporting 0.13.1", - "indexmap", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.114", -] - -[[package]] -name = "cxxbridge-cmd" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0956799fa8678d4c50eed028f2de1c0552ae183c76e976cf7ca8c4e36a7c328" -dependencies = [ - "clap", - "codespan-reporting 0.13.1", - "indexmap", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23384a836ab4f0ad98ace7e3955ad2de39de42378ab487dc28d3990392cb283a" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6acc6b5822b9526adfb4fc377b67128fdd60aac757cc4a741a6278603f763cf" -dependencies = [ - "indexmap", - "proc-macro2", - "quote", - "syn 2.0.114", -] - [[package]] name = "darling" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core 0.20.11", - "darling_macro 0.20.11", -] - -[[package]] -name = "darling" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" -dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", -] - -[[package]] -name = "darling" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" -dependencies = [ - "darling_core 0.23.0", - "darling_macro 0.23.0", + "darling_core", + "darling_macro", ] [[package]] @@ -2083,34 +1399,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.114", -] - -[[package]] -name = "darling_core" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.114", -] - -[[package]] -name = "darling_core" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" -dependencies = [ - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -2119,31 +1408,9 @@ version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core 0.20.11", + "darling_core", "quote", - "syn 2.0.114", -] - -[[package]] -name = "darling_macro" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" -dependencies = [ - "darling_core 0.21.3", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "darling_macro" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" -dependencies = [ - "darling_core 0.23.0", - "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -2162,24 +1429,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" - -[[package]] -name = "decorum" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "281759d3c8a14f5c3f0c49363be56810fcd7f910422f97f2db850c2920fde5cf" -dependencies = [ - "num-traits", -] +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "deranged" -version = "0.5.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -2195,6 +1453,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-new" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "derive-new" version = "0.7.0" @@ -2203,38 +1472,41 @@ checksum = "2cdc8d50f426189eef89dac62fabfa0abb27d5cc008f25bf4156a0203325becc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", ] [[package]] name = "derive_more" -version = "2.1.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.1.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "convert_case 0.10.0", "proc-macro2", "quote", - "rustc_version", - "syn 2.0.114", + "syn 2.0.104", "unicode-xid", ] -[[package]] -name = "deunicode" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" - [[package]] name = "diff" version = "0.1.13" @@ -2253,12 +1525,12 @@ dependencies = [ ] [[package]] -name = "directories" -version = "6.0.0" +name = "dirs" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "dirs-sys", + "dirs-sys 0.4.1", ] [[package]] @@ -2267,7 +1539,19 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "dirs-sys", + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.4.6", + "windows-sys 0.48.0", ] [[package]] @@ -2278,8 +1562,8 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users", - "windows-sys 0.61.2", + "redox_users 0.5.0", + "windows-sys 0.59.0", ] [[package]] @@ -2290,101 +1574,48 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "document-features" -version = "0.2.12" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" dependencies = [ "litrs", ] [[package]] name = "dyn-stack" -version = "0.13.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4713e43e2886ba72b8271aa66c93d722116acf7a75555cce11dcde84388fe8" +checksum = "56e53799688f5632f364f8fb387488dd05db9fe45db7011be066fc20e7027f8b" dependencies = [ "bytemuck", - "dyn-stack-macros", + "reborrow", ] [[package]] -name = "dyn-stack-macros" -version = "0.1.3" +name = "dyn-stack" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9" +checksum = "490bd48eb68fffcfed519b4edbfd82c69cbe741d175b84f0e0cbe8c57cbe0bdd" +dependencies = [ + "bytemuck", +] [[package]] name = "either" -version = "1.15.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "embassy-futures" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" - -[[package]] -name = "embassy-time" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f820157f198ada183ad62e0a66f554c610cdcd1a9f27d4b316358103ced7a1f8" -dependencies = [ - "cfg-if", - "critical-section", - "document-features", - "embassy-time-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "futures-util", -] - -[[package]] -name = "embassy-time-driver" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" -dependencies = [ - "document-features", -] - -[[package]] -name = "embedded-hal" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" -dependencies = [ - "nb 0.1.3", - "void", -] - -[[package]] -name = "embedded-hal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" - -[[package]] -name = "embedded-hal-async" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" -dependencies = [ - "embedded-hal 1.0.0", -] - -[[package]] -name = "entities" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" [[package]] name = "enum-as-inner" @@ -2395,36 +1626,14 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", -] - -[[package]] -name = "enumset" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" -dependencies = [ - "enumset_derive", - "serde", -] - -[[package]] -name = "enumset_derive" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" -dependencies = [ - "darling 0.21.3", - "proc-macro2", - "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "env_filter" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", "regex", @@ -2432,9 +1641,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "humantime", "is-terminal", @@ -2445,14 +1654,14 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" dependencies = [ "anstream", "anstyle", "env_filter", - "jiff", + "humantime", "log", ] @@ -2473,30 +1682,30 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "equivalent" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.14" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] name = "event-listener" -version = "5.4.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -2515,9 +1724,9 @@ dependencies = [ [[package]] name = "exr" -version = "1.74.0" +version = "1.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" dependencies = [ "bit_field", "half", @@ -2528,28 +1737,6 @@ dependencies = [ "zune-inflate", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure 0.12.6", -] - [[package]] name = "fallible-iterator" version = "0.3.0" @@ -2568,26 +1755,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "fax" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" -dependencies = [ - "fax_derive", -] - -[[package]] -name = "fax_derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - [[package]] name = "fdeflate" version = "0.3.7" @@ -2597,34 +1764,11 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "filetime" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" -dependencies = [ - "cfg-if", - "libc", - "libredox", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "flate2" -version = "1.1.9" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -2636,33 +1780,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d" -[[package]] -name = "float4" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5939bac0ef2ad7c83a53e4fb889c1d81f007b07061d648cd271071984d86f257" - -[[package]] -name = "float8" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4203231de188ebbdfb85c11f3c20ca2b063945710de04e7b59268731e728b462" -dependencies = [ - "half", -] - -[[package]] -name = "float8" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719a903cc23e4a89e87962c2a80fdb45cdaad0983a89bd150bb57b4c8571a7d5" -dependencies = [ - "half", - "num-traits", - "rand 0.9.2", - "rand_distr", -] - [[package]] name = "fnv" version = "1.0.7" @@ -2671,15 +1788,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" [[package]] name = "foreign-types" @@ -2699,7 +1810,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -2710,55 +1821,19 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - [[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-io" version = "0.3.31" @@ -2767,9 +1842,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.6.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ "fastrand", "futures-core", @@ -2786,15 +1861,9 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - [[package]] name = "futures-task" version = "0.3.31" @@ -2813,13 +1882,9 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "futures-channel", "futures-core", - "futures-io", "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", "slab", @@ -2827,120 +1892,238 @@ dependencies = [ [[package]] name = "gemm" -version = "0.19.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa0673db364b12263d103b68337a68fbecc541d6f6b61ba72fe438654709eacb" +checksum = "6ab24cc62135b40090e31a76a9b2766a501979f3070fa27f689c27ec04377d32" dependencies = [ - "dyn-stack", - "gemm-c32", - "gemm-c64", - "gemm-common", - "gemm-f16", - "gemm-f32", - "gemm-f64", + "dyn-stack 0.10.0", + "gemm-c32 0.17.1", + "gemm-c64 0.17.1", + "gemm-common 0.17.1", + "gemm-f16 0.17.1", + "gemm-f32 0.17.1", + "gemm-f64 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab96b703d31950f1aeddded248bc95543c9efc7ac9c4a21fda8703a83ee35451" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-c32 0.18.2", + "gemm-c64 0.18.2", + "gemm-common 0.18.2", + "gemm-f16 0.18.2", + "gemm-f32 0.18.2", + "gemm-f64 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] [[package]] name = "gemm-c32" -version = "0.19.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086936dbdcb99e37aad81d320f98f670e53c1e55a98bee70573e83f95beb128c" +checksum = "b9c030d0b983d1e34a546b86e08f600c11696fde16199f971cd46c12e67512c0" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-c32" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6db9fd9f40421d00eea9dd0770045a5603b8d684654816637732463f4073847" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] [[package]] name = "gemm-c64" -version = "0.19.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c8aeeeec425959bda4d9827664029ba1501a90a0d1e6228e48bef741db3a3f" +checksum = "fbb5f2e79fefb9693d18e1066a557b4546cd334b226beadc68b11a8f9431852a" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-c64" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfcad8a3d35a43758330b635d02edad980c1e143dc2f21e6fd25f9e4eada8edf" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] [[package]] name = "gemm-common" -version = "0.19.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88027625910cc9b1085aaaa1c4bc46bb3a36aad323452b33c25b5e4e7c8e2a3e" +checksum = "a2e7ea062c987abcd8db95db917b4ffb4ecdfd0668471d8dc54734fdff2354e8" dependencies = [ "bytemuck", - "dyn-stack", + "dyn-stack 0.10.0", + "half", + "num-complex", + "num-traits", + "once_cell", + "paste", + "pulp 0.18.22", + "raw-cpuid 10.7.0", + "rayon", + "seq-macro", + "sysctl 0.5.5", +] + +[[package]] +name = "gemm-common" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a352d4a69cbe938b9e2a9cb7a3a63b7e72f9349174a2752a558a8a563510d0f3" +dependencies = [ + "bytemuck", + "dyn-stack 0.13.0", "half", "libm", "num-complex", "num-traits", "once_cell", "paste", - "pulp", - "raw-cpuid", + "pulp 0.21.5", + "raw-cpuid 11.5.0", "rayon", "seq-macro", - "sysctl", + "sysctl 0.6.0", ] [[package]] name = "gemm-f16" -version = "0.19.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3df7a55202e6cd6739d82ae3399c8e0c7e1402859b30e4cb780e61525d9486e" +checksum = "7ca4c06b9b11952071d317604acb332e924e817bd891bec8dfb494168c7cedd4" dependencies = [ - "dyn-stack", - "gemm-common", - "gemm-f32", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", + "gemm-f32 0.17.1", "half", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "rayon", + "seq-macro", +] + +[[package]] +name = "gemm-f16" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff95ae3259432f3c3410eaa919033cd03791d81cebd18018393dc147952e109" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "gemm-f32 0.18.2", + "half", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "rayon", "seq-macro", ] [[package]] name = "gemm-f32" -version = "0.19.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e0b8c9da1fbec6e3e3ab2ce6bc259ef18eb5f6f0d3e4edf54b75f9fd41a81c" +checksum = "e9a69f51aaefbd9cf12d18faf273d3e982d9d711f60775645ed5c8047b4ae113" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-f32" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc8d3d4385393304f407392f754cd2dc4b315d05063f62cf09f47b58de276864" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] [[package]] name = "gemm-f64" -version = "0.19.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "056131e8f2a521bfab322f804ccd652520c79700d81209e9d9275bbdecaadc6a" +checksum = "aa397a48544fadf0b81ec8741e5c0fba0043008113f71f2034def1935645d2b0" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-f64" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35b2a4f76ce4b8b16eadc11ccf2e083252d8237c1b589558a49b0183545015bd" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] @@ -2956,52 +2139,42 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", - "js-sys", "libc", - "wasi", - "wasm-bindgen", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.3.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi", - "wasip2", - "wasm-bindgen", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] name = "gif" -version = "0.14.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +checksum = "fcc37f9a2bfe731e69f1e08d29d91d30604b9ce24bcb2880a961e82d89c6ed89" dependencies = [ "color_quant", "weezl", ] -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - [[package]] name = "gix-features" -version = "0.45.2" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56aad357ae016449434705033df644ac6253dfcf1281aad3af3af9e907560d1" +checksum = "56f4399af6ec4fd9db84dd4cf9656c5c785ab492ab40a7c27ea92b4241923fed" dependencies = [ "gix-trace", "gix-utils", @@ -3010,56 +2183,59 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.18.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "785b9c499e46bc78d7b81c148c21b3fca18655379ee729a856ed19ce50d359ec" +checksum = "67a0637149b4ef24d3ea55f81f77231401c8463fae6da27331c987957eb597c7" dependencies = [ "bstr", "fastrand", "gix-features", "gix-path", "gix-utils", - "thiserror 2.0.18", + "thiserror 2.0.12", ] [[package]] name = "gix-path" -version = "0.10.22" +version = "0.10.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb06c3e4f8eed6e24fd915fa93145e28a511f4ea0e768bae16673e05ed3f366" +checksum = "567f65fec4ef10dfab97ae71f26a27fd4d7fe7b8e3f90c8a58551c41ff3fb65b" dependencies = [ "bstr", "gix-trace", "gix-validate", - "thiserror 2.0.18", + "home", + "once_cell", + "thiserror 2.0.12", ] [[package]] name = "gix-tempfile" -version = "20.0.1" +version = "17.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad89218e74850f42d364ed3877c7291f0474c8533502df91bb877ecc5cb0dd40" +checksum = "c750e8c008453a2dba67a2b0d928b7716e05da31173a3f5e351d5457ad4470aa" dependencies = [ "dashmap", "gix-fs", "libc", + "once_cell", "parking_lot", - "signal-hook 0.4.3", + "signal-hook", "signal-hook-registry", "tempfile", ] [[package]] name = "gix-trace" -version = "0.1.17" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e42a4c2583357721ba2d887916e78df504980f22f1182df06997ce197b89504" +checksum = "7c396a2036920c69695f760a65e7f2677267ccf483f25046977d87e4cb2665f7" [[package]] name = "gix-utils" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "befcdbdfb1238d2854591f760a48711bed85e72d80a10e8f2f93f656746ef7c5" +checksum = "5351af2b172caf41a3728eb4455326d84e0d70fe26fc4de74ab0bd37df4191c5" dependencies = [ "fastrand", "unicode-normalization", @@ -3067,12 +2243,12 @@ dependencies = [ [[package]] name = "gix-validate" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1e63a5b516e970a594f870ed4571a8fdcb8a344e7bd407a20db8bd61dbfde4" +checksum = "77b9e00cacde5b51388d28ed746c493b18a6add1f19b5e01d686b3b9ece66d4d" dependencies = [ "bstr", - "thiserror 2.0.18", + "thiserror 2.0.12", ] [[package]] @@ -3088,9 +2264,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "glow" @@ -3119,7 +2295,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "gpu-alloc-types", ] @@ -3129,7 +2305,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", ] [[package]] @@ -3150,9 +2326,9 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "gpu-descriptor-types", - "hashbrown 0.15.5", + "hashbrown 0.15.4", ] [[package]] @@ -3161,7 +2337,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", ] [[package]] @@ -3170,50 +2346,30 @@ version = "0.3.1" source = "git+https://github.com/MathisWellmann/gym-rs.git#5283afaa86a3a7c45c46c882cfad459f02539b62" dependencies = [ "derivative", - "derive-new", + "derive-new 0.7.0", "log", "nalgebra", "num-traits", - "ordered-float 5.1.0", + "ordered-float 5.0.0", "rand 0.8.5", - "rand_pcg 0.3.1", + "rand_pcg", "sdl2", "serde", ] -[[package]] -name = "h2" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" -version = "2.7.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "bytemuck", "cfg-if", "crunchy", "num-traits", - "rand 0.9.2", + "rand 0.9.1", "rand_distr", "serde", - "zerocopy", ] [[package]] @@ -3230,30 +2386,22 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ + "ahash", "allocator-api2", - "equivalent", - "foldhash 0.1.5", "serde", ] [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "allocator-api2", "equivalent", - "foldhash 0.2.0", + "foldhash", "serde", - "serde_core", ] [[package]] @@ -3262,7 +2410,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.15.4", ] [[package]] @@ -3271,6 +2419,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hermit-abi" version = "0.5.2" @@ -3293,199 +2447,19 @@ dependencies = [ ] [[package]] -name = "http" -version = "1.4.0" +name = "home" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "bytes", - "itoa", + "windows-sys 0.59.0", ] -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" -version = "2.3.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" - -[[package]] -name = "hyper" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots 1.0.6", -] - -[[package]] -name = "hyper-util" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "ident_case" @@ -3495,30 +2469,19 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.1.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "image" -version = "0.25.9" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" dependencies = [ "bytemuck", "byteorder-lite", @@ -3526,7 +2489,6 @@ dependencies = [ "exr", "gif", "image-webp", - "moxcms", "num-traits", "png", "qoi", @@ -3534,15 +2496,15 @@ dependencies = [ "rayon", "rgb", "tiff", - "zune-core 0.5.1", - "zune-jpeg 0.5.12", + "zune-core", + "zune-jpeg", ] [[package]] name = "image-webp" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b" dependencies = [ "byteorder-lite", "quick-error", @@ -3550,57 +2512,45 @@ dependencies = [ [[package]] name = "imgref" -version = "1.12.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" [[package]] name = "indexmap" -version = "2.13.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.15.4", ] [[package]] name = "indoc" -version = "2.0.7" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" -dependencies = [ - "rustversion", -] +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" [[package]] name = "inout" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ "generic-array", ] [[package]] name = "instability" -version = "0.3.11" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357b7205c6cd18dd2c86ed312d1e70add149aea98e7ef72b9fdf0270e555c11d" +checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" dependencies = [ - "darling 0.23.0", - "indoc", - "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] -[[package]] -name = "internal-iterator" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969ee3fc68ec2e88eb21434ce4d9b7e1600d1ce92ff974560a6c4a304f5124b9" - [[package]] name = "interpolate_name" version = "0.2.4" @@ -3609,47 +2559,31 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" -dependencies = [ - "memchr", - "serde", + "syn 2.0.104", ] [[package]] name = "is-terminal" -version = "0.4.17" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.61.2", + "hermit-abi 0.3.9", + "rustix 0.38.37", + "windows-sys 0.48.0", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.2" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" -version = "0.10.5" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -3674,33 +2608,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" - -[[package]] -name = "jiff" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89a5b5e10d5a9ad6e5d1f4bd58225f655d6fe9767575a5e8ac5a6fe64e04495" -dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde_core", -] - -[[package]] -name = "jiff-static" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff7a39c8862fc1369215ccf0a8f12dd4598c7f6484704359f0351bd617034dbf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jni-sys" @@ -3710,19 +2620,25 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.3.3", "libc", ] [[package]] -name = "js-sys" -version = "0.3.85" +name = "jpeg-decoder" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -3753,21 +2669,21 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lebe" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.180" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libfuzzer-sys" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75" dependencies = [ "arbitrary", "cc", @@ -3775,57 +2691,35 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.9" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-link 0.2.1", -] - -[[package]] -name = "liblzma" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c36d08cad03a3fbe2c4e7bb3a9e84c57e4ee4135ed0b065cade3d98480c648" -dependencies = [ - "liblzma-sys", - "num_cpus", -] - -[[package]] -name = "liblzma-sys" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2db66f3268487b5033077f266da6777d057949b8f93c8ad82e441df25e6186" -dependencies = [ - "cc", - "libc", - "pkg-config", + "windows-targets 0.52.6", ] [[package]] name = "libm" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "libc", - "redox_syscall 0.7.0", ] [[package]] name = "libsqlite3-sys" -version = "0.35.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f" +checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7" dependencies = [ "cc", "pkg-config", @@ -3833,52 +2727,38 @@ dependencies = [ ] [[package]] -name = "link-cplusplus" -version = "1.0.12" +name = "linux-raw-sys" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" -dependencies = [ - "cc", -] +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litrs" -version = "1.0.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lock_api" -version = "0.4.14" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.29" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "loop9" @@ -3895,20 +2775,14 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.15.4", ] -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - [[package]] name = "macerator" -version = "0.2.10" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b0b2dbe8b22f9e96ba12e29964889010117f92e6bd006010887320ae58e2f0" +checksum = "bce07f822458c4c303081d133a90610406162e7c8df17434956ac1892faf447b" dependencies = [ "bytemuck", "cfg_aliases", @@ -3917,19 +2791,18 @@ dependencies = [ "moddef", "num-traits", "paste", - "rustc_version", ] [[package]] name = "macerator-macros" -version = "0.1.3" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd48b535b9b37a25a2589ab8d4f997886a2c68f59960ce06588525f38dd4944" +checksum = "a2b955a106dca78c0577269d67a6d56114abb8644b810fc995a22348276bb9dd" dependencies = [ - "darling 0.20.11", + "darling", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -3941,21 +2814,6 @@ dependencies = [ "libc", ] -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "matchit" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" - [[package]] name = "matrixmultiply" version = "0.3.10" @@ -3981,35 +2839,26 @@ dependencies = [ [[package]] name = "md5" -version = "0.8.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae960838283323069879657ca3de837e9f7bbb4c7bf6ea7f1b290d5e9476d2e0" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.8.0" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" -version = "0.9.9" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", "stable_deref_trait", ] -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - [[package]] name = "merge" version = "0.1.0" @@ -4034,11 +2883,11 @@ dependencies = [ [[package]] name = "metal" -version = "0.32.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" +checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "block", "core-graphics-types", "foreign-types", @@ -4047,12 +2896,6 @@ dependencies = [ "paste", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -4071,55 +2914,45 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "log", - "wasi", - "windows-sys 0.61.2", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", ] [[package]] name = "moddef" -version = "0.3.0" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0b3262dc837d2513fe2ef31ff8461352ef932dcca31ba0c0abe33547cf6b9b" - -[[package]] -name = "moxcms" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97" -dependencies = [ - "num-traits", - "pxfm", -] +checksum = "4e519fd9c6131c1c9a4a67f8bdc4f32eb4105b16c1468adea1b8e68c98c85ec4" [[package]] name = "naga" -version = "26.0.0" +version = "25.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916cbc7cb27db60be930a4e2da243cf4bc39569195f22fd8ee419cd31d5b662c" +checksum = "2b977c445f26e49757f9aca3631c3b8b836942cb278d69a92e7b80d3b24da632" dependencies = [ - "arrayvec 0.7.6", + "arrayvec", "bit-set", - "bitflags 2.10.0", - "cfg-if", + "bitflags 2.9.1", "cfg_aliases", - "codespan-reporting 0.12.0", + "codespan-reporting", "half", - "hashbrown 0.15.5", + "hashbrown 0.15.4", "hexf-parse", "indexmap", - "libm", "log", "num-traits", "once_cell", - "rustc-hash 1.1.0", + "rustc-hash", "spirv", - "thiserror 2.0.18", + "strum 0.26.3", + "thiserror 2.0.12", "unicode-ident", ] @@ -4147,44 +2980,14 @@ checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.1.0", -] - -[[package]] -name = "nb" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" - [[package]] name = "ndarray" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits", - "portable-atomic", - "portable-atomic-util", - "rawpointer", -] - -[[package]] -name = "ndarray" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d" dependencies = [ "matrixmultiply", "num-complex", @@ -4198,9 +3001,9 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.6.0+11769913" +version = "0.5.0+25.2.9519653" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" dependencies = [ "jni-sys", ] @@ -4211,24 +3014,6 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" -[[package]] -name = "no-std-compat" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df270209a7f04d62459240d890ecb792714d5db12c92937823574a09930276b4" - -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - [[package]] name = "nom" version = "7.1.3" @@ -4239,15 +3024,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nom" -version = "8.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" -dependencies = [ - "memchr", -] - [[package]] name = "noop_proc_macro" version = "0.3.0" @@ -4256,20 +3032,21 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "ntapi" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" dependencies = [ "winapi", ] [[package]] name = "nu-ansi-term" -version = "0.50.3" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "windows-sys 0.61.2", + "overload", + "winapi", ] [[package]] @@ -4308,9 +3085,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-derive" @@ -4320,7 +3097,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -4370,10 +3147,31 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi", + "hermit-abi 0.5.2", "libc", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "num_threads" version = "0.1.7" @@ -4385,11 +3183,11 @@ dependencies = [ [[package]] name = "nvml-wrapper" -version = "0.11.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d5c6c0ef9702176a570f06ad94f3198bc29c524c8b498f1b9346e1b1bdcbb3a" +checksum = "0c9bff0aa1d48904a1385ea2a8b97576fbdcbc9a3cfccd0d31fe978e1c4038c5" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "libloading", "nvml-wrapper-sys", "static_assertions", @@ -4399,9 +3197,9 @@ dependencies = [ [[package]] name = "nvml-wrapper-sys" -version = "0.9.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd23dbe2eb8d8335d2bce0299e0a07d6a63c089243d626ca75b770a962ff49e6" +checksum = "698d45156f28781a4e79652b6ebe2eaa0589057d588d3aec1333f6466f13fcb5" dependencies = [ "libloading", ] @@ -4415,34 +3213,6 @@ dependencies = [ "malloc_buf", ] -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "objc2-io-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" -dependencies = [ - "libc", - "objc2-core-foundation", -] - -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - [[package]] name = "octets" version = "0.2.0" @@ -4455,17 +3225,11 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - [[package]] name = "opaque-debug" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "option-ext" @@ -4484,15 +3248,21 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.1.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" +checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01" dependencies = [ "num-traits", "rand 0.8.5", "serde", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.1" @@ -4501,9 +3271,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.5" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", "parking_lot_core", @@ -4511,15 +3281,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.12" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-targets 0.48.5", ] [[package]] @@ -4539,12 +3309,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pastey" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" - [[package]] name = "pbkdf2" version = "0.11.0" @@ -4559,19 +3323,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset", - "indexmap", -] +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pico-args" @@ -4599,11 +3353,11 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "png" -version = "0.18.0" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ - "bitflags 2.10.0", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", @@ -4623,31 +3377,22 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" dependencies = [ "serde", ] [[package]] name = "portable-atomic-util" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" dependencies = [ "portable-atomic", ] -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -4656,12 +3401,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.21" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "presser" @@ -4671,9 +3413,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" [[package]] name = "pretty_assertions" -version = "1.4.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" dependencies = [ "diff", "yansi", @@ -4681,21 +3423,21 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.37" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ - "toml_edit 0.23.10+spec-1.0.0", + "toml_edit", ] [[package]] @@ -4724,9 +3466,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -4747,104 +3489,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "pulp" -version = "0.22.2" +version = "0.18.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e205bb30d5b916c55e584c22201771bcf2bad9aabd5d4127f38387140c38632" +checksum = "a0a01a0dc67cf4558d279f0c25b0962bd08fc6dec0137699eae304103e882fe6" +dependencies = [ + "bytemuck", + "libm", + "num-complex", + "reborrow", +] + +[[package]] +name = "pulp" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b86df24f0a7ddd5e4b95c94fc9ed8a98f1ca94d3b01bdce2824097e7835907" dependencies = [ "bytemuck", "cfg-if", "libm", "num-complex", - "paste", - "pulp-wasm-simd-flag", - "raw-cpuid", "reborrow", "version_check", ] -[[package]] -name = "pulp-wasm-simd-flag" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40e24eee682d89fb193496edf918a7f407d30175b2e785fe057e4392dfd182e0" - -[[package]] -name = "pxfm" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8" -dependencies = [ - "num-traits", -] - -[[package]] -name = "pyo3" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872" -dependencies = [ - "cfg-if", - "indoc", - "libc", - "memoffset", - "once_cell", - "portable-atomic", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb" -dependencies = [ - "once_cell", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-macros" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028" -dependencies = [ - "heck", - "proc-macro2", - "pyo3-build-config", - "quote", - "syn 2.0.114", -] - [[package]] name = "qoi" version = "0.4.1" @@ -4860,66 +3533,11 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.1.1", - "rustls", - "socket2", - "thiserror 2.0.18", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" -dependencies = [ - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash 2.1.1", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.18", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - [[package]] name = "quote" -version = "1.0.44" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -4943,27 +3561,15 @@ dependencies = [ [[package]] name = "r2d2_sqlite" -version = "0.31.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63417e83dc891797eea3ad379f52a5986da4bca0d6ef28baf4d14034dd111b0c" +checksum = "180da684f0a188977d3968f139eb44260192ef8d9a5b7b7cbd01d881e0353179" dependencies = [ "r2d2", "rusqlite", "uuid", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg 0.2.1", -] - [[package]] name = "rand" version = "0.8.5" @@ -4978,22 +3584,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_core 0.9.3", ] [[package]] @@ -5013,32 +3609,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.5", + "rand_core 0.9.3", ] -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "serde", ] [[package]] name = "rand_core" -version = "0.9.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.3.3", ] [[package]] @@ -5048,25 +3638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ "num-traits", - "rand 0.9.2", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", + "rand 0.9.1", ] [[package]] @@ -5078,28 +3650,40 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_xoshiro" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "range-alloc" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" +[[package]] +name = "ratatui" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" +dependencies = [ + "bitflags 2.9.1", + "cassowary", + "compact_str", + "crossterm", + "instability", + "itertools 0.13.0", + "lru", + "paste", + "strum 0.26.3", + "strum_macros 0.26.4", + "unicode-segmentation", + "unicode-truncate", + "unicode-width 0.1.14", +] + [[package]] name = "ratatui" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "cassowary", "compact_str", "crossterm", @@ -5117,21 +3701,19 @@ dependencies = [ [[package]] name = "rav1e" -version = "0.8.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" dependencies = [ - "aligned-vec", "arbitrary", "arg_enum_proc_macro", - "arrayvec 0.7.6", - "av-scenechange", + "arrayvec", "av1-grain", "bitstream-io", "built", "cfg-if", "interpolate_name", - "itertools 0.14.0", + "itertools 0.12.1", "libc", "libfuzzer-sys", "log", @@ -5140,21 +3722,23 @@ dependencies = [ "noop_proc_macro", "num-derive", "num-traits", + "once_cell", "paste", "profiling", - "rand 0.9.2", - "rand_chacha 0.9.0", + "rand 0.8.5", + "rand_chacha 0.3.1", "simd_helpers", - "thiserror 2.0.18", + "system-deps", + "thiserror 1.0.69", "v_frame", "wasm-bindgen", ] [[package]] name = "ravif" -version = "0.12.0" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285" +checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b" dependencies = [ "avif-serialize", "imgref", @@ -5167,11 +3751,20 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.6.0" +version = "10.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" dependencies = [ - "bitflags 2.10.0", + "bitflags 1.3.2", +] + +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags 2.9.1", ] [[package]] @@ -5188,9 +3781,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.11.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -5198,9 +3791,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.13.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -5214,38 +3807,40 @@ checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" [[package]] name = "redox_syscall" -version = "0.5.18" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "redox_syscall" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" -dependencies = [ - "bitflags 2.10.0", + "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.5.2" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "libredox", - "thiserror 2.0.18", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.12", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -5255,9 +3850,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -5266,9 +3861,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relative-path" @@ -5304,52 +3899,11 @@ dependencies = [ "log", ] -[[package]] -name = "reqwest" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 1.0.6", -] - [[package]] name = "rgb" -version = "0.8.52" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" [[package]] name = "ring" @@ -5359,7 +3913,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.17", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -5373,39 +3927,43 @@ checksum = "3df6368f71f205ff9c33c076d170dd56ebf68e8161c733c0caa07a7a5509ed53" [[package]] name = "rmp" -version = "0.8.15" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" dependencies = [ + "byteorder", "num-traits", + "paste", ] [[package]] name = "rmp-serde" -version = "1.3.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" dependencies = [ + "byteorder", "rmp", "serde", ] [[package]] name = "rstest" -version = "0.26.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" dependencies = [ "futures-timer", "futures-util", "rstest_macros", + "rustc_version", ] [[package]] name = "rstest_macros" -version = "0.26.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" dependencies = [ "cfg-if", "glob", @@ -5415,17 +3973,17 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.114", + "syn 2.0.104", "unicode-ident", ] [[package]] name = "rusqlite" -version = "0.37.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" +checksum = "37e34486da88d8e051c7c0e23c3f15fd806ea8546260aa2fec247e97242ec143" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -5433,24 +3991,12 @@ dependencies = [ "smallvec", ] -[[package]] -name = "rustc-demangle" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" - [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - [[package]] name = "rustc_version" version = "0.4.1" @@ -5462,38 +4008,37 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "errno", "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", ] [[package]] name = "rustix" -version = "1.1.3" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "errno", "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.36" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", - "once_cell", "ring", "rustls-pki-types", "rustls-webpki", @@ -5503,19 +4048,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ - "web-time", "zeroize", ] [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -5524,15 +4068,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "safe_arch" @@ -5555,11 +4099,10 @@ dependencies = [ [[package]] name = "safetensors" -version = "0.7.0" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675656c1eabb620b921efea4f9199f97fc86e36dd6ffd1fbbe48d0f59a4987f5" +checksum = "44560c11236a6130a46ce36c836a62936dc81ebf8c36a37947423571be0e55b6" dependencies = [ - "hashbrown 0.16.1", "serde", "serde_json", ] @@ -5573,6 +4116,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "sanitize-filename" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "sanitize-filename" version = "0.6.0" @@ -5597,12 +4150,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scratch" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" - [[package]] name = "sdl2" version = "0.37.0" @@ -5625,14 +4172,14 @@ dependencies = [ "cfg-if", "cmake", "libc", - "version-compare", + "version-compare 0.1.1", ] [[package]] name = "semver" -version = "1.0.27" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "seq-macro" @@ -5642,76 +4189,53 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ - "serde_core", "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.19" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" dependencies = [ "serde", - "serde_core", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", + "ryu", "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_path_to_error" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" -dependencies = [ - "itoa", - "serde", - "serde_core", ] [[package]] name = "serde_rusqlite" -version = "0.40.1" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8bd74f47e124e760475a7e863b5820dcef09cae50782d03d65961f5ca1e6d9" +checksum = "1e77d42c863496aee3253704aa621691088f718cd8800bd50bcdc19f9bd2a8ea" dependencies = [ "rusqlite", - "serde_core", + "serde", ] [[package]] @@ -5723,27 +4247,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha1" version = "0.10.6" @@ -5783,19 +4286,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook" -version = "0.3.18" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b57709da74f9ff9f4a27dce9526eec25ca8407c45a7887243b031a58935fb8e" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" dependencies = [ "libc", "signal-hook-registry", @@ -5803,30 +4296,29 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio", - "signal-hook 0.3.18", + "signal-hook", ] [[package]] name = "signal-hook-registry" -version = "1.4.8" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ - "errno", "libc", ] [[package]] name = "simba" -version = "0.9.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" dependencies = [ "approx", "num-complex", @@ -5837,9 +4329,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "simd_helpers" @@ -5852,43 +4344,33 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.12" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "slotmap" -version = "1.1.1" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] -[[package]] -name = "slug" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" -dependencies = [ - "deunicode", - "wasm-bindgen", -] - [[package]] name = "smallvec" -version = "1.15.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] -name = "socket2" -version = "0.6.2" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ - "libc", - "windows-sys 0.60.2", + "lock_api", + "portable-atomic", ] [[package]] @@ -5907,23 +4389,14 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "stable-vec" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1dff32a2ce087283bec878419027cebd888760d8760b2941ad0843531dc9ec8" -dependencies = [ - "no-std-compat", + "bitflags 2.9.1", ] [[package]] name = "stable_deref_trait" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "static_assertions" @@ -5931,6 +4404,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "store" +version = "0.1.0" +dependencies = [ + "base64 0.21.7", + "log", + "merge", + "rand 0.8.5", + "serde", + "transpose", +] + [[package]] name = "strength_reduce" version = "0.2.4" @@ -5954,11 +4439,11 @@ dependencies = [ [[package]] name = "strum" -version = "0.27.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" dependencies = [ - "strum_macros 0.27.2", + "strum_macros 0.27.1", ] [[package]] @@ -5971,26 +4456,27 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "strum_macros" -version = "0.27.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "rustversion", + "syn 2.0.104", ] [[package]] name = "subtle" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -6005,36 +4491,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.2" @@ -6043,7 +4508,21 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", +] + +[[package]] +name = "sysctl" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea" +dependencies = [ + "bitflags 2.9.1", + "byteorder", + "enum-as-inner", + "libc", + "thiserror 1.0.69", + "walkdir", ] [[package]] @@ -6052,7 +4531,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "byteorder", "enum-as-inner", "libc", @@ -6062,57 +4541,45 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.36.1" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d" +checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01" dependencies = [ + "core-foundation-sys", "libc", "memchr", "ntapi", - "objc2-core-foundation", - "objc2-io-kit", - "windows 0.61.3", + "rayon", + "windows 0.57.0", ] [[package]] -name = "sysinfo" -version = "0.37.2" +name = "system-deps" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ - "libc", - "memchr", - "ntapi", - "objc2-core-foundation", - "objc2-io-kit", - "windows 0.61.3", + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare 0.2.0", ] [[package]] name = "systemstat" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5021f5184d44b26fb184acd689671bbe1e4bbd24bbdaa6bc7ec383fad32d2033" +checksum = "668a4db78b439df482c238f559e4ea869017f9e62ef0a059c8bfcd841a4df544" dependencies = [ "bytesize", "lazy_static", "libc", - "nom 7.1.3", + "nom", "time", "winapi", ] -[[package]] -name = "tar" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" -dependencies = [ - "filetime", - "libc", - "xattr", -] - [[package]] name = "target-lexicon" version = "0.12.16" @@ -6121,14 +4588,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tch" -version = "0.22.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e09b91610202dc4820c21eb474a42b386ef69f323b1c0902b5472ba7456ebb5" +checksum = "aa1ed622c8f13b0c42f8b1afa0e5e9ccccd82ecb6c0e904120722ab52fdc5234" dependencies = [ "half", "lazy_static", "libc", - "ndarray 0.16.1", + "ndarray", "rand 0.8.5", "safetensors 0.3.3", "thiserror 1.0.69", @@ -6138,15 +4605,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.3.3", "once_cell", - "rustix 1.1.3", - "windows-sys 0.61.2", + "rustix 1.0.7", + "windows-sys 0.59.0", ] [[package]] @@ -6169,12 +4636,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "textdistance" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa672c55ab69f787dbc9126cc387dbe57fdd595f585e4524cf89018fa44ab819" - [[package]] name = "thiserror" version = "1.0.69" @@ -6186,11 +4647,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.12", ] [[package]] @@ -6201,18 +4662,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -6235,23 +4696,20 @@ dependencies = [ [[package]] name = "tiff" -version = "0.10.3" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" dependencies = [ - "fax", "flate2", - "half", - "quick-error", + "jpeg-decoder", "weezl", - "zune-jpeg 0.4.21", ] [[package]] name = "time" -version = "0.3.47" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -6259,51 +4717,32 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde_core", + "serde", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", ] -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinystr" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" -dependencies = [ - "displaydoc", - "zerovec", -] - [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -6314,69 +4753,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "1.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "tracing", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite", -] - -[[package]] -name = "tokio-util" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - [[package]] name = "toml" version = "0.8.23" @@ -6384,24 +4760,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit 0.22.27", -] - -[[package]] -name = "toml" -version = "0.9.11+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned 1.0.4", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow", + "serde_spanned", + "toml_datetime", + "toml_edit", ] [[package]] @@ -6413,15 +4774,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - [[package]] name = "toml_edit" version = "0.22.27" @@ -6430,50 +4782,16 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", + "serde_spanned", + "toml_datetime", "winnow", ] -[[package]] -name = "toml_edit" -version = "0.23.10+spec-1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" -dependencies = [ - "indexmap", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "winnow", -] - -[[package]] -name = "toml_parser" -version = "1.0.6+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" -dependencies = [ - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "toml_writer" -version = "1.0.6+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" - [[package]] name = "torch-sys" -version = "0.22.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef40c585e342df95b66a1fa7c923188623999c2b657227befb481dfb03a6a42" +checksum = "ef14f5d239e3d60f4919f536a5dfe1d4f71b27b7abf6fe6875fd3a4b22c2dcd5" dependencies = [ "anyhow", "cc", @@ -6484,138 +4802,12 @@ dependencies = [ "zip 0.6.6", ] -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "bitflags 2.10.0", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracel-llvm" -version = "20.1.4-7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982535db9eb1a30ac0f2c50239a0eec3e5cf50993a88e92b04747bd2f4d365b2" -dependencies = [ - "tracel-mlir-rs", - "tracel-mlir-sys", -] - -[[package]] -name = "tracel-llvm-bundler" -version = "20.1.4-7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c75b8e477cb8d49d907afab029ca74d48459f5b88c27bdb4c6cd6acb5e61977" -dependencies = [ - "anyhow", - "bytes", - "constcat", - "dirs", - "liblzma", - "regex", - "reqwest", - "serde", - "serde_json", - "sha2", - "tar", - "walkdir", -] - -[[package]] -name = "tracel-mlir-rs" -version = "20.1.4-7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a478a35efd68d0ba73f747adfb7923b121c64e7f5be9cd8364ca1dcb772d5c" -dependencies = [ - "tracel-mlir-rs-macros", - "tracel-mlir-sys", -] - -[[package]] -name = "tracel-mlir-rs-macros" -version = "20.1.4-7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a94f36868c3b10b1825945223d99d106c73f4d249f063caa4651deeb9379344" -dependencies = [ - "comrak", - "convert_case 0.8.0", - "proc-macro2", - "quote", - "regex", - "syn 2.0.114", - "tracel-llvm-bundler", - "tracel-tblgen-rs", - "unindent", -] - -[[package]] -name = "tracel-mlir-sys" -version = "20.1.4-7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f26d31af0c225a6d2e3d65d012fd6de848c9fc776897b152ee83b7d1bd15c4" -dependencies = [ - "tracel-llvm-bundler", -] - -[[package]] -name = "tracel-tblgen-rs" -version = "20.1.4-7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d2581070380418ccc33b500f3739e4d4869421fdb477fcea51ff97c6253a52" -dependencies = [ - "bindgen", - "cc", - "paste", - "thiserror 2.0.18", - "tracel-llvm-bundler", -] - [[package]] name = "tracing" -version = "0.1.44" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -6623,32 +4815,32 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.18", + "thiserror 1.0.69", "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.31" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] name = "tracing-core" -version = "0.1.36" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -6667,152 +4859,93 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ - "matchers", "nu-ansi-term", - "once_cell", - "regex-automata", "sharded-slab", "smallvec", "thread_local", - "tracing", "tracing-core", "tracing-log", ] [[package]] name = "transpose" -version = "0.2.3" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" +checksum = "e6522d49d03727ffb138ae4cbc1283d3774f0d10aa7f9bf52e6784c45daf9b23" dependencies = [ "num-integer", "strength_reduce", ] [[package]] -name = "trictrac-bot" +name = "trictrac-server" version = "0.1.0" dependencies = [ - "board-game", - "burn", - "burn-rl", - "confy", - "env_logger 0.10.2", - "internal-iterator", - "log", - "pretty_assertions", - "rand 0.9.2", - "serde", - "serde_json", - "trictrac-store", -] - -[[package]] -name = "trictrac-client_cli" -version = "0.1.0" -dependencies = [ - "anyhow", "bincode 1.3.3", - "env_logger 0.11.8", - "itertools 0.13.0", + "env_logger 0.10.0", "log", "pico-args", - "pretty_assertions", "renet", - "trictrac-bot", - "trictrac-store", + "store", ] -[[package]] -name = "trictrac-store" -version = "0.1.0" -dependencies = [ - "anyhow", - "base64 0.21.7", - "cxx", - "cxx-build", - "log", - "merge", - "pyo3", - "rand 0.9.2", - "serde", - "transpose", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "tungstenite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" -dependencies = [ - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand 0.9.2", - "sha1", - "thiserror 2.0.18", - "utf-8", -] - -[[package]] -name = "type-map" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" -dependencies = [ - "rustc-hash 2.1.1", -] - -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - -[[package]] -name = "typed-path" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3015e6ce46d5ad8751e4a772543a30c7511468070e98e64e20165f8f81155b64" - [[package]] name = "typenum" -version = "1.19.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ug" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03719c61a91b51541f076dfdba45caacf750b230cefaa4b32d6f5411c3f7f437" +dependencies = [ + "gemm 0.18.2", + "half", + "libloading", + "memmap2", + "num", + "num-traits", + "num_cpus", + "rayon", + "safetensors 0.4.5", + "serde", + "thiserror 1.0.69", + "tracing", + "yoke", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-normalization" -version = "0.1.25" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-truncate" @@ -6843,18 +4976,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "unindent" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" - [[package]] name = "universal-hash" version = "0.5.1" @@ -6879,9 +5000,9 @@ checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" [[package]] name = "ureq" -version = "2.12.1" +version = "2.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" dependencies = [ "base64 0.22.1", "flate2", @@ -6889,6 +5010,7 @@ dependencies = [ "once_cell", "rustls", "rustls-pki-types", + "rustls-webpki", "serde", "serde_json", "url", @@ -6897,28 +5019,15 @@ dependencies = [ [[package]] name = "url" -version = "2.5.8" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" @@ -6927,13 +5036,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.20.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.3.3", "js-sys", - "rand 0.9.2", + "rand 0.9.1", "wasm-bindgen", ] @@ -6962,7 +5071,7 @@ checksum = "41b6d82be61465f97d42bd1d15bf20f3b0a3a0905018f38f9d6f6962055b0b5c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -6977,18 +5086,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "walkdir" version = "2.5.0" @@ -7000,50 +5109,53 @@ dependencies = [ ] [[package]] -name = "want" -version = "0.3.1" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ - "wit-bindgen", + "wit-bindgen-rt", ] [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.104", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", - "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -7052,9 +5164,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7062,31 +5174,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ - "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", + "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -7108,36 +5220,35 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.6", + "webpki-roots 1.0.1", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" dependencies = [ "rustls-pki-types", ] [[package]] name = "weezl" -version = "0.1.12" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" +checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" [[package]] name = "wgpu" -version = "26.0.1" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b6ff82bbf6e9206828e1a3178e851f8c20f1c9028e74dd3a8090741ccd5798" +checksum = "ec8fb398f119472be4d80bc3647339f56eb63b2a331f6a3d16e25d8144197dd9" dependencies = [ - "arrayvec 0.7.6", - "bitflags 2.10.0", - "cfg-if", + "arrayvec", + "bitflags 2.9.1", "cfg_aliases", "document-features", - "hashbrown 0.15.5", + "hashbrown 0.15.4", "js-sys", "log", "naga", @@ -7157,17 +5268,17 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "26.0.1" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f62f1053bd28c2268f42916f31588f81f64796e2ff91b81293515017ca8bd9" +checksum = "f7b882196f8368511d613c6aeec80655160db6646aebddf8328879a88d54e500" dependencies = [ - "arrayvec 0.7.6", + "arrayvec", "bit-set", "bit-vec", - "bitflags 2.10.0", + "bitflags 2.9.1", "cfg_aliases", "document-features", - "hashbrown 0.15.5", + "hashbrown 0.15.4", "indexmap", "log", "naga", @@ -7176,9 +5287,9 @@ dependencies = [ "portable-atomic", "profiling", "raw-window-handle", - "rustc-hash 1.1.0", + "rustc-hash", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.12", "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", "wgpu-core-deps-windows-linux-android", @@ -7188,42 +5299,42 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "26.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18ae5fbde6a4cbebae38358aa73fcd6e0f15c6144b67ef5dc91ded0db125dbdf" +checksum = "cfd488b3239b6b7b185c3b045c39ca6bf8af34467a4c5de4e0b1a564135d093d" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "26.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7670e390f416006f746b4600fdd9136455e3627f5bd763abf9a65daa216dd2d" +checksum = "f09ad7aceb3818e52539acc679f049d3475775586f3f4e311c30165cf2c00445" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "26.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "720a5cb9d12b3d337c15ff0e24d3e97ed11490ff3f7506e7f3d98c68fa5d6f14" +checksum = "cba5fb5f7f9c98baa7c889d444f63ace25574833df56f5b817985f641af58e46" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "26.0.6" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d0e67224cc7305b3b4eb2cc57ca4c4c3afc665c1d1bee162ea806e19c47bdd" +checksum = "f968767fe4d3d33747bbd1473ccd55bf0f6451f55d733b5597e67b5deab4ad17" dependencies = [ "android_system_properties", - "arrayvec 0.7.6", + "arrayvec", "ash", "bit-set", - "bitflags 2.10.0", + "bitflags 2.9.1", "block", "bytemuck", "cfg-if", @@ -7234,7 +5345,7 @@ dependencies = [ "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hashbrown 0.15.5", + "hashbrown 0.15.4", "js-sys", "khronos-egl", "libc", @@ -7247,13 +5358,12 @@ dependencies = [ "ordered-float 4.6.0", "parking_lot", "portable-atomic", - "portable-atomic-util", "profiling", "range-alloc", "raw-window-handle", "renderdoc-sys", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.12", "wasm-bindgen", "web-sys", "wgpu-types", @@ -7263,15 +5373,15 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "26.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca7a8d8af57c18f57d393601a1fb159ace8b2328f1b6b5f80893f7d672c9ae2" +checksum = "2aa49460c2a8ee8edba3fca54325540d904dd85b2e086ada762767e17d06e8bc" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.1", "bytemuck", "js-sys", "log", - "thiserror 2.0.18", + "thiserror 2.0.12", "web-sys", ] @@ -7303,11 +5413,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.11" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "windows-sys 0.61.2", + "winapi", ] [[package]] @@ -7316,6 +5426,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.58.0" @@ -7327,25 +5447,15 @@ dependencies = [ ] [[package]] -name = "windows" -version = "0.61.3" +name = "windows-core" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ - "windows-collections", - "windows-core 0.61.2", - "windows-future", - "windows-link 0.1.3", - "windows-numerics", -] - -[[package]] -name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core 0.61.2", + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", + "windows-targets 0.52.6", ] [[package]] @@ -7357,32 +5467,19 @@ dependencies = [ "windows-implement 0.58.0", "windows-interface 0.58.0", "windows-result 0.2.0", - "windows-strings 0.1.0", + "windows-strings", "windows-targets 0.52.6", ] [[package]] -name = "windows-core" -version = "0.61.2" +name = "windows-implement" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - -[[package]] -name = "windows-future" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", - "windows-threading", + "proc-macro2", + "quote", + "syn 2.0.104", ] [[package]] @@ -7393,18 +5490,18 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] -name = "windows-implement" -version = "0.60.2" +name = "windows-interface" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -7415,40 +5512,16 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] -name = "windows-interface" -version = "0.59.3" +name = "windows-result" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-numerics" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-targets 0.52.6", ] [[package]] @@ -7460,15 +5533,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - [[package]] name = "windows-strings" version = "0.1.0" @@ -7480,12 +5544,12 @@ dependencies = [ ] [[package]] -name = "windows-strings" -version = "0.4.2" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-link 0.1.3", + "windows-targets 0.48.5", ] [[package]] @@ -7507,21 +5571,18 @@ dependencies = [ ] [[package]] -name = "windows-sys" -version = "0.60.2" +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -7533,7 +5594,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -7541,30 +5602,10 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.53.5" +name = "windows_aarch64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link 0.2.1", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows-threading" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" -dependencies = [ - "windows-link 0.1.3", -] +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" @@ -7573,10 +5614,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" +name = "windows_aarch64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" @@ -7585,10 +5626,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" +name = "windows_i686_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" @@ -7596,12 +5637,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" @@ -7609,10 +5644,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" +name = "windows_i686_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" @@ -7621,10 +5656,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "windows_i686_msvc" -version = "0.53.1" +name = "windows_x86_64_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" @@ -7633,10 +5668,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" +name = "windows_x86_64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" @@ -7645,10 +5680,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" +name = "windows_x86_64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" @@ -7656,26 +5691,23 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen" -version = "0.51.0" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] [[package]] name = "wrapcenum-derive" @@ -7683,52 +5715,31 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76ff259533532054cfbaefb115c613203c73707017459206380f03b3b3f266e" dependencies = [ - "darling 0.20.11", + "darling", "proc-macro2", "quote", - "syn 2.0.114", -] - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "xattr" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix 1.1.3", + "syn 2.0.104", ] [[package]] name = "xml-rs" -version = "0.8.28" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" - -[[package]] -name = "y4m" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" +checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" [[package]] name = "yansi" -version = "1.0.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "yoke" -version = "0.8.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ + "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -7736,34 +5747,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", - "synstructure 0.13.2", + "syn 2.0.104", + "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.104", ] [[package]] @@ -7783,48 +5794,15 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", - "synstructure 0.13.2", + "syn 2.0.104", + "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" [[package]] name = "zip" @@ -7848,22 +5826,19 @@ dependencies = [ [[package]] name = "zip" -version = "7.4.0" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc12baa6db2b15a140161ce53d72209dacea594230798c24774139b54ecaa980" +checksum = "9cc23c04387f4da0374be4533ad1208cbb091d5c11d070dfef13676ad6497164" dependencies = [ + "arbitrary", "crc32fast", + "crossbeam-utils", + "displaydoc", "indexmap", - "memchr", - "typed-path", + "num_enum", + "thiserror 1.0.69", ] -[[package]] -name = "zmij" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" - [[package]] name = "zstd" version = "0.11.2+zstd.1.5.2" @@ -7885,9 +5860,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", @@ -7899,12 +5874,6 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" -[[package]] -name = "zune-core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" - [[package]] name = "zune-inflate" version = "0.2.54" @@ -7916,18 +5885,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.21" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" +checksum = "7384255a918371b5af158218d131530f694de9ad3815ebdd0453a940485cb0fa" dependencies = [ - "zune-core 0.4.12", -] - -[[package]] -name = "zune-jpeg" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410e9ecef634c709e3831c2cfdb8d9c32164fae1c67496d5b68fff728eec37fe" -dependencies = [ - "zune-core 0.5.1", + "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index b9e6d45..6068644 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,4 @@ [workspace] resolver = "2" -members = ["client_cli", "bot", "store"] +members = ["client_tui", "client_cli", "bot", "server", "store"] diff --git a/README.md b/README.md index e5a0f39..d2808fa 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,7 @@ # Trictrac -This is a game of [Trictrac](https://en.wikipedia.org/wiki/Trictrac) rust implementation. +Game of [Trictrac](https://en.wikipedia.org/wiki/Trictrac) in rust. -The project is on its early stages. -Rules (without "schools") are implemented, as well as a rudimentary terminal interface which allow you to play against a bot which plays randomly. +wip -Training of AI bots is the work in progress. -## Usage - -`cargo run --bin=client_cli -- --bot random` - -## Roadmap - -- [x] rules -- [x] command line interface -- [x] basic bot (random play) -- [ ] AI bot -- [ ] network game -- [ ] web client - -## Code structure - -- game rules and game state are implemented in the _store/_ folder. -- the command-line application is implemented in _client_cli/_; it allows you to play against a bot, or to have two bots play against each other -- the bots algorithms and the training of their models are implemented in the _bot/_ folder - -### _store_ package - -The game state is defined by the `GameState` struct in _store/src/game.rs_. The `to_string_id()` method allows this state to be encoded compactly in a string (without the played moves history). For a more readable textual representation, the `fmt::Display` trait is implemented. - -### _client_cli_ package - -`client_cli/src/game_runner.rs` contains the logic to make two bots play against each other. - -### _bot_ package - -- `bot/src/strategy/default.rs` contains the code for a basic bot strategy: it determines the list of valid moves (using the `get_possible_moves_sequences` method of `store::MoveRules`) and simply executes the first move in the list. -- `bot/src/strategy/dqnburn.rs` is another bot strategy that uses a reinforcement learning trained model with the DQN algorithm via the burn library (). -- `bot/scripts/trains.sh` allows you to train agents using different algorithms (DQN, PPO, SAC). diff --git a/bot/Cargo.toml b/bot/Cargo.toml index de957df..135deae 100644 --- a/bot/Cargo.toml +++ b/bot/Cargo.toml @@ -1,24 +1,29 @@ [package] -name = "trictrac-bot" +name = "bot" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [[bin]] -name = "burn_train" -path = "src/burnrl/main.rs" +name = "train_dqn_burn_valid" +path = "src/dqn/burnrl_valid/main.rs" + +[[bin]] +name = "train_dqn_burn" +path = "src/dqn/burnrl/main.rs" + +[[bin]] +name = "train_dqn_simple" +path = "src/dqn/simple/main.rs" [dependencies] pretty_assertions = "1.4.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -trictrac-store = { path = "../store" } -rand = "0.9" +store = { path = "../store" } +rand = "0.8" env_logger = "0.10" -burn = { version = "0.20", features = ["ndarray", "autodiff"] } +burn = { version = "0.17", features = ["ndarray", "autodiff"] } burn-rl = { git = "https://github.com/yunjhongwu/burn-rl-examples.git", package = "burn-rl" } log = "0.4.20" -confy = "1.0.0" -board-game = "0.8.2" -internal-iterator = "0.2.3" diff --git a/bot/python/test.py b/bot/python/test.py deleted file mode 100644 index 8c4f16b..0000000 --- a/bot/python/test.py +++ /dev/null @@ -1,5 +0,0 @@ -import trictrac_store - -game = trictrac_store.TricTrac() -print(game.current_player_idx()) -print(game.get_legal_actions(game.current_player_idx())) diff --git a/bot/scripts/train.sh b/bot/scripts/train.sh index d96e690..78e7e3f 100755 --- a/bot/scripts/train.sh +++ b/bot/scripts/train.sh @@ -1,50 +1,38 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ROOT="$(cd "$(dirname "$0")" && pwd)/../.." LOGS_DIR="$ROOT/bot/models/logs" -CFG_SIZE=17 -BINBOT=burn_train -# BINBOT=train_ppo_burn -# BINBOT=train_dqn_burn -# BINBOT=train_dqn_burn_big -# BINBOT=train_dqn_burn_before +CFG_SIZE=12 OPPONENT="random" PLOT_EXT="png" train() { - ALGO=$1 - cargo build --release --bin=$BINBOT - NAME="$(date +%Y-%m-%d_%H:%M:%S)" - LOGS="$LOGS_DIR/$ALGO/$NAME.out" - mkdir -p "$LOGS_DIR/$ALGO" - LD_LIBRARY_PATH="$ROOT/target/release" "$ROOT/target/release/$BINBOT" $ALGO | tee "$LOGS" + cargo build --release --bin=train_dqn_burn + NAME="train_$(date +%Y-%m-%d_%H:%M:%S)" + LOGS="$LOGS_DIR/$NAME.out" + mkdir -p "$LOGS_DIR" + LD_LIBRARY_PATH="$ROOT/target/release" "$ROOT/target/release/train_dqn_burn" | tee "$LOGS" } plot() { - ALGO=$1 - NAME=$(ls -rt "$LOGS_DIR/$ALGO" | grep -v png | tail -n 1) - LOGS="$LOGS_DIR/$ALGO/$NAME" - cfgs=$(grep -v "info:" "$LOGS" | head -n $CFG_SIZE) + NAME=$(ls "$LOGS_DIR" | tail -n 1) + LOGS="$LOGS_DIR/$NAME" + cfgs=$(head -n $CFG_SIZE "$LOGS") for cfg in $cfgs; do eval "$cfg" done + # tail -n +$((CFG_SIZE + 2)) "$LOGS" tail -n +$((CFG_SIZE + 2)) "$LOGS" | grep -v "info:" | awk -F '[ ,]' '{print $5}' | - feedgnuplot --lines --points --unset grid --title "adv = $OPPONENT ; density = $dense_size ; decay = $eps_decay ; max steps = $max_steps" --terminal $PLOT_EXT >"$LOGS_DIR/$ALGO/$NAME.$PLOT_EXT" + feedgnuplot --lines --points --unset grid --title "adv = $OPPONENT ; density = $dense_size ; decay = $eps_decay ; max steps = $max_steps" --terminal $PLOT_EXT >"$LOGS_DIR/$OPPONENT-$dense_size-$eps_decay-$max_steps-$NAME.$PLOT_EXT" } -if [[ -z "$1" ]]; then - echo "Usage : train [plot] " -elif [ "$1" = "plot" ]; then - if [[ -z "$2" ]]; then - echo "Usage : train [plot] " - else - plot $2 - fi +if [ "$1" = "plot" ]; then + plot else - train $1 + train fi diff --git a/bot/scripts/trainValid.sh b/bot/scripts/trainValid.sh index 55424a2..349517d 100755 --- a/bot/scripts/trainValid.sh +++ b/bot/scripts/trainValid.sh @@ -17,7 +17,7 @@ train() { } plot() { - NAME=$(ls -rt "$LOGS_DIR" | grep -v "png" | tail -n 1) + NAME=$(ls "$LOGS_DIR" | tail -n 1) LOGS="$LOGS_DIR/$NAME" cfgs=$(head -n $CFG_SIZE "$LOGS") for cfg in $cfgs; do @@ -31,19 +31,8 @@ plot() { feedgnuplot --lines --points --unset grid --title "adv = $OPPONENT ; density = $dense_size ; decay = $eps_decay ; max steps = $max_steps" --terminal $PLOT_EXT >"$LOGS_DIR/$OPPONENT-$dense_size-$eps_decay-$max_steps-$NAME.$PLOT_EXT" } -avg() { - NAME=$(ls -rt "$LOGS_DIR" | grep -v "png" | tail -n 1) - LOGS="$LOGS_DIR/$NAME" - echo $LOGS - tail -n +$((CFG_SIZE + 2)) "$LOGS" | - grep -v "info:" | - awk -F '[ ,]' '{print $5}' | awk '{ sum += $1; n++ } END { if (n > 0) print sum / n; }' -} - if [ "$1" = "plot" ]; then plot -elif [ "$1" = "avg" ]; then - avg else train fi diff --git a/bot/src/burnrl/algos/mod.rs b/bot/src/burnrl/algos/mod.rs deleted file mode 100644 index 5a67dfc..0000000 --- a/bot/src/burnrl/algos/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod dqn; -pub mod dqn_valid; -pub mod ppo; -pub mod ppo_valid; -pub mod sac; -pub mod sac_valid; diff --git a/bot/src/burnrl/algos/ppo.rs b/bot/src/burnrl/algos/ppo.rs deleted file mode 100644 index df6818c..0000000 --- a/bot/src/burnrl/algos/ppo.rs +++ /dev/null @@ -1,191 +0,0 @@ -use crate::burnrl::environment::TrictracEnvironment; -use crate::burnrl::utils::Config; -use burn::backend::{ndarray::NdArrayDevice, NdArray}; -use burn::module::Module; -use burn::nn::{Initializer, Linear, LinearConfig}; -use burn::optim::AdamWConfig; -use burn::record::{CompactRecorder, Recorder}; -use burn::tensor::activation::{relu, softmax}; -use burn::tensor::backend::{AutodiffBackend, Backend}; -use burn::tensor::Tensor; -use burn_rl::agent::{PPOModel, PPOOutput, PPOTrainingConfig, PPO}; -use burn_rl::base::{Action, Agent, ElemType, Environment, Memory, Model, State}; -use std::env; -use std::fs; -use std::time::SystemTime; - -#[derive(Module, Debug)] -pub struct Net { - linear: Linear, - linear_actor: Linear, - linear_critic: Linear, -} - -impl Net { - #[allow(unused)] - pub fn new(input_size: usize, dense_size: usize, output_size: usize) -> Self { - let initializer = Initializer::XavierUniform { gain: 1.0 }; - Self { - linear: LinearConfig::new(input_size, dense_size) - .with_initializer(initializer.clone()) - .init(&Default::default()), - linear_actor: LinearConfig::new(dense_size, output_size) - .with_initializer(initializer.clone()) - .init(&Default::default()), - linear_critic: LinearConfig::new(dense_size, 1) - .with_initializer(initializer) - .init(&Default::default()), - } - } -} - -impl Model, PPOOutput, Tensor> for Net { - fn forward(&self, input: Tensor) -> PPOOutput { - let layer_0_output = relu(self.linear.forward(input)); - let policies = softmax(self.linear_actor.forward(layer_0_output.clone()), 1); - let values = self.linear_critic.forward(layer_0_output); - - PPOOutput::::new(policies, values) - } - - fn infer(&self, input: Tensor) -> Tensor { - let layer_0_output = relu(self.linear.forward(input)); - softmax(self.linear_actor.forward(layer_0_output.clone()), 1) - } -} - -impl PPOModel for Net {} -#[allow(unused)] -const MEMORY_SIZE: usize = 512; - -type MyAgent = PPO>; - -#[allow(unused)] -pub fn run< - E: Environment + AsMut, - B: AutodiffBackend, ->( - conf: &Config, - visualized: bool, - // ) -> PPO> { -) -> impl Agent { - let mut env = E::new(visualized); - env.as_mut().max_steps = conf.max_steps; - - let mut model = Net::::new( - <::StateType as State>::size(), - conf.dense_size, - <::ActionType as Action>::size(), - ); - let agent = MyAgent::default(); - let config = PPOTrainingConfig { - gamma: conf.gamma, - lambda: conf.lambda, - epsilon_clip: conf.epsilon_clip, - critic_weight: conf.critic_weight, - entropy_weight: conf.entropy_weight, - learning_rate: conf.learning_rate, - epochs: conf.epochs, - batch_size: conf.batch_size, - clip_grad: Some(burn::grad_clipping::GradientClippingConfig::Value( - conf.clip_grad, - )), - }; - - let mut optimizer = AdamWConfig::new() - .with_grad_clipping(config.clip_grad.clone()) - .init(); - let mut memory = Memory::::default(); - for episode in 0..conf.num_episodes { - let mut episode_done = false; - let mut episode_reward = 0.0; - let mut episode_duration = 0_usize; - let mut now = SystemTime::now(); - - env.reset(); - while !episode_done { - let state = env.state(); - if let Some(action) = MyAgent::::react_with_model(&state, &model) { - let snapshot = env.step(action); - episode_reward += <::RewardType as Into>::into( - snapshot.reward().clone(), - ); - - memory.push( - state, - *snapshot.state(), - action, - snapshot.reward().clone(), - snapshot.done(), - ); - - episode_duration += 1; - episode_done = snapshot.done() || episode_duration >= conf.max_steps; - } - } - println!( - "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"duration\": {}}}", - now.elapsed().unwrap().as_secs(), - ); - - now = SystemTime::now(); - model = MyAgent::train::(model, &memory, &mut optimizer, &config); - memory.clear(); - } - - if let Some(path) = &conf.save_path { - let device = NdArrayDevice::default(); - let recorder = CompactRecorder::new(); - let tmp_path = env::temp_dir().join("tmp_model.mpk"); - - // Save the trained model (backend B) to a temporary file - recorder - .record(model.clone().into_record(), tmp_path.clone()) - .expect("Failed to save temporary model"); - - // Create a new model instance with the target backend (NdArray) - let model_to_save: Net> = Net::new( - <::StateType as State>::size(), - conf.dense_size, - <::ActionType as Action>::size(), - ); - - // Load the record from the temporary file into the new model - let record = recorder - .load(tmp_path.clone(), &device) - .expect("Failed to load temporary model"); - let model_with_loaded_weights = model_to_save.load_record(record); - - // Clean up the temporary file - fs::remove_file(tmp_path).expect("Failed to remove temporary model file"); - - save_model(&model_with_loaded_weights, path); - } - agent.valid(model) -} - -pub fn save_model(model: &Net>, path: &String) { - let recorder = CompactRecorder::new(); - let model_path = format!("{path}.mpk"); - println!("info: Modèle de validation sauvegardé : {model_path}"); - recorder - .record(model.clone().into_record(), model_path.into()) - .unwrap(); -} - -pub fn load_model(dense_size: usize, path: &String) -> Option>> { - let model_path = format!("{path}.mpk"); - // println!("Chargement du modèle depuis : {model_path}"); - - CompactRecorder::new() - .load(model_path.into(), &NdArrayDevice::default()) - .map(|record| { - Net::new( - ::StateType::size(), - dense_size, - ::ActionType::size(), - ) - .load_record(record) - }) - .ok() -} diff --git a/bot/src/burnrl/algos/ppo_valid.rs b/bot/src/burnrl/algos/ppo_valid.rs deleted file mode 100644 index 8a391fb..0000000 --- a/bot/src/burnrl/algos/ppo_valid.rs +++ /dev/null @@ -1,191 +0,0 @@ -use crate::burnrl::environment_valid::TrictracEnvironment; -use crate::burnrl::utils::Config; -use burn::backend::{ndarray::NdArrayDevice, NdArray}; -use burn::module::Module; -use burn::nn::{Initializer, Linear, LinearConfig}; -use burn::optim::AdamWConfig; -use burn::record::{CompactRecorder, Recorder}; -use burn::tensor::activation::{relu, softmax}; -use burn::tensor::backend::{AutodiffBackend, Backend}; -use burn::tensor::Tensor; -use burn_rl::agent::{PPOModel, PPOOutput, PPOTrainingConfig, PPO}; -use burn_rl::base::{Action, Agent, ElemType, Environment, Memory, Model, State}; -use std::env; -use std::fs; -use std::time::SystemTime; - -#[derive(Module, Debug)] -pub struct Net { - linear: Linear, - linear_actor: Linear, - linear_critic: Linear, -} - -impl Net { - #[allow(unused)] - pub fn new(input_size: usize, dense_size: usize, output_size: usize) -> Self { - let initializer = Initializer::XavierUniform { gain: 1.0 }; - Self { - linear: LinearConfig::new(input_size, dense_size) - .with_initializer(initializer.clone()) - .init(&Default::default()), - linear_actor: LinearConfig::new(dense_size, output_size) - .with_initializer(initializer.clone()) - .init(&Default::default()), - linear_critic: LinearConfig::new(dense_size, 1) - .with_initializer(initializer) - .init(&Default::default()), - } - } -} - -impl Model, PPOOutput, Tensor> for Net { - fn forward(&self, input: Tensor) -> PPOOutput { - let layer_0_output = relu(self.linear.forward(input)); - let policies = softmax(self.linear_actor.forward(layer_0_output.clone()), 1); - let values = self.linear_critic.forward(layer_0_output); - - PPOOutput::::new(policies, values) - } - - fn infer(&self, input: Tensor) -> Tensor { - let layer_0_output = relu(self.linear.forward(input)); - softmax(self.linear_actor.forward(layer_0_output.clone()), 1) - } -} - -impl PPOModel for Net {} -#[allow(unused)] -const MEMORY_SIZE: usize = 512; - -type MyAgent = PPO>; - -#[allow(unused)] -pub fn run< - E: Environment + AsMut, - B: AutodiffBackend, ->( - conf: &Config, - visualized: bool, - // ) -> PPO> { -) -> impl Agent { - let mut env = E::new(visualized); - env.as_mut().max_steps = conf.max_steps; - - let mut model = Net::::new( - <::StateType as State>::size(), - conf.dense_size, - <::ActionType as Action>::size(), - ); - let agent = MyAgent::default(); - let config = PPOTrainingConfig { - gamma: conf.gamma, - lambda: conf.lambda, - epsilon_clip: conf.epsilon_clip, - critic_weight: conf.critic_weight, - entropy_weight: conf.entropy_weight, - learning_rate: conf.learning_rate, - epochs: conf.epochs, - batch_size: conf.batch_size, - clip_grad: Some(burn::grad_clipping::GradientClippingConfig::Value( - conf.clip_grad, - )), - }; - - let mut optimizer = AdamWConfig::new() - .with_grad_clipping(config.clip_grad.clone()) - .init(); - let mut memory = Memory::::default(); - for episode in 0..conf.num_episodes { - let mut episode_done = false; - let mut episode_reward = 0.0; - let mut episode_duration = 0_usize; - let mut now = SystemTime::now(); - - env.reset(); - while !episode_done { - let state = env.state(); - if let Some(action) = MyAgent::::react_with_model(&state, &model) { - let snapshot = env.step(action); - episode_reward += <::RewardType as Into>::into( - snapshot.reward().clone(), - ); - - memory.push( - state, - *snapshot.state(), - action, - snapshot.reward().clone(), - snapshot.done(), - ); - - episode_duration += 1; - episode_done = snapshot.done() || episode_duration >= conf.max_steps; - } - } - println!( - "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"duration\": {}}}", - now.elapsed().unwrap().as_secs(), - ); - - now = SystemTime::now(); - model = MyAgent::train::(model, &memory, &mut optimizer, &config); - memory.clear(); - } - - if let Some(path) = &conf.save_path { - let device = NdArrayDevice::default(); - let recorder = CompactRecorder::new(); - let tmp_path = env::temp_dir().join("tmp_model.mpk"); - - // Save the trained model (backend B) to a temporary file - recorder - .record(model.clone().into_record(), tmp_path.clone()) - .expect("Failed to save temporary model"); - - // Create a new model instance with the target backend (NdArray) - let model_to_save: Net> = Net::new( - <::StateType as State>::size(), - conf.dense_size, - <::ActionType as Action>::size(), - ); - - // Load the record from the temporary file into the new model - let record = recorder - .load(tmp_path.clone(), &device) - .expect("Failed to load temporary model"); - let model_with_loaded_weights = model_to_save.load_record(record); - - // Clean up the temporary file - fs::remove_file(tmp_path).expect("Failed to remove temporary model file"); - - save_model(&model_with_loaded_weights, path); - } - agent.valid(model) -} - -pub fn save_model(model: &Net>, path: &String) { - let recorder = CompactRecorder::new(); - let model_path = format!("{path}.mpk"); - println!("info: Modèle de validation sauvegardé : {model_path}"); - recorder - .record(model.clone().into_record(), model_path.into()) - .unwrap(); -} - -pub fn load_model(dense_size: usize, path: &String) -> Option>> { - let model_path = format!("{path}.mpk"); - // println!("Chargement du modèle depuis : {model_path}"); - - CompactRecorder::new() - .load(model_path.into(), &NdArrayDevice::default()) - .map(|record| { - Net::new( - ::StateType::size(), - dense_size, - ::ActionType::size(), - ) - .load_record(record) - }) - .ok() -} diff --git a/bot/src/burnrl/algos/sac.rs b/bot/src/burnrl/algos/sac.rs deleted file mode 100644 index 67db72a..0000000 --- a/bot/src/burnrl/algos/sac.rs +++ /dev/null @@ -1,221 +0,0 @@ -use crate::burnrl::environment::TrictracEnvironment; -use crate::burnrl::utils::{soft_update_linear, Config}; -use burn::backend::{ndarray::NdArrayDevice, NdArray}; -use burn::module::Module; -use burn::nn::{Linear, LinearConfig}; -use burn::optim::AdamWConfig; -use burn::record::{CompactRecorder, Recorder}; -use burn::tensor::activation::{relu, softmax}; -use burn::tensor::backend::{AutodiffBackend, Backend}; -use burn::tensor::Tensor; -use burn_rl::agent::{SACActor, SACCritic, SACNets, SACOptimizer, SACTrainingConfig, SAC}; -use burn_rl::base::{Action, Agent, ElemType, Environment, Memory, Model, State}; -use std::time::SystemTime; - -#[derive(Module, Debug)] -pub struct Actor { - linear_0: Linear, - linear_1: Linear, - linear_2: Linear, -} - -impl Actor { - pub fn new(input_size: usize, dense_size: usize, output_size: usize) -> Self { - Self { - linear_0: LinearConfig::new(input_size, dense_size).init(&Default::default()), - linear_1: LinearConfig::new(dense_size, dense_size).init(&Default::default()), - linear_2: LinearConfig::new(dense_size, output_size).init(&Default::default()), - } - } -} - -impl Model, Tensor> for Actor { - fn forward(&self, input: Tensor) -> Tensor { - let layer_0_output = relu(self.linear_0.forward(input)); - let layer_1_output = relu(self.linear_1.forward(layer_0_output)); - - softmax(self.linear_2.forward(layer_1_output), 1) - } - - fn infer(&self, input: Tensor) -> Tensor { - self.forward(input) - } -} - -impl SACActor for Actor {} - -#[derive(Module, Debug)] -pub struct Critic { - linear_0: Linear, - linear_1: Linear, - linear_2: Linear, -} - -impl Critic { - pub fn new(input_size: usize, dense_size: usize, output_size: usize) -> Self { - Self { - linear_0: LinearConfig::new(input_size, dense_size).init(&Default::default()), - linear_1: LinearConfig::new(dense_size, dense_size).init(&Default::default()), - linear_2: LinearConfig::new(dense_size, output_size).init(&Default::default()), - } - } - - fn consume(self) -> (Linear, Linear, Linear) { - (self.linear_0, self.linear_1, self.linear_2) - } -} - -impl Model, Tensor> for Critic { - fn forward(&self, input: Tensor) -> Tensor { - let layer_0_output = relu(self.linear_0.forward(input)); - let layer_1_output = relu(self.linear_1.forward(layer_0_output)); - - self.linear_2.forward(layer_1_output) - } - - fn infer(&self, input: Tensor) -> Tensor { - self.forward(input) - } -} - -impl SACCritic for Critic { - fn soft_update(this: Self, that: &Self, tau: ElemType) -> Self { - let (linear_0, linear_1, linear_2) = this.consume(); - - Self { - linear_0: soft_update_linear(linear_0, &that.linear_0, tau), - linear_1: soft_update_linear(linear_1, &that.linear_1, tau), - linear_2: soft_update_linear(linear_2, &that.linear_2, tau), - } - } -} - -#[allow(unused)] -const MEMORY_SIZE: usize = 4096; - -type MyAgent = SAC>; - -#[allow(unused)] -pub fn run< - E: Environment + AsMut, - B: AutodiffBackend, ->( - conf: &Config, - visualized: bool, -) -> impl Agent { - let mut env = E::new(visualized); - env.as_mut().max_steps = conf.max_steps; - let state_dim = <::StateType as State>::size(); - let action_dim = <::ActionType as Action>::size(); - - let actor = Actor::::new(state_dim, conf.dense_size, action_dim); - let critic_1 = Critic::::new(state_dim, conf.dense_size, action_dim); - let critic_2 = Critic::::new(state_dim, conf.dense_size, action_dim); - let mut nets = SACNets::, Critic>::new(actor, critic_1, critic_2); - - let mut agent = MyAgent::default(); - - let config = SACTrainingConfig { - gamma: conf.gamma, - tau: conf.tau, - learning_rate: conf.learning_rate, - min_probability: conf.min_probability, - batch_size: conf.batch_size, - clip_grad: Some(burn::grad_clipping::GradientClippingConfig::Value( - conf.clip_grad, - )), - }; - - let mut memory = Memory::::default(); - - let optimizer_config = AdamWConfig::new().with_grad_clipping(config.clip_grad.clone()); - - let mut optimizer = SACOptimizer::new( - optimizer_config.clone().init(), - optimizer_config.clone().init(), - optimizer_config.clone().init(), - optimizer_config.init(), - ); - - let mut step = 0_usize; - - for episode in 0..conf.num_episodes { - let mut episode_done = false; - let mut episode_reward = 0.0; - let mut episode_duration = 0_usize; - let mut state = env.state(); - let mut now = SystemTime::now(); - - while !episode_done { - if let Some(action) = MyAgent::::react_with_model(&state, &nets.actor) { - let snapshot = env.step(action); - - episode_reward += <::RewardType as Into>::into( - snapshot.reward().clone(), - ); - - memory.push( - state, - *snapshot.state(), - action, - snapshot.reward().clone(), - snapshot.done(), - ); - - if config.batch_size < memory.len() { - nets = agent.train::(nets, &memory, &mut optimizer, &config); - } - - step += 1; - episode_duration += 1; - - if snapshot.done() || episode_duration >= conf.max_steps { - env.reset(); - episode_done = true; - - println!( - "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"duration\": {}}}", - now.elapsed().unwrap().as_secs() - ); - now = SystemTime::now(); - } else { - state = *snapshot.state(); - } - } - } - } - - let valid_agent = agent.valid(nets.actor); - if let Some(path) = &conf.save_path { - if let Some(model) = valid_agent.model() { - save_model(model, path); - } - } - valid_agent -} - -pub fn save_model(model: &Actor>, path: &String) { - let recorder = CompactRecorder::new(); - let model_path = format!("{path}.mpk"); - println!("info: Modèle de validation sauvegardé : {model_path}"); - recorder - .record(model.clone().into_record(), model_path.into()) - .unwrap(); -} - -pub fn load_model(dense_size: usize, path: &String) -> Option>> { - let model_path = format!("{path}.mpk"); - // println!("Chargement du modèle depuis : {model_path}"); - - CompactRecorder::new() - .load(model_path.into(), &NdArrayDevice::default()) - .map(|record| { - Actor::new( - ::StateType::size(), - dense_size, - ::ActionType::size(), - ) - .load_record(record) - }) - .ok() -} \ No newline at end of file diff --git a/bot/src/burnrl/algos/sac_valid.rs b/bot/src/burnrl/algos/sac_valid.rs deleted file mode 100644 index 81523c4..0000000 --- a/bot/src/burnrl/algos/sac_valid.rs +++ /dev/null @@ -1,222 +0,0 @@ -use crate::burnrl::environment_valid::TrictracEnvironment; -use crate::burnrl::utils::{soft_update_linear, Config}; -use burn::backend::{ndarray::NdArrayDevice, NdArray}; -use burn::module::Module; -use burn::nn::{Linear, LinearConfig}; -use burn::optim::AdamWConfig; -use burn::record::{CompactRecorder, Recorder}; -use burn::tensor::activation::{relu, softmax}; -use burn::tensor::backend::{AutodiffBackend, Backend}; -use burn::tensor::Tensor; -use burn_rl::agent::{SACActor, SACCritic, SACNets, SACOptimizer, SACTrainingConfig, SAC}; -use burn_rl::base::{Action, Agent, ElemType, Environment, Memory, Model, State}; -use std::time::SystemTime; - -#[derive(Module, Debug)] -pub struct Actor { - linear_0: Linear, - linear_1: Linear, - linear_2: Linear, -} - -impl Actor { - pub fn new(input_size: usize, dense_size: usize, output_size: usize) -> Self { - Self { - linear_0: LinearConfig::new(input_size, dense_size).init(&Default::default()), - linear_1: LinearConfig::new(dense_size, dense_size).init(&Default::default()), - linear_2: LinearConfig::new(dense_size, output_size).init(&Default::default()), - } - } -} - -impl Model, Tensor> for Actor { - fn forward(&self, input: Tensor) -> Tensor { - let layer_0_output = relu(self.linear_0.forward(input)); - let layer_1_output = relu(self.linear_1.forward(layer_0_output)); - - softmax(self.linear_2.forward(layer_1_output), 1) - } - - fn infer(&self, input: Tensor) -> Tensor { - self.forward(input) - } -} - -impl SACActor for Actor {} - -#[derive(Module, Debug)] -pub struct Critic { - linear_0: Linear, - linear_1: Linear, - linear_2: Linear, -} - -impl Critic { - pub fn new(input_size: usize, dense_size: usize, output_size: usize) -> Self { - Self { - linear_0: LinearConfig::new(input_size, dense_size).init(&Default::default()), - linear_1: LinearConfig::new(dense_size, dense_size).init(&Default::default()), - linear_2: LinearConfig::new(dense_size, output_size).init(&Default::default()), - } - } - - fn consume(self) -> (Linear, Linear, Linear) { - (self.linear_0, self.linear_1, self.linear_2) - } -} - -impl Model, Tensor> for Critic { - fn forward(&self, input: Tensor) -> Tensor { - let layer_0_output = relu(self.linear_0.forward(input)); - let layer_1_output = relu(self.linear_1.forward(layer_0_output)); - - self.linear_2.forward(layer_1_output) - } - - fn infer(&self, input: Tensor) -> Tensor { - self.forward(input) - } -} - -impl SACCritic for Critic { - fn soft_update(this: Self, that: &Self, tau: ElemType) -> Self { - let (linear_0, linear_1, linear_2) = this.consume(); - - Self { - linear_0: soft_update_linear(linear_0, &that.linear_0, tau), - linear_1: soft_update_linear(linear_1, &that.linear_1, tau), - linear_2: soft_update_linear(linear_2, &that.linear_2, tau), - } - } -} - -#[allow(unused)] -const MEMORY_SIZE: usize = 4096; - -type MyAgent = SAC>; - -#[allow(unused)] -pub fn run< - E: Environment + AsMut, - B: AutodiffBackend, ->( - conf: &Config, - visualized: bool, -) -> impl Agent { - let mut env = E::new(visualized); - env.as_mut().max_steps = conf.max_steps; - let state_dim = <::StateType as State>::size(); - let action_dim = <::ActionType as Action>::size(); - - let actor = Actor::::new(state_dim, conf.dense_size, action_dim); - let critic_1 = Critic::::new(state_dim, conf.dense_size, action_dim); - let critic_2 = Critic::::new(state_dim, conf.dense_size, action_dim); - let mut nets = SACNets::, Critic>::new(actor, critic_1, critic_2); - - let mut agent = MyAgent::default(); - - let config = SACTrainingConfig { - gamma: conf.gamma, - tau: conf.tau, - learning_rate: conf.learning_rate, - min_probability: conf.min_probability, - batch_size: conf.batch_size, - clip_grad: Some(burn::grad_clipping::GradientClippingConfig::Value( - conf.clip_grad, - )), - }; - - let mut memory = Memory::::default(); - - let optimizer_config = AdamWConfig::new().with_grad_clipping(config.clip_grad.clone()); - - let mut optimizer = SACOptimizer::new( - optimizer_config.clone().init(), - optimizer_config.clone().init(), - optimizer_config.clone().init(), - optimizer_config.init(), - ); - - let mut step = 0_usize; - - for episode in 0..conf.num_episodes { - let mut episode_done = false; - let mut episode_reward = 0.0; - let mut episode_duration = 0_usize; - let mut state = env.state(); - let mut now = SystemTime::now(); - - while !episode_done { - if let Some(action) = MyAgent::::react_with_model(&state, &nets.actor) { - let snapshot = env.step(action); - - episode_reward += <::RewardType as Into>::into( - snapshot.reward().clone(), - ); - - memory.push( - state, - *snapshot.state(), - action, - snapshot.reward().clone(), - snapshot.done(), - ); - - if config.batch_size < memory.len() { - nets = agent.train::(nets, &memory, &mut optimizer, &config); - } - - step += 1; - episode_duration += 1; - - if snapshot.done() || episode_duration >= conf.max_steps { - env.reset(); - episode_done = true; - - println!( - "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"duration\": {}}}", - now.elapsed().unwrap().as_secs() - ); - now = SystemTime::now(); - } else { - state = *snapshot.state(); - } - } - } - } - - let valid_agent = agent.valid(nets.actor); - if let Some(path) = &conf.save_path { - if let Some(model) = valid_agent.model() { - save_model(model, path); - } - } - valid_agent -} - -pub fn save_model(model: &Actor>, path: &String) { - let recorder = CompactRecorder::new(); - let model_path = format!("{path}.mpk"); - println!("info: Modèle de validation sauvegardé : {model_path}"); - recorder - .record(model.clone().into_record(), model_path.into()) - .unwrap(); -} - -pub fn load_model(dense_size: usize, path: &String) -> Option>> { - let model_path = format!("{path}.mpk"); - // println!("Chargement du modèle depuis : {model_path}"); - - CompactRecorder::new() - .load(model_path.into(), &NdArrayDevice::default()) - .map(|record| { - Actor::new( - ::StateType::size(), - dense_size, - ::ActionType::size(), - ) - .load_record(record) - }) - .ok() -} - diff --git a/bot/src/burnrl/main.rs b/bot/src/burnrl/main.rs deleted file mode 100644 index 9275f59..0000000 --- a/bot/src/burnrl/main.rs +++ /dev/null @@ -1,90 +0,0 @@ -use trictrac_bot::burnrl::algos::{dqn, dqn_valid, ppo, ppo_valid, sac, sac_valid}; -use trictrac_bot::burnrl::environment::TrictracEnvironment; -use trictrac_bot::burnrl::environment_valid::TrictracEnvironment as TrictracEnvironmentValid; -use trictrac_bot::burnrl::utils::{demo_model, Config}; -use burn::backend::{Autodiff, NdArray}; -use burn_rl::base::ElemType; -use std::env; - -type Backend = Autodiff>; - -fn main() { - let args: Vec = env::args().collect(); - let algo = &args[1]; - // let dir_path = &args[2]; - - let path = format!("bot/models/burnrl_{algo}"); - println!( - "info: loading configuration from file {:?}", - confy::get_configuration_file_path("trictrac_bot", None).unwrap() - ); - let mut conf: Config = confy::load("trictrac_bot", None).expect("Could not load config"); - conf.save_path = Some(path.clone()); - println!("{conf}----------"); - - match algo.as_str() { - "dqn" => { - let _agent = dqn::run::(&conf, false); - println!("> Chargement du modèle pour test"); - let loaded_model = dqn::load_model(conf.dense_size, &path); - let loaded_agent: burn_rl::agent::DQN = - burn_rl::agent::DQN::new(loaded_model.unwrap()); - - println!("> Test avec le modèle chargé"); - demo_model(loaded_agent); - } - "dqn_valid" => { - let _agent = dqn_valid::run::(&conf, false); - println!("> Chargement du modèle pour test"); - let loaded_model = dqn_valid::load_model(conf.dense_size, &path); - let loaded_agent: burn_rl::agent::DQN = - burn_rl::agent::DQN::new(loaded_model.unwrap()); - - println!("> Test avec le modèle chargé"); - demo_model(loaded_agent); - } - "sac" => { - let _agent = sac::run::(&conf, false); - println!("> Chargement du modèle pour test"); - let loaded_model = sac::load_model(conf.dense_size, &path); - let loaded_agent: burn_rl::agent::SAC = - burn_rl::agent::SAC::new(loaded_model.unwrap()); - - println!("> Test avec le modèle chargé"); - demo_model(loaded_agent); - } - "sac_valid" => { - let _agent = sac_valid::run::(&conf, false); - println!("> Chargement du modèle pour test"); - let loaded_model = sac_valid::load_model(conf.dense_size, &path); - let loaded_agent: burn_rl::agent::SAC = - burn_rl::agent::SAC::new(loaded_model.unwrap()); - - println!("> Test avec le modèle chargé"); - demo_model(loaded_agent); - } - "ppo" => { - let _agent = ppo::run::(&conf, false); - println!("> Chargement du modèle pour test"); - let loaded_model = ppo::load_model(conf.dense_size, &path); - let loaded_agent: burn_rl::agent::PPO = - burn_rl::agent::PPO::new(loaded_model.unwrap()); - - println!("> Test avec le modèle chargé"); - demo_model(loaded_agent); - } - "ppo_valid" => { - let _agent = ppo_valid::run::(&conf, false); - println!("> Chargement du modèle pour test"); - let loaded_model = ppo_valid::load_model(conf.dense_size, &path); - let loaded_agent: burn_rl::agent::PPO = - burn_rl::agent::PPO::new(loaded_model.unwrap()); - - println!("> Test avec le modèle chargé"); - demo_model(loaded_agent); - } - &_ => { - println!("unknown algo {algo}"); - } - } -} diff --git a/bot/src/burnrl/mod.rs b/bot/src/burnrl/mod.rs deleted file mode 100644 index 292bbb8..0000000 --- a/bot/src/burnrl/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod algos; -pub mod environment; -pub mod environment_valid; -pub mod utils; diff --git a/bot/src/burnrl/utils.rs b/bot/src/burnrl/utils.rs deleted file mode 100644 index 9233819..0000000 --- a/bot/src/burnrl/utils.rs +++ /dev/null @@ -1,132 +0,0 @@ -use burn::module::{Param, ParamId}; -use burn::nn::Linear; -use burn::tensor::backend::Backend; -use burn::tensor::Tensor; -use burn_rl::base::{Agent, ElemType, Environment}; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize)] -pub struct Config { - pub save_path: Option, - pub max_steps: usize, // max steps by episode - pub num_episodes: usize, - pub dense_size: usize, // neural network complexity - - // discount factor. Plus élevé = encourage stratégies à long terme - pub gamma: f32, - // soft update rate. Taux de mise à jour du réseau cible. Plus bas = adaptation plus lente moins sensible aux coups de chance - pub tau: f32, - // taille du pas. Bas : plus lent, haut : risque de ne jamais - pub learning_rate: f32, - // nombre d'expériences passées sur lesquelles pour calcul de l'erreur moy. - pub batch_size: usize, - // limite max de correction à apporter au gradient (default 100) - pub clip_grad: f32, - - // ---- for SAC - pub min_probability: f32, - - // ---- for DQN - // epsilon initial value (0.9 => more exploration) - pub eps_start: f64, - pub eps_end: f64, - // eps_decay higher = epsilon decrease slower - // used in : epsilon = eps_end + (eps_start - eps_end) * e^(-step / eps_decay); - // epsilon is updated at the start of each episode - pub eps_decay: f64, - - // ---- for PPO - pub lambda: f32, - pub epsilon_clip: f32, - pub critic_weight: f32, - pub entropy_weight: f32, - pub epochs: usize, -} - -impl Default for Config { - fn default() -> Self { - Self { - save_path: None, - max_steps: 2000, - num_episodes: 1000, - dense_size: 256, - gamma: 0.999, - tau: 0.005, - learning_rate: 0.001, - batch_size: 32, - clip_grad: 100.0, - min_probability: 1e-9, - eps_start: 0.9, - eps_end: 0.05, - eps_decay: 1000.0, - lambda: 0.95, - epsilon_clip: 0.2, - critic_weight: 0.5, - entropy_weight: 0.01, - epochs: 8, - } - } -} - -impl std::fmt::Display for Config { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let mut s = String::new(); - s.push_str(&format!("max_steps={:?}\n", self.max_steps)); - s.push_str(&format!("num_episodes={:?}\n", self.num_episodes)); - s.push_str(&format!("dense_size={:?}\n", self.dense_size)); - s.push_str(&format!("eps_start={:?}\n", self.eps_start)); - s.push_str(&format!("eps_end={:?}\n", self.eps_end)); - s.push_str(&format!("eps_decay={:?}\n", self.eps_decay)); - s.push_str(&format!("gamma={:?}\n", self.gamma)); - s.push_str(&format!("tau={:?}\n", self.tau)); - s.push_str(&format!("learning_rate={:?}\n", self.learning_rate)); - s.push_str(&format!("batch_size={:?}\n", self.batch_size)); - s.push_str(&format!("clip_grad={:?}\n", self.clip_grad)); - s.push_str(&format!("min_probability={:?}\n", self.min_probability)); - s.push_str(&format!("lambda={:?}\n", self.lambda)); - s.push_str(&format!("epsilon_clip={:?}\n", self.epsilon_clip)); - s.push_str(&format!("critic_weight={:?}\n", self.critic_weight)); - s.push_str(&format!("entropy_weight={:?}\n", self.entropy_weight)); - s.push_str(&format!("epochs={:?}\n", self.epochs)); - write!(f, "{s}") - } -} - -pub fn demo_model(agent: impl Agent) { - let mut env = E::new(true); - let mut state = env.state(); - let mut done = false; - while !done { - if let Some(action) = agent.react(&state) { - let snapshot = env.step(action); - state = *snapshot.state(); - done = snapshot.done(); - } - } -} - -fn soft_update_tensor( - this: &Param>, - that: &Param>, - tau: ElemType, -) -> Param> { - let that_weight = that.val(); - let this_weight = this.val(); - let new_weight = this_weight * (1.0 - tau) + that_weight * tau; - - Param::initialized(ParamId::new(), new_weight) -} - -pub fn soft_update_linear( - this: Linear, - that: &Linear, - tau: ElemType, -) -> Linear { - let weight = soft_update_tensor(&this.weight, &that.weight, tau); - let bias = match (&this.bias, &that.bias) { - (Some(this_bias), Some(that_bias)) => Some(soft_update_tensor(this_bias, that_bias, tau)), - _ => None, - }; - - Linear:: { weight, bias } -} diff --git a/bot/src/burnrl/algos/dqn_valid.rs b/bot/src/dqn/burnrl/dqn_model.rs similarity index 67% rename from bot/src/burnrl/algos/dqn_valid.rs rename to bot/src/dqn/burnrl/dqn_model.rs index 6198100..3e90904 100644 --- a/bot/src/burnrl/algos/dqn_valid.rs +++ b/bot/src/dqn/burnrl/dqn_model.rs @@ -1,16 +1,15 @@ -use crate::burnrl::environment_valid::TrictracEnvironment; -use crate::burnrl::utils::{soft_update_linear, Config}; -use burn::backend::{ndarray::NdArrayDevice, NdArray}; +use crate::dqn::burnrl::environment::TrictracEnvironment; +use crate::dqn::burnrl::utils::soft_update_linear; use burn::module::Module; use burn::nn::{Linear, LinearConfig}; use burn::optim::AdamWConfig; -use burn::record::{CompactRecorder, Recorder}; use burn::tensor::activation::relu; use burn::tensor::backend::{AutodiffBackend, Backend}; use burn::tensor::Tensor; use burn_rl::agent::DQN; use burn_rl::agent::{DQNModel, DQNTrainingConfig}; -use burn_rl::base::{Action, Agent, ElemType, Environment, Memory, Model, State}; +use burn_rl::base::{Action, ElemType, Environment, Memory, Model, State}; +use std::fmt; use std::time::SystemTime; #[derive(Module, Debug)] @@ -63,19 +62,71 @@ impl DQNModel for Net { #[allow(unused)] const MEMORY_SIZE: usize = 8192; +pub struct DqnConfig { + pub min_steps: f32, + pub max_steps: usize, + pub num_episodes: usize, + pub dense_size: usize, + pub eps_start: f64, + pub eps_end: f64, + pub eps_decay: f64, + + pub gamma: f32, + pub tau: f32, + pub learning_rate: f32, + pub batch_size: usize, + pub clip_grad: f32, +} + +impl fmt::Display for DqnConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut s = String::new(); + s.push_str(&format!("min_steps={:?}\n", self.min_steps)); + s.push_str(&format!("max_steps={:?}\n", self.max_steps)); + s.push_str(&format!("num_episodes={:?}\n", self.num_episodes)); + s.push_str(&format!("dense_size={:?}\n", self.dense_size)); + s.push_str(&format!("eps_start={:?}\n", self.eps_start)); + s.push_str(&format!("eps_end={:?}\n", self.eps_end)); + s.push_str(&format!("eps_decay={:?}\n", self.eps_decay)); + s.push_str(&format!("gamma={:?}\n", self.gamma)); + s.push_str(&format!("tau={:?}\n", self.tau)); + s.push_str(&format!("learning_rate={:?}\n", self.learning_rate)); + s.push_str(&format!("batch_size={:?}\n", self.batch_size)); + s.push_str(&format!("clip_grad={:?}\n", self.clip_grad)); + write!(f, "{s}") + } +} + +impl Default for DqnConfig { + fn default() -> Self { + Self { + min_steps: 250.0, + max_steps: 2000, + num_episodes: 1000, + dense_size: 256, + eps_start: 0.9, + eps_end: 0.05, + eps_decay: 1000.0, + + gamma: 0.999, + tau: 0.005, + learning_rate: 0.001, + batch_size: 32, + clip_grad: 100.0, + } + } +} + type MyAgent = DQN>; #[allow(unused)] -// pub fn run, B: AutodiffBackend>( -pub fn run< - E: Environment + AsMut, - B: AutodiffBackend, ->( - conf: &Config, +pub fn run, B: AutodiffBackend>( + conf: &DqnConfig, visualized: bool, - // ) -> DQN> { -) -> impl Agent { +) -> DQN> { + // ) -> impl Agent { let mut env = E::new(visualized); + env.as_mut().min_steps = conf.min_steps; env.as_mut().max_steps = conf.max_steps; let model = Net::::new( @@ -143,7 +194,8 @@ pub fn run< if snapshot.done() || episode_duration >= conf.max_steps { let envmut = env.as_mut(); println!( - "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"epsilon\": {eps_threshold:.3}, \"rollpoints\":{}, \"duration\": {}}}", + "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"epsilon\": {eps_threshold:.3}, \"goodmoves\": {}, \"rollpoints\":{}, \"duration\": {}}}", + envmut.goodmoves_count, envmut.pointrolls_count, now.elapsed().unwrap().as_secs(), ); @@ -155,35 +207,5 @@ pub fn run< } } } - let valid_agent = agent.valid(); - if let Some(path) = &conf.save_path { - save_model(valid_agent.model().as_ref().unwrap(), path); - } - valid_agent -} - -pub fn save_model(model: &Net>, path: &String) { - let recorder = CompactRecorder::new(); - let model_path = format!("{path}.mpk"); - println!("info: Modèle de validation sauvegardé : {model_path}"); - recorder - .record(model.clone().into_record(), model_path.into()) - .unwrap(); -} - -pub fn load_model(dense_size: usize, path: &String) -> Option>> { - let model_path = format!("{path}.mpk"); - // println!("Chargement du modèle depuis : {model_path}"); - - CompactRecorder::new() - .load(model_path.into(), &NdArrayDevice::default()) - .map(|record| { - Net::new( - ::StateType::size(), - dense_size, - ::ActionType::size(), - ) - .load_record(record) - }) - .ok() + agent } diff --git a/bot/src/burnrl/environment.rs b/bot/src/dqn/burnrl/environment.rs similarity index 67% rename from bot/src/burnrl/environment.rs rename to bot/src/dqn/burnrl/environment.rs index 4a7bdcb..a774b12 100644 --- a/bot/src/burnrl/environment.rs +++ b/bot/src/dqn/burnrl/environment.rs @@ -1,15 +1,8 @@ -use std::io::Write; - +use crate::dqn::dqn_common; use burn::{prelude::Backend, tensor::Tensor}; use burn_rl::base::{Action, Environment, Snapshot, State}; -use rand::{rng, Rng}; -use trictrac_store::training_common; -use trictrac_store::{GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage}; - -const ERROR_REWARD: f32 = -1.0012121; -const REWARD_VALID_MOVE: f32 = 1.0012121; -const REWARD_RATIO: f32 = 0.1; -const WIN_POINTS: f32 = 100.0; +use rand::{thread_rng, Rng}; +use store::{GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage}; /// État du jeu Trictrac pour burn-rl #[derive(Debug, Clone, Copy)] @@ -52,10 +45,10 @@ pub struct TrictracAction { impl Action for TrictracAction { fn random() -> Self { - use rand::{rng, Rng}; - let mut rng = rng(); + use rand::{thread_rng, Rng}; + let mut rng = thread_rng(); TrictracAction { - index: rng.random_range(0..Self::size() as u32), + index: rng.gen_range(0..Self::size() as u32), } } @@ -66,7 +59,7 @@ impl Action for TrictracAction { } fn size() -> usize { - 514 + 1252 } } @@ -91,7 +84,7 @@ pub struct TrictracEnvironment { current_state: TrictracState, episode_reward: f32, pub step_count: usize, - pub best_ratio: f32, + pub min_steps: f32, pub max_steps: usize, pub pointrolls_count: usize, pub goodmoves_count: usize, @@ -114,7 +107,7 @@ impl Environment for TrictracEnvironment { let player2_id = 2; // Commencer la partie - let _ = game.consume(&GameEvent::BeginGame { goes_first: 1 }); + game.consume(&GameEvent::BeginGame { goes_first: 1 }); let current_state = TrictracState::from_game_state(&game); TrictracEnvironment { @@ -124,7 +117,7 @@ impl Environment for TrictracEnvironment { current_state, episode_reward: 0.0, step_count: 0, - best_ratio: 0.0, + min_steps: 250.0, max_steps: 2000, pointrolls_count: 0, goodmoves_count: 0, @@ -139,13 +132,12 @@ impl Environment for TrictracEnvironment { fn reset(&mut self) -> Snapshot { // Réinitialiser le jeu - let history = self.game.history.clone(); self.game = GameState::new(false); self.game.init_player("DQN Agent"); self.game.init_player("Opponent"); // Commencer la partie - let _ = self.game.consume(&GameEvent::BeginGame { goes_first: 1 }); + self.game.consume(&GameEvent::BeginGame { goes_first: 1 }); self.current_state = TrictracState::from_game_state(&self.game); self.episode_reward = 0.0; @@ -154,22 +146,11 @@ impl Environment for TrictracEnvironment { } else { self.goodmoves_count as f32 / self.step_count as f32 }; - self.best_ratio = self.best_ratio.max(self.goodmoves_ratio); - let _warning = if self.best_ratio > 0.7 && self.goodmoves_ratio < 0.1 { - let path = "bot/models/logs/debug.log"; - if let Ok(mut out) = std::fs::File::create(path) { - write!(out, "{history:?}").expect("could not write history log"); - } - "!!!!" - } else { - "" - }; - // println!( - // "info: correct moves: {} ({}%) {}", - // self.goodmoves_count, - // (100.0 * self.goodmoves_ratio).round() as u32, - // warning - // ); + println!( + "info: correct moves: {} ({}%)", + self.goodmoves_count, + (100.0 * self.goodmoves_ratio).round() as u32 + ); self.step_count = 0; self.pointrolls_count = 0; self.goodmoves_count = 0; @@ -184,7 +165,8 @@ impl Environment for TrictracEnvironment { let trictrac_action = Self::convert_action(action); let mut reward = 0.0; - let is_rollpoint; + let mut is_rollpoint = false; + let mut terminated = false; // Exécuter l'action si c'est le tour de l'agent DQN if self.game.active_player_id == self.active_player_id { @@ -193,13 +175,12 @@ impl Environment for TrictracEnvironment { if is_rollpoint { self.pointrolls_count += 1; } - if reward != ERROR_REWARD { + if reward != Self::ERROR_REWARD { self.goodmoves_count += 1; } } else { // Action non convertible, pénalité - panic!("action non convertible"); - //reward = -0.5; + reward = -0.5; } } @@ -209,24 +190,22 @@ impl Environment for TrictracEnvironment { } // Vérifier si la partie est terminée - // let max_steps = self.max_steps; - // let max_steps = self.min_steps - // + (self.max_steps as f32 - self.min_steps) - // * f32::exp((self.goodmoves_ratio - 1.0) / 0.25); + let max_steps = self.min_steps + + (self.max_steps as f32 - self.min_steps) + * f32::exp((self.goodmoves_ratio - 1.0) / 0.25); let done = self.game.stage == Stage::Ended || self.game.determine_winner().is_some(); if done { // Récompense finale basée sur le résultat if let Some(winner_id) = self.game.determine_winner() { if winner_id == self.active_player_id { - reward += WIN_POINTS; // Victoire + reward += 50.0; // Victoire } else { - reward -= WIN_POINTS; // Défaite + reward -= 25.0; // Défaite } } } - let terminated = done || self.step_count >= self.max_steps; - // let terminated = done || self.step_count >= max_steps.round() as usize; + let terminated = done || self.step_count >= max_steps.round() as usize; // Mettre à jour l'état self.current_state = TrictracState::from_game_state(&self.game); @@ -244,60 +223,120 @@ impl Environment for TrictracEnvironment { } impl TrictracEnvironment { + const ERROR_REWARD: f32 = -1.12121; + const REWARD_RATIO: f32 = 1.0; + /// Convertit une action burn-rl vers une action Trictrac - pub fn convert_action(action: TrictracAction) -> Option { - training_common::TrictracAction::from_action_index(action.index.try_into().unwrap()) + pub fn convert_action(action: TrictracAction) -> Option { + dqn_common::TrictracAction::from_action_index(action.index.try_into().unwrap()) } /// Convertit l'index d'une action au sein des actions valides vers une action Trictrac - #[allow(dead_code)] fn convert_valid_action_index( &self, action: TrictracAction, game_state: &GameState, - ) -> Option { - use training_common::get_valid_actions; + ) -> Option { + use dqn_common::get_valid_actions; // Obtenir les actions valides dans le contexte actuel - if let Ok(valid_actions) = get_valid_actions(game_state) { - // Mapper l'index d'action sur une action valide - let action_index = (action.index as usize) % valid_actions.len(); - Some(valid_actions[action_index].clone()) - } else { - None + let valid_actions = get_valid_actions(game_state); + + if valid_actions.is_empty() { + return None; } + + // Mapper l'index d'action sur une action valide + let action_index = (action.index as usize) % valid_actions.len(); + Some(valid_actions[action_index].clone()) } /// Exécute une action Trictrac dans le jeu // fn execute_action( // &mut self, - // action: training_common::TrictracAction, + // action: dqn_common::TrictracAction, // ) -> Result> { - fn execute_action(&mut self, action: training_common::TrictracAction) -> (f32, bool) { - use training_common::TrictracAction; + fn execute_action(&mut self, action: dqn_common::TrictracAction) -> (f32, bool) { + use dqn_common::TrictracAction; let mut reward = 0.0; let mut is_rollpoint = false; + let event = match action { + TrictracAction::Roll => { + // Lancer les dés + reward += 0.1; + Some(GameEvent::Roll { + player_id: self.active_player_id, + }) + } + // TrictracAction::Mark => { + // // Marquer des points + // let points = self.game. + // reward += 0.1 * points as f32; + // Some(GameEvent::Mark { + // player_id: self.active_player_id, + // points, + // }) + // } + TrictracAction::Go => { + // Continuer après avoir gagné un trou + reward += 0.2; + Some(GameEvent::Go { + player_id: self.active_player_id, + }) + } + TrictracAction::Move { + dice_order, + from1, + from2, + } => { + // Effectuer un mouvement + let (dice1, dice2) = if dice_order { + (self.game.dice.values.0, self.game.dice.values.1) + } else { + (self.game.dice.values.1, self.game.dice.values.0) + }; + let mut to1 = from1 + dice1 as usize; + let mut to2 = from2 + dice2 as usize; + + // Gestion prise de coin par puissance + let opp_rest_field = 13; + if to1 == opp_rest_field && to2 == opp_rest_field { + to1 -= 1; + to2 -= 1; + } + + let checker_move1 = store::CheckerMove::new(from1, to1).unwrap_or_default(); + let checker_move2 = store::CheckerMove::new(from2, to2).unwrap_or_default(); + + reward += 0.2; + Some(GameEvent::Move { + player_id: self.active_player_id, + moves: (checker_move1, checker_move2), + }) + } + }; + // Appliquer l'événement si valide - if let Some(event) = action.to_event(&self.game) { + if let Some(event) = event { if self.game.validate(&event) { - let _ = self.game.consume(&event); - // reward += REWARD_VALID_MOVE; + self.game.consume(&event); + // Simuler le résultat des dés après un Roll if matches!(action, TrictracAction::Roll) { - let mut rng = rng(); - let dice_values = (rng.random_range(1..=6), rng.random_range(1..=6)); + let mut rng = thread_rng(); + let dice_values = (rng.gen_range(1..=6), rng.gen_range(1..=6)); let dice_event = GameEvent::RollResult { player_id: self.active_player_id, - dice: trictrac_store::Dice { + dice: store::Dice { values: dice_values, }, }; if self.game.validate(&dice_event) { - let _ = self.game.consume(&dice_event); + self.game.consume(&dice_event); let (points, adv_points) = self.game.dice_points; - reward += REWARD_RATIO * (points as f32 - adv_points as f32); + reward += Self::REWARD_RATIO * (points - adv_points) as f32; if points > 0 { is_rollpoint = true; // println!("info: rolled for {reward}"); @@ -309,12 +348,8 @@ impl TrictracEnvironment { // Pénalité pour action invalide // on annule les précédents reward // et on indique une valeur reconnaissable pour statistiques - reward = ERROR_REWARD; - self.game.mark_points_for_bot_training(self.opponent_id, 1); + reward = Self::ERROR_REWARD; } - } else { - reward = ERROR_REWARD; - self.game.mark_points_for_bot_training(self.opponent_id, 1); } (reward, is_rollpoint) @@ -337,24 +372,22 @@ impl TrictracEnvironment { *strategy.get_mut_game() = self.game.clone(); // Exécuter l'action selon le turn_stage - let mut calculate_points = false; - let opponent_color = trictrac_store::Color::Black; let event = match self.game.turn_stage { TurnStage::RollDice => GameEvent::Roll { player_id: self.opponent_id, }, TurnStage::RollWaiting => { - let mut rng = rng(); - let dice_values = (rng.random_range(1..=6), rng.random_range(1..=6)); - calculate_points = true; + let mut rng = thread_rng(); + let dice_values = (rng.gen_range(1..=6), rng.gen_range(1..=6)); GameEvent::RollResult { player_id: self.opponent_id, - dice: trictrac_store::Dice { + dice: store::Dice { values: dice_values, }, } } TurnStage::MarkPoints => { + let opponent_color = store::Color::Black; let dice_roll_count = self .game .players @@ -363,13 +396,16 @@ impl TrictracEnvironment { .dice_roll_count; let points_rules = PointsRules::new(&opponent_color, &self.game.board, self.game.dice); + let (points, adv_points) = points_rules.get_points(dice_roll_count); + reward -= Self::REWARD_RATIO * (points - adv_points) as f32; // Récompense proportionnelle aux points + GameEvent::Mark { player_id: self.opponent_id, - points: points_rules.get_points(dice_roll_count).0, + points, } } TurnStage::MarkAdvPoints => { - let opponent_color = trictrac_store::Color::Black; + let opponent_color = store::Color::Black; let dice_roll_count = self .game .players @@ -378,10 +414,11 @@ impl TrictracEnvironment { .dice_roll_count; let points_rules = PointsRules::new(&opponent_color, &self.game.board, self.game.dice); + let points = points_rules.get_points(dice_roll_count).1; // pas de reward : déjà comptabilisé lors du tour de blanc GameEvent::Mark { player_id: self.opponent_id, - points: points_rules.get_points(dice_roll_count).1, + points, } } TurnStage::HoldOrGoChoice => { @@ -397,20 +434,7 @@ impl TrictracEnvironment { }; if self.game.validate(&event) { - let _ = self.game.consume(&event); - if calculate_points { - let dice_roll_count = self - .game - .players - .get(&self.opponent_id) - .unwrap() - .dice_roll_count; - let points_rules = - PointsRules::new(&opponent_color, &self.game.board, self.game.dice); - let (points, adv_points) = points_rules.get_points(dice_roll_count); - // Récompense proportionnelle aux points - reward -= REWARD_RATIO * (points as f32 - adv_points as f32); - } + self.game.consume(&event); } } reward diff --git a/bot/src/dqn/burnrl/main.rs b/bot/src/dqn/burnrl/main.rs new file mode 100644 index 0000000..d8b200f --- /dev/null +++ b/bot/src/dqn/burnrl/main.rs @@ -0,0 +1,53 @@ +use bot::dqn::burnrl::{ + dqn_model, environment, + utils::{demo_model, load_model, save_model}, +}; +use burn::backend::{Autodiff, NdArray}; +use burn_rl::agent::DQN; +use burn_rl::base::ElemType; + +type Backend = Autodiff>; +type Env = environment::TrictracEnvironment; + +fn main() { + // println!("> Entraînement"); + + // See also MEMORY_SIZE in dqn_model.rs : 8192 + let conf = dqn_model::DqnConfig { + // defaults + num_episodes: 40, // 40 + min_steps: 500.0, // 1000 min of max steps by episode (mise à jour par la fonction) + max_steps: 3000, // 1000 max steps by episode + dense_size: 256, // 128 neural network complexity (default 128) + eps_start: 0.9, // 0.9 epsilon initial value (0.9 => more exploration) + eps_end: 0.05, // 0.05 + // eps_decay higher = epsilon decrease slower + // used in : epsilon = eps_end + (eps_start - eps_end) * e^(-step / eps_decay); + // epsilon is updated at the start of each episode + eps_decay: 2000.0, // 1000 ? + + gamma: 0.999, // 0.999 discount factor. Plus élevé = encourage stratégies à long terme + tau: 0.005, // 0.005 soft update rate. Taux de mise à jour du réseau cible. Plus bas = adaptation + // plus lente moins sensible aux coups de chance + learning_rate: 0.001, // 0.001 taille du pas. Bas : plus lent, haut : risque de ne jamais + // converger + batch_size: 32, // 32 nombre d'expériences passées sur lesquelles pour calcul de l'erreur moy. + clip_grad: 100.0, // 100 limite max de correction à apporter au gradient (default 100) + }; + println!("{conf}----------"); + let agent = dqn_model::run::(&conf, false); //true); + + let valid_agent = agent.valid(); + + println!("> Sauvegarde du modèle de validation"); + + let path = "models/burn_dqn_40".to_string(); + save_model(valid_agent.model().as_ref().unwrap(), &path); + + println!("> Chargement du modèle pour test"); + let loaded_model = load_model(conf.dense_size, &path); + let loaded_agent = DQN::new(loaded_model.unwrap()); + + println!("> Test avec le modèle chargé"); + demo_model(loaded_agent); +} diff --git a/bot/src/dqn/burnrl/mod.rs b/bot/src/dqn/burnrl/mod.rs new file mode 100644 index 0000000..f4380eb --- /dev/null +++ b/bot/src/dqn/burnrl/mod.rs @@ -0,0 +1,3 @@ +pub mod dqn_model; +pub mod environment; +pub mod utils; diff --git a/bot/src/dqn/burnrl/utils.rs b/bot/src/dqn/burnrl/utils.rs new file mode 100644 index 0000000..a1d5480 --- /dev/null +++ b/bot/src/dqn/burnrl/utils.rs @@ -0,0 +1,114 @@ +use crate::dqn::burnrl::{ + dqn_model, + environment::{TrictracAction, TrictracEnvironment}, +}; +use crate::dqn::dqn_common::get_valid_action_indices; +use burn::backend::{ndarray::NdArrayDevice, Autodiff, NdArray}; +use burn::module::{Module, Param, ParamId}; +use burn::nn::Linear; +use burn::record::{CompactRecorder, Recorder}; +use burn::tensor::backend::Backend; +use burn::tensor::cast::ToElement; +use burn::tensor::Tensor; +use burn_rl::agent::{DQNModel, DQN}; +use burn_rl::base::{Action, ElemType, Environment, State}; + +pub fn save_model(model: &dqn_model::Net>, path: &String) { + let recorder = CompactRecorder::new(); + let model_path = format!("{path}_model.mpk"); + println!("Modèle de validation sauvegardé : {model_path}"); + recorder + .record(model.clone().into_record(), model_path.into()) + .unwrap(); +} + +pub fn load_model(dense_size: usize, path: &String) -> Option>> { + let model_path = format!("{path}_model.mpk"); + // println!("Chargement du modèle depuis : {model_path}"); + + CompactRecorder::new() + .load(model_path.into(), &NdArrayDevice::default()) + .map(|record| { + dqn_model::Net::new( + ::StateType::size(), + dense_size, + ::ActionType::size(), + ) + .load_record(record) + }) + .ok() +} + +pub fn demo_model>(agent: DQN) { + let mut env = TrictracEnvironment::new(true); + let mut done = false; + while !done { + // let action = match infer_action(&agent, &env, state) { + let action = match infer_action(&agent, &env) { + Some(value) => value, + None => break, + }; + // Execute action + let snapshot = env.step(action); + done = snapshot.done(); + } +} + +fn infer_action>( + agent: &DQN, + env: &TrictracEnvironment, +) -> Option { + let state = env.state(); + // Get q-values + let q_values = agent + .model() + .as_ref() + .unwrap() + .infer(state.to_tensor().unsqueeze()); + // Get valid actions + let valid_actions_indices = get_valid_action_indices(&env.game); + if valid_actions_indices.is_empty() { + return None; // No valid actions, end of episode + } + // Set non valid actions q-values to lowest + let mut masked_q_values = q_values.clone(); + let q_values_vec: Vec = q_values.into_data().into_vec().unwrap(); + for (index, q_value) in q_values_vec.iter().enumerate() { + if !valid_actions_indices.contains(&index) { + masked_q_values = masked_q_values.clone().mask_fill( + masked_q_values.clone().equal_elem(*q_value), + f32::NEG_INFINITY, + ); + } + } + // Get best action (highest q-value) + let action_index = masked_q_values.argmax(1).into_scalar().to_u32(); + let action = TrictracAction::from(action_index); + Some(action) +} + +fn soft_update_tensor( + this: &Param>, + that: &Param>, + tau: ElemType, +) -> Param> { + let that_weight = that.val(); + let this_weight = this.val(); + let new_weight = this_weight * (1.0 - tau) + that_weight * tau; + + Param::initialized(ParamId::new(), new_weight) +} + +pub fn soft_update_linear( + this: Linear, + that: &Linear, + tau: ElemType, +) -> Linear { + let weight = soft_update_tensor(&this.weight, &that.weight, tau); + let bias = match (&this.bias, &that.bias) { + (Some(this_bias), Some(that_bias)) => Some(soft_update_tensor(this_bias, that_bias, tau)), + _ => None, + }; + + Linear:: { weight, bias } +} diff --git a/bot/src/burnrl/algos/dqn.rs b/bot/src/dqn/burnrl_valid/dqn_model.rs similarity index 69% rename from bot/src/burnrl/algos/dqn.rs rename to bot/src/dqn/burnrl_valid/dqn_model.rs index efec37e..4dd5180 100644 --- a/bot/src/burnrl/algos/dqn.rs +++ b/bot/src/dqn/burnrl_valid/dqn_model.rs @@ -1,16 +1,15 @@ -use crate::burnrl::environment::TrictracEnvironment; -use crate::burnrl::utils::{soft_update_linear, Config}; -use burn::backend::{ndarray::NdArrayDevice, NdArray}; +use crate::dqn::burnrl_valid::environment::TrictracEnvironment; +use crate::dqn::burnrl_valid::utils::soft_update_linear; use burn::module::Module; use burn::nn::{Linear, LinearConfig}; use burn::optim::AdamWConfig; -use burn::record::{CompactRecorder, Recorder}; use burn::tensor::activation::relu; use burn::tensor::backend::{AutodiffBackend, Backend}; use burn::tensor::Tensor; use burn_rl::agent::DQN; use burn_rl::agent::{DQNModel, DQNTrainingConfig}; -use burn_rl::base::{Action, Agent, ElemType, Environment, Memory, Model, State}; +use burn_rl::base::{Action, ElemType, Environment, Memory, Model, State}; +use std::fmt; use std::time::SystemTime; #[derive(Module, Debug)] @@ -63,20 +62,67 @@ impl DQNModel for Net { #[allow(unused)] const MEMORY_SIZE: usize = 8192; +pub struct DqnConfig { + pub max_steps: usize, + pub num_episodes: usize, + pub dense_size: usize, + pub eps_start: f64, + pub eps_end: f64, + pub eps_decay: f64, + + pub gamma: f32, + pub tau: f32, + pub learning_rate: f32, + pub batch_size: usize, + pub clip_grad: f32, +} + +impl fmt::Display for DqnConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut s = String::new(); + s.push_str(&format!("max_steps={:?}\n", self.max_steps)); + s.push_str(&format!("num_episodes={:?}\n", self.num_episodes)); + s.push_str(&format!("dense_size={:?}\n", self.dense_size)); + s.push_str(&format!("eps_start={:?}\n", self.eps_start)); + s.push_str(&format!("eps_end={:?}\n", self.eps_end)); + s.push_str(&format!("eps_decay={:?}\n", self.eps_decay)); + s.push_str(&format!("gamma={:?}\n", self.gamma)); + s.push_str(&format!("tau={:?}\n", self.tau)); + s.push_str(&format!("learning_rate={:?}\n", self.learning_rate)); + s.push_str(&format!("batch_size={:?}\n", self.batch_size)); + s.push_str(&format!("clip_grad={:?}\n", self.clip_grad)); + write!(f, "{s}") + } +} + +impl Default for DqnConfig { + fn default() -> Self { + Self { + max_steps: 2000, + num_episodes: 1000, + dense_size: 256, + eps_start: 0.9, + eps_end: 0.05, + eps_decay: 1000.0, + + gamma: 0.999, + tau: 0.005, + learning_rate: 0.001, + batch_size: 32, + clip_grad: 100.0, + } + } +} + type MyAgent = DQN>; #[allow(unused)] -// pub fn run, B: AutodiffBackend>( -pub fn run< - E: Environment + AsMut, - B: AutodiffBackend, ->( - conf: &Config, +pub fn run, B: AutodiffBackend>( + conf: &DqnConfig, visualized: bool, - // ) -> DQN> { -) -> impl Agent { +) -> DQN> { + // ) -> impl Agent { let mut env = E::new(visualized); - // env.as_mut().min_steps = conf.min_steps; env.as_mut().max_steps = conf.max_steps; let model = Net::::new( @@ -143,13 +189,8 @@ pub fn run< if snapshot.done() || episode_duration >= conf.max_steps { let envmut = env.as_mut(); - let goodmoves_ratio = ((envmut.goodmoves_count as f32 / episode_duration as f32) - * 100.0) - .round() as u32; println!( - "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"epsilon\": {eps_threshold:.3}, \"goodmoves\": {}, \"ratio\": {}%, \"rollpoints\":{}, \"duration\": {}}}", - envmut.goodmoves_count, - goodmoves_ratio, + "{{\"episode\": {episode}, \"reward\": {episode_reward:.4}, \"steps count\": {episode_duration}, \"epsilon\": {eps_threshold:.3}, \"rollpoints\":{}, \"duration\": {}}}", envmut.pointrolls_count, now.elapsed().unwrap().as_secs(), ); @@ -161,35 +202,5 @@ pub fn run< } } } - let valid_agent = agent.valid(); - if let Some(path) = &conf.save_path { - save_model(valid_agent.model().as_ref().unwrap(), path); - } - valid_agent -} - -pub fn save_model(model: &Net>, path: &String) { - let recorder = CompactRecorder::new(); - let model_path = format!("{path}.mpk"); - println!("info: Modèle de validation sauvegardé : {model_path}"); - recorder - .record(model.clone().into_record(), model_path.into()) - .unwrap(); -} - -pub fn load_model(dense_size: usize, path: &String) -> Option>> { - let model_path = format!("{path}.mpk"); - // println!("Chargement du modèle depuis : {model_path}"); - - CompactRecorder::new() - .load(model_path.into(), &NdArrayDevice::default()) - .map(|record| { - Net::new( - ::StateType::size(), - dense_size, - ::ActionType::size(), - ) - .load_record(record) - }) - .ok() + agent } diff --git a/bot/src/burnrl/environment_valid.rs b/bot/src/dqn/burnrl_valid/environment.rs similarity index 73% rename from bot/src/burnrl/environment_valid.rs rename to bot/src/dqn/burnrl_valid/environment.rs index eaf4223..93e6c14 100644 --- a/bot/src/burnrl/environment_valid.rs +++ b/bot/src/dqn/burnrl_valid/environment.rs @@ -1,11 +1,8 @@ +use crate::dqn::dqn_common; use burn::{prelude::Backend, tensor::Tensor}; use burn_rl::base::{Action, Environment, Snapshot, State}; -use rand::{rng, Rng}; -use trictrac_store::training_common; -use trictrac_store::{GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage}; - -const ERROR_REWARD: f32 = -1.0012121; -const REWARD_RATIO: f32 = 0.1; +use rand::{thread_rng, Rng}; +use store::{GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage}; /// État du jeu Trictrac pour burn-rl #[derive(Debug, Clone, Copy)] @@ -48,10 +45,10 @@ pub struct TrictracAction { impl Action for TrictracAction { fn random() -> Self { - use rand::{rng, Rng}; - let mut rng = rng(); + use rand::{thread_rng, Rng}; + let mut rng = thread_rng(); TrictracAction { - index: rng.random_range(0..Self::size() as u32), + index: rng.gen_range(0..Self::size() as u32), } } @@ -109,7 +106,7 @@ impl Environment for TrictracEnvironment { let player2_id = 2; // Commencer la partie - let _ = game.consume(&GameEvent::BeginGame { goes_first: 1 }); + game.consume(&GameEvent::BeginGame { goes_first: 1 }); let current_state = TrictracState::from_game_state(&game); TrictracEnvironment { @@ -136,7 +133,7 @@ impl Environment for TrictracEnvironment { self.game.init_player("Opponent"); // Commencer la partie - let _ = self.game.consume(&GameEvent::BeginGame { goes_first: 1 }); + self.game.consume(&GameEvent::BeginGame { goes_first: 1 }); self.current_state = TrictracState::from_game_state(&self.game); self.episode_reward = 0.0; @@ -159,26 +156,17 @@ impl Environment for TrictracEnvironment { if self.game.active_player_id == self.active_player_id { if let Some(action) = trictrac_action { (reward, is_rollpoint) = self.execute_action(action); - // if reward != 0.0 { - // println!("info: self rew {reward}"); - // } if is_rollpoint { self.pointrolls_count += 1; } } else { // Action non convertible, pénalité - println!("info: action non convertible -> -1 {trictrac_action:?}"); reward = -1.0; } } // Faire jouer l'adversaire (stratégie simple) while self.game.active_player_id == self.opponent_id && self.game.stage != Stage::Ended { - // let op_rew = self.play_opponent_if_needed(); - // if op_rew != 0.0 { - // println!("info: op rew {op_rew}"); - // } - // reward += op_rew; reward += self.play_opponent_if_needed(); } @@ -217,57 +205,112 @@ impl TrictracEnvironment { const REWARD_RATIO: f32 = 1.0; /// Convertit une action burn-rl vers une action Trictrac - pub fn convert_action(action: TrictracAction) -> Option { - training_common::TrictracAction::from_action_index(action.index.try_into().unwrap()) + pub fn convert_action(action: TrictracAction) -> Option { + dqn_common::TrictracAction::from_action_index(action.index.try_into().unwrap()) } /// Convertit l'index d'une action au sein des actions valides vers une action Trictrac fn convert_valid_action_index( &self, action: TrictracAction, - ) -> Option { - use training_common::get_valid_actions; + ) -> Option { + use dqn_common::get_valid_actions; // Obtenir les actions valides dans le contexte actuel - if let Ok(valid_actions) = get_valid_actions(&self.game) { - // Mapper l'index d'action sur une action valide - let action_index = (action.index as usize) % valid_actions.len(); - Some(valid_actions[action_index]) - } else { - None + let valid_actions = get_valid_actions(&self.game); + + if valid_actions.is_empty() { + return None; } + + // Mapper l'index d'action sur une action valide + let action_index = (action.index as usize) % valid_actions.len(); + Some(valid_actions[action_index].clone()) } /// Exécute une action Trictrac dans le jeu // fn execute_action( // &mut self, - // action: training_common::TrictracAction, + // action: dqn_common::TrictracAction, // ) -> Result> { - fn execute_action(&mut self, action: training_common::TrictracAction) -> (f32, bool) { - use training_common::TrictracAction; + fn execute_action(&mut self, action: dqn_common::TrictracAction) -> (f32, bool) { + use dqn_common::TrictracAction; let mut reward = 0.0; let mut is_rollpoint = false; + let event = match action { + TrictracAction::Roll => { + // Lancer les dés + Some(GameEvent::Roll { + player_id: self.active_player_id, + }) + } + // TrictracAction::Mark => { + // // Marquer des points + // let points = self.game. + // reward += 0.1 * points as f32; + // Some(GameEvent::Mark { + // player_id: self.active_player_id, + // points, + // }) + // } + TrictracAction::Go => { + // Continuer après avoir gagné un trou + Some(GameEvent::Go { + player_id: self.active_player_id, + }) + } + TrictracAction::Move { + dice_order, + from1, + from2, + } => { + // Effectuer un mouvement + let (dice1, dice2) = if dice_order { + (self.game.dice.values.0, self.game.dice.values.1) + } else { + (self.game.dice.values.1, self.game.dice.values.0) + }; + let mut to1 = from1 + dice1 as usize; + let mut to2 = from2 + dice2 as usize; + + // Gestion prise de coin par puissance + let opp_rest_field = 13; + if to1 == opp_rest_field && to2 == opp_rest_field { + to1 -= 1; + to2 -= 1; + } + + let checker_move1 = store::CheckerMove::new(from1, to1).unwrap_or_default(); + let checker_move2 = store::CheckerMove::new(from2, to2).unwrap_or_default(); + + Some(GameEvent::Move { + player_id: self.active_player_id, + moves: (checker_move1, checker_move2), + }) + } + }; + // Appliquer l'événement si valide - if let Some(event) = action.to_event(&self.game) { + if let Some(event) = event { if self.game.validate(&event) { - let _ = self.game.consume(&event); - // reward += REWARD_VALID_MOVE; + self.game.consume(&event); + // Simuler le résultat des dés après un Roll if matches!(action, TrictracAction::Roll) { - let mut rng = rng(); - let dice_values = (rng.random_range(1..=6), rng.random_range(1..=6)); + let mut rng = thread_rng(); + let dice_values = (rng.gen_range(1..=6), rng.gen_range(1..=6)); let dice_event = GameEvent::RollResult { player_id: self.active_player_id, - dice: trictrac_store::Dice { + dice: store::Dice { values: dice_values, }, }; if self.game.validate(&dice_event) { - let _ = self.game.consume(&dice_event); + self.game.consume(&dice_event); let (points, adv_points) = self.game.dice_points; - reward += REWARD_RATIO * (points as f32 - adv_points as f32); + reward += Self::REWARD_RATIO * (points - adv_points) as f32; if points > 0 { is_rollpoint = true; // println!("info: rolled for {reward}"); @@ -279,12 +322,8 @@ impl TrictracEnvironment { // Pénalité pour action invalide // on annule les précédents reward // et on indique une valeur reconnaissable pour statistiques - reward = ERROR_REWARD; - self.game.mark_points_for_bot_training(self.opponent_id, 1); + reward = Self::ERROR_REWARD; } - } else { - reward = ERROR_REWARD; - self.game.mark_points_for_bot_training(self.opponent_id, 1); } (reward, is_rollpoint) @@ -307,24 +346,22 @@ impl TrictracEnvironment { *strategy.get_mut_game() = self.game.clone(); // Exécuter l'action selon le turn_stage - let mut calculate_points = false; - let opponent_color = trictrac_store::Color::Black; let event = match self.game.turn_stage { TurnStage::RollDice => GameEvent::Roll { player_id: self.opponent_id, }, TurnStage::RollWaiting => { - let mut rng = rng(); - let dice_values = (rng.random_range(1..=6), rng.random_range(1..=6)); - calculate_points = true; + let mut rng = thread_rng(); + let dice_values = (rng.gen_range(1..=6), rng.gen_range(1..=6)); GameEvent::RollResult { player_id: self.opponent_id, - dice: trictrac_store::Dice { + dice: store::Dice { values: dice_values, }, } } TurnStage::MarkPoints => { + let opponent_color = store::Color::Black; let dice_roll_count = self .game .players @@ -333,12 +370,16 @@ impl TrictracEnvironment { .dice_roll_count; let points_rules = PointsRules::new(&opponent_color, &self.game.board, self.game.dice); + let (points, adv_points) = points_rules.get_points(dice_roll_count); + reward -= Self::REWARD_RATIO * (points - adv_points) as f32; // Récompense proportionnelle aux points + GameEvent::Mark { player_id: self.opponent_id, - points: points_rules.get_points(dice_roll_count).0, + points, } } TurnStage::MarkAdvPoints => { + let opponent_color = store::Color::Black; let dice_roll_count = self .game .players @@ -367,20 +408,7 @@ impl TrictracEnvironment { }; if self.game.validate(&event) { - let _ = self.game.consume(&event); - if calculate_points { - let dice_roll_count = self - .game - .players - .get(&self.opponent_id) - .unwrap() - .dice_roll_count; - let points_rules = - PointsRules::new(&opponent_color, &self.game.board, self.game.dice); - let (points, adv_points) = points_rules.get_points(dice_roll_count); - reward -= Self::REWARD_RATIO * (points - adv_points) as f32; - // Récompense proportionnelle aux points - } + self.game.consume(&event); } } reward diff --git a/bot/src/dqn/burnrl_valid/main.rs b/bot/src/dqn/burnrl_valid/main.rs new file mode 100644 index 0000000..ee0dd1f --- /dev/null +++ b/bot/src/dqn/burnrl_valid/main.rs @@ -0,0 +1,52 @@ +use bot::dqn::burnrl_valid::{ + dqn_model, environment, + utils::{demo_model, load_model, save_model}, +}; +use burn::backend::{Autodiff, NdArray}; +use burn_rl::agent::DQN; +use burn_rl::base::ElemType; + +type Backend = Autodiff>; +type Env = environment::TrictracEnvironment; + +fn main() { + // println!("> Entraînement"); + + // See also MEMORY_SIZE in dqn_model.rs : 8192 + let conf = dqn_model::DqnConfig { + // defaults + num_episodes: 100, // 40 + max_steps: 1000, // 1000 max steps by episode + dense_size: 256, // 128 neural network complexity (default 128) + eps_start: 0.9, // 0.9 epsilon initial value (0.9 => more exploration) + eps_end: 0.05, // 0.05 + // eps_decay higher = epsilon decrease slower + // used in : epsilon = eps_end + (eps_start - eps_end) * e^(-step / eps_decay); + // epsilon is updated at the start of each episode + eps_decay: 2000.0, // 1000 ? + + gamma: 0.999, // 0.999 discount factor. Plus élevé = encourage stratégies à long terme + tau: 0.005, // 0.005 soft update rate. Taux de mise à jour du réseau cible. Plus bas = adaptation + // plus lente moins sensible aux coups de chance + learning_rate: 0.001, // 0.001 taille du pas. Bas : plus lent, haut : risque de ne jamais + // converger + batch_size: 32, // 32 nombre d'expériences passées sur lesquelles pour calcul de l'erreur moy. + clip_grad: 100.0, // 100 limite max de correction à apporter au gradient (default 100) + }; + println!("{conf}----------"); + let agent = dqn_model::run::(&conf, false); //true); + + let valid_agent = agent.valid(); + + println!("> Sauvegarde du modèle de validation"); + + let path = "bot/models/burn_dqn_valid_40".to_string(); + save_model(valid_agent.model().as_ref().unwrap(), &path); + + println!("> Chargement du modèle pour test"); + let loaded_model = load_model(conf.dense_size, &path); + let loaded_agent = DQN::new(loaded_model.unwrap()); + + println!("> Test avec le modèle chargé"); + demo_model(loaded_agent); +} diff --git a/bot/src/dqn/burnrl_valid/mod.rs b/bot/src/dqn/burnrl_valid/mod.rs new file mode 100644 index 0000000..f4380eb --- /dev/null +++ b/bot/src/dqn/burnrl_valid/mod.rs @@ -0,0 +1,3 @@ +pub mod dqn_model; +pub mod environment; +pub mod utils; diff --git a/bot/src/dqn/burnrl_valid/utils.rs b/bot/src/dqn/burnrl_valid/utils.rs new file mode 100644 index 0000000..61522e9 --- /dev/null +++ b/bot/src/dqn/burnrl_valid/utils.rs @@ -0,0 +1,114 @@ +use crate::dqn::burnrl_valid::{ + dqn_model, + environment::{TrictracAction, TrictracEnvironment}, +}; +use crate::dqn::dqn_common::get_valid_action_indices; +use burn::backend::{ndarray::NdArrayDevice, Autodiff, NdArray}; +use burn::module::{Module, Param, ParamId}; +use burn::nn::Linear; +use burn::record::{CompactRecorder, Recorder}; +use burn::tensor::backend::Backend; +use burn::tensor::cast::ToElement; +use burn::tensor::Tensor; +use burn_rl::agent::{DQNModel, DQN}; +use burn_rl::base::{Action, ElemType, Environment, State}; + +pub fn save_model(model: &dqn_model::Net>, path: &String) { + let recorder = CompactRecorder::new(); + let model_path = format!("{path}_model.mpk"); + println!("Modèle de validation sauvegardé : {model_path}"); + recorder + .record(model.clone().into_record(), model_path.into()) + .unwrap(); +} + +pub fn load_model(dense_size: usize, path: &String) -> Option>> { + let model_path = format!("{path}_model.mpk"); + // println!("Chargement du modèle depuis : {model_path}"); + + CompactRecorder::new() + .load(model_path.into(), &NdArrayDevice::default()) + .map(|record| { + dqn_model::Net::new( + ::StateType::size(), + dense_size, + ::ActionType::size(), + ) + .load_record(record) + }) + .ok() +} + +pub fn demo_model>(agent: DQN) { + let mut env = TrictracEnvironment::new(true); + let mut done = false; + while !done { + // let action = match infer_action(&agent, &env, state) { + let action = match infer_action(&agent, &env) { + Some(value) => value, + None => break, + }; + // Execute action + let snapshot = env.step(action); + done = snapshot.done(); + } +} + +fn infer_action>( + agent: &DQN, + env: &TrictracEnvironment, +) -> Option { + let state = env.state(); + // Get q-values + let q_values = agent + .model() + .as_ref() + .unwrap() + .infer(state.to_tensor().unsqueeze()); + // Get valid actions + let valid_actions_indices = get_valid_action_indices(&env.game); + if valid_actions_indices.is_empty() { + return None; // No valid actions, end of episode + } + // Set non valid actions q-values to lowest + let mut masked_q_values = q_values.clone(); + let q_values_vec: Vec = q_values.into_data().into_vec().unwrap(); + for (index, q_value) in q_values_vec.iter().enumerate() { + if !valid_actions_indices.contains(&index) { + masked_q_values = masked_q_values.clone().mask_fill( + masked_q_values.clone().equal_elem(*q_value), + f32::NEG_INFINITY, + ); + } + } + // Get best action (highest q-value) + let action_index = masked_q_values.argmax(1).into_scalar().to_u32(); + let action = TrictracAction::from(action_index); + Some(action) +} + +fn soft_update_tensor( + this: &Param>, + that: &Param>, + tau: ElemType, +) -> Param> { + let that_weight = that.val(); + let this_weight = this.val(); + let new_weight = this_weight * (1.0 - tau) + that_weight * tau; + + Param::initialized(ParamId::new(), new_weight) +} + +pub fn soft_update_linear( + this: Linear, + that: &Linear, + tau: ElemType, +) -> Linear { + let weight = soft_update_tensor(&this.weight, &that.weight, tau); + let bias = match (&this.bias, &that.bias) { + (Some(this_bias), Some(that_bias)) => Some(soft_update_tensor(this_bias, that_bias, tau)), + _ => None, + }; + + Linear:: { weight, bias } +} diff --git a/bot/src/dqn/dqn_common.rs b/bot/src/dqn/dqn_common.rs new file mode 100644 index 0000000..2da4aa5 --- /dev/null +++ b/bot/src/dqn/dqn_common.rs @@ -0,0 +1,255 @@ +use std::cmp::{max, min}; + +use serde::{Deserialize, Serialize}; +use store::{CheckerMove, Dice}; + +/// Types d'actions possibles dans le jeu +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum TrictracAction { + /// Lancer les dés + Roll, + /// Continuer après avoir gagné un trou + Go, + /// Effectuer un mouvement de pions + Move { + dice_order: bool, // true = utiliser dice[0] en premier, false = dice[1] en premier + from1: usize, // position de départ du premier pion (0-24) + from2: usize, // position de départ du deuxième pion (0-24) + }, + // Marquer les points : à activer si support des écoles + // Mark, +} + +impl TrictracAction { + /// Encode une action en index pour le réseau de neurones + pub fn to_action_index(&self) -> usize { + match self { + TrictracAction::Roll => 0, + TrictracAction::Go => 1, + TrictracAction::Move { + dice_order, + from1, + from2, + } => { + // Encoder les mouvements dans l'espace d'actions + // Indices 2+ pour les mouvements + // de 2 à 1251 (2 à 626 pour dé 1 en premier, 627 à 1251 pour dé 2 en premier) + let mut start = 2; + if !dice_order { + // 25 * 25 = 625 + start += 625; + } + start + from1 * 25 + from2 + } // TrictracAction::Mark => 1252, + } + } + + /// Décode un index d'action en TrictracAction + pub fn from_action_index(index: usize) -> Option { + match index { + 0 => Some(TrictracAction::Roll), + // 1252 => Some(TrictracAction::Mark), + 1 => Some(TrictracAction::Go), + i if i >= 3 => { + let move_code = i - 3; + let (dice_order, from1, from2) = Self::decode_move(move_code); + Some(TrictracAction::Move { + dice_order, + from1, + from2, + }) + } + _ => None, + } + } + + /// Décode un entier en paire de mouvements + fn decode_move(code: usize) -> (bool, usize, usize) { + let mut encoded = code; + let dice_order = code < 626; + if !dice_order { + encoded -= 625 + } + let from1 = encoded / 25; + let from2 = 1 + encoded % 25; + (dice_order, from1, from2) + } + + /// Retourne la taille de l'espace d'actions total + pub fn action_space_size() -> usize { + // 1 (Roll) + 1 (Go) + mouvements possibles + // Pour les mouvements : 2*25*25 = 1250 (choix du dé + position 0-24 pour chaque from) + // Mais on peut optimiser en limitant aux positions valides (1-24) + 2 + (2 * 25 * 25) // = 1252 + } + + // pub fn to_game_event(&self, player_id: PlayerId, dice: Dice) -> GameEvent { + // match action { + // TrictracAction::Roll => Some(GameEvent::Roll { player_id }), + // TrictracAction::Mark => Some(GameEvent::Mark { player_id, points }), + // TrictracAction::Go => Some(GameEvent::Go { player_id }), + // TrictracAction::Move { + // dice_order, + // from1, + // from2, + // } => { + // // Effectuer un mouvement + // let checker_move1 = store::CheckerMove::new(move1.0, move1.1).unwrap_or_default(); + // let checker_move2 = store::CheckerMove::new(move2.0, move2.1).unwrap_or_default(); + // + // Some(GameEvent::Move { + // player_id: self.agent_player_id, + // moves: (checker_move1, checker_move2), + // }) + // } + // }; + // } +} + +/// Obtient les actions valides pour l'état de jeu actuel +pub fn get_valid_actions(game_state: &crate::GameState) -> Vec { + use store::TurnStage; + + let mut valid_actions = Vec::new(); + + let active_player_id = game_state.active_player_id; + let player_color = game_state.player_color_by_id(&active_player_id); + + if let Some(color) = player_color { + match game_state.turn_stage { + TurnStage::RollDice | TurnStage::RollWaiting => { + valid_actions.push(TrictracAction::Roll); + } + TurnStage::MarkPoints | TurnStage::MarkAdvPoints => { + // valid_actions.push(TrictracAction::Mark); + } + TurnStage::HoldOrGoChoice => { + valid_actions.push(TrictracAction::Go); + + // Ajoute aussi les mouvements possibles + let rules = store::MoveRules::new(&color, &game_state.board, game_state.dice); + let possible_moves = rules.get_possible_moves_sequences(true, vec![]); + + // Modififier checker_moves_to_trictrac_action si on doit gérer Black + assert_eq!(color, store::Color::White); + for (move1, move2) in possible_moves { + valid_actions.push(checker_moves_to_trictrac_action( + &move1, + &move2, + &game_state.dice, + )); + } + } + TurnStage::Move => { + let rules = store::MoveRules::new(&color, &game_state.board, game_state.dice); + let possible_moves = rules.get_possible_moves_sequences(true, vec![]); + + // Modififier checker_moves_to_trictrac_action si on doit gérer Black + assert_eq!(color, store::Color::White); + for (move1, move2) in possible_moves { + valid_actions.push(checker_moves_to_trictrac_action( + &move1, + &move2, + &game_state.dice, + )); + } + } + } + } + + valid_actions +} + +// Valid only for White player +fn checker_moves_to_trictrac_action( + move1: &CheckerMove, + move2: &CheckerMove, + dice: &Dice, +) -> TrictracAction { + let to1 = move1.get_to(); + let to2 = move2.get_to(); + let from1 = move1.get_from(); + let from2 = move2.get_from(); + + let mut diff_move1 = if to1 > 0 { + // Mouvement sans sortie + to1 - from1 + } else { + // sortie, on utilise la valeur du dé + if to2 > 0 { + // sortie pour le mouvement 1 uniquement + let dice2 = to2 - from2; + if dice2 == dice.values.0 as usize { + dice.values.1 as usize + } else { + dice.values.0 as usize + } + } else { + // double sortie + if from1 < from2 { + max(dice.values.0, dice.values.1) as usize + } else { + min(dice.values.0, dice.values.1) as usize + } + } + }; + + // modification de diff_move1 si on est dans le cas d'un mouvement par puissance + let rest_field = 12; + if to1 == rest_field + && to2 == rest_field + && max(dice.values.0 as usize, dice.values.1 as usize) + min(from1, from2) != rest_field + { + // prise par puissance + diff_move1 += 1; + } + TrictracAction::Move { + dice_order: diff_move1 == dice.values.0 as usize, + from1: move1.get_from(), + from2: move2.get_from(), + } +} + +/// Retourne les indices des actions valides +pub fn get_valid_action_indices(game_state: &crate::GameState) -> Vec { + get_valid_actions(game_state) + .into_iter() + .map(|action| action.to_action_index()) + .collect() +} + +/// Sélectionne une action valide aléatoire +pub fn sample_valid_action(game_state: &crate::GameState) -> Option { + use rand::{seq::SliceRandom, thread_rng}; + + let valid_actions = get_valid_actions(game_state); + let mut rng = thread_rng(); + valid_actions.choose(&mut rng).cloned() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn to_action_index() { + let action = TrictracAction::Move { + dice_order: true, + from1: 3, + from2: 4, + }; + let index = action.to_action_index(); + assert_eq!(Some(action), TrictracAction::from_action_index(index)); + assert_eq!(81, index); + } + + #[test] + fn from_action_index() { + let action = TrictracAction::Move { + dice_order: true, + from1: 3, + from2: 4, + }; + assert_eq!(Some(action), TrictracAction::from_action_index(81)); + } +} diff --git a/bot/src/dqn/mod.rs b/bot/src/dqn/mod.rs new file mode 100644 index 0000000..7f1572e --- /dev/null +++ b/bot/src/dqn/mod.rs @@ -0,0 +1,5 @@ +pub mod burnrl; +pub mod dqn_common; +pub mod simple; + +pub mod burnrl_valid; diff --git a/bot/src/dqn/simple/dqn_model.rs b/bot/src/dqn/simple/dqn_model.rs new file mode 100644 index 0000000..ba46212 --- /dev/null +++ b/bot/src/dqn/simple/dqn_model.rs @@ -0,0 +1,154 @@ +use crate::dqn::dqn_common::TrictracAction; +use serde::{Deserialize, Serialize}; + +/// Configuration pour l'agent DQN +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DqnConfig { + pub state_size: usize, + pub hidden_size: usize, + pub num_actions: usize, + pub learning_rate: f64, + pub gamma: f64, + pub epsilon: f64, + pub epsilon_decay: f64, + pub epsilon_min: f64, + pub replay_buffer_size: usize, + pub batch_size: usize, +} + +impl Default for DqnConfig { + fn default() -> Self { + Self { + state_size: 36, + hidden_size: 512, // Augmenter la taille pour gérer l'espace d'actions élargi + num_actions: TrictracAction::action_space_size(), + learning_rate: 0.001, + gamma: 0.99, + epsilon: 0.1, + epsilon_decay: 0.995, + epsilon_min: 0.01, + replay_buffer_size: 10000, + batch_size: 32, + } + } +} + +/// Réseau de neurones DQN simplifié (matrice de poids basique) +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SimpleNeuralNetwork { + pub weights1: Vec>, + pub biases1: Vec, + pub weights2: Vec>, + pub biases2: Vec, + pub weights3: Vec>, + pub biases3: Vec, +} + +impl SimpleNeuralNetwork { + pub fn new(input_size: usize, hidden_size: usize, output_size: usize) -> Self { + use rand::{thread_rng, Rng}; + let mut rng = thread_rng(); + + // Initialisation aléatoire des poids avec Xavier/Glorot + let scale1 = (2.0 / input_size as f32).sqrt(); + let weights1 = (0..hidden_size) + .map(|_| { + (0..input_size) + .map(|_| rng.gen_range(-scale1..scale1)) + .collect() + }) + .collect(); + let biases1 = vec![0.0; hidden_size]; + + let scale2 = (2.0 / hidden_size as f32).sqrt(); + let weights2 = (0..hidden_size) + .map(|_| { + (0..hidden_size) + .map(|_| rng.gen_range(-scale2..scale2)) + .collect() + }) + .collect(); + let biases2 = vec![0.0; hidden_size]; + + let scale3 = (2.0 / hidden_size as f32).sqrt(); + let weights3 = (0..output_size) + .map(|_| { + (0..hidden_size) + .map(|_| rng.gen_range(-scale3..scale3)) + .collect() + }) + .collect(); + let biases3 = vec![0.0; output_size]; + + Self { + weights1, + biases1, + weights2, + biases2, + weights3, + biases3, + } + } + + pub fn forward(&self, input: &[f32]) -> Vec { + // Première couche + let mut layer1: Vec = self.biases1.clone(); + for (i, neuron_weights) in self.weights1.iter().enumerate() { + for (j, &weight) in neuron_weights.iter().enumerate() { + if j < input.len() { + layer1[i] += input[j] * weight; + } + } + layer1[i] = layer1[i].max(0.0); // ReLU + } + + // Deuxième couche + let mut layer2: Vec = self.biases2.clone(); + for (i, neuron_weights) in self.weights2.iter().enumerate() { + for (j, &weight) in neuron_weights.iter().enumerate() { + if j < layer1.len() { + layer2[i] += layer1[j] * weight; + } + } + layer2[i] = layer2[i].max(0.0); // ReLU + } + + // Couche de sortie + let mut output: Vec = self.biases3.clone(); + for (i, neuron_weights) in self.weights3.iter().enumerate() { + for (j, &weight) in neuron_weights.iter().enumerate() { + if j < layer2.len() { + output[i] += layer2[j] * weight; + } + } + } + + output + } + + pub fn get_best_action(&self, input: &[f32]) -> usize { + let q_values = self.forward(input); + q_values + .iter() + .enumerate() + .max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap()) + .map(|(index, _)| index) + .unwrap_or(0) + } + + pub fn save>( + &self, + path: P, + ) -> Result<(), Box> { + let data = serde_json::to_string_pretty(self)?; + std::fs::write(path, data)?; + Ok(()) + } + + pub fn load>(path: P) -> Result> { + let data = std::fs::read_to_string(path)?; + let network = serde_json::from_str(&data)?; + Ok(network) + } +} + diff --git a/bot/src/dqn/simple/dqn_trainer.rs b/bot/src/dqn/simple/dqn_trainer.rs new file mode 100644 index 0000000..78e6dc7 --- /dev/null +++ b/bot/src/dqn/simple/dqn_trainer.rs @@ -0,0 +1,490 @@ +use crate::{CheckerMove, Color, GameState, PlayerId}; +use rand::prelude::SliceRandom; +use rand::{thread_rng, Rng}; +use serde::{Deserialize, Serialize}; +use std::collections::VecDeque; +use store::{GameEvent, MoveRules, PointsRules, Stage, TurnStage}; + +use super::dqn_model::{DqnConfig, SimpleNeuralNetwork}; +use crate::dqn::dqn_common::{get_valid_actions, TrictracAction}; + +/// Expérience pour le buffer de replay +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Experience { + pub state: Vec, + pub action: TrictracAction, + pub reward: f32, + pub next_state: Vec, + pub done: bool, +} + +/// Buffer de replay pour stocker les expériences +#[derive(Debug)] +pub struct ReplayBuffer { + buffer: VecDeque, + capacity: usize, +} + +impl ReplayBuffer { + pub fn new(capacity: usize) -> Self { + Self { + buffer: VecDeque::with_capacity(capacity), + capacity, + } + } + + pub fn push(&mut self, experience: Experience) { + if self.buffer.len() >= self.capacity { + self.buffer.pop_front(); + } + self.buffer.push_back(experience); + } + + pub fn sample(&self, batch_size: usize) -> Vec { + let mut rng = thread_rng(); + let len = self.buffer.len(); + if len < batch_size { + return self.buffer.iter().cloned().collect(); + } + + let mut batch = Vec::with_capacity(batch_size); + for _ in 0..batch_size { + let idx = rng.gen_range(0..len); + batch.push(self.buffer[idx].clone()); + } + batch + } + + pub fn len(&self) -> usize { + self.buffer.len() + } +} + +/// Agent DQN pour l'apprentissage par renforcement +#[derive(Debug)] +pub struct DqnAgent { + config: DqnConfig, + model: SimpleNeuralNetwork, + target_model: SimpleNeuralNetwork, + replay_buffer: ReplayBuffer, + epsilon: f64, + step_count: usize, +} + +impl DqnAgent { + pub fn new(config: DqnConfig) -> Self { + let model = + SimpleNeuralNetwork::new(config.state_size, config.hidden_size, config.num_actions); + let target_model = model.clone(); + let replay_buffer = ReplayBuffer::new(config.replay_buffer_size); + let epsilon = config.epsilon; + + Self { + config, + model, + target_model, + replay_buffer, + epsilon, + step_count: 0, + } + } + + pub fn select_action(&mut self, game_state: &GameState, state: &[f32]) -> TrictracAction { + let valid_actions = get_valid_actions(game_state); + + if valid_actions.is_empty() { + // Fallback si aucune action valide + return TrictracAction::Roll; + } + + let mut rng = thread_rng(); + if rng.gen::() < self.epsilon { + // Exploration : action valide aléatoire + valid_actions + .choose(&mut rng) + .cloned() + .unwrap_or(TrictracAction::Roll) + } else { + // Exploitation : meilleure action valide selon le modèle + let q_values = self.model.forward(state); + + let mut best_action = &valid_actions[0]; + let mut best_q_value = f32::NEG_INFINITY; + + for action in &valid_actions { + let action_index = action.to_action_index(); + if action_index < q_values.len() { + let q_value = q_values[action_index]; + if q_value > best_q_value { + best_q_value = q_value; + best_action = action; + } + } + } + + best_action.clone() + } + } + + pub fn store_experience(&mut self, experience: Experience) { + self.replay_buffer.push(experience); + } + + pub fn train(&mut self) { + if self.replay_buffer.len() < self.config.batch_size { + return; + } + + // Pour l'instant, on simule l'entraînement en mettant à jour epsilon + // Dans une implémentation complète, ici on ferait la backpropagation + self.epsilon = (self.epsilon * self.config.epsilon_decay).max(self.config.epsilon_min); + self.step_count += 1; + + // Mise à jour du target model tous les 100 steps + if self.step_count % 100 == 0 { + self.target_model = self.model.clone(); + } + } + + pub fn save_model>( + &self, + path: P, + ) -> Result<(), Box> { + self.model.save(path) + } + + pub fn get_epsilon(&self) -> f64 { + self.epsilon + } + + pub fn get_step_count(&self) -> usize { + self.step_count + } +} + +/// Environnement Trictrac pour l'entraînement +#[derive(Debug)] +pub struct TrictracEnv { + pub game_state: GameState, + pub agent_player_id: PlayerId, + pub opponent_player_id: PlayerId, + pub agent_color: Color, + pub max_steps: usize, + pub current_step: usize, +} + +impl Default for TrictracEnv { + fn default() -> Self { + let mut game_state = GameState::new(false); + game_state.init_player("agent"); + game_state.init_player("opponent"); + + Self { + game_state, + agent_player_id: 1, + opponent_player_id: 2, + agent_color: Color::White, + max_steps: 1000, + current_step: 0, + } + } +} + +impl TrictracEnv { + pub fn reset(&mut self) -> Vec { + self.game_state = GameState::new(false); + self.game_state.init_player("agent"); + self.game_state.init_player("opponent"); + + // Commencer la partie + self.game_state.consume(&GameEvent::BeginGame { + goes_first: self.agent_player_id, + }); + + self.current_step = 0; + self.game_state.to_vec_float() + } + + pub fn step(&mut self, action: TrictracAction) -> (Vec, f32, bool) { + let mut reward = 0.0; + + // Appliquer l'action de l'agent + if self.game_state.active_player_id == self.agent_player_id { + reward += self.apply_agent_action(action); + } + + // Faire jouer l'adversaire (stratégie simple) + while self.game_state.active_player_id == self.opponent_player_id + && self.game_state.stage != Stage::Ended + { + reward += self.play_opponent_turn(); + } + + // Vérifier si la partie est terminée + let done = self.game_state.stage == Stage::Ended + || self.game_state.determine_winner().is_some() + || self.current_step >= self.max_steps; + + // Récompense finale si la partie est terminée + if done { + if let Some(winner) = self.game_state.determine_winner() { + if winner == self.agent_player_id { + reward += 100.0; // Bonus pour gagner + } else { + reward -= 50.0; // Pénalité pour perdre + } + } + } + + self.current_step += 1; + let next_state = self.game_state.to_vec_float(); + (next_state, reward, done) + } + + fn apply_agent_action(&mut self, action: TrictracAction) -> f32 { + let mut reward = 0.0; + + let event = match action { + TrictracAction::Roll => { + // Lancer les dés + reward += 0.1; + Some(GameEvent::Roll { + player_id: self.agent_player_id, + }) + } + // TrictracAction::Mark => { + // // Marquer des points + // let points = self.game_state. + // reward += 0.1 * points as f32; + // Some(GameEvent::Mark { + // player_id: self.agent_player_id, + // points, + // }) + // } + TrictracAction::Go => { + // Continuer après avoir gagné un trou + reward += 0.2; + Some(GameEvent::Go { + player_id: self.agent_player_id, + }) + } + TrictracAction::Move { + dice_order, + from1, + from2, + } => { + // Effectuer un mouvement + let (dice1, dice2) = if dice_order { + (self.game_state.dice.values.0, self.game_state.dice.values.1) + } else { + (self.game_state.dice.values.1, self.game_state.dice.values.0) + }; + let mut to1 = from1 + dice1 as usize; + let mut to2 = from2 + dice2 as usize; + + // Gestion prise de coin par puissance + let opp_rest_field = 13; + if to1 == opp_rest_field && to2 == opp_rest_field { + to1 -= 1; + to2 -= 1; + } + + let checker_move1 = store::CheckerMove::new(from1, to1).unwrap_or_default(); + let checker_move2 = store::CheckerMove::new(from2, to2).unwrap_or_default(); + + reward += 0.2; + Some(GameEvent::Move { + player_id: self.agent_player_id, + moves: (checker_move1, checker_move2), + }) + } + }; + + // Appliquer l'événement si valide + if let Some(event) = event { + if self.game_state.validate(&event) { + self.game_state.consume(&event); + + // Simuler le résultat des dés après un Roll + if matches!(action, TrictracAction::Roll) { + let mut rng = thread_rng(); + let dice_values = (rng.gen_range(1..=6), rng.gen_range(1..=6)); + let dice_event = GameEvent::RollResult { + player_id: self.agent_player_id, + dice: store::Dice { + values: dice_values, + }, + }; + if self.game_state.validate(&dice_event) { + self.game_state.consume(&dice_event); + } + } + } else { + // Pénalité pour action invalide + reward -= 2.0; + } + } + + reward + } + + // TODO : use default bot strategy + fn play_opponent_turn(&mut self) -> f32 { + let mut reward = 0.0; + let event = match self.game_state.turn_stage { + TurnStage::RollDice => GameEvent::Roll { + player_id: self.opponent_player_id, + }, + TurnStage::RollWaiting => { + let mut rng = thread_rng(); + let dice_values = (rng.gen_range(1..=6), rng.gen_range(1..=6)); + GameEvent::RollResult { + player_id: self.opponent_player_id, + dice: store::Dice { + values: dice_values, + }, + } + } + TurnStage::MarkAdvPoints | TurnStage::MarkPoints => { + let opponent_color = self.agent_color.opponent_color(); + let dice_roll_count = self + .game_state + .players + .get(&self.opponent_player_id) + .unwrap() + .dice_roll_count; + let points_rules = PointsRules::new( + &opponent_color, + &self.game_state.board, + self.game_state.dice, + ); + let (points, adv_points) = points_rules.get_points(dice_roll_count); + reward -= 0.3 * (points - adv_points) as f32; // Récompense proportionnelle aux points + + GameEvent::Mark { + player_id: self.opponent_player_id, + points, + } + } + TurnStage::Move => { + let opponent_color = self.agent_color.opponent_color(); + let rules = MoveRules::new( + &opponent_color, + &self.game_state.board, + self.game_state.dice, + ); + let possible_moves = rules.get_possible_moves_sequences(true, vec![]); + + // Stratégie simple : choix aléatoire + let mut rng = thread_rng(); + let choosen_move = *possible_moves + .choose(&mut rng) + .unwrap_or(&(CheckerMove::default(), CheckerMove::default())); + + GameEvent::Move { + player_id: self.opponent_player_id, + moves: if opponent_color == Color::White { + choosen_move + } else { + (choosen_move.0.mirror(), choosen_move.1.mirror()) + }, + } + } + TurnStage::HoldOrGoChoice => { + // Stratégie simple : toujours continuer + GameEvent::Go { + player_id: self.opponent_player_id, + } + } + }; + if self.game_state.validate(&event) { + self.game_state.consume(&event); + } + reward + } +} + +/// Entraîneur pour le modèle DQN +pub struct DqnTrainer { + agent: DqnAgent, + env: TrictracEnv, +} + +impl DqnTrainer { + pub fn new(config: DqnConfig) -> Self { + Self { + agent: DqnAgent::new(config), + env: TrictracEnv::default(), + } + } + + pub fn train_episode(&mut self) -> f32 { + let mut total_reward = 0.0; + let mut state = self.env.reset(); + // let mut step_count = 0; + + loop { + // step_count += 1; + let action = self.agent.select_action(&self.env.game_state, &state); + let (next_state, reward, done) = self.env.step(action.clone()); + total_reward += reward; + + let experience = Experience { + state: state.clone(), + action, + reward, + next_state: next_state.clone(), + done, + }; + self.agent.store_experience(experience); + self.agent.train(); + + if done { + break; + } + // if step_count % 100 == 0 { + // println!("{:?}", next_state); + // } + state = next_state; + } + + total_reward + } + + pub fn train( + &mut self, + episodes: usize, + save_every: usize, + model_path: &str, + ) -> Result<(), Box> { + println!("Démarrage de l'entraînement DQN pour {} épisodes", episodes); + + for episode in 1..=episodes { + let reward = self.train_episode(); + + if episode % 100 == 0 { + println!( + "Épisode {}/{}: Récompense = {:.2}, Epsilon = {:.3}, Steps = {}", + episode, + episodes, + reward, + self.agent.get_epsilon(), + self.agent.get_step_count() + ); + } + + if episode % save_every == 0 { + let save_path = format!("{}_episode_{}.json", model_path, episode); + self.agent.save_model(&save_path)?; + println!("Modèle sauvegardé : {}", save_path); + } + } + + // Sauvegarder le modèle final + let final_path = format!("{}_final.json", model_path); + self.agent.save_model(&final_path)?; + println!("Modèle final sauvegardé : {}", final_path); + + Ok(()) + } +} diff --git a/bot/src/dqn/simple/main.rs b/bot/src/dqn/simple/main.rs new file mode 100644 index 0000000..30fd933 --- /dev/null +++ b/bot/src/dqn/simple/main.rs @@ -0,0 +1,112 @@ +use bot::dqn::dqn_common::TrictracAction; +use bot::dqn::simple::dqn_model::DqnConfig; +use bot::dqn::simple::dqn_trainer::DqnTrainer; +use std::env; + +fn main() -> Result<(), Box> { + env_logger::init(); + + let args: Vec = env::args().collect(); + + // Paramètres par défaut + let mut episodes = 1000; + let mut model_path = "models/dqn_model".to_string(); + let mut save_every = 100; + + // Parser les arguments de ligne de commande + let mut i = 1; + while i < args.len() { + match args[i].as_str() { + "--episodes" => { + if i + 1 < args.len() { + episodes = args[i + 1].parse().unwrap_or(1000); + i += 2; + } else { + eprintln!("Erreur : --episodes nécessite une valeur"); + std::process::exit(1); + } + } + "--model-path" => { + if i + 1 < args.len() { + model_path = args[i + 1].clone(); + i += 2; + } else { + eprintln!("Erreur : --model-path nécessite une valeur"); + std::process::exit(1); + } + } + "--save-every" => { + if i + 1 < args.len() { + save_every = args[i + 1].parse().unwrap_or(100); + i += 2; + } else { + eprintln!("Erreur : --save-every nécessite une valeur"); + std::process::exit(1); + } + } + "--help" | "-h" => { + print_help(); + std::process::exit(0); + } + _ => { + eprintln!("Argument inconnu : {}", args[i]); + print_help(); + std::process::exit(1); + } + } + } + + // Créer le dossier models s'il n'existe pas + std::fs::create_dir_all("models")?; + + println!("Configuration d'entraînement DQN :"); + println!(" Épisodes : {}", episodes); + println!(" Chemin du modèle : {}", model_path); + println!(" Sauvegarde tous les {} épisodes", save_every); + println!(); + + // Configuration DQN + let config = DqnConfig { + state_size: 36, // state.to_vec size + hidden_size: 256, + num_actions: TrictracAction::action_space_size(), + learning_rate: 0.001, + gamma: 0.99, + epsilon: 0.9, // Commencer avec plus d'exploration + epsilon_decay: 0.995, + epsilon_min: 0.01, + replay_buffer_size: 10000, + batch_size: 32, + }; + + // Créer et lancer l'entraîneur + let mut trainer = DqnTrainer::new(config); + trainer.train(episodes, save_every, &model_path)?; + + println!("Entraînement terminé avec succès !"); + println!("Pour utiliser le modèle entraîné :"); + println!( + " cargo run --bin=client_cli -- --bot dqn:{}_final.json,dummy", + model_path + ); + + Ok(()) +} + +fn print_help() { + println!("Entraîneur DQN pour Trictrac"); + println!(); + println!("USAGE:"); + println!(" cargo run --bin=train_dqn [OPTIONS]"); + println!(); + println!("OPTIONS:"); + println!(" --episodes Nombre d'épisodes d'entraînement (défaut: 1000)"); + println!(" --model-path Chemin de base pour sauvegarder les modèles (défaut: models/dqn_model)"); + println!(" --save-every Sauvegarder le modèle tous les N épisodes (défaut: 100)"); + println!(" -h, --help Afficher cette aide"); + println!(); + println!("EXEMPLES:"); + println!(" cargo run --bin=train_dqn"); + println!(" cargo run --bin=train_dqn -- --episodes 5000 --save-every 500"); + println!(" cargo run --bin=train_dqn -- --model-path models/my_model --episodes 2000"); +} diff --git a/bot/src/dqn/simple/mod.rs b/bot/src/dqn/simple/mod.rs new file mode 100644 index 0000000..8090a29 --- /dev/null +++ b/bot/src/dqn/simple/mod.rs @@ -0,0 +1,2 @@ +pub mod dqn_model; +pub mod dqn_trainer; diff --git a/bot/src/lib.rs b/bot/src/lib.rs index a9b04d5..f9a4617 100644 --- a/bot/src/lib.rs +++ b/bot/src/lib.rs @@ -1,16 +1,14 @@ -pub mod burnrl; +pub mod dqn; pub mod strategy; -pub mod trictrac_board; -use log::debug; +use log::{debug, error}; +use store::{CheckerMove, Color, GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage}; pub use strategy::default::DefaultStrategy; +pub use strategy::dqn::DqnStrategy; pub use strategy::dqnburn::DqnBurnStrategy; pub use strategy::erroneous_moves::ErroneousStrategy; pub use strategy::random::RandomStrategy; pub use strategy::stable_baselines3::StableBaselines3Strategy; -use trictrac_store::{ - CheckerMove, Color, GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage, -}; pub trait BotStrategy: std::fmt::Debug { fn get_game(&self) -> &GameState; @@ -71,14 +69,14 @@ impl Bot { debug!(">>>> {:?} BOT handle", self.color); let game = self.strategy.get_mut_game(); let internal_event = if self.color == Color::Black { - &event.get_mirror(false) + &event.get_mirror() } else { event }; let init_player_points = game.who_plays().map(|p| (p.points, p.holes)); let turn_stage = game.turn_stage; - let _ = game.consume(internal_event); + game.consume(internal_event); if game.stage == Stage::Ended { debug!("<<<< end {:?} BOT handle", self.color); return None; @@ -126,7 +124,7 @@ impl Bot { return if self.color == Color::Black { debug!(" bot (internal) evt : {internal_event:?} ; points : {player_points:?}"); debug!("<<<< end {:?} BOT handle", self.color); - internal_event.map(|evt| evt.get_mirror(false)) + internal_event.map(|evt| evt.get_mirror()) } else { debug!("<<<< end {:?} BOT handle", self.color); internal_event @@ -145,7 +143,7 @@ impl Bot { #[cfg(test)] mod tests { use super::*; - use trictrac_store::{Dice, Stage}; + use store::{Dice, Stage}; #[test] fn test_new() { diff --git a/bot/src/strategy/default.rs b/bot/src/strategy/default.rs index f8b191d..628ce83 100644 --- a/bot/src/strategy/default.rs +++ b/bot/src/strategy/default.rs @@ -1,5 +1,5 @@ use crate::{BotStrategy, CheckerMove, Color, GameState, PlayerId}; -use trictrac_store::MoveRules; +use store::MoveRules; #[derive(Debug)] pub struct DefaultStrategy { diff --git a/bot/src/strategy/dqn.rs b/bot/src/strategy/dqn.rs new file mode 100644 index 0000000..cf24684 --- /dev/null +++ b/bot/src/strategy/dqn.rs @@ -0,0 +1,174 @@ +use crate::{BotStrategy, CheckerMove, Color, GameState, PlayerId}; +use log::info; +use std::path::Path; +use store::MoveRules; + +use crate::dqn::dqn_common::{get_valid_actions, sample_valid_action, TrictracAction}; +use crate::dqn::simple::dqn_model::SimpleNeuralNetwork; + +/// Stratégie DQN pour le bot - ne fait que charger et utiliser un modèle pré-entraîné +#[derive(Debug)] +pub struct DqnStrategy { + pub game: GameState, + pub player_id: PlayerId, + pub color: Color, + pub model: Option, +} + +impl Default for DqnStrategy { + fn default() -> Self { + Self { + game: GameState::default(), + player_id: 1, + color: Color::White, + model: None, + } + } +} + +impl DqnStrategy { + pub fn new() -> Self { + Self::default() + } + + pub fn new_with_model + std::fmt::Debug>(model_path: P) -> Self { + let mut strategy = Self::new(); + if let Ok(model) = SimpleNeuralNetwork::load(&model_path) { + info!("Loading model {model_path:?}"); + strategy.model = Some(model); + } + strategy + } + + /// Utilise le modèle DQN pour choisir une action valide + fn get_dqn_action(&self) -> Option { + if let Some(ref model) = self.model { + let state = self.game.to_vec_float(); + let valid_actions = get_valid_actions(&self.game); + + if valid_actions.is_empty() { + return None; + } + + // Obtenir les Q-values pour toutes les actions + let q_values = model.forward(&state); + + // Trouver la meilleure action valide + let mut best_action = &valid_actions[0]; + let mut best_q_value = f32::NEG_INFINITY; + + for action in &valid_actions { + let action_index = action.to_action_index(); + if action_index < q_values.len() { + let q_value = q_values[action_index]; + if q_value > best_q_value { + best_q_value = q_value; + best_action = action; + } + } + } + + Some(best_action.clone()) + } else { + // Fallback : action aléatoire valide + sample_valid_action(&self.game) + } + } +} + +impl BotStrategy for DqnStrategy { + fn get_game(&self) -> &GameState { + &self.game + } + + fn get_mut_game(&mut self) -> &mut GameState { + &mut self.game + } + + fn set_color(&mut self, color: Color) { + self.color = color; + } + + fn set_player_id(&mut self, player_id: PlayerId) { + self.player_id = player_id; + } + + fn calculate_points(&self) -> u8 { + self.game.dice_points.0 + } + + fn calculate_adv_points(&self) -> u8 { + self.game.dice_points.1 + } + + fn choose_go(&self) -> bool { + // Utiliser le DQN pour décider si on continue + if let Some(action) = self.get_dqn_action() { + matches!(action, TrictracAction::Go) + } else { + // Fallback : toujours continuer + true + } + } + + fn choose_move(&self) -> (CheckerMove, CheckerMove) { + // Utiliser le DQN pour choisir le mouvement + if let Some(TrictracAction::Move { + dice_order, + from1, + from2, + }) = self.get_dqn_action() + { + let dicevals = self.game.dice.values; + let (mut dice1, mut dice2) = if dice_order { + (dicevals.0, dicevals.1) + } else { + (dicevals.1, dicevals.0) + }; + + if from1 == 0 { + // empty move + dice1 = 0; + } + let mut to1 = from1 + dice1 as usize; + if 24 < to1 { + // sortie + to1 = 0; + } + if from2 == 0 { + // empty move + dice2 = 0; + } + let mut to2 = from2 + dice2 as usize; + if 24 < to2 { + // sortie + to2 = 0; + } + + let checker_move1 = CheckerMove::new(from1, to1).unwrap_or_default(); + let checker_move2 = CheckerMove::new(from2, to2).unwrap_or_default(); + + let chosen_move = if self.color == Color::White { + (checker_move1, checker_move2) + } else { + (checker_move1.mirror(), checker_move2.mirror()) + }; + + return chosen_move; + } + + // Fallback : utiliser la stratégie par défaut + let rules = MoveRules::new(&self.color, &self.game.board, self.game.dice); + let possible_moves = rules.get_possible_moves_sequences(true, vec![]); + + let chosen_move = *possible_moves + .first() + .unwrap_or(&(CheckerMove::default(), CheckerMove::default())); + + if self.color == Color::White { + chosen_move + } else { + (chosen_move.0.mirror(), chosen_move.1.mirror()) + } + } +} diff --git a/bot/src/strategy/dqnburn.rs b/bot/src/strategy/dqnburn.rs index 37f9b7f..4fc0c06 100644 --- a/bot/src/strategy/dqnburn.rs +++ b/bot/src/strategy/dqnburn.rs @@ -4,15 +4,12 @@ use burn_rl::base::{ElemType, Model, State}; use crate::{BotStrategy, CheckerMove, Color, GameState, PlayerId}; use log::info; -use trictrac_store::MoveRules; +use store::MoveRules; -use crate::burnrl::algos::dqn; -use crate::burnrl::environment; -use trictrac_store::training_common::{ - get_valid_action_indices, sample_valid_action, TrictracAction, -}; +use crate::dqn::burnrl::{dqn_model, environment, utils}; +use crate::dqn::dqn_common::{get_valid_action_indices, sample_valid_action, TrictracAction}; -type DqnBurnNetwork = dqn::Net>; +type DqnBurnNetwork = dqn_model::Net>; /// Stratégie DQN pour le bot - ne fait que charger et utiliser un modèle pré-entraîné #[derive(Debug)] @@ -42,7 +39,7 @@ impl DqnBurnStrategy { pub fn new_with_model(model_path: &String) -> Self { info!("Loading model {model_path:?}"); let mut strategy = Self::new(); - strategy.model = dqn::load_model(256, model_path); + strategy.model = utils::load_model(256, model_path); strategy } @@ -50,32 +47,30 @@ impl DqnBurnStrategy { fn get_dqn_action(&self) -> Option { if let Some(ref model) = self.model { let state = environment::TrictracState::from_game_state(&self.game); - if let Ok(valid_actions_indices) = get_valid_action_indices(&self.game) { - if valid_actions_indices.is_empty() { - return None; // No valid actions, end of episode - } - - // Obtenir les Q-values pour toutes les actions - let q_values = model.infer(state.to_tensor().unsqueeze()); - - // Set non valid actions q-values to lowest - let mut masked_q_values = q_values.clone(); - let q_values_vec: Vec = q_values.into_data().into_vec().unwrap(); - for (index, q_value) in q_values_vec.iter().enumerate() { - if !valid_actions_indices.contains(&index) { - masked_q_values = masked_q_values.clone().mask_fill( - masked_q_values.clone().equal_elem(*q_value), - f32::NEG_INFINITY, - ); - } - } - // Get best action (highest q-value) - let action_index = masked_q_values.argmax(1).into_scalar().to_u32(); - return environment::TrictracEnvironment::convert_action( - environment::TrictracAction::from(action_index), - ); + let valid_actions_indices = get_valid_action_indices(&self.game); + if valid_actions_indices.is_empty() { + return None; // No valid actions, end of episode } - return None; + + // Obtenir les Q-values pour toutes les actions + let q_values = model.infer(state.to_tensor().unsqueeze()); + + // Set non valid actions q-values to lowest + let mut masked_q_values = q_values.clone(); + let q_values_vec: Vec = q_values.into_data().into_vec().unwrap(); + for (index, q_value) in q_values_vec.iter().enumerate() { + if !valid_actions_indices.contains(&index) { + masked_q_values = masked_q_values.clone().mask_fill( + masked_q_values.clone().equal_elem(*q_value), + f32::NEG_INFINITY, + ); + } + } + // Get best action (highest q-value) + let action_index = masked_q_values.argmax(1).into_scalar().to_u32(); + environment::TrictracEnvironment::convert_action(environment::TrictracAction::from( + action_index, + )) } else { // Fallback : action aléatoire valide sample_valid_action(&self.game) @@ -122,8 +117,8 @@ impl BotStrategy for DqnBurnStrategy { // Utiliser le DQN pour choisir le mouvement if let Some(TrictracAction::Move { dice_order, - checker1, - checker2, + from1, + from2, }) = self.get_dqn_action() { let dicevals = self.game.dice.values; @@ -133,65 +128,23 @@ impl BotStrategy for DqnBurnStrategy { (dicevals.1, dicevals.0) }; - assert_eq!(self.color, Color::White); - let from1 = self - .game - .board - .get_checker_field(&self.color, checker1 as u8) - .unwrap_or(0); - if from1 == 0 { // empty move dice1 = 0; } - let mut to1 = from1; - if self.color == Color::White { - to1 += dice1 as usize; - if 24 < to1 { - // sortie - to1 = 0; - } - } else { - let fto1 = to1 as i16 - dice1 as i16; - to1 = if fto1 < 0 { 0 } else { fto1 as usize }; + let mut to1 = from1 + dice1 as usize; + if 24 < to1 { + // sortie + to1 = 0; } - - let checker_move1 = trictrac_store::CheckerMove::new(from1, to1).unwrap_or_default(); - - let mut tmp_board = self.game.board.clone(); - let move_res = tmp_board.move_checker(&self.color, checker_move1); - if move_res.is_err() { - panic!("could not move {move_res:?}"); - } - let from2 = tmp_board - .get_checker_field(&self.color, checker2 as u8) - .unwrap_or(0); if from2 == 0 { // empty move dice2 = 0; } - let mut to2 = from2; - if self.color == Color::White { - to2 += dice2 as usize; - if 24 < to2 { - // sortie - to2 = 0; - } - } else { - let fto2 = to2 as i16 - dice2 as i16; - to2 = if fto2 < 0 { 0 } else { fto2 as usize }; - } - - // Gestion prise de coin par puissance - let opp_rest_field = if self.color == Color::White { 13 } else { 12 }; - if to1 == opp_rest_field && to2 == opp_rest_field { - if self.color == Color::White { - to1 -= 1; - to2 -= 1; - } else { - to1 += 1; - to2 += 1; - } + let mut to2 = from2 + dice2 as usize; + if 24 < to2 { + // sortie + to2 = 0; } let checker_move1 = CheckerMove::new(from1, to1).unwrap_or_default(); @@ -200,7 +153,6 @@ impl BotStrategy for DqnBurnStrategy { let chosen_move = if self.color == Color::White { (checker_move1, checker_move2) } else { - // XXX : really ? (checker_move1.mirror(), checker_move2.mirror()) }; diff --git a/bot/src/strategy/mod.rs b/bot/src/strategy/mod.rs index 00293cb..b9fa3b2 100644 --- a/bot/src/strategy/mod.rs +++ b/bot/src/strategy/mod.rs @@ -1,5 +1,6 @@ pub mod client; pub mod default; +pub mod dqn; pub mod dqnburn; pub mod erroneous_moves; pub mod random; diff --git a/bot/src/strategy/random.rs b/bot/src/strategy/random.rs index 08d851d..0bfd1c6 100644 --- a/bot/src/strategy/random.rs +++ b/bot/src/strategy/random.rs @@ -1,6 +1,5 @@ use crate::{BotStrategy, CheckerMove, Color, GameState, PlayerId}; -use rand::{prelude::IndexedRandom, rng}; -use trictrac_store::MoveRules; +use store::MoveRules; #[derive(Debug)] pub struct RandomStrategy { @@ -52,7 +51,8 @@ impl BotStrategy for RandomStrategy { let rules = MoveRules::new(&self.color, &self.game.board, self.game.dice); let possible_moves = rules.get_possible_moves_sequences(true, vec![]); - let mut rng = rng(); + use rand::{seq::SliceRandom, thread_rng}; + let mut rng = thread_rng(); let choosen_move = possible_moves .choose(&mut rng) .cloned() diff --git a/bot/src/strategy/stable_baselines3.rs b/bot/src/strategy/stable_baselines3.rs index 78aa583..4b94311 100644 --- a/bot/src/strategy/stable_baselines3.rs +++ b/bot/src/strategy/stable_baselines3.rs @@ -5,7 +5,7 @@ use std::io::Read; use std::io::Write; use std::path::Path; use std::process::Command; -use trictrac_store::MoveRules; +use store::MoveRules; #[derive(Debug)] pub struct StableBaselines3Strategy { @@ -66,25 +66,25 @@ impl StableBaselines3Strategy { // Remplir les positions des pièces blanches (valeurs positives) for (pos, count) in self.game.board.get_color_fields(Color::White) { if pos < 24 { - board[pos] = count; + board[pos] = count as i8; } } // Remplir les positions des pièces noires (valeurs négatives) for (pos, count) in self.game.board.get_color_fields(Color::Black) { if pos < 24 { - board[pos] = -count; + board[pos] = -(count as i8); } } // Convertir l'étape du tour en entier let turn_stage = match self.game.turn_stage { - trictrac_store::TurnStage::RollDice => 0, - trictrac_store::TurnStage::RollWaiting => 1, - trictrac_store::TurnStage::MarkPoints => 2, - trictrac_store::TurnStage::HoldOrGoChoice => 3, - trictrac_store::TurnStage::Move => 4, - trictrac_store::TurnStage::MarkAdvPoints => 5, + store::TurnStage::RollDice => 0, + store::TurnStage::RollWaiting => 1, + store::TurnStage::MarkPoints => 2, + store::TurnStage::HoldOrGoChoice => 3, + store::TurnStage::Move => 4, + store::TurnStage::MarkAdvPoints => 5, }; // Récupérer les points et trous des joueurs @@ -270,3 +270,4 @@ impl BotStrategy for StableBaselines3Strategy { } } } + diff --git a/bot/src/trictrac_board.rs b/bot/src/trictrac_board.rs deleted file mode 100644 index 7fce992..0000000 --- a/bot/src/trictrac_board.rs +++ /dev/null @@ -1,171 +0,0 @@ -// https://docs.rs/board-game/ implementation -use board_game::board::{ - Board as BoardGameBoard, BoardDone, BoardMoves, Outcome, PlayError, Player as BoardGamePlayer, -}; -use board_game::impl_unit_symmetry_board; -use internal_iterator::InternalIterator; -use std::fmt; -use std::hash::Hash; -use std::ops::ControlFlow; -use trictrac_store::training_common::{get_valid_actions, TrictracAction}; -use trictrac_store::Color; - -#[derive(Clone, Debug, Eq, PartialEq, Hash)] -pub struct TrictracBoard(crate::GameState); - -impl Default for TrictracBoard { - fn default() -> Self { - TrictracBoard(crate::GameState::new_with_players("white", "black")) - } -} - -impl fmt::Display for TrictracBoard { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.0.fmt(f) - } -} - -impl_unit_symmetry_board!(TrictracBoard); - -impl BoardGameBoard for TrictracBoard { - // impl TrictracBoard { - type Move = TrictracAction; - - fn next_player(&self) -> BoardGamePlayer { - self.0 - .who_plays() - .map(|p| { - if p.color == Color::Black { - BoardGamePlayer::B - } else { - BoardGamePlayer::A - } - }) - .unwrap_or(BoardGamePlayer::A) - } - - fn is_available_move(&self, mv: Self::Move) -> Result { - self.check_done()?; - let is_valid = mv - .to_event(&self.0) - .map(|evt| self.0.validate(&evt)) - .unwrap_or(false); - Ok(is_valid) - } - - fn play(&mut self, mv: Self::Move) -> Result<(), PlayError> { - self.check_can_play(mv)?; - if let Some(evt) = mv.to_event(&self.0) { - let _ = self.0.consume(&evt); - Ok(()) - } else { - Err(PlayError::UnavailableMove) - } - } - - fn outcome(&self) -> Option { - if self.0.stage == crate::Stage::Ended { - self.0.determine_winner().map(|player_id| { - Outcome::WonBy(if player_id == 1 { - BoardGamePlayer::A - } else { - BoardGamePlayer::B - }) - }) - } else { - None - } - } - - fn can_lose_after_move() -> bool { - true - } -} - -impl TrictracBoard { - pub fn inner(&self) -> &crate::GameState { - &self.0 - } - - pub fn to_fen(&self) -> String { - self.0.to_string_id() - } - - pub fn from_fen(fen: &str) -> Result { - crate::GameState::from_string_id(fen).map(TrictracBoard) - } -} - -impl<'a> BoardMoves<'a, TrictracBoard> for TrictracBoard { - type AllMovesIterator = TrictracAllMovesIterator; - type AvailableMovesIterator = TrictracAvailableMovesIterator<'a>; - - fn all_possible_moves() -> Self::AllMovesIterator { - TrictracAllMovesIterator::default() - } - - fn available_moves(&'a self) -> Result { - TrictracAvailableMovesIterator::new(self) - } -} - -#[derive(Debug, Clone)] -pub struct TrictracAllMovesIterator; - -impl Default for TrictracAllMovesIterator { - fn default() -> Self { - TrictracAllMovesIterator - } -} - -impl InternalIterator for TrictracAllMovesIterator { - type Item = TrictracAction; - - fn try_for_each ControlFlow>(self, mut f: F) -> ControlFlow { - f(TrictracAction::Roll)?; - f(TrictracAction::Go)?; - for dice_order in [false, true] { - for checker1 in 0..16 { - for checker2 in 0..16 { - f(TrictracAction::Move { - dice_order, - checker1, - checker2, - })?; - } - } - } - - ControlFlow::Continue(()) - } -} - -#[derive(Debug, Clone)] -pub struct TrictracAvailableMovesIterator<'a> { - board: &'a TrictracBoard, -} - -impl<'a> TrictracAvailableMovesIterator<'a> { - pub fn new(board: &'a TrictracBoard) -> Result { - board.check_done()?; - Ok(TrictracAvailableMovesIterator { board }) - } - - pub fn board(&self) -> &'a TrictracBoard { - self.board - } -} - -impl InternalIterator for TrictracAvailableMovesIterator<'_> { - type Item = TrictracAction; - - fn try_for_each(self, f: F) -> ControlFlow - where - F: FnMut(Self::Item) -> ControlFlow, - { - match get_valid_actions(&self.board.0) { - Ok(actions) => actions.into_iter().try_for_each(f), - Err(_) => ControlFlow::Continue(()), - } - } -} diff --git a/client_bevy/.cargo/config.toml b/client_bevy/.cargo/config.toml new file mode 100644 index 0000000..b6bc0d3 --- /dev/null +++ b/client_bevy/.cargo/config.toml @@ -0,0 +1,8 @@ +[target.x86_64-unknown-linux-gnu] +linker = "clang" +rustflags = ["-Clink-arg=-fuse-ld=lld", "-Zshare-generics=y"] + +# Optional: Uncommenting the following improves compile times, but reduces the amount of debug info to 'line number tables only' +# In most cases the gains are negligible, but if you are on macos and have slow compile times you should see significant gains. +#[profile.dev] +#debug = 1 diff --git a/client_bevy/Cargo.toml b/client_bevy/Cargo.toml new file mode 100644 index 0000000..aaa6b7d --- /dev/null +++ b/client_bevy/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "trictrac-client" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.75" +bevy = { version = "0.11.3" } +bevy_renet = "0.0.9" +bincode = "1.3.3" +renet = "0.0.13" +store = { path = "../store" } diff --git a/client_bevy/assets/Inconsolata.ttf b/client_bevy/assets/Inconsolata.ttf new file mode 100644 index 0000000..34848ca Binary files /dev/null and b/client_bevy/assets/Inconsolata.ttf differ diff --git a/client_bevy/assets/board.png b/client_bevy/assets/board.png new file mode 100644 index 0000000..5d16ac3 Binary files /dev/null and b/client_bevy/assets/board.png differ diff --git a/client_bevy/assets/sound/click.wav b/client_bevy/assets/sound/click.wav new file mode 100644 index 0000000..8b6c99d Binary files /dev/null and b/client_bevy/assets/sound/click.wav differ diff --git a/client_bevy/assets/sound/throw.wav b/client_bevy/assets/sound/throw.wav new file mode 100755 index 0000000..cb5e438 Binary files /dev/null and b/client_bevy/assets/sound/throw.wav differ diff --git a/client_bevy/assets/tac.png b/client_bevy/assets/tac.png new file mode 100644 index 0000000..2c18813 Binary files /dev/null and b/client_bevy/assets/tac.png differ diff --git a/client_bevy/assets/tic.png b/client_bevy/assets/tic.png new file mode 100644 index 0000000..786e0c7 Binary files /dev/null and b/client_bevy/assets/tic.png differ diff --git a/client_bevy/src/main.rs b/client_bevy/src/main.rs new file mode 100644 index 0000000..504602e --- /dev/null +++ b/client_bevy/src/main.rs @@ -0,0 +1,334 @@ +use std::{net::UdpSocket, time::SystemTime}; + +use renet::transport::{NetcodeClientTransport, NetcodeTransportError, NETCODE_USER_DATA_BYTES}; +use store::{GameEvent, GameState, CheckerMove}; + +use bevy::prelude::*; +use bevy::window::PrimaryWindow; +use bevy_renet::{ + renet::{transport::ClientAuthentication, ConnectionConfig, RenetClient}, + transport::{client_connected, NetcodeClientPlugin}, + RenetClientPlugin, +}; + +#[derive(Debug, Resource)] +struct CurrentClientId(u64); + +#[derive(Resource)] +struct BevyGameState(GameState); + +impl Default for BevyGameState { + fn default() -> Self { + Self { + 0: GameState::default(), + } + } +} + +#[derive(Resource, Deref, DerefMut)] +struct GameUIState { + selected_tile: Option, +} + +impl Default for GameUIState { + fn default() -> Self { + Self { + selected_tile: None, + } + } +} + +#[derive(Event)] +struct BevyGameEvent(GameEvent); + +// This id needs to be the same as the server is using +const PROTOCOL_ID: u64 = 2878; + +fn main() { + // Get username from stdin args + let args = std::env::args().collect::>(); + let username = &args[1]; + + let (client, transport, client_id) = new_renet_client(&username).unwrap(); + App::new() + // Lets add a nice dark grey background color + .insert_resource(ClearColor(Color::hex("282828").unwrap())) + .add_plugins(DefaultPlugins.set(WindowPlugin { + primary_window: Some(Window { + // Adding the username to the window title makes debugging a whole lot easier. + title: format!("TricTrac <{}>", username), + resolution: (1080.0, 1080.0).into(), + ..default() + }), + ..default() + })) + // Add our game state and register GameEvent as a bevy event + .insert_resource(BevyGameState::default()) + .insert_resource(GameUIState::default()) + .add_event::() + // Renet setup + .add_plugins(RenetClientPlugin) + .add_plugins(NetcodeClientPlugin) + .insert_resource(client) + .insert_resource(transport) + .insert_resource(CurrentClientId(client_id)) + .add_systems(Startup, setup) + .add_systems(Update, (update_waiting_text, input, update_board, panic_on_error_system)) + .add_systems( + PostUpdate, + receive_events_from_server.run_if(client_connected()), + ) + .run(); +} + +////////// COMPONENTS ////////// +#[derive(Component)] +struct UIRoot; + +#[derive(Component)] +struct WaitingText; + +#[derive(Component)] +struct Board { + squares: [Square; 26] +} + +impl Default for Board { + fn default() -> Self { + Self { + squares: [Square { count: 0, color: None, position: 0}; 26] + } + } +} + +impl Board { + fn square_at(&self, position: usize) -> Square { + self.squares[position] + } +} + +#[derive(Component, Clone, Copy)] +struct Square { + count: usize, + color: Option, + position: usize, +} + +////////// UPDATE SYSTEMS ////////// +fn update_board( + mut commands: Commands, + game_state: Res, + mut game_events: EventReader, + asset_server: Res, +) { + for event in game_events.iter() { + match event.0 { + GameEvent::Move { player_id, moves } => { + // trictrac positions, TODO : dépend de player_id + let (x, y) = if moves.0.get_to() < 13 { (13 - moves.0.get_to(), 1) } else { (moves.0.get_to() - 13, 0)}; + let texture = + asset_server.load(match game_state.0.players[&player_id].color { + store::Color::Black => "tac.png", + store::Color::White => "tic.png", + }); + + info!("spawning tictac sprite"); + commands.spawn(SpriteBundle { + transform: Transform::from_xyz( + 83.0 * (x as f32 - 1.0), + -30.0 + 540.0 * (y as f32 - 1.0), + 0.0, + ), + sprite: Sprite { + custom_size: Some(Vec2::new(83.0, 83.0)), + ..default() + }, + texture: texture.into(), + ..default() + }); + } + _ => {} + } + } +} + +fn update_waiting_text(mut text_query: Query<&mut Text, With>, time: Res