In EvoX 's modern computing foundation, the smallest unit of execution for evolutionary operators is no longer the "individual," but the entirepopulation tensor: operators such as mutation, crossover, and selection cover all individuals in a single call. On top of this,computational graph compilationorganizes the sequence of operators into an optimizable execution plan, improving execution efficiency while preserving the algorithm's semantics.
Operator Parallelism: Tensor-Based Batch Evolution
- Tensor-level operators: Mutation, crossover, and selection can operate directly on a population tensor of shape [N, D] (where N is the population size and D is the dimension of decision variables), with a single operator call covering all N individuals.
- Eliminate per-individual loops: No more writing
for ind in population: ind = mutate(ind)—the kind of serial Python/CPU loop that adds frequent function scheduling and framework call overhead. - Trade batch dimension for throughput: Once the individual dimension serves as the batch dimension, operators execute in a massively parallel manner on the device, and the throughput of batch evolution scales with population size.
Computational Graph Compilation: From Operator Sequences to Execution Plans
By organizing the operator dependencies of "mutation → crossover → selection" into acomputational graph, the compiler can perform global optimization across the entire graph rather than calling off-the-shelf implementations operator by operator:
- Operator fusion: Merges multiple element-wise operations into a single kernel, reducing the creation and repeated reads/writes of intermediate tensors.
- Kernel generation and scheduling: Generates efficient kernels for the fused subgraph, completing an entire generation of evolution with fewer kernel launches.
- Memory reuse: Pre-plans buffers for intermediate results, reducing the extra overhead of GPU memory allocation and data movement.
Efficiency Changes, Semantics Don't
It's important to distinguish"how to compute"from"what to compute". Operator parallelism and compilation optimization only change the execution method—the number of kernels, the size of intermediate tensors, and memory and scheduling strategies—without altering the logical meaning of mutation, crossover, and selection themselves. The algorithm layer still composes operators according to evolutionary semantics, so under the same random seed, the evolutionary trajectory and results before and after optimization should be identical. In a nutshell: tensorization addresses "how fast batches compute," computational graph compilation addresses "how well kernels are scheduled," while "what is computed" remains unchanged.
