Ошибка алгоритма комбинации Cuda: CUDA_ERROR_LAUNCH_FAILED - PullRequest
0 голосов
/ 14 октября 2019

Я пытаюсь реализовать алгоритм комбинирования, описанный в этой статье https://www.developertyrone.com/blog/generating-the-mth-lexicographical-element-of-a-mathematical-combination/ на CUDA.

, он работает для C (100,4)

     n=100
     k=4

, но когда япопробуйте C (200,4) Я получил сообщение об ошибке CUDA_ERROR_LAUNCH_FAILED .

    n=200
    k=4

Я почти уверен, что нет переполнения для вычисления комбинации n = 200, но я не мог выяснитьпричина.

Я отладил код, и переполнения не было. Одним интересным моментом является то, что код иногда запускается для C (150,4), а иногда не работает.

Я ввел все целые числа как int64. Я попытался отметить каждую строку одну за другой, чтобы найти точное положение, вызывающее ошибку. Когда кажется, что проблема с этими двумя строками в самой большой функции V

    while choose(v, b) > x:
        v -= 1

Когда я отметил эти две строки, она не падает.

Полный код приведен ниже:

import numba
from numba import cuda
import math
import numpy as np
from pdb import set_trace


@cuda.jit(device=True)
def choose(n, k):
    if n < k:
        return 0
    if n == k:
        return 1

    delta = imax = 0
    if k < n-k:
        delta = n-k
        imax = k
    else:
        delta = k
        imax = n-k

    ans = numba.int64(delta + 1)

    for i in range(2, imax+1):
        ans = numba.int64((ans * (delta + i)) / i)

    return ans


@cuda.jit(device=True)
def largestV(a, b, x):

    v = numba.int64(a-1)
    while choose(v, b) > x:
        v -= 1

    return v


@cuda.jit
def cuda_calculateMth(n, k, d_result):
    pos = cuda.grid(1)     # pylint: disable=not-callable
    if pos >= len(d_result):
        return

    m = numba.int64(pos)
    a = numba.int64(n)
    b = numba.int64(k)
    x = numba.int64((choose(a, b) - 1) - m)

    for i in range(k):
        d_result[pos][i] = largestV(a, b, x)

        x = x - choose(d_result[pos][i], b)
        a = d_result[pos][i]
        b -= 1

    for i in range(k):
        d_result[m][i] = (n-1) - d_result[m][i]




if __name__ == "__main__":

    n = 200
    k = 4
    totalcount = int((n*(n-1)*(n-2)*(n-3)) / (4 * 3 * 2))
    result = np.zeros((totalcount, 4), dtype="uint")
    temp = np.zeros(10, dtype="uint")

    d_result = cuda.to_device(result)
    d_temp = cuda.to_device(temp)

    threadsperblock = 128
    blockspergrid = (totalcount +
                     (threadsperblock - 1)) // threadsperblock

    cuda_calculateMth[blockspergrid, threadsperblock](  
        n, k, d_result)
    result = d_result.copy_to_host()
    print(result[-30:])

1 Ответ

0 голосов
/ 14 октября 2019

Благодаря talonmies, это проблема тайм-аута. Я установил TDR Timeout на 30, и теперь он работает.

...