2,917 karma · joined April 21, 2019
I've interacted with ~15 projects on Sourcehut, and all of them are by the same team of people maintaining Sway.
I'm not projecting to all sourcehut projects, just recollecting the experience of all sourcehut projects I've ever interacted with.
I fully agree, nobody wants to search IRC logs for technical information about a project.
If the only documentation about a technical decision in an open source project is an IRC discussion, then that project is just doing open source wrong. Those logs are at best hard to search for, and more often than not, non-existent.
When we have "online" meetings (IRC / Discord / Zulip / Matrix / Zoom / ...) to discuss technical issues in our open source projects, we always publish a full summary of the meetings so that everyone who wasn't there can read them and follow the rationale, or raise issues with it.
IRC isn't the problem, the problem is synchrnonous communication channels in general (IRC, whatsapp, telephone, Matrix, ....). If somebody is not available when the discussion is ongoing, they can't participate. That does make your communication channel much less open than, e.g., a mailing list, where somebody from a different timezone can read the discussion 8 hours later and participate in it.
> User entitlement is a huge problem in open source, and it burns out maintainers faster than anything else. I don't stand for it.
What burns maintainers is having too much to do, and the root cause of that is failing to grow other maintainers to help you with your projects, which is impossible to do if you act as a burned maintainer, because open source is something most people do on their free time for fun, and stressed / burned / overworked maintainers aren't fun to deal with.
Sustainable projects have a high-ratio of contributors relative to users. When this ratio is high, it doesn't matter that some users act entitled, because there are enough maintainers to deal with that load. If you have a lot of users, but a relatively small contributor base, that's when things become problematic.
Attracting contributors is probably the hardest part of open source, and like it or not, every project is competing against all other projects for contributors. Projects that are super nice to every user that interacts with them, no matter how "wrong"/"entitled" the user is, or tired its maintainers are, attract the most contributors, because people like working there.
Being tired while dealing with an entitled user and trying to be super nice with them is super tough, but all other alternatives I know are much worse.
Not really. Ideally, I'd have read a comment saying: "We discussed this on IRC, and for this and that reason, we decided that this is probably never going to be worth doing. If you have any new information or argument that was not considered above, please do raise it with us, but we are closing this issue for now."
> There's a lot of discussion you don't see, too. Discussion on the IRC channel, private discussions between maintainers, snippets here and there on patch reviews and other issues... just because you didn't get your say, doesn't mean that the issue wasn't sufficiently discussed.
If your discussions don't happen in the open, how open is your open source project really?
You can discuss things on IRC, or whatsapp, or wherever you want, but if a synchronous and/or private communication channel is used to decide on technical issues that impact the project, then you are essentially excluding everyone that doesn't live in your same time-zone, wasn't there on IRC at that time, can't search those IRC logs, wasn't invited in the room, etc. from impacting your project.
That's just not open enough for me, so I don't contribute to projects that work like that.
Rust or th linux kernel discuss everything in the open, so that everyone can see it and participate, whenever they have time to, and make their case. Whether that's a mailing list, a forum, or a github issue doesn't matter.
But closing an issue with "no" isn't very helpful for all those users that weren't in the room where that was decided, and they will all wonder "why".
> that doesn't make me a bad maintainer IMO.
There are dozens of different ways of maintaining open source projects. Just because sway's way doesn't fit me doesn't mean it's bad. It just means that it doesn't fit me. If you'd like to change something so that it fits people like me, the above hopefully explains what the issues for me were. But I don't expect you to do that, and you don't have to do that, and its perfectly fine for you to disagree and don't want to do that.
Citation needed.
Rust lacks so many fundamental C++ "features" (variadics, thin pointers, HKTs, const generics, specialization, overloading, inheritance, good FFI with C++, C++ exceptions, ...), that trying to sell it as a C++ replacement is quite hard.
OTOH, Rust is pretty much at feature parity with C, having excellent interoperability with it, and only lacking somewhat in inline assembly, allocas/VLAs, etc.
You can take any C project, and implement a new feature or refactor some part of it in Rust without issues.
You can't do the same for C++ code easily: integrating with C++ templates is hard (e.g. try to use a C++ Boost library, or the C++ standard library from Rust), integrating with C++ error handling is hard (try to write Rust code that can error using C++ exceptions, or that can be unwinded with one), calling C++ ABIs is hard from Rust, interfacing C++ types with Rust is also hard (inheritance, virtual functions, etc.).
Any successful C++ projects that uses Rust (e.g. Firefox), uses Rust as a better C to implement a C library, that can be called from C++. That's not "being a better C++" in any way of the word.
https://github.com/swaywm/sway/issues/1005#issuecomment-3315...
where the comment that closes the issue just says "we'll never implement this, issue closed".
I sympathize with you in that, if you had little time and other things to attend to, then just closing an issue is an instant reward of having something less to do.
But I think it would have been better to, first, don't do anything about that issue if you didn't had the time to do it properly (even if you were the one that filled the issue!), which would have been to write down the rationale why you think that feature is not worth its tradeoffs, and also, to have let other users speak up their mind, and see what others think, before making a decision.
For me, that difference in "project culture" is the difference between an open source project that's worth contributing to, and one that is not.
I've grown a couple of very large open source projects, and some of them I look at once a year, and they keep growing with dozens of PRs per week or day! The main reason I am able to just move on to other things is because I've grown and mentor the new maintainers and leaders of these projects , and I know they both carefully listen to the projects users, and are able to grow new contributors, just like I did.
For countries that don't test, that number is zero. Quite the useless metric to report.
Much more meaningful would be: "(actual deaths/day) - (avg deaths/day of 2019)"
Rust is an alternative to C++ or C, not to Go, C# or Python.
Sure, you can write any program on any language, but if you try to write bare metal C code from C# or Python, your frustration will be quite large as well.
Use the right tool for the job.
Do you know many people that used to do this with macOS and are now using Windows ?
Like, oh boy, I tried, but after 4 months I ended up back with macOS.
The interaction was of the form: "I'm having this problem, I've looked at this, what would be the best way for me to improve this". Reply from Drew "No [issue closed]".
Then using sway, I ran into a lot of problems, and many of them were already reported, but closed issues, which closed with a similar exchange.
At some point, every time I had a sway problem, I would search for my issue on Github with the closed filter first. Finding those issues, with no rationale, workarounds, path forward, discussion of any kind....
Yeah, I just stopped using sway a while after and went back to i3. It at least worked, so I never had to interact with their community.
Like... that's the program that handles everything that you mentioned.
However, I don't like how they treat users, potential contributors, etc.
Like, I started using sway full time, posted a question, started looking at the source code to fix it myself, and then just ended up fixing it for my fork and never pushing it upstream because the main thing I learned through my questions was that my free time is to valuable to deal with them.
Maybe 30 years ago the badge of being able to contribute to open source even though the maintainers are "super tough" meant something. But it's 2020: I want to do things in my free time that make me happy, I want to learn something while contributing to open source, and ideally learn from those who know more than me. So I'd rather just continue contributing to Rust, where everybody is super nice, those who know more teach and mentor those who know less, and in general the community is super open and reflective (e.g. the attitude is not "how come you didn't know this" but rather "which mistake did _we_ make that led you here without learning this along the way").
To me sourcehut is just a fence that keeps the kind of maintainers I don't like at the other side of the github fence.
This attitude is super harmful. Drew is just one person, and they can only do so much, and that does reflect on Sway, which is why I ended up switching back to i3.
One can pretty easily see the impact of COVID-19 there, even on countries that are not testing and therefore not reporting any cases...
Unfortunately I haven't been able to find that data for the US.
That's because HIP requires changes to the program source code, but AMD has managed to upstream those patches to other projects. If they haven't done that for Tensorflow, that's kind of their problem.
Clang can compile CUDA code, and it has an AMDGpu backend. AMD could compile that CUDA code to SPIRV if they wanted. Intel and PGI do compile CUDA to x86-64 using LLVM without problems.
Rust does not have
fn foo() -> let { ... }
where fn foo() -> let { 0_i32 }
let x: i32 = foo();
fn bar() -> let { 0_f32 }
let y: f32 = bar();
That is, you can't have an opaque function return type, that's both opaque, but simultaneously the user can name and use all interfaces from.If you change the implementation of `bar` with such a feature to return `i32` instead, all calling code of `bar` would break. And that's precisely why Rust doesn't have D/C++'s `auto` in return position.
They want to have a generic function that returns opaque types implementing different interfaces depending on the inputs. I've replied to that above.
You can provide more interfaces in Rust:
fn map(...) -> impl Iterator<Item=U> + Index<Target=U>
but you can't provide "conditional" interfaces (for most interfaces at least), e.g., this won't work: fn map(...) -> impl Iterator<Item=U> + ?Index<Target=U>
where `?Index` reads as "maybe implements Index".To allow that you would essentially need to say that "if the input implements `Index`, the output implements `Index`":
fn map<U, T, F, I, O>(it: I) -> O
where I: Iterator<Item=T>, U: From<T>,
O: impl Iterator<Item=U>,
I:?Index<Target=T> -> O:?Index<Target=U>
{
it.map(|t| From::from(t))
}
The type system implementation already supports these types of constraints, but there isn't a language extension that exposes that. I don't see any fundamental reasons that make this impossible, but there are many trade-offs involved.Notice that, for example, the output Range does not implement the same interfaces as the input range, e.g., the input Range implements an `Index` interface over a range of `T`s, but the output Range implements an `Index` interface over a range of `U`s. In D this is super implicit in the implementation details (body) of an equivalent `map` function, but in Rust it needs to be part of the type signature to avoid changes to a function body to silently cause API breaking changes. In D, you could change the body of map to map only from Range(T) -> Range(T), without changing its interface, and that would break all code using it to map a Range(T)->Range(U).
When I see someone saying that they prefer D/Nim/Zig value proposition as a "better C" than Rust, what I see is that people are just starting to realize that there are many more options than C for doing programming tasks that require a more precise interaction with the hardware.
It's just not "assembly", but there are multiple different assemblers with different trade-offs. It's also not "assembler < C" anymore, since in some aspects newer languages do offer more low level control about certain things than C.
It's also not just C/C++/Zig/Rust/Nim/D competing at the lowest-level of the space. Ada, Forth, Scheme, and many other languages are also widely used in this space. They just aren't the "next new thing".
fn map<U, T, F, I>(it: I) -> impl Iterator<Item=U>
where I: Iterator<Item=T>, U: From<T>
{
it.map(|t| From::from(t))
}
infinitely more readable than fn map<U, T, F, I>(it: I) -> auto
where I: Iterator<Item=T>, U: From<T>
{
it.map(|t| From::from(t))
}
The type signature of the first one clearly tells me that the return type is an `Iterator<U>`, even though the actual type cannot be named because of the anonymous closure.The second one leaves me guessing what the return type is.
If the actual type cannot be named, it is rarely the case that this is all there is to it. Usually, users are expected to use that type "somehow" (it is a `Range`?), and that means that there are some interfaces that these types implement.
Implementation and standardization should go hand-in-hand, to make sure that you don't standardize something that's unimplementable.
If you can't find companies to implement the standard while it's being developed, then maybe nobody cares?
If you are installing TF from source, then it becomes your job. TF docs should help you here, and TF's build-system should be able to guide you through what you need to install.
- NVIDIA themselves ship multiple CUDA to multi-core x86-64 compilers for different programming languages CUDA C/C++/Fortran
- AMD has been shiping hip for a while, advertising it as production ready, without any lawsuits (AFAIK). hip is also being used in production.
- LLVM and clang have had open-source CUDA (and PTX) support for years, and nvidia have not enforced any kind of patents there.
The people who picked up CUDA can now easily compile it to target NVIDA and AMD GPUs, as well as x86-64 CPUs, using a pletora of compilers (nvcc, hip's framework, PGI compiler for CUDA->x86, Intel's CUDA compiler, ...). Each upgrade to the CUDA platform has been backward compatible, and improved performance by quite a bit.
Those who went for OpenCL lost Apple's platform support, have so-so AMD and Intel CPU support, and not so great AMD and NVIDIA GPU support, and now are getting an "ecosystem reset".
I find this quite ironic TBH. The main advantage of OpenCL over CUDA on paper was supposed to be the vendor portability, but CUDA is delivering better on that "feature" than OpenCL.
And now they land an ecosystem reset. I hope that people can easily migrate their OpenCL 2.x code to OpenCL 3.0. If doing that requires a rewrite, they might as well rewrite their code in CUDA..
Do Apple and NVIDIA have good support for OpenCL ?
EDIT: From the same article, further below:
> Apple has deprecated OpenCL
> AMD’s OpenCL drivers are a mess,
> NVIDIA’s interest is tempered by the fact that they already have their very successful CUDA API,
That's an interesting thought. I'm not sure I agree, maybe?
The user job is to express how to partition the problem. To do that properly, they need to know, e.g., "how many bytes can I fit in the next partition per unit-of-compute", so the langue/run-time has to tell them that.
I don't know if knowing the costs of memory access at each level or across levels is useful. It is a reasonable assumption that, at the next level, memory accesses are at least one order of magnitude faster, and that synchronizing across the hierarchy is very expensive and should be minimized. That's a good assumption to write your programs with, and knowing actual costs do not really help you there.
> Another subtle but important question is: what primitives should a language provide to access a memory level, and which ones to move between levels. An obvious choice is to treat each level as an array
I think CUDA's __shared__ memory is quite good. E.g. per kernel, a way to obtain memory in the level of the hierarchy that the kernel is currently working on. Nobody has extended CUDA to multiple levels because there hasn't been a need, but I expect these programs to be "recursive" in the sense that they recursively partition a problem, and for __shared__ memory on each recursion level to give you memory at a different level of the hierarchy.
To move memory across levels of the hierarchy, you would just use raw pointers, with appropriate reads/writes (e.g. atomic ones). The exact instructions that get emitted would then depend on which level of the hierarchy you are. For that the compiler needs to know something about the architecture it is compiling for, but that seems unavoidable.
> [1] Z. DeVito, J. Hegarty, A. Aiken, P. Hanrahan, J. Vitek, Terra: A Multi-Stage Language for High-Performance Computing. https://cs.stanford.edu/~zdevito/pldi071-devito.pdf
Thanks, I actually hadn't read the Terra paper. I'll try to get to it this weekend. I think that using a Lua-like language as the meta-programming for your language (e.g. Regent) is an interesting approach, but it is not necessary.
For example, Scheme, Lisp, Haskell, D and Rust have shown that you can do meta-programming quite well in the same language you do normal programming in, without having to learn a completely different "meta-language".
I particularly like Rust procedural macros. It is normal run-time Rust code that just get first compiled, and then executed (with your source code as input) during compilation, with some twist to make that quite fast (e.g. the compiler parses an AST, and the proc macros do AST->AST folds).
If one wants to delay that until run-time, one should just do so (e.g. you just embed your compiler in your app, and when your proc macros run, its "run-time"). No need to layer multiple languages, but maybe the Terra paper convices me otherwise.
I think I was expecting to have a similar level of control as with CUDA or OpenCL, but it turns out that wgpu/Vulkan compute is more like "OpenGL compute shaders", which is "compute for a rendering pipeline", something quite different than "CUDA/OpenCL compute", which has nothing to do with rendering.
If all you want is to stick a compute shader in your rendering pipeline, then wgpu/vulkan are great IMO.
If you want to do CFD, linear algebra, or machine learning, then it feels like fighting against a technology that just wasn't meant to be used for that. I managed to write a tiny explicit CFD code with Vulkan compute just fine, but the moment I wanted to implement a slightly more complicated algorithm, I was limited by things like how to properly do linear algebra (e.g. I needed a algebraic multi-grid preconditioner and a conjugate gradients implementation, and ended up fighting against how to control what's get put into shared memory when). When trying some NN kernels, I got stuck with the same issue. I managed to implement an FFT and convolutions with Vulkan, but... I couldn't manage to get convolutions achieve the same perf as with CUDA cause with Vulkan I had to use a "pull" algorithm (read from all points in the window, write to one point), but that just performed way worse than the "push" algorithms that are possible to implement with CUDA (maintain a shared memory cache where you write, and as you read one value from the window, write its contribution to multiple locations, then do a full cache write to global memory). In numbers, I went from ~150 Gb/s throughput with Vulkan to ~700Gb/s with CUDA.
I think maybe Vulkan/SPIRV could benefit from better compilers that take the "pull" algorithm and compile it to a "push" one using shared memory, but you are then at the mercy of the compiler for a 4x perf diff.
I think that if I have a rendering pipeline in which I want to integrate some compute, then wgpu/Vulkan are great, particularly because chances are that the compute you need is per "vertex/pixel/..." kind of naive-massively-parallel kind of compute. But if I just have a raw compute pipeline, then it feels like using the wrong tool for the job.
That's why if you are shipping code to the AppStore, you probably don't really care whether Apple uses x86, ARM, RiscV, powerpc, or all of them in different devices. Producing working binaries becomes Apple's job.
(You do not ship binaries to the AppStore, but LLVM-bitcode, that Apple compiles for you for whatever hardware they decide to ship next).
If you are not shipping Apps through the AppStore, you are on your own.