Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Casting from dualnum to float for use in Lua functions #3

Open
chrisranderson opened this issue Sep 19, 2016 · 1 comment
Open

Casting from dualnum to float for use in Lua functions #3

chrisranderson opened this issue Sep 19, 2016 · 1 comment

Comments

@chrisranderson
Copy link

chrisranderson commented Sep 19, 2016

So I'm trying to do some stuff in Lua and send it back to Terra (maybe sounds familiar from my past stuff). Long story short, I modified ad.t to get it to work, I'm just checking to see if I'm thinking on the right lines.

Here's my model, with the cast of my lua function right before it:

    local terra_get_image_diff = terralib.cast({float, float, float, float, float, float, float, float} -> int8 , get_image_difference)

    return terra()

      var x_center = qs.gaussian(IMAGE_WIDTH/2.0, 10.0, {struc=false})
      var y_center = qs.gaussian(IMAGE_HEIGHT/2.0, 10.0, {struc=false})

      var width = qs.gaussian(30.0, 1.0, {struc=false})
      var height = qs.gaussian(30.0, 1.0, {struc=false})

      var floor_intensity = qs.uniform(0.0, 1.0, {struc=false})
      var ceiling_intensity = qs.uniform(0.0, 1.0, {struc=false})
      var wall_intensity = qs.uniform(0.0, 1.0, {struc=false})
      var square_intensity = qs.uniform(0.0, 1.0, {struc=false})

      var difference = terra_get_image_diff(x_center, y_center, width, height, floor_intensity, ceiling_intensity, wall_intensity, square_intensity)

      -- should take into account previous difference
      qs.factor(-difference/25.0)

      return 0

(full file here)

I would run it and get this error:

terra hallway-match.t 
src/terralib.lua:575: Errors reported during compilation.
hallway-match.t:219: invalid conversion from dualnum to float
      var difference = terra_get_image_diff(x_center, y_center, width, height, floor_intensity, ceiling_intensity, wall_intensity, square_intensity)

I fixed it like this, at this line in ad.t:

function num.metamethods.__cast(from, to, exp)

    if from:isfloat() and to == num then
        return `num { DualNumBase.new(exp, nil) }
    elseif from == num and to:isfloat() then
        return `[to](exp:val())
    else
        error(string.format("ad.t: Cannot cast '%s' to '%s'", tostring(from), tostring(to)))
    end
end

Is this close to what needs to happen?

@chrisranderson chrisranderson changed the title Casting from dualnum for use in Lua functions Casting from dualnum to float for use in Lua functions Sep 19, 2016
@dritchie
Copy link
Owner

This looks like it will work (as in not crash), but there are a couple issues I can see with it:

  • It's been a while since I've dug into Terra details, so I'm not sure how often / where it does implicit conversions using the __cast metamethod. With the change you've made to num:__cast, it might be possible to run into a situation where you're calling a function on a num, and that function has an overload for num, but it instead converts to float and invokes the float overload. I know I avoided adding the num to float cast for this reason. Maybe this isn't actually a problem; closer reading of the Terra documentation / experience with more code might be illuminating.
  • More importantly: by casting down to float, you're breaking the flow of derivatives between the random variables and the likelihood, which will dramatically drop HMC's performance (I assume you're using HMC). Basically, it'll behave as a random walk sampler with respect to any factor statements you have. You'd be better off implementing your likelihood functions (e.g. terra_get_image_diff) as autodifferentiable Terra functions if you want to get benefits from HMC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants