Browse Source

Initialise LuaJIT FFI to Fortran iso_c_binding example

Peter Colberg 6 years ago
commit
2325b3cc80
7 changed files with 124 additions and 0 deletions
  1. 3
    0
      .gitignore
  2. 19
    0
      LICENSE
  3. 16
    0
      Makefile
  4. 26
    0
      particle.lua
  5. 31
    0
      test.lua
  6. 22
    0
      verlet.f90
  7. 7
    0
      verlet.lua

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
1
+*.mod
2
+*.o
3
+*.so

+ 19
- 0
LICENSE View File

@@ -0,0 +1,19 @@
1
+Copyright © 2012 Peter Colberg.
2
+
3
+Permission is hereby granted, free of charge, to any person obtaining a copy
4
+of this software and associated documentation files (the "Software"), to deal
5
+in the Software without restriction, including without limitation the rights
6
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+copies of the Software, and to permit persons to whom the Software is
8
+furnished to do so, subject to the following conditions:
9
+
10
+The above copyright notice and this permission notice shall be included in
11
+all copies or substantial portions of the Software.
12
+
13
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
16
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+THE SOFTWARE.

+ 16
- 0
Makefile View File

@@ -0,0 +1,16 @@
1
+FC = gfortran
2
+LUAJIT = luajit
3
+
4
+test: test.lua verlet.so
5
+	$(LUAJIT) $<
6
+
7
+%.so: %.o
8
+	$(FC) -fPIC -shared -o $@ $<
9
+
10
+%.o: %.f90
11
+	$(FC) -fPIC -c -o $@ -c $<
12
+
13
+clean:
14
+	rm -f *.so *.o *.mod
15
+
16
+.PRECIOUS: %.so

+ 26
- 0
particle.lua View File

@@ -0,0 +1,26 @@
1
+local ffi = require("ffi")
2
+
3
+ffi.cdef[[
4
+struct particle {
5
+  const int n;
6
+  struct { double x, y, z; } *const pos, *const vel;
7
+};
8
+
9
+void *calloc(size_t, size_t);
10
+void free(void *);
11
+]]
12
+
13
+local double = ffi.typeof("double")
14
+
15
+return ffi.metatype("struct particle", {
16
+  __new = function(ct, n)
17
+    local pos = ffi.C.calloc(n, 3*ffi.sizeof(double))
18
+    local vel = ffi.C.calloc(n, 3*ffi.sizeof(double))
19
+    return ffi.new(ct, n, pos, vel)
20
+  end,
21
+
22
+  __gc = function(self)
23
+    ffi.C.free(self.pos)
24
+    ffi.C.free(self.vel)
25
+  end,
26
+})

+ 31
- 0
test.lua View File

@@ -0,0 +1,31 @@
1
+#!/usr/bin/env luajit
2
+
3
+local particle = require("particle")
4
+local verlet = require("verlet")
5
+
6
+local part = particle(10000)
7
+assert(part.n == 10000)
8
+
9
+for i = 0, part.n-1 do
10
+  part.pos[i].x = 6*i + 1
11
+  part.pos[i].y = 6*i + 2
12
+  part.pos[i].z = 6*i + 3
13
+  part.vel[i].x = 6*i + 4
14
+  part.vel[i].y = 6*i + 5
15
+  part.vel[i].z = 6*i + 6
16
+end
17
+
18
+local dt = 1
19
+
20
+for step = 1, 100 do
21
+  verlet.integrate(part, dt)
22
+
23
+  for i = 0, part.n-1 do
24
+    assert(part.pos[i].x == 6*i + 1 + (6*i + 4)*step)
25
+    assert(part.pos[i].y == 6*i + 2 + (6*i + 5)*step)
26
+    assert(part.pos[i].z == 6*i + 3 + (6*i + 6)*step)
27
+    assert(part.vel[i].x == 6*i + 4)
28
+    assert(part.vel[i].y == 6*i + 5)
29
+    assert(part.vel[i].z == 6*i + 6)
30
+  end
31
+end

+ 22
- 0
verlet.f90 View File

@@ -0,0 +1,22 @@
1
+module verlet
2
+  use, intrinsic :: iso_c_binding
3
+  implicit none
4
+  type, bind(c) :: particle
5
+    integer(c_int) :: n
6
+    type(c_ptr) :: pos
7
+    type(c_ptr) :: vel
8
+  end type
9
+contains
10
+  subroutine integrate(part, dt) bind(c)
11
+    implicit none
12
+    type(particle) :: part
13
+    real(c_double), value :: dt
14
+    real(c_double), pointer :: pos(:, :)
15
+    real(c_double), pointer :: vel(:, :)
16
+
17
+    call c_f_pointer(part%pos, pos, [3, part%n])
18
+    call c_f_pointer(part%vel, vel, [3, part%n])
19
+
20
+    pos(:, :) = pos(:, :) + vel(:, :)*dt
21
+  end subroutine
22
+end module

+ 7
- 0
verlet.lua View File

@@ -0,0 +1,7 @@
1
+local ffi = require("ffi")
2
+
3
+ffi.cdef[[
4
+void integrate(struct particle *, double);
5
+]]
6
+
7
+return ffi.load("./verlet.so")

Loading…
Cancel
Save