galaaz 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fc6f307a98f073e4ad49a39f5b4fcfddbd948c9054722caea814c16d6be62fa
4
- data.tar.gz: d899ca8013e16d158cb1c035a3e8d1393b3d377782fad502b09d1e81d9eb868a
3
+ metadata.gz: fe7e81157b29ea65c61ca9bb97ab5a7f458b90b601cd1c76d8e1740e95e1f69f
4
+ data.tar.gz: bfd7e6b8f867ef903cb5119837d0e045b11c57e3aa2b5c9a717447abd0922478
5
5
  SHA512:
6
- metadata.gz: a73ce81b2b86550af39562adc7d1566746c5239d0b74688c8d1d1cef52bb5371ab5449cb3dbe3d6b14b2608e1c33e3289937f745a9749c7c425f026a4d8f8659
7
- data.tar.gz: 3d84d7e16f678ed8b13920585099df2ae641293ae74f65e7920d7bd7ee42c971deaa9c7dd1985343fb2eadf17be582d3922eecf3d20d009bfc45180f762b7b26
6
+ metadata.gz: 5599509abe5d487fb7e19d8ae3fb1a80a558dcc6928e4a526753253ff816820d41509d2f179d6968ca985bbb19084c60ab0f0fc82e34276d840a49a627ad171d
7
+ data.tar.gz: 3560c286e71ce88fe5486d71f62c4fb2cba342bf8af03f93e87a2c34ded854fce98eed90b57fb094acd39d333d0d0ea9bb49c35f651a0b33367b2bbc96c09b62
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.1.2
4
+
5
+ ### Fixed
6
+
7
+ - CRAN installs (`galaaz setup` / `galaaz add`) use a writable user library
8
+ (`R_LIBS_USER`, default `~/.local/lib/R/library`) so Omarchy/Arch no longer fail
9
+ with `lib = "/usr/lib/R/library" is not writable`.
10
+ - Gatekeeper `ext/new_bridge` Makefile uses `R CMD config --ldflags` instead of
11
+ hardcoded `-L$(R_HOME)/lib -lR` (breaks when `RHOME` is `/usr/lib64/R`).
12
+ - `galaaz setup` marks profile `core` on success.
13
+
14
+ ### Notes
15
+
16
+ - Omarchy dogfood: pin `script/omarchy/install-galaaz.sh` to this version; re-copy
17
+ the installer into `~/.local/bin/omarchy-install-galaaz` after updating.
18
+
19
+ ## 2.1.1
20
+
21
+ ### Added
22
+
23
+ - CLI on `bin/galaaz`: `setup`, `blogs init`, `doctor`, `add` (knit / arrow / tex / bio /
24
+ examples / ledger / demo). Legacy unknown args still forward to rake.
25
+ - Omarchy dogfood helpers under `script/omarchy/` (install/remove scripts + menu overlay).
26
+ - `galaaz doctor` reports both CRuby and JRuby when available (mise-aware).
27
+ - Package lists `r_requires/knit.txt`, `knit-extras.txt`, `arrow.txt` for add-on installs.
28
+ - Cold-install CRuby path uses `galaaz setup` + `galaaz blogs init`.
29
+
30
+ ### Notes
31
+
32
+ - Omarchy / stranger install remains `gem install galaaz` then `galaaz setup` (no
33
+ `bundle install` for core use). See `Documentation/PLAN_OMARCHY_INTEGRATION.md`.
34
+
3
35
  ## 2.1.0
4
36
 
5
37
  Galaaz **2.1** keeps the **galaaz2_0** integration line as the main development branch and marks
@@ -10,14 +42,16 @@ Galaaz **2.1** keeps the **galaaz2_0** integration line as the main development
10
42
  - First-class **CRuby** NewBridge path alongside JRuby (engine-aware launchers, cold-install /
11
43
  CI coverage for both).
12
44
  - Docs: treat JRuby and CRuby as equal supported runtimes for the bridge.
13
- - [Documentation/ROADMAP_ARROW_RUBY_R.md](Documentation/ROADMAP_ARROW_RUBY_R.md) — roadmap for
14
- Ruby↔R Arrow IPC / mmap handoff (stage B) then shared-memory bus (stage C).
45
+ - [Documentation/ROADMAP_ARROW_RUBY_R.md](Documentation/ROADMAP_ARROW_RUBY_R.md) — stages A (copy),
46
+ B1/B2 (IPC/mmap file; shipped), C (shared-memory bus; future).
47
+ - Stage **B1/B2** APIs: `Galaaz::ArrowIpc`, `R::Arrow.open_ipc`, `R::Arrow.write_ipc` (CRuby
48
+ red-arrow + system Arrow GLib; JRuby Arrow Java + `JAVA_OPTS` nio opens).
15
49
 
16
50
  ### Notes
17
51
 
18
52
  - Git branch **`galaaz2_0`** remains the integration branch name; the gem version is **2.1.0**.
19
- - Apache Arrow **zero-copy shared RAM** is still future work (see the roadmap); today’s helpers
20
- build R-side tables after a handoff, then use proxy / Remote Control calls.
53
+ - Apache Arrow **zero-copy shared RAM** (Stage C) is still future work. Stage A copies into R;
54
+ Stage B uses an IPC file and only the path crosses NewBridge. See the roadmap.
21
55
 
22
56
  ## 2.0.0
23
57
 
data/README.md CHANGED
@@ -59,9 +59,11 @@ CRuby when you prefer MRI. R remains the same **GNU R** you use interactively—
59
59
  compiled extensions and Bioconductor. Earlier GraalVM / TruffleRuby / FastR experiments
60
60
  are no longer the focus.
61
61
 
62
- The bridge handles **communication and typing** between the two worlds; large tables can
63
- also flow through **Apache Arrow** on the R side when you use the optional helpers described
64
- later in this manual.
62
+ The bridge handles **communication and typing** between the two worlds. Large tables can use
63
+ **Apache Arrow** in two shipped modes (described later): **Stage A** copies Ruby batches into an
64
+ R-side Arrow table (`R::Arrow.from_ruby_batches`); **Stage B** writes an Arrow IPC file and only
65
+ the **path** crosses NewBridge (`Galaaz::ArrowIpc` + `R::Arrow.open_ipc` / `write_ipc`). Shared-heap
66
+ zero-copy is **Stage C** and is not shipped.
65
67
 
66
68
  ## R-on-Rails: the one-person app for R scientists
67
69
 
@@ -340,7 +342,7 @@ The supported install is **`gem install` + compile the gatekeeper**. You do not
340
342
  make -C "${gem_dir}/ext/new_bridge" all
