BLAS bindings for Rust

Overview

RBLAS

MIT licensed crates.io

Rust bindings and wrappers for BLAS (Basic Linear Algebra Subprograms).

Overview

RBLAS wraps each external call in a trait with the same name (but capitalized). This trait contains a single static method, of the same name. These traits are generic over the four main types of numbers BLAS supports: f32, f64, Complex32, and Complex64.

For example the functions cblas_saxpy, cblas_daxpy, cblas_caxypy, and cblas_zaxpy are called with the function Axpy::axpy.

Additionally, RBLAS introduces a few traits to shorten calls to these BLAS functions: Vector for types that implement vector-like characteristics and Matrix for types that implement matrix-like characteristics. The Vector trait is already implemented by Vec and [] types.

Documentation

Installation

By default, the library links with blas dynamically. To link to an alternate implementation, like OpenBLAS, use the environment variable CARGO_BLAS. If you've already built the bindings, you may need to clean and build again.

export CARGO_BLAS=openblas

Example

extern crate rblas;

use rblas::Dot;

fn main() {
    let x = vec![1.0, -2.0, 3.0, 4.0];
    let y = [1.0, 1.0, 1.0, 1.0, 7.0];

    let d = Dot::dot(&x, &y[..x.len()]);
    assert_eq!(d, 6.0);
}

Sugared Example (Soon to be Deprecated)

#[macro_use]
extern crate rblas as blas;
use blas::math::Mat;
use blas::{Matrix, Vector};
use blas::math::Marker::T;

