Online and Real-time Object Tracking Algorithm with Extremely Small Matrices
Jesmin Jahan Tithi Sriram Aananthakrishnan Fabrizio Petrini
cs.DC cs.LG stat.ML





Online and Real-time Object Tracking Algorithm with Extremely Small Matrices
    Jesmin Jahan Tithi1, Sriram
    Aananthakrishnan2 and Fabrizio
    Petrini1
  
    1Intel Parallel Computing Labs,
    2Intel Data Center Group
    

    Email: {jesmin.jahan.tithi,
    sriram.aananthakrishnan,
    fabrizio.petrini}@intel.com

    December 30, 2023
=======================================================================================================================================================================================================================================================




Online and Real-time Object Tracking is an interesting workload that can be used to track objects (e.g., car, human, animal) in a series of video sequences in real-time. For simple object tracking on edge devices, the output of object tracking could be as simple as drawing a bounding box around a detected object and in some cases, the input matrices used in such computation are quite small (e.g., 4x7, 3x3, 5x5, etc). As a result, the amount of actual work is low. Therefore, a typical multi-threading based parallelization technique can not accelerate the tracking application; instead, a throughput based parallelization technique where each thread operates on independent video sequences is more rewarding. In this paper, we share our experience in parallelizing a Simple Online and Real-time Tracking (SORT) application on shared-memory multicores.



Simple Online and Real-time Tracking (SORT), Object Tracking, Multiple Object Tracking, Hungarian Algorithm, Kalman Filtering, MOT, Assignment problem, Linear Assignment.




§ INTRODUCTION

Online and Real-time object tracking can be used to track objects in a series of video sequences in real-time and has applications in object detection systems such as autonomous vehicles, security cameras, other surveillance, and robotics. Because of the real-time and online nature of the task, it is often latency-sensitive. For simple object tracking (especially, on edge devices, mobile phones, cameras), the output could be as simple as drawing bounding boxes around the target objects. For this task, the input matrices are often very small and as a result, a typical multi-threading based parallelization technique to accelerate these applications is not scalable. In fact, a well-optimized serial code on a high-end x86 CPU would perform better than a multi-threaded code due to scheduling and sychronization overheads with multi-threading.

In this paper, we share our experience of parallelizing a Simple Online and Real-time Tracking (SORT) workload <cit.> for shared-memory multicores. The SORT <cit.> application was originally written in python and used many python libraries such as filterpy <cit.> and linear assignment <cit.> libraries, parallel matrix libraries and BLAS routines for matrix operations. We implemented a C version of it and our sequential C version is 44× to 100× faster than the parallel python code. We also parallelized the code using OpenMP and we shared our insights and lessons learned during that work which we found quite challenging. 

Our contributions in this paper are:


  * We present a very thorough analysis of the Simple Online and Real-time Tracking (SORT) workload including the runtime analysis of the original python code and our C code for SORT. 

  * We re-implement the SORT code in C which is over 44 to 100× times faster than the original parallel python implementation.

  * We parallelize the code using openMP and show scalability analysis using three different types of scaling methods: strong scaling, weak scaling, and throughput scaling and conclude that for this workload and with the type of dataset we used, weak-scaling or throughput scaling is more rewarding.
 



§ BACKGROUND


The main part of the SORT algorithm consists of a combination of the Kalman filter <cit.> and the Hungarian algorithm <cit.> (e.g, optimal cost assignment problem), to identify and track target objects in a video frame. SORT analyzes past and current frames and detects objects on the fly. The baseline code of SORT is written using 300 lines of Python code and relies on the  , , ,  libraries. 

The evaluation of SORT is done on the Multiple Object Tracking (MOT) benchmark <cit.> data set that has 11 input files. Table <ref> shows properties of the given dataset.







 §.§ Kalman Filtering

Kalman filtering <cit.> is an algorithm that uses a series of measurements observed over time, containing statistical noise to produce estimates of unknown variables that tend to be more accurate than those based on a single measurement alone, by estimating a joint probability distribution over the variables for each timeframe. Figure <ref> shows the workflow of a standard Kalman filter. The algorithm works in two steps: prediction and update. In the prediction step, the Kalman filter produces estimates of the current state variables x(k|k-1), along with their uncertainties P(k|k-1). Once the outcome of the next measurement z_k is observed (necessarily corrupted with some amount of error, including random noise), these estimates are updated (x(k|k),  P(k|k)) using a weighted average. It can run in real-time, using only the present input measurements, previously calculated state and a given uncertainty matrix; no additional past information is required. There is a sequential dependency in between the Kalman filter states across consecutive frames of a video sequence which limits parallelism. 





 §.§ Hungarian Algorithm

