nimble-dev / nimble

The base NIMBLE package for R
http://R-nimble.org
BSD 3-Clause "New" or "Revised" License
158 stars 24 forks source link

size-related compilation issues when adding scalar to vector to matrix in model #1425

Closed paciorek closed 3 months ago

paciorek commented 8 months ago

Issue 1: this fails if project is a vector (but is fine if it is a 3x2 matrix)

code<- nimbleCode({
    for(i in 1:4)
    p[1:3,1:2,i] <- B.0[i] + B.1[i] *project[1:3] + B.yday*yday[1:3,1:2]+ B.lag[i]*lag[1:3,1:2,i]
})
m <- nimbleModel(code, data=list(project=rnorm(3),yday=matrix(rnorm(6),3,2), lag=array(rnorm(24),c(3,2,4))))
cm <- compileNimble(m)
Error: In sizeBinaryCwise: Fixed size mismatch.
 This occurred for: model_B_dot_0[getNodeFunctionIndexedInfo(ARG1_INDEXEDNODEINFO__,1)] + model_B_dot_1[getNodeFunctionIndexedInfo(ARG1_INDEXEDNODEINFO__,1)] * eigenBlock(model_project,1:3) + model_B_dot_yday[1] * eigenBlock(model_yday,1:3,1:2) + model_B_dot_lag[getNodeFunctionIndexedInfo(ARG1_INDEXEDNODEINFO__,1)] * map(name,2,call,list,list)
 This was part of the call:  model_p[1:3, 1:2, getNodeFunctionIndexedInfo(ARG1_INDEXEDNODEINFO__,1)] <<- model_B_dot_0[getNodeFunctionIndexedInfo(ARG1_INDEXEDNODEINFO__,1)] + model_B_dot_1[getNodeFunctionIndexedInfo(ARG1_INDEXEDNODEINFO__,1)] * eigenBlock(model_project,1:3) + model_B_dot_yday[1] * eigenBlock(model_yday,1:3,1:2) + model_B_dot_lag[getNodeFunctionIndexedInfo(ARG1_INDEXEDNODEINFO__,1)] * map(name,2,call,list,list)

Issue #2: if the lag part of the summation is left out we get a run-time size error:

code<- nimbleCode({
    for(i in 1:4)
    p[1:3,1:2,i] <- B.0[i] + B.1[i] *project[1:3] + B.yday*yday[1:3,1:2] # + B.lag[i]*lag[1:3,1:2,i]
})
m <- nimbleModel(code, data=list(project=rnorm(3),yday=matrix(rnorm(6),3,2), lag=array(rnorm(24),c(3,2,4))))
cm <- compileNimble(m)
cm$simulate('p')
Error in callEnv[[funName]](..., .basePtr = basePtrList[[index]]) : 
  Run-time size error: expected 2 == 1

On the other hand, both of these subsets of the summation are fine:

code<- nimbleCode({
    for(i in 1:4)
    p[1:3,1:2,i] <- B.0[i] + B.1[i] *project[1:3]
})
m <- nimbleModel(code, data=list(project=rnorm(3),B.0=rnorm(4),B.1=rnorm(4)))
cm <- compileNimble(m)
cm$simulate()

code<- nimbleCode({
    for(i in 1:4)
    p[1:3,1:2,i] <- B.0[i] + B.yday*yday[1:3,1:2]
})
m <- nimbleModel(code, data=list(project=rnorm(3),yday=matrix(rnorm(6),3,2), lag=array(rnorm(24),c(3,2,4))))
cm <- compileNimble(m)
cm$simulate('p')

So there seems to be some interaction between arrays, recycling, and what is being added together that fails in some situations but not all.

paciorek commented 5 months ago

We can also get compilation errors in related cases where the LHS is an array (seems fine if it is a matrix):

nf <- nimbleFunction(
    run=function(b0 = double()) {
        x <- array(0,c(3,2,4))
        x[1:3,1:2,1:4] <- b0
        returnType(double(3))
        return(x)
    })
cnf <- compileNimble(nf)
using C++ compiler: ‘g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’
P_55_rcFun_R_GlobalEnv24.cpp: In function ‘NimArr<3, double> rcFun_R_GlobalEnv24(double)’:
P_55_rcFun_R_GlobalEnv24.cpp:20:13: error: no match for ‘operator=’ (operand types are ‘NimArr<3, double>’ and ‘double’)
   20 | Interm_44 = ARG1_b0_;
      |             ^~~~~~~~
In file included from /accounts/vis/paciorek/R/x86_64-pc-linux-gnu-library-ubuntu-22.04/4.3/nimble/include/nimble/RcppNimbleUtils.h:25,
                 from /accounts/vis/paciorek/R/x86_64-pc-linux-gnu-library-ubuntu-22.04/4.3/nimble/include/nimble/NamedObjects.h:28,
                 from /accounts/vis/paciorek/R/x86_64-pc-linux-gnu-library-ubuntu-22.04/4.3/nimble/include/nimble/EigenTypedefs.h:26,
                 from P_55_rcFun_R_GlobalEnv24.cpp:8:
/accounts/vis/paciorek/R/x86_64-pc-linux-gnu-library-ubuntu-22.04/4.3/nimble/include/nimble/NimArr.h:625:17: note: candidate: ‘NimArr<3, T>& NimArr<3, T>::operator=(const NimArr<3, T>&) [with T = double]’
  625 |   NimArr<3, T> &operator=(const NimArr<3, T> &other) {
      |                 ^~~~~~~~
/accounts/vis/paciorek/R/x86_64-pc-linux-gnu-library-ubuntu-22.04/4.3/nimble/include/nimble/NimArr.h:625:47: note:   no known conversion for argument 1 from ‘double’ to ‘const NimArr<3, double>&’
  625 |   NimArr<3, T> &operator=(const NimArr<3, T> &other) {
      |                           ~~~~~~~~~~~~~~~~~~~~^~~~~
paciorek commented 5 months ago

We don't assign scalar into array.

perrydv commented 5 months ago

These should all give compile-time or run-time errors, so the one that seems wrong is the one with

p[1:3,1:2,i] <- B.0[i] + B.1[i] *project[1:3]

which does not appear to generate an error.