Zulip Chat Archive
Stream: lean4
Topic: BLAS bindings
Tomas Skrivan (Dec 15 2024 at 14:04):
I have created C BLAS bindings for Lean, LeanBLAS. Right now I have just level 1 for double precision.
Also I started writing specification in Spec
directory, for level one I'm still missing iamax
, rotg
, rotmg
and rot
.
If anyone is interested in contributing, here is a list of things to do:
- add level one for single precision float
- add level one for complex numbers
- finish specification for level one
- add bindings for level 2 and 3
- write specification for level 2 and 3
- set up build for cuBLAS
- set up build for clBLAS
Copilot is really good at writing this kind of code. I would be interested if anyone would manage to oneshot all of this with some AI code generator.
Eric Wieser (Dec 15 2024 at 18:30):
Should ComplexFloat
be in Lean core, since C99 has it natively?
Eric Wieser (Dec 15 2024 at 18:37):
Maybe the better question is "while it's not in Lean core, can we use implemented_by
to compile it to C complex double
?".
Tomas Skrivan (Dec 15 2024 at 18:53):
Good question, I'm planing to implement single precision float as
opaque Float32 := UInt32
Unfortunately, current compiler boxes types when they are marked opaque, so for some time it would have to be def Float32 := UInt32
and just not exploit defeq.
Similarly complex float
can be done using UInt64
but for complex double
I would need UInt128
.
But it is not so bad as values in ComplexFloat
are no boxed as they would be in Float × Float
.
Hopefully, compiling ComplexFloat
down to complex double
will be possible as user code in the new complier.
Henrik Böving (Dec 15 2024 at 19:23):
Tomas Skrivan said:
Good question, I'm planing to implement single precision float as
opaque Float32 := UInt32
Unfortunately, current compiler boxes types when they are marked opaque, so for some time it would have to be
def Float32 := UInt32
and just not exploit defeq.Similarly
complex float
can be done usingUInt64
but forcomplex double
I would needUInt128
.But it is not so bad as values in
ComplexFloat
are no boxed as they would be inFloat × Float
.Hopefully, compiling
ComplexFloat
down tocomplex double
will be possible as user code in the new complier.
Leo added built-in support for Float32
this week
Henrik Böving (Dec 15 2024 at 19:23):
Eric Wieser said:
Maybe the better question is "while it's not in Lean core, can we use
implemented_by
to compile it to Ccomplex double
?".
That is not something that is technically possible with implemented_by
, the set of types that Lean accepts as unboxed is currently not open to extension and hard controlled by the compiler.
Eric Wieser (Dec 15 2024 at 20:24):
Relatedly, perhaps mathlib's Complex
should be generalized to Complex Real
or similar (perhaps in batteries), so that you can get Complex Float64
for "free"
Eric Wieser (Dec 15 2024 at 20:24):
I don't know if defaulting the type argument to Real
is well-behaved, but at least mathlib pretty much exclusively uses the notation anyway.
Eric Wieser (Dec 15 2024 at 20:25):
Plus then we can merge Complex and GaussianInt
Tomas Skrivan (Dec 15 2024 at 20:27):
Also you could use it for vector space complexification.
Edward van de Meent (Dec 15 2024 at 21:30):
Eric Wieser said:
Plus then we can merge Complex and GaussianInt
Then presumably we want to generalize docs#Zsqrtd to any type rather than just Int
, and possibly upstream?
Kevin Buzzard (Dec 15 2024 at 23:01):
We should do it the Bourbaki way really, and have instead of just . This is the general free rank 2 -algebra, you can't complete the square if 2 isn't invertible in .
Kevin Buzzard (Dec 15 2024 at 23:02):
Maybe we have special notation or whatever for the case but we should really have the general thing too.
Edward van de Meent (Dec 15 2024 at 23:06):
that makes it noncomputable though
Edward van de Meent (Dec 15 2024 at 23:06):
(at least, i think?)
Edward van de Meent (Dec 15 2024 at 23:07):
there is docs#AdjoinRoot
Edward van de Meent (Dec 15 2024 at 23:09):
anyhow, the point is not to do fancy math things for Complex numbers, but to get a nice memory layout, and i don't believe going through Polynomial
does that.
Edward van de Meent (Dec 15 2024 at 23:28):
Kevin Buzzard said:
We should do it the Bourbaki way really, and have instead of just .
As a small note, right now neither Complex
nor GaussianInt
is defined this way.
Kim Morrison (Dec 16 2024 at 00:34):
I think one can have both memory layout and mathematical generality. We'll define (apologies, on mobile)
structure Complex' (R : Type) (b : R := by exact -1) (a := by exact 0) where
re : R
im : R
The parameters a
and b
are then not used until it's time to define multiplication.
Andrew Yang (Dec 16 2024 at 00:35):
No the thing Kevin suggesting is not going through Polynomial
but just generalize docs#Zsqrtd from pairs such that to .
Kim Morrison (Dec 16 2024 at 00:35):
The by exact
is a trick to allow default values without typeclasses in the signature.
Edward van de Meent (Dec 17 2024 at 22:02):
i'm trying to define instances for the suggested structure... Just to be sure, is there a sensible instance of Star
when a
is nonzero? because simply negating the imaginary component is not it...
Edward van de Meent (Dec 17 2024 at 22:36):
i.e. does not yield a StarRing
assuming the original ring is a CommRing
Edward van de Meent (Dec 17 2024 at 22:37):
(maybe at this point the conversation should be moved to either #mathlib4 or #maths?)
Kim Morrison (Dec 18 2024 at 00:30):
You need 2 to be invertible, so you can send X
to the other root.
Doesn't X \mapsto -X + a
work?
Edward van de Meent (Dec 18 2024 at 20:31):
i've run into a small issue, and i don't know what's causing it:
import Mathlib
set_option autoImplicit false
structure Complex' (R : Type*) (b : R := by exact -1) (a : R := by exact 0) where
re : R
im : R
namespace Complex'
def of {R : Type*} {b a : R} [Zero R] (r:R) : Complex' R b a where
re := r
im := 0
-- not relevant afaict
instance {R : Type*} {b a : R} : Mul (Complex' R b a) := sorry
-- issue in this declaration
theorem exists_coprime_of_gcd_pos {d:ℤ} {x : Complex' ℤ d} :
∃ (y : Complex' ℤ d), x = (of (x.re.gcd x.im : ℤ) : Complex' ℤ d) * y := by -- could not synthesize default value for parameter 'a' using tactics
sorry
-- similar issue in this declaration, now at a different position
theorem exists_coprime_of_gcd_pos {d:ℤ} {x : Complex' ℤ d} : -- could not synthesize default value for parameter 'a' using tactics
∃ y, x = (of (x.re.gcd x.im : ℤ)) * y := by
sorry
end Complex'
the error occurs at the uses of Complex'
in the marked lines.
Fixing is easy enough, just provide the parameter explicitly... still, i'd love to know what triggers this issue...
Kim Morrison (Dec 20 2024 at 00:46):
I'm not sure. I wonder if there is some obstruction to running autoparams inside type ascriptions??
Tomas Skrivan (Feb 03 2025 at 15:05):
Does anyone have experience with BLAS on Windows? I'm really do not know how can I make the library easily portable :( Should I include source of OpenBLAS and just compile it on user machine? Should I download binaries?
cc @Mac Malone what is the recommended way for Lean project to depend on C library?
On Linux or Mac you just run sudo apt-get install libblas-dev
or brew install openblas
but on Windows you can't do anything simple like that.
Tomas Skrivan (Feb 03 2025 at 15:08):
Also I would like to provide optional dependency on CUDA/cuBLAS. What would be the recommended way of adding an ENABLE_CUDA
switch? And how should downstream projects use this switch?
Last updated: May 02 2025 at 03:31 UTC