[Antik-devel] Matlisp, CLOS
Nicolas Neuss
neuss at math.fau.de
Fri Mar 8 12:09:00 UTC 2013
[I added some more people to the CC]
Akshay Srinivasan <akshaysrinivasan at gmail.com> writes:
> At Thu, 07 Mar 2013 10:35:46 +0100,
> Nicolas Neuss wrote:
>>
>> Akshay Srinivasan <akshaysrinivasan at gmail.com> writes:
>>
>> > I wanted to polish the whole "static object" thing I'm doing write now,
>> > by writing a thin layer over defclass itself. This seems awful lot like
>> > MOP.
>> >
>> > What I'm doing right now is essentially that every tensor class has a set
>> > of inlined functions associated with it, which are then used inside macros
>> > everywhere to define type specific functions.
>> >
>> > From what I understand of MOP, I can possibly define a meta-class which holds
>> > all these functions, and then possibly define the defmethod over instances of the
>> > metaclass (which sort of does the equivalent of macroexpansion ?). Essentially
>> > I don't really want to have runtime dispatch; can I define in some sense a
>> > meta-version of defmethod/defgeneric on a class so that it wraps the code for the
>> > method inside a symbol-macrolet to replace things like "+,-" with something
>> > specialised for the class?
>>
>> Although I already can imagine what you want quite well - could you
>> maybe sketch an example (as simple as possible)?
>>
>> > I can't find any real resource on MOP, so forgive me if this doesn't
>> > make any sense whatsoever.
>>
>> The chapters 5 and 6 of the AMOP book should be freely available, see
>>
>> http://www.clisp.org/impnotes/mop-chap.html
>>
>> or google for "mop_spec.pdf".
>>
>> > Nicholas: I know this is probably more up your alley. Do you think this sort of
>> > thing is possible with MOP ?
>>
>> I doubt a little that the MOP is sufficient for achieving this, but I
>> also would not find using something like DEFMETHOD* instead of DEFMETHOD
>> very bad and then you have all liberty you want. As I see it the MOP
>> was created for achieving high flexibility, but not high performance,
>> and so implementations like CMUCL or SBCL have a slightly similar but
>> more lowlevel mechanism (compiler transforms, IIRC) how one can instruct
>> the compiler to optimize operations with type information that is known
>> at compile time.
> Sigh. I was hoping to avoid doing all the superclass ordering and stuff,
> oh well. I sort of want to do things like the macro generate-typed-copy!
> in the file:
> https://github.com/enupten/matlisp/blob/tensor/src/level-1/copy.lisp
> without having to read things from a Hashtable everytime. Maybe writing a
> new object system is overkill, and I should just use a macro like with-slots.
What about doing a type-specialized compilation on-demand as I do in
femlisp/src/matlisp/blas-basic.lisp?
Alternatively, this could also be triggered when NO-APPLICABLE-METHOD is
called.
>> > Akshay
>>
>> Apropos: I am still trying to build and run your Matlisp without
>> success. First, I had difficulties because f77 did not know the "exit"
>> command used in "iladlr.f", for example. Using gfortran compiled at
>> least the Fortran code, however after compilation I am left in a state
>> with apparently nothing new available.
> Is this the Intel compiler ?
>From the Manpages on my system
gfortran - GNU Fortran compiler
f77=fort77 - invoke f2c Fortran translator transparently, like a
compiler
I think this has changed recently. Some time ago, f77 was the GNU
Fortran compiler.
>> [...]
>> ; /home/neuss/.cache/common-lisp/sbcl-1.1.5.5-203e2ac-linux-x64/home/neuss/matlisp/src/sugar/ASDF-TMP-seq.fasl written
>> ; compilation finished in 0:00:00.022
>> ;
>> ; compilation unit finished
>> ; printed 8 notes
>>
>>
>> ** MATLISP is loaded. Type (HELP MATLISP)
>> to see a list of available symbols.
>> To use matlisp:
>>
>> (use-package "MATLISP")
>>
>> or
>>
>> (in-package "MATLISP-USER")
>>
>> * (help matlisp)
>> ; in: HELP MATLISP
>> ; (HELP MATLISP)
>> ;
>> ; caught STYLE-WARNING:
>> ; undefined function: HELP
>> ;
>> ; caught WARNING:
>> ; undefined variable: MATLISP
>> ;
>> ; compilation unit finished
>> ; Undefined function:
>> ; HELP
>> ; Undefined variable:
>> ; MATLISP
>> ; caught 1 WARNING condition
>> ; caught 1 STYLE-WARNING condition
>>
>> debugger invoked on a UNBOUND-VARIABLE in thread
>> #<THREAD "main thread" RUNNING {10029D9833}>:
>> The variable MATLISP is unbound.
>>
>> Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
>>
>> restarts (invokable by number or by possibly-abbreviated name):
>> 0: [ABORT] Exit debugger, returning to top level.
>>
>> ((LAMBDA ()))
>> 0] 0
>>
>> * (apropos "matlisp")
>>
>> COMMON-LISP-USER::MATLISP
>> :MATLISP (bound)
>> :MATLISP-TESTS (bound)
>> :MATLISP-USER (bound)
>> *MATLISP-VERSION* (bound)
>> MATLISP
>> MATLISP-HERALD (fbound)
>> MATLISP-NAME
>> MATLISP-VERSION (fbound)
>> SAVE-MATLISP (fbound)
>> MATLISP-FFI::MATLISP-SPECIALIZED-ARRAY
>> MATLISP-SYSTEM::MATLISP
>> MATLISP-SYSTEM::MATLISP-CONDITIONS
>> MATLISP-SYSTEM::MATLISP-CONFIG
>> MATLISP-SYSTEM::MATLISP-PACKAGES
>> MATLISP-SYSTEM::MATLISP-TESTS
>> MATLISP-SYSTEM::MATLISP-UTILITIES
>
> Yes, the old help system isn't yet incorporated. I'm sorry that you've to
> tread through my undocumented code.
>
> Assuming you want to test the GEMM, you'd want to do something like:
> -----------------------------------------------------------------------------
> (in-package :matlisp)
>
> (let ((A (make-real-tensor 1000 1000))
> (B (make-real-tensor 1000 1000)))
> ;;Slow and dynamic
> (time
> (mod-dotimes (idx (dimensions A))
> do (progn
> (setf (tensor-ref A idx) (random 1d0)
> (tensor-ref B idx) (random 1d0)))))
> ;;Faster (although random slows it down quite a bit).
> #+nil
> (time
> (let-typed ((sto-a (store A) :type real-store-vector)
> (sto-b (store B) :type real-store-vector))
> (mod-dotimes (idx (dimensions A))
> with (linear-sums
> (of-a (strides A) (head A))
> (of-b (strides B) (head B)))
> do (progn
> (real-typed.value-writer (random 1d0) sto-a of-a)
> (real-typed.value-writer (random 1d0) sto-b of-b)))))
> ;;Use lisp
> (let ((*real-l3-fcall-lb* 1000))
> (time (gemm 1d0 A B nil nil)))
> ;;Use fortran
> (let ((*real-l3-fcall-lb* 0))
> (time (gemm 1d0 A B nil nil))))
> --------------------------------------------------------------------------------
> I realised I haven't actually added all my "test" files into the repository.
> I'll add them to the repo today.
>
> On my computer the timings are something like:
> Lisp: 3.2s
> C (tests/mm.c): 2.2s
> Goto: 0.2s
>
> Akshay
OK, this works.
Some further questions and remarks:
- Do you have also a reader macro like [...] in old Matlisp? And could
you illustrate how slicing works?
- Looking at how complicated e.g. "gemm.lisp" is, I am not sure if doing
this in CL is really worthwile. Optimizing for small matrices might
be the wrong idea from the beginning.
- I would be interested in the minimal amount of code necessary for
adding some new LAPACK routine. If possible, the stub should be even
smaller than in femlisp/src/matlisp/ggev.lisp and
femlisp/src/matlisp/hgev.lisp (solutions of generalized eigenvalue
problems).
- I really am interested in single-float stuff too, because I will look
more closely in generating high-performance code in the next future.
In this domain, using single-float is often interesting, because it
needs only half the memory and using it can lead to double efficiency
in situations where memory bandwidth is the limiting factor.
Nicolas
--
Nicolas Neuss neuss at math.fau.de
More information about the antik-devel
mailing list