Какие проблемы могут привести к CuDNNError с ConvolutionND

Я использую в своей цепочке трехмерные сверточные ссылки (с ConvolutionND).

Прямое вычисление проходит гладко (я проверил формы промежуточных результатов, чтобы убедиться, что правильно понял значение параметров convolution_nd), но во время обратного вычисления возникает CuDNNError с сообщением CUDNN_STATUS_NOT_SUPPORTED.

Параметр cover_all ConvolutionND в качестве значения по умолчанию False, поэтому из документа я не вижу, что может быть причиной ошибки.

Вот как я определяю один из слоев свертки:

self.conv1 = chainer.links.ConvolutionND(3, 1, 4, (3, 3, 3)).to_gpu(self.GPU_1_ID)

И стек вызовов

File "chainer/function_node.py", line 548, in backward_accumulate
    gxs = self.backward(target_input_indexes, grad_outputs)
File "chainer/functions/connection/convolution_nd.py", line 118, in backward
    gy, W, stride=self.stride, pad=self.pad, outsize=x_shape)
File "chainer/functions/connection/deconvolution_nd.py", line 310, in deconvolution_nd
    y, = func.apply(args)
File chainer/function_node.py", line 258, in apply
    outputs = self.forward(in_data)
File "chainer/functions/connection/deconvolution_nd.py", line 128, in forward
    return self._forward_cudnn(x, W, b)
File "chainer/functions/connection/deconvolution_nd.py", line 105, in _forward_cudnn
    tensor_core=tensor_core)
File "cupy/cudnn.pyx", line 881, in cupy.cudnn.convolution_backward_data
File "cupy/cuda/cudnn.pyx", line 975, in cupy.cuda.cudnn.convolutionBackwardData_v3
File "cupy/cuda/cudnn.pyx", line 461, in cupy.cuda.cudnn.check_status
cupy.cuda.cudnn.CuDNNError: CUDNN_STATUS_NOT_SUPPORTED

Итак, есть ли особые моменты, о которых нужно позаботиться при использовании ConvolutionND?

Неудачный код, например:

import chainer
from chainer import functions as F
from chainer import links as L
from chainer.backends import cuda

import numpy as np
import cupy as cp

chainer.global_config.cudnn_deterministic = False

NB_MASKS = 60
NB_FCN = 3
NB_CLASS = 17

class MFEChain(chainer.Chain):
    """docstring for Wavelphasenet."""
    def __init__(self,
                 FCN_Dim,
                 gpu_ids=None):
        super(MFEChain, self).__init__()

        self.GPU_0_ID, self.GPU_1_ID = (0, 1) if gpu_ids is None else gpu_ids
        with self.init_scope():
            self.conv1 = chainer.links.ConvolutionND(3, 1, 4, (3, 3, 3)).to_gpu(
                self.GPU_1_ID
            )

    def __call__(self, inputs):
        ### Pad input ###
        processed_sequences = []
        for convolved in inputs:
            ## Transform to sequences)
            copy = convolved if self.GPU_0_ID == self.GPU_1_ID else F.copy(convolved, self.GPU_1_ID)
            processed_sequences.append(copy)

        reprocessed_sequences = []
        with cuda.get_device(self.GPU_1_ID):
            for convolved in processed_sequences:
                convolved = F.expand_dims(convolved, 0)
                convolved = F.expand_dims(convolved, 0)
                convolved = self.conv1(convolved)

                reprocessed_sequences.append(convolved)

            states = F.vstack(reprocessed_sequences)

            logits = states

            ret_logits = logits if self.GPU_0_ID == self.GPU_1_ID else F.copy(logits, self.GPU_0_ID)
        return ret_logits

def mfe_test():
    mfe = MFEChain(150)
    inputs = list(
        chainer.Variable(
            cp.random.randn(
                NB_MASKS,
                11,
                in_len,
                dtype=cp.float32
            )
        ) for in_len in [53248]
    )
    val = mfe(inputs)
    grad = cp.ones(val.shape, dtype=cp.float32)
    val.grad = grad
    val.backward()
    for i in inputs:
        print(i.grad)

if __name__ == "__main__":
    mfe_test()

person lforg37    schedule 19.07.2018    source источник
comment
Вы проверяли версию cudnn? Совместимо ли это с вашей версией CUDA?   -  person corochann    schedule 19.07.2018
comment
Да, они совместимы (cuda 9.2 и cudnn 7.1.4 для cuda 9.2).   -  person lforg37    schedule 20.07.2018


Ответы (1)


cupy.cuda.cudnn.convolutionBackwardData_v3 несовместим с некоторыми конкретными параметрами, как описано в ошибке официального github. .

К сожалению, проблема касалась только deconvolution_2d.py (а не deconvolution_nd.py), поэтому принятие решения о том, используется ли cudnn или нет, в вашем случае, я думаю, не удалось.

вы можете проверить свой параметр, подтвердив

  1. проверьте, передается ли в свертку параметр расширения (!=1) или параметр группы (!=1).
  2. print chainer.config.cudnn_deterministic, configuration.config.autotune и configuration.config.use_cudnn_tensor_core.

Дальнейшую поддержку можно получить, подняв вопрос на официальном github.

Код, который вы показали, очень сложен.

Чтобы прояснить проблему, приведенный ниже код поможет.

from chainer import Variable, Chain
from chainer import links as L
from chainer import functions as F

import numpy as np
from six import print_

batch_size = 1
in_channel = 1
out_channel = 1

class MyLink(Chain):
    def __init__(self):
        super(MyLink, self).__init__()
        with self.init_scope():
            self.conv = L.ConvolutionND(3, 1, 1, (3, 3, 3), nobias=True, initialW=np.ones((in_channel, out_channel, 3, 3, 3)))

    def __call__(self, x):
        return F.sum(self.conv(x))

if __name__ == "__main__":
    my_link = MyLink()
    my_link.to_gpu(0)
    batch = Variable(np.ones((batch_size, in_channel, 3, 3, 3)))
    batch.to_gpu(0)
    loss = my_link(batch)
    loss.backward()
    print_(batch.grad)
person Yuki Hashimoto    schedule 20.07.2018
comment
Как описано на официальном сайте NVIDIA, детерминированная реализация несовместимо с дилатацией!=1. - person Yuki Hashimoto; 20.07.2018
comment
Я установил для cudnn_deterministic значение false, но проблема все еще есть. Я не передал параметр расширения или группы в конструктор ConvolutionND. Я пытаюсь создать минимальный пример, показывающий проблему, и обновлю вопрос с ним. - person lforg37; 20.07.2018
comment
Может помочь более простой тест... из ссылок импорта цепочки как L - person Yuki Hashimoto; 22.07.2018
comment
Я попробовал ваш тест, и он сработал. После расследования проблема зависит от размера ввода, поэтому я предполагаю, что ошибка связана с нехваткой памяти. - person lforg37; 23.07.2018