Я пишу код гамильтоновой эволюции, который в значительной степени основан на умножении матриц, поэтому я пытался узнать о разработке для графического процессора с использованием Python.
Однако, когда я запускаю эти строки кода внутри моей функции-оболочки временной эволюции:
в строке cuda.synchronize().
При попытке отладить это с помощью операторов печати я заметил, что код начал успешно компилироваться, а также давать правдоподобные ответы, предполагая, что он работает правильно, когда оператор печати добавляется в код. Это наводит меня на мысль, что существует какая-то проблема с синхронизацией потоков, и скомпилированная версия с оператором печати каким-то образом позволяет избежать этого. Код momentum_update выглядит следующим образом:
Фактический код momentum_update_kernel не представляет особого интереса и, по сути, просто определяет idx и вызывает momentum_update, поэтому я не включил его сюда.
Теперь одной из возможных проблем является своего рода состояние гонки, поскольку momentum_update одновременно читает и записывает данные из конфигурации. Однако я подозреваю, что это не так. config — это массив (2, N, d, 2, 2), и каждый поток при обновлении импульса должен читать только из:
массива ссылок, массива (N, d, 2, 2), хранящегося в config[0], и
конкретного значения импульса, которое он обновляет.
Таким образом, несколько потоков могут читать из одной и той же памяти. сразу, но ничего не должно читаться из чего-то, куда записывает другой поток.
Когда я масштабирую размер моделирования до размера, с которым я действительно хочу его запустить, он начинает давать сбой независимо от присутствия оператора печати, поэтому я не могу просто оставить оператор печати в качестве хакерского исправления.
Есть ли хотя бы способ отладить это? Очевидно, что momentum_update вызывает несколько других функций, но если бы это была какая-то ошибка с другими функциями, я бы ожидал, что гамильтонова эволюция начнет давать мне неправильные ответы (ранее у меня были ошибки, скажем, в matmul_2x2_cuda, из-за которых она не работала должным образом, когда выходной массив был таким же, как один из входных данных, но я мог это сказать, потому что внезапно моделирование стало численно нестабильным), чего, похоже, не происходит.
Я запускаю это на GTX1060 на своем настольном компьютере, но ошибка также присутствует, скажем, на узлах графического процессора ComputeCanada (и на самом деле хак оператора печати там не работает).>
Я пишу код гамильтоновой эволюции, который в значительной степени основан на умножении матриц, поэтому я пытался узнать о разработке для графического процессора с использованием Python. Однако, когда я запускаю эти строки кода внутри моей функции-оболочки временной эволюции: [code]momentum_update_kernel[blocks, threads_per_block](config, dt / 2, staple_gpu, Barray_gpu, V2Barray_gpu, g_in) cuda.synchronize() print("momentum updated") link_update_kernel[blocks, threads_per_block](config, dt, lie_gens) [/code] Я начал получать:
"ошибку 700"
в строке cuda.synchronize(). При попытке отладить это с помощью операторов печати я заметил, что код начал успешно компилироваться, а также давать правдоподобные ответы, предполагая, что он работает правильно, когда оператор печати добавляется в код. Это наводит меня на мысль, что существует какая-то проблема с синхронизацией потоков, и скомпилированная версия с оператором печати каким-то образом позволяет избежать этого. Код momentum_update выглядит следующим образом: [code]def momentum_update(config, dt, staple_index_array, Barray, V2Barray, idx, out, g):
#calculating new momentum add_2x2_cuda(momentum[nodeindex, direction], temp, temp2) for i in range(2): for j in range(2): config[1][nodeindex, direction,i,j] = temp2[i,j]
[/code] Фактический код momentum_update_kernel не представляет особого интереса и, по сути, просто определяет idx и вызывает momentum_update, поэтому я не включил его сюда. Теперь одной из возможных проблем является своего рода состояние гонки, поскольку momentum_update одновременно читает и записывает данные из конфигурации. Однако я подозреваю, что это не так. config — это массив (2, N, d, 2, 2), и каждый поток при обновлении импульса должен читать только из: [list] [*]массива ссылок, массива (N, d, 2, 2), хранящегося в config[0], и [*]конкретного значения импульса, которое он обновляет. [/list] Таким образом, несколько потоков могут читать из одной и той же памяти. сразу, но ничего не должно читаться из чего-то, куда записывает другой поток. Когда я масштабирую размер моделирования до размера, с которым я действительно хочу его запустить, он начинает давать сбой независимо от присутствия оператора печати, поэтому я не могу просто оставить оператор печати в качестве хакерского исправления. Есть ли хотя бы способ отладить это? Очевидно, что momentum_update вызывает несколько других функций, но если бы это была какая-то ошибка с другими функциями, я бы ожидал, что гамильтонова эволюция начнет давать мне неправильные ответы (ранее у меня были ошибки, скажем, в matmul_2x2_cuda, из-за которых она не работала должным образом, когда выходной массив был таким же, как один из входных данных, но я мог это сказать, потому что внезапно моделирование стало численно нестабильным), чего, похоже, не происходит. Я запускаю это на GTX1060 на своем настольном компьютере, но ошибка также присутствует, скажем, на узлах графического процессора ComputeCanada (и на самом деле хак оператора печати там не работает).>