From 0ea5f541944d0999a93fb4503bda388c5b6ff466 Mon Sep 17 00:00:00 2001 From: Arity-T Date: Mon, 16 Mar 2026 18:44:11 +0300 Subject: [PATCH] Refine task1 Intel LINPACK workflow --- report/report.tex | 202 +++++++++++++++++++++++++- task1/README.md | 7 +- task1/intel/lininput_report_xeon64 | 7 + task1/scripts/run_intel_linpack.slurm | 4 +- task1/stdio/.gitkeep | 1 + 5 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 task1/intel/lininput_report_xeon64 create mode 100644 task1/stdio/.gitkeep diff --git a/report/report.tex b/report/report.tex index 622d096..c45d97c 100755 --- a/report/report.tex +++ b/report/report.tex @@ -7,6 +7,7 @@ \usepackage[utf8]{inputenc} \usepackage[russian]{babel} \usepackage{amsmath} +\usepackage{amssymb} \usepackage[left=25mm, top=20mm, right=20mm, bottom=20mm, footskip=10mm]{geometry} \usepackage{ragged2e} %для растягивания по ширине \usepackage{setspace} %для межстрочного интервала @@ -53,6 +54,19 @@ \usepackage{enumitem} %для перечислений \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} %отступ в перечислениях @@ -190,9 +204,195 @@ \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 --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{Выводы} +В рамках первого задания была подготовлена собственная CUDA-реализация LINPACK-подобного теста для решения плотной СЛАУ методом Якоби. Программа поддерживает запуск серии экспериментов, измерение времени выполнения, оценку производительности в GFLOPS, а также вычисление невязки и ошибки относительно известного точного решения. + +Дополнительно были подготовлены сценарии пакетного запуска на СКЦ Политехнический: отдельный скрипт для собственной CUDA-реализации и отдельный скрипт для стандартного Intel LINPACK. Это позволяет провести воспроизводимое сравнение двух подходов и получить необходимые для отчёта доказательства выполнения работы: логин пользователя, конфигурацию узла, время выполнения и число задействованных узлов. + +На текущем этапе можно зафиксировать, что собственная CUDA-реализация корректно работает на узле \texttt{tornado-k40}, обеспечивает сходимость на всём исследованном диапазоне размеров и достигает производительности до $1920.138$ GFLOPS. После успешного запуска Intel LINPACK останется дополнить сравнительную часть таблицы \ref{tab:task1-results} и окончательно сформулировать вывод о преимуществе или проигрыше GPU-варианта относительно эталонного CPU-теста. + \section{Задача 2} @@ -206,4 +406,4 @@ \printbibliography[heading=bibintoc] -\end{document} \ No newline at end of file +\end{document} diff --git a/task1/README.md b/task1/README.md index 5b25dd9..05195f9 100644 --- a/task1/README.md +++ b/task1/README.md @@ -124,6 +124,9 @@ cd ~/supercomputers/task1 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. Проверь статус: ```bash @@ -136,6 +139,8 @@ sacct -j --format=JobID,JobName,Partition,State,Start,End,Elapsed, less <НУЖНЫЙ_КАТАЛОГ_С_XLINPACK>/stdio/task1-intel-linpack-.out ``` +В этом файле ищи строки с размерами `1000`, `1500`, `2000`, `2500`, `3000`, `3500`, а внизу --- секцию `Performance Summary`. + ## Что нужно собрать для отчёта Ниже последовательность, которая даст все обязательные материалы для отчёта и скриншотов. @@ -196,7 +201,7 @@ cat results/task1-cuda-.csv Для Intel LINPACK значения времени и GFLOPS бери из: ```bash -less results/task1-intel-linpack-.out +less ~/supercomputers/task1/stdio/task1-intel-linpack-.out ``` Ищи секцию `Performance Summary`. diff --git a/task1/intel/lininput_report_xeon64 b/task1/intel/lininput_report_xeon64 new file mode 100644 index 0000000..4585d96 --- /dev/null +++ b/task1/intel/lininput_report_xeon64 @@ -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) diff --git a/task1/scripts/run_intel_linpack.slurm b/task1/scripts/run_intel_linpack.slurm index 69d253f..491c728 100755 --- a/task1/scripts/run_intel_linpack.slurm +++ b/task1/scripts/run_intel_linpack.slurm @@ -10,10 +10,11 @@ set -euo pipefail +TASK1_DIR="${SLURM_SUBMIT_DIR:-$PWD}" module purge 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 echo "LINPACK directory not found: ${LINPACK_DIR}" @@ -78,6 +79,7 @@ fi echo echo "===== intel linpack =====" echo "LINPACK_DIR=${LINPACK_DIR}" +echo "LINPACK_INPUT=${LINPACK_INPUT}" export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK:-56}" export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK:-56}" diff --git a/task1/stdio/.gitkeep b/task1/stdio/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/task1/stdio/.gitkeep @@ -0,0 +1 @@ +