Skip to content
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

gamma, lgamma, digamma work with GPU #294

Merged
merged 13 commits into from Apr 1, 2019

Conversation

xukai92
Copy link
Contributor

@xukai92 xukai92 commented Mar 31, 2018

Related issues:
#290
#292

Related PR:
#291

deps/cuda1.jl Outdated Show resolved Hide resolved
@CarloLucibello
Copy link
Collaborator

CarloLucibello commented Apr 1, 2018

in order to pass tests, we should:

  • add a REQUIRE file in the test directory containing the single line SpecialFunctions. Even better, I'd like SpecialFunctions to be a proper dependence of the package, if @denizyuret agrees. It is a lean and well mantained package.
  • define the derivative of trigamma(x) as poligamma(2,x) or just avoid testing testing its grad in test/unary.jl

.

@xukai92
Copy link
Contributor Author

xukai92 commented Apr 3, 2018

How should I "define the derivative of trigamma(x) as poligamma(2,x)" in Knet.jl? I think that's in AutoGrad.jl isn't it?

@CarloLucibello
Copy link
Collaborator

CarloLucibello commented Apr 3, 2018

hmhm, looks like trigamma derivative is already defined in autograd, but polygamma(2,x) has to be defined for KnetArray. So maybe add something along the line of (just a guess):

    J=broadcast_func("polygamma")
    for S in (32,64)
        T = Symbol("Float$S")
        F = "polygamma_impl_$S"
        @eval begin
            function $J(n::Int, x::KnetArray{$T})
                y = similar(x)
                @knet8($F,(Cint, Cint,Ptr{$T},Ptr{$T}), n, length(y), x, y)
                return y
            end
        end
    end

@denizyuret
Copy link
Owner

denizyuret commented Apr 3, 2018 via email

@CarloLucibello
Copy link
Collaborator

CarloLucibello commented Apr 3, 2018

@xukai92 if you don't need trigamma's derivative for KnetArray, the easiest way out (once you fix the problem with importing SpecialFunctions) is to just skip the test in test/unary.jl

@testset "unary" begin
    broken_grads = [trigamma] 
    for f in unary_fns
        f in broken_grads && continue
        ....

@xukai92
Copy link
Contributor Author

xukai92 commented Sep 2, 2018

