-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC][Rust][Roadmap] Expand Rust capabilities #2523
Comments
If TVM moves to Rust, I will certainly cease to be interested. |
That wasn't necessarily the proposal, nor do I have the authority to declare this so. However, I would say that proper use of C interop allows bindings in other languages. Having the core in Rust would improve maintainability, though. Also, the Rust standard library has been ported to more architectures including aarch, riscv, and wasm, which would help extend TVM device support. Would you mind expanding on the reasoning behind your comment a bit? Are you a python proponent? If not, what about C++ does your use case require? |
@nhynes I like the idea very much and can see how an elegant rewrite would help the future directions of TVM. Definitely, leveraging the power of Also one more +1 for mentioning
This proposal is not about moving TVM to Rust entirely for now (though it could happen later). Hopefully when we figure this out, the end result would be appealing enough that would catch your interests. |
@nhynes @ehsanmok the reason that Rust is unattractive in anything we do with TVM/VTA is that we are interfacing with systems that are 10M LoC of C++ that took hundreds of millions of dollars to create. These systems are not going to be Rust compatible for the rest of their economic life. Most of these lines are implementations of complex optimization algorithms where clever memory management techniques are the only way these algorithms produce any results. I have nothing against Rust, but any Rust related dependencies in TVM will make our use of the TVM/VTA stack much less attractive as compared to TF et. al. |
would C++ bindings not solve that? it sounds like your (completely reasonable) issue with Rust is just that it doesn't have a C++ ABI. |
@nhynes C++ bindings would at least make it compatible. However, the additional complexity of yet another language/compiler/build/package environment that needs to be supported among two dozen compiler and hardware environments is so very unattractive. We like to do science, not spent 95% of our time keeping the build going, :-( If Rust would be an independent add-on, all would be fine. We could just exclude it from the builds and regressions and we would be on our way. |
-1. Besides the pain that @Ravenwater mentioned, rapidly growing a community requires a stable core stack, which is essential to new contributors, and to experienced developers/researchers who keep building new features upon that. IMHO TVM is in its critical moment of growing, we'd better not introduce extra distraction which can have large impact on our contributors and users. |
I didn't intend the porting effort as a top-level project. It's more of a thing I was hoping to help with anyway. The idea was that a Rust impl would eventually get good enough that people would choose to use it over C++ or Python. If you think that, even as a side project, it would detract from contributions to the main project, then I will gladly table the idea. Ideally, we'd focus on tight interop between all languages such that it's possible to freely use whatever language that's convenient. |
What I only say is -1. TVM is not toy project and is not the place expressing the favor of one programming language and try to introduce it into project. TVM is growing rapidly and many companies are trying to use or have used it. We shouldn’t introduce any unnessary distraction for developers and make other companies not use it because of this. |
@FrozenGene understood. I will extract the high-level idea of your comment and say that the development of any Rust functionality will be independent of the main project. Although I jokingly suggested that the reason to rewrite in Rust is because of the language alone, doing so would have the benefits of easier extensibility/prototyping and bringing any re-implemented functionality to new platforms like riscv. For instance, imagine having an in-browser editor for TVM modules backed by a Wasm compiler enabled by Rust; or a F1 instance running a riscv soft core with VTA. As @Ravenwater mentioned, many of us (myself included) are trying to do science. Having more options as long as it's not a distraction to the core project can only help that goal. |
Great discussions :) First of all, as many people said, I think the core of TVM will stay C++ in the foreseeable future. On the other hand, the question is that, can we enable the use of rust(optionally), along with C++ core? I think the answer is yes. Let me elaborate that a bit. The TVM project is a layered system: we have runtime, frontend and compiler core. So we should really ask what does it mean to introduce rust in each setting. Rust Runtime BackendRuntime backend means implementing the C APIs in Thanks to @nhynes , we already have good rust runtime backend support, and I think it makes sense to think about supporting graph to some extent to get good WASM support(without libc). Rust Frontend SupportFrontend means wrap C APIs in Compiler Core and Node SystemSo the most interesting questions come when we want to think about Rust for compiler cores. In particular, we should ask where should the AST(i.e. TVM's Node class) live. Nodes are important not only because they are in C++, but also because we have clean API to expose them to python. While I have no doubt it is possible to re-implement the Node system in rust, it makes C++ obsolete, because you cannot directly visit these memory object directly as struct pointer access in C++, so it is not a realistic option. A more realistic, but still a challenging question, is whether can we enable writing passes in rust, and plug them in as PackedFunc to the C++ core. I have some serious thoughts in that direction. The simplest way is to use frontend API, like python. However, that is only good for prototyping purposes, because we need to do C API calls just like python did. A Common Node SystemWhat we really want in our case, is to make rust access the C++ AST as backend language, so the Node field access can be done natively via struct address accessing, without getting into C API. Because some folks in the community expressed interest in Rust, I gave some serious thought into this. I think it can done, but also technically challenging. The general idea is to make use of C ABI. That is, we build most of the Node system as C objects, which then allows us to expose them directly to Rust. The primary AST and core are still in C++, but the rust language module can directly access these in-memory AST fields via pointer de-referencing. The key challenges here, however, is how can we solve the problem of virtual functions tables, since they are part of C++ ABI and not visible in Rust. For the base Node system, that is partially achievable by defining our own version of vtable struct. In that way, we might be able to expose some of the Nodes partially to rust. I have not tried it out, but it could be an interesting step as long as it does not change the current c++ code base. Summary of My Take
Most of the current @nhynes 's proposal makes sense since they fall into support rust runtime, perhaps we should change the title to Enable rust support instead of rewriting :) |
I think @tqchen's summary makes sense - I think there's definitely space for alternative runtime backends/implementations. @nhynes if you're interested, one thing that I think Rust could do that would make the Rust backend compelling would be enabling something like a |
I think now, this is more qualified as a pre-RFC to be more specific IMHO. Some features included (2018 edition, I should say that |
@ajtulloch a no-std runtime is a nice idea! It's actually possible to use the current implementation with a custom sysroot built using xargo that only pulls in |
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models (#3567) This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for #3159, or the usecases I was thinking about in #2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models (apache#3567) This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models (apache#3567) This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
… of TVM models (apache#3567) This is an alternative implementation of a subset of the TVM runtime API (and graph runtime) that focuses entirely on reducing code size, at the expense of functionality (no tvm.extern(..) calls via PackedFunc, CPU only, etc). It might be worth incrementally expanding the surface area if there's interest. The motivation for this work was seeing what the minimal useful subset of the TVM runtime is. This is relevant for e.g. super code-size constrained applications in e.g. embedded/mobile. The current runtime is more like O(100KiB) or so, so this might be compelling for some users. The smaller surface area for auditing might make this relevant for apache#3159, or the usecases I was thinking about in apache#2523 (comment) re: the Rust runtime. The symbols in the tvm::minimalruntime space (i.e. excluding std:: and picojson::) are about 5KiB, so I think there's a bunch of room here (i.e. we could replace picojson:: with [`jsmn`](https://zserge.com/jsmn.html) or something, and we could replace more of the `std::unordered_map` usage, etc with custom primitives as well (similar to the `DynArray`).
close as many discussed feature landed. let us open new threads for incoming goals |
The one thing that common to Rust programmers is that, if it's not written in Rust, it
probablyalmost definitely should be. In the case of TVM, we can do this rather painlessly and incrementally since the "frontend" (i.e. bindings) made by @ehsanmok allow us to replicate the functionality of c++ TVM until the pure-Rust portion (currently a CPU-only static runtime) is feature complete.The target for the next TVM release (0.6) will be (in order):
tvm
namespacecommon
, remove tvm-syspacked_func
,module
,(DL)Tensor
failure
crate for errorsFor those wondering "why even??," my main response would be that rust is more ergonomic than C++ (having powerful macros, a package manager, a sane standard library); safety is also nice to have but mostly for the runtime. In an ideal world, all of the boilerplate associated with creating new passes and operators is handled by a few
proc_macro
s and somebuild.rs
scripts--same with generating the python bindings (complete with docs; ref: #2328 (comment)).The text was updated successfully, but these errors were encountered: