Analysis tool

This commit is contained in:
2022-05-09 17:58:25 +02:00
parent 15497619dd
commit c11f09ebe2
9 changed files with 368 additions and 229 deletions

View File

@@ -60,6 +60,12 @@ encoding=UTF-8
highlight=LaTeX
mode=LaTeX
[item:inc/x.implementation.tex]
archive=true
encoding=UTF-8
highlight=LaTeX
mode=LaTeX
[item:thesis.kilepr]
archive=true
encoding=

View File

@@ -3,3 +3,24 @@ The option `-shell-escape` has to be appended to the PDFLatex command line. As o
~~Update:
Don't use the package `minted` that comes with the template. Instead use the one from the package manager. Then also the LivePreview works together with the `-shell-escape` command. The option `[cache=false]` is not required.~~
### Nomenclature
https://tex.stackexchange.com/a/96596
```
Using kile, I have configured the QuikBuild command as follows:
go to: Settings -> Configure Kile... -> Build
create a new tool:
Name: "MakeIndexNomencl"
Command: makeindex
Options: '%S.nlo' -s nomencl.ist -o '%S.nls'
add MakeIndexNomencl and a second PDFLaTeX to the QuickBuild tool:
PDFLaTeX
MakeIndexNomencl
PDFLaTeX
```

View File

@@ -24,7 +24,7 @@
\usepackage{listings}
\usepackage{trsym}
\usepackage{trfsigns}
\usepackage{minted}
\usepackage[cache=false]{minted}
\usepackage{multirow}
\usepackage{fancyhdr}
\usepackage{nomencl}
@@ -33,6 +33,7 @@
\usepackage{subfig}
\usepackage{url}
\usepackage{hyperref}
\usepackage{tikzit}
%\usepackage{listings}
%\input{subsections.sty}
\setcounter{secnumdepth}{5}
@@ -156,6 +157,9 @@
\input{inc/1.introduction}
\newpage
\clearpage
\input{inc/6.implementation}
\newpage
\clearpage
%\input{2.usw.usw}
%\newpage
%\clearpage

97
img/drcachesim.tikz Normal file
View File

