New feature: Installing SwiftPM packages in Jupyter

I edited my post to reflect that cuda is not necessary. I assumed that some image processing functions would be automatically performed by the GPU - is that not the case, or is it just that we are (naturally) not worried about performance right now?

OK, done :slight_smile: https://github.com/fastai/fastai_docs/pull/101
I couldn’t make automatic PR check pass, it seems to fail on some other unstripped notebooks.

Had to add more opencv functions, e.g. for flipping images - Tensor and ShapedArray don’t have flip. Also I couldn’t figure out how to make a slice of ShapedArray to crop part of the image in Swift, e.g. arr[0..<100,0..<100] doesn’t work. warpAffine can crop, but it’s not as convenient as slicing in numpy.
Please let me know if you need more or different examples or have problems with package installation.

Thank you for checking! Glad it worked for you.
I wasn’t trying to use CUDA, just enabled all optimizations to see it if will compile :slight_smile:
As I understand using GPU will only make worse if images are loaded/processed one by one because copying to/from GPU memory will probably take more time than processing itself. You want to load as much as possible into GPU RAM first, it’s interesting to see it there’re dataloaders that do load image files into GPU to decode/crop/resize/etc.

2 Likes

@marcrasi Are there any restrictions for packages that can be installed & imported in the swift-jupyter?
I’m trying to play with Vapor package (which is silly to do in jupyter I know :slight_smile:), but:

import Vapor
expression failed to parse, unknown error

After that the kernel is in bad state:

Kernel is in a bad state. Try restarting the kernel.

Exception in `_execute_cell`:
Error setting parent message: SwiftError(result=<lldb.SBValue; proxy of <Swig Object of type 'lldb::SBValue *' at 0x7f7344336f00> >, description='error: <Cell 8>:2:13: error: use of unresolved identifier \'JupyterKernel\'\n            JupyterKernel.communicator.updateParentMessage(\n            ^~~~~~~~~~~~~\n\nerror: <Cell 8>:3:21: error: use of unresolved identifier \'KernelCommunicator\'\n                to: KernelCommunicator.ParentMessage(json: "{\\"header\\": {\\"msg_id\\": \\"5AC9351C07524D46896CB1F193D91480\\", \\"username\\": \\"username\\", \\"session\\": \\"5E1E5CA9481F4D3D8B54FCFAFE910FE5\\", \\"msg_type\\": \\"execute_request\\", \\"version\\": \\"5.2\\", \\"date\\": \\"2019-04-24T17:39:36.779166+00:00\\"}, \\"msg_id\\": \\"5AC9351C07524D46896CB1F193D91480\\", \\"msg_type\\": \\"execute_request\\", \\"parent_header\\": {}, \\"metadata\\": {}, \\"content\\": {\\"code\\": \\"print(\\\\\\"test\\\\\\")\\", \\"silent\\": false, \\"store_history\\": true, \\"user_expressions\\": {}, \\"allow_stdin\\": true, \\"stop_on_error\\": true}, \\"buffers\\": []}"))\n                    ^~~~~~~~~~~~~~~~~~\n\n')

Problem reproduces in Colab and in local docker image with swift-jupyter (LLVM dcb9eb74a7, Clang 95cdf7c9af, Swift 4c94878dd2; swift-jupyter rev. 1e08b1d).
However, in the same docker container, I can compile & start my app that uses Vapor package.
Can you advice how to troubleshoot what’s causing this? Thanks!

I don’t know about any specific things that the installation doesn’t support, but I haven’t tested it on very many packages, so we’ll probably keep finding packages that don’t work for a while. You just found Vapor! :slight_smile:

Here’s some troubleshooting advice (I’ll go add this to the README soon because it seems like something that many people will need):

When you run the install cell, you should see something like “Working in: /tmp/xyzxyzxyzxyz/swift-install”. Start the swift CLI REPL with this command: SWIFT_IMPORT_SEARCH_PATH=/tmp/xyzxyzxyzxyz/swift-install/modules swift. (swift is in the usr/bin directory of the toolchain. In the Docker container, /swift-tensorflow-toolchain/usr/bin/swift). In the REPL, run

import Glibc
dlopen("/tmp/xyzxyzxyzxyz/swift-install/package/.build/debug/libjupyterInstalledPackages.so", RTLD_NOW)

import TheModuleThatYouHaveTriedToInstall

This will usually give you an error message that is more informative than “expression failed to parse, unknown error”.

(A very useful thing to do would be to fix swift-jupyter so that it shows the informative error message instead of “expression failed to parse, unknown error”. I’ve never looked into this, so I don’t know where to start and I don’t know how hard it would be. I might investigate at some point.)

4 Likes

@marcrasi Thanks for your advice on how to debug the problem!

With Vapor, it turned out that some of module.modulemap's contain relative paths to headers, so when the file is copied to /tmp/xxx it stops working.
Another problem with modulemaps you’ve mentioned occurs because swift does not place local dependency into the .build folder of fake jupyterInstalledPackages package, and the code that copies modulemap files doesn’t know where to look for them.

I was able to fix both issues by 1) reading list of dependencies’ modulemaps from .build/build.db file and 2) replacing all relative headers paths with absolute when copying modulemaps.
Here’s commit, if you think this approach is adequate I can open PR.

@vova a PR would be great!

OK, I made a PR and described my concerns there :slight_smile:

Here’s how to install the PR before it’s merged:

git fetch origin pull/58/head:fixdeps
git checkout fixdeps
python register.py --sys-prefix --swift-python-use-conda --use-conda-shared-libs   --swift-toolchain ~/swift
1 Like