Skip to content

Commit 3b70c23

Browse files
cleanup C - Julia BigFloat interop (#104)
* cleanup C - Julia BigFloat interop * rework help text
1 parent fc78aad commit 3b70c23

File tree

5 files changed

+38
-63
lines changed

5 files changed

+38
-63
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "FastTransforms"
22
uuid = "057dd010-8810-581a-b7be-e3fc3b93f78c"
3-
version = "0.9.1"
3+
version = "0.9.2"
44

55
[deps]
66
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
@@ -22,7 +22,7 @@ BinaryProvider = "0.5"
2222
DSP = "0.6"
2323
FFTW = "1"
2424
FastGaussQuadrature = "0.4"
25-
FastTransforms_jll = "0.3.1"
25+
FastTransforms_jll = "0.3.2"
2626
Reexport = "0.2"
2727
SpecialFunctions = "0.8, 0.9, 0.10"
2828
ToeplitzMatrices = "0.6"

deps/build.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using BinaryProvider
22
import Libdl
33

4-
version = v"0.3.1"
4+
version = v"0.3.2"
55

66
if arch(platform_key_abi()) != :x86_64
77
@warn "FastTransforms has only been tested on x86_64 architectures."

src/FastTransforms.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import Base: unsafe_convert, eltype, ndims, adjoint, transpose, show, *, \,
1212
inv, size, view
1313

1414
import Base.GMP: Limb
15-
import Base.MPFR: BigFloat, _BigFloat
1615

1716
import AbstractFFTs: Plan, ScaledPlan,
1817
fft, ifft, bfft, fft!, ifft!, bfft!,

src/libfasttransforms.jl

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,21 @@ struct mpfr_t <: AbstractFloat
3232
d::Ptr{Limb}
3333
end
3434

35-
mpfr_t(x::BigFloat) = mpfr_t(x.prec, x.sign, x.exp, x.d)
35+
"""
36+
`BigFloat` is a mutable struct and there is no guarantee that each entry in
37+
an `Array{BigFloat}` has unique pointers. For example, looking at the `Limb`s,
38+
39+
Id = Matrix{BigFloat}(I, 3, 3)
40+
map(x->x.d, Id)
3641
37-
function BigFloat(x::mpfr_t)
38-
nb = ccall((:mpfr_custom_get_size,:libmpfr), Csize_t, (Clong,), precision(BigFloat))
39-
nb = (nb + Core.sizeof(Limb) - 1) ÷ Core.sizeof(Limb) # align to number of Limb allocations required for this
40-
str = unsafe_string(Ptr{UInt8}(x.d), nb * Core.sizeof(Limb))
41-
_BigFloat(x.prec, x.sign, x.exp, str)
42+
shows that the ones and the zeros all share the same pointers. If a C function
43+
assumes unicity of each datum, then the array must be renewed with a `deepcopy`.
44+
"""
45+
function renew!(x::Array{BigFloat})
46+
for i in eachindex(x)
47+
@inbounds x[i] = deepcopy(x[i])
48+
end
49+
return x
4250
end
4351

4452
set_num_threads(n::Integer) = ccall((:ft_set_num_threads, libfasttransforms), Cvoid, (Cint, ), n)
@@ -602,31 +610,22 @@ for (fJ, fC, elty) in ((:lmul!, :ft_bfmvf, :Float32),
602610
end
603611
end
604612

605-
for (fJ, fC) in ((:lmul!, :ft_mpfr_trmv),
606-
(:ldiv!, :ft_mpfr_trsv))
613+
for (fJ, fC) in ((:lmul!, :ft_mpfr_trmv_ptr),
614+
(:ldiv!, :ft_mpfr_trsv_ptr))
607615
@eval begin
608616
function $fJ(p::FTPlan{BigFloat, 1}, x::Vector{BigFloat})
609617
checksize(p, x)
610-
xt = deepcopy.(x)
611-
xc = mpfr_t.(xt)
612-
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{mpfr_t}, Int32), 'N', p.n, p, p.n, xc, Base.MPFR.ROUNDING_MODE[])
613-
x .= BigFloat.(xc)
618+
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{BigFloat}, Int32), 'N', p.n, p, p.n, renew!(x), Base.MPFR.ROUNDING_MODE[])
614619
return x
615620
end
616621
function $fJ(p::AdjointFTPlan{BigFloat, FTPlan{BigFloat, 1, K}}, x::Vector{BigFloat}) where K
617622
checksize(p, x)
618-
xt = deepcopy.(x)
619-
xc = mpfr_t.(xt)
620-
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{mpfr_t}, Int32), 'T', p.parent.n, p, p.parent.n, xc, Base.MPFR.ROUNDING_MODE[])
621-
x .= BigFloat.(xc)
623+
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{BigFloat}, Int32), 'T', p.parent.n, p, p.parent.n, renew!(x), Base.MPFR.ROUNDING_MODE[])
622624
return x
623625
end
624626
function $fJ(p::TransposeFTPlan{BigFloat, FTPlan{BigFloat, 1, K}}, x::Vector{BigFloat}) where K
625627
checksize(p, x)
626-
xt = deepcopy.(x)
627-
xc = mpfr_t.(xt)
628-
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{mpfr_t}, Int32), 'T', p.parent.n, p, p.parent.n, xc, Base.MPFR.ROUNDING_MODE[])
629-
x .= BigFloat.(xc)
628+
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{BigFloat}, Int32), 'T', p.parent.n, p, p.parent.n, renew!(x), Base.MPFR.ROUNDING_MODE[])
630629
return x
631630
end
632631
end
@@ -655,31 +654,22 @@ for (fJ, fC, elty) in ((:lmul!, :ft_bfmmf, :Float32),
655654
end
656655
end
657656

658-
for (fJ, fC) in ((:lmul!, :ft_mpfr_trmm),
659-
(:ldiv!, :ft_mpfr_trsm))
657+
for (fJ, fC) in ((:lmul!, :ft_mpfr_trmm_ptr),
658+
(:ldiv!, :ft_mpfr_trsm_ptr))
660659
@eval begin
661660
function $fJ(p::FTPlan{BigFloat, 1}, x::Matrix{BigFloat})
662661
checksize(p, x)
663-
xt = deepcopy.(x)
664-
xc = mpfr_t.(xt)
665-
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{mpfr_t}, Cint, Cint, Int32), 'N', p.n, p, p.n, xc, size(x, 1), size(x, 2), Base.MPFR.ROUNDING_MODE[])
666-
x .= BigFloat.(xc)
662+
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{BigFloat}, Cint, Cint, Int32), 'N', p.n, p, p.n, renew!(x), size(x, 1), size(x, 2), Base.MPFR.ROUNDING_MODE[])
667663
return x
668664
end
669665
function $fJ(p::AdjointFTPlan{BigFloat, FTPlan{BigFloat, 1, K}}, x::Matrix{BigFloat}) where K
670666
checksize(p, x)
671-
xt = deepcopy.(x)
672-
xc = mpfr_t.(xt)
673-
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{mpfr_t}, Cint, Cint, Int32), 'T', p.parent.n, p, p.parent.n, xc, size(x, 1), size(x, 2), Base.MPFR.ROUNDING_MODE[])
674-
x .= BigFloat.(xc)
667+
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{BigFloat}, Cint, Cint, Int32), 'T', p.parent.n, p, p.parent.n, renew!(x), size(x, 1), size(x, 2), Base.MPFR.ROUNDING_MODE[])
675668
return x
676669
end
677670
function $fJ(p::TransposeFTPlan{BigFloat, FTPlan{BigFloat, 1, K}}, x::Matrix{BigFloat}) where K
678671
checksize(p, x)
679-
xt = deepcopy.(x)
680-
xc = mpfr_t.(xt)
681-
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{mpfr_t}, Cint, Cint, Int32), 'T', p.parent.n, p, p.parent.n, xc, size(x, 1), size(x, 2), Base.MPFR.ROUNDING_MODE[])
682-
x .= BigFloat.(xc)
672+
ccall(($(string(fC)), libfasttransforms), Cvoid, (Cint, Cint, Ptr{mpfr_t}, Cint, Ptr{BigFloat}, Cint, Cint, Int32), 'T', p.parent.n, p, p.parent.n, renew!(x), size(x, 1), size(x, 2), Base.MPFR.ROUNDING_MODE[])
683673
return x
684674
end
685675
end

test/libfasttransformstests.jl

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ FastTransforms.set_num_threads(ceil(Int, Base.Sys.CPU_THREADS/2))
2424
end
2525

2626
α, β, γ, δ, λ, μ = 0.1, 0.2, 0.3, 0.4, 0.5, 0.6
27-
function test_1d_plans(p1, p2, x; skip::Bool=false)
27+
function test_1d_plans(p1, p2, x)
2828
y = p1*x
2929
z = p2*y
3030
@test z x
@@ -44,51 +44,37 @@ FastTransforms.set_num_threads(ceil(Int, Base.Sys.CPU_THREADS/2))
4444
@test z x
4545
P = p1*I
4646
Q = p2*P
47-
skip ? (@test_skip Q I) : (@test Q I)
47+
@test Q I
4848
P = p1*I
4949
Q = p1'P
5050
P = transpose(p1)*Q
5151
Q = transpose(p1)\P
5252
P = p1'\Q
5353
Q = p1\P
54-
skip ? (@test_skip Q I) : (@test Q I)
54+
@test Q I
5555
P = p2*I
5656
Q = p2'P
5757
P = transpose(p2)*Q
5858
Q = transpose(p2)\P
5959
P = p2'\Q
6060
Q = p2\P
61-
skip ? (@test_skip Q I) : (@test Q I)
61+
@test Q I
6262
end
6363

