Re: Building dynamically functions to compile

Yann LeCun <[email protected]>
Newsgroups gmane.lisp.lush.devel
Message-ID <[email protected]>
Sebastien,

> As there is not lush-user@mailing lists,...

Hmm good point.

Here is an solution to youyr problem. There is an example of a similar
thing in the fast convolution library (LUSH/lsh/libidx/idx-convol.lsh). 
Have a look at the macro midx-m1fastconvolacc

It's a splicing macro (dmd). When used in compiled functions, a
splicing macro acts pretty much like a #define in C, i.e., the
compiler "executes" the macro body once, and compiles the result. So
you can use macros to generate code at compile time (or at run time in
interpreted mode).

The midx-m1fastconvolacc uses cinline to generate unrolled loops a to
build a circular register stack to speed up convolutions with a known
kernel size. Type the following to see the kind of code it generates:
 ^P(macro-expand (midx-m1fastconvolacc in kernel out 3 "float"))

Anyway, cinline works like sprintf, except that the %s
are replaced by the C name of the lisp symbols passed as arguments.
So for example:
  (cinline "b[i] = a[i] + (%s);" zz)
generates the C code:
  b[i] = a[i] + whatever_C_name_zz_has;

Your dmd should look like this

(dmd fast-update (x e a b)
   (some-expression-whose-evaluation-returns-the-code-to-run))

the matrices a and b should be set to their desired values
before compiling the function in which fast-update is called.

Here is an example that adds a constant vector "a" (known
at compile time) to vector "x". The code only produces an
instruction for non-zero elements of a:

(dmd fast-addv (x a)
  (let ((l `(progn (cinline "{ double *px = IDX_PTR(%s,double);" ,x))))
    (for (i 0 (1- (idx-dim a 0)))
      (when (<> 0 (a i)) 
        (setq l (nconc1 l `(cinline "px[%s] += %s;" ,i ,(a i))))))
    (setq l (nconc1 l '(cinline "}")))))
 
? ^P(macro-expand (fast-addv x [0 0 0 3 0 4]))
(progn
  (cinline "{ double *px = IDX_PTR(%s,double);" x)
  (cinline "px[%s] += %s;" 3 3)
  (cinline "px[%s] += %s;" 5 4)
  (cinline "}") )

? (de asd (z) ((-idx1- (-double-)) z) (fast-addv z [0 0 0 3 0 4]) ())
= asd
? (dhc-make () asd)

Here is the generated C code ( C/asd.c ):

    extern_c char
    C_asd (struct idx *L1_z)
    {
      TRACE_PUSH ("C_asd");
      {
        {
          double *px = IDX_PTR (L1_z, double);
          px[3] += 3;
          px[5] += 4;
        };
        TRACE_POP ("C_asd");
        return 0;
      }
    }

Here ya go.

> Any documentation on cinline ?

Soon.

  -- Yann


On Wednesday 27 November 2002 04:40, [email protected] 
wrote:
> For a numerical simulation I need to update a vector at each step with a
> formula of the type:
>
>   x[t] = A . x[t-1] + B . e[t]
>
> where x[t] is a vector of size n, e[t] a vector of size m, A a matrix of
> size (n x n) and B a matrix of size (n x m)
> with m,n < 10.
> But as A and B may be quite sparse (only 10 % different of 0),  I want to
> avoid to make the multiplications by 0.
> My strategy was to give to a function the known matrix A and B (i.e. list
> of list) that will build the C expansion of
> 	 x[t] = A . x[t-1] + B . e[t]
> with all zeros written explicitlty and let the C compiler optimize and get
> rid of all 0.
>
> Hence, something like
> 	(setq stepper (build-stepper A B))
> 	(dhc-make "stepper_code" stepper)
>
> 	;; loop
> 	(repeat (setq x (stepper x e))
>
> Now, how can I build easely the build-stepper high order function ?
> I can't use the #{ #} construct with references to A and B as it will give
> an awful code.
> I want to use cinline directly but there is no documentation about it. I
> was thinking to something like
>
> (de build-stepper (A B)
> 	;; build string of C code with sprintf and code
> 	(let ((c-code (sprintf "bla %s bla %i" ...)))
> 		(cinline c-code)))
>
> Well, has anybody used lush with this kind of goal in mind (sorta
> specialisation of important code) ?
> Any hint ?
>
> TX
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: Get the new Palm Tungsten T
> handheld. Power & Color in a compact size!
> http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en
> _______________________________________________
> Lush-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/lush-devel


-------------------------------------------------------
This SF.net email is sponsored by: Get the new Palm Tungsten T 
handheld. Power & Color in a compact size! 
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.