GithubHelp home page GithubHelp logo

rust-blas's People

Contributors

bluss avatar bovee avatar mikkyang avatar raineszm avatar skade 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-blas's Issues

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.

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:

fn into(self) -> Vec<T> {
let n = self.len() as usize;
let mut x = Vec::with_capacity(n);
unsafe { x.set_len(n); }
Copy::copy(self, &mut x);
x
}

rust-blas/src/math/mat.rs

Lines 121 to 123 in bf6d331

unsafe { result.data.set_len(len); }
Copy::copy_mat(a, &mut result);

let mut result = Vec::with_capacity(n);
unsafe { result.set_len(n); }
let scale = Default::one();
let clear = Default::zero();
let t = Transpose::NoTrans;
Gemv::gemv(t, &scale, self, x, &clear, &mut result);

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();
}

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.

`syrk` C API function is called with incorrect arguments ?

i think there is a small bug in the syrk implementation.

code in question:

a.rows(), a.cols(),

you are passing a.rows() as argument 4 whereas the blas documentation specifies argument 4 as the order of c. the order of c is c.rows() or alternatively c.cols() since c.rows() == c.cols().

N Order of matrix C.

you are passing a.cols() as argument 5 whereas the blas documentation specifies argument 5 as (translated to rust in the context of that function):

match trans {
  Transpose::NoTrans => a.cols(),
  Transpose::Trans => a.rows(),
  Transpose::ConjTrans => a.rows(),
}

Number of columns in matrix A (or number of rows if matrix A is transposed).

On entry with TRANS = 'N' or 'n', K specifies the number of columns of the matrix A, and on entry with TRANS = 'T' or 't' or 'C' or 'c', K specifies the number of rows of the matrix A. K must be at least zero.

sources:
https://developer.apple.com/library/mac/documentation/Accelerate/Reference/BLAS_Ref/index.html#//apple_ref/c/func/cblas_ssyrk
http://www.netlib.org/lapack/explore-html/db/dc9/group__single__blas__level3.html#gae953a93420ca237670f5c67bbde9d9ff
https://software.intel.com/en-us/node/468490

this bug prevents me from using syrk in any meaningful way: i always get an error from blas.

i'd be happy to fix this, write tests and do a PR.

let me know.

i'd also go over the other implementations (syr2k, etc) and audit the arguments.

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

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!

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).

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.

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.