From 65522a8cfa820dfc251908b3b8e20aa1181c64f5 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 12 Feb 2024 18:45:27 +0100 Subject: [PATCH] FIMDRAM Memory Layout --- src/acronyms.tex | 4 +++ src/chapters/pim.tex | 58 ++++++++++++++++++++++++++++++++---- src/images/hbm_old.pdf | Bin 85801 -> 0 bytes src/images/input_vector.tex | 20 +++++++++++++ 4 files changed, 77 insertions(+), 5 deletions(-) delete mode 100644 src/images/hbm_old.pdf create mode 100644 src/images/input_vector.tex diff --git a/src/acronyms.tex b/src/acronyms.tex index ef43537..04c9d25 100644 --- a/src/acronyms.tex +++ b/src/acronyms.tex @@ -243,6 +243,10 @@ short = ISA, long = instruction set architecture, } +\DeclareAcronym{c}{ + short = C, + long = The C Programming Language, +} \DeclareAcronym{tlm}{ short = TLM, long = transaction-level modeling, diff --git a/src/chapters/pim.tex b/src/chapters/pim.tex index 5ed7039..4aa5c44 100644 --- a/src/chapters/pim.tex +++ b/src/chapters/pim.tex @@ -88,7 +88,7 @@ While copying, the data layout must be changed to store the data words continuou UPMEM provides a \ac{sdk} that orchestrates the data movement from the main memory to the \ac{pim} banks and modifies the data layout. Each \ac{dpu} is a multithreaded $\qty{32}{bit}$ \ac{risc} core with a full set of general purpose registers and a 14-stage pipeline. -The \acp{dpu} execute compiled C code using a specialized compiler toolchain that provides limited support of the standard library. +The \acp{dpu} execute compiled \acs{c} code using a specialized compiler toolchain that provides limited support of the standard library. With a system clock of $\qty{400}{\mega\hertz}$, the internal bandwidth of a \ac{dpu} amounts to $\qty[per-mode = symbol]{800}{\mega\byte\per\second}$. A system can integrate 128 \acp{dpu} per \ac{dimm}, with a total of 20 UPMEM \acp{dimm}. This gives a maximum theoretical \ac{pim} bandwidth of $\qty[per-mode = symbol]{2}{\tera\byte\per\second}$ \cite{gomez-luna2022}. @@ -199,7 +199,7 @@ The data layout of these three instruction groups is shown in Table \ref{tab:isa \begin{table} \centering - \includegraphics[width=\linewidth]{images/isa} + \includegraphics[width=0.9\linewidth]{images/isa} \caption[The instruction format of the processing units]{The instruction format of the processing units \cite{lee2021}.} \label{tab:isa} \end{table} @@ -276,7 +276,7 @@ With this method, the register indices and the bank address cannot get out of sy \begin{figure} \centering \includegraphics[width=0.5\linewidth]{images/aam} - \caption[Exemplary calculation of the GRF-A and GRF-B index using the row and column address]{Exemplary calculation of the GRF-A and GRF-B index using the row and column address \cite{lee2021}.} + \caption[Exemplary calculation of the \ac{grf}-A and \ac{grf}-B index using the row and column address]{Exemplary calculation of the \ac{grf}-A and \ac{grf}-B index using the row and column address \cite{lee2021}.} \label{img:aam} \end{figure} @@ -292,7 +292,7 @@ JUMP -1, 7 \label{lst:gemv} \end{listing} -Since the column address of the memory access is incremented after each iteration, all entries of the GRF-A register file, where the input vector is stored, are used to multiply it with the matrix weights loaded on the fly from the memory banks. +Since the column address of the memory access is incremented after each iteration, all entries of the \ac{grf}-A register file, where the input vector is stored, are used to multiply it with the matrix weights loaded on the fly from the memory banks. The actual order of the memory accesses is irrelevant, only before and after the \ac{mac} kernel the host must place memory barrier instructions to synchronize the execution again. To achieve this particular operation, where the addresses can be used to calculate the register indices, the memory layout of the weight matrix has to follow a special pattern. This memory layout is explained in detail in Section \ref{sec:memory_layout}. @@ -315,11 +315,59 @@ Thus, a total of 64 thread groups running in parallel can be spawned in a \ac{hb \subsubsection{Memory Layout} \label{sec:memory_layout} +As already described in Section \ref{sec:instruction_ordering}, the use of the \ac{aam} mode requires a special memory layout so that the register indices are correctly calculated from the column and row addresses of a memory access. +To make use of all eight \ac{grf}-A registers, the input address has to increment linearly, resulting in a row-major matrix layout. +In a row-major matrix layout, the entries of a row are stored sequentially before switching to the next row, according to the \texttt{MATRIX[R][C]} \ac{c}-like array notation. + +The \ac{hbm}-\ac{pim} architecture imposes certain dimensional constraints on the weight matrix and the input vector. +As all eight processing units in a \ac{pch} operate at the same time, the number of rows must be a multiple of eight to make use of the full processing bandwidth. +Those matrix row blocks possibly span over multiple \ac{dram} rows or even other \acp{pch}. +Furthermore, the number of columns must be set so that exactly after one matrix row, the next bank in the \ac{pch} is addressed, so that all the processing units operate on eight different rows, stored in eight different banks, at the same time. +This does not mean that a matrix row must be the same size as a \ac{dram} row, only that the \ac{am} of the memory controller must switch to the next bank after a complete matrix row. +Once all banks have been accessed, the mapping of the column bits can continue. + +The input vector must adhere also a special memory layout. +Since a vector is essentially a single-column matrix, it is always laid out sequentially in memory. +However, since all processing units must access the same input vector elements at the same time, all processing units must load the respective vector elements into their \ac{grf}-A registers during the initialization phase of the microkernel. +As there is no communication between the banks, every bank needs to have its own copy of the input vector. +Consequently, from the perspective of the linear address space, multiple copies chunks of the input vector must be interleaved in such a way that the input vector is continuous from the perspective of each bank. +This interleaving is illustrated in Figure \ref{img:input_vector}. + +\begin{figure} + \centering + \input{images/input_vector} + \caption[Input vector in linear address space, where one chunk is mapped to all banks]{Input vector in linear address space, where one chunk is mapped to all banks.} + \label{img:input_vector} +\end{figure} + +To initialize the input vector in this way, the host processor can use all-bank mode. +From the processor's point of view, only the first bank is initialized, but the all-bank mode ensures that the same data is written to all banks at the same time. + +An example with a weight matrix of dimensions (128,8), an input vector of size (128), and an output vector of size (8) will be analyzed in the following to describe how the processing units execute a \ac{gemv} microkernel. +With the processing unit \textit{i}, the number of iterations \textit{j}, the input vector \textit{a} and the weight matrix \textit{w}, the partial sum $psum[i,0:15]$ is calculated as follows: + +\begin{equation} +psum[i,0:15]=\sum_{j=0}^{8}(a[j*16:j*16+15]*w[i,j*16:j*16+15]) +\end{equation} + +The partial sum vector $psum[0:7,0:15]$ must then be reduced by the host processor to obtain the final output vector $b[0:7]$. +This reduction step is mandatory because there is no means in the \ac{hbm}-\ac{pim} architecture to reduce the output sums of the 16-wide \ac{simd} \acp{fpu}. +In contrast, SK Hynix's Newton implements adder trees in the \ac{pim} units to reduce the partial sums directly in memory. +The operation of this concrete \ac{gemv} microkernel is illustrated in Figure \ref{img:memory_layout}. + \begin{figure} \centering \includegraphics[width=0.8\linewidth]{images/memory_layout} - \caption[]{} + \caption[Procedure to perform a (128)*(128,8)\ac{gemv} operation]{Procedure to perform a (128)*(128,8)\ac{gemv} operation. One cell represents 16 \ac{fp16} elements forming a $\qty{32}{\byte}$ block \cite{kang2022}.} \label{img:memory_layout} \end{figure} +In the Figure \ref{img:memory_layout} it can be seen that a processing unit is responsible for multiplying and adding one row of the matrix with the input vector in eight cycles, forming the partial sum. +This example only demonstrates the execution of the native matrix dimensions for one \ac{pch}. +To increase the number of rows in the matrix, simply additional iterations of this 8-cycle microkernel are required, while feeding in the other memory addresses for the subsequent matrix rows. +As a side effect of the incremented bank address, this also results in an increment of the \ac{grf}-B index, making it possible to increase the maximum number of matrix rows to $8*8=64$ before all eight \ac{grf}-B entries are filled with partial sums. +To increase the number of columns, new entries of the input vector must be loaded into the processing units. +Therefore, it is necessary to execute the \ac{gemv} microkernel several times with different input vector and weight matrix addresses. +In general, the more the dimensions exceed the native \ac{pim} matrix dimensions, the more often the \ac{mac} core of the \ac{gemv} microkernel must be executed. + \subsubsection{Performance and Power Efficiency Achievements} diff --git a/src/images/hbm_old.pdf b/src/images/hbm_old.pdf deleted file mode 100644 index ca1eb91ad105ed0e69b63492665eba06d40e3c0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85801 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 diff --git a/src/images/input_vector.tex b/src/images/input_vector.tex new file mode 100644 index 0000000..bd2f6dc --- /dev/null +++ b/src/images/input_vector.tex @@ -0,0 +1,20 @@ +\begin{tikzpicture} +\tiny + +\node[draw,outer sep=0,minimum width=1.5cm,fill=TealBlue!30] (inputchunk0) {a[0:127]}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=TealBlue!30,right=0 of inputchunk0] (inputchunk1) {a[0:127]}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=RoyalBlue!30,right=0 of inputchunk1] (inputchunk2) {a[128:255]}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=RoyalBlue!30,right=0 of inputchunk2] (inputchunk3) {a[128:255]}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=Blue!30,right=0 of inputchunk3] (inputchunk4) {a[256:383]}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=Blue!30,right=0 of inputchunk4] (inputchunk5) {a[256:383]}; + +\node[draw,outer sep=0,minimum width=1.5cm,fill=Green!30,below=0 of inputchunk0] {Bank 0}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=SpringGreen!30,below=0 of inputchunk1] {Bank 1}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=Green!30,below=0 of inputchunk2] {Bank 0}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=SpringGreen!30,below=0 of inputchunk3] {Bank 1}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=Green!30,below=0 of inputchunk4] {Bank 0}; +\node[draw,outer sep=0,minimum width=1.5cm,fill=SpringGreen!30,below=0 of inputchunk5] {Bank 1}; + +\node[right=of inputchunk5.south east,anchor=east] (inputchunk6) {\normalsize\dots}; + +\end{tikzpicture}