@@ -0,0 +1,97 @@
\begin{tikzpicture}
\begin{pgfonlayer}{nodelayer}
\node [style=none] (2) at (5, 15.5) {};
\node [style=none] (3) at (8.75, 15.5) {};
\node [style=none] (4) at (5, 13.5) {};
\node [style=none] (5) at (8.75, 13.5) {};
\node [style=none] (7) at (7.25, 14.5) {memref\_t};
\node [style=application] (9) at (5.5, 27) {Multithreaded application};
\node [style=none] (10) at (0.25, 24) {};
\node [style=none] (11) at (0.25, 18) {};
\node [style=none] (12) at (13.5, 24) {};
\node [style=none] (13) at (13.5, 18) {};
\node [style=none] (14) at (5.5, 24) {};
\node [style=none] (15) at (5.5, 18) {};
\node [style=none] (16) at (3, 21) {DynamoRIO};
\node [style=none] (17) at (9.5, 23) {DrCacheSim Client};
\node [style=none] (18) at (5.5, 24) {};
\node [style=function] (19) at (9.5, 21.5) {event\_bb\_analysis()};
\node [style=function] (20) at (9.5, 20) {event\_thread\_init()};
\node [style=none] (28) at (9.5, 19) {\vdots};
\node [style=none] (30) at (13.5, 21) {};
\node [style=none] (31) at (0, 11) {};
\node [style=none] (32) at (13.75, 11) {};
\node [style=none] (33) at (0, 0) {};
\node [style=none] (34) at (13.75, 0) {};
\node [style=none] (36) at (9.35, 14.5) {};
\node [style=none] (37) at (7, 10) {DrCacheSim Analyzer};
\node [style=none] (38) at (5.5, 8.75) {};
\node [style=none] (39) at (13, 8.75) {};
\node [style=none] (40) at (5.5, 5.75) {};
\node [style=none] (41) at (13, 5.75) {};
\node [style=none] (43) at (9.25, 8) {DRAMTracer};
\node [style=function] (44) at (9.25, 6.75) {process\_memref()};
\node [style=none] (45) at (5.5, 3.75) {};
\node [style=none] (46) at (13, 3.75) {};
\node [style=none] (47) at (5.5, 0.75) {};
\node [style=none] (48) at (13, 0.75) {};
\node [style=none] (49) at (9.25, 3) {Other analysis\_tool\_t};
\node [style=function] (50) at (9.25, 1.75) {process\_memref()};
\node [style=none] (51) at (9.25, 5) {.};
\node [style=none] (52) at (9.25, 4.75) {.};
\node [style=none] (53) at (9.25, 4.5) {.};
\node [style=none] (54) at (7, 16) {Named pipe};
\node [style=none] (55) at (1, 11) {};
\node [style=none] (56) at (1, 1.75) {};
\node [style=none] (57) at (1, 6.75) {};
\node [style=none] (58) at (3.25, 7.25) {memref\_t \&};
\node [style=none] (59) at (3.25, 2.25) {memref\_t \&};
\node [style=none] (60) at (15, 21) {};
\node [style=none] (61) at (15, 14.5) {};
\node [style=none] (62) at (1, 14.5) {};
\node [style=none] (63) at (5, 14.5) {};
\end{pgfonlayer}
\begin{pgfonlayer}{edgelayer}
\draw [style=pipe] (2.center)
to [bend right=90, looseness=0.75] (4.center)
to [bend right=90, looseness=0.75] cycle;
\draw [style=pipe] (4.center)
to [bend right=90, looseness=0.75] (2.center)
to (3.center)
to [bend left=90] (5.center)
to cycle;
\draw [style=block] (12.center)
to (13.center)
to (15.center)
to (11.center)
to (10.center)
to (14.center)
to cycle;
\draw [style=dashed line] (14.center) to (15.center);
\draw [style=block] (33.center)
to (31.center)
to (32.center)
to (34.center)
to cycle;
\draw [style=inner block] (38.center)
to (40.center)
to (41.center)
to (39.center)
to cycle;
\draw [style=inner block] (47.center)
to (48.center)
to (46.center)
to (45.center)
to cycle;
\draw [style=arrow without head] (55.center) to (57.center);
\draw [style=arrow without head] (57.center) to (56.center);
\draw [style=arrow] (57.center) to (44);
\draw [style=arrow] (56.center) to (50);
\draw [style=arrow] (9) to (18.center);
\draw [style=arrow without head] (30.center) to (60.center);
\draw [style=arrow without head] (60.center) to (61.center);
\draw [style=arrow without head] (63.center) to (62.center);
\draw [style=arrow] (61.center) to (36.center);
\draw [style=arrow] (62.center) to (55.center);
\end{pgfonlayer}
\end{tikzpicture}

24
img/thesis.tikzstyles Normal file
View File

@@ -0,0 +1,24 @@
% TiKZ style file generated by TikZiT. You may edit this file manually,
% but some things (e.g. comments) may be overwritten. To be readable in
% TikZiT, the only non-comment lines must be of the form:
% \tikzstyle{NAME}=[PROPERTY LIST]
% Node styles
\tikzstyle{function}=[fill={rgb,255: red,255; green,125; blue,125}, draw=red, shape=rectangle, rounded corners=3pt, thick]
\tikzstyle{application}=[fill={rgb,255: red,238; green,238; blue,238}, draw=black, shape=rectangle, minimum width=3cm, minimum height=1cm, thick]
\tikzstyle{thread player}=[fill=white, draw=black, shape=rectangle, minimum width=3cm, minimum height=8mm]
\tikzstyle{initiator socket}=[fill=black, draw=black, shape=rectangle, minimum width=2mm, minimum height=5mm]
\tikzstyle{interconnect thin}=[fill=white, draw=black, shape=rectangle, minimum height=3.5cm, align=center, minimum width=2.5cm]
\tikzstyle{interconnect thick}=[fill=white, draw=black, shape=rectangle, minimum height=3.5cm, align=center, minimum width=3.5cm]
\tikzstyle{target socket}=[fill=white, draw=black, shape=rectangle, minimum width=2mm, minimum height=5mm]
\tikzstyle{cache}=[fill=white, draw=black, shape=rectangle, minimum height=8mm, minimum width=1.75cm]
\tikzstyle{l3cache}=[fill=white, draw=black, shape=rectangle, minimum height=2.5cm, minimum width=1.75cm]
% Edge styles
\tikzstyle{dashed line}=[-, dashed]
\tikzstyle{arrow}=[->, thick]
\tikzstyle{pipe}=[-, fill={rgb,255: red,137; green,216; blue,131}, draw={rgb,255: red,0; green,125; blue,0}, thick]
\tikzstyle{block}=[-, thick, fill={rgb,255: red,238; green,238; blue,238}]
\tikzstyle{inner block}=[-, fill={rgb,255: red,199; green,213; blue,255}, thick, draw={rgb,255: red,60; green,106; blue,255}]
\tikzstyle{dotted line}=[-, dotted]
\tikzstyle{arrow without head}=[-, thick]

