From e5ab7e072a8bac14be8a1aa98d8b0684324015e6 Mon Sep 17 00:00:00 2001
From: perrydv <pdevalpine@berkeley.edu>
Date: Mon, 5 Jun 2017 17:34:41 -0700
Subject: [PATCH 1/6] initial setup for refactoring size processing to separate
 eigen-specific steps.

---
 packages/nimble/DESCRIPTION                   |   1 +
 packages/nimble/R/RCfunction_compile.R        |   5 +
 packages/nimble/R/cppDefs_RCfunction.R        |   1 -
 packages/nimble/R/genCpp_exprClass.R          |   3 +-
 packages/nimble/R/genCpp_insertAssertions.R   |   2 +-
 packages/nimble/R/genCpp_sizeProcessing.R     |  26 +-
 packages/nimble/R/genCpp_toEigenize.R         | 277 ++++++++++++++++++
 packages/nimble/R/options.R                   |   2 +
 .../tests/test-refactorCompilationSteps.R     |  42 +++
 9 files changed, 347 insertions(+), 12 deletions(-)
 create mode 100644 packages/nimble/R/genCpp_toEigenize.R
 create mode 100644 packages/nimble/inst/tests/test-refactorCompilationSteps.R

diff --git a/packages/nimble/DESCRIPTION b/packages/nimble/DESCRIPTION
index adb862fb5..038b0e172 100644
--- a/packages/nimble/DESCRIPTION
+++ b/packages/nimble/DESCRIPTION
@@ -50,6 +50,7 @@ Collate:
     genCpp_buildIntermediates.R
     genCpp_processSpecificCalls.R
     genCpp_sizeProcessing.R
+    genCpp_toEigenize.R
     genCpp_insertAssertions.R
     genCpp_maps.R
     genCpp_liftMaps.R
diff --git a/packages/nimble/R/RCfunction_compile.R b/packages/nimble/R/RCfunction_compile.R
index ad49f6a06..8f48c9e1e 100644
--- a/packages/nimble/R/RCfunction_compile.R
+++ b/packages/nimble/R/RCfunction_compile.R
@@ -269,6 +269,11 @@ RCfunProcessing <- setRefClass('RCfunProcessing',
                                        if(inherits(tryResult, 'try-error')) {
                                            stop(paste('There is some problem at the insertAdditions processing step for this code:\n', paste(deparse(compileInfo$origRcode), collapse = '\n'), collapse = '\n'), call. = FALSE)
                                        }
+
+                                       if(nimbleOptions('useRefactoredSizeProcessing')) {
+                                           exprClasses_setToEigenize(compileInfo$nimExpr, compileInfo$newLocalSymTab, compileInfo$typeEnv)
+                                       }
+                                       
                                        if(debug) {
                                            print('compileInfo$nimExpr$show(showAssertions = TRUE)')
                                            compileInfo$nimExpr$show(showAssertions = TRUE)
diff --git a/packages/nimble/R/cppDefs_RCfunction.R b/packages/nimble/R/cppDefs_RCfunction.R
index a82688270..f178ee377 100644
--- a/packages/nimble/R/cppDefs_RCfunction.R
+++ b/packages/nimble/R/cppDefs_RCfunction.R
@@ -96,7 +96,6 @@ RCfunctionDef <- setRefClass('RCfunctionDef',
                                    
                                    if(is.character(SEXPinterfaceCname) && is.null(dll) && eval) {
                                      warning("creating a .Call() expression with no DLL information")
-                                     browser()                                     
                                    }
                                                                      
                                    # avoid R CMD check problem with registration
diff --git a/packages/nimble/R/genCpp_exprClass.R b/packages/nimble/R/genCpp_exprClass.R
index aa8a73461..5fa3ad51b 100644
--- a/packages/nimble/R/genCpp_exprClass.R
+++ b/packages/nimble/R/genCpp_exprClass.R
@@ -24,7 +24,8 @@ exprClass <- setRefClass('exprClass',
                              toEigenize =  'ANY',	#'character', ##'yes', 'no', or 'maybe'
                              caller = 'ANY',            # exprClass object for the call to which this is an argument (if any)
                              callerArgID =  'ANY',	#'numeric', ## index in the calling object's args list for this object.
-                             assertions =  'ANY'	#'list'
+                             assertions =  'ANY',	#'list'
+                             aux = 'ANY'                # anything needed for specific operators
                              ),
                          methods = list(
                              initialize = function(...) {sizeExprs <<- list(); args <<- list();toEigenize <<- 'unknown';assertions <<- list(); eigMatrix <<- logical(); callSuper(...)},
diff --git a/packages/nimble/R/genCpp_insertAssertions.R b/packages/nimble/R/genCpp_insertAssertions.R
index f2d691467..8a323d7b6 100644
--- a/packages/nimble/R/genCpp_insertAssertions.R
+++ b/packages/nimble/R/genCpp_insertAssertions.R
@@ -34,7 +34,7 @@ exprClasses_insertAssertions <- function(code) {
             if(length(code$args[[i]]$assertions) > 0) {
                 toInsert <- lapply(code$args[[i]]$assertions, function(x) if(inherits(x, 'exprClass')) x else RparseTree2ExprClasses(x))
                 before <- unlist(lapply(toInsert, function(x) {if(x$name == 'after') FALSE else TRUE}))
-                
+                if(nimbleOptions('useRefactoredSizeProcessing')) code$args[[i]]$assertions <- list()  ## Clear assertions field so it can be used by later compiler stages
                 newExpr <- newBracketExpr(args = c(lapply(toInsert[before], ## assertions will be inserted recursively IF they are in {}
                                                           function(z) {exprClasses_insertAssertions(z); z}),
                                                    code$args[i],
diff --git a/packages/nimble/R/genCpp_sizeProcessing.R b/packages/nimble/R/genCpp_sizeProcessing.R
index b49f3e357..98623ebce 100644
--- a/packages/nimble/R/genCpp_sizeProcessing.R
+++ b/packages/nimble/R/genCpp_sizeProcessing.R
@@ -251,6 +251,8 @@ sizeDim <- function(code, symTab, typeEnv) {
 }
 
 sizeDiagonal <- function(code, symTab, typeEnv) {
+    ## refactor: code$name change step stays here
+    ## because the 3 cases are not implementation-specific
     asserts <- recurseSetSizes(code, symTab, typeEnv)
     argIsExprClass <- inherits(code$args[[1]], 'exprClass')
     nDimArg <- if(argIsExprClass) code$args[[1]]$nDim else 0
@@ -301,8 +303,10 @@ sizeWhich <- function(code, symTab, typeEnv) {
     code$toEigenize <- 'yes'
     code$name <- 'setWhich'
 
-    if(!(code$caller$name %in% assignmentOperators)) {
-        asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
+    if(!nimbleOptions('doSelfLiftSeparately')) {
+        if(!(code$caller$name %in% assignmentOperators)) {
+            asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
+        }
     }
     if(length(asserts) == 0) NULL else asserts
 }
@@ -331,7 +335,7 @@ sizeRecyclingRule <- function(code, symTab, typeEnv) { ## also need an entry in
     code$sizeExprs <- newSizeExprs
     code$type <- 'double' ## will need to look up from a list
     code$nDim <- 1
-    code$toEigenize <- TRUE
+    code$toEigenize <- 'yes' ## toEigen: N.B. This had TRUE
     return(asserts)
 }
 
@@ -345,6 +349,7 @@ sizeRecyclingRuleRfunction <- function(code, symTab, typeEnv) {
     ## If scalar, that gives size
     ## If vector, size is length of first argument.
     ## Problem is vector of length 1, where size should be value of first element, not length of 1.
+    ## toEigen: keep this lift here for now, since it sets up sizes.
     if(inherits(code$args[[1]], 'exprClass')) {
         if(!code$args[[1]]$isName) {
             asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
@@ -894,7 +899,6 @@ sizeGetBound <- function(code, symTab, typeEnv) {
         asserts <- list()
     }
  
-    
     boundInfoSym <- symTab$getSymbolObject(code$args[[3]]$name, inherits = TRUE)
     code$type <- boundInfoSym$boundInfo$type
     code$nDim <- boundInfoSym$boundInfo$nDim
@@ -950,6 +954,7 @@ sizeAsRowOrCol <- function(code, symTab, typeEnv) {
 
 ## a$b becomes nfVar(a, 'b')
 sizeNFvar <- function(code, symTab, typeEnv) {
+    ## toEigen: Is it correct that this does not mark toEigen?
     asserts <- list()
     if(!inherits(code$args[[1]], 'exprClass'))
         stop(exprClassProcessingErrorMsg(code, 'Problem using $: no name on the right?'), call. = FALSE)
@@ -1040,10 +1045,12 @@ sizeNimbleListReturningFunction <- function(code, symTab, typeEnv) {
       symTab$addSymbol(symbolObject)
   }
   code$sizeExprs <- symbolObject
-  code$toEigenize <- "yes"  # This is specialized for nimSvd and nimEigen.
+  code$toEigenize <- "yes"  
   code$nDim <- 0
-  if(!(code$caller$name %in% assignmentOperators))
-      asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
+  if(!nimbleOptions('doSelfLiftSeparately')) {
+      if(!(code$caller$name %in% assignmentOperators))
+          asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
+  }
   if(length(asserts) == 0) NULL else asserts
 }
 
@@ -1329,6 +1336,7 @@ assignmentTypeWarn <- function(LHS, RHS) {
 }
 
 ## used for setAll
+## toEigen: N.B. This may be deprecated.
 sizeOneEigenCommand <- function(code, symTab, typeEnv) {
     if(!code$args[[1]]$isName) stop(exprClassProcessingErrorMsg(code, 'In sizeOneEigenCommand:  First arg should be a name.'), call. = FALSE)
     recurseSetSizes(code, symTab, typeEnv)
@@ -1357,6 +1365,7 @@ sizeforceEigenize <- function(code, symTab, typeEnv) {
     if(length(asserts) == 0) NULL else asserts
 }
 
+## toEigen: N.B. Deprecated (see external-c-calls in development)
 sizecallC <- function(code, symTab, typeEnv) {
     asserts <- recurseSetSizes(code$args[[1]], symTab, typeEnv)
     asserts
@@ -1451,6 +1460,7 @@ sizeSetSize <- function(code, symTab, typeEnv) {
 
 
 ## This was redundant and we should eventually be able to remove it
+## toEigen: N.B. omitting this
 sizeResizeNoPtr <- function(code, symTab, typeEnv){
     sym <- symTab$getSymbolObject(code$args[[1]]$name, inherits = TRUE)
     if(length(code$args[[2]]) != 1)  stop(exprClassProcessingErrorMsg(code, 'In sizeResizeNoPtr: Problem with number of dimensions provided in resize.'), call. = FALSE)
@@ -1536,8 +1546,6 @@ sizeAssign <- function(code, symTab, typeEnv) {
     if(length(asserts) == 0) NULL else asserts
 }
 
-
-
 ## Handler for assignment
 sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALSE) {
     LHS <- code$args[[1]]
diff --git a/packages/nimble/R/genCpp_toEigenize.R b/packages/nimble/R/genCpp_toEigenize.R
new file mode 100644
index 000000000..a49add6ed
--- /dev/null
+++ b/packages/nimble/R/genCpp_toEigenize.R
@@ -0,0 +1,277 @@
+## It is hoped substantial sets of these calls can be combined
+## or implemented by a rule system.
+
+toEigenizeNoCalls <- c('dim', 'run.time','nimOptimDefaultControl')
+
+toEigenizeYesCalls <- c(paste0('nimDiagonal', c('D','I','B')),
+                        'diagonal',
+                        'which',
+                        scalar_distribution_dFuns,
+                        scalar_distribution_pFuns,
+                        scalar_distribution_qFuns,
+                        paste0(c('d','q','p'), 't'),
+                        paste0(c('d','q','p'), 'exp'),
+                        scalar_distribution_rFuns,
+                        'rt',
+                        'rexp',
+                        'asRow','asCol',
+                        nimbleListReturningOperators, ## should these be in 'maybe'?
+                        'setAll' ## deprecate?
+                        )
+
+toEigenizeMaybeCalls <- c('map',
+                          c('decide', 'size', 'getsize','getNodeFunctionIndexedInfo', 'endNimbleTimer'),
+                          c('blank', 'nfMethod', 'getPtr', 'startNimbleTimer'))
+
+toEigenizeUseRuleCalls <- c('nimPrint')
+
+toEigenCalls <- c(makeCallList(binaryOperators, 'toEigenBinaryCwise'),
+                  makeCallList(binaryMidLogicalOperators, 'sizeBinaryCwiseLogical'),
+                  makeCallList(binaryOrUnaryOperators, 'toEigenBinaryUnaryCwise'),
+                  makeCallList(unaryOperators, 'toEigenUnaryCwise'), 
+                  makeCallList(unaryOrNonaryOperators, 'sizeUnaryNonaryCwise'),
+                  makeCallList(assignmentOperators, 'toEigenAssign'), 
+                  makeCallList(reductionUnaryOperators, 'sizeUnaryReduction'), 
+                  makeCallList(matrixSquareReductionOperators, 'sizeMatrixSquareReduction'),
+                  makeCallList(reductionBinaryOperators, 'sizeBinaryReduction'),
+                  makeCallList(matrixMultOperators, 'sizeMatrixMult'), 
+                  makeCallList(matrixFlipOperators, 'sizeTranspose'),
+                  makeCallList(matrixSolveOperators, 'sizeSolveOp'), 
+                  makeCallList(matrixSquareOperators, 'sizeUnaryCwiseSquare'),
+                  ##               makeCallList(nimbleListReturningOperators, 'sizeNimbleListReturningFunction'),
+                  nimOptim = 'toEigenOptim',
+                  ##nimOptimDefaultControl = 'sizeOptimDefaultControl',
+                  
+                  makeCallList(paste0('nimC',c('d','i','b')), 'toEigenConcatenate'),
+                  makeCallList(paste0('nimRep',c('d','i','b')), 'toEigenRep'),
+                  list('debugSizeProcessing' = 'sizeProxyForDebugging',
+                       ##      diag = 'toEigenYes',
+                       ##      dim = 'toEigenNo',
+                       ##       RRtest_add = 'toEigenYes', ## testing!
+                       ##      which = 'toEigenYes',
+                       
+                       nimRep = 'sizeRep',
+                       nimSeqBy = 'sizeSeq',
+                       nimSeqLen = 'sizeSeq',
+                       nimSeqByLen = 'sizeSeq',
+                       'return' = 'sizeReturn',
+                       ##  'asRow' = 'sizeAsRowOrCol',
+                       ##  'asCol' = 'sizeAsRowOrCol',
+                       makeNewNimbleListObject = 'toEigenNewNimbleList',
+                       getParam = 'toEigenGetParam',
+                       getBound = 'toEigenGetBound',
+                       ## nimSwitch = 'sizeSwitch', ## NEVER GETS MARKED WITH TOEIGENIZE
+                       asDoublePtr = 'toEigenIgnoreForNow',
+                       '[' = 'sizeIndexingBracket',
+                       ##'[[' = 'sizeDoubleBracket', ## for nimbleFunctionList, this will always  go through chainedCall(nfList[[i]], 'foo')(arg1, arg2) ## NEVER GETS MARKED WITH TOEIGENIZE
+                       chainedCall = 'toEigenChainedCall',
+                       ## nfVar = 'sizeNFvar', ## NEVER GETS MARKED WITH TOEIGENIZE
+                       ## map = 'sizemap',
+                       ':' = 'sizeColonOperator',
+                       ##dim = 'sizeDimOperator',
+                       'if' = 'recurseSetSizes', ##OK
+                       'while' = 'recurseSetSizes',
+                       callC = 'sizecallC', 
+                       'for' = 'toEigenFor', 
+                       cppPointerDereference = 'toEigenCppPointerDereference',
+                       values = 'toEigenValues',
+                       '(' = 'sizeUnaryCwise',
+                       setSize = 'toEigenSetSize', ## OK but not done for numericLists
+                       ## resizeNoPtr = 'sizeResizeNoPtr', ## may not be used any more 
+                       nimArr_rcat = 'toEigenScalarRecurse',
+                       nimArr_rinterval = 'toEigenScalarRecurse',
+                       ##nimPrint = 'sizeforceEigenize',
+                       ##nimCat = 'sizeforceEigenize',
+                       as.integer = 'sizeUnaryCwise', ## Note as.integer and as.numeric will not work on a non-scalar yet
+                       as.numeric = 'sizeUnaryCwise',
+                       nimArrayGeneral = 'toEigenNimArrayGeneral',
+                       ##setAll = 'sizeOneEigenCommand',
+                       voidPtr = 'sizeVoidPtr'
+                       ),
+                    ##run.time = 'sizeRunTime'),
+                  ##               makeCallList(scalar_distribution_dFuns, 'toEigenYes'),
+                  ##               makeCallList(scalar_distribution_pFuns, 'toEigenYes'),
+                  ##               makeCallList(scalar_distribution_qFuns, 'sizeRecyclingRule'),
+                  ##               makeCallList(scalar_distribution_rFuns, 'sizeRecyclingRuleRfunction'),
+                  makeCallList(distributionFuns[!(distributionFuns %in% c(scalar_distribution_dFuns, scalar_distribution_pFuns, scalar_distribution_qFuns, scalar_distribution_rFuns))], 'toEigenScalarRecurse'),
+                                        # R dist functions that are not used by NIMBLE but we allow in DSL
+                  ## makeCallList(paste0(c('d','q','p'), 't'), 'sizeRecyclingRule'),
+                  ## rt = 'sizeRecyclingRuleRfunction',
+                  ## makeCallList(paste0(c('d','q','p'), 'exp'), 'sizeRecyclingRule'),
+                  ## rexp = 'sizeRecyclingRuleRfunction',
+                  makeCallList(c('isnan','ISNAN','ISNA'), 'toEigenScalarRecurse'),
+                  makeCallList(c('nimArr_dmnorm_chol', 'nimArr_dmvt_chol', 'nimArr_dwish_chol', 'nimArr_dinvwish_chol', 'nimArr_dmulti', 'nimArr_dcat', 'nimArr_dinterval', 'nimArr_ddirch'), 'toEigenScalarRecurse'),
+                  makeCallList(c('nimArr_rmnorm_chol', 'nimArr_rmvt_chol', 'nimArr_rwish_chol', 'nimArr_rinvwish_chol', 'nimArr_rmulti', 'nimArr_rdirch'), 'sizeRmultivarFirstArg'),
+                  ##      makeCallList(c('decide', 'size', 'getsize','getNodeFunctionIndexedInfo', 'endNimbleTimer'), 'sizeScalar'),
+                  ## makeCallList(c('calculate','calculateDiff', 'getLogProb'), 'toEigenScalarModelOp'),
+                  simulate = 'toEigenIgnoreForNow'
+                  ##               makeCallList(c('blank', 'nfMethod', 'getPtr', 'startNimbleTimer'), 'sizeUndefined')
+                  )
+
+
+exprClasses_setToEigenize <- function(code, symTab, typeEnv) { ## input code is exprClass
+    ## name:
+    if(code$isName) {
+        return(list()) ## names don't have toEigen annotation
+    }
+    if(code$isCall) {
+        if(code$name == '{') {
+            ## recurse over lines
+            for(i in seq_along(code$args)) {
+                if(inherits(code$args[[i]], 'exprClass')) {
+                    newAsserts <- exprClasses_setToEigenize(code$args[[i]], symTab, typeEnv)
+                    code$args[[i]]$assertions <- if(is.null(newAsserts)) list() else newAsserts
+                }
+            }
+            return(invisible(NULL))
+        }
+        thisCall <- toEigenCalls[[code$name]]
+        if(!is.null(thisCall)) {
+            test0 <- eval(call(thisCall, code, symTab, typeEnv))
+            return(test0)
+        }
+        if(symTab$symbolExists(code$name, TRUE)) { ## could be a nimbleFunction object
+            return(toEigenNimbleFunction(code, symTab, typeEnv) )
+        }
+        ## Finally, it could be an RCfunction (a nimbleFunction with no setup == a simple function) {
+
+        if(exists(code$name)) {
+            obj <- get(code$name)
+            if(is.rcf(obj)) { ## it is an RC function
+                message('figure out how to extract the RCfunProc that should already exist')
+                browser()
+                RCfunProc <- typeEnv$.nimbleProject$compileRCfun(obj, initialTypeInference = TRUE)
+                
+                return(toEigenRCfunction(code, symTab, typeEnv, nfmObj, RCfunProc))
+            }
+        }
+    }
+    invisible(NULL)
+}
+
+toEigenNo <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'no'
+    return(list())
+}
+
+toEigenYes <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'yes'
+    return(list())
+}
+
+toEigenNo <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'no'
+    return(list())
+}
+
+toEigenMaybe <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'maybe'
+    return(list())
+}
+
+toEigenUseRule <- function(code, symTab, typeEnv) {
+    message('need to implement rules for toEigenUseRule')
+    return(list())
+}
+
+toEigenConcatenate <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'yes'
+    return(list())
+}
+
+toEigenRep <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'yes'
+    return(list())
+}
+
+toEigenNewNimbleList <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'maybe'
+    return(list())
+}
+
+toEigenNimArrayGeneral <- function(code, symTab, typeEnv) {
+    ## won't even have the same name at this point
+    stop('setting toEigenize for nimArrayGeneral must be handled')
+}
+
+toEigenGetParam <- function(code, symTab, typeEnv) {
+    stop('setting toEigenize for getParam must be handled')
+    return(list())
+}
+
+toEigenGetBound <- function(code, symTab, typeEnv) {
+    stop('setting toEigenize for getBound must be handled')
+    return(list())
+}
+
+toEigenOptim <- function(code, symTab, typeEnv) {
+    code$toEigenize <- 'no'
+    return(list())
+}
+
+toEigenCppPointerDereference <- function(code, symTab, typeEnv) {
+    code$toEigenize <- code$args[[1]]$toEigenize
+    return(list())
+}
+
+toEigenChainedCall <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for chained call must be handled')
+    return(list())
+}
+
+toEigenValues <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for values must be handled')
+    return(list())
+}
+
+toEigenRCfunction <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for RCfunction must be handled')
+    return(list())
+}
+
+toEigenNimbleFunction <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for RCfunction must be handled')
+    return(list())
+}
+
+toEigenSetSize <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for toEigenSetSize must be handled')
+    return(list())
+}
+
+toEigenFor <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for toEigenFor must be handled')
+    return(list())
+}
+
+toEigenAssign <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for toEigenAssign must be handled')
+    return(list())
+}
+
+toEigenIgnoreForNow <- function(code, symTab, typeEnv) {
+    message('Can not set toEigenize: to ignore for now')
+    return(list())
+}
+
+toEigenScalarModelOp <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for toEigenScalarModelOp must be handled')
+    return(list())
+}
+
+toEigenScalarRecurse <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for toEigenScalarRecurse must be handled')
+    return(list())
+}
+
+toEigenBinaryUnaryCwise <- function(code, symTab, typeEnv) {
+    if(length(code$args) == 1) return(toEigenUnaryCwise(code, symTab, typeEnv))
+    if(length(code$args) == 2) return(toEigenBinaryCwise(code, symTab, typeEnv))
+    stop(exprClassProcessingErrorMsg(code, paste0('In toEigenBinaryUnarycWise: Length of arguments is not 1 or 2.')), call. = FALSE)
+}
+
+toEigenBinaryCwise <- function(code, symTab, typeEnv) {
+    message('setting toEigenize for toEigenBinaryCwise must be handled')
+    return(list())
+}
+
diff --git a/packages/nimble/R/options.R b/packages/nimble/R/options.R
index bcaf5be82..c76fa956e 100644
--- a/packages/nimble/R/options.R
+++ b/packages/nimble/R/options.R
@@ -7,6 +7,8 @@ nimbleUserNamespace <- as.environment(list(sessionSpecificDll = NULL))
 # These options are for development use at this point.
 .nimbleOptions <- as.environment(
     list(
+        useRefactoredSizeProcessing = FALSE,
+        doSelfListSeparately = FALSE,
         enableSpecialHandling = FALSE,
         pauseAfterWritingFiles = FALSE,
         convertSingleVectorsToScalarsInSetupArgs = TRUE,
diff --git a/packages/nimble/inst/tests/test-refactorCompilationSteps.R b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
new file mode 100644
index 000000000..18cb18e2c
--- /dev/null
+++ b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
@@ -0,0 +1,42 @@
+require(testthat)
+
+context("Testing of old vs. new generated C++ during refactoring steps")
+
+oldWarnLevel <- options('warn')
+options(warn = -1)
+
+compareOldAndNewCompilationRC <- function(input) {
+    run <- input$run
+    name <- input$name
+    require(testthat)
+    foo <- nimbleFunction(run = run, name = 'foo')
+    nimbleOptions(useRefactoredSizeProcessing = FALSE)
+    testProject <- nimble:::nimbleProjectClass(name = 'test')
+    ## management of compilation through the control list is crude and leads to error
+    ## but the project does contain the result, so we can run this, catch the error
+    ## and extract the result from the project
+    old <- try(compileNimble(foo, project = testProject, control = list(writeFiles = TRUE, compileCpp = FALSE, loadSO = FALSE)))
+    filename <- testProject$RCfunInfos[['foo']][['cppClass']]$filename
+    ## we could regenerate it, but might as well read it from the file
+    oldFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
+    oldFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
+    
+    nimbleOptions(useRefactoredSizeProcessing = TRUE)
+    testProject <- nimble:::nimbleProjectClass(name = 'test')
+    new <- try(compileNimble(foo, project = testProject, control = list(writeFiles = TRUE, compileCpp = FALSE, loadSO = FALSE)))
+    filename <- testProject$RCfunInfos[['foo']][['cppClass']]$filename
+    ## we could regenerate it, but might as well read it from the file
+    newFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
+    newFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
+    test_that(paste0(name,': .cpp matches'), expect_identical(oldFooCppOutput, newFooCppOutput))
+    test_that(paste0(name,': .h matches'), expect_identical(oldFooHOutput, newFooHOutput))
+}
+
+testCases <- list(
+    list(name = 'Y <- x',
+         run = function(x = double(1)) {
+             Y <- x
+         }))
+
+ans <- lapply(testCases, compareOldAndNewCompilationRC)
+options(warn = as.numeric(oldWarnLevel))

From a7d03ec4f10798afd7038bba17eb5b97397785f6 Mon Sep 17 00:00:00 2001
From: perrydv <pdevalpine@berkeley.edu>
Date: Thu, 8 Jun 2017 07:40:00 -0700
Subject: [PATCH 2/6] toEigenAssign

---
 packages/nimble/R/RCfunction_compile.R        |   9 +-
 packages/nimble/R/genCpp_sizeProcessing.R     |  17 ++-
 packages/nimble/R/genCpp_toEigenize.R         | 124 +++++++++++++++++-
 .../tests/test-refactorCompilationSteps.R     |   8 +-
 packages/nimble/inst/tests/test_utils.R       |  12 ++
 run_tests.R                                   |   2 +-
 6 files changed, 153 insertions(+), 19 deletions(-)

diff --git a/packages/nimble/R/RCfunction_compile.R b/packages/nimble/R/RCfunction_compile.R
index 8f48c9e1e..051e7e757 100644
--- a/packages/nimble/R/RCfunction_compile.R
+++ b/packages/nimble/R/RCfunction_compile.R
@@ -265,14 +265,15 @@ RCfunProcessing <- setRefClass('RCfunProcessing',
                                            browser()
                                        }
 
+                                       if(nimbleOptions('useRefactoredSizeProcessing')) {
+                                           browser()
+                                           exprClasses_setToEigenize(compileInfo$nimExpr, compileInfo$newLocalSymTab, compileInfo$typeEnv)
+                                       }
+
                                        tryResult <- try(exprClasses_insertAssertions(compileInfo$nimExpr))
                                        if(inherits(tryResult, 'try-error')) {
                                            stop(paste('There is some problem at the insertAdditions processing step for this code:\n', paste(deparse(compileInfo$origRcode), collapse = '\n'), collapse = '\n'), call. = FALSE)
                                        }
-
-                                       if(nimbleOptions('useRefactoredSizeProcessing')) {
-                                           exprClasses_setToEigenize(compileInfo$nimExpr, compileInfo$newLocalSymTab, compileInfo$typeEnv)
-                                       }
                                        
                                        if(debug) {
                                            print('compileInfo$nimExpr$show(showAssertions = TRUE)')
diff --git a/packages/nimble/R/genCpp_sizeProcessing.R b/packages/nimble/R/genCpp_sizeProcessing.R
index 98623ebce..cb97177c0 100644
--- a/packages/nimble/R/genCpp_sizeProcessing.R
+++ b/packages/nimble/R/genCpp_sizeProcessing.R
@@ -1507,7 +1507,9 @@ sizeInsertIntermediate <- function(code, argID, symTab, typeEnv, forceAssign = F
         newArgExpr <- RparseTree2ExprClasses(as.name(newName))
         newArgExpr$type <- code$args[[argID]]$type
         newArgExpr$sizeExprs <- code$args[[argID]]$sizeExprs
-        newArgExpr$toEigenize <- 'maybe'
+        if(!nimbleOptions('useRefactoredSizeProcessing')) {
+            newArgExpr$toEigenize <- 'maybe'
+        }
         newArgExpr$nDim <- code$args[[argID]]$nDim
     } else {
 
@@ -1524,7 +1526,9 @@ sizeInsertIntermediate <- function(code, argID, symTab, typeEnv, forceAssign = F
         newArgExpr <- RparseTree2ExprClasses(as.name(newName))
         newArgExpr$type <- newExpr$args[[1]]$type
         newArgExpr$sizeExprs <- newExpr$args[[1]]$sizeExprs
-        newArgExpr$toEigenize <- 'maybe'
+        if(!nimbleOptions('useRefactoredSizeProcessing')) {
+            newArgExpr$toEigenize <- 'maybe'
+        }
         newArgExpr$nDim <- newExpr$args[[1]]$nDim
     }
     setArg(code, argID, newArgExpr)
@@ -1608,7 +1612,9 @@ sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALS
                 }
             } else { ## yes in symTab
                 ## This case is ok.  It is in the symbol table but not the typeEnv.  So it is something like ptr <- getPtr(A)
+                 if(!nimbleOptions('useRefactoredSizeProcessing')) {
                 code$toEigenize <- 'no'
+                 } ##useRefactoredSizeProcessing
                 code$nDim <- 0
                 code$type <- 'unknown'
                 code$sizeExprs <- list()
@@ -1646,6 +1652,8 @@ sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALS
     ## Note this can use LHS$name for RHSsizeExprs when returning from a nimbleFunction on RHS.  But this is probably not needed any more.
     if(any(unlist(lapply(RHSsizeExprs, is.null)))) RHSsizeExprs <- makeSizeExpressions(rep(NA, RHSnDim), LHS$name) ## reset sizeExprs for the LHS var. re-using RHSsizeExprs for LHS.  This would only be valid if it is a nimbleFunction returning something on the RHS.  For assignment to be executed in Eigen, the RHS sizes MUST be known
 
+     if(!nimbleOptions('useRefactoredSizeProcessing')) {
+                
     if(LHS$toEigenize == 'yes') {
         code$toEigenize <- 'yes'
 ##        message('Warning from sizeAssign: not expecting LHS to have toEigenize == yes')
@@ -1664,7 +1672,8 @@ sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALS
             else 'no'
         }
     }
-
+    
+                
     if(code$toEigenize == 'yes') { ## this would make more sense in eigenize_assign
     ## generate setSize(LHS, ...) where ... are dimension expressions
         if(length(RHSnDim) == 0) {
@@ -1717,7 +1726,7 @@ sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALS
             if(LHS$name == 'map') assert <- c(assert, sizeInsertIntermediate(code, 1, symTab, typeEnv) )
         }
     }
-
+     } ##useRefactoredSizeProcessing
     if(!(LHS$name %in% c('eigenBlock', 'diagonal', 'coeffSetter', 'nimNonseqIndexedd', 'nimNonseqIndexedi','nimNonseqIndexedb'))) {
         ## should already be annotated if it is an indexed assignment.
         ## It should be harmless to re-annotated EXCEPT in case like out[1:5] <- scalar
diff --git a/packages/nimble/R/genCpp_toEigenize.R b/packages/nimble/R/genCpp_toEigenize.R
index a49add6ed..fb19a35f3 100644
--- a/packages/nimble/R/genCpp_toEigenize.R
+++ b/packages/nimble/R/genCpp_toEigenize.R
@@ -120,7 +120,8 @@ exprClasses_setToEigenize <- function(code, symTab, typeEnv) { ## input code is
             for(i in seq_along(code$args)) {
                 if(inherits(code$args[[i]], 'exprClass')) {
                     newAsserts <- exprClasses_setToEigenize(code$args[[i]], symTab, typeEnv)
-                    code$args[[i]]$assertions <- if(is.null(newAsserts)) list() else newAsserts
+                    code$args[[i]]$assertions <- c(code$args[[i]]$assertions,
+                                                   if(is.null(newAsserts)) list() else newAsserts)
                 }
             }
             return(invisible(NULL))
@@ -149,6 +150,25 @@ exprClasses_setToEigenize <- function(code, symTab, typeEnv) { ## input code is
     invisible(NULL)
 }
 
+
+recurseSetToEigenize <- function(code, symTab, typeEnv, useArgs = rep(TRUE, length(code$args))) {
+    asserts <- list()
+    for(i in seq_along(code$args)) {
+        if(useArgs[i]) {
+            if(inherits(code$args[[i]], 'exprClass')) {
+                asserts <- c(asserts, exprClasses_setToEigenize(code$args[[i]], symTab, typeEnv))
+            }
+        }
+    }
+    if(length(asserts)==0) NULL else asserts
+}
+
+toEigenInsertIntermediate <- function(code, argID, symTab, typeEnv) {
+    newLine <- sizeInsertIntermediate(code, argID, symTab, typeEnv)
+    exprClasses_setToEigenize(newLine, symTab, typeEnv)
+    newLine
+}
+
 toEigenNo <- function(code, symTab, typeEnv) {
     code$toEigenize <- 'no'
     return(list())
@@ -174,6 +194,103 @@ toEigenUseRule <- function(code, symTab, typeEnv) {
     return(list())
 }
 
+toEigenAssign <- function(code, symTab, typeEnv) {
+    asserts <- recurseSetToEigenize(code, symTab, typeEnv, useArgs = c(FALSE, TRUE))
+    asserts <- c(asserts, toEigenAssignLHS(code, symTab, typeEnv))
+    asserts
+}
+
+toEigenAssignLHS <- function(code, symTab, typeEnv, NoEigenizeMap = FALSE) {
+    ## In original size processing, NoEigenizeMap exists to be set as TRUE from sizeInsertIntermediate.
+    if(identical(code$type, 'unknown')) {
+        code$toEigenize <- 'no'
+        return(list())
+    }
+    assert <- list()
+    LHS <- code$args[[1]]
+    RHS <- code$args[[2]]
+    
+    if(LHS$toEigenize == 'yes') { ## unexpected?
+        code$toEigenize <- 'yes'
+    } else {
+        code$toEigenize <-
+            if(inherits(RHS, 'exprClass')) {
+                if(RHS$toEigenize == 'no') 'no'
+                else {
+                    if(RHS$toEigenize == 'unknown') 'no'
+                    else {
+                        if(RHS$toEigenize != 'yes' &
+                           (!(LHS$name %in% c('eigenBlock', 'diagonal', 'coeffSetter'))) &
+                           (RHS$nDim == 0 | RHS$isName | (RHS$name == 'map' & NoEigenizeMap)))
+                            'no' ## if it is scalar or is just a name or a map, we will do it via NimArr operator= .  Used to have "| RHS$name == 'map'", but this allowed X[1:3] <- X[2:4], which requires eigen, with eval triggered, to get right
+                        else 'yes' ## if it is 'maybe' and non-scalar and not just a name, default to 'yes'
+                    }
+                }
+            } else {
+                if(is.numeric(LHS$nDim))
+                    if(LHS$nDim > 0) 'yes' ## This is for cases like out[1:4] <- scalar
+                    else 'no'
+                else 'no'
+            }
+    }
+    ## if LHS is set to eigenize 'yes set code to Eigenize 'yes'
+    
+    if(code$toEigenize == 'yes') { ## this would make more sense in eigenize_assign
+        ## generate setSize(LHS, ...) where ... are dimension expressions
+        if(length(RHS$nDim) == 0) {
+            message("confused about trying to eigenize something with nDim = 0")
+            browser()
+        }
+        if(RHS$nDim > 0) {
+            if(!(RHS$name %in% setSizeNotNeededOperators)) {
+                if(LHS$isName | LHS$name == "nfVar") {
+                    assert <- substitute(setSize(LHS), list(LHS = nimbleGeneralParseDeparse(LHS)))
+                    for(i in seq_along(RHS$sizeExprs)) { ## N.B. RHS$sizeExprs may be modified by sizeAssignAfterRecursing
+                        test <- try(assert[[i + 2]] <- RHS$sizeExprs[[i]])
+                        if(inherits(test, 'try-error')) browser()
+                    }
+                    assert[[ length(assert) + 1]] <- 0 ## copyValues = false
+                    assert[[ length(assert) + 1]] <- 0 ## fillZeros  = false
+                    assert <- list(assert)
+                } else { ## We have an indexed LHS of an eigenizable expression
+                    ## need special handling if it is a row assignment like x[i,] <- ...
+                    ## also need to generate size assertions                    
+                    if(LHS$nDim == 1) {
+                        if(RHS$nDim == 2) {
+                            if(is.numeric(RHS$sizeExprs[[1]])) {
+                                if(RHS$sizeExprs[[1]] == 1) {
+                                    newExpr <- insertExprClassLayer(code, 1, 'asRow', type = LHS$type)
+                                    newExpr$sizeExprs <- RHS$sizeExprs 
+                                    newExpr$type <- LHS$type
+                                    newExpr$nDim <- RHS$nDim
+                                    if(!is.numeric(LHS$sizeExprs[[1]]) | !is.numeric(RHS$sizeExprs[[2]])) {
+                                        assertMessage <- paste0("Run-time size error: expected ", deparse(LHS$sizeExprs[[1]]), " == ", deparse(RHS$sizeExprs[[2]]))
+                                        thisAssert <- identityAssert(LHS$sizeExprs[[1]], RHS$sizeExprs[[2]], assertMessage)
+                                        if(!is.null(thisAssert)) assert[[length(assert) + 1]] <- thisAssert 
+                                    } else {
+                                        if(LHS$sizeExprs[[1]] != RHS$sizeExprs[[2]]) stop(exprClassProcessingErrorMsg(code, paste0('In sizeAssignAfterRecursing: Fixed size mismatch.')), call. = FALSE)
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        if(inherits(RHS, 'exprClass')) {
+            ## If we have A <- map(B, ...), we need to generate a setMap for the RHS, which will be done by sizeInsertIntermediate 
+            if(RHS$name == 'map') assert <- c(assert, toEigenInsertIntermediate(code, 2, symTab, typeEnv) )
+        }
+        if(inherits(LHS, 'exprClass')) {
+                                        # ditto
+            if(LHS$name == 'map') assert <- c(assert, toEigenInsertIntermediate(code, 1, symTab, typeEnv) )
+        }
+    }
+    assert
+    
+}
+        
 toEigenConcatenate <- function(code, symTab, typeEnv) {
     code$toEigenize <- 'yes'
     return(list())
@@ -244,11 +361,6 @@ toEigenFor <- function(code, symTab, typeEnv) {
     return(list())
 }
 
-toEigenAssign <- function(code, symTab, typeEnv) {
-    message('setting toEigenize for toEigenAssign must be handled')
-    return(list())
-}
-
 toEigenIgnoreForNow <- function(code, symTab, typeEnv) {
     message('Can not set toEigenize: to ignore for now')
     return(list())
diff --git a/packages/nimble/inst/tests/test-refactorCompilationSteps.R b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
index 18cb18e2c..8f75bfd19 100644
--- a/packages/nimble/inst/tests/test-refactorCompilationSteps.R
+++ b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
@@ -11,9 +11,9 @@ compareOldAndNewCompilationRC <- function(input) {
     require(testthat)
     foo <- nimbleFunction(run = run, name = 'foo')
     nimbleOptions(useRefactoredSizeProcessing = FALSE)
-    testProject <- nimble:::nimbleProjectClass(name = 'test')
-    ## management of compilation through the control list is crude and leads to error
-    ## but the project does contain the result, so we can run this, catch the error
+    testProject <- nimble:::nimbleProjectClass(name = 'original')
+    ## management of compilation through the control list is crude and leads to error we don't care about
+    ## but the project does contain the result, so we can run this, catch the error to keep running
     ## and extract the result from the project
     old <- try(compileNimble(foo, project = testProject, control = list(writeFiles = TRUE, compileCpp = FALSE, loadSO = FALSE)))
     filename <- testProject$RCfunInfos[['foo']][['cppClass']]$filename
@@ -22,7 +22,7 @@ compareOldAndNewCompilationRC <- function(input) {
     oldFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
     
     nimbleOptions(useRefactoredSizeProcessing = TRUE)
-    testProject <- nimble:::nimbleProjectClass(name = 'test')
+    testProject <- nimble:::nimbleProjectClass(name = 'refactored')
     new <- try(compileNimble(foo, project = testProject, control = list(writeFiles = TRUE, compileCpp = FALSE, loadSO = FALSE)))
     filename <- testProject$RCfunInfos[['foo']][['cppClass']]$filename
     ## we could regenerate it, but might as well read it from the file
diff --git a/packages/nimble/inst/tests/test_utils.R b/packages/nimble/inst/tests/test_utils.R
index 05f64739b..efbb500a5 100644
--- a/packages/nimble/inst/tests/test_utils.R
+++ b/packages/nimble/inst/tests/test_utils.R
@@ -897,3 +897,15 @@ compareFilesByLine <- function(trialResults, correctResults, main = "") {
     }, 1:linesToTest, trialResults, correctResults)
     invisible(NULL)
 }
+
+compareFilesUsingDiff <- function(trialFile, correctFile, main = "") {
+    test_that(paste0(main, ': same number of output lines'),
+          expect_equal(length(trialResults), length(correctResults)))
+    
+    linesToTest <- min(length(trialResults), length(correctResults))
+    mapply(function(lineno, trialLine, correctLine) {
+        test_that(paste0(main, ": output line #", lineno),
+                  expect_identical(trialLine, correctLine))
+    }, 1:linesToTest, trialResults, correctResults)
+    invisible(NULL)
+}
diff --git a/run_tests.R b/run_tests.R
index c42722e88..ad1f9edfb 100755
--- a/run_tests.R
+++ b/run_tests.R
@@ -2,7 +2,7 @@
 # This script runs most tests in nimble/inst/tests/ prioritized by duration.
 
 # Avoid running these blacklisted tests, since they take too long.
-blacklist <- c('test-Math2.R', 'test-Mcmc2.R', 'test-Mcmc3.R', 'test-Filtering2.R')
+blacklist <- c('test-Math2.R', 'test-Mcmc2.R', 'test-Mcmc3.R', 'test-Filtering2.R', 'test-refactorSizeProcessing.R')
 if(Sys.getenv('SKIP_EXPENSIVE_TESTS') == 'TRUE') {
     blacklist <- c(blacklist, 'test-mcmc.R', 'test-numericTypes.R')
 }

From b8f6b655d6d663931dd8306814420536fe9c0539 Mon Sep 17 00:00:00 2001
From: perrydv <perry@Perrys-iMac.local>
Date: Thu, 8 Jun 2017 16:48:32 -0700
Subject: [PATCH 3/6] fixing up code comparison test system

---
 packages/nimble/R/all_utils.R                 | 39 ++++++++++++-------
 .../tests/test-refactorCompilationSteps.R     | 28 ++++++++-----
 packages/nimble/inst/tests/test_utils.R       | 13 +++----
 3 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/packages/nimble/R/all_utils.R b/packages/nimble/R/all_utils.R
index 82dac2e1a..82bf3dac8 100644
--- a/packages/nimble/R/all_utils.R
+++ b/packages/nimble/R/all_utils.R
@@ -2,20 +2,33 @@
 
 double <- function(ndim, dims) {}
 
-labelFunctionCreator <- function(lead, start = 1) {
-  nextIndex <- start
-  force(lead)
-  labelGenerator <- function(reset = FALSE, count = 1, envName = "") {
-    if(reset) {
-      nextIndex <<- 1
-      return(invisible(NULL))
+labelFunctionCreator <- function() {
+    allLabelFunctionCreators <- list()
+
+    creatorFun <- function(lead, start = 1) {
+        nextIndex <- start
+        force(lead)
+        labelGenerator <- function(reset = FALSE, count = 1, envName = "") {
+            if(reset) {
+                nextIndex <<- 1
+                return(invisible(NULL))
+            }
+            lead <- paste(lead, envName , sep = '_')
+            ans <- paste0(lead, nextIndex - 1 + (1:count))
+            nextIndex <<- nextIndex + count
+            ans
+        }
+        allLabelFunctionCreators[[ length(allLabelFunctionCreators) ]] <<- labelGenerator
+        labelGenerator
+    }
+    creatorFun
+}()
+
+resetLabelFunctionCreators <- function() {
+    allLabelFunctionCreators <- environment(labelFunctionCreator)$allLabelFunctionCreators
+    for(i in allLabelFunctionCreators) {
+        environment(i)$nextIndex <- 1
     }
-    lead <- paste(lead, envName , sep = '_')
-    ans <- paste0(lead, nextIndex - 1 + (1:count))
-    nextIndex <<- nextIndex + count
-    ans
-  }
-  labelGenerator
 }
 
 nimbleUniqueID <- labelFunctionCreator("UID")
diff --git a/packages/nimble/inst/tests/test-refactorCompilationSteps.R b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
index 8f75bfd19..31031f9bf 100644
--- a/packages/nimble/inst/tests/test-refactorCompilationSteps.R
+++ b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
@@ -1,4 +1,4 @@
-require(testthat)
+source(system.file(file.path('tests', 'test_utils.R'), package = 'nimble'))
 
 context("Testing of old vs. new generated C++ during refactoring steps")
 
@@ -11,25 +11,35 @@ compareOldAndNewCompilationRC <- function(input) {
     require(testthat)
     foo <- nimbleFunction(run = run, name = 'foo')
     nimbleOptions(useRefactoredSizeProcessing = FALSE)
-    testProject <- nimble:::nimbleProjectClass(name = 'original')
+    testProject <- nimble:::nimbleProjectClass(name = 'for_comparison')
     ## management of compilation through the control list is crude and leads to error we don't care about
     ## but the project does contain the result, so we can run this, catch the error to keep running
     ## and extract the result from the project
     old <- try(compileNimble(foo, project = testProject, control = list(writeFiles = TRUE, compileCpp = FALSE, loadSO = FALSE)))
     filename <- testProject$RCfunInfos[['foo']][['cppClass']]$filename
+    newfilename <- paste0(filename,'_original')
+    pathedfilename <- file.path(tempdir(), 'nimble_generatedCode', filename)
+    original_pathedfilename <- file.path(tempdir(), 'nimble_generatedCode', newfilename)
+    for(ext in c('.h', '.cpp')) file.copy(paste0(pathedfilename, ext), paste0(original_pathedfilename, ext))
     ## we could regenerate it, but might as well read it from the file
-    oldFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
-    oldFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
+   ## oldFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
+   ## oldFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
     
     nimbleOptions(useRefactoredSizeProcessing = TRUE)
-    testProject <- nimble:::nimbleProjectClass(name = 'refactored')
+    testProject <- nimble:::nimbleProjectClass(name = 'for_comparison')
     new <- try(compileNimble(foo, project = testProject, control = list(writeFiles = TRUE, compileCpp = FALSE, loadSO = FALSE)))
     filename <- testProject$RCfunInfos[['foo']][['cppClass']]$filename
     ## we could regenerate it, but might as well read it from the file
-    newFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
-    newFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
-    test_that(paste0(name,': .cpp matches'), expect_identical(oldFooCppOutput, newFooCppOutput))
-    test_that(paste0(name,': .h matches'), expect_identical(oldFooHOutput, newFooHOutput))
+    refactored_pathedfilename <- file.path(tempdir(), 'nimble_generatedCode', filename)
+
+    for(ext in c('.h','.cpp'))
+        compareFilesUsingDiff(paste0(refactored_pathedfilename, ext), paste0(original_pathedfilename, ext),
+                              main = paste0(ext, ' files do not match for: ', name))
+    
+    ## newFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
+    ## newFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
+    ## test_that(paste0(name,': .cpp matches'), expect_identical(oldFooCppOutput, newFooCppOutput))
+    ## test_that(paste0(name,': .h matches'), expect_identical(oldFooHOutput, newFooHOutput))
 }
 
 testCases <- list(
diff --git a/packages/nimble/inst/tests/test_utils.R b/packages/nimble/inst/tests/test_utils.R
index efbb500a5..80e139c03 100644
--- a/packages/nimble/inst/tests/test_utils.R
+++ b/packages/nimble/inst/tests/test_utils.R
@@ -899,13 +899,10 @@ compareFilesByLine <- function(trialResults, correctResults, main = "") {
 }
 
 compareFilesUsingDiff <- function(trialFile, correctFile, main = "") {
-    test_that(paste0(main, ': same number of output lines'),
-          expect_equal(length(trialResults), length(correctResults)))
-    
-    linesToTest <- min(length(trialResults), length(correctResults))
-    mapply(function(lineno, trialLine, correctLine) {
-        test_that(paste0(main, ": output line #", lineno),
-                  expect_identical(trialLine, correctLine))
-    }, 1:linesToTest, trialResults, correctResults)
+    if(main == "") main <- paste0(trialFile, ' and ', correctFile, ' do not match\n')
+    diffOutput <- system2('diff', c(trialFile, correctFile), stdout = TRUE)
+    test_that(paste0(main, paste0(diffOutput, collapse = '\n')),
+              expect_true(length(diffOutput) == 0)
+              )
     invisible(NULL)
 }

From c0402e53638d60d9dd816671d2c88a8ad5a403b4 Mon Sep 17 00:00:00 2001
From: perrydv <pdevalpine@berkeley.edu>
Date: Fri, 9 Jun 2017 07:17:33 -0700
Subject: [PATCH 4/6] basicMathTests produce identical C++

---
 packages/nimble/R/RCfunction_compile.R        |   1 -
 packages/nimble/R/genCpp_exprClass.R          |   9 +-
 packages/nimble/R/genCpp_sizeProcessing.R     |  94 +++++----
 packages/nimble/R/genCpp_toEigenize.R         |  99 ++++++++-
 packages/nimble/inst/tests/mathTestLists.R    | 197 ++++++++++++++++++
 packages/nimble/inst/tests/test-math.R        | 193 +----------------
 .../tests/test-refactorCompilationSteps.R     |  26 ++-
 7 files changed, 361 insertions(+), 258 deletions(-)
 create mode 100644 packages/nimble/inst/tests/mathTestLists.R

diff --git a/packages/nimble/R/RCfunction_compile.R b/packages/nimble/R/RCfunction_compile.R
index 90f8d566a..b1d416034 100644
--- a/packages/nimble/R/RCfunction_compile.R
+++ b/packages/nimble/R/RCfunction_compile.R
@@ -266,7 +266,6 @@ RCfunProcessing <- setRefClass('RCfunProcessing',
                                        }
 
                                        if(nimbleOptions('useRefactoredSizeProcessing')) {
-                                           browser()
                                            exprClasses_setToEigenize(compileInfo$nimExpr, compileInfo$newLocalSymTab, compileInfo$typeEnv)
                                        }
 
diff --git a/packages/nimble/R/genCpp_exprClass.R b/packages/nimble/R/genCpp_exprClass.R
index 6ef83d80d..14990692a 100644
--- a/packages/nimble/R/genCpp_exprClass.R
+++ b/packages/nimble/R/genCpp_exprClass.R
@@ -25,15 +25,8 @@ exprClass <- setRefClass('exprClass',
                              caller = 'ANY',            # exprClass object for the call to which this is an argument (if any)
                              callerArgID =  'ANY',	#'numeric', ## index in the calling object's args list for this object.
                              assertions =  'ANY',	#'list'
-                             
-                             eigMatrix =  'ANY',		#'logical', ## vs. Array.  Only used for Eigenized expressions
-                             toEigenize =  'ANY',		#'character', ##'yes', 'no', or 'maybe'
-                             caller = 'ANY', ## exprClass object for the call to which this is an argument (if any)
-                             callerArgID =  'ANY',		#'numeric', ## index in the calling object's args list for this object.
-                             assertions =  'ANY',		#'list'
-                             cppADCode = 'ANY',    #'logical ## is expr in code generated for cppad?
+                             cppADCode = 'ANY',         #'logical' ## is expr in code generated for cppad?
                              aux = 'ANY'                # anything needed for specific operators
-
                              ),
                          methods = list(
                              initialize = function(...) {sizeExprs <<- list(); args <<- list();toEigenize <<- 'unknown';assertions <<- list(); eigMatrix <<- logical(); cppADCode <<- FALSE; callSuper(...)},
diff --git a/packages/nimble/R/genCpp_sizeProcessing.R b/packages/nimble/R/genCpp_sizeProcessing.R
index 5b4a4f48a..30379a88f 100644
--- a/packages/nimble/R/genCpp_sizeProcessing.R
+++ b/packages/nimble/R/genCpp_sizeProcessing.R
@@ -2409,9 +2409,11 @@ sizeUnaryCwise <- function(code, symTab, typeEnv) {
     ## lift intermediates
     a1 <- code$args[[1]]
     if(inherits(a1, 'exprClass')) {
-        if(a1$toEigenize == 'no') {
-            asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
-            a1 <- code$args[[1]]
+        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+            if(a1$toEigenize == 'no') {
+                asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
+                a1 <- code$args[[1]]
+            }
         }
         code$nDim <- a1$nDim
         code$sizeExprs <- a1$sizeExprs
@@ -2421,7 +2423,7 @@ sizeUnaryCwise <- function(code, symTab, typeEnv) {
     }
     code$type <- setReturnType(code$name, getArgumentType(a1))
     if(length(code$nDim) != 1) stop(exprClassProcessingErrorMsg(code, 'In sizeUnaryCwise: nDim is not set.'), call. = FALSE)
-    code$toEigenize <- if(code$nDim > 0) 'yes' else 'maybe'
+    if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- if(code$nDim > 0) 'yes' else 'maybe'
     return(asserts)
 }
 
@@ -2538,9 +2540,11 @@ sizeUnaryReduction <- function(code, symTab, typeEnv) {
                 stop(exprClassProcessingErrorMsg(code, 'NIMBLE compiler does not support var with a matrix (or higher dimensional) argument.'), call. = FALSE) 
             }
         }
-        if(!code$args[[1]]$isName) {
-            if(code$args[[1]]$toEigenize == 'no') {
-                asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
+        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+            if(!code$args[[1]]$isName) {
+                if(code$args[[1]]$toEigenize == 'no') {
+                    asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
+                }
             }
         }
     }
@@ -2548,10 +2552,12 @@ sizeUnaryReduction <- function(code, symTab, typeEnv) {
     code$nDim <- 0
     code$sizeExprs <- list()
     code$type <- setReturnType(code$name, code$args[[1]]$type)
-    code$toEigenize <- 'yes'
+    if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
 
-    if(!(code$caller$name %in% c('{','<-','<<-','='))) {
-        asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
+    if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+        if(!(code$caller$name %in% c('{','<-','<<-','='))) {
+            asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
+        }
     }
 
     if(length(asserts) == 0) NULL else asserts
@@ -2620,14 +2626,15 @@ sizeMatrixMult <- function(code, symTab, typeEnv) {
     a2 <- code$args[[2]]
     
     if(a1$nDim == 0 | a2$nDim == 0) stop(exprClassProcessingErrorMsg(code, 'In sizeMatrixMult: Cannot do matrix multiplication with a scalar.'), call. = FALSE) 
-
-    if(a1$toEigenize == 'no') {
-        asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
-        a1 <- code$args[[1]]
-    }
-    if(a2$toEigenize == 'no') {
-        asserts <- c(asserts, sizeInsertIntermediate(code, 2, symTab, typeEnv))
-        a2 <- code$args[[2]]
+    if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+        if(a1$toEigenize == 'no') {
+            asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
+            a1 <- code$args[[1]]
+        }
+        if(a2$toEigenize == 'no') {
+            asserts <- c(asserts, sizeInsertIntermediate(code, 2, symTab, typeEnv))
+            a2 <- code$args[[2]]
+        }
     }
     
     ## Note that we could insert RUN-TIME adaptation of mat %*% vec and vec %*% mat
@@ -2672,7 +2679,7 @@ sizeMatrixMult <- function(code, symTab, typeEnv) {
     code$nDim <- 2
     code$sizeExprs <- list(a1$sizeExprs[[1]], a2$sizeExprs[[2]])
     code$type <- setReturnType(code$name, arithmeticOutputType(a1$type, a2$type))
-    code$toEigenize <- 'yes'
+    if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
     assertMessage <- paste0("Run-time size error: expected ", deparse(a1$sizeExprs[[2]]), " == ", deparse(a2$sizeExprs[[1]]))
     newAssert <- identityAssert(a1$sizeExprs[[2]], a2$sizeExprs[[1]], assertMessage)
     if(is.null(newAssert))
@@ -2783,40 +2790,44 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
     a2 <- code$args[[2]]
     ## pull out aXDropNdim, aXnDim, aXsizeExprs, and aXtype (X = 1 or 2)
     if(inherits(a1, 'exprClass')) {
-        if(a1$toEigenize == 'no') {
-            asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
-            a1 <- code$args[[1]]
+        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+            if(a1$toEigenize == 'no') {
+                asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
+                a1 <- code$args[[1]]
+            }
         }
         a1Drop <- dropSingleSizes(a1$sizeExprs)
         a1DropNdim <- length(a1Drop$sizeExprs)
         a1nDim <- a1$nDim
         a1sizeExprs <- a1$sizeExprs
         a1type <- a1$type
-        a1toEigenize <- a1$toEigenize
+        if(!nimbleOptions('useRefactoredSizeProcessing') ) a1toEigenize <- a1$toEigenize
     } else {
         a1DropNdim <- 0
         a1nDim <- 0
         a1sizeExprs <- list()
         a1type <- storage.mode(a1)
-        a1toEigenize <- 'maybe'
+        if(!nimbleOptions('useRefactoredSizeProcessing') ) a1toEigenize <- 'maybe'
     }
     if(inherits(a2, 'exprClass')) {
-        if(a2$toEigenize == 'no') {
-            asserts <- c(asserts, sizeInsertIntermediate(code, 2, symTab, typeEnv))
-            a2 <- code$args[[2]]
+        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+            if(a2$toEigenize == 'no') {
+                asserts <- c(asserts, sizeInsertIntermediate(code, 2, symTab, typeEnv))
+                a2 <- code$args[[2]]
+            }
         }
         a2Drop <- dropSingleSizes(a2$sizeExprs)
         a2DropNdim <- length(a2Drop$sizeExprs)
         a2nDim <- a2$nDim
         a2sizeExprs <- a2$sizeExprs
         a2type <- a2$type
-        a2toEigenize <- a2$toEigenize
+        if(!nimbleOptions('useRefactoredSizeProcessing') )  a2toEigenize <- a2$toEigenize
     } else {
         a2DropNdim <- 0
         a2nDim <- 0
         a2sizeExprs <- list()
         a2type <- storage.mode(a2)
-        a2toEigenize <- 'maybe'
+        if(!nimbleOptions('useRefactoredSizeProcessing') )  a2toEigenize <- 'maybe'
     }
     
     ## Choose the output type by type promotion
@@ -2824,15 +2835,18 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
     if(length(a2type) == 0) {warning('Problem with type of arg2 in sizeBinaryCwise', call. = FALSE); browser()}
     code$type <- setReturnType(code$name, arithmeticOutputType(a1type, a2type))
 
-    forceYesEigenize <- identical(a1toEigenize, 'yes') | identical(a2toEigenize, 'yes')
-    code$toEigenize <- if(a1DropNdim == 0 & a2DropNdim == 0)
-                           if(forceYesEigenize)
-                               'yes'
-                           else
-                               'maybe'
-                       else 'yes'
-     
+    if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+        forceYesEigenize <- identical(a1toEigenize, 'yes') | identical(a2toEigenize, 'yes')
+        code$toEigenize <- if(a1DropNdim == 0 & a2DropNdim == 0)
+                               if(forceYesEigenize)
+                                   'yes'
+                               else
+                                   'maybe'
+                           else 'yes'
+    }
+    
     ## Catch the case that there is at least one scalar-equivalent (all lengths == 1)
+    ## The 3 'code$toEigenize <- ' should be redundant with above and could be removed during refactor
     if(a1DropNdim == 0 | a2DropNdim == 0) { 
         ## Here we will process effective scalar additions
         ## and not do any other type of size promotion/dropping
@@ -2840,17 +2854,17 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
             if(a2DropNdim == 0) { ##both are scalar-equiv
                 code$nDim <- max(a1nDim, a2nDim) ## use the larger nDims
                 code$sizeExprs <- rep(list(1), code$nDim) ## set sizeExprs to all 1
-                code$toEigenize <- if(forceYesEigenize) 'yes' else 'maybe'
+                if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- if(forceYesEigenize) 'yes' else 'maybe'
             } else {
                 ## a2 is not scalar equiv, so take nDim and sizeExprs from it
                 code$nDim <- a2nDim
                 code$sizeExprs <- a2sizeExprs
-                code$toEigenize <- 'yes'
+                if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
             }
         } else { ## a2 is scalar-equiv, and a1 is not
             code$nDim <- a1nDim
             code$sizeExprs <- a1sizeExprs
-            code$toEigenize <- 'yes'
+            if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
         }
         return(if(length(asserts) == 0) NULL else asserts)
     }
diff --git a/packages/nimble/R/genCpp_toEigenize.R b/packages/nimble/R/genCpp_toEigenize.R
index fb19a35f3..344a505d4 100644
--- a/packages/nimble/R/genCpp_toEigenize.R
+++ b/packages/nimble/R/genCpp_toEigenize.R
@@ -25,16 +25,16 @@ toEigenizeMaybeCalls <- c('map',
 
 toEigenizeUseRuleCalls <- c('nimPrint')
 
-toEigenCalls <- c(makeCallList(binaryOperators, 'toEigenBinaryCwise'),
+toEigenCalls <- c(makeCallList(binaryOperators, 'toEigenBinaryCwise'),             #ok
                   makeCallList(binaryMidLogicalOperators, 'sizeBinaryCwiseLogical'),
-                  makeCallList(binaryOrUnaryOperators, 'toEigenBinaryUnaryCwise'),
-                  makeCallList(unaryOperators, 'toEigenUnaryCwise'), 
+                  makeCallList(binaryOrUnaryOperators, 'toEigenBinaryUnaryCwise'), #ok
+                  makeCallList(unaryOperators, 'toEigenUnaryCwise'),               #ok
                   makeCallList(unaryOrNonaryOperators, 'sizeUnaryNonaryCwise'),
-                  makeCallList(assignmentOperators, 'toEigenAssign'), 
-                  makeCallList(reductionUnaryOperators, 'sizeUnaryReduction'), 
+                  makeCallList(assignmentOperators, 'toEigenAssign'),              #ok
+                  makeCallList(reductionUnaryOperators, 'sizeUnaryReduction'),     # drafted
                   makeCallList(matrixSquareReductionOperators, 'sizeMatrixSquareReduction'),
                   makeCallList(reductionBinaryOperators, 'sizeBinaryReduction'),
-                  makeCallList(matrixMultOperators, 'sizeMatrixMult'), 
+                  makeCallList(matrixMultOperators, 'toEigenMatrixMult'),          # drafted
                   makeCallList(matrixFlipOperators, 'sizeTranspose'),
                   makeCallList(matrixSolveOperators, 'sizeSolveOp'), 
                   makeCallList(matrixSquareOperators, 'sizeUnaryCwiseSquare'),
@@ -383,7 +383,90 @@ toEigenBinaryUnaryCwise <- function(code, symTab, typeEnv) {
 }
 
 toEigenBinaryCwise <- function(code, symTab, typeEnv) {
-    message('setting toEigenize for toEigenBinaryCwise must be handled')
-    return(list())
+    asserts <- recurseSetToEigenize(code, symTab, typeEnv)
+    a1 <- code$args[[1]] 
+    a2 <- code$args[[2]]
+    if(inherits(a1, 'exprClass')) {
+        if(a1$toEigenize == 'no') {
+            asserts <- c(asserts, toEigenInsertIntermediate(code, 1, symTab, typeEnv))
+            a1 <- code$args[[1]]
+        }
+        a1DropNdim <- length(dropSingleSizes(a1$sizeExprs)$sizeExprs)
+        a1toEigenize <- a1$toEigenize
+    } else {
+        a1DropNdim <- 0
+        a1toEigenize <- 'maybe'
+    }
+    if(inherits(a2, 'exprClass')) {
+        if(a2$toEigenize == 'no') {
+            asserts <- c(asserts, toEigenInsertIntermediate(code, 2, symTab, typeEnv))
+            a2 <- code$args[[2]]
+        }
+        a2DropNdim <- length(dropSingleSizes(a2$sizeExprs)$sizeExprs)
+        a2toEigenize <- a2$toEigenize
+    } else {
+        a2DropNdim <- 0
+        a2toEigenize <- 'maybe'
+    }
+    forceYesEigenize <- identical(a1toEigenize, 'yes') | identical(a2toEigenize, 'yes')
+    code$toEigenize <- if(a1DropNdim == 0 & a2DropNdim == 0)
+                           if(forceYesEigenize)
+                               'yes'
+                           else
+                               'maybe'
+                       else 'yes'
+    asserts
+}
+
+toEigenUnaryCwise <- function(code, symTab, typeEnv) {
+    asserts <- recurseSetSizes(code, symTab, typeEnv)
+    a1 <- code$args[[1]]
+    ## lifting rule: lift if not eigenizable
+    if(inherits(a1, 'exprClass')) {
+        if(a1$toEigenize == 'no') {
+            asserts <- c(asserts, toEigenInsertIntermediate(code, 1, symTab, typeEnv))
+            a1 <- code$args[[1]]
+        }
+    }
+    ## propagation rule: yes or maybe
+    code$toEigenize <- if(code$nDim > 0) 'yes' else 'maybe'
+    asserts
+}
+
+toEigenMatrixMult <- function(code, symTab, typeEnv) {
+    asserts <- recurseSetToEigenize(code, symTab, typeEnv)
+    a1 <- code$args[[1]]
+    a2 <- code$args[[2]]
+    ## POSSIBLE DIFFERENT BEHAVIOR:
+    ## sizeMatrixMult may insert an asRow() or asCol()
+    ## It would do so *after* sizeInsertIntermediate
+    ## But now that would happen *before* sizeInsertIntermediate
+    ## Options: (1) The new code made be just as valid.  (2) We could make toEigenInsertIntermediate be smart about asRow or asCol
+    if(a1$toEigenize == 'no') {
+        asserts <- c(asserts, toEigenInsertIntermediate(code, 1, symTab, typeEnv))
+    }
+    if(a2$toEigenize == 'no') {
+        asserts <- c(asserts, toEigenInsertIntermediate(code, 2, symTab, typeEnv))
+    }
+    code$toEigenize <- 'yes'
+    asserts
 }
 
+toEigenUnaryReduction <- function(code, symTab, typeEnv) {
+    asserts <- recurseSetToEigenize(code, symTab, typeEnv)
+    if(inherits(code$args[[1]], 'exprClass')) {
+        if(!code$args[[1]]$isName) {
+            if(code$args[[1]]$toEigenize == 'no') {
+                asserts <- c(asserts, toEigenInsertIntermediate(code, 1, symTab, typeEnv))
+            }
+        }
+    }
+
+    code$toEigenize <- 'yes'
+
+    if(!(code$caller$name %in% c('{','<-','<<-','='))) {
+        asserts <- c(asserts, toEigenInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
+    }
+    
+    if(length(asserts) == 0) NULL else asserts
+}
diff --git a/packages/nimble/inst/tests/mathTestLists.R b/packages/nimble/inst/tests/mathTestLists.R
new file mode 100644
index 000000000..51ca794ca
--- /dev/null
+++ b/packages/nimble/inst/tests/mathTestLists.R
@@ -0,0 +1,197 @@
+1### INSTRUCTIONS:
+## enter each test as a list, with an informative name, NIMBLE expression to evaluate, vector of input dimensions, value of output dimension, and (if NIMBLE expression cannot be directly evaluated in R) the equivalent pure R expression whose result should match the NIMBLE result
+
+testsVaried = list(
+  list(name = "matrix direct product", expr = quote(out <- arg1 * arg2), inputDim = c(2,2), outputDim = 2),
+  list(name = "matrix direct product with scalar addition", expr = quote(out <- (arg1+1) * (arg2+1)), inputDim = c(2,2), outputDim = 2),
+  list(name = "matrix absolute value", expr = quote(out <- abs(arg1)), inputDim = c(2), outputDim = 2),
+  list(name = "matrix absolute value with scalar addition", expr = quote(out <- abs(arg1 - 2)), inputDim = c(2), outputDim = 2),
+  list(name = "vector pmin", expr = quote(out <- pmin(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
+  list(name = "vector pmax", expr = quote(out <- pmax(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
+  list(name = "sd with addition", expr = quote(out <- sd(arg1) + 3), inputDim = c(1), outputDim = 0),
+  list(name = "sd of vector with addition", expr = quote(out <- sd(arg1 + 3)), inputDim = c(1), outputDim = 0),
+  list(name = "sd of matrix-vector multiply", expr = quote(out <- sd(arg1 %*% arg2)), inputDim = c(2,1), outputDim = 0),
+  list(name = "var of vector", expr = quote(out <- var(arg1)), inputDim = c(1), outputDim = 0),
+  list(name = "log determinant", expr = quote(out <- logdet(arg1)), inputDim = c(2), outputDim = 0)
+  )
+
+testsBasicMath = list(
+  list(name = 'exp of scalar', expr = quote(out <- exp(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'log of scalar', expr = quote(out <- log(abs(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'sqrt of scalar', expr = quote(out <- sqrt(abs(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'abs of scalar', expr = quote(out <- abs(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'step of scalar', expr = quote(out <- step(arg1)), inputDim = 0, outputDim = 0, Rcode = quote( out <- as.numeric(arg1 > 0))),
+  list(name = 'cube of scalar', expr = quote(out <- cube(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'cos of scalar', expr = quote(out <- cos(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'acos of cos of scalar', expr = quote(out <- acos(cos(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'sin of scalar', expr = quote(out <- sin(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'asin of sin of scalar', expr = quote(out <- asin(sin(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'tan of scalar', expr = quote(out <- tan(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'atan of tan of scalar', expr = quote(out <- atan(tan(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'cosh of scalar', expr = quote(out <- cosh(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'sinh of scalar', expr = quote(out <- sinh(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'tanh of scalar', expr = quote(out <- tanh(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'acosh of scalar', expr = quote(out <- acosh(1 + abs(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'asinh of scalar', expr = quote(out <- asinh(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'atanh of scalar', expr = quote(out <- atanh(abs(arg1)%%1)), inputDim = 0, outputDim = 0),
+  ###
+  list(name = 'exp of vector', expr = quote(out <- exp(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'log of vector', expr = quote(out <- log(abs(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'sqrt of vector', expr = quote(out <- sqrt(abs(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'abs of vector', expr = quote(out <- abs(arg1)), inputDim = 1, outputDim = 1),
+##  list(name = 'step of vector', expr = quote(out <- step(arg1)), inputDim = 1, outputDim = 1, Rcode = quote(out <- as.numeric(arg1 > 0))),   ## FAILS on compileNimble(nfR) with Eigen error
+  list(name = 'cube of vector', expr = quote(out <- cube(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'cos of vector', expr = quote(out <- cos(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'acos of cos of vector', expr = quote(out <- acos(cos(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'sin of vector', expr = quote(out <- sin(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'asin of sin of vector', expr = quote(out <- asin(sin(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'tan of vector', expr = quote(out <- tan(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'atan of tan of vector', expr = quote(out <- atan(tan(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'cosh of vector', expr = quote(out <- cosh(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'sinh of vector', expr = quote(out <- sinh(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'tanh of vector', expr = quote(out <- tanh(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'acosh of vector', expr = quote(out <- acosh(1 + abs(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'asinh of vector', expr = quote(out <- asinh(arg1)), inputDim = 1, outputDim = 1),
+##  list(name = 'atanh of vector', expr = quote(out <- atanh(arg1%%1)), inputDim = 1, outputDim = 1), ## FAILS - issue here is probably that modulo on vecs doesn't work but need to restrict domain for atanh
+  ###
+  list(name = 'scalar + scalar', expr = quote(out <- arg1 + arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'diff of scalars', expr = quote(out <- arg1 - arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'product of scalars', expr = quote(out <- arg1 * arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'ratio of scalars', expr = quote(out <- arg1 / arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'power of scalars via ^', expr = quote(out <- arg1 ^ arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'power of scalars via pow', expr = quote(out <- pow(arg1, arg2)), inputDim = c(0,0), outputDim = 0),
+  list(name = 'power of scalars via ^ with positive first arg', expr = quote(out <- exp(arg1) ^ arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'power of scalars via pow with positive first arg', expr = quote(out <- pow(exp(arg1), arg2)), inputDim = c(0,0), outputDim = 0),
+  list(name = 'modulo of scalars', expr = quote(out <- arg1 %% arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'min of scalars', expr = quote(out <- min(arg1, arg2)), inputDim = c(0,0), outputDim = 0),
+  list(name = 'max of scalars', expr = quote(out <- max(arg1, arg2)), inputDim = c(0,0), outputDim = 0),
+  ###
+  list(name = 'vector + vector', expr = quote(out <- arg1 + arg2), inputDim = c(1,1), outputDim = 1),
+  list(name = 'diff of vectors', expr = quote(out <- arg1 - arg2), inputDim = c(1,1), outputDim = 1),
+  list(name = 'product of vectors', expr = quote(out <- arg1 * arg2), inputDim = c(1,1), outputDim = 1),
+  list(name = 'ratio of vectors', expr = quote(out <- arg1 / arg2), inputDim = c(1,1), outputDim = 1),
+##  list(name = 'power of vectors via ^', expr = quote(out <- arg1 ^ arg2), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen casting
+  ## list(name = 'power of vectors via pow', expr = quote(out <- pow(arg1, arg2)), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen casting
+  ## list(name = 'modulo of vectors', expr = quote(out <- arg1 %% arg2), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen casting
+  list(name = 'pmin of vectors', expr = quote(out <- pmin(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
+  list(name = 'pmax of vectors', expr = quote(out <- pmax(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
+  ###
+  list(name = 'vector + scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
+  list(name = 'diff of vector and scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
+  list(name = 'product of vector and scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
+  list(name = 'ratio of vector and scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
+  list(name = 'power of vector and scalar via ^', expr = quote(out <- arg1 ^ arg2), inputDim = c(1,0), outputDim = 1),
+  list(name = 'power of vector and scalar via pow', expr = quote(out <- pow(arg1, arg2)), inputDim = c(1,0), outputDim = 1),
+  list(name = 'power of vector and constant via ^', expr = quote(out <- arg1 ^ 2), inputDim = c(1,0), outputDim = 1),
+  list(name = 'power of vector and constant via pow', expr = quote(out <- pow(arg1, 2)), inputDim = c(1,0), outputDim = 1),
+  list(name = 'power of vector and scalar via ^ with positive first arg', expr = quote(out <- exp(arg1) ^ arg2), inputDim = c(1,0), outputDim = 1),
+  list(name = 'power of vector and scalar via pow with positive first arg', expr = quote(out <- pow(exp(arg1), arg2)), inputDim = c(1,0), outputDim = 1)
+  ## list(name = 'modulo of vector and scalar', expr = quote(out <- arg1 %% arg2), inputDim = c(1,0), outputDim = 1) ## FAILS with Eigen casting
+  )
+
+testsMoreMath = list(
+  list(name = 'inverse cloglog of scalar', expr = quote(out <- icloglog(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'cloglog/inverse cloglog of scalar', expr = quote(out <- cloglog(icloglog(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'inverse logit of scalar', expr = quote(out <- ilogit(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'expit of scalar', expr = quote(out <- expit(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'logit/expit of scalar', expr = quote(out <- logit(expit(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'inverse probit of scalar', expr = quote(out <- iprobit(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'inverse probit of scalar via phi', expr = quote(out <- phi(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'probit/iprobit of scalar', expr = quote(out <- probit(iprobit(arg1))), inputDim = 0, outputDim = 0),
+  ###
+  list(name = 'ceiling of scalar', expr = quote(out <- ceiling(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'floor of scalar', expr = quote(out <- floor(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'round of scalar', expr = quote(out <- round(arg1)), inputDim = 0, outputDim = 0),
+  list(name = 'trunc of scalar', expr = quote(out <- trunc(arg1)), inputDim = 0, outputDim = 0),
+  ###
+  list(name = 'gamma of scalar', expr = quote(out <- gamma(abs(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'lgamma of scalar', expr = quote(out <- lgamma(abs(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'loggam of scalar', expr = quote(out <- loggam(abs(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'log1p of scalar', expr = quote(out <- log1p(abs(arg1))), inputDim = 0, outputDim = 0),
+  list(name = 'factorial of scalar', expr = quote(out <- factorial(ceiling(abs(arg1)))), inputDim = 0, outputDim = 0),
+  list(name = 'lfactorial of scalar', expr = quote(out <- lfactorial(ceiling(abs(arg1)))), inputDim = 0, outputDim = 0),
+  ###
+  list(name = 'inverse cloglog of vector', expr = quote(out <- icloglog(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'cloglog/inverse cloglog of vector', expr = quote(out <- cloglog(icloglog(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'inverse logit of vector', expr = quote(out <- ilogit(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'expit of vector', expr = quote(out <- expit(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'logit/expit of vector', expr = quote(out <- logit(expit(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'inverse probit of vector', expr = quote(out <- iprobit(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'inverse probit of vector via phi', expr = quote(out <- phi(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'probit/iprobit of vector', expr = quote(out <- probit(iprobit(arg1))), inputDim = 1, outputDim = 1),
+  ###
+  list(name = 'ceiling of vector', expr = quote(out <- ceiling(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'floor of vector', expr = quote(out <- floor(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'round of vector', expr = quote(out <- round(arg1)), inputDim = 1, outputDim = 1),
+  list(name = 'trunc of vector', expr = quote(out <- trunc(arg1)), inputDim = 1, outputDim = 1),
+  ###
+  list(name = 'gamma of vector', expr = quote(out <- gamma(abs(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'lgamma of vector', expr = quote(out <- lgamma(abs(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'loggam of vector', expr = quote(out <- loggam(abs(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'log1p of vector', expr = quote(out <- log1p(abs(arg1))), inputDim = 1, outputDim = 1),
+  list(name = 'factorial of vector', expr = quote(out <- factorial(ceiling(abs(arg1)))), inputDim = 1, outputDim = 1),
+  list(name = 'lfactorial of vector', expr = quote(out <- lfactorial(ceiling(abs(arg1)))), inputDim = 1, outputDim = 1)
+  )
+
+testsReduction = list(
+  ### vector
+  list(name = 'min of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
+  list(name = 'max of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
+  list(name = 'sum of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
+  list(name = 'mean of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
+  list(name = 'sd of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
+  list(name = 'var of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
+  list(name = 'prod of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
+  ## list(name = 'norm of vector', expr = quote(out <- norm(arg1)), inputDim = 1, outputDim = 0),  ## norm doesn't work on vector in R
+  ### matrix
+  list(name = 'min of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
+  list(name = 'max of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
+  list(name = 'sum of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
+  list(name = 'mean of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
+##  list(name = 'sd of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
+  list(name = 'var of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
+  list(name = 'prod of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0)
+##  list(name = 'norm of matrix', expr = quote(out <- norm(arg1)), inputDim = 2, outputDim = 0, Rcode = quote(out <- norm(arg1, "F"))) ## NIMBLE's C norm is apparently Frobenius, so R and C nimble functions differ => FAILS
+  )
+
+testsComparison = list(
+  ## scalar
+  list(name = 'greater than, scalar', expr = quote(out <- arg1 > arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'equals, scalar', expr = quote(out <- arg1 == arg2), inputDim = c(0,0), outputDim = 0),
+  list(name = 'not equals, scalar', expr = quote(out <- arg1 != arg2), inputDim = c(0,0), outputDim = 0),
+  ## vector
+  ## list(name = 'greater than, vector', expr = quote(out <- arg1 > arg2), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen issue
+  ## list(name = 'equals, vector', expr = quote(out <- arg1 == arg2), inputDim = c(1,1), outputDim = 1),  ## FAILS with Eigen issue
+  ## list(name = 'not equals, vector', expr = quote(out <- arg1 != arg2), inputDim = c(1,1), outputDim = 1),  ## FAILS with Eigen issue
+  ## logical
+  list(name = 'and operator, scalar', expr = quote(out <- arg1 & arg2), inputDim = c(0,0), outputDim = 0, logicalArgs = c(TRUE, TRUE)),
+  list(name = 'or operator, scalar', expr = quote(out <- arg1 | arg2), inputDim = c(0,0), outputDim = 0, logicalArgs = c(TRUE, TRUE)),
+  list(name = 'not operator, scalar', expr = quote(out <- !arg1), inputDim = c(0), outputDim = 0, logicalArgs = c(TRUE))
+)
+
+
+testsMatrix = list(
+    list(name = 'forwardsolve matrix-vector', expr = quote(out <- forwardsolve(arg1, arg2)), inputDim = c(2, 1), outputDim = 1),
+    list(name = 'forwardsolve matrix-matrix', expr = quote(out <- forwardsolve(arg1, arg2)), inputDim = c(2, 2), outputDim = 2),
+    list(name = 'backsolve matrix-vector', expr = quote(out <- backsolve(arg1, arg2)), inputDim = c(2, 1), outputDim = 1),
+    list(name = 'backsolve matrix-matrix', expr = quote(out <- backsolve(arg1, arg2)), inputDim = c(2, 2), outputDim = 2),
+
+    list(name = 'forwardsolve matrix-vector with indices', expr = quote(out <- forwardsolve(arg1[1:2,1:2], arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
+    list(name = 'forwardsolve matrix-matrix with indices', expr = quote(out <- forwardsolve(arg1[1:2,1:2], arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
+    list(name = 'backsolve matrix-vector with indices', expr = quote(out <- backsolve(arg1[1:2,1:2], arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
+    list(name = 'backsolve matrix-matrix with indices', expr = quote(out <- backsolve(arg1[1:2,1:2], arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
+
+    list(name = 'forwardsolve matrix-vector amid expr', expr = quote(out <- arg2[1:2] + forwardsolve(arg1[1:2,1:2], arg2[1:2] + arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
+    list(name = 'forwardsolve matrix-matrix amid expr', expr = quote(out <- arg2[1:2,1:2] + forwardsolve(arg1[1:2,1:2], arg2[1:2,1:2] + arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
+    list(name = 'backsolve matrix-vector amid expr', expr = quote(out <- arg2[1:2] + backsolve(arg1[1:2,1:2], arg2[1:2] + arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
+    list(name = 'backsolve matrix-matrix amid expr', expr = quote(out <- arg2[1:2,1:2] + backsolve(arg1[1:2,1:2], arg2[1:2,1:2] + arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
+
+    list(name = 'chol', expr = quote({ A <- arg1; for(i in 1:dim(A)[1]) A[i,i] <- A[i,i] + 10; out <- chol(A) }), inputDim = c(2), outputDim = 2),
+    list(name = 'matrix-vector multiply', expr = quote(out <- arg1 %*% arg2), inputDim = c(2, 1), outputDim = 2),
+    list(name = 'vector-matrix multiply', expr = quote(out <- t(arg1) %*% arg2), inputDim = c(1, 2), outputDim = 2),
+    list(name = 'matrix-matrix multiply', expr = quote(out <- arg1 %*% arg2), inputDim = c(2, 2), outputDim = 2)
+)
+
+
+
+
diff --git a/packages/nimble/inst/tests/test-math.R b/packages/nimble/inst/tests/test-math.R
index 13f9036cf..9541252e9 100644
--- a/packages/nimble/inst/tests/test-math.R
+++ b/packages/nimble/inst/tests/test-math.R
@@ -1,201 +1,12 @@
 ### INSTRUCTIONS:
+## got to mathTestLists.R:
 ## enter each test as a list, with an informative name, NIMBLE expression to evaluate, vector of input dimensions, value of output dimension, and (if NIMBLE expression cannot be directly evaluated in R) the equivalent pure R expression whose result should match the NIMBLE result
 
 source(system.file(file.path('tests', 'test_utils.R'), package = 'nimble'))
 
 context("Testing of math functions in NIMBLE code")
 
-testsVaried = list(
-  list(name = "matrix direct product", expr = quote(out <- arg1 * arg2), inputDim = c(2,2), outputDim = 2),
-  list(name = "matrix direct product with scalar addition", expr = quote(out <- (arg1+1) * (arg2+1)), inputDim = c(2,2), outputDim = 2),
-  list(name = "matrix absolute value", expr = quote(out <- abs(arg1)), inputDim = c(2), outputDim = 2),
-  list(name = "matrix absolute value with scalar addition", expr = quote(out <- abs(arg1 - 2)), inputDim = c(2), outputDim = 2),
-  list(name = "vector pmin", expr = quote(out <- pmin(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
-  list(name = "vector pmax", expr = quote(out <- pmax(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
-  list(name = "sd with addition", expr = quote(out <- sd(arg1) + 3), inputDim = c(1), outputDim = 0),
-  list(name = "sd of vector with addition", expr = quote(out <- sd(arg1 + 3)), inputDim = c(1), outputDim = 0),
-  list(name = "sd of matrix-vector multiply", expr = quote(out <- sd(arg1 %*% arg2)), inputDim = c(2,1), outputDim = 0),
-  list(name = "var of vector", expr = quote(out <- var(arg1)), inputDim = c(1), outputDim = 0),
-  list(name = "log determinant", expr = quote(out <- logdet(arg1)), inputDim = c(2), outputDim = 0)
-  )
-
-testsBasicMath = list(
-  list(name = 'exp of scalar', expr = quote(out <- exp(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'log of scalar', expr = quote(out <- log(abs(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'sqrt of scalar', expr = quote(out <- sqrt(abs(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'abs of scalar', expr = quote(out <- abs(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'step of scalar', expr = quote(out <- step(arg1)), inputDim = 0, outputDim = 0, Rcode = quote( out <- as.numeric(arg1 > 0))),
-  list(name = 'cube of scalar', expr = quote(out <- cube(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'cos of scalar', expr = quote(out <- cos(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'acos of cos of scalar', expr = quote(out <- acos(cos(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'sin of scalar', expr = quote(out <- sin(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'asin of sin of scalar', expr = quote(out <- asin(sin(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'tan of scalar', expr = quote(out <- tan(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'atan of tan of scalar', expr = quote(out <- atan(tan(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'cosh of scalar', expr = quote(out <- cosh(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'sinh of scalar', expr = quote(out <- sinh(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'tanh of scalar', expr = quote(out <- tanh(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'acosh of scalar', expr = quote(out <- acosh(1 + abs(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'asinh of scalar', expr = quote(out <- asinh(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'atanh of scalar', expr = quote(out <- atanh(abs(arg1)%%1)), inputDim = 0, outputDim = 0),
-  ###
-  list(name = 'exp of vector', expr = quote(out <- exp(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'log of vector', expr = quote(out <- log(abs(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'sqrt of vector', expr = quote(out <- sqrt(abs(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'abs of vector', expr = quote(out <- abs(arg1)), inputDim = 1, outputDim = 1),
-##  list(name = 'step of vector', expr = quote(out <- step(arg1)), inputDim = 1, outputDim = 1, Rcode = quote(out <- as.numeric(arg1 > 0))),   ## FAILS on compileNimble(nfR) with Eigen error
-  list(name = 'cube of vector', expr = quote(out <- cube(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'cos of vector', expr = quote(out <- cos(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'acos of cos of vector', expr = quote(out <- acos(cos(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'sin of vector', expr = quote(out <- sin(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'asin of sin of vector', expr = quote(out <- asin(sin(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'tan of vector', expr = quote(out <- tan(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'atan of tan of vector', expr = quote(out <- atan(tan(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'cosh of vector', expr = quote(out <- cosh(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'sinh of vector', expr = quote(out <- sinh(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'tanh of vector', expr = quote(out <- tanh(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'acosh of vector', expr = quote(out <- acosh(1 + abs(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'asinh of vector', expr = quote(out <- asinh(arg1)), inputDim = 1, outputDim = 1),
-##  list(name = 'atanh of vector', expr = quote(out <- atanh(arg1%%1)), inputDim = 1, outputDim = 1), ## FAILS - issue here is probably that modulo on vecs doesn't work but need to restrict domain for atanh
-  ###
-  list(name = 'sum of scalars', expr = quote(out <- arg1 + arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'diff of scalars', expr = quote(out <- arg1 - arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'product of scalars', expr = quote(out <- arg1 * arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'ratio of scalars', expr = quote(out <- arg1 / arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'power of scalars via ^', expr = quote(out <- arg1 ^ arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'power of scalars via pow', expr = quote(out <- pow(arg1, arg2)), inputDim = c(0,0), outputDim = 0),
-  list(name = 'power of scalars via ^ with positive first arg', expr = quote(out <- exp(arg1) ^ arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'power of scalars via pow with positive first arg', expr = quote(out <- pow(exp(arg1), arg2)), inputDim = c(0,0), outputDim = 0),
-  list(name = 'modulo of scalars', expr = quote(out <- arg1 %% arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'min of scalars', expr = quote(out <- min(arg1, arg2)), inputDim = c(0,0), outputDim = 0),
-  list(name = 'max of scalars', expr = quote(out <- max(arg1, arg2)), inputDim = c(0,0), outputDim = 0),
-  ###
-  list(name = 'sum of vectors', expr = quote(out <- arg1 + arg2), inputDim = c(1,1), outputDim = 1),
-  list(name = 'diff of vectors', expr = quote(out <- arg1 - arg2), inputDim = c(1,1), outputDim = 1),
-  list(name = 'product of vectors', expr = quote(out <- arg1 * arg2), inputDim = c(1,1), outputDim = 1),
-  list(name = 'ratio of vectors', expr = quote(out <- arg1 / arg2), inputDim = c(1,1), outputDim = 1),
-##  list(name = 'power of vectors via ^', expr = quote(out <- arg1 ^ arg2), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen casting
-  ## list(name = 'power of vectors via pow', expr = quote(out <- pow(arg1, arg2)), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen casting
-  ## list(name = 'modulo of vectors', expr = quote(out <- arg1 %% arg2), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen casting
-  list(name = 'pmin of vectors', expr = quote(out <- pmin(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
-  list(name = 'pmax of vectors', expr = quote(out <- pmax(arg1, arg2)), inputDim = c(1,1), outputDim = 1),
-  ###
-  list(name = 'sum of vector and scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
-  list(name = 'diff of vector and scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
-  list(name = 'product of vector and scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
-  list(name = 'ratio of vector and scalar', expr = quote(out <- arg1 + arg2), inputDim = c(1,0), outputDim = 1),
-  list(name = 'power of vector and scalar via ^', expr = quote(out <- arg1 ^ arg2), inputDim = c(1,0), outputDim = 1),
-  list(name = 'power of vector and scalar via pow', expr = quote(out <- pow(arg1, arg2)), inputDim = c(1,0), outputDim = 1),
-  list(name = 'power of vector and constant via ^', expr = quote(out <- arg1 ^ 2), inputDim = c(1,0), outputDim = 1),
-  list(name = 'power of vector and constant via pow', expr = quote(out <- pow(arg1, 2)), inputDim = c(1,0), outputDim = 1),
-  list(name = 'power of vector and scalar via ^ with positive first arg', expr = quote(out <- exp(arg1) ^ arg2), inputDim = c(1,0), outputDim = 1),
-  list(name = 'power of vector and scalar via pow with positive first arg', expr = quote(out <- pow(exp(arg1), arg2)), inputDim = c(1,0), outputDim = 1)
-  ## list(name = 'modulo of vector and scalar', expr = quote(out <- arg1 %% arg2), inputDim = c(1,0), outputDim = 1) ## FAILS with Eigen casting
-  )
-
-testsMoreMath = list(
-  list(name = 'inverse cloglog of scalar', expr = quote(out <- icloglog(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'cloglog/inverse cloglog of scalar', expr = quote(out <- cloglog(icloglog(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'inverse logit of scalar', expr = quote(out <- ilogit(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'expit of scalar', expr = quote(out <- expit(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'logit/expit of scalar', expr = quote(out <- logit(expit(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'inverse probit of scalar', expr = quote(out <- iprobit(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'inverse probit of scalar via phi', expr = quote(out <- phi(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'probit/iprobit of scalar', expr = quote(out <- probit(iprobit(arg1))), inputDim = 0, outputDim = 0),
-  ###
-  list(name = 'ceiling of scalar', expr = quote(out <- ceiling(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'floor of scalar', expr = quote(out <- floor(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'round of scalar', expr = quote(out <- round(arg1)), inputDim = 0, outputDim = 0),
-  list(name = 'trunc of scalar', expr = quote(out <- trunc(arg1)), inputDim = 0, outputDim = 0),
-  ###
-  list(name = 'gamma of scalar', expr = quote(out <- gamma(abs(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'lgamma of scalar', expr = quote(out <- lgamma(abs(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'loggam of scalar', expr = quote(out <- loggam(abs(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'log1p of scalar', expr = quote(out <- log1p(abs(arg1))), inputDim = 0, outputDim = 0),
-  list(name = 'factorial of scalar', expr = quote(out <- factorial(ceiling(abs(arg1)))), inputDim = 0, outputDim = 0),
-  list(name = 'lfactorial of scalar', expr = quote(out <- lfactorial(ceiling(abs(arg1)))), inputDim = 0, outputDim = 0),
-  ###
-  list(name = 'inverse cloglog of vector', expr = quote(out <- icloglog(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'cloglog/inverse cloglog of vector', expr = quote(out <- cloglog(icloglog(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'inverse logit of vector', expr = quote(out <- ilogit(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'expit of vector', expr = quote(out <- expit(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'logit/expit of vector', expr = quote(out <- logit(expit(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'inverse probit of vector', expr = quote(out <- iprobit(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'inverse probit of vector via phi', expr = quote(out <- phi(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'probit/iprobit of vector', expr = quote(out <- probit(iprobit(arg1))), inputDim = 1, outputDim = 1),
-  ###
-  list(name = 'ceiling of vector', expr = quote(out <- ceiling(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'floor of vector', expr = quote(out <- floor(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'round of vector', expr = quote(out <- round(arg1)), inputDim = 1, outputDim = 1),
-  list(name = 'trunc of vector', expr = quote(out <- trunc(arg1)), inputDim = 1, outputDim = 1),
-  ###
-  list(name = 'gamma of vector', expr = quote(out <- gamma(abs(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'lgamma of vector', expr = quote(out <- lgamma(abs(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'loggam of vector', expr = quote(out <- loggam(abs(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'log1p of vector', expr = quote(out <- log1p(abs(arg1))), inputDim = 1, outputDim = 1),
-  list(name = 'factorial of vector', expr = quote(out <- factorial(ceiling(abs(arg1)))), inputDim = 1, outputDim = 1),
-  list(name = 'lfactorial of vector', expr = quote(out <- lfactorial(ceiling(abs(arg1)))), inputDim = 1, outputDim = 1)
-  )
-
-testsReduction = list(
-  ### vector
-  list(name = 'min of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
-  list(name = 'max of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
-  list(name = 'sum of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
-  list(name = 'mean of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
-  list(name = 'sd of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
-  list(name = 'var of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
-  list(name = 'prod of vector', expr = quote(out <- min(arg1)), inputDim = 1, outputDim = 0),
-  ## list(name = 'norm of vector', expr = quote(out <- norm(arg1)), inputDim = 1, outputDim = 0),  ## norm doesn't work on vector in R
-  ### matrix
-  list(name = 'min of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
-  list(name = 'max of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
-  list(name = 'sum of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
-  list(name = 'mean of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
-##  list(name = 'sd of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
-  list(name = 'var of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0),
-  list(name = 'prod of matrix', expr = quote(out <- min(arg1)), inputDim = 2, outputDim = 0)
-##  list(name = 'norm of matrix', expr = quote(out <- norm(arg1)), inputDim = 2, outputDim = 0, Rcode = quote(out <- norm(arg1, "F"))) ## NIMBLE's C norm is apparently Frobenius, so R and C nimble functions differ => FAILS
-  )
-
-testsComparison = list(
-  ## scalar
-  list(name = 'greater than, scalar', expr = quote(out <- arg1 > arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'equals, scalar', expr = quote(out <- arg1 == arg2), inputDim = c(0,0), outputDim = 0),
-  list(name = 'not equals, scalar', expr = quote(out <- arg1 != arg2), inputDim = c(0,0), outputDim = 0),
-  ## vector
-  ## list(name = 'greater than, vector', expr = quote(out <- arg1 > arg2), inputDim = c(1,1), outputDim = 1), ## FAILS with Eigen issue
-  ## list(name = 'equals, vector', expr = quote(out <- arg1 == arg2), inputDim = c(1,1), outputDim = 1),  ## FAILS with Eigen issue
-  ## list(name = 'not equals, vector', expr = quote(out <- arg1 != arg2), inputDim = c(1,1), outputDim = 1),  ## FAILS with Eigen issue
-  ## logical
-  list(name = 'and operator, scalar', expr = quote(out <- arg1 & arg2), inputDim = c(0,0), outputDim = 0, logicalArgs = c(TRUE, TRUE)),
-  list(name = 'or operator, scalar', expr = quote(out <- arg1 | arg2), inputDim = c(0,0), outputDim = 0, logicalArgs = c(TRUE, TRUE)),
-  list(name = 'not operator, scalar', expr = quote(out <- !arg1), inputDim = c(0), outputDim = 0, logicalArgs = c(TRUE))
-)
-
-
-testsMatrix = list(
-    list(name = 'forwardsolve matrix-vector', expr = quote(out <- forwardsolve(arg1, arg2)), inputDim = c(2, 1), outputDim = 1),
-    list(name = 'forwardsolve matrix-matrix', expr = quote(out <- forwardsolve(arg1, arg2)), inputDim = c(2, 2), outputDim = 2),
-    list(name = 'backsolve matrix-vector', expr = quote(out <- backsolve(arg1, arg2)), inputDim = c(2, 1), outputDim = 1),
-    list(name = 'backsolve matrix-matrix', expr = quote(out <- backsolve(arg1, arg2)), inputDim = c(2, 2), outputDim = 2),
-
-    list(name = 'forwardsolve matrix-vector with indices', expr = quote(out <- forwardsolve(arg1[1:2,1:2], arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
-    list(name = 'forwardsolve matrix-matrix with indices', expr = quote(out <- forwardsolve(arg1[1:2,1:2], arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
-    list(name = 'backsolve matrix-vector with indices', expr = quote(out <- backsolve(arg1[1:2,1:2], arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
-    list(name = 'backsolve matrix-matrix with indices', expr = quote(out <- backsolve(arg1[1:2,1:2], arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
-
-    list(name = 'forwardsolve matrix-vector amid expr', expr = quote(out <- arg2[1:2] + forwardsolve(arg1[1:2,1:2], arg2[1:2] + arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
-    list(name = 'forwardsolve matrix-matrix amid expr', expr = quote(out <- arg2[1:2,1:2] + forwardsolve(arg1[1:2,1:2], arg2[1:2,1:2] + arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
-    list(name = 'backsolve matrix-vector amid expr', expr = quote(out <- arg2[1:2] + backsolve(arg1[1:2,1:2], arg2[1:2] + arg2[1:2])), inputDim = c(2, 1), outputDim = 1),
-    list(name = 'backsolve matrix-matrix amid expr', expr = quote(out <- arg2[1:2,1:2] + backsolve(arg1[1:2,1:2], arg2[1:2,1:2] + arg2[1:2,1:2])), inputDim = c(2, 2), outputDim = 2),
-
-    list(name = 'chol', expr = quote({ A <- arg1; for(i in 1:dim(A)[1]) A[i,i] <- A[i,i] + 10; out <- chol(A) }), inputDim = c(2), outputDim = 2),
-    list(name = 'matrix-vector multiply', expr = quote(out <- arg1 %*% arg2), inputDim = c(2, 1), outputDim = 2),
-    list(name = 'vector-matrix multiply', expr = quote(out <- t(arg1) %*% arg2), inputDim = c(1, 2), outputDim = 2),
-    list(name = 'matrix-matrix multiply', expr = quote(out <- arg1 %*% arg2), inputDim = c(2, 2), outputDim = 2)
-)
-
+source(system.file(file.path('tests', 'mathTestLists.R'), package = 'nimble'))
 
 set.seed(0)
 ans1 <- sapply(testsVaried, test_math)    ## 12
diff --git a/packages/nimble/inst/tests/test-refactorCompilationSteps.R b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
index 4b1bb8e65..1a5e24e3d 100644
--- a/packages/nimble/inst/tests/test-refactorCompilationSteps.R
+++ b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
@@ -5,6 +5,8 @@ context("Testing of old vs. new generated C++ during refactoring steps")
 oldWarnLevel <- options('warn')
 options(warn = -1)
 
+## Known concern: ordering of asRow()/asCol() and intermediates
+
 compareOldAndNewCompilationRC <- function(input) {
     run <- input$run
     name <- input$name
@@ -22,10 +24,7 @@ compareOldAndNewCompilationRC <- function(input) {
     newfilename <- paste0(filename,'_original')
     pathedfilename <- file.path(tempdir(), 'nimble_generatedCode', filename)
     original_pathedfilename <- file.path(tempdir(), 'nimble_generatedCode', newfilename)
-    for(ext in c('.h', '.cpp')) file.copy(paste0(pathedfilename, ext), paste0(original_pathedfilename, ext))
-    ## we could regenerate it, but might as well read it from the file
-   ## oldFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
-   ## oldFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
+    for(ext in c('.h', '.cpp')) file.copy(paste0(pathedfilename, ext), paste0(original_pathedfilename, ext), overwrite = TRUE)
     
     nimbleOptions(useRefactoredSizeProcessing = TRUE)
     nimble:::resetLabelFunctionCreators() ## sets any generated IDs back to 1
@@ -37,12 +36,7 @@ compareOldAndNewCompilationRC <- function(input) {
 
     for(ext in c('.h','.cpp'))
         compareFilesUsingDiff(paste0(refactored_pathedfilename, ext), paste0(original_pathedfilename, ext),
-                              main = paste0(ext, ' files do not match for: ', name))
-    
-    ## newFooCppOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.cpp')))
-    ## newFooHOutput <- readLines(file.path(tempdir(), 'nimble_generatedCode', paste0(filename, '.h')))
-    ## test_that(paste0(name,': .cpp matches'), expect_identical(oldFooCppOutput, newFooCppOutput))
-    ## test_that(paste0(name,': .h matches'), expect_identical(oldFooHOutput, newFooHOutput))
+                              main = paste0(ext, ' files do not match for: ', name))    
 }
 
 testCases <- list(
@@ -53,3 +47,15 @@ testCases <- list(
 
 ans <- lapply(testCases, compareOldAndNewCompilationRC)
 options(warn = as.numeric(oldWarnLevel))
+
+source(system.file(file.path('tests', 'mathTestLists.R'), package = 'nimble'))
+
+compareOldAndNewMathTest <- function(input) {
+    runFun <- gen_runFun(input)
+    input$run <- runFun
+    compareOldAndNewCompilationRC(input)
+}
+
+boolUseTest <- unlist(lapply(testsBasicMath, function(x) grepl('\\+', x$name))) ## 3 cases
+ans <- lapply(testsBasicMath[boolUseTest], compareOldAndNewMathTest)
+ans <- lapply(testsBasicMath, compareOldAndNewMathTest)

From ed5eb7e2ee792cdf73f5afcc75b6199d5a06b8fd Mon Sep 17 00:00:00 2001
From: perrydv <perry@Perrys-iMac.local>
Date: Fri, 9 Jun 2017 09:12:17 -0700
Subject: [PATCH 5/6] fix typo

---
 packages/nimble/R/options.R | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/nimble/R/options.R b/packages/nimble/R/options.R
index 93d6127ef..ccb1a8600 100644
--- a/packages/nimble/R/options.R
+++ b/packages/nimble/R/options.R
@@ -8,7 +8,7 @@ nimbleUserNamespace <- as.environment(list(sessionSpecificDll = NULL))
 .nimbleOptions <- as.environment(
     list(
         useRefactoredSizeProcessing = FALSE,
-        doSelfListSeparately = FALSE,
+        doSelfLiftSeparately = FALSE,
         enableSpecialHandling = FALSE,
         pauseAfterWritingFiles = FALSE,
         CppAD_directory = NA,

From 4ef0a9d31472354560ddbaa0cb97213e5ddedda4 Mon Sep 17 00:00:00 2001
From: perrydv <perry@Perrys-iMac.local>
Date: Fri, 9 Jun 2017 13:43:50 -0700
Subject: [PATCH 6/6] responses to code review

---
 packages/nimble/R/RCfunction_compile.R        |  2 +-
 packages/nimble/R/all_utils.R                 | 13 +++++
 packages/nimble/R/genCpp_insertAssertions.R   |  2 +-
 packages/nimble/R/genCpp_sizeProcessing.R     | 56 +++++++++----------
 packages/nimble/R/options.R                   |  4 +-
 .../tests/test-refactorCompilationSteps.R     | 10 ++--
 run_tests.R                                   |  2 +-
 7 files changed, 50 insertions(+), 39 deletions(-)

diff --git a/packages/nimble/R/RCfunction_compile.R b/packages/nimble/R/RCfunction_compile.R
index b1d416034..85cdd9bad 100644
--- a/packages/nimble/R/RCfunction_compile.R
+++ b/packages/nimble/R/RCfunction_compile.R
@@ -265,7 +265,7 @@ RCfunProcessing <- setRefClass('RCfunProcessing',
                                            browser()
                                        }
 
-                                       if(nimbleOptions('useRefactoredSizeProcessing')) {
+                                       if(nimbleOptions('experimentalNewSizeProcessing')) {
                                            exprClasses_setToEigenize(compileInfo$nimExpr, compileInfo$newLocalSymTab, compileInfo$typeEnv)
                                        }
 
diff --git a/packages/nimble/R/all_utils.R b/packages/nimble/R/all_utils.R
index 93af7de45..1f6333240 100644
--- a/packages/nimble/R/all_utils.R
+++ b/packages/nimble/R/all_utils.R
@@ -2,6 +2,19 @@
 
 double <- function(ndim, dims) {}
 
+## Sequential label generation system:
+## labelFunctionMetaCreator returns a function that returns a function.
+## labelFunctionMetaCreator is only called once, immediately below, to create labelFunctionCreator
+## The outer layer allows allLabelFunctionCreators to be in the closure of every function returned
+## by labelFunctionCreator.  Each of those functions is registered as an element of allLableFunctionCreators.
+## 
+## This scheme allows the function resetLabelFunctionCreators below to work simply,
+## resetting the count to 1 for all of the label generators.
+##
+## The motivation for resetLabelFunctionCreators is for testing: If we want to check
+## that two pathways to code generation (one existing, one experimental) create identical
+## code, it is helpful to have identical generated labels.  Resetting all label generators
+## supports this goal.
 labelFunctionMetaCreator <- function() {
     allLabelFunctionCreators <- list()
 
diff --git a/packages/nimble/R/genCpp_insertAssertions.R b/packages/nimble/R/genCpp_insertAssertions.R
index 8a323d7b6..db5d8b2d9 100644
--- a/packages/nimble/R/genCpp_insertAssertions.R
+++ b/packages/nimble/R/genCpp_insertAssertions.R
@@ -34,7 +34,7 @@ exprClasses_insertAssertions <- function(code) {
             if(length(code$args[[i]]$assertions) > 0) {
                 toInsert <- lapply(code$args[[i]]$assertions, function(x) if(inherits(x, 'exprClass')) x else RparseTree2ExprClasses(x))
                 before <- unlist(lapply(toInsert, function(x) {if(x$name == 'after') FALSE else TRUE}))
-                if(nimbleOptions('useRefactoredSizeProcessing')) code$args[[i]]$assertions <- list()  ## Clear assertions field so it can be used by later compiler stages
+                if(nimbleOptions('experimentalNewSizeProcessing')) code$args[[i]]$assertions <- list()  ## Clear assertions field so it can be used by later compiler stages
                 newExpr <- newBracketExpr(args = c(lapply(toInsert[before], ## assertions will be inserted recursively IF they are in {}
                                                           function(z) {exprClasses_insertAssertions(z); z}),
                                                    code$args[i],
diff --git a/packages/nimble/R/genCpp_sizeProcessing.R b/packages/nimble/R/genCpp_sizeProcessing.R
index 30379a88f..c37726a87 100644
--- a/packages/nimble/R/genCpp_sizeProcessing.R
+++ b/packages/nimble/R/genCpp_sizeProcessing.R
@@ -252,8 +252,8 @@ sizeDim <- function(code, symTab, typeEnv) {
 }
 
 sizeDiagonal <- function(code, symTab, typeEnv) {
-    ## refactor: code$name change step stays here
-    ## because the 3 cases are not implementation-specific
+    ## experimentalNewSizeProcessing: code$name change step stays here
+    ## experimentalNewSizeProcessing: because the 3 cases are not implementation-specific
     asserts <- recurseSetSizes(code, symTab, typeEnv)
     argIsExprClass <- inherits(code$args[[1]], 'exprClass')
     nDimArg <- if(argIsExprClass) code$args[[1]]$nDim else 0
@@ -304,7 +304,7 @@ sizeWhich <- function(code, symTab, typeEnv) {
     code$toEigenize <- 'yes'
     code$name <- 'setWhich'
 
-    if(!nimbleOptions('doSelfLiftSeparately')) {
+    if(!nimbleOptions('experimentalSelfLiftStage')) {
         if(!(code$caller$name %in% assignmentOperators)) {
             asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
         }
@@ -1075,7 +1075,7 @@ sizeNimbleListReturningFunction <- function(code, symTab, typeEnv) {
   if(code$name == 'getDerivs')
       code$toEigenize <- 'no'  ## Temp. solution to ensure that derivsOrders argument is a nimArray and not an eigen type.
   code$nDim <- 0
-  if(!nimbleOptions('doSelfLiftSeparately')) {
+  if(!nimbleOptions('experimentalSelfLiftStage')) {
       if(!(code$caller$name %in% assignmentOperators))
           asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
   }
@@ -1535,7 +1535,7 @@ sizeInsertIntermediate <- function(code, argID, symTab, typeEnv, forceAssign = F
         newArgExpr <- RparseTree2ExprClasses(as.name(newName))
         newArgExpr$type <- code$args[[argID]]$type
         newArgExpr$sizeExprs <- code$args[[argID]]$sizeExprs
-        if(!nimbleOptions('useRefactoredSizeProcessing')) {
+        if(!nimbleOptions('experimentalNewSizeProcessing')) {
             newArgExpr$toEigenize <- 'maybe'
         }
         newArgExpr$nDim <- code$args[[argID]]$nDim
@@ -1554,7 +1554,7 @@ sizeInsertIntermediate <- function(code, argID, symTab, typeEnv, forceAssign = F
         newArgExpr <- RparseTree2ExprClasses(as.name(newName))
         newArgExpr$type <- newExpr$args[[1]]$type
         newArgExpr$sizeExprs <- newExpr$args[[1]]$sizeExprs
-        if(!nimbleOptions('useRefactoredSizeProcessing')) {
+        if(!nimbleOptions('experimentalNewSizeProcessing')) {
             newArgExpr$toEigenize <- 'maybe'
         }
         newArgExpr$nDim <- newExpr$args[[1]]$nDim
@@ -1640,9 +1640,9 @@ sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALS
                 }
             } else { ## yes in symTab
                 ## This case is ok.  It is in the symbol table but not the typeEnv.  So it is something like ptr <- getPtr(A)
-                 if(!nimbleOptions('useRefactoredSizeProcessing')) {
+                 if(!nimbleOptions('experimentalNewSizeProcessing')) {
                 code$toEigenize <- 'no'
-                 } ##useRefactoredSizeProcessing
+                 } ##experimentalNewSizeProcessing
                 code$nDim <- 0
                 code$type <- 'unknown'
                 code$sizeExprs <- list()
@@ -1680,7 +1680,7 @@ sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALS
     ## Note this can use LHS$name for RHSsizeExprs when returning from a nimbleFunction on RHS.  But this is probably not needed any more.
     if(any(unlist(lapply(RHSsizeExprs, is.null)))) RHSsizeExprs <- makeSizeExpressions(rep(NA, RHSnDim), LHS$name) ## reset sizeExprs for the LHS var. re-using RHSsizeExprs for LHS.  This would only be valid if it is a nimbleFunction returning something on the RHS.  For assignment to be executed in Eigen, the RHS sizes MUST be known
 
-     if(!nimbleOptions('useRefactoredSizeProcessing')) {
+     if(!nimbleOptions('experimentalNewSizeProcessing')) {
                 
     if(LHS$toEigenize == 'yes') {
         code$toEigenize <- 'yes'
@@ -1754,7 +1754,7 @@ sizeAssignAfterRecursing <- function(code, symTab, typeEnv, NoEigenizeMap = FALS
             if(LHS$name == 'map') assert <- c(assert, sizeInsertIntermediate(code, 1, symTab, typeEnv) )
         }
     }
-     } ##useRefactoredSizeProcessing
+     } ##experimentalNewSizeProcessing
     if(!(LHS$name %in% c('eigenBlock', 'diagonal', 'coeffSetter', 'nimNonseqIndexedd', 'nimNonseqIndexedi','nimNonseqIndexedb'))) {
         ## should already be annotated if it is an indexed assignment.
         ## It should be harmless to re-annotated EXCEPT in case like out[1:5] <- scalar
@@ -2409,7 +2409,7 @@ sizeUnaryCwise <- function(code, symTab, typeEnv) {
     ## lift intermediates
     a1 <- code$args[[1]]
     if(inherits(a1, 'exprClass')) {
-        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+        if(!nimbleOptions('experimentalNewSizeProcessing') ) {
             if(a1$toEigenize == 'no') {
                 asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
                 a1 <- code$args[[1]]
@@ -2423,7 +2423,7 @@ sizeUnaryCwise <- function(code, symTab, typeEnv) {
     }
     code$type <- setReturnType(code$name, getArgumentType(a1))
     if(length(code$nDim) != 1) stop(exprClassProcessingErrorMsg(code, 'In sizeUnaryCwise: nDim is not set.'), call. = FALSE)
-    if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- if(code$nDim > 0) 'yes' else 'maybe'
+    if(!nimbleOptions('experimentalNewSizeProcessing') ) code$toEigenize <- if(code$nDim > 0) 'yes' else 'maybe'
     return(asserts)
 }
 
@@ -2540,7 +2540,7 @@ sizeUnaryReduction <- function(code, symTab, typeEnv) {
                 stop(exprClassProcessingErrorMsg(code, 'NIMBLE compiler does not support var with a matrix (or higher dimensional) argument.'), call. = FALSE) 
             }
         }
-        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+        if(!nimbleOptions('experimentalNewSizeProcessing') ) {
             if(!code$args[[1]]$isName) {
                 if(code$args[[1]]$toEigenize == 'no') {
                     asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
@@ -2552,9 +2552,9 @@ sizeUnaryReduction <- function(code, symTab, typeEnv) {
     code$nDim <- 0
     code$sizeExprs <- list()
     code$type <- setReturnType(code$name, code$args[[1]]$type)
-    if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
+    if(!nimbleOptions('experimentalNewSizeProcessing') ) code$toEigenize <- 'yes'
 
-    if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+    if(!nimbleOptions('experimentalNewSizeProcessing') ) {
         if(!(code$caller$name %in% c('{','<-','<<-','='))) {
             asserts <- c(asserts, sizeInsertIntermediate(code$caller, code$callerArgID, symTab, typeEnv))
         }
@@ -2626,7 +2626,7 @@ sizeMatrixMult <- function(code, symTab, typeEnv) {
     a2 <- code$args[[2]]
     
     if(a1$nDim == 0 | a2$nDim == 0) stop(exprClassProcessingErrorMsg(code, 'In sizeMatrixMult: Cannot do matrix multiplication with a scalar.'), call. = FALSE) 
-    if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+    if(!nimbleOptions('experimentalNewSizeProcessing') ) {
         if(a1$toEigenize == 'no') {
             asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
             a1 <- code$args[[1]]
@@ -2679,7 +2679,7 @@ sizeMatrixMult <- function(code, symTab, typeEnv) {
     code$nDim <- 2
     code$sizeExprs <- list(a1$sizeExprs[[1]], a2$sizeExprs[[2]])
     code$type <- setReturnType(code$name, arithmeticOutputType(a1$type, a2$type))
-    if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
+    if(!nimbleOptions('experimentalNewSizeProcessing') ) code$toEigenize <- 'yes'
     assertMessage <- paste0("Run-time size error: expected ", deparse(a1$sizeExprs[[2]]), " == ", deparse(a2$sizeExprs[[1]]))
     newAssert <- identityAssert(a1$sizeExprs[[2]], a2$sizeExprs[[1]], assertMessage)
     if(is.null(newAssert))
@@ -2790,7 +2790,7 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
     a2 <- code$args[[2]]
     ## pull out aXDropNdim, aXnDim, aXsizeExprs, and aXtype (X = 1 or 2)
     if(inherits(a1, 'exprClass')) {
-        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+        if(!nimbleOptions('experimentalNewSizeProcessing') ) {
             if(a1$toEigenize == 'no') {
                 asserts <- c(asserts, sizeInsertIntermediate(code, 1, symTab, typeEnv))
                 a1 <- code$args[[1]]
@@ -2801,16 +2801,16 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
         a1nDim <- a1$nDim
         a1sizeExprs <- a1$sizeExprs
         a1type <- a1$type
-        if(!nimbleOptions('useRefactoredSizeProcessing') ) a1toEigenize <- a1$toEigenize
+        if(!nimbleOptions('experimentalNewSizeProcessing') ) a1toEigenize <- a1$toEigenize
     } else {
         a1DropNdim <- 0
         a1nDim <- 0
         a1sizeExprs <- list()
         a1type <- storage.mode(a1)
-        if(!nimbleOptions('useRefactoredSizeProcessing') ) a1toEigenize <- 'maybe'
+        if(!nimbleOptions('experimentalNewSizeProcessing') ) a1toEigenize <- 'maybe'
     }
     if(inherits(a2, 'exprClass')) {
-        if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+        if(!nimbleOptions('experimentalNewSizeProcessing') ) {
             if(a2$toEigenize == 'no') {
                 asserts <- c(asserts, sizeInsertIntermediate(code, 2, symTab, typeEnv))
                 a2 <- code$args[[2]]
@@ -2821,13 +2821,13 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
         a2nDim <- a2$nDim
         a2sizeExprs <- a2$sizeExprs
         a2type <- a2$type
-        if(!nimbleOptions('useRefactoredSizeProcessing') )  a2toEigenize <- a2$toEigenize
+        if(!nimbleOptions('experimentalNewSizeProcessing') )  a2toEigenize <- a2$toEigenize
     } else {
         a2DropNdim <- 0
         a2nDim <- 0
         a2sizeExprs <- list()
         a2type <- storage.mode(a2)
-        if(!nimbleOptions('useRefactoredSizeProcessing') )  a2toEigenize <- 'maybe'
+        if(!nimbleOptions('experimentalNewSizeProcessing') )  a2toEigenize <- 'maybe'
     }
     
     ## Choose the output type by type promotion
@@ -2835,7 +2835,7 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
     if(length(a2type) == 0) {warning('Problem with type of arg2 in sizeBinaryCwise', call. = FALSE); browser()}
     code$type <- setReturnType(code$name, arithmeticOutputType(a1type, a2type))
 
-    if(!nimbleOptions('useRefactoredSizeProcessing') ) {
+    if(!nimbleOptions('experimentalNewSizeProcessing') ) {
         forceYesEigenize <- identical(a1toEigenize, 'yes') | identical(a2toEigenize, 'yes')
         code$toEigenize <- if(a1DropNdim == 0 & a2DropNdim == 0)
                                if(forceYesEigenize)
@@ -2846,7 +2846,7 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
     }
     
     ## Catch the case that there is at least one scalar-equivalent (all lengths == 1)
-    ## The 3 'code$toEigenize <- ' should be redundant with above and could be removed during refactor
+    ## experimentalNewSizeProcessing: The 3 'code$toEigenize <- ' should be redundant with above and could be removed during refactor
     if(a1DropNdim == 0 | a2DropNdim == 0) { 
         ## Here we will process effective scalar additions
         ## and not do any other type of size promotion/dropping
@@ -2854,17 +2854,17 @@ sizeBinaryCwise <- function(code, symTab, typeEnv) {
             if(a2DropNdim == 0) { ##both are scalar-equiv
                 code$nDim <- max(a1nDim, a2nDim) ## use the larger nDims
                 code$sizeExprs <- rep(list(1), code$nDim) ## set sizeExprs to all 1
-                if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- if(forceYesEigenize) 'yes' else 'maybe'
+                if(!nimbleOptions('experimentalNewSizeProcessing') ) code$toEigenize <- if(forceYesEigenize) 'yes' else 'maybe'
             } else {
                 ## a2 is not scalar equiv, so take nDim and sizeExprs from it
                 code$nDim <- a2nDim
                 code$sizeExprs <- a2sizeExprs
-                if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
+                if(!nimbleOptions('experimentalNewSizeProcessing') ) code$toEigenize <- 'yes'
             }
         } else { ## a2 is scalar-equiv, and a1 is not
             code$nDim <- a1nDim
             code$sizeExprs <- a1sizeExprs
-            if(!nimbleOptions('useRefactoredSizeProcessing') ) code$toEigenize <- 'yes'
+            if(!nimbleOptions('experimentalNewSizeProcessing') ) code$toEigenize <- 'yes'
         }
         return(if(length(asserts) == 0) NULL else asserts)
     }
diff --git a/packages/nimble/R/options.R b/packages/nimble/R/options.R
index ccb1a8600..e9f9dd244 100644
--- a/packages/nimble/R/options.R
+++ b/packages/nimble/R/options.R
@@ -7,8 +7,8 @@ nimbleUserNamespace <- as.environment(list(sessionSpecificDll = NULL))
 # These options are for development use at this point.
 .nimbleOptions <- as.environment(
     list(
-        useRefactoredSizeProcessing = FALSE,
-        doSelfLiftSeparately = FALSE,
+        experimentalNewSizeProcessing = FALSE,
+        experimentalSelfLiftStage = FALSE,
         enableSpecialHandling = FALSE,
         pauseAfterWritingFiles = FALSE,
         CppAD_directory = NA,
diff --git a/packages/nimble/inst/tests/test-refactorCompilationSteps.R b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
index 1a5e24e3d..492721ee8 100644
--- a/packages/nimble/inst/tests/test-refactorCompilationSteps.R
+++ b/packages/nimble/inst/tests/test-refactorCompilationSteps.R
@@ -46,9 +46,6 @@ testCases <- list(
          }))
 
 ans <- lapply(testCases, compareOldAndNewCompilationRC)
-options(warn = as.numeric(oldWarnLevel))
-
-source(system.file(file.path('tests', 'mathTestLists.R'), package = 'nimble'))
 
 compareOldAndNewMathTest <- function(input) {
     runFun <- gen_runFun(input)
@@ -56,6 +53,7 @@ compareOldAndNewMathTest <- function(input) {
     compareOldAndNewCompilationRC(input)
 }
 
-boolUseTest <- unlist(lapply(testsBasicMath, function(x) grepl('\\+', x$name))) ## 3 cases
-ans <- lapply(testsBasicMath[boolUseTest], compareOldAndNewMathTest)
-ans <- lapply(testsBasicMath, compareOldAndNewMathTest)
+source(system.file(file.path('tests', 'mathTestLists.R'), package = 'nimble'))
+ans2 <- lapply(testsBasicMath, compareOldAndNewMathTest)
+
+options(warn = as.numeric(oldWarnLevel))
diff --git a/run_tests.R b/run_tests.R
index 415df3d30..b9ce9a565 100755
--- a/run_tests.R
+++ b/run_tests.R
@@ -2,7 +2,7 @@
 # This script runs most tests in nimble/inst/tests/ prioritized by duration.
 
 # Avoid running these blacklisted tests, since they take too long.
-blacklist <- c('test-Math2.R', 'test-Mcmc2.R', 'test-Mcmc3.R', 'test-Filtering2.R', 'test-ADfunctions.R', 'test-ADmodels.R','test-refactorSizeProcessing.R')
+blacklist <- c('test-Math2.R', 'test-Mcmc2.R', 'test-Mcmc3.R', 'test-Filtering2.R', 'test-ADfunctions.R', 'test-ADmodels.R')
 if(Sys.getenv('SKIP_EXPENSIVE_TESTS') == 'TRUE') {
     blacklist <- c(blacklist, 'test-mcmc.R', 'test-numericTypes.R')
 }
