diff --git a/mindspore/_extends/parallel_compile/akg_compiler/compiler.py b/mindspore/_extends/parallel_compile/akg_compiler/compiler.py index 55bdded4694..a86ca81ffda 100644 --- a/mindspore/_extends/parallel_compile/akg_compiler/compiler.py +++ b/mindspore/_extends/parallel_compile/akg_compiler/compiler.py @@ -27,7 +27,7 @@ def run_compiler(op_json, attrs=None): Returns: None """ - from get_file_path import get_akg_path + from .get_file_path import get_akg_path sys.path.insert(0, get_akg_path()) p = __import__("akg", globals(), locals(), ['ms'], 0) func = getattr(p.ms, "compilewithjson") @@ -35,6 +35,18 @@ def run_compiler(op_json, attrs=None): if not res: raise ValueError("Compile error") +def run_compiler_with_json_name(op_json_name, attrs=None): + """ + Run AKG compiler with json file name + + Args: + op_json_name (str): json file name of the op + + Returns: + None + """ + with open(op_json_name, 'r') as f: + return run_compiler(f.read().strip(), attrs) if __name__ == "__main__": if len(sys.argv) > 2: diff --git a/mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/akg_build.cc b/mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/akg_build.cc new file mode 100644 index 00000000000..ae0764de2be --- /dev/null +++ b/mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/akg_build.cc @@ -0,0 +1,181 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "backend/optimizer/graph_kernel/lite_adapter/akg_build.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "backend/kernel_compiler/akg/akg_kernel_json_generator.h" +#include "ir/anf.h" +#include "ir/func_graph.h" +#include "utils/file_utils.h" +#include "utils/log_adapter.h" + +namespace mindspore::graphkernel { +bool CompileSingleJson(const std::string &json_name) { + std::string attrs = "None"; + std::ostringstream py_cmd; + py_cmd << "from mindspore._extends.parallel_compile.akg_compiler.compiler import run_compiler_with_json_name\n"; + py_cmd << "run_compiler_with_json_name(\'" << json_name << "\', " << attrs << ")"; + std::string cmd = "python -c \"" + py_cmd.str() + "\""; + auto ret = system(cmd.c_str()); + if (!WIFEXITED(ret)) { + MS_LOG(ERROR) << "python process start fail!"; + return false; + } + if (WEXITSTATUS(ret) != 0) { + MS_LOG(ERROR) << "Error json file is: " << json_name; + return false; + } + return true; +} + +bool RetStatus(const int status) { + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) { + MS_LOG(INFO) << "compile all pass for subprocess!"; + return true; + } else { + MS_LOG(ERROR) << "Some jsons compile fail, please check log!"; + } + } else if (WIFSIGNALED(status)) { + MS_LOG(ERROR) << "compile stopped by signal, maybe cost too long time!"; + } else if (WSTOPSIG(status)) { + MS_LOG(ERROR) << "compile process is stopped by others!"; + } else { + MS_LOG(ERROR) << "unknown error in compiling!"; + } + return false; +} + +bool CompileJsonsInList(const std::string &dir_path, const std::vector &json_list) { + size_t i; + pid_t pid; + std::vector child_process; + for (i = 0; i < PROCESS_LIMIT; ++i) { + pid = fork(); + if (pid < 0) { + MS_LOG(ERROR) << "fork error"; + return false; + } else if (pid == 0) { + break; + } else { + child_process.emplace_back(pid); + } + } + if (pid == 0) { + setpgrp(); + (void)alarm(TIME_OUT); + bool all_pass{true}; + for (size_t j = i; j < json_list.size(); j += PROCESS_LIMIT) { + auto res = CompileSingleJson(dir_path + "/" + json_list[j] + ".info"); + if (!res) { + all_pass = false; + } + } + if (all_pass) { + exit(0); + } else { + exit(1); + } + } else { + for (size_t j = 0; j < PROCESS_LIMIT; ++j) { + int status = 0; + waitpid(child_process[j], &status, 0); + // kill child process of child process if overtime + kill(-child_process[j], SIGTERM); + return RetStatus(status); + } + } + return false; +} + +bool SaveJsonInfo(const std::string &json_name, const std::string &info) { + std::string path = json_name + ".info"; + std::ofstream filewrite(path); + if (!filewrite.is_open()) { + MS_LOG(ERROR) << "Open file '" << path << "' failed!"; + return false; + } + filewrite << info << std::endl; + filewrite.close(); + return true; +} + +void GetValidKernelNodes(const FuncGraphPtr &func_graph, std::vector *node_list, + std::vector *input_list, std::vector *output_list) { + MS_EXCEPTION_IF_NULL(func_graph); + MS_EXCEPTION_IF_NULL(node_list); + MS_EXCEPTION_IF_NULL(input_list); + std::vector node_lists = TopoSort(func_graph->get_return()); + for (auto const &node : node_lists) { + auto cnode = node->cast(); + if (cnode == nullptr || !AnfUtils::IsRealKernel(node)) { + continue; + } + node_list->push_back(node); + } + auto parameters = func_graph->parameters(); + input_list->insert(input_list->begin(), parameters.begin(), parameters.end()); + if (IsPrimitiveCNode(func_graph->output(), prim::kPrimMakeTuple)) { + auto fg_output = func_graph->output()->cast(); + MS_EXCEPTION_IF_NULL(fg_output); + output_list->assign(fg_output->inputs().begin() + 1, fg_output->inputs().end()); + } else { + output_list->push_back(func_graph->output()); + } +} + +bool AkgKernelBuilder::CompileJsonsInAnfnodes(const AnfNodePtrList &node_list) { + auto dir_path = FileUtils::CreateNotExistDirs(std::string("./kernel_meta")); + if (!dir_path.has_value()) { + MS_LOG(ERROR) << "Failed to CreateNotExistDirs: ./kernel_meta"; + return false; + } + std::vector json_list; + for (const auto &node : node_list) { + graphkernel::DumpOption option; + option.get_compute_capability = true; + graphkernel::AkgKernelJsonGenerator akg_kernel_json_generator(option); + auto fg = GetCNodeFuncGraph(node); + MS_EXCEPTION_IF_NULL(fg); + auto mng = fg->manager(); + if (mng == nullptr) { + mng = Manage(fg, true); + fg->set_manager(mng); + } + std::vector node_list, input_list, output_list; + GetValidKernelNodes(fg, &node_list, &input_list, &output_list); + akg_kernel_json_generator.CollectFusedJson(node_list, input_list, output_list); + auto json_kernel_name = akg_kernel_json_generator.kernel_name(); + if (find(json_list.begin(), json_list.end(), json_kernel_name) != json_list.end()) { + continue; + } + json_list.push_back(json_kernel_name); + if (!SaveJsonInfo(dir_path.value() + "/" + json_kernel_name, akg_kernel_json_generator.kernel_json_str())) { + return false; + } + } + return CompileJsonsInList(dir_path.value(), json_list); +} +} // namespace mindspore::graphkernel diff --git a/mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/akg_build.h b/mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/akg_build.h new file mode 100644 index 00000000000..83ecef74e22 --- /dev/null +++ b/mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/akg_build.h @@ -0,0 +1,34 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_LITE_ADAPTER_AKG_BUILD_H_ +#define MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_LITE_ADAPTER_AKG_BUILD_H_ +#include +#include "utils/anf_utils.h" + +namespace mindspore::graphkernel { +constexpr size_t PROCESS_LIMIT = 8; +constexpr size_t TIME_OUT = 100; + +class AkgKernelBuilder { + public: + AkgKernelBuilder() = default; + ~AkgKernelBuilder() = default; + + bool CompileJsonsInAnfnodes(const AnfNodePtrList &node_list); +}; +} // namespace mindspore::graphkernel +#endif // MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_LITE_ADAPTER_AKG_BUILD_H_ diff --git a/tests/ut/cpp/CMakeLists.txt b/tests/ut/cpp/CMakeLists.txt index 70151e170e1..4f764cdbe9d 100644 --- a/tests/ut/cpp/CMakeLists.txt +++ b/tests/ut/cpp/CMakeLists.txt @@ -201,6 +201,7 @@ list(REMOVE_ITEM MINDSPORE_SRC_LIST "../../../mindspore/ccsrc/backend/optimizer/ list(REMOVE_ITEM MINDSPORE_SRC_LIST "../../../mindspore/ccsrc/backend/optimizer/gpu/batch_norm_add_relu_grad_fusion.cc") list(REMOVE_ITEM MINDSPORE_SRC_LIST "../../../mindspore/ccsrc/backend/optimizer/gpu/batch_norm_relu_fusion.cc") list(REMOVE_ITEM MINDSPORE_SRC_LIST "../../../mindspore/ccsrc/backend/optimizer/gpu/batch_norm_relu_grad_fusion.cc") +list(REMOVE_ITEM MINDSPORE_SRC_LIST "../../../mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/akg_build.cc") list(REMOVE_ITEM MINDSPORE_SRC_LIST "../../../mindspore/ccsrc/backend/optimizer/graph_kernel/lite_adapter/callback_impl.cc") list(REMOVE_ITEM MINDSPORE_SRC_LIST "../../../mindspore/ccsrc/backend/kernel_compiler/tbe/tbe_kernel_compile.cc")