Change:
This causes to not work properly on newly created empty sparse tensors. In the example below, both should print 1 instead.

Discussion:
v = self.ValueTensor([5]).cuda(0) self.assertRaises(RuntimeError, lambda: self.SparseTensor(i, v, torch.Size([3]))) <ins> def _test_new_device(self, size, device): with torch.cuda.device(device): x = torch.cuda.sparse.DoubleTensor(*size) self.assertEqual(x.get_device(), device) x1 = x.new() x2 = x.new(2, 3) self.assertEqual(x1.get_device(), device) self.assertEqual(x2.get_device(), device) </ins> @cuda_only <del> @unittest.skipIf(torch.cuda.device_count() < 2, "only one GPU detected") def test_new_device(self): with torch.cuda.device(1): x = torch.cuda.sparse.DoubleTensor(30, 2) self.assertEqual(x.get_device(), 1) </del> <ins> def test_new_device_single_gpu(self): self._test_new_device((), 0) self._test_new_device((30, 20), 0) self._test_new_device((30, 20, 10), 0) </ins> <del> y = x.new(2, 3) self.assertEqual(y.get_device(), 1) </del> <ins> @cuda_only @unittest.skipIf(torch.cuda.device_count() < 2, "only one GPU detected") def test_new_device_multi_gpu(self): self._test_new_device((), 1) self._test_new_device((30, 20), 1) self._test_new_device((30, 20, 10), 1) </ins> class TestUncoalescedSparse(TestSparse):

PyObject *THSPTensorClass = NULL; <del> static void THSPTensor_(initStorage)(THSTensor* tensor) </del> <ins> static void THSTensor_(initStorage)(THSTensor* tensor) </ins> { // Ensure that PyTorch's "storage is not NULL" invariant is upheld. // See Note [Storage is not NULL]

} } <del> PyObject * THSPTensor_(NewEmpty)() { auto r = THSTensor_(new)(LIBRARY_STATE_NOARGS); THSPTensor_(initStorage)(r); return THSPTensor_(New)(r); } </del> PyObject * THSPTensor_(New)(THSTensor *tensor) { THSTensorPtr ptr(tensor);

return obj; } <ins> PyObject * THSPTensor_(NewEmpty)() { THSTensorPtr tensor(THSTensor_(new)(LIBRARY_STATE_NOARGS)); THSTensor_(initStorage)(tensor.get()); return THSPTensor_(New)(tensor.release()); } </ins> static void THSPTensor_(dealloc)(THSPTensor* self) { if (self->cdata)

// torch.SparseTensor() if (num_args == 0) { self->cdata = THSTensor_(new)(LIBRARY_STATE_NOARGS); <del> return (PyObject*)self.release(); } PyObject *first_arg = PyTuple_GET_ITEM(args, 0); </del> <ins> } else { PyObject *first_arg = PyTuple_GET_ITEM(args, 0); </ins> <del> // torch.SparseTensor(size) if (num_args == 1 && THPUtils_checkLong(first_arg)) { long size = THPUtils_unpackLong(first_arg); self->cdata = THSTensor_(newWithSize1d)(LIBRARY_STATE size); } // torch.SparseTensor(torch.Size sizes) else if (num_args == 1 && THPSize_Check(first_arg)) { THLongStoragePtr sizes(THPUtils_unpackSize(first_arg)); self->cdata = THSTensor_(newWithSize)(LIBRARY_STATE sizes.get()); } // torch.SparseTensor(torch.LongTensor indices, torch.LongTensor values) else if (num_args == 2 && THPIndexTensor_Check(first_arg)) { PyObject *second_arg = PyTuple_GET_ITEM(args, 1); if (!THPTensor_(Check)(second_arg)) goto invalid_arguments; </del> <ins> // torch.SparseTensor(size) if (num_args == 1 && THPUtils_checkLong(first_arg)) { long size = THPUtils_unpackLong(first_arg); self->cdata = THSTensor_(newWithSize1d)(LIBRARY_STATE size); } // torch.SparseTensor(torch.Size sizes) else if (num_args == 1 && THPSize_Check(first_arg)) { THLongStoragePtr sizes(THPUtils_unpackSize(first_arg)); self->cdata = THSTensor_(newWithSize)(LIBRARY_STATE sizes.get()); } // torch.SparseTensor(torch.LongTensor indices, torch.LongTensor values) else if (num_args == 2 && THPIndexTensor_Check(first_arg)) { PyObject *second_arg = PyTuple_GET_ITEM(args, 1); if (!THPTensor_(Check)(second_arg)) goto invalid_arguments; </ins> <del> THIndexTensor *indices = ((THPIndexTensor*)first_arg)->cdata; THTensor *values = ((THPTensor*)second_arg)->cdata; </del> <ins> THIndexTensor *indices = ((THPIndexTensor*)first_arg)->cdata; THTensor *values = ((THPTensor*)second_arg)->cdata; </ins> #ifdef THC_GENERIC_FILE <del> THCAssertSameGPU(THSTensor_(checkGPU)(LIBRARY_STATE 0, 2, indices, values)); </del> <ins> THCAssertSameGPU(THSTensor_(checkGPU)(LIBRARY_STATE 0, 2, indices, values)); </ins> #endif <del> self->cdata = THSTensor_(newWithTensor)(LIBRARY_STATE indices, values); } // torch.SparseTensor(torch.LongTensor indices, //                    torch.Tensor values, //                    torch.Size sizes) else if (num_args > 2 && THPIndexTensor_Check(first_arg)) { PyObject *second_arg = PyTuple_GET_ITEM(args, 1); PyObject *third_arg = PyTuple_GET_ITEM(args, 2); if (!THPTensor_(Check)(second_arg)) goto invalid_arguments; if (!THPSize_Check(third_arg)) goto invalid_arguments; </del> <ins> self->cdata = THSTensor_(newWithTensor)(LIBRARY_STATE indices, values); } // torch.SparseTensor(torch.LongTensor indices, //                    torch.Tensor values, //                    torch.Size sizes) else if (num_args > 2 && THPIndexTensor_Check(first_arg)) { PyObject *second_arg = PyTuple_GET_ITEM(args, 1); PyObject *third_arg = PyTuple_GET_ITEM(args, 2); if (!THPTensor_(Check)(second_arg)) goto invalid_arguments; if (!THPSize_Check(third_arg)) goto invalid_arguments; </ins> <del> THIndexTensor *indices = ((THPIndexTensor*)first_arg)->cdata; THTensor *values = ((THPTensor*)second_arg)->cdata; THLongStoragePtr sizes(THPUtils_unpackSize(third_arg)); </del> <ins> THIndexTensor *indices = ((THPIndexTensor*)first_arg)->cdata; THTensor *values = ((THPTensor*)second_arg)->cdata; THLongStoragePtr sizes(THPUtils_unpackSize(third_arg)); </ins> #ifdef THC_GENERIC_FILE <del> THCAssertSameGPU(THSTensor_(checkGPU)(LIBRARY_STATE 0, 2, indices, values)); </del> <ins> THCAssertSameGPU(THSTensor_(checkGPU)(LIBRARY_STATE 0, 2, indices, values)); </ins> #endif <del> self->cdata = THSTensor_(newWithTensorAndSize)( LIBRARY_STATE indices, values, sizes); } // torch.SparseTensor(int ...) else if (THPUtils_tryUnpackLongVarArgs(args, 0, sizes)) { self->cdata = THSTensor_(newWithSize)(LIBRARY_STATE sizes.get()); </del> <ins> self->cdata = THSTensor_(newWithTensorAndSize)( LIBRARY_STATE indices, values, sizes); } // torch.SparseTensor(int ...) else if (THPUtils_tryUnpackLongVarArgs(args, 0, sizes)) { self->cdata = THSTensor_(newWithSize)(LIBRARY_STATE sizes.get()); } else goto invalid_arguments; // All other cases </ins> } <del> else goto invalid_arguments; // All other cases THSPTensor_(initStorage)(self->cdata); </del> <ins> THSTensor_(initStorage)(self->cdata); </ins> return (PyObject*)self.release(); invalid_arguments: