Papers
Topics
Authors
Recent
Search
2000 character limit reached

FlexiWalker: GPU Framework for Dynamic Walks

Updated 5 July 2026
  • FlexiWalker is an extensible GPU framework for dynamic random walks that adapts per-step transition probabilities using runtime state.
  • It employs two optimized GPU kernels—eRVS and eRJS—with a lightweight runtime cost model to dynamically select the best sampling strategy per node.
  • Its compile-time specialization pipeline transforms user-defined walk logic into efficient sampling building blocks, delivering significant speedups over traditional methods.

FlexiWalker is an extensible GPU framework for efficient dynamic random walks with runtime adaptation. It targets graph workloads in which per-step transition probabilities depend on the runtime state of the walk and environment, rather than remaining fixed per node as in static random walks. In that setting, precomputed alias tables and cumulative distributions cease to be reusable, and existing CPU and GPU optimizations become ineffective or brittle. FlexiWalker addresses this by combining optimized GPU sampling kernels, a lightweight runtime cost model that selects the better kernel per node at runtime, and a compile-time specialization pipeline that transforms user-supplied walk logic into optimized building blocks (Park et al., 30 Nov 2025).

1. Dynamic random walks and the problem setting

Random walks on graphs select successive neighbors according to a probability distribution and are used broadly for embedding, ranking, and exploration tasks. Static random walks assume transition probabilities are fixed per node, often equal to normalized edge weights. Dynamic random walks generalize this by making the per-step transition distribution depend on the runtime state of the walk and environment. Formally, at step tt for current node uu and a neighbor vN(u)v \in N(u), a dynamic random walk specifies

P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},

where sts_t is the walk state and

w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).

Here, sts_t may encode the previous node, hop count, past path, label schema, or user parameters (Park et al., 30 Nov 2025).

The framework’s motivating examples include Node2Vec, MetaPath, and Second-Order PageRank. In Node2Vec, wlogicw_{\text{logic}} depends on dist(v,v)\mathrm{dist}(v',v) with parameters a,ba,b, giving

uu0

MetaPath uses a label-schema mask, and Second-Order PageRank depends on uu1 and degrees uu2 with hyperparameter uu3.

The central systems problem is that widely used GPU and CPU methods for static walks amortize sampling by precomputing per-node alias tables or cumulative distributions. In dynamic walks, uu4 changes at runtime with uu5, even across successive steps at the same node, so precomputed structures cannot be reused or would need to be rebuilt per step. On real graphs with high degrees and long walks, rebuilding alias tables or prefix sums per step is prohibitively expensive and memory-inefficient on GPUs. This is the gap FlexiWalker is designed to fill.

2. Framework architecture and GPU design principles

FlexiWalker is organized around three components that decouple user-supplied walk logic from sampling:

Component Role Core mechanism
Flexi-Kernels Sampling execution eRJS and eRVS GPU kernels
Flexi-Runtime Per-node kernel selection Lightweight first-order cost model
Flexi-Compiler User-logic specialization Compile-time analysis and helper generation

Its GPU design is explicitly shaped by massive parallelism, memory hierarchy, warp execution, and synchronization costs (Park et al., 30 Nov 2025). Many walkers proceed concurrently, so the framework seeks high occupancy while minimizing synchronization. Because global memory bandwidth dominates, FlexiWalker emphasizes coalesced loads, avoidance of full scans or redundant accesses, and minimization of atomics. Shared memory and registers are used for warp-local reductions and temporary keys. Warp-level execution favors coherent control flow, so the framework groups reservoir sampling into warp-wide cooperation and allows independent rejection sampling per thread, switching modes with __ballot_sync and __shfl_sync to minimize divergence. Global reductions are treated as particularly expensive and are avoided in the inner loop.

A design-space study motivates the framework’s sampling choices. Alias tables and inverse transform sampling require rebuilding auxiliary structures whenever uu6 changes; under dynamic workloads, this rebuilding cost dominates and can lead to large slowdowns or out-of-time behavior on big weighted graphs. Multinomial sampling with global reductions and repeated normalization scales poorly when distributions vary per step. Rejection sampling and reservoir sampling, by contrast, require no persistent auxiliary structures and adapt naturally to runtime-dependent weights because they only need current-step access to neighbors. The study reports that rejection sampling dominates on some unweighted workloads, reservoir sampling dominates on weighted ones, and the optimal choice varies across nodes and over time.

3. Sampling kernels: eRVS and eRJS

FlexiWalker’s reservoir kernel, eRVS, replaces prefix-sum-based weighted reservoir sampling with a key-based method due to Efraimidis–Spirakis. Each neighbor uu7 receives a key

uu8

and the selected neighbor is uu9 (Park et al., 30 Nov 2025). This converts sampling into an argmax over i.i.d. keys, eliminates prefix sums, and halves memory traffic because only the current weights are read once. In warp-parallel form, threads cooperatively load weights in coalesced fashion, reduce keys with warp-local max operations in registers or shared memory, and avoid any global prefix sum or global reduction.

A further optimization is a jump technique that reduces random-number generation. Rather than generating a random key at every neighbor, the kernel samples the index of the next update directly. If vN(u)v \in N(u)0 is the current global key maximum, then a threshold

vN(u)v \in N(u)1

is used, and scanning proceeds until the accumulated weight exceeds vN(u)v \in N(u)2. Only when the jump condition is met does the kernel generate a new key and update vN(u)v \in N(u)3. This reduces random-number generation and redundant memory traffic during warp-parallel scanning.

The rejection kernel, eRJS, is designed around the observation that classic GPU rejection sampling often incurs heavy reduction cost to find the maximum weight at each step. FlexiWalker avoids this by using a runtime-computable upper bound vN(u)v \in N(u)4 that is guaranteed to be at least the true maximum ratio needed for rejection sampling, thereby removing neighborwise max reduction while preserving correctness. With proposal distribution vN(u)v \in N(u)5 and target distribution proportional to weights, acceptance proceeds by drawing a candidate neighbor and a uniform random variable and accepting if

vN(u)v \in N(u)6

For uniform proposal, the one-trial acceptance probability is vN(u)v \in N(u)7, and the expected number of trials is vN(u)v \in N(u)8.

The kernel-level optimizations are distinct but complementary. eRVS is prefix-free and uses warp-local max reductions; eRJS avoids full scans and accesses one weight per trial. eRVS reduces memory traffic through the key-based formulation, while eRJS reduces work when weights are flat and bounds are tight. FlexiWalker also eliminates atomics from inner loops; only a global counter is used for fetching the next query.

4. Runtime adaptation and compile-time specialization

Because degree and weight skew vary per node and per step, FlexiWalker does not commit statically to either sampling strategy. Its runtime layer uses a first-order cost model that compares estimated per-node memory cost of reservoir and rejection sampling (Park et al., 30 Nov 2025). Let vN(u)v \in N(u)9 be the node degree, and let P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},0 and P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},1 be per-step estimates of the maximum and sum of weights over P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},2. With profiled edge costs P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},3 and P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},4, the model is

