Threads for zmitchell

  1. 3

    I’m at RustConf in Portland! I’m here through Sunday. I’m listening to talks, meeting people, and doing some recruiting.

    1. 3

      Company: Standard.ai

      Company site: standard.ai

      Positions:

      Location: FULLY REMOTE, countries vary by position (check the job listing for specifics)

      Description:

      At Standard.ai we’re building autonomous checkout technology (i.e. walk in, grab your stuff, walk out) to create a frictionless experience for shoppers. Our technology is built with a real-time computer vision system and cutting edge machine learning. Here’s a product overview video.

      Personally I find it an interesting product because it feels like something from the future. Even though our technology is based on computer vision we explicitly don’t use facial recognition to identify customers.

      My team is responsible for the service that computes shopper positions from multiple camera feeds and associates them with a consistent shopper from frame to frame.

      Here’s a video about our company, including an interview with our CEO. I think it illustrates the value our product provides to both shoppers and retailers: How Autonomous Checkout can save your corner store, with Standard AI.

      Tech stack:

      Depends on the team, but my team uses Rust and the video ingestion software is Rust bindings to GStreamer. Python is also used widely for ML stuff. Infrastructure is hosted on Google Cloud Platform and services communicate over PubSub.

      Compensation: I don’t have compensation numbers available, but pay is competitive in my experience, full benefits are provided, and PTO is unlimited (I haven’t seen people needing to haggle to use “unlimited” PTO either).

      Contact: Email me at “zach at standard dot ai” or message me here if you have questions. Include a resume if you’re interested!

      1. 1

        Hey, just a heads up: the link to the site is broken – add the protocol to fix it. (Not sure why Lobsters is hyperlinking it.)

        1. 1

          Fixed! Thanks

      1. 1

        This is so cool! Always liked the idea of Datalog and here’s a nice modern interface for it!

        1. 1

          FYI Datalog-style interfaces are frequently used to talk to databases in the Clojure ecosystem. See Datomic and EQL (EDN Query Language, where EDN is Extensible Data Notation, the JSON of the Clojure world).

        1. 1

          Starting a new job! After posting an article about optimizing some simulations I got some bites from potential employers.

          As of today I start working part-time while I finish the last couple of months of my PhD. This is my first Big Boy Job, so I’m sure there will be some adjustment, but overall I’m very excited. I think I’m going to get some great opportunities to soak up a ton of knowledge.

          1. 1

            Recently I was trying to profile some code on macOS and discovered that perf and friends when run in a container/VM don’t have access to hardware performance counters. As far as I’m aware, that leaves you with DTrace (and potentially Instruments, I don’t know, I’ve never used it). I found this while looking for learning resources.

            1. 1

              As far as I’m aware, that leaves you with DTrace (and potentially Instruments, I don’t know, I’ve never used it)

              Instruments is a (very nice) DTrace GUI, so it will work if DTrace works. Hardware performance counters are available in VMs if the hypervisor virtualises them. I’m pretty sure both Xen and Hyper-V do, I think bhyve does, what are you using?

              1. 1

                I’m just using Docker or VirtualBox on my laptop. That’s good news about Instruments!

                1. 1

                  I don’t think VirtualBox virtualises performance counters. Docker uses xhyve (a port of FreeBSD’s bhyve) to run on top of Apple’s hypervisor.framework, but I don’t think it did last time I looked, unless it’s something that the framework does transparently. What are you actually trying to measure though? Instruments is Mac only, are you running macOS inside the VM or trying to measure something about the VM from outside?

                  1. 1

                    I think there’s a miscommunication. I have a macOS laptop and I was trying to run some Linux profiling tools (perf, Cachegrind) on a binary inside of a Docker container. If you know of an equivalent to Cachegrind that has support for recent versions of macOS I would love to hear about it.

                    1. 1

                      Ah, I see. I was confused by your references to macOS tools, because macOS is completely irrelevant to your use case. Docker for Mac uses xhyve to run a Linux VM for each container, so macOS is completely out of the loop except to reserve some memory and schedule the VCPUs. The question is about tools that run inside a Linux VM.

                      You’ll need a hypervisor that virtualises performance counters to be able to use things like perf. It looks as if VMWare supports it, Parallels might (though given that their response a bug that causes reproducible kernel panics was to demand more money for the version with the bug fix, they’re never getting my money ever again). Valgrind’s cachegrind doesn’t need performance counters but its cache model is not fantastic. Anything that uses binary instrumentation (e.g. gprof, DTrace’s FBT) will work.

            1. 2

              I’ve never needed to downcast in Rust. This seems like a major anti-pattern to me. Perhaps it’s just more familiar to people used to OO languages or Go? I would say ADTs and/or trait bounds should be used instead.

              1. 2

                The only place I’ve used downcasting myself is with Python interop via PyO3. When you have an arbitrary object and want to do an attribute lookup Rust has no knowledge of the specific types contained in the attributes. The attribute lookup returns a PyObject or something along those lines, and you either live with that PyObject or downcast it into a more specific type because you have some out of band knowledge that the compiler doesn’t.

              1. 2

                Did you ever consider using Julia? I‘ve never used the language for something serious, but from the talks I listened to this sounds like a prime example for it.

                From my understanding Julia is especially well suited if you have hot loops, meaning many small calculations happening over and over again. Your core loop takes milliseconds, but you execute it for hours.

                It would be great if some experienced Julia programmer could share their opinion here.

                Funnily enough I‘ve written a Rust extension for Python myself the other day. Mainly like you because I just wanted to and it was certainly an enjoyable experience :)

                1. 1

                  I’m aware of Julia but I actually didn’t consider Julia at all. The reasons aren’t technical. I’ve heard good things about Julia, especially the differential equation libraries.

                  The context here is that I have this program fmo_analysis which does the number crunching, loading input files, saving results, etc, and is also part of a CLI application, but I also have a bunch of scripts/simulations that I’ve written that use fmo_analysis as a library. These simulations are little one-off things I did to test out various ideas, prove whether certain physical effects matter, etc.

                  I don’t know the Julia ecosystem at all, so I would need to (1) learn Julia, (2) rewrite fmo_analysis, then (3) rewrite all of the little scripts and simulations that use fmo_analysis. Instead what I chose to do was rewrite just one piece of fmo_analysis (the actual number crunching) in Rust, a language I already knew. That saves me a bunch of time, which is nice considering I want nothing more these days than to finish my PhD as fast as possible :)

                1. 5

                  I don’t always get opportunities to do deep dives on the software I write for my research, but when I do it tends to be pretty fun. In this case I had a simulation that was taking about 8 hours to run, which made me grumpy. I decided to see how fast I could make it and ended up making HUGE improvements. Read on to see how I did it and how much faster it was in the end!

                  1. 2

                    I enjoyed following your iterative process (rather than a post-mortem “here is how I ended up doing this”). Thanks for sharing.

                    I would have reached for Numba before rewriting in Rust to see how far it would get me, but I don’t write Rust so this choice would be an ergonomic/practical one. Do you have any comment on taking that approach? I’d also probably reach for CPython before a full rewrite (in C or Rust or anything else).

                    As an aside re: finding bottlenecks - my first pass after profiling is always to look for the Python loops that can be replaced by NumPy. Most of the time, that’s as far as I need to go in practice.

                    1. 1

                      I enjoyed following your iterative process

                      Thanks! I wanted it to be an end-to-end description of the process so that new-ish programmers can see what the process is like (measure, tweak, measure, tweak, etc). It’s also meant to show that optimization is often a case of compounding smaller optimizations rather than one BIG honking optimization.

                      I would have reached for Numba before rewriting in Rust to see how far it would get me, but I don’t write Rust so this choice would be an ergonomic/practical one. Do you have any comment on taking that approach?

                      Sure! I was aware of things like Numba, PyPy, etc, but I remembered that at least with PyPy there were some restrictions on which Python versions you could use, which libraries could be used with it, etc. I didn’t do a ton of research into this. I also think I mixed up Numba and Dask in my head and immediately discounted it because I only wanted to run this program on my 2-core laptop, not a cluster, so I figured the additional overhead would eat into any performance gains. I’ve actually had more than one person recommend Numba to me since I published this, so I’ll probably go back to a previous version in git and test it out to see how far that would have gotten me in comparison. I’ll post an update on the piece whenever I get around to that.

                      Writing a Python extension has been on my programming bucket-list for a while, so this was just enough of an excuse to actually do it. I already knew Rust well enough to get by, so that wasn’t a big concern. I also kind of welcomed the opportunity to see how I could tweak the low-level details to squeeze out some performance here and there.

                  1. 12

                    Working out. Avoiding salt/sodium. Taking walks. De-stressing. Sleeping. Anything to get my blood pressure down. Take care of yourself this weekend, maybe check your blood pressure, high blood pressure often have no symptoms but have pretty dire downstream effects.

                    1. 3

                      Found out recently that my blood pressure was pretty regularly 150/90. That’s as a 30 year old vegetarian that’s relatively active. Check your blood pressure even if you’re otherwise leading a healthy lifestyle!

                    1. 2

                      Strange. I’m getting 500 errors on Github.

                      1. 2
                        1. 1

                          Github seems down for everyone

                        1. 12

                          Disjoint captures is my favorite feature, that was a wishlist item for a lot of people for a long time. To be clear, it never stopped me from building anything, but it was a “this should really exist but I don’t want to be the one to work on it” item for me.

                          1. 2

                            Possibly related: If the compiler can capture single struct fields, shouldn’t it be able to borrow single slice elements?

                            error[E0499]: cannot borrow `vec` as mutable more than once at a time
                               |
                            10 |     take_three(&mut vec[0], &mut vec[1], &mut vec[2]);
                               |     ----------      ---          ---          ^^^ third mutable borrow occurs here
                               |     |               |            |
                               |     |               |            second mutable borrow occurs here
                               |     |               first mutable borrow occurs here
                               |     first borrow later used by call
                            

                            It is already possible to solve this, but rather manually: There is a function, slice::split_at_mut(), which partitions the slice in two. Not very ergonomic to have to use, especially for more than 2 elements.

                            In lack of a better word, I think “automatically split borrows” should also exist. When I read about disjoint captures, I had a hope they would have fixed this too, so I had to try (rustc 1.56, edition 2021), but apparently not.

                          1. 1

                            Because each key you need to store can fit into ~10 bits of data you can trade a small amount of memory to avoid overloading your backend systems.

                            Where does this 10-bits figure come from?

                            1. 6

                              Simplex noise is patented (because apparently you can patent math??). Completely uninteresting to me. I’m betting this is a not-insignificant reason for why Simplex noise didn’t take off.

                              1. 5

                                According to Wikipedia the patent will expire in about six months, so I’d say depending on how fast you plan to code, now’s a pretty safe time to get interested in it.

                                1. 3

                                  Probably not, there are other implementations such as OpenSimplex.

                                  1. 5

                                    OpenSimplex is not just an implementation of Simplex noise, it is a new algorithm that produces visually different results, with different performance characteristics, especially in 3D where the simplex patent is in force. The original OpenSimplex algorithm is more expensive to compute in 3D than Simplex, with the benefit of smoother output. The output was further away from the desired range of [-1,1] than wanted, and the original algorithm was difficult to implement efficiently as a GPU shader. There were directional artifacts fixed in later designs. The original OpenSimplex was not fully competitive with Simplex.

                                    Today we can use OpenSimplex2 from the same author, with two variants: OpenSimplex2F is as fast as Simplex, and OpenSimplex2S is slower (same speed as OpenSimplex) but smoother. Better output range close to [-1,1], faster shader code. Plus the directional artifacts are fixed–the new stuff is lattice symmetric: “symmetry with the lattice (without letting neighboring points’ vectors line up with each other) can result in a more isotropic (non-axis-aligned) and more uniform appearance, especially when the noise is oriented in different ways.” https://github.com/KdotJPG/OpenSimplex2

                                1. 2

                                  I’ve gotten back into generative art with Clojure and Quil/Processing, so I’m tinkering away at my current piece.

                                  I learned Clojure just so I could use Quil, so I plan to write up an article about my experiences as a Clojure beginner once I’m done with this piece.

                                  1. 1

                                    I remember this being so frustrating the first time I used Docker to run some self-hosted programs.

                                    1. 12

                                      TIL about starship for prompts. Looks good, I will give that a try.

                                      1. 3

                                        I used it when it was a regular zsh script. I got tired of having to re-configure it whenever updates broke my configuration as it changed or removed features I used. I’m not sure how stable it is now but I did enjoy it while it lasted.

                                        1. 2

                                          I’ve been using it for a while and haven’t had any of the problems that the other commenter seemed to have. My setup is pretty simple though.

                                          1. 3

                                            There was one significant backwards-incompatible change that I can recall, but it was trivial to address. And for my part, I’d rather have my software evolving than never releasing a change in case it breaks someone somewhere.

                                          2. 1

                                            I used starship previously and something happened to make it grind to a halt. I moved to romkatv/powerlevel10k and have had no such issues since. I once saw a discussion around a plug-in being implemented which was rejected as it took 10ms to run!

                                            Edit: found the discussion, it was 11.4ms and it was reworked rather than rejected, but hopefully you get the point I was trying to make

                                            1. 2

                                              One aspect of my choice of Starship that doesn’t come through in this post is that I use the fish shell as my daily driver, but I use zsh and bash on remote hosts in various places. Having a consistent prompt on all three of those is a huge selling point, even if my prompt might take 50-70ms to render.

                                              1. 2

                                                Don’t worry, not trying to invalidate your choices or anything. I’m sure it was something I did otherwise the GitHub issues would be full of noise! Having a consistent prompt is a really solid pro for sure.

                                                1. 1

                                                  I didn’t think you were :D

                                                  I just figured it might help to have a bit of clarity on the rationale. Arguably I should edit the post with that :)

                                                2. 1

                                                  I’m curious why such a dichotomy? Are you required to use zsh/bash on the remote machines or is it a matter of convenience? I’m forced to use bash, but would gladly switch to zsh if I could install it…

                                            1. 12

                                              For anyone else ignorant of what “flakes” are in this context, here is an intro.

                                              1. 7

                                                Been working on my site almost every week for a while now https://www.unstitched.xyz The idea is to help men learn how to style clothes through experimentation by using capsule wardrobes (You can skip the sign in and see the capsules here - https://www.unstitched.xyz/home ). It’s still early days so I’m still quite embarrassed about it since it doesn’t have all the features I’d like it too.

                                                I just keep going over it, refining the design or functionality and never really reaching out to people. Maybe it’s the fear of rejection, I don’t know… But I figured this week I should try reaching out to different bloggers and see what they make of it and if they thing it’s actually a useful tool. (If anyone has any tips or advice on how to get over the initial fear of trying to get people to use what you built even if you’re still embarrassed about it, please share :o )

                                                1. 2

                                                  So a capsule is like a set of clothes for a specific use case? I like this!

                                                  I’ve been really minimalist for the past, well, however many years. So I can definitely see the appeal. If I want to “do thing” and there’s a recommended minimal (good) set of stuff to do “a thing”, I’d seriously look at it.

                                                  And really minimalist means 2 shirts, 2 pants, x underwear (hey, if you really want to know, I’m not shy about sharing), compact jacket, compact rainjacket, etc. All in all, under 8kg. Happy to share more if that would make a good capsule

                                                  1. 2

                                                    Yup! That’s pretty much the concept. Users can create capsule’s based on an occasion and can share it with the community (I’ve found most guys seem to shop on a “needs” basis, i.e. need clothes for work, or that date, etc so that was the inspiration). On a personal level, I had also found that if I saw an outfit online, and maybe I didn’t like the jacket I’d struggle to see how else I could wear it, or how to make it work with clothes I already owned. So a capsule gives you a kind of framework where you can swap clothes and make different combinations knowing each combination should work to varying degrees. But user’s can also “stitch” outfits (i.e. ‘like’) So you can see the most popular combos. I’ve created a wardrobe feature as well, with the future intention of allowing users to search for capsules or outfits that contain items they own. I’ve got a lot of features I want to add and it just seems that there are too few hours in a day along with full time work

                                                  2. 1

                                                    With respect to reaching out, allow yourself to be pleasantly surprised.

                                                    For what it’s worth, I really like the idea :)

                                                  1. 2

                                                    tldr: A scalar field assigns a single value (real or complex) to every set of coordinates (typically space and time) in the coordinate space. A vector field assigns a vector to each set of coordinates. A tensor field assigns a tensor (matrix with special transformation properties) to each set of coordinates.

                                                    1. 2

                                                      Something I see in common between Elixir (in this context) and Clojure (which I’ve been learning recently) is the emphasis on simplicity. I know very little about Elixir and I’ve only been learning Clojure for about a month, but I’ve grown to appreciate the burden that’s lifted when you can focus on one isolated procedure at a time while working on a larger program.

                                                      1. 4

                                                        Elixir borrowed a lot from Clojure - macros, build system (Mix team was using some insights from Leiningen authors), pipelines, etc.

                                                        On the other hand I see that Clojure borrowed a little from Erlang, so this is like closed loop of good design inspirations.