Saturday, March 16, 2019

Debugging Python Module Built with Pybind11

Pybind11 is a wonderful library to build native c++ functions callable within Python. Let's see how we can debug a module built with Pybind11.

For this project, we will use the very simple Pybind11 example module. Let's get started.

Clone the repository
$ git clone https://github.com/pybind/python_example.git
$ cd python_example

Install the package
$ python setup.py install

Run gdb on Python
$ gdb -q python

Break into the desired function, such as
(gdb) b add
(gdb) b src/main.cpp:4

Run the command
(gdb) r tests/test.py

That is it!

Friday, March 1, 2019

Network Visualization with Intermediate Layer Shapes

Network visualization is very important. Looking at the network graph is much easier than reading through the network description. In this post, I will discuss how to create visual graph of a (Pytorch) network using Netron and include intermediate layer shapes as well.

Netron is an excellent tool for network visualization. At the moment, however, Netron does not support Pytorch natively (experimental feature but not stable). The best thing is to convert Pytorch model to ONNX and then use Netron to graph it.

The following is an example code that graphs ResNet50.
import torch
from torchvision import models
import onnx
from onnx import shape_inference

DEVICE = 'cuda:1'
PATH = 'resnet.onnx'
model = models.resnet50().to(DEVICE)
model.eval()
dummy_input = torch.randn(1,3,224,224).to(DEVICE)
torch.onnx.export(model, dummy_input, PATH, verbose=False)
onnx.save(shape_inference.infer_shapes(onnx.load(PATH)), PATH) # this is required for displaying intermediate shapes




To graph it, simply download Netron and run
$ netron resnet.onnx

That's it!

Sunday, February 24, 2019

Resolving Bluetooth Issues with Ubuntu 18.04 LTS

So there are a few things that I do not like about Linux in general; quite a lot of things do not work automatically. One of the problems I have faced is that my Microsoft Designer mouse won't work with Ubuntu 18.04 LTS. After some research, I found this solution suggested by Newbuntie to work well, so I'm going to post this here for any other people going through the same trouble.

Basically, enter the following commands and you are good to go.
$ sudo add-apt-repository ppa:bluetooth/bluez
$ sudo apt install bluez


Enjoy!

Friday, December 7, 2018

Use pkg-config with CMake

Say you want to build a binary which uses OpenCV library. For example, the following would be a typical command for compiling your program
$ g++ `pkg-config --cflags opencv` main.cpp `pkg-config --libs opencv` -o opencv_example

Now, the question is how do we do this with CMake? The following would be what you would write in CMakeLists.txt
project(opencv_example)

# this is where we get pkg-config info
find_package(PkgConfig REQUIRED)
pkg_check_modules(OPENCV REQUIRED opencv)

# this is where you compile your app
add_executable(opencv_example main.cpp)
target_link_libraries(opencv_example ${OPENCV_LIBRARIES})
target_include_directories(opencv_example PUBLIC ${OPENCV_INCLUDE_DIRS})
target_compile_options(opencv_example PUBLIC ${OPENCV_CFLAGS_OTHER})

Happy hacking!

Friday, November 23, 2018

Learn Swift on Ubuntu: install and compile

Swift is a new language developed by Apple. Recently, I am studying Swift so that I can build iOS or macOS apps. In this post, I will go over how to setup Swift environment on Ubuntu 18.04 LTS.

First, install clang
$ sudo apt-get update && sudo apt-get install clang -y

Next, download Swift from Swift.org
$ wget https://swift.org/builds/swift-4.2.1-release/ubuntu1804/swift-4.2.1-RELEASE/swift-4.2.1-RELEASE-ubuntu18.04.tar.gz

Decompress
$ tar xfz swift-4.2.1-RELEASE-ubuntu18.04.tar.gz

Add swift binary directory to your PATH environment
$ export PATH=/path/to/swift/usr/bin:${PATH}

This is it for setting up the environment. Let's now build "hello world" in Swift.

Create hello.swift with the following content:
print("hello world")

To run your code, simply run
$ swift hello.swift
hello world

To compile and create a binary, run
$ swiftc hello.swift
./hello
hello world

That's it for this post. Happy hacking!

Sunday, November 4, 2018

Simple 2-Way Chat with Java

In this post, I'm going to discuss how to create a simple chat application with Java. Basically, this is going to be a tutorial on Socket API and Java Thread API.

