Blog
Thoughts on programming, systems, robotics, and everything in between, sharing what I learn and build.

Build an iOS App from Scratch with SwiftUI
Background On Valentine’s day 2021 I put together a small static website, Infinite Love, to hold a handful of pictures. Because it is static, adding a new photo means editing the source and redeploying, not something you want to do from your phone. So I set out to wrap it in an iOS app with a proper “new post” button. I had done plenty of web development, but this was my first time writing anything for iOS. What follows is the walkthrough I wish I’d had: taking an empty Xcode project all the way to an app running on a real iPhone.
Use Internet Explorer in Windows 11
Background With Windows 11, Microsoft has removed several outdated apps and features, including the long-hated Internet Explorer. However, some proprietary apps and legacy sites still require Internet Explorer functionality to run. Several posts suggest using the IE mode in Microsoft Edge. However, it does not work for some websites: a few government service portals, for instance, still fail to load correctly in Edge’s IE mode. Solution Step 1. Create a VB script, named ie.vbs with the following content.
Compile Caffe without Root Privileges
On shared servers or HPC clusters, you often don’t have sudo access, which makes installing system-level dependencies impossible. In this tutorial, we are going to introduce how to install Caffe entirely in user space, without root privileges. We assume that you have installed Anaconda and CUDA on your PC. Note: This tutorial is based on CUDA 9.0, Caffe 1.0, protobuf 3.2.0, and OpenCV 3.4.3. You may need to adjust the version numbers for your own setup.
Accelerate WordPress with CDN and Cache Servers
It has been a long time since I last wrote a blog post. In the past few days, I updated the architecture of Infinite Script to accelerate the speed for Chinese users. In this article, I share the new architecture of our website with you, illustrated in the figure above. Optimizing a CDN for Static Content Delivery Static content does not change over a period of time. If it does change, the changes are predictable. Static content includes images, CSS sheets, JavaScripts, and PDF files. Because of this, CDNs can cache a copy of the content at their edge servers. They can then serve it whenever a client requests it. CDNs are best at optimizing the delivery of static content from edge servers to users. Therefore, we use the CDN from Alibaba Cloud.
Build PyTorch Extensions with CUDA and CFFI
Deprecated warning: PyTorch 1.0+ replaced the old TH/THC tensor backend with ATen, and the torch.utils.ffi toolchain described here was removed along the way. If you target PyTorch 1.0 or newer, write your extensions with torch.utils.cpp_extension instead, see this GitHub repository for a working example. The article below documents the older CFFI-based approach and is kept for reference. Python is one of the most popular languages for deep learning, but as an interpreted language it is slow at tight numerical loops. Most of the time this does not matter, because the heavy lifting happens inside libraries written in C and CUDA. It starts to matter the moment you need an operation that the framework does not provide out of the box.
Getting Started with JUnit 5: Test your Spring MVC Application with it
In this post, we describe how to use JUnit 5 to test your Spring MVC application with Maven. Before diving into the pom.xml, it helps to know that JUnit 5 is not a single library but three sub-projects: the Platform (the foundation that discovers and launches tests), Jupiter (the new programming and extension model you actually write tests against), and Vintage (a backward-compatible engine that still runs your old JUnit 3/4 tests). This split is what makes the Maven coordinates below, and the SpringExtension we plug in later, much less mysterious.
Lua in a Nutshell: A Quick Tutorial for Lua
I’m reading source code written with Torch these days. Torch is a well-known deep learning framework written in Lua. So I summarize its grammar and provide a quick tutorial here. Getting Started Like many languages, Lua is case-sensitive. The following code outputs “Hello World” with Lua. Note that the semicolon at the end of a line is optional, like JavaScript. print('Hello World') You can use the interpreter of Lua in the command line:
Making Requests Non-blocking in Tornado
Tornado is one of the most popular web frameworks for Python, which is based on a single thread IO loop (aka event loop). You can handle high concurrency with optimal performance. However, Tornado is single-threaded (in its common usage, although it supports multiple threads in advanced configurations), therefore any “blocking” task will block the whole server. This means that a blocking task will not allow the framework to pick the next task waiting to be processed.