LibTorch on WatchOS?

mapes911: <p>Hi all,</p>
<p>Does anyone have a guide/tutorial on how to get LibTorch (C++) installed/setup for a WatchOS project?<br>
I was hoping it would be as easy as installing a Pod like the iOS version… but I get</p>
<p><code>The platform of the target </code>XXX WatchKit Extension<code>(watchOS 6.1) is not compatible with</code>LibTorch (1.4.0)<code>, which does not support </code>watchOS<code>.</code></p>
<p>I’ve also tried pulling the source and building using:</p>
<p><code>IOS_PLATFORM=WATCHOS scripts/build_ios.sh</code></p>
<p>But I keep running into various build issues… and even then I’m not totally sure how to get that built version into my XCode project if I did manage to get it built.</p>
<p>Has anyone out there successfully set up a WatchOS project with LibTorch?</p>
<p>Thanks in advance!!</p>

xta0: <p>Hi <a class="mention" href="/u/mapes911">@mapes911</a>, we haven’t run any tests on WatchOS yet. But you should be able to compile the code for that architecture. Can you double check your build command? The one below works on my machine.</p>
<pre><code class="lang-auto">BUILD_PYTORCH_MOBILE=1 IOS_PLATFORM=WATCHOS ./scripts/build_ios.sh
</code></pre>

mapes911: <p>Hi <a class="mention" href="/u/xta0">@xta0</a>,</p>
<p>Thanks! That did it. The build worked this time <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>
<p>I’m running up against another issue now though… not sure if it’s because I was messing around with Eigen libraries earlier or not… but I’m getting these math errors after importing pytorch into my XCode library.</p>
<pre><code class="lang-auto">.../pytorch/include/caffe2/perfkernels/math.h:3:10: 'cstdint' file not found
.../WatchSimulator6.1.sdk/usr/include/dispatch/dispatch.h:25:10: Could not build module 'Darwin'
.../WatchSimulator6.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:10: Could not build module 'CoreFoundation'
</code></pre>
<p>I’ve uninstalled and re-installed XCode as per some Stack Overflow posts I’ve found with similar issues and no luck.</p>
<p>Any ideas?</p>
<p>Thanks again for responding!</p>

mapes911: <p>Scratch that, I found the problem.  I had my Header Search Paths set to recursive and that caused my issues.</p>
<p>For anyone that finds this… here’s what I did to get this installed on WatchOS.</p>
<ul>
<li>cloned the pytorch repo</li>
<li>cd pytorch</li>
<li>git checkout v1.4.0</li>
<li>git submodule sync</li>
<li>git submodule update --init --recursive</li>
<li>BUILD_PYTORCH_MOBILE=1 IOS_PLATFORM=WATCHOS scripts/build_ios.sh</li>
<li>add files from build_ios/install/include/ and build_ios/install/lib/ to my XCode project</li>
<li>in XCode target build settings, add the include directory to Header Search Paths, make sure it’s non-recursive.</li>
<li>in XCode target build settings, Other Linker Flags,  -force_load “path to lib directory”</li>
</ul>
<p>That should do it!</p>

xta0: <p>That’s awesome news. Thanks for sharing this.</p>

mapes911: <p><a class="mention" href="/u/xta0">@xta0</a> I’m afraid I spoke too soon.  I thought my build was ok because it was just failing on one of my own bugs, but once I fixed that I’ve run into a couple of issues that I’m not sure how to solve.</p>
<p>I’m getting this error.</p>
<blockquote>
<p>libtorch.a(SparseCPUType.cpp.o)’ does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7k</p>
</blockquote>
<p>there is no setting for WatchOS to disable bitcode in the build like there is for iOS. is there a way to build the pytorch libs with bitcode enabled?</p>
<p>another issue I was seeing was…</p>
<blockquote>
<p>building for watchOS-arm64_32 but attempting to link with file built for watchOS-armv7k</p>
</blockquote>
<p>I am attempting to load onto a series 4 watch… any ideas?</p>
<p>Thanks again for your help!!</p>

