# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3 (ipykernel)
#     language: python
#     name: python3
# ---

# +
import cv2 
from openvino.inference_engine import IECore, StatusCode
import numpy as np

import matplotlib.pyplot as plt
import glob
import time
from tqdm.notebook import tqdm
# -

# ## Read Images

image_paths = glob.glob('data/images/cats_dogs/*')
image_paths

# ## 

# ## OpenVINO Inference

# Get SqueezeNet Labels
# https://github.com/runwayml/model-squeezenet/blob/master/labels.json
with open('data/sqNet_labels.txt','r') as f:
    labels_map = f.read()
    labels = eval(labels_map)
labels

# ### Prepare Model

# +
# Model Path
model_xml = "intel_models/squeezenet1.1.xml"
model_bin = "intel_models/squeezenet1.1.bin"

"""
After a few tests, setting device to GPU does not necessarily improve FPS
"""
# Device
device = 'GPU' # Options include CPU, GPU, MYRIAD, [HDDL or HETERO] I am not familiar with the last two


# +
def PrepareAsyncNetWork(model_xml,model_bin,device,num_requests):
    ie = IECore()
    net = ie.read_network(model = model_xml,weights = model_bin)

    ####################### Very Important $$$$
    # Check to make sure that the plugin has support for all layers in the model
    supported_layers = ie.query_network(net,device_name = device)
    unsupported_layers = [layer for layer in supported_layers.values() if layer!= device]
    if len(unsupported_layers)>0:
        raise Exception(f"Number of unsupported layers {len(unsupported_layers)}")
    ####################################################################################
    

    exec_net = ie.load_network(network=net,num_requests = num_requests, device_name = device)

    # Store name of input and output blobs
    input_blob = next(iter(net.input_info))
    output_blob = next(iter(net.outputs))
    
    # Extract Dimension (n:batch, c:color channel,h: height, w: width )
    n, c ,h ,w = net.input_info[input_blob].input_data.shape
    print('Extract Model Input Dimension:',n,c,h,w)
    
    return input_blob, output_blob, exec_net, (n,c,h,w)

def PrepareInputImages(input_paths):
    
    images = []
    
    for path in input_paths:
        
        image = cv2.imread(path)
        input_height,input_width = image.shape[:2]
    
        # Resize
        in_frame = cv2.resize(image,(w,h))
        in_frame = in_frame.transpose((2,0,1)) # Moving color channels to head
        in_frame = in_frame.reshape((n,c,h,w))
        
        images.append(in_frame)
        
        
    return images
# -

num_requests = len(image_paths)
input_blob, output_blob, execution_network,dimensions = PrepareAsyncNetWork(model_xml,
                                                                            model_bin,
                                                                            device,
                                                                            num_requests=num_requests)
n,c,h,w = dimensions
frames = PrepareInputImages(image_paths)


def MakeAsyncPrediction(execution_network, input_blob,output_blob, inference_frames):
    results = []
    
    st_time = time.time()
    
    for idx,frame in enumerate(inference_frames):
        infer_request_handle = execution_network.start_async(request_id=idx, inputs={input_blob: frame})
        infer_status = infer_request_handle.wait()
        res = infer_request_handle.output_blobs[output_blob]
        res = res.buffer
        
        results.append(res)
    
    
    ed_time = time.time()
    time_sp = ed_time-st_time
    FPS = np.round((len(inference_frames)/time_sp),4)
    
    print(f"FPS: {FPS}")
        
    return FPS, results

FPS_records = []
for _ in tqdm(range(100)):
    FPS,results = MakeAsyncPrediction(execution_network,input_blob,output_blob,frames)
    FPS_records.append(FPS)

np.mean(FPS_records)

StarcoderdataJupyterScriptsDedupFiltered