90
img/with_caching.tikz Normal file
View File

@@ -0,0 +1,90 @@
\begin{tikzpicture}
\begin{pgfonlayer}{nodelayer}
\node [style=thread player] (0) at (-16, 0) {DbiThreadPlayer};
\node [style=initiator socket] (1) at (-12.75, 0) {};
\node [style=thread player] (2) at (-16, -2) {DbiThreadPlayer};
\node [style=initiator socket] (3) at (-12.75, -2) {};
\node [style=thread player] (4) at (-16, -5) {DbiThreadPlayer};
\node [style=initiator socket] (5) at (-12.75, -5) {};
\node [style=interconnect thin] (10) at (18, -2.5) {MultiCoupler\\(Interconnect)};
\node [style=none] (12) at (-16, -3.25) {\vdots};
\node [style=target socket] (13) at (15.25, -2.5) {};
\node [style=none] (14) at (15, -2.5) {};
\node [style=initiator socket] (15) at (20.75, -2.5) {};
\node [style=initiator socket] (16) at (22, -2.5) {};
\node [style=initiator socket] (17) at (22.5, -2.5) {};
\node [style=none] (18) at (-19.5, 2.5) {};
\node [style=none] (19) at (22.25, 2.5) {};
\node [style=none] (20) at (-19.5, -7) {};
\node [style=none] (21) at (22.25, -7) {};
\node [style=none] (22) at (1.5, 1.75) {DbiPlayer};
\node [style=none] (24) at (21, -2.5) {};
\node [style=none] (25) at (21, -2.5) {};
\node [style=none] (28) at (21.75, -2.5) {};
\node [style=none] (30) at (25, 2.5) {};
\node [style=none] (31) at (25, -7) {};
\node [style=target socket] (32) at (24.75, -2.5) {};
\node [style=none] (35) at (24.5, -2.5) {};
\node [style=none] (38) at (22.75, -2.5) {};
\node [style=none] (40) at (30.25, 2.5) {};
\node [style=none] (41) at (30.25, -7) {};
\node [style=none] (43) at (27.75, -2.5) {DRAMSys};
\node [style=cache] (44) at (-9.5, 0) {L1 Cache};
\node [style=initiator socket] (45) at (-7.5, 0) {};
\node [style=target socket] (46) at (-11.5, 0) {};
\node [style=cache] (47) at (-9.5, -2) {L1 Cache};
\node [style=initiator socket] (48) at (-7.5, -2) {};
\node [style=target socket] (49) at (-11.5, -2) {};
\node [style=cache] (50) at (-9.5, -5) {L1 Cache};
\node [style=initiator socket] (51) at (-7.5, -5) {};
\node [style=target socket] (52) at (-11.5, -5) {};
\node [style=none] (53) at (-9.5, -3.25) {\vdots};
\node [style=cache] (54) at (-4, 0) {L2 Cache};
\node [style=initiator socket] (55) at (-2, 0) {};
\node [style=target socket] (56) at (-6, 0) {};
\node [style=cache] (57) at (-4, -2) {L2 Cache};
\node [style=initiator socket] (58) at (-2, -2) {};
\node [style=target socket] (59) at (-6, -2) {};
\node [style=cache] (60) at (-4, -5) {L2 Cache};
\node [style=initiator socket] (61) at (-2, -5) {};
\node [style=target socket] (62) at (-6, -5) {};
\node [style=none] (63) at (-4, -3.25) {\vdots};
\node [style=interconnect thick] (64) at (4, -2.5) {MultiSimpleCoupler\\(Interconnect)};
\node [style=target socket] (65) at (0.25, -2.5) {};
\node [style=none] (66) at (0, -2.5) {};
\node [style=initiator socket] (67) at (7.75, -2.5) {};
\node [style=none] (69) at (8, -2.5) {};
\node [style=none] (70) at (-1.75, 0) {};
\node [style=none] (71) at (-1.75, -2) {};
\node [style=none] (72) at (-1.75, -5) {};
\node [style=l3cache] (74) at (11.5, -2.5) {L3 Cache};
\node [style=initiator socket] (75) at (13.5, -2.5) {};
\node [style=target socket] (76) at (9.5, -2.5) {};
\node [style=none] (77) at (13.75, -2.5) {};
\end{pgfonlayer}
\begin{pgfonlayer}{edgelayer}
\draw [style=block] (18.center)
to (19.center)
to (21.center)
to (20.center)
to cycle;
\draw (25.center) to (28.center);
\draw [style=block] (41.center)
to (31.center)
to (30.center)
to (40.center)
to cycle;
\draw (38.center) to (35.center);
\draw (1) to (46);
\draw (3) to (49);
\draw (5) to (52);
\draw (45) to (56);
\draw (48) to (59);
\draw (51) to (62);
\draw (72.center) to (66.center);
\draw (71.center) to (66.center);
\draw (70.center) to (66.center);
\draw (77.center) to (14.center);
\draw (69.center) to (76);
\end{pgfonlayer}
\end{tikzpicture}

