Skip to content

Commit f0c7827

Browse files
committed
update
1 parent c6eeaa7 commit f0c7827

9 files changed

Lines changed: 61 additions & 30 deletions

File tree

src/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
build_dataloader,
2929
build_dataset,
3030
build_sampler,
31-
is_ram_cache_supported,
3231
validate_ram_cache_config,
3332
)
3433

src/dataloaders/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
build_dataloader,
88
build_dataset,
99
build_sampler,
10-
is_ram_cache_supported,
1110
validate_ram_cache_config,
1211
)
1312
from .tensor_cache import TensorCache

src/dataloaders/build.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,6 @@
2020
"""Registry for dataset classes."""
2121

2222

23-
def is_ram_cache_supported() -> bool:
24-
"""Check if RAM cache is supported on the current platform.
25-
26-
Returns:
27-
bool: True if RAM cache is supported (Linux only), False otherwise.
28-
"""
29-
return platform.system() == "Linux"
30-
31-
3223
def validate_ram_cache_config(use_ram_cache: bool, verbose: bool = True) -> bool:
3324
"""Validate RAM cache configuration for current platform.
3425
@@ -39,7 +30,7 @@ def validate_ram_cache_config(use_ram_cache: bool, verbose: bool = True) -> bool
3930
Returns:
4031
bool: True if RAM cache can be used, False otherwise.
4132
"""
42-
if use_ram_cache and not is_ram_cache_supported():
33+
if use_ram_cache and platform.system() != "Linux":
4334
if verbose:
4435
logger.warning(
4536
f"RAM cache is only supported on Linux. Current OS: {platform.system()}. "
@@ -161,7 +152,7 @@ def build_sampler(
161152
return sampler, batch_sampler
162153

163154

164-
def collate(batch: list[DatasetOutput]) -> dict[str, torch.Tensor]:
155+
def collate(batch: list[DatasetOutput]) -> DatasetOutput:
165156
"""Collate function for combining dataset outputs into batches.
166157
167158
Automatically handles stacking of tensors and conversion of numeric
@@ -183,4 +174,4 @@ def collate(batch: list[DatasetOutput]) -> dict[str, torch.Tensor]:
183174
output[k] = torch.stack(output[k], dim=0)
184175
elif isinstance(output[k][0], (int, float)):
185176
output[k] = torch.tensor(output[k])
186-
return output
177+
return DatasetOutput(**output)

src/dataloaders/dummy.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from dataclasses import dataclass
22

3-
import torch
43
from torchvision.transforms.v2 import Compose
54

65
from .base import BaseDataset
@@ -58,4 +57,4 @@ def __getitem__(self, idx: int) -> DatasetOutput:
5857
Returns:
5958
Synthetic data sample with ones tensor and modulo label.
6059
"""
61-
return DatasetOutput(data=torch.ones(8), label=idx % 4)
60+
return DatasetOutput.dummy()

src/dataloaders/types.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import NotRequired, TypedDict
22

3+
import torch
34
from torch import Tensor
45

56

@@ -11,5 +12,24 @@ class DatasetOutput(TypedDict, total=False):
1112
label: The target label as integer (optional).
1213
"""
1314

15+
# GPUに転送するキーのリスト
16+
__gpu_keys__: tuple[str] = ("data", "label")
17+
1418
data: NotRequired[Tensor]
1519
label: NotRequired[int]
20+
21+
@classmethod
22+
def dummy(cls, batch: int | None = None) -> "DatasetOutput":
23+
"""Create dummy DatasetOutput for testing.
24+
25+
Args:
26+
batch: Batch size. If None, returns single sample with label as int.
27+
If specified, returns batched data with label as Tensor.
28+
29+
Returns:
30+
DatasetOutput with dummy values.
31+
"""
32+
if batch is None:
33+
return cls(data=torch.randn(3, 224, 224), label=torch.randint(0, 1000, (1,)).item())
34+
else:
35+
return cls(data=torch.randn(batch, 3, 224, 224), label=torch.randint(0, 1000, (batch,)))

src/models/types.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import NotRequired, Required, TypedDict
22

3+
import torch
34
from torch import Tensor
45

56

@@ -12,6 +13,26 @@ class LossOutput(TypedDict, total=False):
1213

1314
total_loss: Required[Tensor]
1415

16+
@classmethod
17+
def dummy(cls) -> "LossOutput":
18+
"""Create dummy LossOutput for testing."""
19+
return cls(total_loss=torch.rand(1))
20+
21+
22+
class PredOutput(TypedDict, total=False):
23+
"""Output structure for model predictions.
24+
25+
Attributes:
26+
preds: Dictionary containing model predictions.
27+
"""
28+
29+
preds: NotRequired[Tensor]
30+
31+
@classmethod
32+
def dummy(cls, batch: int = 1) -> "PredOutput":
33+
"""Create dummy PredOutput for testing."""
34+
return cls(preds=torch.rand(batch, 10))
35+
1536

1637
class ModelOutput(TypedDict, total=False):
1738
"""Output structure for model forward passes.
@@ -22,4 +43,9 @@ class ModelOutput(TypedDict, total=False):
2243
"""
2344

2445
losses: NotRequired[LossOutput]
25-
preds: NotRequired[dict[str, Tensor]]
46+
preds: NotRequired[PredOutput]
47+
48+
@classmethod
49+
def dummy(cls, batch: int = 1) -> "ModelOutput":
50+
"""Create dummy ModelOutput for testing."""
51+
return cls(losses=LossOutput.dummy(), preds=PredOutput.dummy(batch))

src/runner/base_trainer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def _do_one_epoch(self, state: TrainingState) -> EpochResult:
278278
with torch.set_grad_enabled(state.phase == "train"):
279279
# Prepare Input
280280
for k, v in inputs.items():
281-
if isinstance(v, torch.Tensor):
281+
if isinstance(v, torch.Tensor) and k in DatasetOutput.__gpu_keys__:
282282
inputs[k] = v.to(self.device, non_blocking=True)
283283
if self.batched_transforms[state.phase]:
284284
inputs = self.batched_transforms[state.phase](inputs)

tests/test_evaluator.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from pathlib import Path
22

33
import pytest
4-
import torch
54
import yaml
65
from torchmetrics import MetricCollection
76

87
from src.config.config import EvaluatorConfig
98
from src.dataloaders.types import DatasetOutput
109
from src.evaluator.build import EVALUATOR_REGISTRY
10+
from src.models.types import PredOutput
1111

1212
CONFIG_PATH = "config/__base__/evaluator/dummy_evaluator.yaml"
1313

@@ -17,18 +17,13 @@ class TestEvaluatorHelpers:
1717

1818
@staticmethod
1919
def create_dataset_data(batch_size: int = 2) -> DatasetOutput:
20-
"""Create mock HODatasetData for testing"""
21-
data = DatasetOutput()
22-
data["data"] = torch.rand(batch_size, 3, 224, 224)
23-
data["label"] = torch.randint(0, 10, (batch_size,))
24-
return data
20+
"""Create mock dataset data for testing"""
21+
return DatasetOutput.dummy(batch=batch_size)
2522

2623
@staticmethod
27-
def create_pred_output(batch_size: int = 2) -> dict:
28-
"""Create mock HOPEPredOutput for testing"""
29-
output = {}
30-
output["pred"] = torch.rand(batch_size, 10)
31-
return output
24+
def create_pred_output(batch_size: int = 2) -> PredOutput:
25+
"""Create mock pred output for testing"""
26+
return PredOutput.dummy(batch=batch_size)
3227

3328

3429
class TestEvaluatorFromConfig:

tests/test_modules.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ def test_dataloader() -> None:
123123
transform = build_transforms(dataset_cfg.test.transforms)
124124
dataset = build_dataset(dataset_cfg.test, transform)
125125
_, batch_sampler = build_sampler(dataset, phase="test", batch_size=2)
126-
dataloader = build_dataloader(dataset, num_workers=2, batch_sampler=batch_sampler)
126+
dataloader = build_dataloader(
127+
dataset, num_workers=2, batch_sampler=batch_sampler, pin_memory=False
128+
)
127129
if dataset_cfg.test.batch_transforms is not None:
128130
batched_transform = build_batched_transform(dataset_cfg.test.batch_transforms)
129131
else:

0 commit comments

Comments
 (0)