torch.device是一个代表张量所在设备的对象。它表示张量Tensor已经或将会被分配的地方。
torch.device的参数包含设备类型(最常见的是“cpu”或“cuda”)和设备序号(可选)。
如果设备序号没有给出,则使用当前设备。大家如果不知道当前设备,请使用下面代码查看一下:
import torch
print(torch.cuda.current_device())
综上所示,用设备"cuda"
构造的张量等价于"cuda:X"
,其中X
是torch.cuda.current_device()
的结果。
新建torch.device的方式有两种,如下所示:
(1)通过字符串新建torch.device
>>> torch.device("cuda:0")
device(type="cuda", index=0)
>>> torch.device("cpu")
device(type="cpu")
>>> torch.device("mps")
device(type="mps")
>>> torch.device("cuda") # current cuda device
device(type="cuda")
(2)通过字符串(设备类型)和设备序号新建torch.device
>>> torch.device("cuda", 0)
device(type="cuda", index=0)
>>> torch.device("mps", 0)
device(type="mps", index=0)
>>> torch.device("cpu", 0)
device(type="cpu", index=0)
>>> with torch.device("cuda:1"):
... r = torch.randn(2, 3)
>>> r.device
device(type="cuda", index=1)
函数中的torch.device参数通常可以用字符串替换。代码如下所示:
>>> cuda1 = torch.device("cuda:1")
>>> torch.randn((2,3), device=cuda1)
>>> # 可以用字符串代替orch.device
>>> torch.randn((2,3), device="cuda:1")
甚至还可以更简单。出于传统原因,可以通过单个设备序号构建设备,该序号被视为cuda设备。这与Tensor.get_device()匹配,后者返回cuda张量的序号,不支持cpu张量。
>>> torch.randn((2,3), device=1)
device(type="cuda", index=1)
>>> torch.randn((2,3), device=1)
张量永远不会在设备之间自动移动,需要用户进行显式调用。标量张量(tensor.dim()==0)是此规则的唯一例外,当需要时,它们会自动从CPU转移到GPU,因为此操作可以“自动”完成。例子:
>>> # two scalars
>>> torch.ones(()) + torch.ones(()).cuda() # OK, scalar auto-transferred from CPU to GPU
>>> torch.ones(()).cuda() + torch.ones(()) # OK, scalar auto-transferred from CPU to GPU
>>> # one scalar (CPU), one vector (GPU)
>>> torch.ones(()) + torch.ones(1).cuda() # OK, scalar auto-transferred from CPU to GPU
>>> torch.ones(1).cuda() + torch.ones(()) # OK, scalar auto-transferred from CPU to GPU
>>> # one scalar (GPU), one vector (CPU)
>>> torch.ones(()).cuda() + torch.ones(1) # Fail, scalar not auto-transferred from GPU to CPU and non-scalar not auto-transferred from CPU to GPU
>>> torch.ones(1) + torch.ones(()).cuda() # Fail, scalar not auto-transferred from GPU to CPU and non-scalar not auto-transferred from CPU to GPU