61
img/without_caching.tikz Normal file
View File

@@ -0,0 +1,61 @@
\begin{tikzpicture}
\begin{pgfonlayer}{nodelayer}
\node [style={thread_player}] (0) at (0, 0) {DbiThreadPlayer};
\node [style={initiator_socket}] (1) at (3.25, 0) {};
\node [style={thread_player}] (2) at (0, -2) {DbiThreadPlayer};
\node [style={initiator_socket}] (3) at (3.25, -2) {};
\node [style={thread_player}] (4) at (0, -5) {DbiThreadPlayer};
\node [style={initiator_socket}] (5) at (3.25, -5) {};
\node [style=interconnect] (10) at (11.25, -2.5) {MultiCoupler\\(Interconnect)};
\node [style=none] (12) at (0, -3.25) {\vdots};
\node [style={target_socket}] (13) at (8.5, -2.5) {};
\node [style=none] (14) at (8.25, -2.5) {};
\node [style={initiator_socket}] (15) at (14, -2.5) {};
\node [style={initiator_socket}] (16) at (16.75, -2.5) {};
\node [style={initiator_socket}] (17) at (17.25, -2.5) {};
\node [style=none] (18) at (-3.5, 2) {};
\node [style=none] (19) at (17, 2) {};
\node [style=none] (20) at (-3.5, -7) {};
\node [style=none] (21) at (17, -7) {};
\node [style=none] (22) at (6.5, 1.25) {DbiPlayer};
\node [style=none] (23) at (14.25, -2.25) {};
\node [style=none] (24) at (14.25, -2.5) {};
\node [style=none] (25) at (14.25, -2.5) {};
\node [style=none] (26) at (14.25, -2.75) {};
\node [style=none] (27) at (16.5, -2.25) {};
\node [style=none] (28) at (16.5, -2.5) {};
\node [style=none] (29) at (16.5, -2.75) {};
\node [style=none] (30) at (19.75, 2) {};
\node [style=none] (31) at (19.75, -7) {};
\node [style={initiator_socket}] (32) at (19.5, -2.5) {};
\node [style=none] (34) at (19.25, -2.25) {};
\node [style=none] (35) at (19.25, -2.5) {};
\node [style=none] (36) at (19.25, -2.75) {};
\node [style=none] (37) at (17.5, -2.25) {};
\node [style=none] (38) at (17.5, -2.5) {};
\node [style=none] (39) at (17.5, -2.75) {};
\node [style=none] (40) at (25, 2) {};
\node [style=none] (41) at (25, -7) {};
\node [style=none] (43) at (22.5, -2.5) {DRAMSys};
\end{pgfonlayer}
\begin{pgfonlayer}{edgelayer}
\draw (1) to (14.center);
\draw (3) to (14.center);
\draw (5) to (14.center);
\draw (18.center)
to (19.center)
to (21.center)
to (20.center)
to cycle;
\draw (23.center) to (27.center);
\draw (25.center) to (28.center);
\draw (26.center) to (29.center);
\draw (30.center) to (31.center);
\draw (37.center) to (34.center);
\draw (38.center) to (35.center);
\draw (39.center) to (36.center);
\draw (30.center) to (40.center);
\draw (40.center) to (41.center);
\draw (41.center) to (31.center);
\end{pgfonlayer}
\end{tikzpicture}

63
inc/6.implementation.tex Normal file
View File

