Answering my own question, and for future reference, it seems there is a sense in which the CPU result is more accurate. While it is correct that both are implementing the standard, the CPU result may be closer to the actual value of the expression. This document explains the difference very well and is worth a read in my opinion: Precision & Performance: Floating Point and IEEE 754 Compliance for NVIDIA GPUs 61
Here is an example:
FloatTensor = torch.cuda.FloatTensor
DoubleTensor = torch.cuda.DoubleTensor

A = (255 * np.random.random([1000, 1000])).astype(np.uint8)

R_cpu_32 = FloatTensor(A.astype(np.float32) / 255)
R_gpu_32 = FloatTensor(A) / 255

R_cpu_64 = DoubleTensor(A.astype(np.float64) / 255)
R_gpu_64 = DoubleTensor(A) / 255

print(torch.abs(R_cpu_64 - R_cpu_32.double()).mean(),
      torch.abs(R_cpu_64 - R_gpu_32.double()).mean())
print(torch.abs(R_gpu_64 - R_cpu_32.double()).mean(),
      torch.abs(R_gpu_64 - R_gpu_32.double()).mean())

For me, the above fragment prints
9.961657723698238e-09 2.970265274337254e-08
9.96165772978204e-09 2.970265274945634e-08

where even though neither result violates the standard, the CPU result is more accurate.