-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new DFT api #12087
new DFT api #12087
Conversation
(Note that the patch is large, but most of this is due merely to rearranging the FFT stuff into an |
Also, it was convenient to have |
I'll definitely prefer this than #11994. Is there a summary of the API changes and should this be accompanied by the document update? (I only see very small update in Without reading through the code and the discussion in the old PR (#6193), I'd like to know if this contain an interface that I found the most useful with my simulation. Is there a way to do Edit:
I guess this is what I want? |
@yuyichao, I believe that I documented all of the user-visible API changes. There weren't many. I didn't provide an |
Ah. for some reason, I thought the second paragraph in
That's good enough. I don't really care about function names. Thanks! |
Hmm, this seems to break socket.jl:35 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:41.
Warning: Method definition call(Type{Base.IPv6}, AbstractString) in module Base at socket.jl:78 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:42.
Warning: Method definition isless(#T<:Base.IPAddr, #T<:Base.IPAddr) in module Base at socket.jl:6 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:47.
Warning: Method definition call(Type{Base.Dict}, Any) in module Base at dict.jl:430 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:59.
ERROR: LoadError: LoadError: LoadError: LoadError: TypeError: apply_type: in Type, expected Type{T}, got Tuple{TypeVar,TypeVar}
in include at ./boot.jl:254
in include_from_node1 at ./loading.jl:133
in reload_path at ./loading.jl:157
in _require at ./loading.jl:69
in require at ./loading.jl:55
in include at ./boot.jl:254
in include_from_node1 at ./loading.jl:133
in reload_path at ./loading.jl:157
in _require at ./loading.jl:69
in require at ./loading.jl:55
in include at ./boot.jl:254
in include_from_node1 at ./loading.jl:133
in reload_path at ./loading.jl:157
in _require at ./loading.jl:69
in require at ./loading.jl:52
in include at ./boot.jl:254
in include_from_node1 at ./loading.jl:133
in process_options at ./client.jl:306
in _start at ./client.jl:406
while loading /usr/share/julia/site/v0.4/Compat/src/Compat.jl, in expression starting on line 60
while loading /usr/share/julia/site/v0.4/PyCall/src/PyCall.jl, in expression starting on line 25
while loading /usr/share/julia/site/v0.4/PyPlot/src/PyPlot.jl, in expression starting on line 3
while loading /home/yuyichao/projects/nacs-lab/yyc-data/calculations/single-atom/ode-test5.jl, in expression starting on line 5 |
Actually it breaks Warning: Method definition call(Type{Base.IPv4}, AbstractString) in module Base at socket.jl:35 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:41.
Warning: Method definition call(Type{Base.IPv6}, AbstractString) in module Base at socket.jl:78 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:42.
Warning: Method definition isless(#T<:Base.IPAddr, #T<:Base.IPAddr) in module Base at socket.jl:6 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:47.
Warning: Method definition call(Type{Base.Dict}, Any) in module Base at dict.jl:430 overwritten in module Compat at /usr/share/julia/site/v0.4/Compat/src/Compat.jl:59.
ERROR: LoadError: TypeError: apply_type: in Type, expected Type{T}, got Tuple{TypeVar,TypeVar}
in include at ./boot.jl:254
in include_from_node1 at ./loading.jl:133
in reload_path at ./loading.jl:157
in _require at ./loading.jl:69
in require at ./loading.jl:52
while loading /usr/share/julia/site/v0.4/Compat/src/Compat.jl, in expression starting on line 60 |
It also breaks the old api |
It's also a little strange to use the |
@yuyichao, I can't reproduce the Compat problem: |
Right, I forgot that I changed the |
Other than the issues mentioned above, this branch yields the same performance with #11994. A summary of the issues I've seen:
|
Oh, yeah, and the keyword argument makes the compilation slower (~ |
I did a |
@stevengj The allocation seems to come from the type instability of (The allocation does not increase with this PR so I guess this issue isn't new). |
Relavant GenSym(2) = (top(tuple))((top(arraysize))(X::Array{Complex{Float64},1},1)::Int64)::Tuple{Int64}
GenSym(1) = (top(getfield))(p::Base.DFT.FFTW.cFFTWPlan{Complex{Float64},-1,true},:sz)::Tuple{Vararg{Int64}}
GenSym(3) = GenSym(2) == GenSym(1)::Bool and relavant define void @julia_assert_applicable_21150(%jl_value_t*, %jl_value_t*) {
top:
%const = bitcast i64 140728651486960 to i64
%2 = alloca [6 x %jl_value_t*], align 8
%.sub26 = bitcast [6 x %jl_value_t*]* %2 to %jl_value_t**
%3 = getelementptr [6 x %jl_value_t*]* %2, i64 0, i64 2
%4 = getelementptr [6 x %jl_value_t*]* %2, i64 0, i64 4
%5 = bitcast [6 x %jl_value_t*]* %2 to i64*
store i64 8, i64* %5, align 8
%6 = getelementptr [6 x %jl_value_t*]* %2, i64 0, i64 1
%7 = bitcast %jl_value_t** %6 to %jl_value_t***
%8 = load %jl_value_t*** @jl_pgcstack, align 8
store %jl_value_t** %8, %jl_value_t*** %7, align 8
store %jl_value_t** %.sub26, %jl_value_t*** @jl_pgcstack, align 8
store %jl_value_t* null, %jl_value_t** %3, align 8
%9 = getelementptr [6 x %jl_value_t*]* %2, i64 0, i64 3
store %jl_value_t* null, %jl_value_t** %9, align 8
store %jl_value_t* null, %jl_value_t** %4, align 8
%10 = getelementptr [6 x %jl_value_t*]* %2, i64 0, i64 5
store %jl_value_t* null, %jl_value_t** %10, align 8
%11 = getelementptr inbounds %jl_value_t* %1, i64 3, i32 0
%12 = bitcast %jl_value_t** %11 to i64*
%13 = load i64* %12, align 8
%14 = insertvalue [1 x i64] undef, i64 %13, 0
%15 = getelementptr inbounds %jl_value_t* %0, i64 1, i32 0
%16 = load %jl_value_t** %15, align 8
store %jl_value_t* %16, %jl_value_t** %3, align 8
%17 = call %jl_value_t* @jl_gc_allocobj(i64 8)
%18 = getelementptr inbounds %jl_value_t* %17, i64 -1, i32 0
%const_mat19 = add i64 %const, -1036320
%19 = inttoptr i64 %const_mat19 to %jl_value_t*
store %jl_value_t* %19, %jl_value_t** %18, align 8
%20 = bitcast %jl_value_t* %17 to [1 x i64]*
store [1 x i64] %14, [1 x i64]* %20, align 16
store %jl_value_t* %17, %jl_value_t** %4, align 8
store %jl_value_t* %16, %jl_value_t** %10, align 8
%const_mat24 = add i64 %const, 4382528
%21 = inttoptr i64 %const_mat24 to %jl_value_t*
%22 = call %jl_value_t* @jl_apply_generic(%jl_value_t* %21, %jl_value_t** %4, i32 2)
%23 = bitcast %jl_value_t* %22 to i8*
%24 = load i8* %23, align 1
%25 = and i8 %24, 1
%26 = icmp eq i8 %25, 0
br i1 %26, label %if, label %L
|
I don't quite see why Julia can't emit fast code for |
@yuyichao, I just pushed a modified patch that documents the change of |
The main problem with not deprecating the old |
Depending on what kind of input the plan accept, it might be necessary to have more than one parameters (or not). I think sth like this should be sufficient. |
I was going to implement it myself and then I hit #12089 |
BTW. why is the type assersion in the |
With this patch (and after reverting #11996 ) I can get the tests all pass and the allocation down by a lot. |
Given this (type stability) is blocked by other bug and it doesn't give a huge performance gain. I think it's not that necessary to include that in this PR.... |
@stevengj I pushed a rebased version with a fix of the type stability of |
The |
So the reason I think we can keep the old interface
The first one I guess I can get used to. The second one depends on how many public packages are using it (assuming other usage usually don't require compatibility for multiple julia versions). I just did a grep on all registered packages and the only direct user of the Other than this, I vote for rebase and merge this one (and I'll submit another PR on top of this to fix the left over type stability issues). |
@stevengj Does this sound like a reasonable plan? Seems good to me. |
@stevengj I'd like to merge this PR the coming weekend if there's no objection. (Note that since this is not in the julialang repo, I would need to open a new PR with the rebased commit to trigger CI builds) As for the breakage of packages, I had a look at the ApproxFun and it seems that the bigger issue there is that it is only expecting a |
With the |
I think this is conservative and good to do. |
Merged as #12201 |
Thanks! |
This is a rewritten DFT API that provides:
p = plan_fft(x)
(and similar) now returns a subtype ofBase.DFT.Plan
. It acts like a linear operator: you can apply it to an existing array withp * x
, and apply it to a preallocated output array withA_mul_B!(y, p, x)
. You can apply the inverse plan withp \ x
orinv(p) * x
.Unlike #6193, this patch contains only the API changes, not the pure-Julia FFT implementation (which can easily be added later). Like #11994, this should give a non-negligible performance improvement (by eliminating anonymous functions and allowing for pre-allocated output).
cc: @yuyichao, @ViralBShah.