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

LogAbsDet #3959

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

LogAbsDet #3959

wants to merge 6 commits into from

Conversation

harpone
Copy link

@harpone harpone commented Jan 31, 2016

Travis CI corrections (Python 3.3 compatibility fixes; PEP8 fixes)

Second go at the LogAbsDet op. Has gradient, but no GPU code so far... if anyone wants to help/ point me to PyCuda/CUDA implementation of SVD, let me know!

This is very similar to numpy.linalg.slogdet, except that the sign of the determinant is omitted, so it just computes log(abs(det(M))) for a matrix M.

Note that M does not need to be positive semidefinite, since we're taking the absolute value (as happens in e.g. maximum likelihood estimation).

do the op for gh-150, the optimization isn't done.

(x,) = inputs
(z,) = outputs
s = numpy.linalg.svd(x, compute_uv=False)
log_abs_det = numpy.sum(numpy.log(numpy.abs(s)))
Copy link
Member

Choose a reason for hiding this comment

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

I didn't check the math. But this can be done by reusing current op. The svd op and the elemwise op. This will be better as the elemwise op will get optimized by Theano and will work on the GPU (for the elemwise).

Then the only think missing to make it work on the GPU would be to have an svn op on the GPU. There is one implementation here that won't request c code: http://scikit-cuda.readthedocs.org/en/latest/generated/skcuda.linalg.svd.html

Copy link
Member

Choose a reason for hiding this comment

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

In fact, I think it is a good idea to keep this as an op. It will lower memory usage during the gradient on the CPU and will provide a gradient (the currrent svd op don't have a grad implemented).

but an easy way to have this on the GPU would be to make an optimization that will convert this op to a graph that reuse the elemwise on the GPU and make an svd op. For the gradient, MatrixInverse will also need a GPU op to have this work on the GPU. But the first step, is to get this working!

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, I have no idea what the gradient of SVD would be :) grad of log abs det is very simple on the other hand, so maybe it's better to leave this out of the theano optimizations...

OK didn't know there's no GPU op for MatrixInverse... so step 1 would now be to get LogAbsDet work on GPU? Is it possible to use the skcuda.linalg.svd directly? (I have no idea how the make_thunk works...). So not sure if I should try to do the GPU SVD here directly or in the SVD op? Damn it's still a bit confusing :)

Copy link
Member

Choose a reason for hiding this comment

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

We didn't document much making new gpu op as we are in transition to a new gpu back-end...

For a first pass, you can make one GPU op that have its gradient on the CPU and use it directly. Then after, you can add an optimization that will convert the CPU op to the GPU op (I can help, it is very easy when you know how to do it).

To make a GPU op, I would use as an example the code of CuFFTOp in sandbox/cuda/fftconv.py. This use scikits.cuda for computation, so you can reuse it for the svd implementation.

Copy link
Author

Choose a reason for hiding this comment

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

OK thanks, I'll probably get that done some time soon (been a bit busy lately)!

@lamblin
Copy link
Member

lamblin commented Feb 4, 2016

Forcing new run of Travis after #3885 has been merged.

@twiecki
Copy link
Contributor

twiecki commented Mar 5, 2016

This might be a relevant PR for pymc3 too. Any way that the theano simplification would change a manual log(det()) to use this logdet directly?

raise

def grad(self, inputs, g_outputs):
gz, = g_outputs
Copy link
Contributor

Choose a reason for hiding this comment

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

The comma here can be hard to spot, why not use single-element list syntax instead?

[gz] = g_outputs

Copy link
Author

Choose a reason for hiding this comment

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

[gz] = g_outputs

yeah sounds good...

Copy link
Author

Choose a reason for hiding this comment

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

Any way that the theano simplification would change a manual log(det()) to use this logdet directly?

There may be some problems with that if positivity of det is not enforced... not sure how to handle that...

@superbobry
Copy link
Contributor

This looks great! Is it possible to automatically optimize log(det(...)) to logdet(...)?

s = numpy.linalg.svd(x, compute_uv=False)
log_abs_det = numpy.sum(numpy.log(numpy.abs(s)))
z[0] = numpy.asarray(log_abs_det, dtype=x.dtype)
except Exception:
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to be more specific about the exception type here?

Copy link
Author

Choose a reason for hiding this comment

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

Is it possible to be more specific about the exception type here?

hmm I guess one should look inside numpy.linalg.svd for similar clauses... or the tests??

Actually I'm pretty swamped with other stuff at the moment, so I'd appreciate if someone else finished this stuff :)

Copy link
Author

Choose a reason for hiding this comment

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

This looks great! Is it possible to automatically optimize log(det(...)) to logdet(...)?

see here

minor semantic fixes
@harpone
Copy link
Author

harpone commented Mar 5, 2016

Fixed the tests and did the minor change as suggested by @superbobry but Travis CI seems to be failing... don't know why and I have no time to check now

@abergeron abergeron closed this Mar 7, 2016
@abergeron abergeron reopened this Mar 7, 2016
@abergeron
Copy link
Member

There was some breakage in the travis setup. A the new run should go fine (assuming there are no problems in this PR).

@harpone
Copy link
Author

harpone commented Mar 12, 2016

@nouiz I think this is done now (except for the GPU version)

@lamblin
Copy link
Member

lamblin commented Mar 23, 2016

Now that the release is over, is there anything preventing this from being merged?

@nouiz
Copy link
Member

nouiz commented Mar 23, 2016

I have comments that haven't been done. Mostly, the author started a new jobs, so he have difficulty to find time to finish this.

@harpone
Copy link
Author

harpone commented Mar 24, 2016

It should be working now. I fixed the tests too 12 days ago. The only thing missing is the CUDA code, which is of course a major omission... prolly can't find time for that any time soon...

@springcoil
Copy link

Is it possible to get this merged in without the CUDA code, and seperate that to another PR?
Due to it's interest for PyMC3

@twiecki
Copy link
Contributor

twiecki commented Feb 16, 2017

@nouiz What would adding GPU support entail? Writing CUDA? Presumably SVD already exists for GPU.

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

Successfully merging this pull request may close these issues.

None yet

7 participants