Skip to content

Commit

Permalink
Add Source §4 GPU (source-academy#576)
Browse files Browse the repository at this point in the history
* Add GPU specific code as a folder

* Call GPU code in transpile + update global symbols to include new function

* Add new dependency - gpu.js

* Update snapshots

* Tweak and upgrade gpu folder

* Add new functions to astcreator

* Modify Transpiler to work with gpu

* Fix bug in external variable evaluation

* Add runtime checks to make sure array is initialized

* run code manually under certain conditions

* minor bug fixes - array check + loc undefined error

* Update external variable lookup

* Bug fixes and optimizations to handle library

* Update snapshots in test

* Update loop condition check

* Add new variant : source 4 GPU + update tests

* Add display statements to program when the GPU is used

* Improve display statement message

* Update snapshots in test

* Add documentation for source gpu

* Remove __createKernal if variant is not GPU + update snapshots

* Update lock file

* Add postive + negative tests for gpu code

* Improve display statement message

* Improve latex documentation

* Improve latex documentation

* Update tests

* Revert change to stringify tests

* Add more tests + fix bugs

* Update latex docs

* Update documentation + bug fixes

* Add failing test: empty for loop

* Fix failing test

* Add failing test: __createKernel used in program

* Fix failing test: get unique name

* Remove concurrency library from docs

Co-authored-by: martin-henz <[email protected]>
  • Loading branch information
rrtheonlyone and martin-henz authored Apr 29, 2020
1 parent eb5fd65 commit 3ba3c3f
Show file tree
Hide file tree
Showing 20 changed files with 4,282 additions and 1,549 deletions.
104 changes: 104 additions & 0 deletions docs/md/README_4_GPU.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
Source §4 GPU is a small programming language, designed to allow users to accelerate their programs
by making use of their GPUs!

## What names are predeclared in Source §4 GPU?

On the right, you see all predeclared names of Source §4, in alphabetical
order. Click on a name to see how it is used. They come in these two groups:
<ul>
<li>
<a href="../MISC/index.html">MISC</a>: Miscellaneous constants and functions
</li>
<li>
<a href="../MATH/index.html">MATH</a>: Mathematical constants and functions
</li>
<li>
<a href="../LISTS/index.html">LISTS</a>: Support for lists
</li>
<li>
<a href="../PAIRMUTATORS/index.html">PAIRMUTATORS</a>: Mutating pairs
</li>
<li>
<a href="../ARRAYS/index.html">ARRAYS</a>: Support for arrays
</li>
<li>
<a href="../STREAMS/index.html">STREAMS</a>: Support for streams
</li>
<li>
<a href="../MCE/index.html">MCE</a>: Support for the meta-circular evaluator
</li>
</ul>

The <a href="https://sourceacademy.nus.edu.sg">Source Academy</a>,
a learning environment that uses SICP JS and Source, comes with the following
<a href="External libraries/">external libraries</a>:
<ul>
<li>
<a href="../RUNES/index.html">RUNES</a>: Library for runes graphics
</li>
<li>
<a href="../CURVES/index.html">CURVES</a>: Library for curve graphics
</li>
<li>
<a href="../SOUNDS/index.html">SOUNDS</a>: Library for sound processing
</li>
<li>
<a href="../BINARYTREES/index.html">BINARYTREES</a>: Library for binary trees
</li>
<li>
<a href="../PIX%26FLIX/index.html">PIX&amp;FLIX</a>: image and video processing
</li>
</ul>

## What can you do in Source §4 GPU?

You can write for loops as per normal source and if certain conditions are met, the GPU will
be invoked to run the program!

### Example:

```=javascript
const size = 100;
const L = [];
const R = [];
for (let r = 0; r < size; r = r + 1) {
L[r] = [];
R[r] = [];
for (let c = 0; c < size; c = c + 1) {
L[r][c] = r*c;
R[r][c] = r + c;
}
}
const res = [];
for (let r = 0; r < size; r = r + 1) {
res[r] = [];
}
const startTime = runtime();
for (let r = 0; r < size; r = r + 1) {
for (let c = 0; c < size; c = c + 1) {
let sum = 0;
for (let i = 0; i < size; i = i + 1) {
sum = sum + L[r][i] * R[i][c];
}
res[r][c] = sum;
}
}
const endTime = runtime();
const elapsed = endTime - startTime;
display(res);
display(elapsed, "Time taken: ");
```

## You want the definitive specs?

For our development team, we are maintaining a definitive description
of the language, called the
<a href="../source_4_gpu.pdf">Specification of Source §4 GPU</a>. Feel free to
take a peek!


2 changes: 2 additions & 0 deletions docs/md/README_top.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

## <a href="source_4/">Source §4</a>

## <a href="source_4_gpu/">Source §4 GPU</a>

## <a href="External libraries/">External Libraries</a>

The <a href="https://sourceacademy.nus.edu.sg">Source Academy</a>,
Expand Down
179 changes: 179 additions & 0 deletions docs/specs/source_4_gpu.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
\input source_header.tex

\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\docheader{2021}{Source}{\S 4 GPU}{Martin Henz, Rahul Rajesh, Zhang Yuntong}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\input source_intro.tex

\section*{Changes}

Source \S 4 GPU allows for Source programs to be accelerated on the GPU if certain conditions are met.
The exact specifications for this is outlined on page \pageref{gpu_supp}. Source \S 4 GPU defines a formal specification
to identify areas in the program that are embarrssingly parallel (e.g. for loops etc.) . These will then
be run in parallel across GPU threads. Experimentation has shown that Source \S 4 GPU is orders of magnitude faster
than Source \S 4 for heavy CPU bound tasks (matrix multiplication of large matrices)

\input source_bnf.tex

\input source_3_bnf.tex

\newpage

\input source_boolean_operators

\input source_loops

\input source_return_3

\input source_names

\input source_lists

\input source_pair_mutators

\input source_array_support

\input source_streams

\input source_numbers

\input source_strings

\input source_arrays

\input source_typing_3

\input source_interpreter

\input source_comments

\input source_js_differences

\newpage

\section*{GPU Acceleration}
\label{gpu_supp}
This section outlines the specifications for programs to be accelerated using the GPU.\
\input source_gpu_bnf.tex

\newpage

\section*{Restrictions}

Even if the BNF syntax is met, GPU acceleration can only take place if all the restrictions below are satisfied. If all criteria are met, the \textit{gpu\_statement} loops are embarrassingly parallel.

\subsection*{Special For Loops}

In the BNF, we have special loops that take on this form:
\begin{alignat*}{9}
&& \textbf{\texttt{for}}\ \textbf{\texttt{(}}
\ \textit{gpu\_for\_let} \textbf{\texttt{;}} \\
&& \ \ \textit{gpu\_condition} \textbf{\texttt{;}} \\
&& \textit{gpu\_for\_assignment} \ \textbf{\texttt{)}}
\end{alignat*}

These are the loops that will be taken into consideration for parallelization. However, on top of the BNF syntax, the below requirement must also be statisfied:

\begin{itemize}
\item{the names declared in each \textit{gpu\_for\_let} have to be different across the loops}
\item{in each loop, the \textit{gpu\_condition} and the \textit{gpu\_for\_assignment} must use the name declared
in the respective \textit{gpu\_for\_let} statement}
\end{itemize}

\subsection*{GPU Function}

A \textit{gpu\_function} has to be a \textit{math\_\texttt{*}} function

\subsection*{Core Statement}

Within \textit{core\_statement}, there are some constraints:

\begin{itemize}
\item{no assignment to any global variables (all assignments can only be done to variables defined in the \textit{gpu\_block}})
\item{no use of the variable in \textit{gpu\_result\_assignment} at an offset from the current index e.g. cannot be i - 1}
\end{itemize}

\subsection*{GPU Result Statement}

The \textit{gpu\_result\_assignment} is the statement that stores a value calculated in core statements into a result array.
It access an array at a certain coordinate e.g. ${array[{i_1}][{i_2}][{i_3}]}$. For this:

\begin{itemize}
\item{This result array has to be defined outside the \textit{gpu\_block}.}
\item{The sequence of coordinates which we access in the result array ${{i_1}, {i_2}, {i_3} ... i_{k}}$ must be a
prefix of the special for loop counters ${[c_1,c_2 ... c_n]}$.}
\item{ If you have ${n}$ special for loops, the array expression can take on ${k}$ coordinates where ${0 < k \leq n}$.
The order matters as well, it has to follow the same order as the special for loops: you cannot have ${name[c_2][c_1]}$.}
\end{itemize}

\section*{Examples}

Below are some examples of valid and invalid source gpu programs:\\

\textbf{Valid} - Using first loop counter. (meaning the loop will be run across N threads; the first loop is parallelized away):
\begin{verbatim}
for (let i = 0; i < N; i = i + 1) {
for (let k = 0; k < M; k = k + 1) {
res[i] = arr[k % 2] + 1;
}
}
\end{verbatim}

\textbf{Invalid} - Counter used is not a prefix of for loop counters:
\begin{verbatim}
for (let i = 0; i < N; i = i + 1) {
for (let k = 0; k < M; k = k + 1) {
res[k] = arr[i % 2] + 1;
}
}
\end{verbatim}

\textbf{Valid} - Using first three loop counters (meaning the loop will be run across N*M*C threads, if available):
\begin{verbatim}
for (let i = 0; i < N; i = i + 1) {
for (let j = 0; j < M; j = j + 1) {
for (let k = 0; k < C; k = k + 1) {
let x = math_pow(2, 10);
let y = x * (1000);
arr[i][j][k] = (x + y * 2);
}
}
}
\end{verbatim}

\textbf{Invalid} - Indices are in wrong order (must respect for loop counter orders):
\begin{verbatim}
for (let i = 0; i < N; i = i + 1) {
for (let j = 0; j < M; j = j + 1) {
for (let k = 0; k < C; k = k + 1) {
let x = math_pow(2, 10);
let y = x * (1000);
res[k][j][i] = (x + y * 2);
}
}
}
\end{verbatim}

\textbf{Invalid} - Using an index that is not part of a special for loop (see above):
\begin{verbatim}
for (let i = 0; i < N; i = i + 1) {
for (let j = 0; j < M; j = j + 1) {
for (let k = 1; k < C; k = k + 2) {
res[k] = arr1[i] + arr2[j];
}
}
}
\end{verbatim}

\newpage

\input source_list_library

\newpage

\input source_stream_library


\end{document}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"lodash": "^4.17.13",
"node-getopt": "^0.3.2",
"source-map": "^0.7.3",
"xmlhttprequest-ts": "^1.0.1"
"xmlhttprequest-ts": "^1.0.1",
"gpu.js": "^2.9.3"
},
"main": "dist/index",
"types": "dist/index",
Expand Down
13 changes: 13 additions & 0 deletions scripts/jsdoc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ run() {
${LIB}/array.js \
${LIB}/pairmutator.js \
${LIB}/mce.js

# Source §4 GPU

${JSDOC} -r -t ${TMPL} \
-c docs/jsdoc/conf.json \
-R ${MD}/README_4_GPU.md \
-d ${DST}/"source_4_gpu"/ \
${LIB}/misc.js \
${LIB}/math.js \
${LIB}/list.js \
${LIB}/stream.js \
${LIB}/array.js \
${LIB}/pairmutator.js

# MISC

Expand Down
Loading

0 comments on commit 3ba3c3f

Please sign in to comment.