@@ -0,0 +1,63 @@
\section{Implementation}
In this section, the new components that were developed that enable the tracing of an arbitrary application in real-time, as well as the replay of those traces in DRAMSys, will be introduced.
At first, the DynamoRIO analyzer tool that produces the memory access traces and its place in the DrCacheSim-Framework will be explained.
Furthermore, the trace player for DRAMSys will acquire special focus as well as the mandatory cache model that is used to model the cache-filtering in a real system.
The last part will concentrate on the special architecture of new trace player and challenges the internal interconnection solves.
\subsection{Analysis tool}
As described in section TODO the dynamic binary instrumentation tool DynamoRIO will be used to trace the memory accesses while the target application is running.
Instead of writing a DynamoRIO client from the ground up, the DrCacheSim framework is used.
DrCacheSim is a DynamoRIO client that gathers memory and instruction access traces and forwards them to an analyzer tool.
It is a purely observational client, as it does not modify the behavior of the application.
Optionally, DrCacheSim converts the addresses of the memory accesses from virtual addresses into physical addresses, which is an important step for simulating a real memory system.
The physical address conversion only works on Linux and requires root privileges (or alternatively the CAP\_SYS\_ADMIN capability) for modern kernel versions.
The analyzer tool can either be running alongside with DrCacheSim (online) or operate on an internal trace format (offline).
As of writing this thesis, the offline tracing mode does not yet support the physical address conversation, so the online mode has to be used.
In case of the online tracing, DrCacheSim consists of two seperate processes:
\begin{itemize}
\item
A client-side which injects observational instructions into the application's code cache.
For every instruction or memory access, a data packet of the type \texttt{memref\_t} is generated.
\item
An analyzer-side which connects to the client and processes the \texttt{memref\_t} data packets.
The analyzer-side can contain many analysis tools that operate on those stream of records.
\end{itemize}
The \abbr{inter-process communication}{IPC} between the two parts is achieved through a \textit{named\ pipe}.
\begin{figure}
\input{img/thesis.tikzstyles}
\begin{center}
\tikzfig{img/drcachesim}
\caption{Structure of the DrCacheSim online tracing.}
\end{center}
\end{figure}
A \texttt{memref\_t} can either represent an instruction, a data reference or a metadata event such as a timestamp or a CPU identifier.
Besides of the type, the \abbr{process identifier}{PID} and \abbr{thread identifier}{TID} is included in every record to be able to associate them.
For an instruction marker, the size of the instruction as well as the virtual address of the instruction in the memory map is provided.
DrCacheSim stores the current mapping of all binary executables and shared libraries in a seperate file, so that it is possible to decode named instructions even after the application has exited.
For data references, the address and size of the desired access is provided as well the \abbr{program counter}{PC} from which it was initiated.
Analysis tools implement the \texttt{analysis\_tool\_t} interface as this enables the analyzer to forward a received record to multiple tools in a polymorphic manner.
In particular, the \texttt{process\_memref\_t()} method of a tool is called for incoming every record.
The newly developed DRAMTracer tool creates for every thread of the application a seperate trace file.
As it is not known how many threads an application will spawn, the tool will listen for records with new TIDs that it did not register yet.
For every data reference, a new entry in the corresponding trace file is made which contains the size and the address of the access, whether it was a read or write, and also a count of (computational) instructions that have been executed since the last reference.
This instruction count is used to approximate the delay between the memory accesses when the trace is replayed by DRAMSys as described in section TODO.
As of writing this thesis, there is no application binary interface for analysis tools defined in the DrCacheSim-Framework.
Therefore it is not possible to load the DRAMTracer tool as a shared library but rather it is required to modify the DynamoRIO source code to integrate the tool.
\subsection{DbiPlayer architecture}
This section covers the general architecture of the DbiPlayer, the new trace player for DRAMSys that replays the captured trace files.

View File

