So the first issue with the RG16 vs R16 format for the PNG is because the included PNG file has an alpha channel (though nothing is in it). The MTK Texture Loader will produce a R16 format without an alpha channel, and an RG16 format with an alpha channel. I've tried out using a simple compute kernel to generate an R16 only texture instead of using a blit encoder to copy the texture, which requires that the two formats match. I think the fixes the problem where the texture is RG16 or R16--so that's one change needed for the sample.
However, the main problem of using R16Unorm in the shader is that it might not be supported across every device which supports Tier 2 (which devices exactly, I honestly don't have a clue). But this can also be fixed by using one of the supported texture formats. One alternative is to use a ping-pong design pattern. and another is to manually convert to/from float in your shader kernel. I tried using F32Float which maintains the precision of the incoming 16-bit values and works with Tier1 as well. So this would be the necessary second change for the sample to align with our documentation.
Lastly, since I couldn't definitely find a statement in the Metal Shading Language specification that guarantees that you could alias the memory by using a read-only texture and a write-only texture, and both bound to the same MTLTexture, I'm hesitant to say that we recommend this without reservation. This simple example of a read followed by a write in a very defined pattern in a very simple shader is (IMHO) not likely to be problematic, but it's impossible for me to assure you of that.