Slide 1

Slide 1 text

Copenhagen Denmark BRIDGE THE PHYSICAL WORLD: KOTLIN/NATIVE ON RASPBERRY PI QIAN JIN @bonbonking

Slide 2

Slide 2 text

Android Developer, GDE for IoT Made in China Live in Paris @bonbonking

Slide 3

Slide 3 text

•Context •Rock-Paper-Scissor Hand Robot •Kotlin/Native as an alternative •Project setup •Step by step •Step 0 - Hello Kotlin Native •Step 1 - Basic GPIO: Blink the LED •Tip 1 - Move the project into IntelliJ •Tip 2 - Deploy with Gradle SSH plugin •Step 2 - Button Callback •Step 3 - Control servomotors •Step 4 - Capture image with pi camera •Step 5 - Run TensorFlow with Kotlin/Native (on raspberry pi?!) •Demo - Kotlin/Native on Raspberry Pi in actions! 3 Agenda

Slide 4

Slide 4 text

Rock-Paper-Scissor hand game robot ✌✊ with Android Things

Slide 5

Slide 5 text

5

Slide 6

Slide 6 text

Source:

Slide 7

Slide 7 text

Source:

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

• Data collection tool: raw data for model training • Hardware components: robot arms + game control • Application running on Android Things • Game logic and interactions • Image capture with camera preview • Gesture recognition with TensorFlow 9 Break Down the Project

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

GDPR? Not compliant…

Slide 13

Slide 13 text

• Android Things Starter Kit - NXP i.MX7D (~200€) • 16-Channel PWM/Servo Driver (~12€) • Power Supply or battery (~5€) • 5 servomotors (~12€) • Cardboard + wood sticks (~0€) • Glue Gun (~10€) • Electronic jumper + Resistors + LED + Button + Breadboard (~10€) 13 Hardware (Android Things Version)

Slide 14

Slide 14 text

Source: https://developer.android.com/things

Slide 15

Slide 15 text

Source: https://www.adafruit.com/product/815 16-Channel 12-bit PWM/Servo Driver (I2C interface/PCA9685)

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Source:

Slide 18

Slide 18 text

Source: https://commons.wikimedia.org/wiki/File:Android_robot_skateboarding.svg

Slide 19

Slide 19 text

Source: https://android-developers.googleblog.com/2019/02/an-update-on-android-things.html

Slide 20

Slide 20 text

Source: https://www.iconfinder.com/icons/1172126/android_crying_emoji_mobile_mood_robot_sad_icon

Slide 21

Slide 21 text

Kotlin/Native (Explained to a cat)

Slide 22

Slide 22 text

Source: https://kotlinlang.org/docs/reference/native-overview.html Kotlin/Native is an LLVM based backend for the Kotlin compiler and native implementation of the Kotlin standard library. It compiles Kotlin code to native binaries, which can run without a virtual machine.

Slide 23

Slide 23 text

Source: https://en.wikipedia.org/wiki/Compiler Front End Middle End (Optimizer) Back End Source Code C C++ Java Kotlin … Machine Code ARM Sparc X86 PowerPC … Compiler Design

Slide 24

Slide 24 text

Source: https://www.aosabook.org/en/llvm.html LLVM Optimizer LLVM X86 Backend LLVM PowerPC Backend LLVM ARM Backend Clang C/C++/ObjC Front End Kotlin Front End Rust Front End LLVM IR LLVM IR LLVM's Implementation of the Three-Phase Design

Slide 25

Slide 25 text

Source: https://github.com/JetBrains/kotlin-native/tree/master/backend.native IR Kotlin/Native as a LLVM Backend LLVM IR 0101 0101 …… IR: Intermediate Representation

Slide 26

Slide 26 text

Source: https://github.com/JetBrains/kotlin-native/tree/master/backend.native IR LLVM IR 0101 0101 …… IR: Intermediate Representation Kotlin/Native as a LLVM Backend

Slide 27

Slide 27 text

Kotlin/Native target presets • Android: androidNativeArm32, androidNativeArm64 • iOS: iosArm32, iosArm64, iosX64 • Linux: linuxArm32Hfp, linuxMips32, linuxMipsel32, linuxX64 • MacOS: macosX64 • Windows: mingwX64, mingwX86 • WebAssembly: wasm32 • watchOS, tvOS… ℹ Linux MIPS targets (linuxMips32 and linuxMipsel32) require a Linux host. Other Linux targets can be built on any supported host. Source: https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#supported-platforms https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#using-kotlinnative-targets 27

