init
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
*.fls
|
||||||
|
*.log
|
||||||
|
*.aux
|
||||||
|
*.fdb_latexmk
|
||||||
|
*.bbl
|
||||||
|
*.blg
|
||||||
|
main.synctex.gz
|
||||||
|
*.toc
|
||||||
657
BYUPhys.cls
Normal file
@@ -0,0 +1,657 @@
|
|||||||
|
% Revision: 07-25-2007
|
||||||
|
% Revision History
|
||||||
|
% 07-10-2008 : Corrected Alignment of signature boxes on Masters/PhD Approval page
|
||||||
|
% 07-25-2007 : Corrected some spelling errors
|
||||||
|
% 05-16-2006 : Added etd option and moved most packages from class file to template
|
||||||
|
% 05-15-2006 : Initial version.
|
||||||
|
%
|
||||||
|
% Known bugs
|
||||||
|
% Having a tiny bit of the abstract spill to second page defeats page number removal.
|
||||||
|
% Workaround: make the abstract a little longer or a little shorter.
|
||||||
|
%
|
||||||
|
% The BYUPhys class is for producing theses and dissertations
|
||||||
|
% in the BYU department of physics and astronomy. You can supply
|
||||||
|
% the following optional arguments in the square brackets to
|
||||||
|
% specify the thesis type:
|
||||||
|
%
|
||||||
|
% senior : Produces the senior thesis preliminary pages (default)
|
||||||
|
% honors : Produces the honors thesis preliminary pages
|
||||||
|
% masters : Produces the masters thesis preliminary pages
|
||||||
|
% phd : Produces the PhD dissertation preliminary pages
|
||||||
|
%
|
||||||
|
% The default format is appropriate for printing, with blank pages
|
||||||
|
% inserted after the preliminary pages in twoside mode so you can
|
||||||
|
% send it directly to a two-sided printer. However, for ETD
|
||||||
|
% submission the blank pages need to be removed from the final output.
|
||||||
|
% The following option does this:
|
||||||
|
%
|
||||||
|
% etd : Produces an electronic copy with no blank pages in the preliminary section
|
||||||
|
%
|
||||||
|
% The rest of the class options are the same as the regular book class.
|
||||||
|
% A few to remember:
|
||||||
|
%
|
||||||
|
% oneside : Produces single sided print layout (recommended for theses less than 50 pages)
|
||||||
|
% twoside : Produces single sided print layout (the default if you remove oneside)
|
||||||
|
%
|
||||||
|
% The BYUPhys class provides the following macros:
|
||||||
|
%
|
||||||
|
% \makepreliminarypages : Makes the preliminary pages
|
||||||
|
% \clearemptydoublepage : same as \cleardoublepage but doesn't put page numbers
|
||||||
|
% on blank intervening pages
|
||||||
|
% \singlespace : switch to single spaced lines
|
||||||
|
% \doublespace : switch to double spaced lines
|
||||||
|
%
|
||||||
|
% ------------------------------------------------------------------------------------------------------
|
||||||
|
%
|
||||||
|
\NeedsTeXFormat{LaTeX2e} \ProvidesClass{BYUPhys}
|
||||||
|
|
||||||
|
% ---------------------------- declarations -------------------------
|
||||||
|
%
|
||||||
|
% These macros are used to declare arguments needed for the
|
||||||
|
% construction of the preliminary pages
|
||||||
|
|
||||||
|
% The year and month the degree is awarded
|
||||||
|
\newcommand{\University}[1]{\gdef\@University{#1}}
|
||||||
|
\newcommand{\Faculty}[1]{\gdef\@Faculty{#1}}
|
||||||
|
\newcommand{\Chair}[1]{\gdef\@Chair{#1}}
|
||||||
|
\newcommand{\Lab}[1]{\gdef\@Lab{#1}}
|
||||||
|
|
||||||
|
\newcommand{\GrText}[1]{\gdef\@GrText{#1}}
|
||||||
|
\newcommand{\AcadGroup}[1]{\gdef\@AcadGroup{#1}}
|
||||||
|
\newcommand{\AdvisorText}[1]{\gdef\@AdvisorText{#1}}
|
||||||
|
\newcommand{\ConsultantText}[1]{\gdef\@ConsultantText{#1}}
|
||||||
|
|
||||||
|
\newcommand{\ApprovalText}[1]{\gdef\@ApprovalText{#1}}
|
||||||
|
\newcommand{\ApprovalAText}[1]{\gdef\@ApprovalAText{#1}}
|
||||||
|
\newcommand{\ApprovalBText}[1]{\gdef\@ApprovalBText{#1}}
|
||||||
|
|
||||||
|
\newcommand{\DateText}[1]{\gdef\@DateText{#1}}
|
||||||
|
|
||||||
|
\newcommand{\Year}[1]{\gdef\@Year{#1}}
|
||||||
|
\newcommand{\Month}[1]{\gdef\@Month{#1}}
|
||||||
|
\newcommand{\City}[1]{\gdef\@City{#1}}
|
||||||
|
|
||||||
|
% The full name of the degree
|
||||||
|
\newcommand{\degree}[1]{\gdef\@degree{#1}}
|
||||||
|
|
||||||
|
% The name of this document (thesis/dissertation)
|
||||||
|
\newcommand{\docname}[1]{\gdef\@docname{#1}}
|
||||||
|
|
||||||
|
% First line of title
|
||||||
|
%\newcommand{\TitleTop}[1]{\gdef\@TitleTop{\mbox{\uppercase{#1}}}}
|
||||||
|
\newcommand{\TitleTop}[1]{\gdef\@TitleTop{\mbox{#1}}}
|
||||||
|
\newcommand{\TitleTopEng}[1]{\gdef\@TitleTopEng{\mbox{#1}}}
|
||||||
|
|
||||||
|
% Second line of title
|
||||||
|
\newcommand{\TitleMiddle}[1]{\gdef\@TitleMiddle{\mbox{#1}}}
|
||||||
|
\newcommand{\TitleMiddleEng}[1]{\gdef\@TitleMiddleEng{\mbox{#1}}}
|
||||||
|
|
||||||
|
% Third line of title
|
||||||
|
\newcommand{\TitleBottom}[1]{\gdef\@TitleBottom{\mbox{#1}}}
|
||||||
|
\newcommand{\TitleBottomEng}[1]{\gdef\@TitleBottomEng{\mbox{#1}}}
|
||||||
|
|
||||||
|
% Title page text
|
||||||
|
\newcommand{\TitlePageText}[1]{\gdef\@TitlePageText{#1}}
|
||||||
|
|
||||||
|
% Abstract text
|
||||||
|
\newcommand{\Abstract}[1]{\gdef\@Abstract{#1}}
|
||||||
|
\newcommand{\AbstractEng}[1]{\gdef\@AbstractEng{#1}}
|
||||||
|
\newcommand{\AbstractText}[1]{\gdef\@AbstractText{#1}}
|
||||||
|
|
||||||
|
% Acknowledgments text
|
||||||
|
\newcommand{\Acknowledgments}[1]{\gdef\@Acknowledgments{#1}}
|
||||||
|
\newcommand{\AcknowledgmentsText}[1]{\gdef\@AcknowledgmentsText{#1}}
|
||||||
|
|
||||||
|
% The author's name
|
||||||
|
\newcommand{\AuthorText}[1]{\gdef\@AuthorText{#1}}
|
||||||
|
\newcommand{\Author}[1]{\gdef\@Author{#1}}
|
||||||
|
\newcommand{\AuthorEng}[1]{\gdef\@AuthorEng{#1}}
|
||||||
|
\newcommand{\AuthorGenitiveCase}[1]{\gdef\@AuthorGenitiveCase{#1}}
|
||||||
|
|
||||||
|
% The name of the advisor
|
||||||
|
\newcommand{\Advisor}[1]{\gdef\@Advisor{#1}}
|
||||||
|
\newcommand{\AdvisorDegree}[1]{\gdef\@AdvisorDegree{#1}}
|
||||||
|
|
||||||
|
% The name of the consultant
|
||||||
|
\newcommand{\Consultant}[1]{\gdef\@Consultant{#1}}
|
||||||
|
\newcommand{\ConsultantDegree}[1]{\gdef\@ConsultantDegree{#1}}
|
||||||
|
|
||||||
|
% The name of the committee member 2
|
||||||
|
\newcommand{\MemberA}[1]{\gdef\@MemberA{#1}}
|
||||||
|
|
||||||
|
% The name of the committee member 3
|
||||||
|
\newcommand{\MemberB}[1]{\gdef\@MemberB{#1}}
|
||||||
|
|
||||||
|
% The name of the committee member 4
|
||||||
|
\newcommand{\MemberC}[1]{\gdef\@MemberC{#1}}
|
||||||
|
|
||||||
|
% The name of the committee member 5
|
||||||
|
\newcommand{\MemberD}[1]{\gdef\@MemberD{#1}}
|
||||||
|
|
||||||
|
% The name of the department chair
|
||||||
|
\newcommand{\DepRep}[1]{\gdef\@DepRep{#1}}
|
||||||
|
|
||||||
|
% The title of the department chair (allow for associate chair, etc.)
|
||||||
|
\newcommand{\DepRepTitle}[1]{\gdef\@DepRepTitle{#1}}
|
||||||
|
|
||||||
|
% The name of the department undergraduate coordinator
|
||||||
|
\newcommand{\UgradCoord}[1]{\gdef\@UgradCoord{#1}}
|
||||||
|
|
||||||
|
% The name of the dean
|
||||||
|
\newcommand{\Dean}[1]{\gdef\@Dean{#1}}
|
||||||
|
|
||||||
|
% The title of the dean
|
||||||
|
\newcommand{\DeanTitle}[1]{\gdef\@DeanTitle{#1}}
|
||||||
|
|
||||||
|
% The name of the honors dean
|
||||||
|
\newcommand{\HonorsDean}[1]{\gdef\@HonorsDean{#1}}
|
||||||
|
|
||||||
|
% Set default values for fields
|
||||||
|
\University{2010}
|
||||||
|
\Year{2010}
|
||||||
|
\Month{Month}
|
||||||
|
\Author{Author}
|
||||||
|
\TitleTop{Title}
|
||||||
|
% \Abstract{Abstract text goes here.}
|
||||||
|
% \Acknowledgments{Acknowledgment text goes here.}
|
||||||
|
% \degree{Bachelor of Science}
|
||||||
|
\docname{Master Thesis}
|
||||||
|
\Advisor{Advisor}
|
||||||
|
\MemberA{Committee Member A}
|
||||||
|
\MemberB{Committee Member B}
|
||||||
|
\MemberC{Committee Member C}
|
||||||
|
\MemberD{Committee Member D}
|
||||||
|
\DepRep{Department Chair Name}
|
||||||
|
\DepRepTitle{Chair}
|
||||||
|
\Dean{Dean Name}
|
||||||
|
\DeanTitle{Associate Dean}
|
||||||
|
\HonorsDean{Honors Dean Name}
|
||||||
|
\UgradCoord{Department Ugrad Coordinator }
|
||||||
|
|
||||||
|
% ---------------------------- options ------------------------------
|
||||||
|
|
||||||
|
% A command to switch to single spaced lines
|
||||||
|
\newcommand{\singlespace}{\renewcommand{\baselinestretch}{1}\small\normalsize}
|
||||||
|
|
||||||
|
\newcommand{\oneandhalfspace}{\renewcommand{\baselinestretch}{1.33}\small\normalsize}
|
||||||
|
|
||||||
|
% A command to switch to double spaced lines
|
||||||
|
\newcommand{\doublespace}{\renewcommand{\baselinestretch}{1.66}\small\normalsize}
|
||||||
|
|
||||||
|
% A command pirated from chngpage.sty
|
||||||
|
\DeclareRobustCommand{\ch@ngetext}{%
|
||||||
|
\setlength{\@colht}{\textheight}\setlength{\@colroom}{\textheight}%
|
||||||
|
\setlength{\vsize}{\textheight}\setlength{\columnwidth}{\textwidth}%
|
||||||
|
\if@twocolumn%
|
||||||
|
\advance\columnwidth-\columnsep \divide\columnwidth\tw@%
|
||||||
|
\@firstcolumntrue%
|
||||||
|
\fi%
|
||||||
|
\setlength{\hsize}{\columnwidth}%
|
||||||
|
\setlength{\linewidth}{\hsize}%
|
||||||
|
}
|
||||||
|
|
||||||
|
% A command to make margins right for the initial single sided business.
|
||||||
|
\newcommand{\preliminarymargins}{%
|
||||||
|
\addtolength{\textwidth}{-0.5in}%
|
||||||
|
\addtolength{\evensidemargin}{0.5in}%
|
||||||
|
\ch@ngetext%
|
||||||
|
}
|
||||||
|
|
||||||
|
% A command to fix the margins after the initial single sided business.
|
||||||
|
\newcommand{\fixmargins}{%
|
||||||
|
\addtolength{\textwidth}{0.5in}
|
||||||
|
\addtolength{\evensidemargin}{-0.5in}
|
||||||
|
\ch@ngetext%
|
||||||
|
}
|
||||||
|
|
||||||
|
% Define the preliminary section for a senior thesis.
|
||||||
|
% The senior option is essentially ignored since it is the default
|
||||||
|
\newcommand{\makepreliminarypages}{
|
||||||
|
\preliminarymargins
|
||||||
|
\titlepage
|
||||||
|
%\copyrightpage
|
||||||
|
%\seniorapprovalpage
|
||||||
|
\abstractpage
|
||||||
|
\fixmargins
|
||||||
|
\renewcommand{\clearemptydoublepage}{\cle@remptydoublep@ge}
|
||||||
|
}
|
||||||
|
|
||||||
|
% Define the honors thesis preliminary section if the 'honors' option is specified
|
||||||
|
\DeclareOption{honors}{
|
||||||
|
\renewcommand{\makepreliminarypages}{
|
||||||
|
\preliminarymargins
|
||||||
|
\honorstitlepage
|
||||||
|
\copyrightpage
|
||||||
|
\seniorapprovalpage
|
||||||
|
\abstractpage
|
||||||
|
% \acknowledgmentspage
|
||||||
|
\fixmargins
|
||||||
|
\renewcommand{\clearemptydoublepage}{\cle@remptydoublep@ge}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
% Changes to masters thesis preliminary section if the 'masters' option is specified
|
||||||
|
\DeclareOption{masters}{
|
||||||
|
\degree{Master of Science}
|
||||||
|
\docname{thesis}
|
||||||
|
\renewcommand{\makepreliminarypages}{
|
||||||
|
\preliminarymargins
|
||||||
|
\titlepage
|
||||||
|
\copyrightpage
|
||||||
|
\masterapprovalpage
|
||||||
|
\acceptancepage
|
||||||
|
\abstractpage
|
||||||
|
% \acknowledgmentspage
|
||||||
|
\fixmargins
|
||||||
|
\renewcommand{\clearemptydoublepage}{\cle@remptydoublep@ge}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
% Changes to PhD preliminary section if the 'phd' option is specified
|
||||||
|
\DeclareOption{phd}{
|
||||||
|
\degree{Doctor of Philosophy}
|
||||||
|
\docname{dissertation}
|
||||||
|
\renewcommand{\makepreliminarypages}{
|
||||||
|
\preliminarymargins
|
||||||
|
\titlepage
|
||||||
|
\copyrightpage
|
||||||
|
\phdapprovalpage
|
||||||
|
\acceptancepage
|
||||||
|
\abstractpage
|
||||||
|
% \acknowledgmentspage
|
||||||
|
\fixmargins
|
||||||
|
\renewcommand{\clearemptydoublepage}{\cle@remptydoublep@ge}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
% --------------------- Some commands to handle the single sided preliminary pages ------------------
|
||||||
|
|
||||||
|
% Define the '\clearemptydoublepage' command to clear pages but not number any blank pages inserted.
|
||||||
|
% This is taken from the BYUThesis.cls file
|
||||||
|
\let\cle@rdoublep@ge\cleardoublepage
|
||||||
|
\newcommand{\cle@remptydoublep@ge}{
|
||||||
|
\clearpage
|
||||||
|
\if@twoside
|
||||||
|
\ifodd\c@page\else
|
||||||
|
\fi\fi
|
||||||
|
{\pagestyle{empty}\cle@rdoublep@ge}}
|
||||||
|
\newcommand{\clearemptydoublepage}{\cle@remptydoublep@ge}
|
||||||
|
|
||||||
|
|
||||||
|
% Create an abstract environment which is single sided, even in a double sided book.
|
||||||
|
% again, this was taken from BYUThesis.cls
|
||||||
|
\def\skip@bstr@ctp@ges{\relax}
|
||||||
|
\def\@@skip@bstr@ctp@ges{%
|
||||||
|
\if@twoside
|
||||||
|
\ifodd\c@page\else
|
||||||
|
\vbox{\vbox to \vsize{}}
|
||||||
|
\clearpage\fi
|
||||||
|
\else
|
||||||
|
\fi
|
||||||
|
\afterpage{\skip@bstr@ctp@ges}
|
||||||
|
}
|
||||||
|
\newenvironment{abstractenv}{
|
||||||
|
\def\skip@bstr@ctp@ges{\@@skip@bstr@ctp@ges}
|
||||||
|
\afterpage{\skip@bstr@ctp@ges}
|
||||||
|
\pagestyle{empty}
|
||||||
|
}
|
||||||
|
|
||||||
|
% Redefine above commands if etd option is specified. The blank pages make printing nice,
|
||||||
|
% but they don't want them in the submitted PDF
|
||||||
|
%\DeclareOption{etd}{
|
||||||
|
% \renewcommand{\clearemptydoublepage}{ \clearpage }
|
||||||
|
% \renewenvironment{abstractenv}{\afterpage{\thispagestyle{empty}}\pagestyle{empty}}{}
|
||||||
|
% }
|
||||||
|
|
||||||
|
% ------------------------ Load the class and needed packages ---------------------------------
|
||||||
|
|
||||||
|
% Load the book class
|
||||||
|
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
|
||||||
|
\ProcessOptions\relax
|
||||||
|
\LoadClass[a4,12pt]{article}
|
||||||
|
|
||||||
|
% The afterpage package is required to make single sided formal pages
|
||||||
|
% in a double sided environment
|
||||||
|
\RequirePackage{afterpage}
|
||||||
|
|
||||||
|
% Note: the hyperref package is required to make an appropriate ETD.
|
||||||
|
% However, we don't require it here since it is supposed to be the last
|
||||||
|
% package loaded and students may want to load other packages in the
|
||||||
|
% main tex file. So that this class file doesn't crash if the student
|
||||||
|
% forgets to load hyperref, we have used the following commands below:
|
||||||
|
%
|
||||||
|
% \providecommand\phantomsection{}
|
||||||
|
% \providecommand\pdfbookmark[3][]{}
|
||||||
|
%
|
||||||
|
% These commands provide dummy versions of the macros, but won't
|
||||||
|
% bother the real versions if the hyperref package is loaded in the
|
||||||
|
% tex file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% ---------------------------- main code ----------------------------
|
||||||
|
|
||||||
|
% Set the margins to BYU specifications for the single sided preliminary
|
||||||
|
% pages. At the end of the \makepreliminarypages command we fix the margins
|
||||||
|
% to be appropriate alternating values for double sided printing (if selected).
|
||||||
|
% If the \makepreliminarypages macro is not run, this never gets fixed.
|
||||||
|
\setlength{\marginparwidth}{0pt}
|
||||||
|
\setlength{\marginparsep}{0pt}
|
||||||
|
\setlength{\oddsidemargin}{0.3in}
|
||||||
|
\setlength{\evensidemargin}{0in}
|
||||||
|
\setlength{\textwidth}{6in}
|
||||||
|
\setlength{\topmargin}{0in}
|
||||||
|
\setlength{\headheight}{0.125in}
|
||||||
|
\setlength{\headsep}{0.25in}
|
||||||
|
\setlength{\textheight}{8.625in}
|
||||||
|
\setlength{\footskip}{0.25in}
|
||||||
|
\raggedbottom
|
||||||
|
|
||||||
|
% Redefine the Table of Contents to deal with some blank page
|
||||||
|
% and bookmarking issues relating to ETD submission
|
||||||
|
%\let\TEMPtableofcontents\tableofcontents
|
||||||
|
%\renewcommand{\tableofcontents}{
|
||||||
|
% \clearemptydoublepage
|
||||||
|
%\providecommand\phantomsection{} \phantomsection
|
||||||
|
%\addcontentsline{toc}{chapter}{Оглавление}
|
||||||
|
%\TEMPtableofcontents
|
||||||
|
%}
|
||||||
|
|
||||||
|
% Redefine the List of Figures to deal with some blank page
|
||||||
|
% and bookmarking issues
|
||||||
|
%\let\TEMPlistoffigures\listoffigures
|
||||||
|
%\renewcommand{\listoffigures}{
|
||||||
|
% \providecommand\phantomsection{} \phantomsection
|
||||||
|
%\addcontentsline{toc}{chapter}{List of Figures}
|
||||||
|
%\TEMPlistoffigures
|
||||||
|
%}
|
||||||
|
|
||||||
|
% Redefine the Bibliography to deal with a bookmarking issues
|
||||||
|
\let\TEMPbibliography\bibliography
|
||||||
|
\renewcommand{\bibliography}{
|
||||||
|
\cleardoublepage \phantomsection
|
||||||
|
\TEMPbibliography
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%---------------------------- The Preliminary Page Definitions --------------------------
|
||||||
|
|
||||||
|
% ============================== Title Page ===============================
|
||||||
|
\renewcommand{\titlepage}{
|
||||||
|
\begin{center}
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[1]{\@TitlePageText}{bm:Title}
|
||||||
|
\includegraphics[height=4cm,keepaspectratio]{src/assets/msu_title.png}\\[0.1cm]
|
||||||
|
%\vspace*{0.375in}
|
||||||
|
\@University\\
|
||||||
|
\@Faculty\\
|
||||||
|
\@Chair\\
|
||||||
|
\ifdefined\@Lab{\scriptsize \@Lab\\[\baselineskip]}\fi
|
||||||
|
\vspace{2.5cm}
|
||||||
|
{\large \@Author \\[\baselineskip]
|
||||||
|
%\HRule \\[0.4cm]
|
||||||
|
\textbf{\@TitleTop}\\
|
||||||
|
\ifdefined\@TitleMiddle\textbf{\@TitleMiddle}\\\fi
|
||||||
|
\ifdefined\@TitleBottom\textbf{\@TitleBottom}\\\fi
|
||||||
|
\ifdefined\@TitleTopEng\textbf{\\\@TitleTopEng}\\\fi
|
||||||
|
\ifdefined\@TitleMiddleEng\textbf{\@TitleMiddleEng}\\\fi
|
||||||
|
\ifdefined\@TitleBottomEng\textbf{\@TitleBottomEng}\\\fi}
|
||||||
|
\vspace{1.5cm}
|
||||||
|
\@docname\\
|
||||||
|
%\HRule \\[1.5cm]
|
||||||
|
\normalsize
|
||||||
|
\vfill
|
||||||
|
\begin{flushright}
|
||||||
|
%\emph{\@AuthorText:\\}
|
||||||
|
%{\small \@GrText~\@AcadGroup\\}
|
||||||
|
%{\large \@Author \\[\baselineskip]}
|
||||||
|
\textbf{\@AdvisorText:\\}
|
||||||
|
{\large ~ \@AdvisorDegree~ \@Advisor\\}
|
||||||
|
\ifdefined\@Consultant
|
||||||
|
\textbf{\\\@ConsultantText:\\}
|
||||||
|
{\large ~ \ifdefined\@ConsultantDegree\@ConsultantDegree\fi~ \@Consultant\\}
|
||||||
|
\fi
|
||||||
|
\end{flushright}
|
||||||
|
\vfill
|
||||||
|
|
||||||
|
%\vskip0.667in
|
||||||
|
%\@degree \\
|
||||||
|
\vfill
|
||||||
|
|
||||||
|
\@City, \@Year \\[\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\cleardoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% ============================== Honors Title Page ========================
|
||||||
|
\newcommand{\honorstitlepage}{
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\begin{center}
|
||||||
|
%\providecommand\pdfbookmark[3][]{} \pdfbookmark[0]{Title Page}{bm:Title}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
\@TitleTop\\[\baselineskip]
|
||||||
|
\@TitleBottom\\
|
||||||
|
\vfill
|
||||||
|
\@Author,
|
||||||
|
\vfill
|
||||||
|
%Submitted to Brigham Young University in partial fulfillment\\[\baselineskip]
|
||||||
|
%of graduation requirements for University Honors\\[2\baselineskip]
|
||||||
|
%Department of Physics and Astronomy\\[\baselineskip]
|
||||||
|
%\@Month~\@Year
|
||||||
|
\@City,~\@Year
|
||||||
|
\vfill
|
||||||
|
\end{center}
|
||||||
|
\parbox[t]{2.75in}{
|
||||||
|
Advisor: \@Advisor \\[.5\baselineskip]
|
||||||
|
Signature: \hrulefill}
|
||||||
|
\hfill
|
||||||
|
\parbox[t]{2.75in}{
|
||||||
|
Honors Dean: \@HonorsDean \\[.5\baselineskip]
|
||||||
|
Signature: \hrulefill}
|
||||||
|
\clearemptydoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
% ======================== Copyright page ===============================
|
||||||
|
\newcommand{\copyrightpage}{
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[0]{Copyright}{bm:Copyright}
|
||||||
|
\vspace*{\fill}
|
||||||
|
\begin{center}
|
||||||
|
Copyright \copyright\ \@Year~\@Author\\[\baselineskip]
|
||||||
|
All Rights Reserved\\[5\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\vspace{1in}
|
||||||
|
\vfill
|
||||||
|
\clearemptydoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
% =============================== Approval page =======================
|
||||||
|
\newcommand{\datebox}{
|
||||||
|
\parbox[t]{1.5in}{
|
||||||
|
\ \\[2\baselineskip]
|
||||||
|
\rule{1.5in}{0.4pt}\\
|
||||||
|
\@DateText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newcommand{\signaturebox}[1]{
|
||||||
|
\parbox[t]{3.6in}{
|
||||||
|
\ \\[2\baselineskip]
|
||||||
|
\rule{3.6in}{0.4pt}\\
|
||||||
|
#1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newcommand{\phdapprovalpage}{
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\begin{center}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[0]{Graduate Committee Approval}{bm:ComAp}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
BRIGHAM YOUNG UNIVERSITY\\[3\baselineskip]
|
||||||
|
GRADUATE COMMITTEE APPROVAL\\[5\baselineskip]
|
||||||
|
of a \@docname~submitted by\\[\baselineskip]
|
||||||
|
\@Author\\[2\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\noindent
|
||||||
|
This dissertation has been read by each member of the following graduate committee
|
||||||
|
and by majority vote has been found to be satisfactory.\\[\baselineskip]
|
||||||
|
\datebox\hfill\signaturebox{\@Advisor, Chair}\\
|
||||||
|
\datebox\hfill\signaturebox{\@MemberA}\\
|
||||||
|
\datebox\hfill\signaturebox{\@MemberB}\\
|
||||||
|
\datebox\hfill\signaturebox{\@MemberC}\\
|
||||||
|
\datebox\hfill\signaturebox{\@MemberD}
|
||||||
|
\vfill
|
||||||
|
\clearemptydoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
\newcommand{\masterapprovalpage}{
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\begin{center}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[0]{Graduate Committee Approval}{bm:ComAp}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
BRIGHAM YOUNG UNIVERSITY\\[3\baselineskip]
|
||||||
|
GRADUATE COMMITTEE APPROVAL\\[5\baselineskip]
|
||||||
|
of a \@docname~submitted by\\[\baselineskip]
|
||||||
|
\@Author\\[2\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\noindent
|
||||||
|
This thesis has been read by each member of the following graduate committee
|
||||||
|
and by majority vote has been found to be satisfactory.\\[\baselineskip]
|
||||||
|
\datebox\hfill\signaturebox{\@Advisor, Chair}\\
|
||||||
|
\datebox\hfill\signaturebox{\@MemberA}\\
|
||||||
|
\datebox\hfill\signaturebox{\@MemberB}\\
|
||||||
|
\vfill
|
||||||
|
\clearemptydoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
\newcommand{\seniorapprovalpage}{
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\begin{center}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[0]{Department Approval}{bm:DepAp}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
\@University\\[3\baselineskip]
|
||||||
|
{\bf \@ApprovalText}\\[5\baselineskip]
|
||||||
|
\@docname~\@ApprovalAText\\[\baselineskip]
|
||||||
|
{\em \@AuthorGenitiveCase}\\[2\baselineskip]
|
||||||
|
\@ApprovalBText
|
||||||
|
\\[\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\datebox\hfill\signaturebox{\@Advisor, \@AdvisorText}\\
|
||||||
|
%\datebox\hfill\signaturebox{\@UgradCoord, Research Coordinator}\\
|
||||||
|
%\datebox\hfill\signaturebox{\@DepRep, \@DepRepTitle}\\
|
||||||
|
\vfill
|
||||||
|
\clearemptydoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
% ======================= Acceptance Page ============================
|
||||||
|
\newcommand{\acceptancepage}{
|
||||||
|
\thispagestyle{empty}%
|
||||||
|
\begin{center}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[0]{Acceptance Page}{bm:Accept}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
BRIGHAM YOUNG UNIVERSITY\\[3\baselineskip]
|
||||||
|
\end{center}%
|
||||||
|
\noindent%
|
||||||
|
As chair of the candidate's graduate committee, I have read the
|
||||||
|
\@docname\ of \@Author \ in its final form and have found
|
||||||
|
that (1) its format, citations, and bibliographical style are
|
||||||
|
consistent and acceptable and fulfill university and department
|
||||||
|
style requirements; (2) its illustrative materials including
|
||||||
|
figures, tables, and charts are in place; and (3) the final
|
||||||
|
manuscript is satisfactory to the graduate committee
|
||||||
|
and is ready for submission to the university library.\\[2\baselineskip]
|
||||||
|
\datebox\hfill\signaturebox{\@Advisor\\Chair, Graduate Committee}
|
||||||
|
\vskip 0pt plus 2fill
|
||||||
|
\noindent Accepted for the Department\par\hfill%
|
||||||
|
\signaturebox{\@DepRep, \@DepRepTitle\\Department of Physics and
|
||||||
|
Astronomy }{} \vfill \noindent Accepted for the College\par\hfill
|
||||||
|
\signaturebox{\@Dean, \@DeanTitle \\
|
||||||
|
College of Physical and Mathematical Sciences}
|
||||||
|
\clearemptydoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
% ========================= Abstract ===================================
|
||||||
|
|
||||||
|
\newcommand{\abstractpage}{
|
||||||
|
\begin{abstractenv}
|
||||||
|
\ifdefined\@Abstract
|
||||||
|
\begin{center}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[1]{\@AbstractText}{bm:Abstract}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
{\bf \@AbstractText}\\[1\baselineskip]
|
||||||
|
\@TitleTop
|
||||||
|
\ifdefined\@TitleMiddle\\\@TitleMiddle\fi
|
||||||
|
\ifdefined\@TitleBottom\\\@TitleBottom\fi\\[1\baselineskip]
|
||||||
|
{\em \@Author}\\[\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\renewcommand{\baselinestretch}{1.33}\small\normalsize
|
||||||
|
\@Abstract
|
||||||
|
\cleardoublepage
|
||||||
|
\fi
|
||||||
|
|
||||||
|
\ifdefined\@AbstractEng
|
||||||
|
\begin{center}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[1]{Abstract}{bm:AbstractEng}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
{\bf Abstract}\\[1\baselineskip]
|
||||||
|
\@TitleTopEng
|
||||||
|
\ifdefined\@TitleMiddleEng\\\@TitleMiddleEng\fi
|
||||||
|
\ifdefined\@TitleBottomEng\\\@TitleBottomEng\fi\\[1\baselineskip]
|
||||||
|
{\em \@AuthorEng}\\[\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\renewcommand{\baselinestretch}{1.33}\small\normalsize
|
||||||
|
\@AbstractEng
|
||||||
|
\cleardoublepage
|
||||||
|
\fi
|
||||||
|
|
||||||
|
\ifdefined\@Acknowledgments\acknowledgmentspage\fi
|
||||||
|
|
||||||
|
\end{abstractenv}
|
||||||
|
}
|
||||||
|
|
||||||
|
% ========================= Acknowledgments ==============================
|
||||||
|
\newcommand{\acknowledgmentspage}{
|
||||||
|
\begin{center}
|
||||||
|
\providecommand\pdfbookmark[3][]{} \pdfbookmark[1]{\@AcknowledgmentsText}{bm:Acknowledgments}
|
||||||
|
\vspace*{0.375in}
|
||||||
|
{\bf \@AcknowledgmentsText}\\[1\baselineskip]
|
||||||
|
\end{center}
|
||||||
|
\renewcommand{\baselinestretch}{1.33}\small\normalsize
|
||||||
|
\@Acknowledgments
|
||||||
|
\cleardoublepage
|
||||||
|
}
|
||||||
|
|
||||||
|
\RequirePackage{float}
|
||||||
|
|
||||||
|
\newfloat{listing}{thp}{lol}
|
||||||
|
\floatname{listing}{\@ListingText}
|
||||||
|
\newcommand{\ListingText}[1]{\gdef\@ListingText{#1}}
|
||||||
|
|
||||||
|
\RequirePackage{algorithm}
|
||||||
|
|
||||||
|
\newcommand{\AlgorithmText}[1]{\gdef\@AlgorithmText{#1}}
|
||||||
|
\renewcommand{\ALG@name}{\@AlgorithmText}
|
||||||
|
|
||||||
|
\RequirePackage{algorithmicx} % Для записи алгоритмов в псевдокоде
|
||||||
|
\RequirePackage[noend]{algpseudocode}
|
||||||
|
\algnewcommand{\IfThenElse}[3]{% \IfThenElse{<if>}{<then>}{<else>}
|
||||||
|
\State \algorithmicif\ #1\ \algorithmicthen\ #2\ \algorithmicelse\ #3}
|
||||||
|
|
||||||
|
\RequirePackage{titlesec}
|
||||||
|
\RequirePackage[unicode, hidelinks]{hyperref}
|
||||||
|
\hypersetup{colorlinks=false}
|
||||||
|
|
||||||
|
\RequirePackage{cite}
|
||||||
|
|
||||||
|
\RequirePackage{bookmark}
|
||||||
|
|
||||||
|
\newcommand{\PDFTitle}{\@Author~-~\@TitleTop\ifdefined\@TitleMiddle~\@TitleMiddle\fi\ifdefined\@TitleBottom~\@TitleBottom\fi}
|
||||||
|
\newcommand{\PDFAuthor}{\@Author}
|
||||||
|
|
||||||
|
\emergencystretch 3em
|
||||||
1465
gost780u.bst
Normal file
33
main.tex
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
\documentclass[oneside,senior,etd]{BYUPhys}
|
||||||
|
|
||||||
|
\input{style}
|
||||||
|
\input{src/titlepage}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\fixmargins
|
||||||
|
\makepreliminarypages
|
||||||
|
|
||||||
|
\oneandhalfspace
|
||||||
|
|
||||||
|
\pdfbookmark[section]{\contentsname}{toc}
|
||||||
|
\tableofcontents
|
||||||
|
|
||||||
|
\include{src/sections/intro/intro}
|
||||||
|
\include{src/sections/task/task}
|
||||||
|
\include{src/sections/solution/solution}
|
||||||
|
\include{src/sections/impl/impl}
|
||||||
|
\include{src/sections/tests/tests}
|
||||||
|
\include{src/sections/conclusion}
|
||||||
|
|
||||||
|
\bibliographystyle{gost780u.bst} % Для соответствия требованиям об оформлении списка литературы
|
||||||
|
\raggedright
|
||||||
|
\bibliography{src/refs}
|
||||||
|
% Раскомментируйте, если нужно приложение
|
||||||
|
% \appendix
|
||||||
|
|
||||||
|
% \cleardoublepage \phantomsection
|
||||||
|
% \section*{Приложение}
|
||||||
|
% \addcontentsline{toc}{section}{Приложение}
|
||||||
|
|
||||||
|
\end{document}
|
||||||
3
src/abstract.tex
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
В данной работе рассматривается решение задачи автоматического распараллеливания фортран-программ для случая целевой системы с общей оперативной памятью. Задача решается в рамках доработки системы SAPFOR с использьзованием модели DVMH в качестве технологии распараллеливания.
|
||||||
|
|
||||||
|
Во введении приводятся некоторые сведения о распараллеливании, как общепринятые, так и те, что относятся только к системам SAPFOR и DVM, приводится описание этих систем. Далее, во второй главе описывается проблема распараллеливания на общую память с точки зрения DVM и с точки зрения автоматизации, рассматриваюся подходы к её решению. В этой главе так же определяются основные цели работы, описываются основные сценарии использования разрабатываемого фунционала. В третьей главе подробно описывается ход решения поставленной задачи, который был разбит на три этапа -- теоретическую подготовку, реализацию и тестирование. В четвёртой главе приведено описание существовавших и добавленных алгоритмов, о которых шла речь в главе 3. В пятой главе приводятся результаты исследования эффективности получаемого распараллеливания на примере программ из пакета NAS Parallel Benchmarks.
|
||||||
BIN
src/assets/array_graph.png
Normal file
|
After Width: | Height: | Size: 379 KiB |
BIN
src/assets/gpu.png
Normal file
|
After Width: | Height: | Size: 675 KiB |
BIN
src/assets/hp.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/msu_title.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
src/assets/pass_deps_dist.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
src/assets/pass_deps_nodist_0.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
src/assets/pass_deps_nodist_1.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
src/assets/titan_12_all_classes.png
Normal file
|
After Width: | Height: | Size: 856 KiB |
BIN
src/assets/titan_c_all.png
Normal file
|
After Width: | Height: | Size: 410 KiB |
72
src/refs.bib
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
@online{keldysh,
|
||||||
|
title = "сайт Института прикладной математики им. М.В. Келдыша Российской академии наук",
|
||||||
|
url = "https://www.keldysh.ru/"
|
||||||
|
}
|
||||||
|
|
||||||
|
@online{dvm-site,
|
||||||
|
title = "сайт DVM-системы",
|
||||||
|
url = "http://dvm-system.org/"
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{sapfor-1,
|
||||||
|
author = "Н.А. Катаев, С.А. Черных",
|
||||||
|
title = "Автоматизация распараллеливания программ в системе SAPFOR",
|
||||||
|
booktitle = "Научный сервис в сети Интернет: труды XXII Всероссийской научной конференции",
|
||||||
|
year = "2020",
|
||||||
|
url = "https://doi.org/10.20948/abrau-2020-24"
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{sapfor-2,
|
||||||
|
author = "Катаев Н.А., Колганов А.С.",
|
||||||
|
title = "Автоматизированное распараллеливание программ для гетерогенных кластеров с помощью системы SAPFOR",
|
||||||
|
booktitle = "Вычислительные методы и программирование",
|
||||||
|
year = "2022",
|
||||||
|
number = "4",
|
||||||
|
url = "https://num-meth.ru/index.php/journal/article/view/1246/1214"
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{par-reg,
|
||||||
|
author = "Колганов А.С.",
|
||||||
|
title = "Опыт применения механизма областей для поэтапного распараллеливания программных комплексов с помощью системы SAPFOR",
|
||||||
|
booktitle = "Вычислительные методы и программирование",
|
||||||
|
year = "2020",
|
||||||
|
number = "4",
|
||||||
|
url = "https://num-meth.ru/index.php/journal/article/view/1073/1131"
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{lom_readings,
|
||||||
|
author = "Крюков В. А., Колганов А. С., Кочармин М. Д.",
|
||||||
|
title = "Автоматизированное распараллеливание Фортран-программ на общую память",
|
||||||
|
booktitle = "Ломоносовские чтения",
|
||||||
|
year = "2024",
|
||||||
|
url = "https://conf.msu.ru/file/event/8752/eid8752_attach_a7f03100cf01a40d0a1bc490c7691661e89e5edc.pdf"
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{pri-var,
|
||||||
|
author = "А.C. Колганов and Н.Н. Королев",
|
||||||
|
title = "Статический анализ приватных переменных в системе автоматизированного распараллеливания Фортран-программ",
|
||||||
|
url = "http://omega.sp.susu.ru/pavt2018/short/018.pdf",
|
||||||
|
booktitle = {Параллельные вычислительные технологии (ПаВТ{’}2018)},
|
||||||
|
}
|
||||||
|
|
||||||
|
@book{dragonbook,
|
||||||
|
title = {Компиляторы: принципы, технологии и инструментарий, 2-е изд.},
|
||||||
|
author = {Ахо, Альфред В. and Лам, Моника С. and Рави Сети and Джеффри Д. Ульман},
|
||||||
|
year = {2006}
|
||||||
|
}
|
||||||
|
|
||||||
|
@online{sage,
|
||||||
|
title = "Библиотека Sage++",
|
||||||
|
url = "http://www.extreme.indiana.edu/sage/"
|
||||||
|
}
|
||||||
|
|
||||||
|
@online{npb,
|
||||||
|
title = "NAS Parallel Benchmarks",
|
||||||
|
url = "https://www.nas.nasa.gov/software/npb.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{disser,
|
||||||
|
author = "А.C. Колганов",
|
||||||
|
title = "Автоматизация распараллеливания Фортран-программ для гетерогенных кластеров",
|
||||||
|
url = "http://TODO"
|
||||||
|
}
|
||||||
13
src/sections/conclusion.tex
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
\section{Заключение}
|
||||||
|
|
||||||
|
Итак, была проведена работа по исследованию и улучшению системы автоматизированного распараллеливания SAPFOR. В качестве разультата в систему SAPFOR был добавлен новый режим работы распараллеливания на общую память, что позволило расширить класс распараллеливаемых программ.
|
||||||
|
|
||||||
|
Разработанный проход был должным образом интегрирован в систему SAPFOR. Были поддержаны как директивы системе SAPFOR, так и взаимодействие с диалоговой оболочкой, в частности функция запуска прохода анализа кода. Добавленный проход использует как преобразованные версии уже существоваших алгоритмов, так и новые решения.
|
||||||
|
|
||||||
|
Добавленный код был тщательно протестирован. Было выполнено тестирование на большом множестве различных программ на предмет корректности получаемого параллельного DVMH-кода. Также с помощью нового прохода были распараллены тесты из пакета NAS Parallel Benchmarks.
|
||||||
|
|
||||||
|
Распараллеливание программ из пакета NAS Parallel Benchmarks вызвало некоторые трудности, большинство из которых удалось преодолеть с помощью графической оболочки системы SAPFOR. В результате для большей части тестов были получены эффективные параллельные версии на языке DVM, конкурирующие с эталонными версиями на OpenMP. В доказательство их эффективности были приведены результаты запусков на различных устройствах: на многопоточном процессоре и на графических ускорителях.
|
||||||
|
|
||||||
|
Результаты работы были представлены на конференции \textit{<<Ломоносовские чтения 2024>>} и опубликованы в её сборнике тезисов \cite{lom_readings}.
|
||||||
|
|
||||||
|
Таким образом, все поставленные цели были выполнены, что дало решение исходной задачи автоматизации распараллеливания на общую память.
|
||||||
87
src/sections/impl/distr.tex
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
\subsection{Алгоритмы распараллеливания с распределением данных}
|
||||||
|
|
||||||
|
Рассмотрим подробнее устройство проходов, отвечающих за построение схемы распределения данных и распараллеливании (см. Рис. \ref{fig:distr-alg}).
|
||||||
|
|
||||||
|
Начнём с прохода LOOP\_ANALYZER\_DATA\_DIST\_S0. На вход он получает АСТ, заполненные структуры \texttt{FuncInfo} и \texttt{LoopGraph} для всей программы. Результатом данного прохода является заполненный граф измерений массивов.
|
||||||
|
|
||||||
|
В проходе происходит итерация по всем структурам \texttt{FuncInfo}, то есть по каждой функции. Для каждой функции выполняется следующее:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item выполняется проход по всем операторам функции;
|
||||||
|
|
||||||
|
\item если этот оператор содержит запись в элемент массива или чтение из массива и этот массив распределяемый, то есть он не является нигде приватным или редукционным, происходит отображение этой операции на содержащие её циклы;
|
||||||
|
|
||||||
|
\item отображение заключается в сохранении записей вида \textit{<цикл, массив, тип операции, номер измерения, A, B>} во временную структуру. Такая запись создаётся для каждого измерения, обращение по которому в текущей операции имеет вид \textit{A*i+B}, где \textit{A} и \textit{B} - целые числа, \textit{i} - счётчик цикла.
|
||||||
|
|
||||||
|
\item после похода по оператором, для каждого цикла проводится анализ зависимостей по данным. То есть проверка на то, что никакой виток цикла не использует данные, записываемые другими витками. Исключения составляют зависимости с фиксированным расстоянием между записывающим и читающим витками циклов. При наличии зависимостей в цикле, в структуру \texttt{LoopGraph} заносится соответствующая пометка.
|
||||||
|
|
||||||
|
\item далее происходит добавление полученных записей об обращениях к массив в специальную структура данных -- граф измерений массивов. Эта структура используется для построения схемы распределения данных и представляет собой граф, вершинами которого являются измерения массивов, в дугами -- связи между измерениями массивов согласно их использованию в циклах программы (см. пример на Рис. \ref{fig:array_graph}). Подробно построение графа массивов описано в \cite{disser};
|
||||||
|
|
||||||
|
\item после обработки всех функций проход завершает работу;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.5]{src/assets/array_graph.png}
|
||||||
|
\caption{пример графа измерений массивов.}
|
||||||
|
\label{fig:array_graph}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
Далее запускается проход LOOP\_ANALYZER\_DATA\_DIST\_S1. Входные данные у него такие же, как и у LOOP\_ANALYZER\_DATA\_DIST\_S0. Его цель -- собрать информацию о зависимостях по данным в циклах и обнавить соответствующие флаги в структурах \texttt{LoopGraph}.
|
||||||
|
|
||||||
|
В этом проходе также идёт итерация по всем функциям программы и производятся следующие действия:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item опять выполняется проход по всем операторам функции;
|
||||||
|
|
||||||
|
\item точно так же обрабатываются обращения к массивам с сохранением записей вида \textit{<цикл, массив, тип операции, номер измерения, A, B>};
|
||||||
|
|
||||||
|
\item вместо добавления информации в граф измерений массивов, выявляются зависимости по данным внутри циклов путём построения специального графа зависимостей;
|
||||||
|
|
||||||
|
\item для каждого цикла, который имеет зависимости по данным, заносится пометка в структуру \texttt{LoopGraph} о том, что цикл имеет зависимость по данным и не может быть распараллелен;
|
||||||
|
|
||||||
|
\item исключения составляют зависимости фиксированной длинны, то есть такие, что номера записывающих и читающих витков отличаются на фиксированную величину. Такие циклы могут быть распараллелены с помощью директивы ACROSS (см. пример на Рис. \ref{fig:hp} в главе \ref{sec:benchmark});
|
||||||
|
|
||||||
|
\item после обработки всех функций проход завершает работу;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Проход LOOP\_ANALYZER\_DATA\_DIST\_S2 получает на вход граф измерений массивов. Результатом прохода является усечённый граф измерений массивов (такого графа измерений массивов, который не содержит циклов, порождающие конфликтные ситуации) для последующего создания распределения данных.
|
||||||
|
|
||||||
|
Он имеет следующий алгоритм:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item рассматривается граф измерений массивов;
|
||||||
|
|
||||||
|
\item происходит поиск циклов в графе;
|
||||||
|
|
||||||
|
\item из графа удаляются дуги так, чтобы разорвать циклы, приводящие к конфликтам распределения данных. В последствии удаление дуг приведёт к появлению директив удалённого доступа к данным;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Проход CRATE\_TEMPLATE\_LINKS получает на вход оптимизированный граф измерений массивов, в котором отсутствуют циклы. Поскольку в этом графе нет циклов, все его компоненты связности представляют собой деревья. В каждом таком дереве находится массив с наибольшей размерностью и по нему создаётся служебный массив-шаблон, на который выравниваются все массивы рассматриваемого дерева. Таким образом, на вход этот проход принимает граф измерений массивов, а на выходе получаются директивы распределения и выравнивания данных, представленные структурой \texttt{DataDirective}, хранящей всю необходимую информацию.
|
||||||
|
|
||||||
|
После этого запускается проход LOOP\_ANALYZER\_COMP\_DIST распределения вычислений согласно построенному распределению данных. На вход он получает АСТ программы, получает АСТ, структуры \texttt{FuncInfo}, \texttt{LoopGraph}, граф измерений массивов и построенное распределение данных. Общая схема работы совпадает с LOOP\_ANALYZER\_DATA\_DIST\_S0 и LOOP\_ANALYZER\_DATA\_DIST\_S1: происходит итерация по всем функциям и заполнение кортежей \textit{<цикл, массив, тип операции, номер измерения, A, B>}. После заполнения этой информации, происходят следующие действия:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item по отдельности рассматривается каждый цикл;
|
||||||
|
|
||||||
|
\item по группе флагов структуры \texttt{LoopNode} определяется, есть ли факторы, препятствующие распараллеливанию цикла.
|
||||||
|
|
||||||
|
\item среди всех массивов, используемых в цикле, выбирается лучший для того, чтобы относительно него распределить витки циклы. Предпочтение отдаётся массивам, в которые происходит запись и имеют наибольшее количество измерений. Если таких нет, выбираются массивы, из которых происходит чтение.
|
||||||
|
|
||||||
|
\item для каждого цикла без ограничений на распараллеливание создаётся структура типа \texttt{ParallelDirective}, в которую записывается выбранный массив и другая информация, такая как ACROSS-зависимости и др., извлекаемая в том числе из графа измерений массивов;
|
||||||
|
|
||||||
|
\item полученные структуры \texttt{ParallelDirective} сохраняются в соответствующих структурах \texttt{LoopNode}.
|
||||||
|
|
||||||
|
\item после создание всех директив, для каждого тесновложенного гнезда параллельных циклов происходит объединение \texttt{ParallelDirective} для того, чтобы распараллеливался не только самый верхний цикл, а всё гнездо.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Следом вызывается проход CREATE\_PARALLEL\_DIRS. На вход он получает построенные директивы распределения данных и директивы распараллеливания циклов в виде внутренних структур системы SAPFOR \texttt{DataDirective} и \texttt{ParallelDirective}.
|
||||||
|
|
||||||
|
Сначала рассматриваются директивы распределения данных. Для каждой директивы, по информации из структуры, строится её текстовое представление, в виде строк конструируются такие DVM-директивы как ALIGN и DISTRIBUTE.
|
||||||
|
|
||||||
|
Далее аналогичный процесс происходит с директивами распараллеливания: формируются директивы PARALLEL ON и все нужные клаузы, такие как PRIVATE, REDUCTION, ACROSS, SHADOW\_RENEW, REMOTE\_ACCESS.
|
||||||
|
|
||||||
|
Текстовые директивы DVM-системы сохраняются в виде множества структур \texttt{CreatedDirective}, которые хранят текст директивы и строку, перед которой её необходимо будет вставить.
|
||||||
|
|
||||||
|
Наконец, проход INSERT\_PARALLEL\_DIRS, получающий множество созданных директив, производит их вставку в виде комментариев в АСТ обрабатываемой программы перед соответствующими операторами.
|
||||||
|
|
||||||
20
src/sections/impl/impl.tex
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
\section{Описание алгоритмов}
|
||||||
|
|
||||||
|
В предыдущей главе поверхностно описывались функции проходов, работающих при распараллеливании с распределением данных и их аналогов для случая общей памяти. В этой главе приводится подробное описание алгоритмов, с помощью которых реализованы эти проходы.
|
||||||
|
|
||||||
|
Весь исходный код системы SAPFOR написан на языке C++. Программа, поступающая на вход системе, переводится в абстрактное синтаксическое дерево операторов (АСТ). В качестве реализации абстрактного синтаксического дерева используется библиотека Sage++ \cite{sage}. Используя это представление, входную программу можно анализировать, модифицировать и переводить обратно в код на фортране.
|
||||||
|
|
||||||
|
Помимо библиотеки Sage++, в системе SAPFOR введён ряд типов данных, упрощающих разработку. Среди них можно выделить следующие наиболее используемые:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item \texttt{Array} -- тип, отражающий массив, используемый во входной программе. Помимо прочего, содержит информацию о его имени, размерности, месте определения, местах использования;
|
||||||
|
|
||||||
|
\item \texttt{FuncInfo} -- отражает функцию входной программы. Содержит информацию о имени, месте определения, точках её вызова, подключенных common-блоков, именах её формальных аргументов, информацию о наличие побочных эффектов и т. д.;
|
||||||
|
|
||||||
|
\item \texttt{LoopGraph} -- отражает цикл. Имеет информацию о месте расположения, вложенных циклах, вызовах функций внутри цикла, операциях над массивами внутри цикла. Если цикл находится в канонической форме, дополнительно содержит название итерационной переменной, границах и шаге итерирования, глубину гнезда тесновложенных циклов. Кроме этого структура содержит набор флагов, отмечающих интересующие с точки зрения распараллеливания свойства;
|
||||||
|
|
||||||
|
\item \texttt{ParallelDirective} -- структура, отражающая созданную директиву распараллеливания. Содержит информацию о размере распараллеливаемого гнезда, о клаузах типа SHADOW\_RENEW, ACROSS, REMOTE\_ACCESS, REDUCTION, PRIVATE и используемых в них массивах;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\input{src/sections/impl/distr}
|
||||||
|
\input{src/sections/impl/nodistr}
|
||||||
39
src/sections/impl/nodistr.tex
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
\subsection{Алгоритмы распараллеливания на общую память}
|
||||||
|
|
||||||
|
Как было описано ранее, проходы LOOP\_ANALYZER\_DATA\_DIST\_S* и CREATE\_TEMPLATE\_LINKS отвечают сугубо за распределение данных, поэтому работа по распараллеливанию на общую память начинается сразу с аналога прохода LOOP\_ANALYZER\_COMP\_DIST, который получил название LOOP\_ANALYZER\_NODIST.
|
||||||
|
|
||||||
|
На вход он также принимает АСТ программы, множество структур \texttt{LoopGraph} и \texttt{FuncInfo} (но без графа измерений массивов). Отличия в работе начинаются со способа построения кортежей \textit{<цикл, массив, тип операции, номер измерения, A, B>}: при распределении данных такие записи не сохранялись для массивов, которые являются приватными в каком либо цикле программы. При распараллеливании на общую память есть возможность снять это ограничение и отображать на цикл все его неприватные массивы, даже если для других циклов они являются приватными.
|
||||||
|
|
||||||
|
Далее, появилась возможность обойти отображение витков цикла на распределяемый массив. Преобразованный алгоритм не запускает поиск наилучшего распределённого массива для распределения вычислений и не заполняет соответствующее поле в структуре \texttt{ParallelDirective}, хотя заполнение других полей, таких как ACROSS-зависимости, остаёься актуальным.
|
||||||
|
|
||||||
|
На следующем этапе работает новый проход SELECT\_ARRAY\_DIM\_CONF решающий проблему распараллеливания циклов, использующих секции массивов. Подробно проблема описывалась в предыдущей главе. На вход алгоритм принимает множество структур \texttt{LoopNode} с заполенными полями параллельных директив \texttt{ParallelDirective}. Так же передаётся граф связей между массивами. Вершинами этого ориентированного графа являются структуры \texttt{Array}. Дуги строятся по следующему правилу: пусть массив \textit{B} является формальным аргументом процедуры \textit{F}. Тогда в графе существует дуга от массива \textit{A} к \textit{B} в том и только том случае, если есть вызов процедуры \textit{F} с предачей секции массива \textit{A} в качестве фактического аргумента для \textit{B}.
|
||||||
|
|
||||||
|
Перед тем как рассматривать работу алгоритма, введём два понятия. Будем называть масив \textit{главным}, если он не является формальным аргументом функции, в которой он определён. Заметим, что в графе связей между массивами главными будут те и только те, которые не имеют входящих дуг. Также назовём \textit{конфигурацией} n-мерного массива кортеж из n чисел $a_{i}$, в котором $a_{i}$ является длинной i-го измерения.
|
||||||
|
|
||||||
|
Алгоритм работает следующим образом:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item для каждого главного массива строится множество конфигураций массивов, достижимых из главного в графе связей массивов;
|
||||||
|
|
||||||
|
\item для каждого главного массива выбирается лучшая конфигурация -- такая, которая соовтветствует наибольшему суммарному количеству элементов (суммарное кол-во элементов вычисляется как произведение элементов кортежа);
|
||||||
|
|
||||||
|
\item рассматриваются все невыбранные конфигурации. Все циклы, которые используют хоть один массив, конфигурация которого не была выбрана на прошлом шаге, отстраняются от распараллеливания путём поднятия специального флага \texttt{hasAccessToSubArray} в структуре \texttt{LoopGraph} и удаляет в ней директиву распараллеливания, если она была;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Таким образом, после данного прохода от распараллеливания будут отстранены циклы, которые могут спровоцировать ошибку выполнения системы DVM.
|
||||||
|
|
||||||
|
Далее в проходе INSERT\_PARALLEL\_DIRS\_NODIST запускается алгоритм получения текстового представления директив распараллеливания \texttt{ParallelDirective}, которое имет следующие отличия от случая распараллеливания с распределением:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item директивы распределения данных не используются проходом и не обрабатываются;
|
||||||
|
|
||||||
|
\item в параллельных директивах не происходит конструирование клаузы ON;
|
||||||
|
|
||||||
|
\item не происходит конструирование клауз SHADOW\_RENEW и REMOTE\_ACCESS;
|
||||||
|
|
||||||
|
\item добавлено конструирование клауз TIE. Для заполнения списка отображаемых массивов используется сохранённая информация об обращениях к массивам с прохода LOOP\_ANALYZER\_NODIST.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
В результате получается множество созданных директив \textit{CreatedDirective}, содержащее только директивы распараллеливания на общую память.
|
||||||
|
|
||||||
|
Завершает распараллеливание на общую память вставка директив путём вызова кода прохода INSERT\_PARALLEL\_DIRS с передачей множества созданных директив \texttt{CreatedDirective}.
|
||||||
15
src/sections/intro/dvm.tex
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
\subsection{DVM-система и модель параллелизма по данным}
|
||||||
|
|
||||||
|
DVM-система (Distributed Virtual Memory или Distributed Virtual Maсhine) представляет собой набор программных средств, которые позволяют пользователю производить следующие операции:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item компилировать параллельные программы на языках C-DVMH (расширение языка Си) и Fortran-DVMH (расширение языка фортран);
|
||||||
|
\item запускать скомпилированные программы;
|
||||||
|
\item отлаживать скомпилированные программы (на предмет производительности и корректности распараллеливания);
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
DVM-система ведёт работу с программами, написанными на языках C-DVMH или Fortran-DVMH, которые представляют собой расширения для языков Си и фортран соответственно. Они позволяют распараллеливать последовательные программы при помощи добавления директив -- прагм (для языка Си) или спецкомментариев (для языка фортран). Похожий подход используется в технологиях OpenMP, OpenACC и др.
|
||||||
|
|
||||||
|
Целевая вычислительная система модели DVMH рассматривается как совокупность узлов, каждый из которых имеет свою оперативную память. Чаще всего такие узлы состоят из процессора, к которому подключено несколько ускорителей.
|
||||||
|
|
||||||
|
При этом, DVMH-модель основана на параллелизме по данным. Это означает, что DVM, в соответствии с заданными пользователем директивами, распределяет данные (в данном случае элементы массивов) по доступным узлам вычислительной системы. После этого, по принципу собственных вычислений, согласно которому каждый узел выполняет те и только те вычисления, которые относятся к данным, расположенным в его оперативной памяти, происходит распределение вычислений.
|
||||||
85
src/sections/intro/general.tex
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
\subsection{Общие сведения и термины из параллельного программирования}
|
||||||
|
|
||||||
|
Когда речь идёт о достаточно высокоуровневых технологиях распараллеливания (OpenMP, OpenACC, DVM), говорят о распараллеливании витков циклов. На это есть несколько причин:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item обычно, большая часть вычислительной работы в программах находится именно в циклах;
|
||||||
|
|
||||||
|
\item анализировать абстрактные последовательности операторов с точки зрения возможности их параллельного выполнения сложнее, чем анализировать зависимости между витками циклов;
|
||||||
|
|
||||||
|
\item явное указание распараллеливаемых частей кода влечёт за собой изменения в структуре кода, в то время как указание параллельного цикла обычно выглядит как директива перед его заголовком;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Более того, принято рассматривать только циклы, находящиеся в \textit{канонической форме}, то есть циклы, у которых есть итерационная переменная, проходящая заданный диапазон значений с заданным шагом:
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример цикла в канонической форме на языке фортран с итерационной переменной \texttt{i}, принимающая все значения от 1 до 10.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
DO i = 1, 10
|
||||||
|
...
|
||||||
|
ENDDO
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Иногда приходится иметь дело с вложенными циклами, у которых нет операторов между заголовками и концами циклов. Их совокупность называют \textit{гездом тесновложенных циклов}, или просто гнездом циклов. С точки зрения параллелизма, в общем случае выгоднее распараллеливать не только самый верхний цикл в гнезде, а гездо целиком, увеличивая тем самым итерационное пространство.
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример гнезда из трёх тесновложенных циклов.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
DO i = 1, 10
|
||||||
|
DO j = 2, 20
|
||||||
|
DO k = 3, 30
|
||||||
|
...
|
||||||
|
ENDDO
|
||||||
|
ENDDO
|
||||||
|
ENDDO
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Будем говорить, что витки цикла (или гнезда циклов) имеют \textit{зависимость по данным}, если в нём существуют два витка $i_0$ и $i_1$ такие, что в последовательной программе виток $i_0$ записывает какие-либо данные, а виток $i_1$ их считывает.
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример цикла с зависимостью по данным, где каждый виток с номером $i$ записывает данные, которые читают витки $i+1$ и $i+2$.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
DO i = 3, 10
|
||||||
|
A(i) = A(i - 1) + A(i - 2)
|
||||||
|
ENDDO
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
В общем случае такие циклы нельзя распараллеливать, так как в них важен порядок итераций, но существует несколько разных приёмов, позволяющих в некоторых случаях избегать зависимости по данным.
|
||||||
|
|
||||||
|
Важным этапом распараллеливания явлется определение того, какие данные являются локальными или общими по отношению к виткам циклов. Если скалярная переменная или массив перед использованием переопределяется (перезаписываются значения элементов соответственно) на той же самой итерации, то говорят, что такая переменная является \textit{приватной переменной} или \textit{приватным массивом} соответственно. Из определения следует, что счётчик цикла всегда приватен.
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример цикла по \texttt{i} с приватным массивом \texttt{TMP} и приватными переменными \texttt{i} (счётчик), \texttt{j}, \texttt{t}.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
DO i = 1, 10
|
||||||
|
DO j = 1, 100
|
||||||
|
TMP(j) = j
|
||||||
|
ENDDO
|
||||||
|
|
||||||
|
t = TMP(100)
|
||||||
|
...
|
||||||
|
ENDDO
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Похожим является класс \textit{редукционных переменных}. Он состоит из переменных, значения которых после цикла зависят от каждой итерации цикла, но не зависят от порядка их выполнения. При этом бинарная операция, с помощью которых объединяются частичные значения, называется \textit{редукционной}.
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример цикла с редукционной переменной \texttt{sum} (редукционная операция -- сложение).
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
sum = 0
|
||||||
|
DO i = 1, 10
|
||||||
|
sum = sum + A(i)
|
||||||
|
ENDDO
|
||||||
|
|
||||||
|
write(*, *) sum
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
17
src/sections/intro/intro.tex
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
\section{Введение}
|
||||||
|
|
||||||
|
В современном мире спрос на вычисления растёт быстрее, чем тактовая частота работы процессоров, что обусловлено физическими проблемами и ограничениями. Из-за этого вычислительные системы наращивают свою мощь за счёт увеличения числа вычислительных ядер. Это привело к тому, что в настоящее время стала актуальна тема параллельных вычислений. Различные технологии параллельного программирования дают людям возможность эффективно использовать многоядерные процессоры и графические ускорители.
|
||||||
|
|
||||||
|
Создание параллельного кода -- задача, требующая больших трудозатрат и высокой квалификации. Есть технологии, которые требуют от разработчиков большого внимания к деталям распараллеливания. Они интегрируются в логику программ, что позволяет писать максимально эффективный код, что, в свою очередь, ведёт к дополнительному, иногда огромному, усложнению структур программ. Примерами таких технологий являются библиотеки параллельного программирования pthreads, CUDA, HIP, OpenCL.
|
||||||
|
|
||||||
|
Для борьбы со сложностью разработки параллельного кода, были созданы средства, с помощью которых можно добиться распараллеливания не изменяя логику работы программ. При таком подходе можно потерять в эффективности по сравнению с предыдущими технологиями, но сэкономить человеческие ресурсы. Такие технологии обычно предоставляют программисту лёгкий у удобный интерфейс, оформленный в виде специальных директив компилятору. Сюда можно отнести технологии OpenMP, OpenACC, DVM.
|
||||||
|
|
||||||
|
Наконец, существуют инструменты, которые ещё сильнее снижают трудозатраты процесса распараллеливания. С помощью них можно в автоматизированном режиме получать параллельные программы из последовательных. Часто это накладывает ограничения на возможности распараллеливания, но ввиду нехватки человеческих ресурсов такой подход в определённых случаях может быть оправдан. К этому классу относятся инструменты такие как CAPTools/Parawise, FORGE Magic/DM, ParalWare Trainer, SAPFOR.
|
||||||
|
|
||||||
|
Больших успехов в направлении экономии человеческих ресурсов достигли учёные из Института прикладной математики им. М.В. Келдыша Российской академии наук \cite{keldysh}. В Институте были разработаны и активно поддерживаются два средства параллельного программирования: это DVM-система \cite{dvm-site} -- программный комплекс для компиляции, выполнения и отладки параллельного кода, а также инструмент для автоматизированного распараллеливания программ -- система SAPFOR \cite{sapfor-1}, \cite{sapfor-2}.
|
||||||
|
|
||||||
|
Перед тем, как перейти к основной теме данной работы, в этой главе будут описаны некоторые сведения о параллельном программированнии, как общеизвестные, так и относящиеся исключительно к DVM и SAPFOR, на базе которых и проводилась работа.
|
||||||
|
|
||||||
|
\input{src/sections/intro/general}
|
||||||
|
\input{src/sections/intro/dvm}
|
||||||
|
\input{src/sections/intro/sapfor}
|
||||||
41
src/sections/intro/sapfor.tex
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
\subsection{SAPFOR}
|
||||||
|
|
||||||
|
Система SAPFOR (System FOR Automated Parallelization) предназначена для автоматизации процесса распараллеливания программ с использованием технологии DVMH. Она, так же как и DVM система, поддерживает языки Си и фортран. Система SAPFOR разделена на два проекта, каждый их которых отвечает за свой язык. В данной работе рассматривается только часть, связанная с языком фортран.
|
||||||
|
|
||||||
|
С помощью системы SAPFOR можно производить не только само распараллеливание, но и множество других преобразований, позволяющих приводить программы к \textit{потенциально параллельному виду} -- к форме, в которой она может быть автоматически переведена в параллельную без участия пользователя. Для удобства проведения таких манипуляций была создана графическая оболочка, которая предоставляет пользователям системы удобный интерфейс для использования системы SAPFOR.
|
||||||
|
|
||||||
|
Также система SAPFOR предоставляет набор директив, с помощью которых пользователь может управлять поведением системы при обработке программы. Например, с помощью таких директив можно задавать различные свойства программы, давать указания на расстановку контрольных точек, ограничивать распараллеливание. Сейчас системой поддерживается около десяти различных директив.
|
||||||
|
|
||||||
|
Рассмотрим подробнее две из них, которые будут упомянаться далее в работе, более пристально. Это директивы приватизации и редукции. Директива приватизации, как и все директивы системе SAPFOR, представлена в виде комментария, начинающегося с префикса \texttt{\$SPF}. Далее идёт тело директивы, которое имеет вид \texttt{ANALYSIS (PRIVATE(...))}, где вместо троеточия должен быть указан список приватных переменных (скаляров или массивов) через запятую. Следующий пример демонстрирует использование директивы \texttt{PRIVATE} системы SAPFOR:
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример задания приватного массива B для цикла на строке 3 с помощью директивы системе SAPFOR.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
!$SPF ANALYSIS(PRIVATE(B))
|
||||||
|
DO I = 1, N
|
||||||
|
DO J = 1, N
|
||||||
|
B(J) = J
|
||||||
|
END DO
|
||||||
|
|
||||||
|
A(I) = B(A(I))
|
||||||
|
END DO
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Хотя скаляры и можно объявлять в директиве приватизации, на практике обычно это не используется, потому что в системе SAPFOR при распараллеливании автоматически производится анализ приватных скалярных переменных.
|
||||||
|
|
||||||
|
Аналогично устроена директива \texttt{!\$SPF ANALYSIS (REDUCTION(OP(...)))}, задающая редукцию по переменным из списка, стоящем вместо троеточия с бинарной редукционной операцией \texttt{OP}. Далее приведён приведён пример использования этой директивы:
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример задания редукции по переменной EPS с редукционной операцией взятия максимума.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
!$SPF ANALYSIS(REDUCTION (MAX(EPS)))
|
||||||
|
DO I = 1, N
|
||||||
|
DO J = 1, N
|
||||||
|
EPS = MAX(EPS, ABS(B(I,J) - A(I,J)))
|
||||||
|
A(I, J) = B(I, J)
|
||||||
|
END DO
|
||||||
|
END DO
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
20
src/sections/solution/impl.tex
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
\subsection{Второй этап -- реализация}
|
||||||
|
|
||||||
|
Таким образом, новый режим работы был оформлен как отдельных проход. По аналогии этот проход был назван INSERT\_PARALLEL\_DIRS\_NODIST, что подчёркивает отсутвие построения распределения данных. Поскольку INSERT\_PARALLEL\_DIRS осуществляет только вставку созданных заранее директив, его функционал менять не пришлось, поэтому внутри INSERT\_PARALLEL\_DIRS\_NODIST вызывается код прохода INSERT\_PARALLEL\_DIRS.
|
||||||
|
|
||||||
|
Само создание текста параллельных директив, которое происходило в проходе CREATE\_PARALLEL\_DIRS, подверглось правкам. Оттуда полностью убран код, отвечающий за директивы распределения данных. Также изменён код для конструирования параллельных директив: убрано создание приставки ON в директиве и клауз удалённого доступа к данным, среди которых SHADOW\_RENEW и REMOTE\_ACCESS. Также был переработан алгоитм заполнения клауз TIE (который был реализован для старого режима распараллеливания на общую память). В нём использовались массивы, согласно которым распределялись витки цикла, а в новом режиме отображения витков циклов на массивы нет. Новый алгоритм напрямую использует обращения к массивам, происходящие внутри цикла. Оказалось, что новая версия CREATE\_PARALLEL\_DIRS стала намного компактнее и было решено не создавать для неё отдельный проход и сделать частью INSERT\_PARALLEL\_DIRS\_NODIST.
|
||||||
|
|
||||||
|
|
||||||
|
Также, новый проход не унаследовал зависимости от проходов \\ CREATE\_TEMPLATE\_LINKS и LOOP\_ANALYZER\_DATA\_DIST\_S*, посколько они отвечали только за распределение данных.
|
||||||
|
|
||||||
|
Ещё пришлось переработать проход LOOP\_ANALYZER\_COMP\_DIST. Он отвечал за анализ обращений к массивам внутри цикла и распараллеливание, на основе этой информации. Главное что пришлось изменить -- убрать часть с выбором массива, согласно которому распределяются витки цикла. Преобразованный проход получил название LOOP\_ANALYZER\_NODIST.
|
||||||
|
|
||||||
|
В результате схема зависимостей изменилась следующим образом:
|
||||||
|
\pagebreak
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.5]{src/assets/pass_deps_nodist_0.png}
|
||||||
|
\caption{сравнение схемы работы проходов режима распараллеливания с распределением данных (слева) с новым режимом распараллеливания на общую память (справа).}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
Далее, следует сказать о ещё одной немаловажной части работы -- интеграции с инструментом для визуализации (диалоговой оболочкой) системы SAPFOR. Здесь требовалось реализовать два основных сценария работы. Первый основной сценарий -- запуск распараллеливания на общую память. Требовалось предоставить интерфейс для вызова прохода визуализатором. С этим не возникло сложностей, так как для этого потребовалось написать простую функцию \texttt{SPF\_SharedMemoryParallelization}, которую вызывает диалоговая оболочка и которая в свою очередь запускает проход INSERT\_PARALLEL\_DIRS\_NODIST. Второй сценарий работы предполагал запуск анализа распараллеливания без фактической вставки директив. Аналгично запуску распараллеливания, была добавлена возможность вызывать из визуализатора проход LOOP\_ANALYZER\_NODIST.
|
||||||
15
src/sections/solution/issues.tex
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
\subsection{Дополнительные проблемы}
|
||||||
|
|
||||||
|
Так же в процессе тестирования были обнаружены некоторые другие проблемы, которые не относятся напрямую с распараллеливанием на общую память. Среди них есть как недочёты системы SAPFOR, так и DVM:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item неправильная обработка OpenMP директив (SAPFOR)
|
||||||
|
|
||||||
|
\item распараллеливание циклов, содержащих оператор return (SAPFOR)
|
||||||
|
|
||||||
|
\item неправильная обработка встроенных функций Фортрана (функция int() обрабатывалась как обычная переменная) (DVM)
|
||||||
|
|
||||||
|
\item ошибки при создании кода для CUDA-устройств связанные со встроенными битовыми операциями (DVM)
|
||||||
|
|
||||||
|
\item ошибки при создании кода для CUDA-устройств связанные с использованием в фортране ключевых слов языка Си (DVM)
|
||||||
|
\end{itemize}
|
||||||
46
src/sections/solution/prep.tex
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
\subsection{Первый этап -- подготовка}
|
||||||
|
|
||||||
|
Основной целью данного этапа стал анализ внутреннего устройства системы SAPFOR, так как было принято решение реализовывать распараллеливание как часть её функционала. На данном этапе было проведено исследование исходного кода системы, которое дало ответы на следующие вопросы:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item как происходит запуск распараллеливания с распределением данных;
|
||||||
|
|
||||||
|
\item какой код и в какой последовательни работает при распараллеливании с распределением данных;
|
||||||
|
|
||||||
|
\item какие органичивающие проверки планируется убрать в проходе распараллеливания на общую память;
|
||||||
|
|
||||||
|
\item какие структуры данных используются;
|
||||||
|
|
||||||
|
\item использование каких структур данных нужно избежать;
|
||||||
|
|
||||||
|
\item какие существующие алгоритмы (с можификациями или без) можно (и нужно) переиспользовать в добавляемом режиме;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Путём чтения исходного кода, документации и общения с авторами системы все эти вопросы были разрешены. Далее излагаются основные полученные сведения.
|
||||||
|
|
||||||
|
Как уже упомяналось ранее, структурно система SAPFOR состоит из множества алгоритмов, которые логически разделены на отдельные блоки -- проходы. Каждый проход выполняет свою функцию и может зависеть от других проходов. При запуске прохода перед ним запускаются все проходы, от которых он зависит непосредственно или транзитивно, при чём каждый проход запускается не больше одного раза. Таким образом в системе выстраивается дерево зависимостей проходов. На данный момент в системе их уже больше сотни.
|
||||||
|
|
||||||
|
Конечным проходом при распараллеливании с распределением данных явлется проход с названием INSERT\_PARALLEL\_DIRS, который производит вставку созданных директив в код. Главные его зависимости -- проход CREATE\_PARALLEL\_DIRS создания параллельных директив (без вставки) по полученной информации из анализа циклов. Анализ циклов производится следующей группой проходов:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item LOOP\_ANALYZER\_COMP\_DIST;
|
||||||
|
|
||||||
|
\item LOOP\_ANALYZER\_DATA\_DIST\_S2;
|
||||||
|
|
||||||
|
\item LOOP\_ANALYZER\_DATA\_DIST\_S1;
|
||||||
|
|
||||||
|
\item LOOP\_ANALYZER\_DATA\_DIST\_S0;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Они заполняют структуры, описывающие циклы, анализируют обращения к массивам внутри циклов, отображают обращения к массивам на циклы. Вместе с этим происходит вызов прохода CREATE\_TEMPLATE\_LINKS, который создаёт структуру данных, позволяющую строить распределение данных. Эта структура данных называется \textit{графом измерений массивов}. Кроме этого в работе распараллеливания участвует ещё множество других проходов (всего порядка семидесяти), которые не относятся к распараллеливанию напрямую. Эти проходы не касаются распределения данных, поэтому они пристально не рассматривались. Часть дерева зависимостей прохода вставки параллельных директив изображена на Рис. \ref{fig:distr-alg}.
|
||||||
|
|
||||||
|
\pagebreak
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.5]{src/assets/pass_deps_dist.png}
|
||||||
|
\caption{упрощённая схема работы проходов при распараллеливании с распределением данных.}
|
||||||
|
\label{fig:distr-alg}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
Таким образом, было установлено, что для успешной реализации распараллеливания на общую память необходимо и достаточно внести изменения в эти семь проходов, а от прохода CREATE\_TEMPLATE\_LINKS стоит полностью отказаться в новом режиме.
|
||||||
11
src/sections/solution/solution.tex
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
\section{Построение решения}
|
||||||
|
|
||||||
|
Весь процесс построения решения можно разделить на три основных этапа -- исследование кодовой базы системы SAPFOR, внесение необходимых правок и тестирование реализованного функционала.
|
||||||
|
|
||||||
|
\input{src/sections/solution/prep}
|
||||||
|
\input{src/sections/solution/impl}
|
||||||
|
\input{src/sections/solution/testing}
|
||||||
|
|
||||||
|
% \input{src/sections/solution/issues}
|
||||||
|
|
||||||
|
\todo{Описание реализованных алгоритмов можно сюда добавить, прям по проходам}
|
||||||
50
src/sections/solution/testing.tex
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
\subsection{Третий этап -- тестирование и решение возникших проблем}
|
||||||
|
|
||||||
|
Поскольку работа ведётся с исходным кодом фортран-программ, множество возможных вариантов входных программ слишком велико, чтобы предусмотреть абсолютно все ситуации на этапе реализации. Из-за этого было необходимо произвести тщательное тестирование, чтобы выявить основные случаи некорректного поведения системы SAPFOR.
|
||||||
|
|
||||||
|
Было проведено тщательное тестирование добавленного функционала на предмет корректности. Оно проводилось как на небольших модельных примерах, так и на больших примерах практически используемых программ. Суммарно за всё тестирование было обнаружено порядка тридцати различных примеров некорректного поведения добавленного режима. Далее описаны наиболее содержательных из найденных ошибок и то, как они были исправлены.
|
||||||
|
|
||||||
|
Первая из них касалась обработки приватных массивов. При распределении данных в DVM-системе запрещается распределять массивы, которые являются приватными хотябы для одного цикла. Поэтому в системе SAPFOR такие массивы не отображаются на циклы при построении схемы распределения данных. При распараллеливании на общую память DVM система допускает использование одного массива в качестве приватного и неприватного для разных циклов. Поэтому для режима распараллеливания на общую память было добавлено отображение на цикл всех неприватных для него массивов (в частности, это нужно для заполнения клаузы TIE). Из-за этого пришлось внести правки в проход LOOP\_ANALYZER\_NODIST.
|
||||||
|
|
||||||
|
Ещё одна проблема связана с обработкой передаваемых в процедуры секций массивов. Дело в том, что в DVM-системе запрещено использование в разных циклах пересекающихся по памяти различных секций массивов. Рассмотрим следующий пример:
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={пример, вызывающий ошибку выполнения.}]
|
||||||
|
program p
|
||||||
|
...
|
||||||
|
integer:: A(100)
|
||||||
|
call foo(A)
|
||||||
|
|
||||||
|
!DVM$ REGION
|
||||||
|
!DVM$ PARALLEL (i), TIE(A(i))
|
||||||
|
do i = 1, 100
|
||||||
|
A(i) = ...
|
||||||
|
endo
|
||||||
|
!DVM$ END REGION
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine foo(A)
|
||||||
|
integer:: A(50)
|
||||||
|
|
||||||
|
!DVM$ REGION
|
||||||
|
!DVM$ PARALLEL (i), TIE(A(i))
|
||||||
|
do i = 1, 50
|
||||||
|
A(i) = ...
|
||||||
|
endo
|
||||||
|
!DVM$ END REGION
|
||||||
|
end
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
В нём нём есть два параллельных цикла (строки 8 и 19). Один из них использует полный массив A (который объявлен на строке 3). Другой же использует секцию массива A, которая содержит его первые 50 элементов (объявление на строке 15). Запуск этого примера приводит к ошибке выполнения системы DVM. При этом если бы в подпрограмме \texttt{foo} было объявлено, что массив имеет размер 100 (то есть фактически передавался бы массив целиком), то ошибки бы не было.
|
||||||
|
|
||||||
|
В случае аналогичного распараллеливания с распределением, ошибок выполнения DVM не возникает. Из-за этого в цепь проходов распараллеливания на общую память был добавлен новый проход, который получил название SELECT\_ARRAY\_DIM\_CONF. Он запускается после анализа циклов и фильтрует параллельные циклы так, чтобы в них не было пересечений по памяти используемых массивов. При обнаружение конфликтной группы циклов, выбирается один из них, который будет распараллелен, а другие к распараллеливанию не допускаются.
|
||||||
|
|
||||||
|
Таким образом схема проходов нового режима получила окончательный вид, представленный на Рис. \ref{fig:deps-final}:
|
||||||
|
|
||||||
|
% \pagebreak
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.5]{src/assets/pass_deps_nodist_1.png}
|
||||||
|
\caption{итоговая схема работы проходов при распределении на общую память.}
|
||||||
|
|
||||||
|
\label{fig:deps-final}
|
||||||
|
\end{figure}
|
||||||
53
src/sections/task/aims.tex
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
\subsection{Постановка задачи, определение целей работы}
|
||||||
|
|
||||||
|
Так возникает задача добавления в систему SAPFOR дополнительного сценария работы -- распараллеливания фортран-программ без построения схемы распределения данных и с использованием директив PARALLEL без клаузы ON.
|
||||||
|
|
||||||
|
Требуется, чтобы новый режим мог обходить ограничения, накладываемые распределением данных, тем самым расширяя класс распараллеливаемых программ на общую память по сравнению со стандартным распараллеливанием на кластер. В частности, вставляемые директивы должны корректно описывать все данные, используемые в цикле, их область хранения в памяти и зависимости типа ACROSS, если они есть.
|
||||||
|
|
||||||
|
Также от добавляемого функционала естественно потребовать его \textit{корректность}: при условии, если входная программа корректная, то система SAPFOR должна выдавать правильную параллельную программу, которая должен успешно компилироваться и выполняться.
|
||||||
|
|
||||||
|
Помимо этого, результирующее распараллеливание должно быть эффективным, то есть давать приемлемый прирост производительности за счёт многопоточного выполнения: не замедлять программу существенно в худших случаях и получать распараллеливание, конкурирующие с ручным в лучших случаях. В это требование дополнительно входит расстановка оптимизирующих клауз TIE в директивы PARALLEL везде, где это возможно.
|
||||||
|
|
||||||
|
Поскольку работа ведётся в рамках доработки системы SAPFOR, решение должно быть в неё интегрировано должным образом:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item в системе SAPFOR каждое преобразование оформляется в виде последовательности \textit{проходов} -- алгоритмов, которые логически разделены на блоки. Поэтому новый функционал должен быть реализован в виде нового прохода (или в виде последовательности новых проходов);
|
||||||
|
|
||||||
|
\item новый режим распараллеливания, должен учитывать и правильно обрабатывать директивы системы SAPFOR;
|
||||||
|
|
||||||
|
\item должна быть добавлена возможность вызова это режима через диалоговую графическую оболочку;
|
||||||
|
|
||||||
|
\item вместе с самим распараллеливанием должен быть добавлен функционал анализа входного кода, который выдавал бы информацию по распараллеливанию без фактической вставки директив. Аналогичный анализ в системе SAPFOR есть и для режима распараллеливания на кластер. Он служит для выявления проблем при автоматизированном распараллеливании;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Ещё одной подцелью работы является проверка выполнения этих требований путём проведения тестирования на выбранном множестве программ, которые должны содержать достаточное количество распараллеливаемых циклов разных видов.
|
||||||
|
|
||||||
|
Рассмотрим небольшой пример ожидаемого распараллеливания на общую память на отрывке программы, реализующей алгоритм Якоби (см. Рис). Система SAPFOR должна успешно вставить все присутствующие директивы DVM-системы. При запуске анализа кода диалоговая система должна сообщить, что внешний цикл распараллелить нельзя (и указать причину), и что внутренние циклы распараллеливаются без препятствий.
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример ожидаемого распараллеливания.}]
|
||||||
|
...
|
||||||
|
do it = 1,itmax
|
||||||
|
eps = 0.
|
||||||
|
!DVM$ REGION
|
||||||
|
!DVM$ PARALLEL (j,i), PRIVATE (i,j),TIE (a(i,j),b(i,j)),REDUCTION (max (eps))
|
||||||
|
do j = 2,l - 1
|
||||||
|
do i = 2,l - 1
|
||||||
|
eps = max (eps,abs (b(i,j) - a(i,j)))
|
||||||
|
a(i,j) = b(i,j)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
!DVM$ PARALLEL (j,i), PRIVATE (i,j),TIE (a(i,j),b(i,j))
|
||||||
|
do j = 2,l - 1
|
||||||
|
do i = 2,l - 1
|
||||||
|
b(i,j) = calculate (a(i - 1,j) + a(i,j - 1) + a(i + 1,j) + a(i,j + 1))
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
!DVM$ END REGION
|
||||||
|
if (eps .lt. maxeps) goto 3
|
||||||
|
enddo
|
||||||
|
3 continue
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
В дополнение к описанному, существует ещё несколько сценариев использования системы SAPFOR, при котором может пригодиться новый функционал. Во-первых, с помощью режима распараллеливания на общую память можно будет распараллеливать программы, написаные на технологии MPI, что может дать дополнительное ускорение. Во-вторых, данный режим может быть полезен и при обычном распараллеливании с распределением данных: с его помощью можно предварительно оценивать программы на предмет потенциала к распараллеливанию, например заранее узнавать, какие циклы могут быть распараллелены, а какие нет. Используя полученную информацию, можно оценивать вероятность того, что распараллеливание даст положительный эффект ещё до создания схемы распределения данных.
|
||||||
55
src/sections/task/dvm_shared.tex
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
\subsection{Реализация в DVM-системе}
|
||||||
|
|
||||||
|
Как описывалось во введении, распараллеливание в модели DVM происходит при помощи специальных директив. При привычном распараллеливании с распределением данных, в основном, используются следующие директивы:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item DISTRIBUTE -- предназначена для распределения элементов массивов по узлам
|
||||||
|
|
||||||
|
\item ALIGN -- отображает элементы нескольких массивов на заданный распределённый массив и распределяет их на соответствующие узлы
|
||||||
|
|
||||||
|
\item REGION -- определяет область кода, которую следует выполнять параллельно
|
||||||
|
|
||||||
|
\item PARALLEL ... ON -- определяет цикл, витки которого следует выполнять параллельно, при этом задавая отображение пространства витков цикла на распределённый массив.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример распараллеленного в модели DVM гнезда циклов. Здесь происходит отображение элементов массива B на элементы массива A, распределение массива A и распараллеливание гнезда циклов. При запуске на кластере каждый узел получит непрерывные и примерно равные секции массива A, точно такие же секции B и соответствующие этим элементам итерации цикла.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
!DVM$ DISTRIBUTE (BLOCK,BLOCK) :: A
|
||||||
|
!DVM$ ALIGN B(I,J) WITH A(I,J)
|
||||||
|
|
||||||
|
!DVM$ REGION
|
||||||
|
!DVM$ PARALLEL (I,J) ON A(I,J), REDUCTION (MAX(EPS))
|
||||||
|
DO I = 1, N
|
||||||
|
DO J = 1, N
|
||||||
|
EPS = MAX(EPS, ABS(B(I,J) - A(I,J)))
|
||||||
|
A(I, J) = B(I, J)
|
||||||
|
END DO
|
||||||
|
END DO
|
||||||
|
!DVM$ END REGION
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Чтобы дать пользователю возможность распараллеливать программы на общую память, в синтаксис языка DVM-системы была добавлена новая форма директивы PARALLEL для распараллеливания без распределения данных.
|
||||||
|
|
||||||
|
Новый вариант директивы PARALLEL отличается от исходного тем, что в ней отсутствует клауза ON. При использовании таких директив не надо указывать распределённые массивы. Сами директивы распределения данных также не нужны в таких программах. Более того, в таких директивах PARALLEL не должны присутствовать клаузы доступа к удалённым данных, такие как SHADOW\_RENEW, SHADOW\_COMPUTE и REMOTE\_ACCESS.
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример распарараллеливания гнезда циклов на общую память. Здесь не должно быть ни директив распределения данных, ни клаузы ON отображения витков цикла на массив.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
!DVM$ REGION
|
||||||
|
!DVM$ PARALLEL (I,J), REDUCTION (MAX(EPS)), TIE(A(I, J), B(I, J))
|
||||||
|
DO I = 1, N
|
||||||
|
DO J = 1, N
|
||||||
|
EPS = MAX(EPS, ABS(B(I,J) - A(I,J)))
|
||||||
|
A(I, J) = B(I, J)
|
||||||
|
END DO
|
||||||
|
END DO
|
||||||
|
!DVM$ END REGION
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Так же в таком варианте директивы PARALLEL может присутствовать клауза TIE, сопоставляющая итерации цикла с массивом, которая используется в DVM-системе для улучшения производительности выходного исполняемого кода.
|
||||||
5
src/sections/task/existing_solution.tex
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
\subsection{Обзор существующих решений}
|
||||||
|
|
||||||
|
Исследования по теме автоматизированного распараллеливания программ ведутся достаточно давно. На данный момент существует не так много широко используемых средств, позволяющих получать параллельный код. Среди средств, которые в той или иной степени помогают в процессе распараллеливания программ можно выделить следующие: Polaris, CAPO, WPP, SUIF, VAST/Parallel, OSCAR, ParallelWare, Intel Parallel Studio XE.
|
||||||
|
|
||||||
|
Однако, открытых реализаций алгоритмов распараллеливания почти нет, поэтому за основу решения был взят уже существующие в системе SAPFOR режим распараллеливания с распределением данных. Этот подход не только помог учесть спицифику языков фортран и DVM, но и позволил минимизировать объём внесённых в систему SAPFOR изменений.
|
||||||
7
src/sections/task/sapfor_shared.tex
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
\subsection{Мотивация поддержки режима распараллеливания на общую память в системе SAPFOR}
|
||||||
|
|
||||||
|
Поскольку система SAPFOR не способна проанализировать все тонкости логики работы программы, процесс построения оптимальной схемы распределения данных затрудняется. Поэтому аналогичная потребность в функционале распараллеливания на общую память возникает и в системе SAPFOR. Таким образом, реализация нового режима работы системы SAPFOR для распараллеливания на общую память стала для данной работы основной целью, которая детально описывается в последующих параграфах.
|
||||||
|
|
||||||
|
% Существующий режим распараллеливания основан на построении графа измерений массивов. Это граф, в котором вершинами являются измерения массивов, а дуги представляют собой информацию о совместном использовании элементов массива внутри отдельной итерации цикла. После этого по определённым правилам дуги взвешиваются и строится подграф, минимизирующий суммарный вес не вошедших в него дуг. По этому подграфу в результате строится распределение данных, и чем меньше суммарный вес не вошедших дуг, тем схема оптимальнее с точки зрения эффективности выполнения параллельной программы. Поэтому, в программах, где нет оптимального решения этой подзадачи, схема распределения строится плохо, возникает много обращений к данным с удалённых узлов и полученная программа получается неэффективной.
|
||||||
|
|
||||||
|
% Таким образом, возникает потребность в новом функционале системы SAPFOR, позволяющем распараллеливать программы на общую память. Разработка и реализация такого режима работы системы SAPFOR и стали главной целью данной работы.
|
||||||
14
src/sections/task/task.tex
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
\section{Распараллеливание на общую память}
|
||||||
|
|
||||||
|
При написании параллельных DVMH-программ пользователь решает две задачи: он должен найти оптимальный способ распределения данных и обозначить циклы, которые могут выполняться параллельно. На практике нередко возникают ситуации, когда для рассматриваемой программы решить первую из этих задачу слишком сложно или невозможно, но вторая задача решается успешно, то есть программа обладает хорошим потенциалом для распараллеливания.
|
||||||
|
|
||||||
|
Основной проблемой, возникающей при попытке построить схему распределения данных, является то, что разные циклы для их распараллеливания могут требовать разных, конфликтующих, схем распределения данных. При распараллеливании практически значимых программ, в силу их объёмности, такие конфликты возникают повсеместно. Эта проблема подробно рассматривается в \cite{par-reg}.
|
||||||
|
|
||||||
|
Выходом из такой ситуации является рассмотрение частного случая -- распараллеливания на общую память. При таком распараллеливании предполагается, что целевая вычислительная система состоит из единственного устройства. Это ограничение позволяет обойти потребность в распределении данных, так как все данные располагаются в общей оперативной памяти устройства.
|
||||||
|
|
||||||
|
В качестве устройства для запуска программы, распараллеленной на общую память, можно рассматривать многопоточный процссор или графический ускоритель (видеокарту).
|
||||||
|
|
||||||
|
\input{src/sections/task/dvm_shared}
|
||||||
|
\input{src/sections/task/sapfor_shared}
|
||||||
|
\input{src/sections/task/aims}
|
||||||
|
\input{src/sections/task/existing_solution}
|
||||||
20
src/sections/tests/npb.tex
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
\subsection{NAS Parallel Benchmarks}
|
||||||
|
|
||||||
|
NAS Parallel Benchmarks -- это пакет из десяти программ, разработанных для тестирования производительности многопоточных вычислительных систем, восемь из них написаны на фортране, остальные -- на языке Си. Тесты на фортране включают следующие программы:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item BT, SP, LU --
|
||||||
|
\textbf{B}lock \textbf{T}ri-diagonal,
|
||||||
|
\textbf{S}calar \textbf{P}entadiagonal,
|
||||||
|
\textbf{L}ower-\textbf{U}pper. Решают синтетическую систему нелинейных диффиренциальных уравнений в частных производных (3-мерная система уравнений Навье — Стокса для сжимаемой жидкости или газа), используя три алгоритма: блочная трёхдиагональная схема с методом переменных направлений (BT), скалярная пятидиагональная схема (SP) и метод симметричной последовательной верхней релаксации (алгоритм SSOR, задача LU);
|
||||||
|
\item CG -- \textbf{C}onjugate \textbf{G}radient. Приближение к наименьшему собственному значению большой разреженной симметричной положительно-определённой матрицы с использованием метода обратных итераций вместе с методом сопряжённых градиентов в качестве подпрограммы для решения СЛАУ;
|
||||||
|
\item EP -- \textbf{E}mbarrassingly \textbf{P}arallel. Генерация независимых нормально распределённых случайных величин;
|
||||||
|
\item FT -- \textbf{F}ourier \textbf{T}ransform. Решение трёхмерного уравнения в частных производных при помощи быстрого преобразования Фурье;
|
||||||
|
\item MG -- \textbf{M}ulti-\textbf{G}rid. Аппроксимация решения трёхмерного дискретного уравнения Пуассона при помощи V-циклового многосеточного метода;
|
||||||
|
\item UA -- \textbf{U}nstructured \textbf{A}daptive mesh. Решение уравнения теплопроводности с учётом диффузии и конвекции в кубе. Источник тепла подвижен, сетка нерегулярна и меняется каждые 5 шагов;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
Каждая программа пакета имеет параллельные версии на OpenMP и на MPI. Кроме того, некоторые тесты имеют также несколько вариантов распараллеливания. Так, например, для теста LU можно выбрать конвеерное распараллеливание, распараллеливание по гиперплоскостям и DO-ACROSS версию. Это распараллеливание было произведено создателями пакета, профессионалами в области параллельных вычислений, поэтому было принято решение взять эти версии за эталон распараллеливания.
|
||||||
|
|
||||||
|
Также этот пакет позволяет запускать все тесты на разных \textit{классах}, что даёт возможность подбирать для конкретной вычислительной системы оптимальный размер задачи, чтобы тест работал не слишком быстро и не слишком долго. Для удобства в каждую программу встроены средства для замера времени работы теста и самопроверка результатов вычислений.
|
||||||
45
src/sections/tests/parallelizing.tex
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
\subsection{Процесс распараллеливания}
|
||||||
|
|
||||||
|
Часто для того, чтобы получить эффективный параллельный вариант программы с помощью системы SAPFOR, требуется провести ряд преобразований исходного кода. При распараллеливании тестов NAS приходилось совершать много преобразований трёх видов: слияние файлов, подстановка процедур, указание приватных и редукционных массивов.
|
||||||
|
|
||||||
|
Слияние файлов представляет собой несложное преобразование, объединяющие все файлы программы в один. Это преобразование нужно из-за проблем при раздельной компиляции фортран-файлов системой DVM. При помощи диалоговой оболочки это преобразование можно легко делать <<в один клик>>.
|
||||||
|
|
||||||
|
В некоторых местах распараллеливание циклов осложнено наличием в теле цикла вызовов процедур. Чтобы распараллелить такие циклы, можно попытаться подставить тело процедуры вместо её вызова. Так как в диалоговой оболочке есть проходы анализа кода и подстановки процедур, можно также без больших усилий найти циклы, которые не распараллеливаются из-за вызовов процедур и произвести подстановку в нужных местах.
|
||||||
|
|
||||||
|
Нередко в коде встречаются приватные и редукционные массивы. Так как система SAPFOR в данный момент не поддерживает автоматическое обнаружение таких массивов, их приходится вручную указывать при помощи директив SPF ANALYSIS (PRIVATE) и SPF ANALYSIS (REDUCTION).
|
||||||
|
|
||||||
|
Отдельного внимания потребовала программа LU. Основная вычислительная нагрузка программы приходится на алгоритм SSOR (метод симмтричной последовательной верхней релаксации). Он представляет собой пару гнёзд циклов глубины два. Рассмотрим первое из этих гнёзд, так как второе распараллеливается полностью аналогично. Возможности параллельного выполнения витков этого цикла мешает только зависимость по данным массива \texttt{rsd}: каждая итерация с номером \textit{(i, j)} использует элементы, которые вычисляются витками \textit{(i - 1, j)}, \textit{(i, j - 1)}. В такой ситуации витки имеют частичный порядок и некоторые группы витков могут выполняться параллельно. В пакете есть три реализации такого распараллеливания:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item версия с использованием так называемого \textit{конвейерного параллелизма}. В ней поддержание корректной последовательности витков цикла осуществляется за счёт использования служебного синхронизационного массива и примитивов синхронизации OpenMP \texttt{atomic read} и \texttt{atomic write};
|
||||||
|
|
||||||
|
\item в другой версии, которая называется DO-ACROSS, используется похожая схема, только синхронизация реализована механизмом упорядоченного выполнения витков цикла. Для этого в OpenMP есть специальная директива ORDERED;
|
||||||
|
|
||||||
|
\item последняя версия использует \textit{параллелизм по гиперплоскостям}. При наличии такой зависимости, витки с номерами \textit{(i, j)}, у которых сумма \textit{i + j} совпадает, образуют гиперплоскости и могут выполняться параллельно (см. Рис. \ref{fig:hp});
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=1]{src/assets/hp.png}
|
||||||
|
\caption{разделение итерационного пространства на гиперплоскости. Внутри одной гиперплоскости элементы могут считаться параллельно.}
|
||||||
|
\label{fig:hp}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
В силу того, что SAPFOR не способен проанализировать логику синхронизаций и зависимости между разными гиперплоскостями, первый и третий варинты распараллелить не удалось. Однако во втором варианте система SAPFOR успешно распознала зависимость по данным и распараллелила цикл с использованием клаузы ACROSS:
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=FORT,caption={
|
||||||
|
пример вставленной клаузы ACROSS, задающую зависимость размера 1 по последним двум измерениям массива \texttt{rsd}. В теле цикла происходит чтение элементов массива \texttt{rsd(*,*,j-1,k)}, \texttt{rsd(*,*,j,k-1)}, \texttt{rsd(*,*,j-1,k-1)} и запись в элементы массива \texttt{rsd(*,*,j,k)}.
|
||||||
|
}]
|
||||||
|
...
|
||||||
|
!DVM$ REGION
|
||||||
|
!DVM$ PARALLEL (k,j), PRIVATE (...), TIE(..., rsd(*,*,j,k)), ACROSS (rsd(0:0,0:0,1:0,1:0))
|
||||||
|
do k = 2,nz - 1
|
||||||
|
do j = jst,jend
|
||||||
|
...
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
!DVM$ END REGION
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Таким образом, в результате автоматизированного распараллеливания были получены параллельные версии тестов BT, CG, EP, FT, SP, LU. Остальные тесты (то есть MG и UA) распараллелить не удалось, даже при помощи преобразований. Причиной этому служит наличие в этих тестах нетривиальной логики, которая не позволяет системе SAPFOR производить распараллеливание.
|
||||||
66
src/sections/tests/results.tex
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
\subsection{Результаты запусков}
|
||||||
|
|
||||||
|
После получения распараллеленных на общую память версий тестов был проведен их запуск на различных вычислительных устройствах. Произведено сравнение полученных версий с параллельными версиями на OpenMP. Запуск на процессоре Intel Core i7 980x (6 ядер, 12 потоков, компилятор mpiifort с уровнем оптимизации -O3) показал следующие результаты (см. Рис. \ref{fig:titan_12_all_classes} и \ref{fig:titan_c_all}):
|
||||||
|
\pagebreak
|
||||||
|
|
||||||
|
\begin{figure}[hbt!]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.35]{src/assets/titan_12_all_classes.png}
|
||||||
|
\caption{замер времени работы полученных версий на DVMH и эталонных версий на OpenMP на процессоре Intel Core i7 980x (12 потоков).}
|
||||||
|
\label{fig:titan_12_all_classes}
|
||||||
|
\end{figure}
|
||||||
|
\pagebreak
|
||||||
|
\begin{figure}[hbt!]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.5]{src/assets/titan_c_all.png}
|
||||||
|
\caption{сравнение времени работы тестов на различном количестве потоков на процессоре Intel Core i7 980x (класс C).}
|
||||||
|
\label{fig:titan_c_all}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
Исследуя данные графики, можно сделать следующие выводы:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item сами по себе тесты ускоряются не одинаково: тесты CG, FT, SP дают максимальное ускорение примернов два раза, BT и LU -- в четыре с половиной, EP -- в восемь с половиной;
|
||||||
|
|
||||||
|
\item на одном и том же классе разные тесты сильно отличаются по времени работы (например, тест BT на 12 потоках работает около 400 секунд, а EP - около 20ти секунд);
|
||||||
|
|
||||||
|
\item разрыв между DVM-версиями и OpenMP-версиями на классе A составляет около 10-20\% в пользу OpenMP; на тесте FT разрыва нет вовсе;
|
||||||
|
|
||||||
|
\item с ростом размера задач разрыв уменьшается до 0-5\% на классе C;
|
||||||
|
|
||||||
|
\item на классе C тесты FT, LU, SP показывают одинаковое ускорение, на BT и CG сохраняется замедление DVM-версий, DVM-версия EP ускоряется немного лучше, чем OpenMP-версия;
|
||||||
|
|
||||||
|
\item время работы DVM-версий и OpenMP-версий на различном количестве используемых потоков также отличается несущественно, с ростом количества потоков это различие уменьшается;
|
||||||
|
|
||||||
|
\item в целом, есть примеры, на которых DVM-версии быстрее, чем версии на OpenMP и наоборот;
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
Дополнительно были получены результаты работы на графических ускорителях. При тестировании использовались видеокарты Nvidia GeForce GTX 1660 Ti и Nvidia GeForce GTX 1050 Ti.
|
||||||
|
|
||||||
|
В процессе запусков возникли проблемы с тестом FT. Параллельная версия этого теста содержит приватные массивы больших размеров, что приводило к переполнению памяти видеокарты. Поэтому было принято решение отказаться от запуска программы FT на ускорителях.
|
||||||
|
|
||||||
|
Результаты представлены на Рис. \ref{fig:gpu}:
|
||||||
|
\pagebreak
|
||||||
|
\begin{figure}[hbt!]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.35]{src/assets/gpu.png}
|
||||||
|
\caption{демонстрация ускорения работы полученных версий на ускорителях Nvidia относительно запуска последовательной программы на процессоре Intel Core i7 980x.}
|
||||||
|
\label{fig:gpu}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
Относительно результатов работы полученных версий на видеокартах спаведливы следующие факты:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item тест BT на видеокарте ускорился в 15,3 раз (против 3,6 раз на 12ти потоках на классе C);
|
||||||
|
|
||||||
|
\item CG -- ускорение в 8,6 раз против 2,7;
|
||||||
|
|
||||||
|
\item EP -- ускорение в 39,7 раз против 8,5 -- самое высокое ускорение;
|
||||||
|
|
||||||
|
\item LU -- ускорение в 5,4 раз против 3,8 -- видеокарта почти не даёт выигрыш по сравнению с многопоточным процессором;
|
||||||
|
|
||||||
|
\item SP -- ускорение в 10,4 раз против 2,5;
|
||||||
|
|
||||||
|
\item с ростом мощности видеокарты растёт и ускорение (модель GeForce GTX 1660 Ti современней и мощней чем GeForce GTX 1050 Ti);
|
||||||
|
\end{itemize}
|
||||||
8
src/sections/tests/tests.tex
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
\section{Исследование эффективности}
|
||||||
|
\label{sec:benchmark}
|
||||||
|
|
||||||
|
Немаловажную роль в оценке качества выполненной работы играет тестирование на предмет эффективности получаемого распараллеливания. Для этих целей был выбран специальный пакет программ, который широко используется в сфере исследования эффективности распараллеливания -- пакет \textit{NAS Parallel Benchmarks} \cite{npb}, который далее будет детально рассмотрен.
|
||||||
|
|
||||||
|
\input{src/sections/tests/npb}
|
||||||
|
\input{src/sections/tests/parallelizing}
|
||||||
|
\input{src/sections/tests/results}
|
||||||
54
src/titlepage.tex
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
\Faculty{Факультет вычислительной математики и кибернетики}
|
||||||
|
\Chair{Кафедра системного программирования}
|
||||||
|
% Лаборатория
|
||||||
|
% \Lab{~}
|
||||||
|
\Year{2024}
|
||||||
|
\Month{Месяц}
|
||||||
|
\City{Москва}
|
||||||
|
\AuthorText{Автор:}
|
||||||
|
\Author{Кочармин Михаил Дмитриевич}
|
||||||
|
\AuthorEng{Kocharmin Mikhail Dmitrievich}
|
||||||
|
\AcadGroup{427}
|
||||||
|
|
||||||
|
\TitleTop{Разработка и реализация алгоритма распараллеливания}
|
||||||
|
% Раскомментируйте, если нужны еще строчки названия
|
||||||
|
\TitleMiddle{фортран-программ на общую память}
|
||||||
|
% \TitleBottom{Третья строка названия}
|
||||||
|
% Uncomment if you need English title
|
||||||
|
% \TitleTopEng{Thesis theme, first line}
|
||||||
|
% \TitleMiddleEng{Thesis theme, second line}
|
||||||
|
% \TitleBottomEng{Thesis theme, third line}
|
||||||
|
|
||||||
|
\docname{ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ РАБОТА}
|
||||||
|
\Advisor{Крюков Виктор Алексеевич}
|
||||||
|
\AdvisorDegree{д.ф.-м.н., профессор\\}
|
||||||
|
% Раскомментируйте, чтобы добавить научного консультанта
|
||||||
|
\Consultant{Колганов Александр Сергеевич}
|
||||||
|
\ConsultantDegree{к.ф.-м.н.\\}
|
||||||
|
|
||||||
|
% Закомментируйте, если аннотация не нужна
|
||||||
|
\Abstract{
|
||||||
|
\input{src/abstract}
|
||||||
|
}
|
||||||
|
% Раскомментируйте, если нужна английская аннотация
|
||||||
|
% \AbstractEng{Abstract in English}
|
||||||
|
|
||||||
|
% Раскомментируйте, чтобы написать благодарности
|
||||||
|
% \Acknowledgments{Благодарности.}
|
||||||
|
|
||||||
|
%%%% DON'T change this. It is here because .sty does not support cyrillic cp properly %%%%
|
||||||
|
\TitlePageText{Титульная страница}
|
||||||
|
\University{Московский государственный университет имени М.В.Ломоносова}
|
||||||
|
\GrText{гр.}
|
||||||
|
\AdvisorText{Научный руководитель}
|
||||||
|
\ConsultantText{Научный консультант}
|
||||||
|
\AbstractText{Аннотация}
|
||||||
|
\AcknowledgmentsText{Благодарности}
|
||||||
|
\ListingText{Листинг}
|
||||||
|
\AlgorithmText{Алгоритм}
|
||||||
|
|
||||||
|
% Set PDF title and author
|
||||||
|
\hypersetup{
|
||||||
|
pdftitle={\PDFTitle},
|
||||||
|
pdfauthor={\PDFAuthor}
|
||||||
|
}
|
||||||
111
style.tex
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
\usepackage{cmap} % Для корректной кодировки в pdf
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage{rotating}
|
||||||
|
|
||||||
|
\usepackage[russian]{babel}
|
||||||
|
\usepackage{amsfonts} % Пакеты для математических символов и теорем
|
||||||
|
\usepackage{amstext}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{amsthm}
|
||||||
|
\usepackage{graphicx} % Пакеты для вставки графики
|
||||||
|
\usepackage{subfig}
|
||||||
|
\usepackage{color}
|
||||||
|
\usepackage[unicode]{hyperref}
|
||||||
|
\usepackage[nottoc]{tocbibind} % Для того, чтобы список литературы отображался в оглавлении
|
||||||
|
\usepackage{verbatim} % Для вставок заранее подготовленного текста в режиме as-is
|
||||||
|
\usepackage{listings}
|
||||||
|
|
||||||
|
\newcommand{\sectionbreak}{\clearpage} % Раздел с новой станицы
|
||||||
|
|
||||||
|
\usepackage{tikz}
|
||||||
|
\usepackage{pgfplots}
|
||||||
|
\usetikzlibrary{arrows,positioning}
|
||||||
|
\usepackage{adjustbox}
|
||||||
|
|
||||||
|
\usepackage{makecell}
|
||||||
|
\usepackage{booktabs}
|
||||||
|
\usepackage{boldline}
|
||||||
|
|
||||||
|
\usepackage[usenames,dvipsnames]{xcolor}
|
||||||
|
\usepackage{soul}
|
||||||
|
\usepackage{url}
|
||||||
|
\usepackage{multirow}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{algpseudocode}
|
||||||
|
|
||||||
|
\usepackage{pifont}
|
||||||
|
\usepackage{indentfirst} % Делать отступ в начале первого параграфа
|
||||||
|
|
||||||
|
% \usepackage{minted}
|
||||||
|
% \usemintedstyle{tango}
|
||||||
|
|
||||||
|
\usepackage{geometry}
|
||||||
|
\usepackage{tikz}
|
||||||
|
\usetikzlibrary{calc}
|
||||||
|
\usepackage{tcolorbox}
|
||||||
|
\usepackage{etoolbox}
|
||||||
|
\tcbuselibrary{skins,breakable}
|
||||||
|
|
||||||
|
% \newenvironment{tmpbox}{%
|
||||||
|
% \tcolorbox[%
|
||||||
|
% empty,
|
||||||
|
% parbox=false,
|
||||||
|
% noparskip,
|
||||||
|
% enhanced,
|
||||||
|
% breakable,
|
||||||
|
% frame hidden,
|
||||||
|
% boxrule=0pt,
|
||||||
|
% colback=white,
|
||||||
|
% left=-.5ex, % right=-4pt,
|
||||||
|
% before skip=.1ex plus 2pt,
|
||||||
|
% after skip=1ex plus 2pt,
|
||||||
|
% overlay unbroken and last={%
|
||||||
|
% \draw ($(frame.north west)+(0, -5ex)$)
|
||||||
|
% -- +(1\textwidth, 0);
|
||||||
|
% \draw ($(frame.south west)+(0, 0ex)$)
|
||||||
|
% -- +(1\textwidth, 0);
|
||||||
|
% }]
|
||||||
|
% }{\endtcolorbox}
|
||||||
|
|
||||||
|
% \usepackage{listings}
|
||||||
|
% \lstdefinestyle{CEE}{%
|
||||||
|
% frame=l, language=C, numbers=left, numbersep=1em, xleftmargin=2em
|
||||||
|
% }
|
||||||
|
|
||||||
|
\lstdefinestyle{FORT}{
|
||||||
|
breaklines=true,
|
||||||
|
xleftmargin=25pt,
|
||||||
|
xrightmargin=25pt,
|
||||||
|
aboveskip=10pt,
|
||||||
|
belowskip=10pt,
|
||||||
|
basicstyle=\ttfamily,
|
||||||
|
% backgroundcolor=\color{lightlightgray},
|
||||||
|
showstringspaces=false,
|
||||||
|
frame=tb,
|
||||||
|
language=fortran,
|
||||||
|
tabsize=2,
|
||||||
|
numbers=left,
|
||||||
|
numberstyle=\small,
|
||||||
|
numbersep=8pt,
|
||||||
|
morekeywords={*, factorial, sum, erlang},
|
||||||
|
keywordstyle=\textbf,
|
||||||
|
commentstyle=\textit,
|
||||||
|
captionpos=b,
|
||||||
|
breaklines=true,
|
||||||
|
postbreak=\mbox{$\hookrightarrow$}\space
|
||||||
|
}
|
||||||
|
|
||||||
|
% Общие параметры листингов
|
||||||
|
\lstset{
|
||||||
|
% frame=ltrb,
|
||||||
|
% showstringspaces=false,
|
||||||
|
% tabsize=4,
|
||||||
|
% basicstyle=\linespread{1.0}\tt\small, % делаем листинги компактнее
|
||||||
|
% breaklines=true,
|
||||||
|
% texcl=true, % русские буквы в комментах
|
||||||
|
% captionpos=b,
|
||||||
|
% aboveskip=\baselineskip,
|
||||||
|
% commentstyle=\tt
|
||||||
|
}
|
||||||
|
|
||||||
|
\newcommand{\todo}[1]{\textcolor{red}{#1}}
|
||||||