-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Small incompatibility between C/Cuda maskedFill / maskedSelect #231
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
Comments
The underlying problem seems to be that torch comparison operations return different types of tensors depending on whether a result tensor is provided or not: b = torch.rand(5)
a = b:lt(0.5)
print(a:type()) -- torch.ByteTensor
a = torch.Tensor()
a:lt(b, 0.5) -- must be a torch.Tensor This seems to be a deliberate decision (https://github.com/torch/torch7/blob/master/TensorMath.lua#L771), although I don't know why. |
This decision precedes me. If I had to guess, it is because a mask is best stored in a ByteTensor than a larger tensor (memory efficiency). We do need to extend the cuda side (soon) to have more tensor types (at the very least, even if the tensor types dont have all the math implemented). |
But why does torch return a ByteTensor when no result tensor is provided, On Wed, 20 May 2015, 08:39 Soumith Chintala notifications@github.com
|
@dominikgrewe It's down to the way that function dispatch is done by torch. It finds the correct C function to call by inspecting the metatable of the first argument. For example, there is a C function implementing
The code that does all this is autogenerated during the build with cwrap. This chunk is used to generate the function that decides how to dispatch the The underlying C functions that take a ByteTensor or the correctly typed functions both exist, so we just need to work out what is the correct one to call for any particular lua function call. By jiggling cwrap it should be possible to make The real underlying root of the problem is that while the macro based templating mechanism makes it easy to be generic across one Tensor type, it is hard to be generic across two types. The only function that works across types is |
@fmassa There is a way round: local t = torch.rand(4)
local mask_byte = torch.ByteTensor(4)
local mask_double = torch.Tensor(4)
-- Both of these work:
torch.Tensor.lt(mask_byte, t, 0.5)
torch.Tensor.lt(mask_double, t, 0.5) |
@timharley Thanks for the example. t = torch.rand(5):float()
mask_byte = torch.ByteTensor()
-- using torch.Tensor.lt doesn't work because
--we are accessing the lt function of the default (double) type
torch.FloatTensor.lt(mask_byte,t,0.5) Futhermore, this solution doesn't work for I was aware of those problems of the comparison operator when I posted this issue, that's the main reason why I was proposing changing the behaviour of But again, I don't know if that's the best solution for this problem. |
I almost posted this on torch/cutorch#70, but I think it should be addressed here.
There is a small incompatibility between C and CUDA versions of
maskedFill
andmaskedSelect
.In the C version, the
mask
needs to be aByteTensor
, whereas CUDA version accepts bothByteTensor
andCudaTensor
.This is probably motivated by the fact that the comparison operations in CUDA returns
CudaTensor
s, while their C counterparts returnsByteTensor
sBy itself, that's not a big deal, but on C side, one needs two buffers when using comparison operations in order to use
maskedFill
ormaskedSelect
, one for the comparison operator (which is of typeTensor
if one reuses a tensor for the output), and oneByteTensor
for the masking.An example is maybe clearer:
With that in mind, wouldn't it be better to adapt the C version of
maskedFill
andmaskedSelect
to also accept the current sourceTensor
type for themask
, as in its CUDA version ? Or maybe we should accept the output of the comparison operators to also beTensor
instead of onlyByteTensor
? Or both ?The text was updated successfully, but these errors were encountered: