diff --git a/codegen/compiler/src/Quidditch/Target/CMakeLists.txt b/codegen/compiler/src/Quidditch/Target/CMakeLists.txt index b3f93569..030c8cf0 100644 --- a/codegen/compiler/src/Quidditch/Target/CMakeLists.txt +++ b/codegen/compiler/src/Quidditch/Target/CMakeLists.txt @@ -20,15 +20,18 @@ iree_cc_library( HDRS "Passes.h" "Passes.h.inc" + "TilingScheme.h" SRCS "ConvertToLLVM.cpp" "ConfigureForSnitch.cpp" + "ConfigureTiles.cpp" "DisableQuidditchVariant.cpp" "LinkExecutables.cpp" "PadToTilingConfig.cpp" "ReluToMax.cpp" "RemoveTrivialLoops.cpp" "TensorTile.cpp" + "TilingScheme.cpp" DEPS ::PassesIncGen Quidditch::Conversion::ConvertSnitchToLLVM diff --git a/codegen/compiler/src/Quidditch/Target/ConfigureForSnitch.cpp b/codegen/compiler/src/Quidditch/Target/ConfigureTiles.cpp similarity index 51% rename from codegen/compiler/src/Quidditch/Target/ConfigureForSnitch.cpp rename to codegen/compiler/src/Quidditch/Target/ConfigureTiles.cpp index 16399e1f..01047006 100644 --- a/codegen/compiler/src/Quidditch/Target/ConfigureForSnitch.cpp +++ b/codegen/compiler/src/Quidditch/Target/ConfigureTiles.cpp @@ -1,16 +1,20 @@ #include "Passes.h" +#include +#include #include "Quidditch/Dialect/Snitch/IR/QuidditchSnitchAttrs.h" +#include "TilingScheme.h" #include "iree/compiler/Codegen/Dialect/Codegen/IR/IREECodegenAttrs.h" #include "iree/compiler/Codegen/Utils/CPUUtils.h" #include "iree/compiler/Codegen/Utils/Utils.h" #include "iree/compiler/Dialect/HAL/IR/HALOps.h" +#include "llvm/Support/raw_ostream.h" #include "mlir/Dialect/MemRef/Transforms/Transforms.h" #include "mlir/Interfaces/FunctionInterfaces.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" namespace quidditch { -#define GEN_PASS_DEF_CONFIGUREFORSNITCHPASS +#define GEN_PASS_DEF_CONFIGURETILES #include "Quidditch/Target/Passes.h.inc" } // namespace quidditch @@ -18,13 +22,22 @@ using namespace mlir; using namespace mlir::iree_compiler; namespace { -class ConfigureForSnitch - : public quidditch::impl::ConfigureForSnitchPassBase { + +class ConfigureTiles + : public quidditch::impl::ConfigureTilesBase { public: using Base::Base; + ConfigureTiles(const quidditch::ConfigureTilesOptions &options) { + this->importTiles = options.importTiles; + this->tbl = (quidditch::TileInfoTbl *)options.tablePointer; + } protected: void runOnOperation() override; + +private: + std::string importTiles = ""; + quidditch::TileInfoTbl *tbl; }; } // namespace @@ -36,62 +49,44 @@ static LogicalResult setTranslationInfo(FunctionOpInterface funcOp) { IREE::Codegen::DispatchLoweringPassPipeline::None, SymbolRefAttr())); } -static LogicalResult setRootConfig(FunctionOpInterface funcOp, - Operation *rootOp) { +static LogicalResult +setRootConfig(FunctionOpInterface funcOp, Operation *rootOp, + quidditch::TileInfoTbl *tbl) { return TypeSwitch(rootOp) .Case([&](linalg::LinalgOp op) { - // [0]: Always one in our matvec case. - - // [1]: How many rows we are processing. Should fit in L1. - // Should be as high as possible for subgroup distribution. - // Should be a multiple of 8 to be further distributed to compute cores. - - // [2]: Reduction dimension. How many columns are we - // processing at once? Cannot be distributed but has a few effects: - // * It allows us to make [1] larger by fitting more rows into L1. - // This therefore also gives us more parallelism compute core wise. - // * It makes our workgroups larger, reducing dispatch overhead and - // memory bandwidth (by only needing to copy loop invariant memory - // once + needing to copy back the result fewer times). This could - // come at the cost of concurrency for distributing workgroups but is - // only applicable once on Occamy. + // Assume tiling scheme passed in with --iree-quidditch-import-tiles SmallVector workgroupTiles(3, 0); SmallVector l1Tiles(3, 0); SmallVector l1Interchange = {2, 0, 1}; - bool dualBuffer = true; - - if (funcOp.getName() == - "main$async_dispatch_9_matmul_transpose_b_1x161x600_f64") { - l1Tiles[0] = 0; - l1Tiles[1] = 56; - l1Tiles[2] = 100; - } - if (funcOp.getName() == - "main$async_dispatch_0_matmul_transpose_b_1x400x161_f64") { - l1Tiles[1] = 40; - // TODO: Switch to 82 and true once correctness bugs are fixed. - l1Tiles[2] = 0; - dualBuffer = false; + bool dualBuffer = false; + // if table of tiling schemes is invalid, throw an error + if (tbl == 0) { + funcOp.emitWarning() << "\nConfigureTiles: Table pointer is zero!!"; + return failure(); } - if (funcOp.getName() == - "main$async_dispatch_7_matmul_transpose_b_1x600x400_f64") { - l1Tiles[0] = 0; - l1Tiles[1] = 40; - l1Tiles[2] = 100; + + // Look up the tile size, interchange, and double buffering settings + // from table + auto search = tbl->find(funcOp.getName().str()); + if (search == tbl->end()) { + funcOp.emitWarning() + << "\nConfigureTiles: Root operation of this dispatch " + "is a missing tiling scheme"; + return failure(); } - if (funcOp.getName() == - "main$async_dispatch_8_matmul_transpose_b_1x600x600_f64") { - l1Tiles[0] = 0; - l1Tiles[1] = 40; - l1Tiles[2] = 100; + quidditch::TilingScheme &ts = search->second; + if (!ts.getTiles_flat(l1Tiles)) { + funcOp.emitWarning() << "\nConfigureTiles: Found tiling scheme, but " + "couldn't get l1 tile list"; + return failure(); } - if (funcOp.getName() == - "main$async_dispatch_1_matmul_transpose_b_1x1200x400_f64") { - l1Tiles[0] = 0; - l1Tiles[1] = 40; - l1Tiles[2] = 100; + if (!ts.getOrder_flat(l1Interchange)) { + funcOp.emitWarning() << "\nConfigureTiles: Found tiling scheme, but " + "couldn't get l1 interchange"; + return failure(); } - + dualBuffer = ts.getDualBuffer(); + // set lowering config according to info in table setLoweringConfig(rootOp, quidditch::Snitch::LoweringConfigAttr::get( rootOp->getContext(), workgroupTiles, l1Tiles, l1Interchange, dualBuffer)); @@ -100,35 +95,46 @@ static LogicalResult setRootConfig(FunctionOpInterface funcOp, .Default(success()); } -void ConfigureForSnitch::runOnOperation() { +void ConfigureTiles::runOnOperation() { FunctionOpInterface funcOp = getOperation(); if (getTranslationInfo(funcOp)) return; SmallVector computeOps = getComputeOps(funcOp); FailureOr rootOp = getRootOperation(computeOps); - if (failed(rootOp)) + if (failed(rootOp)) { return signalPassFailure(); + } Operation *rootOperation = rootOp.value(); - if (!rootOperation) + if (!rootOperation) { return; + } // Set the same translation info for all functions right now. // This should move into 'setRootConfig' if we gain different pass pipelines // for different kernels. - if (failed(setTranslationInfo(funcOp))) + if (failed(setTranslationInfo(funcOp))) { return signalPassFailure(); + } + // Annotate root linalg ops with tile sizes auto loweringConfig = getLoweringConfig(rootOperation); - if (!loweringConfig) - if (failed(setRootConfig(funcOp, rootOperation))) + if (!loweringConfig) { + if (failed(setRootConfig(funcOp, rootOperation, tbl))) { + funcOp.emitWarning() + << "\nConfigureTiles: set root config failed\n"; return signalPassFailure(); + } + } // The root configuration setting introduces `tensor.dim` operations. // Resolve those away. RewritePatternSet patterns(funcOp.getContext()); memref::populateResolveRankedShapedTypeResultDimsPatterns(patterns); - if (failed(applyPatternsAndFoldGreedily(funcOp, std::move(patterns)))) + if (failed(applyPatternsAndFoldGreedily(funcOp, std::move(patterns)))) { + funcOp.emitWarning() << "\nConfigureTiles: apply patterns and " + "fold greedily failed\n"; signalPassFailure(); + } } diff --git a/codegen/compiler/src/Quidditch/Target/Passes.td b/codegen/compiler/src/Quidditch/Target/Passes.td index bb6e7aa8..532ddbbf 100644 --- a/codegen/compiler/src/Quidditch/Target/Passes.td +++ b/codegen/compiler/src/Quidditch/Target/Passes.td @@ -3,6 +3,7 @@ include "mlir/Pass/PassBase.td" + def LinkExecutablesPass : Pass<"quidditch-link-executables", "mlir::ModuleOp"> { let description = [{ Combines all `hal.executable.variant`s of the same target into a single @@ -29,6 +30,21 @@ def ConfigureForSnitchPass : InterfacePass<"quidditch-configure-for-snitch", "mlir::FunctionOpInterface">; +def ConfigureTiles : InterfacePass<"quidditch-configure-tiles", "mlir::FunctionOpInterface"> { + let summary = "Annotate linalg operations with tile sizes"; + let description = [{ + Within each iree dispatch, annotate the root linalg operation with a tiling scheme (tile sizes + loop interchange). + Caveat: only tiles linalg operations of type matmul_transpose_b (for now) + Set the importTiles option to the path to the json file containing the tiling scheme for each dispatch. + }]; + let options = [ + Option<"importTiles", "import-tiles", "std::string", /*default=*/"", + "Name of a JSON file specifying loop bounds and order for each root linalg operation.">, + Option<"tablePointer", "NeverPassAValueHere", "std::uintptr_t", /*default=*/"0", + "Avoids opening the input file multiple times. Never pass a value to this option via the command line.">, + ]; +} + def TensorTilePass : InterfacePass<"quidditch-tensor-tile", "mlir::FunctionOpInterface"> { let options = [ diff --git a/codegen/compiler/src/Quidditch/Target/QuidditchTarget.cpp b/codegen/compiler/src/Quidditch/Target/QuidditchTarget.cpp index f6735592..0d69fa8b 100644 --- a/codegen/compiler/src/Quidditch/Target/QuidditchTarget.cpp +++ b/codegen/compiler/src/Quidditch/Target/QuidditchTarget.cpp @@ -50,6 +50,9 @@ #include "LibraryBuilder.h" #include "Passes.h" +#include "TilingScheme.h" +#include "llvm/Support/ErrorHandling.h" + using namespace mlir; using namespace mlir::iree_compiler; using namespace quidditch::Snitch; @@ -81,6 +84,9 @@ struct QuidditchTargetOptions { std::string xDSLOptPath; std::string toolChainRoot; bool assertCompiled = false; + std::string importTiles = ""; // added for Configure Tiles Pass + quidditch::TileInfoTbl tileInfo = + quidditch::TileInfoTbl(); // added for Configure Tiles Pass // TODO: This should actually be 112640 but DMA stack overflows. Ooopsie! unsigned l1MemoryBytes = 100000; @@ -108,6 +114,11 @@ struct QuidditchTargetOptions { "iree-quidditch-toolchain-root", toolChainRoot, llvm::cl::cat(category), llvm::cl::desc("Path to the root directory of the Quidditch toolchain " "(containing the toolchain file)")); + // added for Configure Tiles Pass + binder.opt( + "iree-quidditch-import-tiles", importTiles, llvm::cl::cat(category), + llvm::cl::desc( + "Path to a JSON file from which we import tiling schemes")); binder.opt( "iree-quidditch-assert-compiled", assertCompiled, llvm::cl::cat(category), @@ -173,7 +184,20 @@ class QuidditchTargetBackend final : public IREE::HAL::TargetBackend { } modulePassManager.addPass(createMaterializeUserConfigsPass()); FunctionLikeNest funcPassManager(modulePassManager); - funcPassManager.addPass(quidditch::createConfigureForSnitchPass); + + // import any manually supplied tile sizes + if (targetOptions.importTiles != "") { + std::string errs; + quidditch::fillTileInfoTable(&targetOptions.tileInfo, + targetOptions.importTiles, errs); + } + + // automatically tile the dispatches + funcPassManager.addPass([&] { + auto thePass = quidditch::createConfigureTiles( + {targetOptions.importTiles, (std::uintptr_t)&targetOptions.tileInfo}); + return thePass; + }); } void buildTranslationPassPipeline(IREE::HAL::ExecutableTargetAttr targetAttr, diff --git a/codegen/compiler/src/Quidditch/Target/TilingScheme.cpp b/codegen/compiler/src/Quidditch/Target/TilingScheme.cpp new file mode 100644 index 00000000..fb8cff35 --- /dev/null +++ b/codegen/compiler/src/Quidditch/Target/TilingScheme.cpp @@ -0,0 +1,244 @@ +#include "TilingScheme.h" + +// using namespace quidditch; +using namespace mlir; +using namespace mlir::iree_compiler; + +// Tiling Scheme Functions defined below +namespace quidditch { + +TileInfoTbl *fillTileInfoTable(TileInfoTbl *tbl, const std::string &filePath, + std::string &errs) { + TileInfoTbl *result = tbl; + // try to open file + std::ifstream ifs(filePath); + if (!ifs.is_open()) { + std::stringstream ss; + ss << "\nTiling Scheme File does not exist or cannot be opened.\n" + << "Troublesome file path is " << filePath << "\n"; + errs = ss.str(); + return 0; + } + // try to read file + std::stringstream ss; + ss << ifs.rdbuf(); + if (ss.str().length() == 0) { + errs = "\nTiling Scheme file cannot have content length of 0\n"; + ifs.close(); + return 0; + } + // try to parse list of schemes + if (!parseTilingSchemes(tbl, StringRef(ss.str()), errs)) { + result = 0; + } + ifs.close(); + return result; +} + +bool parseTilingSchemes(TileInfoTbl *tbl, llvm::StringRef fileContent, + std::string &errs) { + // try to parse + llvm::Expected maybeParsed = + llvm::json::parse(fileContent); + if (!maybeParsed) { + std::stringstream ss; + ss << "\nError when parsing JSON file contents: " + << llvm::toString(maybeParsed.takeError()) << "\n"; + errs = ss.str(); + return false; + } + // try to get the top level json object + if (!maybeParsed->getAsObject()) { + errs = "\nError: top-level value is not a JSON object\n"; + return false; + } + llvm::json::Object *O = maybeParsed->getAsObject(); + // make sure object has at least one field + if (O->empty()) { + errs = "\nError: top-level JSON object is empty\n"; + return false; + } + // try to parse each tiling scheme from function name key + std::stringstream ss; + for (const auto &func : *O) { + struct TilingScheme ts = parseTilingScheme(func.getSecond(), errs); + if (!ts.valid) { + return false; + } else { + // only insert the tiling scheme if an entry does not exist already + // (NO OVERRIDING KEY-VALUE pairs in the table!!) + auto search = tbl->find(func.getFirst().str()); + if (search == tbl->end()) { + tbl->insert(std::pair(func.getFirst().str(), ts)); + ss << func.getFirst().str() << ":\n"; + ss << ts; + } + } + } + errs = ss.str(); + return true; +} + +struct TilingScheme parseTilingScheme(llvm::json::Value v, std::string &errs) { + + struct TilingScheme ts; + auto O = v.getAsObject(); + if (!O) { + errs = "RHS of key_value pair is not a JSON object!"; + return ts; + } + bool read_tile_sizes = parseListOfListOfInts(O, "tile-sizes", ts.tiles, errs); + bool read_loop_order = parseListOfListOfInts(O, "loop-order", ts.order, errs); + bool read_dual_buffer = parseBool(O, "dual-buffer", ts.dualBuffer, errs); + ts.valid = read_tile_sizes && read_loop_order && read_dual_buffer; + return ts; +} + +// TODO: call parseListOfInts inside parseListOfListOfInts +bool parseListOfListOfInts(llvm::json::Object *obj, std::string listName, + std::vector> &out, + std::string &errs) { + llvm::json::Value *bnds = obj->get(StringRef(listName)); + if (!bnds) { + std::stringstream ss; + ss << "\nError: field labeled '" << listName << "' does not exist \n "; + errs = ss.str(); + return false; + } + + if (!bnds->getAsArray()) { // getAsArray returns a (const json::Array *) + std::stringstream ss; + ss << "\nError: field labeled '" << listName << "' is not a JSON array \n "; + errs = ss.str(); + return false; + } + llvm::json::Path::Root Root("Try-to-parse-integer"); + for (const auto &Item : + *(bnds->getAsArray())) { // loop over a json::Array type + if (!Item.getAsArray()) { + std::stringstream ss; + ss << "\nError: elt of '" << listName << "' is not also a JSON array \n "; + errs = ss.str(); + return false; + } + std::vector sublist; + int bound; + for (const auto &elt : + *(Item.getAsArray())) { // loop over a json::Array type + if (!fromJSON(elt, bound, Root)) { + std::stringstream ss; + ss << llvm::toString(Root.getError()) << "\n"; + errs = ss.str(); + return false; + } + sublist.push_back(bound); + } + out.push_back(sublist); + } + return true; +} + +bool parseListOfInts(llvm::json::Object *obj, std::string listName, + std::vector &out, std::string &errs) { + llvm::json::Value *bnds = obj->get(StringRef(listName)); + if (!bnds) { + std::stringstream ss; + ss << "\nError: field labeled '" << listName << "' does not exist \n "; + errs = ss.str(); + return false; + } + if (!bnds->getAsArray()) { // getAsArray returns a (const json::Array *) + std::stringstream ss; + ss << "\nError: field labeled '" << listName << "' is not a JSON array \n "; + errs = ss.str(); + return false; + } + llvm::json::Path::Root Root("Try-to-parse-integer"); + int theNumber; + for (const auto &elt : + *(bnds->getAsArray())) { // loop over a json::Array type + if (!fromJSON(elt, theNumber, Root)) { + std::stringstream ss; + ss << llvm::toString(Root.getError()) << "\n"; + errs = ss.str(); + return false; + } + out.push_back(theNumber); + } + return true; +} + +bool parseBool(llvm::json::Object *obj, std::string boolName, bool &out, + std::string &errs) { + llvm::json::Value *theBool = obj->get(StringRef(boolName)); + if (!theBool) { + std::stringstream ss; + ss << "\nError: field labeled '" << boolName << "' does not exist \n "; + errs = ss.str(); + return false; + } + if (!theBool->getAsBoolean()) { // getAsBoolean returns an optional boolean + std::stringstream ss; + ss << "\nError: field labeled '" << boolName << "' is not a boolean \n "; + errs = ss.str(); + return false; + } + out = *(theBool->getAsBoolean()); + return true; +} + +bool TilingScheme::getTiles_flat(llvm::SmallVector &out) { + if (out.size() != tiles.size()) { + return false; + } else { + for (size_t i = 0; i < tiles.size(); i++) { + out[i] = (int64_t)tiles[i][0]; + } + } + return true; +} + +bool TilingScheme::getOrder_flat(llvm::SmallVector &out) { + if (out.size() != order.size()) { + return false; + } else { + for (size_t i = 0; i < order.size(); i++) { + out[i] = (int64_t)order[i][0]; + } + } + + return true; +} + +std::string TilingScheme::str() { + std::stringstream ts_ss; + ts_ss << *this; + return ts_ss.str(); +} + +std::stringstream &operator<<(std::stringstream &ss, + const struct TilingScheme &ts) { + ss << "tiling scheme: {\nbounds: [ "; + for (const auto &sublist : ts.tiles) { + ss << "[ "; + for (const auto &tile : sublist) { + ss << " " << tile << " "; + } + ss << "] "; + } + ss << "]\n"; + ss << "order: [ "; + for (const auto &sublist : ts.order) { + ss << "[ "; + for (const auto &pos : sublist) { + ss << " " << pos << " "; + } + ss << "] "; + } + ss << "]\n"; + ss << "dual buffer: " << ts.dualBuffer << "\n"; + ss << "]\n}"; + return ss; +} + +} // namespace quidditch diff --git a/codegen/compiler/src/Quidditch/Target/TilingScheme.h b/codegen/compiler/src/Quidditch/Target/TilingScheme.h new file mode 100644 index 00000000..a81c810c --- /dev/null +++ b/codegen/compiler/src/Quidditch/Target/TilingScheme.h @@ -0,0 +1,64 @@ + + +#include +#include +#include // to open tiling scheme file +#include +#include // for string compare +#include // to store parsed tiling schemes in a hash table +#include "Quidditch/Dialect/Snitch/IR/QuidditchSnitchAttrs.h" +#include "iree/compiler/Codegen/Dialect/Codegen/IR/IREECodegenAttrs.h" +#include "iree/compiler/Codegen/Transforms/Transforms.h" +#include "iree/compiler/Codegen/Utils/Utils.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" // to parse tiling scheme +#include "mlir/Dialect/Arith/Utils/Utils.h" +#include "mlir/Dialect/Linalg/IR/Linalg.h" +#include "mlir/Dialect/Linalg/Passes.h" +#include "mlir/Dialect/Linalg/Transforms/Transforms.h" +#include "mlir/Dialect/Linalg/Utils/Utils.h" +#include "mlir/Dialect/SCF/Transforms/TileUsingInterface.h" +#include "mlir/IR/Attributes.h" +#include "mlir/Interfaces/FunctionInterfaces.h" +#include "mlir/Transforms/DialectConversion.h" + +namespace quidditch { +// define a struct that stores +// tile size and loop interchange information +// for an iree dispatch's root operation +struct TilingScheme { + bool valid = false; + std::vector> tiles; + std::vector> order; + bool dualBuffer = false; + std::string errs = ""; + // member funcs + TilingScheme() = default; + std::string str(); + bool getTiles_flat(llvm::SmallVector &out); + bool getOrder_flat(llvm::SmallVector &out); + bool getDualBuffer() { return dualBuffer; } + // overloaded output operator + friend std::stringstream &operator<<(std::stringstream &ss, + const struct TilingScheme &ts); +}; + +// define a table that maps +// each iree dispatch function name to its tiling scheme. +typedef std::unordered_map + TileInfoTbl; +// function to read a json file and puts its contents in a TileInfo Table +TileInfoTbl *fillTileInfoTable(TileInfoTbl *tbl, const std::string &filePath, + std::string &errs); +// json parsing helper functions +struct TilingScheme parseTilingScheme(llvm::json::Value v, std::string &errs); +bool parseTilingSchemes(TileInfoTbl *tbl, llvm::StringRef fileContent, + std::string &errs); +bool parseListOfListOfInts(llvm::json::Object *obj, std::string listName, + std::vector> &out, + std::string &errs); +bool parseListOfInts(llvm::json::Object *obj, std::string listName, + std::vector &out, std::string &errs); +bool parseBool(llvm::json::Object *obj, std::string listName, bool &out, + std::string &errs); +} // namespace quidditch diff --git a/runtime/samples/nsnet2/CMakeLists.txt b/runtime/samples/nsnet2/CMakeLists.txt index 71a5e7c1..4a3300a5 100644 --- a/runtime/samples/nsnet2/CMakeLists.txt +++ b/runtime/samples/nsnet2/CMakeLists.txt @@ -1,7 +1,7 @@ iree_turbine(SRC NsNet2.py DST ${CMAKE_CURRENT_BINARY_DIR}/nsnet2.mlirbc DTYPE "f64") -quidditch_module(SRC ${CMAKE_CURRENT_BINARY_DIR}/nsnet2.mlirbc DST nsnet2) -quidditch_module(SRC ${CMAKE_CURRENT_BINARY_DIR}/nsnet2.mlirbc LLVM DST nsnet2_llvm) +quidditch_module(SRC ${CMAKE_CURRENT_BINARY_DIR}/nsnet2.mlirbc DST nsnet2 FLAGS --iree-quidditch-import-tiles=${CMAKE_CURRENT_LIST_DIR}/manually-chosen-tiles.json) +quidditch_module(SRC ${CMAKE_CURRENT_BINARY_DIR}/nsnet2.mlirbc LLVM DST nsnet2_llvm FLAGS --iree-quidditch-import-tiles=${CMAKE_CURRENT_LIST_DIR}/manually-chosen-tiles.json) add_library(nsnet2_util nsnet2_util.c) target_link_libraries(nsnet2_util diff --git a/runtime/samples/nsnet2/manually-chosen-tiles.json b/runtime/samples/nsnet2/manually-chosen-tiles.json new file mode 100644 index 00000000..04d4decf --- /dev/null +++ b/runtime/samples/nsnet2/manually-chosen-tiles.json @@ -0,0 +1,27 @@ +{ + "main$async_dispatch_1_matmul_transpose_b_1x1200x400_f64" : { + "tile-sizes":[[0], [40], [100]], + "loop-order":[[2,0], [0,0], [1,0]], + "dual-buffer": true + }, + "main$async_dispatch_0_matmul_transpose_b_1x400x161_f64" : { + "tile-sizes":[[0],[40],[0]], + "loop-order":[[2,0], [0,0], [1,0]], + "dual-buffer": false + }, + "main$async_dispatch_7_matmul_transpose_b_1x600x400_f64" : { + "tile-sizes":[[0], [40], [100]], + "loop-order":[[2,0], [0,0], [1,0]], + "dual-buffer": true + }, + "main$async_dispatch_8_matmul_transpose_b_1x600x600_f64" : { + "tile-sizes":[[0], [40], [100]], + "loop-order":[[2,0], [0,0], [1,0]], + "dual-buffer": true + }, + "main$async_dispatch_9_matmul_transpose_b_1x161x600_f64" : { + "tile-sizes":[[0], [56], [100]], + "loop-order":[[2,0], [0,0], [1,0]], + "dual-buffer": true + } +}