From 5899b8782ec7878fd77ad0fb3627e5aa519cfcb6 Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Wed, 22 Apr 2026 13:44:13 +0100 Subject: [PATCH 1/8] Register mori under content/software Adds shikokuchuo/mori to data/github-repos.toml and a software page at content/software/mori/ with a forest-green placeholder hex sticker and a readme copy of the package README. Registers mori ahead of the 0.1.0 announcement post so the blog post's software: mori frontmatter tag resolves. --- content/software/mori/_index.md | 35 +++++ content/software/mori/logo.svg | 3 + content/software/mori/readme | 223 ++++++++++++++++++++++++++++++++ data/github-repos.toml | 17 +++ 4 files changed, 278 insertions(+) create mode 100644 content/software/mori/_index.md create mode 100644 content/software/mori/logo.svg create mode 100644 content/software/mori/readme diff --git a/content/software/mori/_index.md b/content/software/mori/_index.md new file mode 100644 index 000000000..ae3808f81 --- /dev/null +++ b/content/software/mori/_index.md @@ -0,0 +1,35 @@ +--- +topics: +- Best Practices +color: '#4A7C59' +description: Shared Memory for R Objects +github: shikokuchuo/mori +image: logo.svg +languages: +- R +latest_release: '2026-04-22T00:00:00+00:00' +people: +- Charlie Gao +title: mori +website: https://shikokuchuo.net/mori/ + +external: # updated automatically, do not edit + description: Shared Memory for R Objects + first_commit: '2026-04-16T12:27:58+01:00' + forks: 0 + languages: + - R + last_updated: '2026-04-22T00:00:00+00:00' + latest_release: '2026-04-22T00:00:00+00:00' + license: MIT License + people: + - Charlie Gao + repo: shikokuchuo/mori + stars: 0 + title: mori + website: https://shikokuchuo.net/mori/ +--- + +mori shares R objects across processes on the same machine via a single copy in OS-level shared memory — POSIX shared memory on Linux and macOS, Win32 file mapping on Windows. Every process reads from the same physical pages through the R ALTREP framework, giving lazy, zero-copy access. + +`share()` writes an R object into shared memory and returns an ALTREP wrapper that behaves like a regular R vector. Shared objects serialize compactly as their shared-memory name rather than their full contents, so sending a shared data frame to a mirai daemon transmits ~300 bytes instead of the underlying 200 MB. Shared memory is managed by R's garbage collector and freed automatically when the last reference is dropped, and consumer processes see the data as read-only so copy-on-write keeps mutations local. diff --git a/content/software/mori/logo.svg b/content/software/mori/logo.svg new file mode 100644 index 000000000..43f4f7d96 --- /dev/null +++ b/content/software/mori/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/content/software/mori/readme b/content/software/mori/readme new file mode 100644 index 000000000..81f3f2571 --- /dev/null +++ b/content/software/mori/readme @@ -0,0 +1,223 @@ + + + +# mori + + + +[![Lifecycle: +experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) +[![CRAN +status](https://www.r-pkg.org/badges/version/mori)](https://CRAN.R-project.org/package=mori) +[![R-CMD-check](https://github.com/shikokuchuo/mori/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/shikokuchuo/mori/actions/workflows/R-CMD-check.yaml) +[![Codecov test +coverage](https://codecov.io/gh/shikokuchuo/mori/graph/badge.svg)](https://app.codecov.io/gh/shikokuchuo/mori) + + + ________ + /\ mori \ + / \ \ + \ / 森 / + \/_______/ + +Shared Memory for R Objects + +→ `share()` writes an R object into shared memory and returns a shared +version + +→ ALTREP serialization hooks — shared objects serialize compactly and +work transparently with `serialize()` and `mirai()` + +→ ALTREP-backed lazy access — a 100-column data frame is one `mmap`; +columns materialize on first touch + +→ OS-level shared memory (POSIX / Win32) — pure C, no external +dependencies; read-only in other processes, preventing corruption of +shared data + +→ Automatic cleanup — shared memory is freed when the R object is +garbage collected + +
+ +## Installation + +``` r +install.packages("mori") +``` + +## Quick Start + +`share()` writes an R object once into shared memory and returns a +zero-copy ALTREP view. Shared objects serialize compactly via ALTREP +serialization hooks, working transparently with mirai and any R +serialization path. Shared memory is automatically freed when the object +is garbage collected. + +``` r +library(mori) + +# Share a vector — returns an ALTREP-backed object +x <- share(rnorm(1e6)) +mean(x) +#> [1] 0.0005982035 + +# Serialized form is ~100 bytes, not ~8 MB +x |> serialize(NULL) |> length() +#> [1] 124 +``` + +## Sharing by Name + +`shared_name()` extracts the SHM name from a shared object. +`map_shared()` opens a shared region by name — useful for accessing the +same data from another process without serialization: + +``` r +x <- share(1:1e6) + +# Extract the SHM name +nm <- shared_name(x) +nm +#> [1] "/mori_4c0f_1" + +# Another process can map the same region by name +y <- map_shared(nm) +identical(x[], y[]) +#> [1] TRUE +``` + +## Use with mirai + +Shared objects can be sent to local daemons — the ALTREP serialization +hooks ensure only the SHM name crosses the wire, and the daemon maps the +same physical memory. + +``` r +library(lobstr) +library(mirai) + +daemons(1) + +x <- share(rnorm(1e6)) + +# Worker maps the same shared memory — 0 bytes copied +m <- mirai(list(mean = mean(x), size = lobstr::obj_size(x)), x = x) +m[] +#> $mean +#> [1] 0.0008675476 +#> +#> $size +#> 840 B + +daemons(0) +``` + +Elements of a shared list also serialize compactly — each element +travels as a reference to its position in the parent shared region, not +as the full data: + +``` r +daemons(3) + +# Share a list — all 3 vectors in a single shared region +x <- list(a = rnorm(1e6), b = rnorm(1e6), c = rnorm(1e6)) |> share() + +# Each element is sent as (parent_name, index) — zero-copy on the worker +mirai_map(x, \(v) lobstr::obj_size(v) |> format())[.flat] +#> a b c +#> "840 B" "840 B" "840 B" + +daemons(0) +``` + +## Why mori + +Parallel computing multiplies memory. When 8 workers each need the same +210 MB dataset, that is 1.7 GB of serialization, transfer, and +deserialization — with 8 separate copies consuming RAM. + +mori eliminates all of it. `share()` writes data into shared memory +once. Each worker maps the same physical pages, receiving a reference of +~300 bytes instead of the full dataset — a payload ~700,000 times +smaller, which translates into a significant saving in memory usage as +well as total runtime: + +``` r +daemons(8) + +# 200 MB data frame — 5 columns × 5M rows +df <- as.data.frame(matrix(rnorm(25e6), ncol = 5)) +shared_df <- share(df) + +boot_mean <- \(i, data) colMeans(data[sample(nrow(data), replace = TRUE), ]) + +# Without mori — each daemon deserializes a full copy +mirai_map(1:8, boot_mean, data = df)[] |> system.time() +#> user system elapsed +#> 2.135 38.222 5.823 + +# With mori — each daemon maps the same shared memory +mirai_map(1:8, boot_mean, data = shared_df)[] |> system.time() +#> user system elapsed +#> 1.377 27.121 3.949 + +daemons(0) +``` + +## How It Works + +### What gets shared + +All atomic vector types and lists / data frames are written directly +into shared memory, with attributes preserved end-to-end. Pairlists are +coerced to lists. `share()` returns ALTREP wrappers that point into the +shared pages — no deserialization, no per-process memory allocation. + +All other R objects (environments, closures, language objects) are +returned unchanged by `share()` — no shared memory region is created. + +
+ + +
+ +### Lazy access + +A data frame with 10 columns lives in a single shared region. A task +that touches 3 columns pays for 3. Character strings are accessed lazily +per element. + +### Lifetime + +Shared memory is managed by R’s garbage collector. The SHM region stays +alive as long as the shared object (or any element extracted from it) is +referenced in R. When no references remain, the garbage collector frees +the shared memory automatically. + +**Important:** Always assign the result of `share()` to a variable. The +shared memory is kept alive by the R object reference — if the result is +used temporarily (not assigned), the garbage collector may free the +shared memory before a consumer process has mapped it. + +### Copy-on-write + +Shared data is mapped read-only. Mutations are always local — R’s +copy-on-write mechanism ensures other processes continue reading the +original shared data: + +- **Structural changes** to a list or data frame (adding, removing, or + reordering elements) produce a regular R list. The shared region is + unaffected. +- **Modifying values** within a shared vector (e.g., `X[1] <- 0`) + materializes just that vector into a private copy. Other vectors in + the same shared region stay zero-copy. + +– + +Please note that the mori project is released with a [Contributor Code +of Conduct](https://shikokuchuo.net/mori/CODE_OF_CONDUCT.html). By +contributing to this project, you agree to abide by its terms. diff --git a/data/github-repos.toml b/data/github-repos.toml index 130dfce4e..d43203152 100644 --- a/data/github-repos.toml +++ b/data/github-repos.toml @@ -25339,3 +25339,20 @@ forks = 0 language = "HTML" first_commit = "2026-03-20T03:48:34+00:00" last_updated = "2026-03-20T10:27:38.525786+00:00" + +[[repos]] +repo = "shikokuchuo/mori" +name = "mori" +description = "Shared Memory for R Objects" +website = "https://shikokuchuo.net/mori/" +stars = 0 +forks = 0 +latest_release = "2026-04-22T00:00:00+00:00" +first_commit = "2026-04-16T12:27:58+01:00" +license = "MIT License" +contributors = [ + "shikokuchuo", +] +last_updated = "2026-04-22T00:00:00+00:00" +releases = 1 +language = "R" From 263a13e6548c76880dc5117eb25f58a638b6d73b Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Wed, 22 Apr 2026 13:44:22 +0100 Subject: [PATCH 2/8] Add mori 0.1.0 announcement post Announces the first CRAN release of mori, a new R package for sharing R objects across processes via OS-level shared memory. The post covers the ALTREP-based share() API, a mirai-based bootstrap benchmark (~160x wall-clock on this render), access/lifetime semantics, and how mori positions relative to bigmemory, SharedObject, Arrow memory-mapped Parquet, and fork-based parallelism. --- content/blog/mori-0-1-0/.Rprofile | 1 + content/blog/mori-0-1-0/featured.jpg | Bin 0 -> 228123 bytes content/blog/mori-0-1-0/index.md | 193 +++ content/blog/mori-0-1-0/index.qmd | 162 +++ content/blog/mori-0-1-0/mori-diagram.svg | 45 + content/blog/mori-0-1-0/renv.lock | 1206 ++++++++++++++++ content/blog/mori-0-1-0/renv/.gitignore | 7 + content/blog/mori-0-1-0/renv/activate.R | 1438 ++++++++++++++++++++ content/blog/mori-0-1-0/renv/settings.json | 21 + 9 files changed, 3073 insertions(+) create mode 100644 content/blog/mori-0-1-0/.Rprofile create mode 100644 content/blog/mori-0-1-0/featured.jpg create mode 100644 content/blog/mori-0-1-0/index.md create mode 100644 content/blog/mori-0-1-0/index.qmd create mode 100644 content/blog/mori-0-1-0/mori-diagram.svg create mode 100644 content/blog/mori-0-1-0/renv.lock create mode 100644 content/blog/mori-0-1-0/renv/.gitignore create mode 100644 content/blog/mori-0-1-0/renv/activate.R create mode 100644 content/blog/mori-0-1-0/renv/settings.json diff --git a/content/blog/mori-0-1-0/.Rprofile b/content/blog/mori-0-1-0/.Rprofile new file mode 100644 index 000000000..81b960f5c --- /dev/null +++ b/content/blog/mori-0-1-0/.Rprofile @@ -0,0 +1 @@ +source("renv/activate.R") diff --git a/content/blog/mori-0-1-0/featured.jpg b/content/blog/mori-0-1-0/featured.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a994ce17939696c96573b635935d0a36181662a1 GIT binary patch literal 228123 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 z z$WOXqV3M|#CB^HlI_h|k5-J}wlf%kWsD8S##f*g@X=vrETi7AV!5uh5C0W0A`A!t ze_cf_wFy__g-54WaOEjTCA>G&G*Y|(euINfII}9QXUL9jgoJC55)zO`Ce#~7Wk^;K zh}8n3orz&9$h5Mo9!r41+UNjS0_mK!`n%eXyUi8>(@hvs?66>dk{`elXb+Ai{1Mca z;$xr!ovX#9)9XekMK}?q&buOzE1qsE0i2P?Z$BgCQpDXT&pl=9Q0;5*eL%JoBdc_WoHCe z*~6q2VqS0qzl=UYG3B7&YISH3a{xKB)j5w&;S+`}VX()uZy2%?yb>?B0OjBtX~tN% zS}9z2=5>?q8JjCsMTHRxe3qpTt!=-kuv?8^5cFG5yR5J(2r=Zp1#rJdeE#?zWfa-6 z_q!GJqGGh)W31Qft0xg_Rom=qSBx+xm7p)fdgh#ZiFilGbdaA>Dl7UKsq2TzI=w3f zcE?}Q6K>T#19sRV>NmqQmk%Wua6)9F8%tXb+;~F zrK(ZrwJi+wW`kDHXH#pDr;zb!G9Ti~^d>bK;RQj^piU$B4(J`bE7HZ%s$9ZFu5sDR zT3`<4=0U(tK~yI?@-vt*YG&O`lr99%sy=?z?jI)@KpGNxrO$ni*HhjZ;S(fesHG$7 zZ@ta~x}4Gf8sr*Ndtl5N=tK#xsVoCohOPU`l=wz>poXY_phapP9ftXw3OZsSw={@Q z7|0wL8L_(lgic|(_1H-;DY&xS^=;`Sz=OIe6CHm|c0n5qExc!q0@FFXX)~%B-XIcT zfli+?w++Y`gv!GDc@g3y`10zY@pY?s?@pl8!cMs1v%giMDvrY9xXwFvDz*yW1Zb%Z zgz0ppx&4MRmDh5)PcWR%sye)QM^qag)SxJ4!fG!_g$U6-; zNi{$yh%&~TN}-7bsat;Wx_j1xiq*Ivf7r`IlGR}x7PyNDTb(#zz_HsuY{p@w+4hoW zgW|Dv>zmQAg5^dNV2lK@K`1s+sa8HeDr=Z|SK(0hdZtWoDs5g~Z@p$+NBhH8;A>tf zt+51)1+rC1;cuPGh;^0>GX?Z)eJDwea8e&p;gY;8qEqt{%9notoO-abcLKVPo(VK_ zajD8T^-CQ-Y>^jYDh-u+R8#5|z;f+RfcpOJGm`M|;n4MD*N|V<{N)c=JNpL;y|!|E zd{dD0C@8IwKZe*2urch4m>K}YAHfS!Oztwa31y`aPc4FXKoT_YFXwK zeTe;QWH?E$sHlU&MoYUV1n0&Xck0ucGB;a zxUnp=&Sea(5S_opV}V-Jg0Vv9gTK-YX#b!ImT-l)_bjB+Qtqrf7WW1TnIz$jKyu^7ykAX0a?J$e1LA zDbbHfp&EQs5Mw;VV^!=ggRo8d8M<1Nn@D3iv?PliM7XwcRcaAawql6t5oU63;QJ#{ zqIx&CEJi%u3ca`Cg-!35*3#hpyohc$1C^THkuML*wE+P8B<;q!ya`htH`PRc?(A z@E_(LBohm8ZQHXhg`!^=1xU8+!dKDy^O|PSE6qkJw^OzWMexXRp(Vq@aFb~f4n08t z(+=tJBO6XrWo$J6 z2ePry2nw7gFdJ-78-9b0$^3-_R;I+I1$xjb^edr^VG&y^N}Ptj zlgzGu8CG|djBbd3;218!9WTCe6uz`6jT_wGbZl65Ml%Qeu}ja*x9)-W%zG3Y{h7fN zkx0Vx&H;V$ADlw3U!sU79#85uK>}8A%>ZUclhP#-d{f?^pJViCoQ1pv9eCBj4V zy>W(cBocqz0SQ2Y#%$xFBD@=psYi9Q9-^0tgR$!ED%eE0We2(tu%H(L*;0W0;U31n zlf_l)s(4NbsltJ~VV-j_`eVjd`6BeM2+bl#hlw>~1ocOVyx+({h5O&KQb_BjV^BL6 zb{kc*r~i=Xn^j8O{?3}3WEH9j6mTdLhCd_pK*uX-A|_DwB$EcBo)s*#5_d%Hq2NeZiEUSRzG_N&+X{v1t^gUqb@`x|z zhB067`q2qLIdNaJvf_3bkdXxN8$BVHNeEIw&_K9Gw;U-*1Cz3=Y0SW|ctuPlQbP&N zTlvRKw^1sul3+5={EjX*Gz#60F}DHyKUL@b&*mGx{n(orwW&SYAVzJq_oh{`SI|oA zs=fD~F{^gvi9`Ugve5*ZVq-Lr`rZjlZ`j zQr`37xYsjalL!~6gd=)I&cpZ!osqntA%8)|DGFxrEm<&^-9rO~b(GSlX!7Xs@#BVL zjpm<27_)|B=iOMC{>-P5tJ3GOXxV>Yq&rKGeJBP-u+tk3m*JRs4{!p0G<2gN9%24d zjTj{O;4MlI0ILyTxtb`V_`t-a3zTbzeQdaTdQs$HKD&9%DQE`Sid3Uae0(Iv5$88f zI8}?GgWMyUJ_WT|dYFu%Q9ku{Vh$H_Po zmrqR9*vBE#TOpBvMDtTWgfM|OA_NC_Xv%_AjN^(io^Kdg$;S6$Z$Ysj;xQp7XEZaj zJl{iyOz5vn$Uy^AIZ>M`m5*Npv(_rdo6e_;6Wa|)?seg@GL@g8zkqTz; zgct6(RqLbzEr@&Zl%UzK$;dTiG_!`qacaYuK17hPKaydLC=k?;@K+Z+2_kABK2=ic zR2@`oD2lIYag5`x&mJXUq1BIj*C0Mwh2iiDM|<~0AxH~&d$?L@i11LNYZ`fg8Qd6w zM9zp5c`(*d|iOup6`7{AXQa%N8fkEyON8m{>XEuz{*%hcyO9SSj8H!NI z_v33;QU~y=s4GhA6`m?E1#b)+L85ILq7P! z=*Q^CLMg=p`O0|s;ux3g=!A$UdB5EGY;v_d4H>7&NTqFhdvbO8gm%Ut%%LS`=i?56 zlQeC?2wD}{y(gOC%%&hfTuCIcUYVe$n06m{a#;EiXUUAY>|`RrVeAUw`bWYL%Du4? zjqk!Sy(C0gP6F(`*4d793d*YEl$<>ZMaAq|B;=<Af86R;JYw>5)YG+F-W)KEvMdGG> z!1vb*pCI{wZ%mSGZ}|A%B7htZ2Y^eBM-2b~FBcdpA4w0nlS2~`I#1Njgd6uO%WYfL z;^p0<`V`Cg`GR;7$<)VEcAr19dD*x{t#~ z{K^q@hJCae>vm@&UnisuSOXe!l%_pjY!zA&Q+>UJCGCY63cbPRIy?WocFDtVmr>O$I(Da#R)3vRi{X~Iv5~+uo#+VP3`%$psNgHq z6U#iB@0F>j;HfCs*TN{3IFw-bpSUY?sEX@}>IL+g%|58bR%saD) z+L7gMlsM?y@)hi7yma5?eP6-{@tzyE2z`oWm)FAI`h{9P{4lAK;st(amXUd%O{fYA znI>=f@nkQ2x)gxtFUvMF687Q*)+yHd9dF!umy!hdkx7x9OP|5&Kc<}n!O*ML5x{99 z;J+p^?-sg7p9=E5xbNh|op;eToX z>`XPgEDTm#_)R|g`D5lhr^ueZU+knSsD4^m9|G?AS#01@(*KC>jdvx4Bl4pDKPUSq zu<$2l!!cb{?|I+cXrCG;ZN_HyJ?`eRj}0<ei~4n!jW1thBCD(8Qy&GPq~C9 z+YdZ`ZKmQD0^?cV#i-y>l2q?3z`}H7$sI4)h{kwqDs`LelWE)HZ|_A-a@Ve$waZeP zuO7D&nV1tbU;vg{FIu{u##zhSQpOs0RKM_56Q}FBTlITnx4r81lK!>YOY8bL5Ui!$ zml)j&`wC%s?UyxleyaL$kF_cCAHZ+=Z#KM6W)Ea?I&T%c6jNawn4tMfpLi;bwJ`ln zBbBC#4f}IY7@Z1f>>wLDjsD>3_RCjeXR?r~$N<0hA?te2lh3eO6p?^Uf|#xRLn(Cs zH$9)+g_IJS*S7HA)3c+0KB2~rf|7uLLzWH0TWonwQ;=~Y@zQ=9pkG9bZl35PMQWrb zBOW0uRlvMCTp&oK4%I8+qDv0jeZ?#{6I6ky&SKr3&&g5z+wDZGa0KOv{|7ky#Ux($ zJmo&jKr;iR0os6Dh0!a1&KRRhos_}zbIJL`+N|W@ffRu%bCdBH5r8W@&JD!b-bBBl zplSP>CQ~aikuOp|)DCtfBq4nB2{&8zh{j?+08}c~S2%%i<{IcD`cj9RP^xn!ISbb6y1a)wmtS3ol>371g_&=CU1LVS z@iVjM^5;F9MTQ3Z5|cSXZ%LwkTlZt%@EEYHJ$^wI750$5@psdJW#{BXJgx(1Sp# z$a#jCD=y;=yyepOV>%DC%d-Fojf}$TP1l?{lGa~qK!NW(jO!lwqH0F8(zw}!PN{* zN{4U)Sm^XAL$w+?(pEsz9{?Ip=CD98POu%mRUe*~UizC4kG)n_0@8|(28=CPg?^hy zY^G;w=DSg5_^pIw_bnc^)q~(6$8U!}gh~(S@dtdHKyL4Fyu@oceVO0eu11U!e)^~K z_EcXRKZS2A9pIe^ztzd zGY55p>go+c9{cO%ag~r4Q5vqDNw;VI%F23yWWpvljuQp;ax}x&aA<1F)Y34ap$|f- z0A(T>3H4WMXKdM-)*5fn1RS`W$`L=B0#D@z4aK`6>dl72>PN4DThe$=_f*EBp&s0p<0xySp_~w(o?*Zesel$$hKc>qZG+tGj%V=bS z0A>Mc4h&u1dNHbtrh+-7Z5G#{qt16CHZ!odeZKw868x3U_(yy)_S)GOGgQ8(k5&K$BNL6G+7jL)>|{4VvJ5bX;u%p;P@{R zEWx`2Oy#)BguJ^bRypq@OJf$*rM`NLuPV7zOdar&qsLH;skAFUK{{PW0y!iQmu`GM zieG6(Yyx^`TeySF&#YwVC-N@$clty)tSCSIQsavx5N|;EgVrCBEiMCWFOQ3nYul z4NcehEb^_BWT%98OjeI)o1Zo@Oo#am%qwa@eoIj*#GNK6f0U&pNj1jgHNZbV+}x^Q z&IqWk0Q})m$LNr5l07eZXq2A641bU7hOcWe`qbs3c$AUQ0Gn{2P zDTwH$y&dm}=v|2lUXxk;%;WJL8@@l;o@6~f3x3d+#fFw)C?zQZPWvQG-ps^cd0#1B z(p0us4Mk?93qJks8pqT(ClkI`kHdwL8WGi=2Zby10+BpfkA4Ijs*h&mgJ#Ry=!t9^n9bW7wufnu0SX3`WrR67N*L=-&VJmzjdi8J(tzf92ZT{)9 zo9|jAsi$gUgs>3FxWsJXr`=I)`fTYJZOV6*%PNkYemw8BXPEEt$R_0_iRqsJBQCrD z>(=(~ufGq+F&t|Iy+A@K>~BHt{OGvO&5h1>04+0MJQd2sS5JUaB4Hn!m8aZn3YyRBlnRjS(f@Y=eK!@PFh>Wy$Mejqbi~8XH9S`8^*Hg{4gGvvbINl&(g~giA6;G1C+JX<-zr+ zMHQjXghO|Z1EkC4PY7o0j`jx<3>N2vJL^Ra}AT7Pkl=FTHuw6%> zl;>*_E5FYhUn!)49CjyS@VZ?V_X7SZ27=i5y(c4fRk!ES`c}jX&-|TU`r%>dJ?UoS zp2p)ZX5YhkSRor-=m~nZ?a*5_h|Gmdr)y&mu=>}3INRd^Bep%ZFS>Q#fW5O5%)mk0 z(x=|vfECd>_2*{#XlPU(ApF!Ft4Vc)%Erubv@uqs<^01x}f&PlmFDavVT;lMk=~x z1bo^_!P=W6ruR;Yyotv(tW*srLxxBvOYXNW=Q+!E*>a^@KH+QXlY)I}hLMfl2H$%H zVvG)@%cC-u%?5rx=+;`4AtR9YWs^V?{|5=8F}m(Tm*>Uyk>yd~E@kwmO;+H$=65Aco>(HR{PI|Xo>?i87MlpUNk z(dj)W4N&WhkLIx?^igW#WxWMUo6yd2Z9^k{p0pNXGL%x0*bj9QN&D}%TaAA9CzM}y z5eSQ)-o(-A>wcIa`xsguz0}e2Tv9DXdM7;PjYf%xx!Io}9IPtGt1Q+ntj|dcfq~+I zOtP5XJP*l6j|2zpmxK`$WH}Dtnj~2%Hg>Rl`E*@KB_x39RVP$~9pCO7RS}=Tbdbt> z@9hkRsTsBjS=*jGQ5{V)0fOS;s~`V@@f{otK6iE+0eJmO%!rG2V7i=Y&sv?J`y|%P1l)zQcNXZtRhK?S}0IzBl9Q(7^*`k!1CZ!VLW3&W+k*NPJ( zo}uAGC)Q>c!;hJnnV*GXUieJODLYSlwwohi-{IqhE!cZF{1rlFD0 zS>FiNSek8zCBj!;;4}Q_lenS}hZktv|-zD1`j=;ch-+HBcaW=3wbGaWs5EF$y?5!8T5%7+H$@@|hC z*Hs;p`*oE0@~3I{^G9FTS#fdO7!0L#(kj6s0uO#X7M3xpcz<7L_OLos(!@srme| zI28%1`Janhw%8wH=Wv);^G~S3uJ8)yEyo>u_0<@inm={g;_3nNqnwZR&?C#ymxkLb z)Wg3&{`F5tvRg5A#c}e|vBy0uSd1@vB3f|y%bmwdKHoY1>A+HHUA@G|@`{jS7i!3h zc?Ks$n@IPi7rCSB5)s+al=ZDDe?!944KH0;YQ$1wzln{hApiR$s`UT1NlB&i{+P1T za0DHeyeG)aM1&PGSkX?$Zjdx_-~l3^Aa9-cXj)ZVM+K_ST*;F>(Yp@|aTg<$;$oy_3$=dlEI0T1Wts9gxw@ms!x2IN~~iwqV<>oq`YC zk^5U9#G>$SzRr6_yN@VFeIV6nIXzV+NlZ5-{IsSk9)2J4j#5DsIItvnTN>BfQ!qh< zJ+->OA-=7>UC8Dp7++JhKB~>oq_3-&-HCQh&m@5(dU7k%s6|DeGL7qoZOsiFV#cE9 z{O~RIw9KX=GnAETppoD-o&epHlP?Ubm4pwyj;KO-o|?qj*`VID9yj|fJk7>vIk7cF zsE}agI~^!sKJ__1{tI$`n=z5(k83CS53ypi9dLuR6f?Pf7ig!2y6)}dJ&rP$UWRs; z61t4II-639KzO`1)9?`+24Uy)2uKGLHXcW^375o^x{PnDdM7oMJRXr*TZ%@% zaJ!@MOFLh{VI9j=G1!j@t6X^yZJIMZS4O4(_Jc=skuNSB)N97fCl0GI?->d|km-_; z9P7Adu_^OBk9ErFzMZR}Yr8V za8v_XKdFL$3Tu72rQSspula?jU+D>}#3{Ck5 zI4b0>xW22|x7Y+o6IG4zHgvul;_bYlMz7e#exCWXr&!kNE=&1nnV6Z-QJ2Hf^;)1{ zx;{*L&sCp4ro~u8rw|vx`VYWjXZuR~VuR=FLyR`zPvRu$@3bVNLb<<-0r>{1;R3Kh zQ5MUu4_99__cj_+E+Wx1*Xv3RsyOMz8i1#47<@v)n{k>aO^2J+)qjg~Nn*z%&(uk3yn(hIf&rwPzI8{l2kFD*>pPKa5fWNgo z3B%=GtMZ?WOT7N{pvYlVjhxBYqr;$pRsZe^s{!`W0FBai{{sA7$ z$&8tFN}S>a>`b#{?qf3W&;WJP}x!_dm*_2=lD@wRsT2L9IZ- z;cJkYlGin{8r*!~J>*b}6rfzU{gNiJ_zIBiVmMUaRO!^Ci{1EwL)5-A`iQTX_%Vo- zLSl-qXNVj2OIE@^X-Cx%cyb`q_n5{N_^=?(ulNJxL*GrM!NQSO9!$pS1>n$1Qcc19 z?d)~S(wu`+_>OGPM@mzz<)+s?`dZr>;Xd-VH`3}tvVg}DflBzsu)+=S3lT{OAXa}< zN6mqtNT8#8XGCy}S@V}7-gK9tFY!0bt`o(S4D%3Ag~0b81>DdDdIR`7C1qc-W}{n9 z5hXS5_Y1FUo4|`j0^k0dNWF;1H~)_;1c=jQtTwc4YHCC;?|Q1NPg+Ou4-I%ijf3+* z0v;Y5Jp2bH007_ss5wP}${b*0doQJkjM9dw6Qkbs(+6fijDtswqX@h~-H_dYx_17+ za5C%GP}d&Mnp04JwsR%>#(7aEb4^0pVs`m~y4*x`r+jWY$gaaK!LXOP3#g|WjbjY` z@G8_9HeeCE-du##1;q+DW1l6sc~@YBj<0N-7$#Te0_(cecb9hyH@N)U>5U*^%DL~m zEQ2+LQkr>%2-52-p$K?3d6&=`X3ry5{d7bGBo%wI`Z|HG9h#fm#T2I97{Ww@0V+WV zGKWzV6@4Od{+OG(u7H5$u4&pDyTk~nv$52){#w^)mwc5~FEu@W+nDPh&^{#Qj?mVn zrawezYjFIdo*J*tFq4>09|ly5yoPVWYikp_DAsn!BD6GKeX@~}+N~GK3R7;rkPBwn z!z{1GVv&}lVo_uiiJE5_qNYqd7*GRpSfu=E(x8nuc`9$C0xnm@V!K^JZcJCznJtY+ zLp|ei$z5brG+ zOh>sAS!t1@vn?-Uri0b<9adQ>8y)oW#hjlkx6_;XxPJ4}fi@e9E@3<&0bVN} z9bFrkok!WW3gPx#?Szw}VnZF0%5(!f$gzAWT(K(`cSB;57aT@H@i5azu>buf+PqlW zu5}cI=2U27G+xX(mll&TAcbwdB)F(`hB`0cQwOv3TEf@snmzdG>?L)+)&cAKgwXHp zv5Y+QoW1*{usH&|5q^SeK}Y>#q(}_eFAtVrmO)#MRkox(@h6MK9937)oZMt2W*p)$ zkdrMr0`VW>)3a-Rl2J@;83CVN6s=>k{zl^LWHI^(`F&`+`NGm)q+KLm3Qd6wNCb#b zFcg&_G21x^2uyMex?2-~Y%xyo^l}{+I4A5IZboXh9vn|KY`5vJdrzffZs18jv6v8z zXJ1_`1&BM~>s11-wMgW_A82#xVQnTEXouJHJq`X`!@RJQIZhoX8y9AA8hKVCtW z(+Z9nYk2A^d7i{|^LxGv;ZYb&Hi&)rZUp;6^S|>SOt_tNL9KOVx8fd%1^+95%zBPe zY(EZ%bdDp8t8T@TJX4-Gr79x@jr!U(m~=zlRn!F$HfOXzx#6m2XnXWaWZx#d^$0S9 zZgqv&vXyi(F{FOMK^<#2+RJM{?zo$O>ODt$Hssk-k6eR~4e{MfWBvi~(VqFoW_{SK zJja?58fM_)rQl4iST}t)!;yC12zDI95c}uh^RTYmQkuKv*)0b~$VIrmRN8qVXKuxZ z0jcd<6^5zj{%D?R{$3#OzNR0q;WC>`ksSX9>k$bn8j%QSy>4UTHes3BPTb2pZ|DsW z;XMhgD>PdoDOvI@><2D=pI|kXl-Odc1qr)5vZ1F>#{L14S3oqr76ti8DT*&f6zR|< zCWi&O&W)%z@CwTayfmHM;xg(&P3CQ~6eZ}A18i|Hm?sk9zewSsN1cyeHk%azYx;cl z=n<#n6>dEI)@JgExVNf15zpZx`GXlk?@{xQeCmOek4D$2SR%_-VgoYn;cwKms7|Fp z!JfX=_IW!8QF#;#GwRG76sVmiY|5|CeVGK`@wzr>VR4n=HdBz?Hea#)*3j@QO5;*k zEpsz|NgrLpm4vSHQIa=i{tamgS;FKBRW)NgezL5iR@v&g$YrcG#4th);Xyh3QT6Yk z$JD@`$%a50zwzmp$kbu6esY6jPS3Re{PBV^tqp`k2##44oaE!*CI6J~FSM3!a^bs_ z@mtG0zJtRvYcvn`-Ow5SU-bmI)tvXzRSUTxWnLh=@0`~alBp$q*C=b-Ip`%vxYIuX zrDzPo%;s6egz-Si4kqUH-(k0)<^)Uo5f}?=QzGJ(7>zU~H~2H)+ehyU>8K2a3E*i% zQ0z(>+toWnKK1BMpLiL&0xFq0Z_t_!lkjzD32DNim=Gl0%q~PsCAtL;{jGdh@S|#C z0#@rF+ogZ!ZX@<*-N{Q>g*;It)>f#Q7hBYD-O%xkPRd27p_RstwONN1UatFo!HPk` z%S(M9)VEGjV8);|t{Z)U4Jc;?N;yfnWi;u&M(2NqAASC^E1+z}I3haJzTHHDc8q|@ zYJ|zeIq3R3JcH*>hvUt00Th@_gq)6A;s?8;z_t3B<%w`_LDfk$=q z3-SZNzddJOp5 z%a3^GboBWnEG9&$at5Mg5b?;=%D}YFomY=OnNk0cypnOBYPn)

