2016-12-22 22 views
-2

У меня есть код, написанный в OpenMP изначально. Теперь я хочу перенести его в OpenACC. Рассмотрим следующее:openacc - несоответствия между ta = multicore и ta = nvidia компиляция

1. Прежде всего, результат вывода OpenMP считается конечным результатом, и выход OpenACC должен следовать за ними.

2 Во-вторых, в коде есть 2 функции, которые активируются при вводе в программу на терминале. Поэтому либо F1, либо F2 работает на основе флага ввода.

Итак, как упоминалось ранее, я передал свой код OpenACC. Теперь я могу скомпилировать код OpenACC с -ta=multicore и -ta=nvidia для компиляции областей OpenACC для разных архитектур.

Для F1 выход обеих архитектур аналогичен OpenMP. Таким образом, это означает, что когда я скомпилирую свою программу с -ta=multicore и -ta=nvidia, я получаю правильные выходные результаты, подобные OpenMP, когда выбрано F1.

Для F2 это немного отличается. Компиляция с -ta=multicore дает мне правильный результат как OpenMP, но то же самое не происходит для архитектуры nvidia. Когда я компилирую свой код с -ta=nvidia, результаты неверны.

Любые идеи, что может быть неправильным с F2 или даже build process?

Примечание: Я использую PGI компилятор 16 и мой NVIDIA GPU имеет CC, равный 5,2.

+1

Управляете ли вы перемещением данных и синхронизацией данных хоста и устройства при ориентации на GPU? При многоядерном перемещении данных нет необходимости, но с графическим процессором. Получает ли код правильные ответы, если вы компилируете с помощью «-ta = tesla: managed»? Управляемый позволяет унифицированной памяти CUDA, тем самым устраняя необходимость управления динамическими данными. Если управление работает, то это определенно проблема перемещения данных.Проводка примера воспроизведения также будет полезна. –

+0

Спасибо @MatColgrove Он работал с управляемым! Но я попытался перенести все необходимые данные на свое устройство. Есть ли способ выяснить, указываю ли я на что-то мусор на своем устройстве или что-то легитимное (помимо использования acc_is_present)? – Millad

+1

Итак, это означает, что у вас есть проблема синхронизации, когда данные узла или устройства не обновляются. Я предполагаю, что вы используете неструктурированные области данных или область структуры, которая охватывает несколько вычислительных областей. В этом случае поместите директивы «update» до и после каждой области вычисления, синхронизируя копии хоста и устройства. Затем систематически удаляйте каждую переменную. Если это не удается, сохраните его в обновлении. Наконец, как только вы узнаете, какие переменные вызывают проблемы, отслеживайте их использование и используйте директиву обновления и/или добавляйте дополнительные вычислительные области. –

ответ

0

Причина, по которой были некоторые несоответствия между двумя архитектурами, была связана с неправильной передачей данных между хостом и устройством. В какой-то момент хост потребовал некоторые массивы для перераспределения данных.

Благодаря комментариям Мата Колгроува я нашел массив преступников и решил проблему, перенеся ее правильно.

Сначала я включил единую память (-ta=nvidia:managed), чтобы убедиться, что мой алгоритм является безошибочным. Это очень помогло мне. Итак, я удалил managed, чтобы исследовать мой код и найти массив, который вызывает проблему.

Затем я последовал следующий процедуру, основанную на комментарий Мэта (супер полезный):

Ok, так что это означает, что у вас есть проблемы синхронизации, когда либо хост или данные устройства не получает обновление. Я предполагаю, что вы используете неструктурированные области данных или область структуры, которая охватывает несколько вычислительных областей. В этом случае поместите директивы «update» до и после каждой области вычисления, синхронизируя копии хоста и устройства. Затем систематически удаляйте каждую переменную. Если это не удается, сохраните его в обновлении. Наконец, как только вы узнаете, какие переменные вызывают проблемы, отслеживайте их использование и используйте директиву обновления и/или добавляйте дополнительные вычислительные области.