mirror of
https://github.com/cdtools-developers/cdtools.git
synced 2026-09-21 01:42:09 +02:00
Add the ability for datasets to change what device they output to even if data remains stored on cpu
This commit is contained in:
+32
-1
@@ -107,6 +107,11 @@ class CDataset(torchdata.Dataset):
|
||||
else:
|
||||
self.mask = None
|
||||
|
||||
if t.cuda.is_available():
|
||||
self.get_as(device='cuda:0')
|
||||
else:
|
||||
self.get_as(device='cpu')
|
||||
|
||||
|
||||
def to(self,*args,**kwargs):
|
||||
# The mask should always stay a uint8, but it should switch devices
|
||||
@@ -119,7 +124,33 @@ class CDataset(torchdata.Dataset):
|
||||
if self.mask is not None:
|
||||
self.mask = self.mask.to(*args,**mask_kwargs)
|
||||
|
||||
|
||||
def get_as(self, *args, **kwargs):
|
||||
self.get_as_args = (args, kwargs)
|
||||
|
||||
|
||||
def __getitem__(self, index):
|
||||
# Deals with loading to appropriate device/dtype, if
|
||||
# specified via a call to get_as
|
||||
inputs, outputs = self._load(index)
|
||||
if hasattr(self, 'get_as_args'):
|
||||
outputs = outputs.to(*self.get_as_args[0],**self.get_as_args[1])
|
||||
moved_inputs = []
|
||||
for inp in inputs:
|
||||
try:
|
||||
moved_inputs.append(inp.to(*self.get_as_args[0],**self.get_as_args[1]) )
|
||||
except:
|
||||
moved_inputs.append(inp)
|
||||
else:
|
||||
moved_inputs = inputs
|
||||
return moved_inputs, outputs
|
||||
|
||||
|
||||
def _load(self, index):
|
||||
# Internal function to load data
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_cxi(cls, cxi_file):
|
||||
entry_info = cdtdata.get_entry_info(cxi_file)
|
||||
@@ -177,7 +208,7 @@ class Ptycho_2D_Dataset(CDataset):
|
||||
def __len__(self):
|
||||
return self.patterns.shape[0]
|
||||
|
||||
def __getitem__(self, index):
|
||||
def _load(self, index):
|
||||
return (index, self.translations[index]), self.patterns[index]
|
||||
|
||||
|
||||
|
||||
+24
-1
@@ -27,6 +27,7 @@ def test_CDataset_init():
|
||||
mask = np.ones((256,256))
|
||||
dataset = CDataset(entry_info, sample_info,
|
||||
wavelength, detector_geometry, mask)
|
||||
|
||||
assert t.all(t.eq(dataset.mask,t.tensor(mask)))
|
||||
assert dataset.entry_info == entry_info
|
||||
assert dataset.sample_info == sample_info
|
||||
@@ -231,13 +232,35 @@ def test_Ptycho_2D_Dataset_to(ptycho_cxi_1):
|
||||
assert dataset.patterns.device == t.device('cuda:0')
|
||||
assert dataset.translations.device == t.device('cuda:0')
|
||||
|
||||
|
||||
|
||||
|
||||
def test_Ptycho_2D_Dataset_ops(ptycho_cxi_1):
|
||||
cxi, expected = ptycho_cxi_1
|
||||
dataset = Ptycho_2D_Dataset.from_cxi(cxi)
|
||||
dataset.get_as('cpu')
|
||||
|
||||
assert len(dataset) == expected['data'].shape[0]
|
||||
(idx, translation), pattern = dataset[3]
|
||||
assert idx == 3
|
||||
assert t.allclose(translation, t.tensor(expected['translations'][3,:]))
|
||||
assert t.allclose(pattern, t.tensor(expected['data'][3,:,:]))
|
||||
|
||||
|
||||
def test_Ptycho_2D_Dataset_get_as(ptycho_cxi_1):
|
||||
cxi, expected = ptycho_cxi_1
|
||||
dataset = Ptycho_2D_Dataset.from_cxi(cxi)
|
||||
if t.cuda.is_available():
|
||||
dataset.get_as('cuda:0')
|
||||
assert len(dataset) == expected['data'].shape[0]
|
||||
|
||||
(idx, translation), pattern = dataset[3]
|
||||
assert str(translation.device) == 'cuda:0'
|
||||
assert str(pattern.device) == 'cuda:0'
|
||||
|
||||
assert idx == 3
|
||||
assert t.allclose(translation.to(device='cpu'),
|
||||
t.tensor(expected['translations'][3,:]))
|
||||
assert t.allclose(pattern.to(device='cpu'),
|
||||
t.tensor(expected['data'][3,:,:]))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user