Skip to content

Commit e1e8720

Browse files
authored
Merge pull request #1357 from herbie-fp/codex/generalize-from-libm-to-from-ffi
Generalize libm generator to accept an FFI library
2 parents d9e44c1 + b77b5b2 commit e1e8720

File tree

3 files changed

+35
-19
lines changed

3 files changed

+35
-19
lines changed

src/syntax/generators.rkt

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"types.rkt")
99

1010
(provide from-rival
11+
from-ffi
1112
from-libm
1213
from-bigfloat
1314
define-generator
@@ -32,32 +33,36 @@
3233
(first exs)
3334
fail)))
3435

35-
; ----------------------- LIBM GENERATOR ----------------------------
36+
; ----------------------- FFI GENERATOR -----------------------------
3637

3738
;; Looks up a function `name` with type signature `itype -> ... -> otype`
38-
;; in the system libm and returns the FFI function or `#f` if
39-
;; the procedure cannot be found.
39+
;; in the given FFI library and returns the function or `#f` if it
40+
;; cannot be found.
4041
;; ```
41-
;; (make-libm (<name> <itype> ... <otype))
42+
;; (make-ffi <lib> (<name> <itype> ... <otype>))
4243
;; ```
43-
(define (make-libm name itypes otype)
44+
(define (make-ffi lib name itypes otype)
4445
; Repr matching
4546
(define (repr->ffi repr)
4647
(match (representation-name repr)
4748
['binary64 _double]
4849
['binary32 _float]
4950
['integer _int]
5051
[else (raise-syntax-error 'repr->type "unknown type" repr)]))
51-
(get-ffi-obj name #f (_cprocedure (map repr->ffi itypes) (repr->ffi otype)) (const #f)))
52+
(get-ffi-obj name lib (_cprocedure (map repr->ffi itypes) (repr->ffi otype)) (const #f)))
5253

53-
(define-generator ((from-libm name) spec ctx)
54+
(define-generator ((from-ffi lib name) spec ctx)
5455
(let ([itypes (context-var-reprs ctx)]
5556
[otype (context-repr ctx)])
56-
(define fl (make-libm name itypes otype))
57+
(define fl (make-ffi lib name itypes otype))
5758
(unless fl
58-
(error 'libm-generator "Could not find libm implementation of `~a ~a ~a`" otype name itypes))
59+
(error 'ffi-generator "Could not find FFI implementation of `~a ~a ~a`" otype name itypes))
5960
fl))
6061

62+
(define libm-lib (ffi-lib #f))
63+
(define (from-libm name)
64+
(from-ffi libm-lib name))
65+
6166
; ----------------------- BIGFLOAT GENERATOR ------------------------
6267

6368
(define (repr->bf x type)

www/doc/2.3/platforms.html

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,22 @@ <h3>Math Library Functions</h3>
214214
<pre>(define-operation (fabs.f32 [x &lt;binary32&gt;]) &lt;binary32&gt;
215215
#:spec (fabs x) #:impl (from-libm 'fabsf) #:cost 0.125)</pre>
216216

217-
<p>The <code>from-libm</code> uses dynamic linking to
218-
load <code>libm</code>, extracts the symbol passed
219-
to <code>from-libm</code>, and then uses the operation's signature
220-
to call into the dynamically-linked library from Racket. Must make
221-
sure to pass the correct symbol name; for single-precision
222-
functions, make sure to add the "<code>f</code>" suffix.</p>
217+
<p>The <code>from-libm</code> helper uses dynamic linking to load
218+
<code>libm</code>, extracts the symbol passed to
219+
<code>from-libm</code>, and then uses the operation's signature to
220+
call into the dynamically-linked library from Racket. Be sure to
221+
pass the correct symbol name; for single-precision functions, add the
222+
"<code>f</code>" suffix.</p>
223+
224+
<p>For other libraries, open them with
225+
<code>ffi-lib</code> and use <code>from-ffi</code>, which
226+
generalizes <code>from-libm</code>. For example, to load functions
227+
from the GNU Scientific Library:</p>
228+
229+
<pre>(require ffi/unsafe)
230+
(define libgsl (ffi-lib "gsl"))
231+
(define-operation (cos.gsl [x &lt;binary64&gt;]) &lt;binary64&gt;
232+
#:spec (cos x) #:impl (from-ffi libgsl 'gsl_sf_cos) #:cost 0.125)</pre>
223233

224234
<h3>Numeric Variations</h3>
225235

www/doc/2.3/plugins.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ <h2>Defining representations</h2>
114114
<h2>Defining Generators</h2>
115115

116116
<p><dfn>Generators</dfn> are helper functions for generating
117-
implementations in <code>define-operation</code>. For
118-
example, <a href="platforms.html"><code>from-libm</code>
119-
and <code>from-rival</code></a> are generators.</p>
117+
implementations in <code>define-operation</code>. For example,
118+
<a href="platforms.html"><code>from-ffi</code></a> is a
119+
generator.</p>
120120

121121
<p>To define a generator, use <code>define-generator</code>:</p>
122122

@@ -128,7 +128,8 @@ <h2>Defining Generators</h2>
128128
<p>Here, <code>from-<var>foo</var></code> is the name of your
129129
generator, and <var>args</var> are any additional arguments the
130130
generator takes. For example, <code>from-libm</code> takes one
131-
argument, the symbol name.</p>
131+
argument, the symbol name, while <code>from-ffi</code> takes an open
132+
library and a symbol name.</p>
132133

133134
<p>Then, inside the <var>body</var>, you can use those arguments as
134135
well as <code>spec</code> and <code>ctx</code>, to construct an

0 commit comments

Comments
 (0)