2M^&dQW_snqe~ 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 z

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 H{P*^M2k@Sg literal 0 HcmV?d00001 diff --git a/content/blog/mori-0-1-0/index.md b/content/blog/mori-0-1-0/index.md new file mode 100644 index 000000000..61f39dc49 --- /dev/null +++ b/content/blog/mori-0-1-0/index.md @@ -0,0 +1,193 @@ +--- +title: 'mori: Shared memory for R objects' +date: 2026-04-22T00:00:00.000Z +people: + - Charlie Gao +description: > + mori is a new R package for sharing R objects across processes via OS-level + shared memory. Parallel workers get zero-copy, lazy ALTREP access to the same + physical pages — share once, read anywhere. +image: featured.jpg +image-alt: > + Macro close-up of a computer RAM module, showing the blue circuit board and + metallic connectors in sharp detail with a shallow depth-of-field blur. +topics: + - Best Practices +software: + - mori +languages: + - R +tags: + - Parallelism +photo: + url: https://unsplash.com/photos/macro-shot-photo-of-a-computer-ram-lYxQ5F9xBDM + author: Liam Briese +nohero: false +hidesubscription: false +--- + + +We're pleased to announce the first CRAN release of [mori](https://shikokuchuo.net/mori/). + +Until now, parallel R has meant serializing your data to every worker and duplicating it in each worker's RAM. Eight workers × 1 GB is 8 GB, plus the serialization, transfer, and deserialization work to get it there. R processes don't share memory --- each has its own heap, so data crosses between them through a serialization pipe. + +mori changes that. It places an R object once into OS-level shared memory and lets every process on the machine read the same physical pages directly --- with no data copying between processes. + +``` r +install.packages("mori") +``` + +mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP.html) (Alternative Representation) framework, which lets a package expose a custom vector backend that reads its data from somewhere other than ordinary R memory --- a memory map, a database, a compressed store. Here, that somewhere is OS shared memory. + +## How it looks + +The entry point is `share()`. You pass it an R object, you get back a shared version you can use like any other R vector: + +``` r +library(mori) + +set.seed(42) +x <- share(rnorm(1e6)) +mean(x) +``` + + [1] 0.0005737398 + +`share()` works on atomic vector types, lists, and data frames --- it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those primitives. Environments, functions, S4 objects, and external pointers pass through unchanged, since their references don't map naturally to shared pages. + +The returned object is an ALTREP view into shared memory --- it costs no additional RAM beyond the original region. It also serializes compactly: instead of sending the full 8 MB payload, mori's ALTREP hooks serialize shared objects as their shared-memory name, just over 100 bytes on the wire. + +``` r +x |> serialize(NULL) |> length() +``` + + [1] 125 + +That compact serialization is what makes the rest of the picture work. + +## Parallel workers, one copy + + + +mori pairs naturally with [mirai](https://mirai.r-lib.org/). When you send a shared object to a local daemon, only the shared-memory name crosses the wire; the daemon maps the same physical pages and sees the full data with no deserialization cost. The same is true for any other parallel backend that uses R serialization. + +Here's the motivating case --- a bootstrap across eight workers on a 200 MB data frame: + +``` r +library(mirai) + +daemons(8) + +df <- as.data.frame(matrix(rnorm(25e6), ncol = 5)) +shared_df <- share(df) + +boot_mean <- \(i, data) colMeans(data[sample(nrow(data), replace = TRUE), ]) + +# Without mori — each daemon deserializes its own copy +mirai_map(1:8, boot_mean, data = df)[] |> system.time() +``` + + user system elapsed + 0.487 4.317 4.937 + +``` r +# With mori — each daemon maps the same shared memory +mirai_map(1:8, boot_mean, data = shared_df)[] |> system.time() +``` + + user system elapsed + 0.000 0.001 0.031 + +``` r +daemons(0) +``` + +The payload each daemon receives is ~300 bytes instead of 200 MB --- roughly 700,000× smaller. That's well over 100× wall-clock on this run. The algorithm hasn't changed; the savings come from not copying data that's already in RAM. Eight workers share one copy, not eight. + +The gap shrinks as per-task compute grows: workloads where each worker does substantial work see proportionally smaller wall-clock wins, though never worse than the baseline. The headline number is what you see when data transfer dominates, which it often does in bootstrap, cross-validation, and parameter sweeps. + +Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole frame. + +``` r +daemons(3) + +x <- list(a = rnorm(1e6), b = rnorm(1e6), c = rnorm(1e6)) |> share() + +mirai_map(x, \(v) lobstr::obj_size(v) |> format())[.flat] +``` + + a b c + "840 B" "840 B" "840 B" + +``` r +daemons(0) +``` + +## What this unlocks + +Anywhere parallel R workers process the same large dataset, `share()` removes the per-worker copy: + +- A [Shiny](https://shiny.posit.co/) dashboard where every worker process reads from one shared reference dataset instead of loading its own +- A [tidymodels](https://www.tidymodels.org/) `tune_grid()` sweep --- or a [targets](https://docs.ropensci.org/targets/) pipeline branching over model variants --- where every fit reads the same training data without copying it +- Bootstrap, Monte Carlo, or permutation work dispatched across [mirai](https://mirai.r-lib.org/) or [crew](https://wlandau.github.io/crew/), where thousands of iterations all read from one shared dataset + +The pattern is the same in each case: call `share()` on your dataset once, then pass the result wherever you'd normally pass the data. Parallel dispatches that hit the serialization path transmit only the reference, not the data. + +## Access and lifetime + +A shared data frame lives in a single shared region, but ALTREP columns are only materialized when touched. A task that reads three columns out of one hundred pays for three --- character vectors are lazier still, with per-element access. Workers only pay for the data they actually touch. + +Shared memory is tied to R's garbage collector. As long as the shared object (or anything extracted from it) is live in R, the shared region stays alive. When the last reference is dropped, the region is freed automatically --- there are no lingering SHM segments to clean up. + +Shared data is mapped read-only in consumers, so accidental writes can't corrupt data another process is reading. Mutations go through R's normal copy-on-write: editing a value inside a shared vector produces a private copy of that one vector, leaving the rest of the shared region untouched. + +``` r +x <- share(rnorm(1e6)) +lobstr::obj_size(x) +``` + + 960 B + +``` r +x[1] <- 0 # local mutation materializes a private copy +lobstr::obj_size(x) +``` + + 8.00 MB + +**One thing to keep in mind:** always assign the result of `share()` to a variable. The lifetime of the shared region is governed by the R reference, and an unassigned result can be garbage-collected before a consumer process has mapped it. + +## Sharing by name + +If you want to access a shared region from another process without going through serialization at all, you can pass its name directly: + +``` r +x <- share(1:1e6) + +nm <- shared_name(x) +nm +``` + + [1] "/mori_12689_4" + +``` r +# Works from another process; same session here to demonstrate +y <- map_shared(nm) +identical(x[], y[]) +``` + + [1] TRUE + +Handy when the consumer needs to attach by name rather than receive the shared object through R's serialization path. + +## How mori fits + +R has had partial answers to cross-process data sharing before. [bigmemory](https://CRAN.R-project.org/package=bigmemory) offers shared `big.matrix` objects --- effective, but limited to numeric matrices. [SharedObject](https://bioconductor.org/packages/SharedObject/) on Bioconductor targets a similar goal with its own memory-sharing machinery, oriented around BiocParallel workflows. [Arrow](https://arrow.apache.org/docs/r/)'s memory-mapped Parquet gives zero-copy columnar reads across processes, though the data lives on disk. On Unix, `parallel::mclapply` gets shared memory for free via fork copy-on-write --- until a worker writes to a page, with the usual fork caveats (unsafe in GUI sessions, with open DB connections, or alongside multithreaded libraries), and with no equivalent on Windows. + +mori is usable across any backend that plugs into R's standard serialization --- mirai, future, parallel, foreach, callr --- with no special cooperation required. Atomic vectors, lists, and character vectors are all supported, with lazy per-element access preserved in every process. Lifetimes are managed by R's garbage collector: shared regions are freed automatically when the last reference drops. And mori itself is pure C --- POSIX shared memory on Linux and macOS, Win32 file mapping on Windows, nothing beyond the package to install. + +## Try it + +mori is [available from CRAN](https://CRAN.R-project.org/package=mori). The [package website](https://shikokuchuo.net/mori/) has a walkthrough of the mirai integration and full reference documentation. mori is designed to slot quietly into existing parallel-R workflows --- anywhere a worker currently receives a big dataset, `share()` it first and you're done. It complements [mirai](https://mirai.r-lib.org/): mirai handles async evaluation and daemon coordination, mori handles shared access to the data those daemons work on. + +The package is in the `experimental` lifecycle stage while the API settles, so feedback and issue reports on [GitHub](https://github.com/shikokuchuo/mori/issues) are very welcome. diff --git a/content/blog/mori-0-1-0/index.qmd b/content/blog/mori-0-1-0/index.qmd new file mode 100644 index 000000000..340d41e13 --- /dev/null +++ b/content/blog/mori-0-1-0/index.qmd @@ -0,0 +1,162 @@ +--- +title: "mori: Shared memory for R objects" +date: 2026-04-22 +people: + - Charlie Gao +description: > + mori is a new R package for sharing R objects across processes via OS-level + shared memory. Parallel workers get zero-copy, lazy ALTREP access to the same + physical pages — share once, read anywhere. +image: featured.jpg +image-alt: > + Macro close-up of a computer RAM module, showing the blue circuit board and + metallic connectors in sharp detail with a shallow depth-of-field blur. +topics: + - Best Practices +software: + - mori +languages: + - R +tags: + - Parallelism +photo: + url: https://unsplash.com/photos/macro-shot-photo-of-a-computer-ram-lYxQ5F9xBDM + author: Liam Briese +nohero: false +hidesubscription: false +--- + +We're pleased to announce the first CRAN release of [mori](https://shikokuchuo.net/mori/). + +Until now, parallel R has meant serializing your data to every worker and duplicating it in each worker's RAM. Eight workers × 1 GB is 8 GB, plus the serialization, transfer, and deserialization work to get it there. R processes don't share memory — each has its own heap, so data crosses between them through a serialization pipe. + +mori changes that. It places an R object once into OS-level shared memory and lets every process on the machine read the same physical pages directly — with no data copying between processes. + +```{r} +#| eval: false +install.packages("mori") +``` + +mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP.html) (Alternative Representation) framework, which lets a package expose a custom vector backend that reads its data from somewhere other than ordinary R memory — a memory map, a database, a compressed store. Here, that somewhere is OS shared memory. + +## How it looks + +The entry point is `share()`. You pass it an R object, you get back a shared version you can use like any other R vector: + +```{r} +library(mori) + +set.seed(42) +x <- share(rnorm(1e6)) +mean(x) +``` + +`share()` works on atomic vector types, lists, and data frames — it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those primitives. Environments, functions, S4 objects, and external pointers pass through unchanged, since their references don't map naturally to shared pages. + +The returned object is an ALTREP view into shared memory — it costs no additional RAM beyond the original region. It also serializes compactly: instead of sending the full 8 MB payload, mori's ALTREP hooks serialize shared objects as their shared-memory name, just over 100 bytes on the wire. + +```{r} +x |> serialize(NULL) |> length() +``` + +That compact serialization is what makes the rest of the picture work. + +## Parallel workers, one copy + +![](mori-diagram.svg){fig-alt="Diagram: share() writes an R object once into OS-level shared memory; multiple worker processes each memory-map the same region via zero-copy ALTREP wrappers, so every worker sees the same physical pages with no deserialization."} + +mori pairs naturally with [mirai](https://mirai.r-lib.org/). When you send a shared object to a local daemon, only the shared-memory name crosses the wire; the daemon maps the same physical pages and sees the full data with no deserialization cost. The same is true for any other parallel backend that uses R serialization. + +Here's the motivating case — a bootstrap across eight workers on a 200 MB data frame: + +```{r} +library(mirai) + +daemons(8) + +df <- as.data.frame(matrix(rnorm(25e6), ncol = 5)) +shared_df <- share(df) + +boot_mean <- \(i, data) colMeans(data[sample(nrow(data), replace = TRUE), ]) + +# Without mori — each daemon deserializes its own copy +mirai_map(1:8, boot_mean, data = df)[] |> system.time() + +# With mori — each daemon maps the same shared memory +mirai_map(1:8, boot_mean, data = shared_df)[] |> system.time() + +daemons(0) +``` + +The payload each daemon receives is ~300 bytes instead of 200 MB — roughly 700,000× smaller. That's well over 100× wall-clock on this run. The algorithm hasn't changed; the savings come from not copying data that's already in RAM. Eight workers share one copy, not eight. + +The gap shrinks as per-task compute grows: workloads where each worker does substantial work see proportionally smaller wall-clock wins, though never worse than the baseline. The headline number is what you see when data transfer dominates, which it often does in bootstrap, cross-validation, and parameter sweeps. + +Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole frame. + +```{r} +daemons(3) + +x <- list(a = rnorm(1e6), b = rnorm(1e6), c = rnorm(1e6)) |> share() + +mirai_map(x, \(v) lobstr::obj_size(v) |> format())[.flat] + +daemons(0) +``` + +## What this unlocks + +Anywhere parallel R workers process the same large dataset, `share()` removes the per-worker copy: + +- A [Shiny](https://shiny.posit.co/) dashboard where every worker process reads from one shared reference dataset instead of loading its own +- A [tidymodels](https://www.tidymodels.org/) `tune_grid()` sweep — or a [targets](https://docs.ropensci.org/targets/) pipeline branching over model variants — where every fit reads the same training data without copying it +- Bootstrap, Monte Carlo, or permutation work dispatched across [mirai](https://mirai.r-lib.org/) or [crew](https://wlandau.github.io/crew/), where thousands of iterations all read from one shared dataset + +The pattern is the same in each case: call `share()` on your dataset once, then pass the result wherever you'd normally pass the data. Parallel dispatches that hit the serialization path transmit only the reference, not the data. + +## Access and lifetime + +A shared data frame lives in a single shared region, but ALTREP columns are only materialized when touched. A task that reads three columns out of one hundred pays for three — character vectors are lazier still, with per-element access. Workers only pay for the data they actually touch. + +Shared memory is tied to R's garbage collector. As long as the shared object (or anything extracted from it) is live in R, the shared region stays alive. When the last reference is dropped, the region is freed automatically — there are no lingering SHM segments to clean up. + +Shared data is mapped read-only in consumers, so accidental writes can't corrupt data another process is reading. Mutations go through R's normal copy-on-write: editing a value inside a shared vector produces a private copy of that one vector, leaving the rest of the shared region untouched. + +```{r} +x <- share(rnorm(1e6)) +lobstr::obj_size(x) + +x[1] <- 0 # local mutation materializes a private copy +lobstr::obj_size(x) +``` + +**One thing to keep in mind:** always assign the result of `share()` to a variable. The lifetime of the shared region is governed by the R reference, and an unassigned result can be garbage-collected before a consumer process has mapped it. + +## Sharing by name + +If you want to access a shared region from another process without going through serialization at all, you can pass its name directly: + +```{r} +x <- share(1:1e6) + +nm <- shared_name(x) +nm + +# Works from another process; same session here to demonstrate +y <- map_shared(nm) +identical(x[], y[]) +``` + +Handy when the consumer needs to attach by name rather than receive the shared object through R's serialization path. + +## How mori fits + +R has had partial answers to cross-process data sharing before. [bigmemory](https://CRAN.R-project.org/package=bigmemory) offers shared `big.matrix` objects — effective, but limited to numeric matrices. [SharedObject](https://bioconductor.org/packages/SharedObject/) on Bioconductor targets a similar goal with its own memory-sharing machinery, oriented around BiocParallel workflows. [Arrow](https://arrow.apache.org/docs/r/)'s memory-mapped Parquet gives zero-copy columnar reads across processes, though the data lives on disk. On Unix, `parallel::mclapply` gets shared memory for free via fork copy-on-write — until a worker writes to a page, with the usual fork caveats (unsafe in GUI sessions, with open DB connections, or alongside multithreaded libraries), and with no equivalent on Windows. + +mori is usable across any backend that plugs into R's standard serialization — mirai, future, parallel, foreach, callr — with no special cooperation required. Atomic vectors, lists, and character vectors are all supported, with lazy per-element access preserved in every process. Lifetimes are managed by R's garbage collector: shared regions are freed automatically when the last reference drops. And mori itself is pure C — POSIX shared memory on Linux and macOS, Win32 file mapping on Windows, nothing beyond the package to install. + +## Try it + +mori is [available from CRAN](https://CRAN.R-project.org/package=mori). The [package website](https://shikokuchuo.net/mori/) has a walkthrough of the mirai integration and full reference documentation. mori is designed to slot quietly into existing parallel-R workflows — anywhere a worker currently receives a big dataset, `share()` it first and you're done. It complements [mirai](https://mirai.r-lib.org/): mirai handles async evaluation and daemon coordination, mori handles shared access to the data those daemons work on. + +The package is in the `experimental` lifecycle stage while the API settles, so feedback and issue reports on [GitHub](https://github.com/shikokuchuo/mori/issues) are very welcome. diff --git a/content/blog/mori-0-1-0/mori-diagram.svg b/content/blog/mori-0-1-0/mori-diagram.svg new file mode 100644 index 000000000..8bda26003 --- /dev/null +++ b/content/blog/mori-0-1-0/mori-diagram.svg @@ -0,0 +1,45 @@ + + + + Shared Memory + (OS-backed) + + + share(obj) + write once + + + + + + + + + + + + mmap + + + + Process 1 + + + Process 2 + + + Process 3 + + + Process 4 + + + ALTREP wrappers — zero-copy reads + + + + + + + + diff --git a/content/blog/mori-0-1-0/renv.lock b/content/blog/mori-0-1-0/renv.lock new file mode 100644 index 000000000..105b1aa8a --- /dev/null +++ b/content/blog/mori-0-1-0/renv.lock @@ -0,0 +1,1206 @@ +{ + "R": { + "Version": "4.5.2", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cloud.r-project.org" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.6.1", + "Source": "Repository", + "Title": "Encapsulated Classes with Reference Semantics", + "Authors@R": "c( person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Creates classes with reference semantics, similar to R's built-in reference classes. Compared to reference classes, R6 classes are simpler and lighter-weight, and they are not built on S4 classes so they do not require the methods package. These classes allow public and private members, and they support inheritance, even when the classes are defined in different packages.", + "License": "MIT + file LICENSE", + "URL": "https://r6.r-lib.org, https://github.com/r-lib/R6", + "BugReports": "https://github.com/r-lib/R6/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Suggests": [ + "lobstr", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate, ggplot2, microbenchmark, scales", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "RSPM" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-6", + "Source": "Repository", + "Title": "Tools for 'base64' Encoding", + "Author": "Simon Urbanek [aut, cre, cph] (https://urbanek.nz, ORCID: )", + "Authors@R": "person(\"Simon\", \"Urbanek\", role=c(\"aut\",\"cre\",\"cph\"), email=\"Simon.Urbanek@r-project.org\", comment=c(\"https://urbanek.nz\", ORCID=\"0000-0003-2297-1732\"))", + "Maintainer": "Simon Urbanek ", + "Depends": [ + "R (>= 2.9.0)" + ], + "Enhances": [ + "png" + ], + "Description": "Tools for handling 'base64' encoding. It is more flexible than the orphaned 'base64' package.", + "License": "GPL-2 | GPL-3", + "URL": "https://www.rforge.net/base64enc", + "BugReports": "https://github.com/s-u/base64enc/issues", + "NeedsCompilation": "yes", + "Repository": "CRAN" + }, + "bslib": { + "Package": "bslib", + "Version": "0.10.0", + "Source": "Repository", + "Title": "Custom 'Bootstrap' 'Sass' Themes for 'shiny' and 'rmarkdown'", + "Authors@R": "c( person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Garrick\", \"Aden-Buie\", , \"garrick@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0002-7111-0077\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Javi\", \"Aguilar\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap colorpicker library\"), person(\"Thomas\", \"Park\", role = c(\"ctb\", \"cph\"), comment = \"Bootswatch library\"), person(, \"PayPal\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap accessibility plugin\") )", + "Description": "Simplifies custom 'CSS' styling of both 'shiny' and 'rmarkdown' via 'Bootstrap' 'Sass'. Supports 'Bootstrap' 3, 4 and 5 as well as their various 'Bootswatch' themes. An interactive widget is also provided for previewing themes in real time.", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/bslib/, https://github.com/rstudio/bslib", + "BugReports": "https://github.com/rstudio/bslib/issues", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "base64enc", + "cachem", + "fastmap (>= 1.1.1)", + "grDevices", + "htmltools (>= 0.5.8)", + "jquerylib (>= 0.1.3)", + "jsonlite", + "lifecycle", + "memoise (>= 2.0.1)", + "mime", + "rlang", + "sass (>= 0.4.9)" + ], + "Suggests": [ + "brand.yml", + "bsicons", + "curl", + "fontawesome", + "future", + "ggplot2", + "knitr", + "lattice", + "magrittr", + "rappdirs", + "rmarkdown (>= 2.7)", + "shiny (>= 1.11.1)", + "testthat", + "thematic", + "tools", + "utils", + "withr", + "yaml" + ], + "Config/Needs/deploy": "BH, chiflights22, colourpicker, commonmark, cpp11, cpsievert/chiflights22, cpsievert/histoslider, dplyr, DT, ggplot2, ggridges, gt, hexbin, histoslider, htmlwidgets, lattice, leaflet, lubridate, markdown, modelr, plotly, reactable, reshape2, rprojroot, rsconnect, rstudio/shiny, scales, styler, tibble", + "Config/Needs/routine": "chromote, desc, renv", + "Config/Needs/website": "brio, crosstalk, dplyr, DT, ggplot2, glue, htmlwidgets, leaflet, lorem, palmerpenguins, plotly, purrr, rprojroot, rstudio/htmltools, scales, stringr, tidyr, webshot2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "zzzz-bs-sass, fonts, zzz-precompile, theme-*, rmd-*", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "Collate": "'accordion.R' 'breakpoints.R' 'bs-current-theme.R' 'bs-dependencies.R' 'bs-global.R' 'bs-remove.R' 'bs-theme-layers.R' 'bs-theme-preset-bootswatch.R' 'bs-theme-preset-brand.R' 'bs-theme-preset-builtin.R' 'bs-theme-preset.R' 'utils.R' 'bs-theme-preview.R' 'bs-theme-update.R' 'bs-theme.R' 'bslib-package.R' 'buttons.R' 'card.R' 'deprecated.R' 'files.R' 'fill.R' 'imports.R' 'input-code-editor.R' 'input-dark-mode.R' 'input-submit.R' 'input-switch.R' 'layout.R' 'nav-items.R' 'nav-update.R' 'navbar_options.R' 'navs-legacy.R' 'navs.R' 'onLoad.R' 'page.R' 'popover.R' 'precompiled.R' 'print.R' 'shiny-devmode.R' 'sidebar.R' 'staticimports.R' 'toast.R' 'tooltip.R' 'utils-deps.R' 'utils-shiny.R' 'utils-tags.R' 'value-box.R' 'version-default.R' 'versions.R'", + "NeedsCompilation": "no", + "Author": "Carson Sievert [aut, cre] (ORCID: ), Joe Cheng [aut], Garrick Aden-Buie [aut] (ORCID: ), Posit Software, PBC [cph, fnd], Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Javi Aguilar [ctb, cph] (Bootstrap colorpicker library), Thomas Park [ctb, cph] (Bootswatch library), PayPal [ctb, cph] (Bootstrap accessibility plugin)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "cachem": { + "Package": "cachem", + "Version": "1.1.0", + "Source": "Repository", + "Title": "Cache R Objects with Automatic Pruning", + "Description": "Key-value stores with automatic pruning. Caches can limit either their total size or the age of the oldest object (or both), automatically pruning objects to maintain the constraints.", + "Authors@R": "c( person(\"Winston\", \"Chang\", , \"winston@posit.co\", c(\"aut\", \"cre\")), person(family = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")))", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "ByteCompile": "true", + "URL": "https://cachem.r-lib.org/, https://github.com/r-lib/cachem", + "Imports": [ + "rlang", + "fastmap (>= 1.2.0)" + ], + "Suggests": [ + "testthat" + ], + "RoxygenNote": "7.2.3", + "Config/Needs/routine": "lobstr", + "Config/Needs/website": "pkgdown", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "RSPM" + }, + "cli": { + "Package": "cli", + "Version": "3.6.6", + "Source": "Repository", + "Title": "Helpers for Developing Command Line Interfaces", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"gabor@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Kirill\", \"Müller\", role = \"ctb\"), person(\"Salim\", \"Brüggemann\", , \"salim-b@pm.me\", role = \"ctb\", comment = c(ORCID = \"0000-0002-5329-5987\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "A suite of tools to build attractive command line interfaces ('CLIs'), from semantic elements: headings, lists, alerts, paragraphs, etc. Supports custom themes via a 'CSS'-like language. It also contains a number of lower level 'CLI' elements: rules, boxes, trees, and 'Unicode' symbols with 'ASCII' alternatives. It support ANSI colors and text styles as well.", + "License": "MIT + file LICENSE", + "URL": "https://cli.r-lib.org, https://github.com/r-lib/cli", + "BugReports": "https://github.com/r-lib/cli/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "utils" + ], + "Suggests": [ + "callr", + "covr", + "crayon", + "digest", + "glue (>= 1.6.0)", + "grDevices", + "htmltools", + "htmlwidgets", + "knitr", + "methods", + "processx", + "ps (>= 1.3.4.9000)", + "rlang (>= 1.0.2.9003)", + "rmarkdown", + "rprojroot", + "rstudioapi", + "testthat (>= 3.2.0)", + "tibble", + "whoami", + "withr" + ], + "Config/Needs/website": "r-lib/asciicast, bench, brio, cpp11, decor, desc, fansi, prettyunits, sessioninfo, tidyverse/tidytemplate, usethis, vctrs", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2025-04-25", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2.9000", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre], Hadley Wickham [ctb], Kirill Müller [ctb], Salim Brüggemann [ctb] (ORCID: ), Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "cpp11": { + "Package": "cpp11", + "Version": "0.5.4", + "Source": "Repository", + "Title": "A C++11 Interface for R's C Interface", + "Authors@R": "c( person(\"Davis\", \"Vaughan\", email = \"davis@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4777-038X\")), person(\"Jim\",\"Hester\", role = \"aut\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Romain\", \"François\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Benjamin\", \"Kietzman\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a header only, C++11 interface to R's C interface. Compared to other approaches 'cpp11' strives to be safe against long jumps from the C API as well as C++ exceptions, conform to normal R function semantics and supports interaction with 'ALTREP' vectors.", + "License": "MIT + file LICENSE", + "URL": "https://cpp11.r-lib.org, https://github.com/r-lib/cpp11", + "BugReports": "https://github.com/r-lib/cpp11/issues", + "Depends": [ + "R (>= 4.0.0)" + ], + "Suggests": [ + "bench", + "brio", + "callr", + "cli", + "covr", + "decor", + "desc", + "ggplot2", + "glue", + "knitr", + "lobstr", + "mockery", + "progress", + "rmarkdown", + "scales", + "Rcpp", + "testthat (>= 3.2.0)", + "tibble", + "utils", + "vctrs", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/Needs/cpp11/cpp_register": "brio, cli, decor, desc, glue, tibble, vctrs", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "no", + "Author": "Davis Vaughan [aut, cre] (ORCID: ), Jim Hester [aut] (ORCID: ), Romain François [aut] (ORCID: ), Benjamin Kietzman [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN" + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.3", + "Source": "Repository", + "Title": "Colored Terminal Output", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Brodie\", \"Gaslam\", , \"brodie.gaslam@yahoo.com\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "The crayon package is now superseded. Please use the 'cli' package for new projects. Colored terminal output on terminals that support 'ANSI' color and highlight codes. It also works in 'Emacs' 'ESS'. 'ANSI' color support is automatically detected. Colors and highlighting can be combined and nested. New styles can also be created easily. This package was inspired by the 'chalk' 'JavaScript' project.", + "License": "MIT + file LICENSE", + "URL": "https://r-lib.github.io/crayon/, https://github.com/r-lib/crayon", + "BugReports": "https://github.com/r-lib/crayon/issues", + "Imports": [ + "grDevices", + "methods", + "utils" + ], + "Suggests": [ + "mockery", + "rstudioapi", + "testthat", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Collate": "'aaa-rstudio-detect.R' 'aaaa-rematch2.R' 'aab-num-ansi-colors.R' 'aac-num-ansi-colors.R' 'ansi-256.R' 'ansi-palette.R' 'combine.R' 'string.R' 'utils.R' 'crayon-package.R' 'disposable.R' 'enc-utils.R' 'has_ansi.R' 'has_color.R' 'link.R' 'styles.R' 'machinery.R' 'parts.R' 'print.R' 'style-var.R' 'show.R' 'string_operations.R'", + "NeedsCompilation": "no", + "Author": "Gábor Csárdi [aut, cre], Brodie Gaslam [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "RSPM" + }, + "digest": { + "Package": "digest", + "Version": "0.6.39", + "Source": "Repository", + "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Antoine\", \"Lucas\", role=\"ctb\", comment = c(ORCID = \"0000-0002-8059-9767\")), person(\"Jarek\", \"Tuszynski\", role=\"ctb\"), person(\"Henrik\", \"Bengtsson\", role=\"ctb\", comment = c(ORCID = \"0000-0002-7579-5165\")), person(\"Simon\", \"Urbanek\", role=\"ctb\", comment = c(ORCID = \"0000-0003-2297-1732\")), person(\"Mario\", \"Frasca\", role=\"ctb\"), person(\"Bryan\", \"Lewis\", role=\"ctb\"), person(\"Murray\", \"Stokely\", role=\"ctb\"), person(\"Hannes\", \"Muehleisen\", role=\"ctb\", comment = c(ORCID = \"0000-0001-8552-0029\")), person(\"Duncan\", \"Murdoch\", role=\"ctb\"), person(\"Jim\", \"Hester\", role=\"ctb\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Wush\", \"Wu\", role=\"ctb\", comment = c(ORCID = \"0000-0001-5180-0567\")), person(\"Qiang\", \"Kou\", role=\"ctb\", comment = c(ORCID = \"0000-0001-6786-5453\")), person(\"Thierry\", \"Onkelinx\", role=\"ctb\", comment = c(ORCID = \"0000-0001-8804-4216\")), person(\"Michel\", \"Lang\", role=\"ctb\", comment = c(ORCID = \"0000-0001-9754-0393\")), person(\"Viliam\", \"Simko\", role=\"ctb\"), person(\"Kurt\", \"Hornik\", role=\"ctb\", comment = c(ORCID = \"0000-0003-4198-9911\")), person(\"Radford\", \"Neal\", role=\"ctb\", comment = c(ORCID = \"0000-0002-2473-3407\")), person(\"Kendon\", \"Bell\", role=\"ctb\", comment = c(ORCID = \"0000-0002-9093-8312\")), person(\"Matthew\", \"de Queljoe\", role=\"ctb\"), person(\"Dmitry\", \"Selivanov\", role=\"ctb\", comment = c(ORCID = \"0000-0003-0492-6647\")), person(\"Ion\", \"Suruceanu\", role=\"ctb\", comment = c(ORCID = \"0009-0005-6446-4909\")), person(\"Bill\", \"Denney\", role=\"ctb\", comment = c(ORCID = \"0000-0002-5759-428X\")), person(\"Dirk\", \"Schumacher\", role=\"ctb\"), person(\"András\", \"Svraka\", role=\"ctb\", comment = c(ORCID = \"0009-0008-8480-1329\")), person(\"Sergey\", \"Fedorov\", role=\"ctb\", comment = c(ORCID = \"0000-0002-5970-7233\")), person(\"Will\", \"Landau\", role=\"ctb\", comment = c(ORCID = \"0000-0003-1878-3253\")), person(\"Floris\", \"Vanderhaeghe\", role=\"ctb\", comment = c(ORCID = \"0000-0002-6378-6229\")), person(\"Kevin\", \"Tappe\", role=\"ctb\"), person(\"Harris\", \"McGehee\", role=\"ctb\"), person(\"Tim\", \"Mastny\", role=\"ctb\"), person(\"Aaron\", \"Peikert\", role=\"ctb\", comment = c(ORCID = \"0000-0001-7813-818X\")), person(\"Mark\", \"van der Loo\", role=\"ctb\", comment = c(ORCID = \"0000-0002-9807-4686\")), person(\"Chris\", \"Muir\", role=\"ctb\", comment = c(ORCID = \"0000-0003-2555-3878\")), person(\"Moritz\", \"Beller\", role=\"ctb\", comment = c(ORCID = \"0000-0003-4852-0526\")), person(\"Sebastian\", \"Campbell\", role=\"ctb\", comment = c(ORCID = \"0009-0000-5948-4503\")), person(\"Winston\", \"Chang\", role=\"ctb\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Dean\", \"Attali\", role=\"ctb\", comment = c(ORCID = \"0000-0002-5645-3493\")), person(\"Michael\", \"Chirico\", role=\"ctb\", comment = c(ORCID = \"0000-0003-0787-087X\")), person(\"Kevin\", \"Ushey\", role=\"ctb\", comment = c(ORCID = \"0000-0003-2880-7407\")), person(\"Carl\", \"Pearson\", role=\"ctb\", comment = c(ORCID = \"0000-0003-0701-7860\")))", + "Date": "2025-11-19", + "Title": "Create Compact Hash Digests of R Objects", + "Description": "Implementation of a function 'digest()' for the creation of hash digests of arbitrary R objects (using the 'md5', 'sha-1', 'sha-256', 'crc32', 'xxhash', 'murmurhash', 'spookyhash', 'blake3', 'crc32c', 'xxh3_64', and 'xxh3_128' algorithms) permitting easy comparison of R language objects, as well as functions such as 'hmac()' to create hash-based message authentication code. Please note that this package is not meant to be deployed for cryptographic purposes for which more comprehensive (and widely tested) libraries such as 'OpenSSL' should be used.", + "URL": "https://github.com/eddelbuettel/digest, https://eddelbuettel.github.io/digest/, https://dirk.eddelbuettel.com/code/digest.html", + "BugReports": "https://github.com/eddelbuettel/digest/issues", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "utils" + ], + "License": "GPL (>= 2)", + "Suggests": [ + "tinytest", + "simplermarkdown", + "rbenchmark" + ], + "VignetteBuilder": "simplermarkdown", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Dirk Eddelbuettel [aut, cre] (ORCID: ), Antoine Lucas [ctb] (ORCID: ), Jarek Tuszynski [ctb], Henrik Bengtsson [ctb] (ORCID: ), Simon Urbanek [ctb] (ORCID: ), Mario Frasca [ctb], Bryan Lewis [ctb], Murray Stokely [ctb], Hannes Muehleisen [ctb] (ORCID: ), Duncan Murdoch [ctb], Jim Hester [ctb] (ORCID: ), Wush Wu [ctb] (ORCID: ), Qiang Kou [ctb] (ORCID: ), Thierry Onkelinx [ctb] (ORCID: ), Michel Lang [ctb] (ORCID: ), Viliam Simko [ctb], Kurt Hornik [ctb] (ORCID: ), Radford Neal [ctb] (ORCID: ), Kendon Bell [ctb] (ORCID: ), Matthew de Queljoe [ctb], Dmitry Selivanov [ctb] (ORCID: ), Ion Suruceanu [ctb] (ORCID: ), Bill Denney [ctb] (ORCID: ), Dirk Schumacher [ctb], András Svraka [ctb] (ORCID: ), Sergey Fedorov [ctb] (ORCID: ), Will Landau [ctb] (ORCID: ), Floris Vanderhaeghe [ctb] (ORCID: ), Kevin Tappe [ctb], Harris McGehee [ctb], Tim Mastny [ctb], Aaron Peikert [ctb] (ORCID: ), Mark van der Loo [ctb] (ORCID: ), Chris Muir [ctb] (ORCID: ), Moritz Beller [ctb] (ORCID: ), Sebastian Campbell [ctb] (ORCID: ), Winston Chang [ctb] (ORCID: ), Dean Attali [ctb] (ORCID: ), Michael Chirico [ctb] (ORCID: ), Kevin Ushey [ctb] (ORCID: ), Carl Pearson [ctb] (ORCID: )", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "https://packagemanager.posit.co/cran/latest" + }, + "evaluate": { + "Package": "evaluate", + "Version": "1.0.5", + "Source": "Repository", + "Type": "Package", + "Title": "Parsing and Evaluation Tools that Provide More Details than the Default", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Yihui\", \"Xie\", role = \"aut\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Michael\", \"Lawrence\", role = \"ctb\"), person(\"Thomas\", \"Kluyver\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\"), person(\"Barret\", \"Schloerke\", role = \"ctb\"), person(\"Adam\", \"Ryczkowski\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Michel\", \"Lang\", role = \"ctb\"), person(\"Karolis\", \"Koncevičius\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Parsing and evaluation tools that make it easy to recreate the command line behaviour of R.", + "License": "MIT + file LICENSE", + "URL": "https://evaluate.r-lib.org/, https://github.com/r-lib/evaluate", + "BugReports": "https://github.com/r-lib/evaluate/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Suggests": [ + "callr", + "covr", + "ggplot2 (>= 3.3.6)", + "lattice", + "methods", + "pkgload", + "ragg (>= 1.4.0)", + "rlang (>= 1.1.5)", + "knitr", + "testthat (>= 3.0.0)", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Yihui Xie [aut] (ORCID: ), Michael Lawrence [ctb], Thomas Kluyver [ctb], Jeroen Ooms [ctb], Barret Schloerke [ctb], Adam Ryczkowski [ctb], Hiroaki Yutani [ctb], Michel Lang [ctb], Karolis Koncevičius [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "RSPM" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.2.0", + "Source": "Repository", + "Title": "Fast Data Structures", + "Authors@R": "c( person(\"Winston\", \"Chang\", email = \"winston@posit.co\", role = c(\"aut\", \"cre\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(given = \"Tessil\", role = \"cph\", comment = \"hopscotch_map library\") )", + "Description": "Fast implementation of data structures, including a key-value store, stack, and queue. Environments are commonly used as key-value stores in R, but every time a new key is used, it is added to R's global symbol table, causing a small amount of memory leakage. This can be problematic in cases where many different keys are used. Fastmap avoids this memory leak issue by implementing the map using data structures in C++.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Suggests": [ + "testthat (>= 2.1.1)" + ], + "URL": "https://r-lib.github.io/fastmap/, https://github.com/r-lib/fastmap", + "BugReports": "https://github.com/r-lib/fastmap/issues", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd], Tessil [cph] (hopscotch_map library)", + "Maintainer": "Winston Chang ", + "Repository": "RSPM" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.3", + "Source": "Repository", + "Type": "Package", + "Title": "Easily Work with 'Font Awesome' Icons", + "Description": "Easily and flexibly insert 'Font Awesome' icons into 'R Markdown' documents and 'Shiny' apps. These icons can be inserted into HTML content through inline 'SVG' tags or 'i' tags. There is also a utility function for exporting 'Font Awesome' icons as 'PNG' images for those situations where raster graphics are needed.", + "Authors@R": "c( person(\"Richard\", \"Iannone\", , \"rich@posit.co\", c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"ctb\"), person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome font\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/fontawesome, https://rstudio.github.io/fontawesome/", + "BugReports": "https://github.com/rstudio/fontawesome/issues", + "Encoding": "UTF-8", + "ByteCompile": "true", + "RoxygenNote": "7.3.2", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "rlang (>= 1.0.6)", + "htmltools (>= 0.5.1.1)" + ], + "Suggests": [ + "covr", + "dplyr (>= 1.0.8)", + "gt (>= 0.9.0)", + "knitr (>= 1.31)", + "testthat (>= 3.0.0)", + "rsvg" + ], + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Richard Iannone [aut, cre] (), Christophe Dervieux [ctb] (), Winston Chang [ctb], Dave Gandy [ctb, cph] (Font-Awesome font), Posit Software, PBC [cph, fnd]", + "Maintainer": "Richard Iannone ", + "Repository": "RSPM" + }, + "fs": { + "Package": "fs", + "Version": "2.1.0", + "Source": "Repository", + "Title": "Cross-Platform File System Operations Based on 'libuv'", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Gábor\", \"Csárdi\", role = \"aut\"), person(\"Jeroen\", \"Ooms\", , \"jeroenooms@gmail.com\", role = \"cre\"), person(\"libuv project contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Joyent, Inc. and other Node contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "A cross-platform interface to file system operations, built on top of the 'libuv' C library.", + "License": "MIT + file LICENSE", + "URL": "https://fs.r-lib.org, https://github.com/r-lib/fs", + "BugReports": "https://github.com/r-lib/fs/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "covr", + "crayon", + "knitr", + "pillar (>= 1.0.0)", + "rmarkdown", + "spelling", + "testthat (>= 3.0.0)", + "tibble (>= 1.1.0)", + "vctrs (>= 0.3.0)", + "withr" + ], + "VignetteBuilder": "knitr", + "SystemRequirements": "libuv: libuv-devel (rpm) or libuv1-dev (deb). Alternatively to build the vendored libuv 'cmake' is required. GNU make.", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2025-04-23", + "Copyright": "file COPYRIGHTS", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "yes", + "Author": "Jim Hester [aut], Hadley Wickham [aut], Gábor Csárdi [aut], Jeroen Ooms [cre], libuv project contributors [cph] (libuv library), Joyent, Inc. and other Node contributors [cph] (libuv library), Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "highr": { + "Package": "highr", + "Version": "0.12", + "Source": "Repository", + "Type": "Package", + "Title": "Syntax Highlighting for R Source Code", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Yixuan\", \"Qiu\", role = \"aut\"), person(\"Christopher\", \"Gandrud\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\") )", + "Description": "Provides syntax highlighting for R source code. Currently it supports LaTeX and HTML output. Source code of other languages is supported via Andre Simon's highlight package ().", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "xfun (>= 0.18)" + ], + "Suggests": [ + "knitr", + "markdown", + "testit" + ], + "License": "GPL", + "URL": "https://github.com/yihui/highr", + "BugReports": "https://github.com/yihui/highr/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (ORCID: ), Yixuan Qiu [aut], Christopher Gandrud [ctb], Qiang Li [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.9", + "Source": "Repository", + "Type": "Package", + "Title": "Tools for HTML", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Barret\", \"Schloerke\", , \"barret@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Yihui\", \"Xie\", , \"yihui@posit.co\", role = \"aut\"), person(\"Jeff\", \"Allen\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools for HTML generation and output.", + "License": "GPL (>= 2)", + "URL": "https://github.com/rstudio/htmltools, https://rstudio.github.io/htmltools/", + "BugReports": "https://github.com/rstudio/htmltools/issues", + "Depends": [ + "R (>= 2.14.1)" + ], + "Imports": [ + "base64enc", + "digest", + "fastmap (>= 1.1.0)", + "grDevices", + "rlang (>= 1.0.0)", + "utils" + ], + "Suggests": [ + "Cairo", + "markdown", + "ragg", + "shiny", + "testthat", + "withr" + ], + "Enhances": [ + "knitr" + ], + "Config/Needs/check": "knitr", + "Config/Needs/website": "rstudio/quillt, bench", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "Collate": "'colors.R' 'fill.R' 'html_dependency.R' 'html_escape.R' 'html_print.R' 'htmltools-package.R' 'images.R' 'known_tags.R' 'selector.R' 'staticimports.R' 'tag_query.R' 'utils.R' 'tags.R' 'template.R'", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut], Carson Sievert [aut, cre] (ORCID: ), Barret Schloerke [aut] (ORCID: ), Winston Chang [aut] (ORCID: ), Yihui Xie [aut], Jeff Allen [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Title": "Obtain 'jQuery' as an HTML Dependency Object", + "Authors@R": "c( person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"), person(family = \"RStudio\", role = \"cph\"), person(family = \"jQuery Foundation\", role = \"cph\", comment = \"jQuery library and jQuery UI library\"), person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt\") )", + "Description": "Obtain any major version of 'jQuery' () and use it in any webpage generated by 'htmltools' (e.g. 'shiny', 'htmlwidgets', and 'rmarkdown'). Most R users don't need to use this package directly, but other R packages (e.g. 'shiny', 'rmarkdown', etc.) depend on this package to avoid bundling redundant copies of 'jQuery'.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Config/testthat/edition": "3", + "RoxygenNote": "7.0.2", + "Imports": [ + "htmltools" + ], + "Suggests": [ + "testthat" + ], + "NeedsCompilation": "no", + "Author": "Carson Sievert [aut, cre] (), Joe Cheng [aut], RStudio [cph], jQuery Foundation [cph] (jQuery library and jQuery UI library), jQuery contributors [ctb, cph] (jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt)", + "Maintainer": "Carson Sievert ", + "Repository": "RSPM" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "2.0.0", + "Source": "Repository", + "Title": "A Simple and Robust JSON Parser and Generator for R", + "License": "MIT + file LICENSE", + "Depends": [ + "methods" + ], + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Duncan\", \"Temple Lang\", role = \"ctb\"), person(\"Lloyd\", \"Hilaiel\", role = \"cph\", comment=\"author of bundled libyajl\"))", + "URL": "https://jeroen.r-universe.dev/jsonlite https://arxiv.org/abs/1403.2805", + "BugReports": "https://github.com/jeroen/jsonlite/issues", + "Maintainer": "Jeroen Ooms ", + "VignetteBuilder": "knitr, R.rsp", + "Description": "A reasonably fast JSON parser and generator, optimized for statistical data and the web. Offers simple, flexible tools for working with JSON in R, and is particularly powerful for building pipelines and interacting with a web API. The implementation is based on the mapping described in the vignette (Ooms, 2014). In addition to converting JSON data from/to R objects, 'jsonlite' contains functions to stream, validate, and prettify JSON data. The unit tests included with the package verify that all edge cases are encoded and decoded consistently for use with dynamic data in systems and applications.", + "Suggests": [ + "httr", + "vctrs", + "testthat", + "knitr", + "rmarkdown", + "R.rsp", + "sf" + ], + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), Duncan Temple Lang [ctb], Lloyd Hilaiel [cph] (author of bundled libyajl)", + "Repository": "CRAN" + }, + "knitr": { + "Package": "knitr", + "Version": "1.51", + "Source": "Repository", + "Type": "Package", + "Title": "A General-Purpose Package for Dynamic Report Generation in R", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Abhraneel\", \"Sarma\", role = \"ctb\"), person(\"Adam\", \"Vogt\", role = \"ctb\"), person(\"Alastair\", \"Andrew\", role = \"ctb\"), person(\"Alex\", \"Zvoleff\", role = \"ctb\"), person(\"Amar\", \"Al-Zubaidi\", role = \"ctb\"), person(\"Andre\", \"Simon\", role = \"ctb\", comment = \"the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de\"), person(\"Aron\", \"Atkins\", role = \"ctb\"), person(\"Aaron\", \"Wolen\", role = \"ctb\"), person(\"Ashley\", \"Manton\", role = \"ctb\"), person(\"Atsushi\", \"Yasumoto\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8335-495X\")), person(\"Ben\", \"Baumer\", role = \"ctb\"), person(\"Brian\", \"Diggs\", role = \"ctb\"), person(\"Brian\", \"Zhang\", role = \"ctb\"), person(\"Bulat\", \"Yapparov\", role = \"ctb\"), person(\"Cassio\", \"Pereira\", role = \"ctb\"), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person(\"David\", \"Hall\", role = \"ctb\"), person(\"David\", \"Hugh-Jones\", role = \"ctb\"), person(\"David\", \"Robinson\", role = \"ctb\"), person(\"Doug\", \"Hemken\", role = \"ctb\"), person(\"Duncan\", \"Murdoch\", role = \"ctb\"), person(\"Elio\", \"Campitelli\", role = \"ctb\"), person(\"Ellis\", \"Hughes\", role = \"ctb\"), person(\"Emily\", \"Riederer\", role = \"ctb\"), person(\"Fabian\", \"Hirschmann\", role = \"ctb\"), person(\"Fitch\", \"Simeon\", role = \"ctb\"), person(\"Forest\", \"Fang\", role = \"ctb\"), person(c(\"Frank\", \"E\", \"Harrell\", \"Jr\"), role = \"ctb\", comment = \"the Sweavel package at inst/misc/Sweavel.sty\"), person(\"Garrick\", \"Aden-Buie\", role = \"ctb\"), person(\"Gregoire\", \"Detrez\", role = \"ctb\"), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Hao\", \"Zhu\", role = \"ctb\"), person(\"Heewon\", \"Jeon\", role = \"ctb\"), person(\"Henrik\", \"Bengtsson\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Ian\", \"Lyttle\", role = \"ctb\"), person(\"Hodges\", \"Daniel\", role = \"ctb\"), person(\"Jacob\", \"Bien\", role = \"ctb\"), person(\"Jake\", \"Burkhead\", role = \"ctb\"), person(\"James\", \"Manton\", role = \"ctb\"), person(\"Jared\", \"Lander\", role = \"ctb\"), person(\"Jason\", \"Punyon\", role = \"ctb\"), person(\"Javier\", \"Luraschi\", role = \"ctb\"), person(\"Jeff\", \"Arnold\", role = \"ctb\"), person(\"Jenny\", \"Bryan\", role = \"ctb\"), person(\"Jeremy\", \"Ashkenas\", role = c(\"ctb\", \"cph\"), comment = \"the CSS file at inst/misc/docco-classic.css\"), person(\"Jeremy\", \"Stephens\", role = \"ctb\"), person(\"Jim\", \"Hester\", role = \"ctb\"), person(\"Joe\", \"Cheng\", role = \"ctb\"), person(\"Johannes\", \"Ranke\", role = \"ctb\"), person(\"John\", \"Honaker\", role = \"ctb\"), person(\"John\", \"Muschelli\", role = \"ctb\"), person(\"Jonathan\", \"Keane\", role = \"ctb\"), person(\"JJ\", \"Allaire\", role = \"ctb\"), person(\"Johan\", \"Toloe\", role = \"ctb\"), person(\"Jonathan\", \"Sidi\", role = \"ctb\"), person(\"Joseph\", \"Larmarange\", role = \"ctb\"), person(\"Julien\", \"Barnier\", role = \"ctb\"), person(\"Kaiyin\", \"Zhong\", role = \"ctb\"), person(\"Kamil\", \"Slowikowski\", role = \"ctb\"), person(\"Karl\", \"Forner\", role = \"ctb\"), person(c(\"Kevin\", \"K.\"), \"Smith\", role = \"ctb\"), person(\"Kirill\", \"Mueller\", role = \"ctb\"), person(\"Kohske\", \"Takahashi\", role = \"ctb\"), person(\"Lorenz\", \"Walthert\", role = \"ctb\"), person(\"Lucas\", \"Gallindo\", role = \"ctb\"), person(\"Marius\", \"Hofert\", role = \"ctb\"), person(\"Martin\", \"Modrák\", role = \"ctb\"), person(\"Michael\", \"Chirico\", role = \"ctb\"), person(\"Michael\", \"Friendly\", role = \"ctb\"), person(\"Michal\", \"Bojanowski\", role = \"ctb\"), person(\"Michel\", \"Kuhlmann\", role = \"ctb\"), person(\"Miller\", \"Patrick\", role = \"ctb\"), person(\"Nacho\", \"Caballero\", role = \"ctb\"), person(\"Nick\", \"Salkowski\", role = \"ctb\"), person(\"Niels Richard\", \"Hansen\", role = \"ctb\"), person(\"Noam\", \"Ross\", role = \"ctb\"), person(\"Obada\", \"Mahdi\", role = \"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role = \"ctb\", comment=c(ORCID = \"0000-0002-9101-3362\")), person(\"Pedro\", \"Faria\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\"), person(\"Ramnath\", \"Vaidyanathan\", role = \"ctb\"), person(\"Richard\", \"Cotton\", role = \"ctb\"), person(\"Robert\", \"Krzyzanowski\", role = \"ctb\"), person(\"Rodrigo\", \"Copetti\", role = \"ctb\"), person(\"Romain\", \"Francois\", role = \"ctb\"), person(\"Ruaridh\", \"Williamson\", role = \"ctb\"), person(\"Sagiru\", \"Mati\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1413-3974\")), person(\"Scott\", \"Kostyshak\", role = \"ctb\"), person(\"Sebastian\", \"Meyer\", role = \"ctb\"), person(\"Sietse\", \"Brouwer\", role = \"ctb\"), person(c(\"Simon\", \"de\"), \"Bernard\", role = \"ctb\"), person(\"Sylvain\", \"Rousseau\", role = \"ctb\"), person(\"Taiyun\", \"Wei\", role = \"ctb\"), person(\"Thibaut\", \"Assus\", role = \"ctb\"), person(\"Thibaut\", \"Lamadon\", role = \"ctb\"), person(\"Thomas\", \"Leeper\", role = \"ctb\"), person(\"Tim\", \"Mastny\", role = \"ctb\"), person(\"Tom\", \"Torsney-Weir\", role = \"ctb\"), person(\"Trevor\", \"Davis\", role = \"ctb\"), person(\"Viktoras\", \"Veitas\", role = \"ctb\"), person(\"Weicheng\", \"Zhu\", role = \"ctb\"), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Zachary\", \"Foster\", role = \"ctb\"), person(\"Zhian N.\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a general-purpose tool for dynamic report generation in R using Literate Programming techniques.", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "evaluate (>= 0.15)", + "highr (>= 0.11)", + "methods", + "tools", + "xfun (>= 0.52)", + "yaml (>= 2.1.19)" + ], + "Suggests": [ + "bslib", + "DBI (>= 0.4-1)", + "digest", + "formatR", + "gifski", + "gridSVG", + "htmlwidgets (>= 0.7)", + "jpeg", + "JuliaCall (>= 0.11.1)", + "magick", + "litedown", + "markdown (>= 1.3)", + "otel", + "otelsdk", + "png", + "ragg", + "reticulate (>= 1.4)", + "rgl (>= 0.95.1201)", + "rlang", + "rmarkdown", + "sass", + "showtext", + "styler (>= 1.2.0)", + "targets (>= 0.6.0)", + "testit", + "tibble", + "tikzDevice (>= 0.10)", + "tinytex (>= 0.56)", + "webshot", + "rstudioapi", + "svglite" + ], + "License": "GPL", + "URL": "https://yihui.org/knitr/", + "BugReports": "https://github.com/yihui/knitr/issues", + "Encoding": "UTF-8", + "VignetteBuilder": "litedown, knitr", + "SystemRequirements": "Package vignettes based on R Markdown v2 or reStructuredText require Pandoc (http://pandoc.org). The function rst2pdf() requires rst2pdf (https://github.com/rst2pdf/rst2pdf).", + "Collate": "'block.R' 'cache.R' 'citation.R' 'hooks-html.R' 'plot.R' 'utils.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R' 'themes.R' 'header.R' 'hooks-asciidoc.R' 'hooks-chunk.R' 'hooks-extra.R' 'hooks-latex.R' 'hooks-md.R' 'hooks-rst.R' 'hooks-textile.R' 'hooks.R' 'otel.R' 'output.R' 'package.R' 'pandoc.R' 'params.R' 'parser.R' 'pattern.R' 'rocco.R' 'spin.R' 'table.R' 'template.R' 'utils-conversion.R' 'utils-rd2html.R' 'utils-string.R' 'utils-sweave.R' 'utils-upload.R' 'utils-vignettes.R' 'zzz.R'", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (ORCID: , URL: https://yihui.org), Abhraneel Sarma [ctb], Adam Vogt [ctb], Alastair Andrew [ctb], Alex Zvoleff [ctb], Amar Al-Zubaidi [ctb], Andre Simon [ctb] (the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de), Aron Atkins [ctb], Aaron Wolen [ctb], Ashley Manton [ctb], Atsushi Yasumoto [ctb] (ORCID: ), Ben Baumer [ctb], Brian Diggs [ctb], Brian Zhang [ctb], Bulat Yapparov [ctb], Cassio Pereira [ctb], Christophe Dervieux [ctb], David Hall [ctb], David Hugh-Jones [ctb], David Robinson [ctb], Doug Hemken [ctb], Duncan Murdoch [ctb], Elio Campitelli [ctb], Ellis Hughes [ctb], Emily Riederer [ctb], Fabian Hirschmann [ctb], Fitch Simeon [ctb], Forest Fang [ctb], Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty), Garrick Aden-Buie [ctb], Gregoire Detrez [ctb], Hadley Wickham [ctb], Hao Zhu [ctb], Heewon Jeon [ctb], Henrik Bengtsson [ctb], Hiroaki Yutani [ctb], Ian Lyttle [ctb], Hodges Daniel [ctb], Jacob Bien [ctb], Jake Burkhead [ctb], James Manton [ctb], Jared Lander [ctb], Jason Punyon [ctb], Javier Luraschi [ctb], Jeff Arnold [ctb], Jenny Bryan [ctb], Jeremy Ashkenas [ctb, cph] (the CSS file at inst/misc/docco-classic.css), Jeremy Stephens [ctb], Jim Hester [ctb], Joe Cheng [ctb], Johannes Ranke [ctb], John Honaker [ctb], John Muschelli [ctb], Jonathan Keane [ctb], JJ Allaire [ctb], Johan Toloe [ctb], Jonathan Sidi [ctb], Joseph Larmarange [ctb], Julien Barnier [ctb], Kaiyin Zhong [ctb], Kamil Slowikowski [ctb], Karl Forner [ctb], Kevin K. Smith [ctb], Kirill Mueller [ctb], Kohske Takahashi [ctb], Lorenz Walthert [ctb], Lucas Gallindo [ctb], Marius Hofert [ctb], Martin Modrák [ctb], Michael Chirico [ctb], Michael Friendly [ctb], Michal Bojanowski [ctb], Michel Kuhlmann [ctb], Miller Patrick [ctb], Nacho Caballero [ctb], Nick Salkowski [ctb], Niels Richard Hansen [ctb], Noam Ross [ctb], Obada Mahdi [ctb], Pavel N. Krivitsky [ctb] (ORCID: ), Pedro Faria [ctb], Qiang Li [ctb], Ramnath Vaidyanathan [ctb], Richard Cotton [ctb], Robert Krzyzanowski [ctb], Rodrigo Copetti [ctb], Romain Francois [ctb], Ruaridh Williamson [ctb], Sagiru Mati [ctb] (ORCID: ), Scott Kostyshak [ctb], Sebastian Meyer [ctb], Sietse Brouwer [ctb], Simon de Bernard [ctb], Sylvain Rousseau [ctb], Taiyun Wei [ctb], Thibaut Assus [ctb], Thibaut Lamadon [ctb], Thomas Leeper [ctb], Tim Mastny [ctb], Tom Torsney-Weir [ctb], Trevor Davis [ctb], Viktoras Veitas [ctb], Weicheng Zhu [ctb], Wush Wu [ctb], Zachary Foster [ctb], Zhian N. Kamvar [ctb] (ORCID: ), Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.5", + "Source": "Repository", + "Title": "Manage the Life Cycle of your Package Functions", + "Authors@R": "c( person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Manage the life cycle of your exported functions with shared conventions, documentation badges, and user-friendly deprecation warnings.", + "License": "MIT + file LICENSE", + "URL": "https://lifecycle.r-lib.org/, https://github.com/r-lib/lifecycle", + "BugReports": "https://github.com/r-lib/lifecycle/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "rlang (>= 1.1.0)" + ], + "Suggests": [ + "covr", + "knitr", + "lintr (>= 3.1.0)", + "rmarkdown", + "testthat (>= 3.0.1)", + "tibble", + "tidyverse", + "tools", + "vctrs", + "withr", + "xml2" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate, usethis", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "no", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut] (ORCID: ), Posit Software, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "lobstr": { + "Package": "lobstr", + "Version": "1.2.1", + "Source": "Repository", + "Title": "Visualize R Data Structures with Trees", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A set of tools for inspecting and understanding R data structures inspired by str(). Includes ast() for visualizing abstract syntax trees, ref() for showing shared references, cst() for showing call stack trees, and obj_size() for computing object sizes.", + "License": "MIT + file LICENSE", + "URL": "https://lobstr.r-lib.org/, https://github.com/r-lib/lobstr", + "BugReports": "https://github.com/r-lib/lobstr/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "crayon", + "methods", + "prettyunits", + "rlang (>= 1.0.0)" + ], + "Suggests": [ + "covr", + "pillar", + "pkgdown", + "testthat (>= 3.0.0)" + ], + "LinkingTo": [ + "cpp11 (>= 0.4.2)" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "Config/build/compilation-database": "true", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Title": "'Memoisation' of Functions", + "Authors@R": "c(person(given = \"Hadley\", family = \"Wickham\", role = \"aut\", email = \"hadley@rstudio.com\"), person(given = \"Jim\", family = \"Hester\", role = \"aut\"), person(given = \"Winston\", family = \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@rstudio.com\"), person(given = \"Kirill\", family = \"Müller\", role = \"aut\", email = \"krlmlr+r@mailbox.org\"), person(given = \"Daniel\", family = \"Cook\", role = \"aut\", email = \"danielecook@gmail.com\"), person(given = \"Mark\", family = \"Edmondson\", role = \"ctb\", email = \"r@sunholo.com\"))", + "Description": "Cache the results of a function so that when you call it again with the same arguments it returns the previously computed value.", + "License": "MIT + file LICENSE", + "URL": "https://memoise.r-lib.org, https://github.com/r-lib/memoise", + "BugReports": "https://github.com/r-lib/memoise/issues", + "Imports": [ + "rlang (>= 0.4.10)", + "cachem" + ], + "Suggests": [ + "digest", + "aws.s3", + "covr", + "googleAuthR", + "googleCloudStorageR", + "httr", + "testthat" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Jim Hester [aut], Winston Chang [aut, cre], Kirill Müller [aut], Daniel Cook [aut], Mark Edmondson [ctb]", + "Maintainer": "Winston Chang ", + "Repository": "RSPM" + }, + "mime": { + "Package": "mime", + "Version": "0.13", + "Source": "Repository", + "Type": "Package", + "Title": "Map Filenames to MIME Types", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Jeffrey\", \"Horner\", role = \"ctb\"), person(\"Beilei\", \"Bian\", role = \"ctb\") )", + "Description": "Guesses the MIME type from a filename extension using the data derived from /etc/mime.types in UNIX-type systems.", + "Imports": [ + "tools" + ], + "License": "GPL", + "URL": "https://github.com/yihui/mime", + "BugReports": "https://github.com/yihui/mime/issues", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Jeffrey Horner [ctb], Beilei Bian [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "RSPM" + }, + "mirai": { + "Package": "mirai", + "Version": "2.6.1", + "Source": "Repository", + "Type": "Package", + "Title": "Minimalist Async Evaluation Framework for R", + "Authors@R": "c( person(\"Charlie\", \"Gao\", , \"charlie.gao@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-0750-061X\")), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")), person(\"Hibiki AI Limited\", role = \"cph\") )", + "Description": "Evaluates R expressions asynchronously and in parallel, locally or distributed across networks. An official parallel cluster type for R. Built on 'nanonext' and 'NNG', its non-polling, event-driven architecture scales from a laptop to thousands of processes across high-performance computing clusters and cloud platforms. Features FIFO scheduling with task cancellation, promises for reactive programming, 'OpenTelemetry' distributed tracing, and custom serialization for cross-language data types.", + "License": "MIT + file LICENSE", + "URL": "https://mirai.r-lib.org, https://github.com/r-lib/mirai", + "BugReports": "https://github.com/r-lib/mirai/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "nanonext (>= 1.8.0)" + ], + "Suggests": [ + "cli", + "later", + "litedown", + "otel", + "otelsdk", + "secretbase" + ], + "Enhances": [ + "parallel", + "promises" + ], + "VignetteBuilder": "litedown", + "Config/Needs/coverage": "rlang", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/usethis/last-upkeep": "2025-04-23", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "no", + "Author": "Charlie Gao [aut, cre] (ORCID: ), Joe Cheng [ctb], Posit Software, PBC [cph, fnd] (ROR: ), Hibiki AI Limited [cph]", + "Maintainer": "Charlie Gao ", + "Repository": "CRAN" + }, + "mori": { + "Package": "mori", + "Version": "0.1.0", + "Source": "Repository", + "Title": "Shared Memory for R Objects", + "Authors@R": "c( person(\"Charlie\", \"Gao\", , \"charlie.gao@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-0750-061X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "Share R objects across processes on the same machine via a single copy in 'POSIX' shared memory (Linux, macOS) or a 'Win32' file mapping (Windows). Every process reads from the same physical pages through the R Alternative Representation ('ALTREP') framework, giving lazy, zero-copy access. Shared objects serialize compactly as their shared memory name rather than their full contents.", + "License": "MIT + file LICENSE", + "URL": "https://shikokuchuo.net/mori/, https://github.com/shikokuchuo/mori", + "BugReports": "https://github.com/shikokuchuo/mori/issues", + "Depends": [ + "R (>= 4.3)" + ], + "Suggests": [ + "lobstr", + "mirai", + "testthat (>= 3.0.0)" + ], + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "RoxygenNote": "7.3.3", + "Author": "Charlie Gao [aut, cre] (ORCID: ), Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Charlie Gao ", + "Repository": "CRAN" + }, + "nanonext": { + "Package": "nanonext", + "Version": "1.8.2", + "Source": "Repository", + "Type": "Package", + "Title": "Lightweight Toolkit for Messaging, Concurrency and the Web", + "Authors@R": "c( person(\"Charlie\", \"Gao\", , \"charlie.gao@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-0750-061X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")), person(\"Hibiki AI Limited\", role = \"cph\"), person(\"R Consortium\", role = \"fnd\", comment = c(ROR = \"01z833950\")) )", + "Description": "R binding for NNG (Nanomsg Next Gen), a successor to ZeroMQ. A toolkit for messaging, concurrency and the web. High-performance socket messaging over in-process, IPC, TCP, WebSocket and secure TLS transports implements 'Scalability Protocols', a standard for common communications patterns including publish/subscribe, request/reply and survey. A threaded concurrency framework with intuitive 'aio' objects that resolve automatically upon completion of asynchronous operations, and synchronisation primitives that allow R to wait on events signalled by concurrent threads. A unified HTTP server hosting REST endpoints, WebSocket connections and streaming on a single port, with a built-in HTTP client.", + "License": "MIT + file LICENSE", + "URL": "https://nanonext.r-lib.org, https://github.com/r-lib/nanonext", + "BugReports": "https://github.com/r-lib/nanonext/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Suggests": [ + "later", + "litedown" + ], + "Enhances": [ + "promises" + ], + "VignetteBuilder": "litedown", + "Biarch": "true", + "Config/build/compilation-database": "true", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/usethis/last-upkeep": "2025-04-23", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "SystemRequirements": "'libnng' >= 1.9 and 'libmbedtls' >= 2.5, or 'cmake' to compile NNG and/or Mbed TLS included in package sources", + "NeedsCompilation": "yes", + "Author": "Charlie Gao [aut, cre] (ORCID: ), Posit Software, PBC [cph, fnd] (ROR: ), Hibiki AI Limited [cph], R Consortium [fnd] (ROR: )", + "Maintainer": "Charlie Gao ", + "Repository": "CRAN" + }, + "prettyunits": { + "Package": "prettyunits", + "Version": "1.2.0", + "Source": "Repository", + "Title": "Pretty, Human Readable Formatting of Quantities", + "Authors@R": "c( person(\"Gabor\", \"Csardi\", email=\"csardi.gabor@gmail.com\", role=c(\"aut\", \"cre\")), person(\"Bill\", \"Denney\", email=\"wdenney@humanpredictions.com\", role=c(\"ctb\"), comment=c(ORCID=\"0000-0002-5759-428X\")), person(\"Christophe\", \"Regouby\", email=\"christophe.regouby@free.fr\", role=c(\"ctb\")) )", + "Description": "Pretty, human readable formatting of quantities. Time intervals: '1337000' -> '15d 11h 23m 20s'. Vague time intervals: '2674000' -> 'about a month ago'. Bytes: '1337' -> '1.34 kB'. Rounding: '99' with 3 significant digits -> '99.0' p-values: '0.00001' -> '<0.0001'. Colors: '#FF0000' -> 'red'. Quantities: '1239437' -> '1.24 M'.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/prettyunits", + "BugReports": "https://github.com/r-lib/prettyunits/issues", + "Depends": [ + "R(>= 2.10)" + ], + "Suggests": [ + "codetools", + "covr", + "testthat" + ], + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Gabor Csardi [aut, cre], Bill Denney [ctb] (), Christophe Regouby [ctb]", + "Maintainer": "Gabor Csardi ", + "Repository": "CRAN" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.4", + "Source": "Repository", + "Type": "Package", + "Title": "Application Directories: Determine Where to Save Data, Caches, and Logs", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"trl\", \"cre\", \"cph\")), person(\"Sridhar\", \"Ratnakumar\", role = \"aut\"), person(\"Trent\", \"Mick\", role = \"aut\"), person(\"ActiveState\", role = \"cph\", comment = \"R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs\"), person(\"Eddy\", \"Petrisor\", role = \"ctb\"), person(\"Trevor\", \"Davis\", role = c(\"trl\", \"aut\"), comment = c(ORCID = \"0000-0001-6341-4639\")), person(\"Gabor\", \"Csardi\", role = \"ctb\"), person(\"Gregory\", \"Jefferis\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "An easy way to determine which directories on the users computer you should use to save data, caches and logs. A port of Python's 'Appdirs' () to R.", + "License": "MIT + file LICENSE", + "URL": "https://rappdirs.r-lib.org, https://github.com/r-lib/rappdirs", + "BugReports": "https://github.com/r-lib/rappdirs/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Suggests": [ + "covr", + "roxygen2", + "testthat (>= 3.2.0)", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2025-05-05", + "Copyright": "Original python appdirs module copyright (c) 2010 ActiveState Software Inc. R port copyright Hadley Wickham, Posit, PBC. See file LICENSE for details.", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [trl, cre, cph], Sridhar Ratnakumar [aut], Trent Mick [aut], ActiveState [cph] (R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs), Eddy Petrisor [ctb], Trevor Davis [trl, aut] (ORCID: ), Gabor Csardi [ctb], Gregory Jefferis [ctb], Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "renv": { + "Package": "renv", + "Version": "1.2.1", + "Source": "Repository", + "Type": "Package", + "Title": "Project Environments", + "Authors@R": "c( person(\"Kevin\", \"Ushey\", role = c(\"aut\", \"cre\"), email = \"kevin@rstudio.com\", comment = c(ORCID = \"0000-0003-2880-7407\")), person(\"Hadley\", \"Wickham\", role = c(\"aut\"), email = \"hadley@rstudio.com\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A dependency management toolkit for R. Using 'renv', you can create and manage project-local R libraries, save the state of these libraries to a 'lockfile', and later restore your library as required. Together, these tools can help make your projects more isolated, portable, and reproducible.", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/renv/, https://github.com/rstudio/renv", + "BugReports": "https://github.com/rstudio/renv/issues", + "Imports": [ + "utils" + ], + "Suggests": [ + "BiocManager", + "cli", + "compiler", + "covr", + "cpp11", + "curl", + "devtools", + "generics", + "gitcreds", + "jsonlite", + "jsonvalidate", + "knitr", + "miniUI", + "modules", + "packrat", + "pak", + "R6", + "remotes", + "reticulate", + "rmarkdown", + "rstudioapi", + "shiny", + "testthat", + "uuid", + "waldo", + "yaml", + "webfakes" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "bioconductor,python,install,restore,snapshot,retrieve,remotes", + "NeedsCompilation": "no", + "Author": "Kevin Ushey [aut, cre] (ORCID: ), Hadley Wickham [aut] (ORCID: ), Posit Software, PBC [cph, fnd]", + "Maintainer": "Kevin Ushey ", + "Repository": "CRAN" + }, + "rlang": { + "Package": "rlang", + "Version": "1.2.0", + "Source": "Repository", + "Title": "Functions for Base Types and Core R and 'Tidyverse' Features", + "Description": "A toolbox for working with base types, core R features like the condition system, and core 'Tidyverse' features like tidy evaluation.", + "Authors@R": "c( person(\"Lionel\", \"Henry\", ,\"lionel@posit.co\", c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", ,\"hadley@posit.co\", \"aut\"), person(given = \"mikefc\", email = \"mikefc@coolbutuseless.com\", role = \"cph\", comment = \"Hash implementation based on Mike's xxhashlite\"), person(given = \"Yann\", family = \"Collet\", role = \"cph\", comment = \"Author of the embedded xxHash library\"), person(given = \"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "License": "MIT + file LICENSE", + "ByteCompile": "true", + "Biarch": "true", + "Depends": [ + "R (>= 4.0.0)" + ], + "Imports": [ + "utils" + ], + "Suggests": [ + "cli (>= 3.1.0)", + "covr", + "crayon", + "desc", + "fs", + "glue", + "knitr", + "magrittr", + "methods", + "pillar", + "pkgload", + "rmarkdown", + "stats", + "testthat (>= 3.3.2)", + "tibble", + "usethis", + "vctrs (>= 0.2.3)", + "withr" + ], + "Enhances": [ + "winch" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "URL": "https://rlang.r-lib.org, https://github.com/r-lib/rlang", + "BugReports": "https://github.com/r-lib/rlang/issues", + "Config/build/compilation-database": "true", + "Config/testthat/edition": "3", + "Config/Needs/website": "dplyr, tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut], mikefc [cph] (Hash implementation based on Mike's xxhashlite), Yann Collet [cph] (Author of the embedded xxHash library), Posit, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.31", + "Source": "Repository", + "Type": "Package", + "Title": "Dynamic Documents for R", + "Authors@R": "c( person(\"JJ\", \"Allaire\", , \"jj@posit.co\", role = \"aut\"), person(\"Yihui\", \"Xie\", , \"xie@yihui.name\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Jonathan\", \"McPherson\", , \"jonathan@posit.co\", role = \"aut\"), person(\"Javier\", \"Luraschi\", role = \"aut\"), person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"aut\"), person(\"Aron\", \"Atkins\", , \"aron@posit.co\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\"), person(\"Richard\", \"Iannone\", , \"rich@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Andrew\", \"Dunning\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0464-5036\")), person(\"Atsushi\", \"Yasumoto\", role = c(\"ctb\", \"cph\"), comment = c(ORCID = \"0000-0002-8335-495X\", cph = \"Number sections Lua filter\")), person(\"Barret\", \"Schloerke\", role = \"ctb\"), person(\"Carson\", \"Sievert\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Devon\", \"Ryan\", , \"dpryan79@gmail.com\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8549-0971\")), person(\"Frederik\", \"Aust\", , \"frederik.aust@uni-koeln.de\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4900-788X\")), person(\"Jeff\", \"Allen\", , \"jeff@posit.co\", role = \"ctb\"), person(\"JooYoung\", \"Seo\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4064-6012\")), person(\"Malcolm\", \"Barrett\", role = \"ctb\"), person(\"Rob\", \"Hyndman\", , \"Rob.Hyndman@monash.edu\", role = \"ctb\"), person(\"Romain\", \"Lesur\", role = \"ctb\"), person(\"Roy\", \"Storey\", role = \"ctb\"), person(\"Ruben\", \"Arslan\", , \"ruben.arslan@uni-goettingen.de\", role = \"ctb\"), person(\"Sergio\", \"Oller\", role = \"ctb\"), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(, \"jQuery UI contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery UI library; authors listed in inst/rmd/h/jqueryui/AUTHORS.txt\"), person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"), person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Alexander\", \"Farkas\", role = c(\"ctb\", \"cph\"), comment = \"html5shiv library\"), person(\"Scott\", \"Jehl\", role = c(\"ctb\", \"cph\"), comment = \"Respond.js library\"), person(\"Ivan\", \"Sagalaev\", role = c(\"ctb\", \"cph\"), comment = \"highlight.js library\"), person(\"Greg\", \"Franko\", role = c(\"ctb\", \"cph\"), comment = \"tocify library\"), person(\"John\", \"MacFarlane\", role = c(\"ctb\", \"cph\"), comment = \"Pandoc templates\"), person(, \"Google, Inc.\", role = c(\"ctb\", \"cph\"), comment = \"ioslides library\"), person(\"Dave\", \"Raggett\", role = \"ctb\", comment = \"slidy library\"), person(, \"W3C\", role = \"cph\", comment = \"slidy library\"), person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome\"), person(\"Ben\", \"Sperry\", role = \"ctb\", comment = \"Ionicons\"), person(, \"Drifty\", role = \"cph\", comment = \"Ionicons\"), person(\"Aidan\", \"Lister\", role = c(\"ctb\", \"cph\"), comment = \"jQuery StickyTabs\"), person(\"Benct Philip\", \"Jonsson\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\"), person(\"Albert\", \"Krewinkel\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\") )", + "Description": "Convert R Markdown documents into a variety of formats.", + "License": "GPL-3", + "URL": "https://github.com/rstudio/rmarkdown, https://pkgs.rstudio.com/rmarkdown/", + "BugReports": "https://github.com/rstudio/rmarkdown/issues", + "Depends": [ + "R (>= 3.0)" + ], + "Imports": [ + "bslib (>= 0.2.5.1)", + "evaluate (>= 0.13)", + "fontawesome (>= 0.5.0)", + "htmltools (>= 0.5.1)", + "jquerylib", + "jsonlite", + "knitr (>= 1.43)", + "methods", + "tinytex (>= 0.31)", + "tools", + "utils", + "xfun (>= 0.36)", + "yaml (>= 2.1.19)" + ], + "Suggests": [ + "digest", + "dygraphs", + "fs", + "rsconnect", + "downlit (>= 0.4.0)", + "katex (>= 1.4.0)", + "sass (>= 0.4.0)", + "shiny (>= 1.6.0)", + "testthat (>= 3.0.3)", + "tibble", + "vctrs", + "cleanrmd", + "withr (>= 2.4.2)", + "xml2" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "rstudio/quillt, pkgdown", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "SystemRequirements": "pandoc (>= 1.14) - http://pandoc.org", + "NeedsCompilation": "no", + "Author": "JJ Allaire [aut], Yihui Xie [aut, cre] (ORCID: ), Christophe Dervieux [aut] (ORCID: ), Jonathan McPherson [aut], Javier Luraschi [aut], Kevin Ushey [aut], Aron Atkins [aut], Hadley Wickham [aut], Joe Cheng [aut], Winston Chang [aut], Richard Iannone [aut] (ORCID: ), Andrew Dunning [ctb] (ORCID: ), Atsushi Yasumoto [ctb, cph] (ORCID: , cph: Number sections Lua filter), Barret Schloerke [ctb], Carson Sievert [ctb] (ORCID: ), Devon Ryan [ctb] (ORCID: ), Frederik Aust [ctb] (ORCID: ), Jeff Allen [ctb], JooYoung Seo [ctb] (ORCID: ), Malcolm Barrett [ctb], Rob Hyndman [ctb], Romain Lesur [ctb], Roy Storey [ctb], Ruben Arslan [ctb], Sergio Oller [ctb], Posit Software, PBC [cph, fnd], jQuery UI contributors [ctb, cph] (jQuery UI library; authors listed in inst/rmd/h/jqueryui/AUTHORS.txt), Mark Otto [ctb] (Bootstrap library), Jacob Thornton [ctb] (Bootstrap library), Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Alexander Farkas [ctb, cph] (html5shiv library), Scott Jehl [ctb, cph] (Respond.js library), Ivan Sagalaev [ctb, cph] (highlight.js library), Greg Franko [ctb, cph] (tocify library), John MacFarlane [ctb, cph] (Pandoc templates), Google, Inc. [ctb, cph] (ioslides library), Dave Raggett [ctb] (slidy library), W3C [cph] (slidy library), Dave Gandy [ctb, cph] (Font-Awesome), Ben Sperry [ctb] (Ionicons), Drifty [cph] (Ionicons), Aidan Lister [ctb, cph] (jQuery StickyTabs), Benct Philip Jonsson [ctb, cph] (pagebreak Lua filter), Albert Krewinkel [ctb, cph] (pagebreak Lua filter)", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "sass": { + "Package": "sass", + "Version": "0.4.10", + "Source": "Repository", + "Type": "Package", + "Title": "Syntactically Awesome Style Sheets ('Sass')", + "Description": "An 'SCSS' compiler, powered by the 'LibSass' library. With this, R developers can use variables, inheritance, and functions to generate dynamic style sheets. The package uses the 'Sass CSS' extension language, which is stable, powerful, and CSS compatible.", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@rstudio.com\", \"aut\"), person(\"Timothy\", \"Mastny\", , \"tim.mastny@gmail.com\", \"aut\"), person(\"Richard\", \"Iannone\", , \"rich@rstudio.com\", \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Barret\", \"Schloerke\", , \"barret@rstudio.com\", \"aut\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Carson\", \"Sievert\", , \"carson@rstudio.com\", c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Christophe\", \"Dervieux\", , \"cderv@rstudio.com\", c(\"ctb\"), comment = c(ORCID = \"0000-0003-4474-2498\")), person(family = \"RStudio\", role = c(\"cph\", \"fnd\")), person(family = \"Sass Open Source Foundation\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Greter\", \"Marcel\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Mifsud\", \"Michael\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Hampton\", \"Catlin\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Natalie\", \"Weizenbaum\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Chris\", \"Eppstein\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Adams\", \"Joseph\", role = c(\"ctb\", \"cph\"), comment = \"json.cpp\"), person(\"Trifunovic\", \"Nemanja\", role = c(\"ctb\", \"cph\"), comment = \"utf8.h\") )", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/sass/, https://github.com/rstudio/sass", + "BugReports": "https://github.com/rstudio/sass/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "GNU make", + "Imports": [ + "fs (>= 1.2.4)", + "rlang (>= 0.4.10)", + "htmltools (>= 0.5.1)", + "R6", + "rappdirs" + ], + "Suggests": [ + "testthat", + "knitr", + "rmarkdown", + "withr", + "shiny", + "curl" + ], + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut], Timothy Mastny [aut], Richard Iannone [aut] (), Barret Schloerke [aut] (), Carson Sievert [aut, cre] (), Christophe Dervieux [ctb] (), RStudio [cph, fnd], Sass Open Source Foundation [ctb, cph] (LibSass library), Greter Marcel [ctb, cph] (LibSass library), Mifsud Michael [ctb, cph] (LibSass library), Hampton Catlin [ctb, cph] (LibSass library), Natalie Weizenbaum [ctb, cph] (LibSass library), Chris Eppstein [ctb, cph] (LibSass library), Adams Joseph [ctb, cph] (json.cpp), Trifunovic Nemanja [ctb, cph] (utf8.h)", + "Maintainer": "Carson Sievert ", + "Repository": "RSPM" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.59", + "Source": "Repository", + "Type": "Package", + "Title": "Helper Functions to Install and Maintain TeX Live, and Compile LaTeX Documents", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"Christophe\", \"Dervieux\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Devon\", \"Ryan\", role = \"ctb\", email = \"dpryan79@gmail.com\", comment = c(ORCID = \"0000-0002-8549-0971\")), person(\"Ethan\", \"Heinzen\", role = \"ctb\"), person(\"Fernando\", \"Cagua\", role = \"ctb\"), person() )", + "Description": "Helper functions to install and maintain the 'LaTeX' distribution named 'TinyTeX' (), a lightweight, cross-platform, portable, and easy-to-maintain version of 'TeX Live'. This package also contains helper functions to compile 'LaTeX' documents, and install missing 'LaTeX' packages automatically.", + "Imports": [ + "xfun (>= 0.48)" + ], + "Suggests": [ + "testit", + "rstudioapi" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/tinytex", + "BugReports": "https://github.com/rstudio/tinytex/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre, cph] (ORCID: ), Posit Software, PBC [cph, fnd], Christophe Dervieux [ctb] (ORCID: ), Devon Ryan [ctb] (ORCID: ), Ethan Heinzen [ctb], Fernando Cagua [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "xfun": { + "Package": "xfun", + "Version": "0.57", + "Source": "Repository", + "Type": "Package", + "Title": "Supporting Functions for Packages Maintained by 'Yihui Xie'", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Daijiang\", \"Li\", role = \"ctb\"), person(\"Xianying\", \"Tan\", role = \"ctb\"), person(\"Salim\", \"Brüggemann\", role = \"ctb\", email = \"salim-b@pm.me\", comment = c(ORCID = \"0000-0002-5329-5987\")), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person() )", + "Description": "Miscellaneous functions commonly used in other packages maintained by 'Yihui Xie'.", + "Depends": [ + "R (>= 3.2.0)" + ], + "Imports": [ + "grDevices", + "stats", + "tools" + ], + "Suggests": [ + "testit", + "parallel", + "codetools", + "methods", + "rstudioapi", + "tinytex (>= 0.30)", + "mime", + "litedown (>= 0.6)", + "commonmark", + "knitr (>= 1.50)", + "remotes", + "pak", + "curl", + "xml2", + "jsonlite", + "magick", + "yaml", + "data.table", + "qs2" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/yihui/xfun", + "BugReports": "https://github.com/yihui/xfun/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "VignetteBuilder": "litedown", + "NeedsCompilation": "yes", + "Author": "Yihui Xie [aut, cre, cph] (ORCID: , URL: https://yihui.org), Wush Wu [ctb], Daijiang Li [ctb], Xianying Tan [ctb], Salim Brüggemann [ctb] (ORCID: ), Christophe Dervieux [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.12", + "Source": "Repository", + "Type": "Package", + "Title": "Methods to Convert R Data to YAML and Back", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"cre\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Shawn\", \"Garbett\", , \"shawn.garbett@vumc.org\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4079-5621\")), person(\"Jeremy\", \"Stephens\", role = c(\"aut\", \"ctb\")), person(\"Kirill\", \"Simonov\", role = \"aut\"), person(\"Yihui\", \"Xie\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Zhuoer\", \"Dong\", role = \"ctb\"), person(\"Jeffrey\", \"Horner\", role = \"ctb\"), person(\"reikoch\", role = \"ctb\"), person(\"Will\", \"Beasley\", role = \"ctb\", comment = c(ORCID = \"0000-0002-5613-5006\")), person(\"Brendan\", \"O'Connor\", role = \"ctb\"), person(\"Michael\", \"Quinn\", role = \"ctb\"), person(\"Charlie\", \"Gao\", role = \"ctb\"), person(c(\"Gregory\", \"R.\"), \"Warnes\", role = \"ctb\"), person(c(\"Zhian\", \"N.\"), \"Kamvar\", role = \"ctb\") )", + "Description": "Implements the 'libyaml' 'YAML' 1.1 parser and emitter () for R.", + "License": "BSD_3_clause + file LICENSE", + "URL": "https://yaml.r-lib.org, https://github.com/r-lib/yaml/", + "BugReports": "https://github.com/r-lib/yaml/issues", + "Suggests": [ + "knitr", + "rmarkdown", + "testthat (>= 3.0.0)" + ], + "Config/testthat/edition": "3", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "VignetteBuilder": "knitr", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [cre] (ORCID: ), Shawn Garbett [ctb] (ORCID: ), Jeremy Stephens [aut, ctb], Kirill Simonov [aut], Yihui Xie [ctb] (ORCID: ), Zhuoer Dong [ctb], Jeffrey Horner [ctb], reikoch [ctb], Will Beasley [ctb] (ORCID: ), Brendan O'Connor [ctb], Michael Quinn [ctb], Charlie Gao [ctb], Gregory R. Warnes [ctb], Zhian N. Kamvar [ctb]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + } + } +} diff --git a/content/blog/mori-0-1-0/renv/.gitignore b/content/blog/mori-0-1-0/renv/.gitignore new file mode 100644 index 000000000..0ec0cbba2 --- /dev/null +++ b/content/blog/mori-0-1-0/renv/.gitignore @@ -0,0 +1,7 @@ +library/ +local/ +cellar/ +lock/ +python/ +sandbox/ +staging/ diff --git a/content/blog/mori-0-1-0/renv/activate.R b/content/blog/mori-0-1-0/renv/activate.R new file mode 100644 index 000000000..187592214 --- /dev/null +++ b/content/blog/mori-0-1-0/renv/activate.R @@ -0,0 +1,1438 @@ + +local({ + + # the requested version of renv + version <- "1.2.1" + attr(version, "md5") <- "51fff37c14949274ac148a9a087ab6bd" + attr(version, "sha") <- NULL + + # the project directory + project <- Sys.getenv("RENV_PROJECT") + if (!nzchar(project)) + project <- getwd() + + # use start-up diagnostics if enabled + diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") + if (diagnostics) { + start <- Sys.time() + profile <- tempfile("renv-startup-", fileext = ".Rprof") + utils::Rprof(profile) + on.exit({ + utils::Rprof(NULL) + elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L) + writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed))) + writeLines(sprintf("- Profile: %s", profile)) + print(utils::summaryRprof(profile)) + }, add = TRUE) + } + + # figure out whether the autoloader is enabled + enabled <- local({ + + # first, check config option + override <- getOption("renv.config.autoloader.enabled") + if (!is.null(override)) + return(override) + + # if we're being run in a context where R_LIBS is already set, + # don't load -- presumably we're being run as a sub-process and + # the parent process has already set up library paths for us + rcmd <- Sys.getenv("R_CMD", unset = NA) + rlibs <- Sys.getenv("R_LIBS", unset = NA) + if (!is.na(rlibs) && !is.na(rcmd)) + return(FALSE) + + # next, check environment variables + # prefer using the configuration one in the future + envvars <- c( + "RENV_CONFIG_AUTOLOADER_ENABLED", + "RENV_AUTOLOADER_ENABLED", + "RENV_ACTIVATE_PROJECT" + ) + + for (envvar in envvars) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(tolower(envval) %in% c("true", "t", "1")) + } + + # enable by default + TRUE + + }) + + # bail if we're not enabled + if (!enabled) { + + # if we're not enabled, we might still need to manually load + # the user profile here + profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile") + if (file.exists(profile)) { + cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE") + if (tolower(cfg) %in% c("true", "t", "1")) + sys.source(profile, envir = globalenv()) + } + + return(FALSE) + + } + + # avoid recursion + if (identical(getOption("renv.autoloader.running"), TRUE)) { + warning("ignoring recursive attempt to run renv autoloader") + return(invisible(TRUE)) + } + + # signal that we're loading renv during R startup + options(renv.autoloader.running = TRUE) + on.exit(options(renv.autoloader.running = NULL), add = TRUE) + + # signal that we've consented to use renv + options(renv.consent = TRUE) + + # load the 'utils' package eagerly -- this ensures that renv shims, which + # mask 'utils' packages, will come first on the search path + library(utils, lib.loc = .Library) + + # unload renv if it's already been loaded + if ("renv" %in% loadedNamespaces()) + unloadNamespace("renv") + + # load bootstrap tools + ansify <- function(text) { + if (renv_ansify_enabled()) + renv_ansify_enhanced(text) + else + renv_ansify_default(text) + } + + renv_ansify_enabled <- function() { + + override <- Sys.getenv("RENV_ANSIFY_ENABLED", unset = NA) + if (!is.na(override)) + return(as.logical(override)) + + pane <- Sys.getenv("RSTUDIO_CHILD_PROCESS_PANE", unset = NA) + if (identical(pane, "build")) + return(FALSE) + + testthat <- Sys.getenv("TESTTHAT", unset = "false") + if (tolower(testthat) %in% "true") + return(FALSE) + + iderun <- Sys.getenv("R_CLI_HAS_HYPERLINK_IDE_RUN", unset = "false") + if (tolower(iderun) %in% "false") + return(FALSE) + + TRUE + + } + + renv_ansify_default <- function(text) { + text + } + + renv_ansify_enhanced <- function(text) { + + # R help links + pattern <- "`\\?(renv::(?:[^`])+)`" + replacement <- "`\033]8;;x-r-help:\\1\a?\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # runnable code + pattern <- "`(renv::(?:[^`])+)`" + replacement <- "`\033]8;;x-r-run:\\1\a\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # return ansified text + text + + } + + renv_ansify_init <- function() { + + envir <- renv_envir_self() + if (renv_ansify_enabled()) + assign("ansify", renv_ansify_enhanced, envir = envir) + else + assign("ansify", renv_ansify_default, envir = envir) + + } + + `%||%` <- function(x, y) { + if (is.null(x)) y else x + } + + catf <- function(fmt, ..., appendLF = TRUE) { + + quiet <- getOption("renv.bootstrap.quiet", default = FALSE) + if (quiet) + return(invisible()) + + # also check for config environment variables that should suppress messages + # https://github.com/rstudio/renv/issues/2214 + enabled <- Sys.getenv("RENV_CONFIG_STARTUP_QUIET", unset = NA) + if (!is.na(enabled) && tolower(enabled) %in% c("true", "1")) + return(invisible()) + + enabled <- Sys.getenv("RENV_CONFIG_SYNCHRONIZED_CHECK", unset = NA) + if (!is.na(enabled) && tolower(enabled) %in% c("false", "0")) + return(invisible()) + + msg <- sprintf(fmt, ...) + cat(msg, file = stdout(), sep = if (appendLF) "\n" else "") + + invisible(msg) + + } + + header <- function(label, + ..., + prefix = "#", + suffix = "-", + n = min(getOption("width"), 78)) + { + label <- sprintf(label, ...) + n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L) + if (n <= 0) + return(paste(prefix, label)) + + tail <- paste(rep.int(suffix, n), collapse = "") + paste0(prefix, " ", label, " ", tail) + + } + + heredoc <- function(text, leave = 0) { + + # remove leading, trailing whitespace + trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text) + + # split into lines + lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]] + + # compute common indent + indent <- regexpr("[^[:space:]]", lines) + common <- min(setdiff(indent, -1L)) - leave + text <- paste(substring(lines, common), collapse = "\n") + + # substitute in ANSI links for executable renv code + ansify(text) + + } + + bootstrap <- function(version, library) { + + friendly <- renv_bootstrap_version_friendly(version) + section <- header(sprintf("Bootstrapping renv %s", friendly)) + catf(section) + + # ensure the target library path exists; required for file.copy(..., recursive = TRUE) + dir.create(library, showWarnings = FALSE, recursive = TRUE) + + # try to install renv from cache + md5 <- attr(version, "md5", exact = TRUE) + if (length(md5)) { + pkgpath <- renv_bootstrap_find(version) + if (length(pkgpath) && file.exists(pkgpath)) { + ok <- file.copy(pkgpath, library, recursive = TRUE) + if (isTRUE(ok)) + return(invisible()) + } + } + + # attempt to download renv + catf("- Downloading renv ... ", appendLF = FALSE) + withCallingHandlers( + tarball <- renv_bootstrap_download(version), + error = function(err) { + catf("FAILED") + stop("failed to download:\n", conditionMessage(err)) + } + ) + catf("OK") + on.exit(unlink(tarball), add = TRUE) + + # now attempt to install + catf("- Installing renv ... ", appendLF = FALSE) + withCallingHandlers( + status <- renv_bootstrap_install(version, tarball, library), + error = function(err) { + catf("FAILED") + stop("failed to install:\n", conditionMessage(err)) + } + ) + catf("OK") + + # add empty line to break up bootstrapping from normal output + catf("") + return(invisible()) + } + + renv_bootstrap_tests_running <- function() { + getOption("renv.tests.running", default = FALSE) + } + + renv_bootstrap_repos <- function() { + + # get CRAN repository + cran <- getOption("renv.repos.cran", "https://cloud.r-project.org") + + # check for repos override + repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) + if (!is.na(repos)) { + + # split on ';' if present + parts <- strsplit(repos, ";", fixed = TRUE)[[1L]] + + # split into named repositories if present + idx <- regexpr("=", parts, fixed = TRUE) + keys <- substring(parts, 1L, idx - 1L) + vals <- substring(parts, idx + 1L) + names(vals) <- keys + + # if we have a single unnamed repository, call it CRAN + if (length(vals) == 1L && identical(keys, "")) + names(vals) <- "CRAN" + + return(vals) + + } + + # check for lockfile repositories + repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) + if (!inherits(repos, "error") && length(repos)) + return(repos) + + # retrieve current repos + repos <- getOption("repos") + + # ensure @CRAN@ entries are resolved + repos[repos == "@CRAN@"] <- cran + + # add in renv.bootstrap.repos if set + default <- c(FALLBACK = "https://cloud.r-project.org") + extra <- getOption("renv.bootstrap.repos", default = default) + repos <- c(repos, extra) + + # remove duplicates that might've snuck in + dupes <- duplicated(repos) | duplicated(names(repos)) + repos[!dupes] + + } + + renv_bootstrap_repos_lockfile <- function() { + + lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock") + if (!file.exists(lockpath)) + return(NULL) + + lockfile <- tryCatch(renv_json_read(lockpath), error = identity) + if (inherits(lockfile, "error")) { + warning(lockfile) + return(NULL) + } + + repos <- lockfile$R$Repositories + if (length(repos) == 0) + return(NULL) + + keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1)) + vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1)) + names(vals) <- keys + + return(vals) + + } + + renv_bootstrap_download <- function(version) { + + sha <- attr(version, "sha", exact = TRUE) + + methods <- if (!is.null(sha)) { + + # attempting to bootstrap a development version of renv + c( + function() renv_bootstrap_download_tarball(sha), + function() renv_bootstrap_download_github(sha) + ) + + } else { + + # attempting to bootstrap a release version of renv + c( + function() renv_bootstrap_download_tarball(version), + function() renv_bootstrap_download_cran_latest(version), + function() renv_bootstrap_download_cran_archive(version) + ) + + } + + for (method in methods) { + path <- tryCatch(method(), error = identity) + if (is.character(path) && file.exists(path)) + return(path) + } + + stop("All download methods failed") + + } + + renv_bootstrap_download_impl <- function(url, destfile) { + + mode <- "wb" + + # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 + fixup <- + Sys.info()[["sysname"]] == "Windows" && + substring(url, 1L, 5L) == "file:" + + if (fixup) + mode <- "w+b" + + args <- list( + url = url, + destfile = destfile, + mode = mode, + quiet = TRUE + ) + + if ("headers" %in% names(formals(utils::download.file))) { + headers <- renv_bootstrap_download_custom_headers(url) + if (length(headers) && is.character(headers)) + args$headers <- headers + } + + do.call(utils::download.file, args) + + } + + renv_bootstrap_download_custom_headers <- function(url) { + + headers <- getOption("renv.download.headers") + if (is.null(headers)) + return(character()) + + if (!is.function(headers)) + stopf("'renv.download.headers' is not a function") + + headers <- headers(url) + if (length(headers) == 0L) + return(character()) + + if (is.list(headers)) + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) + + ok <- + is.character(headers) && + is.character(names(headers)) && + all(nzchar(names(headers))) + + if (!ok) + stop("invocation of 'renv.download.headers' did not return a named character vector") + + headers + + } + + renv_bootstrap_download_cran_latest <- function(version) { + + spec <- renv_bootstrap_download_cran_latest_find(version) + type <- spec$type + repos <- spec$repos + + baseurl <- utils::contrib.url(repos = repos, type = type) + ext <- if (identical(type, "source")) + ".tar.gz" + else if (Sys.info()[["sysname"]] == "Windows") + ".zip" + else + ".tgz" + name <- sprintf("renv_%s%s", version, ext) + url <- paste(baseurl, name, sep = "/") + + destfile <- file.path(tempdir(), name) + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (inherits(status, "condition")) + return(FALSE) + + # report success and return + destfile + + } + + renv_bootstrap_download_cran_latest_find <- function(version) { + + # check whether binaries are supported on this system + binary <- + getOption("renv.bootstrap.binary", default = TRUE) && + !identical(.Platform$pkgType, "source") && + !identical(getOption("pkgType"), "source") && + Sys.info()[["sysname"]] %in% c("Darwin", "Windows") + + types <- c(if (binary) "binary", "source") + + # iterate over types + repositories + for (type in types) { + for (repos in renv_bootstrap_repos()) { + + # build arguments for utils::available.packages() call + args <- list(type = type, repos = repos) + + # add custom headers if available -- note that + # utils::available.packages() will pass this to download.file() + if ("headers" %in% names(formals(utils::download.file))) { + headers <- renv_bootstrap_download_custom_headers(repos) + if (length(headers) && is.character(headers)) + args$headers <- headers + } + + # retrieve package database + db <- tryCatch( + as.data.frame( + do.call(utils::available.packages, args), + stringsAsFactors = FALSE + ), + error = identity + ) + + if (inherits(db, "error")) + next + + # check for compatible entry + entry <- db[db$Package %in% "renv" & db$Version %in% version, ] + if (nrow(entry) == 0) + next + + # found it; return spec to caller + spec <- list(entry = entry, type = type, repos = repos) + return(spec) + + } + } + + # if we got here, we failed to find renv + fmt <- "renv %s is not available from your declared package repositories" + stop(sprintf(fmt, version)) + + } + + renv_bootstrap_download_cran_archive <- function(version) { + + name <- sprintf("renv_%s.tar.gz", version) + repos <- renv_bootstrap_repos() + urls <- file.path(repos, "src/contrib/Archive/renv", name) + destfile <- file.path(tempdir(), name) + + for (url in urls) { + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (identical(status, 0L)) + return(destfile) + + } + + return(FALSE) + + } + + renv_bootstrap_find <- function(version) { + + path <- renv_bootstrap_find_cache(version) + if (length(path) && file.exists(path)) { + catf("- Using renv %s from global package cache", version) + return(path) + } + + } + + renv_bootstrap_find_cache <- function(version) { + + md5 <- attr(version, "md5", exact = TRUE) + if (is.null(md5)) + return() + + # infer path to renv cache + cache <- Sys.getenv("RENV_PATHS_CACHE", unset = "") + if (!nzchar(cache)) { + root <- Sys.getenv("RENV_PATHS_ROOT", unset = NA) + if (!is.na(root)) + cache <- file.path(root, "cache") + } + + if (!nzchar(cache)) { + tools <- asNamespace("tools") + if (is.function(tools$R_user_dir)) { + root <- tools$R_user_dir("renv", "cache") + cache <- file.path(root, "cache") + } + } + + # start completing path to cache + file.path( + cache, + renv_bootstrap_cache_version(), + renv_bootstrap_platform_prefix(), + "renv", + version, + md5, + "renv" + ) + + } + + renv_bootstrap_download_tarball <- function(version) { + + # if the user has provided the path to a tarball via + # an environment variable, then use it + tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA) + if (is.na(tarball)) + return() + + # allow directories + if (dir.exists(tarball)) { + name <- sprintf("renv_%s.tar.gz", version) + tarball <- file.path(tarball, name) + } + + # bail if it doesn't exist + if (!file.exists(tarball)) { + + # let the user know we weren't able to honour their request + fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + msg <- sprintf(fmt, tarball) + warning(msg) + + # bail + return() + + } + + catf("- Using local tarball '%s'.", tarball) + tarball + + } + + renv_bootstrap_github_token <- function() { + for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(envval) + } + } + + renv_bootstrap_download_github <- function(version) { + + enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") + if (!identical(enabled, "TRUE")) + return(FALSE) + + # prepare download options + token <- renv_bootstrap_github_token() + if (is.null(token)) + token <- "" + + if (nzchar(Sys.which("curl")) && nzchar(token)) { + fmt <- "--location --fail --header \"Authorization: token %s\"" + extra <- sprintf(fmt, token) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "curl", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } else if (nzchar(Sys.which("wget")) && nzchar(token)) { + fmt <- "--header=\"Authorization: token %s\"" + extra <- sprintf(fmt, token) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "wget", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } + + url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) + name <- sprintf("renv_%s.tar.gz", version) + destfile <- file.path(tempdir(), name) + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (!identical(status, 0L)) + return(FALSE) + + renv_bootstrap_download_augment(destfile) + + return(destfile) + + } + + # Add Sha to DESCRIPTION. This is stop gap until #890, after which we + # can use renv::install() to fully capture metadata. + renv_bootstrap_download_augment <- function(destfile) { + sha <- renv_bootstrap_git_extract_sha1_tar(destfile) + if (is.null(sha)) { + return() + } + + # Untar + tempdir <- tempfile("renv-github-") + on.exit(unlink(tempdir, recursive = TRUE), add = TRUE) + untar(destfile, exdir = tempdir) + pkgdir <- dir(tempdir, full.names = TRUE)[[1]] + + # Modify description + desc_path <- file.path(pkgdir, "DESCRIPTION") + desc_lines <- readLines(desc_path) + remotes_fields <- c( + "RemoteType: github", + "RemoteHost: api.github.com", + "RemoteRepo: renv", + "RemoteUsername: rstudio", + "RemotePkgRef: rstudio/renv", + paste("RemoteRef: ", sha), + paste("RemoteSha: ", sha) + ) + writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path) + + # Re-tar + local({ + old <- setwd(tempdir) + on.exit(setwd(old), add = TRUE) + + tar(destfile, compression = "gzip") + }) + invisible() + } + + # Extract the commit hash from a git archive. Git archives include the SHA1 + # hash as the comment field of the tarball pax extended header + # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) + # For GitHub archives this should be the first header after the default one + # (512 byte) header. + renv_bootstrap_git_extract_sha1_tar <- function(bundle) { + + # open the bundle for reading + # We use gzcon for everything because (from ?gzcon) + # > Reading from a connection which does not supply a 'gzip' magic + # > header is equivalent to reading from the original connection + conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) + on.exit(close(conn)) + + # The default pax header is 512 bytes long and the first pax extended header + # with the comment should be 51 bytes long + # `52 comment=` (11 chars) + 40 byte SHA1 hash + len <- 0x200 + 0x33 + res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) + + if (grepl("^52 comment=", res)) { + sub("52 comment=", "", res) + } else { + NULL + } + } + + renv_bootstrap_install <- function(version, tarball, library) { + + # attempt to install it into project library + dir.create(library, showWarnings = FALSE, recursive = TRUE) + output <- renv_bootstrap_install_impl(library, tarball) + + # check for successful install + status <- attr(output, "status") + if (is.null(status) || identical(status, 0L)) + return(status) + + # an error occurred; report it + header <- "installation of renv failed" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- paste(c(header, lines, output), collapse = "\n") + stop(text) + + } + + renv_bootstrap_install_impl <- function(library, tarball) { + + # invoke using system2 so we can capture and report output + bin <- R.home("bin") + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + R <- file.path(bin, exe) + + args <- c( + "--vanilla", "CMD", "INSTALL", "--no-multiarch", + "-l", shQuote(path.expand(library)), + shQuote(path.expand(tarball)) + ) + + system2(R, args, stdout = TRUE, stderr = TRUE) + + } + + renv_bootstrap_platform_prefix_default <- function() { + + # read version component + version <- Sys.getenv("RENV_PATHS_VERSION", unset = "R-%v") + + # expand placeholders + placeholders <- list( + list("%v", format(getRversion()[1, 1:2])), + list("%V", format(getRversion()[1, 1:3])) + ) + + for (placeholder in placeholders) + version <- gsub(placeholder[[1L]], placeholder[[2L]], version, fixed = TRUE) + + # include SVN revision for development versions of R + # (to avoid sharing platform-specific artefacts with released versions of R) + devel <- + identical(R.version[["status"]], "Under development (unstable)") || + identical(R.version[["nickname"]], "Unsuffered Consequences") + + if (devel) + version <- paste(version, R.version[["svn rev"]], sep = "-r") + + version + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- renv_bootstrap_platform_prefix_default() + + # build list of path components + components <- c(version, R.version$platform) + + # include prefix if provided by user + prefix <- renv_bootstrap_platform_prefix_impl() + if (!is.na(prefix) && nzchar(prefix)) + components <- c(prefix, components) + + # build prefix + paste(components, collapse = "/") + + } + + renv_bootstrap_platform_prefix_impl <- function() { + + # if an explicit prefix has been supplied, use it + prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) + if (!is.na(prefix)) + return(prefix) + + # if the user has requested an automatic prefix, generate it + auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (is.na(auto) && getRversion() >= "4.4.0") + auto <- "TRUE" + + if (auto %in% c("TRUE", "True", "true", "1")) + return(renv_bootstrap_platform_prefix_auto()) + + # empty string on failure + "" + + } + + renv_bootstrap_platform_prefix_auto <- function() { + + prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) + if (inherits(prefix, "error") || prefix %in% "unknown") { + + msg <- paste( + "failed to infer current operating system", + "please file a bug report at https://github.com/rstudio/renv/issues", + sep = "; " + ) + + warning(msg) + + } + + prefix + + } + + renv_bootstrap_platform_os <- function() { + + sysinfo <- Sys.info() + sysname <- sysinfo[["sysname"]] + + # handle Windows + macOS up front + if (sysname == "Windows") + return("windows") + else if (sysname == "Darwin") + return("macos") + + # check for os-release files + for (file in c("/etc/os-release", "/usr/lib/os-release")) + if (file.exists(file)) + return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) + + # check for redhat-release files + if (file.exists("/etc/redhat-release")) + return(renv_bootstrap_platform_os_via_redhat_release()) + + "unknown" + + } + + renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { + + # read /etc/os-release + release <- utils::read.table( + file = file, + sep = "=", + quote = c("\"", "'"), + col.names = c("Key", "Value"), + comment.char = "#", + stringsAsFactors = FALSE + ) + + vars <- as.list(release$Value) + names(vars) <- release$Key + + # get os name + os <- tolower(sysinfo[["sysname"]]) + + # read id + id <- "unknown" + for (field in c("ID", "ID_LIKE")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + id <- vars[[field]] + break + } + } + + # read version + version <- "unknown" + for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + version <- vars[[field]] + break + } + } + + # join together + paste(c(os, id, version), collapse = "-") + + } + + renv_bootstrap_platform_os_via_redhat_release <- function() { + + # read /etc/redhat-release + contents <- readLines("/etc/redhat-release", warn = FALSE) + + # infer id + id <- if (grepl("centos", contents, ignore.case = TRUE)) + "centos" + else if (grepl("redhat", contents, ignore.case = TRUE)) + "redhat" + else + "unknown" + + # try to find a version component (very hacky) + version <- "unknown" + + parts <- strsplit(contents, "[[:space:]]")[[1L]] + for (part in parts) { + + nv <- tryCatch(numeric_version(part), error = identity) + if (inherits(nv, "error")) + next + + version <- nv[1, 1] + break + + } + + paste(c("linux", id, version), collapse = "-") + + } + + renv_bootstrap_library_root_name <- function(project) { + + # use project name as-is if requested + asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") + if (asis) + return(basename(project)) + + # otherwise, disambiguate based on project's path + id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) + paste(basename(project), id, sep = "-") + + } + + renv_bootstrap_library_root <- function(project) { + + prefix <- renv_bootstrap_profile_prefix() + + path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) + if (!is.na(path)) + return(paste(c(path, prefix), collapse = "/")) + + path <- renv_bootstrap_library_root_impl(project) + if (!is.null(path)) { + name <- renv_bootstrap_library_root_name(project) + return(paste(c(path, prefix, name), collapse = "/")) + } + + renv_bootstrap_paths_renv("library", project = project) + + } + + renv_bootstrap_library_root_impl <- function(project) { + + root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) + if (!is.na(root)) + return(root) + + type <- renv_bootstrap_project_type(project) + if (identical(type, "package")) { + userdir <- renv_bootstrap_user_dir() + return(file.path(userdir, "library")) + } + + } + + renv_bootstrap_validate_version <- function(version, description = NULL) { + + # resolve description file + # + # avoid passing lib.loc to `packageDescription()` below, since R will + # use the loaded version of the package by default anyhow. note that + # this function should only be called after 'renv' is loaded + # https://github.com/rstudio/renv/issues/1625 + description <- description %||% packageDescription("renv") + + # check whether requested version 'version' matches loaded version of renv + sha <- attr(version, "sha", exact = TRUE) + valid <- if (!is.null(sha)) + renv_bootstrap_validate_version_dev(sha, description) + else + renv_bootstrap_validate_version_release(version, description) + + if (valid) + return(TRUE) + + # the loaded version of renv doesn't match the requested version; + # give the user instructions on how to proceed + dev <- identical(description[["RemoteType"]], "github") + remote <- if (dev) + paste("rstudio/renv", description[["RemoteSha"]], sep = "@") + else + paste("renv", description[["Version"]], sep = "@") + + # display both loaded version + sha if available + friendly <- renv_bootstrap_version_friendly( + version = description[["Version"]], + sha = if (dev) description[["RemoteSha"]] + ) + + fmt <- heredoc(" + renv %1$s was loaded from project library, but this project is configured to use renv %2$s. + - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile. + - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library. + ") + catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) + + FALSE + + } + + renv_bootstrap_validate_version_dev <- function(version, description) { + + expected <- description[["RemoteSha"]] + if (!is.character(expected)) + return(FALSE) + + pattern <- sprintf("^\\Q%s\\E", version) + grepl(pattern, expected, perl = TRUE) + + } + + renv_bootstrap_validate_version_release <- function(version, description) { + expected <- description[["Version"]] + is.character(expected) && identical(c(expected), c(version)) + } + + renv_bootstrap_hash_text <- function(text) { + + hashfile <- tempfile("renv-hash-") + on.exit(unlink(hashfile), add = TRUE) + + writeLines(text, con = hashfile) + tools::md5sum(hashfile) + + } + + renv_bootstrap_load <- function(project, libpath, version) { + + # try to load renv from the project library + if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) + return(FALSE) + + # warn if the version of renv loaded does not match + renv_bootstrap_validate_version(version) + + # execute renv load hooks, if any + hooks <- getHook("renv::autoload") + for (hook in hooks) + if (is.function(hook)) + tryCatch(hook(), error = warnify) + + # load the project + renv::load(project) + + TRUE + + } + + renv_bootstrap_profile_load <- function(project) { + + # if RENV_PROFILE is already set, just use that + profile <- Sys.getenv("RENV_PROFILE", unset = NA) + if (!is.na(profile) && nzchar(profile)) + return(profile) + + # check for a profile file (nothing to do if it doesn't exist) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) + if (!file.exists(path)) + return(NULL) + + # read the profile, and set it if it exists + contents <- readLines(path, warn = FALSE) + if (length(contents) == 0L) + return(NULL) + + # set RENV_PROFILE + profile <- contents[[1L]] + if (!profile %in% c("", "default")) + Sys.setenv(RENV_PROFILE = profile) + + profile + + } + + renv_bootstrap_profile_prefix <- function() { + profile <- renv_bootstrap_profile_get() + if (!is.null(profile)) + return(file.path("profiles", profile, "renv")) + } + + renv_bootstrap_profile_get <- function() { + profile <- Sys.getenv("RENV_PROFILE", unset = "") + renv_bootstrap_profile_normalize(profile) + } + + renv_bootstrap_profile_set <- function(profile) { + profile <- renv_bootstrap_profile_normalize(profile) + if (is.null(profile)) + Sys.unsetenv("RENV_PROFILE") + else + Sys.setenv(RENV_PROFILE = profile) + } + + renv_bootstrap_profile_normalize <- function(profile) { + + if (is.null(profile) || profile %in% c("", "default")) + return(NULL) + + profile + + } + + renv_bootstrap_path_absolute <- function(path) { + + substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( + substr(path, 1L, 1L) %in% c(letters, LETTERS) && + substr(path, 2L, 3L) %in% c(":/", ":\\") + ) + + } + + renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { + renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") + root <- if (renv_bootstrap_path_absolute(renv)) NULL else project + prefix <- if (profile) renv_bootstrap_profile_prefix() + components <- c(root, renv, prefix, ...) + paste(components, collapse = "/") + } + + renv_bootstrap_project_type <- function(path) { + + descpath <- file.path(path, "DESCRIPTION") + if (!file.exists(descpath)) + return("unknown") + + desc <- tryCatch( + read.dcf(descpath, all = TRUE), + error = identity + ) + + if (inherits(desc, "error")) + return("unknown") + + type <- desc$Type + if (!is.null(type)) + return(tolower(type)) + + package <- desc$Package + if (!is.null(package)) + return("package") + + "unknown" + + } + + renv_bootstrap_user_dir <- function() { + dir <- renv_bootstrap_user_dir_impl() + path.expand(chartr("\\", "/", dir)) + } + + renv_bootstrap_user_dir_impl <- function() { + + # use local override if set + override <- getOption("renv.userdir.override") + if (!is.null(override)) + return(override) + + # use R_user_dir if available + tools <- asNamespace("tools") + if (is.function(tools$R_user_dir)) + return(tools$R_user_dir("renv", "cache")) + + # try using our own backfill for older versions of R + envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") + for (envvar in envvars) { + root <- Sys.getenv(envvar, unset = NA) + if (!is.na(root)) + return(file.path(root, "R/renv")) + } + + # use platform-specific default fallbacks + if (Sys.info()[["sysname"]] == "Windows") + file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") + else if (Sys.info()[["sysname"]] == "Darwin") + "~/Library/Caches/org.R-project.R/R/renv" + else + "~/.cache/R/renv" + + } + + renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { + sha <- sha %||% attr(version, "sha", exact = TRUE) + parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = "") + } + + renv_bootstrap_exec <- function(project, libpath, version) { + if (!renv_bootstrap_load(project, libpath, version)) + renv_bootstrap_run(project, libpath, version) + } + + renv_bootstrap_run <- function(project, libpath, version) { + tryCatch( + renv_bootstrap_run_impl(project, libpath, version), + error = function(e) { + msg <- paste( + "failed to bootstrap renv: the project will not be loaded.", + paste("Reason:", conditionMessage(e)), + "Use `renv::activate()` to re-initialize the project.", + sep = "\n" + ) + warning(msg, call. = FALSE) + } + ) + } + + renv_bootstrap_run_impl <- function(project, libpath, version) { + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + return(renv::load(project = project)) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + + } + + renv_bootstrap_cache_version <- function() { + # NOTE: users should normally not override the cache version; + # this is provided just to make testing easier + Sys.getenv("RENV_CACHE_VERSION", unset = "v5") + } + + renv_bootstrap_cache_version_previous <- function() { + version <- renv_bootstrap_cache_version() + number <- as.integer(substring(version, 2L)) + paste("v", number - 1L, sep = "") + } + + renv_json_read <- function(file = NULL, text = NULL) { + + jlerr <- NULL + + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) { + + json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + jlerr <- json + + } + + # otherwise, fall back to the default JSON reader + json <- tryCatch(renv_json_read_default(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + # report an error + if (!is.null(jlerr)) + stop(jlerr) + else + stop(json) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_patterns <- function() { + + list( + + # objects + list("{", "\t\n\tobject(\t\n\t", TRUE), + list("}", "\t\n\t)\t\n\t", TRUE), + + # arrays + list("[", "\t\n\tarray(\t\n\t", TRUE), + list("]", "\n\t\n)\n\t\n", TRUE), + + # maps + list(":", "\t\n\t=\t\n\t", TRUE), + + # newlines + list("\\u000a", "\n", FALSE) + + ) + + } + + renv_json_read_envir <- function() { + + envir <- new.env(parent = emptyenv()) + + envir[["+"]] <- `+` + envir[["-"]] <- `-` + + envir[["object"]] <- function(...) { + result <- list(...) + names(result) <- as.character(names(result)) + result + } + + envir[["array"]] <- list + + envir[["true"]] <- TRUE + envir[["false"]] <- FALSE + envir[["null"]] <- NULL + + envir + + } + + renv_json_read_remap <- function(object, patterns) { + + # repair names if necessary + if (!is.null(names(object))) { + + nms <- names(object) + for (pattern in patterns) + nms <- gsub(pattern[[2L]], pattern[[1L]], nms, fixed = TRUE) + names(object) <- nms + + } + + # repair strings if necessary + if (is.character(object)) { + for (pattern in patterns) + object <- gsub(pattern[[2L]], pattern[[1L]], object, fixed = TRUE) + } + + # recurse for other objects + if (is.recursive(object)) + for (i in seq_along(object)) + object[i] <- list(renv_json_read_remap(object[[i]], patterns)) + + # return remapped object + object + + } + + renv_json_read_default <- function(file = NULL, text = NULL) { + + # read json text + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + + # convert into something the R parser will understand + patterns <- renv_json_read_patterns() + transformed <- text + for (pattern in patterns) + transformed <- gsub(pattern[[1L]], pattern[[2L]], transformed, fixed = TRUE) + + # parse it + rfile <- tempfile("renv-json-", fileext = ".R") + on.exit(unlink(rfile), add = TRUE) + writeLines(transformed, con = rfile) + json <- parse(rfile, keep.source = FALSE, srcfile = NULL)[[1L]] + + # evaluate in safe environment + result <- eval(json, envir = renv_json_read_envir()) + + # fix up strings if necessary -- do so only with reversible patterns + patterns <- Filter(function(pattern) pattern[[3L]], patterns) + renv_json_read_remap(result, patterns) + + } + + + # load the renv profile, if any + renv_bootstrap_profile_load(project) + + # construct path to library root + root <- renv_bootstrap_library_root(project) + + # construct library prefix for platform + prefix <- renv_bootstrap_platform_prefix() + + # construct full libpath + libpath <- file.path(root, prefix) + + # run bootstrap code + renv_bootstrap_exec(project, libpath, version) + + invisible() + +}) diff --git a/content/blog/mori-0-1-0/renv/settings.json b/content/blog/mori-0-1-0/renv/settings.json new file mode 100644 index 000000000..46f2f31cc --- /dev/null +++ b/content/blog/mori-0-1-0/renv/settings.json @@ -0,0 +1,21 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [], + "lockfile.sanitize": true, + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.dev": false, + "snapshot.type": "implicit", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} From 2d953f781e8b3d1b45f7feb5bead35feb97d971d Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Wed, 22 Apr 2026 20:34:19 +0100 Subject: [PATCH 3/8] Update mori stars/forks to current GitHub values The initial software registration used stars: 0 / forks: 0 as placeholders, which caused mori to be filtered out of the /software/ listing and the Pagefind search index (layouts/software/terms.html and taxonomy.itemindex.json both gate inclusion on a truthy stars value). Brings the counts into line with the live GitHub repo so mori surfaces correctly. --- content/software/mori/_index.md | 4 ++-- data/github-repos.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/software/mori/_index.md b/content/software/mori/_index.md index ae3808f81..14c27d747 100644 --- a/content/software/mori/_index.md +++ b/content/software/mori/_index.md @@ -16,7 +16,7 @@ website: https://shikokuchuo.net/mori/ external: # updated automatically, do not edit description: Shared Memory for R Objects first_commit: '2026-04-16T12:27:58+01:00' - forks: 0 + forks: 1 languages: - R last_updated: '2026-04-22T00:00:00+00:00' @@ -25,7 +25,7 @@ external: # updated automatically, do not edit people: - Charlie Gao repo: shikokuchuo/mori - stars: 0 + stars: 19 title: mori website: https://shikokuchuo.net/mori/ --- diff --git a/data/github-repos.toml b/data/github-repos.toml index d43203152..4e9371800 100644 --- a/data/github-repos.toml +++ b/data/github-repos.toml @@ -25345,8 +25345,8 @@ repo = "shikokuchuo/mori" name = "mori" description = "Shared Memory for R Objects" website = "https://shikokuchuo.net/mori/" -stars = 0 -forks = 0 +stars = 19 +forks = 1 latest_release = "2026-04-22T00:00:00+00:00" first_commit = "2026-04-16T12:27:58+01:00" license = "MIT License" From cd07ea03537002d3dd9a53c37250d97d4314b499 Mon Sep 17 00:00:00 2001 From: Charlie Gao <53399081+shikokuchuo@users.noreply.github.com> Date: Wed, 22 Apr 2026 22:42:31 +0100 Subject: [PATCH 4/8] Apply suggestions from code review Co-authored-by: Hadley Wickham --- content/blog/mori-0-1-0/index.qmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/blog/mori-0-1-0/index.qmd b/content/blog/mori-0-1-0/index.qmd index 340d41e13..eb9c57835 100644 --- a/content/blog/mori-0-1-0/index.qmd +++ b/content/blog/mori-0-1-0/index.qmd @@ -97,7 +97,7 @@ Lists and data frames travel element-wise too: sending a single column of a shar ```{r} daemons(3) -x <- list(a = rnorm(1e6), b = rnorm(1e6), c = rnorm(1e6)) |> share() +x <- share(list(a = rnorm(1e6), b = rnorm(1e6), c = rnorm(1e6))) mirai_map(x, \(v) lobstr::obj_size(v) |> format())[.flat] @@ -120,7 +120,7 @@ A shared data frame lives in a single shared region, but ALTREP columns are only Shared memory is tied to R's garbage collector. As long as the shared object (or anything extracted from it) is live in R, the shared region stays alive. When the last reference is dropped, the region is freed automatically — there are no lingering SHM segments to clean up. -Shared data is mapped read-only in consumers, so accidental writes can't corrupt data another process is reading. Mutations go through R's normal copy-on-write: editing a value inside a shared vector produces a private copy of that one vector, leaving the rest of the shared region untouched. +Mutations go through R's normal copy-on-write: editing a value inside a shared vector produces a private copy of that one vector, leaving the rest of the shared region untouched. ```{r} x <- share(rnorm(1e6)) @@ -159,4 +159,4 @@ mori is usable across any backend that plugs into R's standard serialization — mori is [available from CRAN](https://CRAN.R-project.org/package=mori). The [package website](https://shikokuchuo.net/mori/) has a walkthrough of the mirai integration and full reference documentation. mori is designed to slot quietly into existing parallel-R workflows — anywhere a worker currently receives a big dataset, `share()` it first and you're done. It complements [mirai](https://mirai.r-lib.org/): mirai handles async evaluation and daemon coordination, mori handles shared access to the data those daemons work on. -The package is in the `experimental` lifecycle stage while the API settles, so feedback and issue reports on [GitHub](https://github.com/shikokuchuo/mori/issues) are very welcome. +The package is in the experimental lifecycle stage while the API settles, so feedback and issue reports on [GitHub](https://github.com/shikokuchuo/mori/issues) are very welcome. From 179eb00a5bb22b847d11380680fde71d9f27ea15 Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Wed, 22 Apr 2026 22:47:24 +0100 Subject: [PATCH 5/8] Apply suggestions from @hadley --- content/blog/mori-0-1-0/index.md | 45 ++++---- content/blog/mori-0-1-0/index.qmd | 33 +++--- content/blog/mori-0-1-0/renv.lock | 177 ++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+), 32 deletions(-) diff --git a/content/blog/mori-0-1-0/index.md b/content/blog/mori-0-1-0/index.md index 61f39dc49..aab937f01 100644 --- a/content/blog/mori-0-1-0/index.md +++ b/content/blog/mori-0-1-0/index.md @@ -53,7 +53,7 @@ mean(x) [1] 0.0005737398 -`share()` works on atomic vector types, lists, and data frames --- it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those primitives. Environments, functions, S4 objects, and external pointers pass through unchanged, since their references don't map naturally to shared pages. +`share()` works on atomic vector types, lists, and data frames --- it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those types. Environments, functions, S4 objects, and external pointers are passed through as the original object --- `share()` skips them, since their references don't map naturally to shared pages. The returned object is an ALTREP view into shared memory --- it costs no additional RAM beyond the original region. It also serializes compactly: instead of sending the full 8 MB payload, mori's ALTREP hooks serialize shared objects as their shared-memory name, just over 100 bytes on the wire. @@ -75,43 +75,52 @@ Here's the motivating case --- a bootstrap across eight workers on a 200 MB data ``` r library(mirai) +library(purrr) daemons(8) df <- as.data.frame(matrix(rnorm(25e6), ncol = 5)) shared_df <- share(df) -boot_mean <- \(i, data) colMeans(data[sample(nrow(data), replace = TRUE), ]) - # Without mori — each daemon deserializes its own copy -mirai_map(1:8, boot_mean, data = df)[] |> system.time() +fn <- in_parallel( + \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), + data = df +) +system.time(map(1:8, fn)) ``` user system elapsed - 0.487 4.317 4.937 + 0.429 3.188 10.175 ``` r # With mori — each daemon maps the same shared memory -mirai_map(1:8, boot_mean, data = shared_df)[] |> system.time() +fn <- in_parallel( + \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), + data = shared_df +) +system.time(map(1:8, fn)) ``` user system elapsed - 0.000 0.001 0.031 + 0.000 0.000 4.785 ``` r daemons(0) ``` -The payload each daemon receives is ~300 bytes instead of 200 MB --- roughly 700,000× smaller. That's well over 100× wall-clock on this run. The algorithm hasn't changed; the savings come from not copying data that's already in RAM. Eight workers share one copy, not eight. +The payload each daemon receives is ~300 bytes instead of 200 MB --- roughly 700,000× smaller. That's about 2× wall-clock on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same, and the savings come from not copying data that's already in RAM. + +`share()` itself is paid once upfront --- roughly the cost of one serialize pass to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly --- so even a single send is a net win, and the savings compound with every additional daemon. -The gap shrinks as per-task compute grows: workloads where each worker does substantial work see proportionally smaller wall-clock wins, though never worse than the baseline. The headline number is what you see when data transfer dominates, which it often does in bootstrap, cross-validation, and parameter sweeps. +The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work --- bootstrap, cross-validation, parameter sweeps --- serialization dominates and the wall-clock win is largest; as each task does more substantial work the ratio shrinks, although we always get the memory saving. Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole frame. ``` r daemons(3) -x <- list(a = rnorm(1e6), b = rnorm(1e6), c = rnorm(1e6)) |> share() +x <- share(list(a = rnorm(1e6), b = rnorm(1e6), c = rnorm(1e6))) mirai_map(x, \(v) lobstr::obj_size(v) |> format())[.flat] ``` @@ -127,9 +136,9 @@ daemons(0) Anywhere parallel R workers process the same large dataset, `share()` removes the per-worker copy: -- A [Shiny](https://shiny.posit.co/) dashboard where every worker process reads from one shared reference dataset instead of loading its own -- A [tidymodels](https://www.tidymodels.org/) `tune_grid()` sweep --- or a [targets](https://docs.ropensci.org/targets/) pipeline branching over model variants --- where every fit reads the same training data without copying it -- Bootstrap, Monte Carlo, or permutation work dispatched across [mirai](https://mirai.r-lib.org/) or [crew](https://wlandau.github.io/crew/), where thousands of iterations all read from one shared dataset +- A [Shiny](https://shiny.posit.co/) dashboard where every worker process reads from one shared reference dataset instead of loading its own. +- A [tidymodels](https://www.tidymodels.org/) `tune_grid()` sweep --- or a [targets](https://docs.ropensci.org/targets/) pipeline branching over model variants --- where every fit reads the same training data without copying it. +- Bootstrap, Monte Carlo, or permutation work dispatched across [mirai](https://mirai.r-lib.org/) or [crew](https://wlandau.github.io/crew/), where thousands of iterations all read from one shared dataset. The pattern is the same in each case: call `share()` on your dataset once, then pass the result wherever you'd normally pass the data. Parallel dispatches that hit the serialization path transmit only the reference, not the data. @@ -137,9 +146,9 @@ The pattern is the same in each case: call `share()` on your dataset once, then A shared data frame lives in a single shared region, but ALTREP columns are only materialized when touched. A task that reads three columns out of one hundred pays for three --- character vectors are lazier still, with per-element access. Workers only pay for the data they actually touch. -Shared memory is tied to R's garbage collector. As long as the shared object (or anything extracted from it) is live in R, the shared region stays alive. When the last reference is dropped, the region is freed automatically --- there are no lingering SHM segments to clean up. +Shared memory is tied to R's garbage collector. As long as the shared object (or anything extracted from it) is live in R, the data stays available; when the last reference is dropped, it's freed automatically with no manual cleanup. The process that called `share()` needs to hold its reference until a consumer has mapped a view --- from that point on, the view itself keeps the shared memory alive. -Shared data is mapped read-only in consumers, so accidental writes can't corrupt data another process is reading. Mutations go through R's normal copy-on-write: editing a value inside a shared vector produces a private copy of that one vector, leaving the rest of the shared region untouched. +Mutations go through R's normal copy-on-write: editing a value inside a shared vector produces a private copy of that one vector, leaving the rest of the shared region untouched. ``` r x <- share(rnorm(1e6)) @@ -155,8 +164,6 @@ lobstr::obj_size(x) 8.00 MB -**One thing to keep in mind:** always assign the result of `share()` to a variable. The lifetime of the shared region is governed by the R reference, and an unassigned result can be garbage-collected before a consumer process has mapped it. - ## Sharing by name If you want to access a shared region from another process without going through serialization at all, you can pass its name directly: @@ -168,7 +175,7 @@ nm <- shared_name(x) nm ``` - [1] "/mori_12689_4" + [1] "/mori_10df5_4" ``` r # Works from another process; same session here to demonstrate @@ -190,4 +197,4 @@ mori is usable across any backend that plugs into R's standard serialization --- mori is [available from CRAN](https://CRAN.R-project.org/package=mori). The [package website](https://shikokuchuo.net/mori/) has a walkthrough of the mirai integration and full reference documentation. mori is designed to slot quietly into existing parallel-R workflows --- anywhere a worker currently receives a big dataset, `share()` it first and you're done. It complements [mirai](https://mirai.r-lib.org/): mirai handles async evaluation and daemon coordination, mori handles shared access to the data those daemons work on. -The package is in the `experimental` lifecycle stage while the API settles, so feedback and issue reports on [GitHub](https://github.com/shikokuchuo/mori/issues) are very welcome. +The package is in the experimental lifecycle stage while the API settles, so feedback and issue reports on [GitHub](https://github.com/shikokuchuo/mori/issues) are very welcome. diff --git a/content/blog/mori-0-1-0/index.qmd b/content/blog/mori-0-1-0/index.qmd index eb9c57835..7343c945f 100644 --- a/content/blog/mori-0-1-0/index.qmd +++ b/content/blog/mori-0-1-0/index.qmd @@ -51,7 +51,7 @@ x <- share(rnorm(1e6)) mean(x) ``` -`share()` works on atomic vector types, lists, and data frames — it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those primitives. Environments, functions, S4 objects, and external pointers pass through unchanged, since their references don't map naturally to shared pages. +`share()` works on atomic vector types, lists, and data frames — it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those types. Environments, functions, S4 objects, and external pointers are passed through as the original object — `share()` skips them, since their references don't map naturally to shared pages. The returned object is an ALTREP view into shared memory — it costs no additional RAM beyond the original region. It also serializes compactly: instead of sending the full 8 MB payload, mori's ALTREP hooks serialize shared objects as their shared-memory name, just over 100 bytes on the wire. @@ -71,26 +71,35 @@ Here's the motivating case — a bootstrap across eight workers on a 200 MB data ```{r} library(mirai) +library(purrr) daemons(8) df <- as.data.frame(matrix(rnorm(25e6), ncol = 5)) shared_df <- share(df) -boot_mean <- \(i, data) colMeans(data[sample(nrow(data), replace = TRUE), ]) - # Without mori — each daemon deserializes its own copy -mirai_map(1:8, boot_mean, data = df)[] |> system.time() +fn <- in_parallel( + \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), + data = df +) +system.time(map(1:8, fn)) # With mori — each daemon maps the same shared memory -mirai_map(1:8, boot_mean, data = shared_df)[] |> system.time() +fn <- in_parallel( + \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), + data = shared_df +) +system.time(map(1:8, fn)) daemons(0) ``` -The payload each daemon receives is ~300 bytes instead of 200 MB — roughly 700,000× smaller. That's well over 100× wall-clock on this run. The algorithm hasn't changed; the savings come from not copying data that's already in RAM. Eight workers share one copy, not eight. +The payload each daemon receives is ~300 bytes instead of 200 MB — roughly 700,000× smaller. That's about 2× wall-clock on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same, and the savings come from not copying data that's already in RAM. + +`share()` itself is paid once upfront — roughly the cost of one serialize pass to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly — so even a single send is a net win, and the savings compound with every additional daemon. -The gap shrinks as per-task compute grows: workloads where each worker does substantial work see proportionally smaller wall-clock wins, though never worse than the baseline. The headline number is what you see when data transfer dominates, which it often does in bootstrap, cross-validation, and parameter sweeps. +The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work — bootstrap, cross-validation, parameter sweeps — serialization dominates and the wall-clock win is largest; as each task does more substantial work the ratio shrinks, although we always get the memory saving. Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole frame. @@ -108,9 +117,9 @@ daemons(0) Anywhere parallel R workers process the same large dataset, `share()` removes the per-worker copy: -- A [Shiny](https://shiny.posit.co/) dashboard where every worker process reads from one shared reference dataset instead of loading its own -- A [tidymodels](https://www.tidymodels.org/) `tune_grid()` sweep — or a [targets](https://docs.ropensci.org/targets/) pipeline branching over model variants — where every fit reads the same training data without copying it -- Bootstrap, Monte Carlo, or permutation work dispatched across [mirai](https://mirai.r-lib.org/) or [crew](https://wlandau.github.io/crew/), where thousands of iterations all read from one shared dataset +- A [Shiny](https://shiny.posit.co/) dashboard where every worker process reads from one shared reference dataset instead of loading its own. +- A [tidymodels](https://www.tidymodels.org/) `tune_grid()` sweep — or a [targets](https://docs.ropensci.org/targets/) pipeline branching over model variants — where every fit reads the same training data without copying it. +- Bootstrap, Monte Carlo, or permutation work dispatched across [mirai](https://mirai.r-lib.org/) or [crew](https://wlandau.github.io/crew/), where thousands of iterations all read from one shared dataset. The pattern is the same in each case: call `share()` on your dataset once, then pass the result wherever you'd normally pass the data. Parallel dispatches that hit the serialization path transmit only the reference, not the data. @@ -118,7 +127,7 @@ The pattern is the same in each case: call `share()` on your dataset once, then A shared data frame lives in a single shared region, but ALTREP columns are only materialized when touched. A task that reads three columns out of one hundred pays for three — character vectors are lazier still, with per-element access. Workers only pay for the data they actually touch. -Shared memory is tied to R's garbage collector. As long as the shared object (or anything extracted from it) is live in R, the shared region stays alive. When the last reference is dropped, the region is freed automatically — there are no lingering SHM segments to clean up. +Shared memory is tied to R's garbage collector. As long as the shared object (or anything extracted from it) is live in R, the data stays available; when the last reference is dropped, it's freed automatically with no manual cleanup. The process that called `share()` needs to hold its reference until a consumer has mapped a view — from that point on, the view itself keeps the shared memory alive. Mutations go through R's normal copy-on-write: editing a value inside a shared vector produces a private copy of that one vector, leaving the rest of the shared region untouched. @@ -130,8 +139,6 @@ x[1] <- 0 # local mutation materializes a private copy lobstr::obj_size(x) ``` -**One thing to keep in mind:** always assign the result of `share()` to a variable. The lifetime of the shared region is governed by the R reference, and an unassigned result can be garbage-collected before a consumer process has mapped it. - ## Sharing by name If you want to access a shared region from another process without going through serialization at all, you can pass its name directly: diff --git a/content/blog/mori-0-1-0/renv.lock b/content/blog/mori-0-1-0/renv.lock index 105b1aa8a..0b4cfd29f 100644 --- a/content/blog/mori-0-1-0/renv.lock +++ b/content/blog/mori-0-1-0/renv.lock @@ -143,6 +143,12 @@ "Maintainer": "Winston Chang ", "Repository": "RSPM" }, + "carrier": { + "Package": "carrier", + "Version": "0.3.0.4", + "Source": "Repository", + "Repository": "CRAN" + }, "cli": { "Package": "cli", "Version": "3.6.6", @@ -430,6 +436,47 @@ "Maintainer": "Jeroen Ooms ", "Repository": "CRAN" }, + "glue": { + "Package": "glue", + "Version": "1.8.1", + "Source": "Repository", + "Title": "Interpreted String Literals", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Jennifer\", \"Bryan\", , \"jenny@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-6983-2759\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "An implementation of interpreted string literals, inspired by Python's Literal String Interpolation and Docstrings and Julia's Triple-Quoted String Literals .", + "License": "MIT + file LICENSE", + "URL": "https://glue.tidyverse.org/, https://github.com/tidyverse/glue", + "BugReports": "https://github.com/tidyverse/glue/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "crayon", + "DBI (>= 1.2.0)", + "dplyr", + "knitr", + "rlang", + "rmarkdown", + "RSQLite", + "testthat (>= 3.2.0)", + "vctrs (>= 0.3.0)", + "waldo (>= 0.5.3)", + "withr" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/Needs/website": "bench, forcats, ggbeeswarm, ggplot2, R.utils, rprintf, tidyr, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2026-04-16", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "yes", + "Author": "Jim Hester [aut] (ORCID: ), Jennifer Bryan [aut, cre] (ORCID: ), Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN" + }, "highr": { "Package": "highr", "Version": "0.12", @@ -698,6 +745,37 @@ "Maintainer": "Hadley Wickham ", "Repository": "CRAN" }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.5", + "Source": "Repository", + "Type": "Package", + "Title": "A Forward-Pipe Operator for R", + "Authors@R": "c( person(\"Stefan Milton\", \"Bache\", , \"stefan@stefanbache.dk\", role = c(\"aut\", \"cph\"), comment = \"Original author and creator of magrittr\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"cre\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "Provides a mechanism for chaining commands with a new forward-pipe operator, %>%. This operator will forward a value, or the result of an expression, into the next function call/expression. There is flexible support for the type of right-hand side expressions. For more information, see package vignette. To quote Rene Magritte, \"Ceci n'est pas un pipe.\"", + "License": "MIT + file LICENSE", + "URL": "https://magrittr.tidyverse.org, https://github.com/tidyverse/magrittr", + "BugReports": "https://github.com/tidyverse/magrittr/issues", + "Depends": [ + "R (>= 3.4.0)" + ], + "Suggests": [ + "covr", + "knitr", + "rlang", + "rmarkdown", + "testthat" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "Yes", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "yes", + "Author": "Stefan Milton Bache [aut, cph] (Original author and creator of magrittr), Hadley Wickham [aut], Lionel Henry [cre], Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, "memoise": { "Package": "memoise", "Version": "2.0.1", @@ -874,6 +952,55 @@ "Maintainer": "Gabor Csardi ", "Repository": "CRAN" }, + "purrr": { + "Package": "purrr", + "Version": "1.2.2", + "Source": "Repository", + "Title": "Functional Programming Tools", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"https://ror.org/03wc8by49\")) )", + "Description": "A complete and consistent functional programming toolkit for R.", + "License": "MIT + file LICENSE", + "URL": "https://purrr.tidyverse.org/, https://github.com/tidyverse/purrr", + "BugReports": "https://github.com/tidyverse/purrr/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "cli (>= 3.6.1)", + "lifecycle (>= 1.0.3)", + "magrittr (>= 1.5.0)", + "rlang (>= 1.1.1)", + "vctrs (>= 0.6.3)" + ], + "Suggests": [ + "carrier (>= 0.3.0)", + "covr", + "dplyr (>= 0.7.8)", + "httr", + "knitr", + "lubridate", + "mirai (>= 2.5.1)", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble", + "tidyselect" + ], + "LinkingTo": [ + "cli" + ], + "VignetteBuilder": "knitr", + "Biarch": "true", + "Config/build/compilation-database": "true", + "Config/Needs/website": "tidyverse/tidytemplate, tidyr", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "TRUE", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre] (ORCID: ), Lionel Henry [aut], Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, "rappdirs": { "Package": "rappdirs", "Version": "0.3.4", @@ -1128,6 +1255,56 @@ "Maintainer": "Yihui Xie ", "Repository": "CRAN" }, + "vctrs": { + "Package": "vctrs", + "Version": "0.7.3", + "Source": "Repository", + "Title": "Vector Helpers", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = c(\"aut\", \"cre\")), person(\"data.table team\", role = \"cph\", comment = \"Radix sort based on data.table's forder() and their contribution to R's order()\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Defines new notions of prototype and size that are used to provide tools for consistent and well-founded type-coercion and size-recycling, and are in turn connected to ideas of type- and size-stability useful for analysing function interfaces.", + "License": "MIT + file LICENSE", + "URL": "https://vctrs.r-lib.org/, https://github.com/r-lib/vctrs", + "BugReports": "https://github.com/r-lib/vctrs/issues", + "Depends": [ + "R (>= 4.0.0)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "glue", + "lifecycle (>= 1.0.3)", + "rlang (>= 1.1.7)" + ], + "Suggests": [ + "bit64", + "covr", + "crayon", + "dplyr (>= 0.8.5)", + "generics", + "knitr", + "pillar (>= 1.4.4)", + "pkgdown (>= 2.0.1)", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble (>= 3.1.3)", + "waldo (>= 0.2.0)", + "withr", + "xml2", + "zeallot" + ], + "VignetteBuilder": "knitr", + "Config/build/compilation-database": "true", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Encoding": "UTF-8", + "KeepSource": "true", + "Language": "en-GB", + "RoxygenNote": "7.3.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut], Lionel Henry [aut], Davis Vaughan [aut, cre], data.table team [cph] (Radix sort based on data.table's forder() and their contribution to R's order()), Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN" + }, "xfun": { "Package": "xfun", "Version": "0.57", From cd68961ed09bee9ccb884c3b9d0d9221e3f74b44 Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Thu, 23 Apr 2026 09:09:07 +0100 Subject: [PATCH 6/8] Final polish --- content/blog/mori-0-1-0/index.md | 38 +++++++++++++++---------------- content/blog/mori-0-1-0/index.qmd | 30 ++++++++++++------------ 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/content/blog/mori-0-1-0/index.md b/content/blog/mori-0-1-0/index.md index aab937f01..4480ec764 100644 --- a/content/blog/mori-0-1-0/index.md +++ b/content/blog/mori-0-1-0/index.md @@ -29,7 +29,7 @@ hidesubscription: false We're pleased to announce the first CRAN release of [mori](https://shikokuchuo.net/mori/). -Until now, parallel R has meant serializing your data to every worker and duplicating it in each worker's RAM. Eight workers × 1 GB is 8 GB, plus the serialization, transfer, and deserialization work to get it there. R processes don't share memory --- each has its own heap, so data crosses between them through a serialization pipe. +Until now, parallel R has meant serializing your data to every worker and duplicating it in each worker's RAM. Eight workers × 1 GB is 8 GB, plus the serialization, transfer, and deserialization cost to get it there. R processes don't share memory --- each has its own heap, so data crosses between them through a serialization pipe. mori changes that. It places an R object once into OS-level shared memory and lets every process on the machine read the same physical pages directly --- with no data copying between processes. @@ -37,11 +37,11 @@ mori changes that. It places an R object once into OS-level shared memory and le install.packages("mori") ``` -mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP.html) (Alternative Representation) framework, which lets a package expose a custom vector backend that reads its data from somewhere other than ordinary R memory --- a memory map, a database, a compressed store. Here, that somewhere is OS shared memory. +mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP.html) (Alternative Representation) framework, which lets a package expose a custom vector backend that reads its data from somewhere other than ordinary R memory --- a memory map, a database, a compressed store, or in this case, OS shared memory. ## How it looks -The entry point is `share()`. You pass it an R object, you get back a shared version you can use like any other R vector: +The entry point is `share()`. You pass it an R object, you get back a shared version of it that you can use the same way as the original: ``` r library(mori) @@ -61,7 +61,7 @@ The returned object is an ALTREP view into shared memory --- it costs no additio x |> serialize(NULL) |> length() ``` - [1] 125 + [1] 124 That compact serialization is what makes the rest of the picture work. @@ -82,40 +82,38 @@ daemons(8) df <- as.data.frame(matrix(rnorm(25e6), ncol = 5)) shared_df <- share(df) +boot <- \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]) + # Without mori — each daemon deserializes its own copy -fn <- in_parallel( - \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), - data = df +system.time( + map(1:8, in_parallel(\(i) boot(i), boot = boot, data = df)) ) -system.time(map(1:8, fn)) ``` user system elapsed - 0.429 3.188 10.175 + 0.423 3.200 10.080 ``` r # With mori — each daemon maps the same shared memory -fn <- in_parallel( - \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), - data = shared_df +system.time( + map(1:8, in_parallel(\(i) boot(i), boot = boot, data = shared_df)) ) -system.time(map(1:8, fn)) ``` user system elapsed - 0.000 0.000 4.785 + 0.001 0.001 4.762 ``` r daemons(0) ``` -The payload each daemon receives is ~300 bytes instead of 200 MB --- roughly 700,000× smaller. That's about 2× wall-clock on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same, and the savings come from not copying data that's already in RAM. +The payload each daemon receives is ~300 bytes instead of 200 MB --- roughly 700,000× smaller. There's a ~2× wall-clock saving on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same; the savings come from not copying data that's already in RAM. -`share()` itself is paid once upfront --- roughly the cost of one serialize pass to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly --- so even a single send is a net win, and the savings compound with every additional daemon. +`share()` itself is paid once upfront --- roughly the cost of one serialization to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly --- so even a single send is a net win, and the savings compound with every additional daemon. -The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work --- bootstrap, cross-validation, parameter sweeps --- serialization dominates and the wall-clock win is largest; as each task does more substantial work the ratio shrinks, although we always get the memory saving. +The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work --- bootstrap, cross-validation, parameter sweeps --- serialization dominates and the wall-clock win is largest; as each task involves more substantial compute, the ratio shrinks, although we always get the memory saving. -Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole frame. +Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole data frame. ``` r daemons(3) @@ -175,7 +173,7 @@ nm <- shared_name(x) nm ``` - [1] "/mori_10df5_4" + [1] "/mori_20ea_4" ``` r # Works from another process; same session here to demonstrate @@ -189,7 +187,7 @@ Handy when the consumer needs to attach by name rather than receive the shared o ## How mori fits -R has had partial answers to cross-process data sharing before. [bigmemory](https://CRAN.R-project.org/package=bigmemory) offers shared `big.matrix` objects --- effective, but limited to numeric matrices. [SharedObject](https://bioconductor.org/packages/SharedObject/) on Bioconductor targets a similar goal with its own memory-sharing machinery, oriented around BiocParallel workflows. [Arrow](https://arrow.apache.org/docs/r/)'s memory-mapped Parquet gives zero-copy columnar reads across processes, though the data lives on disk. On Unix, `parallel::mclapply` gets shared memory for free via fork copy-on-write --- until a worker writes to a page, with the usual fork caveats (unsafe in GUI sessions, with open DB connections, or alongside multithreaded libraries), and with no equivalent on Windows. +R has had partial answers to cross-process data sharing before. [bigmemory](https://CRAN.R-project.org/package=bigmemory) offers shared `big.matrix` objects --- effective, but limited to numeric matrices. [SharedObject](https://bioconductor.org/packages/SharedObject/) on Bioconductor targets a similar goal with its own memory-sharing machinery, oriented around BiocParallel workflows. [Arrow](https://arrow.apache.org/docs/r/)'s memory-mapped Parquet gives zero-copy columnar reads across processes, though the data lives on disk. On Unix, `parallel::mclapply` gets shared memory via fork copy-on-write (until a worker writes to a page), with the usual fork caveats (unsafe in GUI sessions, with open DB connections, or alongside multithreaded libraries), and with no equivalent on Windows. mori is usable across any backend that plugs into R's standard serialization --- mirai, future, parallel, foreach, callr --- with no special cooperation required. Atomic vectors, lists, and character vectors are all supported, with lazy per-element access preserved in every process. Lifetimes are managed by R's garbage collector: shared regions are freed automatically when the last reference drops. And mori itself is pure C --- POSIX shared memory on Linux and macOS, Win32 file mapping on Windows, nothing beyond the package to install. diff --git a/content/blog/mori-0-1-0/index.qmd b/content/blog/mori-0-1-0/index.qmd index 7343c945f..44f642a9a 100644 --- a/content/blog/mori-0-1-0/index.qmd +++ b/content/blog/mori-0-1-0/index.qmd @@ -28,7 +28,7 @@ hidesubscription: false We're pleased to announce the first CRAN release of [mori](https://shikokuchuo.net/mori/). -Until now, parallel R has meant serializing your data to every worker and duplicating it in each worker's RAM. Eight workers × 1 GB is 8 GB, plus the serialization, transfer, and deserialization work to get it there. R processes don't share memory — each has its own heap, so data crosses between them through a serialization pipe. +Until now, parallel R has meant serializing your data to every worker and duplicating it in each worker's RAM. Eight workers × 1 GB is 8 GB, plus the serialization, transfer, and deserialization cost to get it there. R processes don't share memory — each has its own heap, so data crosses between them through a serialization pipe. mori changes that. It places an R object once into OS-level shared memory and lets every process on the machine read the same physical pages directly — with no data copying between processes. @@ -37,11 +37,11 @@ mori changes that. It places an R object once into OS-level shared memory and le install.packages("mori") ``` -mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP.html) (Alternative Representation) framework, which lets a package expose a custom vector backend that reads its data from somewhere other than ordinary R memory — a memory map, a database, a compressed store. Here, that somewhere is OS shared memory. +mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP.html) (Alternative Representation) framework, which lets a package expose a custom vector backend that reads its data from somewhere other than ordinary R memory — a memory map, a database, a compressed store, or in this case, OS shared memory. ## How it looks -The entry point is `share()`. You pass it an R object, you get back a shared version you can use like any other R vector: +The entry point is `share()`. You pass it an R object, you get back a shared version of it that you can use the same way as the original: ```{r} library(mori) @@ -78,30 +78,28 @@ daemons(8) df <- as.data.frame(matrix(rnorm(25e6), ncol = 5)) shared_df <- share(df) +boot <- \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]) + # Without mori — each daemon deserializes its own copy -fn <- in_parallel( - \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), - data = df +system.time( + map(1:8, in_parallel(\(i) boot(i), boot = boot, data = df)) ) -system.time(map(1:8, fn)) # With mori — each daemon maps the same shared memory -fn <- in_parallel( - \(i) colMeans(data[sample(nrow(data), replace = TRUE), ]), - data = shared_df +system.time( + map(1:8, in_parallel(\(i) boot(i), boot = boot, data = shared_df)) ) -system.time(map(1:8, fn)) daemons(0) ``` -The payload each daemon receives is ~300 bytes instead of 200 MB — roughly 700,000× smaller. That's about 2× wall-clock on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same, and the savings come from not copying data that's already in RAM. +The payload each daemon receives is ~300 bytes instead of 200 MB — roughly 700,000× smaller. There's a ~2× wall-clock saving on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same; the savings come from not copying data that's already in RAM. -`share()` itself is paid once upfront — roughly the cost of one serialize pass to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly — so even a single send is a net win, and the savings compound with every additional daemon. +`share()` itself is paid once upfront — roughly the cost of one serialization to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly — so even a single send is a net win, and the savings compound with every additional daemon. -The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work — bootstrap, cross-validation, parameter sweeps — serialization dominates and the wall-clock win is largest; as each task does more substantial work the ratio shrinks, although we always get the memory saving. +The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work — bootstrap, cross-validation, parameter sweeps — serialization dominates and the wall-clock win is largest; as each task involves more substantial compute, the ratio shrinks, although we always get the memory saving. -Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole frame. +Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole data frame. ```{r} daemons(3) @@ -158,7 +156,7 @@ Handy when the consumer needs to attach by name rather than receive the shared o ## How mori fits -R has had partial answers to cross-process data sharing before. [bigmemory](https://CRAN.R-project.org/package=bigmemory) offers shared `big.matrix` objects — effective, but limited to numeric matrices. [SharedObject](https://bioconductor.org/packages/SharedObject/) on Bioconductor targets a similar goal with its own memory-sharing machinery, oriented around BiocParallel workflows. [Arrow](https://arrow.apache.org/docs/r/)'s memory-mapped Parquet gives zero-copy columnar reads across processes, though the data lives on disk. On Unix, `parallel::mclapply` gets shared memory for free via fork copy-on-write — until a worker writes to a page, with the usual fork caveats (unsafe in GUI sessions, with open DB connections, or alongside multithreaded libraries), and with no equivalent on Windows. +R has had partial answers to cross-process data sharing before. [bigmemory](https://CRAN.R-project.org/package=bigmemory) offers shared `big.matrix` objects — effective, but limited to numeric matrices. [SharedObject](https://bioconductor.org/packages/SharedObject/) on Bioconductor targets a similar goal with its own memory-sharing machinery, oriented around BiocParallel workflows. [Arrow](https://arrow.apache.org/docs/r/)'s memory-mapped Parquet gives zero-copy columnar reads across processes, though the data lives on disk. On Unix, `parallel::mclapply` gets shared memory via fork copy-on-write (until a worker writes to a page), with the usual fork caveats (unsafe in GUI sessions, with open DB connections, or alongside multithreaded libraries), and with no equivalent on Windows. mori is usable across any backend that plugs into R's standard serialization — mirai, future, parallel, foreach, callr — with no special cooperation required. Atomic vectors, lists, and character vectors are all supported, with lazy per-element access preserved in every process. Lifetimes are managed by R's garbage collector: shared regions are freed automatically when the last reference drops. And mori itself is pure C — POSIX shared memory on Linux and macOS, Win32 file mapping on Windows, nothing beyond the package to install. From 33ed8f745fd44e86609e3e2d3bd728d197e6348e Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Thu, 23 Apr 2026 09:13:30 +0100 Subject: [PATCH 7/8] Update blog date --- content/blog/mori-0-1-0/index.md | 8 ++++---- content/blog/mori-0-1-0/index.qmd | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/blog/mori-0-1-0/index.md b/content/blog/mori-0-1-0/index.md index 4480ec764..f27ade24e 100644 --- a/content/blog/mori-0-1-0/index.md +++ b/content/blog/mori-0-1-0/index.md @@ -1,6 +1,6 @@ --- title: 'mori: Shared memory for R objects' -date: 2026-04-22T00:00:00.000Z +date: 2026-04-23T00:00:00.000Z people: - Charlie Gao description: > @@ -91,7 +91,7 @@ system.time( ``` user system elapsed - 0.423 3.200 10.080 + 0.409 3.102 10.015 ``` r # With mori — each daemon maps the same shared memory @@ -101,7 +101,7 @@ system.time( ``` user system elapsed - 0.001 0.001 4.762 + 0.001 0.001 4.784 ``` r daemons(0) @@ -173,7 +173,7 @@ nm <- shared_name(x) nm ``` - [1] "/mori_20ea_4" + [1] "/mori_2426_4" ``` r # Works from another process; same session here to demonstrate diff --git a/content/blog/mori-0-1-0/index.qmd b/content/blog/mori-0-1-0/index.qmd index 44f642a9a..7aecc1be9 100644 --- a/content/blog/mori-0-1-0/index.qmd +++ b/content/blog/mori-0-1-0/index.qmd @@ -1,6 +1,6 @@ --- title: "mori: Shared memory for R objects" -date: 2026-04-22 +date: 2026-04-23 people: - Charlie Gao description: > From 2f9f4f819fbd2e90030623bb9a177eb02245360b Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Thu, 23 Apr 2026 12:58:41 +0100 Subject: [PATCH 8/8] Pre-merge edits --- content/blog/mori-0-1-0/index.md | 16 ++++++++-------- content/blog/mori-0-1-0/index.qmd | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/content/blog/mori-0-1-0/index.md b/content/blog/mori-0-1-0/index.md index f27ade24e..bd4e4ac1a 100644 --- a/content/blog/mori-0-1-0/index.md +++ b/content/blog/mori-0-1-0/index.md @@ -41,7 +41,7 @@ mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP ## How it looks -The entry point is `share()`. You pass it an R object, you get back a shared version of it that you can use the same way as the original: +The entry point is `share()`. You pass it an R object, you get back a shared version that you can use in the same way as the original: ``` r library(mori) @@ -53,7 +53,7 @@ mean(x) [1] 0.0005737398 -`share()` works on atomic vector types, lists, and data frames --- it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those types. Environments, functions, S4 objects, and external pointers are passed through as the original object --- `share()` skips them, since their references don't map naturally to shared pages. +`share()` works on atomic vector types, lists, and data frames --- it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those types. Environments, functions, S4 objects, and external pointers are returned unchanged, since their state can't be meaningfully exposed as raw bytes in shared memory. The returned object is an ALTREP view into shared memory --- it costs no additional RAM beyond the original region. It also serializes compactly: instead of sending the full 8 MB payload, mori's ALTREP hooks serialize shared objects as their shared-memory name, just over 100 bytes on the wire. @@ -61,7 +61,7 @@ The returned object is an ALTREP view into shared memory --- it costs no additio x |> serialize(NULL) |> length() ``` - [1] 124 + [1] 125 That compact serialization is what makes the rest of the picture work. @@ -91,7 +91,7 @@ system.time( ``` user system elapsed - 0.409 3.102 10.015 + 0.445 3.338 10.454 ``` r # With mori — each daemon maps the same shared memory @@ -101,17 +101,17 @@ system.time( ``` user system elapsed - 0.001 0.001 4.784 + 0.001 0.000 4.959 ``` r daemons(0) ``` -The payload each daemon receives is ~300 bytes instead of 200 MB --- roughly 700,000× smaller. There's a ~2× wall-clock saving on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same; the savings come from not copying data that's already in RAM. +The payload each daemon receives is ~300 bytes instead of 200 MB --- roughly 700,000× smaller. There's a ~2× wall-clock saving on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function call is the same; the savings come from not copying data that's already in RAM. `share()` itself is paid once upfront --- roughly the cost of one serialization to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly --- so even a single send is a net win, and the savings compound with every additional daemon. -The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work --- bootstrap, cross-validation, parameter sweeps --- serialization dominates and the wall-clock win is largest; as each task involves more substantial compute, the ratio shrinks, although we always get the memory saving. +The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work --- bootstrap, cross-validation, parameter sweeps --- serialization dominates and the wall-clock win is largest; the ratio shrinks as each task starts to involve more substantial compute, although we always get the memory saving. Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole data frame. @@ -173,7 +173,7 @@ nm <- shared_name(x) nm ``` - [1] "/mori_2426_4" + [1] "/mori_113fe_4" ``` r # Works from another process; same session here to demonstrate diff --git a/content/blog/mori-0-1-0/index.qmd b/content/blog/mori-0-1-0/index.qmd index 7aecc1be9..816bd3d9c 100644 --- a/content/blog/mori-0-1-0/index.qmd +++ b/content/blog/mori-0-1-0/index.qmd @@ -41,7 +41,7 @@ mori is built on R's [ALTREP](https://svn.r-project.org/R/branches/ALTREP/ALTREP ## How it looks -The entry point is `share()`. You pass it an R object, you get back a shared version of it that you can use the same way as the original: +The entry point is `share()`. You pass it an R object, you get back a shared version that you can use in the same way as the original: ```{r} library(mori) @@ -51,7 +51,7 @@ x <- share(rnorm(1e6)) mean(x) ``` -`share()` works on atomic vector types, lists, and data frames — it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those types. Environments, functions, S4 objects, and external pointers are passed through as the original object — `share()` skips them, since their references don't map naturally to shared pages. +`share()` works on atomic vector types, lists, and data frames — it writes them directly into shared memory with attributes preserved. In practice that also covers tibbles, data.tables, factors, dates, and matrices, since they're built on those types. Environments, functions, S4 objects, and external pointers are returned unchanged, since their state can't be meaningfully exposed as raw bytes in shared memory. The returned object is an ALTREP view into shared memory — it costs no additional RAM beyond the original region. It also serializes compactly: instead of sending the full 8 MB payload, mori's ALTREP hooks serialize shared objects as their shared-memory name, just over 100 bytes on the wire. @@ -93,11 +93,11 @@ system.time( daemons(0) ``` -The payload each daemon receives is ~300 bytes instead of 200 MB — roughly 700,000× smaller. There's a ~2× wall-clock saving on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function is the same; the savings come from not copying data that's already in RAM. +The payload each daemon receives is ~300 bytes instead of 200 MB — roughly 700,000× smaller. There's a ~2× wall-clock saving on this run, and eight workers now share a single 200 MB copy in memory instead of materializing one each. The function call is the same; the savings come from not copying data that's already in RAM. `share()` itself is paid once upfront — roughly the cost of one serialization to write into shared memory. Daemons don't pay a deserialize cost on the other end, since they read the same physical memory directly — so even a single send is a net win, and the savings compound with every additional daemon. -The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work — bootstrap, cross-validation, parameter sweeps — serialization dominates and the wall-clock win is largest; as each task involves more substantial compute, the ratio shrinks, although we always get the memory saving. +The wall-clock gap depends on how much of the run is data transfer versus compute. On cheap per-task work — bootstrap, cross-validation, parameter sweeps — serialization dominates and the wall-clock win is largest; the ratio shrinks as each task starts to involve more substantial compute, although we always get the memory saving. Lists and data frames travel element-wise too: sending a single column of a shared data frame transmits only that element's reference, not the whole data frame.