From df02efef61047c18818c8663cd57b53bc71c9cac Mon Sep 17 00:00:00 2001 From: ZZWHU <1306328198@qq.com> Date: Thu, 26 Aug 2021 00:49:57 -0700 Subject: [PATCH 1/5] change the malloc of odla_trt --- ODLA/platforms/tensorrt/odla_tensorrt.cc | 84 +++++++++++++++++++----- 1 file changed, 67 insertions(+), 17 deletions(-) diff --git a/ODLA/platforms/tensorrt/odla_tensorrt.cc b/ODLA/platforms/tensorrt/odla_tensorrt.cc index d1c9ada4a..8231906f4 100644 --- a/ODLA/platforms/tensorrt/odla_tensorrt.cc +++ b/ODLA/platforms/tensorrt/odla_tensorrt.cc @@ -20,8 +20,11 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -31,10 +34,12 @@ #include #include #include +#include #include "plugins/initPlugin.h" using namespace nvinfer1; +using namespace std; #if !defined(ODLA_VERSION_NUMBER) || (ODLA_VERSION_NUMBER < 50) #error This library requires minimum ODLA version 0.5 @@ -173,8 +178,7 @@ struct _odla_computation { network = builder->createNetworkV2(flags); #endif } - } - + } ~_odla_computation() { if (!load_engine_mode) { builder->destroy(); @@ -189,6 +193,8 @@ struct _odla_context { odla_computation comp = nullptr; nvinfer1::ICudaEngine* engine = nullptr; nvinfer1::IExecutionContext* ctx = nullptr; + void* temp_input_ptr = nullptr; + void* temp_output_ptr = nullptr; #if NV_TENSORRT_MAJOR >= 7 nvinfer1::IBuilderConfig* builder_cfg = nullptr; nvinfer1::IOptimizationProfile* builder_profile = nullptr; @@ -210,6 +216,7 @@ struct _odla_context { std::unordered_map input_ptrs; int run_batch_size = 0; + // CUdeviceptr cumemalloc_address; _odla_context(odla_computation comp) : comp(comp) { if (!comp->load_engine_mode) { #if NV_TENSORRT_MAJOR < 7 @@ -238,7 +245,6 @@ struct _odla_context { builder_cfg->addOptimizationProfile(builder_profile); } builder_cfg->setMaxWorkspaceSize(comp->max_workspace_size); - if (comp->fp16_mode) { builder_cfg->setFlag(BuilderFlag::kFP16); builder_cfg->setFlag(BuilderFlag::kSTRICT_TYPES); @@ -509,13 +515,18 @@ odla_status odla_SetContextItem(odla_context context, odla_item_type type, switch (type) { case ODLA_RUN_BATCH_SIZE: context->run_batch_size = *(reinterpret_cast(value)); + // odla_value_shape real_shape = value->type.shape; + // size_t bytes = + // GetTotalElements(real_shape) * GetElementSize(value->type.element_type); + // CUdeviceptr dev_ptr; + // CHECK(cuMemAlloc(&dev_ptr, bytes)); + // context->cumemalloc_address = dev_ptr; break; default: std::cerr << "Unsupported property type: " << type << std::endl; return ODLA_FAILURE; } - return ODLA_SUCCESS; } @@ -534,7 +545,15 @@ odla_value odla_CreateArgument(odla_value_type type, const odla_value_id id) { auto input = g_comp->network->addInput(name, GetNVDataType(type.element_type), GetNVDims(type.shape)); odla_value v = CreateValue(input, type, id); - g_comp->inputs[name] = v; + g_comp->inputs[name] = v; //inputs[input] = v + // odla_value_shape real_shape = v->type.shape; + // std::cerr << "odla_value_shape:" << real_shape << "\n"; + // size_t bytes = + // GetTotalElements(real_shape) * GetTotalElements(v->type.element_type); + // CHECK(cudaMalloc(&dev_ptr, bytes)); + // void* validated_data_ptr = + // ValidateValuePtr(value->type, const_cast(data_ptr)); + // // CHECK(cudaMemcpy(dev_ptr, )) g_comp->input_vals.push_back(v); return v; } @@ -576,7 +595,7 @@ odla_status odla_SetValueAsOutput(const odla_value val) { val->tensor->setName(name); g_comp->network->markOutput(*val->tensor); return ODLA_SUCCESS; -} +} odla_status odla_GetNumOfOutputsFromComputation( const odla_computation computation, odla_uint32* num_outputs) { *num_outputs = computation->output_vals.size(); @@ -594,8 +613,11 @@ odla_status odla_GetOutputFromComputationByIdx( return ODLA_SUCCESS; } +//这里 每运行一个batch都会运行 odla_status odla_BindToArgument(odla_value value, const odla_void* data_ptr, odla_context context) { + // CUdeviceptr dev_ptr; + clock_t startTime, endTime; void* dev_ptr = nullptr; odla_value_shape real_shape = value->type.shape; if ((g_comp && g_comp->is_dynamic_batch) || context->run_batch_size) { @@ -603,13 +625,31 @@ odla_status odla_BindToArgument(odla_value value, const odla_void* data_ptr, } size_t bytes = GetTotalElements(real_shape) * GetElementSize(value->type.element_type); - CHECK(cudaMalloc(&dev_ptr, bytes)); + // CHECK(cuMemAlloc(&dev_ptr, bytes)); + // CHECK(cudaMalloc(&dev_ptr, bytes)); + // 在这里检测一下有没有预先cudamalloc过,如果有过,将数据传到对应地址 + // CUdeviceptr dev_ptr = context->cumemalloc_addres; + // std::cerr << "context->temp_input_ptr:" << context->temp_input_ptr << "\n"; + if (context->temp_input_ptr == nullptr) { + CHECK(cudaMalloc(&(context->temp_input_ptr), bytes)); + } + dev_ptr = context->temp_input_ptr; void* validated_data_ptr = ValidateValuePtr(value->type, const_cast(data_ptr)); + // void* pagelocked_buffer = context->input_ptrs[value->name].host_ptr; + // startTime = clock(); + // CHECK(cuMemcpyHtoD(dev_ptr, validated_data_ptr, bytes)); CHECK(cudaMemcpy(dev_ptr, validated_data_ptr, bytes, cudaMemcpyHostToDevice)); - + // endTime = clock(); + // std::cout << "the run time is:" << (double) (endTime - startTime) /CLOCKS_PER_SEC << "s" << std::endl; + // std::ofstream outf; + // outf.open("odla_cudamemcpy_times.txt", std::ios::app); + // outf << (double) (endTime - startTime) /CLOCKS_PER_SEC << std::endl; + // outf.close(); + // void* dev1_ptr; + // dev1_ptr = (void*) dev_ptr; + // CHECK(cudaMemcpy(dev_ptr, validated_data_ptr, bytes, cudaMemcpyHostToDevice)); context->input_ptrs[value->name] = {.host_ptr = data_ptr, .dev_ptr = dev_ptr}; - return ODLA_SUCCESS; } @@ -623,6 +663,7 @@ odla_status odla_BindToArgumentById(const odla_value_id value_id, odla_status odla_BindToOutput(odla_value value, odla_void* data_ptr, odla_context context) { + // CUdeviceptr dst; void* dst = nullptr; odla_value_shape real_shape = value->type.shape; if ((g_comp && g_comp->is_dynamic_batch) || context->run_batch_size) { @@ -630,8 +671,11 @@ odla_status odla_BindToOutput(odla_value value, odla_void* data_ptr, } size_t bytes = GetTotalElements(real_shape) * GetElementSize(value->type.element_type); - - CHECK(cudaMalloc(&dst, bytes)); + if (context->temp_output_ptr == nullptr){ + CHECK(cudaMalloc(&(context->temp_output_ptr), bytes)); + } + dst = context->temp_output_ptr; + // CHECK(cudaMalloc(&dst, bytes)); context->output_ptrs[value->name] = { .host_ptr = data_ptr, .dev_ptr = dst, .len = bytes, .vt = value->type}; @@ -852,6 +896,9 @@ odla_status odla_GetValueType(const odla_value value, odla_status odla_ExecuteComputation(odla_computation comp, odla_context context, odla_compute_mode mode, odla_device device) { + + // clock_t startTime, endTime; + std::vector buffers; auto add_to_buffer = [&](const std::string& name, void* ptr) { int idx = context->engine->getBindingIndex(name.c_str()); @@ -863,9 +910,14 @@ odla_status odla_ExecuteComputation(odla_computation comp, odla_context context, } }; for (auto& kv : context->input_ptrs) { - add_to_buffer(kv.first, kv.second.dev_ptr); + // void* kv_second_devptr; + // kv_second_devptr = (void*) kv.second.dev_ptr; + add_to_buffer(kv.first, kv.second.dev_ptr); //kv.first: input, kv.second.dev_ptr: 0x7f7698600000 } for (auto& kv : context->output_ptrs) { + // void* kv_second_devptr; + // kv_second_devptr = (void*) kv.second.dev_ptr; + // add_to_buffer(kv.first, kv_second_devptr); add_to_buffer(kv.first, kv.second.dev_ptr); } if (comp->is_dynamic_batch) { @@ -894,12 +946,10 @@ odla_status odla_ExecuteComputation(odla_computation comp, odla_context context, cudaMemcpyDeviceToHost)); } } - // copy results and free temp buffers. - for (auto& ptr : buffers) { - CHECK(cudaFree(ptr)); - } - + // for (auto& ptr : buffers) { + // CHECK(cudaFree(ptr)); + // } context->input_ptrs.clear(); context->output_ptrs.clear(); return ODLA_SUCCESS; From 089ab815687550aa57e6535b5a27d58b523892a1 Mon Sep 17 00:00:00 2001 From: ZZWHU <1306328198@qq.com> Date: Thu, 26 Aug 2021 02:04:47 -0700 Subject: [PATCH 2/5] add native tensorrt test api --- models/env.src | 2 +- models/vision/common.py | 214 ++++++++++++++++++++++++ models/vision/invoke_halo.py | 160 +++++++++++++++--- models/vision/onnx2tensorrt.py | 288 ++++++++++++++++++++++++++++++++ models/vision/onnx_add_batch.py | 47 ++++++ 5 files changed, 683 insertions(+), 28 deletions(-) create mode 100644 models/vision/common.py create mode 100644 models/vision/onnx2tensorrt.py create mode 100644 models/vision/onnx_add_batch.py diff --git a/models/env.src b/models/env.src index a6fd510fd..45605e83c 100644 --- a/models/env.src +++ b/models/env.src @@ -2,7 +2,7 @@ export SRC_DIR=${PWD}/.. export BUILD_DIR=$SRC_DIR/build export MODELS_SRC=/models - +export MODELS_ROOT=/models export HALO_BIN=$BUILD_DIR/bin/halo export ODLA_INC=$SRC_DIR/ODLA/include export ODLA_LIB=$BUILD_DIR/lib diff --git a/models/vision/common.py b/models/vision/common.py new file mode 100644 index 000000000..bed24df5e --- /dev/null +++ b/models/vision/common.py @@ -0,0 +1,214 @@ +# +# Copyright 1993-2020 NVIDIA Corporation. All rights reserved. +# +# NOTICE TO LICENSEE: +# +# This source code and/or documentation ("Licensed Deliverables") are +# subject to NVIDIA intellectual property rights under U.S. and +# international Copyright laws. +# +# These Licensed Deliverables contained herein is PROPRIETARY and +# CONFIDENTIAL to NVIDIA and is being provided under the terms and +# conditions of a form of NVIDIA software license agreement by and +# between NVIDIA and Licensee ("License Agreement") or electronically +# accepted by Licensee. Notwithstanding any terms or conditions to +# the contrary in the License Agreement, reproduction or disclosure +# of the Licensed Deliverables to any third party without the express +# written consent of NVIDIA is prohibited. +# +# NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE +# LICENSE AGREEMENT, NVIDIA MAKES NO REPRESENTATION ABOUT THE +# SUITABILITY OF THESE LICENSED DELIVERABLES FOR ANY PURPOSE. IT IS +# PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. +# NVIDIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THESE LICENSED +# DELIVERABLES, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, +# NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. +# NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE +# LICENSE AGREEMENT, IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY +# SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THESE LICENSED DELIVERABLES. +# +# U.S. Government End Users. These Licensed Deliverables are a +# "commercial item" as that term is defined at 48 C.F.R. 2.101 (OCT +# 1995), consisting of "commercial computer software" and "commercial +# computer software documentation" as such terms are used in 48 +# C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Government +# only as a commercial end item. Consistent with 48 C.F.R.12.212 and +# 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), all +# U.S. Government End Users acquire the Licensed Deliverables with +# only those rights set forth herein. +# +# Any use of the Licensed Deliverables in individual and commercial +# software must include, in the user documentation and internal +# comments to the code, the above Disclaimer and U.S. Government End +# Users Notice. +# + +from itertools import chain +import argparse +import os +import time +import pycuda.driver as cuda +import pycuda.autoinit +import numpy as np + +import tensorrt as trt + +try: + # Sometimes python2 does not understand FileNotFoundError + FileNotFoundError +except NameError: + FileNotFoundError = IOError + +EXPLICIT_BATCH = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) + +def GiB(val): + return val * 1 << 30 + + +def add_help(description): + parser = argparse.ArgumentParser(description=description, formatter_class=argparse.ArgumentDefaultsHelpFormatter) + args, _ = parser.parse_known_args() + + +def find_sample_data(description="Runs a TensorRT Python sample", subfolder="", find_files=[]): + ''' + Parses sample arguments. + + Args: + description (str): Description of the sample. + subfolder (str): The subfolder containing data relevant to this sample + find_files (str): A list of filenames to find. Each filename will be replaced with an absolute path. + + Returns: + str: Path of data directory. + ''' + + # Standard command-line arguments for all samples. + kDEFAULT_DATA_ROOT = os.path.join(os.sep, "usr", "src", "tensorrt", "data") + parser = argparse.ArgumentParser(description=description, formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument("-d", "--datadir", help="Location of the TensorRT sample data directory, and any additional data directories.", action="append", default=[kDEFAULT_DATA_ROOT]) + args, _ = parser.parse_known_args() + + def get_data_path(data_dir): + # If the subfolder exists, append it to the path, otherwise use the provided path as-is. + data_path = os.path.join(data_dir, subfolder) + if not os.path.exists(data_path): + print("WARNING: " + data_path + " does not exist. Trying " + data_dir + " instead.") + data_path = data_dir + # Make sure data directory exists. + if not (os.path.exists(data_path)): + print("WARNING: {:} does not exist. Please provide the correct data path with the -d option.".format(data_path)) + return data_path + + data_paths = [get_data_path(data_dir) for data_dir in args.datadir] + return data_paths, locate_files(data_paths, find_files) + +def locate_files(data_paths, filenames): + """ + Locates the specified files in the specified data directories. + If a file exists in multiple data directories, the first directory is used. + + Args: + data_paths (List[str]): The data directories. + filename (List[str]): The names of the files to find. + + Returns: + List[str]: The absolute paths of the files. + + Raises: + FileNotFoundError if a file could not be located. + """ + found_files = [None] * len(filenames) + for data_path in data_paths: + # Find all requested files. + for index, (found, filename) in enumerate(zip(found_files, filenames)): + if not found: + file_path = os.path.abspath(os.path.join(data_path, filename)) + if os.path.exists(file_path): + found_files[index] = file_path + + # Check that all files were found + for f, filename in zip(found_files, filenames): + if not f or not os.path.exists(f): + raise FileNotFoundError("Could not find {:}. Searched in data paths: {:}".format(filename, data_paths)) + return found_files + +# Simple helper data class that's a little nicer to use than a 2-tuple. +class HostDeviceMem(object): + def __init__(self, host_mem, device_mem): + self.host = host_mem + self.device = device_mem + + def __str__(self): + return "Host:\n" + str(self.host) + "\nDevice:\n" + str(self.device) + + def __repr__(self): + return self.__str__() + +# Allocates all buffers required for an engine, i.e. host/device inputs/outputs. +def allocate_buffers(engine): + inputs = [] + outputs = [] + bindings = [] + stream = cuda.Stream() + for binding in engine: + print("engine.get_binding_shape(binding):") + print(engine.get_binding_shape(binding)) + size = trt.volume(engine.get_binding_shape(binding)) * engine.max_batch_size #64*3*224*224 + dtype = trt.nptype(engine.get_binding_dtype(binding)) #float32 + # Allocate host and device buffers + host_mem = cuda.pagelocked_empty(size, dtype) # 申请主机显存 + device_mem = cuda.mem_alloc(host_mem.nbytes) # 申请cuda显存 + # Append the device buffer to device bindings. + bindings.append(int(device_mem)) + # Append to the appropriate list. + if engine.binding_is_input(binding): + inputs.append(HostDeviceMem(host_mem, device_mem)) + else: + outputs.append(HostDeviceMem(host_mem, device_mem)) + return inputs, outputs, bindings, stream + +# This function is generalized for multiple inputs/outputs. +# inputs and outputs are expected to be lists of HostDeviceMem objects. +def do_inference(context, bindings, inputs, outputs, stream, batch_size=1): + print(len(inputs))# Transfer input data to the GPU. + # for i,inp in enumerate(inputs): + # print(i) + # print(len(inp.host)) + [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs] + # Run inference. + context.execute_async(batch_size=batch_size, bindings=bindings, stream_handle=stream.handle) + # Transfer predictions back from the GPU. + [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs] + # Synchronize the stream + stream.synchronize() + # Return only the host outputs. + return [out.host for out in outputs] + +# This function is generalized for multiple inputs/outputs for full dimension networks. +# inputs and outputs are expected to be lists of HostDeviceMem objects. +def do_inference_v2(context, bindings, inputs, outputs, stream): + # Transfer input data to the GPU. + + [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs] + # Run inference. + context.execute_async_v2(bindings=bindings, stream_handle=stream.handle) + # Transfer predictions back from the GPU. + [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs] + # Synchronize the stream + stream.synchronize() + # Return only the host outputs. + return [out.host for out in outputs] + +def do_inference_v3(context, bindings, inputs, outputs, stream, batch_size=1): + [cuda.memcpy_htod(inp.device, inp.host) for inp in inputs] + start = time.time() + context.execute(batch_size=batch_size, bindings=bindings) + end = time.time() + [cuda.memcpy_dtoh(out.host, out.device) for out in outputs] + cost_time = end - start + return [out.host for out in outputs], cost_time \ No newline at end of file diff --git a/models/vision/invoke_halo.py b/models/vision/invoke_halo.py index f6ef3c9dd..11f635302 100755 --- a/models/vision/invoke_halo.py +++ b/models/vision/invoke_halo.py @@ -26,13 +26,16 @@ import numpy as np import shutil import argparse - +import time +import random # Check halo +random.seed(10) halo_exe = os.environ.get('HALO_BIN') halo_include = os.environ.get('ODLA_INC') halo_lib = os.environ.get('ODLA_LIB') halo_tmp = os.environ.get('TEST_TEMP_DIR') - +# CUDA_VISIBLE_DEVICES=2,3 +os.environ["CUDA_VISIBLE_DEVICES"]="1" if not os.path.exists(halo_exe): print("Invalid HALO executable path:({})".format(halo_exe)) exit(1) @@ -65,7 +68,7 @@ def compile(model_path, halo_flags): print('\n[Host Compiler] {} ==> {}'.format(cc_file, obj_file)) verify(subprocess.run( - ['g++', cc_file, debug, '-c', '-fPIC', '-o', obj_file, '-I' + halo_include])) + ['g++', cc_file, debug, '-c', '-fPIC', '-o', obj_file, '-I' + halo_include, '-I' + '/usr/local/cuda-10.0/include'])) return obj_file @@ -75,18 +78,22 @@ def link(obj, as_shared, odla): flags = '-shared' if as_shared else '' print('\n[Host Compiler] {} ==> {}'.format(obj, exe)) + # verify(subprocess.run(['g++', flags, obj, bin, + # '-lodla_' + odla, '-L', halo_lib, '-Wl,-rpath=' + halo_lib, '-o', exe])) verify(subprocess.run(['g++', flags, obj, bin, - '-lodla_' + odla, '-L', halo_lib, '-Wl,-rpath=' + halo_lib, '-o', exe])) + '-lodla_' + odla, '-L', halo_lib,'-lnvinfer', '-lcudart', '-Wl,-rpath=' + halo_lib, '-lcuda', '-o', exe])) + print("daozhele") return exe -def compile_with_halo(model_path, func_name, odla_lib, layout_to, input_shapes): +def compile_with_halo(model_path, func_name, odla_lib, layout_to, input_shapes, batch_size): halo_flags = [] halo_flags.append('-target') halo_flags.append('cxx') halo_flags.append('-disable-broadcasting') halo_flags.append('-entry-func-name=' + func_name) - halo_flags.append('-batch-size=1') + halo_flags.append('-batch-size=' + str(batch_size)) + # halo_flags.append('-d') for s in input_shapes: halo_flags.append('--input-shape=' + s) if odla_lib == 'xnnpack' or odla_lib == 'eigen': @@ -153,15 +160,17 @@ def preprocess_image_minus_128(img_data): parser.add_argument('--input_w', type=int, default=224) parser.add_argument('--input-shape', type=str, nargs='+', default=[]) parser.add_argument('--output_size', type=int, default=1000) - + parser.add_argument('--batch_size', type=int, default=1) + parser.add_argument('--random_iter_nums', type=int, default=100) args = parser.parse_args() model_file = [m.name for m in args.model] image_path = args.image_dir - + if args.odla != "tensorrt": + sys.exit(0) print('Using halo: {}'.format(halo_exe)) model_lib = compile_with_halo( - model_file, "model", args.odla, args.convert_layout_to, args.input_shape) + model_file, "model", args.odla, args.convert_layout_to, args.input_shape, args.batch_size) clsidx = [] if args.label_file: clsidx = args.label_file.readlines() @@ -171,35 +180,132 @@ def preprocess_image_minus_128(img_data): if not files: print("No images found in " + image_path) exit(1) - + + #暂时只用一张图片 + files = [image_path + '/dog.jpg'] c_lib = ctypes.CDLL(model_lib) res_info = [] + time_with_preprocess = [] + time_without_preprocess = [] ### preprocessing ### - for i, path in enumerate(files): - image = get_image_as_ndarray(path, args.input_h, args.input_w) - image = image.transpose([2, 0, 1]) # TO CHW - pp = 'preprocess_image' - if args.img_preprocess: - pp = pp + '_' + args.img_preprocess - pp_method = globals()[pp] - image = pp_method(image) - if args.convert_layout_to == 'nhwc': - image = image.transpose([1, 2, 0]) - image = image.flatten().astype(ctypes.c_float) - ret = (ctypes.c_float * args.output_size)() - c_lib.model(ctypes.c_void_p(image.ctypes.data), ret) + def data_iter(batch_size, features): + num_examples = len(features) + indices = list(range(num_examples)) + random.shuffle(indices) + for i in range(0, num_examples, batch_size): + j = np.array(indices[i: min(batch_size+i, num_examples)]) + result = [] + for idx in j: + result.append(features[idx]) + yield result + + def random_select_data_iter(batch_size, features, iter_nums): + for i in range(iter_nums): + result = random.choices(features, k=batch_size) + yield result + + for path in random_select_data_iter(args.batch_size, files, args.random_iter_nums): + start1 = time.time() + images = [] + batch_size = len(path) + for image in path: + image = get_image_as_ndarray(image, args.input_h, args.input_w) + image = image.transpose([2, 0, 1]) # TO CHW + pp = 'preprocess_image' + if args.img_preprocess: + pp = pp + '_' + args.img_preprocess + pp_method = globals()[pp] + image = pp_method(image) + if args.convert_layout_to == 'nhwc': + image = image.transpose([1, 2, 0]) + image = image.flatten().astype(ctypes.c_float) + image = np.expand_dims(image, axis=0) + images.append(image) + if batch_size != args.batch_size: + images.extend(np.zeros(image.shape)*(args.batch_size - args.batch_size)) + less_batch = args.batch_size - batch_size + images = np.array(images) + ret = (ctypes.c_float * args.output_size * args.batch_size)() + start2 = time.time() + # 从这里输入的如果在model中 + c_lib.model(ctypes.c_void_p(images.ctypes.data), ret) + # print(np.ctypeslib.as_array(images.ctypes.data)) 这是数据存储地址 + end2 = time.time() + time_without_preprocess.append(end2 - start2) ret = np.array(ret) - ind = ret.argsort()[-3:][::-1] if clsidx: - print(os.path.basename(path), '==>', clsidx[ind[0]].strip('\n')) - res_info.append(path.split('/')[-1] + ' ==> ' + clsidx[ind[0]]) + for i in range(len(path)): + ind = ret[i].argsort()[-3:][::-1] + # print(ind) + # print(os.path.basename(path[i]), '==>', clsidx[ind[0]].strip('\n')) + res_info.append(path[i].split('/')[-1] + ' ==> ' + clsidx[ind[0]]) else: print(ind) res_info.append(ind) + # print(res_info) + end1 = time.time() + time_with_preprocess.append(end1 - start1) + # print(ret) + + # for i, path in enumerate(files): + # start1 = time.time() + # image = get_image_as_ndarray(path, args.input_h, args.input_w) + # image = image.transpose([2, 0, 1]) # TO CHW + # pp = 'preprocess_image' + # if args.img_preprocess: + # pp = pp + '_' + args.img_preprocess + # pp_method = globals()[pp] + # image = pp_method(image) + # if args.convert_layout_to == 'nhwc': + # image = image.transpose([1, 2, 0]) + # image = image.flatten().astype(ctypes.c_float) + # image = np.expand_dims(image, axis=0) + # image_2 = np.concatenate([image, image], axis=0) + # ret = (ctypes.c_float * args.output_size*2)() + # start2 = time.time() + # c_lib.model(ctypes.c_void_p(image_2.ctypes.data), ret) + # end2 = time.time() + # time_without_preprocess.append(end2 - start2) + # ret = np.array(ret) + # print(ret) + # ind = ret.argsort()[-3:][::-1] + + # if clsidx: + # print(os.path.basename(path), '==>', clsidx[ind[0][0]].strip('\n')) + # res_info.append(path.split('/')[-1] + ' ==> ' + clsidx[ind[0][0]]) + # else: + # print(ind) + # res_info.append(ind) + # end1 = time.time() + # time_with_preprocess.append(end1 - start1) #resfile = os.path.splitext(os.path.basename(model_file[0]))[0] #resfile = resfile + '_' + args.odla + '.txt' #resfile = os.path.join('/tmp', resfile) #with open(resfile, 'w') as f: # f.write(''.join(str(i) for i in res_info)) - print("======== Testing Done ========") + # print("======== Testing Done ========") + # print(res_info) + # print("The time of reference without preprocessing is {}, and the time with prerprocessing is {}".format(time_without_preprocess, time_with_preprocess)) + # print(time_without_preprocess) + avg_image_time = sum(time_without_preprocess[2:])/(args.random_iter_nums*args.batch_size - args.batch_size*2)*1000 + print(args.model) + avg_batch_time = sum(time_without_preprocess[2:])/(args.random_iter_nums - 2)*1000 + print(avg_batch_time) + print(avg_image_time) + # print(time_without_preprocess[1:]) + std_batch_time = np.std(np.array(time_without_preprocess[2:]))*1000 + print(std_batch_time) + std_image_time = np.std(np.array([i/args.batch_size for i in time_without_preprocess[2:]]))*1000 + print(std_image_time) + # print([i*1000 for i in time_without_preprocess]) + # with open("vision/Plot/inceptionv3_odla_before_avg_std_result.txt", "a+") as f: + # f.write(str([avg_batch_time, std_batch_time, avg_image_time, std_image_time]) + '\n') + + + # with open("odla_tensorrt_times.txt", "r") as f: + # lines = f.readlines() + # time_per_iter = [float(line.split("\n")[0]) for line in lines] + # average_execute_time = sum(time_per_iter[-1*args.random_iter_nums + 1:])/(args.random_iter_nums*args.batch_size - args.batch_size) + # print(average_execute_time) + # print(sum(time_per_iter[-1*args.random_iter_nums + 1:])/(args.random_iter_nums - 1)) \ No newline at end of file diff --git a/models/vision/onnx2tensorrt.py b/models/vision/onnx2tensorrt.py new file mode 100644 index 000000000..2aee92f84 --- /dev/null +++ b/models/vision/onnx2tensorrt.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python3 + +import os +import sys +import ctypes +import random +import time +import warnings + +import numpy as np +import pycuda.autoinit +import tensorrt as trt +import pycuda.driver as cuda +import argparse +import glob +from PIL import Image +import common +import shutil +random.seed(10) +warnings.filterwarnings('ignore') +TRT_LOGGER = trt.Logger(trt.Logger.WARNING) +trt_runtime = trt.Runtime(TRT_LOGGER) +os.environ["CUDA_VISIBLE_DEVICES"]="2" + +def get_engine(onnx_file_path, engine_file_path): + """Attempts to load a serialized engine if available, otherwise builds a new TensorRT engine and saves it.""" + def build_engine(): + """Takes an ONNX file and creates a TensorRT engine to run inference with""" + builder = trt.Builder(TRT_LOGGER) + # if max_batch_size > 1: + builder.max_batch_size = 1 + + # builder.batchsize = batch_size + network = builder.create_network(common.EXPLICIT_BATCH) + config = builder.create_builder_config() + # print(config) + config.max_workspace_size = 1 << 28 + parser = trt.OnnxParser(network, TRT_LOGGER) + + # Parse model file + print('Loading ONNX file from path {}...'.format(onnx_file_path)) + with open(onnx_file_path, 'rb') as model: + # parser.parse(model.read()) + print('Beginning ONNX file parsing') + if not parser.parse(model.read()): + print('ERROR: Failed to parse the ONNX file.') + for error in range(parser.num_errors): + print(parser.get_error(error)) + return None + + # network.get_input(0).shape = shape + print('Completed parsing of ONNX file') + engine = builder.build_cuda_engine(network) + + with open(engine_file_path, "wb") as f: + f.write(engine.serialize()) + return engine + + if os.path.exists(engine_file_path): + # If a serialized engine exists, use it instead of building an engine. + print("Reading engine from file {}".format(engine_file_path)) + with open(engine_file_path, "rb") as f, trt.Runtime(TRT_LOGGER) as runtime: + return runtime.deserialize_cuda_engine(f.read()) + else: + return build_engine() + +def save_engine(engine, file_name): + buf = engine.serialize() + with open(file_name, 'wb') as f: + f.write(buf) + +def load_engine(trt_runtime, engine_path): + with open(engine_path,'rb') as f: + engine_data = f.read() + engine = trt_runtime.deserialize_cuda_engine(engine_data) + return engine + +def preprocess_image(img_data): + mean_vec = np.array([0.485, 0.456, 0.406]) + stddev_vec = np.array([0.229, 0.224, 0.225]) + norm_img_data = np.zeros(img_data.shape).astype('float32') + for i in range(img_data.shape[0]): + norm_img_data[i, :, :] = ( + img_data[i, :, :] / 255.0 - mean_vec[i]) / stddev_vec[i] + return norm_img_data + +def preprocess_image_minus_128(img_data): + #mean_vec = np.array([122.7717, 115.9465, 102.9801]) + mean_vec = np.array([128.0, 128.0, 128.0]) + norm_img_data = np.zeros(img_data.shape).astype('float32') + for i in range(img_data.shape[0]): + norm_img_data[i, :, :] = img_data[i, :, :] - mean_vec[i] + return norm_img_data + +# def load_normalized_test_case(test_image, pagelocked_buffer): +# # Converts the input image to a CHW Numpy array +# def normalize_image(image): +# # Resize, antialias and transpose the image to CHW. +# c, h, w = ModelData.INPUT_SHAPE +# image_arr = image.astype(trt.nptype(ModelData.DTYPE)).ravel() +# # This particular ResNet50 model requires some preprocessing, specifically, mean normalization. +# return (image_arr / 255.0 - 0.45) / 0.225 + +# # Normalize the image and copy to pagelocked memory. +# np.copyto(pagelocked_buffer, normalize_image(image)) +# return test_image + +def get_image_as_ndarray(path, dst_h, dst_w): + image = Image.open(path) + image = image.resize((dst_h, dst_w)) + mode = image.mode + image = np.array(image) # type uint8 + if mode != 'RGB': + print('Unsupported image mode {}'.format(mode)) + exit(1) + return image + +def data_iter(batch_size, features): + num_examples = len(features) + indices = list(range(num_examples)) + random.shuffle(indices) + for i in range(0, num_examples, batch_size): + j = np.array(indices[i: min(batch_size+i, num_examples)]) + result = [] + for idx in j: + result.append(features[idx]) + yield result + +def random_select_data_iter(batch_size, features, iter_nums): + for i in range(iter_nums): + result = random.choices(features, k=batch_size) + yield result + +# # 生成mode_data.h +# def generate_hfile(args): +# model_name = args.model.split("/")[-1].split(".")[0] +# input_size = "1*3*"+str(args.input_h)+"*"+str(args.input_w) +# output_size = str(args.output_size) +# hfile_name = model_name + '_data.h' +# with open(hfile_name, "w+"): +# f.write('static const float input_') + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--model', type=str) + parser.add_argument('--label-file', type=open, default='./classification/1000_labels.txt') + parser.add_argument('--image_dir', type=str, default='/models/vision/test_images') + # parser.add_argument('--odla', type=str) + parser.add_argument('--img-preprocess', type=str, default='') + parser.add_argument('--convert-layout-to', type=str) + parser.add_argument('--input_h', type=int, default=224) + parser.add_argument('--input_w', type=int, default=224) + parser.add_argument('--input-shape', type=str, nargs='+', default=[]) + parser.add_argument('--output_size', type=int, default=1000) + parser.add_argument('--batch_size', type=int, default=1) + parser.add_argument('--random_iter_nums', type=int, default=100) + args = parser.parse_args() + # model_file = [m.name for m in args.model] + # image_path = args.image_dir + + # engine = build(args.model, [1, 3, 224, 224]) + # context = engine.create_execution_context() + class ModelData(object): + if args.convert_layout_to == "nhwc": + INPUT_SHAPE = [args.batch_size, args.input_h, args.input_w, 3] + else: + INPUT_SHAPE = [args.batch_size, 3, args.input_h, args.input_w] + DTYPE = trt.float32 + input_shape = ModelData.INPUT_SHAPE + model = args.model + if args.batch_size > 1: + model = model.split(".")[-2] + "_bs" + str(args.batch_size) + ".onnx" + + engine_path = args.model.split("/")[-1].split(".")[0] + model_name = engine_path + engine_file_path = './tensorrt_files/'+engine_path+'_batch'+str(args.batch_size)+'.trt' + + engine = get_engine(model, engine_file_path) + + context = engine.create_execution_context() + input_output_file = './input_output/'+model_name + + isExists = os.path.exists(input_output_file) + if not isExists: + os.makedirs(input_output_file) + + image_path = args.image_dir + INPUT_SHAPE = ModelData.INPUT_SHAPE + DTYPE = trt.float32 + clsidx = [] + if args.label_file: + clsidx = args.label_file.readlines() + + files = sorted(glob.glob(image_path + '/*.jpg')) + + files = [image_path + '/dog.jpg'] + if not files: + print("No images found in " + image_path) + exit(1) + + inputs, outputs, bindings, stream = common.allocate_buffers(engine) + test_list = [] + result = [] + # 填充model_data.h 内容 + hfile_context = "" + label_result = [] + # for i, path in enumerate(files): + # input_filename = input_output_file + '/input_data_' + str(i) + '.txt' + # if args.convert_layout_to == 'nhwc': + # str_input_size = "[1 * "+str(args.input_h)+" * "+str(args.input_w)+" * 3]" + # else: + # str_input_size = "[1 * 3 * "+str(args.input_h)+" * "+str(args.input_w)+"]" + # input_class_context = "static const float input_"+str(i)+str_input_size+"= { \n#include \"input_data_"+str(i)+".txt\"\n};\n\n" + # hfile_context = hfile_context + input_class_context + for paths in random_select_data_iter(args.batch_size, files, args.random_iter_nums): + images = [] + images_batch = [] + # isExists = os.path.exists(input_filename) + # if isExists: + # image = np.loadtxt(input_filename) + # with open(input_filename, 'r') as f: + # data = f.read() + # data = data.split('\n') + # image = map(float, data) + # print(image) + for i, path in enumerate(paths): + image = get_image_as_ndarray(path, args.input_h, args.input_w) + image = image.transpose([2,0,1]) + pp = 'preprocess_image' + if args.img_preprocess: + pp = pp + '_' + args.img_preprocess + pp_method = globals()[pp] + image = pp_method(image) + if args.convert_layout_to == 'nhwc': + image = image.transpose([1, 2, 0]) + images.append(image) + image = image.flatten().astype(ctypes.c_float) + images = np.array(images) + if args.batch_size == 1: + images = images[0] + images = images.flatten().astype(ctypes.c_float) + pagelocked_buffer = inputs[0].host + # np.copyto(pagelocked_buffer, images) + np.copyto(pagelocked_buffer, images) + # image = load_normalized_test_case(image, inputs[0].host) + start = time.time() + trt_output, execute_cost_time = common.do_inference_v3(context, bindings=bindings, inputs=inputs, outputs=outputs, stream=stream)#, batch_size=args.batch_size) + end = time.time() + # output_filename = input_output_file + '/output_data_' + str(i) + '.txt' + # output_class_context = "static const float output_ref_"+str(i)+"["+str(args.output_size)+"] = { \n#include \"output_data_"+str(i)+".txt\"\n};\n\n" + # hfile_context = hfile_context + output_class_context + # hfile_context += "static float output_"+str(i)+"["+str(args.output_size)+"]; \n\n" + # with open(output_filename, "w+") as f: + # for j in trt_output[0]: + # f.write(str(j)+'\n') + cost_time = end - start + result.append(cost_time) + pred = [] + for i in range(args.batch_size): + # print(trt_output[0][i*args.output_size: (i+1)*args.output_size]) + pred.append(clsidx[np.argmax(trt_output[0][i*args.output_size: (i+1)*args.output_size])]) + # pred = clsidx[np.argmax(trt_output[0])] + label_result.append(pred) + # print(label_result) + # print(result) + print(engine_file_path) + # print(result) + avg_batch_time = sum(result[1:])/(args.random_iter_nums - 1)*1000 + print(avg_batch_time) + avg_image_time = sum(result[1:])/(args.random_iter_nums*args.batch_size - args.batch_size)*1000 + print(avg_image_time) + std_batch_time = np.std(np.array(result[1:]))*1000 + print(std_batch_time) + std_image_time = np.std(np.array([i/args.batch_size for i in result[1:]]))*1000 + print(std_image_time) + + # with open("Plot/inceptionv3_trt_avg_std_result.txt", "a+") as f: + # f.write(str([avg_batch_time, std_batch_time, avg_image_time, std_image_time]) + '\n') + + # print(label_result) + # with open("result.txt","a+") as f: + # f.write(engine_path+':'+" ".join(result)+"\n") + # # print(result) + # with open(input_output_file +"/"+engine_path + '_data.h', "w+") as f: + # f.write(hfile_context) + # pred = np.argmax(trt_outputs[0]) + # print(pred) + # print(clsidx[pred]) \ No newline at end of file diff --git a/models/vision/onnx_add_batch.py b/models/vision/onnx_add_batch.py new file mode 100644 index 000000000..5f205466b --- /dev/null +++ b/models/vision/onnx_add_batch.py @@ -0,0 +1,47 @@ +import torch +import torch.onnx +import sys +import onnx + +def change_input_dim(model, batch_size): + # The following code changes the first dimension of every input to be batch_size + # Modify as appropriate ... note that this requires all inputs to + # have the same batch_size + inputs = model.graph.input + # print(inputs[0]) + # print(inputs[0].type.tensor_type.shape.dim[0]) + for input in inputs: + # Checks omitted.This assumes that all inputs are tensors and have a shape with first dim. + # Add checks as needed. + dim1 = input.type.tensor_type.shape.dim[0] + # print(dim1) + # update dim to be a symbolic value + if isinstance(batch_size, str): + # set dynamic batch size + dim1.dim_param = batch_size + elif (isinstance(batch_size, str) and batch_size.isdigit()) or isinstance(batch_size, int): + # set given batch size + dim1.dim_value = int(batch_size) + else: + # set batch size of 1 + dim1.dim_value = 1 + + +def apply(transform, infile, outfile, batch_size): + model = onnx.load(infile) + transform(model, batch_size) + onnx.save(model, outfile) +if __name__ == "__main__": + name = sys.argv[1] + inputfile = name + '.onnx' + for i in range(1, 7): + bs = 2**i + outputfile = name + '_bs' + str(bs) + '.onnx' + apply(change_input_dim, inputfile, outputfile, bs) +# rebatch('resnet50-v2-7.onnx', 'resnet50-v2-7_bs4.onnx', '4') + # def read_onnx(model): + # model = onnx.load(model) + # graph = model.graph + # node = graph.node + # print(node[2469:2569]) + # read_onnx(inputfile) \ No newline at end of file From adb035aad7d73a570c27a368865968d3981ff542 Mon Sep 17 00:00:00 2001 From: ZZWHU <1306328198@qq.com> Date: Thu, 26 Aug 2021 05:42:38 -0700 Subject: [PATCH 3/5] run all tensorrt baseline --- models/vision/classification/1000_labels.txt | 1000 ----------------- .../classification/caffenet/run_caffenet.sh | 27 - .../caffenet/run_caffenet_onnx.sh | 26 - models/vision/classification/coco_classes.txt | 80 -- .../classification/densenet/run_densenet.sh | 5 +- .../densenet/run_densenet_tensorrt.sh | 29 + .../efficientnet/run_efficientnet.sh | 35 + .../efficientnet/run_efficientnet_tensorrt.sh | 28 + .../get_cls_model_from_pytorch.py | 15 - .../classification/googlenet/run_googlenet.sh | 5 +- .../googlenet/run_googlenet_tensorrt.sh | 30 + .../inception/run_inception_v1.sh | 5 +- .../inception/run_inception_v1_tensorrt.sh | 30 + .../inception/run_inception_v3.sh | 5 +- .../inception/run_inception_v3_tensorrt.sh | 31 + .../classification/mnist_simple/.gitignore | 2 - .../classification/mnist_simple/main.cc | 86 -- .../mnist_simple/mnist_simple.pb | Bin 31736 -> 0 bytes .../mnist_simple/mnist_simple.png | Bin 16558 -> 0 bytes .../mnist_simple/mnist_simple.svg | 1 - .../mnist_simple/run_mnist_simple.sh | 32 - .../mobilenet/run_mobilenet_v2.sh | 5 +- .../mobilenet/run_mobilenet_v2_tensorrt.sh | 30 + .../run_rcnn-ilsvrc13-9.sh} | 16 +- .../classification/rcnn/run_rcnn_tensorrt.sh | 28 + .../classification/resnet/run_resnet_v1_18.sh | 5 +- .../resnet/run_resnet_v1_18_tensorrt.sh | 38 + .../resnet/run_resnet_v2_101.sh | 5 +- .../resnet/run_resnet_v2_101_tensorrt.sh | 38 + .../classification/resnet/run_resnet_v2_50.sh | 5 +- .../resnet/run_resnet_v2_50_tensorrt.sh | 38 + .../shufflenet/run_shufflenet.sh | 5 +- .../shufflenet/run_shufflenet_tensorrt.sh | 38 + .../squeezenet/run_squeezenet_1_0.sh | 5 +- .../squeezenet/run_squeezenet_1_0_tensorrt.sh | 36 + .../squeezenet/run_squeezenet_1_1.sh | 9 +- .../squeezenet/run_squeezenet_1_1_tensorrt.sh | 32 + models/vision/classification/vgg/run_vgg16.sh | 5 +- .../classification/vgg/run_vgg16_tensorrt.sh | 38 + models/vision/classification/vgg/run_vgg19.sh | 5 +- .../classification/vgg/run_vgg19_tensorrt.sh | 38 + models/vision/classification/vgg/test.sh | 6 + models/vision/tensorrt_baseline_run_all.sh | 39 + 43 files changed, 645 insertions(+), 1291 deletions(-) delete mode 100644 models/vision/classification/1000_labels.txt delete mode 100755 models/vision/classification/caffenet/run_caffenet.sh delete mode 100755 models/vision/classification/caffenet/run_caffenet_onnx.sh delete mode 100644 models/vision/classification/coco_classes.txt create mode 100755 models/vision/classification/densenet/run_densenet_tensorrt.sh create mode 100755 models/vision/classification/efficientnet/run_efficientnet.sh create mode 100755 models/vision/classification/efficientnet/run_efficientnet_tensorrt.sh delete mode 100755 models/vision/classification/get_cls_model_from_pytorch.py create mode 100755 models/vision/classification/googlenet/run_googlenet_tensorrt.sh create mode 100755 models/vision/classification/inception/run_inception_v1_tensorrt.sh create mode 100755 models/vision/classification/inception/run_inception_v3_tensorrt.sh delete mode 100644 models/vision/classification/mnist_simple/.gitignore delete mode 100644 models/vision/classification/mnist_simple/main.cc delete mode 100644 models/vision/classification/mnist_simple/mnist_simple.pb delete mode 100644 models/vision/classification/mnist_simple/mnist_simple.png delete mode 100644 models/vision/classification/mnist_simple/mnist_simple.svg delete mode 100755 models/vision/classification/mnist_simple/run_mnist_simple.sh create mode 100755 models/vision/classification/mobilenet/run_mobilenet_v2_tensorrt.sh rename models/vision/classification/{alexnet/run_alexnet.sh => rcnn/run_rcnn-ilsvrc13-9.sh} (68%) create mode 100755 models/vision/classification/rcnn/run_rcnn_tensorrt.sh create mode 100755 models/vision/classification/resnet/run_resnet_v1_18_tensorrt.sh create mode 100755 models/vision/classification/resnet/run_resnet_v2_101_tensorrt.sh create mode 100755 models/vision/classification/resnet/run_resnet_v2_50_tensorrt.sh create mode 100755 models/vision/classification/shufflenet/run_shufflenet_tensorrt.sh create mode 100755 models/vision/classification/squeezenet/run_squeezenet_1_0_tensorrt.sh create mode 100755 models/vision/classification/squeezenet/run_squeezenet_1_1_tensorrt.sh create mode 100755 models/vision/classification/vgg/run_vgg16_tensorrt.sh create mode 100755 models/vision/classification/vgg/run_vgg19_tensorrt.sh create mode 100755 models/vision/classification/vgg/test.sh create mode 100644 models/vision/tensorrt_baseline_run_all.sh diff --git a/models/vision/classification/1000_labels.txt b/models/vision/classification/1000_labels.txt deleted file mode 100644 index 40b90699a..000000000 --- a/models/vision/classification/1000_labels.txt +++ /dev/null @@ -1,1000 +0,0 @@ -"tench, Tinca tinca", -"goldfish, Carassius auratus", -"great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias", -"tiger shark, Galeocerdo cuvieri", -"hammerhead, hammerhead shark", -"electric ray, crampfish, numbfish, torpedo", -"stingray", -"cock", -"hen", -"ostrich, Struthio camelus", -"brambling, Fringilla montifringilla", -"goldfinch, Carduelis carduelis", -"house finch, linnet, Carpodacus mexicanus", -"junco, snowbird", -"indigo bunting, indigo finch, indigo bird, Passerina cyanea", -"robin, American robin, Turdus migratorius", -"bulbul", -"jay", -"magpie", -"chickadee", -"water ouzel, dipper", -"kite", -"bald eagle, American eagle, Haliaeetus leucocephalus", -"vulture", -"great grey owl, great gray owl, Strix nebulosa", -"European fire salamander, Salamandra salamandra", -"common newt, Triturus vulgaris", -"eft", -"spotted salamander, Ambystoma maculatum", -"axolotl, mud puppy, Ambystoma mexicanum", -"bullfrog, Rana catesbeiana", -"tree frog, tree-frog", -"tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui", -"loggerhead, loggerhead turtle, Caretta caretta", -"leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea", -"mud turtle", -"terrapin", -"box turtle, box tortoise", -"banded gecko", -"common iguana, iguana, Iguana iguana", -"American chameleon, anole, Anolis carolinensis", -"whiptail, whiptail lizard", -"agama", -"frilled lizard, Chlamydosaurus kingi", -"alligator lizard", -"Gila monster, Heloderma suspectum", -"green lizard, Lacerta viridis", -"African chameleon, Chamaeleo chamaeleon", -"Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis", -"African crocodile, Nile crocodile, Crocodylus niloticus", -"American alligator, Alligator mississipiensis", -"triceratops", -"thunder snake, worm snake, Carphophis amoenus", -"ringneck snake, ring-necked snake, ring snake", -"hognose snake, puff adder, sand viper", -"green snake, grass snake", -"king snake, kingsnake", -"garter snake, grass snake", -"water snake", -"vine snake", -"night snake, Hypsiglena torquata", -"boa constrictor, Constrictor constrictor", -"rock python, rock snake, Python sebae", -"Indian cobra, Naja naja", -"green mamba", -"sea snake", -"horned viper, cerastes, sand viper, horned asp, Cerastes cornutus", -"diamondback, diamondback rattlesnake, Crotalus adamanteus", -"sidewinder, horned rattlesnake, Crotalus cerastes", -"trilobite", -"harvestman, daddy longlegs, Phalangium opilio", -"scorpion", -"black and gold garden spider, Argiope aurantia", -"barn spider, Araneus cavaticus", -"garden spider, Aranea diademata", -"black widow, Latrodectus mactans", -"tarantula", -"wolf spider, hunting spider", -"tick", -"centipede", -"black grouse", -"ptarmigan", -"ruffed grouse, partridge, Bonasa umbellus", -"prairie chicken, prairie grouse, prairie fowl", -"peacock", -"quail", -"partridge", -"African grey, African gray, Psittacus erithacus", -"macaw", -"sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita", -"lorikeet", -"coucal", -"bee eater", -"hornbill", -"hummingbird", -"jacamar", -"toucan", -"drake", -"red-breasted merganser, Mergus serrator", -"goose", -"black swan, Cygnus atratus", -"tusker", -"echidna, spiny anteater, anteater", -"platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus", -"wallaby, brush kangaroo", -"koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus", -"wombat", -"jellyfish", -"sea anemone, anemone", -"brain coral", -"flatworm, platyhelminth", -"nematode, nematode worm, roundworm", -"conch", -"snail", -"slug", -"sea slug, nudibranch", -"chiton, coat-of-mail shell, sea cradle, polyplacophore", -"chambered nautilus, pearly nautilus, nautilus", -"Dungeness crab, Cancer magister", -"rock crab, Cancer irroratus", -"fiddler crab", -"king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica", -"American lobster, Northern lobster, Maine lobster, Homarus americanus", -"spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish", -"crayfish, crawfish, crawdad, crawdaddy", -"hermit crab", -"isopod", -"white stork, Ciconia ciconia", -"black stork, Ciconia nigra", -"spoonbill", -"flamingo", -"little blue heron, Egretta caerulea", -"American egret, great white heron, Egretta albus", -"bittern", -"crane", -"limpkin, Aramus pictus", -"European gallinule, Porphyrio porphyrio", -"American coot, marsh hen, mud hen, water hen, Fulica americana", -"bustard", -"ruddy turnstone, Arenaria interpres", -"red-backed sandpiper, dunlin, Erolia alpina", -"redshank, Tringa totanus", -"dowitcher", -"oystercatcher, oyster catcher", -"pelican", -"king penguin, Aptenodytes patagonica", -"albatross, mollymawk", -"grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus", -"killer whale, killer, orca, grampus, sea wolf, Orcinus orca", -"dugong, Dugong dugon", -"sea lion", -"Chihuahua", -"Japanese spaniel", -"Maltese dog, Maltese terrier, Maltese", -"Pekinese, Pekingese, Peke", -"Shih-Tzu", -"Blenheim spaniel", -"papillon", -"toy terrier", -"Rhodesian ridgeback", -"Afghan hound, Afghan", -"basset, basset hound", -"beagle", -"bloodhound, sleuthhound", -"bluetick", -"black-and-tan coonhound", -"Walker hound, Walker foxhound", -"English foxhound", -"redbone", -"borzoi, Russian wolfhound", -"Irish wolfhound", -"Italian greyhound", -"whippet", -"Ibizan hound, Ibizan Podenco", -"Norwegian elkhound, elkhound", -"otterhound, otter hound", -"Saluki, gazelle hound", -"Scottish deerhound, deerhound", -"Weimaraner", -"Staffordshire bullterrier, Staffordshire bull terrier", -"American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier", -"Bedlington terrier", -"Border terrier", -"Kerry blue terrier", -"Irish terrier", -"Norfolk terrier", -"Norwich terrier", -"Yorkshire terrier", -"wire-haired fox terrier", -"Lakeland terrier", -"Sealyham terrier, Sealyham", -"Airedale, Airedale terrier", -"cairn, cairn terrier", -"Australian terrier", -"Dandie Dinmont, Dandie Dinmont terrier", -"Boston bull, Boston terrier", -"miniature schnauzer", -"giant schnauzer", -"standard schnauzer", -"Scotch terrier, Scottish terrier, Scottie", -"Tibetan terrier, chrysanthemum dog", -"silky terrier, Sydney silky", -"soft-coated wheaten terrier", -"West Highland white terrier", -"Lhasa, Lhasa apso", -"flat-coated retriever", -"curly-coated retriever", -"golden retriever", -"Labrador retriever", -"Chesapeake Bay retriever", -"German short-haired pointer", -"vizsla, Hungarian pointer", -"English setter", -"Irish setter, red setter", -"Gordon setter", -"Brittany spaniel", -"clumber, clumber spaniel", -"English springer, English springer spaniel", -"Welsh springer spaniel", -"cocker spaniel, English cocker spaniel, cocker", -"Sussex spaniel", -"Irish water spaniel", -"kuvasz", -"schipperke", -"groenendael", -"malinois", -"briard", -"kelpie", -"komondor", -"Old English sheepdog, bobtail", -"Shetland sheepdog, Shetland sheep dog, Shetland", -"collie", -"Border collie", -"Bouvier des Flandres, Bouviers des Flandres", -"Rottweiler", -"German shepherd, German shepherd dog, German police dog, alsatian", -"Doberman, Doberman pinscher", -"miniature pinscher", -"Greater Swiss Mountain dog", -"Bernese mountain dog", -"Appenzeller", -"EntleBucher", -"boxer", -"bull mastiff", -"Tibetan mastiff", -"French bulldog", -"Great Dane", -"Saint Bernard, St Bernard", -"Eskimo dog, husky", -"malamute, malemute, Alaskan malamute", -"Siberian husky", -"dalmatian, coach dog, carriage dog", -"affenpinscher, monkey pinscher, monkey dog", -"basenji", -"pug, pug-dog", -"Leonberg", -"Newfoundland, Newfoundland dog", -"Great Pyrenees", -"Samoyed, Samoyede", -"Pomeranian", -"chow, chow chow", -"keeshond", -"Brabancon griffon", -"Pembroke, Pembroke Welsh corgi", -"Cardigan, Cardigan Welsh corgi", -"toy poodle", -"miniature poodle", -"standard poodle", -"Mexican hairless", -"timber wolf, grey wolf, gray wolf, Canis lupus", -"white wolf, Arctic wolf, Canis lupus tundrarum", -"red wolf, maned wolf, Canis rufus, Canis niger", -"coyote, prairie wolf, brush wolf, Canis latrans", -"dingo, warrigal, warragal, Canis dingo", -"dhole, Cuon alpinus", -"African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus", -"hyena, hyaena", -"red fox, Vulpes vulpes", -"kit fox, Vulpes macrotis", -"Arctic fox, white fox, Alopex lagopus", -"grey fox, gray fox, Urocyon cinereoargenteus", -"tabby, tabby cat", -"tiger cat", -"Persian cat", -"Siamese cat, Siamese", -"Egyptian cat", -"cougar, puma, catamount, mountain lion, painter, panther, Felis concolor", -"lynx, catamount", -"leopard, Panthera pardus", -"snow leopard, ounce, Panthera uncia", -"jaguar, panther, Panthera onca, Felis onca", -"lion, king of beasts, Panthera leo", -"tiger, Panthera tigris", -"cheetah, chetah, Acinonyx jubatus", -"brown bear, bruin, Ursus arctos", -"American black bear, black bear, Ursus americanus, Euarctos americanus", -"ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus", -"sloth bear, Melursus ursinus, Ursus ursinus", -"mongoose", -"meerkat, mierkat", -"tiger beetle", -"ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle", -"ground beetle, carabid beetle", -"long-horned beetle, longicorn, longicorn beetle", -"leaf beetle, chrysomelid", -"dung beetle", -"rhinoceros beetle", -"weevil", -"fly", -"bee", -"ant, emmet, pismire", -"grasshopper, hopper", -"cricket", -"walking stick, walkingstick, stick insect", -"cockroach, roach", -"mantis, mantid", -"cicada, cicala", -"leafhopper", -"lacewing, lacewing fly", -"dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", -"damselfly", -"admiral", -"ringlet, ringlet butterfly", -"monarch, monarch butterfly, milkweed butterfly, Danaus plexippus", -"cabbage butterfly", -"sulphur butterfly, sulfur butterfly", -"lycaenid, lycaenid butterfly", -"starfish, sea star", -"sea urchin", -"sea cucumber, holothurian", -"wood rabbit, cottontail, cottontail rabbit", -"hare", -"Angora, Angora rabbit", -"hamster", -"porcupine, hedgehog", -"fox squirrel, eastern fox squirrel, Sciurus niger", -"marmot", -"beaver", -"guinea pig, Cavia cobaya", -"sorrel", -"zebra", -"hog, pig, grunter, squealer, Sus scrofa", -"wild boar, boar, Sus scrofa", -"warthog", -"hippopotamus, hippo, river horse, Hippopotamus amphibius", -"ox", -"water buffalo, water ox, Asiatic buffalo, Bubalus bubalis", -"bison", -"ram, tup", -"bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis", -"ibex, Capra ibex", -"hartebeest", -"impala, Aepyceros melampus", -"gazelle", -"Arabian camel, dromedary, Camelus dromedarius", -"llama", -"weasel", -"mink", -"polecat, fitch, foulmart, foumart, Mustela putorius", -"black-footed ferret, ferret, Mustela nigripes", -"otter", -"skunk, polecat, wood pussy", -"badger", -"armadillo", -"three-toed sloth, ai, Bradypus tridactylus", -"orangutan, orang, orangutang, Pongo pygmaeus", -"gorilla, Gorilla gorilla", -"chimpanzee, chimp, Pan troglodytes", -"gibbon, Hylobates lar", -"siamang, Hylobates syndactylus, Symphalangus syndactylus", -"guenon, guenon monkey", -"patas, hussar monkey, Erythrocebus patas", -"baboon", -"macaque", -"langur", -"colobus, colobus monkey", -"proboscis monkey, Nasalis larvatus", -"marmoset", -"capuchin, ringtail, Cebus capucinus", -"howler monkey, howler", -"titi, titi monkey", -"spider monkey, Ateles geoffroyi", -"squirrel monkey, Saimiri sciureus", -"Madagascar cat, ring-tailed lemur, Lemur catta", -"indri, indris, Indri indri, Indri brevicaudatus", -"Indian elephant, Elephas maximus", -"African elephant, Loxodonta africana", -"lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens", -"giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca", -"barracouta, snoek", -"eel", -"coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch", -"rock beauty, Holocanthus tricolor", -"anemone fish", -"sturgeon", -"gar, garfish, garpike, billfish, Lepisosteus osseus", -"lionfish", -"puffer, pufferfish, blowfish, globefish", -"abacus", -"abaya", -"academic gown, academic robe, judge's robe", -"accordion, piano accordion, squeeze box", -"acoustic guitar", -"aircraft carrier, carrier, flattop, attack aircraft carrier", -"airliner", -"airship, dirigible", -"altar", -"ambulance", -"amphibian, amphibious vehicle", -"analog clock", -"apiary, bee house", -"apron", -"ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin", -"assault rifle, assault gun", -"backpack, back pack, knapsack, packsack, rucksack, haversack", -"bakery, bakeshop, bakehouse", -"balance beam, beam", -"balloon", -"ballpoint, ballpoint pen, ballpen, Biro", -"Band Aid", -"banjo", -"bannister, banister, balustrade, balusters, handrail", -"barbell", -"barber chair", -"barbershop", -"barn", -"barometer", -"barrel, cask", -"barrow, garden cart, lawn cart, wheelbarrow", -"baseball", -"basketball", -"bassinet", -"bassoon", -"bathing cap, swimming cap", -"bath towel", -"bathtub, bathing tub, bath, tub", -"beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon", -"beacon, lighthouse, beacon light, pharos", -"beaker", -"bearskin, busby, shako", -"beer bottle", -"beer glass", -"bell cote, bell cot", -"bib", -"bicycle-built-for-two, tandem bicycle, tandem", -"bikini, two-piece", -"binder, ring-binder", -"binoculars, field glasses, opera glasses", -"birdhouse", -"boathouse", -"bobsled, bobsleigh, bob", -"bolo tie, bolo, bola tie, bola", -"bonnet, poke bonnet", -"bookcase", -"bookshop, bookstore, bookstall", -"bottlecap", -"bow", -"bow tie, bow-tie, bowtie", -"brass, memorial tablet, plaque", -"brassiere, bra, bandeau", -"breakwater, groin, groyne, mole, bulwark, seawall, jetty", -"breastplate, aegis, egis", -"broom", -"bucket, pail", -"buckle", -"bulletproof vest", -"bullet train, bullet", -"butcher shop, meat market", -"cab, hack, taxi, taxicab", -"caldron, cauldron", -"candle, taper, wax light", -"cannon", -"canoe", -"can opener, tin opener", -"cardigan", -"car mirror", -"carousel, carrousel, merry-go-round, roundabout, whirligig", -"carpenter's kit, tool kit", -"carton", -"car wheel", -"cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM", -"cassette", -"cassette player", -"castle", -"catamaran", -"CD player", -"cello, violoncello", -"cellular telephone, cellular phone, cellphone, cell, mobile phone", -"chain", -"chainlink fence", -"chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour", -"chain saw, chainsaw", -"chest", -"chiffonier, commode", -"chime, bell, gong", -"china cabinet, china closet", -"Christmas stocking", -"church, church building", -"cinema, movie theater, movie theatre, movie house, picture palace", -"cleaver, meat cleaver, chopper", -"cliff dwelling", -"cloak", -"clog, geta, patten, sabot", -"cocktail shaker", -"coffee mug", -"coffeepot", -"coil, spiral, volute, whorl, helix", -"combination lock", -"computer keyboard, keypad", -"confectionery, confectionary, candy store", -"container ship, containership, container vessel", -"convertible", -"corkscrew, bottle screw", -"cornet, horn, trumpet, trump", -"cowboy boot", -"cowboy hat, ten-gallon hat", -"cradle", -"crane", -"crash helmet", -"crate", -"crib, cot", -"Crock Pot", -"croquet ball", -"crutch", -"cuirass", -"dam, dike, dyke", -"desk", -"desktop computer", -"dial telephone, dial phone", -"diaper, nappy, napkin", -"digital clock", -"digital watch", -"dining table, board", -"dishrag, dishcloth", -"dishwasher, dish washer, dishwashing machine", -"disk brake, disc brake", -"dock, dockage, docking facility", -"dogsled, dog sled, dog sleigh", -"dome", -"doormat, welcome mat", -"drilling platform, offshore rig", -"drum, membranophone, tympan", -"drumstick", -"dumbbell", -"Dutch oven", -"electric fan, blower", -"electric guitar", -"electric locomotive", -"entertainment center", -"envelope", -"espresso maker", -"face powder", -"feather boa, boa", -"file, file cabinet, filing cabinet", -"fireboat", -"fire engine, fire truck", -"fire screen, fireguard", -"flagpole, flagstaff", -"flute, transverse flute", -"folding chair", -"football helmet", -"forklift", -"fountain", -"fountain pen", -"four-poster", -"freight car", -"French horn, horn", -"frying pan, frypan, skillet", -"fur coat", -"garbage truck, dustcart", -"gasmask, respirator, gas helmet", -"gas pump, gasoline pump, petrol pump, island dispenser", -"goblet", -"go-kart", -"golf ball", -"golfcart, golf cart", -"gondola", -"gong, tam-tam", -"gown", -"grand piano, grand", -"greenhouse, nursery, glasshouse", -"grille, radiator grille", -"grocery store, grocery, food market, market", -"guillotine", -"hair slide", -"hair spray", -"half track", -"hammer", -"hamper", -"hand blower, blow dryer, blow drier, hair dryer, hair drier", -"hand-held computer, hand-held microcomputer", -"handkerchief, hankie, hanky, hankey", -"hard disc, hard disk, fixed disk", -"harmonica, mouth organ, harp, mouth harp", -"harp", -"harvester, reaper", -"hatchet", -"holster", -"home theater, home theatre", -"honeycomb", -"hook, claw", -"hoopskirt, crinoline", -"horizontal bar, high bar", -"horse cart, horse-cart", -"hourglass", -"iPod", -"iron, smoothing iron", -"jack-o'-lantern", -"jean, blue jean, denim", -"jeep, landrover", -"jersey, T-shirt, tee shirt", -"jigsaw puzzle", -"jinrikisha, ricksha, rickshaw", -"joystick", -"kimono", -"knee pad", -"knot", -"lab coat, laboratory coat", -"ladle", -"lampshade, lamp shade", -"laptop, laptop computer", -"lawn mower, mower", -"lens cap, lens cover", -"letter opener, paper knife, paperknife", -"library", -"lifeboat", -"lighter, light, igniter, ignitor", -"limousine, limo", -"liner, ocean liner", -"lipstick, lip rouge", -"Loafer", -"lotion", -"loudspeaker, speaker, speaker unit, loudspeaker system, speaker system", -"loupe, jeweler's loupe", -"lumbermill, sawmill", -"magnetic compass", -"mailbag, postbag", -"mailbox, letter box", -"maillot", -"maillot, tank suit", -"manhole cover", -"maraca", -"marimba, xylophone", -"mask", -"matchstick", -"maypole", -"maze, labyrinth", -"measuring cup", -"medicine chest, medicine cabinet", -"megalith, megalithic structure", -"microphone, mike", -"microwave, microwave oven", -"military uniform", -"milk can", -"minibus", -"miniskirt, mini", -"minivan", -"missile", -"mitten", -"mixing bowl", -"mobile home, manufactured home", -"Model T", -"modem", -"monastery", -"monitor", -"moped", -"mortar", -"mortarboard", -"mosque", -"mosquito net", -"motor scooter, scooter", -"mountain bike, all-terrain bike, off-roader", -"mountain tent", -"mouse, computer mouse", -"mousetrap", -"moving van", -"muzzle", -"nail", -"neck brace", -"necklace", -"nipple", -"notebook, notebook computer", -"obelisk", -"oboe, hautboy, hautbois", -"ocarina, sweet potato", -"odometer, hodometer, mileometer, milometer", -"oil filter", -"organ, pipe organ", -"oscilloscope, scope, cathode-ray oscilloscope, CRO", -"overskirt", -"oxcart", -"oxygen mask", -"packet", -"paddle, boat paddle", -"paddlewheel, paddle wheel", -"padlock", -"paintbrush", -"pajama, pyjama, pj's, jammies", -"palace", -"panpipe, pandean pipe, syrinx", -"paper towel", -"parachute, chute", -"parallel bars, bars", -"park bench", -"parking meter", -"passenger car, coach, carriage", -"patio, terrace", -"pay-phone, pay-station", -"pedestal, plinth, footstall", -"pencil box, pencil case", -"pencil sharpener", -"perfume, essence", -"Petri dish", -"photocopier", -"pick, plectrum, plectron", -"pickelhaube", -"picket fence, paling", -"pickup, pickup truck", -"pier", -"piggy bank, penny bank", -"pill bottle", -"pillow", -"ping-pong ball", -"pinwheel", -"pirate, pirate ship", -"pitcher, ewer", -"plane, carpenter's plane, woodworking plane", -"planetarium", -"plastic bag", -"plate rack", -"plow, plough", -"plunger, plumber's helper", -"Polaroid camera, Polaroid Land camera", -"pole", -"police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria", -"poncho", -"pool table, billiard table, snooker table", -"pop bottle, soda bottle", -"pot, flowerpot", -"potter's wheel", -"power drill", -"prayer rug, prayer mat", -"printer", -"prison, prison house", -"projectile, missile", -"projector", -"puck, hockey puck", -"punching bag, punch bag, punching ball, punchball", -"purse", -"quill, quill pen", -"quilt, comforter, comfort, puff", -"racer, race car, racing car", -"racket, racquet", -"radiator", -"radio, wireless", -"radio telescope, radio reflector", -"rain barrel", -"recreational vehicle, RV, R.V.", -"reel", -"reflex camera", -"refrigerator, icebox", -"remote control, remote", -"restaurant, eating house, eating place, eatery", -"revolver, six-gun, six-shooter", -"rifle", -"rocking chair, rocker", -"rotisserie", -"rubber eraser, rubber, pencil eraser", -"rugby ball", -"rule, ruler", -"running shoe", -"safe", -"safety pin", -"saltshaker, salt shaker", -"sandal", -"sarong", -"sax, saxophone", -"scabbard", -"scale, weighing machine", -"school bus", -"schooner", -"scoreboard", -"screen, CRT screen", -"screw", -"screwdriver", -"seat belt, seatbelt", -"sewing machine", -"shield, buckler", -"shoe shop, shoe-shop, shoe store", -"shoji", -"shopping basket", -"shopping cart", -"shovel", -"shower cap", -"shower curtain", -"ski", -"ski mask", -"sleeping bag", -"slide rule, slipstick", -"sliding door", -"slot, one-armed bandit", -"snorkel", -"snowmobile", -"snowplow, snowplough", -"soap dispenser", -"soccer ball", -"sock", -"solar dish, solar collector, solar furnace", -"sombrero", -"soup bowl", -"space bar", -"space heater", -"space shuttle", -"spatula", -"speedboat", -"spider web, spider's web", -"spindle", -"sports car, sport car", -"spotlight, spot", -"stage", -"steam locomotive", -"steel arch bridge", -"steel drum", -"stethoscope", -"stole", -"stone wall", -"stopwatch, stop watch", -"stove", -"strainer", -"streetcar, tram, tramcar, trolley, trolley car", -"stretcher", -"studio couch, day bed", -"stupa, tope", -"submarine, pigboat, sub, U-boat", -"suit, suit of clothes", -"sundial", -"sunglass", -"sunglasses, dark glasses, shades", -"sunscreen, sunblock, sun blocker", -"suspension bridge", -"swab, swob, mop", -"sweatshirt", -"swimming trunks, bathing trunks", -"swing", -"switch, electric switch, electrical switch", -"syringe", -"table lamp", -"tank, army tank, armored combat vehicle, armoured combat vehicle", -"tape player", -"teapot", -"teddy, teddy bear", -"television, television system", -"tennis ball", -"thatch, thatched roof", -"theater curtain, theatre curtain", -"thimble", -"thresher, thrasher, threshing machine", -"throne", -"tile roof", -"toaster", -"tobacco shop, tobacconist shop, tobacconist", -"toilet seat", -"torch", -"totem pole", -"tow truck, tow car, wrecker", -"toyshop", -"tractor", -"trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi", -"tray", -"trench coat", -"tricycle, trike, velocipede", -"trimaran", -"tripod", -"triumphal arch", -"trolleybus, trolley coach, trackless trolley", -"trombone", -"tub, vat", -"turnstile", -"typewriter keyboard", -"umbrella", -"unicycle, monocycle", -"upright, upright piano", -"vacuum, vacuum cleaner", -"vase", -"vault", -"velvet", -"vending machine", -"vestment", -"viaduct", -"violin, fiddle", -"volleyball", -"waffle iron", -"wall clock", -"wallet, billfold, notecase, pocketbook", -"wardrobe, closet, press", -"warplane, military plane", -"washbasin, handbasin, washbowl, lavabo, wash-hand basin", -"washer, automatic washer, washing machine", -"water bottle", -"water jug", -"water tower", -"whiskey jug", -"whistle", -"wig", -"window screen", -"window shade", -"Windsor tie", -"wine bottle", -"wing", -"wok", -"wooden spoon", -"wool, woolen, woollen", -"worm fence, snake fence, snake-rail fence, Virginia fence", -"wreck", -"yawl", -"yurt", -"web site, website, internet site, site", -"comic book", -"crossword puzzle, crossword", -"street sign", -"traffic light, traffic signal, stoplight", -"book jacket, dust cover, dust jacket, dust wrapper", -"menu", -"plate", -"guacamole", -"consomme", -"hot pot, hotpot", -"trifle", -"ice cream, icecream", -"ice lolly, lolly, lollipop, popsicle", -"French loaf", -"bagel, beigel", -"pretzel", -"cheeseburger", -"hotdog, hot dog, red hot", -"mashed potato", -"head cabbage", -"broccoli", -"cauliflower", -"zucchini, courgette", -"spaghetti squash", -"acorn squash", -"butternut squash", -"cucumber, cuke", -"artichoke, globe artichoke", -"bell pepper", -"cardoon", -"mushroom", -"Granny Smith", -"strawberry", -"orange", -"lemon", -"fig", -"pineapple, ananas", -"banana", -"jackfruit, jak, jack", -"custard apple", -"pomegranate", -"hay", -"carbonara", -"chocolate sauce, chocolate syrup", -"dough", -"meat loaf, meatloaf", -"pizza, pizza pie", -"potpie", -"burrito", -"red wine", -"espresso", -"cup", -"eggnog", -"alp", -"bubble", -"cliff, drop, drop-off", -"coral reef", -"geyser", -"lakeside, lakeshore", -"promontory, headland, head, foreland", -"sandbar, sand bar", -"seashore, coast, seacoast, sea-coast", -"valley, vale", -"volcano", -"ballplayer, baseball player", -"groom, bridegroom", -"scuba diver", -"rapeseed", -"daisy", -"yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", -"corn", -"acorn", -"hip, rose hip, rosehip", -"buckeye, horse chestnut, conker", -"coral fungus", -"agaric", -"gyromitra", -"stinkhorn, carrion fungus", -"earthstar", -"hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa", -"bolete", -"ear, spike, capitulum", -"toilet tissue, toilet paper, bathroom tissue" diff --git a/models/vision/classification/caffenet/run_caffenet.sh b/models/vision/classification/caffenet/run_caffenet.sh deleted file mode 100755 index 87dba04ed..000000000 --- a/models/vision/classification/caffenet/run_caffenet.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -# RUN: %s %t.1 -model_name="caffenet" -model_file="$MODELS_ROOT/vision/classification/$model_name/$model_name" -image_dir="$MODELS_ROOT/vision/test_images" -curr_dir=`dirname $0` -if [[ $# != 0 ]];then - export TEST_TEMP_DIR=`dirname $1` -fi - -# check if GPU is enabled or not -if [[ $TEST_WITH_GPU -eq 1 ]]; then - echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file.prototxt \ - $model_file.caffemodel \ - --label-file $curr_dir/../1000_labels.txt --input_h=227 --input_w=227 \ - --input-shape=data:1x3x227x227 \ - --image-dir $image_dir --odla tensorrt --img-preprocess=minus_128 | tee $1 -# RUN: FileCheck --input-file %t.1 %s -else - echo "This tests uses ODLA TensorRT" -fi - -# CHECK: dog.jpg ==> "Samoyed, Samoyede", -# CHECK-NEXT: food.jpg ==> "ice cream, icecream", -# CHECK-NEXT: plane.jpg ==> "airliner", -# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/caffenet/run_caffenet_onnx.sh b/models/vision/classification/caffenet/run_caffenet_onnx.sh deleted file mode 100755 index e9ef9e3d2..000000000 --- a/models/vision/classification/caffenet/run_caffenet_onnx.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# RUN: %s %t.1 - -model_name="caffenet" -model_file="$MODELS_ROOT/vision/classification/$model_name/$model_name-3.onnx" -image_dir="$MODELS_ROOT/vision/test_images" -curr_dir=`dirname $0` -if [[ $# != 0 ]];then - export TEST_TEMP_DIR=`dirname $1` -fi - -# check if GPU is enabled or not -if [[ $TEST_WITH_GPU -eq 1 ]]; then - echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ - --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ - --odla tensorrt --img-preprocess=minus_128 | tee $1 -# RUN: FileCheck --input-file %t.1 %s -else - echo "This tests uses ODLA TensorRT" -fi - -# CHECK: dog.jpg ==> "Samoyed, Samoyede", -# CHECK-NEXT: food.jpg ==> "ice cream, icecream", -# CHECK-NEXT: plane.jpg ==> "airliner", -# CHECK-NEXT: sport.jpg ==> "ski", \ No newline at end of file diff --git a/models/vision/classification/coco_classes.txt b/models/vision/classification/coco_classes.txt deleted file mode 100644 index 605972b0c..000000000 --- a/models/vision/classification/coco_classes.txt +++ /dev/null @@ -1,80 +0,0 @@ -"person", -"bicycle", -"car", -"motorbike", -"aeroplane", -"bus", -"train", -"truck", -"boat", -"traffic light", -"fire hydrant", -"stop sign", -"parking meter", -"bench", -"bird", -"cat", -"dog", -"horse", -"sheep", -"cow", -"elephant", -"bear", -"zebra", -"giraffe", -"backpack", -"umbrella", -"handbag", -"tie", -"suitcase", -"frisbee", -"skis", -"snowboard", -"sports ball", -"kite", -"baseball bat", -"baseball glove", -"skateboard", -"surfboard", -"tennis racket", -"bottle", -"wine glass", -"cup", -"fork", -"knife", -"spoon", -"bowl", -"banana", -"apple", -"sandwich", -"orange", -"broccoli", -"carrot", -"hot dog", -"pizza", -"donut", -"cake", -"chair", -"sofa", -"pottedplant", -"bed", -"diningtable", -"toilet", -"tvmonitor", -"laptop", -"mouse", -"remote", -"keyboard", -"cell phone", -"microwave", -"oven", -"toaster", -"sink", -"refrigerator", -"book", -"clock", -"vase", -"scissors", -"teddy bear", -"hair drier", -"toothbrush", diff --git a/models/vision/classification/densenet/run_densenet.sh b/models/vision/classification/densenet/run_densenet.sh index b4398adf3..33ccafe1b 100755 --- a/models/vision/classification/densenet/run_densenet.sh +++ b/models/vision/classification/densenet/run_densenet.sh @@ -12,9 +12,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir \ $image_dir --odla tensorrt | tee $1 + done # RUN: FileCheck --input-file %t.1 %s fi diff --git a/models/vision/classification/densenet/run_densenet_tensorrt.sh b/models/vision/classification/densenet/run_densenet_tensorrt.sh new file mode 100755 index 000000000..0e80861fc --- /dev/null +++ b/models/vision/classification/densenet/run_densenet_tensorrt.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# RUN: %s +model_name="densenet" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name""121.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir +for i in 1 2 4 8 16 32 64 +do + echo "=======Testing densenet with TensorRT=======" + python3 $curr_dir/../../onnx2tensorrt.py --model $model_file --label-file $curr_dir/../1000_labels.txt --batch_size $i +done + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/efficientnet/run_efficientnet.sh b/models/vision/classification/efficientnet/run_efficientnet.sh new file mode 100755 index 000000000..72a89350e --- /dev/null +++ b/models/vision/classification/efficientnet/run_efficientnet.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="efficientnet" +model_file="$MODELS_ROOT/vision/classification/efficientnet/$model_name-lite4-11.onnx" +image_dir="$MODELS_ROOT/vision/test_images" +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +curr_dir=`dirname $0` + +# check if GPU is enabled or not +if [[ $TEST_WITH_GPU -eq 1 ]]; then + echo "======== Testing with ODLA TensorRT ========" + for i in 1 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ + --odla tensorrt --convert-layout-to=nhwc | tee $1 + done +# RUN: FileCheck --input-file %t.1 %s +fi + +# Using HALO to compile and run inference with ODLA XNNPACK +echo "======== Testing with ODLA XNNPACK (NHWC) ========" +python3 $curr_dir/../../invoke_halo.py --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ + --odla xnnpack --convert-layout-to=nhwc | tee $2 +# RUN: FileCheck --input-file %t.2 %s + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "ice cream, icecream", +# CHECK-NEXT: plane.jpg ==> "liner, ocean liner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/efficientnet/run_efficientnet_tensorrt.sh b/models/vision/classification/efficientnet/run_efficientnet_tensorrt.sh new file mode 100755 index 000000000..477301f89 --- /dev/null +++ b/models/vision/classification/efficientnet/run_efficientnet_tensorrt.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# RUN: %s +model_name="efficientnet" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name""-lite4-11.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir + +echo "=======Testing efficientnet with TensorRT=======" +python3 $curr_dir/../../onnx2tensorrt.py --model $model_file --convert-layout-to=nhwc + + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/get_cls_model_from_pytorch.py b/models/vision/classification/get_cls_model_from_pytorch.py deleted file mode 100755 index d6f862cb8..000000000 --- a/models/vision/classification/get_cls_model_from_pytorch.py +++ /dev/null @@ -1,15 +0,0 @@ -#! /usr/bin/env python3 -import torch -import torch.onnx -import sys - -if __name__ == "__main__": - name = sys.argv[1] - file_path = sys.argv[2] - h = int(sys.argv[3]) if len(sys.argv) > 3 else 224 - w = int(sys.argv[4]) if len(sys.argv) > 4 else h - url = 'pytorch/vision:v0.6.0' - model = torch.hub.load(url, name, pretrained=True) - torch.onnx.export(model, torch.rand(1, 3, h, w), file_path, export_params=True, - opset_version=10, do_constant_folding=True, - input_names=['input'], output_names=['output']) diff --git a/models/vision/classification/googlenet/run_googlenet.sh b/models/vision/classification/googlenet/run_googlenet.sh index fdd2b429d..61e05f07d 100755 --- a/models/vision/classification/googlenet/run_googlenet.sh +++ b/models/vision/classification/googlenet/run_googlenet.sh @@ -12,9 +12,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $1 + done # RUN: FileCheck --input-file %t.1 %s else echo "This tests uses ODLA TensorRT" diff --git a/models/vision/classification/googlenet/run_googlenet_tensorrt.sh b/models/vision/classification/googlenet/run_googlenet_tensorrt.sh new file mode 100755 index 000000000..299b0c3ca --- /dev/null +++ b/models/vision/classification/googlenet/run_googlenet_tensorrt.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# RUN: %s +model_name="googlenet" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir + +echo "=======Testing googlenet with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file --label-file $curr_dir/../1000_labels.txt +done + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/inception/run_inception_v1.sh b/models/vision/classification/inception/run_inception_v1.sh index 5e6eb30f7..0f73c8df5 100755 --- a/models/vision/classification/inception/run_inception_v1.sh +++ b/models/vision/classification/inception/run_inception_v1.sh @@ -11,9 +11,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt --img-preprocess=minus_128 | tee $1 + done # RUN: FileCheck --input-file %t.1 --check-prefix CHECK-TENSORRT %s # CHECK-TENSORRT: dog.jpg ==> "Samoyed, Samoyede", # CHECK-TENSORRT: food.jpg ==> "jellyfish", diff --git a/models/vision/classification/inception/run_inception_v1_tensorrt.sh b/models/vision/classification/inception/run_inception_v1_tensorrt.sh new file mode 100755 index 000000000..b9c230c0a --- /dev/null +++ b/models/vision/classification/inception/run_inception_v1_tensorrt.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# RUN: %s +model_name="inception" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name-v1-9.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir + +echo "=======Testing inception_v1 with TensorRT=======" +for i in 1 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file --label-file $curr_dir/../1000_labels.txt --img-preprocess=minus_128 +done + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/inception/run_inception_v3.sh b/models/vision/classification/inception/run_inception_v3.sh index 2e869010c..20b83914d 100755 --- a/models/vision/classification/inception/run_inception_v3.sh +++ b/models/vision/classification/inception/run_inception_v3.sh @@ -12,9 +12,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt --input_h 299 --input_w 299 | tee $1 + done # RUN: FileCheck --input-file %t.1 %s else echo "This tests uses ODLA TensorRT" diff --git a/models/vision/classification/inception/run_inception_v3_tensorrt.sh b/models/vision/classification/inception/run_inception_v3_tensorrt.sh new file mode 100755 index 000000000..ec1f648e0 --- /dev/null +++ b/models/vision/classification/inception/run_inception_v3_tensorrt.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# RUN: %s +model_name="inception" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name""_v3.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir + +echo "=======Testing inception_v3 with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file --label-file $curr_dir/../1000_labels.txt --input_h 299 --input_w 299 +done + + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/mnist_simple/.gitignore b/models/vision/classification/mnist_simple/.gitignore deleted file mode 100644 index f75c3b112..000000000 --- a/models/vision/classification/mnist_simple/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -MNIST_data diff --git a/models/vision/classification/mnist_simple/main.cc b/models/vision/classification/mnist_simple/main.cc deleted file mode 100644 index d03297bc7..000000000 --- a/models/vision/classification/mnist_simple/main.cc +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include -#include -#include - -#include "mnist_simple.h" - -int main(int argc, char** argv) { - struct ImageFileHead { - int32_t magic; - uint32_t count; - uint32_t rows; - uint32_t cols; - }; - struct LabelFileHead { - uint32_t magic; - uint32_t count; - }; - - if (argc != 3) { - std::cerr << "Usage: " << argv[0] - << " [MNIST image-idx3 file] [MNIST label-idx3 file]\n"; - return 1; - } - - std::ifstream fs(argv[1], std::ios::binary); - struct ImageFileHead fh { - 0, 0, 0, 0 - }; - struct LabelFileHead lh { - 0, 0 - }; - - fs.read(reinterpret_cast(&fh), sizeof(fh)); - auto to_le = [](uint32_t& x) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - x = __builtin_bswap32(x); -#endif - }; - to_le(fh.count); - to_le(fh.rows); - to_le(fh.cols); - - if (fh.rows != 28 || fh.cols != 28) { - std::cerr << "Invalid data file (rows:" << fh.rows << " cols: " << fh.cols - << ")\n"; - return 1; - } - - std::vector> imgs(fh.count); - for (unsigned i = 0; i < fh.count; ++i) { - fs.read(imgs[i].data(), imgs[i].size()); - if (fs.fail()) { - std::cerr << "Failed to read image file\n"; - } - } - - std::ifstream f(argv[2], std::ios::binary); - f.read(reinterpret_cast(&lh), sizeof(lh)); - - to_le(lh.count); - - if (lh.count != fh.count) { - std::cerr << "data mismatch\n"; - return 1; - } - std::vector labels(lh.count); - f.read(labels.data(), labels.size()); - - int correct = 0; - int nr_tests = lh.count; - mnist_simple_init(); - for (int i = 0; i < nr_tests; ++i) { - std::array input; - std::array output; - std::transform(imgs[i].begin(), imgs[i].end(), input.begin(), - [](char x) { return ((unsigned char)x) / 255.0F; }); - mnist_simple(input.data(), output.data()); - int pred = std::max_element(output.begin(), output.end()) - output.begin(); - correct += (pred == labels[i]); - } - mnist_simple_fini(); - std::cout << "Accuracy " << correct << "/" << nr_tests << " (" - << correct * 100.0 / nr_tests << "%) \n"; -} diff --git a/models/vision/classification/mnist_simple/mnist_simple.pb b/models/vision/classification/mnist_simple/mnist_simple.pb deleted file mode 100644 index 166a5abc3563e8c8c873b73fd1777c4cd671abe7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31736 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 diff --git a/models/vision/classification/mnist_simple/mnist_simple.png b/models/vision/classification/mnist_simple/mnist_simple.png deleted file mode 100644 index 63b4c3c00dbd460323d6e966ba4b3f8c66a694f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16558 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

