I've put together a minimal version of my program that compiles and
exhibits the compilation behavior I don't understand. (You can't
actually run my application, because I've only included a couple of
functions). In the function update-log-pr-xi, I'm getting compiler
notes about float to pointer coercion, and I'm not sure why. I have
many similar functions for which I get no compiler notes. When I run
the program, this function ends up taking about 1/3 of the total time
and doing about 90% of the consing.
AFAICT, it seems that even though the auxiliary function log-sum-exp
is inlined, and is known to return a double-float (and safety is 0 so
no check should be done in any case), it's still allocating on the
heap for every iteration. Any help explaining why, or better yet
figuring out how to avoid this, would be most appreciated.
The commented out functions towards the top are before macroexpansion,
the actual longish functions are the same functions after I've
expanded my own personal macros. (Without macros, writing fast
programs in Lisp would be a LOT more work.)
Cheers,
rif
(declaim (optimize (speed 3) (debug 0) (safety 0)))
(defstruct (likelihood (:conc-name nil))
(num-components 0 :type fixnum)
(num-datapoints 0 :type fixnum)
(Lij (make-array 0) :type (simple-array * (*)))
(Rji (make-array 0) :type (simple-array * (*)))
(log-prob-of-xi (make-array 0 :element-type 'double-float) :type (simple-array
double-float (*)))
(total-log-likelihood 0.0d0 :type double-float))
;; (defun-inline log-sum-exp (v index-to)
;; (let ((vMax (df-vmap-max v :index-to-ignore index-to)))
;; (df+ vMax
;; (log (df-vmap-sum #'(lambda (vK) (exp (- vK vMax)))
;; v
;; :index-to-ignore index-to)))))
;; (defun update-log-pr-xi (likelihood)
;; (let ((nc (num-components likelihood)))
;; (vmap (#'(lambda (dfa)
;; (log-sum-exp dfa nc))
;; :result-element-type df
;; :default-argument-element-type df-vec)
;; (Lij likelihood)
;; :result (log-prob-of-xi likelihood))))
(progn
(declaim (inline log-sum-exp))
(defun log-sum-exp (v index-to)
(let ((vMax (LET* ((INPUT2531 V)
(LENGTH2529 INDEX-TO)
(RESULT2528 MOST-NEGATIVE-DOUBLE-FLOAT))
(DECLARE (TYPE DOUBLE-FLOAT RESULT2528) (TYPE (SIMPLE-ARRAY
DOUBLE-FLOAT (*)) INPUT2531))
(LET ((COUNTER2532 (THE FIXNUM LENGTH2529)))
(DOTIMES (COUNTER2530 COUNTER2532 NIL)
(DECLARE (TYPE FIXNUM COUNTER2530))
(SETF RESULT2528
(FUNCALL #'MAX
RESULT2528
(FUNCALL #'MAX (AREF INPUT2531 COUNTER2530))))))
RESULT2528)))
(THE DOUBLE-FLOAT
(+ (THE DOUBLE-FLOAT VMAX)
(THE DOUBLE-FLOAT
(LOG (LET* ((INPUT2536 V)
(LENGTH2534 (ARRAY-DIMENSION INPUT2536 0))
(RESULT2533 0.0d0))
(DECLARE (TYPE DOUBLE-FLOAT RESULT2533) (TYPE (SIMPLE-ARRAY
DOUBLE-FLOAT (*)) INPUT2536))
(LET ((COUNTER2537 (THE FIXNUM LENGTH2534)))
(DOTIMES (COUNTER2535 COUNTER2537 NIL)
(DECLARE (TYPE FIXNUM COUNTER2535))
(SETF RESULT2533
(FUNCALL #'+
RESULT2533
(FUNCALL #'(LAMBDA (VK) (EXP (- VK VMAX)))
(AREF INPUT2536 COUNTER2535))))))
RESULT2533))))))))
(defun update-log-pr-xi (likelihood)
(let ((nc (num-components likelihood)))
(LET* ((INPUT2518 (LIJ LIKELIHOOD))
(INPUT2519 (LOG-PROB-OF-XI LIKELIHOOD))
(LENGTH2516 (ARRAY-DIMENSION INPUT2518 0))
(RESULT2515 INPUT2519))
(DECLARE (TYPE (SIMPLE-ARRAY double-float (*)) RESULT2515)
(TYPE (SIMPLE-ARRAY (simple-array double-float (*))) INPUT2518)
(TYPE (SIMPLE-ARRAY double-float (*)) INPUT2519))
(LET ((counter2520 (THE FIXNUM LENGTH2516)))
(DOTIMES (COUNTER2517 counter2520 NIL)
(DECLARE (TYPE FIXNUM COUNTER2517))
(SETF (AREF RESULT2515 COUNTER2517)
(FUNCALL #'(LAMBDA (DFA) (LOG-SUM-EXP DFA NC))
(AREF INPUT2518 COUNTER2517)))))
RESULT2515)))