-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MAGICL extensions refactor #125
Changes from all commits
a13da59
6a6733a
3838b02
fa9331b
16525db
ca0dad7
d196a7f
8eb19aa
621dfec
0b768b0
c28ff06
acd15fb
68ee356
90ecb4e
5431fc5
891b4d7
47c704f
347baa9
21bb55c
5265ce0
1d49beb
033b8ee
09b39d8
a1fbd99
c14c140
2c44830
163c132
a1eb8e3
688310f
a42fde6
0434460
2f7794a
d9e2722
7cce767
68a4a5b
b1957ea
1d3f2e6
2bc945d
9bd2fb4
c542d97
8658be0
06bcc40
f19abcd
c17bdb9
205e019
790a13c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
transcendental/libexpokit.dylib | ||
transcendental/libexpokit.so | ||
**/*.dylib | ||
**/*.so |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,35 @@ | ||
# MAGICL | ||
|
||
|
||
_Matrix Algebra proGrams In Common Lisp_ by [Rigetti Computing](http://www.rigetti.com). (née FLAIL: _Finally, Linear Algebra In Lisp!_) | ||
|
||
(**Note**: The high-level interface is experimental and subject to rapid change.) | ||
(**Note**: The high-level interface is experimental and subject to change.) | ||
|
||
## Requirements | ||
|
||
* SBCL (> 1.3.19) or CCL (>= 1.11) on AMD64 | ||
* quicklisp | ||
* libffi | ||
* BLAS and LAPACK | ||
MAGICL has two main systems: | ||
|
||
- `MAGICL/CORE`: This is pure Lisp code with no foreign | ||
dependencies. This system establishes MAGICL's API (for the most | ||
part). | ||
|
||
- `MAGICL`: This is MAGICL with all extensions loaded. | ||
|
||
The system `MAGICL/CORE` requires: | ||
|
||
* SBCL (> 1.3.19) or CCL (>= 1.11) on AMD64 | ||
* quicklisp | ||
|
||
The system `MAGICL`, on the other hand, requires several foreign | ||
dependencies not shipped with MAGICL, like: | ||
|
||
Detailed instructions on how to install `libffi` and BLAS/LAPACK can | ||
be found [here](doc/requirements.md). | ||
- libffi | ||
- BLAS and LAPACK | ||
|
||
Currently this library is SBCL- and CCL-only. The non-portable code | ||
is in `with-array-pointers.lisp` and `magicl.lisp`. | ||
Detailed instructions on how to install `libffi` and BLAS/LAPACK can | ||
be found [here](doc/requirements.md). | ||
|
||
Currently this library is SBCL- and CCL-only. The non-portable code is | ||
in `with-array-pointers.lisp` and `magicl.lisp`. | ||
|
||
## Installation | ||
|
||
|
@@ -29,85 +42,147 @@ running `sbcl` and evaluating `ql:*local-project-directories*`. Once | |
installed, confirm that MAGICL is working properly by running the | ||
tests, as described in the next section. | ||
|
||
## Testing MAGICL | ||
## Lisp-Only vs Accelerated MAGICL | ||
|
||
You can run the MAGICL tests from your Lisp REPL with: | ||
### Extensions | ||
|
||
`MAGICL/CORE` only uses pure ANSI Common Lisp code. If you wish to | ||
accelerate it or extend the functionality, you may load *MAGICL | ||
extensions*. These extensions typically install new backends to MAGICL | ||
functions. The available extensions are: | ||
|
||
- `MAGICL/EXT-BLAS`: for BLAS functions | ||
- `MAGICL/EXT-LAPACK`: for LAPACK functions | ||
- `MAGICL/EXT-EXPOKIT`: for expokit (matrix `exp()`) functions | ||
|
||
For backwards compatibility, `MAGICL` loads every extension under the | ||
kitchen sink. **This may change in future versions of MAGICL! If you | ||
depend on an extension, depend on it explicitly!** | ||
|
||
If you use extensions, you'll need the requisite C/Fortran | ||
libraries. Expokit will automatically build for you, as its source is | ||
included in the distribution of MAGICL. | ||
|
||
### Backends | ||
|
||
Accelerated functionality is installed with a notion called "backends". A | ||
*backend* is a name of a group of functionality, typically denoted by | ||
a symbol or keyword. The `:lisp` backend is the defualt one, and | ||
several backends can be active all at once. Each extension above adds | ||
a new backend. The current backends are: | ||
|
||
- `:lisp`: Pure Lisp code | ||
- `:blas`: BLAS-backed code | ||
- `:lapack`: LAPACK-backed code | ||
- `:expokit`: expokit-backed code | ||
|
||
In most cases, one does not need to concern themselves with backends; | ||
MAGICL functionality should "just work" and dispatch to the | ||
appropriate backend. However, the programmer always has control, even | ||
dynamically in the program, of which backends should be used at a | ||
given time with the `magicl.backends:with-backends` macro. For instance, | ||
|
||
``` | ||
(ql:quickload :magicl-tests) | ||
(asdf:test-system :magicl) | ||
(magicl.backends:with-backends (:blas :lisp) | ||
;; ... code ... | ||
) | ||
``` | ||
|
||
## High-level Interface | ||
says that the code should be executed, always preferring | ||
`:blas`-accelerated functions, and using `:lisp`-implemented functions | ||
as a fall-back. | ||
|
||
See [high-level doc](doc/high-level.md). | ||
``` | ||
(magicl.backends:with-backends (:lisp) | ||
;; ... code ... | ||
) | ||
``` | ||
|
||
## Showing Available Functions | ||
says to *only* use `:lisp`-implemented functions, even if other | ||
backends are loaded. | ||
|
||
Some distributions of a library don't actually provide all of the functions of the reference BLAS and LAPACK. One can look at a summary of available and unavailable functions with the function `magicl:print-availability-report`. By default, it will show all functions and their availability. There are three arguments to fine-tune this behavior: | ||
|
||
1. Key `:show-available <boolean>` (default `t`): show available functions | ||
2. Key `:show-unavailable <boolean>` (default `t`): show unavailable functions | ||
3. Key `:search <string>`: only show functions which have `<string>` as a substring. **This argument takes into account the previous two arguments.** | ||
The active backends can be found with the function | ||
`magicl.backends:active-backends`, which lists the backends to use in | ||
priority order. | ||
|
||
For example, we can look for all available functions which might relate to `svd` by doing the following: | ||
One can be even finer-grained than `with-backends`. Given a function | ||
`f` which has many backend implementations, one can get a specific | ||
implementation by using the function: | ||
|
||
``` | ||
CL-USER> (magicl:print-availability-report :search "svd" :show-unavailable nil) | ||
Fortran Function Lisp Function | ||
------------------------------------------------------------------------ | ||
|
||
Library LIBBLAS: /usr/local/opt/lapack/lib/libblas.dylib | ||
|
||
Library LIBLAPACK: /usr/local/opt/lapack/lib/liblapack.dylib | ||
[x] CGESVD MAGICL.LAPACK-CFFI:%CGESVD | ||
[x] CGESVDX MAGICL.LAPACK-CFFI:%CGESVDX | ||
[x] CGGSVD3 MAGICL.LAPACK-CFFI:%CGGSVD3 | ||
[x] DBDSVDX MAGICL.LAPACK-CFFI:%DBDSVDX | ||
[x] DGESVD MAGICL.LAPACK-CFFI:%DGESVD | ||
[x] DGESVDX MAGICL.LAPACK-CFFI:%DGESVDX | ||
[x] DGGSVD3 MAGICL.LAPACK-CFFI:%DGGSVD3 | ||
[x] SBDSVDX MAGICL.LAPACK-CFFI:%SBDSVDX | ||
[x] SGESVD MAGICL.LAPACK-CFFI:%SGESVD | ||
[x] SGESVDX MAGICL.LAPACK-CFFI:%SGESVDX | ||
[x] SGGSVD3 MAGICL.LAPACK-CFFI:%SGGSVD3 | ||
[x] ZGESVD MAGICL.LAPACK-CFFI:%ZGESVD | ||
[x] ZGESVDX MAGICL.LAPACK-CFFI:%ZGESVDX | ||
[x] ZGGSVD3 MAGICL.LAPACK-CFFI:%ZGGSVD3 | ||
(magicl.backends:backend-implementation 'f :backend-name) | ||
``` | ||
|
||
## Generating BLAS and LAPACK Bindings | ||
For instance | ||
|
||
This library takes the approach of automatically generating the bindings to BLAS, LAPACK, and Expokit without relying on any special tools. | ||
``` | ||
(magicl.backends:backend-implementation 'magicl:csd :lapack) | ||
``` | ||
|
||
will give the implementation of the cosine-sine decomposition function | ||
in LAPACK. This can be called in exactly the same way `magicl:csd` can | ||
be called. | ||
|
||
In `backend-implementation`, if both the function name and the backend | ||
name are (quoted) constants, this will be looked up at compile-time, | ||
which is useful for writing efficient code that does not dispatch. But | ||
note that by doing this, `with-backends` will not be respected. | ||
|
||
In order to generate the bindings, you will need to download the Fortran 90 source tarballs for | ||
[BLAS/LAPACK](http://www.netlib.org/lapack/) and [Expokit](https://www.maths.uq.edu.au/expokit/download.html). | ||
Once downloaded, extract the tarballs into a directory and re-generate the bindings with the following commands: | ||
## Testing MAGICL | ||
|
||
You can run the MAGICL tests from your Lisp REPL with: | ||
|
||
``` | ||
(ql:quickload :magicl-gen) | ||
(in-package :magicl.generate-interface) | ||
(generate-blas-files #P"/path/to/lapack-3.7.1/") | ||
(generate-lapack-files* #P"/path/to/lapack-3.7.1/") | ||
(generate-expokit-files #P"/path/to/expokit/") | ||
(asdf:test-system :magicl) | ||
``` | ||
|
||
Currently this will write to the source distribution directory of | ||
MAGICL, namely the files `blas-cffi.lisp`, `lapack*-cffi.lisp`, and | ||
`expokit-cffi.lisp`. | ||
You currently need all of the extensions working for the tests to run. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it worth it to throw in a few easy tests that exercise There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought in a separate test we could write test functions which iterate over the backends using |
||
|
||
## High-level Interface | ||
|
||
See the [high-level doc](doc/high-level.md) for an extensive discussion | ||
and comparison of MAGICL functions with those of MATLAB and NumPy. | ||
|
||
## Developer's Guide: How to Add New Functions | ||
|
||
See the [developer how-to](doc/dev-how-to.md) to understand how to add | ||
new functionality to MAGICL. | ||
|
||
## Fortran Bindings | ||
|
||
See the [Fortran Functions](doc/fortran-functions.md) on how to | ||
re-generate the Fortran bindings from the original BLAS, LAPACK, and | ||
Expokit reference code. | ||
|
||
See the same document for how to query for available Fortran functions | ||
in the currently loaded dynamic libraries. | ||
|
||
|
||
## History and Credits | ||
|
||
MAGICL development started at Rigetti Computing by Robert Smith and Joe Lin in 2017. | ||
MAGICL development started at Rigetti Computing by Robert Smith and | ||
Joe Lin in 2017. | ||
|
||
[CL-BLAPACK](https://github.com/blindglobe/cl-blapack) is a library developed by Ryan Rifkin and Evan Monroig. Rigetti Computing created a fork of this library and renamed it MAGICL, and made significant changes that departed from the original design, including: | ||
[CL-BLAPACK](https://github.com/blindglobe/cl-blapack) is a library | ||
developed by Ryan Rifkin and Evan Monroig. Rigetti Computing created a | ||
fork of this library and renamed it MAGICL, and made significant | ||
changes that departed from the original design, including: | ||
|
||
* Fixing several bugs in the Fortran parsing to make it work with the | ||
latest reference BLAS and LAPACK, leading to significant refactoring. | ||
|
||
* Fixing several bugs in the Fortran parsing to make it work with the latest reference BLAS and LAPACK, leading to significant refactoring. | ||
* Adding support for matrix exponentiation with Expokit. | ||
|
||
* Adding support for loading various BLAS and LAPACK implementations. | ||
|
||
* Removing the use of the FNV library in favor of native Lisp arrays. | ||
|
||
* Adding a high-level interface to various functions. | ||
|
||
* Adding function availability reporting. | ||
|
||
The most important common design decision between CL-BLAPACK and MAGICL is allowing direct access | ||
to the Fortran library functions by way of automatically generated Lisp bindings from the reference sources. | ||
The most important common design decision between CL-BLAPACK and | ||
MAGICL is allowing direct access to the Fortran library functions by | ||
way of automatically generated Lisp bindings from the reference | ||
sources. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐌