diff --git a/deeplens/extern/cache.py b/deeplens/extern/cache.py index 7413e80..b0f1528 100644 --- a/deeplens/extern/cache.py +++ b/deeplens/extern/cache.py @@ -38,7 +38,7 @@ def delete_cache(file): def persist(vstream, file): shape = _array_shape(vstream) - fp = np.memmap(file, dtype='uint8', mode='w+', shape=shape,order='F') + fp = np.memmap(file, dtype='uint8', mode='w+', shape=shape,order='C') #only works for files, not derived stuff vstream.cap = None diff --git a/diagnostics_dante/aggregate_csv.py b/diagnostics_dante/aggregate_csv.py new file mode 100644 index 0000000..53a8783 --- /dev/null +++ b/diagnostics_dante/aggregate_csv.py @@ -0,0 +1,38 @@ +import pandas as pd + +def aggregate_csv(path_to_csv): + df = pd.read_csv(path_to_csv) + df = df.groupby(['Shape','Size']).agg({'File Size': ['min', 'median', 'max'], 'Storage Time': ['min', 'median', 'max'], 'Retrieval Time': ['min', 'median', 'max'], \ + "Storage CPU Median": ['median'], "Storage CPU Max": ['max'], "Storage RAM Median": ['median'], "Storage RAM Max": ['max'], \ + "Storage Read Count Median": ['median'], "Storage Read Count Max": ['max'], "Storage Write Count Median": ['median'], "Storage Write Count Max": ['max'], \ + "Storage Read Bytes Median": ['median'], "Storage Read Bytes Max": ['max'], "Storage Write Bytes Median": ['median'], "Storage Write Bytes Max": ['max'], \ + "Retrieval CPU Median": ['median'], "Retrieval CPU Max": ['max'], "Retrieval RAM Median": ['median'], "Retrieval RAM Max": ['max'], \ + "Retrieval Read Count Median": ['median'], "Retrieval Read Count Max": ['max'], "Retrieval Write Count Median": ['median'], "Retrieval Write Count Max": ['max'], \ + "Retrieval Read Bytes Median": ['median'], "Retrieval Read Bytes Max": ['max'], "Retrieval Write Bytes Median": ['median'], "Retrieval Write Bytes Max": ['max']}) + df.reset_index(inplace=True) + df.columns = df.columns.get_level_values(0) + df.columns = ['Shape', 'Size', 'File Size Min', 'File Size Median', 'File Size Max', 'Storage Time Min', 'Storage Time Median', 'Storage Time Max', 'Retrieval Time Min', 'Retrieval Time Median', 'Retrieval Time Max', \ + "Storage CPU Median", "Storage CPU Max", "Storage RAM Median", "Storage RAM Max", \ + "Storage Read Count Median", "Storage Read Count Max", "Storage Write Count Median", "Storage Write Count Max", \ + "Storage Read Bytes Median", "Storage Read Bytes Max", "Storage Write Bytes Median", "Storage Write Bytes Max", \ + "Retrieval CPU Median", "Retrieval CPU Max", "Retrieval RAM Median", "Retrieval RAM Max", \ + "Retrieval Read Count Median", "Retrieval Read Count Max", "Retrieval Write Count Median", "Retrieval Write Count Max", \ + "Retrieval Read Bytes Median", "Retrieval Read Bytes Max", "Retrieval Write Bytes Median", "Retrieval Write Bytes Max"] + + df = df.sort_values(by='Size') + df['Size'] = df['Size'].apply(lambda x: human_format(x)) + + path_to_agg_csv = path_to_csv[:-4] + "_agg.csv" + df.to_csv(path_to_agg_csv, index=False) + return path_to_agg_csv + +def human_format(num): + num = float('{:.3g}'.format(num)) + magnitude = 0 + while abs(num) >= 1000: + magnitude += 1 + num /= 1000.0 + return '{}{}'.format('{:f}'.format(num).rstrip('0').rstrip('.'), ['', 'K', 'M', 'B', 'T'][magnitude]) + +# Test +#aggregate_csv("results/diagnostics.csv") \ No newline at end of file diff --git a/diagnostics_dante/autoencoder.py b/diagnostics_dante/autoencoder.py new file mode 100644 index 0000000..518fbbe --- /dev/null +++ b/diagnostics_dante/autoencoder.py @@ -0,0 +1,73 @@ +import tensorflow.keras.layers +import tensorflow.keras.models +import tensorflow.keras.optimizers +import tensorflow.keras.datasets +import numpy +import matplotlib.pyplot + +# Encoder +x = tensorflow.keras.layers.Input(shape=(784), name="encoder_input") + +encoder_dense_layer1 = tensorflow.keras.layers.Dense(units=300, name="encoder_dense_1")(x) +encoder_activ_layer1 = tensorflow.keras.layers.LeakyReLU(name="encoder_leakyrelu_1")(encoder_dense_layer1) + +encoder_dense_layer2 = tensorflow.keras.layers.Dense(units=2, name="encoder_dense_2")(encoder_activ_layer1) +encoder_output = tensorflow.keras.layers.LeakyReLU(name="encoder_output")(encoder_dense_layer2) + +encoder = tensorflow.keras.models.Model(x, encoder_output, name="encoder_model") +encoder.summary() + +# Decoder +decoder_input = tensorflow.keras.layers.Input(shape=(2), name="decoder_input") + +decoder_dense_layer1 = tensorflow.keras.layers.Dense(units=300, name="decoder_dense_1")(decoder_input) +decoder_activ_layer1 = tensorflow.keras.layers.LeakyReLU(name="decoder_leakyrelu_1")(decoder_dense_layer1) + +decoder_dense_layer2 = tensorflow.keras.layers.Dense(units=784, name="decoder_dense_2")(decoder_activ_layer1) +decoder_output = tensorflow.keras.layers.LeakyReLU(name="decoder_output")(decoder_dense_layer2) + +decoder = tensorflow.keras.models.Model(decoder_input, decoder_output, name="decoder_model") +decoder.summary() + +# Autoencoder +ae_input = tensorflow.keras.layers.Input(shape=(784), name="AE_input") +ae_encoder_output = encoder(ae_input) +ae_decoder_output = decoder(ae_encoder_output) + +ae = tensorflow.keras.models.Model(ae_input, ae_decoder_output, name="AE") +ae.summary() + +# RMSE +def rmse(y_true, y_predict): + return tensorflow.keras.backend.mean(tensorflow.keras.backend.square(y_true-y_predict)) + +# AE Compilation +ae.compile(loss="mse", optimizer=tensorflow.keras.optimizers.Adam(lr=0.0005)) + +# Preparing MNIST Dataset +(x_train_orig, y_train), (x_test_orig, y_test) = tensorflow.keras.datasets.mnist.load_data() +x_train_orig = x_train_orig.astype("float32") / 255.0 +x_test_orig = x_test_orig.astype("float32") / 255.0 + +x_train = numpy.reshape(x_train_orig, newshape=(x_train_orig.shape[0], numpy.prod(x_train_orig.shape[1:]))) +x_test = numpy.reshape(x_test_orig, newshape=(x_test_orig.shape[0], numpy.prod(x_test_orig.shape[1:]))) + +# Training AE +ae.fit(x_train, x_train, epochs=20, batch_size=256, shuffle=True, validation_data=(x_test, x_test)) + +encoded_images = encoder.predict(x_train) +decoded_images = decoder.predict(encoded_images) +decoded_images_orig = numpy.reshape(decoded_images, newshape=(decoded_images.shape[0], 28, 28)) + +num_images_to_show = 5 +for im_ind in range(num_images_to_show): + plot_ind = im_ind*2 + 1 + rand_ind = numpy.random.randint(low=0, high=x_train.shape[0]) + matplotlib.pyplot.subplot(num_images_to_show, 2, plot_ind) + matplotlib.pyplot.imshow(x_train_orig[rand_ind, :, :], cmap="gray") + matplotlib.pyplot.subplot(num_images_to_show, 2, plot_ind+1) + matplotlib.pyplot.imshow(decoded_images_orig[rand_ind, :, :], cmap="gray") + +matplotlib.pyplot.figure() +matplotlib.pyplot.scatter(encoded_images[:, 0], encoded_images[:, 1], c=y_train) +matplotlib.pyplot.colorbar() \ No newline at end of file diff --git a/diagnostics_dante/compare_diagnostics.py b/diagnostics_dante/compare_diagnostics.py new file mode 100644 index 0000000..31dda28 --- /dev/null +++ b/diagnostics_dante/compare_diagnostics.py @@ -0,0 +1,46 @@ +import os +import pandas as pd +import matplotlib.pyplot as plt + +def graph_compare(path_to_many_results, shapes): + os.mkdir('comparison_results') + results = [] + for dirpath, dirnames, filenames in os.walk(path_to_many_results): + for fname in filenames: + if fname == "diagnostics_agg.csv": + agg_path = dirpath + '/' + fname + name = dirpath.replace(path_to_many_results + '/', '').replace('/results','') + results.append((name, agg_path)) + + dict_data_by_shapes = {} + for shape in shapes: + key = f"{shape[0]}:{shape[1]}" + dict_data_by_shapes[key] = [] + + for result in results: + name = result[0] + dfo = pd.read_csv(result[1]) + dfo['Total Time'] = dfo.apply(lambda x: x['Retrieval Time Median'] + x['Storage Time Median'], axis=1) + for shape, df in dfo.groupby('Shape'): + sizes = df['Size'].tolist() + # change to be for every col + data = df["Retrieval Write Count Median"].tolist() + dict_data_by_shapes[shape].append((name, sizes, data)) + + for shape in dict_data_by_shapes: + fig = plt.figure(figsize = (10, 5)) + results = dict_data_by_shapes[shape] + for result in results: + plt.plot(result[1], result[2], label=result[0]) + plt.xlabel('Frame Size (pixels)') + plt.ylabel("Storage Read Count Median") + plt.title(f'"Storage Read Count Median" of {shape} results') + plt.legend() + plt.savefig(f"comparison_results/{shape}_retrievalwritecount.png") + + + + + +# Test +#graph_compare("../../Results Usage", [(16,9)]) \ No newline at end of file diff --git a/diagnostics_dante/diagnostic.py b/diagnostics_dante/diagnostic.py new file mode 100644 index 0000000..40ae9d8 --- /dev/null +++ b/diagnostics_dante/diagnostic.py @@ -0,0 +1,173 @@ +import os +import sys +import inspect +import tfci +import tensorflow.compat.v1 as tf +import gzip + +# Is there a better way? +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) + +from deeplens.full_manager.condition import Condition +from deeplens.full_manager.full_video_processing import CropSplitter +from deeplens.tracking.background import FixedCameraBGFGSegmenter +from deeplens.optimizer.deeplens import DeepLensOptimizer + +from deeplens.struct import * +from deeplens.utils import * +from deeplens.dataflow.map import * +from deeplens.full_manager.full_manager import * +from deeplens.utils.testing_utils import * +from deeplens.dataflow.agg import * +from deeplens.tracking.contour import * +from deeplens.tracking.event import * +from deeplens.core import * +from deeplens.simple_manager.manager import * + +from deeplens.utils.ui import play + +from deeplens.extern.cache import persist +from deeplens.struct import RawVideoStream + +sys.path.insert(0,currentdir) + +import time +import os +import numpy as np +import psutil +from multiprocessing import Process, Value, Manager +from statistics import median +import shutil + +def getResourceUsage(done, mlist): + cpu_usage = [] + ram_usage = [] + read_count = [] + write_count = [] + read_bytes = [] + write_bytes = [] + while done.value: + cpu_usage.append(psutil.cpu_percent()) + ram_usage.append(psutil.virtual_memory().percent) + disk_tuple = psutil.disk_io_counters() + read_count.append(disk_tuple[0]) + write_count.append(disk_tuple[1]) + read_bytes.append(disk_tuple[2]) + write_bytes.append(disk_tuple[3]) + time.sleep(1) + mlist.append(cpu_usage) + mlist.append(ram_usage) + mlist.append(read_count) + mlist.append(write_count) + mlist.append(read_bytes) + mlist.append(write_bytes) + + +def diagnostic(video_path, size): + os.system("sudo sync; echo 1 | sudo tee /proc/sys/vm/drop_caches >/dev/null") + file_size = None + time_storage = None + cpu_storage = None + ram_storage = None + read_count_storage = None + write_count_storage = None + read_bytes_storage = None + write_bytes_storage = None + time_retrieve = None + cpu_retrieve = None + ram_retrieve = None + read_count_retrieve = None + write_count_retrieve = None + read_bytes_retrieve = None + write_bytes_retrieve = None + + FILENAME = video_path #the video file that you want to load + LIMIT = 100 + + vstream = VideoStream(FILENAME, limit=LIMIT) #limit is the max number of frames + + vstream = vstream[Crop(0, 0, size[0], size[1])] + + manager = Manager() + mlist = manager.list() + done = Value('i', 1) + resource = Process(target=getResourceUsage, args=(done, mlist)) + resource.start() + + t0 = time.time() + + os.mkdir('cache') + for i, v in enumerate(vstream): + f = gzip.GzipFile(f"cache/{i}.tfci", "w") + np.save(file=f, arr=v) + f.close() + #tfci.compress('mbt2018-mean-msssim-8', v['data'], f"cache/{i}.tfci") + v['data'] = None + + cache = persist(vstream, '/dev/shm/cache.npz') + + done.value -= 1 + resource.join() + cpu_storage = mlist[0] + ram_storage = mlist[1] + read_count_storage = mlist[2] + write_count_storage = mlist[3] + read_bytes_storage = mlist[4] + write_bytes_storage = mlist[5] + + manager = Manager() + mlist = manager.list() + done = Value('i', 1) + resource = Process(target=getResourceUsage, args=(done, mlist)) + resource.start() + + t1 = time.time() + + vstream = RawVideoStream('/dev/shm/cache.npz', shape=(LIMIT,size[1],size[0],3)) #retrieving the data (have to provide dimensions (num frames, w, h, channels) + + for i, v in enumerate(vstream): + f = gzip.GzipFile(f"cache/{i}.tfci", "w") + np.load(f) + f.close() + v['data'] = tfci.decompress(f"cache/{i}.tfci") + + #do something + for v in vstream: + np.copy(v['data'], order='C') + pass + + t2 = time.time() + + done.value -= 1 + resource.join() + cpu_retrieve = mlist[0] + ram_retrieve = mlist[1] + read_count_retrieve = mlist[2] + write_count_retrieve = mlist[3] + read_bytes_retrieve = mlist[4] + write_bytes_retrieve = mlist[5] + + time_storage = t1 - t0 + time_retrieve = t2 - t1 + + total_size = 0 + for root, dirs, files in os.walk("cache"): + for f in files: + total_size += os.path.getsize(os.path.join(root, f)) + file_size = total_size + + shutil.rmtree("cache") + + return (file_size, time_storage, time_retrieve, \ + median(cpu_storage), max(cpu_storage), median(ram_storage), max(ram_storage), \ + median(read_count_storage), max(read_count_storage), median(write_count_storage), max(write_count_storage), \ + median(read_bytes_storage), max(read_bytes_storage), median(write_bytes_storage), max(write_bytes_storage), \ + median(cpu_retrieve), max(cpu_retrieve), median(ram_retrieve), max(ram_retrieve), \ + median(read_count_retrieve), max(read_count_retrieve), median(write_count_retrieve), max(write_count_retrieve), \ + median(read_bytes_retrieve), max(read_bytes_retrieve), median(write_bytes_retrieve), max(write_bytes_retrieve), \ + ) + +# Test +#print(diagnostic('../tcam.mp4', (1080, 1080))) \ No newline at end of file diff --git a/diagnostics_dante/generate_videos.py b/diagnostics_dante/generate_videos.py new file mode 100644 index 0000000..57660f8 --- /dev/null +++ b/diagnostics_dante/generate_videos.py @@ -0,0 +1,26 @@ +import os +import math + +def generate_videos(video_width, video_height, shapes, max_pixels, min_pixels, reducing_factor): + dictionary_of_video_sizes = {} + reducing_factor = 1/reducing_factor + for shape in shapes: + height_temp = video_height + width_temp = video_width + key = f"{shape[0]}:{shape[1]}" + dictionary_of_video_sizes[key] = [] + height_temp = math.ceil((shape[1] / shape[0]) * video_width) + if height_temp > video_height: + height_temp = video_height + width_temp = math.ceil((shape[0] / shape[1]) * video_height) + dictionary_of_video_sizes[key].append((width_temp, height_temp)) + while width_temp * height_temp > min_pixels: + height_temp = math.ceil(height_temp * math.sqrt(reducing_factor)) + width_temp = math.ceil(width_temp * math.sqrt(reducing_factor)) + dictionary_of_video_sizes[key].append((width_temp, height_temp)) + dictionary_of_video_sizes['16:9'] = list(reversed(dictionary_of_video_sizes['16:9'])) + return dictionary_of_video_sizes + +# Test +#Dict = generate_videos(1920, 1080, [(16,9), (1,1), (1,20), (20,1), (2,3)], 1000000000000, 30000, 2) +#print(Dict) diff --git a/diagnostics_dante/graph_diagnostics.py b/diagnostics_dante/graph_diagnostics.py new file mode 100644 index 0000000..28bb739 --- /dev/null +++ b/diagnostics_dante/graph_diagnostics.py @@ -0,0 +1,88 @@ +import os +import pandas as pd +from matplotlib import pyplot as plt +from aggregate_csv import human_format + +def graph_diagnostics(path_to_csv, path_to_agg_csv): + os.mkdir('results/graphs') + os.mkdir('results/graphs/spread') + os.mkdir('results/graphs/file_size') + os.mkdir('results/graphs/total_time') + + dfo = pd.read_csv(path_to_csv) + for shape, dfi in dfo.groupby('Shape'): + storage_time = [] + retrieval_time = [] + sizes = [] + + for size, df in dfi.groupby('Size'): + sizes.append(human_format(size)) + storage_time.append(df['Storage Time'].tolist()) + retrieval_time.append(df['Retrieval Time'].tolist()) + + fig, ax = plt.subplots() + ax.set_title(f"{shape} Storage Time") + ax.boxplot(storage_time, labels=sizes) + plt.xlabel("Size (pixels)") + plt.ylabel("Time (seconds)") + plt.savefig(f"results/graphs/spread/{shape}_storagetime.png") + fig.clf() + + fig, ax = plt.subplots() + ax.set_title(f"{shape} Retrieval Time") + ax.boxplot(retrieval_time, labels=sizes) + plt.xlabel("Size (pixels)") + plt.ylabel("Time (seconds)") + plt.savefig(f"results/graphs/spread/{shape}_retrievaltime.png") + fig.clf() + + dfa = pd.read_csv(path_to_agg_csv) + dfa['Shape'] = dfa['Shape'].apply(lambda x: sum(map(ord, x)) + ord(x[0])) + + fig = plt.figure(figsize = (10, 5)) + norm = plt.Normalize(dfa['Shape'].min(), dfa['Shape'].max()) + cmap = plt.get_cmap("magma") + plt.bar(dfa['Size'], height=dfa['File Size Median'], color=cmap(norm(dfa['Shape'].values))) + plt.xlabel("Video Size (pixels)") + plt.ylabel("Cache size (bytes)") + plt.title(f"File Size") + plt.savefig(f"results/graphs/file_size/filesize.png") + fig.clf() + + fig = plt.figure(figsize = (10, 5)) + norm = plt.Normalize(dfa['Shape'].min(), dfa['Shape'].max()) + cmap = plt.get_cmap("magma") + p1 = plt.bar(dfa['Size'], height=dfa['Storage Time Median'], color=cmap(norm(dfa['Shape'].values))) + p2 = plt.bar(dfa['Size'], height=dfa['Retrieval Time Median'], bottom=dfa['Storage Time Median']) + plt.xlabel("Video Size (pixels)") + plt.ylabel("Total Time (seconds)") + plt.title(f"Total Time") + plt.savefig(f"results/graphs/total_time/totaltime.png") + fig.clf() + + dfa = pd.read_csv(path_to_agg_csv) + for shape, df in dfa.groupby('Shape'): + df = df.reset_index() + + fig = plt.figure(figsize = (10, 5)) + plt.bar(df['Size'], height=df['File Size Median']) + plt.xlabel("Video Size (pixels)") + plt.ylabel("Cache size (bytes)") + plt.title(f"{shape} File Size") + plt.savefig(f"results/graphs/file_size/{shape}_filesize.png") + fig.clf() + + fig = plt.figure(figsize = (10, 5)) + p1 = plt.bar(df['Size'], height=df['Storage Time Median']) + p2 = plt.bar(df['Size'], height=df['Retrieval Time Median'], bottom=df['Storage Time Median']) + plt.xlabel("Video Size (pixels)") + plt.ylabel("Total Time (seconds)") + plt.title(f"{shape} Total Time") + plt.savefig(f"results/graphs/total_time/{shape}_totaltime.png") + fig.clf() + + path_to_graphs = 'results/graphs' # A folder of graphs + return path_to_graphs + +# Test +#graph_diagnostics("results/diagnostics.csv", "results/diagnostics_agg.csv") \ No newline at end of file diff --git a/diagnostics_dante/main.py b/diagnostics_dante/main.py new file mode 100644 index 0000000..672278e --- /dev/null +++ b/diagnostics_dante/main.py @@ -0,0 +1,28 @@ +from generate_videos import generate_videos +from test_videos import test_videos +from aggregate_csv import aggregate_csv +from graph_diagnostics import graph_diagnostics + +video_path = '4KFootage.mkv' +video_width = 3840 +video_height = 2160 +number_of_trials = 1 + +shapes = [(16,9)] # An array of aspect ratio tuples (width, height) + +# These may be replaced by default (8m to 30k reducing by a factor of two) +max_pixels = 80000000 # The max number of pixels per frame (approx) +min_pixels = 30000 # The min number of pixels per frame (approx) +reducing_factor = 2 # Number of pixels in frame reduced by this factor from max_pixels to min_pixels + +# Generate videos +dictionary_of_video_sizes = generate_videos(video_width, video_height, shapes, max_pixels, min_pixels, reducing_factor) + +# Test videos creating csv of results +path_to_csv = test_videos(video_path, dictionary_of_video_sizes, number_of_trials) + +# Aggregate csv by shape and size (min, med, max) +path_to_agg_csv = aggregate_csv(path_to_csv) + +# Graph aggregate csv and put results in new folder +path_to_graphs = graph_diagnostics(path_to_csv, path_to_agg_csv) diff --git a/diagnostics_dante/test_videos.py b/diagnostics_dante/test_videos.py new file mode 100644 index 0000000..4f8382b --- /dev/null +++ b/diagnostics_dante/test_videos.py @@ -0,0 +1,66 @@ +import os +from diagnostic import diagnostic + +def test_videos(video_path, dictionary_of_video_sizes, number_of_trials): + os.mkdir('results') + path_to_csv = "results/diagnostics.csv" + + import csv + with open(path_to_csv, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(["Shape", "Size", "Trial #", "File Size", "Storage Time", "Retrieval Time", \ + "Storage CPU Median", "Storage CPU Max", "Storage RAM Median", "Storage RAM Max", \ + "Storage Read Count Median", "Storage Read Count Max", "Storage Write Count Median", "Storage Write Count Max", \ + "Storage Read Bytes Median", "Storage Read Bytes Max", "Storage Write Bytes Median", "Storage Write Bytes Max", \ + "Retrieval CPU Median", "Retrieval CPU Max", "Retrieval RAM Median", "Retrieval RAM Max", \ + "Retrieval Read Count Median", "Retrieval Read Count Max", "Retrieval Write Count Median", "Retrieval Write Count Max", \ + "Retrieval Read Bytes Median", "Retrieval Read Bytes Max", "Retrieval Write Bytes Median", "Retrieval Write Bytes Max" \ + ]) + + print(dictionary_of_video_sizes) + for shape, sizes in dictionary_of_video_sizes.items(): + for trial_number in range(number_of_trials): + for size in sizes: + info = diagnostic(video_path, size) + file_size = info[0] + time_storage = info[1] + time_retreive = info[2] + + cpu_storage_median = info[3] + cpu_storage_max = info[4] + ram_storage_median = info[5] + ram_storage_max = info[6] + read_count_storage_median = info[7] + read_count_storage_max = info[8] + write_count_storage_median = info[9] + write_count_storage_max = info[10] + read_bytes_storage_median = info[11] + read_bytes_storage_max = info[12] + write_bytes_storage_median = info[13] + write_bytes_storage_max = info[14] + + cpu_retrieval_median = info[15] + cpu_retrieval_max = info[16] + ram_retrieval_median = info[17] + ram_retrieval_max = info[18] + read_count_retrieval_median = info[19] + read_count_retrieval_max = info[20] + write_count_retrieval_median = info[21] + write_count_retrieval_max = info[22] + read_bytes_retrieval_median = info[23] + read_bytes_retrieval_max = info[24] + write_bytes_retrieval_median = info[25] + write_bytes_retrieval_max = info[26] + + with open(path_to_csv, 'a', newline='') as file: + writer = csv.writer(file) + writer.writerow([shape, size[0]*size[1], trial_number, file_size, time_storage, time_retreive, \ + cpu_storage_median, cpu_storage_max, ram_storage_median, ram_storage_max, \ + read_count_storage_median, read_count_storage_max, write_count_storage_median, write_count_storage_max, \ + read_bytes_storage_median, read_bytes_storage_max, write_bytes_storage_median, write_bytes_storage_max, \ + cpu_retrieval_median, cpu_retrieval_max, ram_retrieval_median, ram_retrieval_max, \ + read_count_retrieval_median, read_count_retrieval_max, write_count_retrieval_median, write_count_retrieval_max, \ + read_bytes_retrieval_median, read_bytes_retrieval_max, write_bytes_retrieval_median, write_bytes_retrieval_max, \ + ]) + + return path_to_csv diff --git a/diagnostics_dante/tfci.py b/diagnostics_dante/tfci.py new file mode 100644 index 0000000..db46a07 --- /dev/null +++ b/diagnostics_dante/tfci.py @@ -0,0 +1,160 @@ +import argparse +import os +import sys +import urllib + +from absl import app +from absl.flags import argparse_flags +import tensorflow.compat.v1 as tf + +import tensorflow_compression as tfc # pylint:disable=unused-import + +# Default URL to fetch metagraphs from. +URL_PREFIX = "https://storage.googleapis.com/tensorflow_compression/metagraphs" +# Default location to store cached metagraphs. +METAGRAPH_CACHE = "/tmp/tfc_metagraphs" + +def write_array(image): + """Creates graph to write a PNG image file.""" + image = tf.squeeze(image, 0) + if image.dtype.is_floating: + image = tf.round(image) + if image.dtype != tf.uint8: + image = tf.saturate_cast(image, tf.uint8) + # string = tf.image.encode_png(image) + return image + + +def load_cached(filename): + """Downloads and caches files from web storage.""" + pathname = os.path.join(METAGRAPH_CACHE, filename) + try: + with tf.io.gfile.GFile(pathname, "rb") as f: + string = f.read() + except tf.errors.NotFoundError: + url = URL_PREFIX + "/" + filename + try: + request = urllib.request.urlopen(url) + string = request.read() + finally: + request.close() + tf.io.gfile.makedirs(os.path.dirname(pathname)) + with tf.io.gfile.GFile(pathname, "wb") as f: + f.write(string) + return string + + +def import_metagraph(model): + """Imports a trained model metagraph into the current graph.""" + string = load_cached(model + ".metagraph") + metagraph = tf.MetaGraphDef() + metagraph.ParseFromString(string) + tf.train.import_meta_graph(metagraph) + return metagraph.signature_def + + +def instantiate_signature(signature_def): + """Fetches tensors defined in a signature from the graph.""" + graph = tf.get_default_graph() + inputs = { + k: graph.get_tensor_by_name(v.name) + for k, v in signature_def.inputs.items() + } + outputs = { + k: graph.get_tensor_by_name(v.name) + for k, v in signature_def.outputs.items() + } + return inputs, outputs + + +def compress_image(model, input_image): + """Compresses an image array into a bitstring.""" + with tf.Graph().as_default(): + # Load model metagraph. + signature_defs = import_metagraph(model) + inputs, outputs = instantiate_signature(signature_defs["sender"]) + + # Just one input tensor. + inputs = inputs["input_image"] + # Multiple output tensors, ordered alphabetically, without names. + outputs = [outputs[k] for k in sorted(outputs) if k.startswith("channel:")] + + # Run encoder. + with tf.Session() as sess: + arrays = sess.run(outputs, feed_dict={inputs: input_image}) + + # Pack data into bitstring. + packed = tfc.PackedTensors() + packed.model = model + packed.pack(outputs, arrays) + return packed.string + + +def compress(model, input_array, output_file, target_bpp=None, bpp_strict=False): + # Load image. + with tf.Graph().as_default(): + with tf.Session() as sess: + input_image = sess.run(tf.expand_dims(input_array, 0)) + num_pixels = input_image.shape[-2] * input_image.shape[-3] + + if not target_bpp: + # Just compress with a specific model. + bitstring = compress_image(model, input_image) + else: + # Get model list. + models = load_cached(model + ".models") + models = models.decode("ascii").split() + + # Do a binary search over all RD points. + lower = -1 + upper = len(models) + bpp = None + best_bitstring = None + best_bpp = None + while bpp != target_bpp and upper - lower > 1: + i = (upper + lower) // 2 + bitstring = compress_image(models[i], input_image) + bpp = 8 * len(bitstring) / num_pixels + is_admissible = bpp <= target_bpp or not bpp_strict + is_better = (best_bpp is None or + abs(bpp - target_bpp) < abs(best_bpp - target_bpp)) + if is_admissible and is_better: + best_bitstring = bitstring + best_bpp = bpp + if bpp < target_bpp: + lower = i + if bpp > target_bpp: + upper = i + if best_bpp is None: + assert bpp_strict + raise RuntimeError( + "Could not compress image to less than {} bpp.".format(target_bpp)) + bitstring = best_bitstring + + # Write bitstring to disk. + with tf.io.gfile.GFile(output_file, "wb") as f: + f.write(bitstring) + + +def decompress(input_file): + with tf.Graph().as_default(): + # Unserialize packed data from disk. + with tf.io.gfile.GFile(input_file, "rb") as f: + packed = tfc.PackedTensors(f.read()) + + # Load model metagraph. + signature_defs = import_metagraph(packed.model) + inputs, outputs = instantiate_signature(signature_defs["receiver"]) + + # Multiple input tensors, ordered alphabetically, without names. + inputs = [inputs[k] for k in sorted(inputs) if k.startswith("channel:")] + # Just one output operation. + outputs = write_array(outputs["output_image"]) + + # Unpack data. + arrays = packed.unpack(inputs) + + # Run decoder. + with tf.Session() as sess: + sess.run(outputs, feed_dict=dict(zip(inputs, arrays))) + return outputs \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 564dd8b..463fc62 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -numpy==1.17.2 +numpy==1.19.1 opencv-python==4.1.1.26 absl-py==0.8.0 astor==0.8.0 diff --git a/test_npz.py b/test_npz.py index 9ace197..71ae814 100644 --- a/test_npz.py +++ b/test_npz.py @@ -21,19 +21,36 @@ import cv2 import numpy as np +import time as t from deeplens.extern.cache import persist -FILENAME = '' #the video file that you want to load -vstream = VideoStream(FILENAME, limit=1000) #limit is the max number of frames +FILENAME = 'tcam.mp4' #the video file that you want to load +LIMIT = 100 +vstream = VideoStream(FILENAME, limit=LIMIT) #limit is the max number of frames + +t0 = t.time() size = persist(vstream, 'cache.npz') #how big the size of the stored raw video is +t1 = t.time() + from deeplens.struct import RawVideoStream -vstream = RawVideoStream('cache.npz', shape=(1000,1080,1920,3)) #retrieving the data (have to provide dimensions (num frames, w, h, channels) +vstream = RawVideoStream('cache.npz', shape=(LIMIT,1080,1920,3)) #retrieving the data (have to provide dimensions (num frames, w, h, channels) + #do something +f = 0 for v in vstream: + f += 1 + #print(f) pass +t2 = t.time() + +time_to_storage = t1 - t0 +time_to_retrieve = t2 - t1 +time_total = t2 - t0 + +print(f"Storage: {time_to_storage} + Retrieve: {time_to_retrieve} = Total: {time_total}") \ No newline at end of file