mikkyang / rust-blas Goto Github PK
View Code? Open in Web Editor NEWBLAS bindings for Rust
License: MIT License
BLAS bindings for Rust
License: MIT License
It should be safe, just like Matrix::as_ptr. Just an inconsistency. Thanks :)
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.
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:
&mut Vector
with &mut VectorMut
and everything should work.Disadvantages:
&&[T]
rather than &[T]
.Vec
and their own types would have to move the method.&mut
types are mutable. I suppose Index
and IndexMut
are somewhat similar, though.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:
Disadvantages:
&x
and &y
maybe be different types, we can't constrict them both to the same type and have to specify trait bounds twice.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
:
Lines 30 to 38 in bf6d331
Lines 121 to 123 in bf6d331
rust-blas/src/math/matrix_vector.rs
Lines 23 to 29 in bf6d331
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();
}
It would be useful to have VectorOperations
implemented for &[f64]
etc.
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.
i think there is a small bug in the syrk
implementation.
code in question:
Line 203 in 849c703
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.
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.
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
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!
In for example Gemm
, the ordering of the input a
is used, but this requires that a
, b
, c
all have the same value for .order()
. This is not checked.
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
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).
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.