xNieHPA>HDKgi`aa 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×784MatMulMatMulfloat32[784,10]b〈784×10〉Addaddfloat32[10]y〈10〉Softmaxyxfloat32[?,784] \ No newline at end of file diff --git a/models/vision/classification/mnist_simple/run_mnist_simple.sh b/models/vision/classification/mnist_simple/run_mnist_simple.sh deleted file mode 100755 index b387a7f36..000000000 --- a/models/vision/classification/mnist_simple/run_mnist_simple.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -# RUN: %s %t.1 %t.2 - -curr_dir=`dirname $0` -if [[ $# != 0 ]];then - export TEST_TEMP_DIR=`dirname $1` -fi -out=$TEST_TEMP_DIR - -model_name="mnist_simple" -model_path=$MODELS_ROOT/vision/classification/$model_name - -$HALO_BIN -target cxx -o $out/mnist_simple.so $model_path/$model_name.pb -I $ODLA_INC - -g++ -c $curr_dir/main.cc -I$out -o $out/main.o - -if [[ $TEST_WITH_GPU -eq 1 ]]; then - echo "Using TensorRT based ODLA runtime" - g++ -o $out/test $out/main.o $out/mnist_simple.so \ - -L$ODLA_LIB -lodla_tensorrt -Wl,-rpath=$ODLA_LIB - $out/test $model_path/test_image $model_path/test_label | tee $1 -# RUN: FileCheck --input-file %t.1 %s -fi - -echo "Using DNNL-based ODLA implementation" -g++ -o $out/test $out/main.o $out/mnist_simple.so \ - -L$ODLA_LIB -lodla_dnnl -Wl,-rpath=$ODLA_LIB - -$out/test $model_path/test_image $model_path/test_label | tee $2 -# RUN: FileCheck --input-file %t.2 %s - -# CHECK: Accuracy 919{{.*}}/10000 (91.9{{.*}}%) \ No newline at end of file diff --git a/models/vision/classification/mobilenet/run_mobilenet_v2.sh b/models/vision/classification/mobilenet/run_mobilenet_v2.sh index 73e71e0ac..12da6c2e9 100755 --- a/models/vision/classification/mobilenet/run_mobilenet_v2.sh +++ b/models/vision/classification/mobilenet/run_mobilenet_v2.sh @@ -14,9 +14,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 2 4 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $1 + done # RUN: FileCheck --input-file %t.1 %s fi diff --git a/models/vision/classification/mobilenet/run_mobilenet_v2_tensorrt.sh b/models/vision/classification/mobilenet/run_mobilenet_v2_tensorrt.sh new file mode 100755 index 000000000..629ddbe1c --- /dev/null +++ b/models/vision/classification/mobilenet/run_mobilenet_v2_tensorrt.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# RUN: %s +model_name="mobilenet" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name""_v2.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir + +echo "=======Testing mobilenet_v2 with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --model $model_file --label-file $curr_dir/../1000_labels.txt --batch_size $i +done + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/alexnet/run_alexnet.sh b/models/vision/classification/rcnn/run_rcnn-ilsvrc13-9.sh similarity index 68% rename from models/vision/classification/alexnet/run_alexnet.sh rename to models/vision/classification/rcnn/run_rcnn-ilsvrc13-9.sh index 020e9e15f..5c4876c38 100755 --- a/models/vision/classification/alexnet/run_alexnet.sh +++ b/models/vision/classification/rcnn/run_rcnn-ilsvrc13-9.sh @@ -1,15 +1,17 @@ #!/bin/bash # RUN: %s %t.1 %t.2 -model_name="alexnet" -model_file="$MODELS_ROOT/vision/classification/$model_name/$model_name.onnx" +# set -xv + +model_name="rcnn" +model_file="$MODELS_ROOT/vision/classification/rcnn/$model_name""-ilsvrc13-9.onnx" image_dir="$MODELS_ROOT/vision/test_images" curr_dir=`dirname $0` - if [[ $# != 0 ]];then export TEST_TEMP_DIR=`dirname $1` fi +# check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" python3 $curr_dir/../../invoke_halo.py --model $model_file \ @@ -18,14 +20,14 @@ if [[ $TEST_WITH_GPU -eq 1 ]]; then # RUN: FileCheck --input-file %t.1 %s fi -# Using HALO to compile and run inference with ODLA XNNPACK -echo "======== Testing with ODLA DNNL ========" +# Using HALO to compile and run inference with ODLA DNNL +echo "======== Testing with ODLA DNNL (NHWC) ========" python3 $curr_dir/../../invoke_halo.py --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ - --odla dnnl | tee $2 + --odla dnnl --convert-layout-to=nhwc |tee $2 # RUN: FileCheck --input-file %t.2 %s -# CHECK: dog.jpg ==> "wallaby, brush kangaroo", +# CHECK: dog.jpg ==> "Samoyed, Samoyede", # CHECK-NEXT: food.jpg ==> "ice cream, icecream", # CHECK-NEXT: plane.jpg ==> "airliner", # CHECK-NEXT: sport.jpg ==> "ski", \ No newline at end of file diff --git a/models/vision/classification/rcnn/run_rcnn_tensorrt.sh b/models/vision/classification/rcnn/run_rcnn_tensorrt.sh new file mode 100755 index 000000000..6a294465c --- /dev/null +++ b/models/vision/classification/rcnn/run_rcnn_tensorrt.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# RUN: %s +model_name="rcnn" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name""-ilsvrc13-9.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir + +echo "=======Testing efficientnet with TensorRT=======" +python3 $curr_dir/../../onnx2tensorrt.py --model $model_file --output_size 200 + + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/resnet/run_resnet_v1_18.sh b/models/vision/classification/resnet/run_resnet_v1_18.sh index 3e2dbcb91..126a5d3a7 100755 --- a/models/vision/classification/resnet/run_resnet_v1_18.sh +++ b/models/vision/classification/resnet/run_resnet_v1_18.sh @@ -19,9 +19,12 @@ python3 $curr_dir/../../invoke_halo.py --model $model_file \ # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file --label-file \ $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $2 + done # RUN: FileCheck --input-file %t.2 %s fi diff --git a/models/vision/classification/resnet/run_resnet_v1_18_tensorrt.sh b/models/vision/classification/resnet/run_resnet_v1_18_tensorrt.sh new file mode 100755 index 000000000..f5921eab1 --- /dev/null +++ b/models/vision/classification/resnet/run_resnet_v1_18_tensorrt.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="resnet18-v1" +model_file="/models/vision/classification/resnet/$model_name-7.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# Using Tensorrt to compile and run inference. +echo "=======Testing resnet_v1_18 with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image_dir $image_dir +done +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/resnet/run_resnet_v2_101.sh b/models/vision/classification/resnet/run_resnet_v2_101.sh index 43dd4032d..3771ddb75 100755 --- a/models/vision/classification/resnet/run_resnet_v2_101.sh +++ b/models/vision/classification/resnet/run_resnet_v2_101.sh @@ -18,9 +18,12 @@ python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file --label-file \ $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $2 + done # RUN: FileCheck --input-file %t.2 %s fi diff --git a/models/vision/classification/resnet/run_resnet_v2_101_tensorrt.sh b/models/vision/classification/resnet/run_resnet_v2_101_tensorrt.sh new file mode 100755 index 000000000..da5e92095 --- /dev/null +++ b/models/vision/classification/resnet/run_resnet_v2_101_tensorrt.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="resnet101-v2" +model_file="/models/vision/classification/resnet/$model_name-7.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# Using Tensorrt to compile and run inference. +echo "=======Testing resnet_v2_101 with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image_dir $image_dir +done +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/resnet/run_resnet_v2_50.sh b/models/vision/classification/resnet/run_resnet_v2_50.sh index db03a275c..62fc8c6f8 100755 --- a/models/vision/classification/resnet/run_resnet_v2_50.sh +++ b/models/vision/classification/resnet/run_resnet_v2_50.sh @@ -19,9 +19,12 @@ python3 $curr_dir/../../invoke_halo.py --model $model_file \ # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file --label-file \ $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $2 + done # RUN: FileCheck --input-file %t.2 %s fi diff --git a/models/vision/classification/resnet/run_resnet_v2_50_tensorrt.sh b/models/vision/classification/resnet/run_resnet_v2_50_tensorrt.sh new file mode 100755 index 000000000..7e12f1307 --- /dev/null +++ b/models/vision/classification/resnet/run_resnet_v2_50_tensorrt.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="resnet50-v2" +model_file="/models/vision/classification/resnet/$model_name-7.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# Using Tensorrt to compile and run inference. +echo "=======Testing resnet_v2_50 with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image_dir $image_dir +done +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/shufflenet/run_shufflenet.sh b/models/vision/classification/shufflenet/run_shufflenet.sh index d5113abe6..3b3bfa669 100755 --- a/models/vision/classification/shufflenet/run_shufflenet.sh +++ b/models/vision/classification/shufflenet/run_shufflenet.sh @@ -13,9 +13,12 @@ curr_dir=`dirname $0` # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $1 + done # RUN: FileCheck --input-file %t.1 %s fi diff --git a/models/vision/classification/shufflenet/run_shufflenet_tensorrt.sh b/models/vision/classification/shufflenet/run_shufflenet_tensorrt.sh new file mode 100755 index 000000000..c26d6ce2c --- /dev/null +++ b/models/vision/classification/shufflenet/run_shufflenet_tensorrt.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="shufflenet" +model_file="/models/vision/classification/shufflenet/"$model_name"-9.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# Using Tensorrt to compile and run inference. +echo "=======Testing shufflenet with TensorRT=======" +for i in 1 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image_dir $image_dir +done +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/squeezenet/run_squeezenet_1_0.sh b/models/vision/classification/squeezenet/run_squeezenet_1_0.sh index 5a1e2f3d0..f256fe99b 100755 --- a/models/vision/classification/squeezenet/run_squeezenet_1_0.sh +++ b/models/vision/classification/squeezenet/run_squeezenet_1_0.sh @@ -12,9 +12,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file --label-file \ $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $1 + done # RUN: FileCheck --input-file %t.1 --check-prefix CHECK-TENSORRT %s # CHECK-TENSORRT: dog.jpg ==> "Samoyed, Samoyede", # CHECK-TENSORRT: food.jpg ==> "ice cream, icecream", diff --git a/models/vision/classification/squeezenet/run_squeezenet_1_0_tensorrt.sh b/models/vision/classification/squeezenet/run_squeezenet_1_0_tensorrt.sh new file mode 100755 index 000000000..3bd28428d --- /dev/null +++ b/models/vision/classification/squeezenet/run_squeezenet_1_0_tensorrt.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="squeezenet1" +model_file="/models/vision/classification/squeezenet/$model_name""_0.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# Using Tensorrt to compile and run inference. +echo "=======Testing squeezenet_1_0 with TensorRT=======" +python3 $curr_dir/../../onnx2tensorrt.py --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image_dir $image_dir + +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/squeezenet/run_squeezenet_1_1.sh b/models/vision/classification/squeezenet/run_squeezenet_1_1.sh index 77947cae5..140bad3ec 100755 --- a/models/vision/classification/squeezenet/run_squeezenet_1_1.sh +++ b/models/vision/classification/squeezenet/run_squeezenet_1_1.sh @@ -2,8 +2,8 @@ # RUN: %s %t.1 %t.2 model_name="squeezenet1" -model_file="$MODELS_ROOT/vision/classification/squeezenet/squeezenet1_1.onnx" -image_dir="$MODELS_ROOT/vision/test_images" +model_file="/models/vision/classification/squeezenet/squeezenet1_1.onnx" +image_dir="/models/vision/test_images" curr_dir=`dirname $0` if [[ $# != 0 ]];then export TEST_TEMP_DIR=`dirname $1` @@ -12,8 +12,11 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file --label-file \ $curr_dir/../1000_labels.txt --image-dir $image_dir --odla tensorrt | tee $1 + done # RUN: FileCheck --input-file %t.1 %s fi diff --git a/models/vision/classification/squeezenet/run_squeezenet_1_1_tensorrt.sh b/models/vision/classification/squeezenet/run_squeezenet_1_1_tensorrt.sh new file mode 100755 index 000000000..2d16560bf --- /dev/null +++ b/models/vision/classification/squeezenet/run_squeezenet_1_1_tensorrt.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="squeezenet1" +model_file="/models/vision/classification/squeezenet/$model_name""_1.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# Using Tensorrt to compile and run inference. +echo "=======Testing squeezenet_1_1 with TensorRT=======" +python3 $curr_dir/../../onnx2tensorrt.py --model $model_file --image_dir $image_dir + +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/vgg/run_vgg16.sh b/models/vision/classification/vgg/run_vgg16.sh index 2be389118..e97752af0 100755 --- a/models/vision/classification/vgg/run_vgg16.sh +++ b/models/vision/classification/vgg/run_vgg16.sh @@ -12,9 +12,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt 2>&1 | tee $1 + done # RUN: FileCheck --input-file %t.1 %s fi diff --git a/models/vision/classification/vgg/run_vgg16_tensorrt.sh b/models/vision/classification/vgg/run_vgg16_tensorrt.sh new file mode 100755 index 000000000..2282deca0 --- /dev/null +++ b/models/vision/classification/vgg/run_vgg16_tensorrt.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="vgg16" +model_file="/models/vision/classification/vgg/$model_name.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# Using Tensorrt to compile and run inference. +echo "=======Testing vgg16 with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image_dir $image_dir +done +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/vgg/run_vgg19.sh b/models/vision/classification/vgg/run_vgg19.sh index b82d5b6f6..7b5dab1d5 100755 --- a/models/vision/classification/vgg/run_vgg19.sh +++ b/models/vision/classification/vgg/run_vgg19.sh @@ -12,9 +12,12 @@ fi # check if GPU is enabled or not if [[ $TEST_WITH_GPU -eq 1 ]]; then echo "======== Testing with ODLA TensorRT ========" - python3 $curr_dir/../../invoke_halo.py --model $model_file \ + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --batch_size $i --model $model_file \ --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ --odla tensorrt | tee $1 + done # RUN: FileCheck --input-file %t.1 %s fi diff --git a/models/vision/classification/vgg/run_vgg19_tensorrt.sh b/models/vision/classification/vgg/run_vgg19_tensorrt.sh new file mode 100755 index 000000000..50dc39c79 --- /dev/null +++ b/models/vision/classification/vgg/run_vgg19_tensorrt.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="vgg19" +model_file="/models/vision/classification/vgg/$model_name.onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# Using Tensorrt to compile and run inference. +echo "=======Testing vgg19 with TensorRT=======" +for i in 1 2 4 8 16 32 64 +do +python3 $curr_dir/../../onnx2tensorrt.py --batch_size $i --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image_dir $image_dir +done +# # Using HALO to compile and run inference with ODLA DNNL +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $1 +# # RUN: FileCheck --input-file %t.1 %s + +# # check if GPU is enabled or not +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file \ +# $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla tensorrt | tee $2 +# # RUN: FileCheck --input-file %t.2 %s +# fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "mashed potato", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", diff --git a/models/vision/classification/vgg/test.sh b/models/vision/classification/vgg/test.sh new file mode 100755 index 000000000..eb3b48ef6 --- /dev/null +++ b/models/vision/classification/vgg/test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +curr_dir=`dirname $0` + +echo $curr_dir \ No newline at end of file diff --git a/models/vision/tensorrt_baseline_run_all.sh b/models/vision/tensorrt_baseline_run_all.sh new file mode 100644 index 000000000..e56450927 --- /dev/null +++ b/models/vision/tensorrt_baseline_run_all.sh @@ -0,0 +1,39 @@ +#!/bin/bash +source ../env.src + + +bash ./classification/alexnet/run_alexnet_tensorrt.sh + +# bash ./classification/caffenet/run_caffenet_tensorrt.sh # segmentation fault + +bash ./classification/densenet/run_densenet_tensorrt.sh + +# bash ./classification/googlenet/run_googlenet_tensorrt.sh # segementation fault + +# bash ./classification/inception/run_inception_v1_tensorrt.sh # reshape 问题 + +bash ./classification/inception/run_inception_v3_tensorrt.sh + +bash ./classification/mobilenet/run_mobilenet_v2_tensorrt.sh + +bash ./classification/resnet/run_resnet_v2_50_tensorrt.sh + +bash ./classification/resnet/run_resnet_v1_18_tensorrt.sh + +bash ./classification/resnet/run_resnet_v2_101_tensorrt.sh + +# bash ./classification/shufflenet/run_shufflenet_tensorrt.sh # reshape 问题 + +# bash ./classification/squeezenet/run_squeezenet_1_0_tensorrt.sh # segmentation fault + +# bash ./classification/squeezenet/run_squeezenet_1_1_tensorrt.sh # segmentation fault + +bash ./classification/vgg/run_vgg16_tensorrt.sh + +bash ./classification/vgg/run_vgg19_tensorrt.sh + +bash ./classification/efficientnet/run_efficientnet_tensorrt.sh + +# bash ./classification/rcnn/run_rcnn_tensorrt.sh + +# bash ./body_analysis/arcface/run_arcface_tensorrt.sh \ No newline at end of file From ca8dbea5259317eebb65aa6e0740ea707d68836c Mon Sep 17 00:00:00 2001 From: ZZWHU <1306328198@qq.com> Date: Thu, 26 Aug 2021 05:49:28 -0700 Subject: [PATCH 4/5] run all tensorrt baseline --- .../classification/alexnet/run_alexnet.sh | 34 +++++++++++++++++++ .../alexnet/run_alexnet_tensorrt.sh | 29 ++++++++++++++++ .../classification/caffenet/run_caffenet.sh | 27 +++++++++++++++ 3 files changed, 90 insertions(+) create mode 100755 models/vision/classification/alexnet/run_alexnet.sh create mode 100755 models/vision/classification/alexnet/run_alexnet_tensorrt.sh create mode 100755 models/vision/classification/caffenet/run_caffenet.sh diff --git a/models/vision/classification/alexnet/run_alexnet.sh b/models/vision/classification/alexnet/run_alexnet.sh new file mode 100755 index 000000000..9acff60d1 --- /dev/null +++ b/models/vision/classification/alexnet/run_alexnet.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +model_name="alexnet" +model_file="$MODELS_ROOT/vision/classification/$model_name/$model_name.onnx" +image_dir="$MODELS_ROOT/vision/test_images" +curr_dir=`dirname $0` + +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +if [[ $TEST_WITH_GPU -eq 1 ]]; then + echo "======== Testing with ODLA TensorRT ========" + for i in 1 2 4 8 16 32 64 + do + python3 $curr_dir/../../invoke_halo.py --model $model_file \ + --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ + --odla tensorrt | tee $1 + done +# RUN: FileCheck --input-file %t.1 %s +fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file \ +# --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir \ +# --odla dnnl | tee $2 +# RUN: FileCheck --input-file %t.2 %s + +# CHECK: dog.jpg ==> "wallaby, brush kangaroo", +# CHECK-NEXT: food.jpg ==> "ice cream, icecream", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", \ No newline at end of file diff --git a/models/vision/classification/alexnet/run_alexnet_tensorrt.sh b/models/vision/classification/alexnet/run_alexnet_tensorrt.sh new file mode 100755 index 000000000..431703e35 --- /dev/null +++ b/models/vision/classification/alexnet/run_alexnet_tensorrt.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# RUN: %s +model_name="alexnet" +docker_model_file="/models/vision/classification/$model_name" +model_file="$docker_model_file/$model_name"".onnx" +image_dir="/models/vision/test_images" +curr_dir=`dirname $0` + +# # Download model if it is not exist +# if [ ! -e $model_file ]; then +# $curr_dir/../get_cls_model_from_pytorch.py $model_name $model_file +# fi + +# Download sample images if it is not exist +# $curr_dir/../../get_images.sh $image_dir + +echo "=======Testing alexnet with TensorRT=======" +python3 $curr_dir/../../onnx2tensorrt.py --model $model_file \ + --label-file $curr_dir/../1000_labels.txt + + +# if [[ $TEST_WITH_GPU -eq 1 ]]; then +# echo "======== Testing with ODLA TensorRT ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --image-dir $image_dir --odla tensorrt +# fi + +# # Using HALO to compile and run inference with ODLA XNNPACK +# echo "======== Testing with ODLA DNNL ========" +# python3 $curr_dir/../../invoke_halo.py --model $model_file --label-file $curr_dir/../1000_labels.txt --image-dir $image_dir --odla dnnl \ No newline at end of file diff --git a/models/vision/classification/caffenet/run_caffenet.sh b/models/vision/classification/caffenet/run_caffenet.sh new file mode 100755 index 000000000..87dba04ed --- /dev/null +++ b/models/vision/classification/caffenet/run_caffenet.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# RUN: %s %t.1 +model_name="caffenet" +model_file="$MODELS_ROOT/vision/classification/$model_name/$model_name" +image_dir="$MODELS_ROOT/vision/test_images" +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi + +# check if GPU is enabled or not +if [[ $TEST_WITH_GPU -eq 1 ]]; then + echo "======== Testing with ODLA TensorRT ========" + python3 $curr_dir/../../invoke_halo.py --model $model_file.prototxt \ + $model_file.caffemodel \ + --label-file $curr_dir/../1000_labels.txt --input_h=227 --input_w=227 \ + --input-shape=data:1x3x227x227 \ + --image-dir $image_dir --odla tensorrt --img-preprocess=minus_128 | tee $1 +# RUN: FileCheck --input-file %t.1 %s +else + echo "This tests uses ODLA TensorRT" +fi + +# CHECK: dog.jpg ==> "Samoyed, Samoyede", +# CHECK-NEXT: food.jpg ==> "ice cream, icecream", +# CHECK-NEXT: plane.jpg ==> "airliner", +# CHECK-NEXT: sport.jpg ==> "ski", From 28fe4824480a132212813314c4f258fd5477654e Mon Sep 17 00:00:00 2001 From: ZZWHU <1306328198@qq.com> Date: Thu, 26 Aug 2021 05:51:19 -0700 Subject: [PATCH 5/5] run all tensorrt baseline --- models/vision/classification/1000_labels.txt | 1000 +++++++++++++++++ models/vision/classification/coco_classes.txt | 80 ++ .../classification/mnist_simple/.gitignore | 2 + .../classification/mnist_simple/main.cc | 86 ++ .../mnist_simple/mnist_simple.pb | Bin 0 -> 31736 bytes .../mnist_simple/mnist_simple.png | Bin 0 -> 16558 bytes .../mnist_simple/mnist_simple.svg | 1 + .../mnist_simple/run_mnist_simple.sh | 32 + .../vision/classification/ntsnet/get_model.py | 8 + 9 files changed, 1209 insertions(+) create mode 100755 models/vision/classification/1000_labels.txt create mode 100755 models/vision/classification/coco_classes.txt create mode 100755 models/vision/classification/mnist_simple/.gitignore create mode 100755 models/vision/classification/mnist_simple/main.cc create mode 100755 models/vision/classification/mnist_simple/mnist_simple.pb create mode 100755 models/vision/classification/mnist_simple/mnist_simple.png create mode 100755 models/vision/classification/mnist_simple/mnist_simple.svg create mode 100755 models/vision/classification/mnist_simple/run_mnist_simple.sh create mode 100755 models/vision/classification/ntsnet/get_model.py diff --git a/models/vision/classification/1000_labels.txt b/models/vision/classification/1000_labels.txt new file mode 100755 index 000000000..40b90699a --- /dev/null +++ b/models/vision/classification/1000_labels.txt @@ -0,0 +1,1000 @@ +"tench, Tinca tinca", +"goldfish, Carassius auratus", +"great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias", +"tiger shark, Galeocerdo cuvieri", +"hammerhead, hammerhead shark", +"electric ray, crampfish, numbfish, torpedo", +"stingray", +"cock", +"hen", +"ostrich, Struthio camelus", +"brambling, Fringilla montifringilla", +"goldfinch, Carduelis carduelis", +"house finch, linnet, Carpodacus mexicanus", +"junco, snowbird", +"indigo bunting, indigo finch, indigo bird, Passerina cyanea", +"robin, American robin, Turdus migratorius", +"bulbul", +"jay", +"magpie", +"chickadee", +"water ouzel, dipper", +"kite", +"bald eagle, American eagle, Haliaeetus leucocephalus", +"vulture", +"great grey owl, great gray owl, Strix nebulosa", +"European fire salamander, Salamandra salamandra", +"common newt, Triturus vulgaris", +"eft", +"spotted salamander, Ambystoma maculatum", +"axolotl, mud puppy, Ambystoma mexicanum", +"bullfrog, Rana catesbeiana", +"tree frog, tree-frog", +"tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui", +"loggerhead, loggerhead turtle, Caretta caretta", +"leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea", +"mud turtle", +"terrapin", +"box turtle, box tortoise", +"banded gecko", +"common iguana, iguana, Iguana iguana", +"American chameleon, anole, Anolis carolinensis", +"whiptail, whiptail lizard", +"agama", +"frilled lizard, Chlamydosaurus kingi", +"alligator lizard", +"Gila monster, Heloderma suspectum", +"green lizard, Lacerta viridis", +"African chameleon, Chamaeleo chamaeleon", +"Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis", +"African crocodile, Nile crocodile, Crocodylus niloticus", +"American alligator, Alligator mississipiensis", +"triceratops", +"thunder snake, worm snake, Carphophis amoenus", +"ringneck snake, ring-necked snake, ring snake", +"hognose snake, puff adder, sand viper", +"green snake, grass snake", +"king snake, kingsnake", +"garter snake, grass snake", +"water snake", +"vine snake", +"night snake, Hypsiglena torquata", +"boa constrictor, Constrictor constrictor", +"rock python, rock snake, Python sebae", +"Indian cobra, Naja naja", +"green mamba", +"sea snake", +"horned viper, cerastes, sand viper, horned asp, Cerastes cornutus", +"diamondback, diamondback rattlesnake, Crotalus adamanteus", +"sidewinder, horned rattlesnake, Crotalus cerastes", +"trilobite", +"harvestman, daddy longlegs, Phalangium opilio", +"scorpion", +"black and gold garden spider, Argiope aurantia", +"barn spider, Araneus cavaticus", +"garden spider, Aranea diademata", +"black widow, Latrodectus mactans", +"tarantula", +"wolf spider, hunting spider", +"tick", +"centipede", +"black grouse", +"ptarmigan", +"ruffed grouse, partridge, Bonasa umbellus", +"prairie chicken, prairie grouse, prairie fowl", +"peacock", +"quail", +"partridge", +"African grey, African gray, Psittacus erithacus", +"macaw", +"sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita", +"lorikeet", +"coucal", +"bee eater", +"hornbill", +"hummingbird", +"jacamar", +"toucan", +"drake", +"red-breasted merganser, Mergus serrator", +"goose", +"black swan, Cygnus atratus", +"tusker", +"echidna, spiny anteater, anteater", +"platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus", +"wallaby, brush kangaroo", +"koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus", +"wombat", +"jellyfish", +"sea anemone, anemone", +"brain coral", +"flatworm, platyhelminth", +"nematode, nematode worm, roundworm", +"conch", +"snail", +"slug", +"sea slug, nudibranch", +"chiton, coat-of-mail shell, sea cradle, polyplacophore", +"chambered nautilus, pearly nautilus, nautilus", +"Dungeness crab, Cancer magister", +"rock crab, Cancer irroratus", +"fiddler crab", +"king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica", +"American lobster, Northern lobster, Maine lobster, Homarus americanus", +"spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish", +"crayfish, crawfish, crawdad, crawdaddy", +"hermit crab", +"isopod", +"white stork, Ciconia ciconia", +"black stork, Ciconia nigra", +"spoonbill", +"flamingo", +"little blue heron, Egretta caerulea", +"American egret, great white heron, Egretta albus", +"bittern", +"crane", +"limpkin, Aramus pictus", +"European gallinule, Porphyrio porphyrio", +"American coot, marsh hen, mud hen, water hen, Fulica americana", +"bustard", +"ruddy turnstone, Arenaria interpres", +"red-backed sandpiper, dunlin, Erolia alpina", +"redshank, Tringa totanus", +"dowitcher", +"oystercatcher, oyster catcher", +"pelican", +"king penguin, Aptenodytes patagonica", +"albatross, mollymawk", +"grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus", +"killer whale, killer, orca, grampus, sea wolf, Orcinus orca", +"dugong, Dugong dugon", +"sea lion", +"Chihuahua", +"Japanese spaniel", +"Maltese dog, Maltese terrier, Maltese", +"Pekinese, Pekingese, Peke", +"Shih-Tzu", +"Blenheim spaniel", +"papillon", +"toy terrier", +"Rhodesian ridgeback", +"Afghan hound, Afghan", +"basset, basset hound", +"beagle", +"bloodhound, sleuthhound", +"bluetick", +"black-and-tan coonhound", +"Walker hound, Walker foxhound", +"English foxhound", +"redbone", +"borzoi, Russian wolfhound", +"Irish wolfhound", +"Italian greyhound", +"whippet", +"Ibizan hound, Ibizan Podenco", +"Norwegian elkhound, elkhound", +"otterhound, otter hound", +"Saluki, gazelle hound", +"Scottish deerhound, deerhound", +"Weimaraner", +"Staffordshire bullterrier, Staffordshire bull terrier", +"American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier", +"Bedlington terrier", +"Border terrier", +"Kerry blue terrier", +"Irish terrier", +"Norfolk terrier", +"Norwich terrier", +"Yorkshire terrier", +"wire-haired fox terrier", +"Lakeland terrier", +"Sealyham terrier, Sealyham", +"Airedale, Airedale terrier", +"cairn, cairn terrier", +"Australian terrier", +"Dandie Dinmont, Dandie Dinmont terrier", +"Boston bull, Boston terrier", +"miniature schnauzer", +"giant schnauzer", +"standard schnauzer", +"Scotch terrier, Scottish terrier, Scottie", +"Tibetan terrier, chrysanthemum dog", +"silky terrier, Sydney silky", +"soft-coated wheaten terrier", +"West Highland white terrier", +"Lhasa, Lhasa apso", +"flat-coated retriever", +"curly-coated retriever", +"golden retriever", +"Labrador retriever", +"Chesapeake Bay retriever", +"German short-haired pointer", +"vizsla, Hungarian pointer", +"English setter", +"Irish setter, red setter", +"Gordon setter", +"Brittany spaniel", +"clumber, clumber spaniel", +"English springer, English springer spaniel", +"Welsh springer spaniel", +"cocker spaniel, English cocker spaniel, cocker", +"Sussex spaniel", +"Irish water spaniel", +"kuvasz", +"schipperke", +"groenendael", +"malinois", +"briard", +"kelpie", +"komondor", +"Old English sheepdog, bobtail", +"Shetland sheepdog, Shetland sheep dog, Shetland", +"collie", +"Border collie", +"Bouvier des Flandres, Bouviers des Flandres", +"Rottweiler", +"German shepherd, German shepherd dog, German police dog, alsatian", +"Doberman, Doberman pinscher", +"miniature pinscher", +"Greater Swiss Mountain dog", +"Bernese mountain dog", +"Appenzeller", +"EntleBucher", +"boxer", +"bull mastiff", +"Tibetan mastiff", +"French bulldog", +"Great Dane", +"Saint Bernard, St Bernard", +"Eskimo dog, husky", +"malamute, malemute, Alaskan malamute", +"Siberian husky", +"dalmatian, coach dog, carriage dog", +"affenpinscher, monkey pinscher, monkey dog", +"basenji", +"pug, pug-dog", +"Leonberg", +"Newfoundland, Newfoundland dog", +"Great Pyrenees", +"Samoyed, Samoyede", +"Pomeranian", +"chow, chow chow", +"keeshond", +"Brabancon griffon", +"Pembroke, Pembroke Welsh corgi", +"Cardigan, Cardigan Welsh corgi", +"toy poodle", +"miniature poodle", +"standard poodle", +"Mexican hairless", +"timber wolf, grey wolf, gray wolf, Canis lupus", +"white wolf, Arctic wolf, Canis lupus tundrarum", +"red wolf, maned wolf, Canis rufus, Canis niger", +"coyote, prairie wolf, brush wolf, Canis latrans", +"dingo, warrigal, warragal, Canis dingo", +"dhole, Cuon alpinus", +"African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus", +"hyena, hyaena", +"red fox, Vulpes vulpes", +"kit fox, Vulpes macrotis", +"Arctic fox, white fox, Alopex lagopus", +"grey fox, gray fox, Urocyon cinereoargenteus", +"tabby, tabby cat", +"tiger cat", +"Persian cat", +"Siamese cat, Siamese", +"Egyptian cat", +"cougar, puma, catamount, mountain lion, painter, panther, Felis concolor", +"lynx, catamount", +"leopard, Panthera pardus", +"snow leopard, ounce, Panthera uncia", +"jaguar, panther, Panthera onca, Felis onca", +"lion, king of beasts, Panthera leo", +"tiger, Panthera tigris", +"cheetah, chetah, Acinonyx jubatus", +"brown bear, bruin, Ursus arctos", +"American black bear, black bear, Ursus americanus, Euarctos americanus", +"ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus", +"sloth bear, Melursus ursinus, Ursus ursinus", +"mongoose", +"meerkat, mierkat", +"tiger beetle", +"ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle", +"ground beetle, carabid beetle", +"long-horned beetle, longicorn, longicorn beetle", +"leaf beetle, chrysomelid", +"dung beetle", +"rhinoceros beetle", +"weevil", +"fly", +"bee", +"ant, emmet, pismire", +"grasshopper, hopper", +"cricket", +"walking stick, walkingstick, stick insect", +"cockroach, roach", +"mantis, mantid", +"cicada, cicala", +"leafhopper", +"lacewing, lacewing fly", +"dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", +"damselfly", +"admiral", +"ringlet, ringlet butterfly", +"monarch, monarch butterfly, milkweed butterfly, Danaus plexippus", +"cabbage butterfly", +"sulphur butterfly, sulfur butterfly", +"lycaenid, lycaenid butterfly", +"starfish, sea star", +"sea urchin", +"sea cucumber, holothurian", +"wood rabbit, cottontail, cottontail rabbit", +"hare", +"Angora, Angora rabbit", +"hamster", +"porcupine, hedgehog", +"fox squirrel, eastern fox squirrel, Sciurus niger", +"marmot", +"beaver", +"guinea pig, Cavia cobaya", +"sorrel", +"zebra", +"hog, pig, grunter, squealer, Sus scrofa", +"wild boar, boar, Sus scrofa", +"warthog", +"hippopotamus, hippo, river horse, Hippopotamus amphibius", +"ox", +"water buffalo, water ox, Asiatic buffalo, Bubalus bubalis", +"bison", +"ram, tup", +"bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis", +"ibex, Capra ibex", +"hartebeest", +"impala, Aepyceros melampus", +"gazelle", +"Arabian camel, dromedary, Camelus dromedarius", +"llama", +"weasel", +"mink", +"polecat, fitch, foulmart, foumart, Mustela putorius", +"black-footed ferret, ferret, Mustela nigripes", +"otter", +"skunk, polecat, wood pussy", +"badger", +"armadillo", +"three-toed sloth, ai, Bradypus tridactylus", +"orangutan, orang, orangutang, Pongo pygmaeus", +"gorilla, Gorilla gorilla", +"chimpanzee, chimp, Pan troglodytes", +"gibbon, Hylobates lar", +"siamang, Hylobates syndactylus, Symphalangus syndactylus", +"guenon, guenon monkey", +"patas, hussar monkey, Erythrocebus patas", +"baboon", +"macaque", +"langur", +"colobus, colobus monkey", +"proboscis monkey, Nasalis larvatus", +"marmoset", +"capuchin, ringtail, Cebus capucinus", +"howler monkey, howler", +"titi, titi monkey", +"spider monkey, Ateles geoffroyi", +"squirrel monkey, Saimiri sciureus", +"Madagascar cat, ring-tailed lemur, Lemur catta", +"indri, indris, Indri indri, Indri brevicaudatus", +"Indian elephant, Elephas maximus", +"African elephant, Loxodonta africana", +"lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens", +"giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca", +"barracouta, snoek", +"eel", +"coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch", +"rock beauty, Holocanthus tricolor", +"anemone fish", +"sturgeon", +"gar, garfish, garpike, billfish, Lepisosteus osseus", +"lionfish", +"puffer, pufferfish, blowfish, globefish", +"abacus", +"abaya", +"academic gown, academic robe, judge's robe", +"accordion, piano accordion, squeeze box", +"acoustic guitar", +"aircraft carrier, carrier, flattop, attack aircraft carrier", +"airliner", +"airship, dirigible", +"altar", +"ambulance", +"amphibian, amphibious vehicle", +"analog clock", +"apiary, bee house", +"apron", +"ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin", +"assault rifle, assault gun", +"backpack, back pack, knapsack, packsack, rucksack, haversack", +"bakery, bakeshop, bakehouse", +"balance beam, beam", +"balloon", +"ballpoint, ballpoint pen, ballpen, Biro", +"Band Aid", +"banjo", +"bannister, banister, balustrade, balusters, handrail", +"barbell", +"barber chair", +"barbershop", +"barn", +"barometer", +"barrel, cask", +"barrow, garden cart, lawn cart, wheelbarrow", +"baseball", +"basketball", +"bassinet", +"bassoon", +"bathing cap, swimming cap", +"bath towel", +"bathtub, bathing tub, bath, tub", +"beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon", +"beacon, lighthouse, beacon light, pharos", +"beaker", +"bearskin, busby, shako", +"beer bottle", +"beer glass", +"bell cote, bell cot", +"bib", +"bicycle-built-for-two, tandem bicycle, tandem", +"bikini, two-piece", +"binder, ring-binder", +"binoculars, field glasses, opera glasses", +"birdhouse", +"boathouse", +"bobsled, bobsleigh, bob", +"bolo tie, bolo, bola tie, bola", +"bonnet, poke bonnet", +"bookcase", +"bookshop, bookstore, bookstall", +"bottlecap", +"bow", +"bow tie, bow-tie, bowtie", +"brass, memorial tablet, plaque", +"brassiere, bra, bandeau", +"breakwater, groin, groyne, mole, bulwark, seawall, jetty", +"breastplate, aegis, egis", +"broom", +"bucket, pail", +"buckle", +"bulletproof vest", +"bullet train, bullet", +"butcher shop, meat market", +"cab, hack, taxi, taxicab", +"caldron, cauldron", +"candle, taper, wax light", +"cannon", +"canoe", +"can opener, tin opener", +"cardigan", +"car mirror", +"carousel, carrousel, merry-go-round, roundabout, whirligig", +"carpenter's kit, tool kit", +"carton", +"car wheel", +"cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM", +"cassette", +"cassette player", +"castle", +"catamaran", +"CD player", +"cello, violoncello", +"cellular telephone, cellular phone, cellphone, cell, mobile phone", +"chain", +"chainlink fence", +"chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour", +"chain saw, chainsaw", +"chest", +"chiffonier, commode", +"chime, bell, gong", +"china cabinet, china closet", +"Christmas stocking", +"church, church building", +"cinema, movie theater, movie theatre, movie house, picture palace", +"cleaver, meat cleaver, chopper", +"cliff dwelling", +"cloak", +"clog, geta, patten, sabot", +"cocktail shaker", +"coffee mug", +"coffeepot", +"coil, spiral, volute, whorl, helix", +"combination lock", +"computer keyboard, keypad", +"confectionery, confectionary, candy store", +"container ship, containership, container vessel", +"convertible", +"corkscrew, bottle screw", +"cornet, horn, trumpet, trump", +"cowboy boot", +"cowboy hat, ten-gallon hat", +"cradle", +"crane", +"crash helmet", +"crate", +"crib, cot", +"Crock Pot", +"croquet ball", +"crutch", +"cuirass", +"dam, dike, dyke", +"desk", +"desktop computer", +"dial telephone, dial phone", +"diaper, nappy, napkin", +"digital clock", +"digital watch", +"dining table, board", +"dishrag, dishcloth", +"dishwasher, dish washer, dishwashing machine", +"disk brake, disc brake", +"dock, dockage, docking facility", +"dogsled, dog sled, dog sleigh", +"dome", +"doormat, welcome mat", +"drilling platform, offshore rig", +"drum, membranophone, tympan", +"drumstick", +"dumbbell", +"Dutch oven", +"electric fan, blower", +"electric guitar", +"electric locomotive", +"entertainment center", +"envelope", +"espresso maker", +"face powder", +"feather boa, boa", +"file, file cabinet, filing cabinet", +"fireboat", +"fire engine, fire truck", +"fire screen, fireguard", +"flagpole, flagstaff", +"flute, transverse flute", +"folding chair", +"football helmet", +"forklift", +"fountain", +"fountain pen", +"four-poster", +"freight car", +"French horn, horn", +"frying pan, frypan, skillet", +"fur coat", +"garbage truck, dustcart", +"gasmask, respirator, gas helmet", +"gas pump, gasoline pump, petrol pump, island dispenser", +"goblet", +"go-kart", +"golf ball", +"golfcart, golf cart", +"gondola", +"gong, tam-tam", +"gown", +"grand piano, grand", +"greenhouse, nursery, glasshouse", +"grille, radiator grille", +"grocery store, grocery, food market, market", +"guillotine", +"hair slide", +"hair spray", +"half track", +"hammer", +"hamper", +"hand blower, blow dryer, blow drier, hair dryer, hair drier", +"hand-held computer, hand-held microcomputer", +"handkerchief, hankie, hanky, hankey", +"hard disc, hard disk, fixed disk", +"harmonica, mouth organ, harp, mouth harp", +"harp", +"harvester, reaper", +"hatchet", +"holster", +"home theater, home theatre", +"honeycomb", +"hook, claw", +"hoopskirt, crinoline", +"horizontal bar, high bar", +"horse cart, horse-cart", +"hourglass", +"iPod", +"iron, smoothing iron", +"jack-o'-lantern", +"jean, blue jean, denim", +"jeep, landrover", +"jersey, T-shirt, tee shirt", +"jigsaw puzzle", +"jinrikisha, ricksha, rickshaw", +"joystick", +"kimono", +"knee pad", +"knot", +"lab coat, laboratory coat", +"ladle", +"lampshade, lamp shade", +"laptop, laptop computer", +"lawn mower, mower", +"lens cap, lens cover", +"letter opener, paper knife, paperknife", +"library", +"lifeboat", +"lighter, light, igniter, ignitor", +"limousine, limo", +"liner, ocean liner", +"lipstick, lip rouge", +"Loafer", +"lotion", +"loudspeaker, speaker, speaker unit, loudspeaker system, speaker system", +"loupe, jeweler's loupe", +"lumbermill, sawmill", +"magnetic compass", +"mailbag, postbag", +"mailbox, letter box", +"maillot", +"maillot, tank suit", +"manhole cover", +"maraca", +"marimba, xylophone", +"mask", +"matchstick", +"maypole", +"maze, labyrinth", +"measuring cup", +"medicine chest, medicine cabinet", +"megalith, megalithic structure", +"microphone, mike", +"microwave, microwave oven", +"military uniform", +"milk can", +"minibus", +"miniskirt, mini", +"minivan", +"missile", +"mitten", +"mixing bowl", +"mobile home, manufactured home", +"Model T", +"modem", +"monastery", +"monitor", +"moped", +"mortar", +"mortarboard", +"mosque", +"mosquito net", +"motor scooter, scooter", +"mountain bike, all-terrain bike, off-roader", +"mountain tent", +"mouse, computer mouse", +"mousetrap", +"moving van", +"muzzle", +"nail", +"neck brace", +"necklace", +"nipple", +"notebook, notebook computer", +"obelisk", +"oboe, hautboy, hautbois", +"ocarina, sweet potato", +"odometer, hodometer, mileometer, milometer", +"oil filter", +"organ, pipe organ", +"oscilloscope, scope, cathode-ray oscilloscope, CRO", +"overskirt", +"oxcart", +"oxygen mask", +"packet", +"paddle, boat paddle", +"paddlewheel, paddle wheel", +"padlock", +"paintbrush", +"pajama, pyjama, pj's, jammies", +"palace", +"panpipe, pandean pipe, syrinx", +"paper towel", +"parachute, chute", +"parallel bars, bars", +"park bench", +"parking meter", +"passenger car, coach, carriage", +"patio, terrace", +"pay-phone, pay-station", +"pedestal, plinth, footstall", +"pencil box, pencil case", +"pencil sharpener", +"perfume, essence", +"Petri dish", +"photocopier", +"pick, plectrum, plectron", +"pickelhaube", +"picket fence, paling", +"pickup, pickup truck", +"pier", +"piggy bank, penny bank", +"pill bottle", +"pillow", +"ping-pong ball", +"pinwheel", +"pirate, pirate ship", +"pitcher, ewer", +"plane, carpenter's plane, woodworking plane", +"planetarium", +"plastic bag", +"plate rack", +"plow, plough", +"plunger, plumber's helper", +"Polaroid camera, Polaroid Land camera", +"pole", +"police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria", +"poncho", +"pool table, billiard table, snooker table", +"pop bottle, soda bottle", +"pot, flowerpot", +"potter's wheel", +"power drill", +"prayer rug, prayer mat", +"printer", +"prison, prison house", +"projectile, missile", +"projector", +"puck, hockey puck", +"punching bag, punch bag, punching ball, punchball", +"purse", +"quill, quill pen", +"quilt, comforter, comfort, puff", +"racer, race car, racing car", +"racket, racquet", +"radiator", +"radio, wireless", +"radio telescope, radio reflector", +"rain barrel", +"recreational vehicle, RV, R.V.", +"reel", +"reflex camera", +"refrigerator, icebox", +"remote control, remote", +"restaurant, eating house, eating place, eatery", +"revolver, six-gun, six-shooter", +"rifle", +"rocking chair, rocker", +"rotisserie", +"rubber eraser, rubber, pencil eraser", +"rugby ball", +"rule, ruler", +"running shoe", +"safe", +"safety pin", +"saltshaker, salt shaker", +"sandal", +"sarong", +"sax, saxophone", +"scabbard", +"scale, weighing machine", +"school bus", +"schooner", +"scoreboard", +"screen, CRT screen", +"screw", +"screwdriver", +"seat belt, seatbelt", +"sewing machine", +"shield, buckler", +"shoe shop, shoe-shop, shoe store", +"shoji", +"shopping basket", +"shopping cart", +"shovel", +"shower cap", +"shower curtain", +"ski", +"ski mask", +"sleeping bag", +"slide rule, slipstick", +"sliding door", +"slot, one-armed bandit", +"snorkel", +"snowmobile", +"snowplow, snowplough", +"soap dispenser", +"soccer ball", +"sock", +"solar dish, solar collector, solar furnace", +"sombrero", +"soup bowl", +"space bar", +"space heater", +"space shuttle", +"spatula", +"speedboat", +"spider web, spider's web", +"spindle", +"sports car, sport car", +"spotlight, spot", +"stage", +"steam locomotive", +"steel arch bridge", +"steel drum", +"stethoscope", +"stole", +"stone wall", +"stopwatch, stop watch", +"stove", +"strainer", +"streetcar, tram, tramcar, trolley, trolley car", +"stretcher", +"studio couch, day bed", +"stupa, tope", +"submarine, pigboat, sub, U-boat", +"suit, suit of clothes", +"sundial", +"sunglass", +"sunglasses, dark glasses, shades", +"sunscreen, sunblock, sun blocker", +"suspension bridge", +"swab, swob, mop", +"sweatshirt", +"swimming trunks, bathing trunks", +"swing", +"switch, electric switch, electrical switch", +"syringe", +"table lamp", +"tank, army tank, armored combat vehicle, armoured combat vehicle", +"tape player", +"teapot", +"teddy, teddy bear", +"television, television system", +"tennis ball", +"thatch, thatched roof", +"theater curtain, theatre curtain", +"thimble", +"thresher, thrasher, threshing machine", +"throne", +"tile roof", +"toaster", +"tobacco shop, tobacconist shop, tobacconist", +"toilet seat", +"torch", +"totem pole", +"tow truck, tow car, wrecker", +"toyshop", +"tractor", +"trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi", +"tray", +"trench coat", +"tricycle, trike, velocipede", +"trimaran", +"tripod", +"triumphal arch", +"trolleybus, trolley coach, trackless trolley", +"trombone", +"tub, vat", +"turnstile", +"typewriter keyboard", +"umbrella", +"unicycle, monocycle", +"upright, upright piano", +"vacuum, vacuum cleaner", +"vase", +"vault", +"velvet", +"vending machine", +"vestment", +"viaduct", +"violin, fiddle", +"volleyball", +"waffle iron", +"wall clock", +"wallet, billfold, notecase, pocketbook", +"wardrobe, closet, press", +"warplane, military plane", +"washbasin, handbasin, washbowl, lavabo, wash-hand basin", +"washer, automatic washer, washing machine", +"water bottle", +"water jug", +"water tower", +"whiskey jug", +"whistle", +"wig", +"window screen", +"window shade", +"Windsor tie", +"wine bottle", +"wing", +"wok", +"wooden spoon", +"wool, woolen, woollen", +"worm fence, snake fence, snake-rail fence, Virginia fence", +"wreck", +"yawl", +"yurt", +"web site, website, internet site, site", +"comic book", +"crossword puzzle, crossword", +"street sign", +"traffic light, traffic signal, stoplight", +"book jacket, dust cover, dust jacket, dust wrapper", +"menu", +"plate", +"guacamole", +"consomme", +"hot pot, hotpot", +"trifle", +"ice cream, icecream", +"ice lolly, lolly, lollipop, popsicle", +"French loaf", +"bagel, beigel", +"pretzel", +"cheeseburger", +"hotdog, hot dog, red hot", +"mashed potato", +"head cabbage", +"broccoli", +"cauliflower", +"zucchini, courgette", +"spaghetti squash", +"acorn squash", +"butternut squash", +"cucumber, cuke", +"artichoke, globe artichoke", +"bell pepper", +"cardoon", +"mushroom", +"Granny Smith", +"strawberry", +"orange", +"lemon", +"fig", +"pineapple, ananas", +"banana", +"jackfruit, jak, jack", +"custard apple", +"pomegranate", +"hay", +"carbonara", +"chocolate sauce, chocolate syrup", +"dough", +"meat loaf, meatloaf", +"pizza, pizza pie", +"potpie", +"burrito", +"red wine", +"espresso", +"cup", +"eggnog", +"alp", +"bubble", +"cliff, drop, drop-off", +"coral reef", +"geyser", +"lakeside, lakeshore", +"promontory, headland, head, foreland", +"sandbar, sand bar", +"seashore, coast, seacoast, sea-coast", +"valley, vale", +"volcano", +"ballplayer, baseball player", +"groom, bridegroom", +"scuba diver", +"rapeseed", +"daisy", +"yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", +"corn", +"acorn", +"hip, rose hip, rosehip", +"buckeye, horse chestnut, conker", +"coral fungus", +"agaric", +"gyromitra", +"stinkhorn, carrion fungus", +"earthstar", +"hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa", +"bolete", +"ear, spike, capitulum", +"toilet tissue, toilet paper, bathroom tissue" diff --git a/models/vision/classification/coco_classes.txt b/models/vision/classification/coco_classes.txt new file mode 100755 index 000000000..605972b0c --- /dev/null +++ b/models/vision/classification/coco_classes.txt @@ -0,0 +1,80 @@ +"person", +"bicycle", +"car", +"motorbike", +"aeroplane", +"bus", +"train", +"truck", +"boat", +"traffic light", +"fire hydrant", +"stop sign", +"parking meter", +"bench", +"bird", +"cat", +"dog", +"horse", +"sheep", +"cow", +"elephant", +"bear", +"zebra", +"giraffe", +"backpack", +"umbrella", +"handbag", +"tie", +"suitcase", +"frisbee", +"skis", +"snowboard", +"sports ball", +"kite", +"baseball bat", +"baseball glove", +"skateboard", +"surfboard", +"tennis racket", +"bottle", +"wine glass", +"cup", +"fork", +"knife", +"spoon", +"bowl", +"banana", +"apple", +"sandwich", +"orange", +"broccoli", +"carrot", +"hot dog", +"pizza", +"donut", +"cake", +"chair", +"sofa", +"pottedplant", +"bed", +"diningtable", +"toilet", +"tvmonitor", +"laptop", +"mouse", +"remote", +"keyboard", +"cell phone", +"microwave", +"oven", +"toaster", +"sink", +"refrigerator", +"book", +"clock", +"vase", +"scissors", +"teddy bear", +"hair drier", +"toothbrush", diff --git a/models/vision/classification/mnist_simple/.gitignore b/models/vision/classification/mnist_simple/.gitignore new file mode 100755 index 000000000..f75c3b112 --- /dev/null +++ b/models/vision/classification/mnist_simple/.gitignore @@ -0,0 +1,2 @@ +out +MNIST_data diff --git a/models/vision/classification/mnist_simple/main.cc b/models/vision/classification/mnist_simple/main.cc new file mode 100755 index 000000000..d03297bc7 --- /dev/null +++ b/models/vision/classification/mnist_simple/main.cc @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include + +#include "mnist_simple.h" + +int main(int argc, char** argv) { + struct ImageFileHead { + int32_t magic; + uint32_t count; + uint32_t rows; + uint32_t cols; + }; + struct LabelFileHead { + uint32_t magic; + uint32_t count; + }; + + if (argc != 3) { + std::cerr << "Usage: " << argv[0] + << " [MNIST image-idx3 file] [MNIST label-idx3 file]\n"; + return 1; + } + + std::ifstream fs(argv[1], std::ios::binary); + struct ImageFileHead fh { + 0, 0, 0, 0 + }; + struct LabelFileHead lh { + 0, 0 + }; + + fs.read(reinterpret_cast(&fh), sizeof(fh)); + auto to_le = [](uint32_t& x) { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + x = __builtin_bswap32(x); +#endif + }; + to_le(fh.count); + to_le(fh.rows); + to_le(fh.cols); + + if (fh.rows != 28 || fh.cols != 28) { + std::cerr << "Invalid data file (rows:" << fh.rows << " cols: " << fh.cols + << ")\n"; + return 1; + } + + std::vector> imgs(fh.count); + for (unsigned i = 0; i < fh.count; ++i) { + fs.read(imgs[i].data(), imgs[i].size()); + if (fs.fail()) { + std::cerr << "Failed to read image file\n"; + } + } + + std::ifstream f(argv[2], std::ios::binary); + f.read(reinterpret_cast(&lh), sizeof(lh)); + + to_le(lh.count); + + if (lh.count != fh.count) { + std::cerr << "data mismatch\n"; + return 1; + } + std::vector labels(lh.count); + f.read(labels.data(), labels.size()); + + int correct = 0; + int nr_tests = lh.count; + mnist_simple_init(); + for (int i = 0; i < nr_tests; ++i) { + std::array input; + std::array output; + std::transform(imgs[i].begin(), imgs[i].end(), input.begin(), + [](char x) { return ((unsigned char)x) / 255.0F; }); + mnist_simple(input.data(), output.data()); + int pred = std::max_element(output.begin(), output.end()) - output.begin(); + correct += (pred == labels[i]); + } + mnist_simple_fini(); + std::cout << "Accuracy " << correct << "/" << nr_tests << " (" + << correct * 100.0 / nr_tests << "%) \n"; +} diff --git a/models/vision/classification/mnist_simple/mnist_simple.pb b/models/vision/classification/mnist_simple/mnist_simple.pb new file mode 100755 index 0000000000000000000000000000000000000000..166a5abc3563e8c8c873b73fd1777c4cd671abe7 GIT binary patch literal 31736 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 literal 0 HcmV?d00001 diff --git a/models/vision/classification/mnist_simple/mnist_simple.png b/models/vision/classification/mnist_simple/mnist_simple.png new file mode 100755 index 0000000000000000000000000000000000000000..63b4c3c00dbd460323d6e966ba4b3f8c66a694f4 GIT binary patch literal 16558 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

xNieHPA>HDKgi`aa zR=tc>VwMR)m$Nf@RjF6unJU&X%=jbdc(HVps|rZ9A(KY%N;?_%_rGr^DxHUH_guTuWzaC?_SYY*~IzmG*RCwT3OU$ z`KgNukFeNoH!(TFP>RJKa!x1(Cv6P3w8Lf!vcu%#I)3);t&ugs)Qk!OW982bE#-qq z_g8c%_@>8?0V-@9NU5OUL0EZt2~r=MglTA&br|YvV9i{|4oRwabm{^e!ZVR5<*Abe z=JpCT8m(5C=HKe^V~%P@N&P7cB%FSI6P6shI!4{DtF%-JRfG}81@A4$dCO^>`>D4cK+4 zJ}-O2$hPT1_zWmdoV4!V2pqh)07jC8C{hQg0p^2OV^X0)o1s@UOi!futX#4pc_NkI zp+pc`Op*r~wB1BbkKG1;MPkA2wy3Gm0=7dW{TG+#hn`4GXvO0<_XK&e2}1AwAq2uw zxH6auy^xWGsnD>n9Y9bDdQL{(%P;1{jY-W2jNmgpch2rvgdqrqXDvt0=)UjQCEkLc z!}|#g;x*HYtaX@zD@%92uOBzw5D~Q;31IuU+Rl7EXMFnaQ@4#pSm^&~ zVW`qs^+H2Kqv_@-%#gj$8Ld2(jvEkNorym@$C3Q@5C`VsTvFaX*L#751bd(I*#0XE zfSBWn9`5{>X_X!pZ7(Ns^cZ8#>lIB}ipRKTX(AuW>OSuGNrgGaf}kr4pmY4BzXjD> zvcELhkE_!d)~k0O(V)jjp%fj&VL79~o%gRyjrG=9UQ^&$2ErOSV0>48TV9|3C;San064Yzqm~iJ3g|44q(++t--c?E|pAzfU zP!Q3|V<7I-^HUE+Qqnb1ElAA|J47lfB8kN@C*?_1yESq49}!mw_E@u8BhsE=Thivhx>ANs3{1l(#;VMi6n9XrM z?hy|X_*MV@!_ETEBtE?c1Q=B}Qh%PAs{MB6BrMAvzBRdQ7j88@dM)66CEVjH0s36J z?*Ad~R^+(P!O~;knG*{dnjk;=RMUSveW!!pOSd!wT3Z>w(BmEcCr{WLv0H41vjhcx z)keF6aEEY>%M*6>Y%$&fXYyERAtYY{t<6HAEU0sD@9*!Q_(OfoQJl!9s2j^x;6@0~ zLE3^Yj(?RW{in)@LiV`!iI+k~{)nxSh5op?KDVeW(s*+(p)Q-vhZ4p0oHOA^6_LT5 z1{r&s?z+i4u7FY1>iV3zY~wSk$fw`TXAFUk$BKd9TVeBHun~Me;0y?+L$;d_?(dam z{4%v^`I^K$37qsDP|#PNzt)sTaAKmdJCrfLy|f+4$^7u5zvsV|`8ZivP&?V`isMK} z`sh1SV%LAxlk}>MMav=&1klMZ?#PBnS6h6_b&FmBG(*Gfd&lZaU_-@m1{oQ|PaN}}daXEq4 zG*$eVVt1k>ZrR}{%oKo}9iV>9#Rd7S~j zW1siM_rH4G=KXU5c%{|Y8h{`5KrmWZ_$|7M4eOu(Vju<%Rsqn}9*=#VC0pCPU?4}7 zLojT6e-Z+N*A{!B!GS{f8Ib%GDlCUG1PL{fWx#OiNTRkrcjfyQ!ll zz&7%o|5+8STT^6vz-kXxV(c16_iGOI=~37 zQqY_v_RqtU;*4m7NH3_x`I2l=r!XLXP3Eg zqNw=Ib3ks1VUu$8FDo4}4Y|L^ z^rY;+E9*COSP0jUwV)0uMW}0EJl&pJjcMy^;NemYi1?pu{uq-rRo}ivVF5AC>+01o#@n-u(Ly zLZCU>d2r^#5dmZ`_9~b*LMEclb7Q4ONB1Pi7Y)~;_GIiT#lm(Y2wg^b(ml0t%-WCa z`pBa$4z!T%(6<%BB{96iU4vllosf#_pescEIT8;7lC8w zw~yWJB!auXUZ*kj;d@uG)ITCQpcD&tQz2rt#84XVnil3@g`*n+$ zDQf?9f27DTf*4VTPzE^pg7ke`2WBM!AQbocOH4`k_St?*w+QL)cPqwAeuNPn0-_1u z<6<~p0J2uql^bSBFo6f5I}Wx~D85HZ6cNXRJaG?i@&6kM$&uQ^q#?^!+7NtzHvUc# z$laZcTW45V(^K;6?oZcB*g&bcdR{ z5ZyR3TNHifq3_C+=XIa{h?}V84kAGEl$&Vag%XCONIunr=`fNge4*VP?XQ0}$j6Ze zAQZHvznR)kYX&Y}WTM))r4KId|5n0ANM#mWe4G09FaNjT;^sD*nepSdu%IpCMUZ(3 z_&p3VpWd_f0>4MRD=S@|fdi@x5|xDjeWnz6S`l$%?j7HOUa0{bq16*XWhIO>`Xf42 z0XMg%epk?iP{DSQFih?pi0vVs1b{$Ewa=?C8+YU$=&L!c5e>gQi2eX&smebbm+X(d zr@BPo*@IbOxq@Ucys{i4oMxf+<+A61uL@^q_p|`$A!5~osc;SRl(#S*C!3NZB_qmk zLfwZ%6^(nV9_4q>O&Cus;x9-Bv*;>zEs$d?LLKOv;z)mR#086?Qh{a>yQrI=9VX6%Z zaS-eQOer=_(fGo6$gN1P03|M|sB2P`unuy?gHy&R@wS4Xgf@r?C^U?w^D|#uUV0|D ztINB%W7=u&JW>*|Z2o|M8q z1_-V^1cpV^9Rymt=Ql@Aqlnkf!mx?fj(eZpcTwrUNsX$020SD4-r+3KL9R$eNvL(GlRX#0SBL92Aj_t0bEd9KE!~7socA_4 zz_}RF_cXGU0Q$8#C+sHP!|yi6Z5OM;x_6pEI<7QD@+d-IPu@FqReOf^$=TVyNi3s; zNA%`O$R%$XZn95ZD&RmT89&PL9zHvM=S281GHjsx`8St>cmW?r`L#?~JTUzsO?l5$_ z>SCeUO)H(x>_et;-4{gGWwaUBoVx$Nn_%K(7L8Y;_m}iN<&!bXcpl zuC=V;7atKVHUhVZeYOdN*I=A105FvSE3r*u9X#$LV6dMAJdnnGm5NP7U-vUcv>e>E zE`}=(qq&Ly-%~DDMv__WS`-zJ(TCz4kBv{HLD5t^Y2W!aB*&2jqDW3@v5sDA#oYPa zZOL86l>=2u_Pgfq^|%6qvt)33hcktv!Wa-2AbwQZUJU@Ewmb$1ysve3&vk~&8Fi{Rf>hhv~E{m17F{62eg z-8*a#w|2K-OMook9cEyGFzGSPKN>QkKW*5zNugGgoCkH!zu<=?P2_IF7$xOVn6;l- zEE>IbbiZ$cF#nN0k>yviv*k5!K{U)QWt(gnsc7dX6$pX~j7(n@bU>>8i$_AU1H@7h zLbgchJ~MnvCA7v_QC3n^9_DZv=o6f=RnyxBRcjBaVL$s7I-kteJJSQw_B**kLd z$pw&d#%xg>)1utQ4*So*NiU=1 z($xk4w;Y7~O7)^>G{$%JI&xP*a6{`B*#bi~pq=+^uEqBb{|eAA!0@6j*|KswGAC+r zS!~j&HSc^Pc|;JTs1p{-sfJ)t#v?AoWtLr-ObTKmrvF3B3d4F7qt>l+#mVWYhkqJ3 z;`{65q$uy@O{Q8ZCmFG?s7ksyK@0F#wLx1l98CHCsmO1XN%)&md>IsSXw-puDx>>? zX$ic*QSl^GsE?tXL1p7DvK@qI-6HS_35&Pg%yn{Tv?7L=j_ShgXe>Kv+{wqXw*@(k z8|)hps|p~y5bXE;_~YrmH}djm6=S;ABCiHO(3+xu>o|GJ^&U^RM2_ytKgW;V{c35_ z=2hWP)a2PoSNnDr>Iw+6h{uMiZ9{m{fo}2nVM3WVU5W+~syZlDfa}#SY(iQ&5Trfj zcJaT1uCu-Y8Ar;k3yRoZn{N&11`Y0=NUA&tAiFQa>Hz?ib8S|W0hGA50t9(;x7Q!3 zc^sA+&<)Jq^OSYqE(EyC`<4v)51)48BOWC(762Cq zNb}dK#RgKLo7`43LALqs#^Rc6@J8Hd#q7|9!<7={HcbMcEWP~m0dam*=$TpzEfB@L zU8Sc>TS=W?RAeNQw%o5Jlm%XVBYm%15<9yMP^oC?X-y0+nzF7;AP1&0Ap!DYn##c= zgL;^zdw#z-ZTg;2a(Pg;AvOd$18J@#^zAbO3DAVr_=_0sIOxJJ@sCSB)hN?>Y!;qM zc`!x4QH zhx(hezoTYy4j*3pnD6qxcwMM;QuHmQ=;$yz#6)58@^>kkWma5%o#|=QUj8gUhW&Er zh1bCmE4YLVe$Ywe;oDDB272YD{tHdd=`g;}DuK-07c;17@wXI*?vyu_{8kDJO+j4O zk|Bi4pZwo+r*XNN?@9+SmW<>?h+Vg3+&jM-w{g*Pp3As2m2wjsrXAzgd-=OPL@Oci zwA9^9aw1XoSxb=Yv?M8t%Tmw)l3r;qNZ%Sn^=_#-{co^|)ReRJ*CZ_h;=Fv{?(QkL z8!c!VD zCtftT_p`MH@4ugn1aH7pOOA?qVIlOhM2d*nLrSBX-JVviMQmTU`?lfaN_yJTcRKQZ ziDgJ)MxkbF@w#bnnL4;S+p_o#DlO^qAaiBEe`AfXWNq_caXt(KrDhMaD!&YV+V_ZcS{9-47{#;$FK3dNzC6JEN%pe|_rwV<+0Yy3Uk zoQdk7`1qntsKxGonvV-e_N%L6y}Kw2d5n^r@> zrq`q&_K1m6#DD?%_eSmdS0S`+@u(b8$o2@?;-}5wf*p*%Sv6XzY*-reZEwV5ntAj? zb7g{1mU&Iq{9mFevL(}am6J@RiyuSIGvzkExtKv258jl0PCs2QuE0E!M|sdBF&8PC zh)w1;zMQzu7FQrD^Z)cpuRZutWeq0^?l379OCc*WJ)D-3sY2lkArAJg)=M;#)ri%5 z|K!?k)K0uf=Q|@|h{izhBC;(ZTdw_|sYa1hlj!vwvhnB?w(;?Ii;69uEW0EwNhUv~ z^XZm(usTh>t$3Ogk|B_JR&AorzSvawOqPhX<;?;9F)o_X|5$di5u}TH6Un5+YGdj~ z26S3*Yr{n5KiZ1EoXoC$g^um+bbQ8{H|^#vjrJQ0oUVCnN5X{QK?@|R_ zJM6TopB{c87!uihE#U8w^>Q1Ygt0!(enN7m2#$AE@vKklptSWgQz9zXph89czD9oA z9jVEcY_YL#V!Xe-oX+W?Ic8MBHv~&i_=yq38FB{_jf9a;S-xR@umAk4H(>MJGo2Hr zoF6bRWUP;xby?7nTWhB#4Yx8M?%Pn2;okCH@{-hN9Rf@W@o-PYO27wpEQ1VfPxk2 zsT|1U_|p}YNy5;L(-MW~RB3RPzZ9>sJ~MIOVGam7WD@1iS=oIcDn26gcZWEA0+?dy z3Lm?!CAOlySqtO%^BxwZkLKxgdr)yc{~Y}c8im&z9KjIxIk?tX)D%B8g9p4B$U4^I z!C(L>Q>Gf8HA=JI`8`PZ_e0-oju-^V^2vEcqe950w9QC3+_1>O#e|qvX{Etsv}UI3 z_e;9ORZ^>WZQe9xWRXqwJv)Ra*Es}9?+Ojw*Nm|kGd_*R&wKsrBT{=UDLQ;rAzQ|^ z^dIl)3FcfPun=#=-O9Y?J;U)8GDuo4Qymx^878izh>PXA{;k~g5yugGul3buA6HPZ zCCB>4^pVlYOESm2V)MxCrFER|y0(1AsS|ey%LMCe{=&``$6g$~D(c9ankWfph~dvh z+G*`vzJF`q^H(G1PczG;o}#e%+>DL0Tvqh^$;_kZ5F< ziKQ4_Z}%n^M_DEOJsFV2Lw})vqCR2WxnRBP#r>@Hy*|pJBE0Lj<9NmOCFfx}hr^uP z;7(6{(bP%y?rHaz$q7uvft(Wjd=(#klr@C(kK+vNRyf`L;wjl;BfQ+<6;t@-y)>_U;Au%Pb;@)Jq~=yv*+(HA@b?V z!!0wm1!7uXA;#B-!oL58`B=#}qncexXzQ(Yx?Yz^yhgi;Xvj-(Um&@~(@?GU*Y0?eO=A~F! zc!yMc8Et+8cjx}W{VeBe;lo^Utl(h&e6Vnbf-bWF&P`D^9(9#5tS^ zje36gOW*EROpX<``&MBi5pFG0zzW&ix1TXj`;z|bvntsR;K9T$Ngs34A$-!j`=wpW zcyMu|$8GMqfB@X5+UmE3i%^R86=HXmU}`Z19M5?0i#wqohbmE0iqg-X@t8?&Gzp2X z3=}Q3fO-Q>;u0+@0<|zjf3g$Wylly}dn#SjA!bJ=Lwc_q;1Wz8)htFz#KDBNMcK zeY`TGo(sH>ECM1FwOQ=|(t>oY=_c;$qw$Ba55A6Y{YG`gF-8pP%d5oG%2RQNFA3yN zy{ICb`3Z@VC}dd&x?0QUx_|4*k66oH1>BhbS^v9h`cDd^XiSsG7eDhrqh8;J)?b)B z?za+Un%ClpTAu{in+wEs8~lDf=aQ(3+>uG}IN2PYYCbHphO%|OeDo{#p=}?9U@o@y z^FRJen5Mb-LIJ1t+)qp6e_`)NlKFG=Is}Xl7&v??ir1gYm&0ZX(M~h`d_oV&?sg$e zTze$1Q>2@3;Wf$9!Fy<1VOERHcrWng%AX#*clC%*IldCAbhq92P!q(X#SU1O1%zsG za!PM)t_k@ZD*yjUe_H(Br!sgQPMX~XNqXI4)$Ygp;FYof{kM~K+`KJ=;Lih?-Tqww z!k@y(lbte?dv3J1xkGDwx@i7eAV=^lO@jXR?eyLZ1?)8fAmUzxzO_k=1h4Cl2$Uwj z`V$I7+%8L-%p$AX2xC0g3zn{YAmZ{H8g1Is5?wJDqij`P#p4}=3qc+$Ybw?×784MatMulMatMulfloat32[784,10]b〈784×10〉Addaddfloat32[10]y〈10〉Softmaxyxfloat32[?,784] \ No newline at end of file diff --git a/models/vision/classification/mnist_simple/run_mnist_simple.sh b/models/vision/classification/mnist_simple/run_mnist_simple.sh new file mode 100755 index 000000000..b387a7f36 --- /dev/null +++ b/models/vision/classification/mnist_simple/run_mnist_simple.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# RUN: %s %t.1 %t.2 + +curr_dir=`dirname $0` +if [[ $# != 0 ]];then + export TEST_TEMP_DIR=`dirname $1` +fi +out=$TEST_TEMP_DIR + +model_name="mnist_simple" +model_path=$MODELS_ROOT/vision/classification/$model_name + +$HALO_BIN -target cxx -o $out/mnist_simple.so $model_path/$model_name.pb -I $ODLA_INC + +g++ -c $curr_dir/main.cc -I$out -o $out/main.o + +if [[ $TEST_WITH_GPU -eq 1 ]]; then + echo "Using TensorRT based ODLA runtime" + g++ -o $out/test $out/main.o $out/mnist_simple.so \ + -L$ODLA_LIB -lodla_tensorrt -Wl,-rpath=$ODLA_LIB + $out/test $model_path/test_image $model_path/test_label | tee $1 +# RUN: FileCheck --input-file %t.1 %s +fi + +echo "Using DNNL-based ODLA implementation" +g++ -o $out/test $out/main.o $out/mnist_simple.so \ + -L$ODLA_LIB -lodla_dnnl -Wl,-rpath=$ODLA_LIB + +$out/test $model_path/test_image $model_path/test_label | tee $2 +# RUN: FileCheck --input-file %t.2 %s + +# CHECK: Accuracy 919{{.*}}/10000 (91.9{{.*}}%) \ No newline at end of file diff --git a/models/vision/classification/ntsnet/get_model.py b/models/vision/classification/ntsnet/get_model.py new file mode 100755 index 000000000..ff83757bb --- /dev/null +++ b/models/vision/classification/ntsnet/get_model.py @@ -0,0 +1,8 @@ +import torch +import torch.onnx +model = torch.hub.load('nicolalandro/ntsnet-cub200', 'ntsnet', pretrained=True) +torch.onnx.export(model, torch.rand(1, 3, 448, 448), 'ntsnet.onnx', export_params=True, + opset_version=10, do_constant_folding=True, + input_names=['input'], output_names=['output']) + +# RuntimeError: ONNX export failed on an operator with unrecognized namespace torchvision::nms. If you are trying to export a custom operator, make sure you registered it with the right domain and version. \ No newline at end of file