Here is the basic idea. A chat class should be running two tasks simultaneously: one is to send messages that the user inputs, and the other is to receive incoming message from the other side. Because these two tasks should be run simultaneously, we will need to implement a multi-threaded application.

I am going to let the main thread take care of user input and transmitting over to the other side, and a separate thread for receiving any incoming messages. Here we go.

So, the base class is ChatThread, which pretty much takes care of what I described above. The main thread takes care of user input and transmitting over to the other side, whereas a separate thread is going to run in the background, which receives incoming messages.

For this 2-way simple application, there are only two sides: one for server and the other for client. The server needs to take care of creating the server socket and wait for a client to join. Once the client joins, the server starts the ChatThread. The client will simply join the server and start the chatThread.

The implementation here is very basic and doesn't take care of properly exiting the connections. However, this should give you good introduction as to how to deal with socket programming and threading.

Happy hacking!

Friday, October 26, 2018

Build AI Camera App (Caffe2)

AI Camera app from Facebook is an example app that shows how to build Caffe2 on Android platform. Unfortunately, you will find that it does not work with the latest Android Studio. Here is how to get it to work.

One of the main reasons that it does not build is because starting with NDK r18b, GCC has been removed. The easiest way to get it working is to download older version, say r17c, and edit local.properties file and change ndk.dir to r17c folder.

Other than that, a couple of minor changes. In gradle.build file, update gradle version to 3.2.1 as below:

classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.android.tools.build:gradle:3.2.1'


Lastly, edit gradle/wrapper/gradle-wrapper.properties file and change gradle tool version to 4.6 as below:

distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip


After all these changes, the app should successfully build! Happy hacking!

Build Caffe2 using Android NDK

Starting with Google's Android NDK r18b, gcc has been removed (history). That is, only one has to use clang as the toolchain. This may cause some problems if you do not set its toolchain as clang.

In fact, when you try to build Caffe2 for Android with android-ndk, it will fail, complaining

GCC is no longer supported.  See
  https://android.googlesource.com/platform/ndk/+/master/docs/ClangMigration.md.

The solution is to simply edit pytorch/scripts/build_android.sh file, replacing gcc to clang for ANDROID_TOOLCHAIN variable, as shown below:

CMAKE_ARGS+=("-DANDROID_TOOLCHAIN=gcc")
CMAKE_ARGS+=("-DANDROID_TOOLCHAIN=clang")

Happy hacking!

Building Caffe2 and Pytorch for Ubuntu 18.04 LTS

I am trying to export my pytorch model to Android devices. It seems that using onnx and caffe2 is the easiest way to do so. Here, I will describe the steps to build and install pytorch & caffe2 for Ubuntu 18.04 LTS.

Basically, one has to follow the instructions here, but I had some problems building. The easiest way to build is to disable all unnecessary features. For example, since I am only going to port it to caffe2 and do not intend to use GPU for running pytorch model (at least for this python environment), I can set some flags:
$ export NO_CUDA=1
$ export NO_DISTRIBUTED=1

Also, I will build pytorch and caffe2 together. Hence, I set the flag
$ export FULL_CAFFE2=1

With these environment variables set, I successfully built and installed caffe2 and pytorch from the source, following the official instruction.

Happy hacking!

Tuesday, August 14, 2018

Multi-GPU on Pytorch

After some time, I finally figured out how to run multi-gpu on pytorch. In fact, multi-gpu API is just extremely simple in pytorch; the problem was my system.

Here is a simple test code to try out multi-gpu on pytorch. If this works about of the box, then you are good. However, some people may face problems, as discussed in this forum. As pointed out here, the problem is not about pytorch, but with external factor. In my case, it was ngimel 's comment that saved me. To recap her solution,

1. Test p2pBandwithLatencyTest from CUDA samples and make sure it works fine. If it does not pass this one, then the problem is with CUDA installation, etc, and not with pytorch. To download samples, simply run

$ cuda-install-samples-9.2.sh <target_path>

where you would replace the version above to whatever version you have. Then,

$ cd <target_path>/NVIDIA_CUDA-9.2_Samples/1_Utilities/p2pBandwidthLatencyTest/
$ make
$ ./p2pBandwidthLatencyTest

2. In my case, it was IOMMU that was the culprit. Disable it by editing /etc/default/grub and replace
#GRUB_CMDLINE_LINUX="" 
with
GRUB_CMDLINE_LINUX="iommu=soft"

Then update grup
$ sudo update-grup

Then reboot

This is how I solved my problem. I love this open source community forum! Thank you everyone!