The Hungarian method<cit.> is a combinatorial optimization algorithm that solves the assignment problem in polynomial time. There are two ways to formulate the problem: as a matrix or as a bipartite graph. In SORT, the Hungarian algorithm is used in its matrix format. Given a nonnegative n × m matrix, where the element in the i-th row and j-th column represents the cost of assigning the j-th predicted object to the i-th measured object, the Hungarian algorithm finds an assignment of the prediction to the measurements, such that each prediction is assigned to one measured object and each measured object is assigned one prediction, and the total cost of the assignment is minimum. The algorithm works by subtracting the unique minimum element at each row and column and picking the unique [i, j] entry in a row and column with a 0 value and then assigns prediction j to measured object i. If there are multiple 0 in a row or column, the process repeats by subtracting a global minimum from all remaining entries. 



 §.§ Kalman Filter and Hungarian Algorithm in SORT

At a high-level, the Kalman Filter is used to predict the object locations in a video frame, and then the Hungarian algorithm is used to assign the prediction to the measured objects in the frame so that the matching score is maximized. Next, based on the assigned object, the status of the KalmanFilter gets updated and the process is repeated for the next frame. 



 §.§ Challenges

Internally, KalmanFiltering and Hungarian algorithms manipulate matrices. Kalman filter includes matrix multiplications, dot products, transpose, Inverse, Cholesky factorization and transcendental operations. The Hungarian algorithm involves row-wise/column-wise matrix operations and iterative scaling. Table <ref> shows a list of matrix kernels and the sizes of matrices used in SORT. Details about those matrices can be found in <cit.>.


The task of object detection in a video sequence is inherently sequential, i.e., we need to process the frames one after the other so that we can use the updated Kalman Filter from the prior frame. However, parallelism exists inside a single frame which varies with the number of objects on that frame. Although it is not challenging to parallelize KalmanFiltering using optimized matrix libraries (for multiplication, Inverse, Cholesky, transpose, dot product, etc), it becomes a challenge to get any runtime benefit, if the input and output matrices are very small. In fact, parallelization slows down the program. In this paper, we address the parallelization challenge of SORT on shared memory multicore architecture.



§ OBJECT TRACKING ALGORITHM

In this section, we give a high-level algorithmic explanation of the SORT workload. Algorithm <ref> shows a high level pseudocode for SORT. In case of online tracking, the input video sequence is streamed through the system and each video contains data for multiple frames. 
 
For a stream of video sequences, each frame data is read in a dense matrix of size N_R_f× N_s, where N_R_f denotes the number of observations (i.e., detected objects) available in the same frame and N_s denotes the number of sensor outputs. For each frame, it calls the update function 
(Line 5-9) which is the “only timed” function and takes around 78% to 80% of the total run time of SORT. 




Figure <ref> shows the pseudocode of the Update function. It first uses the existing Kalman Filter Trackers to predict potential objects' positions on the frame and stores them into a Trackers array, Trk. It then compresses the Trackers array by removing all rows with invalid data (if any). Next, it tries to assign (or match) the predicted objects with the actual objects on the frame using the Hungarian algorithm <cit.>. From this step, three lists are created: 1) matched predictions, 2) unmatched predictions and 3) unmatched detections on the frame. Next, the current Kalman filters' internal states associated with the matched predictions are updated using the assigned detections. For each unmatched object, a new Kalman Filter tracker is created using the unmatched object as a seed. Finally, it prepares the output from the matched detections and trackers and at the same time discards outdated trackers (if any). 


A simple timing model for SORT can be written as follows: T_frame = a  T_Prediction + b  T_Assignement + c  T_Update + d  T_Output prep + Trackers update, where, a, b, c and d are multiplicative parameters. 


§ WORKLOAD ANALYSIS

We use the server platform Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz, CPU 1800 MHz, with 25MB shared victim L3 cache codenamed Skylake (SKX) for our initial workload analysis on the entire application.  


While the SORT implementation is single-threaded, it uses internally multi-threaded libraries. Table <ref> shows values for performance counters while running the python program. The table shows a low Instructions per cycle (IPC) value, especially since this is an aggregated IPC over all threads (SKX has a peak IPC of 4 per core). The TLB and LLC Miss Per Kilo Instructions (MPKI) is low as well, revealing these components are not limiting performance. Memory bandwidth usage is very low, so the application is not memory bandwidth bound. Neither is it memory latency bound since the LLC MPKI is very low. We assume performance is limited by the high amount of time that is spent in system calls and thread synchronization. 
 

 
We used  to profile the Update function (Figure <ref>). About 30% of the time is spent in the prediction phase, 22.2% time is spent in the assignment phase (Hungarian algorithm) and 34.4% time is spent in the update function. The remaining part is spent in preparing the output array. The Kalman “predict” and “update” functions internally use a number of common matrix kernels as shown in Table <ref>. Python parallel BLAS and LAPPAC modules used to handle most of these matrix and vector operations. The Hungarian algorithm comes from the linear assignment python library.





§ OUR VERSION OF SORT

Our C program for SORT follows algorithmic steps of the original python code. We utilized open-source Kalman Filter <cit.> and Hungarian algorithm <cit.> implementations and optimized them as needed. Table <ref> shows a tabular representation of the algorithmic steps, arithmetic intensity (flops per byte) of each step and % of the time taken. Here, N_T_f= Number of trackers used for frame f. Table <ref> shows a summary of the performance of our code running on 1 core vs. the original code running on all cores of a given machine. Our sequential code obtains 45 to 106× speedup overall. Intel Vtune profiler shows that in C implementation, the matmul takes the most time which appears in predict and update functions of Kalman filter.






§ STRONG-, WEAK- AND THROUGHPUT-SCALING

In this paper, by strong-scaling, we mean parallelizing the task of processing a single video sequence. Since there is sequential dependency across frames in a video sequence in terms of states of the Kalman Filter, strong-scaling requires that the object detection inside a single frame is done in parallel and each frame is processed using p cores where p ∈ [1, 18, 36, 72]. 

In the case of weak-scaling, instead of parallelizing the object detection inside a single frame, parallelization happens across input files (entire video sequence). In weak-scaling, we use 1 core to process 1 video file independently. Thus, 11 video files are processed by 11 cores in parallel. This version should stop scaling after 11 cores. 

In the case of throughput scaling, we run p independent sequential SORT executables on p cores and each of those programs processes k independent video files in parallel, i.e., pk files in total. The difference between weak-scaling and throughput scaling is: weak-scaling runs 1 executable using p cores, and throughput-scaling runs p executables each using 1 core. In throughput scaling, each of the core gets a completely independent fraction of shared resources (cache, memory, bandwidth) whereas, for weak-scaling, threads can share common data and resources.




Since the single-core run takes an only fraction of a second, we expect not to see any benefit of strong scaling which was indeed the case. When we parallelized the code to process each frame with multiple OpenMP threads, the overhead of threading turned out to be larger than the benefit due to the limited parallelism. It slowed down the program instead of making it faster. Table <ref> shows impact of three different types of scaling on the SKX machine in terms of Frames Per Sec (FPS) processed. The best single-core FPS is 47k. The best FPS for OpenMP parallel code with strong scaling is 37k. In strong scaling, performance drops with the increase the in number of cores, because the matrices are too tiny to produce enough work. For throughput scaling, it was able to sustain 37k FPS as before. We replicated the input files 7 times and re-ran the weak and strong scaling on Intel(R) Xeon(R) Platinum 8280 CPU machine which is advanced than SKX. Figure <ref> shows the comparison result. This also shows that weak-scaling works better than strong scaling for SORT. 

 




§ CONCLUSION

 The Simple Online Real-time Tracking (SORT) is an interesting workload with much real-world significance. In this paper, we parallelize SORT using OpenMP and show that due to the nature of dataset (i.e., small matrices) weak-scaling or throughput scaling performs better than strong scaling. The conclusion might change if the dataset properties change. Our parallel implementation is more than 50× faster than its original implementation. We plan to make our code open source.

IEEEtran

