# Windows 常见问题

*   [源码构建](#building-from-source)
    *   [包含可选组件](#include-optional-components)
    *   [加速 Windows 的 CUDA 构建](#speeding-cuda-build-for-windows)
    *   [一个关键的安装脚本](#one-key-install-script)
*   [扩展](#extension)
    *   [CFFI 扩展](#cffi-extension)
    *   [Cpp 扩展](#cpp-extension)
*   [安装](#installation)
    *   [在 win-32 中找不到包](#package-not-found-in-win-32-channel)
    *   [为什么没有 Windows 的 Python 2 包？](#why-are-there-no-python-2-packages-for-windows)
    *   [导入错误](#import-error)
*   [用法（多进程处理）](#usage-multiprocessing)
    *   [无 if 语句保护的多进程处理错误](#multiprocessing-error-without-if-clause-protection)
    *   [多进程处理错误 “损坏的管道”](#multiprocessing-error-broken-pipe)
    *   [多进程处理错误 “驱动程序关闭”](#multiprocessing-error-driver-shut-down)
    *   [CUDA IPC 业务](#cuda-ipc-operations)

### 包含可选组件

Windows PyTorch 支持两种组件：MKL 和 MAGMA。以下是与他们一起构建的步骤。

```py
# REM 确保您安装了 7z 和卷曲
# REM 下载 MKL 文件
curl https://s3.amazonaws.com/ossci-windows/mkl_2018.2.185.7z -k -O
7z x -aoa mkl_2018.2.185.7z -omkl

# REM 下载 MAGMA 文件 
# cuda90 / cuda91 也可在以下行中找到
set CUDA_PREFIX=cuda80
curl -k https://s3.amazonaws.com/ossci-windows/magma_%CUDA_PREFIX%_release_mkl_2018.2.185.7z -o magma.7z
7z x -aoa magma.7z -omagma

# REM 设置基本的环境变量
set "CMAKE_INCLUDE_PATH=%cd%\\mkl\\include"
set "LIB=%cd%\\mkl\\lib;%LIB%"
set "MAGMA_HOME=%cd%\\magma" 
```

### 加速 Windows 的 CUDA 构建

Visual Studio 目前不支持并行自定义任务。作为替代，我们可以使用 `Ninja` 来并行化 CUDA 构建任务。它只能通过输入几行代码来使用。

```py
# REM 先安装 ninja
pip install ninja

# REM 将其设置为 cmake 生成器
set CMAKE_GENERATOR=Ninja 
```

### 一个关键的安装脚本

你可以在这里查阅 [脚本](https://github.com/peterjc123/pytorch-scripts) ，它会给你指引。

### CFFI 扩展

对 CFFI 扩展的支持是非常实验性的。在 Windows 下启用它通常有两个步骤。

首先，在扩展对象中指定其他库以更在 Windows 上构建。

```py
ffi = create_extension(
    '_ext.my_lib',
    headers=headers,
    sources=sources,
    define_macros=defines,
    relative_to=__file__,
    with_cuda=with_cuda,
    extra_compile_args=["-std=c99"],
    libraries=['ATen', '_C'] # Append cuda libaries when necessary, like cudart
) 
```

其次，对于“unresolved external symbol state caused by `extern THCState *state;`” 由`extern THCState *state` 引起的未解析的外部符号状态，将源代码从 C 更改为 C ++。

下面列出了一个例子：

```py
#include <THC/THC.h>
#include <ATen/ATen.h>

THCState *state = at::globalContext().thc_state;

extern "C" int my_lib_add_forward_cuda(THCudaTensor *input1, THCudaTensor *input2,
                                        THCudaTensor *output)
{
    if (!THCudaTensor_isSameSizeAs(state, input1, input2))
    return 0;
    THCudaTensor_resizeAs(state, output, input1);
    THCudaTensor_cadd(state, output, input1, 1.0, input2);
    return 1;
}

extern "C" int my_lib_add_backward_cuda(THCudaTensor *grad_output, THCudaTensor *grad_input)
{
    THCudaTensor_resizeAs(state, grad_input, grad_output);
    THCudaTensor_fill(state, grad_input, 1);
    return 1;
} 
```

### Cpp 扩展

与前一种相比，这种类型的扩展有更好的支持。但是，它仍然需要一些手动配置。首先，您应该打开**VS 2017 的 x86_x64 交叉工具链命令提示符**。然后，您可以打开其中的 Git-Bash。它通常位于 `C：\ Program Files \ Git \ git-bash.exe` 中。最后，您可以开始编译过程。

### 在 win-32 中找不到包

```py
Solving environment: failed

PackagesNotFoundError: The following packages are not available from current channels:

- pytorch

Current channels:
- https://conda.anaconda.org/pytorch/win-32
- https://conda.anaconda.org/pytorch/noarch
- https://repo.continuum.io/pkgs/main/win-32
- https://repo.continuum.io/pkgs/main/noarch
- https://repo.continuum.io/pkgs/free/win-32
- https://repo.continuum.io/pkgs/free/noarch
- https://repo.continuum.io/pkgs/r/win-32
- https://repo.continuum.io/pkgs/r/noarch
- https://repo.continuum.io/pkgs/pro/win-32
- https://repo.continuum.io/pkgs/pro/noarch
- https://repo.continuum.io/pkgs/msys2/win-32
- https://repo.continuum.io/pkgs/msys2/noarch 
```

PyTorch 不适用于 32 位系统。请使用 Windows 和 Python 64 位版本。

### 为什么没有 Windows 的 Python 2 包？

因为它不够稳定。在我们正式发布之前需要解决一些问题。你可以自己构建它。

### 导入错误

```py
from torch._C import *

ImportError: DLL load failed: The specified module could not be found. 
```

这个问题是由于必要文件丢失造成的。实际上，我们几乎包含了除 VC2017 可再发行组件之外 PyTorch 所需的所有必要文件。您可以通过键入以下命令来解决此问题。

```py
conda install -c peterjc123 vc vs2017_runtime 
```

另一个可能的原因可能是您使用的是没有 NVIDIA 图形卡的 GPU 版本。请将您的 GPU 软件包替换为 CPU 软件包。

### 无 if 语句保护的多进程处理错误

```py
RuntimeError:
    An attempt has been made to start a new process before the
    current process has finished its bootstrapping phase.
    在当前进程完成引导阶段之前，已尝试开始一个新进程

   This probably means that you are not using fork to start your
   child processes and you have forgotten to use the proper idiom
   in the main module:
   这可能意味着你没有使用 fork 来启动你的子进程，并且你忘记了在主模块中使用
   正确的用法：

       if __name__ == '__main__':
           freeze_support()
           ...

   The "freeze_support()" line can be omitted if the program
   is not going to be frozen to produce an executable.
   如果程序不会被冻结以生成可执行文件，则可以省略 “freeze_support()” 行。 
```

Windows 上 `multiprocessing` 多进程处理的实现不同，它使用 `spawn` 而不是 `fork`。所以我们必须用 if 条件语句来保护代码不被执行多次。将您的代码重构为以下结构：

```py
import torch

def main()
    for i, data in enumerate(dataloader):
        # do something here

if __name__ == '__main__':
    main() 
```

### 多进程处理错误 “损坏的管道”

```py
ForkingPickler(file, protocol).dump(obj)

BrokenPipeError: [Errno 32] Broken pipe 
```

在父进程发送数据完成之前，子进程先结束就会发生此错误。这说明你的代码可能有问题。你可以通过将 `DataLoader` 的 `num_worker` 减为零来调试代码，看看问题是否仍然存在。

### 多进程处理错误 “驱动程序关闭”

```py
Couldn’t open shared file mapping: <torch_14808_1591070686>, error code: <1455> at torch\lib\TH\THAllocator.c:154

[windows] driver shut down 
```

请更新您的图形驱动程序。如果这种情况持续存在，这可能是因为您的显卡太旧或计算压力对于您的显卡来说太重了。请根据这篇 [文章](https://www.pugetsystems.com/labs/hpc/Working-around-TDR-in-Windows-for-a-better-GPU-computing-experience-777/) 更新 TDR 设置。

### CUDA IPC 业务

```py
THCudaCheck FAIL file=torch\csrc\generic\StorageSharing.cpp line=252 error=63 : OS call failed or operation not supported on this OS 
```

Windows 不支持此类业务。就像在 CUDA 张量上进行多进程处理一样无法成功，有两种方法可供选择：

1.  不要使用多进程处理。将 `DataLoader` 的 `num_worker` 设置为零。
2.  改为 CPU 共享张量。确保您的自定义 `DataSet` 数据集返回 CPU 张量。

### 译者署名

| 用户名 | 头像 | 职能 | 签名 |
| --- | --- | --- | --- |
| 风中劲草 | ![](img/2018033000352689884.jpeg) | 翻译 | 人生总要追求点什么 |