P(z) is a multivariate Gaussian ~N(z|0, I).
The trick is the z vectors in the batch are independent, normally-distributed values. [1]
Therefore samples of z can be drawn from a simple distribution, i.e., N(0, I) using torch.randn_like.
Given the mean and co-variance we first sample e ∼N(0, I), then
compute z = mean(X) + 0.5 sigma(X) ∗ e.
std = torch.exp(0.5 * variance_ln)
e = torch.randn_like(variance_ln).to(device)   # latent prior p(z): ~N(0,I)
z = mu + e * std  # “reparameterization trick”
[1] https://arxiv.org/pdf/1606.05908.pdf 17