例 : unroll-let
(defkernelmacrounroll-let ((n offset vars) &body body)
(let ((unrolled-vars (gensym))
(collected-vars (gensym)))
(setf unrolled-vars (loop for (name init) in vars
collect (loop for i below n
collect (list (gensym (symbol-name name))
init)))
collected-vars (loop for i below n
collect (mapcar #'list
(mapcar #'car vars)
(mapcar #'(lambda (x) (car (nth i x)))
unrolled-vars))))
(append (list 'let
(reduce #'append unrolled-vars))
(loop for expr in body
append (loop for i below n
collect `(symbol-macrolet ((,offset ,i)
,@(nth i collected-vars))
,expr))))))
中間変数定義もアンロール
例 : unroll-sphere
(defkernelmacrounroll-sphere ((r vx vy vz) &body body)
`(progn
,@(loop for z from (- r) to r
append (loop for y from (- r) to r
append (loop for x from (- r) to r
when (>= r (sqrt (+ (* z z)
(* y y)
(* x x))))
collect `(symbol-macrolet ((,vz ,z)
(,vy ,y)
(,vx ,x))
,@body))))))
半径rの球へのアクセスを展開