import torch


def random_rectangles(size, num_rects, max_sidelen=20):
    """
    >>> rects, masks = random_rectangles(256, 10)
    >>> tuple(rects.shape)
    (10, 4)
    >>> tuple(masks.shape)
    (10, 256, 256)
    >>> bool(torch.all((0 <= rects[:, 0]) * (rects[:, 2] < 256)))
    True
    >>> bool(torch.all((0 <= rects[:, 1]) * (rects[:, 3] < 256)))
    True
    >>> bool(torch.all(rects[:, 0] < rects[:, 2]))
    True
    >>> bool(torch.all(rects[:, 1] < rects[:, 3]))
    True
    """
    # We use integer-tensor to make sure there's no issue with precision
    xs, ys = torch.LongTensor(2, num_rects).random_(0, size - max_sidelen - 1)
    ws, hs = torch.LongTensor(2, num_rects).random_(1, max_sidelen)
    masks = torch.zeros(num_rects, size, size, dtype=torch.float32)

    for mask, x, y, w, h in zip(masks, xs, ys, ws, hs):
        mask[y : y + h + 1, x : x + w + 1] = 1

    return torch.stack((xs, ys, xs + ws, ys + hs), dim=-1), masks