Skip to content

Commit cc26b01

Browse files
committed
feat(70): the propagation tier — RWR, heat diffusion, resistance, SimRank, and the triad census
Round 69 asked which algorithms could take MCL's dense-matmul lead; this round builds the five families the scientific-use assessment ranked highest, aimed at network biology's propagation methods. Seven public methods, each with a CPU reference (the spec), executor routing, closed-form Node specs, and — for the five dense forms — GPU kernels, parity specs with verified controls, and benchmark rows. The tier's structural decision: seed forms vs dense forms. randomWalkWithRestart({seeds}) and heatDiffusion({seeds}) — the everyday bio calls — are O(E)-per-step sparse walks, so they are CPU-only and an explicit 'gpu' rejects, pointing at the dense sibling (the weighted-betweenness no-path precedent). The dense forms are the GPU tier: - randomWalkWithRestartProximity: S = c(I − (1−c)W)⁻¹ by Neumann iteration, one matmul per step; CPU = one sparse solve per column. - heatKernel: exp(−tL) by scaling-and-squaring (Taylor chain + s squarings); CPU applies the same scaled operator 2^s times per column — the same power, sparsely. Pinned against the pair and triangle matrix exponentials in closed form. - effectiveResistance (+ commuteTime): B = L + J-blocks (the 1/n_c shift cancels out of every resistance), CPU f64 Gauss–Jordan, GPU Newton–Schulz — O(n³) both sides, so the GPU wins at every density. The NS converge compare is *relative* (NS_COMPARE): an absolute bound sits under f32 noise wherever the inverse's entries are large (measured: 96/96 iterations ran at n=1024; relative freezing took it 642 → 200 ms). - simRank: S′ = C·Q·S·Qᵀ, two matmuls per step, diagonal pinned; pinned against the 4-cycle fixed point x = C(1+x)/2. - motifCensus: the 16 Holland–Leinhardt classes ('030T' = the feed-forward loop) as closed forms over seven trace primitives shared verbatim by both executors — CPU wedge walks, GPU four matmuls + Hadamard folds. The load-bearing spec is a brute-force differential: an independent classifier over every triple of six random digraphs, exact equality per class. Density gates as in round 69 (sparse CPU walks own sparse graphs); resistance gates on size alone. Conventions: simple graph (parallel edges collapse / sum weights, loops drop); RWR sinks absorb (documented leak); heat and resistance demand positive weights (TypeError). Six new guards, all pinned; throw gate at zero unrun; JSDoc gates 100%; 2245 Node specs green. Parity: five new live specs, each proven able to fail by degrading its kernel (C skewed, restart diagonal skewed, a Taylor term dropped, 2I skewed to 2.01I, a fold mask swapped) — all five controls failed, all 20 specs restored green on apple metal-3. Measured on the M2 (one-off; the archive run remains the RX 580's): heatKernel 932× at n=1024 — the largest ratio any family has measured — rwrProximity 119×, simRank 45×, resistance 9×, census 12× at 2048. Bench rows sized so a cell stays in MCL's cost class (the dense CPU references are minutes at n=2048; sizes stop at 1024, heat pins time = 0.02). Claude-Session: https://claude.ai/code/session_01T6ZDogLZVCQ7QRM1aviH4h
1 parent 5101398 commit cc26b01

24 files changed

Lines changed: 4343 additions & 36 deletions

CHANGELOG.md

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,34 @@ that compile and then behave differently.
117117
(O(E) per iteration — orders of magnitude on sparse graphs) and the
118118
hierarchical merge engine went flat-typed, leaving the GPU no edge
119119
to win there.
120-
- **Three new algorithm families, designed matmul-first for the GPU
121-
tier** (round 69), all on the same async `executor` contract and
122-
with no v3 counterpart: **`eles.triangleCount()`** (per-node
123-
triangle counts, local clustering coefficients, total triangles and
124-
transitivity — A²∘A on the GPU), **`eles.neighborhoodSimilarity()`**
125-
(pairwise Jaccard / cosine / overlap coefficients over neighbor
126-
sets — A·Aᵀ on the GPU) and **`eles.katzCentrality()`** (attenuated
127-
walk counting; like PageRank its sparse CPU iteration owns `'auto'`
128-
and the GPU path serves an explicit `'gpu'`). The whole-collection
129-
`closenessCentralityNormalized` joined the async tier in the same
130-
round: its GPU path rides the blocked Floyd–Warshall kernels and
131-
folds each distance row on the device, reading back n floats
132-
instead of the n² matrix.
120+
- **Eight new algorithm families, designed matmul-first for the GPU
121+
tier** (rounds 69–70), all on the same async `executor` contract
122+
and with no v3 counterpart. Round 69: **`eles.triangleCount()`**
123+
(per-node triangle counts, local clustering coefficients, total
124+
triangles and transitivity — A²∘A on the GPU),
125+
**`eles.neighborhoodSimilarity()`** (pairwise Jaccard / cosine /
126+
overlap coefficients over neighbor sets — A·Aᵀ on the GPU) and
127+
**`eles.katzCentrality()`** (attenuated walk counting; like
128+
PageRank its sparse CPU iteration owns `'auto'` and the GPU path
129+
serves an explicit `'gpu'`). Round 70, aimed at network-biology
130+
workloads: **`eles.randomWalkWithRestart()`** (seed-set network
131+
propagation — the disease-gene-prioritization primitive) and
132+
**`eles.randomWalkWithRestartProximity()`** (the all-pairs
133+
proximity matrix, a Neumann matmul iteration on the GPU),
134+
**`eles.heatDiffusion()`** / **`eles.heatKernel()`** (HotNet-style
135+
heat propagation; exp(−t·L) by scaling-and-squaring on the GPU),
136+
**`eles.effectiveResistance()`** (resistance distance and commute
137+
time off the Laplacian pseudo-inverse — f64 elimination on the CPU,
138+
Newton–Schulz matmul iteration on the GPU; O(n³) on both sides, so
139+
the GPU wins at every density), **`eles.simRank()`** (the Jeh–Widom
140+
recursive similarity, two matmuls per iteration) and
141+
**`eles.motifCensus()`** (the sixteen-class Holland–Leinhardt triad
142+
census — '030T' is the feed-forward loop — computed from seven
143+
trace primitives and pinned by a brute-force classifier spec).
144+
The whole-collection `closenessCentralityNormalized` joined the
145+
async tier in round 69: its GPU path rides the blocked
146+
Floyd–Warshall kernels and folds each distance row on the device,
147+
reading back n floats instead of the n² matrix.
133148

134149
### Changed
135150

EXECUTIVE_SUMMARY.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ The v4 rewrite: a columnar model and a WebGPU renderer, per
3838

3939
| | |
4040
|---|---|
41-
| Automated tests | 2,223 unit · 427 module · 24 soak · 386 browser (some skip for want of a WebGPU adapter) |
42-
| Documented API | 366 members over 48 sections, gated at 100% |
43-
| Visual regression | 46 goldens compared **exactly** — zero differing pixels · 45 live v3-vs-v4 pixel-parity scenes, 7 of them close-ups at zoom 3–4 · 11 numeric routing-parity scenes · 15 CPU-vs-GPU algorithm-parity scenes |
41+
| Automated tests | 2,245 unit · 427 module · 24 soak · 396 browser (some skip for want of a WebGPU adapter) |
42+
| Documented API | 373 members over 48 sections, gated at 100% |
43+
| Visual regression | 46 goldens compared **exactly** — zero differing pixels · 45 live v3-vs-v4 pixel-parity scenes, 7 of them close-ups at zoom 3–4 · 11 numeric routing-parity scenes · 20 CPU-vs-GPU algorithm-parity scenes |
4444
| Benchmarks | 25 suites, 4 published profiles · **all 366 v3-comparative pairs read v4-faster** (geometric mean 13.7×, minimum 1.03×) · GPU algorithm executors 13× geo-mean over their CPU reference |
4545
| Style parity | v4 accepts 157 of v3's 291 style property names; the rest dropped by decision |
4646
| Bundle | 691 KiB minified / 185 KiB gzipped — ~1.5× v3 (410 / 126 KiB); the WGSL shaders, which v3 has no equivalent of, are minified at build time |
@@ -166,6 +166,20 @@ The v4 rewrite: a columnar model and a WebGPU renderer, per
166166
- Buys three algorithms v3 never had, on kernels the suite already trusts;
167167
each of the five new parity specs was proven able to fail by degrading its
168168
kernel; crossover numbers await the benchmark machine.
169+
- **12 Aug** — the propagation tier: network biology's algorithms
170+
- Five more families, chosen by scientific usefulness: random walk with
171+
restart (seed propagation — the disease-gene-prioritization primitive —
172+
plus the all-pairs proximity matrix), heat-kernel diffusion (HotNet-style
173+
exp(−tL), seed and all-pairs forms), effective resistance / commute time
174+
(Laplacian pseudo-inverse: f64 elimination on the CPU, Newton–Schulz
175+
matmuls on the GPU — O(n³) both sides, so the GPU wins at every density),
176+
SimRank, and the sixteen-class triad census ('030T' is the biology
177+
literature's feed-forward loop), whose closed forms are pinned by a
178+
brute-force classify-every-triple spec. Seed forms are CPU-only by
179+
design — O(E) walks with nothing for a kernel to win.
180+
- Buys the network-biology propagation toolbox on the existing kernel
181+
machinery; five more parity specs, each proven able to fail; measured on
182+
an M2: RWR proximity 119×, SimRank 45× at n=1024.
169183

170184
---
171185

@@ -183,9 +197,11 @@ The v4 rewrite: a columnar model and a WebGPU renderer, per
183197
`executor: 'cpu' | 'gpu' | 'auto'` — including, since 12 Aug, the
184198
whole-collection `closenessCentralityNormalized`; the single-root form
185199
stays synchronous.
186-
- **Three algorithm families v3 never had**: `triangleCount`,
187-
`neighborhoodSimilarity` and `katzCentrality`, on the same executor
188-
contract.
200+
- **Eight algorithm families v3 never had**, on the same executor
201+
contract: `triangleCount`, `neighborhoodSimilarity`, `katzCentrality`,
202+
`randomWalkWithRestart` (+ its all-pairs proximity form),
203+
`heatDiffusion`/`heatKernel`, `effectiveResistance`, `simRank` and
204+
`motifCensus`.
189205
- **`cy.collection()` throws if passed an argument**; **`cy.$()` and
190206
`cy.byId()`** restored as aliases.
191207

MIGRATING.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,21 @@ slot-native CPU walks. Only the whole-collection
424424
`closenessCentralityNormalized` moved to the async tier — it is the O(n³)
425425
all-pairs computation, exactly what the tier exists for.
426426

427-
**v4 also adds three algorithm families v3 never had**, on the same async
427+
**v4 also adds eight algorithm families v3 never had**, on the same async
428428
`executor` contract: `triangleCount()` (per-node triangles, local
429429
clustering coefficients, transitivity), `neighborhoodSimilarity()`
430-
(pairwise Jaccard / cosine / overlap coefficients over neighbor sets) and
431-
`katzCentrality()` (attenuated walk counting). Nothing to migrate — they
432-
are new surface — but note they read the collection as a simple graph:
433-
parallel edges collapse, loops are excluded, and `triangleCount` ignores
434-
direction outright.
430+
(pairwise Jaccard / cosine / overlap coefficients over neighbor sets),
431+
`katzCentrality()` (attenuated walk counting), `randomWalkWithRestart()`
432+
and `randomWalkWithRestartProximity()` (network propagation from a seed
433+
set, and the all-pairs proximity matrix), `heatDiffusion()` and
434+
`heatKernel()` (heat-kernel propagation, exp(−t·L)),
435+
`effectiveResistance()` (the graph as a resistor network, with
436+
`commuteTime`), `simRank()` (recursive neighborhood similarity) and
437+
`motifCensus()` (the sixteen-class triad census; '030T' is the
438+
feed-forward loop). Nothing to migrate — they are new surface — but
439+
note they read the collection as a simple graph: parallel edges collapse
440+
(summing weights where weights are read), loops are excluded, and the
441+
triangle/heat/resistance families ignore direction outright.
435442

436443
**State is a condition, not a selector.** See "Styling element state" above:
437444
`:selected`, `:active`, `:locked` and the rest are `when` conditions on a

PLAN.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19854,3 +19854,158 @@ closeness should also gain a Brandes-style batched-BFS unweighted path
1985419854
(the FW route was chosen because the CPU reference is FW-shaped, so
1985519855
parity is structural — a BFS path would be faster still on sparse
1985619856
graphs but needs its own reference).
19857+
19858+
## Round 70 — the propagation tier: network biology's algorithms (maintainer goal, 2026-08-12)
19859+
19860+
Round 69 asked "which algorithms could take MCL's lead"; the follow-up
19861+
question was which of the candidates matter for *scientific* use, and
19862+
the answer reordered the queue: network biology has converged on
19863+
propagation methods, so the round builds the five families the
19864+
maintainer picked from that assessment — random walk with restart,
19865+
heat-kernel diffusion, effective resistance / commute time, SimRank,
19866+
and the triad census. Seven public methods, each with a CPU reference
19867+
(the spec), executor routing, hand-computed Node specs, and — for the
19868+
five dense forms — GPU kernels, live parity specs with verified
19869+
controls, and benchmark rows.
19870+
19871+
### 70.1 — the seed/dense split, decided once for the tier
19872+
19873+
RWR and heat diffusion each have two natural forms. The *seed* form —
19874+
propagate from a seed collection, answer a score per node — is the
19875+
everyday bio call, and it is an O(E)-per-step sparse walk: the pageRank
19876+
verdict applies, no kernel can win, so `randomWalkWithRestart` and
19877+
`heatDiffusion` are CPU-only and an explicit `executor: 'gpu'` rejects
19878+
with a message pointing at the dense sibling (the weighted-betweenness
19879+
no-path precedent). The *all-pairs* form — the full proximity/kernel
19880+
matrix — is iterated dense products, the MCL shape, and that is where
19881+
the GPU tier lives: `randomWalkWithRestartProximity` (Neumann
19882+
iteration S′ = (1−c)W·S + cI, one matmul per step),
19883+
`heatKernel` (exp(−tL) by scaling-and-squaring: the scaled Taylor
19884+
series as a matmul chain, then s squarings), `simRank`
19885+
(S′ = C·Q·S·Qᵀ, two matmuls per step) and the census's trace products.
19886+
The CPU references for the all-pairs forms are deliberately *sparse*
19887+
(one seed-vector solve per column; per-column Taylor applications;
19888+
per-row/column neighbor averages), so the density gates are honest:
19889+
the m ≥ n²/16–n²/32 gates of round 69, same reasoning, and 'auto'
19890+
stays on the CPU for sparse graphs however large.
19891+
19892+
`effectiveResistance` is the exception and the headline: the Laplacian
19893+
pseudo-inverse has no sparse shortcut, so the CPU reference is dense
19894+
f64 Gauss–Jordan at O(n³) and the GPU runs Newton–Schulz —
19895+
X ← X(2I − BX), nothing but matmuls, quadratically convergent for the
19896+
positive-definite B = L + J-blocks this family builds (the per-
19897+
component 1/n_c shift makes B invertible while cancelling out of every
19898+
resistance difference). Like MCL it wins at every density. f32
19899+
bounds the achievable accuracy on ill-conditioned systems, documented;
19900+
the parity bound is relative 5e-3 against the f64 elimination.
19901+
19902+
### 70.2 — semantics worth recording
19903+
19904+
- RWR: W column-normalized by out-weight; the undirected default walks
19905+
both ways; a directed sink *absorbs* (its column leaks, scores can
19906+
sum under 1) rather than redistributing — documented, simpler on
19907+
both executors, irrelevant on undirected bio graphs. `seeds` is
19908+
required for the seed form and uniform over its nodes; the fixed
19909+
point is c(I − (1−c)W)⁻¹p₀, pinned in specs by the two-node closed
19910+
form c/(1−(1−c)²).
19911+
- Heat: the combinatorial weighted Laplacian, undirected, positive
19912+
weights enforced (a negative conductance is not a heat problem —
19913+
TypeError). Both executors share the same approximation constants
19914+
(‖tL/2^s‖∞ ≤ ½, ten Taylor terms); the CPU applies the scaled
19915+
operator 2^s times per column, the GPU squares s times — the same
19916+
power. Specs pin the pair and triangle matrix exponentials in
19917+
closed form and heat conservation through the scaling path at t=10.
19918+
- SimRank: Jeh–Widom with in-neighborhoods under `directed: true`,
19919+
all neighbors otherwise (the library's undirected default; bio
19920+
graphs are undirected). Diagonal pinned to 1 per iteration; empty
19921+
neighborhoods answer 0. The 4-cycle fixed point x = C(1+x)/2 →
19922+
x = 2/3 at C = 0.8 pins the maths in specs.
19923+
- Census: sixteen closed forms over seven trace primitives
19924+
(S₁ = ΣC²∘C … S₇ = ΣCCᵀ∘M over the asymmetric and mutual masks),
19925+
the dyad totals and six degree-pair sums, shared verbatim by both
19926+
executors (`censusFromPrimitives`) — the executors can only
19927+
disagree if a matmul disagrees with a wedge walk. **The formulas
19928+
themselves are the risk**, so the load-bearing spec is a
19929+
brute-force differential: an independent classifier written from
19930+
the class definitions, run over every triple of six random digraphs
19931+
sweeping sparse to dense, exact equality demanded per class (plus
19932+
Σ = C(n,3)). It passed on the first complete run of the closed
19933+
forms, and it is the spec that would catch a sign or orientation
19934+
error nothing else can see. `directed: false` files every edge as
19935+
mutual, so the undirected census (empty / one-edge / path /
19936+
triangle) is the same code path reading 003/102/201/300.
19937+
19938+
### 70.3 — verification
19939+
19940+
Node tier: `test/algorithms-propagation.mjs` (24 specs) and
19941+
`test/algorithms-motifs.mjs` (15 assertions per seed across six
19942+
seeds), all closed-form or brute-force; the executor sweep extended by
19943+
seven entries; throw gate at zero unrun (six new guards: seeds,
19944+
restartProbability, time, two positive-weight conductance guards,
19945+
dampingFactor); JSDoc gates 100%; types and full `test:js` green.
19946+
19947+
Parity tier: five new live specs — simRank (1e-4 plus an exact-1
19948+
diagonal, both directions), rwrProximity (1e-4 plus column
19949+
conservation ≥ 0.999), heatKernel (1e-4, symmetry, row conservation,
19950+
at t = 2 so several squarings run), effectiveResistance (relative
19951+
5e-3, the unit-resistor identity, and exact Infinity agreement across
19952+
components on a fixture that has both), motifCensus (all sixteen
19953+
counts exactly equal on a 64-node random digraph, with a
19954+
populated-classes discrimination check). **Every spec was run once
19955+
with its kernel deliberately degraded and failed**: simRank with C
19956+
skewed 1%, rwrProximity with the restart diagonal skewed, heatKernel
19957+
with the k=2 Taylor term dropped, resistance with the Newton–Schulz
19958+
2I skewed to 2.01I, the census with S₆ folded against the wrong mask.
19959+
All five controls failed; all 20 specs green restored.
19960+
19961+
### 70.4 — benchmark rows, and a sizing lesson
19962+
19963+
Five families joined `algorithms-gpu-bench.mjs`: resistance on the
19964+
plain fixture (both sides O(n³) — the MCL-class row), the four
19965+
iterated-product families on the dense fixture. The first draft
19966+
priced the dense families at n = 2048 and had to be walked back: a
19967+
*bench cell* pays REPS×(cpu+gpu) calls, and the dense CPU references
19968+
are MCL-cost already at n = 1024 (rwrProximity is one sparse solve per
19969+
column; heatKernel's scaling exponent grows with t·degree, so its
19970+
bench row pins time = 0.02). Sizes stop at 1024 for those three
19971+
(census stays to 2048 — its CPU walk is O(Σ deg²), far cheaper), and
19972+
the iteration knobs are pinned in the rows per the round-33.2 rule.
19973+
The suite edit moves the harness fingerprint again; the round-69 note
19974+
about `EQUIVALENT_HARNESSES` applies to the new hash the same way,
19975+
and only one entry is needed once a run under the final hash is
19976+
published.
19977+
19978+
**Open**: the crossover sweep on the benchmark machine (density-gate
19979+
constants re-tuned from it, and the resistance family's parity bound
19980+
revisited on the RX 580's f32); a `normalized` Laplacian option for
19981+
the heat family; motif significance tooling (the census exists so it
19982+
can be run per randomized network — the ensemble driver itself is
19983+
app-level and stays out of scope).
19984+
19985+
### 70.5 — measured on the M2 (Metal, one-off; the archive run stays the RX 580's)
19986+
19987+
| family | n=256 | n=512 | n=1024 |
19988+
|---|---:|---:|---:|
19989+
| effectiveResistance | 3.3× | 7.8× | 9.0× |
19990+
| simRank (10 iters, dense) | 14× | 33× | 45× |
19991+
| rwrProximity (dense) | 21× | 68× | **119×** |
19992+
| heatKernel (dense) | 82× | 291× | **932×** |
19993+
| motifCensus (dense, to n=2048) | — | 3.9× | 8.7× / 12.3× @2048 |
19994+
19995+
heatKernel's 932× is the largest ratio any family has measured — its
19996+
CPU reference pays 2^s operator applications per column while the GPU
19997+
pays s squarings total, so the scaling exponent multiplies the CPU
19998+
side only. Two findings from the measurement worth their notes:
19999+
20000+
- **A converge tolerance below f32's noise floor buys nothing and
20001+
costs everything.** Newton–Schulz at an absolute 1e-5 ran 96 of 96
20002+
encoded iterations at n=1024 (642 ms): the inverse's entries grow as
20003+
1/λ₂, so on any weakly-connected graph the iterate's float noise
20004+
exceeds an absolute bound forever and the no-diff converge never
20005+
fires. The compare is *relative* now (`NS_COMPARE`,
20006+
|Δ| > tol·max(1, |x|)) — 642 → 200 ms at n=1024, 9× over the f64
20007+
elimination, and the parity spec still passes at 5e-3 relative.
20008+
- **A bench cell's budget is REPS × the slow side.** The first row
20009+
draft priced the dense families at n = 2048 and a single
20010+
rwrProximity CPU call there runs minutes; sizes stopped at 1024 and
20011+
the heat row pinned time = 0.02 (its CPU cost scales with 2^s).

benchmark/algorithms-gpu-bench.mjs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,59 @@ const FAMILIES = [
276276
cy.elements().katzCentrality({ executor })
277277
.then((r) => r.katz(cy.nodes()[0]))`,
278278
},
279+
// round 70: effective resistance is O(n³) on BOTH executors (a dense
280+
// inverse has no sparse shortcut), so like MCL it is priced on the
281+
// plain fixture and wins at every density
282+
{
283+
key: 'effectiveResistance',
284+
sizes: [256, 512, 1024],
285+
kind: 'graph',
286+
op: `(cy, executor) =>
287+
cy.elements().effectiveResistance({ executor })
288+
.then((r) => r.resistance(cy.nodes()[0], cy.nodes()[1]))`,
289+
},
290+
// round 70: the iterated-product families, priced dense (their 'auto'
291+
// gates route to the GPU only there — sparse CPU walks own the rest).
292+
// Iteration knobs are pinned (the round-33.2 rule), and sizes stop at
293+
// 1024 because the dense CPU references are MCL-cost there already —
294+
// simRank pays 2·n·m per iteration and rwrProximity one sparse solve
295+
// per column; heatKernel's time is small so its scaling exponent (and
296+
// with it the CPU's 2^s operator applications) stays bounded
297+
{
298+
key: 'simRank',
299+
sizes: [256, 512, 1024],
300+
kind: 'graph-dense',
301+
op: `(cy, executor) =>
302+
cy.elements().simRank({ executor, maxIterations: 10 })
303+
.then((r) => r.similarity(cy.nodes()[0], cy.nodes()[1]))`,
304+
},
305+
{
306+
key: 'rwrProximity',
307+
sizes: [256, 512, 1024],
308+
kind: 'graph-dense',
309+
op: `(cy, executor) =>
310+
cy.elements().randomWalkWithRestartProximity({
311+
executor,
312+
restartProbability: 0.3,
313+
tolerance: 0.00001,
314+
}).then((r) => r.proximity(cy.nodes()[0], cy.nodes()[1]))`,
315+
},
316+
{
317+
key: 'heatKernel',
318+
sizes: [256, 512, 1024],
319+
kind: 'graph-dense',
320+
op: `(cy, executor) =>
321+
cy.elements().heatKernel({ executor, time: 0.02 })
322+
.then((r) => r.heat(cy.nodes()[0], cy.nodes()[1]))`,
323+
},
324+
{
325+
key: 'motifCensus',
326+
sizes: [512, 1024, 2048],
327+
kind: 'graph-dense',
328+
op: `(cy, executor) =>
329+
cy.elements().motifCensus({ executor })
330+
.then((r) => r.counts['030T'])`,
331+
},
279332
];
280333

281334
const jobs = [];

0 commit comments

Comments
 (0)