P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},5

with P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},6, and

P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},7

with P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},8. The decision rule selects the kernel with smaller estimated time, equivalently:

P(uvst)=w(u,v,st)xN(u)w(u,x,st),P(u \to v \mid s_t) = \frac{w(u,v,s_t)}{\sum_{x \in N(u)} w(u,x,s_t)},9

The estimators used by this model are intentionally lightweight. sts_t0 is approximated on the fly using a linearity assumption:

sts_t1

where sts_t2 is preprocessed or updated via lightweight profiling if necessary. sts_t3 is produced by compiler-generated helper code derived from user logic without scanning neighbors.

The compile-time layer, Flexi-Compiler, analyzes user code and auto-generates max and sum estimators plus preprocessing helpers. Users implement three CUDA C++ functions in gather–move–update style: init(...), get_weight(graph, state, edge_index), and update(state, next_node). The compiler uses Clang AST and LLVM IR for dependency tracking, flag allocation, and code generation. It detects which expressions influence the return value of get_weight, determines whether estimation granularity should be PER_STEP or PER_KERNEL, generates preprocess() to build reusable templates such as h_MAX[u] and h_SUM[u], and synthesizes get_weight_max() and get_weight_sum() helpers. If it detects convoluted control flow such as deep recursion or data-dependent loops, it falls back to eRVS-only to preserve correctness.

5. Correctness, complexity, and empirical evaluation

The two sampling kernels are presented as unbiased. For eRJS, replacing the true maximum with any upper bound sts_t4 does not change the accepted distribution; it changes only the acceptance rate sts_t5 and therefore the expected number of trials sts_t6. For eRVS, the key method yields

sts_t7

which is the standard Efraimidis–Spirakis result. The complexity trade-off is correspondingly sharp: eRVS performs sts_t8 neighbor visits with low variance and stable runtime across skew, while eRJS has expected trials

sts_t9

making it attractive when w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).0 is close to the average and bounds are tight (Park et al., 30 Nov 2025).

The reported evaluation uses an AMD EPYC 9124P CPU (16C/32T) and up to four NVIDIA A6000 GPUs (48GB), under Ubuntu 22.04 with CUDA 12.1.1 and cuRAND 10.3.2.106. Datasets include YT, CP, LJ, OK, FS from SNAP and EU, AB, UK, TW, SK from LAW, up to 66M nodes and 3.6B edges. Workloads are (un)weighted Node2Vec, (un)weighted MetaPath, and 2nd-Order PageRank, with 80 steps except MetaPath at depth 5; Node2Vec uses w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).1, w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).2; 2nd-Order PageRank uses w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).3; MetaPath uses schema w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).4. Baselines include CPU systems ThunderRW, SOWalker, and KnightKing, and GPU systems C-SAW, Skywalker, NextDoor, and FlowWalker.

Across these workloads and graphs, FlexiWalker achieves a 73.44× geometric mean speedup over the best CPU baselines and 5.91× over the best GPU baselines. Maximum speedups are reported as 4246.71× over CPU and 1040.54× over GPU baselines. Weighted dynamic workloads particularly expose the weakness of static-table methods and max-reduction-based rejection sampling, which often become out-of-time on large graphs, whereas FlexiWalker remains fast. Kernel ablations report 1.44–1.82× speedups for eRVS over FlowWalker using the prefix-free EXP method plus JUMP, and 54.49–1698.35× for eRJS over NextDoor on uniform weights, with up to 7.27× under skew w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).5 due to eliminated max reductions. Runtime selection outperforms degree-based and random selection by geometric means of 2.66× and 15.86×, and improves speed over fixed strategies by up to 3.37× versus eRVS-only and 421.56× versus eRJS-only. Profiling and preprocessing account for 0.46–3.98% of main runtime and are reusable across runs. Multi-GPU execution reaches up to 3.23× speedup with four GPUs via query parallelism. Energy use is reported as up to 10.15× fewer Joules/query than KnightKing and 1.18× lower peak power than FlowWalker.

6. Practical use, limitations, and terminological scope

FlexiWalker is open sourced at https://github.com/AIS-SNU/FlexiWalker. It is built as standard CUDA C++ software on Linux with CUDA 12+ and cuRAND. Input graphs are CSR-like adjacencies with optional per-edge weights w(u,v,st)=wlogic(u,v,st)h(u,v).w(u,v,s_t) = w_{\text{logic}}(u,v,s_t)\cdot h(u,v).6 and labels for MetaPath. Users provide init, get_weight, and update, then rely on the integrated compiler to generate preprocessing and estimator helpers. Runtime configuration includes batch size, initial nodes, walk length, number of queries, RNG seed, optional profiling mode for estimating edge costs, and a cost-model toggle that can force eRVS-only or eRJS-only for diagnostics (Park et al., 30 Nov 2025).

The framework is intended to produce walk sequences for downstream pipelines such as GraphSAGE, Node2Vec-like embedding, second-order proximity computation, and metapath sampling for heterogeneous graphs. A plausible implication is that its separation between user logic and sampling makes it useful when transition rules are application-specific but must still run at GPU throughput.

Its limits are stated explicitly. eRVS is consistently robust under heavy skew or extreme high-degree nodes because it performs one linear pass per step. eRJS is strongest when weights are flat or the maximum is close to the mean and upper bounds are tight. The runtime model can mispredict on instances with rapidly changing weight sums or bounds, though it avoids catastrophic slowdowns relative to single-kernel baselines. User logic must be per-edge pure and deterministic, with no inter-thread communication inside get_weight or update. Memory bandwidth remains the main bottleneck, and register pressure can limit occupancy when user logic is heavy. Planned extensions include multi-GPU partitioning for very large graphs, support for dynamically changing graphs, additional sampling strategies and adaptive profiling, and low-precision edge weights; the framework already reports gains with INT8 weights.

The name should not be conflated with unrelated robotics nomenclature. In the graph-computing literature, FlexiWalker denotes the GPU framework for dynamic random walks (Park et al., 30 Nov 2025). By contrast, the vibration-driven quadruped officially introduced in 2025 is named “Flix-Walker,” although the authors note that “FlexiWalker” may appear in informal discussions of that robot (Jiang et al., 3 Jul 2025).

Topic to Video (Beta)

No one has generated a video about this topic yet.

Whiteboard

No one has generated a whiteboard explanation for this topic yet.

Follow Topic

Get notified by email when new papers are published related to FlexiWalker.