Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Odd type construction behaviour

Tags:

julia

Working with MD simulations, I need to enforce periodic boundary conditions on particle positions. The simplest way of which is using mod(particle position, box dimension). Since I'm working in 3D space, I made a 3D vector type:

immutable Vec3
x::Float32
y::Float32
z::Float32
end

And a mod function:

f1(a::Vec3, b::Vec3) = Vec3(mod(a.x, b.x), mod(a.y, b.y), mod(a.z, b.z))

However, when using this, it fails horribly:

julia> a = Vec3(11,-2,5)
Vec3(11.0f0,-2.0f0,5.0f0)

julia> b = Vec3(10,10,10)
Vec3(10.0f0,10.0f0,10.0f0)

julia> f1(a,b)
Vec3(5.0f0,10.0f0,NaN32)

If I simply return a tuple, it works fine:

f2(a::Vec3, b::Vec3) = mod(a.x,b.x), mod(a.y,b.y), mod(a.z,b.z)

julia> f2(a,b)
(1.0f0,8.0f0,5.0f0)

As a test to see if it was not liking the mod inside the type constructor, I tried a more verbose method:

function f3(a::Vec3, b::Vec3)
    x = mod(a.x,b.x)
    y = mod(a.y,b.y)
    z = mod(a.z,b.z)
    return Vec3(x,y,z)
end

julia> f3(a,b)
Vec3(5.0f0,10.0f0,NaN32)

And then, a version printing the intermediates:

function f4(a::Vec3, b::Vec3)
    x = mod(a.x,b.x)
    y = mod(a.y,b.y)
    z = mod(a.z,b.z)
    println(x, " ", y, " ", z)
    return Vec3(x,y,z)
end

julia> f4(a,b)
1.0 8.0 5.0
Vec3(1.0f0,8.0f0,5.0f0)

Which for some reason now works. I've tried this on multiple computers now, each with the same result. If someone could shed some light on this, I would be most thankful. Julia version is: Version 0.3.2 (2014-10-21 20:18 UTC)

like image 928
Gibz Avatar asked Sep 10 '26 01:09

Gibz


1 Answers

What works and what doesn't

I think this may be a bug, perhaps even an LLVM bug. I was able to reproduce your error on version 0.3.0, but not on version 0.4. Like you, I also obtained correct results by inserting a print statement in the middle.

Furthermore, I found that both the simpler

f1(a::Vec3, b::Vec3) = Vec3(mod(a.x,b.x),mod(a.y,b.y),1)

julia> f1(a,b)
Vec3(1.0f0,8.0f0,1.0f0)

AND the more complicated

julia> f1(a::Vec3, b::Vec3) = Vec3(mod(a.x,b.x),mod(a.y,b.y),mod(a.z,b.z) + 1)
f1 (generic function with 1 method)

julia> f1(a,b)
Vec3(1.0f0,8.0f0,6.0f0)

both work, but the following one doesn't

julia> f1(a::Vec3, b::Vec3) = Vec3(mod(a.x,b.x),mod(a.y,b.y),mod(a.z,b.z))
f1 (generic function with 1 method)

julia> f1(a,b)
Vec3(5.0f0,10.0f0,NaN32)

To LLVM

The LLVM source also looks correct. The various parts of each of the input Vec3 arguments are loaded mod is taken of the arguments using (fadd,frem,fadd) and then the results are stored in the result.

julia> code_llvm(f1,(Vec3,Vec3))

define %Vec3 @"julia_f1;20242"(%Vec3, %Vec3) {
top:
  %2 = extractvalue %Vec3 %1, 0, !dbg !1733
  %3 = extractvalue %Vec3 %1, 1, !dbg !1733
  %4 = extractvalue %Vec3 %1, 2, !dbg !1733
  %5 = extractvalue %Vec3 %0, 0, !dbg !1733
  %6 = frem float %5, %2, !dbg !1733
  %7 = fadd float %2, %6, !dbg !1733
  %8 = frem float %7, %2, !dbg !1733
  %9 = insertvalue %Vec3 undef, float %8, 0, !dbg !1733
  %10 = extractvalue %Vec3 %0, 1, !dbg !1733
  %11 = frem float %10, %3, !dbg !1733
  %12 = fadd float %3, %11, !dbg !1733
  %13 = frem float %12, %3, !dbg !1733
  %14 = insertvalue %Vec3 %9, float %13, 1, !dbg !1733
  %15 = extractvalue %Vec3 %0, 2, !dbg !1733
  %16 = frem float %15, %4, !dbg !1733
  %17 = fadd float %4, %16, !dbg !1733
  %18 = frem float %17, %4, !dbg !1733
  %19 = insertvalue %Vec3 %14, float %18, 2, !dbg !1733, !julia_type !1734
  ret %Vec3 %19, !dbg !1733

Native Code Error?

But the native instructions look incorrect, XMM2 is moved to XMM0, and later XMM0 is used as an operand to addss, but XMM2 doesn't appear to be initialized.

julia> code_native(f1,(Vec3,Vec3))
    .section    __TEXT,__text,regular,pure_instructions
Filename: none
Source line: 1
  push   RBP
  mov    RBP, RSP
  sub    RSP, 16
  movss  DWORD PTR [RBP - 4], XMM5
Source line: 1
  movaps     XMM0, XMM2
  movaps     XMM1, XMM5
  movabs     RAX, 140735600044048
  call   RAX
  movss  XMM1, DWORD PTR [RBP - 4]
  addss  XMM0, XMM1
  movabs RAX, 140735600044048
  add    RSP, 16
  pop    RBP
  jmp    RAX

Update:

Submitted this issue for possible LLVM error.

like image 93
waTeim Avatar answered Sep 13 '26 08:09

waTeim