ffi.scm 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. ; -*- mode: scheme; coding: utf-8 -*-
  2. ; (c) Daniel Llorens - 2021
  3. ; This library is free software; you can redistribute it and/or modify it under
  4. ; the terms of the GNU General Public License as published by the Free
  5. ; Software Foundation; either version 3 of the License, or (at your option) any
  6. ; later version.
  7. ; Fortran FFI sandbox
  8. ; see ffi.cc, https://j3-fortran.org/doc/year/18/18-007r1.pdf
  9. (import (newra) (newra base) (newra ffi)
  10. (srfi srfi-8) (srfi srfi-26) (srfi srfi-71) (srfi srfi-1) (srfi srfi-111)
  11. (ice-9 match) (ice-9 format) (rnrs bytevectors)
  12. (system foreign) (system foreign-library))
  13. (define libexample (load-foreign-library "./libexample"))
  14. (define lookup-xy (fortran-library-function libexample "lookup_xy" double '(double double (double : :))))
  15. (define ranker (fortran-library-function libexample "ranker" int32 '((double ..))))
  16. (define valuer (fortran-library-function libexample "valuer" double '((double ..))))
  17. (define lbounder (fortran-library-function libexample "lbounder" int32 '((double :))))
  18. (define lookup-xy-complex (fortran-library-function libexample "lookup_xy_complex" complex-double '(double double (complex-double : :))))
  19. (define conjg (fortran-library-function libexample "conjugate" complex-double '(complex-double)))
  20. (define x 1.)
  21. (define y 2.)
  22. (define table0 (ra-copy 'f64 (ra-i 3 4)))
  23. (define table1
  24. (let* ((bigtable (make-typed-ra 'f64 0. 10 10))
  25. (table (ra-from bigtable (ra-iota 3 2) (ra-iota 4 3))))
  26. (ra-copy! table (ra-i 3 4))
  27. table))
  28. (define table2 (ra-reshape (ra-reshape (ra-copy 'f64 (ra-i 3 4)) 0 '(2 4)) 1 '(2 5)))
  29. (lookup-xy 1 2 table0) ; 6.
  30. (lookup-xy 1 2 table1) ; 6.
  31. (lookup-xy 1 2 table2) ; 6. :-\
  32. (lookup-xy-complex 1 2 (ra-copy 'c64 table0)) ; 6.0 + 0.0i
  33. (lookup-xy-complex 1 2 (ra-map 'c64 (cut make-rectangular 0 <>) table0)) ; 0.0+6.0i
  34. (lookup-xy-complex 1 2 (ra-map 'c64 (lambda (x) (make-rectangular x (* x .5))) table0)) ; 6.0+3.0i
  35. (ranker (make-typed-ra 'f64 0)) ; 0
  36. (ranker (make-typed-ra 'f64 0 2 2)) ; 2
  37. (ranker (make-typed-ra 'f64 0 1)) ; 1
  38. (valuer (make-typed-ra 'f64 7)) ; 7
  39. (valuer (make-typed-ra 'f64 7 1)) ; 99
  40. (lbounder (make-typed-ra 'f64 1. 3)) ; 1
  41. (lbounder (ra-reshape (make-typed-ra 'f64 1. 3) 0 '(3 5))) ; 1 :-\
  42. (conjg 3+9i) ; 3.0-9.0i
  43. ; inout array
  44. (define fillerf32 (fortran-library-function libexample "fillerf32" void '((float :))))
  45. (define fillerf64 (fortran-library-function libexample "fillerf64" void '((double :))))
  46. (let* ((a (ra-copy (make-ra-root #f32(1 2 3 4 5 6 7 8))))
  47. (b (ra-from a (ra-iota 4 2))))
  48. (fillerf32 b)
  49. (display a) (newline)) ; #%1f32:8(1.0 2.0 9.0 16.0 25.0 36.0 7.0 8.0)
  50. (let* ((a (ra-copy (make-ra-root #f64(1 2 3 4 5 6 7 8))))
  51. (b (ra-from a (ra-iota 4 2))))
  52. (fillerf64 b)
  53. (display a) (newline)) ; #%1f64:8(1.0 2.0 9.0 16.0 25.0 36.0 7.0 8.0)
  54. (define dgemv (fortran-library-function libexample "dgemv" int8 '((double : :) (double :) (double :))))
  55. (let ((a (ra-copy 'f64 (ra-i 4 3)))
  56. (v (make-ra-root #f64(1 2 3)))
  57. (w (ra-copy (make-ra-root #f64(9 8 7 6)))))
  58. (unless (zero? (dgemv a v w)) (throw 'error))
  59. (display w) (newline) ; #%1f64:4(8.0 26.0 44.0 62.0)
  60. w)