Изучить базовый принцип работы с технологией параллельных вычислений
Подробнее про технологии (мануалы, туториалы и ссылки на установку SDK) можно найти в .
2
Написать программу, решающую поставленную задачу
Прочитайте условие работы и задания. В условии будут указаны ограничения на язык и технологии, которые можно использовать.
3
Отправить работу на проверку и получить обратную связь по ней
Правила .
Если вы сомневаетесь, видна ли работы со стороны проверяющего, напишите ему в лс.
4
Получить результат проверки
Если полученный результат устраивает, то готовиться к защите (если за работу не меньше допустимомго минимума) – переход в п.5;
Если балл меньше минимума/желаемого значения, то нужно доделывать работу и заново её отправлять на проверку – переход в п.3;
В случае получения бана – переход в п.2 по другим работам курса.
За плагиат кода будет бан 0 баллов без защиты. Возможно также начисление отрицательных баллов.
5
Защитить работу
К защите работы иметь:
исходный код программы;
возможность запуска программы для демонстрации её работоспособности;
загруженный отчёт.
Отчёт
В отчёте указываются значимые характеристики тестового стенда (своего ПК) и результаты тестирования на скорость/точность вычислений.
Отчёт оформляется в файле REPORT.md, лежащем в корне репозитория.
На защите помимо теоретических аспектов будут обсуждаться результаты замеров (то есть отчётные материалы), так что перед защитой настоятельно рекомендуется осознать, что было намерено и почему результаты получились такими.
Результаты тестирования должны быть представлены как графики времени работы** при различных параметрах алгоритма. Примеры графиков перечислены ниже, выбирайте те, которые применимы к каждой работе:
при различных значениях числа потоков при одинаковом параметре schedule;
при одинаковом значении числа потоков при различных параметрах schedule;
с выключенным OpenMP и с включенным с 1 потоком;
при разных размерах входных данных время разных реализаций алгоритма.
** В данном случае имеется в виду время работы алгоритма без времени на считывание данных и вывод результат.
schedule(kind[, chunk_size]) - kind может принимать значения из набора {static, dynamic}, chunk_size – 1 и несколько (5-6) других осмысленных значений (guided по желанию).
В случае, когда в программе возникают параметры, влияющие на результат, показать время работы программы при различных значениях этого параметра.
Результаты тестирования должны быть представлены как графики времени работы** при различных параметрах алгоритма. Примеры графиков перечислены ниже, выбирайте те, которые применимы к каждой работе:
при различных значениях числа потоков при одинаковом параметре schedule;
при одинаковом значении числа потоков при различных параметрах schedule;
при разных размерах входных данных время разных реализаций алгоритма.
** В данном случае имеется в виду время работы алгоритма без времени на считывание данных и вывод результат.
schedule - реализованный самостоятельно аналог OpenMP schedule.
В случае, когда в программе возникают параметры, влияющие на результат, показать время работы программы при различных значениях этого параметра.
Результаты тестирования должны быть представлены как графики времени работы** программы:
при нескольких размерах входных данных (в том числе, когда работа нацело не делится на вычислители);
если в работе есть разные реализации, то повторить это на всех реализациях (на одинаковых входных данных достаточно большого размера);
в случае, когда в программе возникают параметры, влияющие на результат, показать время работы программы при различных значениях этого параметра;
любые другие, демонстрирующие интересные особенности.
** В данном случае имеется в виду время работы алгоритма без времени на считывание данных, передачу между хостом и девайсом, вывод результата.
[OpenCL only]
Дополнительно к отчёту прикладывается отчёт профайлинга CodeXL, сгенерированного на тестовом стенде.
Тестовый стенд – тестовый сервер курса (с AMD Radeon 5700XT).
Также приветствуется исследование код путём профилирования на любом другом ПК (по возможности).
Требования к работам
В лабораторных ожидается реализация алгоритма в 2 вариантах: функция, где никак не используется OpenMP, и функция, где OpenMP используется. В коде, отправляемом на проверку, необходимо оставить ту комбинацию параметров schedule, которая, по вашему мнению, работает быстрее всего.
Во всех работах нельзя использовать reduction, putenv("OMP_NUM_THREADS=5").
Аргументы программе передаются через командную строку:
В лабораторных ожидается одна реализация алгоритма: функция, где используются стандартные C++ потоки. В коде, отправляемом на проверку, необходимо оставить ту комбинацию параметров schedule, которая, по вашему мнению, работает быстрее всего.
Аргументы программе передаются через командную строку:
Если подано --cpp-threads 1, то программа не должна создавать новых потоков!
C++ для Host кода. Host-код не должен использовать внешние библиотеки, кроме CUDA.
Заголовочные файлы CUDA должны быть подключены следующим образом:
#include <cuda_runtime.h>
Кроме правильности результата будет проверяться скорость работы программы. Поэтому в коде, отправляемом на проверку, необходимо оставить ту комбинацию параметров, которая, по вашему мнению, работает быстрее всего.
Результат выполнения лабораторной работы – консольная программа. Результат работы разработанной программы выводится в файл.
В консоль сначала выводиться имя выбранного device (cudaDeviceProp::name), затем – версию Driver CUDA, в формате: Device: %s\tDriver version: %i.
Затем время. Формат вывода времени работы в миллисекундах: Time: %g\t%g, где сначала выводится время работы кернела без учета передачи данных, а затем полное время (замеренное на хосте) работы алгоритма с учетом передачи данных с host на device и обратно (от memCpy до memCpy).
Далее выводится то, что указано в примечаниях работы.
Аргументы программе передаются через командную строку:
lab0.exe – имя исполняемого файла (в C/C++ argv[0]);
--help – команда вывода справки;
--input name – имя входного файла;
--output name – имя выходного файла;
Вместо объявления макросов в cu-файлах, их можно задавать в строке сборки аргументом как preprocessor definition через ключ -D. Это также упрощает процесс тестирования и замеров времени для графиков.
C++ для Host кода. Host-код не должен использовать внешние библиотеки, кроме HIP.
Заголовочные файлы HIP должны быть подключены следующим образом:
#include <hip/hip_runtime.h>
Кроме правильности результата будет проверяться скорость работы программы. Поэтому в коде, отправляемом на проверку, необходимо оставить ту комбинацию параметров, которая, по вашему мнению, работает быстрее всего.
Результат выполнения лабораторной работы – консольная программа. Результат работы разработанной программы выводится в файл.
В консоль сначала выводиться имя выбранного device (deviceProperties.name, deviceProperties.gcnArchName), затем – версию HIP Runtime, в формате: Device: %s (%s)\tDriver version: %i.
Затем время. Формат вывода времени работы в миллисекундах: Time: %g\t%g, где сначала выводится время работы кернела без учета передачи данных, а затем полное время (замеренное на хосте) работы алгоритма с учетом передачи данных с host на device и обратно (от memCpy до memCpy).
Далее выводится то, что указано в примечаниях работы.
Аргументы программе передаются через командную строку:
lab0.exe – имя исполняемого файла (в C/C++ argv[0]);
--help – команда вывода справки;
--input name – имя входного файла;
--output name – имя выходного файла;
Вместо объявления макросов в hip-файлах, их можно задавать в строке сборки аргументом как preprocessor definition через ключ -D. Это также упрощает процесс тестирования и замеров времени для графиков.
Рекомендуется использовать C или C++ для Host кода. Host-код не должен использовать внешние библиотеки, кроме OpenCL.
Для того, чтобы ваш код отработал у проверяющего, заголовочные файлы OpenCL должны быть подключены следующим образом:
В рамках курса рекомендуется использовать С API, даже если вы пишете на C++.
Кроме правильности результата будет проверяться скорость работы программы. Поэтому в коде, отправляемом на проверку, необходимо оставить ту комбинацию параметров, которая, по вашему мнению, работает быстрее всего.
Результат выполнения лабораторной работы – консольная программа. Результат работы разработанной программы выводится в файл.
В консоль сначала выводиться имя выбранного device (CL_DEVICE_NAME), затем – имя платформы (CL_PLATFORM_NAME), в формате: Device: %s\tPlatform: %s.
Затем время. Формат вывода времени работы в миллисекундах: Time: %g\t%g, где сначала выводится время работы кернела без учета передачи данных, а затем полное время работы алгоритма с учетом передачи данных с host на device и обратно (сумма от cl_event всех clEnqueueXXX функций).
Далее выводится то, что указано в примечаниях работы.
Если необходимо реализовать вариацию алгоритма на хосте (на C/C++ без OpenCL) – выводится время работы алгоритма в формате Time: %g.
Аргументы программе передаются через командную строку:
lab0.exe --help
lab0.exe < --input file_name > \
< --output file_name > \
[ --device-type { dgpu | igpu | gpu | cpu | all } ]
[ --device-index index ]
где:
lab0.exe – имя исполняемого файла (в C/C++ argv[0]);
--help – команда вывода справки;
--input name – имя входного файла;
--output name – имя выходного файла;
--device-type { dgpu | igpu | gpu | cpu | all } – указание типа девайса (дискретная видеокарта, интегрированная видеокарта, процессор, все);
Вместо объявления макросов в cl-файлах, их можно задавать в строке сборки аргументом clBuildProgram как preprocessor definition через ключ -D. Это также упрощает процесс тестирования и замеров времени для графиков.
Девайс по индексу выбирается из всех девайсов на всех доступных платформах, а не на какой-то рандомной. Не забудьте собрать все девайсы со всех платформ перед выбором его по индексу и типу.
Все результаты выводятся в файл, имя которого указано в аргументах командной строки. Вывод результатов в стандартный поток вывода вместо файла (если по заданию нужно записывать результат в файл) или в стандартный поток вывода ошибок вместо стандартного потока вывода приравнивается к непройденному тесту.
Сообщения об ошибках (неверное число аргументов, неправильные параметры программе и пр.) выводятся в стандартный поток вывода ошибок (stderr). Сообщения об ошибках выводятся в поток вывода ошибок по-английски (никакой кириллицы в коде быть не должно, допустимо только в комментариях). Вывод сообщений в стандартный поток вывода приравнивается к непройденному тесту.
Падение программы приравнивается к непройденному тесту, даже если программа в файл или в stdout успела записать верный результат. Падение программы может быть вызвано:
assert
брошенным необработанным исключением
ошибкой в runtime (выход за границы диапазона, обращение к неоткрытому файлу и пр.)
Должны соблюдаться следующие условия:
корректно выделяется и освобождается память;
закрываются файлы;
подано корректное число аргументов на вход программе;
есть обработка ошибок:
не удалось открыть файл.
формат файла не поддерживается. Формат файла != его расширение. Формат - это про то, что внутри файла именно те данные, которые вы ожидаете прочитать (3 числа, например).
не удалось выделить память.
Как не запутаться в условиях, обозначенных выше - ваша программа должна:
освобождать те ресурсы, которые сама выделяет (динамические выделение памяти, файлы)
никогда не падает
и если что-то пошло не так, то сообщает об этом цивилизовано пользователю и завершается
В программе можно использовать только стандартные библиотеки и заголовочные файлы (например, <bits/stdc++.h> таковым не является и его использование влечёт за собой потерю баллов). Модули OpenMP и OpenCL, конечно, разрешены.
Если программа использует функции, которые явно не объявлены в файле с исходным кодом (например, функции из <algorithm> без подключения <algorithm> и пр.), то за это также будут снижаться баллы.
Если вы создаёте свои макросы, то их название не должно быть "DEBUG", "\_DEBUG", "NDEBUG" и прочие, определяемые компиляторами имена. Допустимы любые другие названия из заглавных букв и символов подчёркивания.
Выбор устройства для запуска
Реализация должна поддерживать возможность выбирать device (<номер_девайса>, индексация с 0), на котором будет работать kernel, следующим образом:
Берется весь список доступных девайсов и сортируется в порядке:
Дискретная(ые) видеокарта(ы) dgpu;
Интегрированная видеокарта igpu;
Процессор(ы) cpu;
Все all.
Вместо dgpu и igpu может быть передано значениеgpu, тогда отдельно разбираться дискретные или интегрированные видеокарты не нужно.
Затем девайс определяется по правилу:
если указан device-type, то список фильтруется по указанному типу;
если указан device-index, то index – номер устройства в списке девайсов (если index выходит за пределы числа доступных девайсов, то считаем index = 0)
если указаны оба параметра, то сначала список фильтруется по типу, затем из него выбирается девайс по указанному индексу.
Пример: в конфигурации есть 2 дискретных GPU и 1 процессор.
Случай 1. Указан только device-type dgpu. Тогда кернел запускается на первой найденной дискретной GPU.
Случай 2. Указан только device-index index. Тогда при index = 0 кернел работает на первой найденной GPU, при index = 1 – на второй, при index = 2 – на cpu.
Случай 3. Указаны device-type dgpu device-index index. Тогда при index = 0 кернел работает на первой найденной дискретной GPU, при index = 1 – на второй, при index = 2 – снова на первой дискретной GPU (аналогично index = 0).
Случай 4. Указан device-type igpu. В таком случае пользователь должен увидеть сообщение об ошибке, т.к. интегрированных видеокарт в конфигурации нет и запускаться не на чем.
Порядок устройств одной категории, приведенной выше (например, несколько дискретных видеокарт), не регламентируется.
--device-index – указание порядкового номера девайса (следует обрабатывать как описано в разделе ).
--device-index – указание порядкового номера девайса (следует обрабатывать как описано в разделе ).
--device-index – указание порядкового номера девайса (подробнее ).