Skip to content

Instantly share code, notes, and snippets.

Created May 26, 2013 18:55
Show Gist options
  • Save anonymous/5653687 to your computer and use it in GitHub Desktop.
Save anonymous/5653687 to your computer and use it in GitHub Desktop.
Laplacian operator in Julia and C.
#include "laplace.h"
void laplace3D (double *del_field, double *field, long n1, long n2, long n3) {
long i1, i2, i3, idx1, idx2, idx3, idx4, idx5, idx6, idx7;
for (i1 = 1; i1 < n1-1; i1++) {
for (i2 = 1; i2 < n2-1; i2++) {
for (i3 = 1; i3 < n3-1; i3++) {
idx1 = i1 * n2 * n3 + i2 * n3 + i3;
idx2 = (i1 + 1) * n2 * n3 + i2 * n3 + i3;
idx3 = (i1 - 1) * n2 * n3 + i2 * n3 + i3;
idx4 = i1 * n2 * n3 + (i2 + 1) * n3 + i3;
idx5 = i1 * n2 * n3 + (i2 - 1) * n3 + i3;
idx6 = i1 * n2 * n3 + i2 * n3 + (i3 + 1);
idx7 = i1 * n2 * n3 + i2 * n3 + (i3 - 1);
del_field[idx1] =
field[idx2] + field[idx3] +
field[idx4] + field[idx5] +
field[idx6] + field[idx7] -
6.0 * field[idx1];
}
}
}
}
#ifndef __LAPLACE__
#define __LAPLACE__
#include <stdio.h>
void laplace3D (double *del_field, double *field, long n1, long n2, long n3);
#endif
function laplace (del_x::Array{Float64, 3}, x::Array{Float64, 3})
n1, n2, n3 = size (x)
for i1 = 2:n1-1, i2 = 2:n2-1, i3 = 2:n3-1
del_x[i1,i2,i3] =
x[i1+1,i2,i3] + x[i1-1,i2,i3] +
x[i1,i2+1,i3] + x[i1,i2-1,i3] +
x[i1,i2,i3+1] + x[i1,i2,i3-1] -
6.0 * x[i1,i2,i3]
end
end
function laplace_c (del_x::Array{Float64, 3}, x::Array{Float64, 3})
n1, n2, n3 = size (x)
ccall ( (:laplace3D, "liblaplace"),
Void,
(Ptr{Float64}, Ptr{Float64}, Int64, Int64, Int64),
del_x, x, n1, n2, n3 )
end
require ("laplace.jl")
function main ()
niters = 10
n = 300
field = init_field (n)
del_field = zeros (size (field))
# warmup Julia
laplace (del_field, field)
# timing Julia version
tic ()
for n = 1:niters
laplace (del_field, field)
end
write (STDOUT, "Julia: ")
toc ()
# timing C (serial) version
tic ()
for n = 1:niters
laplace_c (del_field, field)
end
write (STDOUT, "C (serial): ")
toc ()
end
function init_field (n::Int64)
field = zeros (n, n, n)
for i1 = 1:n, i2 = 1:n, i3 = 1:n
if i1 == 1 || i2 == 1 || i3 == 1 || i1 == n || i2 == n || i3 == n
field[i1,i2,i3] = 1.0
end
end
field
end
main ()
all : laplace.so
laplace.so : laplace.h laplace.c
gcc -O3 -fopenmp -fPIC -c laplace.c
gcc -O3 -fopenmp -fPIC -shared -o liblaplace.so laplace.o
rm -f laplace.o
clean:
rm -f laplace.so
@johnmyleswhite
Copy link

One obvious change is that you have the loops going in the wrong order: start from the i3 dimension and work in to i1, rather than the other way around. But that's probably not the source of your main slowodnw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment