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
Add Singular Value Decomposition to cupy #2481
Conversation
Please rebase the master |
I got
while
is OK. |
I rebased this branch. |
@toslunar Thanks for reporting the bug. It seems that this unexpected behavior arises from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Check my minor comments.
cupy/linalg/decomposition.py
Outdated
# Remark 4: Remark 2 is removed since cuda 8.0 (new!) | ||
n, m = a.shape | ||
if m >= n: | ||
x = a.astype(dtype, copy=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is copy required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact there is no need for adding copy = True
as argument since copy
in astype
is True
by default, but I just wanted to clarify a cupy from a
to x
always occurs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, does copy=False
work correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Through reading the following document, I noticed that in this case copy=False
works correctly.
https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.astype.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Through reading the document, in this case copy=False
seems to work correctly.
However, when I tried to use copy=False
, the result becomes unstable and tests failed... Do you know any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need to call ascontiguousarray
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I confirmed that it works well with a pair of copy=False
and ascontiguousarray
.
cupy/linalg/decomposition.py
Outdated
u_ptr, vt_ptr = 0, 0 # Use nullptr | ||
s = cupy.empty(mn, dtype=dtype) | ||
handle = device.get_cusolver_handle() | ||
devInfo = cupy.empty(1, dtype=numpy.int32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use snake case dev_info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
cupy/linalg/decomposition.py
Outdated
devInfo = cupy.empty(1, dtype=numpy.int32) | ||
if compute_uv: | ||
if full_matrices: | ||
jobu, jobvt = ord('A'), ord('A') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need to use two variables? They hold the same value in all cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not need to use two variables in this case, but I just wanted to clarify that jobu
and jobvt
are always the same.
if compute_uv:
job = ord('A') if full_matrices else ord('S')
else:
job = ord('N')
is also OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
@unittest.skipUnless( | ||
cuda.cusolver_enabled, 'Only cusolver in CUDA 8.0 is supported') | ||
@testing.gpu | ||
class TestSVD(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test case for invalid arguments for _assert_rank2
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
a_gpu = cupy.asarray(array, dtype=dtype) | ||
result_cpu = numpy.linalg.svd(a_cpu, full_matrices=self.full_matrices) | ||
result_gpu = cupy.linalg.svd(a_gpu, full_matrices=self.full_matrices) | ||
for b_cpu, b_gpu in zip(result_cpu, result_gpu): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use six.moves.zip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check self.assertEqual(len(result_cpu), len(result_gpu))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
result_gpu = cupy.linalg.svd(a_gpu, full_matrices=self.full_matrices) | ||
for b_cpu, b_gpu in zip(result_cpu, result_gpu): | ||
# Use abs to support an inverse vector | ||
cupy.testing.assert_allclose( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to fix numpy_cupy_allclose
to support tuples?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In near future, yes, but currently it is better to manually check the tuples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
@unnonouno I fixed all the points you have mentioned. Could you check them? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote comments. If it is difficult to fix it, please add TODO comment about the phenomena, and then i'll merge it.
I fixed the problem of |
OK, LGTM! |
Merge after #2412.
This PR aims to add the Singular Value Decomposition (SVD) to cupy.
Note: this PR is based on #1402.