fn main() {
    let x = vec![1.0, 2.0];
    let xr = &x as &Vector<_>;
    let i = mat![1.0, 0.0; 0.0, 1.0];
    let ir = &i as &Matrix<_>;

    assert!(xr + &x == 2.0 * xr);
    assert!(ir * xr == x);

    let dot = (xr ^ T) * xr;
    assert!(dot == 5.0);
}
Comments
  • Remove concat_ident! for module expressions, enable building on stable

    Remove concat_ident! for module expressions, enable building on stable

    Enables rust-blas to build on Rust stable.

    This sorts the function prototypes in the FFI by group, and changes the prefix! and similar macros to using the new modules instead of concat_indent!.

    The future of concat_ident! is uncertain: https://github.com/rust-lang/rust/issues/29599

    opened by skade 4
  • configurable cblas library?

    configurable cblas library?

    Hi, thanks for writing this wrapper @mikkyang! It seems very intuitive and lacks the extra cruft found in some other ports.

    As it stands, I was unable to use this library. In my system "libblas" links to the (fortran?) blas library which has a different interface than the cblas library. Note that the blas functions dont have the "cblas_" prefix. The linker couldn't find the functions I wanted to use.

    In order to get your code working, I had to link against "cblas" instead. You'll notice I linked against openblas instead of cblas in this pull request. There may be other implementations of blas that users of this port may want to use too. I don't suggest merging this pull, or making a new pull linking to "cblas" instead of "openblas". I think a better solution is to let the user decide which library (with the cblas interface) they want to link to. I'm thinking some sort of ENV variable used in the macros, and if the env-var is not defined, use "cblas" as default.

    Thanks again for the port! I'm very new to rust, but if you want this change and you're not feeling up to making this change, I'd be willing to give it a shot. Also, I'm curious if your projects work if you link to "cblas" instead of "blas". I think "cblas" is the proper library to be linking to.

    opened by joshterrell805 4
  • implement trait std::ops::IndexMut for rblas::math::mat::Mat ?

    implement trait std::ops::IndexMut for rblas::math::mat::Mat ?

    hey,

    i’m considering using rblas to speed up some machine learning code i’m working on. i’ve done some benchmarks. unsurprisingly rblas is 4-10 times faster than the same operations in nalgebra.

    i need to fill some rblas::math::mat::Mat with data flexibly and programmatically.

    unfortunately i've not found a nice way to do so. maybe i’m missing something obvious ?

    it would be great if rblas::math::mat::Mat implemented std::ops::IndexMut. is there a specific reason why it doesn't at the moment or is this just an oversight ?

    i’d be happy to implement it and do a pull request !

    let me know.

    best, max

    opened by snd 3
  • Use of usize instead of i32 for dimensions/lengths?

    Use of usize instead of i32 for dimensions/lengths?

    I was curious as to whether there was any reason for using i32 instead of usize for various 'size' parameters? Are negative integers ever returned? And what if (hypothetically speaking) a Vector on a 64-bit machine has a length exceeding the maximum i32 integer?

    I'll have a go at implementing this change, but it will unfortunately break quite a lot of function (though easily fixable, and better late than never).

    opened by JP-Ellis 2
  • Implemented simple matrix type with 2D indexing

    Implemented simple matrix type with 2D indexing

    I have added a simple matrix type that wraps a vector and implements your Matrix trait. It allows use like let A = Mat::::new(4,4); A[0][1] = 1f64; ... and since A[i] yields a slice rows can also be used as a vector. This is some of my first rust code ever so I hope it's not too bad.

    opened by lgottwald 2
  • Traits on slices

    Traits on slices

    Right now, using slices as Vector trait objects don't work. This is because the Vector trait is implemented on [T]. Formerly it was implemented on &[T], but I realized this was incorrect. To receive the correct behavior there are two things I can think of immediately, outlined below. Similar things would be done to Matrix for coherency.

    Option 1: Split the trait Vector into Vector and VectorMut

    Splitting the traits, all of the immutable &self methods would remain in Vector and the mutable &mut self methods would be moved to VectorMut which will be a trait inheriting from Vector.

    Function signatures that were previously:

    fn axpy(alpha: &Self, x: &Vector<Self>, y: &mut Vector<Self>);
    

    would become:

    fn axpy(alpha: &Self, x: &Vector<Self>, y: &mut VectorMut<Self>);
    

    Advantages:

    • Actual operation function signatures just replace &mut Vector with &mut VectorMut and everything should work.

    Disadvantages:

    • This adds a level of indirection (not sure if right word) in the function calls. Essentially, the slices would work because the functions would take &&[T] rather than &[T].
    • Breakage. People that were just using Vec and their own types would have to move the method.
    • Repetitiveness. You already know that &mut types are mutable. I suppose Index and IndexMut are somewhat similar, though.

    Option 2: Generics

    Keep the traits the same, and add an unsized annotation to every function that takes a Vector.

    Function signatures that were previously:

    fn axpy(alpha: &Self, x: &Vector<Self>, y: &mut Vector<Self>);
    

    would become:

    fn axpy<V: ?Sized + Vector<Self>, W: ?Sized + Vector<Self>>(alpha: &Self, x: &V, y: &mut W);
    

    Advantages:

    • Traits remain the same, which means clearer traits.

    Disadvantages:

    • Function signatures become much, much more verbose. Especially because &x and &y maybe be different types, we can't constrict them both to the same type and have to specify trait bounds twice.
    opened by mikkyang 1
  • Fix rblas to build on nightly

    Fix rblas to build on nightly

    Currently rblas is not building with the rust nightly due to changes in features. I made a few changes to get things to build as well as migrating unstable features to stable APIs with the same functionality.

    The code now builds on nightly rust as of today (2015-07-13) and all the tests pats. The only thing that is keeping it from building on stable and beta is the concat_idents! feature gate.

    opened by raineszm 1
  • Not handling matrix dimensions correctly in gemm calls.

    Not handling matrix dimensions correctly in gemm calls.

    When calling gemm, the arguments M, N, and K must describe the dimensions of the transposed matrices (as determined by the transa and transb) instead of the original matrices (http://www.netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html).

    As far as I can tell, gemm is the only routine where this matters.

    opened by raineszm 0
  • Passing wrong LDA to BLAS

    Passing wrong LDA to BLAS

    Sorry to pester.

    The default implementation of Matrix<T> has RowMajor ordering but returns rows for lead_dim which is in turn used by BLAS as the LDA argument for the matrix. However, unless I'm just being dumb, for a row major ordered matrix, the leading dimension should be the number of columns. This appears to have not bee caught by the tests because they use square matrices. As a minimal example of the problem, consider,

            let a = (2, 3,
                     vec![
                     1.0, -3.0, 1.0,
                     2.0, -6.0, 2.0]);
            let x = vec![2.0, 1.0, 1.0];
            let mut y = vec![1.0, 2.0];
            let t = Transpose::NoTrans;
    
            Gemv::gemv(t, &1f32, &a, &x, &0f32, &mut y);
    
            assert_eq!(y, vec![0.0, 0.0]);
    

    which will give an error like BLAS error: Parameter lda passed to cblas_sgemv was 2, which is invalid. depending on what BLAS implementation your using. The solution is either to have lead_dim default to cols or to have it determine the appropriate lead dimension by matching on the ordering. I have a fix in the bugfix branch of my fork if you'd like to use that.

    Thanks!

    opened by raineszm 0
  • Uninitialized memory passed to safe functions in a few locations

    Uninitialized memory passed to safe functions in a few locations

    Hi there, we (Rust group @sslab-gatech) are scanning crates on crates.io for potential soundness bugs. We noticed that in these three code locations, unsafe memory is passed to Copy::copy, Copy::copy_mat and Gemv::gemv:

    https://github.com/mikkyang/rust-blas/blob/bf6d33139eadb2c1215d259fd3b84bf04b531871/src/vector/mod.rs#L30-L38

    https://github.com/mikkyang/rust-blas/blob/bf6d33139eadb2c1215d259fd3b84bf04b531871/src/math/mat.rs#L121-L123

    https://github.com/mikkyang/rust-blas/blob/bf6d33139eadb2c1215d259fd3b84bf04b531871/src/math/matrix_vector.rs#L23-L29

    Copy and Gemv are currently public and safe traits to implement, maybe they should be marked as unsafe or the individual methods that can receive undefined memory marked as unsafe.

    Also note that the Into<Vec<T>> implementation can invoke undefined behavior, see https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#initialization-invariant

    As a consequence, zero-initializing a variable of reference type causes instantaneous undefined behavior, no matter whether that reference ever gets used to access memory

    which means that just doing something like this can invoke undefined behavior:

    #![forbid(unsafe_code)]
    
    use rblas::matrix::Matrix;
    use rblas::vector::ops::Copy;
    use rblas::vector::Vector;
    
    #[derive(Clone, Debug)]
    struct MyType(Box<u64>);
    
    impl Copy for MyType {
        fn copy<V, W>(src: &V, dst: &mut W)
        where
            V: ?Sized + Vector<Self>,
            W: ?Sized + Vector<Self>,
        {
        }
    
        fn copy_mat(src: &Matrix<Self>, dst: &mut Matrix<Self>) {}
    }
    
    fn main() {
        let vec = vec![MyType(Box::new(42))];
        let as_blas_vector = &vec as &Vector<_>;
    
        let back_to_vec: Vec<MyType> = as_blas_vector.into();
    }
    
    opened by ammaraskar 1
  • Link errors when building/testing

    Link errors when building/testing

    I'm on Gentoo and have the sci-libs/cblas-reference and virtual/cblas packages installed. When I run cargo test I get a couple of pages of errors "undefined reference to `cblas_...'"

    I eventually figured out that I need to build with CARGO_BLAS=cblas to make it work.

    opened by canndrew 1
  • Link error In function `rblas::matrix::ops::f32.Gemm::gemm': rblas-0.0.11/src/matrix/ops.rs:34: undefined reference to `cblas_sgemm'

    Link error In function `rblas::matrix::ops::f32.Gemm::gemm': rblas-0.0.11/src/matrix/ops.rs:34: undefined reference to `cblas_sgemm'

    Hello,

    I am on Fedora 23, with blas and blas-devel 3.5.0 installed. I get the following error message when trying to run tests in Leaf using cargo.

    If I switch to openblas, the link error disapears

    opened by rohel01 1
  • Trait objects incur virtual calls

    Trait objects incur virtual calls

    Hi, I am probably moving away from rblas to blas-sys, I wanted to leave some observations anyway. I'm also happy to help with questions if you have any.

    An issue that mostly only should be important for small matrices and vectors is that trait objects (for example the type &Matrix<T>) cause their method calls to be virtual function calls. This makes them uninlinable. This is a bit unfortunate, since all of .order(), cols(), rows(), as_ptr() and so on are called through the trait object.

    opened by bluss 0
Releases(0.0.12)
Owner
Michael Yang
Michael Yang
gmp bindings for rust

Documentation The following functions are intentionally left out of the bindings: gmp_randinit (not thread-safe, obsolete) mpz_random (not thread-safe

Bartłomiej Kamiński 37 Nov 5, 2022
Mathematical optimization in pure Rust

argmin A pure Rust optimization framework This crate offers a numerical optimization toolbox/framework written entirely in Rust. It is at the moment p

argmin 549 Jan 1, 2023
Rust wrapper for ArrayFire

Arrayfire Rust Bindings ArrayFire is a high performance library for parallel computing with an easy-to-use API. It enables users to write scientific c

ArrayFire 696 Dec 30, 2022
Scientific Computing Library in Rust

SciRust Scientific computing library written in Rust programming language. The objective is to design a generic library which can be used as a backbon

In Digits 242 Dec 16, 2022
Statistical computation library for Rust

statrs Current Version: v0.13.0 Should work for both nightly and stable Rust. NOTE: While I will try to maintain backwards compatibility as much as po

Michael Ma 384 Dec 27, 2022
Collection of Optimization algorithm in Rust

rustimization A rust optimization library which includes L-BFGS-B and Conjugate Gradient algorithm. Documentation The simplest way to use these optimi

Naushad Karim 47 Sep 23, 2022
The write-once-run-anywhere GPGPU library for Rust

The old version of Emu (which used macros) is here. Overview Emu is a GPGPU library for Rust with a focus on portability, modularity, and performance.

Caleb Winston 1.5k Dec 30, 2022
BLAS bindings for Rust

RBLAS Rust bindings and wrappers for BLAS (Basic Linear Algebra Subprograms). Overview RBLAS wraps each external call in a trait with the same name (b

Michael Yang 77 Oct 8, 2022
Wrappers for BLAS (Fortran)

BLAS The package provides wrappers for BLAS (Fortran). Architecture Example use blas::*; let (m, n, k) = (2, 4, 3); let a = vec![ 1.0, 4.0, 2

BLAS and LAPACK for Rust 61 Nov 24, 2022
A naive (read: slow) implementation of Word2Vec. Uses BLAS behind the scenes for speed.

SloWord2Vec This is a naive implementation of Word2Vec implemented in Rust. The goal is to learn the basic principles and formulas behind Word2Vec. BT

Lloyd 2 Jul 5, 2018
An esoteric language/compiler written with Rust and Rust LLVM bindings

MeidoLang (メイドラング) A not so useful and esoteric language. The goal of this project was to contain some quirky or novel syntax in a stack-style program

null 0 Dec 24, 2021
Rust based WASM/JS bindings for ur-rust

ur-wasm-js WASM/JS bindings for the ur-rust rust library Getting started Installation Either build the library yourself with wasm-pack or install for

Lightning Digital Entertainment 5 Feb 28, 2024
Rust bindings for libinjection

libinjection-rs Rust bindings for libinjection. How to use Add libinjection to dependencies of Cargo.toml: libinjection = "0.2" Import crate: extern c

ArvanCloud 35 Sep 24, 2022
A project for generating C bindings from Rust code

cbindgen   Read the full user docs here! cbindgen creates C/C++11 headers for Rust libraries which expose a public C API. While you could do this by h

Ryan Hunt 1.7k Jan 3, 2023
Automatically generates Rust FFI bindings to C (and some C++) libraries.

bindgen bindgen automatically generates Rust FFI bindings to C (and some C++) libraries. For example, given the C header doggo.h: typedef struct Doggo

The Rust Programming Language 3.2k Jan 4, 2023
Rust-JDBC bindings

jdbc A Rust library that allows you to use JDBC and JDBC drivers. Usage First, add the following to your Cargo.toml: [dependencies] jdbc = "0.1" Next,

Aurora 18 Feb 9, 2022
Lua 5.3 bindings for Rust

rust-lua53 Aims to be complete Rust bindings for Lua 5.3 and beyond. Currently, master is tracking Lua 5.3.3. Requires a Unix-like environment. On Win

J.C. Moyer 150 Dec 14, 2022
Safe Rust bindings to Lua 5.1

rust-lua Copyright 2014 Lily Ballard Description This is a set of Rust bindings to Lua 5.1. The goal is to provide a (relatively) safe interface to Lu

Lily Ballard 124 Jan 5, 2023
mruby safe bindings for Rust

mrusty. mruby safe bindings for Rust mrusty lets you: run Ruby 1.9 files with a very restricted API (without having to install Ruby) reflect Rust stru

Anima 200 Oct 12, 2022
Rust bindings for writing safe and fast native Node.js modules.

Rust bindings for writing safe and fast native Node.js modules. Getting started Once you have the platform dependencies installed, getting started is

The Neon Project 7k Jan 4, 2023