JuliaSparse / SuiteSparseGraphBLAS.jl

Sparse, General Linear Algebra for Graphs!
MIT License
102 stars 17 forks source link

Construct your own operator (monoid) #74

Closed prenc closed 2 years ago

prenc commented 2 years ago

Is it possible to create your own operator, or monoid more specifically? I can't find an example of this anywhere, however, the documentation says:

users are also free to provide their own functions as operators when necessary.

Currently:

julia> *((a,b)->a+b, *)(A, A)
ERROR: MethodError: objects of type Monoid{var"#5#6"} are not callable
Stacktrace:
 [1] (::Semiring{var"#5#6", typeof(*)})(T::Type, U::Type)
   @ SuiteSparseGraphBLAS.Semirings ~/.julia/packages/SuiteSparseGraphBLAS/Wdprf/src/operators/semirings.jl:24
 [2] mul!(C::GBMatrix{Bool, Nothing}, A::GBMatrix{Bool, Nothing}, B::GBMatrix{Bool, Nothing}, op::Tuple{var"#5#6", typeof(*)}; mask::Nothing, accum::Nothing, desc::Nothing)
   @ SuiteSparseGraphBLAS ~/.julia/packages/SuiteSparseGraphBLAS/Wdprf/src/operations/mul.jl:19
 [3] *(A::GBMatrix{Bool, Nothing}, B::GBMatrix{Bool, Nothing}, op::Tuple{var"#5#6", typeof(*)}; mask::Nothing, accum::Nothing, desc::Nothing)
   @ SuiteSparseGraphBLAS ~/.julia/packages/SuiteSparseGraphBLAS/Wdprf/src/operations/mul.jl:99
 [4] (::SuiteSparseGraphBLAS.var"#114#116"{SuiteSparseGraphBLAS.var"#114#115#117"{var"#5#6", typeof(*)}})(A::GBMatrix{Bool, Nothing}, B::GBMatrix{Bool, Nothing}; mask::Nothing, accum::Nothing, desc::Nothing)
   @ SuiteSparseGraphBLAS ~/.julia/packages/SuiteSparseGraphBLAS/Wdprf/src/operations/mul.jl:154
 [5] (::SuiteSparseGraphBLAS.var"#114#116"{SuiteSparseGraphBLAS.var"#114#115#117"{var"#5#6", typeof(*)}})(A::GBMatrix{Bool, Nothing}, B::GBMatrix{Bool, Nothing})
   @ SuiteSparseGraphBLAS ~/.julia/packages/SuiteSparseGraphBLAS/Wdprf/src/operations/mul.jl:154
 [6] top-level scope
   @ REPL[98]:1
rayegun commented 2 years ago

The current release is bugged for construction of user-defined monoids and semirings, I apologize. I actually didn't realize this until your issue.

I'm doing my best to make a release tonight or tomorrow, that will include a documented interface to do this.

The main problem with Monoids is that I can't really assume what the identity and terminal of the monoid are. So while you can use a BinaryOp anywhere without forward declaring it, you can't really do so with a monoid right now.

The current syntax would be f(x, y) = x + y; @monoid f Int64 id=>zero to declare a monoid for Int64. f can then be used freely where monoids are required (reduce and mul). But as mentioned it is missing some method definitions and therefore bugged.

prenc commented 2 years ago

Thank you for a quick answer. Then I'm waiting for the following improvements

rayegun commented 2 years ago

Fixed in https://github.com/JuliaSparse/SuiteSparseGraphBLAS.jl/pull/86. New syntax would be *(Monoid((a,b)->a+b, zero), *)(A, A) since you need to add an identity. This interface will be documented before the next release.