Skip to content
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

Merged
merged 46 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a13da59
first step in MAGICL refactor
stylewarning Jan 30, 2021
6a6733a
isolate MAGICL-TRANSCENDENTAL and expokit, add EXPM/LOGM to MAGICL
stylewarning Jan 30, 2021
3838b02
completely contain expokit as an extension
stylewarning Jan 30, 2021
fa9331b
organize file structure, delete stale files
stylewarning Jan 30, 2021
16525db
separate out lapack and blas
stylewarning Jan 30, 2021
ca0dad7
fix typo
stylewarning Jan 30, 2021
d196a7f
add MAGICL/FANCY system
stylewarning Jan 30, 2021
8eb19aa
include magicl-csd.lisp in system
stylewarning Jan 30, 2021
621dfec
get examples working
stylewarning Jan 30, 2021
0b768b0
get tests to work
stylewarning Jan 30, 2021
c28ff06
mention extensions in README
stylewarning Jan 30, 2021
acd15fb
add backend function and implementation framework
stylewarning Mar 19, 2021
68ee356
re-export add'l backend symbols
stylewarning Mar 20, 2021
90ecb4e
push new default backends to the front
stylewarning Mar 20, 2021
5431fc5
document how to use backend functions
stylewarning Mar 20, 2021
891b4d7
define :BLAS and :LAPACK backend separately
stylewarning Mar 21, 2021
47c704f
remove MAGICL/FANCY and make MAGICL/CORE
stylewarning Mar 21, 2021
347baa9
add DEFINE-EXTENSIBLE-FUNCTION
stylewarning Mar 21, 2021
21bb55c
fix minor formatting and typos
stylewarning Mar 21, 2021
5265ce0
export more backend framework symbols
stylewarning Mar 21, 2021
1d49beb
warn when defining backend functions outside of MAGICL
stylewarning Mar 21, 2021
033b8ee
put LAPACK into backend framework
stylewarning Mar 21, 2021
09b39d8
better docs
stylewarning Mar 21, 2021
a1fbd99
fix typos
stylewarning Mar 21, 2021
c14c140
check symbol's package more directly
stylewarning Mar 22, 2021
2c44830
only generate backend-function if it doesn't exist
stylewarning Mar 22, 2021
163c132
fix bug in non-quoted uninterned symbol
stylewarning Mar 22, 2021
a1eb8e3
clean up expokit packages
stylewarning Mar 22, 2021
688310f
fix docs typos
stylewarning Mar 22, 2021
a42fde6
use DEFINE-EXTENSIBLE-FUNCTION for EXPM
stylewarning Mar 22, 2021
0434460
delete useless empty :components
stylewarning Mar 22, 2021
2f7794a
delete nickname stuff
stylewarning Mar 22, 2021
d9e2722
add dummy magicl-transcendental system for backward compat
stylewarning Mar 22, 2021
7cce767
make compatible MAGICL-TRANSCENDENTAL package
stylewarning Mar 22, 2021
68a4a5b
remove ASDF deprecated function
stylewarning Mar 22, 2021
b1957ea
simplify magicl-gen bindings location
stylewarning Mar 22, 2021
1d3f2e6
move pkg MAGICL-TRANSCENDENTAL to separate file
stylewarning Mar 22, 2021
2bc945d
fix typos
stylewarning Mar 22, 2021
9bd2fb4
move fortran frobbing to separate doc
stylewarning Mar 22, 2021
c542d97
fix typo
stylewarning Mar 22, 2021
8658be0
re-export PRINT-AVAILABILITY-REPORT
stylewarning Mar 22, 2021
06bcc40
make sure libblas and liblapack are tracked properly
stylewarning Mar 22, 2021
f19abcd
fix symbol tracking bug in libraries
stylewarning Mar 22, 2021
c17bdb9
fix more magicl-gen bugs
stylewarning Mar 23, 2021
205e019
regenerate BLAS/LAPACK bindings from 3.9.0 sources
stylewarning Mar 23, 2021
790a13c
document DEFINE-COMPATIBLE-... macro
stylewarning Mar 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
transcendental/libexpokit.dylib
transcendental/libexpokit.so
**/*.dylib
**/*.so
197 changes: 136 additions & 61 deletions README.md
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.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐌


## 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

Expand All @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The 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 magicl/core explicitly? More broadly, we should probably make an issue to test various backends explicitly.

Copy link
Member Author

Choose a reason for hiding this comment

The 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 with-backends or binding *backends* directly. I don't think I want to do it in this PR though. Made issue #128


## 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.
Loading