@@ -1,227 +0,0 @@
%%
%% This is file `minted.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% minted.dtx (with options: `package')
%% Copyright 2010 Konrad Rudolph
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%% http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% Additionally, the project may be distributed under the terms of the new BSD
%% license.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% The Current Maintainer of this work is Konrad Rudolph.
%%
%% This work consists of the files mints.dtx and mints.ins
%% and the derived file mints.sty.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{minted}[2010/01/27 v1.6 Yet another Pygments shim for LaTeX]
\RequirePackage{keyval}
\RequirePackage{fancyvrb}
\RequirePackage{color}
\RequirePackage{float}
\RequirePackage{ifthen}
\RequirePackage{calc}
\RequirePackage{ifplatform}
\ifwindows
\providecommand\DeleteFile[1]{\immediate\write18{del #1}}
\else
\providecommand\DeleteFile[1]{\immediate\write18{rm #1}}
\fi
\newboolean{AppExists}
\providecommand\TestAppExists[1]{
\ifwindows
\DeleteFile{\jobname.aex}
\immediate\write18{for \string^\@percentchar i in (#1.exe #1.bat #1.cmd)
do set >\jobname.aex <nul: /p x=\string^\@percentchar \string~$PATH:i>>\jobname.aex} %$
\newread\@appexistsfile
\immediate\openin\@appexistsfile\jobname.aex
\expandafter\def\expandafter\@tmp@cr\expandafter{\the\endlinechar}
\endlinechar=-1\relax
\readline\@appexistsfile to \@apppathifexists
\endlinechar=\@tmp@cr
\ifthenelse{\equal{\@apppathifexists}{}}
{\AppExistsfalse}
{\AppExiststrue}
\immediate\closein\@appexistsfile
\DeleteFile{\jobname.aex}
\immediate\typeout{file deleted}
\else
\immediate\write18{which -s #1 && touch \jobname.aex}
\IfFileExists{\jobname.aex}
{\AppExiststrue
\DeleteFile{\jobname.aex}}
{\AppExiststrue}
\fi}
\newcommand\minted@resetoptions{}
\newcommand\minted@defopt[1]{
\expandafter\def\expandafter\minted@resetoptions\expandafter{%
\minted@resetoptions
\@namedef{minted@opt@#1}{}}}
\newcommand\minted@opt[1]{
\expandafter\detokenize%
\expandafter\expandafter\expandafter{\csname minted@opt@#1\endcsname}}
\newcommand\minted@define@opt[3][]{
\minted@defopt{#2}
\ifthenelse{\equal{#1}{}}{
\define@key{minted@opt}{#2}{\@namedef{minted@opt@#2}{#3}}}
{\define@key{minted@opt}{#2}[#1]{\@namedef{minted@opt@#2}{#3}}}}
\newcommand\minted@define@switch[2]{
\minted@defopt{#1}
\define@booleankey{minted@opt}{#1}{
\@namedef{minted@opt@#1}{#2}}
{\@namedef{minted@opt@#1}{}}}
\minted@defopt{extra}
\newcommand\minted@define@extra[1]{
\define@key{minted@opt}{#1}{
\expandafter\def\expandafter\minted@opt@extra\expandafter{%
\minted@opt@extra,#1=##1}}}
\newcommand\minted@define@extra@switch[1]{
\define@booleankey{minted@opt}{#1}
{\expandafter\def\expandafter\minted@opt@extra\expandafter{%
\minted@opt@extra,#1}}
{\expandafter\def\expandafter\minted@opt@extra\expandafter{%
\minted@opt@extra,#1=false}}}
\minted@define@switch{texcl}{-P texcomments}
\minted@define@switch{mathescape}{-P mathescape}
\minted@define@switch{linenos}{-P linenos}
\minted@define@opt{gobble}{-F gobble:n=#1}
\minted@define@opt{bgcolor}{#1}
\minted@define@extra{frame}
\minted@define@extra{framesep}
\minted@define@extra{framerule}
\minted@define@extra{rulecolor}
\minted@define@extra{numbersep}
\minted@define@extra{firstnumber}
\minted@define@extra{stepnumber}
\minted@define@extra{firstline}
\minted@define@extra{lastline}
\minted@define@extra{baselinestretch}
\minted@define@extra{xleftmargin}
\minted@define@extra{xrightmargin}
\minted@define@extra{fillcolor}
\minted@define@extra{tabsize}
\minted@define@extra{fontfamily}
\minted@define@extra{fontsize}
\minted@define@extra{fontshape}
\minted@define@extra{fontseries}
\minted@define@extra{formatcom}
\minted@define@extra@switch{numberblanklines}
\minted@define@extra@switch{showspaces}
\minted@define@extra@switch{resetmargins}
\minted@define@extra@switch{samepage}
\minted@define@extra@switch{showtabs}
\minted@define@extra@switch{obeytabs}
\newsavebox{\minted@bgbox}
\newenvironment{minted@colorbg}[1]{
\def\minted@bgcol{#1}
\noindent
\begin{lrbox}{\minted@bgbox}
\begin{minipage}{\linewidth-2\fboxsep}}
{\end{minipage}
\end{lrbox}%
\colorbox{\minted@bgcol}{\usebox{\minted@bgbox}}}
\newwrite\minted@code
\newcommand\minted@savecode[1]{
\immediate\openout\minted@code\jobname.pyg
\immediate\write\minted@code{#1}
\immediate\closeout\minted@code}
\newcommand\minted@pygmentize[2][\jobname.pyg]{
\def\minted@cmd{pygmentize -l #2 -f latex -F tokenmerge
\minted@opt{gobble} \minted@opt{texcl} \minted@opt{mathescape}
\minted@opt{linenos} -P "verboptions=\minted@opt{extra}"
-o \jobname.out.pyg #1}
\immediate\write18{\minted@cmd}
\ifthenelse{\equal{\minted@opt@bgcolor}{}}
{}
{\begin{minted@colorbg}{\minted@opt@bgcolor}}
\input{\jobname.out.pyg}
\ifthenelse{\equal{\minted@opt@bgcolor}{}}
{}
{\end{minted@colorbg}}
\DeleteFile{\jobname.out.pyg}}
\newcommand\minted@usedefaultstyle{\usemintedstyle{default}}
\newcommand\usemintedstyle[1]{
\renewcommand\minted@usedefaultstyle{}
\immediate\write18{pygmentize -S #1 -f latex > \jobname.pyg}
\input{\jobname.pyg}}
\newcommand\mint[3][]{
\DefineShortVerb{#3}
\minted@resetoptions
\setkeys{minted@opt}{#1}
\SaveVerb[aftersave={
\UndefineShortVerb{#3}
\minted@savecode{\FV@SV@minted@verb}
\minted@pygmentize{#2}
\DeleteFile{\jobname.pyg}}]{minted@verb}#3}
\newcommand\minted@proglang[1]{}
\newenvironment{minted}[2][]
{\VerbatimEnvironment
\renewcommand{\minted@proglang}[1]{#2}
\minted@resetoptions
\setkeys{minted@opt}{#1}
\begin{VerbatimOut}{\jobname.pyg}}%
{\end{VerbatimOut}
\minted@pygmentize{\minted@proglang{}}
\DeleteFile{\jobname.pyg}}
\newcommand\inputminted[3][]{
\minted@resetoptions
\setkeys{minted@opt}{#1}
\minted@pygmentize[#3]{#2}}
\newcommand\newminted[3][]{
\ifthenelse{\equal{#1}{}}
{\def\minted@envname{#2code}}
{\def\minted@envname{#1}}
\newenvironment{\minted@envname}
{\VerbatimEnvironment\begin{minted}[#3]{#2}}
{\end{minted}}
\newenvironment{\minted@envname *}[1]
{\VerbatimEnvironment\begin{minted}[#3,##1]{#2}}
{\end{minted}}}
\newcommand\newmint[3][]{
\ifthenelse{\equal{#1}{}}
{\def\minted@shortname{#2}}
{\def\minted@shortname{#1}}
\expandafter\newcommand\csname\minted@shortname\endcsname[2][]{
\mint[#3,##1]{#2}##2}}
\newcommand\newmintedfile[3][]{
\ifthenelse{\equal{#1}{}}
{\def\minted@shortname{#2file}}
{\def\minted@shortname{#1}}
\expandafter\newcommand\csname\minted@shortname\endcsname[2][]{
\inputminted[#3,##1]{#2}{##2}}}
\newfloat{listing}{h}{lol}
\newcommand\listingscaption{Listing}
\floatname{listing}{\listingscaption}
\newcommand\listoflistingscaption{List of listings}
\providecommand\listoflistings{\listof{listing}{\listoflistingscaption}}
\AtBeginDocument{
\minted@usedefaultstyle}
\AtEndOfPackage{
\ifeof18
\PackageError{minted}
{You must invoke LaTeX with the
-shell-escape flag}
{Pass the -shell-escape flag to LaTeX. Refer to the minted.sty
documentation for more information.}\fi}
\TestAppExists{pygmentize}
\ifAppExists\else
\PackageError{minted}
{You must have `pygmentize' installed
to use this package}
{Refer to the installation instructions in the minted
documentation for more information.}
\fi
\endinput
%%
%% End of file `minted.sty'.