@CarloLucibello Just come back to work on this PR. I merged with master and it seems everything passes (even I didn't exclude the test as suggested by you long time ago).

@CarloLucibello
Copy link
Collaborator

I tried this pr locally and it works fine for gamma, lgamma, digamma and also trigamma's derivatives for KnetArrays. We should merge this.

@denizyuret
Copy link
Owner

I get these errors when I include("test/unary.jl"), is this expected? Some seem to be gradcheck errors, some isapprox errors comparing with cpu for digamma and trigamma.

@xukai92
Copy link
Contributor Author

xukai92 commented Sep 2, 2018

I didn't get errors when I run the complete test on my local. Looking at you gist, it seems that some outputs seem to correct but still reported? E.g.

(f, t, n) = (SpecialFunctions.digamma, Float64, (2, 1))
unary: Test Failed at /home/ec2-user/.julia/dev/Knet/test/unary.jl:39
  Expression: isapprox(cy, Array(gy))
   Evaluated: isapprox([-1.8009; -1.25649], [-1.8009; -1.25649])
Stacktrace:
 [1] macro expansion at /home/ec2-user/.julia/dev/Knet/test/unary.jl:36 [inlined]
 [2] macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:1083 [inlined]
 [3] top-level scope at /home/ec2-user/.julia/dev/Knet/test/unary.jl:6

PS: I'm not very familiar with Knet's test scripts.

@denizyuret
Copy link
Owner

denizyuret commented Sep 2, 2018 via email

@xukai92
Copy link
Contributor Author

xukai92 commented Sep 2, 2018

Oh yes - I also have these errors. We should I do?

@xukai92
Copy link
Contributor Author

xukai92 commented Sep 2, 2018

Should I set separate rtol for these functions or something?

@denizyuret
Copy link
Owner

denizyuret commented Sep 2, 2018 via email

@denizyuret
Copy link
Owner

In particular Float32 gradients for digamma/trigamma do not work for me:

julia> f(x) = sum(digamma.(x))
f (generic function with 1 method)

julia> grad(f)(rand(Float32,1))
1-element Array{Float32,1}:
 6.1312017

julia> grad(f)(ka(rand(Float32,1)))
1-element KnetArray{Float32,1}:
 NaN

julia> grad(f)(ka(rand(Float64,1)))
1-element KnetArray{Float64,1}:
 2.3219245818432324

@xukai92
Copy link
Contributor Author

xukai92 commented Sep 11, 2018

Thanks for pointing this out. I found that I didn't implement the float and double version in two separate functions correctly. I know how to fix that in C but I don't know how to link them to the same Julia function in ops.jl.

Suppose I have gamma_impl_32 and gamma_impl_64 as the float and double versions in C, how should I link them to the gamma function in Julia?

@xukai92
Copy link
Contributor Author

xukai92 commented Sep 11, 2018

Seems that simply using the double version can handle both.

julia> f(x) = sum(digamma.(x))
f (generic function with 1 method)

julia> rs_32 = rand(Float32, 1)
1-element Array{Float32,1}:
 0.35235214

julia> grad(f)(rs_32)
1-element Array{Float32,1}:
 9.129284

julia> grad(f)(ka(rs_32))
1-element KnetArray{Float32,1}:
 9.129284

julia> rs_64 = rand(Float64, 1)
1-element Array{Float64,1}:
 0.6063909020012128

julia> grad(f)(rs_64)
1-element Array{Float64,1}:
 3.573492967407559

julia> grad(f)(ka(rs_64))
1-element KnetArray{Float64,1}:
 3.573492967407558

Is it OK to do so?

@xukai92
Copy link
Contributor Author

xukai92 commented Jan 4, 2019

@CarloLucibello Can we merge this?

@CarloLucibello
Copy link
Collaborator

Where is the code for the kernels coming from? We should credit the author and avoid issues with licenses.

Also, it's not clear what is happening here with the 32/64 issue. Is the kernel being executed at 64 bit precision also when using float 32 knet arrays? If so, we should fix this

@xukai92
Copy link
Contributor Author

xukai92 commented Jan 7, 2019

Where is the code for the kernels coming from? We should credit the author and avoid issues with licenses.

It's based on https://github.com/rachtsingh/lgamma, which is again ported from https://bitbucket.org/eigen/eigen/overview. How should I cite it?

Also, it's not clear what is happening here with the 32/64 issue. Is the kernel being executed at 64 bit precision also when using float 32 knet arrays? If so, we should fix this

Let me try to solve this

@@ -0,0 +1,242 @@
# Gamma family
# Acknowledgement:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CarloLucibello I added a comment to acknowledge the original files. Is it OK?

include("gamma.jl")
print(fp,cuda1gammafamily())

function cuda1src(f, j=f, ex="$f(xi)"; seperate_impl=false, BLK=256, THR=256)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@denizyuret I amended the cuda1src function to support functions which have different CUDA kernel implementation for float and double. Before the kernel is assumed to be same. Does it look good?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CarloLucibello This float v.s. double issues is solved by this.

@xukai92
Copy link
Contributor Author

xukai92 commented Mar 26, 2019

@CarloLucibello I resolved the comments we had before. Please see my notes on changes.

factorial *= (i + 1);
}

$T s = n % 2 == 0 ? -$one_str : $one_str;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for people who wonder why we had numerical errors before: this line was coded as s = powf(-1.0, n + 1) in the original code for float. This causes numerical errors somehow. I changed it to avoid using unnecessary power function to avoid this.

@xukai92
Copy link
Contributor Author

xukai92 commented Apr 1, 2019

@CarloLucibello Can you take a look at the my updates and see if it's good now? Thanks!

test/REQUIRE Outdated
@@ -0,0 +1 @@
SpecialFunctions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need this, since SpecialFunctions is already in the REQUIRE of the package

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

@CarloLucibello CarloLucibello merged commit 7a97d17 into denizyuret:master Apr 1, 2019
@CarloLucibello
Copy link
Collaborator

thanks for your patience and for the good work!

@xukai92
Copy link
Contributor Author

xukai92 commented Apr 1, 2019

Many thanks for your suggestions on improving codes in this PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants