Code Monkey home page Code Monkey logo

lacaml's Introduction

Lacaml - Linear Algebra for OCaml

What is Lacaml?

This OCaml-library interfaces two widely used mathematical FORTRAN-libraries:

This allows developers to write high-performance numerical code for applications that require linear algebra.

Features

  • The BLAS- and LAPACK-libraries have evolved over about two decades of time and are therefore extremely mature both in terms of stability and performance.

  • Lacaml interfaces most of the functions in BLAS and LAPACK (many hundreds!). It supports among other things linear equations, least squares problems, eigenvalue problems, singular value decomposition (SVD), Cholesky and QR-factorization, etc.

  • Many convenience functions for creating and manipulating matrices.

  • Powerful printing functions for large vectors and matrices and supplemental information (e.g. row and column headers). Users can specify easily how much context to print. For example, it is usually sufficient to print small blocks of the four corners of a large result matrix to manually verify the correctness of an algorithm. Lacaml uses this approach to limit the output to human-manageable size.

  • Integration into the OCaml-toplevel allows for easy experimentation for students and researchers as well as demonstration for lecturers. Values of vector and matrix type will be printed automatically without cluttering the screen.

  • The OCaml-interface was designed in a way to combine both the possibility of gaining optimum efficiency (e.g. by allowing the creation of work arrays outside of loops) with simplicity (thanks to labels and default arguments).

  • The code is precision-independent and supports both real and complex transforms in a consistent way. There are four modules that implement the same interface modulo the precision type and specialized real/complex functions. If you refer to elements in this interface only, your code becomes precision- and (if meaningful) real/complex independent, too: you can choose at anytime whether you want to use single-precision or double-precision simply by referring to the required module.

  • You can fully exploit the library within multithreaded programs. Many numerical routines are likely to run for a long time, but they will never block other threads. This also means that you can execute several routines at the same time on several processors if you use POSIX-threads in OCaml.

  • To make things easy for developers used to the "real" implementation in FORTRAN but also for beginners who need detailed documentation, both function- and argument names have been kept compatible to the ones used in the BLAS- and LAPACK-documentation. Only exception: you need not prefix functions with s, d, c or z to indicate the precision and type of numbers, because the OCaml module system provides us with a more convenient means of choosing them.

  • (Almost) all errors are handled within OCaml. Typical mistakes like passing non-conforming matrices, parameters that are out of range, etc., will be caught before calling Fortran code and will raise exceptions. These exceptions will explain the error in detail, for example the received illegal parameter and the range of expected legal values.

Using Lacaml

You can make use of this library by referring to the corresponding module for the required precision and number type. E.g.:

open Lacaml.S  (* Single-precision real numbers *)
open Lacaml.D  (* Double-precision real numbers *)
open Lacaml.C  (* Single-precision complex numbers *)
open Lacaml.Z  (* Double-precision complex numbers *)

These modules become available if you link the lacaml-library with your application. The widely used OCaml-tool findlib will take care of linking lacaml correctly. If you do not use this tool, you will also have to link in the bigarray-library provided by the OCaml-distribution.

The Lacaml.?-modules implement the BLAS/LAPACK-interface. Their corresponding submodules Vec and Mat provide for vector and matrix operations that relate to the given precision and number type.

Most functions were implemented using optional arguments (= default arguments). If you do not provide them at the call-site, sane defaults will be used instead. Here is an example of a function call:

let rank = gelss in_mat out_mat in
(* ... *)

This example computes the solution to a general least squares problem (= linear regression) using the SVD-algorithm with in_mat as the matrix containing the predictor variables and out_mat as the matrix containing (possibly many) response variables (this function can handle several response variables at once). The result is the rank of the matrix. The matrices provided in the arguments will be overwritten with further results (here: the singular vectors and the solution matrix).

If the above happened in a loop, this would be slightly inefficient, because a work-array would have to be allocated (and later deallocated) at each call. You can hoist the creation of this work array out of the loop, e.g. (m, n, nrhs are problem dependent parameters):

let work = gelss_min_work ~m ~n ~nrhs in
for i = 1 to 1000 do
  (* ... *)
  let rank = gelss in_mat ~work out_mat in
  (* ... *)
done

All matrices can be accessed in a restricted way, i.e. you can specify submatrices for all matrix parameters. For example, if some matrix is called a in the interface documentation, you can specify the left upper corner of the wanted submatrix for the operation by setting ar for the row and ac for the column (1 by default). A vector y would have an extra optional parameter ofsy (also 1 by default). Parameters like m or n typically specify the numbers of rows or columns.

Printing vectors and matrices

Here is a toplevel example of printing a large random matrix:

# #require "lacaml";;
# open Lacaml.D;;
# let mat = Mat.random 100 200;;
val mat : Lacaml.D.mat =
              C1        C2        C3          C198       C199      C200
    R1 -0.314362 -0.530711  0.309887 ...  0.519965  -0.230156 0.0479154
    R2  0.835658  0.581404  0.161607 ... -0.749358  -0.630019 -0.858998
    R3 -0.403421  0.458116 -0.497516 ...  0.210811   0.422094  0.589661
             ...       ...       ... ...       ...        ...       ...
   R98 -0.352474  0.878897  0.357842 ...  0.150786   -0.74011  0.353253
   R99  0.104805  0.984924 -0.319127 ... -0.143679  -0.858269  0.859059
  R100  0.419968  0.333358  0.237761 ... -0.483535 -0.0224016  0.513944

Only the corner sections of the matrix, which would otherwise be too large to display readably, are being printed, and ellipses (...) are used in place of the removed parts of the matrix.

If the user required even less context, the Lacaml.Io.Toplevel.lsc function, which is also available in each precision module for convenience (here: Lacaml.D), could be used to indicate how much. In the following example only two-by-two blocks are requested in each corner of the matrix:

# lsc 2;;
- : unit = ()
# mat;;
- : Lacaml.D.mat =
            C1        C2           C199      C200
  R1 -0.314362 -0.530711 ...  -0.230156 0.0479154
  R2  0.835658  0.581404 ...  -0.630019 -0.858998
           ...       ... ...        ...       ...
 R99  0.104805  0.984924 ...  -0.858269  0.859059
R100  0.419968  0.333358 ... -0.0224016  0.513944

Applications can use the standard Format-module in the OCaml-distribution together with Lacaml printing functions to output vectors and matrices. Here is an example using labels and showing the high customizability of the printing functions:

open Lacaml.D
open Lacaml.Io

let () =
  let rows, cols = 200, 100 in
  let a = Mat.random rows cols in
  Format.printf "@[<2>This is an indented random matrix:@\n@\n%a@]@."
    (Lacaml.Io.pp_lfmat
      ~row_labels:
        (Array.init rows (fun i -> Printf.sprintf "Row %d" (i + 1)))
      ~col_labels:
        (Array.init cols (fun i -> Printf.sprintf "Col %d" (i + 1)))
      ~vertical_context:(Some (Context.create 2))
      ~horizontal_context:(Some (Context.create 3))
      ~ellipsis:"*"
      ~print_right:false
      ~print_foot:false ())
    a

The above code might print:

This is an indented random matrix:

              Col 1     Col 2       Col 3      Col 98    Col 99   Col 100
    Row 1  0.852078 -0.316723    0.195646 *  0.513697  0.656419  0.545189
    Row 2 -0.606197  0.411059    0.158064 * -0.368989    0.2174    0.9001
                  *         *           * *         *         *         *
  Row 199 -0.684374 -0.939027 0.000699582 *  0.117598 -0.285587 -0.654935
  Row 200  0.929341 -0.823264    0.895798 *  0.198334  0.725029 -0.621723

Many other options, e.g. for different padding, printing numbers in other formats or with different precision, etc., are available for output customization.

Error handling

Though Lacaml is quite thorough in checking arguments for consistency with BLAS/LAPACK, an exception to the above is illegal contents of vectors and matrices. This can happen, for example, when freshly allocated matrices are used without initialization. Some LAPACK-algorithms may not be able to deal with floats that correspond to NaNs, infinities, or are subnormal. Checking matrices on every call would seem excessive. Some functions also expect matrices with certain properties, e.g. positive-definiteness, which would be way too costly to verify beforehand.

Degenerate value shapes, e.g. empty matrices and vectors, and zero-sized operations may also be handled inconsistently by BLAS/LAPACK itself. It is rather difficult to detect all such corner cases and to predetermine for all on how they should be handled to provide a sane workaround.

Users are well-advised to to ensure the sanity of the contents of values passed to Lacaml functions and to avoid calling Lacaml with values having degenerate dimensions. User code should either raise exceptions if values seem degenerate or handle unusual corner cases explicitly.

Other sources of usage information

API documentation

Besides the Lacaml interface file, the API documentation can also be found online.

BLAS/LAPACK man pages