Slide 28

Slide 28 text

Architecture •ARM (*Originally: Acorn RISC Machine) •ARM (Advanced RISC Machines) •x86 (Successors to Intel’s 8086 processor) •RISC (Reduced Instruction Set Computing) •CISC (Complex Instruction Set Computing) Source: https://github.com/raspberrypi/firmware 28

Slide 29

Slide 29 text

Raspberry Pi 3 Model B+ Spec • BCM2837 1.2 GHz 64-bit quad processor based on the ARMv8 Cortex-A53 • 32-bit Raspbian version, with a 64-bit version later to come if "there is value in moving to 64-bit mode” 29

Slide 30

Slide 30 text

My Raspberry Pi 3B *armhf (ARM Hard Float) ✅ Among target preset (linuxArm32Hfp)

Slide 31

Slide 31 text

Source: https://en.wikipedia.org/wiki/Cross_compiler Host Machine Cross Compiler Source Code Target Machine Target compatible binary Cross Compilation

Slide 32

Slide 32 text

Source: https://en.wikipedia.org/wiki/Cross_compiler MacBook Pro (macosX64) Cross Compiler Raspberry Pi (linuxArm32Hfp) Target compatible binary Cross Compilation Source Code

Slide 33

Slide 33 text

Key Components •konanc: Kotlin/Native compiler •cinterop: produce Kotlin binding for native libraries Source: https://kotlinlang.org/docs/reference/native/c_interop.html 33

Slide 34

Slide 34 text

C Interoperability • Create a .def file describing what to include into bindings • Use the cinterop tool to produce Kotlin bindings • Run Kotlin/Native compiler on an application to produce the final executable Source: https://github.com/JetBrains/kotlin-native/blob/master/INTEROP.md 34 .def .h cinterop .klib

Slide 35

Slide 35 text

• Pointers and arrays => CPointer? • Enums => Kotlin enum or integral values • Structs / unions => types having fields available via the dot notation (i.e. kotlinConfInstance.speakers) • typedef => typealias Source: https://kotlinlang.org/docs/reference/native/c_interop.html 35 Basic Interop Types C Type Kotlin Type Signed, unsigned integral and floating point Kotlin counterpart with the same width Pointers and arrays CPointer? Enums Kotlin enum or integral values Structs / Unions Types having fields available via the dot notation (i.e. kotlinConfInstance.speakers) typedef typealias

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

My Setup Macbook + Raspberry Pi 3 (Model B)

Slide 38

Slide 38 text

• Android Things Starter Kit - NXP i.MX7D (~200€) • Raspberry Pi 3B+ (~40€) + Pi Camera Module V2 (~25€) + Display • … 38 Hardware (Raspberry Pi Version)

Slide 39

Slide 39 text

Source:

Slide 40

Slide 40 text

Source: https://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-header-details-and-pinout/ VCC SDA1 I2C SCL1 I2C LED GPIO Button GPIO Ground

Slide 41

Slide 41 text

February 2019: Me trying to cross compile Kotlin/Native application on my MacBook for the very first time when there were only 3 articles from 2017 which talk about the subject.

Slide 42

Slide 42 text

exception: java.lang.IllegalStateException: Target linux_arm32_hfp is not available on the macos_x64 host at org.jetbrains.kotlin.backend.konan.KonanConfig.(KonanConfig.kt:47) at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:60) at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:35) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:96) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:52) …

Slide 43

Slide 43 text

Source: https://github.com/JetBrains/kotlin-native/releases

Slide 44

Slide 44 text

Step 0: Hello, Kotlin/Native!

Slide 45

Slide 45 text

hello.kt Source: https://hadihariri.com/2017/04/09/kotlin-on-raspberry-pi/ fun main() { println("Hello Kotlin/Native from Qian’s Macbook!") }

Slide 46

Slide 46 text

Compile Manually $ konanc hello.kt -o hello -target raspberrypi $ scp hello.kexe pi@{IP-RASPBERRY-PI}:~/dir/ hello.kexe

Slide 47

Slide 47 text

Source:

Slide 48

Slide 48 text

Step 1: Basic GPIO (General Purpose Input/Output)

Slide 49

Slide 49 text

Source: https://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-header-details-and-pinout/ VCC LED GPIO Ground

Slide 50

Slide 50 text

pigpio pigpio: a library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO), works on all versions of the Pi. Source: https://github.com/joan2937/pigpio 50

Slide 51

Slide 51 text