xta0: <p><a class="mention" href="/u/mapes911">@mapes911</a>, Below is my command that work on my machine. Feel free to try it out.</p>
<pre><code class="lang-auto">BUILD_PYTORCH_MOBILE=1 ENABLE_BITCODE=1 IOS_PLATFORM=WATCHOS IOS_ARCH=arm64_32 ./scripts/build_ios.sh
</code></pre>
<p>As for the bitcode, you can use the commands below to verify</p>
<pre><code class="lang-auto">#check the architecure
&gt; lipo -i libcpuinfo.a
#Non-fat file: libcpuinfo.a is architecture: arm64_32

#verify bitcode
&gt; otool -l libtorch_cpu.a | grep bitcode
# sectname __bitcode
</code></pre>
<p>Again, I haven’t run any tests on watchOS platforms. So I’m not sure whether they’ll work or not. But I’m curious to see your results. Please let me know if you have any questions. THanks.</p>

mapes911: <p><a class="mention" href="/u/xta0">@xta0</a></p>
<p>feels like we’re getting closer!<br>
re-built using the command you sent.</p>
<p>the lipo command shows all the libraries built properly for arm64_32<br>
the otool command you gave is showing “-i functionality obsolete”  but the bitcode errors went away so I’m assuming that worked ok.</p>
<p>after doing that I still got a bunch of errors, but i was able to get rid of most by doing:</p>
<ul>
<li>Build Settings → Valid Architectures.  Removing armv7k and just leaving it as arm64_32.  Is this ok to do? Or will I run into issues later because I removed armv7k.</li>
</ul>
<p>But… now my (hopefully) last hurdle is this error:</p>
<blockquote>
<p>libpytorch_qnnpack.a(8x8-aarch64-neon.S.o), building for watchOS, but linking in object file ( …pytorch/lib//libpytorch_qnnpack.a(8x8-aarch64-neon.S.o)) built for macOS, for architecture arm64_32</p>
</blockquote>
<p>so… I’m not sure how to resolve this issue.  any ideas?</p>
<p>Thanks Tao!!</p>

xta0: <p><a class="mention" href="/u/mapes911">@mapes911</a> that’s because the QNNPACK kernel was written in assembly which has conficts with Apple’s LLVM IR (bitcode). If your model is not quantized, you don’t have to include QNNPACK.</p>
<p>Go to the root <code>CMakeLists.txt</code>, search for <code>set(USE_PYTORCH_QNNPACK ON)</code>, and turn it off</p>
<pre><code class="lang-auto">set(USE_PYTORCH_QNNPACK OFF)
</code></pre>

mapes911: <p><a class="mention" href="/u/xta0">@xta0</a></p>
<p>awesome. it’s compiling, linking and loading on my watch now!! thank you.</p>
<p>however, I am now getting this error when I attempt to load up a trained model.</p>
<blockquote>
<p>libc++abi.dylib: terminating with uncaught exception of type torch::jit::script::ErrorReport:<br>
Unknown builtin op: aten::mul.<br>
Could not find any similar ops to aten::mul. This op may not exist or may not be currently supported in TorchScript</p>
</blockquote>
<p>I’ve tried a couple of models, including one that I was able to load on my phone with LibTorch 1.4.0 using the Podfile install.</p>
<p>How would I look into what this aten::mul method does? Any idea if this has to do with the way I’ve built the libraries?  I’ve found a few other forum posts with similar errors but no immediate solution.</p>
<p>Just in case, here’s the code that loads the model.</p>
<pre><code class="lang-auto">torch::jit::script::Module module;
module = torch::jit::load(file_path);
</code></pre>

xta0: <p><a class="mention" href="/u/mapes911">@mapes911</a> That’s good news to hear. <code>aten::mul</code> is a very basic op that should be registered by default. Did you apply the <code>-all_load</code> to the static libraries? (<code>force_load</code> on libtorch_cpu.a should also work).  Also,  does that model work on your phone?</p>

mapes911: <p>yes! thank you so much. it is compiled/linked and i can now read in my model.</p>
<p>i appreciate all your help <a class="mention" href="/u/xta0">@xta0</a></p>

xta0: <p><a class="mention" href="/u/mapes911">@mapes911</a> No problem, were you able to run your model on your watch?</p>

mapes911: <p>Yes and no <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>
<p>I was able to load the model and run one of my data points through… but the second time through my event handler crashes.  Assuming this is me not really knowing C++ very well anymore… and I’m probably doing something bad with memory or not setting up my tensor properly.</p>
<p>So… I’m not fully sure that the data is going through the model yet.  Will try more when I get home tonight.</p>
<p>Thanks</p>

mapes911: <p><a class="mention" href="/u/xta0">@xta0</a> looks like i’m able to run data through my model just fine on my watch now, thank you very much for your help.</p>
<p>any idea when a WatchOS version will be supported in the LibTorch Podfile?  would love to be able to keep up with new versions without going through this pain.</p>

xta0: <p>Hey <a class="mention" href="/u/mapes911">@mapes911</a> That’s good news to hear! Thanks for letting me know.  We haven’t discussed about supporting watchos via Cocoapods yet. However, we did simplify the build script  - <a href="https://github.com/pytorch/pytorch/pull/33318" rel="nofollow noopener">https://github.com/pytorch/pytorch/pull/33318</a>.</p>

Harsh_Thaker: <p>Hey, I am facing the same issue. Where is CMakeLists.txt file located?</p>

mapes911: <aside class="onebox githubblob">
  <header class="source">
      <a href="https://github.com/pytorch/pytorch/blob/master/CMakeLists.txt" target="_blank" rel="nofollow noopener">github.com</a>
  </header>
  <article class="onebox-body">
    <h4><a href="https://github.com/pytorch/pytorch/blob/master/CMakeLists.txt" target="_blank" rel="nofollow noopener">pytorch/pytorch/blob/master/CMakeLists.txt</a></h4>
<pre><code class="lang-txt">cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
#cmake_policy(SET CMP0022 NEW)
#cmake_policy(SET CMP0023 NEW)

# Use compiler ID "AppleClang" instead of "Clang" for XCode.
# Not setting this sometimes makes XCode C compiler gets detected as "Clang",
# even when the C++ one is detected as "AppleClang".
cmake_policy(SET CMP0010 NEW)
cmake_policy(SET CMP0025 NEW)

# Suppress warning flags in default MSVC configuration.  It's not
# mandatory that we do this (and we don't if cmake is old), but it's
# nice when it's possible, and it's possible on our Windows configs.
if(NOT CMAKE_VERSION VERSION_LESS 3.15.0)
  cmake_policy(SET CMP0092 NEW)
endif()

if(NOT CMAKE_VERSION VERSION_LESS 3.10)
  set(FIND_CUDA_MODULE_DEPRECATED ON)
endif()
</code></pre>

  This file has been truncated. <a href="https://github.com/pytorch/pytorch/blob/master/CMakeLists.txt" target="_blank" rel="nofollow noopener">show original</a>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>


Harsh_Thaker: <p>Thanks for the reply. That’s the path of PyTorch repo. How can changes there resolves the error in XCode? Can you please elaborate the process ?</p>
<p>Error:<br>
ld: warning: building for iOS, but linking in object file (/path-to-project/Pods/LibTorch/install/lib/libpytorch_qnnpack.a(8x8-aarch64-neon.S.o)) built for macOS<br>
ld: warning: building for iOS, but linking in object file (/path-to-project/Pods/LibTorch/install/lib/libpytorch_qnnpack.a(8x8-aarch64-neon.S.o)) built for macOS<br>
Undefined symbols for architecture arm64:<br>
“<em>OBJC_CLASS</em>$_TorchModule”, referenced from:<br>
objc-class-ref in ViewController.o<br>
ld: symbol(s) not found for architecture arm64<br>
clang: error: linker command failed with exit code 1 (use -v to see invocation)</p>

mapes911: <p>Hey there,</p>
<p>The CMakeLists.txt changes I made were to turn off QNNPACK which was causing issues for me when I loaded the model in my XCode project.<br>
I’m not sure what your issue is, but if you read through the thread I had to go through several iterations (and issues) to arrive at a LibTorch build that allowed me to get my trained model running in a WatchOS project.</p>
<p>What is the process you are going through that is getting you to this error?<br>
(I’m no expert in this, but <a class="mention" href="/u/xta0">@xta0</a> 's comments really helped )</p>