# Multiplying boolean matrices

**URL:** https://discourse.julialang.org/t/multiplying-boolean-matrices/71086
**Category:** Performance
**Tags:** question, performance, linearalgebra
**Created:** [November 7, 2021, 10:41am UTC](https://discourse.julialang.org/t/multiplying-boolean-matrices/71086 "2021-11-07T10:41:03Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)
#### Post date: [November 7, 2021, 10:41am UTC](https://discourse.julialang.org/t/multiplying-boolean-matrices/71086/1 "2021-11-07T10:41:03Z")

</div>

Why is there such a performance difference between multiplying float matrices and other kinds of matrices? I understand float matrices hit BLAS which is heavily optimized. But is this a fundamental difference or or just that we are lacking a “BLAS for boolean matrices” for example?

![image](https://global.discourse-cdn.com/julialang/original/3X/6/c/6c47f6759ce925002dd501449787a3025dde1cdb.png)

Can we expect that in the future with a generic Julia implementation of BLAS this difference will disappear?

Is there a package one can use now to speedup boolean matrices?

---

<div class="post-metadata">

### Author: ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)
#### Post date: [November 7, 2021, 10:54am UTC](https://discourse.julialang.org/t/multiplying-boolean-matrices/71086/2 "2021-11-07T10:54:18Z")

</div>

As suggested by @antoine-levitt, it is interesting to look at the non-BLAS float matmul currently implemented in Julia.

![image](https://global.discourse-cdn.com/julialang/original/3X/7/3/73ac3093e3ec66009919905fbd3644f97d56776c.png)

Interesting this is also quite faster than the boolean matrix matmul. Is there some intrinsic difficulty in multiplying against boolean matrices?

Notice that a fast boolean matrix matmul could be useful in deep learning for one-hot represented data.  
If the one-hot data could be represented as BitArray the memory usage would be quite smaller.

---

<div class="post-metadata">

### Author: ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)
#### Post date: [November 7, 2021, 11:10am UTC](https://discourse.julialang.org/t/multiplying-boolean-matrices/71086/3 "2021-11-07T11:10:42Z")

</div>

Hm, generic\_matmatmul still does something fancy (see \_generic\_matmatmul! in LinearAlgebra/src/matmul.jl) so that’s not quite a plain comparison. You’d have to code your own three-loops algorithm to compare. If you want fast bool matmuls, maybe take a look at [GitHub - JuliaLinearAlgebra/Octavian.jl: Multi-threaded BLAS-like library that provides pure Julia matrix multiplication](https://github.com/JuliaLinearAlgebra/Octavian.jl)

---

<div class="post-metadata">

### Author: ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)
#### Post date: [November 7, 2021, 11:33am UTC](https://discourse.julialang.org/t/multiplying-boolean-matrices/71086/4 "2021-11-07T11:33:08Z")

</div>

Using Octavian things are faster:

![image](https://global.discourse-cdn.com/julialang/original/3X/b/1/b1a6be43316a5a47ae9728fa7455aaab24e0064f.png)

But float matmul still wins significantly.

Unfortunately Octavian doesn’t seem to work with `BitMatrix`, [Error with BitArray · Issue #123 · JuliaLinearAlgebra/Octavian.jl · GitHub](https://github.com/JuliaLinearAlgebra/Octavian.jl/issues/123).

---

<div class="post-metadata">

### Author: ![freemint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freemint/32/20013_2.png) [@freemint](https://discourse.julialang.org/u/freemint)
#### Post date: [November 7, 2021, 6:54pm UTC](https://discourse.julialang.org/t/multiplying-boolean-matrices/71086/5 "2021-11-07T18:54:29Z")

</div>

Are you interested in a Matmul with an addition where 1+1 = 1 or 1+1=0?  
The performance difference comes from indexing into a BitArray which involves slicing to get Int with the correct value. It could be implement a lot faster by bit level boolean operation by and-ing the two vectors and then either checking whether it is non-zero (when 1+1=1) or checking the last bit of the intrinsic popcount (when you want 1+1=0).
