It's worth noting that these pre-built blocks are both convenient and incredibly flexible. Before I started getting my hands dirty, it was hard to really see this. For example, here's a masked gather operation along the innermost dimension of an arbitrary rank tensor A:
A[..., idx[mask]]
I'd hate to have to express that in serial code and then pray a compiler could lift the correct vectorized version out of it.