Wiring Pi Wiring Pi: WiringPi is a PIN based GPIO access library written in C for the BCM2835, BCM2836 and BCM2837 SoC devices used in all Raspberry Pi. Source: http://wiringpi.com/ 51

Slide 52

Slide 52 text

• Create a pigpio.def file • Use the cinterop tool to produce Kotlin bindings • ⚠ Build the library on your Raspberry Pi and copy the .so to your Mac for cross compilation • Run Kotlin/Native compiler on an application to produce the final executable Source: https://hadihariri.com/2017/05/28/raspberry-pi-starter-kit-and-kotlin-native/ 52 Make it work! Thank you Hadi Hariri!!

Slide 53

Slide 53 text

pigpio.def headers = pigpio.h

Slide 54

Slide 54 text

Generate Kotlin Binding $ cinterop \ -def pigpio.def \ -compiler-option -I`pwd`/include \ -o pigpio \ -target raspberrypi

Slide 55

Slide 55 text

Generate Kotlin Binding $ cinterop \ -def pigpio.def \ -compiler-option -I`pwd`/include \ -o pigpio \ -target raspberrypi -def pigpio -> the .def file we just created

Slide 56

Slide 56 text

Generate Kotlin Binding $ cinterop \ -def pigpio.def \ -compiler-option -I`pwd`/include \ -o pigpio \ -target raspberrypi -compiler-option -I`pwd`/include —> indicate the path of the header file

Slide 57

Slide 57 text

Generate Kotlin Binding $ cinterop \ -def pigpio.def \ -compiler-option -I`pwd`/include \ -o pigpio \ -target raspberrypi -o pigpio -> the output name for the Kotlin binding

Slide 58

Slide 58 text

Generate Kotlin Binding $ cinterop \ -def pigpio.def \ -compiler-option -I`pwd`/include \ -o pigpio \ -target raspberrypi -target raspberrypi -> our target platform

Slide 59

Slide 59 text

Generate Kotlin Binding $ cinterop \ -def pigpio.def \ -compiler-option -I`pwd`/include \ -o pigpio \ -target raspberrypi pigpio.klib pigpio-build/

Slide 60

Slide 60 text

pigpio: Basic API in C int gpioInitialise(void); int gpioSetMode(unsigned gpio, unsigned mode); int gpioWrite(unsigned gpio, unsigned level); int gpioSleep(unsigned timetype, int seconds, int micros); 60

Slide 61

Slide 61 text

Generated Kotlin Binding @kotlinx.cinterop.internal.CCall fun gpioInitialise(): Int @kotlinx.cinterop.internal.CCall fun gpioSetMode(gpio: UInt, mode: UInt): Int @kotlinx.cinterop.internal.CCall fun gpioWrite(gpio: UInt, level: UInt): Int @kotlinx.cinterop.internal.CCall fun gpioSleep(timetype: UInt, seconds: Int, micros: Int): Int

Slide 62

Slide 62 text

