In 0.4 you can also use the Val{T} type for dispatching on particular
values (it's used in Base.LinAlg in a couple of places).
Things like this highlight how old the BLAS specification really is:
level-3 BLAS (the most recent) is now 27 years old. They were written with
machines such as the Cray 1 in mind (most PCs didn't even have FPUs until
the 486), and predate widespread use of the IEEE754 standard (hence the
funny NaN*0 behaviour).
-simon
On Friday, 22 May 2015 09:34:56 UTC+1, Jutho wrote:
>
> That’s probably true. But using the if construction in the high level
> function is certainly fine; and avoids having to use the if in the
> low-level kernel, which will be called many times.
>
>
> On 22 May 2015, at 10:31, Toivo Henningsson <[email protected]
> <javascript:>> wrote:
>
> I would think that calling the function as in your initial example would
> cause type inference to conclude Union types for alpha and beta, and cause
> code generation to always use dynamic dispatch.
>
> Another thing to consider is to make sure that the called function is
> still type stable when passed a special zero or one in those arguments.
> On 22 May 2015 10:27, "Jutho" <[email protected] <javascript:>> wrote:
>
>> Thanks for the detailed response. The MathConst idea is possibly a great
>> suggestion which I will look into. With respect to the calling the
>> low-level function, I don't think there is a big difference between your
>> suggestion and my one-liner, as long as the return type of the function is
>> the same for all possible combinations of argument types. Although maybe
>> there is some boxing going on in assigning the result of beta == 1 ?
>> _one : (beta == 0 ?_zero : beta)) to a temporary variable.
>>
>> Op vrijdag 22 mei 2015 10:20:57 UTC+2 schreef Toivo Henningsson:
>>>
>>> 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.
>>>
>>>
>