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.
>>>
>>>
>

Reply via email to