This is a code that I prepared and which crashes the R session (https://github.com/pachadotdev/fixest2/blob/cpp11_wip/dev/gdb-debug-4.R). The issue is that the C++ function cpp_get_fe_gnl_() doesn't like the matrix obsCluster, which is a matrix of integers. If we cast it as integer in R, the R session crashes with a 'memory not mapped' message. If we pass it as a double with no cast, the function does nothing and returns an error of 'double vs integer'.
# library(fixest2)
devtools::load_all()
# REPRODUCIBLE ERROR ---
# gravity_pois = fepois(Euros ~ log(dist_km) | Origin + Destination + Product + Year, trade)
# fixedEffects = fixef(gravity_pois)
# Error: Invalid input type, expected 'integer' actual 'double'
# NOW WE SEE IT LINE BY LINE ----
# the problem is in fixef.fixest function L882 Methods.R
# this is the same as to run fixef.fixest line by line
# lines 924-1079 that do not apply for this case
gravity_pois = fepois(Euros ~ log(dist_km) | Origin + Destination + Product + Year, trade)
object <- gravity_pois
notes <- getFixest_notes()
sorted <- TRUE
nthreads <- getFixest_nthreads()
fixef.tol <- 1e-5
fixef.iter <- 10000
S <- object$sumFE
family <- object$family
fixef_names <- object$fixef_vars
fixef_id <- object$fixef_id
Q <- length(fixef_id)
N <- length(S)
id_dummies_vect <- list()
for (i in 1:Q) id_dummies_vect[[i]] <- as.vector(fixef_id[[i]])
is_ref_approx <- FALSE
isSlope <- FALSE
dumMat <- matrix(unlist(id_dummies_vect), N, Q) - 1
orderCluster <- matrix(unlist(lapply(id_dummies_vect, order)), N, Q) - 1
nbCluster <- sapply(fixef_id, max)
# check the data types
print(paste("Q", class(Q)))
print(paste("N", class(N)))
print(paste("S", class(S)))
print(paste("dumMat", class(dumMat)))
print(paste("nbCluster", class(nbCluster)))
print(paste("orderCluster", class(orderCluster)))
# ERROR 1 ----
# THIS IS THE LINE THAT BREAKS FIXEF()
fixef_values <- cpp_get_fe_gnl(Q, N, S, dumMat, nbCluster, orderCluster)
# ERROR MESSAGE:
#
# OK L570OK L5954
# 0
# OK L612OK L6321
#
# *** caught segfault ***
# address 0x5623b3cd0df0, cause 'memory not mapped'
#
# Traceback:
# 1: .Call(`_fixest2_cpp_get_fe_gnl_`, as.integer(Q), as.integer(N), sumFE, as.integer(dumMat), as.integer(cluster_sizes), as.integer(obsCluster))
# 2: cpp_get_fe_gnl(Q, N, S, dumMat, nbCluster, orderCluster)
#
# Possible actions:
# 1: abort (with core dump, if enabled)
# 2: normal R exit
# 3: exit R without saving workspace
# 4: exit R saving workspace
# NOW WE TRY TO STORE THE MATRICES AS INTEGER-TYPE
storage.mode(dumMat) <- "integer"
storage.mode(orderCluster) <- "integer"
# THE FUNCTION BREAKS AGAIN
# fixef_values <- cpp_get_fe_gnl(Q, N, S, dumMat, nbCluster, orderCluster)
# ERROR MESSAGE:
#
# OK L570OK L5954
# 0
# OK L612OK L6321
#
# *** caught segfault ***
# address 0x56144c29706c, cause 'memory not mapped'
#
# Traceback:
# 1: .Call(`_fixest2_cpp_get_fe_gnl_`, as.integer(Q), as.integer(N), sumFE, as.integer(dumMat), as.integer(cluster_sizes), as.integer(obsCluster))
# 2: cpp_get_fe_gnl(Q, N, S, dumMat, nbCluster, orderCluster)
#
# Possible actions:
# 1: abort (with core dump, if enabled)
# 2: normal R exit
# 3: exit R without saving workspace
# 4: exit R saving workspace
To run it, and make the R session crash, I would need this "recipe" to follow the exact same steps I used:
to have a matrix of integers in R you need the following
for the values put in at creation to be integers
for any arithmetic manipulation of the integer based matrix to itself by of an integer type
In your case :
orderCluster <- matrix(unlist(lapply(id_dummies_vect, order)), N, Q) - 1
should become
orderCluster <- matrix(as.integer(unlist(lapply(id_dummies_vect, order))), N, Q) - 1L
Note that I made two changes. as.integer() to wrap the numeric inputs to be cast to integer type for the matrix creation. secondly, using -1L rather than -1 as -1 is numeric (double) / not integer, and would cause an implicit cast to numeric which you want to avoid for your matrix. Rather, -1L is an integer and therefore conforms with the integer nature of the matrix, thus preserving it.