341
343
  ```
342
344
 
343
- 5. Ensure **`R`** starts GNU R and can install packages (network access to CRAN when you first call `R.install_and_loads`). For **Apache Arrow** on Java 9+, pass `-J--add-opens=java.base/java.nio=ALL-UNNAMED` to JRuby (from a checkout, `bin/galaaz-jruby` does this; on CRuby this flag is not needed).
345
+ 5. Ensure **`R`** starts GNU R and can install packages (network access to CRAN when you first call `R.install_and_loads`). For **Apache Arrow** on **JRuby** (Java 9+), the child JVM needs `--add-opens=java.base/java.nio=ALL-UNNAMED` via **`JAVA_OPTS`** (from a checkout, `bin/galaaz-jruby` and `mise.toml` set this; a leading `jruby -J... -S bundle exec` does **not** pass `-J` to rspec). On **CRuby**, install Apache Arrow GLib (`libarrow-glib-dev` from the [Apache Arrow APT](https://arrow.apache.org/install/) repo) and `gem install red-arrow` matching `pkg-config --modversion arrow-glib`. Do not install the unrelated Rubygems package named `arrow`.
344
346
 
345
347
  For **gKnit**, **knitr**, **rmarkdown**, and LaTeX (PDF output), install the corresponding R packages, **Pandoc**, and a TeX distribution if you need PDF; the repository includes helpers such as **`bin/install-tinytex`** where appropriate.
346
348
 
@@ -442,13 +444,15 @@ A practical pattern is:
442
444
 
443
445
  1. Use threads (or a connection pool) to read from **multiple databases or shards** in parallel.
444
446
  2. Merge the rows in Ruby under a `Mutex` if you collect into one structure.
445
- 3. Hand the merged table to R **once** (for example with `R::Arrow.from_ruby_batches` and dplyr,
446
- or by building a data frame) so heavy statistics run in R with fewer bridge round-trips.
447
+ 3. Hand the merged table to R **once**: **`R::Arrow.from_ruby_batches`** (Stage A: copy into R) or
448
+ **`Galaaz::ArrowIpc.write` / `write_batches`** then **`R::Arrow.open_ipc`** (Stage B: IPC file;
449
+ only the path crosses the bridge). Then run dplyr in R.
447
450
 
448
451
  A runnable sketch lives in
449
452
  `examples/multithread_shards_to_r/shards_to_r.rb` (simulated shard queries; swap in your DB
450
453
  driver). For concurrency tests on the bridge itself, see `specs/bridge_concurrent_spec.rb` and
451
- `specs/arrow_from_ruby_batches_spec.rb`.
454
+ `specs/arrow_from_ruby_batches_spec.rb`. Stage B IPC tests: `specs/arrow_ipc_handoff_spec.rb`,
455
+ `specs/arrow_ipc_export_spec.rb`.
452
456
 
453
457
  ## Long-running R calls and a completion block
454
458
 
@@ -4025,35 +4029,77 @@ ans = flights[:all, E.list(R[:arr_delay], R[:dep_delay])]
4025
4029
  # Apache Arrow
4026
4030
 
4027
4031
  [Apache Arrow](https://arrow.apache.org/) is a **columnar** in-memory format used heavily in R
4028
- and Python for analytics. In Galaaz, **Ruby does not hold an Arrow C++ table itself**; instead you
4029
- build ordinary Ruby structures (arrays of row hashes), and **`R::Arrow.from_ruby_batches`** creates
4030
- a real **Arrow `Table` inside GNU R**. From there you use R’s **`arrow`** and **`dplyr`** packages
4031
- as usual: **`group_by`** on the Arrow table, **`summarise`** for aggregates, then **`collect()`** to
4032
- materialize a tibble when you need in-memory R rows.
4033
-
4034
- That pattern matches production use: **JRuby threads** (or sequential code) assemble many rows in
4035
- Ruby; you pay **one** bridge-heavy handoff to R; **dplyr** runs vectorised work on the Arrow table
4036
- in R.
4032
+ and Python for analytics. GNU R still runs in a **separate process**. Ruby does **not** hold a
4033
+ shared Arrow C++ table with R. Stages:
4034
+
4035
+ 1. **Stage A (copy over the bridge):** Ruby row hashes **`R::Arrow.from_ruby_batches`** builds
4036
+ an Arrow `Table` **inside GNU R**. You get a **proxy**.
4037
+ 2. **Stage B1 (Ruby → R IPC file):** **`Galaaz::ArrowIpc.write`** / **`write_batches`** writes an
4038
+ Arrow IPC file (prefer **`/dev/shm`**); **`R::Arrow.open_ipc(path)`** opens it in R. Only the
4039
+ **path** crosses NewBridge. This is **mmap/IPC file handoff**, not a shared heap.
4040
+ 3. **Stage B2 (R → Ruby IPC file):** **`R::Arrow.write_ipc(obj)`** writes uncompressed IPC; Ruby
4041
+ reads with **`Galaaz::ArrowIpc.read`** (column hash) or **`read_batches`** (row hashes). Call
4042
+ **`Galaaz::ArrowIpc.release(path)`** when finished.
4043
+ 4. **Stage C (not shipped):** named shared-memory bus. Do not claim 0 ms shared RAM until then.
4044
+ See **`Documentation/ROADMAP_ARROW_RUBY_R.md`**.
4045
+
4046
+ After ingest, use R’s **`arrow`** / **`dplyr`** on the proxy (`group_by`, `summarise`, `collect`)
4047
+ and unbox only KPIs you need in Ruby.
4048
+
4049
+ **Optional Ruby backends for Stage B**
4050
+
4051
+ * **CRuby:** Apache **red-arrow** — `gem install red-arrow` pinned to the same major as
4052
+ `pkg-config --modversion arrow-glib`, plus system **Arrow GLib** (`libarrow-glib-dev` from the
4053
+ [Apache Arrow APT](https://arrow.apache.org/install/) repo). Do **not** install the unrelated
4054
+ legacy Rubygems package named `arrow`. `bundle exec` still sees a user-installed `red-arrow`
4055
+ via Galaaz’s load-path helper.
4056
+ * **JRuby:** Apache Arrow **Java** JARs — **`GALAAZ_ARROW_JARS`**, `~/arrow_jars`, or
4057
+ `jar-dependencies`. Export **`JAVA_OPTS=--add-opens=java.base/java.nio=ALL-UNNAMED`** on the
4058
+ **child** JVM (`bin/galaaz-jruby`, `mise.toml`). `jruby -J... -S bundle exec rspec` does **not**
4059
+ pass `-J` to rspec.
4060
+
4061
+ **R packages:** **`arrow`** and **`dplyr`**. B2 writes IPC with **`compression: 'uncompressed'`**
4062
+ so JRuby Arrow Java can read without extra compression JARs.
4063
+
4064
+ **Tests:** `specs/arrow_from_ruby_batches_spec.rb` (A);
4065
+ `specs/arrow_ipc_handoff_spec.rb`, `specs/arrow_ipc_export_spec.rb` (B, sync);
4066
+ `new_bridge_specs/arrow_ipc_async_spec.rb`, `new_bridge_specs/arrow_ipc_export_async_spec.rb` (B, async).
4067
+
4068
+ ## `R::Arrow` and `Galaaz::ArrowIpc`
4069
+
4070
+ * **`R::Arrow.from_ruby_batches`** — Stage A ingest.
4071
+ * **`R::Arrow.open_ipc(path)`** — Stage B1: IPC file → R Table proxy.
4072
+ * **`R::Arrow.write_ipc(obj, path = nil)`** — Stage B2: R Table/tibble → IPC path (scratch if omitted).
4073
+ * **`Galaaz::ArrowIpc.write` / `write_batches` / `read` / `read_batches` / `allocate_path` / `release` / `available?`**
4074
+ * **`R::Arrow.table_from(df)`** — wrap an R `data.frame` / tibble as an Arrow table.
4075
+ * **`R::Arrow.read_feather` / `write_feather`**, **`read_parquet`**, **`dataset(path)`** — file and
4076
+ dataset IO on paths visible to R.
4037
4077
 
4038
- **Prerequisites:** install R packages **`arrow`** and **`dplyr`**. Run scripts with
4039
- **`bin/galaaz-jruby`** (or the same JVM flags as in **`docs/testing.md`**) so the Arrow JNI stack is
4040
- available.
4078
+ ## Example: Stage B round-trip (IPC file)
4041
4079
 
4042
- ## Other `R::Arrow` helpers
4080
+ Requires `Galaaz::ArrowIpc.available?` (red-arrow or Arrow JARs) and R **`arrow`**. Not knitted
4081
+ below so a machine without the optional backend still builds this manual.
4043
4082
 
4044
- The Ruby module **`R::Arrow`** (see `lib/R_interface/r_arrow.rb`) also includes:
4083
+ ```ruby
4084
+ path = Galaaz::ArrowIpc.write(id: [1, 2, 3], grp: %w[a a b], value: [1.0, 2.0, 3.5])
4085
+ tbl = R::Arrow.open_ipc(path)
4086
+ Galaaz::ArrowIpc.release(path)
4045
4087
 
