%% Running an Embedded Application on the NVIDIA Jetson TX2 Developer Kit
% This example shows how to generate CUDA(R) code from a SeriesNetwork object
% and target the NVIDIA(R) TX2 board with an external camera. This example
% uses the AlexNet deep learning network to classify images from a USB
% webcam video stream. 
%
%   Copyright 2017 The MathWorks, Inc.
%% Prerequisites
% * Deep Learning Toolbox(TM) to load the SeriesNetwork object.
% * GPU Coder(TM) for generating CUDA code.
% * GPU Coder Interface for Deep Learning Libraries support package. To install
% this support package, use the <matlab:matlab.addons.supportpackage.internal.explorer.showSupportPackages('GPU_DEEPLEARNING_LIB','tripwire') Add-On Explorer>.
% * NVIDIA Jetson TX2 developer kit.
% * USB camera to connect to the TX2.
% * NVIDIA CUDA toolkit installed on the TX2.
% * NVIDIA cuDNN 5.0 library installed on the TX2.
% * OpenCV 3.3.0 libraries for video read and image display operations
% installed on the TX2.
% * OpenCV header and library files must be in the NVCC compiler search
% path of the TX2.
% * Environment variables for the compilers and libraries. For information 
% on the supported versions of the compilers and libraries, see 
% <docid:gpucoder_gs#mw_aa8b0a39-45ea-4295-b244-52d6e6907bff
% Third-party Products>. For setting up the environment variables, see 
% <docid:gpucoder_gs#mw_453fbbd7-fd08-44a8-9113-a132ed383275
% Environment Variables>.
% * This example is supported on the Linux(R) platform only.

%% Verify the GPU Environment for Target Hardware
% Use the <docid:gpucoder_ref#mw_0957d820-192f-400a-8045-0bb746a75278 coder.checkGpuInstall> function
% and verify that the compilers and libraries needed for running this example
% are set up correctly.
coder.checkGpuInstall('tx2','quiet');

%% Get the Pretrained SeriesNetwork
% AlexNet contains 25 layers including convolution, fully connected and the
% classification output layers.
net = getAlexnet();
net.Layers

%% Generate Code for the SeriesNetwork
% Generate code for the TX2 platform.

cfg = coder.gpuConfig('lib');
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
cfg.GenerateReport = true;
cfg.TargetLang = 'C++';
cfg.Toolchain = 'NVIDIA CUDA for Jetson Tegra X2 | gmake (64-bit Linux)';
cfg.HardwareImplementation.TargetHWDeviceType = 'Generic->Custom';

codegen -config cfg -args {ones(227,227,3,'single'), coder.Constant('alexnet.mat')} alexnet_test.m

%% Generated Code Description
% 
% The generated code is compiled into a static library alexnet_test.a. The 
% generated code includes code for entry-point design file, network
% classes, and binary weight files containing the network coefficients.


dir(fullfile('codegen', 'lib', 'alexnet_test'))
%% Main File 
% The custom main file creates and sets up the network object with 
% layers and weights. It uses the OpenCV |VideoCapture| method to 
% read frames from a camera connected to the TX2. 
% Each frame is processed and classified, 
% until no more frames are to be read.

edit(fullfile(matlabroot,'examples','deeplearning_shared','main', 'main_webcam.cu'));

%% Copy Files to the Codegen Folder

% Copy the files required for the executable.

copyfile('create_exe.mk', fullfile('codegen', 'lib', 'alexnet_test', 'create_exe.mk'));
copyfile('synsetWords.txt', fullfile('codegen', 'lib', 'alexnet_test', 'synsetWords.txt'));
copyfile('main_webcam.cu', fullfile('codegen', 'lib', 'alexnet_test', 'main_webcam.cu'));

%% Build and Run on Target Hardware
% Copy the contents of codegen folder to a location on the TX2.
%
%   scp -r ./codegen/lib/alexnet_test username@jetson-tx2-name:/path/to/desired/location
%
% On the TX2, navigate to the copied codegen folder and execute the
% following commands.
%
%   sudo ~/jetson_clocks.sh
%
% The jetson_clocks.sh script is used to boost TX2 performance.
%% 
% Run |make| to generate an executable using the main file, the static library alexnet_test.a, and OpenCV libraries.
%%
%   make -f create_exe.mk
% 
% Run the executable on the TX2 platform with a device number for your webcam.
%
%   ./alexnet_exe 1
%
% This command displays a live video feed from the webcam accompanied by the
% AlexNet predictions of the current image. Press escape at any time to
% quit.
%% AlexNet Classification Output on TX2
% <<../gpucoderdemo_jetson_tx2_alexnet_screenshot.png>>
