From 690a55dfc1f25b26924f1c0e210128c65975ac25 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Thu, 6 Apr 2023 14:00:21 -0700 Subject: [PATCH 1/5] Clean up various autoscheduler tool issues - In CMake, not all of the tooling for Anderson2021 was included in packaging; now it is. - Since the featurization_to_sample and get_host_target tools are 100% identical across all autoschedulers, they now get build only once, and don't get the `adams2019_` (etc) prefix they formerly did. - conversely, the autotune_loop.sh and weightsdir_to_weightsfile tools now *do* get autoscheduler-specific prefixes, because they aren't interchangeable. - Fixes to various scripts etc to use the correct tool names. - When the Anderson2021 autoscheduler was added, we tried to factor out common coding and tooling, but went a bit too far: the weightsdir_to_weightsfile source was moved into common/, and while it and the related Weights source were identical, they needed to include *different* Featurization.h files, and so basically relied on the build rules building it twice, with a different include path each time. IMHO this is unreasonably fragile and weird, so I moved those sources back into the folders in question, as there isn't any compelling reason to keep these sources exactly in sync anyway. - Same story for the test_function_dag test. Note that I started to add support for Anderson2021 to the main Makefile, but it became painful to do -- it works fine for CMake, so I will leave adding Make support for someone who wants to use it there. --- Makefile | 20 +- packaging/CMakeLists.txt | 12 +- src/autoschedulers/adams2019/CMakeLists.txt | 26 +- src/autoschedulers/adams2019/Makefile | 35 +-- .../{common => adams2019}/Weights.cpp | 0 .../{common => adams2019}/Weights.h | 0 ...une_loop.sh => adams2019_autotune_loop.sh} | 4 +- .../test_function_dag.cpp | 0 .../weightsdir_to_weightsfile.cpp | 0 .../anderson2021/CMakeLists.txt | 26 +- src/autoschedulers/anderson2021/Makefile | 99 +++---- src/autoschedulers/anderson2021/Weights.cpp | 250 ++++++++++++++++++ src/autoschedulers/anderson2021/Weights.h | 54 ++++ ..._loop.sh => anderson2021_autotune_loop.sh} | 4 +- .../anderson2021/generate_data.sh | 4 +- .../anderson2021/scripts/utils.sh | 2 +- .../anderson2021/test_function_dag.cpp | 173 ++++++++++++ .../weightsdir_to_weightsfile.cpp | 29 ++ src/autoschedulers/common/CMakeLists.txt | 18 ++ src/autoschedulers/common/Makefile | 20 ++ test/autoschedulers/anderson2021/test.cpp | 2 +- 21 files changed, 645 insertions(+), 133 deletions(-) rename src/autoschedulers/{common => adams2019}/Weights.cpp (100%) rename src/autoschedulers/{common => adams2019}/Weights.h (100%) rename src/autoschedulers/adams2019/{autotune_loop.sh => adams2019_autotune_loop.sh} (98%) rename src/autoschedulers/{common => adams2019}/test_function_dag.cpp (100%) rename src/autoschedulers/{common => adams2019}/weightsdir_to_weightsfile.cpp (100%) create mode 100644 src/autoschedulers/anderson2021/Weights.cpp create mode 100644 src/autoschedulers/anderson2021/Weights.h rename src/autoschedulers/anderson2021/{autotune_loop.sh => anderson2021_autotune_loop.sh} (98%) create mode 100644 src/autoschedulers/anderson2021/test_function_dag.cpp create mode 100644 src/autoschedulers/anderson2021/weightsdir_to_weightsfile.cpp create mode 100644 src/autoschedulers/common/Makefile diff --git a/Makefile b/Makefile index 506b19f8046e..fdd10beb735c 100644 --- a/Makefile +++ b/Makefile @@ -2374,15 +2374,23 @@ ifeq ($(UNAME), Darwin) install_name_tool -id @rpath/$(@F) $(CURDIR)/$@ endif +# Build some common tools +$(DISTRIB_DIR)/bin/featurization_to_sample $(DISTRIB_DIR)/bin/get_host_target: $(DISTRIB_DIR)/lib/libHalide.$(SHARED_EXT) + @mkdir -p $(@D) + $(MAKE) -f $(SRC_DIR)/autoschedulers/common/Makefile $(BIN_DIR)/featurization_to_sample $(BIN_DIR)/get_host_target HALIDE_DISTRIB_PATH=$(CURDIR)/$(DISTRIB_DIR) + for TOOL in featurization_to_sample get_host_target; do \ + cp $(BIN_DIR)/$${TOOL} $(DISTRIB_DIR)/bin/; \ + done + # Adams2019 also includes autotuning tools $(DISTRIB_DIR)/lib/libautoschedule_adams2019.$(PLUGIN_EXT): $(BIN_DIR)/libautoschedule_adams2019.$(PLUGIN_EXT) @mkdir -p $(@D) - $(MAKE) -f $(SRC_DIR)/autoschedulers/adams2019/Makefile $(BIN_DIR)/retrain_cost_model $(BIN_DIR)/featurization_to_sample $(BIN_DIR)/get_host_target HALIDE_DISTRIB_PATH=$(CURDIR)/$(DISTRIB_DIR) + $(MAKE) -f $(SRC_DIR)/autoschedulers/adams2019/Makefile $(BIN_DIR)/adams2019_retrain_cost_model $(BIN_DIR)/adams2019_weightsdir_to_weightsfile HALIDE_DISTRIB_PATH=$(CURDIR)/$(DISTRIB_DIR) cp $< $(DISTRIB_DIR)/lib/ - for TOOL in retrain_cost_model featurization_to_sample get_host_target; do \ - cp $(BIN_DIR)/$${TOOL} $(DISTRIB_DIR)/bin/; \ + for TOOL in adams2019_retrain_cost_model adams2019_weightsdir_to_weightsfile; do \ + cp $(BIN_DIR)/$${TOOL} $(DISTRIB_DIR)/bin/; \ done - cp $(SRC_DIR)/autoschedulers/adams2019/autotune_loop.sh $(DISTRIB_DIR)/tools/ + cp $(SRC_DIR)/autoschedulers/adams2019/adams2019_autotune_loop.sh $(DISTRIB_DIR)/tools/ ifeq ($(UNAME), Darwin) install_name_tool -id @rpath/$(@F) $(CURDIR)/$@ endif @@ -2390,7 +2398,9 @@ endif autoschedulers: \ $(DISTRIB_DIR)/lib/libautoschedule_mullapudi2016.$(PLUGIN_EXT) \ $(DISTRIB_DIR)/lib/libautoschedule_li2018.$(PLUGIN_EXT) \ -$(DISTRIB_DIR)/lib/libautoschedule_adams2019.$(PLUGIN_EXT) +$(DISTRIB_DIR)/lib/libautoschedule_adams2019.$(PLUGIN_EXT) \ +$(DISTRIB_DIR)/bin/featurization_to_sample \ +$(DISTRIB_DIR)/bin/get_host_target .PHONY: distrib distrib: $(DISTRIB_DIR)/lib/libHalide.$(SHARED_EXT) autoschedulers diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index 2c5b038c8bd6..cebfb6adf63b 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -32,7 +32,7 @@ install(TARGETS Halide Halide_Generator Halide_LanguageOptions INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if (TARGET Halide_Adams2019) - install(TARGETS Halide_Adams2019 Halide_Li2018 Halide_Mullapudi2016 + install(TARGETS Halide_Adams2019 Halide_Li2018 Halide_Mullapudi2016 Halide_Anderson2021 EXPORT Halide_Interfaces LIBRARY DESTINATION ${Halide_INSTALL_PLUGINDIR} COMPONENT Halide_Runtime NAMELINK_COMPONENT Halide_Development) @@ -79,7 +79,12 @@ else () set(rbase $ORIGIN) endif () -foreach (util IN ITEMS adams2019_retrain_cost_model adams2019_featurization_to_sample adams2019_get_host_target adams2019_weightsdir_to_weightsfile) +foreach (util IN ITEMS adams2019_retrain_cost_model + adams2019_weightsdir_to_weightsfile + anderson2021_retrain_cost_model + anderson2021_weightsdir_to_weightsfile + featurization_to_sample + get_host_target) if (TARGET ${util}) if (NOT CMAKE_INSTALL_RPATH) set_target_properties(${util} PROPERTIES INSTALL_RPATH "${rbase};${rbase}/${lib_dir}") @@ -121,7 +126,8 @@ install(DIRECTORY ${Halide_SOURCE_DIR}/tools/ PATTERN "build_halide_h.cpp" EXCLUDE PATTERN "find_inverse.cpp" EXCLUDE) -install(PROGRAMS ${Halide_SOURCE_DIR}/src/autoschedulers/adams2019/autotune_loop.sh +install(PROGRAMS ${Halide_SOURCE_DIR}/src/autoschedulers/adams2019/adams2019_autotune_loop.sh + ${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021/anderson2021_autotune_loop.sh DESTINATION ${Halide_INSTALL_TOOLSDIR} COMPONENT Halide_Development) diff --git a/src/autoschedulers/adams2019/CMakeLists.txt b/src/autoschedulers/adams2019/CMakeLists.txt index 4589ebf60ee8..448f6380ef16 100644 --- a/src/autoschedulers/adams2019/CMakeLists.txt +++ b/src/autoschedulers/adams2019/CMakeLists.txt @@ -73,11 +73,11 @@ if (APPLE AND num_archs GREATER 1) ) endif () -# retrain_cost_model +# adams2019_retrain_cost_model if (WITH_UTILS) add_executable(adams2019_retrain_cost_model DefaultCostModel.cpp - ${COMMON_DIR}/Weights.cpp + Weights.cpp retrain_cost_model.cpp $) target_include_directories(adams2019_retrain_cost_model PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/adams2019") @@ -98,7 +98,7 @@ add_autoscheduler( FunctionDAG.cpp LoopNest.cpp State.cpp - ${COMMON_DIR}/Weights.cpp + Weights.cpp $ ) @@ -107,16 +107,10 @@ target_link_libraries(Halide_Adams2019 PRIVATE ASLog ParamParser adams2019_cost_ # ==================================================== # Auto-tuning support utilities. -# TODO(#4053): implement auto-tuning support in CMake? if (WITH_UTILS) - add_executable(adams2019_featurization_to_sample ${COMMON_DIR}/featurization_to_sample.cpp) - - add_executable(adams2019_get_host_target ${COMMON_DIR}/get_host_target.cpp) - target_link_libraries(adams2019_get_host_target PRIVATE Halide::Halide) - - add_executable(adams2019_weightsdir_to_weightsfile ${COMMON_DIR}/weightsdir_to_weightsfile.cpp ${COMMON_DIR}/Weights.cpp) - target_include_directories(adams2019_weightsdir_to_weightsfile PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/adams2019" ${COMMON_DIR}) + add_executable(adams2019_weightsdir_to_weightsfile weightsdir_to_weightsfile.cpp Weights.cpp) + target_include_directories(adams2019_weightsdir_to_weightsfile PRIVATE ${COMMON_DIR}) target_link_libraries(adams2019_weightsdir_to_weightsfile PRIVATE Halide::Runtime) endif () @@ -125,15 +119,9 @@ endif () # which is handled in tests/autoschedulers/Adams2019) if (WITH_TESTS) - - add_executable(adams2019_test_perfect_hash_map ${COMMON_DIR}/test_perfect_hash_map.cpp) - add_test(NAME adams2019_test_perfect_hash_map COMMAND adams2019_test_perfect_hash_map) - set_tests_properties(adams2019_test_perfect_hash_map PROPERTIES LABELS "adams2019;autoschedulers;auto_schedule") - - add_executable(adams2019_test_function_dag ${COMMON_DIR}/test_function_dag.cpp FunctionDAG.cpp) - target_include_directories(adams2019_test_function_dag PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/adams2019" ${COMMON_DIR}) + add_executable(adams2019_test_function_dag test_function_dag.cpp FunctionDAG.cpp) + # target_include_directories(adams2019_test_function_dag PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/adams2019" ${COMMON_DIR}) target_link_libraries(adams2019_test_function_dag PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin) add_test(NAME adams2019_test_function_dag COMMAND adams2019_test_function_dag) set_tests_properties(adams2019_test_function_dag PROPERTIES LABELS "adams2019;autoschedulers;auto_schedule") - endif() diff --git a/src/autoschedulers/adams2019/Makefile b/src/autoschedulers/adams2019/Makefile index 8fdbeb08e34d..6e4b3c32e32e 100644 --- a/src/autoschedulers/adams2019/Makefile +++ b/src/autoschedulers/adams2019/Makefile @@ -36,23 +36,23 @@ $(BIN)/baseline_weights.o: $(BIN)/baseline_weights.cpp $(CXX) -c $< -o $@ AUTOSCHED_COST_MODEL_LIBS=\ -$(BIN)/cost_model/adams2019_cost_model.a \ -$(BIN)/cost_model/adams2019_train_cost_model.a \ +$(BIN)/adams2019_cost_model/adams2019_cost_model.a \ +$(BIN)/adams2019_cost_model/adams2019_train_cost_model.a \ -$(BIN)/cost_model.generator: $(SRC)/cost_model_generator.cpp \ +$(BIN)/adams2019_cost_model.generator: $(SRC)/cost_model_generator.cpp \ $(SRC)/cost_model_schedule.h \ $(SRC)/NetworkSize.h \ $(GENERATOR_DEPS) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(filter %.cpp,$^) -o $@ $(USE_EXPORT_DYNAMIC) $(LIBHALIDE_LDFLAGS) -$(BIN)/auto_schedule_runtime.a: $(BIN)/cost_model.generator +$(BIN)/auto_schedule_runtime.a: $(BIN)/adams2019_cost_model.generator @mkdir -p $(@D) $^ -r auto_schedule_runtime -o $(BIN) target=$(HL_TARGET) -$(BIN)/cost_model/adams2019_%.a: $(BIN)/cost_model.generator +$(BIN)/adams2019_cost_model/adams2019_%.a: $(BIN)/adams2019_cost_model.generator @mkdir -p $(@D) - $^ -g $* -o $(BIN)/cost_model -f $* -n adams2019_$* target=$(HL_TARGET)-no_runtime -e stmt,static_library,h,assembly + $^ -g $* -o $(BIN)/adams2019_cost_model -f $* -n adams2019_$* target=$(HL_TARGET)-no_runtime -e stmt,static_library,h,assembly # It's important to use dynamic lookups for undefined symbols here: all of libHalide # is expected to be present (in the loading binary), so we explicitly make the symbols @@ -68,8 +68,8 @@ $(BIN)/libautoschedule_adams2019.$(PLUGIN_EXT): \ $(SRC)/Cache.cpp \ $(SRC)/DefaultCostModel.h \ $(SRC)/DefaultCostModel.cpp \ - $(COMMON_DIR)/Weights.h \ - $(COMMON_DIR)/Weights.cpp \ + $(SRC)/Weights.h \ + $(SRC)/Weights.cpp \ $(SRC)/FunctionDAG.h \ $(SRC)/FunctionDAG.cpp \ $(SRC)/LoopNest.h \ @@ -85,30 +85,23 @@ $(BIN)/libautoschedule_adams2019.$(PLUGIN_EXT): \ $(BIN)/auto_schedule_runtime.a \ | $(LIB_HALIDE) @mkdir -p $(@D) - $(CXX) -shared $(USE_EXPORT_DYNAMIC) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $(CXXFLAGS) $(OPTIMIZE) -I $(BIN)/cost_model $(filter-out %.h $(LIBHALIDE_LDFLAGS),$^) -o $@ $(HALIDE_SYSTEM_LIBS) $(HALIDE_RPATH_FOR_LIB) -I $(SRC) + $(CXX) -shared $(USE_EXPORT_DYNAMIC) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $(CXXFLAGS) $(OPTIMIZE) -I $(BIN)/adams2019_cost_model $(filter-out %.h $(LIBHALIDE_LDFLAGS),$^) -o $@ $(HALIDE_SYSTEM_LIBS) $(HALIDE_RPATH_FOR_LIB) -I $(SRC) -$(BIN)/retrain_cost_model: $(SRC)/retrain_cost_model.cpp \ +$(BIN)/adams2019_retrain_cost_model: $(SRC)/retrain_cost_model.cpp \ $(COMMON_DIR)/ASLog.cpp \ $(SRC)/DefaultCostModel.h \ $(SRC)/DefaultCostModel.cpp \ - $(COMMON_DIR)/Weights.h \ - $(COMMON_DIR)/Weights.cpp \ + $(SRC)/Weights.h \ + $(SRC)/Weights.cpp \ $(SRC)/CostModel.h \ $(SRC)/NetworkSize.h \ $(AUTOSCHED_COST_MODEL_LIBS) \ $(AUTOSCHED_WEIGHT_OBJECTS) \ $(BIN)/auto_schedule_runtime.a @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) -frtti -Wall -I ../support -I $(BIN)/cost_model $(OPTIMIZE) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_OPEN_MP) $(HALIDE_RPATH_FOR_BIN) -I $(SRC) + $(CXX) $(CXXFLAGS) -frtti -Wall -I ../support -I $(BIN)/adams2019_cost_model $(OPTIMIZE) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_OPEN_MP) $(HALIDE_RPATH_FOR_BIN) -I $(SRC) -$(BIN)/featurization_to_sample: $(COMMON_DIR)/featurization_to_sample.cpp - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) $< $(OPTIMIZE) -o $@ - -$(BIN)/get_host_target: $(COMMON_DIR)/get_host_target.cpp $(LIB_HALIDE) $(HALIDE_DISTRIB_PATH)/include/Halide.h - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) $(filter %.cpp,$^) $(LIBHALIDE_LDFLAGS) $(OPTIMIZE) -o $@ $(HALIDE_RPATH_FOR_BIN) -$(BIN)/weightsdir_to_weightsfile: $(COMMON_DIR)/weightsdir_to_weightsfile.cpp $(COMMON_DIR)/Weights.cpp +$(BIN)/adams2019_weightsdir_to_weightsfile: $(SRC)/weightsdir_to_weightsfile.cpp $(SRC)/Weights.cpp @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $^ $(OPTIMIZE) -o $@ -I $(SRC) diff --git a/src/autoschedulers/common/Weights.cpp b/src/autoschedulers/adams2019/Weights.cpp similarity index 100% rename from src/autoschedulers/common/Weights.cpp rename to src/autoschedulers/adams2019/Weights.cpp diff --git a/src/autoschedulers/common/Weights.h b/src/autoschedulers/adams2019/Weights.h similarity index 100% rename from src/autoschedulers/common/Weights.h rename to src/autoschedulers/adams2019/Weights.h diff --git a/src/autoschedulers/adams2019/autotune_loop.sh b/src/autoschedulers/adams2019/adams2019_autotune_loop.sh similarity index 98% rename from src/autoschedulers/adams2019/autotune_loop.sh rename to src/autoschedulers/adams2019/adams2019_autotune_loop.sh index 92f419c005de..ad6b8789c499 100755 --- a/src/autoschedulers/adams2019/autotune_loop.sh +++ b/src/autoschedulers/adams2019/adams2019_autotune_loop.sh @@ -46,7 +46,7 @@ fi echo Training target is: ${HL_TARGET} if [ -z ${GENERATOR} ]; then -GENERATOR=./bin/demo.generator +GENERATOR=./bin/adams2019_demo.generator fi if [ -z ${PIPELINE} ]; then @@ -213,7 +213,7 @@ for ((BATCH_ID=$((FIRST+1));BATCH_ID<$((FIRST+1+NUM_BATCHES));BATCH_ID++)); do echo Retraining model... find ${SAMPLES} -name "*.sample" | \ - ${AUTOSCHED_BIN}/retrain_cost_model \ + ${AUTOSCHED_BIN}/adams2019_retrain_cost_model \ --epochs=${BATCH_SIZE} \ --rates="0.0001" \ --num_cores=32 \ diff --git a/src/autoschedulers/common/test_function_dag.cpp b/src/autoschedulers/adams2019/test_function_dag.cpp similarity index 100% rename from src/autoschedulers/common/test_function_dag.cpp rename to src/autoschedulers/adams2019/test_function_dag.cpp diff --git a/src/autoschedulers/common/weightsdir_to_weightsfile.cpp b/src/autoschedulers/adams2019/weightsdir_to_weightsfile.cpp similarity index 100% rename from src/autoschedulers/common/weightsdir_to_weightsfile.cpp rename to src/autoschedulers/adams2019/weightsdir_to_weightsfile.cpp diff --git a/src/autoschedulers/anderson2021/CMakeLists.txt b/src/autoschedulers/anderson2021/CMakeLists.txt index b78142348f83..60a4db197fd9 100644 --- a/src/autoschedulers/anderson2021/CMakeLists.txt +++ b/src/autoschedulers/anderson2021/CMakeLists.txt @@ -32,7 +32,7 @@ add_halide_library(anderson2021_train_cost_model FROM anderson2021_cost_model.ge if (WITH_UTILS) add_executable(anderson2021_retrain_cost_model DefaultCostModel.cpp - ${COMMON_DIR}/Weights.cpp + Weights.cpp retrain_cost_model.cpp $) target_include_directories(anderson2021_retrain_cost_model PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021") @@ -55,7 +55,7 @@ add_autoscheduler( SearchSpace.cpp State.cpp Tiling.cpp - ${COMMON_DIR}/Weights.cpp + Weights.cpp $ ) @@ -64,17 +64,9 @@ target_link_libraries(Halide_Anderson2021 PRIVATE ASLog ParamParser anderson2021_cost_model anderson2021_train_cost_model) ## ==================================================== -## Auto-tuning support utilities. -## TODO(#4053): implement auto-tuning support in CMake? - if (WITH_UTILS) - add_executable(anderson2021_featurization_to_sample ${COMMON_DIR}/featurization_to_sample.cpp) - - add_executable(anderson2021_get_host_target ${COMMON_DIR}/get_host_target.cpp) - target_link_libraries(anderson2021_get_host_target PRIVATE Halide::Halide) - - add_executable(anderson2021_weightsdir_to_weightsfile ${COMMON_DIR}/weightsdir_to_weightsfile.cpp ${COMMON_DIR}/Weights.cpp) - target_include_directories(anderson2021_weightsdir_to_weightsfile PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021" ${COMMON_DIR}) + add_executable(anderson2021_weightsdir_to_weightsfile weightsdir_to_weightsfile.cpp Weights.cpp) + target_include_directories(anderson2021_weightsdir_to_weightsfile PRIVATE ${COMMON_DIR}) target_link_libraries(anderson2021_weightsdir_to_weightsfile PRIVATE Halide::Runtime) endif () @@ -83,17 +75,9 @@ endif () # which is handled in tests/autoschedulers/anderson2021) if (WITH_TESTS) - - add_executable(anderson2021_test_perfect_hash_map ${COMMON_DIR}/test_perfect_hash_map.cpp) - - add_test(NAME anderson2021_test_perfect_hash_map COMMAND test_perfect_hash_map) - set_tests_properties(anderson2021_test_perfect_hash_map - PROPERTIES - LABELS Anderson2021) - ## - add_executable(anderson2021_test_function_dag ${COMMON_DIR}/test_function_dag.cpp FunctionDAG.cpp) + add_executable(anderson2021_test_function_dag test_function_dag.cpp FunctionDAG.cpp) target_include_directories(anderson2021_test_function_dag PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021") target_link_libraries(anderson2021_test_function_dag PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin) diff --git a/src/autoschedulers/anderson2021/Makefile b/src/autoschedulers/anderson2021/Makefile index ed829946e138..e906140f2378 100644 --- a/src/autoschedulers/anderson2021/Makefile +++ b/src/autoschedulers/anderson2021/Makefile @@ -2,6 +2,7 @@ THIS_MAKEFILE = $(realpath $(filter %Makefile, $(MAKEFILE_LIST))) SRC = $(strip $(shell dirname $(THIS_MAKEFILE))) HALIDE_SRC_ROOT = $(realpath $(SRC)/../../../) COMMON_DIR ?= $(realpath $(SRC)/../common/) +HALIDE_TEST_DIR ?= $(HALIDE_SRC_ROOT)/test/autoschedulers/anderson2021 HALIDE_DISTRIB_PATH ?= $(HALIDE_SRC_ROOT)/distrib HL_TARGET ?= host @@ -41,34 +42,34 @@ $(BIN)/baseline_weights.o: $(BIN)/baseline_weights.cpp $(CXX) -c $< -o $@ AUTOSCHED_COST_MODEL_LIBS=\ -$(BIN)/cost_model/anderson2021_cost_model.a \ -$(BIN)/cost_model/anderson2021_train_cost_model.a \ +$(BIN)/anderson2021_cost_model/anderson2021_cost_model.a \ +$(BIN)/anderson2021_cost_model/anderson2021_train_cost_model.a \ -$(BIN)/cost_model.generator: $(SRC)/cost_model_generator.cpp \ +$(BIN)/anderson2021_cost_model.generator: $(SRC)/cost_model_generator.cpp \ $(SRC)/cost_model_schedule.h \ $(SRC)/NetworkSize.h \ $(GENERATOR_DEPS) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(filter %.cpp,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_EXPORT_DYNAMIC) -$(BIN)/auto_schedule_runtime.a: $(BIN)/cost_model.generator +$(BIN)/auto_schedule_runtime.a: $(BIN)/anderson2021_cost_model.generator @mkdir -p $(@D) $^ -r auto_schedule_runtime -o $(BIN) target=$(HL_TARGET) -$(BIN)/cost_model/anderson2021_%.a: $(BIN)/cost_model.generator +$(BIN)/anderson2021_cost_model/anderson2021_%.a: $(BIN)/anderson2021_cost_model.generator @mkdir -p $(@D) - $^ -g $* -o $(BIN)/cost_model -f $* -n anderson2021_$* target=$(HL_TARGET)-no_runtime enable_debug_output=$(ENABLE_DEBUG_OUTPUT) -e stmt,static_library,h,assembly + $^ -g $* -o $(BIN)/anderson2021_cost_model -f $* -n anderson2021_$* target=$(HL_TARGET)-no_runtime enable_debug_output=$(ENABLE_DEBUG_OUTPUT) -e stmt,static_library,h,assembly # It's important to use dynamic lookups for undefined symbols here: all of libHalide # is expected to be present (in the loading binary), so we explicitly make the symbols # undefined rather than dependent on libHalide.so. -$(BIN)/libautoschedule_anderson2021.$(SHARED_EXT): $(SRC)/AutoSchedule.cpp \ +$(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT): $(SRC)/AutoSchedule.cpp \ $(SRC)/AutoSchedule.h \ $(COMMON_DIR)/ASLog.cpp \ $(SRC)/DefaultCostModel.h \ $(SRC)/DefaultCostModel.cpp \ - $(COMMON_DIR)/Weights.h \ - $(COMMON_DIR)/Weights.cpp \ + $(SRC)/Weights.h \ + $(SRC)/Weights.cpp \ $(SRC)/FunctionDAG.h \ $(SRC)/FunctionDAG.cpp \ $(SRC)/LoopNest.h \ @@ -94,88 +95,77 @@ $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT): $(SRC)/AutoSchedule.cpp \ $(GENERATOR_DEPS) \ $(BIN)/auto_schedule_runtime.a @mkdir -p $(@D) - $(CXX) -shared $(USE_EXPORT_DYNAMIC) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $(CXXFLAGS) $(OPTIMIZE) -I $(BIN)/cost_model $(filter-out %.h $(LIBHALIDE_LDFLAGS),$^) -o $@ $(HALIDE_SYSTEM_LIBS) -I . + $(CXX) -shared $(USE_EXPORT_DYNAMIC) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $(CXXFLAGS) $(OPTIMIZE) -I $(BIN)/anderson2021_cost_model $(filter-out %.h $(LIBHALIDE_LDFLAGS),$^) -o $@ $(HALIDE_SYSTEM_LIBS) -I . -$(BIN)/retrain_cost_model: $(SRC)/retrain_cost_model.cpp \ +$(BIN)/anderson2021_retrain_cost_model: $(SRC)/retrain_cost_model.cpp \ $(COMMON_DIR)/ASLog.cpp \ $(SRC)/DefaultCostModel.h \ $(SRC)/DefaultCostModel.cpp \ - $(COMMON_DIR)/Weights.h \ - $(COMMON_DIR)/Weights.cpp \ + $(SRC)/Weights.h \ + $(SRC)/Weights.cpp \ $(SRC)/CostModel.h \ $(SRC)/NetworkSize.h \ $(AUTOSCHED_COST_MODEL_LIBS) \ $(AUTOSCHED_WEIGHT_OBJECTS) \ $(BIN)/auto_schedule_runtime.a @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) -frtti -Wall -I ../support -I $(BIN)/cost_model $(OPTIMIZE) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_OPEN_MP) + $(CXX) $(CXXFLAGS) -frtti -Wall -I ../support -I $(BIN)/anderson2021_cost_model $(OPTIMIZE) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_OPEN_MP) -$(BIN)/anderson2021_featurization_to_sample: $(COMMON_DIR)/featurization_to_sample.cpp - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) $< $(OPTIMIZE) -o $@ - -$(BIN)/anderson2021_get_host_target: $(COMMON_DIR)/get_host_target.cpp $(LIB_HALIDE) $(HALIDE_DISTRIB_PATH)/include/Halide.h - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) $(filter %.cpp,$^) $(LIBHALIDE_LDFLAGS) $(OPTIMIZE) -o $@ - -$(BIN)/anderson2021_weightsdir_to_weightsfile: $(COMMON_DIR)/weightsdir_to_weightsfile.cpp $(COMMON_DIR)/Weights.cpp +$(BIN)/anderson2021_weightsdir_to_weightsfile: $(SRC)/weightsdir_to_weightsfile.cpp $(SRC)/Weights.cpp @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $^ $(OPTIMIZE) -o $@ -I . # A sample generator to autoschedule. Note that if it statically links # to libHalide, then it must be build with $(USE_EXPORT_DYNAMIC), or the # autoscheduler can't find the libHalide symbols that it needs. -$(GENERATOR_BIN)/demo.generator: $(COMMON_DIR)/demo_generator.cpp $(GENERATOR_DEPS) +$(GENERATOR_BIN)/anderson2021_demo.generator: $(HALIDE_TEST_DIR)/demo_generator.cpp $(GENERATOR_DEPS) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(USE_EXPORT_DYNAMIC) -g $(filter %.cpp,$^) -o $@ $(LIBHALIDE_LDFLAGS) # To use the autoscheduler, set a few environment variables and use the -p flag to the generator to load the autoscheduler as a plugin -$(BIN)/%/demo.a: $(GENERATOR_BIN)/demo.generator $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) +$(BIN)/%/anderson2021_demo.a: $(GENERATOR_BIN)/anderson2021_demo.generator $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) @mkdir -p $(@D) HL_WEIGHTS_DIR=$(SRC)/baseline.weights \ - $(GENERATOR_BIN)/demo.generator -g demo -o $(@D) -f demo target=$* -p $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) autoscheduler=Anderson2021 + $(GENERATOR_BIN)/anderson2021_demo.generator -g demo -o $(@D) -f anderson2021_demo target=$* -p $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) autoscheduler=Anderson2021 -$(BIN)/%/demo.rungen: $(BIN)/%/RunGenMain.o $(BIN)/%/demo.registration.cpp $(BIN)/%/demo.a +$(BIN)/%/anderson2021_demo.rungen: $(BIN)/%/RunGenMain.o $(BIN)/%/anderson2021_demo.registration.cpp $(BIN)/%/anderson2021_demo.a @mkdir -p $(@D) $(CXX) $(CXXFLAGS) -I$(BIN)/$* $^ -o $@ $(HALIDE_SYSTEM_LIBS) $(IMAGE_IO_FLAGS) # demonstrates single-shot use of the autoscheduler -demo: $(BIN)/$(HL_TARGET)/demo.rungen $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) +anderson2021_demo: $(BIN)/$(HL_TARGET)/anderson2021_demo.rungen $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) $< --benchmarks=all --benchmark_min_time=1 --estimate_all +$(BIN)/featurization_to_sample $(BIN)/get_host_target: + @mkdir -p $(@D) + $(MAKE) -f $(COMMON_DIR)/Makefile $(BIN)/featurization_to_sample $(BIN)/get_host_target + # demonstrates an autotuning loop # (using $(BIN) and $(SRC) here seems overkill, but makes copy-n-paste elsewhere easier) -autotune: $(GENERATOR_BIN)/demo.generator $(BIN)/anderson2021_featurization_to_sample $(BIN)/anderson2021_get_host_target $(BIN)/anderson2021_retrain_cost_model $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) $(SRC)/autotune_loop.sh +autotune: $(GENERATOR_BIN)/anderson2021_demo.generator $(BIN)/featurization_to_sample $(BIN)/get_host_target $(BIN)/anderson2021_retrain_cost_model $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) $(SRC)/anderson2021_autotune_loop.sh SAMPLES_DIR=test_autotuned_samples \ - bash $(SRC)/autotune_loop.sh \ - $(GENERATOR_BIN)/demo.generator \ - demo \ + bash $(SRC)/anderson2021_autotune_loop.sh \ + $(GENERATOR_BIN)/anderson2021_demo.generator \ + anderson2021_demo \ "" \ $(SRC)/baseline.weights \ $(BIN) \ 0 -$(BIN)/test_perfect_hash_map: $(COMMON_DIR)/test_perfect_hash_map.cpp $(COMMON_DIR)/PerfectHashMap.h - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) $< -o $@ - -$(BIN)/test_function_dag: $(COMMON_DIR)/test_function_dag.cpp FunctionDAG.h FunctionDAG.cpp $(COMMON_DIR)/ASLog.h $(COMMON_DIR)/ASLog.cpp +$(BIN)/anderson2021_test_function_dag: test_function_dag.cpp FunctionDAG.h FunctionDAG.cpp $(COMMON_DIR)/ASLog.h $(COMMON_DIR)/ASLog.cpp @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(USE_EXPORT_DYNAMIC) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(HALIDE_SYSTEM_LIBS) # Simple jit-based test -$(BIN)/%/test: test.cpp $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) +$(BIN)/$(HL_TARGET)/test: $(HALIDE_TEST_DIR)/test.cpp $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(USE_EXPORT_DYNAMIC) $^ -o $@ $(LIBHALIDE_LDFLAGS) $(HALIDE_SYSTEM_LIBS) -test_perfect_hash_map: $(BIN)/test_perfect_hash_map - $^ - -test_function_dag: $(BIN)/test_function_dag +anderson2021_test_function_dag: $(BIN)/anderson2021_test_function_dag $^ -run_test: $(BIN)/$(HL_TARGET)/test - HL_WEIGHTS_DIR=$(SRC)/baseline.weights LD_LIBRARY_PATH=$(BIN) $< +run_test: $(BIN)/$(HL_TARGET)/test $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) + HL_WEIGHTS_DIR=$(SRC)/baseline.weights LD_LIBRARY_PATH=$(BIN) $< $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) .PHONY: test clean @@ -190,16 +180,13 @@ test: AUTOSCHED_SAMPLES_OUT = $(BIN)/test_samples_out # to spot-check changes, so it's important to try a little of each of # the important paths here, including single-shot and autotune-loop build: $(BIN)/$(HL_TARGET)/test \ - $(BIN)/test_perfect_hash_map \ - $(BIN)/test_function_dag \ + $(BIN)/anderson2021_test_function_dag \ $(BIN)/$(HL_TARGET)/included_schedule_file.rungen \ - $(GENERATOR_BIN)/demo.generator \ - $(BIN)/anderson2021_featurization_to_sample \ - $(BIN)/anderson2021_get_host_target \ + $(GENERATOR_BIN)/anderson2021_demo.generator \ $(BIN)/anderson2021_retrain_cost_model \ - $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) + $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) -test: test_bounds test_tiling test_storage_strides test_parser test_state test_thread_info run_test test_perfect_hash_map test_function_dag demo included_schedule_file autotune +test: test_bounds test_tiling test_storage_strides test_parser test_state test_thread_info run_test anderson2021_test_function_dag anderson2021_demo included_schedule_file autotune TEST_DIR=$(SRC)/test @@ -257,25 +244,25 @@ clean: # # We'll use the preprocessor (GENERATING_SCHEDULE) to distinguish between these two. -$(GENERATOR_BIN)/included_schedule_file_none.generator: $(COMMON_DIR)/included_schedule_file_generator.cpp $(GENERATOR_DEPS) +$(GENERATOR_BIN)/included_schedule_file_none.generator: $(HALIDE_TEST_DIR)/included_schedule_file_generator.cpp $(GENERATOR_DEPS) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(USE_EXPORT_DYNAMIC) -DGENERATING_SCHEDULE -g $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(HALIDE_SYSTEM_LIBS) # This is the target you build to (re)generate the schedule file. # (Note that we only need the schedule output, so we pass `-e schedule` to # the Generator so that it can skip producing other outputs.) -$(BIN)/%/included_schedule_file.schedule.h: $(GENERATOR_BIN)/included_schedule_file_none.generator $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) +$(BIN)/%/included_schedule_file.schedule.h: $(GENERATOR_BIN)/included_schedule_file_none.generator $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) @mkdir -p $(@D) HL_WEIGHTS_DIR=$(SRC)/baseline.weights \ - $< -g included_schedule_file -o $(@D) -f included_schedule_file target=$* -p $(BIN)/libautoschedule_anderson2021.$(SHARED_EXT) autoscheduler=Anderson2021 autoscheduler.parallelism=80 -e schedule + $< -g included_schedule_file -o $(@D) -f included_schedule_file target=$* -p $(BIN)/libautoschedule_anderson2021.$(PLUGIN_EXT) autoscheduler=Anderson2021 autoscheduler.parallelism=80 -e schedule -# Note that this depends on included_schedule_file.schedule.h rather than $(BIN)/%/included_schedule_file.schedule.h -- +# Note that this depends on $(HALIDE_TEST_DIR)/included_schedule_file.schedule.h rather than $(BIN)/%/included_schedule_file.schedule.h -- # the former should be generated by something like # # make bin/host/included_schedule_file.schedule.h # cp bin/host/included_schedule_file.schedule.h included_schedule_file.schedule.h # -$(GENERATOR_BIN)/included_schedule_file.generator: $(COMMON_DIR)/included_schedule_file_generator.cpp included_schedule_file.schedule.h $(GENERATOR_DEPS) +$(GENERATOR_BIN)/included_schedule_file.generator: $(HALIDE_TEST_DIR)/included_schedule_file_generator.cpp $(HALIDE_TEST_DIR)/included_schedule_file.schedule.h $(GENERATOR_DEPS) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(USE_EXPORT_DYNAMIC) -g $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(HALIDE_SYSTEM_LIBS) diff --git a/src/autoschedulers/anderson2021/Weights.cpp b/src/autoschedulers/anderson2021/Weights.cpp new file mode 100644 index 000000000000..8206410a397f --- /dev/null +++ b/src/autoschedulers/anderson2021/Weights.cpp @@ -0,0 +1,250 @@ +#include +#include +#include + +#include "Featurization.h" +#include "HalideBuffer.h" +#include "NetworkSize.h" +#include "Weights.h" + +namespace Halide { +namespace Internal { + +using Halide::Runtime::Buffer; + +constexpr uint32_t kSignature = 0x68776631; + +void Weights::randomize(uint32_t seed) { + std::mt19937 rng(seed); + // Fill the weights with random values + for_each_buffer([&rng](Buffer &w) { + w.for_each_value([&rng](float &f) { + f = ((float)rng()) / ((float)std::mt19937::max()) - 0.5f; + }); + }); +} + +/* + Structure of the .weights file format: + + uint32 signature always 0x68776631 ('hwf1') + uint32 PipelineFeatures::version + uint32 ScheduleFeatures::version + uint32 buffer-count + uint32 dimension-count + uint32x(dimension-count) dimension-extent + float32x(element-count) data + + (all values little-endian) +*/ + +bool Weights::load(std::istream &i) { + uint32_t signature; + i.read((char *)&signature, sizeof(signature)); + if (i.fail() || signature != kSignature) { + return false; + } + + i.read((char *)&pipeline_features_version, sizeof(pipeline_features_version)); + if (i.fail()) { + return false; + } + + i.read((char *)&schedule_features_version, sizeof(schedule_features_version)); + if (i.fail()) { + return false; + } + + uint32_t buffer_count; + i.read((char *)&buffer_count, sizeof(buffer_count)); + if (i.fail() || buffer_count != 6) { + return false; + } + + const auto load_one = [&i](Buffer &buf) -> bool { + uint32_t dimension_count; + i.read((char *)&dimension_count, sizeof(dimension_count)); + if (i.fail() || dimension_count != (uint32_t)buf.dimensions()) { + return false; + } + for (uint32_t d = 0; d < dimension_count; d++) { + uint32_t extent; + i.read((char *)&extent, sizeof(extent)); + if (i.fail() || (int)extent != (int)buf.extent(d)) { + return false; + } + } + i.read((char *)(buf.data()), buf.size_in_bytes()); + if (i.fail()) { + return false; + } + return true; + }; + + if (!load_one(head1_filter)) { + return false; + } + if (!load_one(head1_bias)) { + return false; + } + if (!load_one(head2_filter)) { + return false; + } + if (!load_one(head2_bias)) { + return false; + } + if (!load_one(conv1_filter)) { + return false; + } + if (!load_one(conv1_bias)) { + return false; + } + + return true; +} +bool Weights::load_from_file(const std::string &filename) { + std::ifstream i(filename, std::ios_base::binary); + return load(i); +} + +bool Weights::save(std::ostream &o) const { + const uint32_t signature = kSignature; + o.write((const char *)&signature, sizeof(signature)); + if (o.fail()) { + return false; + } + + o.write((const char *)&pipeline_features_version, sizeof(pipeline_features_version)); + if (o.fail()) { + return false; + } + + o.write((const char *)&schedule_features_version, sizeof(schedule_features_version)); + if (o.fail()) { + return false; + } + + const uint32_t buffer_count = 6; + o.write((const char *)&buffer_count, sizeof(buffer_count)); + if (o.fail()) { + return false; + } + + const auto save_one = [&o](const Buffer &buf) -> bool { + const uint32_t dimension_count = buf.dimensions(); + o.write((const char *)&dimension_count, sizeof(dimension_count)); + if (o.fail()) { + return false; + } + for (uint32_t d = 0; d < dimension_count; d++) { + uint32_t extent = buf.extent(d); + o.write((const char *)&extent, sizeof(extent)); + if (o.fail()) { + return false; + } + } + o.write((const char *)(buf.data()), buf.size_in_bytes()); + if (o.fail()) { + return false; + } + return true; + }; + + if (!save_one(head1_filter)) { + return false; + } + if (!save_one(head1_bias)) { + return false; + } + if (!save_one(head2_filter)) { + return false; + } + if (!save_one(head2_bias)) { + return false; + } + if (!save_one(conv1_filter)) { + return false; + } + if (!save_one(conv1_bias)) { + return false; + } + + return true; +} + +bool Weights::save_to_file(const std::string &filename) const { + std::ofstream o(filename, std::ios_base::trunc | std::ios_base::binary); + return save(o); +} + +bool Weights::load_from_dir(const std::string &dir) { + const auto buffer_from_file = [](const std::string &filename, Buffer &buf) -> bool { + std::ifstream i(filename, std::ios_base::binary); + i.read((char *)(buf.data()), buf.size_in_bytes()); + i.close(); + if (i.fail()) { + return false; + } + return true; + }; + + if (!buffer_from_file(dir + "/head1_conv1_weight.data", head1_filter)) { + return false; + } + if (!buffer_from_file(dir + "/head1_conv1_bias.data", head1_bias)) { + return false; + } + if (!buffer_from_file(dir + "/head2_conv1_weight.data", head2_filter)) { + return false; + } + if (!buffer_from_file(dir + "/head2_conv1_bias.data", head2_bias)) { + return false; + } + if (!buffer_from_file(dir + "/trunk_conv1_weight.data", conv1_filter)) { + return false; + } + if (!buffer_from_file(dir + "/trunk_conv1_bias.data", conv1_bias)) { + return false; + } + + // Old style data doesn't record the versions, so just assume they are current + pipeline_features_version = PipelineFeatures::version(); + schedule_features_version = ScheduleFeatures::version(); + + return true; +} + +bool Weights::save_to_dir(const std::string &dir) const { + const auto buffer_to_file = [](const Buffer &buf, const std::string &filename) -> bool { + std::ofstream o(filename, std::ios_base::trunc | std::ios_base::binary); + o.write((const char *)(buf.data()), buf.size_in_bytes()); + o.close(); + if (o.fail()) { + return false; + } + return true; + }; + + if (!buffer_to_file(head1_filter, dir + "/head1_conv1_weight.data")) { + return false; + } + if (!buffer_to_file(head1_bias, dir + "/head1_conv1_bias.data")) { + return false; + } + if (!buffer_to_file(head2_filter, dir + "/head2_conv1_weight.data")) { + return false; + } + if (!buffer_to_file(head2_bias, dir + "/head2_conv1_bias.data")) { + return false; + } + if (!buffer_to_file(conv1_filter, dir + "/trunk_conv1_weight.data")) { + return false; + } + if (!buffer_to_file(conv1_bias, dir + "/trunk_conv1_bias.data")) { + return false; + } + return true; +} + +} // namespace Internal +} // namespace Halide diff --git a/src/autoschedulers/anderson2021/Weights.h b/src/autoschedulers/anderson2021/Weights.h new file mode 100644 index 000000000000..c2d2220a03c2 --- /dev/null +++ b/src/autoschedulers/anderson2021/Weights.h @@ -0,0 +1,54 @@ +#ifndef _WEIGHTS +#define _WEIGHTS + +#include +#include +#include + +#include "Featurization.h" +#include "HalideBuffer.h" +#include "NetworkSize.h" + +namespace Halide { +namespace Internal { + +struct Weights { + uint32_t pipeline_features_version = PipelineFeatures::version(); + uint32_t schedule_features_version = ScheduleFeatures::version(); + + Halide::Runtime::Buffer head1_filter{head1_channels, head1_w, head1_h}; + Halide::Runtime::Buffer head1_bias{head1_channels}; + + Halide::Runtime::Buffer head2_filter{head2_channels, head2_w}; + Halide::Runtime::Buffer head2_bias{head2_channels}; + + Halide::Runtime::Buffer conv1_filter{conv1_channels, head1_channels + head2_channels}; + Halide::Runtime::Buffer conv1_bias{conv1_channels}; + + template + void for_each_buffer(F f) { + f(head1_filter); + f(head1_bias); + f(head2_filter); + f(head2_bias); + f(conv1_filter); + f(conv1_bias); + } + + void randomize(uint32_t seed); + + bool load(std::istream &i); + bool save(std::ostream &o) const; + + bool load_from_file(const std::string &filename); + bool save_to_file(const std::string &filename) const; + + // Load/save from the 'classic' form of six raw data files + bool load_from_dir(const std::string &dir); + bool save_to_dir(const std::string &dir) const; +}; + +} // namespace Internal +} // namespace Halide + +#endif // _WEIGHTS diff --git a/src/autoschedulers/anderson2021/autotune_loop.sh b/src/autoschedulers/anderson2021/anderson2021_autotune_loop.sh similarity index 98% rename from src/autoschedulers/anderson2021/autotune_loop.sh rename to src/autoschedulers/anderson2021/anderson2021_autotune_loop.sh index 3ca5061b5cf1..649dfe293925 100644 --- a/src/autoschedulers/anderson2021/autotune_loop.sh +++ b/src/autoschedulers/anderson2021/anderson2021_autotune_loop.sh @@ -62,7 +62,7 @@ fi echo Training target is: ${HL_TARGET} if [ -z ${GENERATOR} ]; then -GENERATOR=./bin/demo.generator +GENERATOR=./bin/anderson2021_demo.generator fi if [ -z ${PIPELINE} ]; then @@ -315,7 +315,7 @@ benchmark_sample() { S=$2 FNAME=$6 - ${AUTOSCHEDULER_BUILD_DIR}/anderson2021_featurization_to_sample ${D}/${FNAME}.featurization $R $P $S ${D}/${FNAME}.sample || echo "featurization_to_sample failed for ${D} (probably because benchmarking failed)" + ${AUTOSCHEDULER_BUILD_DIR}/featurization_to_sample ${D}/${FNAME}.featurization $R $P $S ${D}/${FNAME}.sample || echo "featurization_to_sample failed for ${D} (probably because benchmarking failed)" rm ${D}/${FNAME}.featurization rm ${D}/bench diff --git a/src/autoschedulers/anderson2021/generate_data.sh b/src/autoschedulers/anderson2021/generate_data.sh index 9bdf15b83434..3fa66474605f 100644 --- a/src/autoschedulers/anderson2021/generate_data.sh +++ b/src/autoschedulers/anderson2021/generate_data.sh @@ -4,7 +4,7 @@ # the cost model after each batch. It can be used for generating training data or # for autotuning on an individual app. # -# It is a wrapper around autotune_loop.sh, which handles compiling, benchmarking, +# It is a wrapper around anderson2021_autotune_loop.sh, which handles compiling, benchmarking, # and retraining the cost model. This file makes the process more user friendly # by providing statistics, support for resuming previous batches, autotuning # across multiple apps, etc. @@ -220,7 +220,7 @@ for app in $APPS; do TRAIN_ONLY=${TRAIN_ONLY} \ SAMPLES_DIR=${SAMPLES_DIR} \ HL_DEBUG_CODEGEN=0 \ - bash ${AUTOSCHEDULER_SRC_DIR}/autotune_loop.sh \ + bash ${AUTOSCHEDULER_SRC_DIR}/anderson2021_autotune_loop.sh \ ${GENERATOR} \ ${app} \ ${HL_TARGET} \ diff --git a/src/autoschedulers/anderson2021/scripts/utils.sh b/src/autoschedulers/anderson2021/scripts/utils.sh index c46d98875c11..d05ce89ecf73 100644 --- a/src/autoschedulers/anderson2021/scripts/utils.sh +++ b/src/autoschedulers/anderson2021/scripts/utils.sh @@ -48,7 +48,7 @@ function get_host_target() { local -n host_target_ref=$2 echo "Calling get_host_target()..." - host_target_ref=$(${autoscheduler_build_dir}/anderson2021_get_host_target) + host_target_ref=$(${autoscheduler_build_dir}/get_host_target) echo "host_target = ${host_target_ref}" echo } diff --git a/src/autoschedulers/anderson2021/test_function_dag.cpp b/src/autoschedulers/anderson2021/test_function_dag.cpp new file mode 100644 index 000000000000..af41b06c7752 --- /dev/null +++ b/src/autoschedulers/anderson2021/test_function_dag.cpp @@ -0,0 +1,173 @@ +#include "FunctionDAG.h" +#include "Halide.h" +#include + +using namespace Halide; + +extern "C" int mul_by_two( + halide_buffer_t *input, + halide_buffer_t *output) { + if (input->is_bounds_query()) { + // Bounds query: infer the input dimensions from the output dimensions. In + // this example, the dimensions are exactly the same + for (int i = 0; i < 2; ++i) { + input->dim[i] = output->dim[i]; + } + return 0; + } + + // Actual computation: return 2 times x as an example. The first dimension is + // the innermost, so iterate over it last to avoid inefficient memory access + // patterns. + for (int j = 0; j < input->dim[1].extent; ++j) { + for (int i = 0; i < input->dim[0].extent; ++i) { + float *out = (float *)output->host + i * output->dim[0].stride + + j * output->dim[1].stride; + float *in = (float *)input->host + i * input->dim[0].stride + + j * input->dim[1].stride; + (*out) = 2 * (*in); + } + } + return 0; +} + +void test_coeff_wise(const Target &target) { + Var x("x"), y("y"); + + std::ostringstream with_extern; + { + Func f("f"), g("g"), h("h"); + f(x, y) = (x + y) * (x + y); + + Halide::ExternFuncArgument arg = f; + std::vector vars = {x, y}; + Halide::Type input_type = Halide::Float(32); + g.define_extern( + "mul_by_two", + {arg}, + input_type, + vars, + Halide::NameMangling::C); + g.function().extern_definition_proxy_expr() = f(x, y) * 2.0f; + + h(x, y) = g(x, y) * 2 + 1; + + h.set_estimate(x, 0, 1000).set_estimate(y, 0, 1000); + std::vector v; + v.push_back(h.function()); + Halide::Internal::Autoscheduler::FunctionDAG d(v, target); + + d.dump(with_extern); + } + + std::ostringstream without_extern; + { + Func f("f"), g("g"), h("h"); + f(x, y) = (x + y) * (x + y); + g(x, y) = f(x, y) * 2.0f; + h(x, y) = g(x, y) * 2 + 1; + + h.set_estimate(x, 0, 1000).set_estimate(y, 0, 1000); + std::vector v; + v.push_back(h.function()); + Halide::Internal::Autoscheduler::FunctionDAG d(v, target); + + d.dump(without_extern); + } + + // Disabled for now: there is still work to do to populate the jacobian + // assert(with_extern.str() == without_extern.str()); +} + +extern "C" int matmul( + halide_buffer_t *input1, + halide_buffer_t *input2, + halide_buffer_t *output) { + if (input1->is_bounds_query() || input2->is_bounds_query()) { + // Bounds query: infer the input dimensions from the output dimensions. + // We leave the k dimension alone since we can't infer it from the output dimensions. + input1->dim[0].min = output->dim[0].min; + input1->dim[0].extent = output->dim[0].extent; + input2->dim[1].min = output->dim[1].min; + input2->dim[1].extent = output->dim[1].extent; + return 0; + } + + // Actual computation: return input1 * input2. + const int max_i = output->dim[0].min + output->dim[0].extent; + const int max_j = output->dim[1].min + output->dim[1].extent; + for (int i = output->dim[0].min; i < max_i; ++i) { + for (int j = output->dim[1].min; j < max_j; ++j) { + int pos[2] = {i, j}; + float *out = (float *)output->address_of(pos); + *out = 0.0f; + for (int k = 0; k < input1->dim[1].extent; ++k) { + int pos1[2] = {i, k}; + float *in1 = (float *)input1->address_of(pos1); + int pos2[2] = {k, j}; + float *in2 = (float *)input2->address_of(pos2); + (*out) += (*in1) * (*in2); + } + } + } + return 0; +} + +void test_matmul(const Target &target) { + Var x("x"), y("y"), k("k"); + RDom r(0, 200); + Halide::Buffer input1(200, 200); + Halide::Buffer input2(200, 200); + + std::ostringstream with_extern; + { + Func mm("mm"), h("h"); + + Halide::ExternFuncArgument arg1 = input1; + Halide::ExternFuncArgument arg2 = input2; + std::vector vars = {x, y}; + Halide::Type input_type = Halide::Float(32); + mm.define_extern( + "matmul", + {arg1, arg2}, + {input_type, input_type}, + vars, + Halide::NameMangling::C); + mm.function().extern_definition_proxy_expr() = Halide::sum(input1(x, r) * input2(r, y)); + + h(x, y) = mm(x, y); + + h.set_estimate(x, 0, 200).set_estimate(y, 0, 200); + std::vector v; + v.push_back(h.function()); + Halide::Internal::Autoscheduler::FunctionDAG d(v, target); + + d.dump(with_extern); + } + std::ostringstream without_extern; + { + Func mm("mm"), h("h"); + mm(x, y) = Halide::sum(input1(x, r) * input2(r, y)); + h(x, y) = mm(x, y); + + h.set_estimate(x, 0, 200).set_estimate(y, 0, 200); + std::vector v; + v.push_back(h.function()); + Halide::Internal::Autoscheduler::FunctionDAG d(v, target); + + d.dump(without_extern); + } + + std::cout << "with_extern:\n " << with_extern.str() + << "\n\nwithout_extern:\n " << without_extern.str() << "\n"; +} + +int main(int argc, char **argv) { + // Use a fixed target for the analysis to get consistent results from this test. + Target target("x86-64-linux-sse41-avx-avx2"); + + test_coeff_wise(target); + test_matmul(target); + + return 0; +} diff --git a/src/autoschedulers/anderson2021/weightsdir_to_weightsfile.cpp b/src/autoschedulers/anderson2021/weightsdir_to_weightsfile.cpp new file mode 100644 index 000000000000..f266aa702c94 --- /dev/null +++ b/src/autoschedulers/anderson2021/weightsdir_to_weightsfile.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#include "Weights.h" + +// Utility to convert from the old dir-of-raw-data into a new .weights file. +// Should live only long enough for downstream users to convert existing data files +// to the new format. +int main(int argc, char **argv) { + if (argc != 3) { + std::cout << "Usage: weights_dir weights_file.weights\n"; + return -1; + } + + Halide::Internal::Weights w; + if (!w.load_from_dir(argv[1])) { + std::cerr << "Unable to read input dir: " << argv[1] << "\n"; + return -1; + } + + if (!w.save_to_file(argv[2])) { + std::cerr << "Unable to save output file: " << argv[2] << "\n"; + return -1; + } + + return 0; +} diff --git a/src/autoschedulers/common/CMakeLists.txt b/src/autoschedulers/common/CMakeLists.txt index d90d3f64ec89..ef77eeba8a3c 100644 --- a/src/autoschedulers/common/CMakeLists.txt +++ b/src/autoschedulers/common/CMakeLists.txt @@ -11,3 +11,21 @@ set_property(TARGET ASLog PROPERTY POSITION_INDEPENDENT_CODE YES) add_library(ParamParser INTERFACE) target_include_directories(ParamParser INTERFACE $) + +if (WITH_UTILS) + add_executable(featurization_to_sample featurization_to_sample.cpp) + + add_executable(get_host_target get_host_target.cpp) + target_link_libraries(get_host_target PRIVATE Halide::Halide) +endif () + + +# ================================================================= +# Tests for private/internal functionality of Adams2019 (vs for public functionality, +# which is handled in tests/autoschedulers/Adams2019) + +if (WITH_TESTS) + add_executable(test_perfect_hash_map test_perfect_hash_map.cpp) + add_test(NAME test_perfect_hash_map COMMAND test_perfect_hash_map) + set_tests_properties(test_perfect_hash_map PROPERTIES LABELS "autoschedulers;auto_schedule") +endif() diff --git a/src/autoschedulers/common/Makefile b/src/autoschedulers/common/Makefile new file mode 100644 index 000000000000..edb8ce711ff3 --- /dev/null +++ b/src/autoschedulers/common/Makefile @@ -0,0 +1,20 @@ +THIS_MAKEFILE = $(realpath $(filter %Makefile, $(MAKEFILE_LIST))) +COMMON_DIR = $(strip $(shell dirname $(THIS_MAKEFILE))) +HALIDE_SRC_ROOT = $(realpath $(COMMON_DIR)/../../../) + +HALIDE_DISTRIB_PATH ?= $(HALIDE_SRC_ROOT)/distrib + +# Don't include an autoscheduler in the generator deps +AUTOSCHEDULER= +include $(HALIDE_SRC_ROOT)/apps/support/Makefile.inc + + +$(BIN)/featurization_to_sample: $(COMMON_DIR)/featurization_to_sample.cpp + @mkdir -p $(@D) + $(CXX) $(CXXFLAGS) $< $(OPTIMIZE) -o $@ + +$(BIN)/get_host_target: $(COMMON_DIR)/get_host_target.cpp $(LIB_HALIDE) $(HALIDE_DISTRIB_PATH)/include/Halide.h + @mkdir -p $(@D) + $(CXX) $(CXXFLAGS) $(filter %.cpp,$^) $(LIBHALIDE_LDFLAGS) $(OPTIMIZE) -o $@ + + diff --git a/test/autoschedulers/anderson2021/test.cpp b/test/autoschedulers/anderson2021/test.cpp index b866769a12bd..972b98deafa9 100644 --- a/test/autoschedulers/anderson2021/test.cpp +++ b/test/autoschedulers/anderson2021/test.cpp @@ -14,7 +14,7 @@ int main(int argc, char **argv) { AutoschedulerParams params = {"Anderson2021", {{"parallelism", std::to_string(hardware_parallelism)}}}; // Use a fixed target for the analysis to get consistent results from this test. - Target target("x86-64-linux-sse41-avx-avx2-cuda"); + Target target("x86-64-linux-sse41-avx-avx2-cuda-debug"); Var x("x"), y("y"); From f44ab814ab5ec600fd93a2a1c0601250caf8217b Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 7 Apr 2023 10:05:22 -0700 Subject: [PATCH 2/5] Fix needless renames --- src/autoschedulers/adams2019/Makefile | 10 +++++----- src/autoschedulers/anderson2021/Makefile | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/autoschedulers/adams2019/Makefile b/src/autoschedulers/adams2019/Makefile index 6e4b3c32e32e..a39d13423069 100644 --- a/src/autoschedulers/adams2019/Makefile +++ b/src/autoschedulers/adams2019/Makefile @@ -36,21 +36,21 @@ $(BIN)/baseline_weights.o: $(BIN)/baseline_weights.cpp $(CXX) -c $< -o $@ AUTOSCHED_COST_MODEL_LIBS=\ -$(BIN)/adams2019_cost_model/adams2019_cost_model.a \ -$(BIN)/adams2019_cost_model/adams2019_train_cost_model.a \ +$(BIN)/cost_model/adams2019_cost_model.a \ +$(BIN)/cost_model/adams2019_train_cost_model.a \ -$(BIN)/adams2019_cost_model.generator: $(SRC)/cost_model_generator.cpp \ +$(BIN)/cost_model.generator: $(SRC)/cost_model_generator.cpp \ $(SRC)/cost_model_schedule.h \ $(SRC)/NetworkSize.h \ $(GENERATOR_DEPS) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(filter %.cpp,$^) -o $@ $(USE_EXPORT_DYNAMIC) $(LIBHALIDE_LDFLAGS) -$(BIN)/auto_schedule_runtime.a: $(BIN)/adams2019_cost_model.generator +$(BIN)/auto_schedule_runtime.a: $(BIN)/cost_model.generator @mkdir -p $(@D) $^ -r auto_schedule_runtime -o $(BIN) target=$(HL_TARGET) -$(BIN)/adams2019_cost_model/adams2019_%.a: $(BIN)/adams2019_cost_model.generator +$(BIN)/cost_model/adams2019_%.a: $(BIN)/cost_model.generator @mkdir -p $(@D) $^ -g $* -o $(BIN)/adams2019_cost_model -f $* -n adams2019_$* target=$(HL_TARGET)-no_runtime -e stmt,static_library,h,assembly diff --git a/src/autoschedulers/anderson2021/Makefile b/src/autoschedulers/anderson2021/Makefile index e906140f2378..183c46b9f401 100644 --- a/src/autoschedulers/anderson2021/Makefile +++ b/src/autoschedulers/anderson2021/Makefile @@ -42,21 +42,21 @@ $(BIN)/baseline_weights.o: $(BIN)/baseline_weights.cpp $(CXX) -c $< -o $@ AUTOSCHED_COST_MODEL_LIBS=\ -$(BIN)/anderson2021_cost_model/anderson2021_cost_model.a \ -$(BIN)/anderson2021_cost_model/anderson2021_train_cost_model.a \ +$(BIN)/cost_model/anderson2021_cost_model.a \ +$(BIN)/cost_model/anderson2021_train_cost_model.a \ -$(BIN)/anderson2021_cost_model.generator: $(SRC)/cost_model_generator.cpp \ +$(BIN)/cost_model.generator: $(SRC)/cost_model_generator.cpp \ $(SRC)/cost_model_schedule.h \ $(SRC)/NetworkSize.h \ $(GENERATOR_DEPS) @mkdir -p $(@D) $(CXX) $(CXXFLAGS) $(filter %.cpp,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_EXPORT_DYNAMIC) -$(BIN)/auto_schedule_runtime.a: $(BIN)/anderson2021_cost_model.generator +$(BIN)/auto_schedule_runtime.a: $(BIN)/cost_model.generator @mkdir -p $(@D) $^ -r auto_schedule_runtime -o $(BIN) target=$(HL_TARGET) -$(BIN)/anderson2021_cost_model/anderson2021_%.a: $(BIN)/anderson2021_cost_model.generator +$(BIN)/cost_model/anderson2021_%.a: $(BIN)/cost_model.generator @mkdir -p $(@D) $^ -g $* -o $(BIN)/anderson2021_cost_model -f $* -n anderson2021_$* target=$(HL_TARGET)-no_runtime enable_debug_output=$(ENABLE_DEBUG_OUTPUT) -e stmt,static_library,h,assembly From b7741f4597a1a53573950b8fd510e49ab7a6ec0f Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 7 Apr 2023 10:05:43 -0700 Subject: [PATCH 3/5] Remove scalpel left in patient --- test/autoschedulers/anderson2021/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/autoschedulers/anderson2021/test.cpp b/test/autoschedulers/anderson2021/test.cpp index 972b98deafa9..b866769a12bd 100644 --- a/test/autoschedulers/anderson2021/test.cpp +++ b/test/autoschedulers/anderson2021/test.cpp @@ -14,7 +14,7 @@ int main(int argc, char **argv) { AutoschedulerParams params = {"Anderson2021", {{"parallelism", std::to_string(hardware_parallelism)}}}; // Use a fixed target for the analysis to get consistent results from this test. - Target target("x86-64-linux-sse41-avx-avx2-cuda-debug"); + Target target("x86-64-linux-sse41-avx-avx2-cuda"); Var x("x"), y("y"); From a483b4ffcf24131b5c0e0974e0a7113981875c4e Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 7 Apr 2023 10:31:06 -0700 Subject: [PATCH 4/5] Update CMakeLists.txt --- src/autoschedulers/adams2019/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/autoschedulers/adams2019/CMakeLists.txt b/src/autoschedulers/adams2019/CMakeLists.txt index 448f6380ef16..2aa92b4d2cac 100644 --- a/src/autoschedulers/adams2019/CMakeLists.txt +++ b/src/autoschedulers/adams2019/CMakeLists.txt @@ -120,7 +120,6 @@ endif () if (WITH_TESTS) add_executable(adams2019_test_function_dag test_function_dag.cpp FunctionDAG.cpp) - # target_include_directories(adams2019_test_function_dag PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/adams2019" ${COMMON_DIR}) target_link_libraries(adams2019_test_function_dag PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin) add_test(NAME adams2019_test_function_dag COMMAND adams2019_test_function_dag) set_tests_properties(adams2019_test_function_dag PROPERTIES LABELS "adams2019;autoschedulers;auto_schedule") From f5cdeccdb157bdeff942ed1523dff2f73dbde394 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 7 Apr 2023 10:32:19 -0700 Subject: [PATCH 5/5] Update Makefile --- src/autoschedulers/adams2019/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/autoschedulers/adams2019/Makefile b/src/autoschedulers/adams2019/Makefile index a39d13423069..8a3f0b746e59 100644 --- a/src/autoschedulers/adams2019/Makefile +++ b/src/autoschedulers/adams2019/Makefile @@ -52,7 +52,7 @@ $(BIN)/auto_schedule_runtime.a: $(BIN)/cost_model.generator $(BIN)/cost_model/adams2019_%.a: $(BIN)/cost_model.generator @mkdir -p $(@D) - $^ -g $* -o $(BIN)/adams2019_cost_model -f $* -n adams2019_$* target=$(HL_TARGET)-no_runtime -e stmt,static_library,h,assembly + $^ -g $* -o $(BIN)/cost_model -f $* -n adams2019_$* target=$(HL_TARGET)-no_runtime -e stmt,static_library,h,assembly # It's important to use dynamic lookups for undefined symbols here: all of libHalide # is expected to be present (in the loading binary), so we explicitly make the symbols @@ -85,7 +85,7 @@ $(BIN)/libautoschedule_adams2019.$(PLUGIN_EXT): \ $(BIN)/auto_schedule_runtime.a \ | $(LIB_HALIDE) @mkdir -p $(@D) - $(CXX) -shared $(USE_EXPORT_DYNAMIC) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $(CXXFLAGS) $(OPTIMIZE) -I $(BIN)/adams2019_cost_model $(filter-out %.h $(LIBHALIDE_LDFLAGS),$^) -o $@ $(HALIDE_SYSTEM_LIBS) $(HALIDE_RPATH_FOR_LIB) -I $(SRC) + $(CXX) -shared $(USE_EXPORT_DYNAMIC) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $(CXXFLAGS) $(OPTIMIZE) -I $(BIN)/cost_model $(filter-out %.h $(LIBHALIDE_LDFLAGS),$^) -o $@ $(HALIDE_SYSTEM_LIBS) $(HALIDE_RPATH_FOR_LIB) -I $(SRC) $(BIN)/adams2019_retrain_cost_model: $(SRC)/retrain_cost_model.cpp \ $(COMMON_DIR)/ASLog.cpp \ @@ -99,7 +99,7 @@ $(BIN)/adams2019_retrain_cost_model: $(SRC)/retrain_cost_model.cpp \ $(AUTOSCHED_WEIGHT_OBJECTS) \ $(BIN)/auto_schedule_runtime.a @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) -frtti -Wall -I ../support -I $(BIN)/adams2019_cost_model $(OPTIMIZE) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_OPEN_MP) $(HALIDE_RPATH_FOR_BIN) -I $(SRC) + $(CXX) $(CXXFLAGS) -frtti -Wall -I ../support -I $(BIN)/cost_model $(OPTIMIZE) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) $(USE_OPEN_MP) $(HALIDE_RPATH_FOR_BIN) -I $(SRC) $(BIN)/adams2019_weightsdir_to_weightsfile: $(SRC)/weightsdir_to_weightsfile.cpp $(SRC)/Weights.cpp @mkdir -p $(@D)