Halide: a language for image processing and computational photography

Apparently this has not come up.

Halide (principle: Jonathan Ragan-Kelley). http://halide-lang.org/:

Halide is a programming language designed to make it easier to write high-performance image processing code on modern machines.

The core concept is apparently to split programs into two parts. One part of the program specifies the algorithm, which relates inputs to outputs. The other part of the program specifies the schedule, specifying which parts of the output should be computed when and where.

In lieu of a distinct surface syntax, Halide programs are apparently built by programmatically assembling ASTs:

Its front end is embedded in C++. Compiler targets include x86/SSE, ARM v7/NEON, CUDA, Native Client, and OpenCL.

You build a Halide program by writing C++ code using objects of type Halide::Var, Halide::Expr, and Halide::Func, and then calling Halide::Func::compile_to_file to generate an object file and header (good for deploying large routines), or calling Halide::Func::realize to JIT-compile and run the pipeline immediately (good for testing small routines).

Additionally, Dan Tull has a demo of "Live Coding Halide" for which there is a video here:

https://youtu.be/...

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

introductory talk video

Halide Talk by Andrew Adams.

This presentation is quite lucid and compact.

economic impact

The demos compare real-world, hand-optimized, "inner loops", of some commercially deployed code to analogous code using Halide.

Halide reduced the size of the source code by a factor of 10.

Halide allowed much greater experimentation with the design space of how functional code mapped on to hardware.

Using Halide the researchers, at least in these cases, bested the commercial code with an order of magnitude less code and code of considerably better clarity, simplicity, and flexibility.

The researchers beat a professional effort that probably took at least a few weeks if not months in an afternoon, with a fraction of the code.

Schedule specification and synthesis is great

Same high-level concept let us tackle how-do-you-parallelize-css and crank out big data visualizations :)

Generating great and multibackend code is pretty obvious. I was personally surprised when it helped dev/debug: you quickly get into computer-aided parallel programming. It suggests valid schedules.. Or why your intent is buggy.

example source code fragments imply small scale code inputs

Folks looking for a lot of meat can find it in the thesis linked under the publications section. For example, an early heading in section 1.2 is "a language of schedules", so there is general abstraction to consider.

Looks like functional image processing on the domain of 2D pixel tables. One of the course lecture slides has a note that Halide is not Turing complete, missing if-statement and loops, which contributes to my impression it aims to specify a transform during dataflow from input to output.

re aims to specify a transform during dataflow from input to out

Looks like functional image processing on the domain of 2D pixel tables.

Pure and simple. With expressions that map output and intermediate pixels to relatively positioned input pixels. Separately, how the evaluation of the expressions are mapped onto threads, memory, and specific loop structures is parameterized in a slick way, allowing an afternoon of knob twisting to find sweet spots.

shrinking code size

I almost posted a new topic, to discuss making code smaller, but perhaps no more than three people want to say a couple things about that. :-) So I put it here as follow-up to your observation Halide got results in a small amount of code, which is neat even if the corpus involved has small scale.

Elsewhere LtU has discussed value in knob-twisting to explore value propositions. Rapid turn-around has high value, so a user (typically a dev) can ask "what happens when I do this?" without waiting a long time for answers. Since Halide can quickly remap how spec generates concrete implementation, you can explore options in the algorithm space more thoroughly with low cost. Sometimes re-use seems to have a lot to do with easily re-mapping how abstract requirements attach to concrete versions specialized to some other focus.

Here's a new part about focusing on code size. What if you wanted a lot of complex code services, but preferrably with small total code size, while still keeping as high a clarity to human beings as possible? (In other words, compression isn't a good solution for smaller code, if a human being must see an original big size when working with it.)

