[racket-dev] TR's optimizer eventually going to unbox structs?

From: Neil Toronto (neil.toronto at gmail.com)
Date: Mon Aug 27 12:58:37 EDT 2012

On 08/27/2012 09:11 AM, Vincent St-Amour wrote:
> TR's complex number optimizations eliminate repeated boxing and unboxing
> in chains of operations that each consume and produce complex numbers.
> Similar optimizations for structs would eliminate structs for
> intermediate results in chains of operations that each consume and
> produce that same (single) kind of struct.
> If your code has such chains of operations, then these optimizations
> could apply.
> Do you have code that you think would benefit that I could look at?

Not yet. I've given up on a union of different probability 
representation types for now.

For arrays, I could. An array is just a function with a finite, 
rectangular domain (a "shape"). Think of the type like this:

   (struct: (A) array ([shape : (Vectorof Index)]
                       [proc : ((Vectorof Index) -> A)]))

(This is a bit simplified.) So

   (array-exp (array-abs arr))

doesn't actually compute (log (abs x)) for any `x', it just creates an 
array that would if you asked it for an element. IOW, it's equivalent to

   (array-map (compose exp abs) arr)

which itself is equivalent to

   (array (array-shape arr) (compose exp abs (array-proc arr)))

If I made functions like `array-exp' and `array-map' into macros, and if 
array structs were unboxed, Racket's optimizer could inline the 
compositions. I imagine this eventual lovely outcome:

   (let ([proc  (array-proc arr)])
     (array (array-shape arr)
            (lambda (x) (unsafe-flexp (unsafe-flabs (proc x))))))

There are also FlArray and FCArray, which are subtypes of Array that 
store their elements (unboxed in flvectors and fcvectors). 
FlArray-specific operations are currently about 5x faster than Array's. 
But Array's ops don't allocate stores for intermediate results, so with 
the right optimizations, Array's could be the faster ones.

If you want to have a look right now, checkout


and try this program:

#lang typed/racket

(require math/array)

(define arr (array [[1.2 4.0] [3.2 -1.8]]))
(inline-array-map exp (inline-array-map abs arr))

Neil ⊥

Posted on the dev mailing list.