Нижегородский государственный университет им. Н.И.Лобачевского
Опубликован: 30.05.2014 | Доступ: свободный | Студентов: 292 / 32 | Длительность: 11:26:00

Самостоятельная работа 1: Компиляция и запуск приложений на Intel Xeon Phi

< Лекция 5 || Самостоятельная работа 1: 123456 || Самостоятельная работа 2 >
Скалярное произведение векторов

Рассмотрим следующую простую задачу: необходимо посчитать скалярное произведение двух векторов.

Создадим файл исходного кода main.cpp. Выполним подключение необходимых библиотек:

#include <stdio.h>
#include <stdlib.h>

Создадим функцию для подсчета скалярного произведения двух векторов. Вычисление будет производиться параллельно на всех доступных ядрах вычислительного устройства. Обратите внимание, что код функции dot не содержит в себе специальных директив для выполнения на Intel Xeon Phi:

#pragma offload_attribute(push, target(mic))

float dot(float* a, float* b, int n)
{
    float res = 0;

    #pragma omp parallel for reduction(+: res)
    for (int i = 0; i < n; ++i)
    {
        res += a[i]*b[i];
    }

    return res;
}

#pragma offload_attribute(pop)

Как и прежде, используем директиву offload_attribute для того, чтобы сообщить компилятору о необходимости создания копии этого участка кода для исполнения на сопроцессоре.

Напишем функцию main для тестирования приведенного выше кода. Прежде всего, объявим используемые переменные и массивы:

int main()
{
    int n = 100;
    float* a = new float[n];
    float* b = new float[n];
    float res_cpu, res_mic;

Затем инициализируем вектора a и b случайными числами:

for (int i = 0; i < n; ++i)
    {
        a[i] = (float)rand()/RAND_MAX;
        b[i] = (float)rand()/RAND_MAX;
    }

Запустим вычисление скалярного произведения на центральном процессоре и выведем результат на консоль:

res_cpu = dot(a, b, n);
    
    printf("CPU dot: %f\n", res_cpu);

Далее необходимо запустить функцию dot на сопроцессоре. Для этого воспользуемся уже знакомой нам директивой offload:

    #pragma offload target(mic) in(a[0:n], b[0:n])
    res_mic = dot(a, b, n);
    
    printf("MIC dot: %f\n", res_mic);

Здесь используется дополнительный параметр in для указания того, что массивы a и b размером n элементов необходимо скопировать на сопроцессор перед началом вычислений, обратного копирования при этом делать не нужно. После окончания вычислений выведем результат на консоль. Обратите внимание, что к моменту вызова функции printf сопроцессор гарантированно завершит свою работу.

Далее осталось только удалить используемую память центрального процессора. Память на сопроцессоре в данном случае будет освобождена автоматически по окончании работы функции dot.

    delete[] a;
    delete[] b;

    return 0;
}

Скомпилируем и запустим полученный код:

icc -02 -openmp main.cpp –o lab1_dot_offload
mpiexec.hydra –perhost 1 ./lab1_dot_offload

Результаты работы программы приведены на рис. 6.4.

Результаты работы программы lab1_dot_offload

Рис. 6.4. Результаты работы программы lab1_dot_offload

В заключение данного раздела покажем, как осуществить запуск offload программы в пакетном режиме без предварительного выделения ресурсов (сопроцессоров). Этот же способ подходит для запуска MPI программы в режиме offload. Будем использовать возможности системы управления кластером SLURM.

Прежде всего, необходимо написать скрипт запуска. Пусть X – число MPI процессов, выполняемых на одном узле кластера, а Y – числа узлов. Тогда скрипт будет таким:

#!/bin/sh
mpiexec.hydra –perhost X –n X*Y ./offload_program

Для постановки задачи в очередь нужно выполнить команды:

module load launcher/intel
sbatch –N Y ./run.sh

где run.sh – имя приведенного выше скрипта. После выполнения этих команд задача будет поставлена в очередь, а после выполнения результаты работы программы будут записаны в файл slurm-<номер задачи>.out. Подробнее о работе команды sbatch можно узнать из следующих разделов.

< Лекция 5 || Самостоятельная работа 1: 123456 || Самостоятельная работа 2 >
Svetlana Svetlana
Svetlana Svetlana

Здравствуйие! Я хочу пройти курс Введение в принципы функционирования и применения современных мультиядерных архитектур (на примере Intel Xeon Phi), в презентации самостоятельной работы №1 указаны логин и пароль для доступ на кластер и выполнения самостоятельных работ, но войти по такой паре логин-пароль не получается. Как предполагается выполнение самосоятельных работ в этом курсе?