Led.kt fun blinkLed() { val port = GPIO_LED.toUInt() gpioInitialise() gpioSetMode(port, PI_OUTPUT) println("Start blinking”) while (true) { gpioWrite(port, 0) gpioSleep(PI_TIME_RELATIVE, 0, 500000) gpioWrite(port, 1) gpioSleep(PI_TIME_RELATIVE, 0, 500000) } }

Slide 63

Slide 63 text

$ git clone https://github.com/joan2937/pigpio $ cd pigpio $ make $ sudo make install Install pigpio Retrieve libpigpio.so for cross compilation

Slide 64

Slide 64 text

Generate executable $ konanc led.kt \ -library pigpio \ -linker-options "-L`pwd`/lib -lpigpio" \ -o led \ -target raspberrypi

Slide 65

Slide 65 text

Generate executable $ konanc led.kt \ -library pigpio \ -linker-options "-L`pwd`/lib -lpigpio" \ -o led \ -target raspberrypi -library pigpio -> indicate the Kotlin binding to use

Slide 66

Slide 66 text

Generate executable $ konanc led.kt \ -library pigpio \ -linker-options "-L`pwd`/lib -lpigpio" \ -o led \ -target raspberrypi -linker-options -> link the library libpigpio.so

Slide 67

Slide 67 text

Generate executable $ konanc led.kt \ -library pigpio \ -linker-options "-L`pwd`/lib -lpigpio" \ -o led \ -target raspberrypi -o led -> indicate the output executable name

Slide 68

Slide 68 text

Generate executable $ konanc led.kt \ -library pigpio \ -linker-options "-L`pwd`/lib -lpigpio" \ -o led \ -target raspberrypi -target raspberrypi -> still our target!

Slide 69

Slide 69 text

Generate executable $ konanc led.kt \ -library pigpio \ -linker-options "-L`pwd`/lib -lpigpio" \ -o led \ -target raspberrypi led.kexe

Slide 70

Slide 70 text

Tip 1: Move the project into IntelliJ

Slide 71

Slide 71 text

• kotlin-multiplatform plugin • Still experimental, DSL keeps changing • Samples use the most recent APIs Source: https://github.com/JetBrains/kotlin-native/blob/master/INTEROP.md 71 Move into IntelliJ

Slide 72

Slide 72 text

build.gradle Source: https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html plugins { id 'kotlin-multiplatform' version '1.3.60' } kotlin { linuxArm32Hfp("chifoumi") { binaries { executable { entryPoint “chifoumi.robot.main" // libpigpio.so are compiled on raspberry pi and copied here linkerOpts("-Lsrc/include/pigpio", "-lpigpio") } } compilations.main.cinterops { pigpio { includeDirs ‘src/include/pigpio' } } } }

Slide 73

Slide 73 text

Tip 2: Deploy on Pi with Gradle SSH plugin

Slide 74

Slide 74 text

• Cross compilation repetitive scp • Always automate! ✨ • Step 1: passwordless SSH with your Raspberry Pi • Step 2: write a gradle task which does the job • Step 3: Source: https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md 74 Deploy on Pi with Gradle

Slide 75

Slide 75 text

task deployOnPi Source: https://gradle-ssh-plugin.github.io/ remotes { pi { host = ‘IP address ip of your pi' user = 'pi user' identity = file(‘/path/to/.ssh/id_rsa’) } } task deployOnPi { doLast { ssh.run { session(remotes.pi) { def sourceFile = "$buildDir/path/to/app.kexe" def destinationDir = "/path/on/pi" put from: sourceFile, into: destinationDir } } } }

Slide 76

Slide 76 text

Step 2: Button Callback (Mapping Function Pointer from C)

Slide 77

Slide 77 text

Source: https://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-header-details-and-pinout/ VCC Button GPIO Ground

Slide 78

Slide 78 text

•The executable will launch a continuous loop… •How do we interact with the application? •With a physical input! •So how can we receive the callback?

Slide 79

Slide 79 text

pigpio: Set Alert Function // Register a function to be called (a callback) when the specified GPIO changes state. int gpioSetAlertFunc(unsigned user_gpio, gpioAlertFunc_t f); typedef void (*gpioAlertFunc_t) (int gpio, int level, uint32_t tick); 79

Slide 80

Slide 80 text

Generated Kotlin Binding Source: https://kotlinlang.org/docs/reference/type-aliases.html typealias gpioAlertFunc_t = CPointer Unit>>

Slide 81

Slide 81 text

Generated Kotlin Binding Source: https://kotlinlang.org/docs/reference/type-aliases.html typealias gpioAlertFunc_t = CPointer Unit>> typedef void (*gpioAlertFunc_t) ( int gpio, int level, uint32_t tick );

Slide 82

Slide 82 text

• How to convert a Kotlin function to a pointer to a C function? • staticCFunction(::kotlinFunction) to the rescue! Source: https://kotlinlang.org/docs/tutorials/native/mapping-function-pointers-from-c.html 82 Mapping Function Pointer from C

Slide 83

Slide 83 text

Button Callback val onButtonPressed = staticCFunction { gpio, level, tick -> when (level) { 0 -> println("Button Pressed down, level 0") 1 -> println("Button Released, level 1") 2 -> println("Button GPIO timeout, no level change") } } fun setupButton() { val buttonPort = GPIO_BUTTON.toUInt() gpioSetMode(buttonPort, PI_INPUT) gpioSetAlertFunc(buttonPort, onButtonPressed) }

Slide 84

Slide 84 text

Step 3: Control Servomotors

Slide 85

Slide 85 text

I²C: I-squared-C • I2C bus connects simple peripheral devices with small data payloads • I2C devices connect using a 3-Wire interface consisting of: • Shared clock signal (SCL) • Shared data line (SDA) • Common ground reference (GND) Source: https://developer.android.com/things/sdk/pio/i2c 85

Slide 86

Slide 86 text

Source: https://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-header-details-and-pinout/ VCC SDA1 I2C SCL1 I2C Ground

Slide 87

Slide 87 text

Source:

Slide 88

Slide 88 text

PWM: Pulse Width Modulation • Pulse Width Modulation (PWM) is a common method used to apply a proportional control signal to an external device using a digital output pin. (e.g. servo motors, LCD display) • Frequency: expressed in Hz • Period: the time each cycle takes and is the inverse of frequency • Duty cycle: expressed as a percentage Source: https://developer.android.com/things/sdk/pio/pwm 88

Slide 89

Slide 89 text

Source: https://developer.android.com/things/sdk/pio/pwm

Slide 90

Slide 90 text

• PCA9685 16-Channel 12 Bit PWM Servo Driver • Adafruit C++ lib: not interoperable with Kotlin Native • Small but essential: https://github.com/edlins/ libPCA9685 Source: https://discuss.kotlinlang.org/t/kotlin-native-with-c-libraries/2490/3 90 In search of the C binding

Slide 91

Slide 91 text

$ git clone https://github.com/edlins/libPCA9685 $ cd libPCA9685 && mkdir build && cd build $ cmake .. $ make $ sudo make install Install libPCA9685 Retrieve libPCA9685.so for cross compilation

Slide 92

Slide 92 text

pigpio: Initialize PWM // Open the I2C bus device and assign the default slave address int PCA9685_openI2C(unsigned char adpt, unsigned char addr); // Initialize a PWM device with the frequency int PCA9685_initPWM(int fd, unsigned char addr, unsigned int freq); 92

Slide 93

Slide 93 text

PWM Initialisation val adapterNumber = 1 val fileDescriptor = PCA9685_openI2C( adapterNumber.toUByte(), I2C_SERVO_ADDRESS.toUByte() ) PCA9685_initPWM( fileDescriptor, I2C_SERVO_ADDRESS.toUByte(), PWM_FREQUENCY.toUInt() )

Slide 94

Slide 94 text

pigpio: Set PWM Values // set all PWM channels from two arrays of ON and OFF vals in one transaction int PCA9685_setPWMVals(int fd, unsigned char addr, unsigned int* onVals, unsigned int* offVals); // set a single PWM channel with a 16-bit ON val and a 16-bit OFF val int PCA9685_setPWMVal(int fd, unsigned char addr, unsigned char reg, unsigned int on, unsigned int off); // set all PWM channels with one 16-bit ON val and one 16-bit OFF val int PCA9685_setAllPWM(int fd, unsigned char addr, unsigned int on, unsigned int off); 94

Slide 95

Slide 95 text

pigpio: Set PWM Values // set all PWM channels from two arrays of ON and OFF vals in one transaction int PCA9685_setPWMVals(int fd, unsigned char addr, unsigned int* onVals, unsigned int* offVals); // set a single PWM channel with a 16-bit ON val and a 16-bit OFF val int PCA9685_setPWMVal(int fd, unsigned char addr, unsigned char reg, unsigned int on, unsigned int off); // set all PWM channels with one 16-bit ON val and one 16-bit OFF val int PCA9685_setAllPWM(int fd, unsigned char addr, unsigned int on, unsigned int off); 95

Slide 96

Slide 96 text

Generated Kotlin Binding CValuesRef? public fun PCA9685_setPWMVals( fd: Int, addr: UByte, onVals: CValuesRef?, offVals: CValuesRef? ): Int

Slide 97

Slide 97 text

Source: https://kotlinlang.org/api/latest/jvm/stdlib/kotlinx.cinterop/-c-values-ref/index.html 97 Understand CValuesRef

Slide 98

Slide 98 text

• Get a NativePlacement instance from the memScoped {…} block receiver • Create an array of UIntVar instance with the allocArray extension function in the NativePlacement instance Source: https://jonnyzzz.com/blog/2019/01/14/kn-intptr/ 98 Explicit Native Memory Allocation

Slide 99

Slide 99 text

Set PWM On/Off values (1/2) memScoped { val onValues = allocArray(_PCA9685_CHANS) val offValues = allocArray(_PCA9685_CHANS) for (i in 0 until _PCA9685_CHANS - 1) { onValues[i] = SERVO_ON_ANGLE.toUInt() } for (i in 0 until _PCA9685_CHANS - 1) { offValues[i] = SERVO_OFF_ANGLE.toUInt() } PCA9685_setPWMVals(fileDescriptor, I2C_SERVO_ADDRESS.toUByte(), onValues, offValues) }

Slide 100

Slide 100 text

• The CValuesRef is designed to support C array literals without explicit native memory allocation. • Construct the immutable self-contained sequence of C values: • ${type}Array.toCValues(), where type is the Kotlin primitive type • cValuesOf(vararg elements: ${type}), where type is a primitive or pointer • Array?>.toCValues(), List?>.toCValues() Source: https://github.com/JetBrains/kotlin-native/blob/master/INTEROP.md 100 Oh Wait, Simpler Solution!

Slide 101

Slide 101 text

Set PWM On/Off values (2/2) val onValues = UIntArray(_PCA9685_CHANS) for (i in 0 until _PCA9685_CHANS - 1) { onValues[i] = SERVO_ON_ANGLE.toUInt() } val offValues = UIntArray(_PCA9685_CHANS) for (i in 0 until _PCA9685_CHANS - 1) { offValues[i] = SERVO_OFF_ANGLE.toUInt() } PCA9685_setPWMVals(fileDescriptor, I2C_SERVO_ADDRESS.toUByte(), onValues.toCValues(), offValues.toCValues() )

Slide 102

Slide 102 text

Step 4: Capture Image with Pi Camera

Slide 103

Slide 103 text

Understand raspicam • 4 Applications are provided: raspistill, raspivid, raspiyuv and raspividyuv • Using MMAL (Multi-Media Abstraction Layer) API which runs over OpenMAX* • No really simple C API as I wanted *OpenMAX: non-proprietary and royalty-free cross-platform set of C-language programming interfaces Source: https://www.raspberrypi.org/documentation/usage/camera/raspicam/ 103

Slide 104

Slide 104 text

• POSIX bindings to the rescue • Execute command line from your Kotlin/Native application Source: https://kotlinlang.org/docs/reference/native/platform_libs.html 104 Reinvent the wheel? Nope.

Slide 105

Slide 105 text

Code platform.posix.system("raspistill -t 2000 -o photo.jpg")

Slide 106

Slide 106 text

Run TensorFlow With Kotlin/Native (on raspberry pi?!)

Slide 107

Slide 107 text

• TensorFlow for C is supported on: • Linux, 64-bit, x86 • MacOS X, Version 10.12.6 (Sierra) or higher • Windows, 64-bit x86 • No official C library for Raspberry Pi Source: https://www.tensorflow.org/install/lang_c 107 TensorFlow for C

Slide 108

Slide 108 text

KEEP CALM AND BUILD TENSORFLOW FROM SOURCE

Slide 109

Slide 109 text

No content

Slide 110

Slide 110 text

No documentation ¯\_(ツ)_/¯ Unofficial binaries https://github.com/PINTO0309/Tensorflow-bin *“The behavior is unconfirmed because I do not have C language implementation skills.” Source: https://github.com/PINTO0309/Tensorflow-bin 110 TensorFlow for C

Slide 111

Slide 111 text

Demo: Kotlin/Native on Raspberry Pi in action

Slide 112

Slide 112 text

No content

Slide 113

Slide 113 text

No content

Slide 114

Slide 114 text

No content

Slide 115

Slide 115 text

Conclusion ☕

Slide 116

Slide 116 text

• ⚠ Experimental ⚠ • Tip of the iceberg • Debugging is hard • Fine tuning on the sampling rate is needed • C and cross compilation knowledges are essential • It was fun exploring! 116 What I learned so far

Slide 117

Slide 117 text

• Software is getting incredibly complex and interfacing between languages is increasingly important • Gain low-level control without giving up high-level conveniences • The Openness of Kotlin/Native (for Web Assembly even) 117 Why?

Slide 118

Slide 118 text

• Both using LLVM as a backend • Different memory management systems • Kotlin/Native: automated, reference counter with a cycle collector • Rust: manual, with smart pointers • Maturity level 118 Kotlin/Native v.s. Rust?

Slide 119

Slide 119 text

• Talks: • KotlinConf 2018 - Live Coding Kotlin/Native Snake by Dmitry Kandalov • KotlinConf 2018 - Making Noise with Kotlin Native by Josh Skeen • Articles: •Kotlin on Raspberry Pi •Raspberry Pi Starter Kit and Kotlin/Native •Raspberry Pi GPIO with Kotlin Native •Int ptr in Kotlin/Native 119 References

Slide 120

Slide 120 text

Github: https://github.com/jinqian/kotlin-native-chifoumi

Slide 121

Slide 121 text

#KotlinConf THANK YOU AND REMEMBER TO VOTE Qian Jin @bonbonking