From c03b0c399a5fc8ec064ed5acb7acea9828d6b8c7 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 10 Jan 2022 20:35:44 +0100 Subject: [PATCH] help me --- .idea/markdown.xml | 9 + Cargo.lock | 736 ++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 8 + build.rs | 8 + gpu/Cargo.toml | 12 + gpu/src/lib.rs | 118 ++++++++ rust-toolchain | 9 + src/lib.rs | 291 +++++++----------- 8 files changed, 966 insertions(+), 225 deletions(-) create mode 100644 .idea/markdown.xml create mode 100644 build.rs create mode 100644 gpu/Cargo.toml create mode 100644 gpu/src/lib.rs create mode 100644 rust-toolchain diff --git a/.idea/markdown.xml b/.idea/markdown.xml new file mode 100644 index 0000000..1e34094 --- /dev/null +++ b/.idea/markdown.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 4e58901..8db6692 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "adler" version = "1.0.2" @@ -12,6 +14,24 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +dependencies = [ + "num-traits", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -20,21 +40,39 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "build-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" +dependencies = [ + "semver 0.6.0", +] [[package]] name = "bytemuck" -version = "1.5.1" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58" +checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" [[package]] name = "byteorder" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -50,18 +88,18 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" dependencies = [ "cfg-if", "crossbeam-utils", @@ -69,9 +107,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -80,9 +118,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" +checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" dependencies = [ "cfg-if", "crossbeam-utils", @@ -93,15 +131,113 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" dependencies = [ - "autocfg", "cfg-if", "lazy_static", ] +[[package]] +name = "cuda_builder" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10e260b5de08885d26a2ec5f1e8304a51832a790738edf84fdfa64c1a6203d3f" +dependencies = [ + "find_cuda_helper", + "nvvm", + "rustc_codegen_nvvm", + "serde", + "serde_json", +] + +[[package]] +name = "cuda_std" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513bbb5f3de5abd1164a54b5e919d5cf431694068ef1557b8b16bc5979a28fb8" +dependencies = [ + "bitflags", + "cuda_std_macros", + "half", + "paste", + "vek", +] + +[[package]] +name = "cuda_std_macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd6400923ab36c5c41ed85a3a143ac07dfc1f928440cdef1802fd9b6c9f8a42" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "curl" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de97b894edd5b5bcceef8b78d7da9b75b1d2f2f9a910569d0bde3dd31d84939" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi", +] + +[[package]] +name = "curl-sys" +version = "0.4.52+curl-7.81.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b8c2d1023ea5fded5b7b892e4b8e95f70038a421126a056761a84246a28971" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "winapi", +] + +[[package]] +name = "cust" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e947a46de036afc50a482cbe88e2b09680b1c8ebea79ce714e4c168371a267c9" +dependencies = [ + "bitflags", + "cust_derive", + "cust_raw", + "find_cuda_helper", +] + +[[package]] +name = "cust_derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ca82ac24c045b317909d4722bb7e0dad7ef97bdbdba5b68aebd0e8a79904a6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cust_raw" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf40d6ade12cb9828bbc844b9875c7b93d25e67a3c9bf61c7aa3ae09e402bf8" +dependencies = [ + "find_cuda_helper", +] + [[package]] name = "deflate" version = "0.8.6" @@ -119,20 +255,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] -name = "gif" -version = "0.11.1" +name = "filetime" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02efba560f227847cb41463a7395c514d127d4f74fff12ef0137fff1b84b96c4" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "find_cuda_helper" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f9e65c593dd01ac77daad909ea4ad17f0d6d1776193fc8ea766356177abdad" +dependencies = [ + "glob", +] + +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" dependencies = [ "color_quant", "weezl", ] [[package]] -name = "hermit-abi" -version = "0.1.18" +name = "glob" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "gpu" +version = "0.1.0" +dependencies = [ + "cuda_std", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -156,6 +332,21 @@ dependencies = [ "tiff", ] +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + [[package]] name = "jpeg-decoder" version = "0.1.22" @@ -173,22 +364,71 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.88" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" + +[[package]] +name = "libm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" + +[[package]] +name = "libz-sys" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lzma-sys" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb4b7c3eddad11d3af9e86c487607d2d2442d185d848575365c4856ba96d619" +dependencies = [ + "cc", + "libc", + "pkg-config", +] [[package]] name = "mandelbrot_set" version = "0.1.0" dependencies = [ + "cuda_builder", + "cust", "image", ] [[package]] -name = "memoffset" -version = "0.6.1" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -251,18 +491,71 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ "autocfg", + "libm", ] [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", ] +[[package]] +name = "nvvm" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2863e4a5b7a092579346ff8c22413796467703dc4c1d92495c1c27370f371088" +dependencies = [ + "find_cuda_helper", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "openssl-probe" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" + +[[package]] +name = "openssl-sys" +version = "0.9.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "paste" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + [[package]] name = "png" version = "0.16.8" @@ -276,10 +569,28 @@ dependencies = [ ] [[package]] -name = "rayon" -version = "1.5.0" +name = "proc-macro2" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" dependencies = [ "autocfg", "crossbeam-deque", @@ -289,9 +600,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -300,6 +611,103 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc_codegen_nvvm" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427f9f513c28b4bf32a4501adb9bb200986ce5f27a14c97b425483123d257a1a" +dependencies = [ + "bitflags", + "build-helper", + "cc", + "curl", + "find_cuda_helper", + "libc", + "nvvm", + "once_cell", + "rustc-demangle", + "rustc_codegen_nvvm_macros", + "tar", + "tracing", + "tracing-subscriber", + "xz", +] + +[[package]] +name = "rustc_codegen_nvvm_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bfb9cac01852422f089b5727e0f60533b25f5a73ec892238a1b143a599ee3d9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi", +] + [[package]] name = "scoped_threadpool" version = "0.1.9" @@ -312,6 +720,123 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "semver" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" + +[[package]] +name = "socket2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + [[package]] name = "tiff" version = "0.6.1" @@ -324,7 +849,142 @@ dependencies = [ ] [[package]] -name = "weezl" -version = "0.1.4" +name = "tracing" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a32b378380f4e9869b22f0b5177c68a5519f03b3454fde0b291455ddbae266c" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d81bfa81424cc98cb034b837c985b7a290f592e5b4322f353f94a0ab0f9f594" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vek" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343a216b8dcc20237304602200d904ef88d9208d7d9b7014554db0e1e8da7ee9" +dependencies = [ + "approx", + "num-integer", + "num-traits", + "rustc_version", + "static_assertions", +] + +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + +[[package]] +name = "xz" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c887690ff2a2e233e8e49633461521f98ec57fbff9d59a884c9a4f04ec1da34" +dependencies = [ + "xz2", +] + +[[package]] +name = "xz2" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" +dependencies = [ + "lzma-sys", +] diff --git a/Cargo.toml b/Cargo.toml index f1a3a24..493ac80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = [".", "./gpu"] + [package] name = "mandelbrot_set" version = "0.1.0" @@ -7,7 +10,12 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cust = "0.2.2" image = "0.23.14" [profile.dev] opt-level = 3 + + +[build-dependencies] +cuda_builder = "0.2.0" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..2819ebb --- /dev/null +++ b/build.rs @@ -0,0 +1,8 @@ +use cuda_builder::CudaBuilder; + +fn main() { + CudaBuilder::new("./gpu") + .copy_to("target/gpu.ptx") + .build() + .unwrap(); +} \ No newline at end of file diff --git a/gpu/Cargo.toml b/gpu/Cargo.toml new file mode 100644 index 0000000..8a3a968 --- /dev/null +++ b/gpu/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "gpu" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cuda_std = "0.2.1" diff --git a/gpu/src/lib.rs b/gpu/src/lib.rs new file mode 100644 index 0000000..97daaf4 --- /dev/null +++ b/gpu/src/lib.rs @@ -0,0 +1,118 @@ +#![no_std] +#![feature(register_attr)] +#![register_attr(nvvm_internal)] +#![allow(improper_ctypes_definitions)] + +use core::ops::{Add, Mul}; +use cuda_std::kernel; +use cuda_std::thread; +use cuda_std::vek::Vec2; + +#[derive(Copy, Clone, PartialEq)] +pub struct CNumber { + pub real: f64, + pub imag: f64, +} + +#[derive(Copy, Clone)] +pub struct Cfg { + pub start: CNumber, + pub end: CNumber, + pub height: u32, + pub width: u32, + pub iterations: u32, + pub threshold: u32, +} + +#[kernel] +pub unsafe fn mandelbrot( + start_real: f64, + start_imag: f64, + end_real: f64, + end_imag: f64, + height: u32, + width: u32, + iterations: u32, + threshold: u32, + out: *mut u32, +) { + let cfg = Cfg { + start: CNumber::new(start_real, start_imag), + end: CNumber::new(end_real, end_imag), + height, + width, + iterations, + threshold + }; + + let idx = thread::index_2d(); + + if idx.x >= width || idx.y >= height { + return; + } + + let ret = check_part_of_mandelbrot(cfg, idx); + + let offset = idx.x + (idx.y * cfg.width); + out.add(offset as usize).write(ret) +} + +fn check_part_of_mandelbrot(cfg: Cfg, id: Vec2) -> u32 { + let x_step_size = (cfg.end.real - cfg.start.real) / cfg.width as f64; + let y_step_size = (cfg.end.imag - cfg.start.imag) / cfg.height as f64; + + let x = x_step_size * id.x as f64; + let y = y_step_size * id.y as f64; + + let sample_pos = CNumber { + real: cfg.start.real + x, + imag: cfg.start.imag + y, + }; + + check_mandelbrot(sample_pos, cfg.iterations, cfg.threshold) +} + +fn check_mandelbrot(sample_pos: CNumber, iterations: u32, threshold: u32) -> u32 { + let mut n = CNumber::new(0.0, 0.0); + let c = sample_pos; + + n = n + c; + + for i in 0..iterations { + n = n * n + c; + + if n.imag > threshold as f64 || n.real > threshold as f64 { + return i; + } + } + + iterations +} + +impl CNumber { + pub fn new(real: f64, imag: f64) -> CNumber { + CNumber { real, imag } + } +} + +impl Add for CNumber { + type Output = CNumber; + + fn add(self, b: CNumber) -> Self::Output { + let real = self.real + b.real; + let imag = self.imag + b.imag; + + CNumber { real, imag } + } +} + +impl Mul for CNumber { + type Output = CNumber; + + fn mul(self, b: Self) -> Self::Output { + let real = self.real * b.real - self.imag * b.imag; + let imag = self.real * b.imag + self.imag * b.real; + + CNumber { real, imag } + } +} diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..ecef846 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1,9 @@ +# If you see this, run `rustup self update` to get rustup 1.23 or newer. + +# NOTE: above comment is for older `rustup` (before TOML support was added), +# which will treat the first line as the toolchain name, and therefore show it +# to the user in the error, instead of "error: invalid channel name '[toolchain]'". + +[toolchain] +channel = "nightly-2021-12-04" +components = ["rust-src", "rustc-dev", "llvm-tools-preview"] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c852c7e..e6b0644 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,132 +1,102 @@ +#![allow(dead_code)] + use std::env::Args; use std::error::Error; use std::fmt::{Display, Formatter}; -use std::ops::{Add, Mul}; use std::time::{Duration, SystemTime}; -use image::{ImageBuffer, Rgb, RgbImage, ImageResult}; -use std::sync::{Arc, Mutex}; -use std::thread; +use cust::prelude::*; +use gpu::{CNumber, Cfg}; +use image::{ImageBuffer, ImageResult, Rgb, RgbImage}; + +static PTX: &str = include_str!("../target/gpu.ptx"); pub fn run(config: Config) -> Result<(), Box> { let start_time = SystemTime::now(); - let debug = config.debug; + let debug = config.debug; let height = config.width * 2.0 / 3.0; - let mut handles = vec![]; - let result: Arc>>> = Arc::new(Mutex::new(vec![vec![0; config.width as usize]; height as usize])); + let amount = (height * config.width) as usize; - let thread_size = 10; + let _ctx = cust::quick_init()?; - for i in 0..thread_size { - let mut result = Arc::clone(&result); - let id = i.clone(); - let config = config.clone(); - let thread_size = thread_size; - let handle = thread::spawn(move || { - check_part_of_mandelbrot(&mut result, &config, thread_size, id) - }); + let module = Module::from_str(PTX)?; + let stream = Stream::new(StreamFlags::NON_BLOCKING, None)?; - handles.push(handle); + let mut out = vec![0u32; amount]; + let mut out_buf = out.as_slice().as_dbuf()?; + + let func = module.get_function("mandelbrot")?; + + let (_, block_size) = func.suggested_launch_configuration(amount, 0.into())?; + + let grid_size = (amount as u32 + block_size - 1) / block_size; + + let cfg = Cfg { + start: CNumber::new(-0.5, 0.5), + end: CNumber::new(0.5, 0.5), + height: 500, + width: 500, + iterations: 1000, + threshold: 100, + }; + + unsafe { + launch!( + func<<>>( + cfg.start.real, + cfg.start.imag, + cfg.end.real, + cfg.end.imag, + cfg.height, + cfg.width, + cfg.iterations, + cfg.threshold, + out_buf.as_device_ptr(), + ) + )?; } - for handle in handles { - handle.join().unwrap(); + stream.synchronize()?; + + out_buf.copy_to(&mut out)?; + + create_image(&out, cfg, "gpu.png")?; + + // now do things with out + println!("expected {}, got {} numbers!", amount, out.len()); + + if debug { + println!("calculated in: {}", format_time(start_time.elapsed()?)); } - if config.is_image { - create_image(&result.lock().unwrap(), config.iterations, &*config.image_path)? + if debug { + println!("Total Time: {}", format_time(start_time.elapsed()?)); } - - if debug { println!("calculated in: {}", format_time(start_time.elapsed()?)); } - - if debug { println!("Total Time: {}", format_time(start_time.elapsed()?)); } Ok(()) } +fn create_image(values: &[u32], cfg: Cfg, path: &str) -> ImageResult<()> { -fn check_part_of_mandelbrot(vec: &mut Arc>>>, config: &Config, parts: u32, id: u32) { - let height = config.width * 2.0 / 3.0; + let mut image: RgbImage = ImageBuffer::new(cfg.width, cfg.height); - let step_size = CNumber { - real: 3.0 / config.width, - imag: 2.0 / height, - }; - let offset = CNumber { - real: config.center.real - config.width / 2.0 * step_size.real, - imag: -(config.center.imag - height / 2.0 * step_size.imag) - 2.0, - }; - - let part_height = height as u32 / parts; - let start_index = part_height * id; - let end_index = part_height * (id + 1); - - for i in start_index as usize..end_index as usize { - for j in 0..config.width as usize { - vec.lock().unwrap()[i][j] = check_mandelbrot(j, i, config, &offset, &step_size); - } - } -} - -fn check_mandelbrot(x: usize, y: usize, config: &Config, offset: &CNumber, step_size: &CNumber) -> u32 { - let sample_pos = CNumber { - real: offset.real + step_size.real * x as f64, - imag: offset.imag + step_size.imag * y as f64, - }; - - let mut n = CNumber::new(0.0, 0.0); - let c = sample_pos; - - n = n + c; - - for i in 0..config.iterations { - n = n * n + c; - - if n.imag > config.threshold || n.real > config.threshold { - return i; - } - } - - config.iterations -} - -fn create_image(values: &Vec>, iterations: u32, path: &str) -> ImageResult<()> { - let w = values[0].len() as u32; - let h = values.len() as u32; - - let mut image: RgbImage = ImageBuffer::new(w as u32, h as u32); - - for y in 0..h { - for x in 0..w { - let val = values[y as usize][x as usize]; - *image.get_pixel_mut(x, y) = get_color_for_pixel(val as f32, iterations as f32); + for y in 0..cfg.height { + for x in 0..cfg.width { + let val = values[(x + y * cfg.width) as usize]; + *image.get_pixel_mut(x, y) = get_color_for_pixel(val as f32, cfg.iterations as f32); } } image.save(path) } - fn get_color_for_pixel(value: f32, iter: f32) -> Rgb { let multiplier: f32 = 1.0 - (value * value).min(iter) / iter; let i: u8 = (255 as f32 * multiplier) as u8; image::Rgb([i, i, i]) } -static BAR_SIZE: usize = 50; - -fn progress_bar(progress: f64) -> String { - let mut bar = String::from("["); - let bar_amount = (BAR_SIZE as f64 * progress).round() as usize; - - bar.push_str(&*"#".repeat(bar_amount)); - bar.push_str(&*"-".repeat(BAR_SIZE - bar_amount)); - - bar.push(']'); - bar -} - fn format_time(d: Duration) -> String { if d.as_micros() < 10 { return format!("{}ns", d.as_nanos()); @@ -156,41 +126,6 @@ fn format_time(d: Duration) -> String { format!("{}h {}m {}s {}ms", hours, mins, secs, ms) } - -#[derive(Copy, Clone, Debug, PartialEq)] -struct CNumber { - real: f64, - imag: f64, -} - -impl CNumber { - fn new(real: f64, imag: f64) -> CNumber { - CNumber { real, imag } - } -} - -impl Add for CNumber { - type Output = CNumber; - - fn add(self, b: CNumber) -> Self::Output { - let real = self.real + b.real; - let imag = self.imag + b.imag; - - CNumber { real, imag } - } -} - -impl Mul for CNumber { - type Output = CNumber; - - fn mul(self, b: Self) -> Self::Output { - let real = self.real * b.real - self.imag * b.imag; - let imag = self.real * b.imag + self.imag * b.real; - - CNumber { real, imag } - } -} - #[derive(Clone)] pub struct Config { width: f64, @@ -214,15 +149,22 @@ impl Config { match value { None => config.set_value_flag(key)?, - Some(_) => config.set_value_value(key, value, &arg)? + Some(_) => config.set_value_value(key, value, &arg)?, }; } Ok(config) } - fn set_value_value(&mut self, key: Option<&str>, value: Option<&str>, arg: &String) -> Result<(), Box> { - let val = value.ok_or_else(|| PropertyError { msg: format!("Error while parsing argument {}", arg) })?; + fn set_value_value( + &mut self, + key: Option<&str>, + value: Option<&str>, + arg: &String, + ) -> Result<(), Box> { + let val = value.ok_or_else(|| PropertyError { + msg: format!("Error while parsing argument {}", arg), + })?; return match key { Some("path") | Some("p") => { @@ -238,16 +180,16 @@ impl Config { fn set_value_f64(&mut self, key: Option<&str>, value: f64) -> Result<(), Box> { match key { - Some("iter") | Some("iterations") => - self.iterations = value as u32, - Some("thres") | Some("threshold") => - self.threshold = value, - Some("w") | Some("width") => - self.width = value, - Some("quality") | Some("q") => - self.iterations = value as u32, + Some("iter") | Some("iterations") => self.iterations = value as u32, + Some("thres") | Some("threshold") => self.threshold = value, + Some("w") | Some("width") => self.width = value, + Some("quality") | Some("q") => self.iterations = value as u32, - _ => return Err(Box::new(PropertyError { msg: format!("Property not found: {}", key.unwrap_or_else(|| "")) })) + _ => { + return Err(Box::new(PropertyError { + msg: format!("Property not found: {}", key.unwrap_or_else(|| "")), + })) + } } Ok(()) @@ -255,23 +197,35 @@ impl Config { fn set_value_flag(&mut self, key: Option<&str>) -> Result<(), Box> { match key { - Some("img") | Some("image") => - self.is_image = true, - Some("debug") | Some("dbg") => - self.debug = true, - _ => return Err(Box::new(PropertyError { msg: format!("Property not found: {}", key.unwrap_or_else(|| "")) })) + Some("img") | Some("image") => self.is_image = true, + Some("debug") | Some("dbg") => self.debug = true, + _ => { + return Err(Box::new(PropertyError { + msg: format!("Property not found: {}", key.unwrap_or_else(|| "")), + })) + } } Ok(()) } - pub fn default() -> Config { Config::new(1, 3, 100, 100.0, false, String::from("img.png"), false) } - pub fn new(point_number: usize, quality: i32, width: i32, threshold: f32, is_image: bool, image_path: String, debug: bool) -> Config { - let interesting_points = vec![CNumber::new(-0.75, 0.0), CNumber::new(-0.77568377, 0.13646737)]; + pub fn new( + point_number: usize, + quality: i32, + width: i32, + threshold: f32, + is_image: bool, + image_path: String, + debug: bool, + ) -> Config { + let interesting_points = vec![ + CNumber::new(-0.75, 0.0), + CNumber::new(-0.77568377, 0.13646737), + ]; let center = interesting_points[point_number]; let iterations = config_iter_from_quality(quality); @@ -294,13 +248,13 @@ fn config_iter_from_quality(quality: i32) -> u32 { 2 => 1000, 3 => 5000, 4 => 20000, - _ => quality.abs() as u32 + _ => quality.abs() as u32, } } #[derive(Debug)] struct PropertyError { - msg: String + msg: String, } impl Display for PropertyError { @@ -310,40 +264,3 @@ impl Display for PropertyError { } impl Error for PropertyError {} - -#[cfg(tests)] -mod tests { - use crate::{calculate_sample_points, check_mandelbrot, CNumber, Config, draw, HIGH, LOW}; - - #[test] - fn cnumber_add_test() { - let a = CNumber::new(1.0, 1.0); - let b = CNumber::new(1.0, 1.0); - assert_eq!(a + b, CNumber::new(2.0, 2.0)); - - let a = CNumber::new(0.0, 0.0); - let b = CNumber::new(0.0, -1.0); - assert_eq!(a + b, CNumber::new(0.0, -1.0)); - - let a = CNumber::new(5.0, -13.0); - let b = CNumber::new(10.0, 5.0); - assert_eq!(a + b, CNumber::new(15.0, -8.0)) - } - - #[test] - fn cnumber_mul_test() { - let a = CNumber::new(1.0, 2.0); - let b = CNumber::new(3.0, 4.0); - assert_eq!(a * b, CNumber::new(-5.0, 10.0)); - } - - #[test] - fn draw_test() { - let vector = vec![vec![0, 0, 10, 10, 10]; 2]; - let out = draw(vector, 10); - println!("{}", out); - assert_eq!(out, " ### - ### -") - } -} \ No newline at end of file