-
Notifications
You must be signed in to change notification settings - Fork 26.3k
sparse tensor operations #735
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
Conversation
25ead1d to
8b65c9d
Compare
torch/nn/parameter.py
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/csrc/autograd/variable.cpp
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
0e957a9 to
08635d7
Compare
|
@pytorchbot add to whitelist |
6565285 to
165d7bf
Compare
06312ce to
ed2a0d8
Compare
|
I rebased this PR on top of the latest changes, polished a few things and added some tests. I think it is ready for review / merging, let me know what you think. |
|
There are a few changes compared to the original PR description:
|
apaszke
left a comment
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.
Overall looks good, but I have some questions and comments. The most important is that I don't understand why do we need separate sizes and dimension fields for indices and values.
I'll have to think if choosing the grad type dynamically, and disallowing changing it later won't be too limiting. I'm a bit afraid that it could cause some surprising errors with no easy workarounds.
.gitignore
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
test/test_nn.py
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/_utils.py
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/csrc/autograd/grad_buffer.cpp
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/csrc/autograd/variable.cpp
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/lib/THS/generic/THSTensor.c
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/lib/THS/generic/THSTensor.c
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/lib/THS/generic/THSTensor.c
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
|
Thanks @apaszke for the feedback! I will address your various comments. Regarding the difference between |
|
So sparse tensors now have |
|
That's exactly right. The sparse tensors we had previously were equivalent to |
torch/lib/THS/generic/THSTensor.c
Outdated
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
|
@apaszke the test |
|
I found the issue and it's because of this line. On CUDA |
torch/lib/THS/generic/THSTensor.c
Outdated
| THTensor *dst, THTensor *src1, real value, THTensor *src2, | ||
| long dim, long dstIdx, long src1Idx, long src2Idx) { | ||
| if (src1->nDimension > 1) { | ||
| THTensor_(select)(src1Buffer, src1, dim, src1Idx); |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
| THTensor *dstBuffer, THTensor *src1Buffer, THTensor *src2Buffer, | ||
| THTensor *dst, THTensor *src1, real value, THTensor *src2, | ||
| long dim, long dstIdx, long src1Idx, long src2Idx) { | ||
| if (src1->nDimension > 1) { |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torch/__init__.py
Outdated
| ################################################################################ | ||
|
|
||
| import torch.cuda | ||
| import torch.cuda.sparse |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
|
Phew, that was a big diff! Thanks! 🎉 |
|
Thanks for taking the time to review all this :) |
Rework reduction heuristics, add a large reduction benchmarking suite.
This pull request adds more support for sparse operations in Pytorch.
The original goals:
This request implements the following individual features to achieve those goals:
THSTensor:zero, elementwiseaddandmul, scalarmulanddivaddcmulmethod ofTHTensorcompatible with sparse operandsspmmmethod accessible from Python (I had to use the namedsmmsincesmmwas already taken. Maybe we should rename the currentsmmtossmmto follow the convention)sparse_maskmethod onTHTensor. This produces a sparse tensor from a dense tensor, by using a sparse tensor as a mask. A value is only present in the output sparse tensor if it also exists in the mask. See the changes toadagrad.pyfor an example of why this is needed.Variable's gradient toNoneby default (required updating a few tests). This is because there is no canonical zero gradient anymore (it could be dense or sparse, and if it is sparse we don't know how many dimensions are sparse)...and last but not least: N-dimensional values for sparse tensors. This one is a slightly bigger item. Basically for things like applying sparse updates to embedding matrices, only the first dimension (the one that corresponds to the word index) is sparse. The other dimension is always dense (only whole embedding vectors are updated). An elegant solution is to make the
valuestensor N-dimensional instead of 1-dimensional. For an embedding matrix, the sparse gradient will have avaluestensor of sizennz * embedding_sizeinstead of justnnz. I had to update a few existing functions to make that work, but otherwise the changes are actually not that big. Existing usecases with scalar values should all work as usual.