64-
for T in (Float32, Float64, Complex{Float32}, Complex{Float64})
64+
for T in (Float32, Float64, Complex{Float32}, Complex{Float64}, BigFloat, Complex{BigFloat})
6565
x = T(1)./(1:n)
6666
Id = Matrix{T}(I, n, n)
6767
for (p1, p2) in ((plan_leg2cheb(Id), plan_cheb2leg(Id)),
68-
(plan_ultra2ultra(Id, λ, μ), plan_ultra2ultra(Id, μ, λ)),
69-
(plan_jac2jac(Id, α, β, γ, δ), plan_jac2jac(Id, γ, δ, α, β)),
70-
(plan_lag2lag(Id, α, β), plan_lag2lag(Id, β, α)),
71-
(plan_jac2ultra(Id, α, β, λ), plan_ultra2jac(Id, λ, α, β)),
72-
(plan_jac2cheb(Id, α, β), plan_cheb2jac(Id, α, β)),
73-
(plan_ultra2cheb(Id, λ), plan_cheb2ultra(Id, λ)))
68+
(plan_ultra2ultra(Id, λ, μ), plan_ultra2ultra(Id, μ, λ)),
69+
(plan_jac2jac(Id, α, β, γ, δ), plan_jac2jac(Id, γ, δ, α, β)),
70+
(plan_lag2lag(Id, α, β), plan_lag2lag(Id, β, α)),
71+
(plan_jac2ultra(Id, α, β, λ), plan_ultra2jac(Id, λ, α, β)),
72+
(plan_jac2cheb(Id, α, β), plan_cheb2jac(Id, α, β)),
73+
(plan_ultra2cheb(Id, λ), plan_cheb2ultra(Id, λ)))
7474
test_1d_plans(p1, p2, x)
7575
end
7676
end
7777

78-
for T in (BigFloat, Complex{BigFloat})
79-
x = T(1)./(1:n)
80-
Id = Matrix{T}(I, n, n)
81-
for (p1, p2) in ((plan_leg2cheb(Id), plan_cheb2leg(Id)),
82-
(plan_ultra2ultra(Id, λ, μ), plan_ultra2ultra(Id, μ, λ)),
83-
(plan_jac2jac(Id, α, β, γ, δ), plan_jac2jac(Id, γ, δ, α, β)),
84-
(plan_lag2lag(Id, α, β), plan_lag2lag(Id, β, α)),
85-
(plan_jac2ultra(Id, α, β, λ), plan_ultra2jac(Id, λ, α, β)),
86-
(plan_jac2cheb(Id, α, β), plan_cheb2jac(Id, α, β)),
87-
(plan_ultra2cheb(Id, λ), plan_cheb2ultra(Id, λ)))
88-
test_1d_plans(p1, p2, x; skip=true)
89-
end
90-
end
91-
9278
function test_nd_plans(p, ps, pa, A)
9379
B = copy(A)
9480
C = ps*(p*A)

0 commit comments

Comments
 (0)