A fair amount has been said about that before, in the context of high versus low level languages, where the former can be smaller due to generality and expression of algorithms in a high enough plane to apply to more things. (For example, a map-reduce algorithm doesn't care much about the concrete details, so they are easy to swap as needed.)

You might also think of a language and/or associated libraries as providing a vocabulary of primitives, where the more of these there are, the smaller you can compress a program written in terms of them (because each primitive might fit more precisely what you want to say, and requires less local tweaking each time used). But a big language can require memorizing a lot of stuff; maybe you can't easily understand code until you know a big dictionary.

A language might also address powerful ideas very crisply, making code small provided you grasp the exact nature of those powerful ideas clearly, at the cost of possibly long education about ideas involved, if not already grasped by naive users with little training beyond what is typical in extant school programs. Perhaps small code cannot be understood by someone else who has not yet climbed the Zen mountain involved.

Bigger size might be caused by repetition (like boilerplate), or by weak primitives requiring many of them to get somewhere (building with toothpicks instead of two-by-fours). Size might also be increased by mandatory redundancy, like retelling almost the whole story again from scratch, but with new character names and a different back-story for one central figure, without any way to share code from old stories which are gratuitously incompatible.

I'm interested in comments about making complex systems smaller, while still being easy for a human being to process without fancy tools. (So that if you wrote on paper, the small size would still be a benefit without a software tool that fixes things for you.) I can start a new topic if there's actually much to say about this.

compression and "address powerful ideas very crisply"

A metaphor for intelligent rather than brute concision is the comparison of compressing an image of a part of the Mandelbrot set using gzip, to compressing the image to a few equations grounded in its definition.

The Halide video linked above describes the process by which the inventors came to intelligently understand this particular domain well enough to describe it in terms of simple expressions. (Roughly: they studied how real-world optimized examples differed from simplistic expressions of the functions being computed..)

With this insight, and the scattered unprincipled detritus of C++ and a an abstract assembler, and some basic old PLT concepts, they could express their insight.

separation and hierarchy oriented structure might simplify

Of course, best is a human being noticing a small rule generating the details needed. By compression I meant only the usual, with software applying a brute-force, one-size-fits-all mechanical algorithm typically uninformed by the content beyond things always looked for.

I have few ideas about making code smaller. One approach is aiming for an endoskeleton, around which fleshy detail is hung. But this seems to require a human find a good skeleton. Although a standard skeleton specific to a type of application space might be better than one standardized across all apps wihtout regard for what they do and how. This is a sensible-core metaphor, presuming behavior is thus expressed more concisely when a skeleton approximates movement in code space well.

Another idea is progressive disclosure, with a smaller general summary of abstractions (to express basic themes and detail more essential to intended goals), with other code saying how that maps to a concrete realization (with obvious analogy to how Halide is organized). The idea is to pursue explicit pyramid structure, with a smaller more general pyramid tip, which presumably has more intelligent compression. You would want the smaller pyramid tip to be apparent, somehow, so its role as central explanation was easy to notice. It would make sense for the most general part to be primarily declarative (here are some things, how they relate, rules they follow, and what we want to get). That has a disadvantage of favoring top-down POV when most devs I know prefer to work bottom-up (we have a bunch of code that does vaguely related things, which we'll connect before experimenting, to anneal observed behavior until it gets close to something we want).

I don't have a good plan for either, but I've been asuming if one breaks large programs down into smaller interacting programs, it will be easier to draft a skeleton and to express declarative relations in terms of sub-program roles and connections. Recently I started comparing and contrasting subroutines and programs, with an idea to viewing async operations (anything observably concurrent from a local POV) as if they were invocations of separate programs, and this would unify remote server request, local background tasks and local process parallelism. I have some really mixed up imagery of invoking code from modules using a path notation, that might be either local synchronous function calls or async process execution, where remote server calls can be made to look like the latter. Local code would not need to know what is async. If syntax means call-and-wait-for-result, then it can map to normal function call without cost, or get handled suitably when it actually is async, or a call to an external process.

While I generally like object-oriented structure for a long-running piece of code doing a lot of things (in every language, not just oo ones, so C as well as C++), I don't think the entire global structure of a large app should try to capture everything as objects that look forced to live in one address space. A little compartmentalization would simplify things, especially if some parts must in fact be handled non-locally.

Your comment seems confused and rambly

Was it machine generated?

okay

Humor is welcome, even if sting is intended. A funnier thing to do is pretend I had said something else, and respond to that. (Could be a running LtU joke.)

tips on how to improve writing, thinking, and commenting

These are not systematic tips. A few notes.

This is where you lost me, the reader:

Of course, best is

We have no context in which the word "best" has meaning. (I am not asking for one to be retroactively supplied.)

The phrase "of course", deployed in that manner, is a tell.

The rest of the text appears digressive and comparably vague.

Oh, I can not help it. Here is another example:

I have few ideas about making code smaller. One approach is aiming for an endoskeleton, around which fleshy detail is hung. But this seems to require a human find a good skeleton.

Let's pick this apart.

I have few ideas about making code smaller. One approach is ...

A cursory scan says that "a few" turns out to mean "two". Also that paragraph breaks are somewhat randomly placed.

"ideas about making code smaller" is vague to the point of uselessness. One trick I have found for making code smaller is to print it with a smaller font (fixed width of course, and laser printer perferably). It is possible to print plain-text source code files with two or even four logical pages per printed paper (using standard unix utilities). (Two: side by side. Four: in quadrants.) For some debugging tasks and comprehension tasks (especially in modern languages), that is very useful (depending on what you are doing).

See? Digressive and rambly. Anyone can do it. Nobody should.

Back to your text:

One approach is aiming for an endoskeleton, around which fleshy detail is hung. But this seems to require a human find a good skeleton. Although a standard skeleton specific to a type of application space might be better than one standardized across all apps wihtout regard for what they do and how.

One gathers that "endoskeleton" is meant as some kind of metaphor, in parallel with "fleshy" and "hung" but, honestly:

You sound indistinguishable from a con artist who is trying to fake the lingo.

Let's see how effective a metaphor you have by repurposing it with a hypothetical example. A fake expert could go on the TeeVee news and say:

One way to approach learning about foreign policy is to to aim for a kind of endoskeleton around which fleshy detail is hung. But this seems to require a human to find a good skeleton. Although a standard skeleton specific to a type of policy issue might be better than one standardized across all issues without regard to the what, who, when and where.

Around the room people are no doubt stroking their chins and nodding.

The real topper is how you end that paragraph:

This is a sensible-core metaphor, presuming behavior is thus expressed more concisely when a skeleton approximates movement in code space well.

As if "movement in the code space" and "sensible-core metaphor" are widely agreed upon concepts.

What I am doing here, making fun of your terrible writing this way, is the kind of thing that goes on in the classroom of a good, interactive writing course with a decent teacher. The sort of class to look for is one where you are obligated to write frequently and present your work in class for analysis and critique.

There are a lot of basic mechanics to decent non-fiction writing if you want to be taken seriously. Mastering them can also help a person learn to self-critique their own ideas before saying or writing anything at all.

over and out

I can avoid your topics until I learn how to write. Your critique is useful data on how things I say sound, since I prefer not to guess. I assume you don't want feedback on your hostile wording. No sweat.

The word "few" by itself has slightly different meaning than "a few." If Ned asks Wil how many ideas come to mind about a topic, the response "a few" sounds like "some to several" to Ned. But "few" by itself means "not many at all", though not zero. Two is few. Apparently "very few" works better for you, but I avoid adding "very" gratuitously when meaning doesn't change. A whole sentence at the start that "not many ideas come to mind" would have been less ambiguous, but longer. I should never have tried to say several things in too few words. Anyway, what I find most useful about your comment is that compression by phrasing and metaphor can work badly compared to a longer droning spiel.

This should probably be on

This should probably be on the front page.