fread memory maps entire file even when select= is used to restrict to specific columns
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- r
- Domain
- data, performance
Research direction
Start with the fread implementation and the behavior discussed in issue #4329; run the supplied R reproduction using select= on a very wide file. Done means the selected six columns can be read without attempting to memory-map the entire input or requiring its full virtual-memory footprint.
Written by the indexing model from the issue text.
Description
I am attempting to use fread with the select= option to read the first 6 columns from a file that has 408485 columns and and 125616 rows (including the header).
It fails with the following message:
Error in data.table::fread(infile, header = T, select = cnames[1:6], :
Opened 191.2GB (205254407682 bytes) file ok but could not memory map it. This is a 64bit process. There is probably not enough contiguous virtual memory available.
I see that there has been a previous fixed issue where fread used to do the same thing when nrows= was specified, and that issue has been fixed. But I do not see any previous bug reports for this happening when select= is used to select columns.
(The file is extremely large because this is genetic data. The first six columns are information about what genetic variants are included in each file, the remaining columns that I don't want to read are genotypes for people in the sample. For now I am using command-line tools to extract the first 6 columns from each file so they can be read into R, but it would be nice to be able to do this all in a single step in R.)
Output of sessionInfo():
R version 4.4.2 (2024-10-31)
Platform: x86_64-pc-linux-gnu
Running under: Rocky Linux 8.10 (Green Obsidian)
Matrix products: default
BLAS/LAPACK: [path redacted for github post]/libopenblasp-r0.3.28.so; LAPACK version 3.12.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
time zone: [redacted for github post]
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.16.4
loaded via a namespace (and not attached):
[1] compiler_4.4.2 bigparallelr_0.3.2 flock_0.7
[4] parallel_4.4.2 Rcpp_1.0.13-1 codetools_0.2-20
[7] doParallel_1.0.17 iterators_1.0.14 foreach_1.5.2
[10] bigassertr_0.1.6 RhpcBLASctl_0.23-42
Reproducible example:
# How much fake data to make
num_cols <- 408485
num_datarows <- 125615
num_samples <- num_cols - 6
# Make fake SNPs and fake sample IDs
set.seed(1)
snpmeta <- data.frame(CHR=rep(2,num_datarows),SNP=paste0('rs',1:num_datarows),`(C)M`=0, POS=1:num_datarows,
COUNTED=sample(c('A','C'),num_datarows,replace=T), ALT=sample(c('T','G'),num_datarows,replace=T))
samp_ids <- sample(100000:999999,num_samples,replace=F)
samp_ids <- paste0(samp_ids,'_',samp_ids)
# Write the fake file row-by-row so we don't fill memory with fake genotypes
outfile <- file(paste0('fakedat.traw'),"wt")
writeLines(paste(c('CHR','SNP','(C)M','POS','COUNTED','ALT',samp_ids),collapse='\t'),con=outfile) # Header row
for(i in 1:num_datarows) {
genos <- sample(c(0,1,2,NA),num_samples,replace=T)
writeLines(paste(c(unlist(snpmeta[i,]),genos),collapse='\t'),con=outfile) # Data for the ith row
}
close(outfile)
readmeta <- fread('fakedat.traw',select=c('CHR','SNP','(C)M','POS','COUNTED','ALT'),header=T,stringsAsFactors=F,data.table=F)
I have tested this with smaller files to make sure it's not a problem with how I specify columns to select=. With smaller 17-40 Gb files the fread command completes successfully. It still uses large amounts of memory while reading the file, then when it finishes the memory usage abruptly drops and the result is the requested 6 columns of data.
- Dominant language
- R
- Stars
- 3.9k
- Forks
- 1.1k
- Avg merge
- 14h 4m
- Merged PRs (30d)
- 4
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Rdatatable/data.table
-
as.data.table() recurses without end on a survival::Surv object (or any data.frame carrying one) Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Rdatatable/data.table#7887 ·
-
consistency tests
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Rdatatable/data.table#7853 · 3 comments ·
-
internals
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Rdatatable/data.table#6938 · 1 comment ·
-
encoding fread
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Rdatatable/data.table#5179 · 8 comments ·
-
documentation programming
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Rdatatable/data.table#3199 · 3 comments ·
All issues in Rdatatable/data.table
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
r-lib/pkgdepends#485 · 3 comments ·
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
beginners blocker
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enviPathR OpenBuild Error Build OK Build Warning policies-accepted pre-review precheck-passed
Difficulty 1/5 Under an hour Newbie friendliness 84/100
Bioconductor/BiocContributions#207 · 6 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
datacarpentry/semester-biology#1255 ·