Precompiled Libtorch for Apple Silicon

josevalim: <p>Hi everyone, congratulations on the Apple Silicon and MPS support on Torch v1.12!</p>
<p>Are there any plans to also provide precompiled LibTorch for Apple Silicon <a href="https://pytorch.org/get-started/locally/" rel="noopener nofollow ugc">on the Installation page</a>? We are using the C++ version of the libraries and for now the only way to automate installation is by downloading the wheel file and extracting the precompiled artifacts.</p>
<p>However, given the precompiled artifacts are already built for wheels, maybe they could also be made available on the website?</p>
<p>Thank you!</p>

dfalbel: <p>Oi José <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>It would be nice to have pre-built binaries on the official installation page!</p>
<p>FWIW I have set up a small repository with M1 builds here: <a href="https://github.com/mlverse/libtorch-mac-m1" class="inline-onebox" rel="noopener nofollow ugc">GitHub - mlverse/libtorch-mac-m1: LibTorch builds for the M1 Macs</a> .<br>
I will use builds in this repository for the R bindings while we don’t have official builds available.</p>

josevalim: <p>Cool, obrigado!</p>
<p>Any plans to build 1.12.1 as well? <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>

dfalbel: <p>Done! You will find it here: <a href="https://github.com/mlverse/libtorch-mac-m1/releases" class="inline-onebox" rel="noopener nofollow ugc">Releases · mlverse/libtorch-mac-m1 · GitHub</a></p>

josevalim: <p>Thanks! The wheel version also included libomp (or so it seems), but I have to install it manually with the precompiled version. Do you think this is something worth including too?</p>

dfalbel: <p>Yes, it seems they manually do this in setup.py:</p>
<aside class="onebox githubblob" data-onebox-src="https://github.com/pytorch/pytorch/blob/a75edfa97c9d985a337fbea7b9c0f4061153aaf0/setup.py#L455-L487">
  <header class="source">

      <a href="https://github.com/pytorch/pytorch/blob/a75edfa97c9d985a337fbea7b9c0f4061153aaf0/setup.py#L455-L487" target="_blank" rel="noopener nofollow ugc">github.com</a>
  </header>

  <article class="onebox-body">
    <h4><a href="https://github.com/pytorch/pytorch/blob/a75edfa97c9d985a337fbea7b9c0f4061153aaf0/setup.py#L455-L487" target="_blank" rel="noopener nofollow ugc">pytorch/pytorch/blob/a75edfa97c9d985a337fbea7b9c0f4061153aaf0/setup.py#L455-L487</a></h4>



    <pre class="onebox"><code class="lang-py">
      <ol class="start lines" start="455" style="counter-reset: li-counter 454 ;">
          <li># Copy libiomp5.dylib inside the wheel package on OS X</li>
          <li>def _embed_libiomp(self):</li>
          <li>
          </li>
<li>    lib_dir = os.path.join(self.build_lib, 'torch', 'lib')</li>
          <li>    libtorch_cpu_path = os.path.join(lib_dir, 'libtorch_cpu.dylib')</li>
          <li>    if not os.path.exists(libtorch_cpu_path):</li>
          <li>        return</li>
          <li>    # Parse libtorch_cpu load commands</li>
          <li>    otool_cmds = subprocess.check_output(['otool', '-l', libtorch_cpu_path]).decode('utf-8').split('\n')</li>
          <li>    rpaths, libs = [], []</li>
          <li>    for idx, line in enumerate(otool_cmds):</li>
          <li>        if line.strip() == 'cmd LC_LOAD_DYLIB':</li>
          <li>            lib_name = otool_cmds[idx + 2].strip()</li>
          <li>            assert lib_name.startswith('name ')</li>
          <li>            libs.append(lib_name.split(' ', 1)[1].rsplit('(', 1)[0][:-1])</li>
          <li>
          </li>
<li>        if line.strip() == 'cmd LC_RPATH':</li>
          <li>            rpath = otool_cmds[idx + 2].strip()</li>
          <li>            assert rpath.startswith('path ')</li>
          <li>            rpaths.append(rpath.split(' ', 1)[1].rsplit('(', 1)[0][:-1])</li>
      </ol>
    </code></pre>


  This file has been truncated. <a href="https://github.com/pytorch/pytorch/blob/a75edfa97c9d985a337fbea7b9c0f4061153aaf0/setup.py#L455-L487" target="_blank" rel="noopener nofollow ugc">show original</a>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>We can probably do the same in our builds.</p>

dfalbel: <p>Actually it seems it only embeds openMP in the x86_64 builds, because in this case it’s embedding libiomp5.dylib (the Intel OpenMP version).</p>
<p>I think we could still copy libomp.dylib to the lib directory though, but not sure what kind of problems that could cause.</p>

josevalim: <p>Interesting. I can find “libiomp5.dylib” in the Apple arm64 wheel too, so if this is straightforward to add, it would be very helpful. <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>

dfalbel: <p>Makes sense! I just added a copy of libomp.dylib to the archive.</p>

josevalim: <p>Excellent, it works. Thank you!</p>