forked from FPBench/fpbench.org
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfpimp.html
More file actions
141 lines (114 loc) · 5.76 KB
/
fpimp.html
File metadata and controls
141 lines (114 loc) · 5.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>FPBench</title>
<link rel="stylesheet" type="text/css" href="fpbench.css">
</head>
<body>
<header>
<a href='.' style='color: black; text-decoration: none;'>
<img src='img/logo.png' height='150' alt='FPBench Logo' />
<h1>Writing FPCore using FPImp</h1>
<p>An imperative intermediate language</p>
</a>
</header>
<p>
The <a href=".">FPBench</a>
project's <a href="spec/fpcore-1.0.html">FPCore</a> format is a
common format for the floating-point research community. However,
it can be challenging to translate source code originally written
in an imperative language to FPCore. To help, FPBench provides
FPImp, an imperative language that can be used as an intermediate
language from which to generate FPCore.
</p>
<p>This page describes the semantics of FPImp and describes the
tools FPBench provides to manipulate it.</p>
<section>
<h2>FPImp syntax and semantics</h2>
<p>FPImp is a simple imperative programming language that compiles
to FPCore. Like FPCore, it uses a simple S-expression syntax.</p>
<figure>
<dl class="grammar">
<dt id="g:fpimp">FPImp</dt>
<dd>( FPImp (<a href="spec/fpcore-1.0.html#g:symbol" title="Free variables in benchmark">symbol</a>)*
<a href="spec/fpcore-1.0.html#g:property" title="Metadata properties of the benchmark">property</a>*
<a href="#g:cmd" title="Benchmark commands">cmd</a>*
( output <a href="spec/fpcore-1.0.html#g:expr" title="Output expressions">expr</a>* ))
</dd>
<dt id="g:cmd">cmd</dt>
<dd>[ = <a href="#g:symbol">symbol</a> <a href="spec/fpcore-1.0.html#g:expr">expr</a> ]</dd>
<dd>( while <a href="spec/fpcore-1.0.html#g:expr" title="Loop condition">expr</a> <a href="#g:cmd" title="Loop body">cmd</a>* )</dd>
<dd>( if <a href="#g:if-branch">if-branch</a>* )</dd>
<dt id="g:if-branch">if-branch</dt>
<dd>[ <a href="spec/fpcore-1.0.html#g:expr">expr</a> <a href="#g:cmd">cmd</a>* ]</dd>
<dd>[ else <a href="#g:cmd">cmd</a>* ]</dd>
</dl>
<caption>High-level grammar of FPImp, an imperative intermediate language for writing <a href="spec/fpcore-1.0.html">FPCore</a>. In an <code>if</code> statement, the <code>else</code> <a href="#g:if-branch">if-branch</a> must come last. </caption>
</figure>
<aside>FPImp allows using arbitrary FPCore as expressions, but we don't recommend mixing FPImp and FPCore <code>while</code> and <code>if</code> blocks, since that code can get pretty confusing.</aside>
<p>Unlike FPCore, which is expression-oriented, FPImp has both
statements and expressions. Expressions may be any FPCore
expression, while the statements come in three types:
assignments, <code>while</code> loops, and many-way <code>if</code>
statements. The semantics of assignments, <code>while</code>,
and <code>if</code> statements is standard.</p>
<p>FPImp also allows multiple outputs. This is helpful for
translating code with Fortran <code>out</code> parameters or C
pointer arguments. Note
that <code>output</code> <a href="#g:cmd">cmd</a>s are only valid at
the end of an FPImp program—FPImp does not allow multiple exits from
the a program.</p>
</section>
<section>
<h2>Compiling FPImp to FPCore</h2>
<p>The <code>imp2core</code> tool, which ships in
the <kbd>tools/</kbd> directory of the
FPBench <a href="https://github.com/FPBench/FPBench">codebase</a>,
can compile FPImp programs to FPCore. Run:</p>
<pre class="shell">racket tools/imp2core.rkt <var>[options]</var> < <var>file.fpimp</var> > <var>file.fpcore</var></pre>
<p>The <code>imp2core</code> compiler
preserves <a href="#g:property">property</a>s, and compiles each
FPImp program to multiple FPCore computations, one for each output
of the FPImp program.</p>
<p><code>imp2core</code> accepts two options that modify its
behavior:</p>
<dl class="code-terms">
<dt>--substitute</dt>
<dd>Do not produce FPCore <code>let</code> bindings, instead
expanding the <code>let</code> bindings by substituting the
bound variable's value in the final expression. Can produce much
larger programs.</dd>
<dt>--canonicalize</dt>
<dd>Expand additions, subtractions, multiplications, and
divisions with more than two arguments into binary operators.
This option allows using shorthand arithmetic operators, but
makes the actual order of operations, important for
floating-point computation, less clear.</dd>
<dt>--one-to-one</dt>
<dd>For some uses, it is important that one FPImp program
compile to a single FPCore program, even if the FPImp program
contains multiple outputs. The <code>--one-to-one</code> option
can be set to <code>first</code> to use only the first output of
the FPImp expression, or
to <code>add</code>, <code>min</code>, <code>max</code>,
or <code>mult</code> to use that operator to combine the outputs
of the FPImp expression.</dd>
</dl>
</section>
<section>
<h2>FPImp reference interpreter</h2>
<p>
An FPImp reference interpreter is also located in the <kbd>tools/</kbd>
directory of the FPBench <a href="https://github.com/FPBench/FPBench">codebase</a>,
and can be run with:
</p>
<pre class="shell">racket tools/fpimp.rkt <var>arguments ...</var> < <var>file.fpimp</var></pre>
<p>The <var>arguments</var> in this case are real numbers using the
standard floating-point <a href="spec/fpcore-1.0.htmp#g:number">number</a>
syntax. For example, running:</p>
<pre class="shell">racket tools/fpimp.rkt 1.0 2.0
(FPImp (x y) [= z (+ x y)] (output z))</pre>
<p>produces output <code>3.0</code>.</p>
</body>
</html>