diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bd5edbd1a467666f67c66be132b3a9d9bbd2d540..8bcc4738d02d7f07a497131d74f9a0ff6f119048 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,15 +14,20 @@ cache: - hpvm/llvm/ when: always -build: +build-and-test: stage: build tags: - hpvm script: - - pwd - source activate hpvm && cd hpvm + - mv /root/cfe-9.0.0.src.tar.xz /root/llvm-9.0.0.src.tar.xz ./ + - mv /root/model_params ./test/dnn_benchmarks - ./install.sh -j32 -t "X86" DCMAKE_BUILD_TYPE=Release - - cd .. + - cd build + - make -j32 check-hpvm-pass + - make -j32 check-hpvm-dnn + - make -j32 check-hpvm-profiler + - make -j32 check-hpvm-torch2hpvm only: - hpvm-release-exp - merge_requests diff --git a/hpvm/docs/components/hpvm-profiler.rst b/hpvm/docs/components/hpvm-profiler.rst index 8a0e6603d3b7111d2735a86b5db26d7aa834ebb6..820456799ddf0570be6b92564e35077e31fcd3da 100644 --- a/hpvm/docs/components/hpvm-profiler.rst +++ b/hpvm/docs/components/hpvm-profiler.rst @@ -1,6 +1,6 @@ HPVM Profiler API ====================== -.. autofunction:: hpvm_profiler.profile_configs +.. autofunction:: hpvm_profiler.profile_config_file .. autofunction:: hpvm_profiler.plot_hpvm_configs diff --git a/hpvm/docs/getting-started.rst b/hpvm/docs/getting-started.rst index 82a582283e7f7071a77ef55c1e2d9eca5fa9668d..6976fa012112eace8bc842658d5ea28b31ff04b6 100644 --- a/hpvm/docs/getting-started.rst +++ b/hpvm/docs/getting-started.rst @@ -207,14 +207,14 @@ we obtained in the tuning step. .. code-block:: python - from hpvm_profiler import profile_configs, plot_hpvm_configs + from hpvm_profiler import profile_config_file, plot_hpvm_configs # Set `target_binary` to the path of the plain binary. target_binary = "./alexnet2_cifar10/build/alexnet2_cifar10" # Set `config_file` to the config file produced in tuning, such as "hpvm_confs.txt". config_file = "hpvm_confs.txt" out_config_file = "hpvm_confs_profiled.txt" - profile_configs(target_binary, config_file, out_config_file) + profile_config_file(target_binary, config_file, out_config_file) plot_hpvm_configs(out_config_file, "configs_profiled.png") ``hpvm_confs_profiled.txt`` contains the profiled configurations in HPVM format, diff --git a/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py b/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py index 4e91fbbe4a4af2c16b7583443360a09d88b0ac61..baaf645cb9f5a1c0f7f71a9d9b01269206a9cf18 100644 --- a/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py +++ b/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py @@ -1,19 +1,18 @@ -from dataclasses import dataclass from pathlib import Path from subprocess import PIPE, CalledProcessError from typing import Iterable, List, Tuple, Union import matplotlib.pyplot as plt -from tqdm import trange PathLike = Union[Path, str] conf_opening, conf_closing = "+++++", "-----" -def profile_configs( +def profile_config_file( binary_path: PathLike, config_path: PathLike, output_config_path: PathLike, + progress_bar: bool = True, profile_filename: str = "profile_info.txt", qos_filename: str = "final_accuracy", ) -> None: @@ -33,39 +32,69 @@ def profile_configs( It contains a single float number as the QoS of this run. This defaults to "final_accuracy" and should not be changed for HPVM binaries. """ - - from subprocess import check_call - from tempfile import NamedTemporaryFile - # Read first line ("the float") and configs in config file header, configs = read_hpvm_configs(Path(config_path)) if not configs: raise ValueError("Config file with no configs is unsupported.") - temp_file = NamedTemporaryFile("w") - baseline_time, baseline_acc = None, None - for idx in trange(len(configs), desc="Configs profiled"): - config = configs[idx] - # Write config to temp config file - write_hpvm_config(header, [config], Path(temp_file.name)) - # Run binary_path binary, - # which generates `profile_filename` and `qos_filename` file in cwd. - try: - check_call([str(binary_path), "-c", str(temp_file.name)]) - except CalledProcessError as e: - print("Output from the program:") - print(e.output) - raise e - # Read these two files for time and QoS info. - time = _read_profile_file(Path(profile_filename)) - acc = _read_qos_file(Path(qos_filename)) - if idx == 0: - baseline_time, baseline_acc = time, acc - continue - assert baseline_time is not None and baseline_acc is not None + # Modifies configs in place. + profile_configs( + binary_path, + configs[1:], + configs[0], + progress_bar, + profile_filename, + qos_filename, + ) + write_hpvm_configs(header, configs, Path(output_config_path)) + + +def profile_configs( + binary_path: PathLike, + configs: Iterable["Config"], + baseline_config: "Config", + progress_bar: bool = True, + profile_filename: str = "profile_info.txt", + qos_filename: str = "final_accuracy", +) -> None: + """Profile a sequence of HPVM configs. + This function modifies argument `configs` in place.""" + + from tqdm import tqdm + + baseline_time, baseline_acc = measure_config(binary_path, baseline_config) + iterable = tqdm(configs, desc="Configs profiled") if progress_bar else configs + for config in iterable: + time, acc = measure_config(binary_path, config, profile_filename, qos_filename) speedup = baseline_time / time config.update_profile_results(speedup, acc, baseline_acc) - write_hpvm_config(header, configs, Path(output_config_path)) + return configs + + +def measure_config( + binary_path: PathLike, + config: "Config", + profile_filename: str = "profile_info.txt", + qos_filename: str = "final_accuracy", +): + from subprocess import check_call + from tempfile import NamedTemporaryFile + import os + + temp_file = NamedTemporaryFile("w") + write_hpvm_configs("0.0", [config], Path(temp_file.name)) + # Run binary_path binary, + # which generates `profile_filename` and `qos_filename` file in cwd. + try: + with open(os.devnull, "w") as f: + check_call([str(binary_path), "-c", str(temp_file.name)], stdout=f) + except CalledProcessError as e: + print("Output from the program:") + print(e.output) + raise e + time = _read_profile_file(Path(profile_filename)) + acc = _read_qos_file(Path(qos_filename)) temp_file.close() + return time, acc def plot_hpvm_configs( @@ -102,19 +131,27 @@ def plot_hpvm_configs( return fig -@dataclass class Config: - conf_name: str - speedup: float - energy: float - qos: float - qos_loss: float - # We don't care about the information in this part, and we don't parse this. - config_body: List[str] + def __init__( + self, + conf_name: str, + speedup: float, + energy: float, + qos: float, + qos_loss: float, + config_body: List[str], + ): + self.conf_name = conf_name + self.speedup = speedup + self.energy = energy + self.qos = qos + self.qos_loss = qos_loss + # We don't care about the information in this part, and we don't parse this. + self.config_body = config_body def update_profile_results(self, speedup: float, qos: float, base_qos: float): recorded_base_qos = self.qos + self.qos_loss - if abs(recorded_base_qos - base_qos) > 0.02: + if abs(recorded_base_qos - base_qos) > 0.025: raise ValueError( f"Baseline QoS mismatch. Original: {recorded_base_qos}, measured: {base_qos}" ) @@ -157,15 +194,13 @@ def read_hpvm_configs(config_file: PathLike) -> Tuple[str, List[Config]]: return header, ret_configs -def write_hpvm_config(header: str, configs: Iterable[Config], to_file: PathLike): - +def write_hpvm_configs(header: str, configs: Iterable[Config], to_file: PathLike): text_segs = [header] + [str(config) for config in configs] with open(to_file, "w") as f: f.write("\n".join(text_segs)) f.flush() - def _read_profile_file(profile_file_path: Path): with profile_file_path.open() as f: target_lines = [line.strip() for line in f if "Total Time" in line] diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/compile.py b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py index 172448a60d4f65fc4aafc09c9a76d9cb492ff7b0..d53776b363595dd10b8f46f792474b941f444f2b 100644 --- a/hpvm/projects/torch2hpvm/torch2hpvm/compile.py +++ b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py @@ -173,6 +173,8 @@ class ModelExporter: args = [ "hpvm-clang", + "-O3", + "-fno-exceptions", str(self.codefile), str(output_binary), *self.compile_args, diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py b/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py index a088e6eae5c7cd8fb3db62f5046aa5d9ac945726..5c248f829adef15093b853891927f353aca30c4b 100644 --- a/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py +++ b/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py @@ -198,12 +198,6 @@ class _Pool2DNode(DFGNode, abc.ABC): [self.pool_type, *self.kernel_shape, *self.pads, *self.strides,], ) - def hpvm_codegen(self): - return ( - "__hpvm__tensor_pool_max", - [*self.kernel_shape, *self.pads, *self.strides], - ) - def get_flops(self) -> int: input0 = self.input_shapes[0] return np.prod(input0) if input0 else 0 @@ -214,12 +208,24 @@ class MaxPool2DNode(_Pool2DNode): op_type = "MaxPool2D" hpvm_op_type = "maxpool" + def hpvm_codegen(self): + return ( + "__hpvm__tensor_pool_max", + [*self.kernel_shape, *self.pads, *self.strides], + ) + class AveragePool2DNode(_Pool2DNode): pool_type = "1" op_type = "AveragePool2D" hpvm_op_type = "avgpool" + def hpvm_codegen(self): + return ( + "__hpvm__tensor_pool_mean", + [*self.kernel_shape, *self.pads, *self.strides], + ) + class BiasAddNode(DFGNode): op_type = "BiasAdd" diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in b/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in index 1f6dd875ffa6b39ab57609d7690c9a9ad3944b44..fa252a3e0ce063697d56e771afbfbde69d0c5641 100644 --- a/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in +++ b/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> {% for node in nodes %} diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm_inspect.cpp.in b/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm_inspect.cpp.in index 94a8e0a534c04b323b4b66f369ab2d624a2a745f..8074704ece0988d7897c1e93b41f1ea3c43deb35 100644 --- a/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm_inspect.cpp.in +++ b/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm_inspect.cpp.in @@ -2,7 +2,6 @@ #include <string> #include <array> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> // For writing binary to file descriptors diff --git a/hpvm/test/CMakeLists.txt b/hpvm/test/CMakeLists.txt index 3c4f26472317f511edaab98c5e4a4f8ed7ba2dfb..4ff98a5386d91ce50b755d7e507a84e0fbe1c4dd 100644 --- a/hpvm/test/CMakeLists.txt +++ b/hpvm/test/CMakeLists.txt @@ -8,5 +8,6 @@ set(CLANG_CXX ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/clang++) add_subdirectory(hpvm_pass) # Passes test suite add_subdirectory(benchmarks) add_subdirectory(dnn_benchmarks/hpvm-c) # HPVM-C DNN accuracy test suite +add_subdirectory(dnn_benchmarks/pytorch) # Torch frontend test suite add_subdirectory(dnn_benchmarks/tensor-rt-src) # tensor_runtime DNN (build only, no tests) add_subdirectory(dnn_benchmarks/profiling) # hpvm-profiler test suite diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt b/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt index 9f34317d34157d57468c60cb854828b5c54f1cde..f56312e9c3dabf22731bdc910672748c67ddf50d 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt +++ b/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt @@ -12,7 +12,7 @@ function(compile_hpvm_c target_name src_filepath codegen_target) DEPENDS ${generated_file_path} hpvm-clang COMMAND hpvm-clang ${generated_file_path} ${output_bin_path} -O3 -fno-exceptions - -t ${codegen_target} -I ${CMAKE_CURRENT_SOURCE_DIR}/include ${ARGN} + -t ${codegen_target} ${ARGN} ) add_custom_target(${target_name} DEPENDS ${output_bin_path}) set(test_compile_targets ${test_compile_targets} ${target_name} PARENT_SCOPE) @@ -49,16 +49,17 @@ foreach(dir ${entries}) endforeach(dir) # Install an accuracy comparator under build/bin for test suite. -set(BIN_DIR ${LLVM_BINARY_DIR}/${LLVM_TOOLS_INSTALL_DIR}) +set(BIN_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) add_custom_command( OUTPUT ${BIN_DIR}/check_dnn_acc.py COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/check_dnn_acc.py ${BIN_DIR} COMMAND chmod +x ${BIN_DIR}/check_dnn_acc.py DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/check_dnn_acc.py ) +add_custom_target(check_dnn_acc DEPENDS ${BIN_DIR}/check_dnn_acc.py) message(STATUS "List of HPVM-C DNN benchmarks: ${test_compile_targets}") -add_custom_target(dnn_benchmarks DEPENDS ${test_compile_targets} ${BIN_DIR}/check_dnn_acc.py) +add_custom_target(dnn_benchmarks DEPENDS ${test_compile_targets}) message(STATUS "Target name for compiling all DNN benchmarks: dnn_benchmarks") # --[ llvm-lit test setup @@ -73,6 +74,6 @@ configure_lit_site_cfg( ) add_lit_testsuite(check-hpvm-dnn "Running HPVM DNNs" ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS dnn_benchmarks # Compile all dnn benchmarks to run them + DEPENDS dnn_benchmarks check_dnn_acc # Compile all dnn benchmarks to run them ARGS "-j1" # Run DNN benchmarks sequentially ) diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10.cpp index 39f49784d76470c4e0bab213127369806e1e2531..2faf1413bcdb7c87e280107d38913ae86740a414 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10_cudnn.cpp index dafd1a6ae084c4e1bf819ce1ac94e667c696eb24..bca6ca47cd48015524b496b90219f24e1f27ddb9 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet2_cifar10/alexnet2_cifar10_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10.cpp index 64350c590bb181fa4eaab4b2bf5fb37f69e11c09..d274d52ec18af99393f47d9fdb69b0b593dcbefc 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10_cudnn.cpp index 72af2ff4a1b33aabac427d203101c32c4a7403c7..e82985d04fea11c1d30079e4eacbbee81c95080a 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_cifar10/alexnet_cifar10_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet.cpp index 37e7a34a51a14b6903d549f271d3c0c83822fec8..c058e913c9f7c5bca6eb304759a380d319495caf 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet.cpp @@ -1,7 +1,6 @@ #include <config.h> #include <hpvm.h> #include <string> -#include <tensorTypes.h> #include <tensorUtils.h> void var_0_node(void *t1, size_t bytes_t1, void *t2, size_t bytes_t2) { diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet_cudnn.cpp index 1206d7bac4b9dcff2b4cfd7183f4a3e5f65d73d9..26e717fd732567eb9e6b97f19c60428e564fc9e5 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/alexnet_imagenet/alexnet_imagenet_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist.cpp index d7ab4238ebac5598b92c432aced85a602bb5ce89..8185d9dc69b6899cad46833d71d18be01653bfb3 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist_cudnn.cpp index 26acc65a99287ea9f20e037dd996635315d76e48..a0cd32151e5743d51df34edbe041e0fe8485aced 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/lenet_mnist/lenet_mnist_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10.cpp index 5f8c63dbfbfb800dc6f60f9ed9a6108dee0a9a48..77b448d81d1b352f8ac4ee9e3fc943e69f466772 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10_cudnn.cpp index 2070089053ef0b6e7e0ca33c2c6cc4cea17b8e29..adb140bd699e74be7199f54888ee4249e5515004 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/mobilenet_cifar10/mobilenet_cifar10_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10.cpp index 5b580f26821e67cc96c8347e485b792f40105176..ef94b055bd6a741405c4c9da55958143d3b8c4d1 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10.cpp @@ -1,7 +1,6 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10_cudnn.cpp index 735e2c9abab91f00560faa5496e234321027b82c..ecfa22957352ca2c418c5beb9b041762da9b6de9 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet18_cifar10/resnet18_cifar10_cudnn.cpp @@ -1,7 +1,6 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet.cpp index 160563064cc47effd463c4915b0c7f0d93bff56f..37a4111411229602ca18f806c2186af54728081e 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet_cudnn.cpp index c5cf2cb3a0177a5cce9ad0cf460484e63ded0ecd..1ac5141bca54d7dc60bb63c09cde9dcb8f8c6d32 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/resnet50_imagenet/resnet50_imagenet_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10.cpp index bec6139c2d089e90d09fa239e1b15c9a835fd4ea..c1de0703df94b3f27dfd55b0379377ecf5f0edbe 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10_cudnn.cpp index 4fa7d5c121bacff122821fe983ed443e3c6db249..7bda1213358d0c37d16623425bf19bace4d3a715 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar10/vgg16_cifar10_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100.cpp index 8666030fba4390d29d9324f5a5c7d60324325f05..bee78428df49c52f06bfa618afd7920d113e1647 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100_cudnn.cpp index 6d01caa3b7c0875cff4f3e16131ddd09195e92b7..c12855437b28686528ff4c916a987bfa7b2f280e 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_cifar100/vgg16_cifar100_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet.cpp index b1b2b4f2e312b6372e10a2fce3ef12eab2dddded..b046f4255185e47b44be1a78ca29c05189fc894b 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet_cudnn.cpp b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet_cudnn.cpp index eb29e45805671072428318412f27b05d0da90199..b06c992f3c2108544676c6e7f27810e3ef7244fc 100644 --- a/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet_cudnn.cpp +++ b/hpvm/test/dnn_benchmarks/hpvm-c/benchmarks/vgg16_imagenet/vgg16_imagenet_cudnn.cpp @@ -1,6 +1,5 @@ #include <string> #include <hpvm.h> -#include <tensorTypes.h> #include <tensorUtils.h> #include <config.h> diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/include/tensorTypes.h b/hpvm/test/dnn_benchmarks/hpvm-c/include/tensorTypes.h deleted file mode 100644 index 726080efe7e1a06363e7fca191f9708219d5baeb..0000000000000000000000000000000000000000 --- a/hpvm/test/dnn_benchmarks/hpvm-c/include/tensorTypes.h +++ /dev/null @@ -1,39 +0,0 @@ - -#ifndef TYPES_HEADER -#define TYPES_HEADER - - -/*struct Dimension_t{ - int num_dims; - size_t* dim_sizes; -}; - - -struct Tensor_t{ - int tensor_id; // used for indexing (in the tensor runtime) - int data_type; // {float_type, double_type, half_type, int_type} - int data_format; // {nchw, nhwc} - void* host_data; - size_t num_elems; // Total elements - size_t size_in_bytes; // Total size in bytes - struct Dimension_t dims; -}; - - -enum Tensor_type_t{ - float_type, - double_type, - half_type, - int_type -}; - - -// NOTE: Currently only NCHW is supported due to limited cuDNN support -enum Tensor_format_t{ - nchw, - nhwc -}; - -*/ - -#endif diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/include/tensorUtils.h b/hpvm/test/dnn_benchmarks/hpvm-c/include/tensorUtils.h deleted file mode 100644 index 1d5ac7d908b0990f21de885c645786997640264c..0000000000000000000000000000000000000000 --- a/hpvm/test/dnn_benchmarks/hpvm-c/include/tensorUtils.h +++ /dev/null @@ -1,758 +0,0 @@ - -// Header guards -#ifndef UTILS_HEADER -#define UTILS_HEADER - -#include <sstream> -#include <vector> -#include <bits/stdc++.h> -#include <tensor_runtime.h> -#include <tensor.h> -#include <cmath> - -std::vector<float> run_accuracies; - -void printTensorInfo(void *tensor_ptr) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - if (tensor->gpu_data != NULL) { - printf("Successful cudaMalloc \n"); - } - - printf("tensor dims = %d \n", tensor->dims.num_dims); - printf("dim1_size = %lu \n", tensor->dims.dim_sizes[0]); - printf("dim2_size = %lu \n", tensor->dims.dim_sizes[1]); - printf("num_elems = %lu \n", tensor->num_elems); -} - -// FIXIT: Move this to debug.h and include in all files -void dumpWeightsToFile(char *file_name, void *weights_ptr) { - - struct Tensor *weights = (Tensor *)weights_ptr; - // Move data back to host - hpvm_request_tensor(weights, 0); - - FILE *fp = fopen(file_name, "wb"); - if (fp == NULL) { - printf("File %s could not be created. Check if directory exists \n", - file_name); - abort(); - } - - // printf("size_in_bytes = %lu \n", weights->size_in_bytes); - size_t bytes_written = - fwrite(weights->host_data, 1, weights->size_in_bytes, fp); - // printf("bytes_written = %lu \n", bytes_written); - fclose(fp); -} - -void fillTensorWithOnes(void *tensor_ptr) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - hpvm_request_tensor(tensor, 0); - - // initialization is specific to the floating point type - if (tensor->data_type == CUDNN_DATA_FLOAT) { - float *data_arr = (float *)tensor->host_data; - for (unsigned int i = 0; i < tensor->num_elems; i++) { - data_arr[i] = 1.0; - } - } -} - -void fillWithOnesAndTwos(void *tensor_ptr) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - hpvm_request_tensor(tensor, 0); - - // initialization is specific to the floating point type - if (tensor->data_type == CUDNN_DATA_FLOAT) { - float *data_arr = (float *)tensor->host_data; - for (unsigned int i = 0; i < tensor->num_elems / 2; i++) { - data_arr[i] = 1.0; - } - - for (unsigned int i = tensor->num_elems / 2; i < tensor->num_elems; i++) { - data_arr[i] = 2.0; - } - } -} - -void fillTensorWithVal(void *tensor_ptr, float target_value) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - hpvm_request_tensor(tensor, 0); - - // initialization is specific to the floating point type - if (tensor->data_type == CUDNN_DATA_FLOAT) { - float *data_arr = (float *)tensor->host_data; - for (unsigned int i = 0; i < tensor->num_elems; i++) { - data_arr[i] = target_value; - } - } -} - -void fillTensorWithNegOnes(void *tensor_ptr) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - hpvm_request_tensor(tensor, 0); - - // initialization is specific to the floating point type - if (tensor->data_type == CUDNN_DATA_FLOAT) { - float *data_arr = (float *)tensor->host_data; - for (unsigned int i = 0; i < tensor->num_elems; i++) { - data_arr[i] = -1.0; - } - } -} - -void fillTensorVals(void *tensor_ptr) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - // initialization is specific to the floating point type - if (tensor->data_type == CUDNN_DATA_FLOAT) { - float *data_arr = (float *)tensor->host_data; - for (unsigned int i = 0; i < tensor->num_elems; i++) { - data_arr[i] = i + 1; - } - } -} - -void printTensorValues(void *tensor_ptr) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - hpvm_request_tensor(tensor, 0); - - // printing is specific to the floating point type - if (tensor->data_type == CUDNN_DATA_FLOAT) { - float *data_arr = (float *)tensor->host_data; - for (unsigned int i = 0; i < tensor->num_elems; i++) { - printf("%f,", data_arr[i]); - } - } - - printf("\n"); -} - -void printTensorDims(void *tensor_ptr) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - printf("Num_elems = %lu \n", tensor->num_elems); - for (int i = 0; i < tensor->dims.num_dims; i++) { - printf("dim[%d] = %lu \n", i, tensor->dims.dim_sizes[i]); - } -} - -void compareTensors(void *tensor1_ptr, void *tensor2_ptr) { - - struct Tensor *tensor1 = (struct Tensor *)tensor1_ptr; - struct Tensor *tensor2 = (struct Tensor *)tensor2_ptr; - - hpvm_request_tensor(tensor1, 0); - hpvm_request_tensor(tensor2, 0); - - float *tensor_data1 = (float *)tensor1->host_data; - float *tensor_data2 = (float *)tensor2->host_data; - - for (unsigned int i = 0; i < tensor1->num_elems; i++) { - if (tensor_data1[i] != tensor_data2[i]) { - printf("Tensor data mismatch at index %d \n", i); - abort(); - } - } -} - -void compareValues(void *tensor_ptr, float *data, size_t num_elems) { - - struct Tensor *tensor = (struct Tensor *)tensor_ptr; - - hpvm_request_tensor(tensor, 0); - - float *tensor_data = (float *)tensor->host_data; - for (unsigned int i = 0; i < num_elems; i++) { - if (tensor_data[i] != data[i]) { - printf("Tensor data mismatch"); - abort(); - } - } -} - -void *readInputTensor(const char *file_name, int data_type, int dim1_size, - int dim2_size, int dim3_size, int dim4_size) { - - int type_size = 4; // NOTE: Assuming floating point tensors - int num_elems = dim1_size * dim2_size * dim3_size * dim4_size; - int size_in_bytes = type_size * dim1_size * dim2_size * dim3_size * dim4_size; - uint8_t *file_data = (uint8_t *)malloc(sizeof(char) * num_elems); - float *tensor_data = (float *)malloc(sizeof(float) * num_elems); - int file_header_size = 16; - - FILE *file = fopen(file_name, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting... \n", file_name); - abort(); - } - - fseek(file, file_header_size, SEEK_CUR); // Skipping the file header - size_t bytes_read = fread(file_data, 1, sizeof(uint8_t) * num_elems, file); - - fclose(file); - - for (size_t i = 0; i < num_elems; ++i) { - tensor_data[i] = (float)file_data[i] / 255.0f; - } - - // NOTE: Using NCHW format - struct Tensor *input = (struct Tensor *)create4DTensor( - data_type, nchw, dim1_size, dim2_size, dim3_size, dim4_size); - - initTensorData(input, tensor_data, size_in_bytes); - // compareValues(input, tensor_data, num_elems); - - return input; -} - -//*** FIXIT: Move this to CPU-only -struct Tensor *readTrainedWeightsCPU(const char *file_name, int data_type, - int dim1_size, int dim2_size, - int dim3_size, int dim4_size) { - - // FIXIT: Don't assume floating point types - int type_size = 4; // NOTE: Assuming floating point tensors - long int num_elems = dim1_size * dim2_size * dim3_size * dim4_size; - long int size_in_bytes = - type_size * dim1_size * dim2_size * dim3_size * dim4_size; - float *tensor_data = (float *)malloc(sizeof(float) * num_elems); - int file_header_size = 0; - - FILE *file = fopen(file_name, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting... \n", file_name); - abort(); - } - - fseek(file, file_header_size, SEEK_CUR); // Skipping the file header - size_t bytes_read = fread(tensor_data, 1, size_in_bytes, file); - - printf("size in bytes = %lu, bytes read = %lu \n", size_in_bytes, bytes_read); - - fclose(file); - - struct Tensor *weights = (struct Tensor *)create4DTensor( - data_type, nchw, dim1_size, dim2_size, dim3_size, dim4_size); - - initTensorData(weights, tensor_data, size_in_bytes); - // compareValues(weights, tensor_data, num_elems); - free(tensor_data); - - return weights; -} - -struct Tensor *readTrainedWeights(const char *file_name, int data_type, - long int dim1_size, long int dim2_size, - long int dim3_size, long int dim4_size) { - - // FIXIT: Don't assume floating point types - int type_size = 4; // NOTE: Assuming floating point tensors - long int num_elems = dim1_size * dim2_size * dim3_size * dim4_size; - long int size_in_bytes = - type_size * dim1_size * dim2_size * dim3_size * dim4_size; - float *tensor_data = (float *)malloc(sizeof(float) * num_elems); - printf("size_in_bytes = %lu \n", size_in_bytes); - - int file_header_size = 0; - - FILE *file = fopen(file_name, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting... \n", file_name); - abort(); - } - - fseek(file, file_header_size, SEEK_CUR); // Skipping the file header - size_t bytes_read = fread(tensor_data, 1, size_in_bytes, file); - - // printf("size in bytes = %lu, bytes read = %lu \n", size_in_bytes, - // bytes_read); - - fclose(file); - - struct Tensor *weights = (struct Tensor *)create4DTensor( - data_type, nchw, dim1_size, dim2_size, dim3_size, dim4_size); - - initTensorData(weights, tensor_data, size_in_bytes); - // compareValues(weights, tensor_data, num_elems); - free(tensor_data); - - return weights; -} - -struct Tensor *readInputBatch(const char *file_name, long data_type, long start, - long end, long dim2_size, long dim3_size, - long dim4_size) { - - long int dim1_size = end - start; - // FIXIT: Don't assume floating point types - long int type_size = 4; // NOTE: Assuming floating point tensors - long int num_elems = dim1_size * dim2_size * dim3_size * dim4_size; - long int size_in_bytes = - type_size * dim1_size * dim2_size * dim3_size * dim4_size; - float *tensor_data = (float *)malloc(sizeof(float) * num_elems); - long int file_header_size = - type_size * start * dim2_size * dim3_size * dim4_size; - - FILE *file = fopen(file_name, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting... \n", file_name); - abort(); - } - - fseek(file, file_header_size, SEEK_SET); // Skipping the file header - size_t bytes_read = fread(tensor_data, 1, size_in_bytes, file); - - fclose(file); - - // printf ("FIXED input BATCH read \n"); - - struct Tensor *weights = (struct Tensor *)create4DTensor( - data_type, nchw, dim1_size, dim2_size, dim3_size, dim4_size); - - initTensorData(weights, tensor_data, size_in_bytes); - free(tensor_data); - - return weights; -} - -uint8_t *readLabels(const char *labels_file, int num_labels) { - - uint8_t *labels = (uint8_t *)malloc(sizeof(uint8_t) * num_labels); - FILE *file = fopen(labels_file, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting...\n", labels_file); - abort(); - } - - size_t bytes_read = fread(labels, 1, sizeof(uint8_t) * num_labels, file); - - fclose(file); - - return labels; -} - -uint32_t *readLabels3(const char *labels_file, int num_labels) { - - uint32_t *labels = (uint32_t *)malloc(sizeof(uint32_t) * num_labels); - FILE *file = fopen(labels_file, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting...\n", labels_file); - abort(); - } - - size_t bytes_read = fread(labels, 1, sizeof(uint32_t) * num_labels, file); - - fclose(file); - - return labels; -} - -uint8_t *readLabelsBatch(const char *labels_file, int start, int end) { - - int num_labels = end - start; - int file_header_size = sizeof(uint8_t) * start; - - uint8_t *labels = (uint8_t *)malloc(sizeof(uint8_t) * num_labels); - FILE *file = fopen(labels_file, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting...\n", labels_file); - abort(); - } - - fseek(file, file_header_size, SEEK_SET); // Skipping the file header - - size_t bytes_read = fread(labels, 1, sizeof(uint8_t) * num_labels, file); - - fclose(file); - - // printf("--labels bytes_read = %lu \n", bytes_read); - return labels; -} - -uint32_t *readLabelsBatch3(const char *labels_file, int start, int end) { - - int num_labels = end - start; - int file_header_size = sizeof(uint32_t) * start; - - uint32_t *labels = (uint32_t *)malloc(sizeof(uint32_t) * num_labels); - FILE *file = fopen(labels_file, "rb"); - if (file == NULL) { - printf("Data file %s is not found. Aborting...\n", labels_file); - abort(); - } - - fseek(file, file_header_size, SEEK_SET); // Skipping the file header - - size_t bytes_read = fread(labels, 1, sizeof(uint32_t) * num_labels, file); - - fclose(file); - - return labels; -} - -void computeAccuracy(const char *labels_file, int num_labels, - void *result_ptr) { - - struct Tensor *result = (struct Tensor *)result_ptr; - - uint8_t *labels = readLabels(labels_file, num_labels); - size_t batch_dim = result->dims.dim_sizes[0]; - size_t channels = result->dims.dim_sizes[1]; - float *data = (float *)result->host_data; - int num_errors = 0; - - for (int i = 0; i < batch_dim; i++) { - int chosen = 0; - for (int id = 1; id < 10; ++id) { - if (data[i * channels + chosen] < data[i * channels + id]) - chosen = id; - } - - // printf("chosen = %d, label = %d \n", chosen, labels[i]); - if (chosen != labels[i]) - num_errors++; - } - - float accuracy = ((batch_dim - num_errors) * 1.0 / batch_dim * 1.0) * 100.0; - printf("****** Accuracy = %f \n\n", accuracy); - - FILE *fp = fopen("final_accuracy", "w+"); - if (fp != NULL) { - - std::ostringstream ss; - ss << std::fixed << accuracy; - std::string print_str = ss.str(); - - fwrite(print_str.c_str(), 1, print_str.length(), fp); - fclose(fp); - } -} - -// NOTE: batch_size and num_classes are Unused arguments -float computeAccuracy2(uint8_t *labels, int batch_size, void *result_ptr, - size_t num_classes = 10) { - - struct Tensor *result = (struct Tensor *)result_ptr; - - size_t batch_dim = result->dims.dim_sizes[0]; - num_classes = result->dims.dim_sizes[1]; - float *data = (float *)result->host_data; - int num_errors = 0; - - printf("batch_dim = %lu, channels = %lu \n", batch_dim, num_classes); - - for (unsigned int i = 0; i < batch_dim; i++) { - - int chosen = 0; - for (int id = 1; id < num_classes; ++id) { - if (data[i * num_classes + chosen] < data[i * num_classes + id]) - chosen = id; - } - - if (chosen != labels[i]) - num_errors++; - } - - float accuracy = ((batch_dim - num_errors) * 1.0 / batch_dim * 1.0) * 100.0; - printf("****** Accuracy = %f \n\n", accuracy); - - FILE *fp = fopen("final_accuracy", "w+"); - if (fp != NULL) { - - std::ostringstream ss; - ss << std::fixed << accuracy; - std::string print_str = ss.str(); - - fwrite(print_str.c_str(), 1, print_str.length(), fp); - } - - fclose(fp); - - return accuracy; -} - -float computeAccuracy3(uint32_t *labels, void *result_ptr) { - - struct Tensor *result = (struct Tensor *)result_ptr; - - size_t batch_dim = result->dims.dim_sizes[0]; - size_t num_classes = result->dims.dim_sizes[1]; - float *data = (float *)result->host_data; - int num_errors = 0; - - printf("batch_dim = %lu, num_classes = %lu \n", batch_dim, num_classes); - - for (int i = 0; i < batch_dim; i++) { - - int chosen = 0; - for (int id = 1; id < num_classes; ++id) { - if (data[i * num_classes + chosen] < data[i * num_classes + id]) - chosen = id; - } - - if (chosen != labels[i]) - num_errors++; - } - - float accuracy = ((batch_dim - num_errors) * 1.0 / batch_dim * 1.0) * 100.0; - printf("****** Accuracy = %f \n\n", accuracy); - - FILE *fp = fopen("final_accuracy", "w+"); - if (fp != NULL) { - - std::ostringstream ss; - ss << std::fixed << accuracy; - std::string print_str = ss.str(); - - fwrite(print_str.c_str(), 1, print_str.length(), fp); - } - - fclose(fp); - - return accuracy; -} - -struct ClassProb { - float prob; - int index; -}; - -bool descendFloatComp(ClassProb obj1, ClassProb obj2) { - return obj1.prob > obj2.prob; -} - -float computeTop5Accuracy(uint8_t *labels, int num_labels, void *result_ptr, - unsigned num_classes = 10) { - - struct Tensor *result = (struct Tensor *)result_ptr; - - size_t batch_dim = result->dims.dim_sizes[0]; - size_t channels = result->dims.dim_sizes[1]; - float *data = (float *)result->host_data; - int num_errors = 0; - - printf("batch_dim = %lu, channels = %lu \n", batch_dim, channels); - - for (int i = 0; i < num_labels; i++) { - - std::vector<ClassProb> elem_probs; - for (int id = 0; id < num_classes; ++id) { - ClassProb cProb; - cProb.prob = data[i * channels + id]; - cProb.index = id; - elem_probs.push_back(cProb); - } - - std: - sort(elem_probs.begin(), elem_probs.end(), descendFloatComp); - // Check if any of top-5 predictions matches - bool matched = false; - for (int j = 0; j < 5; j++) { - ClassProb cProb = elem_probs[j]; - if (cProb.index == labels[i]) - matched = true; - } - - if (!matched) - num_errors += 1; - } - - float accuracy = ((batch_dim - num_errors) * 1.0 / batch_dim * 1.0) * 100.0; - printf("****** Accuracy = %f \n\n", accuracy); - - FILE *fp = fopen("final_accuracy", "w+"); - if (fp != NULL) { - - std::ostringstream ss; - ss << std::fixed << accuracy; - std::string print_str = ss.str(); - - fwrite(print_str.c_str(), 1, print_str.length(), fp); - } - - fclose(fp); - - return accuracy; -} - -void dumpFinalAccuracy(float accuracy) { - - printf("\n\n **** Final Accuracy = %f \n", accuracy); - - FILE *fp = fopen("final_accuracy", "w+"); - if (fp != NULL) { - std::ostringstream ss; - ss << std::fixed << accuracy; - std::string print_str = ss.str(); - - fwrite(print_str.c_str(), 1, print_str.length(), fp); - } - - fclose(fp); - - run_accuracies.push_back(accuracy); -} - -void dumpAvgPSNR(float avg_psnr) { - - FILE *fp = fopen("avg_psnr", "w+"); - if (fp != NULL) { - std::ostringstream ss; - ss << std::fixed << avg_psnr; - std::string print_str = ss.str(); - fwrite(print_str.c_str(), 1, print_str.length(), fp); - } - - fclose(fp); -} - -void dumpPSNRStd(float psnr_std) { - - FILE *fp = fopen("psnr_std.txt", "w+"); - if (fp != NULL) { - std::ostringstream ss; - ss << std::fixed << psnr_std; - std::string print_str = ss.str(); - fwrite(print_str.c_str(), 1, print_str.length(), fp); - } - - fclose(fp); -} - -void dumpExecutionAccuracies() { - - FILE *fp = fopen("run_accuracies.txt", "w+"); - if (fp != NULL) { - for (int i = 0; i < run_accuracies.size(); i++) { - float accuracy = run_accuracies[i]; - std::ostringstream ss; - ss << std::fixed << accuracy; - std::string print_str = ss.str(); - fwrite(print_str.c_str(), 1, print_str.length(), fp); - fwrite("\n", 1, 1, fp); - } - } - - fclose(fp); -} - -float readPSNRFromFile(const char *file_name) { - - float psnr; - FILE *pFile = fopen(file_name, "r"); - if (pFile == NULL) { - printf("ERROR: psnr.txt not found! \n"); - abort(); - } - - fscanf(pFile, "%f", &psnr); - printf("**** PSNR read = %f \n\n", psnr); - return psnr; -} - -float computePSNRViolation(void *gold_ptr, void *approx_ptr, - float PSNR_threshold) { - - PSNR_threshold = readPSNRFromFile("psnr.txt"); - std::vector<float> psnr_list; - - struct Tensor *gold_tensor = (struct Tensor *)gold_ptr; - struct Tensor *approx_tensor = (struct Tensor *)approx_ptr; - - size_t *dim_sizes = gold_tensor->dims.dim_sizes; - size_t batch_dim = dim_sizes[0]; - size_t image_size = dim_sizes[1] * dim_sizes[2] * dim_sizes[3]; - - printf("batch_dim = %lu, image_size = %lu \n", batch_dim, image_size); - - float *gold_data = (float *)gold_tensor->host_data; - float *approx_data = (float *)approx_tensor->host_data; - - FILE *fp = fopen("img_psnr.txt", "w+"); - - float sum_psnr = 0.0; - int num_errors = 0; - for (size_t i = 0; i < batch_dim; i++) { - float mse_sum = 0.0; - float max_val = -999999; - size_t offset = i * image_size; - - for (size_t j = 0; j < image_size; j++) { - float diff = gold_data[offset + j] - approx_data[offset + j]; - float diff_square = diff * diff; - mse_sum += diff_square; - - if (max_val < gold_data[offset + j]) { - max_val = gold_data[offset + j]; - } - } - - mse_sum = mse_sum / image_size; - float psnr = 20 * log10(255 / sqrt(mse_sum)); - - sum_psnr += psnr; - if (psnr < PSNR_threshold) - num_errors += 1; - - printf("PSNR value = %f \n", psnr); - psnr_list.push_back(psnr); - - std::ostringstream ss; - ss << std::fixed << psnr; - std::string print_str = ss.str(); - fwrite(print_str.c_str(), 1, print_str.length(), fp); - fwrite("\n", 1, 1, fp); - } - - float violation_rate = (num_errors * 1.0) / batch_dim * 100.0; - printf("*** violation_rate= %f \n\n", violation_rate); - - float avg_psnr = sum_psnr / batch_dim; - printf("*** avg_psnr = %f \n\n", avg_psnr); - dumpAvgPSNR(avg_psnr); - - float success_rate = 100.0 - violation_rate; - dumpFinalAccuracy(success_rate); - - fclose(fp); - - float var = 0.0; - for (size_t i = 0; i < batch_dim; i++) { - var = var + (psnr_list[i] - avg_psnr) * (psnr_list[i] - avg_psnr); - } - - var /= batch_dim; - float std = sqrt(var); - - dumpPSNRStd(std); - - return violation_rate; -} - -void dumpOutput(void *output_ptr, const char *file_name) { - - struct Tensor *out_tensor = (struct Tensor *)output_ptr; - size_t size_in_bytes = out_tensor->size_in_bytes; - printf("** Output size = %lu \n", size_in_bytes); - - float *host_data = (float *)out_tensor->host_data; - FILE *fd = fopen(file_name, "w+"); - fwrite(host_data, 1, size_in_bytes, fd); - fclose(fd); -} - -#endif diff --git a/hpvm/test/dnn_benchmarks/profiling/test_hpvm_c_profiling.py b/hpvm/test/dnn_benchmarks/profiling/test_hpvm_c_profiling.py index 230fdf8b73dfd7959cfaa98fe06eafe6a75087b1..853b0dc3e23a3ea847748ecaeda62650e99ee430 100755 --- a/hpvm/test/dnn_benchmarks/profiling/test_hpvm_c_profiling.py +++ b/hpvm/test/dnn_benchmarks/profiling/test_hpvm_c_profiling.py @@ -2,7 +2,7 @@ from pathlib import Path from sys import argv -from hpvm_profiler import profile_configs, read_hpvm_configs +from hpvm_profiler import profile_configs, read_hpvm_configs, write_hpvm_configs # relative to cwd() benchmarks_bindir = Path("../hpvm-c") @@ -17,4 +17,6 @@ dnn = argv[1] bench_bin_file = benchmarks_bindir / f"hpvm_{dnn}" config_file = benchmarks_srcdir / dnn / "data/tuner_confs.txt" out_config_file = f"./{dnn}.txt" -profile_configs(bench_bin_file, config_file, out_config_file) +header, configs = read_hpvm_configs(config_file) +profile_configs(bench_bin_file, configs[1:6], configs[0], progress_bar=False) +write_hpvm_configs(header, configs[:6], out_config_file) diff --git a/hpvm/test/dnn_benchmarks/pytorch/CMakeLists.txt b/hpvm/test/dnn_benchmarks/pytorch/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..778593a57ddfc3a6abcc4ed045f02614535739f8 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/CMakeLists.txt @@ -0,0 +1,18 @@ +# --[ llvm-lit test setup +# lit.cfg.py looks for tests in CMAKE_CURRENT_BINARY_DIR (see lit.cfg.py) +# as most of the tests require some kind of compilation / generation +# which is best done over there. +configure_lit_site_cfg( + ../../lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py + MAIN_CONFIG + ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py +) +add_lit_testsuite(check-hpvm-torch2hpvm "Run tests for package torch2hpvm" + ${CMAKE_CURRENT_BINARY_DIR} + # We depend on check_dnn_acc.py defined in ../hpvm-c/ + # to compare the inference accuracy of our frontend-generated binary + # to that of the baseline. + DEPENDS check_dnn_acc + ARGS "-j1" # Run frontend generation sequentially +) diff --git a/hpvm/test/dnn_benchmarks/pytorch/alexnet2_cifar10.test b/hpvm/test/dnn_benchmarks/pytorch/alexnet2_cifar10.test new file mode 100644 index 0000000000000000000000000000000000000000..4adf30226b19179be066f150b36ef3bd4a010636 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/alexnet2_cifar10.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py alexnet2_cifar10 +RUN: check_dnn_acc.py final_accuracy alexnet2_cifar10 diff --git a/hpvm/test/dnn_benchmarks/pytorch/alexnet_cifar10.test b/hpvm/test/dnn_benchmarks/pytorch/alexnet_cifar10.test new file mode 100644 index 0000000000000000000000000000000000000000..cffec91e415cda256a72de5a04abb956336519d7 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/alexnet_cifar10.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py alexnet_cifar10 +RUN: check_dnn_acc.py final_accuracy alexnet_cifar10 diff --git a/hpvm/test/dnn_benchmarks/pytorch/alexnet_imagenet.test b/hpvm/test/dnn_benchmarks/pytorch/alexnet_imagenet.test new file mode 100644 index 0000000000000000000000000000000000000000..126de1bfe80106bbd803ace37534cd38ab54a67c --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/alexnet_imagenet.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py alexnet_imagenet +RUN: check_dnn_acc.py final_accuracy alexnet_imagenet diff --git a/hpvm/test/dnn_benchmarks/pytorch/lenet_mnist.test b/hpvm/test/dnn_benchmarks/pytorch/lenet_mnist.test new file mode 100644 index 0000000000000000000000000000000000000000..b87a976bcd1bfa8d637f1298d5259bccb8781419 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/lenet_mnist.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py lenet_mnist +RUN: check_dnn_acc.py final_accuracy lenet_mnist diff --git a/hpvm/test/dnn_benchmarks/pytorch/lit.cfg.py b/hpvm/test/dnn_benchmarks/pytorch/lit.cfg.py new file mode 100644 index 0000000000000000000000000000000000000000..34473d24bea3565d0e2865c7026b43538f927ce7 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/lit.cfg.py @@ -0,0 +1,36 @@ +# -*- Python -*- + +# Configuration file for the 'lit' test runner. + +import os + +import lit.formats +from lit.llvm import llvm_config + +# name: The name of this test suite. +config.name = "HPVM-Torch2HPVM" + +# testFormat: The test format to use to interpret tests. +config.test_format = lit.formats.ShTest(False) + +# suffixes: A list of file extensions to treat as test files. This is overriden +# by individual lit.local.cfg files in the test subdirectories. +config.suffixes = [".test"] + +# test_source_root: The root path where tests are located. +config.test_source_root = os.path.dirname(__file__) + +# test_exec_root: The root path where tests should be run. +current_source_dir = os.path.dirname(os.path.relpath(__file__, config.llvm_src_root)) +current_binary_dir = os.path.join(config.llvm_obj_root, current_source_dir) +config.test_exec_root = current_binary_dir + +# Tweak the PATH to include the tools dir. +llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True) + +# Add substitution for check_dnn_acc.py which goes under build/bin. +llvm_config.add_tool_substitutions( + ["check_dnn_acc.py"], os.path.join(config.llvm_obj_root, "bin") +) +# Add substitution for our main script in this directory. +llvm_config.add_tool_substitutions(["test_frontend.py"], config.test_source_root) diff --git a/hpvm/test/dnn_benchmarks/pytorch/mobilenet_cifar10.test b/hpvm/test/dnn_benchmarks/pytorch/mobilenet_cifar10.test new file mode 100644 index 0000000000000000000000000000000000000000..9964887b420a3896c83eff0114a419ad10740dc1 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/mobilenet_cifar10.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py mobilenet_cifar10 +RUN: check_dnn_acc.py final_accuracy mobilenet_cifar10 diff --git a/hpvm/test/dnn_benchmarks/pytorch/resnet18_cifar10.test b/hpvm/test/dnn_benchmarks/pytorch/resnet18_cifar10.test new file mode 100644 index 0000000000000000000000000000000000000000..71e0881a3f6d81a2982ac3fbd2dddd849f23a08b --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/resnet18_cifar10.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py resnet18_cifar10 +RUN: check_dnn_acc.py final_accuracy resnet18_cifar10 diff --git a/hpvm/test/dnn_benchmarks/pytorch/resnet50_imagenet.test b/hpvm/test/dnn_benchmarks/pytorch/resnet50_imagenet.test new file mode 100644 index 0000000000000000000000000000000000000000..b1ff2e6a92f506da299c1f94ebec10ddd1958159 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/resnet50_imagenet.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py resnet50_imagenet +RUN: check_dnn_acc.py final_accuracy resnet50_imagenet diff --git a/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py b/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py old mode 100644 new mode 100755 index 2fb1de17ee226571e6cd6b808640bf35280932db..3c20c6ea5a472a693156b4881b58d4e0f1fc8575 --- a/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py +++ b/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py @@ -1,52 +1,56 @@ +#!/usr/bin/env python3 import os import shutil import site from pathlib import Path from subprocess import run -import torch +from sys import argv +import torch from torch2hpvm import BinDataset, ModelExporter from torch.nn import Module site.addsitedir(os.path.dirname(__file__)) import dnn -benchmarks = [ - (dnn.LeNet, 1, 28, 5000, "lenet_mnist"), - (dnn.AlexNet, 3, 32, 5000, "alexnet_cifar10"), - (dnn.AlexNet2, 3, 32, 5000, "alexnet2_cifar10"), - (dnn.AlexNetImageNet, 3, 224, 500, "alexnet_imagenet"), - (dnn.MobileNet, 3, 32, 5000, "mobilenet_cifar10"), - (dnn.ResNet18, 3, 32, 5000, "resnet18_cifar10"), - (dnn.ResNet50, 3, 224, 100, "resnet50_imagenet"), - (dnn.VGG16Cifar10, 3, 32, 5000, "vgg16_cifar10"), - (dnn.VGG16Cifar100, 3, 32, 5000, "vgg16_cifar100"), - (dnn.VGG16ImageNet, 3, 224, 100, "vgg16_imagenet"), -] +benchmarks = { + "lenet_mnist": (dnn.LeNet, 1, 28, 1000), + "alexnet_cifar10": (dnn.AlexNet, 3, 32, 500), + "alexnet2_cifar10": (dnn.AlexNet2, 3, 32, 500), + "alexnet_imagenet": (dnn.AlexNetImageNet, 3, 224, 500), + "mobilenet_cifar10": (dnn.MobileNet, 3, 32, 500), + "resnet18_cifar10": (dnn.ResNet18, 3, 32, 500), + "resnet50_imagenet": (dnn.ResNet50, 3, 224, 25), + "vgg16_cifar10": (dnn.VGG16Cifar10, 3, 32, 500), + "vgg16_cifar100": (dnn.VGG16Cifar100, 3, 32, 500), + "vgg16_imagenet": (dnn.VGG16ImageNet, 3, 224, 10), +} self_folder = Path(__file__).parent -for model_cls, nch, img_size, batch_size, pathname in benchmarks: - codegen_dir = Path(f"/tmp/{pathname}") - print(f"Generating {pathname} to {codegen_dir}") - if codegen_dir.exists(): - shutil.rmtree(codegen_dir) +netname = argv[1] +model_cls, nch, img_size, batch_size = benchmarks[netname] +codegen_dir = Path(f"./{netname}") +print(f"Generating {netname} to {codegen_dir}") +if codegen_dir.exists(): + shutil.rmtree(codegen_dir) - params = self_folder / "../model_params" / pathname - dataset_shape = 5000, nch, img_size, img_size - bin_tuneset = BinDataset( - params / "tune_input.bin", params / "tune_labels.bin", dataset_shape - ) - bin_testset = BinDataset( - params / "test_input.bin", params / "test_labels.bin", dataset_shape - ) - model: Module = model_cls() - checkpoint = self_folder / "../model_params/pytorch" / f"{pathname}.pth.tar" - model.load_state_dict(torch.load(checkpoint.as_posix())) +params = self_folder / "../model_params" / netname +dataset_shape = 5000, nch, img_size, img_size +bin_tuneset = BinDataset( + params / "tune_input.bin", params / "tune_labels.bin", dataset_shape +) +bin_testset = BinDataset( + params / "test_input.bin", params / "test_labels.bin", dataset_shape +) +model: Module = model_cls() +checkpoint = self_folder / "../model_params/pytorch" / f"{netname}.pth.tar" +model.load_state_dict(torch.load(checkpoint.as_posix())) +print(model) - build_dir = codegen_dir / "build" - target_binary = build_dir / pathname - conf_file = self_folder / "../hpvm-c/benchmarks" / pathname / "data/tuner_confs.txt" - exporter = ModelExporter( - model, bin_tuneset, bin_testset, codegen_dir, config_file=conf_file - ) - exporter.generate(batch_size=batch_size).compile(target_binary, build_dir) - run([str(target_binary), "test"], check=True) +build_dir = codegen_dir / "build" +target_binary = build_dir / netname +conf_file = self_folder / "../hpvm-c/benchmarks" / netname / "data/tuner_confs.txt" +exporter = ModelExporter( + model, bin_tuneset, bin_testset, codegen_dir, config_file=conf_file +) +exporter.generate(batch_size=batch_size).compile(target_binary, build_dir) +run([str(target_binary), "test"], check=True) diff --git a/hpvm/test/dnn_benchmarks/pytorch/vgg16_cifar10.test b/hpvm/test/dnn_benchmarks/pytorch/vgg16_cifar10.test new file mode 100644 index 0000000000000000000000000000000000000000..5544c75d2823fb31da6624e109c81567770d18ad --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/vgg16_cifar10.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py vgg16_cifar10 +RUN: check_dnn_acc.py final_accuracy vgg16_cifar10 diff --git a/hpvm/test/dnn_benchmarks/pytorch/vgg16_cifar100.test b/hpvm/test/dnn_benchmarks/pytorch/vgg16_cifar100.test new file mode 100644 index 0000000000000000000000000000000000000000..66bd69ee377b4dd84071e3c63ec631f3c041512a --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/vgg16_cifar100.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py vgg16_cifar100 +RUN: check_dnn_acc.py final_accuracy vgg16_cifar100 diff --git a/hpvm/test/dnn_benchmarks/pytorch/vgg16_imagenet.test b/hpvm/test/dnn_benchmarks/pytorch/vgg16_imagenet.test new file mode 100644 index 0000000000000000000000000000000000000000..6529998ec4e4d62d14fc6b99d42474f3161d2eb7 --- /dev/null +++ b/hpvm/test/dnn_benchmarks/pytorch/vgg16_imagenet.test @@ -0,0 +1,2 @@ +RUN: test_frontend.py vgg16_imagenet +RUN: check_dnn_acc.py final_accuracy vgg16_imagenet