I'm not sure if this is the way to go, but I agree that it would be nice to
be able to extract specialized versions of such functions automatically
based on the general version by setting certain arguments to zero or one in
a way that the compiler can reason about.
One thing to consider is that it seems that an ordinary zero is not enough,
but you need a hard zero that such that _zero*NaN is zero. I believe that
False has been used like this in the past. I guess the compiler won't
specialize completely if you supply Bool arguments for alpha and beta
though. (Or will it?)
One thing that comes to mind is MathConst, which is an already existing
abstraction that seems to be close to what you would need for your _zero
and _one values. Though I believe that it's always assumed that a MathConst
is irrational right now, so that might need some changes. Apart from that I
have no idea if it's a good thing to do, but it seems to me that the
ambiguities would already have been handled.
Another possibility might be if you could force an inline call to e.g.
gemm! with specific arguments such as 0 or 1 for alpha or beta. But that
would of course break down if the inlined function doesn't do the work
itself but calls no another function to do it.
On thing I think you should avoid in either case is to have code such as
gemm!((beta == 1 ? _one : (beta == 0 ?_zero : beta)) , C, (alpha == 1 ?_one
: alpha), A,B)
since it's not type stable. I believe the compiler will do a much better
job with e.g.
if beta == 1
if alpha == 1; gemm!(_one, C, _one, A,B)
else gemm!(_one, C, alpha, A,B)
end
elseif beta == 0
if alpha == 1; gemm!(_zero, C, _one, A,B)
else gemm!(_zero, C, alpha, A,B)
end
else
if alpha == 1; gemm!(beta, C, _one, A,B)
else gemm!(beta, C, alpha, A,B)
end
end
even though it's clearly not as nice to write.