nimble icon indicating copy to clipboard operation
nimble copied to clipboard

bug in compiling length-1 vectors?

Open paciorek opened this issue 6 years ago • 1 comments

Claudia ran across this issue. She has a case where in setup code 'p' is sometimes 1 and sometimes 2 and it wasn't compiling for p=1. Here's a simplified example. I haven't dived deeper as I suspect @perrydv or @danielturek may know something about this off the top of their head(s). It looks like the compiler is treating out as a scalar rather than a length-1 vector.

a =nimbleFunction(
    setup = function() {
        p <- 1
        out <- numeric(p)
    },
    run = function() {
        for(i in 1:p)
            out[i] <<- 3.0
        returnType(double(1))
        return(out)
    })
ra = a()
ca=compileNimble(ra)
#Error: Error, wrong number of indices provided for out[i].
# This occurred for: out[i]
# This was part of the call:  out[i] <<- 3

paciorek avatar Nov 24 '18 18:11 paciorek

@paciorek @claudiawehrhahn Yes, as I recall how this is handled, the "dimension" of out will be determined solely based upon the object that's created in the setup function. In this case, a scalar is created by numeric(p) when p=1, thus we determine that out is a scalar. Then, when the run function gets processed before compilation, the indexing that appears as out[i] throws an error, because you're indexing the scalar out.

This is the age-old issue, with the confusion between length-1 vectors and scalars. The typical work-around is to make sure that out is at least a length-2 vector, even if you only ever use the first element. So, for example, the code could be modified to this, which compiles fine:

a =nimbleFunction(
    setup = function() {
        p <- 1
        out <- numeric(p+1)    ## CHANGED HERE
    },
    run = function() {
        for(i in 1:p)
            out[i] <<- 3.0
        returnType(double(1))
        return(out)
    })
ra = a()
ca=compileNimble(ra)

danielturek avatar Nov 24 '18 18:11 danielturek