Repository: open-mmlab/mmdetection

Issue:
RuntimeError: expected device cuda:1 but got device cuda:0
I have 2 titan xp gpus ,and when I run reppoints detection train.py it occurs:
```

python tools/train.py workproject/gureppoints/reppoints_moment_r101_fpn_gn-neck+head_2x_coco.py  --gpu-ids=1 

2020-09-24 17:04:35,811 - mmdet - INFO - Distributed training: False
2020-09-24 17:04:36,261 - mmdet - INFO - Config:
dataset_type = 'CocoDataset'
data_root = 'data/coco/'
img_norm_cfg = dict(
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations', with_bbox=True),
    dict(type='Resize', img_scale=(2048, 1024), keep_ratio=True),
    dict(type='RandomFlip', flip_ratio=0.5),
    dict(
        type='Normalize',
        mean=[123.675, 116.28, 103.53],
        std=[58.395, 57.12, 57.375],
        to_rgb=True),
    dict(type='Pad', size_divisor=32),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=(2048, 1024),
        flip=False,
        transforms=[
            dict(type='Resize', keep_ratio=True),
            dict(type='RandomFlip'),
            dict(
                type='Normalize',
                mean=[123.675, 116.28, 103.53],
                std=[58.395, 57.12, 57.375],
                to_rgb=True),
            dict(type='Pad', size_divisor=32),
            dict(type='ImageToTensor', keys=['img']),
            dict(type='Collect', keys=['img'])
        ])
]
data = dict(
    samples_per_gpu=2,
    workers_per_gpu=4,
    train=dict(
        type='CocoDataset',
        ann_file='data/coco/annotations/instances_train2017.json',
        img_prefix='data/coco/train2017/',
        pipeline=[
            dict(type='LoadImageFromFile'),
            dict(type='LoadAnnotations', with_bbox=True),
            dict(type='Resize', img_scale=(2048, 1024), keep_ratio=True),
            dict(type='RandomFlip', flip_ratio=0.5),
            dict(
                type='Normalize',
                mean=[123.675, 116.28, 103.53],
                std=[58.395, 57.12, 57.375],
                to_rgb=True),
            dict(type='Pad', size_divisor=32),
            dict(type='DefaultFormatBundle'),
            dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])
        ]),
    val=dict(
        type='CocoDataset',
        ann_file='data/coco/annotations/instances_val2017.json',
        img_prefix='data/coco/val2017/',
        pipeline=[
            dict(type='LoadImageFromFile'),
            dict(
                type='MultiScaleFlipAug',
                img_scale=(2048, 1024),
                flip=False,
                transforms=[
                    dict(type='Resize', keep_ratio=True),
                    dict(type='RandomFlip'),
                    dict(
                        type='Normalize',
                        mean=[123.675, 116.28, 103.53],
                        std=[58.395, 57.12, 57.375],
                        to_rgb=True),
                    dict(type='Pad', size_divisor=32),
                    dict(type='ImageToTensor', keys=['img']),
                    dict(type='Collect', keys=['img'])
                ])
        ]),
    test=dict(
        type='CocoDataset',
        ann_file='data/coco/annotations/instances_test2017.json',
        img_prefix='data/coco/test2017/',
        pipeline=[
            dict(type='LoadImageFromFile'),
            dict(
                type='MultiScaleFlipAug',
                img_scale=(2048, 1024),
                flip=False,
                transforms=[
                    dict(type='Resize', keep_ratio=True),
                    dict(type='RandomFlip'),
                    dict(
                        type='Normalize',
                        mean=[123.675, 116.28, 103.53],
                        std=[58.395, 57.12, 57.375],
                        to_rgb=True),
                    dict(type='Pad', size_divisor=32),
                    dict(type='ImageToTensor', keys=['img']),
                    dict(type='Collect', keys=['img'])
                ])
        ]))
evaluation = dict(interval=1, metric='bbox')
optimizer = dict(type='SGD', lr=0.00125, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
lr_config = dict(
    policy='step',
    warmup='linear',
    warmup_iters=500,
    warmup_ratio=0.001,
    step=[16, 22])
total_epochs = 24
checkpoint_config = dict(interval=1)
log_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])
dist_params = dict(backend='nccl')
log_level = 'INFO'
load_from = None
resume_from = None
workflow = [('train', 1)]
model = dict(
    type='RepPointsDetector',
    pretrained='torchvision://resnet101',
    backbone=dict(
        type='ResNet',
        depth=101,
        num_stages=4,
        out_indices=(0, 1, 2, 3),
        frozen_stages=1,
        norm_cfg=dict(type='BN', requires_grad=True),
        norm_eval=True,
        style='pytorch'),
    neck=dict(
        type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        start_level=1,
        add_extra_convs='on_input',
        num_outs=5,
        norm_cfg=dict(type='GN', num_groups=32, requires_grad=True)),
    bbox_head=dict(
        type='RepPointsHead',
        num_classes=6,
        in_channels=256,
        feat_channels=256,
        point_feat_channels=256,
        stacked_convs=3,
        num_points=9,
        gradient_mul=0.1,
        point_strides=[8, 16, 32, 64, 128],
        point_base_scale=4,
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox_init=dict(type='SmoothL1Loss', beta=0.11, loss_weight=0.5),
        loss_bbox_refine=dict(type='SmoothL1Loss', beta=0.11, loss_weight=1.0),
        transform_method='moment',
        norm_cfg=dict(type='GN', num_groups=32, requires_grad=True)))
train_cfg = dict(
    init=dict(
        assigner=dict(type='PointAssigner', scale=4, pos_num=1),
        allowed_border=-1,
        pos_weight=-1,
        debug=False),
    refine=dict(
        assigner=dict(
            type='MaxIoUAssigner',
            pos_iou_thr=0.5,
            neg_iou_thr=0.4,
            min_pos_iou=0,
            ignore_iof_thr=-1),
        allowed_border=-1,
        pos_weight=-1,
        debug=False))
test_cfg = dict(
    nms_pre=1000,
    min_bbox_size=0,
    score_thr=0.05,
    nms=dict(type='nms', iou_threshold=0.5),
    max_per_img=100)
norm_cfg = dict(type='GN', num_groups=32, requires_grad=True)
work_dir = 'workproject/gureppoints'
gpu_ids = [1]

2020-09-24 17:04:37,362 - mmdet - INFO - load model from: torchvision://resnet101
2020-09-24 17:04:38,153 - mmdet - WARNING - The model and loaded state dict do not match exactly

unexpected key in source state_dict: fc.weight, fc.bias

loading annotations into memory...
Done (t=0.29s)
creating index...
index created!
loading annotations into memory...
Done (t=0.06s)
creating index...
index created!
2020-09-24 17:04:44,095 - mmdet - INFO - Start running, host: ys@ys, work_dir: /media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/workproject/gureppoints
2020-09-24 17:04:44,096 - mmdet - INFO - workflow: [('train', 1)], max: 24 epochs
Traceback (most recent call last):
  File "tools/train.py", line 178, in <module>
    main()
  File "tools/train.py", line 174, in main
    meta=meta)
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/apis/train.py", line 143, in train_detector
    runner.run(data_loaders, cfg.workflow, cfg.total_epochs)
  File "/home/ys/anaconda3/envs/tensorflow1/lib/python3.7/site-packages/mmcv/runner/epoch_based_runner.py", line 122, in run
    epoch_runner(data_loaders[i], **kwargs)
  File "/home/ys/anaconda3/envs/tensorflow1/lib/python3.7/site-packages/mmcv/runner/epoch_based_runner.py", line 32, in train
    **kwargs)
  File "/home/ys/anaconda3/envs/tensorflow1/lib/python3.7/site-packages/mmcv/parallel/data_parallel.py", line 67, in train_step
    return self.module.train_step(*inputs[0], **kwargs[0])
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/models/detectors/base.py", line 234, in train_step
    losses = self(**data)
  File "/home/ys/anaconda3/envs/tensorflow1/lib/python3.7/site-packages/torch/nn/modules/module.py", line 532, in __call__
    result = self.forward(*input, **kwargs)
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/core/fp16/decorators.py", line 51, in new_func
    return old_func(*args, **kwargs)
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/models/detectors/base.py", line 168, in forward
    return self.forward_train(img, img_metas, **kwargs)
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/models/detectors/single_stage.py", line 94, in forward_train
    gt_labels, gt_bboxes_ignore)
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/models/dense_heads/base_dense_head.py", line 54, in forward_train
    losses = self.loss(*loss_inputs, gt_bboxes_ignore=gt_bboxes_ignore)
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/models/dense_heads/reppoints_head.py", line 581, in loss
    pts_preds_init)
  File "/media/ys/4E2CD69B656E8D93/guchenliang/mmdetection/mmdet/models/dense_heads/reppoints_head.py", line 368, in offset_to_pts
    pts = xy_pts_shift * self.point_strides[i_lvl] + pts_center
RuntimeError: expected device cuda:1 but got device cuda:0
```
so what's the problem?