BLAS and LAPACK binary packages for Unix operating systems usually come with appropriate man-pages. E.g. to quickly look up how to factorize a positive-definite, complex, single precision matrix, you might enter:

man cpotrf

The corresponding function in Lacaml would be Lacaml.C.potrf. The naming conventions and additional documentation for BLAS and LAPACK can be found at their respective websites.

Examples

The examples-directory contains several demonstrations of how to use this library for various linear algebra problems.

Improving Performance

It is highly recommended that users install a variant of BLAS (or even LAPACK) that has been optimized for their system. Processor vendors (e.g. Intel) usually sell the most optimized implementations for their CPU-architectures. Some computer and OS-vendors like Apple distribute their own implementations with their products, e.g. vecLib, which is part of Apple's Accelerate-framework.

There is also ATLAS, a very efficient and compatible substitute for BLAS. It specializes code for the architecture it is compiled on. Binary packages (e.g. RPMs) for Linux should be available from your distribution vendor's site (you must recompile the package to make sure it is suited to your distribution, see the package documentation for more details.).

Another alternative for BLAS is OpenBLAS.

If a non-standard library or library location is required, the user can override the platform-dependent default by setting the following environment variables:

  • LACAML_CFLAGS
  • LACAML_LIBS

The first one can be used to add compilation flags, and the second one to override the default linking flags (-lblas and -llapack).

Lacaml already passes -O3 -march=native -ffast-math as compiler flags to fully exploit SIMD instructions when supported by the used platform. The current Lacaml code base is probably safe with these options.

Contact Information and Contributing

Please submit bugs reports, feature requests, contributions and similar to the GitHub issue tracker.

Up-to-date information is available at: https://mmottl.github.io/lacaml

lacaml's People

Contributors

chris00 avatar cshardin avatar florenthoareau avatar kit-ty-kate avatar kkirstein avatar mmottl avatar mseri avatar rgrinberg avatar rleonid avatar scemama avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lacaml's Issues

Vec.multiply_const ?

i could not find something like this. would this be a worthwhile addition (analogous to add_const)?

documentation: functions which modify their input

working with lapack is an exercise in general distrust. i just got bit again by gesv a b modifying a. for a seasoned fortran programmer this may be obvious, but it's in stark contrast to the ocaml paradigm of mostly immutable data. so from this point of view it's really more difficult to program in lacaml than in straight fortran: one is not generally in the mindset of pervasive mutability.

anyway, the question is, what can lacaml do to help? for functions with a unit return value i am primed to expect that they modify something. for functions which give back a matrix, such as gesv i was not expecting it e.g. gemm leaves its input intact afaik.

would it be sensible to state in the documentation, at least for functions with a nontrivial return value, what they may modify, if anything?

Creating sub modules for organizing

I sometimes find it a bit overwhelming navigating all of the functions in Lacaml, and wish for a little bit more organization. I'd like to propose a couple of suggestions, they're entirely optional, just to get a discussion started and give some possibilities.

  1. Group the functions in Lacaml_S (and Lacaml_D, Lacaml_C ...) into submodules Blas1, Blas2, Blas3 and Lapack_ar, Lapack_ls, Lapack_svd (... etc, I don't really like the 'simple' and 'expert' driver breakdowns but I'm not certain this would be much better).
  2. In Vec group the Lacaml_float64.vec -> Lacaml_float64.vec functions (exp, exp1m, sin, sqrt ) into a sub module such as Op (for operations) ?
  3. The special matrix functions (hilbert, hankel ...) into a sub module Special .

I understand that to support backward compatibility maybe we'd have to setup some other module not to break existing code.

Release compatible with OCaml 5?

The current master works fine with ocaml 5. Would it be possible to have a new release? Even better if it could include #53

I would be happy to deal with the releasing burden if you don't have time

build script does not use pkg-config to locate libraries

Under NixOS, it would be possible to install lacaml using opam using:

nix run nixpkgs.blas nixpkgs.liblapack
% opam install lacaml

which is a way to install opam packages with c stubs that works most often than not.
This rely on the package to use pkg-config to locate its dependencies though.
lacaml does not, instead using a specific program to locate dependencies that rely on some environment variables.
As a result, the user experience is harder than required. For the record, this is how I eventually managed to install lacaml on NixOs:

/usr/bin/env LACAML_LIBS=-L(nix eval --raw nixpkgs.liblapack)"/lib -L"(nix eval --raw nixpkgs.blas)/lib" -lblas -llapack" opam install lacaml

(notice that's fish shell not bash)

Could lacaml consider using pkg-config instead, which might help with other cases beside NixOs?

toplevel-specific segfault with syevr

Hi Markus,

I noticed the following problem using ocaml 4.13.1 and lacaml 11.0.8:

# #require "lacaml";;
/home/pveber/.opam/4.13.1/lib/ocaml/bigarray.cma: loaded
/home/pveber/.opam/4.13.1/lib/lacaml: added to search path
/home/pveber/.opam/4.13.1/lib/lacaml/lacaml.cma: loaded
# Lacaml.D.syevr @@ Lacaml.D.Mat.of_array [| [| 1. ; 0. |] ; [| 0. ; 1. |] |];;
Erreur de segmentation (core dumped)

The problem shows more generally under bytecode compilation. The function works fine in native mode though. I'm sorry I don't have more to investigate right now, but maybe the issue will be obvious for you ;).

Install fails on FreeBSD 11.3

Hello,

I tried via opam using the public repositories. It can't find gcc & lapack:

opam install lacaml
The following actions will be performed:

  • install conf-lapack 1 [required by lacaml]
  • install lacaml 11.0.6
    ===== 2 to install =====
    Do you want to continue? [Y/n] y

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[lacaml.11.0.6] downloaded from cache at https://opam.ocaml.org/cache

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[ERROR] The compilation of conf-lapack failed at "/bin/sh -exc ${CC:-gcc} $CFLAGS test.c ${LACAML_LIBS:--llapack} $LDFLAGS".

#=== ERROR while compiling conf-lapack.1 ======================================#

context 2.0.6 | freebsd/x86_64 | ocaml-base-compiler.4.10.0 | https://opam.ocaml.org#1d8fdb21

path /usr/home/rmason/.opam/4.10.0/.opam-switch/build/conf-lapack.1

command /bin/sh -exc ${CC:-gcc} $CFLAGS test.c ${LACAML_LIBS:--llapack} $LDFLAGS

exit-code 1

env-file /usr/home/rmason/.opam/log/conf-lapack-70142-d0f245.env

output-file /usr/home/rmason/.opam/log/conf-lapack-70142-d0f245.out

output

[...]

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `chbmv_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `dsyr2_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `zcopy_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `dspr_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `icamax_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `dsymv_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `zhemv_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `ssyrk_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `srotm_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `drot_'

/usr/local/bin/ld: /usr/local/lib/liblapack.so: undefined reference to `ztbmv_'

collect2: error: ld returned 1 exit status

<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+- The following actions failed
| - build conf-lapack 1
+-

  • No changes have been performed

The packages you requested declare the following system dependencies. Please make sure they are installed before retrying:
gcc lapack

I built the git version in the lacaml directory but utop can't find it.
I tried 'opam install .' (https://opam.ocaml.org/doc/Packaging.html) but
it can't find gcc & lapack. Dunno why it needs to given that the package is
already built.

I'm an OCaml novice, so there may be something I'm missing. Meanwhile, back to some other language for LA.

exception from fortran can only be caught at top level

i'm seeing strange behavior like below. i hope the structure is clear even though i have a ton of undefined symbols here.

let find_min x =
  let minim = nm_min teste ~x ~step_size:stepinit in
  try
    let success_steps = ref 0 in
    for i = 1 to maxit do
      Min.iterate minim;
      if Min.test_size minim 0.01
      then incr success_steps
      else success_steps := 0;
      if !success_steps >= succ_steps then raise @@ Converged i;
    done;
    minim
  with
  | Converged i ->
    (Format.printf "tolerance reached in step %d\n@." i;
    minim)
  | _ -> minim

in this function i try to catch all exceptions and always give back the current mutable minimizer object minim. sometimes the function to be minimized teste raises Failure("Lacaml.D.potrf: leading minor of order 66 is not positive definite") - and the catch-all case does not catch it!?

only when wrapping find_min on the top level i can catch it with try find_min x with _ -> default_minim

is it possible that lacaml can somehow smuggle this exception through? or am i doing something weird?

building with alternative blas

hi, i am troubleshooting on os x and have reason to believe that the Accelerate framework may be part of the problem. i therefore like to build lacaml with openblas instead. i installed openblas with homebrew and get this information:

For compilers to find this software you may need to set:
    LDFLAGS:  -L/usr/local/opt/openblas/lib
    CPPFLAGS: -I/usr/local/opt/openblas/include

i assume i can change something in the _oasis file around line 86 to use that instead of the Accelerate framework. what exactly would i need to replace?

thanks for any help!

corner case: gemm with a 0 dimension

i just came across this corner case in code.

open Lacaml.D
let a = Mat.create 2 2
let b = lacpy ~ac:3 a

this gives a b with shape 2, 0 which seems reasonable. (however ~ac > 3 raises)

let c = gemm a b

in the context it was used it would have been meaningful to get a matrix with shape 2,0 out. instead an exception was raised: second dimension 0. is this something within blas or does lacaml do that? in the latter case, would it make sense to allow multiplications which contain empty dimensions but are consistent dimensionally?

printing in ocamldebug

is there a way of installing lacaml's vector and matrix printers under ocamldebug?

i looked for .cma or .cmo files in the distribution and found only lacaml.cma and lacaml_top.cma. the Lacaml_io module in particular does not have a bytecode object. i was unable to load lacaml{,_top}.cma in the debugger due to missing function definitions. am i doing it wrong? printing in the toploop works just fine.

Install of 10.0 on os x without Accelerate

hi, i tried to upgrade to v10 on os x without using accelerate framework, instead using the homebrew-installed openblas. i tried with these environment variables:

LACAML_CFLAGS=-I/usr/local/opt/openblas/include
LACAML_LIBS=-L/usr/local/opt/openblas/lib -lopenblas -llapack

installing lacaml via opam succeeds (on 4.04.2+flambda).
but then

otool -L ~/.opam/4.04.2+flambda/lib/lacaml/lacaml.cmxs

gives

/System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate (compatibility version 1.0.0, current version 4.0.0)
	/usr/local/opt/openblas/lib/libopenblasp-r0.2.20.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)

and in the jbuilder build log i find invocations like this:

(cd _build/default && /Users/nbecker/.opam/4.04.2+flambda/bin/ocamlmklib.opt -g -o src/lacaml_stubs src/impl_c.o src/utils_c.o src/vec2_S_c.o src/vec2_D_c.o src/vec2_C_c.o src/vec2_Z_c.o src/vec4_S_c.o src/vec4_D_c.o src/vec4_C_c.o src/vec4_Z_c.o src/mat2_S_c.o src/mat2_D_c.o src/mat2_C_c.o src/mat2_Z_c.o src/mat4_S_c.o src/mat4_D_c.o src/mat4_C_c.o src/mat4_Z_c.o src/impl2_S_c.o src/impl2_D_c.o src/impl2_C_c.o src/impl2_Z_c.o src/impl4_S_c.o src/impl4_D_c.o src/impl4_C_c.o src/impl4_Z_c.o -framework Accelerate -L/usr/local/opt/openblas/lib -lopenblas -llapack)

which include the accelerate framework. am i doing something wrong?

Build fails on ppc64le because -march=native is not understood

I can easily work around this by setting LACAML_CFLAGS before compiling, but it would be nice if it worked out of the box on Power:

+ LACAML_LIBS=-lflexiblas
+ dune build -j8
         gcc src/config/zdot_is_function_stubs.o (exit 1)
(cd _build/default/src/config && /usr/bin/gcc -O2 -fno-strict-aliasing -fwrapv -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -pthread -fPIC -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -D_FILE_OFFSET_BITS=64 -O2 -fno-strict-aliasing -fwrapv -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -pthread -fPIC -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -Wall -pedantic -Wextra -Wunused -DEXTERNAL_EXP10 -std=c99 -O3 -march=native -ffast-math -fPIC -DPIC -g -I /usr/lib64/ocaml -o zdot_is_function_stubs.o -c zdot_is_function_stubs.c)
cc1: error: unrecognized command-line option '-march=native'
         gcc src/config/zdot_is_procedure_stubs.o (exit 1)
(cd _build/default/src/config && /usr/bin/gcc -O2 -fno-strict-aliasing -fwrapv -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -pthread -fPIC -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -D_FILE_OFFSET_BITS=64 -O2 -fno-strict-aliasing -fwrapv -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -pthread -fPIC -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -Wall -pedantic -Wextra -Wunused -DEXTERNAL_EXP10 -std=c99 -O3 -march=native -ffast-math -fPIC -DPIC -g -I /usr/lib64/ocaml -o zdot_is_procedure_stubs.o -c zdot_is_procedure_stubs.c)
cc1: error: unrecognized command-line option '-march=native'

installation with homebrew, openblas, macos 12.6

on a current installation of macos, i was unable to opam install lacaml with the environment i used successfully previously. i suspect the way gfortran is linked on homebrew has changed. the installation fails becaus libquadmath cannot be found by the linker

Vec.ssqr returns incorrect results in 10.0.1 and 11.0.0

Hi,

After upgrading from 7.2.1 to 11.0.0 (and adjusting the axpy labeled argument issues) I ran into a nasty bug: Vec.ssqr returns incorrect results. This is with OCaml 4.05.0 as well as 4.05.0+trunk+flambda.

I thought this could be a boxing/unboxing issue, but the @unboxed annotation seems to be there for the return value in the generated .ml's.

In the meantime we'll be using 9.3.2 which doesn't have this problem.

test_lapack.zip

open Lacaml.D

let test_ssqr () =
  for k = 1 to 1000 do
    let n = 1 + Random.int 100 in
    let v = Vec.create n in
    for j = 1 to n do
      v.{j} <- Random.float 1.0 -. 0.5
    done;
    let ss = ref 0.0 in
    for j = 1 to n do
      ss := !ss +. v.{j} *. v.{j}
    done;
    let ss' = Vec.ssqr v in
    let err = abs_float (!ss -. ss') in
    let tol = float n *. epsilon_float in
    if err > tol then failwith (Printf.sprintf "test_ssqr: err=%g > tol=%g" err tol)
  done

let _ = test_ssqr ()

testing for Mat.empty

what's the best way to test if a matrix is the empty matrix? is a == Mat.empty safe? should one test for the dimensions being 0?

Mat.mul documentation

please consider writing the word 'element-wise' into the documentation. i just lost some time thinking 'product' refers to the matrix produc (which is in fact gemm as i then learned). disclaimer: lapack newbie.

operations on Mat.empty

as a corner case, i happened on gemm Mat.empty Mat.empty which i expected to yield Mat.empty. however, instead this resulted in an exception from blas. just wanted to point this out in case it is not intentional. one could of course test explicitly for empty matrices. i guess it's a tradeoff between convenience and potentially some overhead if Mat.empty were handled by all functions where it makes sense.

cannot build docs?

trying to upgrade lacaml to 8.0.4 with opam on os x el capitan, ocaml 4.02.3, i get

[ERROR] The compilation of lacaml failed at "ocaml setup.ml -doc".
Processing  1/1: [lacaml: ocamlfind remove]
#=== ERROR while installing lacaml.8.0.4 ======================================#
# opam-version 1.2.2
# os           darwin
# command      ocaml setup.ml -doc
# path         /Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4
# compiler     4.02.3
# exit-code    1
# env-file     /Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/lacaml-95122-6d07ae.env
# stdout-file  /Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/lacaml-95122-6d07ae.out
# stderr-file  /Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/lacaml-95122-6d07ae.err
### stdout ###
# [...]
# an is not a valid exception constructor in "@raise an invalid argument if
#     any arguments are invalid."
# File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 330:
# an is not a valid exception constructor in "@raise an invalid argument if
#     any arguments are invalid."
# File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 335:
# an is not a valid exception constructor in "@raise an invalid argument if
#     any arguments are invalid."
#32 error(s) encountered
# Command exited with code 1.
### stderr ###
# E: Failure("Command ''/Users/nbecker/.opam/4.02.3/bin/ocamlbuild' API.docdir/index.html -tag debug' terminated with error code 10")

the full output file is

/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml.odoc -package bigarray -package bytes -I lib lib/lacaml.mli
+ /Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml.odoc -package bigarray -package bytes -I lib lib/lacaml.mli
Warning: Module or module type Lacaml_utils not found
Warning: Module or module type Lacaml_C not found
Warning: Module or module type Lacaml_Z not found
Warning: Module or module type Lacaml_S not found
Warning: Module or module type Lacaml_D not found
Warning: Module or module type Lacaml_common not found
Warning: Module or module type Lacaml_io not found
Warning: Module or module type Lacaml_utils not found
Warning: Module or module type Lacaml_C not found
Warning: Module or module type Lacaml_Z not found
Warning: Module or module type Lacaml_S not found
Warning: Module or module type Lacaml_D not found
Warning: Module or module type Lacaml_common not found
Warning: Module or module type Lacaml_io not found
/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_common.odoc -package bigarray -package bytes -I lib lib/lacaml_common.mli
/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_io.odoc -package bigarray -package bytes -I lib lib/lacaml_io.mli
/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_S.odoc -package bigarray -package bytes -I lib lib/lacaml_S.mli
+ /Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_S.odoc -package bigarray -package bytes -I lib lib/lacaml_S.mli
Warning: Element S not found
/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_D.odoc -package bigarray -package bytes -I lib lib/lacaml_D.mli
+ /Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_D.odoc -package bigarray -package bytes -I lib lib/lacaml_D.mli
Warning: Element D not found
/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_C.odoc -package bigarray -package bytes -I lib lib/lacaml_C.mli
+ /Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_C.odoc -package bigarray -package bytes -I lib lib/lacaml_C.mli
Warning: Element C not found
/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_Z.odoc -package bigarray -package bytes -I lib lib/lacaml_Z.mli
+ /Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_Z.odoc -package bigarray -package bytes -I lib lib/lacaml_Z.mli
Warning: Element Z not found
/Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_utils.odoc -package bigarray -package bytes -I lib lib/lacaml_utils.ml
+ /Users/nbecker/.opam/4.02.3/bin/ocamlfind ocamldoc -dump lib/lacaml_utils.odoc -package bigarray -package bytes -I lib lib/lacaml_utils.ml
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 128:
an is not a valid exception constructor in "@raise an invalid argument that integer
    variable [var] with name [name] at location [loc] is lower than [0]."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 132:
an is not a valid exception constructor in "@raise an invalid
    argument in that case."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 146:
an is not a valid exception constructor in "@raise an invalid
    argument that dimension [dim] of a vector with name [vec_name] exceeds
    the minimum [min_dim] at location [loc]."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 150:
an is not a valid exception constructor in "@raise an invalid argument otherwise."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 154:
an is not a valid exception constructor in "@raise an invalid
    argument that an offset [ofs] named [ofs_name] for a value having [name]
    is invalid (i.e. is outside of [1..max_ofs])."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 157:
an is not a valid exception constructor in "@raise an invalid argument
    that vector offset [ofs] is invalid (i.e. is outside of [1..max_ofs])."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 161:
an is not a valid exception constructor in "@raise an invalid argument in that case."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 165:
an is not a valid exception constructor in "@raise an invalid
    argument in that case."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 184:
an is not a valid exception constructor in "@raise an invalid argument
    that the maximum operation size (e.g. [m] or [n] for vectors and matrices)
    has been exceeded."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 190:
an is not a valid exception constructor in "@raise an invalid argument if any
    arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 196:
an is not a valid exception constructor in "@raise an invalid
    argument if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 201:
an is not a valid exception constructor in "@raise an invalid
    argument if any of the parameters are illegal."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 212:
an is not a valid exception constructor in "@raise an invalid argument
    that matrix row offset [r] is invalid (i.e. is outside of [1..max_r])."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 215:
an is not a valid exception constructor in "@raise an invalid argument
    that matrix column offset [c] is invalid (i.e. is outside of [1..max_c])."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 219:
an is not a valid exception constructor in "@raise an invalid argument in that case."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 223:
an is not a valid exception constructor in "@raise an invalid argument in that case."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 254:
an is not a valid exception constructor in "@raise an invalid argument if any arguments are
    invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 259:
an is not a valid exception constructor in "@raise an invalid
    argument if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 265:
an is not a valid exception constructor in "@raise an invalid argument if any
    arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 270:
an is not a valid exception constructor in "@raise an invalid argument if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 276:
an is not a valid exception constructor in "@raise an invalid argument if any arguments
    are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 282:
an is not a valid exception constructor in "@raise an
    invalid argument if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 288:
an is not a valid exception constructor in "@raise an invalid argument if any
    arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 293:
an is not a valid exception constructor in "@raise an invalid argument if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 299:
an is not a valid exception constructor in "@raise an
    invalid argument if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 305:
an is not a valid exception constructor in "@raise an invalid argument
    if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 310:
an is not a valid exception constructor in "@raise an invalid argument if any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 315:
an is not a valid exception constructor in "@raise an invalid argument if any arguments
    are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 320:
an is not a valid exception constructor in "@raise an invalid argument if any
    arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 325:
an is not a valid exception constructor in "@raise an invalid argument if
    any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 330:
an is not a valid exception constructor in "@raise an invalid argument if
    any arguments are invalid."
File "/Users/nbecker/.opam/4.02.3/build/lacaml.8.0.4/_build/lib/lacaml_utils.ml", line 335:
an is not a valid exception constructor in "@raise an invalid argument if
    any arguments are invalid."
32 error(s) encountered
Command exited with code 1.

OPAM with MKL

Hi,
I have succeeded to use lacaml with the Intel MKL library on my desktop PC by doing :

export  LACAML_LIBS="-L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_rt -lpthread -lm -ldl"
opam install lacaml

but when I tried on a HPC server, it did not work because on that particular machine there is no libblas.so and liblapack.so. Only the MKL is available. So the installation of conf-blas and conf-lapack fails.

I am not familiar with opam configuration files, so I can't fix the conf-* files myself and submit a pull request, but I could force the installation by doing the following symbolic links in a directory which is in my LIBRARY_PATH:

ln -s $MKLROOT/lib/intel64/libmkl_rt.so libblas.so
ln -s $MKLROOT/lib/intel64/libmkl_rt.so liblapack.so

cheers,

Anthony

Get rid of num_type?

When using Merlin, types such as Lacaml_float64.num_type pop up instead of float which make signatures harder to read. Since we already perform substitutions, how about to remove it (the type num_type would remain)? This would be done in the "public" .mli files only.

gemv with empty vector

this is similar to the last issue but i think it may be an actual bug so opened a new issue:

let a = Mat.create 2 0
let v = Vec.create 0
let w = gemv a v
let d = Vec.dim w

here, i get 2, and w is a vector with uninitialized entries. this seems wrong?

i would argue that actually a vector 0. 0. would be the mathematically correct result. each entry of the result vector w is the scalar product of the corresponding row vector of the input matrix aand the input vector v. since these have length 0, the scalar product is an empty sum and should be 0.

alternatively one may argue that empty inputs are pathological. then it would make sense to raise an exception, similar to what gemv already does.

right now, it's not ideal that a nonsensical result is actually returned, in my opinion. if this is what lapack does, maybe one should protect the user from lapack here?

(edit: nonsense removal)

lacaml on Windows

Hi,

has anybody successfully installed lacaml on Windows7 (64bit)?
I'm trying to do so with opam install lacaml and end with missing symbols from the fortran runtime, e.g. _gfortran_concat_string. libgfortran-3.dll is on my path. I have a cygwin environment with a x86_64-w64-mingw32 toolchain (gcc & gfortran). Maybe I have to add some linking options to setup.conf?
The toolchain and opam seem to be setup correctly, as I can successfully install packages like lablgtk.

Thanks in advance for any hints,
Kay-Uwe

P.S: I'm a newbie at ocaml & opam, so please bare with me, if I missed something obvious...

lacaml.7.2.6_build_output.zip

gen_blas_kind.exe sigsevs

Installing lacaml on a new computer with a new debian sid install fails. The problem seems to be the helper program gen_blas_kind.exe which fails with a SIGSEV error.

teg@zbox:~$ opam install lacaml
The following actions will be performed:
  â install lacaml 11.0.4

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><>    <><><><><><><>
[lacaml.11.0.4] found in cache

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><>    <><><><><><>
[ERROR] The compilation of lacaml failed at "/home/teg/.opam/opam-init/hooks/sandbox.sh     build dune build -p lacaml -j 3".

#=== ERROR while compiling lacaml.11.0.4     ======================================#
# context     2.0.3 | linux/x86_32 | ocaml-variants.4.08.0+flambda |     https://opam.ocaml.org#1f561ea0
# path        ~/.opam/4.08.0+flambda/.opam-switch/build/lacaml.11.0.4
# command     ~/.opam/opam-init/hooks/sandbox.sh build dune build -p lacaml -j 3
# exit-code   1
# env-file    ~/.opam/log/lacaml-14543-d8a4ae.env
# output-file ~/.opam/log/lacaml-14543-d8a4ae.out
### output ###
# gen_blas_kind src/config/blas_kind_flags.sexp (got signal SEGV)
# (cd _build/default/src/config && ./gen_blas_kind.exe)



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><>    <><><><><><><>
ââ The following actions failed
â λ build lacaml 11.0.4
ââ
â¶â No changes have been performed


A bt from gdb:
Starting program: /home/teg/.opam/4.08.0+flambda/.opam-  switch/build/lacaml.11.0.4/_build/default/src/config/gen_blas_kind.exe

Program received signal SIGSEGV, Segmentation fault.
0x00000001 in ?? ()
(gdb) bt
#0  0x00000001 in ?? ()
#1  0x0064e9e8 in camlStdlib__map__set_of_closures_1738 ()
#2  0xb725470c in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

Trying with the sandbox.sh removed does not make any difference.
Compiler error, stdlib error, something else? What more should be tried?

/Jörgen

GGLSE?

Hi Markus,

Do you have any plans for adding GGLSE? I see there is a mention in impl_SDCZ_c.c

PS. Thanks for Lacaml, it's really great. I've been using it extensively.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.