@@ -34,103 +34,125 @@ function vml_check_error()
3434 end
3535end
3636
37- const unary_ops = [(:(Base. acos), :acos! , :Acos ),
38- (:(Base. asin), :asin! , :Asin ),
39- (:(Base. atan), :atan! , :Atan ),
40- (:(Base. cos), :cos! , :Cos ),
41- (:(Base. sin), :sin! , :Sin ),
42- (:(Base. tan), :tan! , :Tan ),
43- (:(Base. acosh), :acosh! , :Acosh ),
44- (:(Base. asinh), :asinh! , :Asinh ),
45- (:(Base. atanh), :atanh! , :Atanh ),
46- (:(Base. cosh), :cosh! , :Cosh ),
47- (:(Base. sinh), :sinh! , :Sinh ),
48- (:(Base. tanh), :tanh! , :Tanh ),
49- (:(Base. cbrt), :cbrt! , :Cbrt ),
50- (:(Base. sqrt), :sqrt! , :Sqrt ),
51- (:(Base. exp), :exp! , :Exp ),
52- (:(Base. expm1), :expm1! , :Expm1 ),
53- (:(Base. log), :log! , :Ln ),
54- (:(Base. log10), :log10! , :Log10 ),
55- (:(Base. log1p), :log1p , :Log1p ),
56- (:(Base. abs), :abs! , :Abs ),
57- (:(Base. abs2), :abs2! , :Sqr ),
58- (:(Base. ceil), :ceil! , :Ceil ),
59- (:(Base. floor), :floor! , :Floor ),
60- (:(Base. round), :round! , :Round ),
61- (:(Base. trunc), :trunc! , :Trunc ),
62- (:(Base. erf), :erf! , :Erf ),
63- (:(Base. erfc), :erfc! , :Erfc ),
64- (:(Base. erfinv), :erfinv! , :ErfInv ),
65- (:(Base. erfcinv), :erfcinv! , :ErfcInv ),
66- (:(Base. lgamma), :lgamma! , :LGamma ),
67- (:(Base. gamma), :gamma! , :TGamma ),
68- # Not in Base
69- (:inv_cbrt , :inv_cbrt! , :InvCbrt ),
70- (:inv_sqrt , :inv_sqrt! , :InvSqrt ),
71- (:pow2o3 , :pow2o3! , :Pow2o3 ),
72- (:pow3o2 , :pow3o2! , :Pow3o2 )]
73-
74- const binary_vector_ops = [(:(Base. atan2), :atan2! , :Atan2 , false ),
75- (:(Base. hypot), :hypot! , :Hypot , false ),
76- (:(Base .(:.^ )), :pow! , :Pow , true ),
77- (:(Base .(:./ )), :divide! , :Div , true )]
78-
79- for (prefix, t) in ((:_vmls , :Float32 ), (:_vmld , :Float64 ))
80- # Unary
81- for (jlname, jlname!, mklname) in unary_ops
82- mklfn = Base. Meta. quot (symbol (" $prefix$mklname " ))
83- exports = Symbol[]
84- isa (jlname, Expr) || push! (exports, jlname)
85- isa (jlname!, Expr) || push! (exports, jlname!)
86- @eval begin
87- $ (isempty (exports) ? nothing : Expr (:export , exports... ))
88- function $ (jlname!){N}(out:: Array{$t,N} , A:: Array{$t,N} )
89- size (out) == size (A) || throw (DimensionMismatch ())
90- ccall (($ mklfn, lib), Void, (Int, Ptr{$ t}, Ptr{$ t}), length (A), A, out)
91- vml_check_error ()
92- out
93- end
94- function $ (jlname!)(A:: Array{$t} )
95- ccall (($ mklfn, lib), Void, (Int, Ptr{$ t}, Ptr{$ t}), length (A), A, A)
96- vml_check_error ()
97- A
98- end
99- function $ (jlname)(A:: Array{$t} )
100- out = similar (A)
101- ccall (($ mklfn, lib), Void, (Int, Ptr{$ t}, Ptr{$ t}), length (A), A, out)
102- vml_check_error ()
103- out
37+ function vml_prefix (t:: DataType )
38+ if t == Float32
39+ return " _vmls"
40+ elseif t == Float64
41+ return " _vmld"
42+ elseif t == Complex{Float32}
43+ return " _vmlc"
44+ elseif t == Complex{Float64}
45+ return " _vmlz"
46+ end
47+ error (" unknown type $t " )
48+ end
49+
50+ function def_unary_op (tin, tout, jlname, jlname!, mklname)
51+ mklfn = Base. Meta. quot (symbol (" $(vml_prefix (tin))$mklname " ))
52+ exports = Symbol[]
53+ isa (jlname, Expr) || push! (exports, jlname)
54+ isa (jlname!, Expr) || push! (exports, jlname!)
55+ @eval begin
56+ $ (isempty (exports) ? nothing : Expr (:export , exports... ))
57+ function $ (jlname!){N}(out:: Array{$tout,N} , A:: Array{$tin,N} )
58+ size (out) == size (A) || throw (DimensionMismatch ())
59+ ccall (($ mklfn, lib), Void, (Int, Ptr{$ tin}, Ptr{$ tout}), length (A), A, out)
60+ vml_check_error ()
61+ out
62+ end
63+ $ (if tin == tout
64+ quote
65+ function $ (jlname!)(A:: Array{$tin} )
66+ ccall (($ mklfn, lib), Void, (Int, Ptr{$ tin}, Ptr{$ tout}), length (A), A, A)
67+ vml_check_error ()
68+ A
69+ end
10470 end
71+ end )
72+ function $ (jlname)(A:: Array{$tin} )
73+ out = similar (A, $ tout)
74+ ccall (($ mklfn, lib), Void, (Int, Ptr{$ tin}, Ptr{$ tout}), length (A), A, out)
75+ vml_check_error ()
76+ out
10577 end
10678 end
79+ end
10780
108- # Binary, two vectors
109- for (jlname, jlname!, mklname, broadcast) in binary_vector_ops
110- mklfn = Base. Meta. quot (symbol (" $prefix$mklname " ))
111- exports = Symbol[]
112- isa (jlname, Expr) || push! (exports, jlname)
113- isa (jlname!, Expr) || push! (exports, jlname!)
114- @eval begin
115- $ (isempty (exports) ? nothing : Expr (:export , exports... ))
116- function $ (jlname!){N}(out:: Array{$t,N} , A:: Array{$t,N} , B:: Array{$t,N} )
117- size (out) == size (A) == size (B) || $ (broadcast ? :(return broadcast! ($ jlname, out, A, B)) : :(throw (DimensionMismatch ())))
118- ccall (($ mklfn, lib), Void, (Int, Ptr{$ t}, Ptr{$ t}, Ptr{$ t}), length (A), A, B, out)
119- vml_check_error ()
120- out
121- end
122- function $ (jlname){N}(A:: Array{$t,N} , B:: Array{$t,N} )
123- size (A) == size (B) || $ (broadcast ? :(return broadcast ($ jlname, A, B)) : :(throw (DimensionMismatch ())))
124- out = similar (A)
125- ccall (($ mklfn, lib), Void, (Int, Ptr{$ t}, Ptr{$ t}, Ptr{$ t}), length (A), A, B, out)
126- vml_check_error ()
127- out
128- end
81+ function def_binary_op (tin, tout, jlname, jlname!, mklname, broadcast)
82+ mklfn = Base. Meta. quot (symbol (" $(vml_prefix (tin))$mklname " ))
83+ exports = Symbol[]
84+ isa (jlname, Expr) || push! (exports, jlname)
85+ isa (jlname!, Expr) || push! (exports, jlname!)
86+ @eval begin
87+ $ (isempty (exports) ? nothing : Expr (:export , exports... ))
88+ function $ (jlname!){N}(out:: Array{$tout,N} , A:: Array{$tin,N} , B:: Array{$tin,N} )
89+ size (out) == size (A) == size (B) || $ (broadcast ? :(return broadcast! ($ jlname, out, A, B)) : :(throw (DimensionMismatch ())))
90+ ccall (($ mklfn, lib), Void, (Int, Ptr{$ tin}, Ptr{$ tin}, Ptr{$ tout}), length (A), A, B, out)
91+ vml_check_error ()
92+ out
93+ end
94+ function $ (jlname){N}(A:: Array{$tout,N} , B:: Array{$tin,N} )
95+ size (A) == size (B) || $ (broadcast ? :(return broadcast ($ jlname, A, B)) : :(throw (DimensionMismatch ())))
96+ out = similar (A)
97+ ccall (($ mklfn, lib), Void, (Int, Ptr{$ tin}, Ptr{$ tin}, Ptr{$ tout}), length (A), A, B, out)
98+ vml_check_error ()
99+ out
129100 end
130101 end
102+ end
103+
104+ for t in (Float32, Float64, Complex64, Complex128)
105+ # Unary, real or complex
106+ def_unary_op (t, t, :(Base. acos), :acos! , :Acos )
107+ def_unary_op (t, t, :(Base. asin), :asin! , :Asin )
108+ def_unary_op (t, t, :(Base. acosh), :acosh! , :Acosh )
109+ def_unary_op (t, t, :(Base. asinh), :asinh! , :Asinh )
110+ def_unary_op (t, t, :(Base. sqrt), :sqrt! , :Sqrt )
111+ def_unary_op (t, t, :(Base. exp), :exp! , :Exp )
112+ def_unary_op (t, t, :(Base. log), :log! , :Ln )
131113
132- # Binary, vector and scalar
133- mklfn = Base. Meta. quot (symbol (" $(prefix) Powx" ))
114+ # Binary, real or complex
115+ def_binary_op (t, t, :(Base .(:.^ )), :pow! , :Pow , true )
116+ def_binary_op (t, t, :(Base .(:./ )), :divide! , :Div , true )
117+ end
118+
119+ for t in (Float32, Float64)
120+ # Unary, real-only
121+ def_unary_op (t, t, :(Base. cbrt), :cbrt! , :Cbrt )
122+ def_unary_op (t, t, :(Base. expm1), :expm1! , :Expm1 )
123+ def_unary_op (t, t, :(Base. log1p), :log1p , :Log1p )
124+ def_unary_op (t, t, :(Base. abs), :abs! , :Abs )
125+ def_unary_op (t, t, :(Base. abs2), :abs2! , :Sqr )
126+ def_unary_op (t, t, :(Base. ceil), :ceil! , :Ceil )
127+ def_unary_op (t, t, :(Base. floor), :floor! , :Floor )
128+ def_unary_op (t, t, :(Base. round), :round! , :Round )
129+ def_unary_op (t, t, :(Base. trunc), :trunc! , :Trunc )
130+ def_unary_op (t, t, :(Base. erf), :erf! , :Erf )
131+ def_unary_op (t, t, :(Base. erfc), :erfc! , :Erfc )
132+ def_unary_op (t, t, :(Base. erfinv), :erfinv! , :ErfInv )
133+ def_unary_op (t, t, :(Base. erfcinv), :erfcinv! , :ErfcInv )
134+ def_unary_op (t, t, :(Base. lgamma), :lgamma! , :LGamma )
135+ def_unary_op (t, t, :(Base. gamma), :gamma! , :TGamma )
136+ # Not in Base
137+ def_unary_op (t, t, :inv_cbrt , :inv_cbrt! , :InvCbrt )
138+ def_unary_op (t, t, :inv_sqrt , :inv_sqrt! , :InvSqrt )
139+ def_unary_op (t, t, :pow2o3 , :pow2o3! , :Pow2o3 )
140+ def_unary_op (t, t, :pow3o2 , :pow3o2! , :Pow3o2 )
141+
142+ # Enabled only for Real. MKL guarantees higher accuracy, but at a
143+ # substantial performance cost.
144+ def_unary_op (t, t, :(Base. atan), :atan! , :Atan )
145+ def_unary_op (t, t, :(Base. cos), :cos! , :Cos )
146+ def_unary_op (t, t, :(Base. sin), :sin! , :Sin )
147+ def_unary_op (t, t, :(Base. tan), :tan! , :Tan )
148+ def_unary_op (t, t, :(Base. atanh), :atanh! , :Atanh )
149+ def_unary_op (t, t, :(Base. cosh), :cosh! , :Cosh )
150+ def_unary_op (t, t, :(Base. sinh), :sinh! , :Sinh )
151+ def_unary_op (t, t, :(Base. tanh), :tanh! , :Tanh )
152+ def_unary_op (t, t, :(Base. log10), :log10! , :Log10 )
153+
154+ # .^ to scalar power
155+ mklfn = Base. Meta. quot (symbol (" $(vml_prefix (t)) Powx" ))
134156 @eval begin
135157 export pow!
136158 function pow! {N} (out:: Array{$t,N} , A:: Array{$t,N} , b:: $t )
@@ -146,6 +168,25 @@ for (prefix, t) in ((:_vmls, :Float32), (:_vmld, :Float64))
146168 out
147169 end
148170 end
171+
172+ # Binary, real-only
173+ def_binary_op (t, t, :(Base. atan2), :atan2! , :Atan2 , false )
174+ def_binary_op (t, t, :(Base. hypot), :hypot! , :Hypot , false )
175+
176+ # Unary, complex-only
177+ def_unary_op (t, Complex{t}, :(Base. cis), :cis! , :CIS )
178+ # def_unary_op(Complex{t}, Complex{t}, :(Base.conj), :conj!, :Conj)
179+ def_unary_op (Complex{t}, t, :(Base. abs), :abs! , :Abs )
180+ def_unary_op (Complex{t}, t, :(Base. angle), :angle! , :Arg )
181+
182+ # Binary, complex-only. These are more accurate but performance is
183+ # either equivalent to Base or slower.
184+ # def_binary_op(Complex{t}, Complex{t}, :(Base.(:+)), :add!, :Add, false)
185+ # def_binary_op(Complex{t}, Complex{t}, :(Base.(:.+)), :add!, :Add, true)
186+ # def_binary_op(Complex{t}, Complex{t}, :(Base.(:.*)), :multiply!, :Mul, true)
187+ # def_binary_op(Complex{t}, Complex{t}, :(Base.(:-)), :subtract!, :Sub, false)
188+ # def_binary_op(Complex{t}, Complex{t}, :(Base.(:.-)), :subtract!, :Sub, true)
189+ # def_binary_op(Complex{t}, Complex{t}, :multiply_conj, :multiply_conj!, :Mul, false)
149190end
150191
151192export VML_LA, VML_HA, VML_EP, vml_set_accuracy, vml_get_accuracy
0 commit comments