Discussion:
Not typo.
`print(args)` shows `gpu_ids=[1]`, and the log shows `gpu_ids = [1]`.
> Not typo.
> `print(args)` shows `gpu_ids=[1]`, and the log shows `gpu_ids = [1]`.

you are right，I don't understand the usage of argparse well
Does passing `device = 'cuda:1'` from `reppoints_head.py` work?

`points = self.point_generators[i].grid_points(featmap_sizes[i], self.point_strides[i], device=device)`
`flags = self.point_generators[i].valid_flags((feat_h, feat_w), (valid_feat_h, valid_feat_w), device=device)`

If so, `pts = xy_pts_shift * self.point_strides[i_lvl] + pts_center.to(xy_pts_shift.device)` would be a tentative fix.

Resolving patch:
diff --git a/mmdet/models/dense_heads/reppoints_head.py b/mmdet/models/dense_heads/reppoints_head.py
--- a/mmdet/models/dense_heads/reppoints_head.py
+++ b/mmdet/models/dense_heads/reppoints_head.py
@@ -292,7 +292,7 @@ def forward_single(self, x):
             pts_out_refine = pts_out_refine + pts_out_init.detach()
         return cls_out, pts_out_init, pts_out_refine
 
-    def get_points(self, featmap_sizes, img_metas):
+    def get_points(self, featmap_sizes, img_metas, device):
         """Get points according to feature map sizes.
 
         Args:
@@ -310,7 +310,7 @@ def get_points(self, featmap_sizes, img_metas):
         multi_level_points = []
         for i in range(num_levels):
             points = self.point_generators[i].grid_points(
-                featmap_sizes[i], self.point_strides[i])
+                featmap_sizes[i], self.point_strides[i], device)
             multi_level_points.append(points)
         points_list = [[point.clone() for point in multi_level_points]
                        for _ in range(num_imgs)]
@@ -326,7 +326,7 @@ def get_points(self, featmap_sizes, img_metas):
                 valid_feat_h = min(int(np.ceil(h / point_stride)), feat_h)
                 valid_feat_w = min(int(np.ceil(w / point_stride)), feat_w)
                 flags = self.point_generators[i].valid_flags(
-                    (feat_h, feat_w), (valid_feat_h, valid_feat_w))
+                    (feat_h, feat_w), (valid_feat_h, valid_feat_w), device)
                 multi_level_flags.append(flags)
             valid_flag_list.append(multi_level_flags)
 
@@ -534,6 +534,7 @@ def loss_single(self, cls_score, pts_pred_init, pts_pred_refine, labels,
         label_weights = label_weights.reshape(-1)
         cls_score = cls_score.permute(0, 2, 3,
                                       1).reshape(-1, self.cls_out_channels)
+        cls_score = cls_score.contiguous()
         loss_cls = self.loss_cls(
             cls_score,
             labels,
@@ -572,11 +573,12 @@ def loss(self,
              gt_bboxes_ignore=None):
         featmap_sizes = [featmap.size()[-2:] for featmap in cls_scores]
         assert len(featmap_sizes) == len(self.point_generators)
+        device = cls_scores[0].device
         label_channels = self.cls_out_channels if self.use_sigmoid_cls else 1
 
         # target for initial stage
         center_list, valid_flag_list = self.get_points(featmap_sizes,
-                                                       img_metas)
+                                                       img_metas, device)
         pts_coordinate_preds_init = self.offset_to_pts(center_list,
                                                        pts_preds_init)
         if self.train_cfg.init.assigner['type'] == 'PointAssigner':
@@ -604,7 +606,7 @@ def loss(self,
 
         # target for refinement stage
         center_list, valid_flag_list = self.get_points(featmap_sizes,
-                                                       img_metas)
+                                                       img_metas, device)
         pts_coordinate_preds_refine = self.offset_to_pts(
             center_list, pts_preds_refine)
         bbox_list = []
@@ -666,6 +668,7 @@ def get_bboxes(self,
                    rescale=False,
                    nms=True):
         assert len(cls_scores) == len(pts_preds_refine)
+        device = cls_scores[0].device
         bbox_preds_refine = [
             self.points2bbox(pts_pred_refine)
             for pts_pred_refine in pts_preds_refine
@@ -673,7 +676,7 @@ def get_bboxes(self,
         num_levels = len(cls_scores)
         mlvl_points = [
             self.point_generators[i].grid_points(cls_scores[i].size()[-2:],
-                                                 self.point_strides[i])
+                                                 self.point_strides[i], device)
             for i in range(num_levels)
         ]
         result_list = []


Test patch: