From a8aa64733cf621b7c5ef83070d2a1bc409234e39 Mon Sep 17 00:00:00 2001
From: Yifan Zhao <yifanz16@illinois.edu>
Date: Mon, 1 Feb 2021 17:48:13 -0600
Subject: [PATCH] Moved hpvm-c test to use approxhpvm.py to compile as well

---
 .../test/dnn_benchmarks/hpvm-c/CMakeLists.txt | 136 ++++--------------
 1 file changed, 26 insertions(+), 110 deletions(-)

diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt b/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt
index 436c88790c..00e5ba507d 100644
--- a/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt
+++ b/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt
@@ -1,117 +1,35 @@
-# Look for CUDA again (already done in hpvm-tensor-rt) so we can include its header
-# This is not the best practice,
-# but easier than having the tensor runtime tell us which CUDA it used.
-find_package(CUDA REQUIRED)
+# First get approxhpvm.py which we then use to compile benchmarks.
+get_filename_component(APPROXHPVM_PY ${PROJECT_BINARY_DIR}/bin/approxhpvm.py REALPATH)
 
-get_filename_component(LLVM_BIN_DIR ${PROJECT_BINARY_DIR}/bin REALPATH)
-set(LLVM_OPT "${LLVM_BIN_DIR}/opt")
-set(LLVM_LINK "${LLVM_BIN_DIR}/llvm-link")
-set(CMAKE_CXX_COMPILER "${LLVM_BIN_DIR}/clang++")
-
-# Configure config.h which tells the benchmarks where's the build directory.
-# We can also use the one in tensor_runtime, but we're avoiding that trying to 
+# Configure config.h which tells the benchmarks where's the model parameter directory.
+# We can also use the one in tensor_runtime, but we're avoiding that so as to 
 # decouple things.
 set(MODEL_PARAMS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../model_params/")
 configure_file(
   "include/config.h.in"
   "${CMAKE_CURRENT_BINARY_DIR}/include/config.h"
 )
+# This will be an extra include directory (specific to these benchmarks)
+# and we'll give this to approxhpvm.py
 set(CONFIG_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
 
-# Directories to include
-set(HPVM_PROJECTS ${PROJECT_SOURCE_DIR}/tools/hpvm/projects)
-set(HPVM_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/tools/hpvm/include)
-set(BENCHMARK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../dnn_benchmarks/include)
-set(TENSOR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
-set(TENSOR_RT_INCLUDE_DIR ${HPVM_PROJECTS}/hpvm-tensor-rt/tensor_runtime/include)
-set(
-  INCLUDES
-  ${CONFIG_INCLUDE_DIR} ${HPVM_INCLUDE_DIR} ${BENCHMARK_INCLUDE_DIR}
-  ${TENSOR_INCLUDE_DIR} ${TENSOR_RT_INCLUDE_DIR} ${CUDA_INCLUDE_DIRS}
-)
-foreach(dir ${INCLUDES})
-  list(APPEND INCLUDE_COMPILER_STRINGS "-I${dir}")
-endforeach()
-
-# Built-in libraries to link
-list(
-  APPEND LINKER_FLAGS
-  "-L${CUDA_TOOLKIT_ROOT_DIR}/lib64"
-  -lpthread -lcudart -lcurand -lcudnn -lcublas -lcufft -lOpenCL -lstdc++fs -lomp -lm
-)
-
-# The hpvm-rt runtime
-# This has to be explicitly set as hpvm-rt.bc is created in a custom_target
-# and does not export its file location.
-# Keep this in sync with hpvm/projects/hpvm-rt/CMakeLists.txt.
-set(HPVM_RT_PATH ${PROJECT_BINARY_DIR}/tools/hpvm/projects/hpvm-rt/hpvm-rt.bc)
-
-# Compile flags (clang++)
-set(CLANG_FLAGS -fno-exceptions -std=c++11 -O3)
-
-# All compilation uses HPVM_DEFAULT_PASSES.
-set(
-  HPVM_DEFAULT_PASSES
-  LLVMBuildDFG
-  LLVMInPlaceDFGAnalysis
-  LLVMDFG2LLVM_CPU
-  LLVMFuseHPVMTensorNodes
-  LLVMClearDFG
-  LLVMGenHPVM
-)
-
-set(WORK_DIR ${CMAKE_CURRENT_BINARY_DIR})
 set(test_compile_targets "")
-function(compile_single_benchmark target src_file extra_passes extra_dfg_flags)
-  foreach(pass ${HPVM_DEFAULT_PASSES} ${extra_passes})
-    list(APPEND LOAD_FILE_FLAGS "-load" "${pass}.so")
-  endforeach()
-  set(
-    HPVM_PASSES ${LOAD_FILE_FLAGS}
-    -buildDFG -inplace -hpvm-fuse ${extra_dfg_flags} -dfg2llvm-cpu -clearDFG
-  )
-
+function(approxhpvm_py_codegen bin_filename src_filepath codegen_target)
   add_custom_command(
-    OUTPUT "${WORK_DIR}/${target}.ll" DEPENDS ${src_file} clang
-    COMMAND ${CMAKE_CXX_COMPILER} ${INCLUDE_COMPILER_STRINGS} ${CLANG_FLAGS} -emit-llvm -S ${src_file}
-      -o ${WORK_DIR}/${target}.ll
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${bin_filename}
+    DEPENDS ${src_filepath} approxhpvm.py
+    COMMAND ${APPROXHPVM_PY}
+      ${src_filepath} ${CMAKE_CURRENT_BINARY_DIR}/${bin_filename}
+      -t ${codegen_target} -I ${CONFIG_INCLUDE_DIR} ${ARGV}
   )
-  add_custom_command(
-    OUTPUT "${WORK_DIR}/${target}.hpvm.ll"
-    DEPENDS "${WORK_DIR}/${target}.ll" opt LLVMGenHPVM
-    COMMAND ${LLVM_OPT} -load LLVMGenHPVM.so -genhpvm -globaldce -S ${WORK_DIR}/${target}.ll
-      -o ${WORK_DIR}/${target}.hpvm.ll
-  )
-  add_custom_command(
-    OUTPUT "${WORK_DIR}/${target}.llvm.ll"
-    DEPENDS "${WORK_DIR}/${target}.hpvm.ll" opt ${HPVM_DEFAULT_PASSES} ${extra_passes}
-    COMMAND ${LLVM_OPT} ${HPVM_PASSES} -S ${WORK_DIR}/${target}.hpvm.ll
-      -o ${WORK_DIR}/${target}.llvm.ll
-  )
-  add_custom_command(
-    OUTPUT "${WORK_DIR}/${target}.linked.bc"
-    DEPENDS "${WORK_DIR}/${target}.llvm.ll" hpvm-rt.bc llvm-link
-    COMMAND ${LLVM_LINK} ${WORK_DIR}/${target}.llvm.ll ${HPVM_RT_PATH}
-      -o ${WORK_DIR}/${target}.linked.bc
-  )
-  add_custom_command(
-    OUTPUT "${WORK_DIR}/${target}"
-    DEPENDS "${WORK_DIR}/${target}.linked.bc" tensor_runtime gpu_profiler promise_profiler
-    COMMAND ${CMAKE_CXX_COMPILER}
-      ${WORK_DIR}/${target}.linked.bc
-      $<TARGET_FILE:tensor_runtime> $<TARGET_FILE:gpu_profiler> $<TARGET_FILE:promise_profiler>
-      -o ${WORK_DIR}/${target} ${LINKER_FLAGS}
-  )
-  add_custom_target(${target} DEPENDS "${WORK_DIR}/${target}")
-
-  set(test_compile_targets ${test_compile_targets} ${target} PARENT_SCOPE)
-endfunction(compile_single_benchmark)
+  add_custom_target(${bin_filename} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${bin_filename})
+  set(test_compile_targets ${test_compile_targets} ${bin_filename} PARENT_SCOPE)
+endfunction(approxhpvm_py_codegen)
 
 set(test_run_targets "")
 function(run_single_benchmark run_target benchmark)
   add_custom_target(
-    ${run_target}
-    COMMAND ${WORK_DIR}/${benchmark}
+    ${run_target} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${benchmark}
   )
   add_dependencies(${run_target} ${benchmark})
   set(test_run_targets ${test_run_targets} ${run_target} PARENT_SCOPE)
@@ -120,22 +38,20 @@ endfunction(run_single_benchmark)
 file(GLOB entries ./benchmarks/*)
 foreach(dir ${entries})
   get_filename_component(dirname "${dir}" NAME)
-  set(
-    loop_extra_flags
-    -dfg2llvm-wrapperapi
-      -quantization-levels-filename=${dir}/data/quant_ranges_rt.txt
-      -configuration-inputs-filename=${dir}/data/tuner_confs.txt
-  )
-  compile_single_benchmark(
-    ${dirname} ${dir}/${dirname}.cpp
-    LLVMDFG2LLVM_WrapperAPI "${loop_extra_flags}"
+  # Generate "tensor"-targeted code
+  approxhpvm_py_codegen(
+    ${dirname} ${dir}/${dirname}.cpp tensor 
+    --quant-file ${dir}/data/quant_ranges_rt.txt
+    --config-file ${dir}/data/tuner_confs.txt
   )
+  # Run tensor binary
   run_single_benchmark(run_${dirname} ${dirname})
-  compile_single_benchmark(
-    ${dirname}_cudnn ${dir}/${dirname}_cudnn.cpp LLVMDFG2LLVM_CUDNN -dfg2llvm-cudnn
-  )
+  # Generate "cudnn"-targeted code
+  approxhpvm_py_codegen(${dirname}_cudnn ${dir}/${dirname}_cudnn.cpp cudnn)
+  # Run cudnn binary
   run_single_benchmark(run_${dirname}_cudnn ${dirname}_cudnn)
 endforeach(dir)
+
 message(STATUS "List of test dnn benchmarks: ${test_compile_targets}")
 add_custom_target(dnn_benchmarks DEPENDS ${test_compile_targets})
 message(STATUS "Target name for compiling all dnn benchmarks: dnn_benchmarks")
-- 
GitLab