4046
- * **`R::Arrow.table_from(df)`** — wrap an R `data.frame` / tibble as an Arrow table.
4047
- * **`R::Arrow.read_feather` / `write_feather`**, **`read_parquet`**, **`dataset(path)`** — file and
4048
- dataset IO on paths visible to R.
4088
+ summed = R.dplyr___summarise(R.dplyr___group_by(tbl, :grp), total: E.sum(:value))
4089
+ out_path = R::Arrow.write_ipc(summed)
4090
+ rows = Galaaz::ArrowIpc.read_batches(out_path)
4091
+ Galaaz::ArrowIpc.release(out_path)
4092
+ # rows => [{:grp=>"a", :total=>3.0}, {:grp=>"b", :total=>3.5}] (illustrative)
4093
+ ```
4049
4094
 
4050
4095
  ## Example: many Ruby rows → Arrow in R → grouped statistics
4051
4096
 
4052
4097
  The repository test **`slow-specs/arrow_large_pipeline_spec.rb`** builds **200k rows** in parallel
4053
- (eight threads × 25,000 rows), pushes them through **`R::Arrow.from_ruby_batches`**, then checks that
4054
- **dplyr** group summaries match a Ruby reference calculation. The same logic appears below at a
4055
- **smaller scale** so this manual can knit quickly; increase `thread_count` and `rows_per_thread`
4056
- when experimenting locally.
4098
+ (eight threads × 25,000 rows), pushes them through **`R::Arrow.from_ruby_batches`** (Stage A), then
4099
+ checks that **dplyr** group summaries match a Ruby reference calculation. The same logic appears
4100
+ below at a **smaller scale** so this manual can knit quickly; increase `thread_count` and
4101
+ `rows_per_thread` when experimenting locally. For the same ingest **without** copying every cell
4102
+ over NewBridge, use Stage B (`write_batches` + `open_ipc`) instead of `from_ruby_batches`.
4057
4103
 
4058
4104
 
4059
4105
  ``` ruby
