Refine task1 Intel LINPACK workflow
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
\usepackage[utf8]{inputenc}
|
\usepackage[utf8]{inputenc}
|
||||||
\usepackage[russian]{babel}
|
\usepackage[russian]{babel}
|
||||||
\usepackage{amsmath}
|
\usepackage{amsmath}
|
||||||
|
\usepackage{amssymb}
|
||||||
\usepackage[left=25mm, top=20mm, right=20mm, bottom=20mm, footskip=10mm]{geometry}
|
\usepackage[left=25mm, top=20mm, right=20mm, bottom=20mm, footskip=10mm]{geometry}
|
||||||
\usepackage{ragged2e} %для растягивания по ширине
|
\usepackage{ragged2e} %для растягивания по ширине
|
||||||
\usepackage{setspace} %для межстрочного интервала
|
\usepackage{setspace} %для межстрочного интервала
|
||||||
@@ -53,6 +54,19 @@
|
|||||||
\usepackage{enumitem} %для перечислений
|
\usepackage{enumitem} %для перечислений
|
||||||
|
|
||||||
\newcommand{\specialcell}[2][l]{\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}
|
\newcommand{\specialcell}[2][l]{\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}
|
||||||
|
\newcommand{\imgplaceholder}[2][0.9\textwidth]{%
|
||||||
|
\IfFileExists{#2}{%
|
||||||
|
\includegraphics[width=#1]{#2}%
|
||||||
|
}{%
|
||||||
|
\fbox{%
|
||||||
|
\parbox[c][0.22\textheight][c]{0.82\textwidth}{%
|
||||||
|
\centering
|
||||||
|
Заглушка для изображения\\
|
||||||
|
\texttt{#2}%
|
||||||
|
}%
|
||||||
|
}%
|
||||||
|
}%
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
\setlist[enumerate,itemize]{leftmargin=1.2cm} %отступ в перечислениях
|
\setlist[enumerate,itemize]{leftmargin=1.2cm} %отступ в перечислениях
|
||||||
@@ -190,9 +204,195 @@
|
|||||||
|
|
||||||
\subsection{Постановка задачи}
|
\subsection{Постановка задачи}
|
||||||
|
|
||||||
|
В рамках первого задания требовалось исследовать производительность вычислительной системы при решении плотной системы линейных алгебраических уравнений и сопоставить результаты собственной реализации с эталонным тестом LINPACK. Для достижения этой цели были поставлены следующие задачи:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item изучить подходы к оценке производительности вычислительных систем;
|
||||||
|
\item разработать собственную CUDA-реализацию LINPACK-подобного теста;
|
||||||
|
\item выполнить экспериментальные запуски на вычислительном узле СКЦ Политехнический;
|
||||||
|
\item сравнить результаты собственной программы и стандартного Intel LINPACK.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
В данной работе все скриншоты и вычислительные эксперименты выполнялись под учётной записью \texttt{tm3u21}. Этот логин должен быть виден на скриншоте входа в систему и на терминальных снимках, приложенных к отчёту.
|
||||||
|
|
||||||
|
\subsection{Математическое описание}
|
||||||
|
|
||||||
|
Тест LINPACK применяется для оценки производительности вычислительных систем при решении плотной системы линейных уравнений \cite{dongarra2003linpack}. Рассматривается задача
|
||||||
|
\begin{equation}
|
||||||
|
A x = b,
|
||||||
|
\end{equation}
|
||||||
|
где $A \in \mathbb{R}^{n \times n}$ --- плотная квадратная матрица, $x \in \mathbb{R}^{n}$ --- искомый вектор решения, $b \in \mathbb{R}^{n}$ --- вектор правой части.
|
||||||
|
|
||||||
|
В классическом варианте LINPACK обычно применяются прямые методы, основанные на LU-разложении \cite{golub2013matrix}. В собственной реализации для первого задания использован итерационный метод Якоби, так как он хорошо распараллеливается на GPU: каждая строка матрицы может обрабатываться независимо \cite{saad2003iterative}.
|
||||||
|
|
||||||
|
Для метода Якоби очередное приближение вычисляется по формуле
|
||||||
|
\begin{equation}
|
||||||
|
x_i^{(k+1)} = \frac{1}{a_{ii}} \left( b_i - \sum\limits_{j \ne i} a_{ij} x_j^{(k)} \right), \quad i = 1, 2, \dots, n.
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
Критерий остановки выбран в виде
|
||||||
|
\begin{equation}
|
||||||
|
\max_i \left| x_i^{(k+1)} - x_i^{(k)} \right| \le \varepsilon.
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
Чтобы обеспечить сходимость метода, в программе формируется строго диагонально доминирующая матрица. Для контроля качества решения дополнительно вычисляются:
|
||||||
|
\begin{equation}
|
||||||
|
\| A x - b \|_{\infty},
|
||||||
|
\end{equation}
|
||||||
|
\begin{equation}
|
||||||
|
\| x - x_{true} \|_{\infty},
|
||||||
|
\end{equation}
|
||||||
|
где $x_{true}$ --- заранее известное опорное решение, использованное при построении тестовой системы.
|
||||||
|
|
||||||
|
Для приближённой оценки производительности используется LINPACK-подобная метрика
|
||||||
|
\begin{equation}
|
||||||
|
R = \frac{\frac{2}{3} n^3}{t},
|
||||||
|
\end{equation}
|
||||||
|
где $t$ --- время решения, измеренное в секундах. В отчёте далее используется величина $R$ в GFLOPS.
|
||||||
|
|
||||||
|
\subsection{Особенности реализации}
|
||||||
|
|
||||||
|
Собственная программа реализована на CUDA C++ и находится в файле \texttt{task1/src/main.cu}. В реализации приняты следующие решения:
|
||||||
|
\begin{itemize}
|
||||||
|
\item для каждой строки матрицы запускается отдельный поток CUDA, который вычисляет новое значение одной компоненты вектора решения;
|
||||||
|
\item матрица $A$ и вектор $b$ один раз копируются на устройство, а далее итерационный процесс выполняется на GPU;
|
||||||
|
\item завершение итераций контролируется через флаг \texttt{converged}, который может быть сброшен любым потоком, если изменение соответствующей компоненты превысило $\varepsilon$;
|
||||||
|
\item после завершения расчёта на стороне CPU вычисляются невязка и ошибка относительно заранее известного решения;
|
||||||
|
\item для удобства дальнейшего анализа программа может сохранять результаты в CSV-файл.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Такой вариант не является буквальной реализацией классического LU-LINPACK, однако решает ту же прикладную задачу --- измерение производительности при решении плотной СЛАУ --- и позволяет исследовать эффективность распараллеливания на GPU.
|
||||||
|
|
||||||
|
\subsection{Сборка и запуск}
|
||||||
|
|
||||||
|
Подготовленные файлы для выполнения задания расположены в каталоге \texttt{task1/}. Сборка и запуск на СКЦ выполняются по шагам:
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
scp -r task1 polytech:~/supercomputers/
|
||||||
|
ssh polytech
|
||||||
|
cd ~/supercomputers/task1
|
||||||
|
sbatch scripts/run_cuda.slurm
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Скрипт \texttt{scripts/run\_cuda.slurm} автоматически:
|
||||||
|
\begin{itemize}
|
||||||
|
\item загружает модули \texttt{compiler/gcc/11} и \texttt{nvidia/cuda/11.6u2};
|
||||||
|
\item собирает программу через \texttt{nvcc};
|
||||||
|
\item печатает в лог данные учётной записи, имя узла, дату, параметры Slurm и конфигурацию узла;
|
||||||
|
\item запускает набор экспериментов и сохраняет CSV с численными результатами.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Для запуска эталонного CPU-варианта Intel LINPACK используется отдельный пакетный скрипт:
|
||||||
|
\begin{lstlisting}
|
||||||
|
скачать архив Intel oneMKL Benchmarks Suite for Linux с официального сайта Intel
|
||||||
|
scp linpack.tgz polytech:~/linpack.tgz
|
||||||
|
ssh polytech
|
||||||
|
mkdir -p ~/LINPACK
|
||||||
|
tar -xzf ~/linpack.tgz -C ~/LINPACK
|
||||||
|
find ~/LINPACK -name xlinpack_xeon64 2>/dev/null
|
||||||
|
cd <каталог_с_xlinpack_xeon64>
|
||||||
|
mkdir -p stdio
|
||||||
|
chmod +x *
|
||||||
|
chmod -x *.*
|
||||||
|
cd ~/supercomputers/task1
|
||||||
|
sbatch --export=ALL,LINPACK_DIR=<каталог_с_xlinpack_xeon64> \
|
||||||
|
/home/ipmmstudy1/tm3u21/supercomputers/task1/scripts/run_intel_linpack.slurm
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
При этом в пакетном сценарии используется собственный входной файл \texttt{task1/intel/lininput\_report\_xeon64}, в котором заданы те же размеры задач, что и для CUDA-реализации: $1000$, $1500$, $2000$, $2500$, $3000$, $3500$. Это позволяет напрямую перенести результаты Intel LINPACK в сравнительную таблицу.
|
||||||
|
|
||||||
|
Сведения о завершённых заданиях рекомендуется получать командой:
|
||||||
|
\begin{lstlisting}
|
||||||
|
sacct -j <job_id> --format=JobID,JobName,Partition,State,Start,End,Elapsed,NNodes,AllocTRES%40,NodeList,ExitCode
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Именно эти данные затем используются в отчёте как подтверждение времени выполнения, количества задействованных узлов и их идентификаторов.
|
||||||
|
|
||||||
|
\subsection{Результаты эксперимента}
|
||||||
|
|
||||||
|
Для корректного оформления отчёта необходимо приложить скриншоты, подтверждающие, что эксперименты выполнялись именно в учётной записи \texttt{tm3u21}. В подготовленном шаблоне отчёта для этого предусмотрены следующие изображения:
|
||||||
|
\begin{itemize}
|
||||||
|
\item скрин входа в систему с командами \texttt{whoami}, \texttt{hostname}, \texttt{date};
|
||||||
|
\item скрин конфигурации узла и GPU из лога CUDA-задания;
|
||||||
|
\item скрин таблицы результатов собственной CUDA-реализации;
|
||||||
|
\item скрин \texttt{sacct} для CUDA-задания;
|
||||||
|
\item скрин запуска и итогов Intel LINPACK;
|
||||||
|
\item скрин \texttt{sacct} для Intel LINPACK.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\imgplaceholder{img/task1-login.png}
|
||||||
|
\caption{Подключение к СКЦ Политехнический под учётной записью \texttt{tm3u21}}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\imgplaceholder{img/task1-cuda-node.png}
|
||||||
|
\caption{Конфигурация узла и графического ускорителя, использованных для CUDA-эксперимента}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\imgplaceholder{img/task1-cuda-run.png}
|
||||||
|
\caption{Вывод собственной CUDA-реализации теста}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\imgplaceholder{img/task1-cuda-sacct.png}
|
||||||
|
\caption{Сведения Slurm о выполнении собственной CUDA-реализации}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\imgplaceholder{img/task1-intel-run.png}
|
||||||
|
\caption{Запуск и результаты стандартного Intel LINPACK}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\imgplaceholder{img/task1-intel-sacct.png}
|
||||||
|
\caption{Сведения Slurm о выполнении Intel LINPACK}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
На момент подготовки отчёта успешно выполнен CUDA-запуск задания \texttt{6616336} на узле \texttt{n02p009}. Для него получены корректные значения времени, производительности и точности решения. Попытка запуска Intel LINPACK заданием \texttt{6616338} завершилась неуспешно из-за отсутствия бинарного файла \texttt{xlinpack\_xeon64} по ожидаемому пути; после уточнения реального расположения пакета на кластере столбцы Intel LINPACK могут быть заполнены без изменения остальной структуры отчёта.
|
||||||
|
|
||||||
|
Численные результаты удобно свести в таблицу \ref{tab:task1-results}. Значения для столбцов CUDA берутся из файла \texttt{results/task1-cuda-6616336.csv}, а значения для столбцов Intel LINPACK --- из секции \texttt{Performance Summary} в выходном файле CPU-задания после успешного запуска.
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\centering
|
||||||
|
\caption{Сравнение собственной CUDA-реализации и Intel LINPACK}
|
||||||
|
\label{tab:task1-results}
|
||||||
|
\begin{tabular}{cccccccc}
|
||||||
|
\toprule
|
||||||
|
$N$ & $t_{CUDA}$, мс & Iter & $\|Ax-b\|_{\infty}$ & $R_{CUDA}$, GFLOPS & $t_{Intel}$, c & $R_{Intel}$, GFLOPS & $S_t$ \\
|
||||||
|
\midrule
|
||||||
|
1000 & 5.0083 & 6 & $2.242 \cdot 10^{-6}$ & 133.114 & -- & -- & -- \\
|
||||||
|
1500 & 7.4931 & 6 & $1.107 \cdot 10^{-6}$ & 300.277 & -- & -- & -- \\
|
||||||
|
2000 & 8.3563 & 5 & $2.443 \cdot 10^{-5}$ & 638.244 & -- & -- & -- \\
|
||||||
|
2500 & 10.4837 & 5 & $1.593 \cdot 10^{-5}$ & 993.608 & -- & -- & -- \\
|
||||||
|
3000 & 12.6709 & 5 & $1.288 \cdot 10^{-5}$ & 1420.573 & -- & -- & -- \\
|
||||||
|
3500 & 14.8861 & 5 & $9.516 \cdot 10^{-6}$ & 1920.138 & -- & -- & -- \\
|
||||||
|
\bottomrule
|
||||||
|
\end{tabular}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
По уже полученным данным CUDA-реализации можно сделать предварительные наблюдения:
|
||||||
|
\begin{itemize}
|
||||||
|
\item все тестовые случаи для размеров от $1000$ до $3500$ успешно сошлись за $5$--$6$ итераций;
|
||||||
|
\item время решения возрастает плавно: от $5.0083$ мс при $N = 1000$ до $14.8861$ мс при $N = 3500$;
|
||||||
|
\item производительность в GFLOPS монотонно увеличивается и достигает $1920.138$ GFLOPS на размере $N = 3500$;
|
||||||
|
\item ошибка по известному решению остаётся на уровне порядка $10^{-9}$--$10^{-8}$, а невязка --- на уровне $10^{-6}$--$10^{-5}$, что подтверждает корректность полученного решения.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
\subsection{Выводы}
|
\subsection{Выводы}
|
||||||
|
|
||||||
|
В рамках первого задания была подготовлена собственная CUDA-реализация LINPACK-подобного теста для решения плотной СЛАУ методом Якоби. Программа поддерживает запуск серии экспериментов, измерение времени выполнения, оценку производительности в GFLOPS, а также вычисление невязки и ошибки относительно известного точного решения.
|
||||||
|
|
||||||
|
Дополнительно были подготовлены сценарии пакетного запуска на СКЦ Политехнический: отдельный скрипт для собственной CUDA-реализации и отдельный скрипт для стандартного Intel LINPACK. Это позволяет провести воспроизводимое сравнение двух подходов и получить необходимые для отчёта доказательства выполнения работы: логин пользователя, конфигурацию узла, время выполнения и число задействованных узлов.
|
||||||
|
|
||||||
|
На текущем этапе можно зафиксировать, что собственная CUDA-реализация корректно работает на узле \texttt{tornado-k40}, обеспечивает сходимость на всём исследованном диапазоне размеров и достигает производительности до $1920.138$ GFLOPS. После успешного запуска Intel LINPACK останется дополнить сравнительную часть таблицы \ref{tab:task1-results} и окончательно сформулировать вывод о преимуществе или проигрыше GPU-варианта относительно эталонного CPU-теста.
|
||||||
|
|
||||||
|
|
||||||
\section{Задача 2}
|
\section{Задача 2}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ cd ~/supercomputers/task1
|
|||||||
sbatch --export=ALL,LINPACK_DIR=<НУЖНЫЙ_КАТАЛОГ_С_XLINPACK> scripts/run_intel_linpack.slurm
|
sbatch --export=ALL,LINPACK_DIR=<НУЖНЫЙ_КАТАЛОГ_С_XLINPACK> scripts/run_intel_linpack.slurm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
По умолчанию скрипт использует файл `task1/intel/lininput_report_xeon64`, где уже зафиксированы размеры
|
||||||
|
`1000 1500 2000 2500 3000 3500`, чтобы Intel LINPACK можно было напрямую сравнить с вашей CUDA-реализацией в отчёте.
|
||||||
|
|
||||||
8. Проверь статус:
|
8. Проверь статус:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -136,6 +139,8 @@ sacct -j <JOBID_INTEL> --format=JobID,JobName,Partition,State,Start,End,Elapsed,
|
|||||||
less <НУЖНЫЙ_КАТАЛОГ_С_XLINPACK>/stdio/task1-intel-linpack-<JOBID_INTEL>.out
|
less <НУЖНЫЙ_КАТАЛОГ_С_XLINPACK>/stdio/task1-intel-linpack-<JOBID_INTEL>.out
|
||||||
```
|
```
|
||||||
|
|
||||||
|
В этом файле ищи строки с размерами `1000`, `1500`, `2000`, `2500`, `3000`, `3500`, а внизу --- секцию `Performance Summary`.
|
||||||
|
|
||||||
## Что нужно собрать для отчёта
|
## Что нужно собрать для отчёта
|
||||||
|
|
||||||
Ниже последовательность, которая даст все обязательные материалы для отчёта и скриншотов.
|
Ниже последовательность, которая даст все обязательные материалы для отчёта и скриншотов.
|
||||||
@@ -196,7 +201,7 @@ cat results/task1-cuda-<JOBID_CUDA>.csv
|
|||||||
Для Intel LINPACK значения времени и GFLOPS бери из:
|
Для Intel LINPACK значения времени и GFLOPS бери из:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
less results/task1-intel-linpack-<JOBID_INTEL>.out
|
less ~/supercomputers/task1/stdio/task1-intel-linpack-<JOBID_INTEL>.out
|
||||||
```
|
```
|
||||||
|
|
||||||
Ищи секцию `Performance Summary`.
|
Ищи секцию `Performance Summary`.
|
||||||
|
|||||||
7
task1/intel/lininput_report_xeon64
Normal file
7
task1/intel/lininput_report_xeon64
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Shared-memory version of Intel(R) Distribution for LINPACK* Benchmark. *Other names and brands may be claimed as the property of others.
|
||||||
|
Custom data file for task1 report.
|
||||||
|
6 # number of tests
|
||||||
|
1000 1500 2000 2500 3000 3500 # problem sizes
|
||||||
|
1000 1504 2000 2504 3000 3504 # leading dimensions
|
||||||
|
8 6 6 5 5 5 # times to run a test
|
||||||
|
4 4 4 4 4 4 # alignment values (in KBytes)
|
||||||
@@ -10,10 +10,11 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
TASK1_DIR="${SLURM_SUBMIT_DIR:-$PWD}"
|
||||||
module purge
|
module purge
|
||||||
|
|
||||||
LINPACK_DIR="${LINPACK_DIR:-$HOME/LINPACK}"
|
LINPACK_DIR="${LINPACK_DIR:-$HOME/LINPACK}"
|
||||||
LINPACK_INPUT="${LINPACK_INPUT:-lininput_xeon64}"
|
LINPACK_INPUT="${LINPACK_INPUT:-$TASK1_DIR/intel/lininput_report_xeon64}"
|
||||||
|
|
||||||
if [ ! -d "${LINPACK_DIR}" ]; then
|
if [ ! -d "${LINPACK_DIR}" ]; then
|
||||||
echo "LINPACK directory not found: ${LINPACK_DIR}"
|
echo "LINPACK directory not found: ${LINPACK_DIR}"
|
||||||
@@ -78,6 +79,7 @@ fi
|
|||||||
echo
|
echo
|
||||||
echo "===== intel linpack ====="
|
echo "===== intel linpack ====="
|
||||||
echo "LINPACK_DIR=${LINPACK_DIR}"
|
echo "LINPACK_DIR=${LINPACK_DIR}"
|
||||||
|
echo "LINPACK_INPUT=${LINPACK_INPUT}"
|
||||||
export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK:-56}"
|
export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK:-56}"
|
||||||
export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK:-56}"
|
export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK:-56}"
|
||||||
|
|
||||||
|
|||||||
1
task1/stdio/.gitkeep
Normal file
1
task1/stdio/.gitkeep
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
Reference in New Issue
Block a user