@@ -4119,10 +4165,10 @@ end
4119
4165
  ```
4120
4166
 
4121
4167
  **What to notice:** (1) Ruby only sees **`Hash`** rows and Ruby **`Thread`** objects; (2) a single
4122
- **`from_ruby_batches`** call creates the Arrow table in R; (3) **`dplyr___group_by`** /
4168
+ **`from_ruby_batches`** call **copies** those columns into an Arrow table in R; (3) **`dplyr___group_by`** /
4123
4169
  **`dplyr___summarise`** / **`dplyr___collect`** mirror **`dplyr::group_by`** /
4124
4170
  **`dplyr::summarise`** / **`dplyr::collect`** on an Arrow-backed table. For a lighter test, see
4125
- **`specs/arrow_from_ruby_batches_spec.rb`**; for the full-size benchmark, run
4171
+ **`specs/arrow_from_ruby_batches_spec.rb`**; for the full-size Stage A benchmark, run
4126
4172
  **`bin/run_slow_rspec slow-specs/arrow_large_pipeline_spec.rb`**.
4127
4173
 
4128
4174
  # Bioconductor and DESeq2
@@ -4260,8 +4306,9 @@ Practical tips:
4260
4306
  glue.
4261
4307
  * **Reuse one process**: running many short scripts cold-starts Ruby, the JVM, and R each time;
4262
4308
  a long-lived process or repeated calls in one run amortize setup (see benchmarks below).
4263
- * **Batch data**: merge shards in Ruby, then call **`R::Arrow.from_ruby_batches`** (or build one
4264
- data frame) instead of millions of tiny R calls.
4309
+ * **Batch data**: merge shards in Ruby, then **`R::Arrow.from_ruby_batches`** (Stage A) or
4310
+ **`Galaaz::ArrowIpc`** + **`R::Arrow.open_ipc`** (Stage B) instead of millions of tiny R calls.
4311
+ When Ruby needs a bulky result table back, **`R::Arrow.write_ipc`** + **`Galaaz::ArrowIpc.read_batches`**.
4265
4312
 
4266
4313
  For measured discussion (including DESeq2-style workloads and warm comparisons), see
4267
4314
  **`docs/performance.md`** and **`docs/deseq2_airway_benchmark.md`** in the Galaaz repository.
data/bin/galaaz CHANGED
@@ -1,5 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- Dir.chdir(File.dirname(File.expand_path('..', __FILE__)))
4
+ # Galaaz CLI: setup / blogs / doctor / add.
5
+ # Unknown commands still forward to rake (legacy example runners).
4
6
 
5
- system ("rake #{ARGV[0]}")
7
+ root = File.expand_path('..', __dir__)
8
+ lib = File.join(root, 'lib')
9
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
10
+
11
+ require 'galaaz/cli'
12
+
13
+ exit Galaaz::CLI.run(ARGV)
data/bin/galaaz-jruby CHANGED
File without changes
data/bin/galaaz-ruby CHANGED
File without changes
@@ -1,6 +1,22 @@
1
- # Galaaz required JVM flags for JRuby (Apache Arrow on Java 9+).
1
+ # Galaaz required JVM flags for JRuby (Apache Arrow memory on Java 9+).
2
2
  # Source from bin/*.sh: source "$ROOT/bin/galaaz_jruby_env.inc.sh"
3
3
  #
4
- # Source of truth in Ruby/Rake: lib/galaaz_jruby.rb (GalaazJRuby::REQUIRED_JRUBY_J_ARGS).
4
+ # Source of truth in Ruby/Rake: lib/galaaz_jruby.rb (GalaazJRuby::JAVA_NIO_ADD_OPENS).
5
5
  # Optional extra -J flags: export GALAAZ_JRUBY_OPTS="-J-Xmx4g" (space-separated).
6
- GALAAZ_REQUIRED_JRUBY_J_ARGS='-J--add-opens=java.base/java.nio=ALL-UNNAMED'
6
+ #
7
+ # JAVA_OPTS is exported so *child* JRuby processes (bundle exec rspec, mise exec)
8
+ # get the same opens flag. -J args on the outer command are not inherited by
9
+ # bundle exec's second JVM.
10
+ GALAAZ_JAVA_NIO_ADD_OPENS='--add-opens=java.base/java.nio=ALL-UNNAMED'
11
+ GALAAZ_REQUIRED_JRUBY_J_ARGS="-J${GALAAZ_JAVA_NIO_ADD_OPENS}"
12
+
13
+ case " ${JAVA_OPTS:-} " in
14
+ *" ${GALAAZ_JAVA_NIO_ADD_OPENS} "*) ;;
15
+ *)
16
+ if [ -n "${JAVA_OPTS:-}" ]; then
17
+ export JAVA_OPTS="${GALAAZ_JAVA_NIO_ADD_OPENS} ${JAVA_OPTS}"
18
+ else
19
+ export JAVA_OPTS="${GALAAZ_JAVA_NIO_ADD_OPENS}"
20
+ fi
21
+ ;;
22
+ esac
@@ -7,6 +7,7 @@
7
7
  #
8
8
  # JRuby and CRuby are both first-class. Override with GALAAZ_RUBY=jruby, GALAAZ_RUBY=ruby,
9
9
  # or a full path. Extra JRuby flags: GALAAZ_JRUBY_OPTS="-J-Xmx4g" (ignored on CRuby).
10
+ # CRuby red-arrow uses system Arrow GLib (Apache Arrow APT / libarrow-glib-dev).
10
11
 
11
12
  GALAAZ_RUBY_BIN="${GALAAZ_RUBY:-ruby}"
12
13
 
@@ -29,6 +30,7 @@ if [[ "$_galaaz_is_jruby" -eq 1 ]]; then
29
30
  # shellcheck source=galaaz_jruby_env.inc.sh
30
31
  source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/galaaz_jruby_env.inc.sh"
31
32
  GALAAZ_RUBY_J_ARGS="$GALAAZ_REQUIRED_JRUBY_J_ARGS ${GALAAZ_JRUBY_OPTS:-}"
33
+ # JAVA_OPTS is exported by galaaz_jruby_env.inc.sh for bundle-exec child JVMs
32
34
  else
33
35
  GALAAZ_REQUIRED_JRUBY_J_ARGS=''
34
36
  GALAAZ_RUBY_J_ARGS=''
data/bin/gbookdown CHANGED
File without changes