@@ -176,7 +176,7 @@ cd ${BASEPATH} | |||
mkdir -p output/plugin/nnengine/ge_config/ | |||
find output/ -name graphengine_lib.tar -exec rm {} \; | |||
cp src/ge/engine_manager/engine_conf.json output/plugin/nnengine/ge_config/ | |||
find output/ -maxdepth 1 -name libengine.so -exec mv {} output/plugin/nnengine/ \; | |||
find output/ -maxdepth 1 -name libengine.so -exec mv -f {} output/plugin/nnengine/ \; | |||
tar -cf graphengine_lib.tar output/* | |||
mv -f graphengine_lib.tar output | |||
echo "---------------- GraphEngine package archive generated ----------------" |
@@ -0,0 +1,36 @@ | |||
/** | |||
* Copyright 2019-2020 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 COMPRESS_H | |||
#define COMPRESS_H | |||
#include <uchar.h> | |||
enum CmpStatus { RET_SUCCESS = 0, RET_ERROR = -1 }; | |||
struct CompressConfig { | |||
size_t inputSize; // length of data to compress | |||
size_t engineNum; // how many decompress engines | |||
size_t maxRatio; // how much size of a basic compression block, only 64 supported now (8x: 64 4x: 32) | |||
size_t channel; // channels of L2 or DDR. For load balance | |||
size_t fractalSize; // size of compressing block | |||
bool isTight; // whether compose compressed data tightly | |||
}; | |||
CmpStatus CompressWeights(char* input, const CompressConfig& compressConfig, char* indexs, char* output, | |||
size_t& compressedLength); | |||
#endif // COMPRESS_H |
@@ -0,0 +1,97 @@ | |||
/** | |||
* Copyright 2019-2020 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 PLATFORM_INFO_H | |||
#define PLATFORM_INFO_H | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "platform_info_def.h" | |||
using std::map; | |||
using std::string; | |||
using std::vector; | |||
namespace fe { | |||
class PlatformInfoManager { | |||
public: | |||
PlatformInfoManager(const PlatformInfoManager &) = delete; | |||
PlatformInfoManager &operator=(const PlatformInfoManager &) = delete; | |||
static PlatformInfoManager &Instance(); | |||
uint32_t InitializePlatformInfo(); | |||
uint32_t Finalize(); | |||
uint32_t GetPlatformInfo(const string SoCVersion, PlatformInfo &platformInfo, OptionalInfo &optiCompilationInfo); | |||
void SetOptionalCompilationInfo(OptionalInfo &optiCompilationInfo); | |||
private: | |||
PlatformInfoManager(); | |||
~PlatformInfoManager(); | |||
uint32_t LoadIniFile(string iniFileRealPath); | |||
void Trim(string &str); | |||
uint32_t LoadConfigFile(string realPath); | |||
string RealPath(const std::string &path); | |||
string GetSoFilePath(); | |||
void ParseVersion(map<string, string> &versionMap, string &socVersion, PlatformInfo &platformInfoTemp); | |||
void ParseSocInfo(map<string, string> &socInfoMap, PlatformInfo &platformInfoTemp); | |||
void ParseCubeOfAICoreSpec(map<string, string> &aiCoreSpecMap, PlatformInfo &platformInfoTemp); | |||
void ParseBufferOfAICoreSpec(map<string, string> &aiCoreSpecMap, PlatformInfo &platformInfoTemp); | |||
void ParseUBOfAICoreSpec(map<string, string> &aiCoreSpecMap, PlatformInfo &platformInfoTemp); | |||
void ParseAICoreSpec(map<string, string> &aiCoreSpecMap, PlatformInfo &platformInfoTemp); | |||
void ParseBufferOfAICoreMemoryRates(map<string, string> &aiCoreMemoryRatesMap, PlatformInfo &platformInfoTemp); | |||
void ParseAICoreMemoryRates(map<string, string> &aiCoreMemoryRatesMap, PlatformInfo &platformInfoTemp); | |||
void ParseUBOfAICoreMemoryRates(map<string, string> &aiCoreMemoryRatesMap, PlatformInfo &platformInfoTemp); | |||
void ParseAICoreintrinsicDtypeMap(map<string, string> &aiCoreintrinsicDtypeMap, PlatformInfo &platformInfoTemp); | |||
void ParseVectorCoreSpec(map<string, string> &vectorCoreSpecMap, PlatformInfo &platformInfoTemp); | |||
void ParseVectorCoreMemoryRates(map<string, string> &vectorCoreMemoryRatesMap, PlatformInfo &platformInfoTemp); | |||
void ParseVectorCoreintrinsicDtypeMap(map<string, string> &vectorCoreintrinsicDtypeMap, | |||
PlatformInfo &platformInfoTemp); | |||
uint32_t ParsePlatformInfoFromStrToStruct(map<string, map<string, string>> &contentInfoMap, string &socVersion, | |||
PlatformInfo &platformInfoTemp); | |||
uint32_t AssemblePlatformInfoVector(map<string, map<string, string>> &contentInfoMap); | |||
private: | |||
bool initFlag_; | |||
map<string, PlatformInfo> platformInfoMap_; | |||
OptionalInfo optiCompilationInfo_; | |||
}; | |||
} // namespace fe | |||
#endif |
@@ -0,0 +1,122 @@ | |||
/** | |||
* Copyright 2019-2020 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 PLATFORM_INFO_DEF_H | |||
#define PLATFORM_INFO_DEF_H | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
using std::map; | |||
using std::string; | |||
using std::vector; | |||
namespace fe { | |||
enum MemoryType { DDR = 0, HBM }; | |||
enum L2Type { Cache = 0, Buff }; | |||
typedef struct tagStrInfo { | |||
string aicVersion; | |||
string ccecAICVersion; | |||
string ccecAIVVersion; | |||
string isSupportAIcpuCompiler; | |||
} StrInfo; | |||
typedef struct tagSoCInfo { | |||
uint32_t aiCoreCnt; | |||
uint32_t vectorCoreCnt; | |||
uint32_t aiCpuCnt; | |||
MemoryType memoryType; | |||
uint64_t memorySize; | |||
L2Type l2Type; | |||
uint64_t l2Size; | |||
uint32_t l2PageNum; | |||
} SoCInfo; | |||
typedef struct tagAiCoreSpec { | |||
double cubeFreq; | |||
uint64_t cubeMSize; | |||
uint64_t cubeNSize; | |||
uint64_t cubeKSize; | |||
uint64_t vecCalcSize; | |||
uint64_t l0ASize; | |||
uint64_t l0BSize; | |||
uint64_t l0CSize; | |||
uint64_t l1Size; | |||
uint64_t smaskBuffer; | |||
uint64_t ubSize; | |||
uint64_t ubblockSize; | |||
uint64_t ubbankSize; | |||
uint64_t ubbankNum; | |||
uint64_t ubburstInOneBlock; | |||
uint64_t ubbankGroupNum; | |||
} AiCoreSpec; | |||
typedef struct tagAiCoreMemoryRates { | |||
double ddrRate; | |||
double l2Rate; | |||
double l2ReadRate; | |||
double l2WriteRate; | |||
double l1ToL0ARate; | |||
double l1ToL0BRate; | |||
double l1ToUBRate; | |||
double l0CToUBRate; | |||
double ubToL2Rate; | |||
double ubToDdrRate; | |||
double ubToL1Rate; | |||
} AiCoreMemoryRates; | |||
typedef struct tagVectorCoreSpec { | |||
uint64_t vecCalcSize; | |||
uint64_t smaskBuffer; | |||
uint64_t ubSize; | |||
uint64_t ubblockSize; | |||
uint64_t ubbankSize; | |||
uint64_t ubbankNum; | |||
uint64_t ubburstInOneBlock; | |||
uint64_t ubbankGroupNum; | |||
} VectorCoreSpec; | |||
typedef struct tagVectorCoreMemoryRates { | |||
double ddrRate; | |||
double l2Rate; | |||
double l2ReadRate; | |||
double l2WriteRate; | |||
double ubToL2Rate; | |||
double ubToDdrRate; | |||
} VectorCoreMemoryRates; | |||
typedef struct tagPlatformInfo { | |||
StrInfo strInfo; | |||
SoCInfo socInfo; | |||
AiCoreSpec aiCoreSpec; | |||
AiCoreMemoryRates aiCoreMemoryRates; | |||
map<string, vector<string>> aiCoreIntrinsicDtypeMap; | |||
VectorCoreSpec vectorCoreSpec; | |||
VectorCoreMemoryRates vectorCoreMemoryRates; | |||
map<string, vector<string>> vectorCoreIntrinsicDtypeMap; | |||
} PlatformInfo; | |||
typedef struct tagOptionalInfo { | |||
string socVersion; | |||
string coreType; | |||
uint32_t aiCoreNum; | |||
string l1FusionFlag; | |||
} OptionalInfo; | |||
} // namespace fe | |||
#endif |
@@ -40,6 +40,8 @@ const char *const OPTION_EXEC_EXTERN_PLUGIN_PATH = "ge.soLoadPath"; | |||
const char *const OPTION_EXEC_ENABLE_DUMP = "ge.exec.enableDump"; | |||
const char *const OPTION_EXEC_DUMP_PATH = "ge.exec.dumpPath"; | |||
const char *const OPTION_EXEC_DUMP_STEP = "ge.exec.dumpStep"; | |||
const char *const OPTION_EXEC_ENABLE_INCRE_BUILD = "ge.exec.enableIncreBuild"; | |||
const char *const OPTION_EXEC_INCRE_BUILD_CACHE_PATH = "ge.exec.increBuildCachePath"; | |||
// Hccl flag, if ge.exec.hcclFlag =1, it means load plugin for opskernel, else:ge.exec.hcclFlag =0 | |||
const char *const OPTION_EXEC_HCCL_FLAG = "ge.exec.hcclFlag"; | |||
const char *const OPTION_EXEC_ATOMIC_FLAG = "ge.exec.enable_atomic"; | |||
@@ -116,27 +116,5 @@ class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY OpReceiver { | |||
namespace ge { | |||
using OpRegistrationData = domi::OpRegistrationData; | |||
using OpReceiver = domi::OpReceiver; | |||
class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY HostCpuOp { | |||
public: | |||
HostCpuOp() = default; | |||
virtual ~HostCpuOp() = default; | |||
virtual graphStatus Compute(Operator &op, const std::map<std::string, const Tensor> &inputs, | |||
std::map<std::string, Tensor> &outputs) = 0; | |||
}; | |||
class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY HostCpuOpRegistrar { | |||
public: | |||
HostCpuOpRegistrar(const char *op_type, HostCpuOp *(*create_fn)()); | |||
}; | |||
#define REGISTER_HOST_CPU_OP_BUILDER(name, op) REGISTER_HOST_CPU_OP_BUILDER_UNIQ_HELPER(__COUNTER__, name, op) | |||
#define REGISTER_HOST_CPU_OP_BUILDER_UNIQ_HELPER(ctr, name, op) REGISTER_HOST_CPU_OP_BUILDER_UNIQ(ctr, name, op) | |||
#define REGISTER_HOST_CPU_OP_BUILDER_UNIQ(ctr, name, op) \ | |||
static ::ge::HostCpuOpRegistrar register_host_cpu_op##ctr __attribute__((unused)) = \ | |||
::ge::HostCpuOpRegistrar(name, []() -> ::ge::HostCpuOp * { return new (std::nothrow) op(); }) | |||
} // namespace ge | |||
#endif // INC_EXTERNAL_REGISTER_REGISTER_H_ |
@@ -434,6 +434,7 @@ REGISTER_OPTYPE_DECLARE(STREAMSWITCH, "StreamSwitch"); | |||
REGISTER_OPTYPE_DECLARE(STREAMSWITCHN, "StreamSwitchN"); | |||
REGISTER_OPTYPE_DECLARE(STREAMACTIVE, "StreamActive"); | |||
REGISTER_OPTYPE_DECLARE(MEMCPYASYNC, "MemcpyAsync"); | |||
REGISTER_OPTYPE_DECLARE(MEMCPYADDRASYNC, "MemcpyAddrAsync"); | |||
REGISTER_OPTYPE_DECLARE(STREAMMERGE, "StreamMerge"); | |||
REGISTER_OPTYPE_DECLARE(ENDGRAPH, "EndGraph"); | |||
REGISTER_OPTYPE_DECLARE(SEND, "Send"); | |||
@@ -441,6 +442,7 @@ REGISTER_OPTYPE_DECLARE(RECV, "Recv"); | |||
REGISTER_OPTYPE_DECLARE(LABELSET, "LabelSet"); | |||
REGISTER_OPTYPE_DECLARE(LABELGOTO, "LabelGoto"); | |||
REGISTER_OPTYPE_DECLARE(LABELGOTOEX, "LabelGotoEx"); | |||
REGISTER_OPTYPE_DECLARE(LABELSWITCH, "LabelSwitch"); | |||
REGISTER_OPTYPE_DECLARE(LABELSWITCHBYINDEX, "LabelSwitchByIndex"); | |||
@@ -979,9 +979,14 @@ GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string ATTR_NAM | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string ATTR_N_BATCH_SPILT; | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string ATTR_NO_TASK_AND_DUMP_NEEDED; | |||
// functional ops attr | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string ATTR_NAME_WHILE_COND; | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string ATTR_NAME_WHILE_BODY; | |||
// used for label switch | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string ATTR_NAME_LABEL_SWITCH_INDEX; | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string ATTR_NAME_LABEL_SWITCH_LIST; | |||
// Varible | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string REF_VAR_SRC_VAR_NAME; | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY extern const std::string VAR_ATTR_SRC_VAR_NAME; | |||
@@ -22,7 +22,7 @@ | |||
#include <string> | |||
#include <vector> | |||
#include "graph/anchor.h" | |||
#include "detail/attributes_holder.h" | |||
#include "graph/detail/attributes_holder.h" | |||
#include "graph/ge_tensor.h" | |||
#include "graph/graph.h" | |||
#include "graph/node.h" | |||
@@ -262,6 +262,8 @@ class GraphUtils { | |||
static graphStatus MoveOutCtrlEdges(NodePtr &src_node, NodePtr &dst_node); | |||
static ComputeGraphPtr FindRootGraph(ComputeGraphPtr graph); | |||
static graphStatus TopologicalSortingByName(const ge::ComputeGraphPtr &compute_graph, vector<NodePtr> &node_vec); | |||
}; | |||
class ComputeGraphBuilder { | |||
@@ -54,17 +54,34 @@ GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY size_t ComputeGraph::GetAllNodesS | |||
return s; | |||
} | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY ComputeGraph::Vistor<NodePtr> ComputeGraph::GetAllNodes() const { | |||
vector<NodePtr> all_nodes(nodes_.size()); | |||
(void)std::copy(nodes_.begin(), nodes_.end(), all_nodes.begin()); | |||
for (const auto &sub_graph : sub_graph_) { | |||
if (sub_graph == nullptr) { | |||
GELOGW("sub graph is nullptr"); | |||
if (sub_graph_.empty()) { | |||
return Vistor<NodePtr>(shared_from_this(), nodes_); | |||
} | |||
std::vector<NodePtr> all_nodes; | |||
std::deque<NodePtr> candidates; | |||
candidates.insert(candidates.begin(), nodes_.begin(), nodes_.end()); | |||
while (!candidates.empty()) { | |||
NodePtr node = candidates.front(); | |||
all_nodes.emplace_back(node); | |||
candidates.pop_front(); | |||
OpDescPtr op_desc = node->GetOpDesc(); | |||
if (op_desc == nullptr) { | |||
continue; | |||
} | |||
for (const auto &node : sub_graph->GetAllNodes()) { | |||
all_nodes.push_back(node); | |||
const auto &subgraph_names = op_desc->GetSubgraphInstanceNames(); | |||
for (auto name_iter = subgraph_names.rbegin(); name_iter != subgraph_names.rend(); ++name_iter) { | |||
auto subgraph = GetSubgraph(*name_iter); | |||
if (subgraph != nullptr) { | |||
candidates.insert(candidates.begin(), subgraph->nodes_.begin(), subgraph->nodes_.end()); | |||
} | |||
} | |||
} | |||
return Vistor<NodePtr>(shared_from_this(), all_nodes); | |||
} | |||
size_t ComputeGraph::GetDirectNodesSize() const { return nodes_.size(); } | |||
@@ -602,7 +619,7 @@ GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY graphStatus ComputeGraph::InsertE | |||
graphStatus ComputeGraph::DFSTopologicalSorting(std::vector<NodePtr> &node_vec, | |||
std::map<NodePtr, uint32_t> &map_in_edge_num, | |||
std::vector<NodePtr> &stack) { | |||
GELOGI("Runing_Dfs_Sort"); | |||
GELOGI("Runing_Dfs_Sort: %s", name_.c_str()); | |||
// Record the number of non data nodes but no input nodes | |||
GE_CHK_BOOL_EXEC(SortNodes(stack, map_in_edge_num) == GRAPH_SUCCESS, return GRAPH_FAILED, "sort nodes failed"); | |||
@@ -647,7 +664,7 @@ graphStatus ComputeGraph::DFSTopologicalSorting(std::vector<NodePtr> &node_vec, | |||
graphStatus ComputeGraph::BFSTopologicalSorting(std::vector<NodePtr> &node_vec, | |||
std::map<NodePtr, uint32_t> &map_in_edge_num, | |||
std::deque<NodePtr> &stack) { | |||
GELOGI("Runing_Bfs_Sort"); | |||
GELOGI("Runing_Bfs_Sort: %s", name_.c_str()); | |||
std::vector<NodePtr> stack_input; | |||
std::map<string, NodePtr> breadth_node_map; | |||
// Record the number of non data nodes but no input nodes | |||
@@ -735,7 +752,7 @@ GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY graphStatus ComputeGraph::Topolog | |||
use_BFS = true; | |||
} | |||
} else { | |||
GELOGW("Get OPTION_GRAPH_RUN_MODE failed, use BFSTopologicalSorting by default."); | |||
GELOGW("OPTION_GRAPH_RUN_MODE not set, use BFSTopologicalSorting by default."); | |||
} | |||
if (use_BFS) { | |||
@@ -955,11 +955,8 @@ const std::string ATTR_NAME_DATA_DUMP_ORIGIN_FORMAT = "_datadump_origin_format"; | |||
const std::string ATTR_NAME_DATA_DUMP_ORIGIN_DATA_TYPE = "_datadump_origin_data_type"; | |||
// functional ops attr | |||
const std::string ATTR_NAME_TCOND = "Tcond"; | |||
const std::string ATTR_NAME_TIN = "Tin"; | |||
const std::string ATTR_NAME_TOUT = "Tout"; | |||
const std::string ATTR_NAME_THEN_BRANCH = "then_branch"; | |||
const std::string ATTR_NAME_ELSE_BRANCH = "else_branch"; | |||
const std::string ATTR_NAME_WHILE_COND = "cond"; | |||
const std::string ATTR_NAME_WHILE_BODY = "body"; | |||
// used for label switch | |||
const std::string ATTR_NAME_LABEL_SWITCH_INDEX = "_label_switch_index"; | |||
@@ -28,6 +28,7 @@ | |||
#include <cstring> | |||
#include <fstream> | |||
#include <iomanip> | |||
#include <queue> | |||
#include "./ge_context.h" | |||
#include "debug/ge_util.h" | |||
@@ -1999,4 +2000,60 @@ void PartialGraphBuilder::BuildExistNodes(graphStatus &error_code, std::string & | |||
GELOGD("Build exist nodes succ."); | |||
} | |||
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY graphStatus | |||
GraphUtils::TopologicalSortingByName(const ge::ComputeGraphPtr &compute_graph, vector<NodePtr> &node_vec) { | |||
std::vector<NodePtr> stack_input; | |||
std::map<NodePtr, uint32_t> map_in_edge_num; | |||
graphStatus ret = compute_graph->SortNodes(stack_input, map_in_edge_num); | |||
if (ret != GRAPH_SUCCESS) { | |||
GELOGE(GRAPH_FAILED, "Sort nodes failed."); | |||
return GRAPH_FAILED; | |||
} | |||
const size_t non_user_input_index = stack_input.size() - compute_graph->inputs_order_.size() - 1; | |||
std::sort(stack_input.begin(), stack_input.begin() + non_user_input_index, | |||
[](const NodePtr &a, const NodePtr &b) -> bool { return (a->GetName() > b->GetName()); }); | |||
std::queue<NodePtr> stack; | |||
NodePtr cur_node = nullptr; | |||
std::map<string, NodePtr> name_node_map; | |||
vector<string> nodes_name; | |||
while (!stack_input.empty() || !stack.empty()) { | |||
if (!stack.empty()) { | |||
cur_node = stack.front(); | |||
stack.pop(); | |||
} else { | |||
cur_node = stack_input.back(); | |||
stack_input.pop_back(); | |||
} | |||
node_vec.emplace_back(cur_node); | |||
compute_graph->CollectBreadthOutNode(cur_node, map_in_edge_num, name_node_map); | |||
for (const auto &iter : name_node_map) { | |||
nodes_name.emplace_back(iter.first); | |||
} | |||
std::sort(nodes_name.begin(), nodes_name.end()); | |||
for (const auto &iter : nodes_name) { | |||
stack.push(name_node_map[iter]); | |||
} | |||
name_node_map.clear(); | |||
nodes_name.clear(); | |||
} | |||
// If they are not equal, there is a closed loop | |||
if (node_vec.size() != compute_graph->nodes_.size()) { | |||
std::set<Node *> itered_nodes_set; | |||
for (auto &node : node_vec) { | |||
itered_nodes_set.insert(node.get()); | |||
} | |||
GE_LOGE("Failed to do topo sorting total %zu, itered %zu, exist closed loop in graph.", | |||
compute_graph->nodes_.size(), node_vec.size()); | |||
for (auto &node : compute_graph->nodes_) { | |||
if (itered_nodes_set.count(node.get()) == 0) { | |||
GE_LOGE("The node %s does not itered when topological sorting", node->GetName().c_str()); | |||
} | |||
} | |||
return GRAPH_FAILED; | |||
} | |||
return GRAPH_SUCCESS; | |||
} | |||
} // namespace ge |
@@ -41,6 +41,7 @@ include_directories(${GE_SOURCE_DIR}/inc/external/graph) | |||
include_directories(${GE_SOURCE_DIR}/inc/framework) | |||
include_directories(${GE_SOURCE_DIR}/inc/framework/common) | |||
include_directories(${GE_SOURCE_DIR}/inc/runtime) | |||
include_directories(${GE_SOURCE_DIR}/third_party/fwkacllib) | |||
include_directories(${GE_SOURCE_DIR}/third_party/fwkacllib/inc) | |||
include_directories(${GE_SOURCE_DIR}/third_party/fwkacllib/inc/cce) | |||
include_directories(${GE_SOURCE_DIR}/third_party/securec/include) | |||
@@ -55,6 +56,7 @@ file(GLOB TRAIN_SRC_LIST RELATIVE ${CMAKE_CURRENT_LIST_DIR} | |||
"common/formats/utils/formats_trans_utils.cc" | |||
"common/fp16_t.cc" | |||
"common/ge/plugin_manager.cc" | |||
"common/helper/model_cache_helper.cc" | |||
"common/profiling/profiling_manager.cc" | |||
"engine_manager/dnnengine_manager.cc" | |||
"ge_local_engine/engine/host_cpu_engine.cc" | |||
@@ -92,6 +94,7 @@ file(GLOB TRAIN_SRC_LIST RELATIVE ${CMAKE_CURRENT_LIST_DIR} | |||
"graph/load/new_model_manager/task_info/kernel_task_info.cc" | |||
"graph/load/new_model_manager/task_info/label_goto_task_info.cc" | |||
"graph/load/new_model_manager/task_info/label_set_task_info.cc" | |||
"graph/load/new_model_manager/task_info/memcpy_addr_async_task_info.cc" | |||
"graph/load/new_model_manager/task_info/memcpy_async_task_info.cc" | |||
"graph/load/new_model_manager/task_info/profiler_trace_task_info.cc" | |||
"graph/load/new_model_manager/task_info/stream_active_task_info.cc" | |||
@@ -269,6 +272,7 @@ file(GLOB INFER_SRC_LIST RELATIVE ${CMAKE_CURRENT_LIST_DIR} | |||
"common/formats/utils/formats_trans_utils.cc" | |||
"common/fp16_t.cc" | |||
"common/ge/plugin_manager.cc" | |||
"common/helper/model_cache_helper.cc" | |||
"common/profiling/profiling_manager.cc" | |||
"engine_manager/dnnengine_manager.cc" | |||
"ge_local_engine/engine/host_cpu_engine.cc" | |||
@@ -305,6 +309,7 @@ file(GLOB INFER_SRC_LIST RELATIVE ${CMAKE_CURRENT_LIST_DIR} | |||
"graph/load/new_model_manager/task_info/kernel_task_info.cc" | |||
"graph/load/new_model_manager/task_info/label_goto_task_info.cc" | |||
"graph/load/new_model_manager/task_info/label_set_task_info.cc" | |||
"graph/load/new_model_manager/task_info/memcpy_addr_async_task_info.cc" | |||
"graph/load/new_model_manager/task_info/memcpy_async_task_info.cc" | |||
"graph/load/new_model_manager/task_info/profiler_trace_task_info.cc" | |||
"graph/load/new_model_manager/task_info/stream_active_task_info.cc" | |||
@@ -470,7 +475,7 @@ target_link_libraries(ge_compiler | |||
${slog} | |||
${mmpa} | |||
${msprof} | |||
${runtime} | |||
${runtime_compiler} | |||
${resouce} | |||
rt | |||
dl) |
@@ -134,10 +134,6 @@ Status DataTypeTransfer::TransDataType(const CastArgs &args, TransResult &result | |||
} | |||
auto trans_mode = iter->second; | |||
if (args.src_data_size == 0) { | |||
GELOGE(PARAM_INVALID, "Invalid src data size %zu", args.src_data_size); | |||
return PARAM_INVALID; | |||
} | |||
int size = GetSizeByDataType(args.dst_data_type); | |||
if (size <= 0) { | |||
GELOGE(PARAM_INVALID, "Failed to calc size from data type %s", | |||
@@ -149,6 +145,12 @@ Status DataTypeTransfer::TransDataType(const CastArgs &args, TransResult &result | |||
return PARAM_INVALID; | |||
} | |||
size_t total_size = static_cast<size_t>(args.src_data_size * size); | |||
result.length = total_size; | |||
if (total_size == 0) { | |||
GELOGI("In TransDataType, total_size is zero, has no data."); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[total_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to alloc the memory for dst buf %zu, data size %zu", total_size, args.src_data_size); | |||
@@ -162,7 +164,6 @@ Status DataTypeTransfer::TransDataType(const CastArgs &args, TransResult &result | |||
return INTERNAL_ERROR; | |||
} | |||
result.data = dst; | |||
result.length = total_size; | |||
return SUCCESS; | |||
} | |||
@@ -134,6 +134,11 @@ Status FormatTransferC1hwncoc0Hwcn::TransFormat(const TransArgs &args, TransResu | |||
int size = GetSizeByDataType(args.src_data_type); | |||
int64_t total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -88,6 +88,11 @@ Status TransFormatDhwckToFz3D(const TransArgs &args, TransResult &result) { | |||
dst_size *= dim; | |||
} | |||
dst_size *= data_size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -89,6 +89,11 @@ Status TransFormatDhwncToFz3DTranspose(const TransArgs &args, TransResult &resul | |||
dst_size *= dim; | |||
} | |||
dst_size *= data_size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -116,6 +116,11 @@ Status CheckShapeRelation(const TransArgs &args, ShapeVector &hw_shape) { | |||
Status TransFormatFromNdToFracNz(const TransArgs &args, TransResult &result, const ShapeVector &hw_shape) { | |||
int size = GetSizeByDataType(args.src_data_type); | |||
int64_t dst_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size](), std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -184,6 +189,11 @@ Status TransFormatFromNdToFracNz(const TransArgs &args, TransResult &result, con | |||
Status TransFormatFromFracNzToNd(const TransArgs &args, TransResult &result, const ShapeVector &dst_hw_shape) { | |||
int size = GetSizeByDataType(args.src_data_type); | |||
int64_t dst_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -119,6 +119,11 @@ Status TransFormatFromNchwToFz(const TransArgs &args, TransResult &result) { | |||
int64_t total_ele_cnt = hf_cnt * vf_cnt * fractal_ele_cnt; | |||
int size = GetSizeByDataType(args.src_data_type); | |||
int64_t dst_size = total_ele_cnt * size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -194,6 +199,11 @@ Status TransFormatHwcnToFz(const TransArgs &args, TransResult &result) { | |||
dst_size *= dim; | |||
} | |||
dst_size *= data_size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -259,6 +269,11 @@ Status TransFormatNhwcToFz(const TransArgs &args, TransResult &result) { | |||
dst_size *= dim; | |||
} | |||
dst_size *= data_size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -117,6 +117,11 @@ Status CheckShapeRelation(const TransArgs &args, ShapeVector &hw_shape) { | |||
Status TransFormatFromNdToFracZz(const TransArgs &args, TransResult &result, const ShapeVector &hw_shape) { | |||
int size = GetSizeByDataType(args.src_data_type); | |||
int64_t dst_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size](), std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -153,8 +158,8 @@ Status TransFormatFromNdToFracZz(const TransArgs &args, TransResult &result, con | |||
auto src_offset = (src_h_head + w1_idx * w0) * size; | |||
auto dst_offset = (h0_head + w1_idx * h0w0) * size; | |||
auto protected_size = dst_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
auto ret = memcpy_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), args.data + src_offset, | |||
static_cast<size_t>(size * w0)); | |||
if (ret != EOK) { | |||
@@ -169,8 +174,8 @@ Status TransFormatFromNdToFracZz(const TransArgs &args, TransResult &result, con | |||
auto src_offset = (src_h_head + src_w_idx) * size; | |||
auto dst_offset = (w0_head + w0_idx) * size; | |||
auto protected_size = dst_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
auto ret = memcpy_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), args.data + src_offset, | |||
static_cast<size_t>(size)); | |||
if (ret != EOK) { | |||
@@ -189,6 +194,11 @@ Status TransFormatFromNdToFracZz(const TransArgs &args, TransResult &result, con | |||
Status TransFormatFromFracZzToNd(const TransArgs &args, TransResult &result, const ShapeVector &dst_hw_shape) { | |||
int size = GetSizeByDataType(args.src_data_type); | |||
int64_t dst_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (dst_size == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size](), std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -226,8 +236,8 @@ Status TransFormatFromFracZzToNd(const TransArgs &args, TransResult &result, con | |||
auto src_offset = (h0_head + w1_idx * h0w0) * size; | |||
auto dst_offset = (dst_h_head + w1_idx * w0) * size; | |||
auto protected_size = dst_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
auto ret = memcpy_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), args.data + src_offset, | |||
static_cast<size_t>(size * w0)); | |||
if (ret != EOK) { | |||
@@ -242,8 +252,8 @@ Status TransFormatFromFracZzToNd(const TransArgs &args, TransResult &result, con | |||
auto dst_w_idx = w1_head + w0_idx; | |||
auto dst_offset = (dst_h_head + dst_w_idx) * size; | |||
auto protected_size = dst_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? dst_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
auto ret = memcpy_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), args.data + src_offset, | |||
static_cast<size_t>(size)); | |||
if (ret != EOK) { | |||
@@ -133,6 +133,12 @@ Status FormatTransferFracZHwcn::TransFormat(const TransArgs &args, TransResult & | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -133,6 +133,12 @@ Status FormatTransferFracZNchw::TransFormat(const TransArgs &args, TransResult & | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -140,6 +146,7 @@ Status FormatTransferFracZNchw::TransFormat(const TransArgs &args, TransResult & | |||
GELOGD("Begin to trans format from FracZ to NCHW, src shape %s, data type %s, dst shape %s, memory size %ld", | |||
ShapeToString(args.src_shape).c_str(), TypeUtils::DataTypeToSerialString(args.src_data_type).c_str(), | |||
ShapeToString(args.dst_shape).c_str(), total_size); | |||
if (GetDstDataAfterTrans(args, result, size, total_size) != SUCCESS) { | |||
GELOGE(INTERNAL_ERROR, "Failed to get data after trans, src shape %s, data type %s, dst shape %s, memory size %ld", | |||
ShapeToString(args.src_shape).c_str(), TypeUtils::DataTypeToSerialString(args.src_data_type).c_str(), | |||
@@ -132,6 +132,12 @@ Status FormatTransferFracZNhwc::TransFormat(const TransArgs &args, TransResult & | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -35,7 +35,7 @@ Status TransShapeHwcnToC1hwncoc0(const DataType &data_type, const std::vector<in | |||
std::vector<int64_t> &dst_shape) { | |||
auto cube_size = GetCubeSizeByDataType(data_type); | |||
dst_shape.clear(); | |||
dst_shape.push_back((src_shape.at(kHwcnC) - 1) / cube_size + 1); | |||
dst_shape.push_back(Ceil(src_shape.at(kHwcnC), static_cast<int64_t>(cube_size))); | |||
dst_shape.push_back(src_shape.at(kHwcnH)); | |||
dst_shape.push_back(src_shape.at(kHwcnW)); | |||
dst_shape.push_back(src_shape.at(kHwcnN)); | |||
@@ -169,6 +169,12 @@ Status FormatTransferHwcnC1hwncoc0::TransFormat(const TransArgs &args, TransResu | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -58,7 +58,7 @@ Status CheckArgsForNc1hwc0ToNchw(const TransArgs &args) { | |||
} | |||
if (src_shape.at(kNc1hwc0H) != dst_shape.at(kNchwH) || src_shape.at(kNc1hwc0W) != dst_shape.at(kNchwW) || | |||
src_shape.at(kNc1hwc0N) != dst_shape.at(kNchwN) || src_shape.at(kNc1hwc0C0) != c0 || | |||
src_shape.at(kNc1hwc0C1) != (dst_shape.at(kNchwC) - 1) / c0 + 1) { | |||
src_shape.at(kNc1hwc0C1) != (Ceil(dst_shape.at(kNchwC), c0))) { | |||
GELOGE(PARAM_INVALID, "Failed to check relationship between src and dst shape, src shape %s, dst shape %s", | |||
ShapeToString(src_shape).c_str(), ShapeToString(dst_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -102,8 +102,8 @@ Status GetDstDataAfterTrans(const TransArgs &args, TransResult &result, const in | |||
auto src_offset = src_idx * size; | |||
auto dst_offset = dst_idx * size; | |||
auto protected_size = total_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
auto ret = memcpy_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), args.data + src_offset, | |||
static_cast<size_t>(size)); | |||
if (ret != EOK) { | |||
@@ -130,6 +130,12 @@ Status FormatTransferNc1hwc0Nchw::TransFormat(const TransArgs &args, TransResult | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -58,7 +58,7 @@ Status CheckArgsForNc1hwc0ToNhwc(const TransArgs &args) { | |||
} | |||
if (src_shape.at(kNc1hwc0H) != dst_shape.at(kNhwcH) || src_shape.at(kNc1hwc0W) != dst_shape.at(kNhwcW) || | |||
src_shape.at(kNc1hwc0N) != dst_shape.at(kNhwcN) || src_shape.at(kNc1hwc0C0) != c0 || | |||
src_shape.at(kNc1hwc0C1) != (dst_shape.at(kNhwcC) - 1) / c0 + 1) { | |||
src_shape.at(kNc1hwc0C1) != (Ceil(dst_shape.at(kNhwcC), c0))) { | |||
GELOGE(PARAM_INVALID, "Failed to check relationship between src and dst shape, src shape %s, dst shape %s", | |||
ShapeToString(src_shape).c_str(), ShapeToString(dst_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -102,8 +102,8 @@ Status GetDstDataAfterTrans(const TransArgs &args, TransResult &result, const in | |||
auto src_offset = src_idx * size; | |||
auto dst_offset = dst_idx * size; | |||
auto protected_size = total_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
auto ret = memcpy_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), args.data + src_offset, | |||
static_cast<size_t>(size)); | |||
if (ret != EOK) { | |||
@@ -130,6 +130,12 @@ Status FormatTransferNc1hwc0Nhwc::TransFormat(const TransArgs &args, TransResult | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -134,6 +134,10 @@ Status TransFormatFromNchwToFzC04(const TransArgs &args, TransResult &result) { | |||
GELOGE(INTERNAL_ERROR, "int64 mul overflow.A[%lld], B[%lld]", total_ele_cnt, size); | |||
return INTERNAL_ERROR); | |||
int64_t dst_size = total_ele_cnt * size; | |||
if (dst_size == 0) { | |||
result.length = 0; | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
@@ -219,6 +223,10 @@ Status PaddingNC(const TransArgs &args, TransArgs &args_tmp, std::shared_ptr<uin | |||
return INTERNAL_ERROR); | |||
int64_t dst_size = total_ele_cnt * size; | |||
if (dst_size == 0) { | |||
return SUCCESS; | |||
} | |||
dst.reset(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, "Failed to trans format from %s to %s, can not alloc the memory for dst buf %ld", | |||
@@ -40,7 +40,7 @@ Status TransShapeNchwToNc1hwc0(const std::vector<int64_t> &src_shape, DataType d | |||
} | |||
dst_shape.clear(); | |||
dst_shape.push_back(src_shape.at(kNchwN)); | |||
dst_shape.push_back((src_shape.at(kNchwC) - 1) / c0 + 1); | |||
dst_shape.push_back(Ceil(src_shape.at(kNchwC), c0)); | |||
dst_shape.push_back(src_shape.at(kNchwH)); | |||
dst_shape.push_back(src_shape.at(kNchwW)); | |||
dst_shape.push_back(c0); | |||
@@ -74,25 +74,8 @@ Status CheckArgsForNchwToNc1hwc0(const TransArgs &args) { | |||
return SUCCESS; | |||
} | |||
} // namespace | |||
Status FormatTransferNchwNc1hwc0::TransFormat(const TransArgs &args, TransResult &result) { | |||
if (CheckArgsForNchwToNc1hwc0(args) != SUCCESS) { | |||
return PARAM_INVALID; | |||
} | |||
// Guarantee the validity of parameters in check function | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
} | |||
GELOGD( | |||
"Begin to trans format from NCHW to NC1HWC0, src shape %s, data type " | |||
"%s, dst shape %s memory size %ld", | |||
ShapeToString(args.src_shape).c_str(), TypeUtils::DataTypeToSerialString(args.src_data_type).c_str(), | |||
ShapeToString(args.dst_shape).c_str(), total_size); | |||
Status GetDstDataAfterTrans(const TransArgs &args, TransResult &result, const int size, const int64_t total_size) { | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[total_size], std::default_delete<uint8_t[]>()); | |||
if (dst == nullptr) { | |||
GELOGE(OUT_OF_MEMORY, | |||
@@ -132,8 +115,8 @@ Status FormatTransferNchwNc1hwc0::TransFormat(const TransArgs &args, TransResult | |||
int64_t dst_index = c0_idx + w_head_addr; | |||
int64_t dst_offset = dst_index * size; | |||
auto protected_size = total_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
int64_t cIdx = c0_idx + c1_idx * c0; | |||
int64_t srcIdx = n_idx * chw + cIdx * hw + h_idx * w + w_idx; | |||
auto src_offset = srcIdx * size; | |||
@@ -150,7 +133,7 @@ Status FormatTransferNchwNc1hwc0::TransFormat(const TransArgs &args, TransResult | |||
} | |||
} else { | |||
auto ret = | |||
memset_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), 0, static_cast<size_t>(size)); | |||
memset_s(dst.get() + dst_offset, static_cast<size_t>(protected_size), 0, static_cast<size_t>(size)); | |||
if (ret != EOK) { | |||
GELOGE(INTERNAL_ERROR, | |||
"Failed to set to 0 to " | |||
@@ -169,6 +152,39 @@ Status FormatTransferNchwNc1hwc0::TransFormat(const TransArgs &args, TransResult | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
} // namespace | |||
Status FormatTransferNchwNc1hwc0::TransFormat(const TransArgs &args, TransResult &result) { | |||
if (CheckArgsForNchwToNc1hwc0(args) != SUCCESS) { | |||
return PARAM_INVALID; | |||
} | |||
// Guarantee the validity of parameters in check function | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
} | |||
GELOGD( | |||
"Begin to trans format from NCHW to NC1HWC0, src shape %s, data type " | |||
"%s, dst shape %s memory size %ld", | |||
ShapeToString(args.src_shape).c_str(), TypeUtils::DataTypeToSerialString(args.src_data_type).c_str(), | |||
ShapeToString(args.dst_shape).c_str(), total_size); | |||
if (GetDstDataAfterTrans(args, result, size, total_size) != SUCCESS) { | |||
GELOGE(INTERNAL_ERROR, "Failed to get data after trans, src shape %s, data type %s, dst shape %s, memory size %ld", | |||
ShapeToString(args.src_shape).c_str(), TypeUtils::DataTypeToSerialString(args.src_data_type).c_str(), | |||
ShapeToString(args.dst_shape).c_str(), total_size); | |||
return INTERNAL_ERROR; | |||
} | |||
return SUCCESS; | |||
} | |||
Status FormatTransferNchwNc1hwc0::TransShape(Format src_format, const std::vector<int64_t> &src_shape, | |||
DataType data_type, Format dst_format, std::vector<int64_t> &dst_shape) { | |||
@@ -38,7 +38,7 @@ Status TransShapeNhwcToNc1hwc0(const std::vector<int64_t> &src_shape, DataType d | |||
} | |||
dst_shape.clear(); | |||
dst_shape.push_back(src_shape.at(kNhwcN)); | |||
dst_shape.push_back((src_shape.at(kNhwcC) - 1) / c0 + 1); | |||
dst_shape.push_back(Ceil(src_shape.at(kNhwcC), c0)); | |||
dst_shape.push_back(src_shape.at(kNhwcH)); | |||
dst_shape.push_back(src_shape.at(kNhwcW)); | |||
dst_shape.push_back(c0); | |||
@@ -119,8 +119,8 @@ Status GetDstDataAfterTrans(const TransArgs &args, TransResult &result, const in | |||
int64_t dst_idx = c0_idx + w_head_addr; | |||
int64_t dst_offset = dst_idx * size; | |||
auto protected_size = total_size - dst_offset < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? total_size - dst_offset | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
int64_t c_idx = c0_idx + c1_idx * c0; | |||
int64_t src_idx = n_idx * hwc + h_idx * wc + w_idx * c + c_idx; | |||
auto src_offset = src_idx * size; | |||
@@ -161,6 +161,12 @@ Status FormatTransferNhwcNc1hwc0::TransFormat(const TransArgs &args, TransResult | |||
int size = GetSizeByDataType(args.src_data_type); | |||
auto total_size = GetItemNumByShape(args.dst_shape) * size; | |||
if (total_size <= 0) { | |||
int64_t src_size = GetItemNumByShape(args.src_shape); | |||
if (total_size == 0 && src_size == 0) { | |||
result.length = static_cast<size_t>(total_size); | |||
return SUCCESS; | |||
} | |||
GELOGE(INTERNAL_ERROR, "Get %ld total size from dst shape %s, src shape %s", total_size, | |||
ShapeToString(args.dst_shape).c_str(), ShapeToString(args.src_shape).c_str()); | |||
return PARAM_INVALID; | |||
@@ -27,22 +27,22 @@ namespace ge { | |||
namespace formats { | |||
namespace { | |||
std::map<Format, std::map<Format, std::vector<int64_t>>> perm_args{ | |||
{FORMAT_NCHW, | |||
{{FORMAT_NHWC, std::vector<int64_t>({0, 2, 3, 1})}, | |||
{FORMAT_HWCN, std::vector<int64_t>({2, 3, 1, 0})}, | |||
{FORMAT_CHWN, std::vector<int64_t>({1, 2, 3, 0})}}}, | |||
{FORMAT_NHWC, | |||
{{FORMAT_NCHW, std::vector<int64_t>({0, 3, 1, 2})}, | |||
{FORMAT_CHWN, std::vector<int64_t>({3, 1, 2, 0})}, | |||
{FORMAT_HWCN, std::vector<int64_t>({1, 2, 3, 0})}}}, | |||
{FORMAT_HWCN, | |||
{{FORMAT_NCHW, std::vector<int64_t>({3, 2, 0, 1})}, | |||
{FORMAT_NHWC, std::vector<int64_t>({3, 0, 1, 2})}, | |||
{FORMAT_CHWN, std::vector<int64_t>({2, 0, 1, 3})}}}, | |||
{FORMAT_CHWN, | |||
{{FORMAT_NCHW, std::vector<int64_t>({3, 0, 1, 2})}, | |||
{FORMAT_NHWC, std::vector<int64_t>({3, 1, 2, 0})}, | |||
{FORMAT_HWCN, std::vector<int64_t>({1, 2, 0, 3})}}}, | |||
{FORMAT_NCHW, | |||
{{FORMAT_NHWC, std::vector<int64_t>({0, 2, 3, 1})}, | |||
{FORMAT_HWCN, std::vector<int64_t>({2, 3, 1, 0})}, | |||
{FORMAT_CHWN, std::vector<int64_t>({1, 2, 3, 0})}}}, | |||
{FORMAT_NHWC, | |||
{{FORMAT_NCHW, std::vector<int64_t>({0, 3, 1, 2})}, | |||
{FORMAT_CHWN, std::vector<int64_t>({3, 1, 2, 0})}, | |||
{FORMAT_HWCN, std::vector<int64_t>({1, 2, 3, 0})}}}, | |||
{FORMAT_HWCN, | |||
{{FORMAT_NCHW, std::vector<int64_t>({3, 2, 0, 1})}, | |||
{FORMAT_NHWC, std::vector<int64_t>({3, 0, 1, 2})}, | |||
{FORMAT_CHWN, std::vector<int64_t>({2, 0, 1, 3})}}}, | |||
{FORMAT_CHWN, | |||
{{FORMAT_NCHW, std::vector<int64_t>({3, 0, 1, 2})}, | |||
{FORMAT_NHWC, std::vector<int64_t>({3, 1, 2, 0})}, | |||
{FORMAT_HWCN, std::vector<int64_t>({1, 2, 0, 3})}}}, | |||
}; | |||
bool IsShapeArgValid(const std::vector<int64_t> &src_shape, const std::vector<int64_t> &perm_arg) { | |||
@@ -51,8 +51,8 @@ bool IsShapeArgValid(const std::vector<int64_t> &src_shape, const std::vector<in | |||
return false; | |||
} | |||
for (auto dim : src_shape) { | |||
if (dim <= 0) { | |||
GELOGE(PARAM_INVALID, "Failed to transpose, zero dim in src shape %s", ShapeToString(src_shape).c_str()); | |||
if (dim < 0) { | |||
GELOGE(PARAM_INVALID, "Failed to transpose, negative dim in src shape %s", ShapeToString(src_shape).c_str()); | |||
return false; | |||
} | |||
} | |||
@@ -146,20 +146,24 @@ Status Transpose(const uint8_t *src, const std::vector<int64_t> &src_shape, Data | |||
int64_t dst_ele_num = GetItemNumByShape(dst_shape); | |||
int64_t data_size = GetSizeByDataType(src_data_type); | |||
int64_t dst_size = data_size * dst_ele_num; | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
GELOGD("Begin to transpose, src shape %s, perm arg %s, dst shape %s, data type %s", JoinToString(src_shape).c_str(), | |||
JoinToString(perm_arg).c_str(), JoinToString(dst_shape).c_str(), | |||
TypeUtils::DataTypeToSerialString(src_data_type).c_str()); | |||
if (dst_ele_num == 0) { | |||
result.length = static_cast<size_t>(dst_size); | |||
return SUCCESS; | |||
} | |||
std::shared_ptr<uint8_t> dst(new (std::nothrow) uint8_t[dst_size], std::default_delete<uint8_t[]>()); | |||
int64_t dst_index = 0; | |||
std::vector<int64_t> dst_indexes(dst_shape.size()); | |||
while (dst_index < dst_ele_num) { | |||
auto src_offset = GenOffset(src_heads, dst_indexes) * data_size; | |||
auto dst_offset_bytes = dst_index * data_size; | |||
auto protected_size = dst_size - dst_offset_bytes < static_cast<int64_t>(SECUREC_MEM_MAX_LEN) | |||
? dst_size - dst_offset_bytes | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
? dst_size - dst_offset_bytes | |||
: static_cast<int64_t>(SECUREC_MEM_MAX_LEN); | |||
auto ret = memcpy_s(dst.get() + dst_offset_bytes, static_cast<size_t>(protected_size), src + src_offset, | |||
static_cast<size_t>(data_size)); | |||
if (ret != EOK) { | |||
@@ -24,6 +24,7 @@ | |||
#include <string> | |||
#include <vector> | |||
#include "common/formats/utils/formats_trans_utils.h" | |||
#include "framework/common/debug/ge_log.h" | |||
#include "framework/common/ge_inner_error_codes.h" | |||
#include "graph/utils/type_utils.h" | |||
@@ -38,10 +39,13 @@ GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY Status TransFormat(const TransArg | |||
TypeUtils::FormatToSerialString(args.dst_format).c_str()); | |||
return UNSUPPORTED; | |||
} | |||
if (args.data == nullptr) { | |||
auto src_shape_size = GetItemNumByShape(args.src_shape); | |||
if (args.data == nullptr && src_shape_size != 0) { | |||
GELOGE(PARAM_INVALID, "Invalid input null data"); | |||
return PARAM_INVALID; | |||
} | |||
return transfer->TransFormat(args, result); | |||
} | |||
@@ -71,6 +75,12 @@ GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY Status TransDataType(const CastAr | |||
TypeUtils::DataTypeToSerialString(args.dst_data_type).c_str()); | |||
return UNSUPPORTED; | |||
} | |||
if (args.data == nullptr && args.src_data_size != 0) { | |||
GELOGE(PARAM_INVALID, "Invalid input null data"); | |||
return PARAM_INVALID; | |||
} | |||
return transfer->TransDataType(args, result); | |||
} | |||
@@ -69,11 +69,11 @@ bool IsShapeValid(const std::vector<int64_t> &shape) { | |||
} | |||
int64_t num = 1; | |||
for (auto dim : shape) { | |||
if (dim < 1) { | |||
GELOGE(PARAM_INVALID, "Invalid zero dim in the shape %s", ShapeToString(shape).c_str()); | |||
if (dim < 0) { | |||
GELOGE(PARAM_INVALID, "Invalid negative dim in the shape %s", ShapeToString(shape).c_str()); | |||
return false; | |||
} | |||
if (kShapeItemNumMAX / dim < num) { | |||
if (dim != 0 && kShapeItemNumMAX / dim < num) { | |||
GELOGE(PARAM_INVALID, "Shape overflow, the total count should be less than %ld!", kShapeItemNumMAX); | |||
return false; | |||
} | |||
@@ -64,6 +64,9 @@ bool IsShapeEqual(const GeShape &src, const GeShape &dst); | |||
template <typename T> | |||
T Ceil(T n1, T n2) { | |||
if (n1 == 0) { | |||
return 0; | |||
} | |||
return (n2 != 0) ? (n1 - 1) / n2 + 1 : 0; | |||
} | |||
@@ -0,0 +1,121 @@ | |||
/** | |||
* Copyright 2019-2020 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 GE_COMMON_HELPER_MODEL_CACHE_HELPER_H_ | |||
#define GE_COMMON_HELPER_MODEL_CACHE_HELPER_H_ | |||
#include <nlohmann/json.hpp> | |||
#include <set> | |||
#include <string> | |||
#include "ge/ge_api_error_codes.h" | |||
#include "graph/compute_graph.h" | |||
#include "graph/manager/graph_var_manager.h" | |||
#include "model/ge_model.h" | |||
namespace ge { | |||
using Json = nlohmann::json; | |||
struct CacheInfo { | |||
size_t node_num; | |||
size_t edge_num; | |||
size_t graph_hash; | |||
map<std::string, size_t> nodes_hash; | |||
CacheInfo() : node_num(0), edge_num(0), graph_hash(0) {} | |||
}; | |||
class ModelCacheHelper { | |||
public: | |||
ModelCacheHelper(uint64_t session_id, uint32_t graph_id, ComputeGraphPtr &compute_graph); | |||
Status SaveCacheInfoToCache() const; | |||
Status SaveVarManagerToCache(bool before_build) const; | |||
Status SaveOmModelToCache(const GeModelPtr &ge_model) const; | |||
bool IsModelCacheHit() const; | |||
Status RecoverVarManagerFromCache() const; | |||
Status LoadOmModelFromCache(GeModelPtr &ge_model) const; | |||
Status RefreshComputeGraph(const ComputeGraphPtr &compute_graph); | |||
Status ClearCache(uint32_t graph_id) const; | |||
private: | |||
Status GetComputeGraphHash(size_t &hash) const; | |||
Status GetNodesHash(map<std::string, size_t> &hash_map) const; | |||
Status GetCacheInfo(CacheInfo &cache_info) const; | |||
Status RecoverMemResource(const Json &json) const; | |||
Status RecoverAllocatedGraphId(const Json &json) const; | |||
Status RecoverChangedGraphId(const Json &json) const; | |||
Status RecoverVarAddrAndTensorDesc(const Json &json) const; | |||
Status RecoverBroadcastInfo(const Json &json) const; | |||
Status RecoverTransRoads(const Json &json) const; | |||
static Status RecompileNodes(GeModelPtr &ge_model); | |||
bool IsNodeHashSameAsCache(const map<std::string, size_t> &hash_map) const; | |||
bool IsMemResourceSameAsCache(Json &json) const; | |||
bool IsChangedGraphIdSameAsCache(Json &json) const; | |||
bool IsAllocatedGraphIdSameAsCache(Json &json) const; | |||
bool IsCurVarTensorDescSameAsCache(Json &json) const; | |||
bool IsVarAddrMgrMapSameAsCache(Json &json) const; | |||
bool IsBroadcastInfoSameAsCache(Json &json) const; | |||
bool IsTransRoadsSameAsCache(Json &json) const; | |||
bool IsVarManagerSameAsCache(Json &json) const; | |||
bool IsVarManagerParamSameAsCache(Json &json) const; | |||
Status SaveJsonToFile(const string &file_name, const Json &json) const; | |||
Status LoadJsonFromFile(const string &file_name, Json &json) const; | |||
Status GetNodesHashMapJson(Json &json) const; | |||
Status GetMemResourceMap(Json &json) const; | |||
Status GetVarAddrMgrMapJson(Json &json) const; | |||
Status GetCurVarTensorDescMapJson(Json &json) const; | |||
Status GetTransRoadsJson(Json &json) const; | |||
Status GetChangedGraphIdJson(Json &json) const; | |||
Status GetAllocatedGraphIdJson(Json &json) const; | |||
Status GetBroadcastInfoJson(Json &json) const; | |||
Status GetVarResourceJson(Json &json) const; | |||
Status GetVarManagerJson(Json &json) const; | |||
static Status TensorDescToJson(const GeTensorDesc &ge_tensor_desc, Json &json); | |||
static Status JsonToTensorDesc(const Json &json, GeTensorDesc &ge_tensor_desc); | |||
static Status ParseMemResourceFromJson(const Json &json, map<rtMemType_t, int64_t> &mem_resource); | |||
static Status ParseVarAddrMgrMapFromJson(const Json &json, | |||
std::vector<std::pair<std::string, VarAddrMgr>> &var_addr_mgr_vector, | |||
std::unordered_set<uint64_t> &var_offset_set); | |||
static Status ParseCurVarTensorDescMapFromJson( | |||
const Json &json, std::unordered_map<std::string, ge::GeTensorDesc> &cur_var_tensor_desc_map); | |||
static Status ParseTransRoadsFromJson(const Json &json, | |||
std::unordered_map<std::string, std::vector<TransNodeInfo>> &trans_roads); | |||
static Status ParseChangedGraphIdFromJson(const Json &json, | |||
std::unordered_map<std::string, uint32_t> &changed_graph_id); | |||
static Status ParseAllocatedGraphIdFromJson(const Json &json, | |||
std::unordered_map<std::string, uint32_t> &allocated_graph_id); | |||
static Status ParseBroadcastInfoFromJson(const Json &json, | |||
std::unordered_map<std::string, VarBroadCastInfo> &var_broadcast_info); | |||
static Status GetVarNameFromVarKey(const string &var_key, const GeTensorDesc &tensor_desc, string &var_name); | |||
uint64_t session_id_; | |||
uint32_t graph_id_; | |||
string cache_path_; | |||
ComputeGraphPtr compute_graph_; | |||
std::set<string> var_names_; | |||
bool is_cache_path_valid_for_output; | |||
static map<uint32_t, uint32_t> graph_id_run_times_; | |||
}; | |||
using ModelCacheHelperPtr = std::shared_ptr<ModelCacheHelper>; | |||
} // namespace ge | |||
#endif // GE_COMMON_HELPER_MODEL_CACHE_HELPER_H_ |
@@ -385,6 +385,7 @@ REGISTER_OPTYPE_DEFINE(STREAMSWITCH, "StreamSwitch"); | |||
REGISTER_OPTYPE_DEFINE(STREAMSWITCHN, "StreamSwitchN"); | |||
REGISTER_OPTYPE_DEFINE(STREAMACTIVE, "StreamActive"); | |||
REGISTER_OPTYPE_DEFINE(MEMCPYASYNC, "MemcpyAsync"); | |||
REGISTER_OPTYPE_DEFINE(MEMCPYADDRASYNC, "MemcpyAddrAsync"); | |||
REGISTER_OPTYPE_DEFINE(STREAMMERGE, "StreamMerge"); | |||
REGISTER_OPTYPE_DEFINE(ENDGRAPH, "EndGraph"); | |||
REGISTER_OPTYPE_DEFINE(SEND, "Send"); | |||
@@ -392,6 +393,7 @@ REGISTER_OPTYPE_DEFINE(RECV, "Recv"); | |||
REGISTER_OPTYPE_DEFINE(LABELSET, "LabelSet"); | |||
REGISTER_OPTYPE_DEFINE(LABELGOTO, "LabelGoto"); | |||
REGISTER_OPTYPE_DEFINE(LABELGOTOEX, "LabelGotoEx"); | |||
REGISTER_OPTYPE_DEFINE(LABELSWITCH, "LabelSwitch"); | |||
REGISTER_OPTYPE_DEFINE(LABELSWITCHBYINDEX, "LabelSwitchByIndex"); | |||
@@ -196,7 +196,7 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY int CreateDirectory(const std:: | |||
GE_CHK_BOOL_EXEC(!directory_path.empty(), return -1, "directory path is empty."); | |||
auto dir_path_len = directory_path.length(); | |||
if (dir_path_len >= PATH_MAX) { | |||
GELOGE(ge::FAILED, "Directory path is too long."); | |||
GELOGW("Directory path is too long."); | |||
return -1; | |||
} | |||
char tmp_dir_path[PATH_MAX] = {0}; | |||
@@ -207,7 +207,7 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY int CreateDirectory(const std:: | |||
int32_t ret = mmMkdir(tmp_dir_path, S_IRUSR | S_IWUSR | S_IXUSR); // 700 | |||
if (ret != 0) { | |||
if (errno != EEXIST) { | |||
GELOGE(ge::FAILED, "Cannot create directory %s. Make sure that the directory exists and writable.", | |||
GELOGW("Cannot create directory %s. Make sure that the directory exists and writable.", | |||
directory_path.c_str()); | |||
return ret; | |||
} | |||
@@ -218,8 +218,7 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY int CreateDirectory(const std:: | |||
int32_t ret = mmMkdir(const_cast<char *>(directory_path.c_str()), S_IRUSR | S_IWUSR | S_IXUSR); // 700 | |||
if (ret != 0) { | |||
if (errno != EEXIST) { | |||
GELOGE(ge::FAILED, "Cannot create directory %s. Make sure that the directory exists and writable.", | |||
directory_path.c_str()); | |||
GELOGW("Cannot create directory %s. Make sure that the directory exists and writable.", directory_path.c_str()); | |||
return ret; | |||
} | |||
} | |||
@@ -339,7 +338,7 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY std::string RealPath(const char | |||
FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool CheckInputPathValid(const std::string &file_path) { | |||
// The specified path is empty | |||
if (file_path.empty()) { | |||
GELOGE(ge::FAILED, "Path is empty."); | |||
GELOGW("Path is empty."); | |||
return false; | |||
} | |||
@@ -358,23 +357,23 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool CheckInputPathValid(const | |||
std::string real_path = RealPath(file_path.c_str()); | |||
// Unable to get absolute path (does not exist or does not have permission to access) | |||
if (real_path.empty()) { | |||
GELOGE(ge::FAILED, "Can not get real path for %s, %s", file_path.c_str(), strerror(errno)); | |||
GELOGW("Can not get real path for %s, %s", file_path.c_str(), strerror(errno)); | |||
return false; | |||
} | |||
// The absolute path points to a file that is not readable | |||
if (access(real_path.c_str(), R_OK) != 0) { | |||
GELOGE(ge::FAILED, "Can not read file in %s, %s", file_path.c_str(), strerror(errno)); | |||
GELOGW("Can not read file in %s, %s", file_path.c_str(), strerror(errno)); | |||
return false; | |||
} | |||
return true; | |||
} | |||
FMK_FUNC_HOST_VISIBILITY bool CheckOutputPathValid(const std::string &file_path) { | |||
FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool CheckOutputPathValid(const std::string &file_path) { | |||
// The specified path is empty | |||
if (file_path.empty()) { | |||
GELOGE(ge::FAILED, "Path is empty."); | |||
GELOGW("Path is empty."); | |||
return false; | |||
} | |||
@@ -394,8 +393,8 @@ FMK_FUNC_HOST_VISIBILITY bool CheckOutputPathValid(const std::string &file_path) | |||
// Can get absolute path (file exists) | |||
if (!real_path.empty()) { | |||
// File is not readable or writable | |||
if (access(real_path.c_str(), R_OK | W_OK | F_OK) != 0) { | |||
GELOGE(ge::FAILED, "Path[ %s ] exists, but can not be write, %s", file_path.c_str(), strerror(errno)); | |||
if (access(real_path.c_str(), W_OK | F_OK) != 0) { | |||
GELOGW("Path[ %s ] exists, but can not be write, %s", file_path.c_str(), strerror(errno)); | |||
return false; | |||
} | |||
} else { | |||
@@ -413,7 +412,7 @@ FMK_FUNC_HOST_VISIBILITY bool CheckOutputPathValid(const std::string &file_path) | |||
std::string prefix_path = std::string(file_path).substr(0, static_cast<size_t>(path_split_pos)); | |||
// Determine whether the specified path is valid by creating the path | |||
if (CreateDirectory(prefix_path) != 0) { | |||
GELOGE(ge::FAILED, "Can not create prefix path for path[ %s ].", file_path.c_str()); | |||
GELOGW("Can not create prefix path for path[ %s ].", file_path.c_str()); | |||
return false; | |||
} | |||
} | |||
@@ -47,6 +47,7 @@ file(GLOB SRC_LIST RELATIVE ${CMAKE_CURRENT_LIST_DIR} | |||
"../graph/load/new_model_manager/task_info/kernel_task_info.cc" | |||
"../graph/load/new_model_manager/task_info/label_goto_task_info.cc" | |||
"../graph/load/new_model_manager/task_info/label_set_task_info.cc" | |||
"../graph/load/new_model_manager/task_info/memcpy_addr_async_task_info.cc" | |||
"../graph/load/new_model_manager/task_info/memcpy_async_task_info.cc" | |||
"../graph/load/new_model_manager/task_info/profiler_trace_task_info.cc" | |||
"../graph/load/new_model_manager/task_info/stream_active_task_info.cc" | |||
@@ -21,7 +21,7 @@ | |||
#include "framework/common/ge_inner_error_codes.h" | |||
#include "graph/node.h" | |||
#include "graph/operator.h" | |||
#include "register/register.h" | |||
#include "inc/register/register.h" | |||
namespace ge { | |||
class HostCpuEngine { | |||
@@ -76,7 +76,7 @@ bool Output::CopyRslt(OutputData *rslt, uint32_t data_begin, uint32_t &data_inde | |||
DataBuffer data_buf = rslt->blobs[data_begin + data_count]; | |||
bool ret = SetDataBuf(data_buf, data_begin, data_count, i, support_mem_share); | |||
if (!ret) { | |||
GELOGE(FAILED, "Copy data to host error. index: %lu", i); | |||
GELOGE(FAILED, "Copy data to host error. index: %lu, addr: %p", i, v_input_data_addr_[i]); | |||
return ret; | |||
} | |||
data_index = data_begin + data_count; | |||
@@ -96,6 +96,7 @@ bool RuntimeModel::InitStream(std::shared_ptr<DavinciModel> &davinci_model) { | |||
GELOGE(RT_FAILED, "Call rt api rtModelBindStream failed, ret: 0x%X", rt_ret); | |||
return false; | |||
} | |||
GELOGI("stream index:%u, stream:%p.", i, stream); | |||
} | |||
return true; | |||
@@ -446,8 +447,11 @@ bool RuntimeModel::InitConstantInfo(std::shared_ptr<DavinciModel> &davinci_model | |||
/// The logic of GetShapeSize is wrong, the scaler tensor's GetShapeSize is zero | |||
/// and that of unknown shape is zero too. | |||
/// Unknown shape will not appear here, so we can use zero judge a tensor is scaler or not. | |||
int64_t elem_num = | |||
(constant->weight_tensors[0].GetShapeSize() == 0) ? 1 : constant->weight_tensors[0].GetShapeSize(); | |||
int64_t elem_num = constant->weight_tensors[0].GetShapeSize(); | |||
if (elem_num == 0 && constant->weight_tensors[0].size == 0) { | |||
elem_num = 1; | |||
} | |||
if (constant->weight_data.size() < sizeof(uint64_t)) { | |||
GELOGE(FAILED, "weight_data size is smaller than sizeof(uint64_t)"); | |||
return false; | |||
@@ -82,6 +82,7 @@ bool CceTask::Distribute() { | |||
stub_func_ = nullptr; | |||
return false; | |||
} | |||
GELOGI("CCETask: stub_func = %s [%p].", task_info_->stub_func().c_str(), stub_func_); | |||
// Flowtable | |||
if (is_flowtable_) { | |||
@@ -43,6 +43,8 @@ EventRecordTask::EventRecordTask(const ModelContext &model_context, | |||
EventRecordTask::~EventRecordTask() {} | |||
bool EventRecordTask::Distribute() { | |||
GELOGI("EventRecordTask Distribute start, stream: %p, event: %p, stream_id: %u, event_id: %u.", stream_, event_, | |||
task_info_->stream_id(), task_info_->event_id()); | |||
rtError_t rt_ret = rtEventRecord(event_, stream_); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt api failed, ret: 0x%X", rt_ret); | |||
@@ -42,6 +42,9 @@ EventWaitTask::EventWaitTask(const ModelContext &model_context, const std::share | |||
EventWaitTask::~EventWaitTask() {} | |||
bool EventWaitTask::Distribute() { | |||
GELOGI("EventWaitTask Distribute start, stream: %p, event: %p, stream_id: %u, event_id: %u.", stream_, event_, | |||
task_info_->stream_id(), task_info_->event_id()); | |||
rtError_t rt_ret = rtStreamWaitEvent(stream_, event_); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt api rtStreamWaitEvent failed, ret: 0x%X", rt_ret); | |||
@@ -101,6 +101,7 @@ bool HcclTask::Distribute() { | |||
char *private_def = reinterpret_cast<char *>(const_cast<char unsigned *>(task_info_->private_def().data())); | |||
auto private_def_len = static_cast<uint32_t>(task_info_->private_def().size()); | |||
GELOGI("the first address of the custom info, privateDef=%p", private_def); | |||
GELOGI("hcclStreamNum =%ld", task_info_->hccl_stream_num()); | |||
for (int64_t i = 0; i < task_info_->hccl_stream_num(); ++i) { | |||
@@ -117,6 +118,7 @@ bool HcclTask::Distribute() { | |||
return false; | |||
} | |||
GELOGI("hccl_stream addr is=%p", stream); | |||
slave_stream_list_.push_back(stream); | |||
} | |||
@@ -62,6 +62,9 @@ bool StreamSwitchTask::Distribute() { | |||
rtStream_t true_stream = stream_list_[task_info_->true_stream_id()]; | |||
rtSwitchDataType_t data_type = static_cast<rtSwitchDataType_t>(task_info_->data_type()); | |||
GELOGI("InitStreamSwitchTask, cond:%d, trueStream:%p, trueStreamID:%ld, datatype:%ld.", cond, true_stream, | |||
task_info_->true_stream_id(), task_info_->data_type()); | |||
GELOGI("StreamSwitchTask Distribute Start."); | |||
rtError_t rt_ret = rtStreamSwitchEx(input, cond, value, true_stream, stream_, data_type); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
@@ -69,6 +72,7 @@ bool StreamSwitchTask::Distribute() { | |||
return false; | |||
} | |||
GELOGI("Distribute StreamSwitch, cond:%d, trueStream:%p, datatype:%ld.", cond, true_stream, task_info_->data_type()); | |||
return true; | |||
} | |||
@@ -69,6 +69,7 @@ bool TbeTask::Distribute() { | |||
stub_func_ = nullptr; | |||
return false; | |||
} | |||
GELOGI("TbeTask: stub_func = %s [%p].", task_info_->stub_func().c_str(), stub_func_); | |||
// Get args | |||
std::vector<void *> tensor_device_addrs; | |||
@@ -18,8 +18,8 @@ | |||
#include "common/ge/ge_util.h" | |||
#include "common/helper/model_helper.h" | |||
#include "common/opskernel/ops_kernel_info_types.h" | |||
#include "graph/build/stream_graph_optimizer.h" | |||
#include "graph/build/run_context.h" | |||
#include "graph/build/stream_graph_optimizer.h" | |||
#include "graph/manager/graph_var_manager.h" | |||
#include "graph/utils/node_utils.h" | |||
#include "graph/utils/type_utils.h" | |||
@@ -98,8 +98,10 @@ Status GraphBuilder::Build(ComputeGraphPtr &comp_graph, std::vector<SubGraphInfo | |||
Status ret = SecondPartition(comp_graph, subgraph_ptr_list); | |||
GE_CHK_STATUS_RET(ret, "Graph second partition Failed."); | |||
auto subgraph_map = graph_partitioner_.GetSubGraphMap(); | |||
GE_TIMESTAMP_START(BuildSubgraph); | |||
ge::ModelBuilder builder(comp_graph, subgraph_ptr_list, stream_max_parallel_num_, hcom_parallel_, build_mode_); | |||
ge::ModelBuilder builder(comp_graph, subgraph_map, stream_max_parallel_num_, hcom_parallel_, build_mode_); | |||
GELOGI("[Build] invoke the other opskernel to generate task."); | |||
@@ -135,7 +137,7 @@ Status GraphBuilder::Build(ComputeGraphPtr &comp_graph, std::vector<SubGraphInfo | |||
} | |||
GE_TIMESTAMP_START(GetTaskInfo); | |||
ret = GetTaskInfo(builder, model_ptr, comp_graph, subgraph_ptr_list, session_id); | |||
ret = GetTaskInfo(builder, model_ptr, comp_graph, subgraph_map, session_id); | |||
GE_TIMESTAMP_END(GetTaskInfo, "GraphBuilder::GetTaskInfo"); | |||
GraphUtils::DumpGEGraph(comp_graph, "AfterGetTask"); | |||
@@ -155,7 +157,7 @@ Status GraphBuilder::Build(ComputeGraphPtr &comp_graph, std::vector<SubGraphInfo | |||
} | |||
Status GraphBuilder::GetTaskInfo(const ge::ModelBuilder &builder, const ModelPtr &model_ptr, | |||
ComputeGraphPtr &comp_graph, std::vector<SubGraphInfoPtr> &subgraph_ptr_list, | |||
ComputeGraphPtr &comp_graph, Graph2SubGraphInfoList &subgraph_map, | |||
uint64_t session_id) { | |||
GE_CHECK_NOTNULL(model_ptr); | |||
GE_CHECK_NOTNULL(comp_graph); | |||
@@ -190,7 +192,7 @@ Status GraphBuilder::GetTaskInfo(const ge::ModelBuilder &builder, const ModelPtr | |||
} | |||
StreamGraphOptimizer stream_optimizer; | |||
ret = stream_optimizer.OptimizeStreamedSubGraph(comp_graph, subgraph_ptr_list, run_context.GetRunContext()); | |||
ret = stream_optimizer.OptimizeStreamedSubGraph(comp_graph, subgraph_map, run_context.GetRunContext()); | |||
if (ret != SUCCESS) { | |||
GELOGE(ret, "Optimize streamed subGraph fail."); | |||
return ret; | |||
@@ -53,7 +53,7 @@ class GraphBuilder { | |||
private: | |||
Status CalcOpParam(const ge::ComputeGraphPtr &graph); | |||
Status GetTaskInfo(const ge::ModelBuilder &builder, const ModelPtr &model_ptr, ComputeGraphPtr &comp_graph, | |||
std::vector<SubGraphInfoPtr> &subgraph_ptr_list, uint64_t session_id = INVALID_SESSION_ID); | |||
Graph2SubGraphInfoList &subgraph_map, uint64_t session_id = INVALID_SESSION_ID); | |||
Status SetInputSize(const ge::NodePtr &node_ptr); | |||
Status UpdateDataInputSize(const ge::NodePtr &node_ptr); | |||
Status SecondPartition(ge::ComputeGraphPtr &comp_graph, vector<ge::SubGraphInfoPtr> &subgraph_ptr_list); | |||
@@ -70,7 +70,7 @@ bool LogicalStreamPass::HasNonConstInputNode(const Subgraph &subgraph) const { | |||
return false; | |||
} | |||
Status AssignByLabelPass::Run(ComputeGraphPtr whole_graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
Status AssignByLabelPass::Run(ComputeGraphPtr graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
bool changed = false; | |||
int64_t &next_stream = context.next_stream; | |||
map<string, int64_t> label_streams; | |||
@@ -97,7 +97,7 @@ Status AssignByLabelPass::Run(ComputeGraphPtr whole_graph, const vector<Subgraph | |||
return changed ? SUCCESS : NOT_CHANGED; | |||
} | |||
Status IndependentStreamPass::Run(ComputeGraphPtr whole_graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
Status IndependentStreamPass::Run(ComputeGraphPtr graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
bool changed = false; | |||
int64_t &next_stream = context.next_stream; | |||
@@ -129,8 +129,7 @@ Status IndependentStreamPass::Run(ComputeGraphPtr whole_graph, const vector<Subg | |||
return changed ? SUCCESS : NOT_CHANGED; | |||
} | |||
Status AssignByDependencyPass::Run(ComputeGraphPtr whole_graph, const vector<SubgraphPtr> &subgraphs, | |||
Context &context) { | |||
Status AssignByDependencyPass::Run(ComputeGraphPtr graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
bool changed = false; | |||
if (IsHeadNodeExceeded(subgraphs)) { | |||
int64_t &next_stream = context.next_stream; | |||
@@ -298,7 +297,7 @@ int64_t AssignByDependencyPass::AssignNewStream(SubgraphPtr subgraph) { | |||
subgraph->stream_id = stream_id; | |||
engine_next_streams_[engine_name] = stream_id + 1; | |||
assigned_subgraphs_.emplace(subgraph); | |||
assigned_subgraphs_.emplace_back(subgraph); | |||
if ((stream_id + 1) > engine_stream_num_[engine_name]) { | |||
engine_stream_num_[engine_name] = stream_id + 1; | |||
@@ -311,6 +310,15 @@ int64_t AssignByDependencyPass::AssignNewStream(SubgraphPtr subgraph) { | |||
} | |||
void AssignByDependencyPass::UpdateAssignedSubgraphs(Context &context) { | |||
// If the parent stream is valid, the first assigned stream will reuse the parent stream id | |||
// and other streams use new id. To ensure that the id of the new stream is continuous, | |||
// we first subtract one from next_stream. | |||
int64_t to_be_updated_stream = kInvalidStream; | |||
if (context.parent_stream != kInvalidStream) { | |||
context.next_stream--; | |||
to_be_updated_stream = context.next_stream; | |||
} | |||
// Update the starting stream id for each engine. | |||
int64_t &next_stream = context.next_stream; | |||
map<string, int64_t> engine_start_streams; | |||
@@ -320,10 +328,16 @@ void AssignByDependencyPass::UpdateAssignedSubgraphs(Context &context) { | |||
next_stream += stream_count; | |||
} | |||
// Update the subgraphs assigned by the engine. | |||
// Update the subgraph streams assigned by engine. | |||
for (auto &subgraph : assigned_subgraphs_) { | |||
subgraph->stream_id += engine_start_streams[subgraph->engine_conf.id]; | |||
GELOGI("Stream of subgraph %s has been updated to %ld.", subgraph->name.c_str(), subgraph->stream_id); | |||
if (subgraph->stream_id == to_be_updated_stream) { | |||
subgraph->stream_id = context.parent_stream; | |||
GELOGI("Subgraph %s of engine %s reuses parent stream %ld.", subgraph->name.c_str(), | |||
subgraph->engine_conf.id.c_str(), context.parent_stream); | |||
} else { | |||
GELOGI("Stream of subgraph %s has been updated to %ld.", subgraph->name.c_str(), subgraph->stream_id); | |||
} | |||
} | |||
} | |||
@@ -337,7 +351,7 @@ void AssignByDependencyPass::UpdateReusedSubgraphs() { | |||
} | |||
} | |||
Status NodeStreamUpdatePass::Run(ComputeGraphPtr whole_graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
Status NodeStreamUpdatePass::Run(ComputeGraphPtr graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
// Check if all subgraphs have been assigned a stream. | |||
for (const SubgraphPtr &subgraph : subgraphs) { | |||
const string &engine_name = subgraph->engine_conf.id; | |||
@@ -353,7 +367,7 @@ Status NodeStreamUpdatePass::Run(ComputeGraphPtr whole_graph, const vector<Subgr | |||
} | |||
// Init the stream id of node. | |||
for (NodePtr &node : whole_graph->GetDirectNode()) { | |||
for (NodePtr &node : graph->GetDirectNode()) { | |||
GE_CHECK_NOTNULL(node->GetOpDesc()); | |||
node->GetOpDesc()->SetStreamId(kInvalidStream); | |||
} | |||
@@ -375,76 +389,11 @@ Status NodeStreamUpdatePass::Run(ComputeGraphPtr whole_graph, const vector<Subgr | |||
} | |||
// Update stream id for nodes belong to skipped engine subgraph | |||
GE_CHK_STATUS_RET(UpdateForSkippedEngine(whole_graph, subgraphs)); | |||
RefreshContinuousStreams(whole_graph, context); | |||
GE_CHK_STATUS_RET(UpdateForSkippedEngine(graph, subgraphs)); | |||
return SUCCESS; | |||
} | |||
Status AllReduceParallelPass::Run(ComputeGraphPtr whole_graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
if (!context.hcom_parallel) { | |||
return NOT_CHANGED; | |||
} | |||
GELOGI("AllReduceParallelPass is enabled."); | |||
GraphUtils::DumpGEGraph(whole_graph, "BeforeAllReduceParallel"); | |||
// All successors of HcomAllReduce. | |||
set<NodePtr> all_reduce_succs; | |||
for (const NodePtr &node : whole_graph->GetDirectNode()) { | |||
if (node->GetType() != HCOMALLREDUCE || node->GetInDataNodes().size() <= 1) { | |||
continue; | |||
} | |||
string reduce_stream_label; | |||
GE_CHECK_NOTNULL(node->GetOpDesc()); | |||
// ATTR_NAME_STREAM_LABEL is optional. | |||
(void)AttrUtils::GetStr(node->GetOpDesc(), ATTR_NAME_STREAM_LABEL, reduce_stream_label); | |||
set<NodePtr> cur_nodes = {node}; | |||
while (!cur_nodes.empty()) { | |||
set<NodePtr> all_out_data_nodes; | |||
for (auto &curr_node : cur_nodes) { | |||
for (const NodePtr &out_node : curr_node->GetOutDataNodes()) { | |||
string out_stream_label; | |||
GE_CHECK_NOTNULL(out_node->GetOpDesc()); | |||
// ATTR_NAME_STREAM_LABEL is optional. | |||
(void)AttrUtils::GetStr(out_node->GetOpDesc(), ATTR_NAME_STREAM_LABEL, out_stream_label); | |||
if (out_stream_label == reduce_stream_label) { | |||
all_reduce_succs.emplace(out_node); | |||
all_out_data_nodes.emplace(out_node); | |||
} | |||
} | |||
} | |||
cur_nodes = all_out_data_nodes; | |||
} | |||
} | |||
map<int64_t, int64_t> old_stream_to_new; | |||
for (const NodePtr &node : all_reduce_succs) { | |||
GE_CHECK_NOTNULL(node->GetOpDesc()); | |||
auto old_stream = node->GetOpDesc()->GetStreamId(); | |||
if (old_stream != kInvalidStream) { | |||
int64_t new_stream = kInvalidStream; | |||
auto iter = old_stream_to_new.find(old_stream); | |||
if (iter != old_stream_to_new.end()) { | |||
new_stream = iter->second; | |||
} else { | |||
new_stream = context.next_stream; | |||
context.next_stream++; | |||
old_stream_to_new.emplace(old_stream, new_stream); | |||
} | |||
GELOGI("Stream of node %s has been updated from %ld to %ld.", node->GetName().c_str(), old_stream, new_stream); | |||
node->GetOpDesc()->SetStreamId(new_stream); | |||
} | |||
} | |||
return !all_reduce_succs.empty() ? SUCCESS : NOT_CHANGED; | |||
} | |||
int64_t NodeStreamUpdatePass::GetSingleInoutStream(const NodePtr &node) const { | |||
set<int64_t> stream_ids; | |||
@@ -472,11 +421,11 @@ int64_t NodeStreamUpdatePass::GetSingleInoutStream(const NodePtr &node) const { | |||
return kInvalidStream; | |||
} | |||
Status NodeStreamUpdatePass::UpdateForSkippedEngine(const ComputeGraphPtr &whole_graph, | |||
Status NodeStreamUpdatePass::UpdateForSkippedEngine(const ComputeGraphPtr &graph, | |||
const vector<SubgraphPtr> &subgraphs) { | |||
set<OpDescPtr> nodes_to_be_updated; | |||
// Check if sub graph is engine skipped and without stream label or not | |||
// Check if subgraph is engine skipped and without stream label or not | |||
for (const SubgraphPtr &subgraph : subgraphs) { | |||
if (IsEngineSkip(*subgraph) && !HasStreamLabel(*subgraph)) { | |||
auto graph = subgraph->subgraph_info.GetSubGraph(); | |||
@@ -492,7 +441,7 @@ Status NodeStreamUpdatePass::UpdateForSkippedEngine(const ComputeGraphPtr &whole | |||
} | |||
// Try reassign the stream id | |||
for (ge::NodePtr &node : whole_graph->GetDirectNode()) { | |||
for (ge::NodePtr &node : graph->GetDirectNode()) { | |||
auto op_desc = node->GetOpDesc(); | |||
GE_CHECK_NOTNULL(op_desc); | |||
int64_t stream_id = op_desc->GetStreamId(); | |||
@@ -509,6 +458,7 @@ Status NodeStreamUpdatePass::UpdateForSkippedEngine(const ComputeGraphPtr &whole | |||
} | |||
} | |||
} | |||
return SUCCESS; | |||
} | |||
@@ -525,40 +475,65 @@ bool NodeStreamUpdatePass::AreAllPredStreamsInvalid(const NodePtr &node) const { | |||
return true; | |||
} | |||
void NodeStreamUpdatePass::RefreshContinuousStreams(ComputeGraphPtr whole_graph, Context &context) const { | |||
int64_t stream_num = context.next_stream; | |||
vector<bool> stream_has_node(stream_num); | |||
Status AllReduceParallelPass::Run(ComputeGraphPtr graph, const vector<SubgraphPtr> &subgraphs, Context &context) { | |||
if (!context.hcom_parallel) { | |||
return NOT_CHANGED; | |||
} | |||
for (const NodePtr &node : whole_graph->GetDirectNode()) { | |||
if (node != nullptr) { | |||
auto op_desc = node->GetOpDesc(); | |||
if (op_desc != nullptr) { | |||
int64_t stream_id = op_desc->GetStreamId(); | |||
if (stream_id != kInvalidStream && stream_id < stream_num) { | |||
stream_has_node[stream_id] = true; | |||
} | |||
} | |||
GELOGI("AllReduceParallelPass is enabled."); | |||
GraphUtils::DumpGEGraph(graph, "BeforeAllReduceParallel"); | |||
// All successors of HcomAllReduce. | |||
set<NodePtr> all_reduce_succs; | |||
for (const NodePtr &node : graph->GetDirectNode()) { | |||
if (node->GetType() != HCOMALLREDUCE || node->GetInDataNodes().size() <= 1) { | |||
continue; | |||
} | |||
} | |||
context.next_stream = 0; | |||
vector<int64_t> old_to_new_streams(stream_num, kInvalidStream); | |||
for (size_t old_stream = 0; old_stream < stream_has_node.size(); ++old_stream) { | |||
if (stream_has_node[old_stream]) { | |||
old_to_new_streams[old_stream] = context.next_stream; | |||
++context.next_stream; | |||
string reduce_stream_label; | |||
GE_CHECK_NOTNULL(node->GetOpDesc()); | |||
(void)AttrUtils::GetStr(node->GetOpDesc(), ATTR_NAME_STREAM_LABEL, reduce_stream_label); | |||
set<NodePtr> cur_nodes = {node}; | |||
while (!cur_nodes.empty()) { | |||
set<NodePtr> all_out_data_nodes; | |||
for (auto &curr_node : cur_nodes) { | |||
for (const NodePtr &out_node : curr_node->GetOutDataNodes()) { | |||
string out_stream_label; | |||
GE_CHECK_NOTNULL(out_node->GetOpDesc()); | |||
(void)AttrUtils::GetStr(out_node->GetOpDesc(), ATTR_NAME_STREAM_LABEL, out_stream_label); | |||
if (out_stream_label == reduce_stream_label) { | |||
all_reduce_succs.emplace(out_node); | |||
all_out_data_nodes.emplace(out_node); | |||
} | |||
} | |||
} | |||
cur_nodes = all_out_data_nodes; | |||
} | |||
} | |||
for (const NodePtr &node : whole_graph->GetDirectNode()) { | |||
auto op_desc = node->GetOpDesc(); | |||
if (op_desc != nullptr) { | |||
int64_t stream_id = op_desc->GetStreamId(); | |||
if (stream_id != kInvalidStream && stream_id < stream_num) { | |||
op_desc->SetStreamId(old_to_new_streams[stream_id]); | |||
map<int64_t, int64_t> old_stream_to_new; | |||
for (const NodePtr &node : all_reduce_succs) { | |||
GE_CHECK_NOTNULL(node->GetOpDesc()); | |||
auto old_stream = node->GetOpDesc()->GetStreamId(); | |||
if (old_stream != kInvalidStream) { | |||
int64_t new_stream = kInvalidStream; | |||
auto iter = old_stream_to_new.find(old_stream); | |||
if (iter != old_stream_to_new.end()) { | |||
new_stream = iter->second; | |||
} else { | |||
new_stream = context.next_stream; | |||
context.next_stream++; | |||
old_stream_to_new.emplace(old_stream, new_stream); | |||
} | |||
GELOGI("Stream of node %s has been updated from %ld to %ld.", node->GetName().c_str(), old_stream, new_stream); | |||
node->GetOpDesc()->SetStreamId(new_stream); | |||
} | |||
} | |||
return !all_reduce_succs.empty() ? SUCCESS : NOT_CHANGED; | |||
} | |||
LogicalStreamAllocator::LogicalStreamAllocator(const map<string, SchedulerConf> &scheduler_confs, | |||
@@ -567,9 +542,10 @@ LogicalStreamAllocator::LogicalStreamAllocator(const map<string, SchedulerConf> | |||
context_.hcom_parallel = hcom_parallel; | |||
} | |||
Status LogicalStreamAllocator::Assign(const ComputeGraphPtr &whole_graph, const vector<SubGraphInfoPtr> &subgraph_infos, | |||
Status LogicalStreamAllocator::Assign(const ComputeGraphPtr &whole_graph, const Graph2SubGraphInfoList &subgraph_map, | |||
int64_t &stream_num) { | |||
GE_CHECK_NOTNULL(whole_graph); | |||
map<string, EngineConfPtr> engine_confs; | |||
GE_TIMESTAMP_START(InitEngineConfs); | |||
for (const auto &item : scheduler_confs_) { | |||
@@ -583,16 +559,64 @@ Status LogicalStreamAllocator::Assign(const ComputeGraphPtr &whole_graph, const | |||
} | |||
GE_TIMESTAMP_END(InitEngineConfs, "GraphBuilder::AssignStreamInitEngineConfs"); | |||
Status status = DoAssign(whole_graph, subgraph_map, engine_confs); | |||
if (status != SUCCESS) { | |||
GELOGE(status, "Assign streams failed."); | |||
return status; | |||
} | |||
vector<ComputeGraphPtr> subgraphs = whole_graph->GetAllSubgraphs(); | |||
for (const ComputeGraphPtr &subgraph : subgraphs) { | |||
Status status = DoAssign(subgraph, subgraph_map, engine_confs); | |||
if (status != SUCCESS) { | |||
GELOGE(status, "Assign streams failed."); | |||
return status; | |||
} | |||
} | |||
RefreshContinuousStreams(whole_graph); | |||
stream_num = context_.next_stream; | |||
GELOGI("Assigned logical stream num: %ld.", stream_num); | |||
return SUCCESS; | |||
} | |||
Status LogicalStreamAllocator::DoAssign(const ComputeGraphPtr &graph, const Graph2SubGraphInfoList &subgraph_map, | |||
const map<string, EngineConfPtr> &engine_confs) { | |||
GE_CHECK_NOTNULL(graph); | |||
NodePtr parent_node = graph->GetParentNode(); | |||
if (parent_node == nullptr || parent_node->GetOpDesc() == nullptr) { | |||
context_.parent_stream = kInvalidStream; | |||
} else { | |||
context_.parent_stream = parent_node->GetOpDesc()->GetStreamId(); | |||
} | |||
auto iter = subgraph_map.find(graph); | |||
if (iter == subgraph_map.end()) { | |||
GELOGE(FAILED, "Graph %s not found.", graph->GetName().c_str()); | |||
return FAILED; | |||
} | |||
const vector<SubGraphInfoPtr> &subgraph_info_list = iter->second; | |||
vector<SubgraphPtr> subgraphs; | |||
GE_TIMESTAMP_START(ConvertSubgraphs); | |||
Status status = ConvertSubgraphs(subgraph_infos, engine_confs, subgraphs); | |||
Status status = ConvertSubgraphs(subgraph_info_list, engine_confs, subgraphs); | |||
GE_TIMESTAMP_END(ConvertSubgraphs, "GraphBuilder::AssignStreamConvertSubgraphs"); | |||
if (status != SUCCESS) { | |||
GELOGE(status, "Create subgraphs failed."); | |||
return status; | |||
} | |||
return RunPasses(whole_graph, subgraphs, stream_num); | |||
GELOGI("Subgraphs of graph %s:", graph->GetName().c_str()); | |||
for (const auto &subgraph : subgraphs) { | |||
if (subgraph != nullptr) { | |||
GELOGI("subgraph: %s", subgraph->name.c_str()); | |||
} | |||
} | |||
return RunPasses(graph, subgraphs); | |||
} | |||
Status LogicalStreamAllocator::ConvertSubgraphs(const vector<SubGraphInfoPtr> &subgraph_infos, | |||
@@ -631,8 +655,7 @@ Status LogicalStreamAllocator::ConvertSubgraphs(const vector<SubGraphInfoPtr> &s | |||
return SUCCESS; | |||
} | |||
Status LogicalStreamAllocator::RunPasses(const ComputeGraphPtr &whole_graph, const vector<SubgraphPtr> &subgraphs, | |||
int64_t &stream_num) { | |||
Status LogicalStreamAllocator::RunPasses(const ComputeGraphPtr &graph, const vector<SubgraphPtr> &subgraphs) { | |||
vector<LogicalStreamPassPtr> passes; | |||
passes.emplace_back(MakeShared<AssignByLabelPass>()); | |||
passes.emplace_back(MakeShared<IndependentStreamPass>()); | |||
@@ -643,7 +666,7 @@ Status LogicalStreamAllocator::RunPasses(const ComputeGraphPtr &whole_graph, con | |||
for (auto &pass : passes) { | |||
GE_CHECK_NOTNULL(pass); | |||
Status status = pass->Run(whole_graph, subgraphs, context_); | |||
Status status = pass->Run(graph, subgraphs, context_); | |||
if (status == SUCCESS) { | |||
GELOGI("Stream pass %s return SUCCESS.", pass->GetName().c_str()); | |||
} else if (status == NOT_CHANGED) { | |||
@@ -654,9 +677,42 @@ Status LogicalStreamAllocator::RunPasses(const ComputeGraphPtr &whole_graph, con | |||
} | |||
} | |||
stream_num = context_.next_stream; | |||
GELOGI("Assigned logical stream num: %ld.", stream_num); | |||
return SUCCESS; | |||
} | |||
void LogicalStreamAllocator::RefreshContinuousStreams(const ComputeGraphPtr &graph) { | |||
int64_t stream_num = context_.next_stream; | |||
vector<bool> stream_has_node(stream_num); | |||
for (const NodePtr &node : graph->GetAllNodes()) { | |||
if (node != nullptr) { | |||
auto op_desc = node->GetOpDesc(); | |||
if (op_desc != nullptr) { | |||
int64_t stream_id = op_desc->GetStreamId(); | |||
if (stream_id != kInvalidStream && stream_id < stream_num) { | |||
stream_has_node[stream_id] = true; | |||
} | |||
} | |||
} | |||
} | |||
context_.next_stream = 0; | |||
vector<int64_t> old_to_new_streams(stream_num, kInvalidStream); | |||
for (size_t old_stream = 0; old_stream < stream_has_node.size(); ++old_stream) { | |||
if (stream_has_node[old_stream]) { | |||
old_to_new_streams[old_stream] = context_.next_stream; | |||
++context_.next_stream; | |||
} | |||
} | |||
for (const NodePtr &node : graph->GetAllNodes()) { | |||
auto op_desc = node->GetOpDesc(); | |||
if (op_desc != nullptr) { | |||
int64_t stream_id = op_desc->GetStreamId(); | |||
if (stream_id != kInvalidStream && stream_id < stream_num) { | |||
op_desc->SetStreamId(old_to_new_streams[stream_id]); | |||
} | |||
} | |||
} | |||
} | |||
} // namespace ge |
@@ -60,7 +60,7 @@ class LogicalStreamPass { | |||
}; | |||
struct Context { | |||
// Next stream id. | |||
int64_t parent_stream = kInvalidStream; | |||
int64_t next_stream = 0; | |||
bool hcom_parallel = false; | |||
}; | |||
@@ -71,7 +71,7 @@ class LogicalStreamPass { | |||
virtual ~LogicalStreamPass() = default; | |||
const std::string &GetName() const; | |||
virtual Status Run(ComputeGraphPtr whole_graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) = 0; | |||
virtual Status Run(ComputeGraphPtr graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) = 0; | |||
protected: | |||
bool IsEngineSkip(const Subgraph &subgraph) const; | |||
@@ -93,21 +93,21 @@ using LogicalStreamPassPtr = std::shared_ptr<LogicalStreamPass>; | |||
class AssignByLabelPass : public LogicalStreamPass { | |||
public: | |||
STREAM_PASS_DEFAULT_FUNC(AssignByLabelPass); | |||
Status Run(ComputeGraphPtr whole_graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
Status Run(ComputeGraphPtr graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
}; | |||
// Engines such as hccl require independent Stream. | |||
class IndependentStreamPass : public LogicalStreamPass { | |||
public: | |||
STREAM_PASS_DEFAULT_FUNC(IndependentStreamPass); | |||
Status Run(ComputeGraphPtr whole_graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
Status Run(ComputeGraphPtr graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
}; | |||
// Reuse streams or assign new streams based on dependencies. | |||
class AssignByDependencyPass : public LogicalStreamPass { | |||
public: | |||
STREAM_PASS_DEFAULT_FUNC(AssignByDependencyPass); | |||
Status Run(ComputeGraphPtr whole_graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
Status Run(ComputeGraphPtr graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
private: | |||
void InitEndSubgraphMap(const std::vector<SubgraphPtr> &subgraphs, std::map<NodePtr, SubgraphPtr> &end_subgraph_map); | |||
@@ -132,7 +132,7 @@ class AssignByDependencyPass : public LogicalStreamPass { | |||
std::map<std::string, int64_t> engine_stream_num_; | |||
// Subgraphs of assign stream by engine | |||
std::set<SubgraphPtr> assigned_subgraphs_; | |||
std::vector<SubgraphPtr> assigned_subgraphs_; | |||
// <current subgraph, reused subgraph> | |||
std::vector<std::pair<SubgraphPtr, SubgraphPtr>> reused_subgraphs_; | |||
@@ -142,7 +142,7 @@ class AssignByDependencyPass : public LogicalStreamPass { | |||
class NodeStreamUpdatePass : public LogicalStreamPass { | |||
public: | |||
STREAM_PASS_DEFAULT_FUNC(NodeStreamUpdatePass); | |||
Status Run(ComputeGraphPtr whole_graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
Status Run(ComputeGraphPtr graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
private: | |||
/// Optimize for case like: | |||
@@ -150,19 +150,18 @@ class NodeStreamUpdatePass : public LogicalStreamPass { | |||
/// To case: | |||
/// NodeA(stream1) -> Const(stream1) -> NodeB(stream1) | |||
/// Which could reduce event number (Const could be other type which belong to skipped engine subgraph) | |||
Status UpdateForSkippedEngine(const ComputeGraphPtr &whole_graph, const std::vector<SubgraphPtr> &subgraphs); | |||
Status UpdateForSkippedEngine(const ComputeGraphPtr &graph, const std::vector<SubgraphPtr> &subgraphs); | |||
int64_t GetSingleInoutStream(const NodePtr &node) const; | |||
// Judge if all predecessors' streams of node are INVALID_STREAM | |||
bool AreAllPredStreamsInvalid(const NodePtr &node) const; | |||
void RefreshContinuousStreams(ComputeGraphPtr whole_graph, Context &context) const; | |||
}; | |||
// AllReduce and backward operators execute in parallel. | |||
class AllReduceParallelPass : public LogicalStreamPass { | |||
public: | |||
STREAM_PASS_DEFAULT_FUNC(AllReduceParallelPass); | |||
Status Run(ComputeGraphPtr whole_graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
Status Run(ComputeGraphPtr graph, const std::vector<SubgraphPtr> &subgraphs, Context &context) override; | |||
}; | |||
// Assign logical streams which is not limited by the number of tasks. | |||
@@ -178,13 +177,16 @@ class LogicalStreamAllocator { | |||
LogicalStreamAllocator &operator=(const LogicalStreamAllocator &) = delete; | |||
~LogicalStreamAllocator() = default; | |||
Status Assign(const ComputeGraphPtr &whole_graph, const std::vector<SubGraphInfoPtr> &subgraphs, int64_t &stream_num); | |||
Status Assign(const ComputeGraphPtr &whole_graph, const Graph2SubGraphInfoList &subgraph_map, int64_t &stream_num); | |||
private: | |||
Status DoAssign(const ComputeGraphPtr &graph, const Graph2SubGraphInfoList &subgraph_map, | |||
const map<string, EngineConfPtr> &engine_confs); | |||
Status ConvertSubgraphs(const std::vector<SubGraphInfoPtr> &subgraph_infos, | |||
const std::map<std::string, EngineConfPtr> &engine_confs, | |||
std::vector<SubgraphPtr> &subgraphs); | |||
Status RunPasses(const ComputeGraphPtr &whole_graph, const std::vector<SubgraphPtr> &subgraphs, int64_t &stream_num); | |||
Status RunPasses(const ComputeGraphPtr &graph, const std::vector<SubgraphPtr> &subgraphs); | |||
void RefreshContinuousStreams(const ComputeGraphPtr &graph); | |||
const std::map<std::string, SchedulerConf> &scheduler_confs_; | |||
const std::map<std::string, int> &max_parallel_num_; | |||
@@ -805,6 +805,9 @@ void SetOffsetSize(const NodeTypeIndex &node_type_index, int64_t offset, size_t | |||
} | |||
} | |||
op_desc->SetOutputOffset(output_list); | |||
GELOGI("[IMAS]Set %s name[%s] output[%d] offset to [%ld] streamid[%ld] size[%zu] realsize[%zu].", | |||
graph_name.c_str(), op_desc->GetName().c_str(), node_type_index.index, offset, op_desc->GetStreamId(), size, | |||
real_size); | |||
} else if (node_type_index.mem_type == kWorkspace) { | |||
vector<int64_t> workspace_list; | |||
workspace_list = op_desc->GetWorkspace(); | |||
@@ -821,6 +824,9 @@ void SetOffsetSize(const NodeTypeIndex &node_type_index, int64_t offset, size_t | |||
workspace_list.at(node_type_index.index) = offset; | |||
} | |||
op_desc->SetWorkspace(workspace_list); | |||
GELOGI("[IMAS]Set %s name[%s] workspace[%u] offset to [%ld] streamid[%ld] size[%zu] realsize[%zu].", | |||
graph_name.c_str(), op_desc->GetName().c_str(), node_type_index.index, offset, op_desc->GetStreamId(), size, | |||
real_size); | |||
} | |||
} | |||
@@ -310,6 +310,11 @@ Status GraphMemoryAssigner::AssignContinuousInputMemory(const ge::NodePtr &node) | |||
if (is_tensor_actual_size == 0) { | |||
AlignMemOffset(MEM_ALIGN_SIZE); | |||
} | |||
GELOGI( | |||
"[IMAS]Continuous input : Set %s name[%s] output[%d] offset to [%zu] stream_id[%ld] size[%zu] " | |||
"real_size[%ld].", | |||
node->GetOwnerComputeGraph()->GetName().c_str(), peer_op_desc->GetName().c_str(), peer_out_data_anchor->GetIdx(), | |||
pre_mem_offset, peer_op_desc->GetStreamId(), (memory_offset_[0].mem_offset_ - pre_mem_offset), tensor_desc_size); | |||
} | |||
return SUCCESS; | |||
@@ -340,6 +345,11 @@ Status GraphMemoryAssigner::AssignContinuousOutputMemory(const ge::NodePtr &node | |||
memory_offset_[0].mem_offset_ += tensor_desc_size; | |||
AlignMemOffset(MEM_ALIGN_SIZE); | |||
GELOGI( | |||
"[IMAS]Continuous output : Set %s name[%s] output[%d] offset to [%zu] stream_id[%ld] size[%zu] " | |||
"real_size[%ld].", | |||
node->GetOwnerComputeGraph()->GetName().c_str(), out_op_desc->GetName().c_str(), out_data_anchor->GetIdx(), | |||
pre_mem_offset, out_op_desc->GetStreamId(), (memory_offset_[0].mem_offset_ - pre_mem_offset), tensor_desc_size); | |||
} | |||
out_op_desc->SetOutputOffset(output_list); | |||
@@ -413,8 +423,10 @@ Status GraphMemoryAssigner::ReAssignReuseAndNoPaddingContinuousInputMemory() { | |||
pre_mem_offset, peer_op_desc->GetStreamId(), out_size, output_mem_size); | |||
} | |||
memory_offset_[0].mem_offset_ += extra_memory_size; | |||
GELOGI("After reassign virtual input node[name:%s, type:%s] memory, memory offset = %zu.", | |||
op_desc->GetName().c_str(), op_desc->GetType().c_str(), memory_offset_[0].mem_offset_); | |||
size_t after_mem_offset = memory_offset_[0].mem_offset_; | |||
AlignMemOffset(MEM_ALIGN_SIZE); | |||
GELOGI("After reassign virtual input node[name:%s, type:%s] memory, memory offset = %zu, align memory = %zu.", | |||
op_desc->GetName().c_str(), op_desc->GetType().c_str(), after_mem_offset, memory_offset_[0].mem_offset_); | |||
} | |||
} | |||
return SUCCESS; | |||
@@ -499,8 +511,10 @@ Status GraphMemoryAssigner::ReAssignReuseAndNoPaddingContinuousOutputMemory() { | |||
} | |||
op_desc->SetOutputOffset(output_list); | |||
memory_offset_[0].mem_offset_ += extra_memory_size; | |||
GELOGI("After reassign virtual output node[name:%s, type:%s] memory, memory offset = %zu.", | |||
op_desc->GetName().c_str(), op_desc->GetType().c_str(), memory_offset_[0].mem_offset_); | |||
size_t after_mem_offset = memory_offset_[0].mem_offset_; | |||
AlignMemOffset(MEM_ALIGN_SIZE); | |||
GELOGI("After reassign virtual output node[name:%s, type:%s] memory, memory offset = %zu, align memory = %zu.", | |||
op_desc->GetName().c_str(), op_desc->GetType().c_str(), after_mem_offset, memory_offset_[0].mem_offset_); | |||
} | |||
} | |||
return SUCCESS; | |||
@@ -567,6 +581,11 @@ Status GraphMemoryAssigner::ReAssignMergeMemory() { | |||
output_list[index] = data_output_offset; | |||
src_node->GetOpDesc()->SetOutputOffset(output_list); | |||
GELOGI( | |||
"[IMAS]ReAssignMergeMemory : Set %s name[%s] output[%d] offset to [%ld] stream_id[%ld] size[%ld] " | |||
"real_size[%ld].", | |||
n->GetOwnerComputeGraph()->GetName().c_str(), src_node->GetOpDesc()->GetName().c_str(), index, | |||
data_output_offset, src_node->GetOpDesc()->GetStreamId(), max_output_size, max_output_size); | |||
input_list.emplace_back(data_output_offset); | |||
} | |||
@@ -897,6 +916,9 @@ Status GraphMemoryAssigner::AssignAtomicOutputMemory(const ge::NodePtr &node) { | |||
} | |||
output_list[output_index] = memory_offset_[0].mem_offset_; | |||
GELOGI("[IMAS]Atomic output : Set %s name[%s] output[%ld] offset to [%zu] stream_id[%ld] size[%ld] real_size[%ld].", | |||
compute_graph_->GetName().c_str(), op_desc->GetName().c_str(), output_index, memory_offset_[0].mem_offset_, | |||
op_desc->GetStreamId(), size, size); | |||
memory_offset_[0].mem_offset_ += size; | |||
AlignMemOffset(MEM_ALIGN_SIZE); | |||
@@ -933,6 +955,11 @@ Status GraphMemoryAssigner::AssignOrdinaryAtomicWorkspaceMemory(const ge::OpDesc | |||
} | |||
workspace_vector[workspace_index] = memory_offset_[0].mem_offset_; | |||
GELOGI( | |||
"[IMAS]Atomic ordinary workspace : Set %s name[%s] workspace[%lu] offset to [%zu] stream_id[%ld] " | |||
"size[%ld] real_size[%ld].", | |||
compute_graph_->GetName().c_str(), op_desc->GetName().c_str(), workspace_index, memory_offset_[0].mem_offset_, | |||
op_desc->GetStreamId(), workspace_size, workspace_size); | |||
memory_offset_[0].mem_offset_ += workspace_size; | |||
} | |||
@@ -958,6 +985,11 @@ Status GraphMemoryAssigner::AssignFusionAtomicWorkspaceMemory(const ge::OpDescPt | |||
auto workspace_size = info_iter.second; | |||
size_t workspace_offset = memory_offset_[0].mem_offset_; | |||
GELOGI( | |||
"[IMAS]Atomic fusion workspace : Set %s name[%s] workspace[%lu] offset to [%zu] stream_id[%ld] size[%ld] " | |||
"real_size[%ld].", | |||
compute_graph_->GetName().c_str(), op_desc->GetName().c_str(), workspace_index, memory_offset_[0].mem_offset_, | |||
op_desc->GetStreamId(), workspace_size, workspace_size); | |||
memory_offset_[0].mem_offset_ += workspace_size; | |||
index_offset.insert(std::make_pair(workspace_index, workspace_offset)); | |||
@@ -1005,7 +1037,8 @@ ge::Status GraphMemoryAssigner::SetInputOffset() { | |||
GELOGE(FAILED, "memory_offset_ is empty."); | |||
return FAILED; | |||
} | |||
GEEVENT("[IMAS]AfterAssignMemory : %s", compute_graph_->GetName().c_str()); | |||
GEEVENT("[IMAS]AfterAssignMemory : %s memoffset[%zu]", compute_graph_->GetName().c_str(), | |||
memory_offset_[0].mem_offset_); | |||
for (const ge::NodePtr &node : compute_graph_->GetDirectNode()) { | |||
if (UpdateOpInputOffset(node) != ge::SUCCESS) { | |||
GELOGE(ge::FAILED, "Update op input offset failed"); | |||
@@ -1166,6 +1199,12 @@ ge::Status GraphMemoryAssigner::SetAtomicCleanAttr(const NodePtr &n, int64_t ato | |||
GE_CHK_BOOL_EXEC(ge::AttrUtils::SetListInt(node_op_desc, ATTR_NAME_AUTOMIC_ADD_MEM_SIZE, mem_size_vector), | |||
GELOGE(FAILED, "SetListInt failed."); | |||
return FAILED); | |||
GELOGI( | |||
"[IMAS]SetAtomicCleanAttr : Set %s name[%s] output[%d] offset to [%ld] streamid[%ld] size[%ld] " | |||
"realsize[%ld].", | |||
node->GetOwnerComputeGraph()->GetName().c_str(), node_op_desc->GetName().c_str(), 0, atomic_mem_start, | |||
node->GetOpDesc()->GetStreamId(), atomic_mem_size, atomic_mem_size); | |||
} | |||
} | |||
return SUCCESS; | |||
@@ -28,6 +28,7 @@ | |||
#include "graph/common/omg_util.h" | |||
#include "graph/debug/ge_attr_define.h" | |||
#include "graph/ge_attr_value.h" | |||
#include "graph/ge_context.h" | |||
#include "graph/ge_error_codes.h" | |||
#include "graph/manager/graph_mem_allocator.h" | |||
#include "graph/manager/graph_var_manager.h" | |||
@@ -39,7 +40,6 @@ | |||
#include "graph/utils/op_desc_utils.h" | |||
#include "graph/utils/tensor_utils.h" | |||
#include "graph/utils/type_utils.h" | |||
#include "graph/ge_context.h" | |||
#include "init/gelib.h" | |||
#include "memory/memory_assigner.h" | |||
#include "omg/version.h" | |||
@@ -78,15 +78,16 @@ bool IsGeLocalOp(const ge::ConstOpDescPtr &op_desc) { | |||
ge::GeTensorDesc output_desc = op_desc->GetOutputDesc(0); | |||
return !(output_desc.GetDataType() == ge::DT_STRING); | |||
} | |||
const set<string> ge_local_set = { | |||
ge::STREAMMERGE, ge::MEMCPYASYNC, ge::STREAMACTIVE, ge::STREAMSWITCH, ge::VARIABLE, ge::NOOP, ge::CONSTANT, | |||
ge::ENTER, ge::REFENTER, ge::LOOPCOND, ge::NEXTITERATION, ge::REFNEXTITERATION, ge::EXIT, ge::REFEXIT}; | |||
const set<string> ge_local_set = {ge::STREAMMERGE, ge::MEMCPYASYNC, ge::STREAMACTIVE, ge::STREAMSWITCH, | |||
ge::VARIABLE, ge::NOOP, ge::CONSTANT, ge::ENTER, | |||
ge::REFENTER, ge::LOOPCOND, ge::NEXTITERATION, ge::REFNEXTITERATION, | |||
ge::EXIT, ge::REFEXIT, ge::MEMCPYADDRASYNC}; | |||
return (ge_local_set.find(type) != ge_local_set.end()); | |||
} | |||
} // namespace | |||
namespace ge { | |||
ModelBuilder::ModelBuilder(ge::ComputeGraphPtr compute_graph, const vector<SubGraphInfoPtr> &subgraphs, | |||
ModelBuilder::ModelBuilder(ge::ComputeGraphPtr compute_graph, const Graph2SubGraphInfoList &subgraphs, | |||
const map<string, int> &stream_max_parallel_num, bool hcom_parallel, int mode) | |||
: mem_offset_(0), | |||
weight_offset_(kWeightsStartOffset), | |||
@@ -225,6 +226,25 @@ Status ModelBuilder::SetInputOutputDesc() { | |||
if (!is_loop_graph_ && node_op_desc->GetType() == LOOPCOND) { | |||
is_loop_graph_ = true; | |||
} | |||
// if user set input node format ND, the expected node for data and netoutput format is ND in | |||
// final graph. | |||
if ((domi::GetContext().format == domi::DOMI_TENSOR_ND) && | |||
((node_op_desc->GetType() == DATA_TYPE) || (node_op_desc->GetType() == NETOUTPUT))) { | |||
GELOGI("The node [%s] format should be set ND.", node_op_desc->GetName().c_str()); | |||
auto inputDescsPtr = node_op_desc->GetAllInputsDescPtr(); | |||
auto outputDescsPtr = node_op_desc->GetAllOutputsDescPtr(); | |||
ge::Format format = ge::FORMAT_ND; | |||
for (auto &inputDescPtr : inputDescsPtr) { | |||
GE_CHECK_NOTNULL(inputDescPtr); | |||
inputDescPtr->SetFormat(format); | |||
inputDescPtr->SetOriginFormat(format); | |||
} | |||
for (auto &outputDescPtr : outputDescsPtr) { | |||
GE_CHECK_NOTNULL(outputDescPtr); | |||
outputDescPtr->SetFormat(format); | |||
outputDescPtr->SetOriginFormat(format); | |||
} | |||
} | |||
if (node_op_desc->GetType() == DATA_TYPE || node_op_desc->GetType() == AIPP_DATA_TYPE) { | |||
GELOGD("Data node: %s.", n->GetName().c_str()); | |||
@@ -37,7 +37,7 @@ | |||
namespace ge { | |||
class ModelBuilder { | |||
public: | |||
ModelBuilder(ge::ComputeGraphPtr whole_graph, const std::vector<SubGraphInfoPtr> &subgraphs, | |||
ModelBuilder(ge::ComputeGraphPtr whole_graph, const Graph2SubGraphInfoList &subgraphs, | |||
const std::map<std::string, int> &stream_max_parallel_num, bool hcom_parallel, | |||
int mode = static_cast<int>(domi::BuildMode::GEN_TASK_WITHOUT_FUSION)); | |||
@@ -85,7 +85,7 @@ class ModelBuilder { | |||
ge::ComputeGraphPtr compute_graph_; | |||
const std::vector<SubGraphInfoPtr> &subgraphs_; | |||
const Graph2SubGraphInfoList &subgraphs_; | |||
int64_t stream_num_; | |||
@@ -164,6 +164,9 @@ Status RunContextUtil::CreateRunContext(Model &model, const ComputeGraphPtr &gra | |||
return ret; | |||
} | |||
GELOGI("CreateRunContext: data_mem_base_ = %p, weight_mem_base_ = %p, memory_size = %lu, weight_size = %lu", | |||
data_mem_base_, weight_mem_base_, data_mem_size_, weight_mem_size_); | |||
run_context_ = {rt_model_, nullptr, session_id, data_mem_size_, data_mem_base_, weight_mem_size_, | |||
weight_mem_base_, buffer, stream_list_, event_list_, label_list_}; | |||
return SUCCESS; | |||
@@ -40,7 +40,7 @@ const uint32_t kMaxSwitchStreamNum = 1; | |||
namespace ge { | |||
Status StreamAllocator::AssignLogicalStreams(const std::map<std::string, int> &max_parallel_num, bool hcom_parallel) { | |||
GELOGI("AssignLogicalStreams start."); | |||
GELOGI("Assign logical streams start."); | |||
GE_CHECK_NOTNULL(whole_graph_); | |||
GraphUtils::DumpGEGraph(whole_graph_, "BeforeAssignedLogicalStreams"); | |||
GraphUtils::DumpGEGraphToOnnx(*whole_graph_, "BeforeAssignedLogicalStreams"); | |||
@@ -52,7 +52,6 @@ Status StreamAllocator::AssignLogicalStreams(const std::map<std::string, int> &m | |||
} | |||
const map<string, SchedulerConf> &scheduler_confs = gelib->DNNEngineManagerObj().GetSchedulers(); | |||
LogicalStreamAllocator logical_allocator(scheduler_confs, max_parallel_num, hcom_parallel); | |||
Status status = logical_allocator.Assign(whole_graph_, subgraphs_, stream_num_); | |||
if (status != SUCCESS) { | |||
@@ -62,7 +61,7 @@ Status StreamAllocator::AssignLogicalStreams(const std::map<std::string, int> &m | |||
GraphUtils::DumpGEGraph(whole_graph_, "AfterAssignedLogicalStreams"); | |||
GraphUtils::DumpGEGraphToOnnx(*whole_graph_, "AfterAssignedLogicalStreams"); | |||
GELOGI("AssignLogicalStreams success."); | |||
GELOGI("Assign logical streams success."); | |||
return SUCCESS; | |||
} | |||
@@ -136,7 +135,7 @@ Status StreamAllocator::RefreshRealStream(int64_t &stream_num, int64_t &event_nu | |||
GELOGI("None of nodes need to assign stream, stream num is 0, it will cause error, so change it to 1"); | |||
stream_num_ = 1; | |||
} | |||
GELOGI("stream_num_: %ld, event_num_: %u.", stream_num_, event_num_); | |||
GELOGI("stream num: %ld, event num: %u.", stream_num_, event_num_); | |||
GELOGI("RefreshRealStream successfully."); | |||
stream_num = stream_num_; | |||
@@ -148,7 +147,7 @@ Status StreamAllocator::RefreshRealStream(int64_t &stream_num, int64_t &event_nu | |||
// Split the stream according to the maximum number of nodes in the stream. | |||
Status StreamAllocator::SplitStreams() { | |||
if (stream_num_ == 0) { | |||
GELOGI("stream_num_ is 0"); | |||
GELOGI("The number of streams is 0 and no need to split."); | |||
return SUCCESS; | |||
} | |||
@@ -30,7 +30,7 @@ | |||
namespace ge { | |||
class StreamAllocator { | |||
public: | |||
StreamAllocator(ComputeGraphPtr whole_graph, const std::vector<SubGraphInfoPtr> &subgraphs) | |||
StreamAllocator(ComputeGraphPtr whole_graph, const Graph2SubGraphInfoList &subgraphs) | |||
: whole_graph_(std::move(whole_graph)), subgraphs_(subgraphs) {} | |||
StreamAllocator(const StreamAllocator &) = delete; | |||
StreamAllocator &operator=(const StreamAllocator &) = delete; | |||
@@ -75,7 +75,7 @@ class StreamAllocator { | |||
bool IsRecvNodeActivatedBySendNode(const NodePtr &send_node_ptr, const NodePtr &recv_node_ptr) const; | |||
ComputeGraphPtr whole_graph_; | |||
const std::vector<SubGraphInfoPtr> &subgraphs_; | |||
const Graph2SubGraphInfoList &subgraphs_; | |||
int64_t stream_num_{0}; | |||
uint32_t event_num_{0}; | |||
@@ -29,19 +29,21 @@ static const int64_t kInvalidStream = -1; | |||
namespace ge { | |||
StreamGraphOptimizer::~StreamGraphOptimizer() {} | |||
void StreamGraphOptimizer::RefreshNodeId(const ComputeGraphPtr &comp_graph, vector<SubGraphInfoPtr> &subgraph_infos) { | |||
void StreamGraphOptimizer::RefreshNodeId(const ComputeGraphPtr &comp_graph, Graph2SubGraphInfoList &subgraph_map) { | |||
size_t node_size = comp_graph->GetDirectNodesSize(); | |||
GELOGI("Refresh placeholder and end nodeId start from node num: %zu", node_size); | |||
for (const auto &sub_graph_info : subgraph_infos) { | |||
ComputeGraphPtr sub_graph = sub_graph_info->GetSubGraph(); | |||
if (sub_graph == nullptr) { | |||
continue; | |||
} | |||
for (ge::NodePtr &node : sub_graph->GetDirectNode()) { | |||
GE_CHECK_NOTNULL_EXEC(node->GetOpDesc(), return ); | |||
if ((node->GetType() == END) || (node->GetType() == PLACEHOLDER)) { | |||
node->GetOpDesc()->SetId(static_cast<int64_t>(node_size)); | |||
node_size++; | |||
for (const auto &subgraph_pair : subgraph_map) { | |||
for (const auto &subgraph_info : subgraph_pair.second) { | |||
ComputeGraphPtr subgraph = subgraph_info->GetSubGraph(); | |||
if (subgraph == nullptr) { | |||
continue; | |||
} | |||
for (ge::NodePtr &node : subgraph->GetDirectNode()) { | |||
GE_CHECK_NOTNULL_EXEC(node->GetOpDesc(), return ); | |||
if ((node->GetType() == END) || (node->GetType() == PLACEHOLDER)) { | |||
node->GetOpDesc()->SetId(static_cast<int64_t>(node_size)); | |||
node_size++; | |||
} | |||
} | |||
} | |||
} | |||
@@ -71,67 +73,71 @@ bool StreamGraphOptimizer::IsSameStreamId(const ComputeGraphPtr &comp_graph) { | |||
} | |||
Status StreamGraphOptimizer::OptimizeStreamedSubGraph(const ComputeGraphPtr &comp_graph, | |||
vector<SubGraphInfoPtr> &subgraph_infos, | |||
Graph2SubGraphInfoList &subgraph_map, | |||
struct RunContext &run_context) { | |||
Status ret = SUCCESS; | |||
GELOGI("Begin to Get optimize streamed subgraph."); | |||
GELOGI("Optimize streamed subgraph start."); | |||
RefreshNodeId(comp_graph, subgraph_infos); | |||
RefreshNodeId(comp_graph, subgraph_map); | |||
std::shared_ptr<GELib> instance = ge::GELib::GetInstance(); | |||
GE_CHECK_NOTNULL(instance); | |||
for (auto &sub_graph_info : subgraph_infos) { | |||
ComputeGraphPtr sub_graph = sub_graph_info->GetSubGraph(); | |||
if (sub_graph == nullptr) { | |||
continue; | |||
} | |||
for (const auto &subgraph_pair : subgraph_map) { | |||
for (const auto &subgraph_info : subgraph_pair.second) { | |||
ComputeGraphPtr subgraph = subgraph_info->GetSubGraph(); | |||
GE_CHECK_NOTNULL(subgraph); | |||
std::string engine_name = sub_graph_info->GetEngineName(); | |||
GELOGI("Optimize subgraph %s", subgraph->GetName().c_str()); | |||
vector<GraphOptimizerPtr> graph_optimizers; | |||
if (instance->DNNEngineManagerObj().IsEngineRegistered(engine_name)) { | |||
instance->OpsKernelManagerObj().GetGraphOptimizerByEngine(engine_name, graph_optimizers); | |||
GELOGI("Subgraph: %s start optimize streamed graph. engineName: %s, subgraph num: %zu, graph Optimizer num: %zu.", | |||
sub_graph->GetName().c_str(), engine_name.c_str(), subgraph_infos.size(), graph_optimizers.size()); | |||
std::string engine_name = subgraph_info->GetEngineName(); | |||
auto nodes = sub_graph->GetDirectNode(); | |||
if (nodes.empty()) { | |||
continue; | |||
} | |||
if (!IsSameStreamId(sub_graph)) { | |||
GELOGI("There are more than one stream in subgraph %s", sub_graph->GetName().c_str()); | |||
continue; | |||
} | |||
OpDescPtr op_desc = nodes.at(0)->GetOpDesc(); | |||
GE_CHECK_NOTNULL(op_desc); | |||
int64_t stream_id = op_desc->GetStreamId(); | |||
if (static_cast<size_t>(stream_id) >= run_context.graphStreamList.size()) { | |||
GELOGE(FAILED, "stream_id is bigger than run_context.graphStreamList.size()"); | |||
return FAILED; | |||
} | |||
run_context.stream = run_context.graphStreamList[stream_id]; | |||
GELOGD("Subgraph has same stream id, subgraph: %s, engine_name: %s, stream_id: %ld, rtstream: %lu.", | |||
sub_graph->GetName().c_str(), engine_name.c_str(), stream_id, | |||
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(run_context.stream))); | |||
for (auto iter = graph_optimizers.begin(); iter != graph_optimizers.end(); ++iter) { | |||
GE_CHECK_NOTNULL(*iter); | |||
ret = (*iter)->OptimizeStreamGraph(*sub_graph, run_context); | |||
if (ret != SUCCESS) { | |||
GELOGE(ret, | |||
"[optimizeStreamedSubGraph]: optimize streamed subgraph failed, subgraph: %s, engine_name: %s, graph " | |||
"Optimizer num: %zu, ret: %u", | |||
sub_graph->GetName().c_str(), engine_name.c_str(), graph_optimizers.size(), ret); | |||
return ret; | |||
vector<GraphOptimizerPtr> graph_optimizers; | |||
if (instance->DNNEngineManagerObj().IsEngineRegistered(engine_name)) { | |||
instance->OpsKernelManagerObj().GetGraphOptimizerByEngine(engine_name, graph_optimizers); | |||
GELOGI("Subgraph: %s start optimize streamed graph. engineName: %s, graph Optimizer num: %zu.", | |||
subgraph->GetName().c_str(), engine_name.c_str(), graph_optimizers.size()); | |||
auto nodes = subgraph->GetDirectNode(); | |||
if (nodes.empty()) { | |||
continue; | |||
} | |||
if (!IsSameStreamId(subgraph)) { | |||
GELOGI("There are more than one stream in subgraph %s", subgraph->GetName().c_str()); | |||
continue; | |||
} | |||
OpDescPtr op_desc = nodes.at(0)->GetOpDesc(); | |||
GE_CHECK_NOTNULL(op_desc); | |||
int64_t stream_id = op_desc->GetStreamId(); | |||
if (static_cast<size_t>(stream_id) >= run_context.graphStreamList.size()) { | |||
GELOGE(FAILED, "stream_id %ld is bigger than run_context.graphStreamList.size() %zu", stream_id, | |||
run_context.graphStreamList.size()); | |||
return FAILED; | |||
} | |||
run_context.stream = run_context.graphStreamList[stream_id]; | |||
GELOGD("Subgraph has same stream id, subgraph: %s, engine_name: %s, stream_id: %ld, rtstream: %lu.", | |||
subgraph->GetName().c_str(), engine_name.c_str(), stream_id, | |||
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(run_context.stream))); | |||
for (auto iter = graph_optimizers.begin(); iter != graph_optimizers.end(); ++iter) { | |||
GE_CHECK_NOTNULL(*iter); | |||
Status ret = (*iter)->OptimizeStreamGraph(*subgraph, run_context); | |||
if (ret != SUCCESS) { | |||
GELOGE( | |||
ret, | |||
"[optimizeStreamedSubGraph]: optimize streamed subgraph failed, subgraph: %s, engine_name: %s, graph " | |||
"Optimizer num: %zu, ret: %u", | |||
subgraph->GetName().c_str(), engine_name.c_str(), graph_optimizers.size(), ret); | |||
return ret; | |||
} | |||
GELOGI( | |||
"[optimizeStreamedSubGraph]: optimize streamed subgraph success, subgraph: %s, engine_name: %s, graph " | |||
"Optimizer num: %zu!", | |||
subgraph->GetName().c_str(), engine_name.c_str(), graph_optimizers.size()); | |||
} | |||
GELOGI( | |||
"[optimizeStreamedSubGraph]: optimize streamed subgraph success, subgraph: %s, engine_name: %s, graph " | |||
"Optimizer num: %zu!", | |||
sub_graph->GetName().c_str(), engine_name.c_str(), graph_optimizers.size()); | |||
} | |||
} | |||
} | |||
return ret; | |||
GELOGI("Optimize streamed subgraph success."); | |||
return SUCCESS; | |||
} | |||
} // namespace ge |
@@ -35,11 +35,11 @@ class StreamGraphOptimizer { | |||
virtual ~StreamGraphOptimizer(); | |||
Status OptimizeStreamedSubGraph(const ComputeGraphPtr &comp_graph, std::vector<SubGraphInfoPtr> &subgraph_ptr_list, | |||
Status OptimizeStreamedSubGraph(const ComputeGraphPtr &comp_graph, Graph2SubGraphInfoList &subgraph_map, | |||
struct RunContext &run_context); | |||
private: | |||
void RefreshNodeId(const ComputeGraphPtr &comp_graph, std::vector<SubGraphInfoPtr> &subgraph_ptr_list); | |||
void RefreshNodeId(const ComputeGraphPtr &comp_graph, Graph2SubGraphInfoList &subgraph_map); | |||
bool IsSameStreamId(const ComputeGraphPtr &comp_graph); | |||
}; | |||
@@ -221,10 +221,8 @@ Status TaskGenerator::SaveL1fusionNodes(map<int64_t, std::vector<NodePtr>> &l1_f | |||
if (call_check) { | |||
auto input_group_id = *input_group_ids.begin(); | |||
if (group_id != input_group_id) { | |||
GELOGE(INTERNAL_ERROR, | |||
"L1Fusion: node[name:%s(%s) with group id:%ld and diff from it's input nodes's group id:%ld ", | |||
GELOGW("L1Fusion: node[name:%s(%s) with group id:%ld and diff from it's input nodes's group id:%ld ", | |||
name.c_str(), type.c_str(), group_id, input_group_id); | |||
return INTERNAL_ERROR; | |||
} | |||
} | |||
} | |||
@@ -172,7 +172,7 @@ NodePtr LabelMaker::AddLabelSetLeave(const ComputeGraphPtr &graph, const std::st | |||
GELOGI("LabelSet: Create node %s.", op_desc->GetName().c_str()); | |||
(void)AttrUtils::SetInt(op_desc, ATTR_NAME_LABEL_SWITCH_INDEX, index); | |||
NodePtr label_set = graph->AddNodeFront(op_desc); | |||
NodePtr label_set = graph->AddNode(op_desc); | |||
GE_CHECK_NOTNULL_EXEC(label_set, return nullptr); | |||
// Link control edge to graph tail. | |||
@@ -202,7 +202,7 @@ NodePtr LabelMaker::AddLabelGotoEnter(const ComputeGraphPtr &graph, const std::s | |||
return nullptr; | |||
} | |||
OpDescPtr op_desc = MakeShared<OpDesc>(name, LABELGOTO); | |||
OpDescPtr op_desc = MakeShared<OpDesc>(name, LABELGOTOEX); | |||
GE_CHECK_NOTNULL_EXEC(op_desc, return nullptr); | |||
SetStreamIdEnter(graph, op_desc); | |||
@@ -238,7 +238,7 @@ NodePtr LabelMaker::AddLabelGotoLeave(const ComputeGraphPtr &graph, const std::s | |||
const NodePtr &node = *it; | |||
GE_CHECK_NOTNULL_EXEC(node, return nullptr); | |||
OpDescPtr op_desc = MakeShared<OpDesc>(name, LABELGOTO); | |||
OpDescPtr op_desc = MakeShared<OpDesc>(name, LABELGOTOEX); | |||
GE_CHECK_NOTNULL_EXEC(op_desc, return nullptr); | |||
SetStreamIdLeave(graph, op_desc); | |||
@@ -366,6 +366,7 @@ NodePtr LabelMaker::AddLabelSwitchIndex(const ComputeGraphPtr &graph, const std: | |||
OpDescPtr op_desc = MakeShared<OpDesc>(name, DATA); | |||
GE_CHECK_NOTNULL_EXEC(op_desc, return nullptr); | |||
op_desc->SetStreamId(kInvalidStreamId); | |||
GELOGI("Data: Create node %s.", op_desc->GetName().c_str()); | |||
if (op_desc->AddOutputDesc(desc) != GRAPH_SUCCESS) { | |||
@@ -20,11 +20,11 @@ | |||
namespace { | |||
const uint32_t kCoreDim = 1; // for rtCpuKernelLaunch | |||
const char *const kCpuTaskModelEnqueue = "modelEnqueue"; | |||
const char *const kCpuTaskPrepareInput = "modelPrepareInput"; | |||
const char *const kCpuTaskWaitEndGraph = "modelWaitEndGraph"; | |||
const char *const kCpuTaskPrepareOutput = "modelPrepareOutput"; | |||
const char *const kCpuTaskPrepareOutput = "bufferPrepareOutput"; | |||
const char *const kCpuTaskModelDequeue = "modelDequeue"; | |||
const char *const kCpuTaskModelRepeat = "modelRepeat"; | |||
const char *const kCpuTaskZeroCopy = "zeroCpy"; | |||
} // namespace | |||
namespace ge { | |||
@@ -93,19 +93,19 @@ Status CpuTaskModelDequeue::Distribute() { | |||
/// | |||
/// @ingroup ge | |||
/// @brief definiteness queue schedule, bind output queue to task. | |||
/// @param [in] addr: NetOutput Op input tensor address. | |||
/// @param [in] size: NetOutput Op input tensor size. | |||
/// @param [in] in_mbuf: input mbuf addr for input data. | |||
/// @brief definiteness queue schedule, zero copy. | |||
/// @param [in] mbuf_list: input/output mbuf addr list for input/output data. | |||
/// @param [in] outside_addrs: model input/output memory addr | |||
/// @return: 0 for success / others for failed | |||
/// | |||
Status CpuTaskPrepareInput::Init(uintptr_t addr, uint32_t size, uintptr_t in_mbuf) { | |||
Status CpuTaskZeroCopy::Init(std::vector<uintptr_t> &mbuf_list, | |||
std::map<const void *, std::vector<void *>> &outside_addrs) { | |||
if ((args_ != nullptr) || (args_size_ > 0)) { | |||
GELOGE(FAILED, "Task already initialized, size: %u", args_size_); | |||
return FAILED; | |||
} | |||
args_size_ = sizeof(PrepareInputInfo); | |||
args_size_ = sizeof(AddrMapInfo); | |||
rtError_t status = rtMalloc(&args_, args_size_, RT_MEMORY_HBM); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt malloc failed, status: 0x%x", status); | |||
@@ -113,36 +113,99 @@ Status CpuTaskPrepareInput::Init(uintptr_t addr, uint32_t size, uintptr_t in_mbu | |||
} | |||
GE_PRINT_DYNAMIC_MEMORY(rtMalloc, "args data.", args_size_) | |||
PrepareInputInfo prepare; | |||
prepare.in_mbuf = in_mbuf; | |||
prepare.mbuf_offset = 0; | |||
prepare.data_size = size; | |||
prepare.data_addr = addr; | |||
status = rtMemcpy(args_, args_size_, &prepare, args_size_, RT_MEMCPY_HOST_TO_DEVICE); | |||
AddrMapInfo addr_map_info; | |||
for (const auto &addrs : outside_addrs) { | |||
addr_map_info.addr_num += addrs.second.size(); | |||
} | |||
GELOGI("addr_map_info.addr_num is %zu", addr_map_info.addr_num); | |||
// init src_addrs/dst_addrs | |||
size_t index = 0; | |||
vector<uint64_t> src_addrs; | |||
vector<uint64_t> dst_addrs; | |||
for (const auto &addrs : outside_addrs) { | |||
for (size_t i = 0; i < addrs.second.size(); ++i) { | |||
src_addrs.push_back(mbuf_list.at(index)); | |||
dst_addrs.push_back(reinterpret_cast<uint64_t>(addrs.second.at(i))); | |||
} | |||
index++; | |||
} | |||
// malloc mem for src_addrs/dst_addrs, and copy data of src_addrs/dst_addrs | |||
status = rtMalloc(&src_addr_, src_addrs.size() * sizeof(uint64_t), RT_MEMORY_HBM); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt malloc failed, status: 0x%x", status); | |||
return RT_FAILED; | |||
} | |||
status = rtMemcpy(src_addr_, src_addrs.size() * sizeof(uint64_t), src_addrs.data(), | |||
src_addrs.size() * sizeof(uint64_t), RT_MEMCPY_HOST_TO_DEVICE); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt memcpy failed, status: 0x%x", status); | |||
return RT_FAILED; | |||
} | |||
status = rtMalloc(&dst_addr_, dst_addrs.size() * sizeof(uint64_t), RT_MEMORY_HBM); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt malloc failed, status: 0x%x", status); | |||
return RT_FAILED; | |||
} | |||
status = rtMemcpy(dst_addr_, dst_addrs.size() * sizeof(uint64_t), dst_addrs.data(), | |||
dst_addrs.size() * sizeof(uint64_t), RT_MEMCPY_HOST_TO_DEVICE); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt memcpy failed, status: 0x%x", status); | |||
return RT_FAILED; | |||
} | |||
// src_addr_list is init to src_addr, which is the point to src_addrs | |||
if (!src_addrs.empty() && !dst_addrs.empty()) { | |||
addr_map_info.src_addr_list = reinterpret_cast<uint64_t>(src_addr_); | |||
addr_map_info.dst_addr_list = reinterpret_cast<uint64_t>(dst_addr_); | |||
GELOGI("src_addr_list is %lu, dst_addr_list is %lu", addr_map_info.src_addr_list, addr_map_info.dst_addr_list); | |||
} | |||
status = rtMemcpy(args_, args_size_, &addr_map_info, sizeof(AddrMapInfo), RT_MEMCPY_HOST_TO_DEVICE); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt memcpy failed, status: 0x%x", status); | |||
return RT_FAILED; | |||
} | |||
return SUCCESS; | |||
} | |||
Status CpuTaskPrepareInput::Distribute() { | |||
Status CpuTaskZeroCopy::Distribute() { | |||
if ((args_ == nullptr) || (args_size_ == 0) || (stream_ == nullptr)) { | |||
GELOGE(FAILED, "Task not initialized, distribute failed, size: %u", args_size_); | |||
return FAILED; | |||
} | |||
rtError_t status = rtCpuKernelLaunch(nullptr, kCpuTaskPrepareInput, kCoreDim, args_, args_size_, nullptr, stream_); | |||
rtError_t status = rtCpuKernelLaunch(nullptr, kCpuTaskZeroCopy, kCoreDim, args_, args_size_, nullptr, stream_); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt CpuKernelLaunch PrepareInput failed, status: 0x%X", status); | |||
GELOGE(RT_FAILED, "Call rt CpuKernelLaunch ZeroCopy failed, status: 0x%X", status); | |||
return RT_FAILED; | |||
} | |||
GELOGI("Cpu kernel launch prepare input task success."); | |||
GELOGI("Cpu kernel launch zero copy task success."); | |||
return SUCCESS; | |||
} | |||
CpuTaskZeroCopy::~CpuTaskZeroCopy() { | |||
if (src_addr_ == nullptr && dst_addr_ == nullptr) { | |||
return; | |||
} | |||
if (src_addr_ != nullptr) { | |||
rtError_t status = rtFree(src_addr_); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGW("Call rt free failed, status: 0x%x", status); | |||
} | |||
} | |||
if (dst_addr_ != nullptr) { | |||
rtError_t status = rtFree(dst_addr_); | |||
if (status != RT_ERROR_NONE) { | |||
GELOGW("Call rt free failed, status: 0x%x", status); | |||
} | |||
} | |||
src_addr_ = nullptr; | |||
dst_addr_ = nullptr; | |||
} | |||
/// | |||
/// @ingroup ge | |||
/// @brief definiteness queue schedule, bind output queue to task. | |||
@@ -47,6 +47,13 @@ struct PrepareOutputInfo { | |||
uintptr_t out_mbuf; // output mbuf addr | |||
}; | |||
// For AICPU task "modelZeroCopy" | |||
struct AddrMapInfo { | |||
uint32_t addr_num = 0; | |||
uint64_t src_addr_list; | |||
uint64_t dst_addr_list; | |||
}; | |||
/// | |||
/// @ingroup ge | |||
/// @brief CpuTask base, inherit from TaskInfo used for manage. | |||
@@ -78,17 +85,21 @@ class CpuTaskModelDequeue : public CpuTaskInfo { | |||
/// | |||
/// @ingroup ge | |||
/// @brief definiteness queue schedule, bind output queue to task. | |||
/// @brief definiteness queue schedule, zero copy. | |||
/// | |||
class CpuTaskPrepareInput : public CpuTaskInfo { | |||
class CpuTaskZeroCopy : public CpuTaskInfo { | |||
public: | |||
explicit CpuTaskPrepareInput(rtStream_t stream) : CpuTaskInfo(stream) {} | |||
~CpuTaskPrepareInput() override {} | |||
explicit CpuTaskZeroCopy(rtStream_t stream) : CpuTaskInfo(stream) {} | |||
~CpuTaskZeroCopy() override; | |||
Status Init(const domi::TaskDef &task_def, DavinciModel *davinci_model) override { return SUCCESS; } | |||
Status Init(uintptr_t addr, uint32_t size, uintptr_t in_mbuf); | |||
Status Init(std::vector<uintptr_t> &mbuf_list, std::map<const void *, std::vector<void *>> &outside_addrs); | |||
Status Distribute() override; | |||
private: | |||
void *src_addr_ = nullptr; | |||
void *dst_addr_ = nullptr; | |||
}; | |||
/// | |||
@@ -340,13 +340,6 @@ class DavinciModel { | |||
vector<InputOutputDescInfo> &output_desc, | |||
std::vector<uint32_t> &inputFormats, std::vector<uint32_t> &output_formats); | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief copy input data to model | |||
/// @return Status | |||
/// | |||
Status CopyInputDataToModel(const std::vector<DataBuffer> &data, uint32_t data_op_index, bool device_data); | |||
Status ReturnResult(uint32_t data_id, const bool rslt_flg, const bool seq_end_flg, OutputData *output_data); | |||
Status ReturnNoOutput(uint32_t data_id); | |||
@@ -413,20 +406,6 @@ class DavinciModel { | |||
/// | |||
uint32_t GetDeviceId() const { return device_id_; } | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief Set Train Mode | |||
/// @return void | |||
/// | |||
void SetTrainMode(bool mode) { is_train_mode_ = mode; } | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief Get Train Mode | |||
/// @return bool true | |||
/// | |||
bool GetTrainMode() { return is_train_mode_; } | |||
GeModelPtr GetGeModel() { return ge_model_; } | |||
const RuntimeParam &GetRuntimeParam() { return runtime_param_; } | |||
@@ -519,15 +498,14 @@ class DavinciModel { | |||
/// | |||
/// @ingroup ge | |||
/// @brief Copy Data addr to model for direct use. | |||
/// @param [in] const vector<void *> &addrs: model input memory addr list. | |||
/// @param [in] const vector<uint32_t> &sizes: model input memory size list. | |||
/// @param [in] const std::map<uint32_t, std::pair<int64_t, void *>> &data_info: model memory addr/size list. | |||
/// @param [in] const std::vector<DataBuffer> &blobs: user input data list. | |||
/// @param [in] bool is_dynamic_input: whether is dynamic input, true: is dynamic input; false: not is dynamic input | |||
/// @param [in] ZeroCopyMode zero_copy_mode: input zero copy or output zero copy | |||
/// @param [in] string batch_label: batch label for multi-batch scenes | |||
/// @return SUCCESS handle successfully / others handle failed | |||
/// | |||
Status ZeroCopyBlobs(const std::vector<void *> &addr_list, const std::vector<int64_t> &size_list, | |||
Status ZeroCopyBlobs(const std::map<uint32_t, std::pair<int64_t, void *>> &data_info, | |||
const std::vector<DataBuffer> &blobs, bool is_dynamic_input, ZeroCopyMode zero_copy_mode, | |||
string batch_label); | |||
@@ -610,11 +588,9 @@ class DavinciModel { | |||
/// @brief Data Op Initialize. | |||
/// @param [in] NodePtr: Data Op. | |||
/// @param [in/out] data_op_index: NetOutput addr size info. | |||
/// @param [in/out] input_data_info: Data index and addr info {index, {size, addr}}. | |||
/// @return Status | |||
/// | |||
Status InitDataOp(const NodePtr &node, uint32_t &data_op_index, | |||
std::map<uint32_t, std::pair<int64_t, void *>> &input_data_info); | |||
Status InitDataOp(const NodePtr &node, uint32_t &data_op_index); | |||
/// | |||
/// @ingroup ge | |||
@@ -633,19 +609,27 @@ class DavinciModel { | |||
Status InitNetOutput(const OpDescPtr &op_desc); | |||
/// | |||
/// @ingroup ge | |||
/// @brief Make Input and Output addr for feature use. | |||
/// @param [in] input_data_info: Data index and addr info {index, {size, addr}}. | |||
/// @return Status | |||
/// | |||
Status CombineDataInfo(const std::map<uint32_t, std::pair<int64_t, void *>> &input_data_info); | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief Constant Op Init. | |||
/// @return Status | |||
/// | |||
Status InitConstant(const ConstOpDescPtr &op_desc) const; | |||
Status InitConstant(const OpDescPtr &op_desc); | |||
Status InitVariable(const OpDescPtr &op_desc); | |||
Status InitEndGraph(const OpDescPtr &op_desc); | |||
/// @ingroup ge | |||
/// @brief LabelSet Op Initialize. | |||
/// @param [in] op_desc: LabelSet Op descriptor. | |||
/// @return Status | |||
Status InitLabelSet(const OpDescPtr &op_desc); | |||
Status InitStreamSwitch(const OpDescPtr &op_desc); | |||
Status InitStreamActive(const OpDescPtr &op_desc); | |||
Status InitStreamSwitchN(const OpDescPtr &op_desc); | |||
/// | |||
/// @ingroup domi_ome | |||
@@ -662,7 +646,7 @@ class DavinciModel { | |||
/// @brief Init model stream for NN model. | |||
/// @return Status | |||
/// | |||
Status InitModelStream(rtStream_t stream, bool async_mode); | |||
Status InitModelStream(rtStream_t stream); | |||
/// | |||
/// @ingroup ge | |||
@@ -678,12 +662,16 @@ class DavinciModel { | |||
/// | |||
Status BindInputQueue(); | |||
Status CpuTaskModelZeroCopy(std::vector<uintptr_t> &mbuf_list, | |||
std::map<const void *, std::vector<void *>> &outside_addrs); | |||
/// | |||
/// @ingroup ge | |||
/// @brief ACL, Bind NetOutput Op addr to output queue. | |||
/// @return: 0 for success / others for fail | |||
/// | |||
Status BindOutputQueue(); | |||
Status CpuModelPrepareOutput(uintptr_t addr, uint32_t size); | |||
/// | |||
/// @ingroup ge | |||
@@ -693,13 +681,6 @@ class DavinciModel { | |||
Status BindActiveStream(); | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief insert active_stream_indication_ | |||
/// @return Status | |||
/// | |||
Status MarkActiveStream(const OpDescPtr &op_desc); | |||
/// | |||
/// @ingroup ge | |||
/// @brief definiteness queue schedule, bind input queue to task. | |||
/// @param [in] queue_id: input queue id from user. | |||
@@ -707,7 +688,7 @@ class DavinciModel { | |||
/// @param [in] size: Data Op output tensor size. | |||
/// @return: 0 for success / others for fail | |||
/// | |||
Status CpuModelDequeue(uint32_t queue_id, uintptr_t addr, uint32_t size); | |||
Status CpuModelDequeue(uint32_t queue_id); | |||
/// | |||
/// @ingroup ge | |||
@@ -734,6 +715,8 @@ class DavinciModel { | |||
/// | |||
Status CpuWaitEndGraph(); | |||
Status BindEnqueue(); | |||
Status CpuModelEnqueue(uint32_t queue_id, uintptr_t out_mbuf); | |||
/// | |||
/// @ingroup ge | |||
/// @brief definiteness queue schedule, repeat run model. | |||
@@ -783,10 +766,8 @@ class DavinciModel { | |||
vector<OpDescPtr> variable_op_list_; | |||
vector<int64_t> output_size_list_; // Init by NetOutput Input Tensor | |||
vector<void *> output_addr_list_; // Init by NetOutput Input Tensor | |||
vector<int64_t> input_size_list_; // Init by Data Output Tensor | |||
vector<void *> input_addr_list_; // Init by Data Output Tensor | |||
std::map<uint32_t, std::pair<int64_t, void *>> input_data_info_; // Init by Data Output Tensor | |||
std::map<uint32_t, std::pair<int64_t, void *>> output_data_info_; // Init by NetOutput Input Tensor | |||
// output op: save cce op actual needed memory size | |||
vector<int64_t> output_memory_size_list_; | |||
@@ -813,6 +794,7 @@ class DavinciModel { | |||
vector<rtEvent_t> event_list_; | |||
vector<rtLabel_t> label_list_; | |||
set<uint32_t> label_id_indication_; | |||
std::mutex outside_addrs_mutex_; | |||
std::map<const void *, std::vector<void *>> input_outside_addrs_; | |||
@@ -830,6 +812,8 @@ class DavinciModel { | |||
bool is_inner_model_stream_; | |||
bool is_async_mode_; // For NN execute, Async mode use rtMemcpyAsync on rt_model_stream_. | |||
// ACL queue schedule, save queue ids for Init. | |||
std::vector<TaskInfoPtr> cpu_task_list_; | |||
std::vector<uint32_t> input_queue_ids_; // input queue ids created by caller. | |||
@@ -847,8 +831,6 @@ class DavinciModel { | |||
uint32_t device_id_; | |||
bool is_train_mode_; | |||
std::mutex flowctrl_op_index_internal_map_mutex_; | |||
std::map<uint32_t, uint32_t> flowctrl_op_index_internal_map_; | |||
std::set<uint32_t> active_stream_indication_; | |||
@@ -358,26 +358,17 @@ Status ModelManager::DataInputTensor(uint32_t model_id, const std::vector<Tensor | |||
input_data.timestamp = 0; | |||
input_data.index = 0; | |||
std::size_t index = 0; | |||
for (const auto &op : model->GetDataList()) { | |||
GE_CHECK_NOTNULL(op); | |||
GE_CHECK_GE(inputs.size(), 1); | |||
GE_CHECK_GE(inputs.size() - 1, index); | |||
for (size_t i = 0; i < inputs.size(); ++i) { | |||
DataBuffer data; | |||
data.data = inputs[index].data.data; | |||
data.length = inputs[index].data.length; | |||
data.data = inputs[i].data.data; | |||
data.length = inputs[i].data.length; | |||
input_data.blobs.push_back(data); | |||
index++; | |||
} | |||
CHECK_FALSE_EXEC(input_data.blobs.size() >= inputs.size(), | |||
GELOGW("cur_inputs size = %zu, inputs size = %zu.", input_data.blobs.size(), inputs.size());); | |||
OutputData output_data; | |||
output_data.model_id = model_id; | |||
output_data.index = 0; | |||
for (size_t i = 0; i < outputs.size(); i++) { | |||
for (size_t i = 0; i < outputs.size(); ++i) { | |||
DataBuffer data; | |||
data.data = outputs[i].data.data; | |||
data.length = outputs[i].data.length; | |||
@@ -675,6 +666,15 @@ Status ModelManager::LoadModelOffline(uint32_t &model_id, const ModelData &model | |||
break; | |||
} | |||
davinci_model->SetId(model_id); | |||
int32_t device_id = 0; | |||
rtError_t rt_ret = rtGetDevice(&device_id); | |||
if (rt_ret != RT_ERROR_NONE || device_id < 0) { | |||
GELOGE(RT_FAILED, "Call rtGetDevice failed, ret = 0x%X, device_id = %d.", rt_ret, device_id); | |||
return FAILED; | |||
} | |||
davinci_model->SetDeviceId(device_id); | |||
ret = davinci_model->Init(dev_ptr, mem_size, weight_ptr, weight_size); | |||
GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(ret != SUCCESS, break, "DavinciInit failed."); | |||
@@ -53,27 +53,6 @@ bool ModelUtils::IsOutput(ConstOpDescPtr op_desc) { | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief Check is the Input need trans code. | |||
/// @return bool | |||
/// | |||
bool ModelUtils::IsInputTensorNeedTrans(ConstOpDescPtr op_desc, size_t tensor_index) { | |||
GE_CHECK_NOTNULL_EXEC(op_desc, return false); | |||
const auto &input_desc = op_desc->MutableInputDesc(static_cast<uint32_t>(tensor_index)); | |||
const auto &output_desc = op_desc->MutableOutputDesc(static_cast<uint32_t>(tensor_index)); | |||
GE_CHECK_NOTNULL_EXEC(input_desc, return false); | |||
GE_CHECK_NOTNULL_EXEC(output_desc, return false); | |||
if ((output_desc->GetFormat() == FORMAT_NC1HWC0) && (output_desc->GetDataType() == DT_INT8)) { | |||
// AIPP input, add attribute in data op to tag aipp | |||
return false; | |||
} | |||
return (input_desc->GetFormat() != output_desc->GetFormat()) || | |||
(input_desc->GetDataType() != output_desc->GetDataType()); | |||
} | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief Get input size. | |||
/// @return vector<uint32_t> | |||
/// | |||
@@ -398,6 +377,8 @@ vector<void *> ModelUtils::GetInputDataAddrs(const RuntimeParam &model_param, Co | |||
GE_CHK_STATUS(TensorUtils::GetDataOffset(tensor_desc, data_offset)); | |||
uint8_t *weight_addr = static_cast<uint8_t *>(weight_base + data_offset - logic_weight_base); | |||
v_input_data_addr.push_back(weight_addr); | |||
GELOGI("[IMAS]GetInputDataAddrs graph_%u type[C] name[%s] input[%zu] memaddr[%p]", model_param.graph_id, | |||
op_desc->GetName().c_str(), i, weight_addr); | |||
}); | |||
non_const_index++; | |||
continue; | |||
@@ -411,7 +392,10 @@ vector<void *> ModelUtils::GetInputDataAddrs(const RuntimeParam &model_param, Co | |||
non_const_index++; | |||
GE_IF_BOOL_EXEC(var_size != 0 && ge::VarManager::Instance(session_id)->IsVarAddr(input_offset), | |||
uint8_t *variable_addr = var_base + input_offset - logic_var_base; | |||
v_input_data_addr.push_back(variable_addr); continue;); | |||
v_input_data_addr.push_back(variable_addr); | |||
GELOGI("[IMAS]GetInputDataAddrs graph_%u type[V] name[%s] input[%lu] memaddr[%p]", | |||
model_param.graph_id, op_desc->GetName().c_str(), i, variable_addr); | |||
continue;); | |||
bool input_tensor = false; | |||
GE_IF_BOOL_EXEC(TensorUtils::GetInputTensor(op_desc->GetOutputDesc(i), input_tensor) != GRAPH_SUCCESS, | |||
@@ -421,12 +405,14 @@ vector<void *> ModelUtils::GetInputDataAddrs(const RuntimeParam &model_param, Co | |||
uint8_t *mem_addr = nullptr; | |||
// l1 fusion | |||
if (has_mem_type_attr && v_memory_type[i] != RT_MEMORY_HBM) { | |||
mem_addr = reinterpret_cast<uint8_t *>(input_offset); | |||
mem_addr = reinterpret_cast<uint8_t *>(reinterpret_cast<intptr_t>(input_offset)); | |||
v_input_data_addr.push_back(mem_addr); | |||
} else { | |||
mem_addr = static_cast<uint8_t *>(mem_base + input_offset - logic_mem_base); | |||
v_input_data_addr.push_back(mem_addr); | |||
} | |||
GELOGI("[IMAS]GetInputDataAddrs graph_%u type[F] name[%s] input[%zu] memaddr[%p]", model_param.graph_id, | |||
op_desc->GetName().c_str(), i, mem_addr); | |||
} | |||
return v_input_data_addr; | |||
@@ -487,12 +473,14 @@ vector<void *> ModelUtils::GetOutputDataAddrs(const RuntimeParam &model_param, C | |||
uint8_t *mem_addr = nullptr; | |||
// l1 fusion | |||
if (has_mem_type_attr && v_memory_type[i] != RT_MEMORY_HBM) { | |||
mem_addr = reinterpret_cast<uint8_t *>(v_output_offset[i]); | |||
mem_addr = reinterpret_cast<uint8_t *>(reinterpret_cast<intptr_t>(v_output_offset[i])); | |||
v_output_data_addr.push_back(mem_addr); | |||
} else { | |||
mem_addr = static_cast<uint8_t *>(mem_base + v_output_offset[i] - logic_mem_base); | |||
v_output_data_addr.push_back(mem_addr); | |||
} | |||
GELOGI("[IMAS]GetOutputDataAddrs graph_%u type[F] name[%s] output[%zu] memaddr[%p]", model_param.graph_id, | |||
op_desc->GetName().c_str(), i, mem_addr); | |||
} | |||
return v_output_data_addr; | |||
} | |||
@@ -530,7 +518,7 @@ vector<void *> ModelUtils::GetWorkspaceDataAddrs(const RuntimeParam &model_param | |||
if (has_mem_type_attr && v_memory_type[i] != RT_MEMORY_HBM) { | |||
v_workspace_data_addr.push_back(reinterpret_cast<uint8_t *>(v_workspace_offset[i])); | |||
GELOGI("L1Fusion: op: %s, GetWorkspaceDataAddrs mem_addr[workspace index %zu]:%p", op_desc->GetName().c_str(), i, | |||
reinterpret_cast<uint8_t *>(v_workspace_offset[i])); | |||
reinterpret_cast<uint8_t *>(reinterpret_cast<intptr_t>(v_workspace_offset[i]))); | |||
} else { | |||
int64_t workspace_offset = v_workspace_offset[i]; | |||
int64_t workspace_bytes = v_workspace_bytes[i]; | |||
@@ -558,6 +546,7 @@ Status ModelUtils::ConvertVirtualAddressToPhysical(uint8_t *virtual_address, uin | |||
return RT_FAILED; | |||
} | |||
GELOGD("virtual_address=%p, physical_address=%p", virtual_address, physical_address); | |||
return SUCCESS; | |||
} | |||
} // namespace ge |
@@ -42,13 +42,6 @@ class ModelUtils { | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief Check is the Input need trans code. | |||
/// @return bool | |||
/// | |||
static bool IsInputTensorNeedTrans(ConstOpDescPtr op_desc, size_t tensor_index); | |||
/// | |||
/// @ingroup domi_ome | |||
/// @brief Get input size. | |||
/// @return vector<uint32_t> | |||
/// | |||
@@ -38,6 +38,7 @@ Status EndGraphTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *davin | |||
} | |||
model_ = davinci_model->GetRtModelHandle(); | |||
GELOGI("InitEndGraphTaskInfo Init Success, model:%p, stream:%p", model_, stream_); | |||
return SUCCESS; | |||
} | |||
@@ -125,6 +125,7 @@ Status HcclTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *davinci_m | |||
return RT_FAILED; | |||
} | |||
GELOGD("hccl_stream addr is=%p", stream); | |||
hccl_stream_list_.push_back(stream); | |||
davinci_model->PushHcclStream(stream); | |||
} | |||
@@ -245,6 +246,8 @@ void HcclTaskInfo::GetPrivateDefByTaskDef(const domi::TaskDef &task) { | |||
GELOGE(RT_FAILED, "Call rtMemcpy Fail, ret = 0x%X.", ret); | |||
return; | |||
} | |||
GELOGI("The first address of the custom info, privateDef=%p.", private_def_); | |||
} | |||
} | |||
} | |||
@@ -41,6 +41,7 @@ Status KernelExTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *davin | |||
} | |||
auto kernel_ex_def = task_def.kernel_ex(); | |||
const RuntimeParam &rts_param = davinci_model->GetRuntimeParam(); | |||
// 1. Copy context from kernelExDef.private to workspace | |||
uint32_t op_index = kernel_ex_def.op_index(); | |||
@@ -50,12 +51,12 @@ Status KernelExTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *davin | |||
return INTERNAL_ERROR; | |||
} | |||
if (CopyTaskInfo(kernel_ex_def, davinci_model->GetRuntimeParam(), op_desc) != SUCCESS) { | |||
if (CopyTaskInfo(kernel_ex_def, rts_param, op_desc) != SUCCESS) { | |||
GELOGE(FAILED, "copy task info to workspace failed."); | |||
return FAILED; | |||
} | |||
vector<void *> workspace_data_addrs = ModelUtils::GetWorkspaceDataAddrs(davinci_model->GetRuntimeParam(), op_desc); | |||
const vector<void *> workspace_data_addrs = ModelUtils::GetWorkspaceDataAddrs(rts_param, op_desc); | |||
if (workspace_data_addrs.empty()) { | |||
GELOGE(FAILED, "workspace_data_addrs is empty."); | |||
return FAILED; | |||
@@ -79,16 +80,16 @@ Status KernelExTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *davin | |||
uint64_t step_id_addr = 0; | |||
OpDescPtr step_id_node = davinci_model->GetVariableOp(NODE_NAME_GLOBAL_STEP); | |||
if (step_id_node != nullptr) { | |||
vector<void *> v_step_id_addr = ModelUtils::GetOutputDataAddrs(davinci_model->GetRuntimeParam(), step_id_node); | |||
vector<void *> v_step_id_addr = ModelUtils::GetOutputDataAddrs(rts_param, step_id_node); | |||
if (!v_step_id_addr.empty()) { | |||
step_id_addr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(v_step_id_addr[0])); | |||
} | |||
} | |||
// 3. Set workspaceaddr, inputOutputDataAddr | |||
uint64_t workspace_base_addr = reinterpret_cast<uint64_t>(workspace_data_addrs[0]); | |||
vector<void *> input_addrs = ModelUtils::GetInputDataAddrs(davinci_model->GetRuntimeParam(), op_desc); | |||
vector<void *> output_addrs = ModelUtils::GetOutputDataAddrs(davinci_model->GetRuntimeParam(), op_desc); | |||
uint64_t workspace_base_addr = reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(workspace_data_addrs[0])); | |||
const vector<void *> input_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc); | |||
const vector<void *> output_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc); | |||
vector<void *> io_addrs; | |||
io_addrs.insert(io_addrs.end(), input_addrs.begin(), input_addrs.end()); | |||
io_addrs.insert(io_addrs.end(), output_addrs.begin(), output_addrs.end()); | |||
@@ -132,7 +133,13 @@ Status KernelExTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *davin | |||
rt_ret = rtMemcpy(kernel_buf_, sizeof(STR_FWK_OP_KERNEL), static_cast<void *>(&fwk_op_kernel), | |||
sizeof(STR_FWK_OP_KERNEL), RT_MEMCPY_HOST_TO_DEVICE); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMemcpy error, ret: Ox%X", rt_ret); return FAILED;) | |||
davinci_model->SetZeroCopyAddr(op_desc, io_addrs, input_output_addr_); | |||
vector<void *> virtual_io_addrs; // use virtual address for zero copy key. | |||
const vector<void *> virtual_in_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc, false); | |||
const vector<void *> virtual_out_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc, false); | |||
virtual_io_addrs.insert(virtual_io_addrs.end(), virtual_in_addrs.begin(), virtual_in_addrs.end()); | |||
virtual_io_addrs.insert(virtual_io_addrs.end(), virtual_out_addrs.begin(), virtual_out_addrs.end()); | |||
davinci_model->SetZeroCopyAddr(op_desc, virtual_io_addrs, input_output_addr_); | |||
kernel_buf_size_ = sizeof(STR_FWK_OP_KERNEL); | |||
davinci_model_ = davinci_model; | |||
@@ -25,6 +25,7 @@ class KernelExTaskInfo : public TaskInfo { | |||
public: | |||
KernelExTaskInfo() | |||
: task_id_(0), | |||
stream_id_(0), | |||
dump_flag_(RT_KERNEL_DEFAULT), | |||
kernel_buf_size_(0), | |||
davinci_model_(nullptr), | |||
@@ -221,13 +221,13 @@ Status KernelTaskInfo::SuperKernelLaunch() { | |||
return RT_FAILED; | |||
} | |||
// Call the fuse API | |||
skt::SuperKernel *superKernel; | |||
skt::SuperKernel *superKernel = nullptr; | |||
if (factory->FuseKernels(skt_kernel_list, skt_arg_list, skt_info_.last_block_dim, superKernel) != SUCCESS) { | |||
GELOGE(RT_FAILED, "SuperKernelLaunch: fuse call failed"); | |||
return RT_FAILED; | |||
} | |||
// Launch a super kernel | |||
if (superKernel->Launch(skt_info_.last_stream, true) != SUCCESS) { | |||
if (superKernel->Launch(skt_info_.last_stream, RT_KERNEL_DUMPFLAG) != SUCCESS) { | |||
GELOGE(RT_FAILED, "SuperKernelLaunch: launch failed"); | |||
return RT_FAILED; | |||
} | |||
@@ -341,6 +341,7 @@ Status KernelTaskInfo::Distribute() { | |||
rtError_t rt_ret = RT_ERROR_NONE; | |||
char *skt_enable_env = getenv("SKT_ENABLE"); | |||
int64_t env_flag = (skt_enable_env != nullptr) ? strtol(skt_enable_env, nullptr, 10) : 0; | |||
bool call_skt = ((env_flag != 0) || is_l1_fusion_enable_); | |||
if (kernel_type_ == cce::ccKernelType::AI_CPU) { | |||
// blockDim is reserved parameter, set to 1 | |||
rt_ret = rtCpuKernelLaunchWithFlag(reinterpret_cast<const void *>(so_name_.c_str()), | |||
@@ -348,11 +349,10 @@ Status KernelTaskInfo::Distribute() { | |||
nullptr, stream_, dump_flag_); | |||
} else { | |||
/* default: not skt launch */ | |||
bool call_skt = ((env_flag != 0) || is_l1_fusion_enable_); | |||
GELOGI( | |||
"KernelTaskInfo Distribute Start, sktenable:%ld taskid:%u sktid:%u last_sktid:%u stubfunc_name:%s " | |||
"KernelTaskInfo Distribute Start, sktenable:%d taskid:%u sktid:%u last_sktid:%u stubfunc_name:%s " | |||
"stubfunc:%p blockdim:%u stream:%p", | |||
env_flag, task_id_, skt_id_, skt_info_.last_task_id, stub_func_name_.c_str(), stub_func_, block_dim_, stream_); | |||
call_skt, task_id_, skt_id_, skt_info_.last_task_id, stub_func_name_.c_str(), stub_func_, block_dim_, stream_); | |||
// l1 fusion enable and env flag open (kCloseSkt for skt debug) | |||
if (call_skt && (env_flag != kCloseSkt)) { | |||
GE_RETURN_IF_ERROR(SuperKernelDistribute()); | |||
@@ -371,7 +371,7 @@ Status KernelTaskInfo::Distribute() { | |||
GELOGI( | |||
"KernelTaskInfo Distribute Success. sktenable:%d taskid:%d sktid:%d stubfunc_name:%s stubfunc:%p " | |||
"blockdim:%d stream:%p", | |||
env_flag, task_id_, skt_id_, stub_func_name_.c_str(), stub_func_, block_dim_, stream_); | |||
call_skt, task_id_, skt_id_, stub_func_name_.c_str(), stub_func_, block_dim_, stream_); | |||
return SUCCESS; | |||
} | |||
@@ -423,12 +423,12 @@ Status KernelTaskInfo::InitTVMTask(DavinciModel *davinci_model, uint16_t offset, | |||
stub_func_ = const_cast<char *>(bin_file_key); | |||
} | |||
const vector<void *> input_data_addrs = ModelUtils::GetInputDataAddrs(davinci_model->GetRuntimeParam(), op_desc); | |||
const vector<void *> output_data_addrs = ModelUtils::GetOutputDataAddrs(davinci_model->GetRuntimeParam(), op_desc); | |||
const vector<void *> workspace_data_addrs = | |||
ModelUtils::GetWorkspaceDataAddrs(davinci_model->GetRuntimeParam(), op_desc); | |||
vector<void *> tensor_device_addrs; | |||
const RuntimeParam &rts_param = davinci_model->GetRuntimeParam(); | |||
const vector<void *> input_data_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc); | |||
const vector<void *> output_data_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc); | |||
const vector<void *> workspace_data_addrs = ModelUtils::GetWorkspaceDataAddrs(rts_param, op_desc); | |||
vector<void *> tensor_device_addrs; | |||
tensor_device_addrs.insert(tensor_device_addrs.end(), input_data_addrs.begin(), input_data_addrs.end()); | |||
tensor_device_addrs.insert(tensor_device_addrs.end(), output_data_addrs.begin(), output_data_addrs.end()); | |||
tensor_device_addrs.insert(tensor_device_addrs.end(), workspace_data_addrs.begin(), workspace_data_addrs.end()); | |||
@@ -468,7 +468,13 @@ Status KernelTaskInfo::InitTVMTask(DavinciModel *davinci_model, uint16_t offset, | |||
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(args_) + offset + sizeof(void *) * input_data_addrs.size()); | |||
} | |||
davinci_model_->SetZeroCopyAddr(op_desc, tensor_device_addrs, static_cast<char *>(args_) + offset); | |||
vector<void *> virtual_io_addrs; // use virtual address for zero copy key. | |||
const vector<void *> virtual_in_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc, false); | |||
const vector<void *> virtual_out_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc, false); | |||
virtual_io_addrs.insert(virtual_io_addrs.end(), virtual_in_addrs.begin(), virtual_in_addrs.end()); | |||
virtual_io_addrs.insert(virtual_io_addrs.end(), virtual_out_addrs.begin(), virtual_out_addrs.end()); | |||
davinci_model_->SetZeroCopyAddr(op_desc, virtual_io_addrs, static_cast<char *>(args_) + offset); | |||
// update origin l2 data | |||
string sm_desc = kernel_def.sm_desc(); | |||
char *sm_contrl = nullptr; | |||
@@ -516,6 +522,7 @@ Status KernelTaskInfo::InitAICPUCustomTask(const std::map<uint32_t, std::shared_ | |||
} | |||
auto op_desc = iter->second; | |||
const RuntimeParam &rts_param = davinci_model_->GetRuntimeParam(); | |||
const domi::KernelContext &context = kernel_def.context(); | |||
const uint32_t kCustomAicpuArgsLen = 5; | |||
@@ -534,11 +541,8 @@ Status KernelTaskInfo::InitAICPUCustomTask(const std::map<uint32_t, std::shared_ | |||
ctx_.argsOffset[i] = (reinterpret_cast<uint16_t *>(const_cast<char *>(context.args_offset().data())))[i]; | |||
} | |||
const std::vector<void *> input_data_addrs = | |||
ModelUtils::GetInputDataAddrs(davinci_model_->GetRuntimeParam(), op_desc); | |||
const std::vector<void *> output_data_addrs = | |||
ModelUtils::GetOutputDataAddrs(davinci_model_->GetRuntimeParam(), op_desc); | |||
const std::vector<void *> input_data_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc); | |||
const std::vector<void *> output_data_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc); | |||
Status ret = StoreInputOutputTensor(input_data_addrs, output_data_addrs, ModelUtils::GetInputDescs(op_desc), | |||
ModelUtils::GetOutputDescs(op_desc)); | |||
@@ -583,15 +587,15 @@ Status KernelTaskInfo::InitAICPUCustomTask(const std::map<uint32_t, std::shared_ | |||
} | |||
} | |||
*(reinterpret_cast<uint64_t *>(args + ctx_.argsOffset[0])) = | |||
reinterpret_cast<uint64_t>(custom_info_.input_descs); // arg 0 | |||
reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(custom_info_.input_descs)); // arg 0 | |||
*(reinterpret_cast<uint64_t *>(args + ctx_.argsOffset[1])) = | |||
reinterpret_cast<uint64_t>(custom_info_.input_addrs); // arg 1 | |||
reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(custom_info_.input_addrs)); // arg 1 | |||
*(reinterpret_cast<uint64_t *>(args + ctx_.argsOffset[2])) = | |||
reinterpret_cast<uint64_t>(custom_info_.output_descs); // arg 2 | |||
reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(custom_info_.output_descs)); // arg 2 | |||
*(reinterpret_cast<uint64_t *>(args + ctx_.argsOffset[3])) = | |||
reinterpret_cast<uint64_t>(custom_info_.output_addrs); // arg 3 | |||
reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(custom_info_.output_addrs)); // arg 3 | |||
*(reinterpret_cast<uint64_t *>(args + ctx_.argsOffset[4])) = | |||
reinterpret_cast<uint64_t>(custom_info_.attr_handle); // arg 4 | |||
reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(custom_info_.attr_handle)); // arg 4 | |||
rt_ret = rtMalloc(&args_, args_size_, RT_MEMORY_HBM); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
@@ -606,8 +610,10 @@ Status KernelTaskInfo::InitAICPUCustomTask(const std::map<uint32_t, std::shared_ | |||
return RT_FAILED; | |||
} | |||
davinci_model_->SetZeroCopyAddr(op_desc, input_data_addrs, custom_info_.input_addrs); | |||
davinci_model_->SetZeroCopyAddr(op_desc, output_data_addrs, custom_info_.output_addrs); | |||
const vector<void *> virtual_in_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc, false); | |||
const vector<void *> virtual_out_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc, false); | |||
davinci_model_->SetZeroCopyAddr(op_desc, virtual_in_addrs, custom_info_.input_addrs); | |||
davinci_model_->SetZeroCopyAddr(op_desc, virtual_out_addrs, custom_info_.output_addrs); | |||
return SUCCESS; | |||
} | |||
@@ -714,8 +720,10 @@ Status KernelTaskInfo::InitAicpuTask(const std::map<uint32_t, OpDescPtr> &op_lis | |||
} | |||
OpDescPtr op_desc = iter->second; | |||
vector<void *> input_addrs = ModelUtils::GetInputDataAddrs(davinci_model_->GetRuntimeParam(), op_desc); | |||
vector<void *> output_addrs = ModelUtils::GetOutputDataAddrs(davinci_model_->GetRuntimeParam(), op_desc); | |||
const RuntimeParam &rts_param = davinci_model_->GetRuntimeParam(); | |||
vector<void *> input_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc); | |||
vector<void *> output_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc); | |||
vector<void *> io_addrs; | |||
io_addrs.insert(io_addrs.end(), input_addrs.begin(), input_addrs.end()); | |||
io_addrs.insert(io_addrs.end(), output_addrs.begin(), output_addrs.end()); | |||
@@ -752,7 +760,13 @@ Status KernelTaskInfo::InitAicpuTask(const std::map<uint32_t, OpDescPtr> &op_lis | |||
sizeof(void *) * input_addrs.size()); | |||
} | |||
davinci_model_->SetZeroCopyAddr(op_desc, io_addrs, static_cast<char *>(args_) + sizeof(aicpu::AicpuParamHead)); | |||
vector<void *> virtual_io_addrs; // use virtual address for zero copy key. | |||
const vector<void *> virtual_in_addrs = ModelUtils::GetInputDataAddrs(rts_param, op_desc, false); | |||
const vector<void *> virtual_out_addrs = ModelUtils::GetOutputDataAddrs(rts_param, op_desc, false); | |||
virtual_io_addrs.insert(virtual_io_addrs.end(), virtual_in_addrs.begin(), virtual_in_addrs.end()); | |||
virtual_io_addrs.insert(virtual_io_addrs.end(), virtual_out_addrs.begin(), virtual_out_addrs.end()); | |||
davinci_model_->SetZeroCopyAddr(op_desc, virtual_io_addrs, | |||
static_cast<char *>(args_) + sizeof(aicpu::AicpuParamHead)); | |||
return SUCCESS; | |||
} | |||
@@ -977,7 +991,7 @@ Status KernelTaskInfo::SetFlowtable(std::string &flowtable, const domi::KernelDe | |||
*(reinterpret_cast<uint64_t *>( | |||
args + (reinterpret_cast<uint16_t *>(const_cast<char *>(context.args_offset().data())))[0])) = | |||
reinterpret_cast<uint64_t>(flowtable_); | |||
reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(flowtable_)); | |||
} | |||
return SUCCESS; | |||
} | |||
@@ -0,0 +1,149 @@ | |||
/** | |||
* Copyright 2019-2020 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 "graph/load/new_model_manager/task_info/memcpy_addr_async_task_info.h" | |||
#include "framework/common/debug/ge_log.h" | |||
#include "graph/load/new_model_manager/davinci_model.h" | |||
namespace ge { | |||
Status MemcpyAddrAsyncTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *davinci_model) { | |||
GELOGI("MemcpyAddrAsyncTaskInfo Init Start."); | |||
if (davinci_model == nullptr) { | |||
GELOGE(PARAM_INVALID, "davinci_model is null!"); | |||
return PARAM_INVALID; | |||
} | |||
Status ret = SetStream(task_def.stream_id(), davinci_model->GetStreamList()); | |||
if (ret != SUCCESS) { | |||
return ret; | |||
} | |||
auto memcpy_async_def = task_def.memcpy_async(); | |||
uint64_t logic_dst = memcpy_async_def.dst(); | |||
uint64_t logic_src = memcpy_async_def.src(); | |||
dst_max_ = memcpy_async_def.dst_max(); | |||
uint64_t update_base_addr = 0; | |||
ret = GetUpdateBaseAddr(davinci_model, logic_src, update_base_addr); | |||
if (ret != SUCCESS) { | |||
return ret; | |||
} | |||
src_ = reinterpret_cast<uint8_t *>(update_base_addr + logic_src); | |||
if (src_ == nullptr) { | |||
GELOGE(PARAM_INVALID, "src_ is null!"); | |||
return PARAM_INVALID; | |||
} | |||
uint64_t mem_base = reinterpret_cast<uint64_t>(davinci_model->MemBase()); | |||
uint64_t logic_mem_base = davinci_model->GetRtBaseAddr(); | |||
dst_ = reinterpret_cast<uint8_t *>(mem_base + (logic_dst - logic_mem_base)); | |||
if (dst_ == nullptr) { | |||
GELOGE(PARAM_INVALID, "dst_ is null!"); | |||
return PARAM_INVALID; | |||
} | |||
count_ = memcpy_async_def.count(); | |||
kind_ = memcpy_async_def.kind(); | |||
// malloc args memory | |||
size_t args_size = sizeof(void *); | |||
rtError_t rt_ret = rtMalloc(&args_, args_size * 2, RT_MEMORY_HBM); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt api failed, ret: 0x%X", rt_ret); | |||
return RT_FAILED; | |||
} | |||
// copy orign src | |||
GELOGI("src_args:%p, destMax:%zu, src_:%p, count=%zu, kind=%u", args_, args_size, src_, args_size, | |||
RT_MEMCPY_HOST_TO_DEVICE); | |||
rt_ret = rtMemcpy(args_, args_size, &src_, args_size, RT_MEMCPY_HOST_TO_DEVICE); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt api for src failed, ret: 0x%X", rt_ret); | |||
return RT_FAILED; | |||
} | |||
// copy orign dst | |||
GELOGI("dst_args:%p, destMax:%zu, dst_:%p, count=%zu, kind=%u", | |||
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(args_) + args_size), args_size, dst_, args_size, | |||
RT_MEMCPY_HOST_TO_DEVICE); | |||
rt_ret = rtMemcpy(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(args_) + args_size), args_size, &dst_, | |||
args_size, RT_MEMCPY_HOST_TO_DEVICE); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt api for dst failed, ret: 0x%X", rt_ret); | |||
return RT_FAILED; | |||
} | |||
GELOGI("InitMemcpyAddrAsyncTaskInfo, logic_src:%p, logic_dst:%p, src:%p, dst:%p, src_args:%p, dst_args:%p", | |||
reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(logic_src)), | |||
reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(logic_dst)), src_, dst_, args_, | |||
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(args_) + args_size)); | |||
return SUCCESS; | |||
} | |||
Status MemcpyAddrAsyncTaskInfo::Distribute() { | |||
GELOGI("MemcpyAddrAsyncTaskInfo Distribute Start."); | |||
GELOGI("Distribute MemcpyAddrAsync, dst_max:%lu, count:%lu, kind:%u.", dst_max_, count_, kind_); | |||
rtError_t rt_ret = rtMemcpyAsync(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(args_) + sizeof(void *)), | |||
dst_max_, args_, count_, static_cast<rtMemcpyKind_t>(kind_), stream_); | |||
if (rt_ret != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt api failed, ret: 0x%X", rt_ret); | |||
return RT_FAILED; | |||
} | |||
return SUCCESS; | |||
} | |||
Status MemcpyAddrAsyncTaskInfo::GetUpdateBaseAddr(DavinciModel *davinci_model, uint64_t update_addr, | |||
uint64_t &base_addr) { | |||
GE_CHECK_NOTNULL(davinci_model); | |||
uint64_t data_base_addr = | |||
reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(davinci_model->MemBase())) - davinci_model->GetRtBaseAddr(); | |||
uint64_t weight_base_addr = reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(davinci_model->WeightsMemBase())) - | |||
davinci_model->GetRtWeightAddr(); | |||
uint64_t var_base_addr = reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(davinci_model->VarMemBase())) - | |||
davinci_model->GetRtVarAddr(); | |||
uint64_t data_base_addr_start = davinci_model->GetRtBaseAddr(); | |||
uint64_t data_base_addr_end = davinci_model->GetRtBaseAddr() + davinci_model->TotalMemSize(); | |||
uint64_t wight_base_addr_start = davinci_model->GetRtWeightAddr(); | |||
uint64_t wight_base_addr_end = davinci_model->GetRtWeightAddr() + davinci_model->TotalWeightsMemSize(); | |||
uint64_t varible_base_addr_start = davinci_model->GetRtVarAddr(); | |||
uint64_t varible_base_addr_end = davinci_model->GetRtVarAddr() + davinci_model->TotalVarMemSize(); | |||
if ((data_base_addr_start <= update_addr) && (update_addr <= data_base_addr_end)) { | |||
base_addr = data_base_addr; | |||
GELOGI("The update_addr is data address."); | |||
} else if ((wight_base_addr_start <= update_addr) && (update_addr <= wight_base_addr_end)) { | |||
base_addr = weight_base_addr; | |||
GELOGI("The update_addr is weight address."); | |||
} else if ((varible_base_addr_start <= update_addr) && (update_addr <= varible_base_addr_end)) { | |||
base_addr = var_base_addr; | |||
GELOGI("The update_addr is variable address."); | |||
} else if (update_addr != 0) { | |||
base_addr = 0; | |||
GELOGE(PARAM_INVALID, "The update_addr is abnormal."); | |||
return PARAM_INVALID; | |||
} | |||
return SUCCESS; | |||
} | |||
REGISTER_TASK_INFO(RT_MODEL_TASK_MEMCPY_ADDR_ASYNC, MemcpyAddrAsyncTaskInfo); | |||
} // namespace ge |
@@ -0,0 +1,55 @@ | |||
/** | |||
* Copyright 2019-2020 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 GE_GRAPH_LOAD_NEW_MODEL_MANAGER_TASK_INFO_MEMCPY_ADDR_ASYNC_TASK_INFO_H_ | |||
#define GE_GRAPH_LOAD_NEW_MODEL_MANAGER_TASK_INFO_MEMCPY_ADDR_ASYNC_TASK_INFO_H_ | |||
#include "graph/load/new_model_manager/task_info/task_info.h" | |||
namespace ge { | |||
class MemcpyAddrAsyncTaskInfo : public TaskInfo { | |||
public: | |||
MemcpyAddrAsyncTaskInfo() : dst_(nullptr), dst_max_(0), src_(nullptr), args_(nullptr), count_(0), kind_(0) {} | |||
~MemcpyAddrAsyncTaskInfo() override { | |||
src_ = nullptr; | |||
dst_ = nullptr; | |||
if (args_ != nullptr) { | |||
rtError_t ret = rtFree(args_); | |||
if (ret != RT_ERROR_NONE) { | |||
GELOGE(RT_FAILED, "Call rt api failed, ret: 0x%X", ret); | |||
} | |||
} | |||
args_ = nullptr; | |||
} | |||
Status Init(const domi::TaskDef &task_def, DavinciModel *davinci_model) override; | |||
Status Distribute() override; | |||
private: | |||
Status GetUpdateBaseAddr(DavinciModel *davinci_model, uint64_t update_addr, uint64_t &base_addr); | |||
void *dst_; | |||
uint64_t dst_max_; | |||
void *src_; | |||
void *args_; | |||
uint64_t count_; | |||
uint32_t kind_; | |||
}; | |||
} // namespace ge | |||
#endif // GE_GRAPH_LOAD_NEW_MODEL_MANAGER_TASK_INFO_MEMCPY_ADDR_ASYNC_TASK_INFO_H_ |
@@ -51,6 +51,9 @@ Status MemcpyAsyncTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *da | |||
count_ = memcpy_async_def.count(); | |||
kind_ = memcpy_async_def.kind(); | |||
GELOGI("MemcpyAsyncTaskInfo Init Success, logic_src:%p, logic_dst:%p, src:%p, dst:%p", | |||
reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(logic_src)), | |||
reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(logic_dst)), src_, dst_); | |||
return SUCCESS; | |||
} | |||
@@ -63,6 +63,8 @@ Status StreamActiveTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *d | |||
active_stream_ = davinci_model->GetStreamList()[active_stream_index_list[internal_index]]; | |||
active_stream_id_ = stream_active_def.active_stream_id(); | |||
GELOGI("InitStreamActiveTaskInfo Init Success, index:%u, activeStream:%p, activeStreamID:%u.", internal_index, | |||
active_stream_, active_stream_id_); | |||
return SUCCESS; | |||
} | |||
@@ -74,6 +76,8 @@ Status StreamActiveTaskInfo::Distribute() { | |||
GELOGE(RT_FAILED, "Call rt api failed, ret: 0x%X", rt_ret); | |||
return RT_FAILED; | |||
} | |||
GELOGI("StreamActiveTaskInfo Distribute Success. activeStreamID:%p.", active_stream_); | |||
return SUCCESS; | |||
} | |||
@@ -95,6 +95,10 @@ Status StreamSwitchTaskInfo::Init(const domi::TaskDef &task_def, DavinciModel *d | |||
} | |||
data_type_ = static_cast<rtSwitchDataType_t>(data_type); | |||
} | |||
GELOGI("InitStreamSwitchTaskInfo Init Success, cond:%d, trueStream:%p, trueStreamID:%u, datatype:%d.", cond_, | |||
true_stream_, true_stream_id_, data_type_); | |||
return SUCCESS; | |||
} | |||
@@ -105,6 +109,8 @@ Status StreamSwitchTaskInfo::Distribute() { | |||
GELOGE(RT_FAILED, "Call rt api failed, ret: 0x%X", rt_ret); | |||
return RT_FAILED; | |||
} | |||
GELOGI("StreamSwitchTaskInfo Distribute Success. cond:%d, stream:%p, datatype:%d.", cond_, true_stream_, data_type_); | |||
return SUCCESS; | |||
} | |||
@@ -19,17 +19,17 @@ | |||
namespace ge { | |||
namespace skt { | |||
Status SuperKernel::Launch(rtStream_t stream, bool dump_flag) { | |||
Status SuperKernel::Launch(rtStream_t stream, uint32_t dump_flag) { | |||
const void *func_stub_ = this->GetFuncStub(); | |||
const void *args[] = {this->GetNavTablePtr(), (const void *)this->GetNavTableSize()}; | |||
const void *args[] = {this->GetNavTablePtr(), | |||
reinterpret_cast<const void *>(reinterpret_cast<uintptr_t>(this->GetNavTableSize()))}; | |||
void *device_args_addr = nullptr; | |||
rtError_t rt_ret = rtMalloc((void **)&(device_args_addr), sizeof(args), RT_MEMORY_HBM); | |||
rtError_t rt_ret = rtMalloc((void **)&(device_args_addr_), sizeof(args), RT_MEMORY_HBM); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMalloc failied. error: 0x%X", rt_ret); return FAILED;) | |||
rt_ret = rtMemcpy((void *)device_args_addr, sizeof(args), (void *)args, sizeof(args), RT_MEMCPY_HOST_TO_DEVICE); | |||
rt_ret = rtMemcpy((void *)device_args_addr_, sizeof(args), (void *)args, sizeof(args), RT_MEMCPY_HOST_TO_DEVICE); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMemcpy failied. error: 0x%X", rt_ret); return FAILED;) | |||
rt_ret = rtKernelLaunchWithFlag((void *const)func_stub_, block_dim_, device_args_addr, sizeof(args), NULL, stream, | |||
rt_ret = rtKernelLaunchWithFlag((void *const)func_stub_, block_dim_, device_args_addr_, sizeof(args), NULL, stream, | |||
dump_flag); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelLaunchWithFlag failied. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
@@ -25,6 +25,7 @@ namespace ge { | |||
namespace skt { | |||
class SuperKernel { | |||
private: | |||
void *device_args_addr_ = nullptr; | |||
const void *func_stub_; | |||
void *dev_nav_table_; | |||
uint64_t nav_table_size_; | |||
@@ -33,8 +34,18 @@ class SuperKernel { | |||
public: | |||
SuperKernel(const void *stub, void *ptr, uint64_t sz, uint32_t dim) | |||
: func_stub_(stub), dev_nav_table_(ptr), nav_table_size_(sz), block_dim_(dim) {} | |||
~SuperKernel() {} | |||
Status Launch(rtStream_t stream, bool dump_flag); | |||
~SuperKernel() { | |||
// free memory when all releasing | |||
if (device_args_addr_ != nullptr) { | |||
GE_CHK_RT(rtFree(device_args_addr_)); | |||
GELOGI("SKT: super_kernel args addr free."); | |||
} | |||
if (dev_nav_table_ != nullptr) { | |||
GE_CHK_RT(rtFree(dev_nav_table_)); | |||
GELOGI("SKT: super_kernel args addr free."); | |||
} | |||
} | |||
Status Launch(rtStream_t stream, uint32_t dump_flag); | |||
const void *GetFuncStub() const { return func_stub_; } | |||
const void *GetNavTablePtr() const { return dev_nav_table_; } | |||
uint64_t GetNavTableSize() const { return nav_table_size_; } | |||
@@ -30,26 +30,26 @@ Status SuperKernelFactory::Init() { | |||
rt_ret = rtGetFunctionByName(this->sk_stub_name_.c_str(), &this->func_stub_); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, | |||
"rtGetFunctionByName " | |||
"failied. stub_func: %s", | |||
"failed. stub_func: %s", | |||
this->sk_stub_name_.c_str()); | |||
return FAILED;) | |||
rt_ret = rtGetAddrByFun(this->func_stub_, &this->func_ptr_); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtGetAddrByFun failied. error: 0x%X", rt_ret); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtGetAddrByFun failed. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
if (this->use_physical_address_ != nullptr) { | |||
void *skt_func = nullptr; | |||
rt_ret = rtKernelConfigTransArg(this->func_ptr_, sizeof(uint64_t), 0, &skt_func); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failied. error: 0x%X", rt_ret); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failed. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
GELOGD( | |||
"SKT: fuseKernels super_kernel_template subFunc %p, device func " | |||
"address %p, device physic PC %p", | |||
(uint64_t)this->func_stub_, (uint64_t)this->func_ptr_, (uint64_t)skt_func); | |||
this->func_stub_, this->func_ptr_, skt_func); | |||
} else { | |||
GELOGD( | |||
"SKT: fuseKernels super_kernel_template subFunc %p, device func " | |||
"address %p", | |||
(uint64_t)this->func_stub_, (uint64_t)this->func_ptr_); | |||
this->func_stub_, this->func_ptr_); | |||
} | |||
} | |||
is_init_ = true; | |||
@@ -94,63 +94,66 @@ Status SuperKernelFactory::FuseKernels(const std::vector<void *> &stub_func_list | |||
uint64_t nav_table_size = 2 * stub_func_list.size() * sizeof(int64_t); | |||
rtError_t rt_ret; | |||
void *hbm_nav_table_addr = nullptr; | |||
if (this->use_physical_address_ != nullptr) { | |||
for (unsigned i = 0; i < stub_func_list.size(); i++) { | |||
void *sub_device_func = nullptr; | |||
rt_ret = rtGetAddrByFun(stub_func_list[i], &sub_device_func); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtGetAddrByFun failied. error: 0x%X", rt_ret); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtGetAddrByFun failed. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
void *sub_device_func_pys = nullptr; | |||
void *args_addr_pys = nullptr; | |||
rt_ret = rtKernelConfigTransArg(sub_device_func, sizeof(uint64_t), 0, &sub_device_func_pys); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failied. error: 0x%X", rt_ret); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failed. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
rt_ret = rtKernelConfigTransArg(args_addr_list[i], sizeof(uint64_t), 0, &args_addr_pys); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failied. error: 0x%X", rt_ret); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failed. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
GELOGD( | |||
"SKT: fuseKernels subFunc %p, device func address %p, device " | |||
"physic func address %p", | |||
stub_func_list[i], (uint64_t)sub_device_func, (uint64_t)sub_device_func_pys); | |||
nav_table[i * 2] = (uint64_t)sub_device_func_pys / 4; | |||
GELOGD("SKT: CALL offet %p", nav_table[i * 2]); | |||
nav_table[i * 2 + 1] = (uint64_t)args_addr_pys; | |||
stub_func_list[i], sub_device_func, sub_device_func_pys); | |||
// store two uint64_t address | |||
// address divided by 4 because of 32bits encoding, call offset will *4 when calculating | |||
nav_table[i * 2] = reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(sub_device_func_pys)) / 4; | |||
GELOGD("SKT: CALL offset %p", nav_table[i * 2]); | |||
nav_table[i * 2 + 1] = reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(args_addr_pys)); | |||
GELOGD("SKT: fuseKernels args base address %p", nav_table[i * 2 + 1]); | |||
} | |||
void *hbm_nav_table_addr = nullptr; | |||
void *hbm_nav_table_addr_pys = nullptr; | |||
rt_ret = rtMalloc((void **)&hbm_nav_table_addr, nav_table_size, RT_MEMORY_HBM); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMalloc failied. error: 0x%X", rt_ret); return FAILED;) | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMalloc failed. error: 0x%X", rt_ret); return FAILED;) | |||
rt_ret = | |||
rtMemcpy((void *)hbm_nav_table_addr, nav_table_size, (void *)nav_table, nav_table_size, RT_MEMCPY_HOST_TO_DEVICE); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMemcpy failied. error: 0x%X", rt_ret); return FAILED;) | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMemcpy failed. error: 0x%X", rt_ret); return FAILED;) | |||
rt_ret = rtKernelConfigTransArg(hbm_nav_table_addr, sizeof(uint64_t), 0, &hbm_nav_table_addr_pys); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failied. error: 0x%X", rt_ret); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtKernelConfigTransArg failed. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
GELOGD("SKT: hbm_nav_table_addr %p, hbm_nav_table_addr_pys %p", (uint64_t)hbm_nav_table_addr, | |||
(uint64_t)hbm_nav_table_addr_pys); | |||
GELOGD("SKT: hbm_nav_table_addr %p, hbm_nav_table_addr_pys %p", hbm_nav_table_addr, hbm_nav_table_addr_pys); | |||
// Create the necessary metadata for the super kernel | |||
h = new SuperKernel(this->func_stub_, hbm_nav_table_addr_pys, nav_table_size, block_dim); | |||
} else { | |||
for (unsigned i = 0; i < stub_func_list.size(); i++) { | |||
void *sub_device_func = nullptr; | |||
rt_ret = rtGetAddrByFun(stub_func_list[i], &sub_device_func); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtGetAddrByFun failied. error: 0x%X", rt_ret); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtGetAddrByFun failed. error: 0x%X", rt_ret); | |||
return FAILED;) | |||
GELOGD("SKT: fuseKernels subFunc %p, device func address %p", stub_func_list[i], (uint64_t)sub_device_func); | |||
nav_table[i * 2] = (uint64_t)sub_device_func / 4; | |||
GELOGD("SKT: fuseKernels subFunc %p, device func address %p", stub_func_list[i], sub_device_func); | |||
// store two uint64_t address | |||
// address divided by 4 because of 32bits encoding, call offset will *4 when calculating | |||
nav_table[i * 2] = reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(sub_device_func)) / 4; | |||
GELOGD("SKT: CALL offet %p", nav_table[i * 2]); | |||
nav_table[i * 2 + 1] = (uint64_t)args_addr_list[i]; | |||
nav_table[i * 2 + 1] = reinterpret_cast<uint64_t>(reinterpret_cast<uintptr_t>(args_addr_list[i])); | |||
GELOGD("SKT: fuseKernels args base address %p", nav_table[i * 2 + 1]); | |||
} | |||
void *hbm_nav_table_addr = nullptr; | |||
rt_ret = rtMalloc((void **)&hbm_nav_table_addr, nav_table_size, RT_MEMORY_HBM); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMalloc failied. error: 0x%X", rt_ret); return FAILED;) | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMalloc failed. error: 0x%X", rt_ret); return FAILED;) | |||
rt_ret = | |||
rtMemcpy((void *)hbm_nav_table_addr, nav_table_size, (void *)nav_table, nav_table_size, RT_MEMCPY_HOST_TO_DEVICE); | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMemcpy failied. error: 0x%X", rt_ret); return FAILED;) | |||
GE_IF_BOOL_EXEC(rt_ret != RT_ERROR_NONE, GELOGE(rt_ret, "rtMemcpy failed. error: 0x%X", rt_ret); return FAILED;) | |||
// Create the necessary metadata for the super kernel | |||
h = new SuperKernel(this->func_stub_, hbm_nav_table_addr, nav_table_size, block_dim); | |||
} | |||
@@ -31,12 +31,12 @@ class SuperKernelFactory { | |||
const char *use_physical_address_ = getenv("GE_USE_PHYSICAL_ADDRESS"); | |||
bool is_init_ = false; | |||
SuperKernelFactory(){}; | |||
~SuperKernelFactory(){}; | |||
public: | |||
SuperKernelFactory(SuperKernelFactory const &) = delete; | |||
void operator=(SuperKernelFactory const &) = delete; | |||
static SuperKernelFactory &GetInstance(); | |||
SuperKernelFactory(const std::string &sk_stub_name_, const std::string &bin_file); | |||
Status Init(); | |||
Status Uninitialize(); | |||
Status FuseKernels(const std::vector<void *> &stub_func_list, const std::vector<void *> &args_addr_list, | |||
@@ -33,6 +33,7 @@ | |||
#include "framework/common/debug/ge_log.h" | |||
#include "framework/common/ge_inner_error_codes.h" | |||
#include "framework/common/ge_types.h" | |||
#include "graph/manager/util/rt_context_util.h" | |||
#include "graph/common/transop_util.h" | |||
#include "graph/debug/ge_attr_define.h" | |||
#include "graph/ge_context.h" | |||
@@ -117,6 +118,7 @@ Status GraphManager::Initialize(const std::map<string, string> &options) { | |||
} | |||
graph_map_.clear(); | |||
cache_helper_map_.clear(); | |||
init_flag_ = true; | |||
thread_run_flag_ = true; | |||
@@ -180,6 +182,7 @@ Status GraphManager::Finalize() { | |||
} | |||
} | |||
graph_map_.clear(); | |||
cache_helper_map_.clear(); | |||
// graph context | |||
if (graph_context_ != nullptr) { | |||
@@ -426,6 +429,13 @@ Status GraphManager::PreRun(const GraphNodePtr &graph_node, const std::vector<Ge | |||
sub_graph_list[0]->SetSubGraph(merged_compute_graph); | |||
// set subgraphlist to graphnode | |||
graph_node->SetSubGraph(sub_graph_list); | |||
// when set incre build, save om model and var manager | |||
auto save_ret = SaveCacheAfterBuild(graph_node->GetGraphId(), merged_compute_graph, ge_model); | |||
if (save_ret != SUCCESS) { | |||
GELOGW("Fail to save cache."); | |||
} | |||
// release rts generate context | |||
RtContextUtil::GetInstance().DestroyrtContexts(); | |||
GE_TIMESTAMP_END(PreRun, "GraphManager::PreRun"); | |||
GEEVENT("[GEPERFTRACE] GE PreRun End"); | |||
return ret; | |||
@@ -444,10 +454,14 @@ Status GraphManager::StartForRunGraph(const GraphNodePtr &graph_node, const std: | |||
return PARAM_INVALID; | |||
} | |||
GeModelPtr ge_model = nullptr; | |||
ret = PreRun(graph_node, inputs, ge_models, ge_model, session_id); | |||
// check need incre build. | |||
ret = IncreBuild(graph_node, ge_model); | |||
if (ret != SUCCESS) { | |||
GELOGE(ret, "PreRun Failed."); | |||
return ret; | |||
ret = PreRun(graph_node, inputs, ge_models, ge_model, session_id); | |||
if (ret != SUCCESS) { | |||
GELOGE(ret, "PreRun Failed."); | |||
return ret; | |||
} | |||
} | |||
ret = LoadGraph(ge_model, graph_node); | |||
if (ret != SUCCESS) { | |||
@@ -492,6 +506,90 @@ Status GraphManager::LoadGraph(const GeModelPtr &ge_model, const GraphNodePtr &g | |||
return SUCCESS; | |||
} | |||
Status GraphManager::LoadFromCache(const GraphNodePtr &graph_node, const ModelCacheHelperPtr &cache_helper, | |||
GeModelPtr &ge_model) { | |||
auto graph_id = graph_node->GetGraphId(); | |||
auto ret = cache_helper->LoadOmModelFromCache(ge_model); | |||
if (ret != SUCCESS) { | |||
GELOGW("Fail to load om model from cache."); | |||
if (cache_helper->ClearCache(graph_id) != SUCCESS) { | |||
GELOGW("Fail to clear cache of graph %u.", graph_id); | |||
} | |||
return FAILED; | |||
} | |||
ret = cache_helper->RecoverVarManagerFromCache(); | |||
if (ret != SUCCESS) { | |||
GELOGW("Fail to recover VarManager from cache."); | |||
if (cache_helper->ClearCache(graph_id) != SUCCESS) { | |||
GELOGW("Fail to clear cache of graph %u.", graph_id); | |||
} | |||
return FAILED; | |||
} | |||
ComputeGraphPtr compute_graph_in_model = GraphUtils::GetComputeGraph(ge_model->GetGraph()); | |||
if (compute_graph_in_model == nullptr) { | |||
GELOGW("Error occurred when get compute graph from om, abandon."); | |||
return FAILED; | |||
} else { | |||
graph_node->SetComputeGraph(compute_graph_in_model); | |||
graph_node->SetGeModel(ge_model); | |||
GELOGI("Load model and graph form cache om file."); | |||
} | |||
return SUCCESS; | |||
} | |||
Status GraphManager::SaveCacheBeforeBuild(uint32_t graph_id, const ModelCacheHelperPtr &cache_helper) { | |||
auto ret = cache_helper->SaveCacheInfoToCache(); | |||
if (ret != SUCCESS) { | |||
GELOGW("Fail to save cache info of graph[%d] to cache.", graph_id); | |||
return FAILED; | |||
} | |||
ret = cache_helper->SaveVarManagerToCache(true); | |||
if (ret != SUCCESS) { | |||
GELOGW("Fail to save var manager to cache."); | |||
cache_helper->ClearCache(graph_id); | |||
return FAILED; | |||
} | |||
GELOGI("Cache files have been saved."); | |||
return SUCCESS; | |||
} | |||
Status GraphManager::SaveCacheAfterBuild(uint32_t graph_id, ge::ComputeGraphPtr graph, GeModelPtr &ge_model) { | |||
std::shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance(); | |||
if ((instance_ptr == nullptr) || !instance_ptr->InitFlag()) { | |||
GELOGW("GELib not initialized."); | |||
return FAILED; | |||
} | |||
if (instance_ptr->IsIncreBuild()) { | |||
auto iter = cache_helper_map_.find(graph_id); | |||
if (iter == cache_helper_map_.end()) { | |||
GELOGW("Can not find ModelCacheHelper of graph[%u]", graph_id); | |||
return FAILED; | |||
} else { | |||
ModelCacheHelperPtr cache_helper = iter->second; | |||
auto ret = cache_helper->RefreshComputeGraph(graph); | |||
if (ret != SUCCESS) { | |||
cache_helper->ClearCache(graph_id); | |||
GELOGW("Fail to refresh cache helper's compute graph"); | |||
return FAILED; | |||
} | |||
ret = cache_helper->SaveVarManagerToCache(false); | |||
if (ret != SUCCESS) { | |||
cache_helper->ClearCache(graph_id); | |||
GELOGW("Fail to save VarManager to cache"); | |||
return FAILED; | |||
} | |||
ret = cache_helper->SaveOmModelToCache(ge_model); | |||
if (ret != SUCCESS) { | |||
cache_helper->ClearCache(graph_id); | |||
GELOGW("Fail to save om model to cache"); | |||
return FAILED; | |||
} | |||
} | |||
} | |||
return SUCCESS; | |||
} | |||
Status GraphManager::InnerRunGraph(GraphNodePtr &graph_node, const GraphId &graph_id, | |||
const std::vector<GeTensor> &inputs, std::vector<GeTensor> &outputs) { | |||
Status ret = graph_executor_.SetCondition(&sync_run_mutex_, &condition_, graph_run_listener_); | |||
@@ -551,6 +649,9 @@ Status GraphManager::RunGraph(const GraphId &graph_id, const std::vector<GeTenso | |||
GELOGE(GE_GRAPH_GRAPH_NODE_NULL, "[RunGraph] compute_graph_tmp is NULL, graph id = %u.", graph_id); | |||
return GE_GRAPH_GRAPH_NODE_NULL;)) | |||
// when set incre build, add cache helper map | |||
AddModelCacheHelperToMap(graph_id, session_id, compute_graph_tmp); | |||
std::vector<GeModelPtr> ge_models; | |||
if (options_.local_fmk_op_flag) { | |||
@@ -583,7 +684,7 @@ Status GraphManager::RunGraph(const GraphId &graph_id, const std::vector<GeTenso | |||
if (!all_sub_graph.empty()) { | |||
auto checkPointGraph = all_sub_graph[0]->GetSubGraph(); | |||
if (IsCheckpointGraph(checkPointGraph)) { | |||
ret = CheckpointHandle(graph_id, outputs); | |||
ret = CheckpointHandle(graph_id, checkPointGraph, outputs); | |||
if (ret != SUCCESS) { | |||
GELOGE(ret, "[RunGraph] CheckpointHandle failed!"); | |||
} | |||
@@ -667,6 +768,15 @@ Status GraphManager::SaveParams(ge::GeModel &model, const std::string &type, con | |||
return SUCCESS; | |||
} | |||
void GraphManager::RemoveModelCacheHelper(const GraphId &graph_id) { | |||
auto iter = cache_helper_map_.find(graph_id); | |||
if (iter != cache_helper_map_.end()) { | |||
cache_helper_map_.erase(iter); | |||
} else { | |||
GELOGW("[GraphManager] cache helper does not exist, graph_id = %u", graph_id); | |||
} | |||
} | |||
Status GraphManager::RemoveGraph(const GraphId &graph_id) { | |||
auto it = graph_map_.find(graph_id); | |||
if (it == graph_map_.end()) { | |||
@@ -716,6 +826,9 @@ Status GraphManager::RemoveGraph(const GraphId &graph_id) { | |||
} | |||
var_acc_ctrl_.RemoveGraph(graph_id); | |||
graph_map_.erase(it); | |||
RemoveModelCacheHelper(graph_id); | |||
auto ge_model = graph_node->GetGeModel(); | |||
if (ge_model != nullptr) { | |||
GELOGI("Unload model %u.", ge_model->GetModelId()); | |||
@@ -1106,21 +1219,15 @@ Status GraphManager::SummaryHandle(const GraphId &graph_id, std::vector<GeTensor | |||
return SUCCESS; | |||
} | |||
Status GraphManager::CheckpointHandle(const GraphId &graph_id, const std::vector<GeTensor> &outputs) { | |||
Status GraphManager::CheckpointHandle(const GraphId &graph_id, const ComputeGraphPtr &compute_graph, | |||
const std::vector<GeTensor> &outputs) { | |||
GELOGI("[GraphManager] CheckpointHandle, outputsSize=%zu.", outputs.size()); | |||
std::vector<InputOutputDescInfo> outputs_desc = graph_executor_.GetOutputsDesc(); | |||
GELOGI("[GraphManager] CheckpointHandle, outputsDescSize=%zu.", outputs_desc.size()); | |||
// find graph | |||
GraphNodePtr graph_node = nullptr; | |||
Status ret = GetGraphNode(graph_id, graph_node); | |||
if (ret != SUCCESS) { | |||
GELOGE(ret, "[CheckpointHandle] graph not exist, graph_id = %u.", graph_id); | |||
return ret; | |||
} | |||
ComputeGraphPtr compute_graph_ptr = GraphUtils::GetComputeGraph(*(graph_node->GetGraph())); | |||
std::map<string, Tensor> save_results; | |||
NodePtr netoutput = nullptr; | |||
for (const auto &node : compute_graph_ptr->GetDirectNode()) { | |||
for (const auto &node : compute_graph->GetDirectNode()) { | |||
if (node->GetType() == kNetOutput) { | |||
netoutput = node; | |||
break; | |||
@@ -1248,6 +1355,8 @@ bool GraphManager::CheckTransOpForCheckpointGraph(NodePtr &node) { | |||
return true; | |||
} | |||
static inline bool CheckConstanOpForCheckpointGraph(NodePtr &node) { return node->GetOutDataNodes().empty(); } | |||
bool GraphManager::IsCheckpointGraph(ComputeGraphPtr &compute_graph) { | |||
if (compute_graph == nullptr) { | |||
GELOGE(GE_GRAPH_PARAM_NULLPTR, "[IsCheckpointGraph] computeGraph is nullptr."); | |||
@@ -1268,6 +1377,10 @@ bool GraphManager::IsCheckpointGraph(ComputeGraphPtr &compute_graph) { | |||
if (!CheckTransOpForCheckpointGraph(node)) { | |||
return false; | |||
} | |||
} else if (op->GetType() == CONSTANTOP) { | |||
if (!CheckConstanOpForCheckpointGraph(node)) { | |||
return false; | |||
} | |||
} else if (op->GetType() != kSend && op->GetType() != kRecv) { | |||
GELOGI("this node is not allow in checkpoint sub graph, node_type: %s, node_name: %s.", op->GetType().c_str(), | |||
op->GetName().c_str()); | |||
@@ -1439,8 +1552,6 @@ Status GraphManager::OptimizeAfterMergeSubGraph(ge::ComputeGraphPtr &compute_gra | |||
names_to_passes.emplace_back("ReshapeRemovePass", &trans_op_nearby_allreduce_fusion_pass); | |||
ReshapeRemovePass reshape_remove_pass; | |||
names_to_passes.emplace_back("ReshapeRemovePass", &reshape_remove_pass); | |||
ReplaceWithEmptyConstPass replace_with_empty_const_pass; | |||
names_to_passes.emplace_back("ReplaceWithEmptyConstPass", &replace_with_empty_const_pass); | |||
ConstantFoldingPass constant_folding_pass; | |||
names_to_passes.emplace_back("ConstantFoldingPass", &constant_folding_pass); | |||
DimensionAdjustPass dimension_adjust_pass; | |||
@@ -1632,6 +1743,51 @@ Status GraphManager::RunGraphAsync(const GraphId &graph_id, const std::vector<ge | |||
return SUCCESS; | |||
} | |||
void GraphManager::AddModelCacheHelperToMap(const GraphId &graph_id, uint64_t session_id, | |||
ComputeGraphPtr &compute_graph) { | |||
std::shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance(); | |||
if (instance_ptr != nullptr && instance_ptr->IsIncreBuild()) { | |||
auto iter = cache_helper_map_.find(graph_id); | |||
if (iter == cache_helper_map_.end()) { | |||
ModelCacheHelperPtr cache_helper = MakeShared<ge::ModelCacheHelper>(session_id, graph_id, compute_graph); | |||
if (cache_helper != nullptr) { | |||
cache_helper_map_.emplace(std::make_pair(graph_id, cache_helper)); | |||
} else { | |||
GELOGW("Cache helper make shared failed, graph_id = %u.", graph_id); | |||
} | |||
} | |||
} | |||
} | |||
Status GraphManager::IncreBuild(const GraphNodePtr &graph_node, GeModelPtr &ge_model) { | |||
std::shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance(); | |||
if (instance_ptr == nullptr || !instance_ptr->IsIncreBuild()) { | |||
return FAILED; | |||
} | |||
const uint32_t graph_id = graph_node->GetGraphId(); | |||
auto iter = cache_helper_map_.find(graph_id); | |||
if (iter == cache_helper_map_.end()) { | |||
GELOGW("Can not find ModelCacheHelper of graph[%u]", graph_id); | |||
return FAILED; | |||
} | |||
ModelCacheHelperPtr cache_helper = iter->second; | |||
if (cache_helper->IsModelCacheHit()) { | |||
GEEVENT("Model cache hit."); | |||
Status ret = LoadFromCache(graph_node, cache_helper, ge_model); | |||
if (ret == SUCCESS) { | |||
return SUCCESS; | |||
} else { | |||
GELOGW("Error occurred when load from cache, abandon."); | |||
} | |||
} else { | |||
GEEVENT("Model cache miss."); | |||
} | |||
if (SaveCacheBeforeBuild(graph_node->GetGraphId(), cache_helper) != SUCCESS) { | |||
GELOGW("Error occurred when save cache."); | |||
} | |||
return FAILED; | |||
} | |||
void GraphManager::PreRunThread(GraphManager *graph_manager) { | |||
if (prctl(PR_SET_NAME, ("GE_PreRun")) != 0) { | |||
GELOGW("Set thread name failed."); | |||
@@ -1685,6 +1841,8 @@ void GraphManager::PreRunThread(GraphManager *graph_manager) { | |||
return; | |||
} | |||
} | |||
// when set incre build, save cache helper. | |||
graph_manager->AddModelCacheHelperToMap(args.graph_id, args.session_id, compute_graph_tmp); | |||
std::vector<GeModelPtr> ge_models; | |||
@@ -1707,12 +1865,15 @@ void GraphManager::PreRunThread(GraphManager *graph_manager) { | |||
return; | |||
} | |||
ret = graph_manager->PreRun(graph_node, ge_inputs, ge_models, ge_model, args.session_id); | |||
if (ret != SUCCESS) { | |||
graph_node->SetRunFlag(false); | |||
ReturnError(graph_manager, args.callback, ret, "PreRun failed, thread exit."); | |||
graph_node->Unlock(); | |||
return; | |||
// check need incre build. | |||
if (graph_manager->IncreBuild(graph_node, ge_model) != SUCCESS) { | |||
ret = graph_manager->PreRun(graph_node, ge_inputs, ge_models, ge_model, args.session_id); | |||
if (ret != SUCCESS) { | |||
graph_node->SetRunFlag(false); | |||
ReturnError(graph_manager, args.callback, ret, "PreRun Failed, thread exit.."); | |||
graph_node->Unlock(); | |||
return; | |||
} | |||
} | |||
graph_node->SetBuildFlag(true); | |||
graph_manager->var_acc_ctrl_.SetGraphBuildEnd(graph_node->GetGraphId()); | |||
@@ -27,6 +27,7 @@ | |||
#include "common/blocking_queue.h" | |||
#include "common/ge_inner_error_codes.h" | |||
#include "common/helper/model_cache_helper.h" | |||
#include "external/graph/types.h" | |||
#include "ge/ge_api_types.h" | |||
#include "graph/build/graph_builder.h" | |||
@@ -211,7 +212,8 @@ class GraphManager { | |||
Status SummaryHandle(const GraphId &graph_id, std::vector<GeTensor> &outputs); | |||
Status CheckpointHandle(const GraphId &graph_id, const std::vector<GeTensor> &outputs); | |||
Status CheckpointHandle(const GraphId &graph_id, const ComputeGraphPtr &compute_graph, | |||
const std::vector<GeTensor> &outputs); | |||
// call the callback function of ME to push summary result data to ME | |||
Status PushSummaryData2ME(const GraphId &graph_id, const std::map<std::string, ge::Tensor> &summary_data); | |||
@@ -260,6 +262,13 @@ class GraphManager { | |||
bool IsGraphNeedBuild(const GraphNodePtr &graph_node); | |||
Status LoadFromCache(const GraphNodePtr &graph_node, const ModelCacheHelperPtr &cache_helper, GeModelPtr &ge_model); | |||
Status SaveCacheBeforeBuild(uint32_t graph_id, const ModelCacheHelperPtr &cache_helper); | |||
Status SaveCacheAfterBuild(uint32_t graph_id, ComputeGraphPtr graph, GeModelPtr &ge_model); | |||
void AddModelCacheHelperToMap(const GraphId &graph_id, uint64_t session_id, ComputeGraphPtr &compute_graph); | |||
Status IncreBuild(const GraphNodePtr &graph_node, GeModelPtr &ge_model); | |||
void RemoveModelCacheHelper(const GraphId &graph_id); | |||
static void PreRunThread(GraphManager *graph_manager); | |||
static void RunThread(GraphManager *graph_manager); | |||
static void StopQueue(GraphManager *graph_manager); | |||
@@ -274,6 +283,8 @@ class GraphManager { | |||
std::map<GraphId, GraphNodePtr> graph_map_; | |||
std::map<GraphId, ModelCacheHelperPtr> cache_helper_map_; | |||
// for run graph synchronous return | |||
std::mutex sync_run_mutex_; | |||
std::condition_variable condition_; | |||
@@ -64,6 +64,10 @@ ge::Status VarResource::GetVarAddr(const std::string &var_name, const ge::GeTens | |||
return SUCCESS; | |||
} | |||
void VarResource::GetAllVarAddrMgr(std::unordered_map<std::string, VarAddrMgr> &var_addr_mgr_map) { | |||
var_addr_mgr_map = var_addr_mgr_map_; | |||
} | |||
void VarResource::SetVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t *dev_ptr, | |||
rtMemType_t memory_type) { | |||
std::string var_key = VarKey(var_name, tensor_desc); | |||
@@ -170,6 +174,14 @@ void VarResource::SaveBroadCastInfo(uint32_t graph_id, const VarBroadCastInfo &b | |||
var_broad_cast_info_[graph_id][broad_cast_info.var_name] = broad_cast_info; | |||
} | |||
ge::Status VarResource::GetBroadCastInfo(uint32_t graph_id, const string &var_name, VarBroadCastInfo &broad_cast_info) { | |||
if (var_broad_cast_info_.count(graph_id) == 0 || var_broad_cast_info_[graph_id].count(var_name) == 0) { | |||
return FAILED; | |||
} | |||
broad_cast_info = var_broad_cast_info_[graph_id][var_name]; | |||
return SUCCESS; | |||
} | |||
ge::Status VarResource::SyncVarData2BroadCast(uint32_t graph_id, const std::string &var_name, | |||
const ge::ConstOpDescPtr &var_op_desc, uint8_t *base_ptr) { | |||
if (var_op_desc == nullptr) { | |||
@@ -282,11 +294,17 @@ Status MemResource::AssignVarMem(const std::string &var_name, uint64_t size, uin | |||
// align 512 BYTE | |||
var_mem_size_ = var_mem_size_ + kSessionMemAlignSize; | |||
GELOGI( | |||
"[IMAS]AssignVarMem Set session_%lu name[%s] output[%d]" | |||
"offset to [%zu] size[%lu] realsize[%lu].", | |||
session_id, var_name.c_str(), 0, mem_offset, (var_mem_size_ - mem_offset), real_size); | |||
return SUCCESS; | |||
} | |||
int64_t MemResource::GetVarMemSize() const { return var_mem_size_; } | |||
void MemResource::UpdateVarMemSize(int64_t mem_size) { var_mem_size_ = mem_size; }; | |||
VarManager::VarManager(uint64_t session_id) | |||
: version_(SessionVersion::OTHER_VERSION), | |||
session_id_(session_id), | |||
@@ -363,6 +381,21 @@ ge::Status VarManager::SetVarAddr(const std::string &var_name, const ge::GeTenso | |||
return ge::SUCCESS; | |||
} | |||
ge::Status VarManager::SaveVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t *address, | |||
rtMemType_t memory_type) { | |||
GELOGI("VarManager::SaveVarAddr var_name = %s, data_type = %s, data_format = %s.", var_name.c_str(), | |||
ge::TypeUtils::DataTypeToSerialString(tensor_desc.GetDataType()).c_str(), | |||
ge::TypeUtils::FormatToSerialString(tensor_desc.GetFormat()).c_str()); | |||
std::lock_guard<std::recursive_mutex> lock(mutex_); | |||
if (var_resource_ == nullptr) { | |||
GELOGW("VarManager has not been init."); | |||
return ge::INTERNAL_ERROR; | |||
} | |||
var_resource_->SaveVarAddr(var_name, tensor_desc, address, memory_type); | |||
return ge::SUCCESS; | |||
} | |||
ge::Status VarManager::GetVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t **dev_ptr, | |||
rtMemType_t &memory_type) { | |||
std::lock_guard<std::recursive_mutex> lock(mutex_); | |||
@@ -388,6 +421,10 @@ ge::Status VarManager::GetVarAddr(const std::string &var_name, const ge::GeTenso | |||
return GetVarAddr(var_name, tensor_desc, dev_ptr, memory_type); | |||
} | |||
void VarManager::GetAllVarAddrMgr(std::unordered_map<std::string, VarAddrMgr> &var_addr_mgr_map) { | |||
var_resource_->GetAllVarAddrMgr(var_addr_mgr_map); | |||
} | |||
int64_t VarManager::GetVarMemSize(rtMemType_t memory_type) { | |||
std::lock_guard<std::recursive_mutex> lock(mutex_); | |||
MemResource *mem_resource = nullptr; | |||
@@ -405,14 +442,36 @@ int64_t VarManager::GetVarMemSize(rtMemType_t memory_type) { | |||
return mem_resource->GetVarMemSize(); | |||
} | |||
Status VarManager::UpdateVarMemSize(rtMemType_t memory_type, int64_t mem_size) { | |||
std::lock_guard<std::recursive_mutex> lock(mutex_); | |||
MemResource *mem_resource = nullptr; | |||
auto iter = mem_resource_map_.find(memory_type); | |||
if (iter == mem_resource_map_.end()) { | |||
mem_resource = new (std::nothrow) MemResource(); | |||
if (mem_resource == nullptr) { | |||
GELOGE(ge::INTERNAL_ERROR, "Alloc MemResource failed, memory_type = %u.", memory_type); | |||
return ge::INTERNAL_ERROR; | |||
} else { | |||
mem_resource_map_[memory_type] = mem_resource; | |||
} | |||
} else { | |||
mem_resource = iter->second; | |||
} | |||
if (mem_resource == nullptr) { | |||
GELOGE(ge::INTERNAL_ERROR, "MemResource is invalid."); | |||
return FAILED; | |||
} | |||
mem_resource->UpdateVarMemSize(mem_size); | |||
return SUCCESS; | |||
} | |||
ge::Status VarManager::AssignVarMem(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, | |||
rtMemType_t memory_type) { | |||
std::lock_guard<std::recursive_mutex> lock(mutex_); | |||
GELOGI( | |||
"VarManager::AssignVarMem var_name = %s, data_type = %s, data_format = " | |||
"%s.", | |||
var_name.c_str(), ge::TypeUtils::DataTypeToSerialString(tensor_desc.GetDataType()).c_str(), | |||
ge::TypeUtils::FormatToSerialString(tensor_desc.GetFormat()).c_str()); | |||
GELOGI("VarManager::AssignVarMem var_name = %s, data_type = %s, data_format = %s.", var_name.c_str(), | |||
ge::TypeUtils::DataTypeToSerialString(tensor_desc.GetDataType()).c_str(), | |||
ge::TypeUtils::FormatToSerialString(tensor_desc.GetFormat()).c_str()); | |||
int64_t tensor_desc_size = 0; | |||
size_t mem_offset = 0; | |||
@@ -475,14 +534,13 @@ ge::Status VarManager::AssignVarMem(const std::string &var_name, const ge::GeTen | |||
if (cur_tensor_desc.GetFormat() != tensor_desc.GetFormat() || | |||
cur_tensor_desc.GetDataType() != tensor_desc.GetDataType() || | |||
cur_tensor_desc.GetShape().GetDims() != tensor_desc.GetShape().GetDims()) { | |||
GELOGI( | |||
"var %s assigned new memory (format, data type, shape) (%s, %s, " | |||
"%zu) from (%s, %s, %zu)", | |||
var_name.c_str(), ge::TypeUtils::DataTypeToSerialString(tensor_desc.GetDataType()).c_str(), | |||
ge::TypeUtils::FormatToSerialString(tensor_desc.GetFormat()).c_str(), tensor_desc.GetShape().GetDims().size(), | |||
ge::TypeUtils::DataTypeToSerialString(cur_tensor_desc.GetDataType()).c_str(), | |||
ge::TypeUtils::FormatToSerialString(cur_tensor_desc.GetFormat()).c_str(), | |||
cur_tensor_desc.GetShape().GetDims().size()); | |||
GELOGI("var %s assigned new memory (format, data type, shape) (%s, %s, %zu) from (%s, %s, %zu)", var_name.c_str(), | |||
ge::TypeUtils::DataTypeToSerialString(tensor_desc.GetDataType()).c_str(), | |||
ge::TypeUtils::FormatToSerialString(tensor_desc.GetFormat()).c_str(), | |||
tensor_desc.GetShape().GetDims().size(), | |||
ge::TypeUtils::DataTypeToSerialString(cur_tensor_desc.GetDataType()).c_str(), | |||
ge::TypeUtils::FormatToSerialString(cur_tensor_desc.GetFormat()).c_str(), | |||
cur_tensor_desc.GetShape().GetDims().size()); | |||
var_resource_->SetVarAddr(var_name, tensor_desc, | |||
reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(mem_offset)), memory_type); | |||
} | |||
@@ -550,6 +608,16 @@ ge::Status VarManager::SaveBroadCastInfo(uint32_t graph_id, const VarBroadCastIn | |||
return SUCCESS; | |||
} | |||
ge::Status VarManager::GetBroadCastInfo(uint32_t graph_id, const string &var_name, VarBroadCastInfo &broad_cast_info) { | |||
std::lock_guard<std::recursive_mutex> lock(mutex_); | |||
if (var_resource_ == nullptr) { | |||
GELOGW("VarManager has not been init."); | |||
return ge::INTERNAL_ERROR; | |||
} | |||
return var_resource_->GetBroadCastInfo(graph_id, var_name, broad_cast_info); | |||
} | |||
ge::Status VarManager::RenewCurVarDesc(const std::string &var_name, ge::OpDescPtr op_desc) { | |||
std::lock_guard<std::recursive_mutex> lock(mutex_); | |||
GELOGD("VarManager::RenewCurVarDesc var_name = %s.", var_name.c_str()); | |||
@@ -672,6 +740,7 @@ Status VarManager::SetMemoryMallocSize(const map<string, string> &options) { | |||
GELOGE(ge::GE_GRAPH_OPTIONS_INVALID, "Parse graph memory manager malloc max size failed."); | |||
return ge::GE_GRAPH_OPTIONS_INVALID; | |||
} | |||
GELOGI("The max size for graph mem is set to %zu", graph_mem_max_size_); | |||
} | |||
it = options.find(VARIABLE_MEMORY_MAX_SIZE); | |||
@@ -101,6 +101,8 @@ class VarResource { | |||
ge::Status GetVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t **dev_ptr, | |||
rtMemType_t &memory_type); | |||
void GetAllVarAddrMgr(std::unordered_map<std::string, VarAddrMgr> &var_addr_mgr_map); | |||
void SetVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t *dev_ptr, | |||
rtMemType_t rtMemType_t); | |||
@@ -113,6 +115,8 @@ class VarResource { | |||
void SaveBroadCastInfo(uint32_t graph_id, const VarBroadCastInfo &broad_cast_info); | |||
ge::Status GetBroadCastInfo(uint32_t graph_id, const string &var_name, VarBroadCastInfo &broad_cast_info); | |||
ge::Status SyncVarData2BroadCast(uint32_t graph_id, const std::string &var_name, | |||
const ge::ConstOpDescPtr &var_op_desc, uint8_t *base_ptr); | |||
@@ -175,6 +179,8 @@ class MemResource { | |||
int64_t GetVarMemSize() const; | |||
void UpdateVarMemSize(int64_t mem_size); | |||
private: | |||
uint64_t total_size_; | |||
uint64_t var_mem_size_; | |||
@@ -196,9 +202,14 @@ class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY VarManager { | |||
ge::Status SetVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t *dev_ptr, | |||
rtMemType_t memory_type); | |||
ge::Status SaveVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t *address, | |||
rtMemType_t memory_type); | |||
ge::Status GetVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t **dev_ptr, | |||
rtMemType_t &memory_type); | |||
void GetAllVarAddrMgr(std::unordered_map<std::string, VarAddrMgr> &var_addr_mgr_map); | |||
ge::Status GetVarAddr(const std::string &var_name, const ge::GeTensorDesc &tensor_desc, uint8_t **dev_ptr); | |||
ge::Status SyncVarData(uint32_t graph_id, const std::string &var_name, ge::ConstOpDescPtr var_op_desc, | |||
@@ -206,6 +217,8 @@ class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY VarManager { | |||
ge::Status SaveBroadCastInfo(uint32_t graph_id, const VarBroadCastInfo &broad_cast_info); | |||
ge::Status GetBroadCastInfo(uint32_t graph_id, const string &var_name, VarBroadCastInfo &broad_cast_info); | |||
ge::Status SyncBroadCastData2Var(uint32_t graph_id, const std::string &var_name, ge::ConstOpDescPtr var_op_desc, | |||
uint8_t *base_ptr); | |||
@@ -251,6 +264,8 @@ class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY VarManager { | |||
int64_t GetVarMemSize(rtMemType_t memory_type); | |||
Status UpdateVarMemSize(rtMemType_t memory_type, int64_t mem_size); | |||
bool IsVarExist(const std::string &var_name, const ge::GeTensorDesc &tensor_desc); | |||
bool IsVarExist(const std::string &var_name); | |||
@@ -238,6 +238,14 @@ Status ge::GraphPartitioner::MergeSubGraph(ge::ComputeGraphPtr &output_merged_co | |||
return FAILED; | |||
} | |||
GE_TIMESTAMP_END(MergeGraphTopologicalSorting, "GraphPartitioner::MergeGraphTopologicalSorting"); | |||
// flush all nodes' engine of merged graph | |||
GE_TIMESTAMP_START(MergeGraphEnginePlacerRun); | |||
graph_info_.engine_placer_.SetComputeGraph(output_merged_compute_graph); | |||
if (graph_info_.engine_placer_.Run() != SUCCESS) { | |||
GELOGE(GE_GRAPH_INIT_FAILED, "[GraphPartitioner]: engine_placer run failed"); | |||
return FAILED; | |||
} | |||
GE_TIMESTAMP_END(MergeGraphEnginePlacerRun, "GraphPartitioner::MergeGraphEnginePlacerRun"); | |||
GELOGI("Graph merge ends."); | |||
return SUCCESS; | |||
} | |||
@@ -200,7 +200,18 @@ bool AtomicAddrCleanPass::IsAtomicOp(const NodePtr &node) { | |||
vector<OpInfo> op_info_vec = ops_kernel_manager.GetOpsKernelInfo(op_desc->GetType()); | |||
for (const auto &op_info : op_info_vec) { | |||
if (op_info.isAtomic) { | |||
GELOGI("Recognized atomic op %s from HCCL engine.", op_desc->GetName().c_str()); | |||
GELOGI("Recognized atomic op %s from DNN_HCCL engine.", op_desc->GetName().c_str()); | |||
// check peer input is DATA | |||
for (auto &in_data_anchor : node->GetAllInDataAnchors()) { | |||
if (in_data_anchor->GetPeerOutAnchor() != nullptr && | |||
in_data_anchor->GetPeerOutAnchor()->GetOwnerNode() != nullptr) { | |||
auto peer_in_node = in_data_anchor->GetPeerOutAnchor()->GetOwnerNode(); | |||
if (peer_in_node->GetType() == DATA) { | |||
GELOGI("Recognized atomic op %s from DNN_HCCL engine and input is DATA.", op_desc->GetName().c_str()); | |||
return false; | |||
} | |||
} | |||
} | |||
hcom_node_vec_.push_back(node); | |||
return true; | |||
} | |||
@@ -49,9 +49,11 @@ Status CastKernel::Compute(const OpDescPtr op_desc_ptr, const std::vector<ConstG | |||
GELOGE(PARAM_INVALID, "Input const_weight_ptr is nullptr."); | |||
return PARAM_INVALID; | |||
} | |||
const uint8_t *src_data = const_weight_ptr->GetData().data(); | |||
if (op_desc_ptr == nullptr || src_data == nullptr) { | |||
GELOGE(PARAM_INVALID, "Parameter's invalid, Input opDescPtr or src_data is nullptr."); | |||
// src_data == nullptr is supported | |||
if (op_desc_ptr == nullptr) { | |||
GELOGE(PARAM_INVALID, "Parameter's invalid, Input opDescPtr is nullptr."); | |||
return PARAM_INVALID; | |||
} | |||
GeTensorDesc op_desc = op_desc_ptr->GetOutputDesc(0); | |||
@@ -73,7 +75,7 @@ Status CastKernel::Compute(const OpDescPtr op_desc_ptr, const std::vector<ConstG | |||
TypeUtils::FormatToSerialString(data_format).c_str(), formats::ShapeToString(data_shape).c_str(), | |||
TypeUtils::DataTypeToSerialString(data_type).c_str()); | |||
GE_CHECK_SIZE(const_weight_ptr->GetData().GetSize()); | |||
// const_weight_ptr->GetData().GetSize() == 0 is supported | |||
auto src_data_size = src_shape.GetShapeSize(); | |||
if (src_data_size == 0 && | |||
static_cast<int>(const_weight_ptr->GetData().GetSize()) == GetSizeByDataType(src_data_type)) { | |||
@@ -113,7 +115,6 @@ Status CastKernel::Compute(const OpDescPtr op_desc_ptr, const std::vector<ConstG | |||
} | |||
if (output_ptr->SetData(trans_result.data.get(), trans_result.length) != SUCCESS) { | |||
GELOGW("Compute: SetData failed"); | |||
return FAILED; | |||
} | |||
v_output.push_back(output_ptr); | |||
return SUCCESS; | |||
@@ -113,12 +113,26 @@ bool KernelUtils::CheckSizeForTransOp(const ge::ConstGeTensorPtr &const_weight_p | |||
GELOGI("Const real value Size:%zu, op_desc Shape Size:%ld, data_type:%s.", data_size, cal_size, | |||
TypeUtils::DataTypeToSerialString(data_type).c_str()); | |||
if ((shape_size != 0) || (length != 0 && (data_size / static_cast<size_t>(length) != 1))) { | |||
if (!(data_size == static_cast<size_t>(cal_size) && data_size != 0)) { | |||
if (shape_size != 0) { | |||
// Standard tensor | |||
if (data_size != static_cast<size_t>(cal_size) || data_size == 0) { | |||
GELOGW("Const input data size is not equal with tensor desc shape"); | |||
return false; | |||
} | |||
} else if (data_shape.GetDimNum() != 0) { | |||
// Empty tensor, has zero in shape vector | |||
if (data_size != 0) { | |||
GELOGW("Const input data size is not equal with tensor desc shape"); | |||
return false; | |||
} | |||
} else { | |||
// Scalar tensor, has only one element in tensor | |||
if (length != 0 && (data_size / static_cast<size_t>(length) != 1)) { | |||
GELOGW("Const input data size is not equal with tensor desc shape"); | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
@@ -29,6 +29,7 @@ namespace ge { | |||
class KernelUtils { | |||
public: | |||
KernelUtils() = delete; | |||
~KernelUtils() = delete; | |||
static Status CheckDimensionNodeInfo(const NodePtr &node_ptr); | |||
static bool CheckFormatSupported(const NodePtr &node_ptr); | |||
static bool CheckSizeForTransOp(const ConstGeTensorPtr &const_weight_ptr, const OpDescPtr &op_desc_ptr); | |||
@@ -41,7 +42,7 @@ class KernelUtils { | |||
* @param [out] output the tensor for save sequence of numbers | |||
* @author | |||
*/ | |||
template<typename T> | |||
template <typename T> | |||
static Status GenData(const int64_t data_num, const T value, const GeTensorPtr &output) { | |||
if (data_num > 0) { | |||
if (!CheckInt64MulOverflow(data_num, static_cast<int64_t>(sizeof(T)))) { | |||
@@ -69,12 +70,12 @@ class KernelUtils { | |||
} | |||
/** | |||
* Calculate dimension | |||
* @param [in] dims save the tensor of the dimension | |||
* @param [in] vec_dim results of each dimension | |||
* @param [out] data_num total size of data | |||
* @author | |||
*/ | |||
* Calculate dimension | |||
* @param [in] dims save the tensor of the dimension | |||
* @param [in] vec_dim results of each dimension | |||
* @param [out] data_num total size of data | |||
* @author | |||
*/ | |||
template <typename T> | |||
static Status CalcDims(const ConstGeTensorPtr dims, std::vector<int64_t> &vec_dim, int64_t &data_num) { | |||
data_num = 1; | |||
@@ -67,8 +67,8 @@ Status PackKernel::ValidateKernelParams(const ge::OpDescPtr &op_desc_ptr, | |||
return PARAM_INVALID; | |||
} | |||
if (!(AttrUtils::GetInt(op_desc_ptr, PACK_ATTR_NAME_NUM, n_))) { | |||
GELOGE(PARAM_INVALID, "Attr %s is not exist.", PACK_ATTR_NAME_NUM.c_str()); | |||
return PARAM_INVALID; | |||
n_ = 0; | |||
GELOGD("Attr %s is not set, default value %ld is used.", PACK_ATTR_NAME_NUM.c_str(), n_); | |||
} | |||
if (!(AttrUtils::GetInt(op_desc_ptr, ATTR_NAME_AXIS, axis_))) { | |||
GELOGE(PARAM_INVALID, "Attr %s is not exist.", ATTR_NAME_AXIS.c_str()); | |||
@@ -105,11 +105,7 @@ Status PackKernel::ValidateInputs(const ge::OpDescPtr &op_desc_ptr, const std::v | |||
GELOGW("Input %ld of pack kernel %s is null.", i, op_desc_ptr->GetName().c_str()); | |||
return PARAM_INVALID; | |||
} | |||
// check if tensor contains data | |||
if (input[i]->GetData().size() == 0) { | |||
GELOGW("Inputs %ld do not have value.", i); | |||
return NOT_CHANGED; | |||
} | |||
if (i == 0) { | |||
// get first input shape | |||
shape = input[0]->GetTensorDesc().GetShape(); | |||
@@ -127,8 +123,8 @@ Status PackKernel::ValidateInputs(const ge::OpDescPtr &op_desc_ptr, const std::v | |||
auto dst_shape = tensor_desc.GetShape(); | |||
int64_t num = 1; | |||
for (auto dim : dst_shape.GetDims()) { | |||
if (dim < 1) { | |||
GELOGW("Invalid zero dim in the shape %s", formats::ShapeToString(shape).c_str()); | |||
if (dim < 0) { | |||
GELOGW("Invalid dim ld% in the shape %s", dim, formats::ShapeToString(shape).c_str()); | |||
return NOT_CHANGED; | |||
} | |||
num *= dim; | |||
@@ -141,6 +137,12 @@ Status PackKernel::ValidateInputs(const ge::OpDescPtr &op_desc_ptr, const std::v | |||
GELOGW("Shape of input %ld is not equal wiht input 0.", i); | |||
return NOT_CHANGED; | |||
} | |||
// check tensor data size is zero ot not | |||
if (input[i]->GetData().size() == 0 && num != 0) { | |||
GELOGW("Inputs %ld do not have value.", i); | |||
return NOT_CHANGED; | |||
} | |||
} | |||
return SUCCESS; | |||
} | |||
@@ -167,6 +169,13 @@ void PackKernel::ExpandDims(const int64_t axis, const std::vector<ge::ConstGeTen | |||
Status PackKernel::CopyOutputData(const GeShape &final_shape, const std::vector<ge::ConstGeTensorPtr> &input, | |||
ge::GeTensorPtr &output_ptr) { | |||
output_ptr->MutableTensorDesc().SetShape(final_shape); | |||
output_ptr->MutableTensorDesc().SetDataType(DataType(data_type_)); | |||
if (final_shape.GetShapeSize() == 0 && final_shape.GetDims().size() != 0) { | |||
// means has zero in shape list, output tnesor data is []. | |||
return SUCCESS; | |||
} | |||
int64_t times = 1; | |||
int64_t unit = 1; | |||
// calculate data unit | |||
@@ -210,8 +219,6 @@ Status PackKernel::CopyOutputData(const GeShape &final_shape, const std::vector< | |||
if (output_ptr->SetData(buf.get(), static_cast<size_t>(output_size * data_size)) != GRAPH_SUCCESS) { | |||
GELOGW("CopyOutputData: SetData failed"); | |||
} | |||
output_ptr->MutableTensorDesc().SetShape(final_shape); | |||
output_ptr->MutableTensorDesc().SetDataType(DataType(data_type_)); | |||
return SUCCESS; | |||
} | |||
@@ -63,10 +63,7 @@ Status ReduceProdKernel::ReduceProdCheck(const ge::OpDescPtr &op_desc_ptr, | |||
GELOGE(PARAM_INVALID, "Axis must be at most rank 1, node node: %s", op_desc_ptr->GetName().c_str()); | |||
return PARAM_INVALID; | |||
} | |||
if (data_tensor->GetData().size() == 0 || axis_tensor->GetData().size() == 0) { | |||
GELOGE(PARAM_INVALID, "ReduceProdKernel data size of inputs is 0, node node: %s", op_desc_ptr->GetName().c_str()); | |||
return PARAM_INVALID; | |||
} | |||
DataType data_type = data_tensor->GetTensorDesc().GetDataType(); | |||
if (kReduceProdSupportedType.find(data_type) == kReduceProdSupportedType.end()) { | |||
GELOGE(PARAM_INVALID, "ReduceProdKernel data type %s not support, node name: %s", | |||
@@ -151,7 +148,6 @@ Status ReduceProdKernel::DataCal(const std::vector<ge::ConstGeTensorPtr> &input, | |||
static_cast<size_t>(head_dim_ * end_dim_ * sizeof(int32_t))) != GRAPH_SUCCESS, | |||
GELOGW("set data failed"); | |||
return INTERNAL_ERROR); | |||
output_ptr->MutableTensorDesc().SetDataType(data_dtype); | |||
} | |||
return SUCCESS; | |||
} | |||
@@ -260,19 +256,32 @@ Status ReduceProdKernel::Compute(const ge::OpDescPtr op_desc_ptr, const std::vec | |||
if (ret != SUCCESS) { | |||
return NOT_CHANGED; | |||
} | |||
} else if (input.at(kReduceProdAxisIndex)->GetData().size() == 0) { | |||
// axis tensor value is [], means no process for input | |||
output_ptr->MutableTensorDesc().SetShape(input.at(kReduceProdDataIndex)->GetTensorDesc().GetShape()); | |||
output_ptr->MutableTensorDesc().SetDataType(input.at(kReduceProdDataIndex)->GetTensorDesc().GetDataType()); | |||
if (output_ptr->SetData(input.at(kReduceProdDataIndex)->GetData()) != GRAPH_SUCCESS) { | |||
GELOGW("Compute: SetData failed"); | |||
} | |||
} else { | |||
// calculate axis to reduce | |||
ret = AxisCal(input); | |||
if (ret != SUCCESS) { | |||
return NOT_CHANGED; | |||
} | |||
// calculate data and data type | |||
ret = DataCal(input, output_ptr); | |||
if (ret != SUCCESS) { | |||
return NOT_CHANGED; | |||
} | |||
// calculate shape | |||
// calculate and set shape | |||
ShapeCal(op_desc_ptr, input, output_ptr); | |||
// set data type | |||
output_ptr->MutableTensorDesc().SetDataType(input.at(kReduceProdDataIndex)->GetTensorDesc().GetDataType()); | |||
// data size == 0 means input tensor has zero in shape, and tensor value is []. | |||
if (input.at(kReduceProdDataIndex)->GetData().size() != 0) { | |||
// calculate data and data type | |||
ret = DataCal(input, output_ptr); | |||
if (ret != SUCCESS) { | |||
return NOT_CHANGED; | |||
} | |||
} | |||
} | |||
// print output tensor information, and will be deleted | |||
@@ -48,8 +48,9 @@ Status TransdataKernel::ValidateInput(const OpDescPtr &op_desc_ptr, const std::v | |||
GELOGE(PARAM_INVALID, "Input const_weight_ptr is nullptr."); | |||
return PARAM_INVALID; | |||
} | |||
const uint8_t *src_data = const_weight_ptr->GetData().data(); | |||
if (op_desc_ptr == nullptr || src_data == nullptr) { | |||
// src_data == nullptr is supported | |||
if (op_desc_ptr == nullptr) { | |||
GELOGE(PARAM_INVALID, "Input opDescPtr is nullptr."); | |||
return PARAM_INVALID; | |||
} | |||
@@ -26,6 +26,7 @@ namespace ge { | |||
class PassUtils { | |||
public: | |||
PassUtils() = delete; | |||
~PassUtils() = delete; | |||
static NodePtr GetInDataNode(const ConstNodePtr &node, int index); | |||
@@ -137,7 +137,7 @@ Status SwitchOpPass::ReplaceSwitchNode(ComputeGraphPtr &graph, NodePtr &switch_n | |||
NodePtr out_node = peer_in_anchor->GetOwnerNode(); | |||
GE_CHK_STATUS_RET(GetOriginalType(out_node, type), "Get node type fail."); | |||
if ((type == MERGE) || (type == REFMERGE)) { | |||
NodePtr memcpy_node = CreateMemcpyAsyncNode(graph, peer_data_anchor); | |||
NodePtr memcpy_node = CreateMemcpyAsyncNode(graph, peer_data_anchor, false); | |||
GE_CHK_BOOL_EXEC(memcpy_node != nullptr, return FAILED, "Create memcpy_async node fail."); | |||
GE_CHK_STATUS(GraphUtils::AddEdge(peer_data_anchor, memcpy_node->GetInDataAnchor(0)), | |||
"MemcpyAsync node add edge fail."); | |||
@@ -234,16 +234,18 @@ Status SwitchOpPass::ReplaceMergeNode(ComputeGraphPtr &graph, NodePtr &merge_nod | |||
need_label_nodes_.emplace_back(stream_merge); | |||
} | |||
bool multi_batch_flag = false; | |||
if (merge_op_desc->HasAttr(ATTR_INSERT_BY_MBATCH)) { | |||
if (!ge::AttrUtils::SetBool(op_desc, ATTR_INSERT_BY_MBATCH, true)) { | |||
GELOGE(FAILED, "Set attr ATTR_INSERT_BY_MBATCH fail, StreamMerge:%s.", node_name.c_str()); | |||
return FAILED; | |||
} | |||
multi_batch_flag = true; | |||
} | |||
(void)bypass_nodes_.insert(merge_node); | |||
GE_CHK_STATUS_RET(AddMemcpyAsyncNodes(graph, stream_merge), "StreamMerge add memcpy node fail."); | |||
GE_CHK_STATUS_RET(AddMemcpyAsyncNodes(graph, stream_merge, multi_batch_flag), "StreamMerge add memcpy node fail."); | |||
return SUCCESS; | |||
} | |||
@@ -302,17 +304,20 @@ NodePtr SwitchOpPass::CreateStreamSwitchNode(ComputeGraphPtr &graph, const NodeP | |||
/// @brief Add MemcpyAsync Node | |||
/// @param [in] graph | |||
/// @param [in] in_node | |||
/// @param [in] multi_batch_flag | |||
/// @return ge::NodePtr | |||
/// | |||
NodePtr SwitchOpPass::CreateMemcpyAsyncNode(ComputeGraphPtr &graph, const OutDataAnchorPtr &out_data_anchor) { | |||
NodePtr SwitchOpPass::CreateMemcpyAsyncNode(ComputeGraphPtr &graph, const OutDataAnchorPtr &out_data_anchor, | |||
bool multi_batch_flag) { | |||
GE_CHK_BOOL_EXEC(out_data_anchor != nullptr, return nullptr, "Param of input node is null."); | |||
OpDescPtr pre_op_desc = out_data_anchor->GetOwnerNode()->GetOpDesc(); | |||
GE_CHK_BOOL_EXEC(pre_op_desc != nullptr, return nullptr, "OpDesc of pre node is invalid."); | |||
std::string node_name = pre_op_desc->GetName() + "_" + MEMCPYASYNC; | |||
std::string memcpy_type = multi_batch_flag ? MEMCPYADDRASYNC : MEMCPYASYNC; | |||
std::string node_name = pre_op_desc->GetName() + "_" + memcpy_type; | |||
node_name = CheckDuplicateName(node_name); | |||
GELOGI("Create MemcpyAsync op:%s.", node_name.c_str()); | |||
OpDescPtr op_desc = MakeShared<OpDesc>(node_name, MEMCPYASYNC); | |||
OpDescPtr op_desc = MakeShared<OpDesc>(node_name, memcpy_type); | |||
if (op_desc == nullptr) { | |||
GELOGE(FAILED, "Create op_desc fail, MemcpyAsync:%s.", node_name.c_str()); | |||
return nullptr; | |||
@@ -432,9 +437,10 @@ NodePtr SwitchOpPass::CreateActiveNode(ComputeGraphPtr &graph, NodePtr &node) { | |||
/// @brief Add MemcpyAsync Op as StreamMerge in_node | |||
/// @param [in] graph | |||
/// @param [in] node | |||
/// @param [in] multi_batch_flag | |||
/// @return Status | |||
/// | |||
Status SwitchOpPass::AddMemcpyAsyncNodes(ComputeGraphPtr &graph, NodePtr &node) { | |||
Status SwitchOpPass::AddMemcpyAsyncNodes(ComputeGraphPtr &graph, NodePtr &node, bool multi_batch_flag) { | |||
GE_CHK_BOOL_EXEC(node != nullptr, return FAILED, "Param of pre node is null."); | |||
for (InDataAnchorPtr &in_data_anchor : node->GetAllInDataAnchors()) { | |||
OutDataAnchorPtr peer_out_anchor = in_data_anchor->GetPeerOutAnchor(); | |||
@@ -447,7 +453,7 @@ Status SwitchOpPass::AddMemcpyAsyncNodes(ComputeGraphPtr &graph, NodePtr &node) | |||
continue); | |||
GE_IF_BOOL_EXEC(type != MEMCPYASYNC, { | |||
in_node = CreateMemcpyAsyncNode(graph, peer_out_anchor); | |||
in_node = CreateMemcpyAsyncNode(graph, peer_out_anchor, multi_batch_flag); | |||
GE_CHK_BOOL_EXEC(in_node != nullptr, return FAILED, "Create MemcpyAsync node fail."); | |||
GE_CHK_STATUS(GraphUtils::RemoveEdge(peer_out_anchor, in_data_anchor), "MemcpyAsync node remove edge fail."); | |||
GE_CHK_STATUS(GraphUtils::AddEdge(peer_out_anchor, in_node->GetInDataAnchor(0)), | |||
@@ -103,13 +103,13 @@ class SwitchOpPass : public GraphPass { | |||
NodePtr CreateStreamSwitchNode(ComputeGraphPtr &graph, const NodePtr &switch_node, const std::string &suffix, | |||
OutDataAnchorPtr &peer_cond_anchor); | |||
NodePtr CreateMemcpyAsyncNode(ComputeGraphPtr &graph, const OutDataAnchorPtr &out_data_anchor); | |||
NodePtr CreateMemcpyAsyncNode(ComputeGraphPtr &graph, const OutDataAnchorPtr &out_data_anchor, bool multi_batch_flag); | |||
Status CombineSwitchNode(ComputeGraphPtr &graph); | |||
NodePtr CreateActiveNode(ComputeGraphPtr &graph, NodePtr &node); | |||
Status AddMemcpyAsyncNodes(ComputeGraphPtr &graph, NodePtr &stream_merge_node); | |||
Status AddMemcpyAsyncNodes(ComputeGraphPtr &graph, NodePtr &stream_merge_node, bool multi_batch_flag); | |||
Status BypassSwitchNode(NodePtr &switch_node, OutDataAnchorPtr &peer_data_anchor, OutDataAnchorPtr &peer_cond_anchor); | |||
@@ -22,11 +22,14 @@ | |||
#include "common/ge/ge_util.h" | |||
#include "external/graph/graph.h" | |||
#include "framework/common/debug/ge_log.h" | |||
#include "graph/common/omg_util.h" | |||
#include "graph/debug/ge_attr_define.h" | |||
#include "graph/node.h" | |||
#include "graph/utils/tensor_utils.h" | |||
namespace ge { | |||
std::map<std::string, std::map<int, int>> VariablePrepareOpPass::ref_node_without_prototype_map_{ | |||
{REFSWITCH, {{0, 0}, {0, 1}}}}; | |||
Status VariablePrepareOpPass::Run(ComputeGraphPtr graph) { | |||
GE_CHECK_NOTNULL(graph); | |||
for (const auto &node : graph->GetDirectNode()) { | |||
@@ -43,9 +46,7 @@ Status VariablePrepareOpPass::Run(ComputeGraphPtr graph) { | |||
for (auto &node : graph->GetDirectNode()) { | |||
GE_IF_BOOL_EXEC(node->GetOpDesc() == nullptr, continue); | |||
bool is_variable = node->GetOpDesc()->GetType() == VARIABLE; | |||
bool is_deal = has_dealed_variable_.find(node->GetName()) == has_dealed_variable_.end(); | |||
if (is_variable && is_deal) { | |||
if (node->GetOpDesc()->GetType() == VARIABLE) { | |||
Status ret = DealVariableNode(node); | |||
if (ret != SUCCESS) { | |||
GELOGE(ret, "variable add back edge failed"); | |||
@@ -149,7 +150,7 @@ NodePtr VariablePrepareOpPass::GetFinalWritableNode(ge::NodePtr &writable_node, | |||
} | |||
} | |||
if (!found_writeable_node) { | |||
GELOGI("final writable node is %s", current_node->GetName().c_str()); | |||
GELOGD("final writable node is %s", current_node->GetName().c_str()); | |||
return current_node; | |||
} | |||
} | |||
@@ -159,53 +160,54 @@ Status VariablePrepareOpPass::AddVariableRef(ge::NodePtr &final_writable_node, g | |||
GE_CHECK_NOTNULL(final_writable_node); | |||
GE_CHECK_NOTNULL(var_node); | |||
NodePtr var_ref_node = CreatVariableRef(final_writable_node, var_node); | |||
GE_CHECK_NOTNULL(var_ref_node); | |||
// add control anchor between var_ref_node and final peer node | |||
// var_ref_node need to execute before other nodes | |||
if (final_writable_node->GetType() == FRAMEWORKOP) { | |||
GELOGD("No need to add variable_ref for frameworkop"); | |||
return SUCCESS; | |||
} | |||
std::stringstream variable_ref_name; | |||
variable_ref_name << "_TO_" << final_writable_node->GetName() << "_REF_" << index; | |||
ge::NodePtr find_node = var_node->GetOwnerComputeGraph()->FindNode(var_node->GetName() + variable_ref_name.str()); | |||
if (find_node != nullptr) { | |||
GELOGD("The corresponding variable_ref [%s] has been added to this connection.", find_node->GetName().c_str()); | |||
return SUCCESS; | |||
} | |||
NodePtr variable_ref_node = CreatVariableRef(var_node->GetName() + variable_ref_name.str(), var_node); | |||
GELOGI("Add variable_ref between [%s] and [%s]", var_node->GetName().c_str(), variable_ref_node->GetName().c_str()); | |||
GE_CHECK_NOTNULL(variable_ref_node); | |||
// add control anchor between variable_ref and final peer node | |||
// variable_ref_node need to execute before other nodes | |||
auto final_writable_outAnchors = final_writable_node->GetAllOutAnchors(); | |||
for (auto &final_writable_outAnchor : final_writable_outAnchors) { | |||
GE_CHECK_NOTNULL(final_writable_outAnchor); | |||
for (auto &final_writable_peerAnchor : final_writable_outAnchor->GetPeerAnchors()) { | |||
GE_CHECK_NOTNULL(final_writable_peerAnchor); | |||
NodePtr peer_node = final_writable_peerAnchor->GetOwnerNode(); | |||
graphStatus ret = ge::GraphUtils::AddEdge(var_ref_node->GetOutControlAnchor(), peer_node->GetInControlAnchor()); | |||
graphStatus ret = | |||
ge::GraphUtils::AddEdge(variable_ref_node->GetOutControlAnchor(), peer_node->GetInControlAnchor()); | |||
if (ret != GRAPH_SUCCESS) { | |||
GELOGE(FAILED, "add control anchor between var_ref_node and final_writable peer_node failed"); | |||
GELOGE(FAILED, "add control anchor between variable_ref and final_writable peer node failed"); | |||
return FAILED; | |||
} | |||
} | |||
} | |||
// add edge final node:index ---> var_ref_node:0 | |||
graphStatus ret = | |||
ge::GraphUtils::AddEdge(final_writable_node->GetOutDataAnchor(index), var_ref_node->GetInDataAnchor(0)); | |||
ge::GraphUtils::AddEdge(final_writable_node->GetOutDataAnchor(index), variable_ref_node->GetInDataAnchor(0)); | |||
if (ret != GRAPH_SUCCESS) { | |||
GELOGE(FAILED, "add data anchor between var_ref_node and final_writable peer_node failed"); | |||
GELOGE(FAILED, "add data anchor between variable_ref and final_writable peer node failed"); | |||
return FAILED; | |||
} | |||
return SUCCESS; | |||
} | |||
ge::NodePtr VariablePrepareOpPass::CreatVariableRef(ge::NodePtr &final_writable_node, ge::NodePtr &var_node) { | |||
if ((final_writable_node == nullptr) || (var_node == nullptr) || (var_node->GetOwnerComputeGraph() == nullptr)) { | |||
GELOGE(FAILED, "parameter ptr is null."); | |||
return nullptr; | |||
} | |||
GELOGD("Create VarRef Op: final_writable_node: [%s] var_node: [%s]>>>>", final_writable_node->GetName().c_str(), | |||
var_node->GetName().c_str()); | |||
static uint32_t var_ref_count = 0; | |||
std::stringstream var_ref_name; | |||
var_ref_name << "_to_" << final_writable_node->GetName() << "_REF_" << var_ref_count++; | |||
ge::NodePtr VariablePrepareOpPass::CreatVariableRef(const std::string &variable_ref_name, ge::NodePtr &var_node) { | |||
OpDescPtr var_op_desc = var_node->GetOpDesc(); | |||
if (var_op_desc == nullptr) { | |||
GELOGE(FAILED, "get var opdesc is nullptr"); | |||
return nullptr; | |||
} | |||
OpDescPtr var_ref_op_desc = | |||
MakeShared<OpDesc>(var_node->GetName() + var_ref_name.str().c_str(), var_op_desc->GetType()); | |||
OpDescPtr var_ref_op_desc = MakeShared<OpDesc>(variable_ref_name.c_str(), var_op_desc->GetType()); | |||
if (var_ref_op_desc == nullptr) { | |||
GELOGE(FAILED, "var_ref opdesc is nullptr"); | |||
return nullptr; | |||
@@ -217,15 +219,15 @@ ge::NodePtr VariablePrepareOpPass::CreatVariableRef(ge::NodePtr &final_writable_ | |||
GE_IF_BOOL_EXEC(var_ref_op_desc->AddInputDesc(var_op_desc->GetOutputDesc(0)) != SUCCESS, | |||
GELOGW("add input desc edge failed"); | |||
return nullptr); | |||
NodePtr var_ref_node = var_node->GetOwnerComputeGraph()->AddNode(var_ref_op_desc); | |||
GE_IF_BOOL_EXEC(var_ref_node == nullptr, GELOGW("var_ref_node is null"); return nullptr); | |||
has_dealed_variable_.insert(var_node->GetName()); | |||
NodePtr variable_ref_node = var_node->GetOwnerComputeGraph()->AddNode(var_ref_op_desc); | |||
GE_IF_BOOL_EXEC(variable_ref_node == nullptr, GELOGW("variable_ref_node is null"); return nullptr); | |||
bool is_set_str = ge::AttrUtils::SetStr(var_ref_op_desc, REF_VAR_SRC_VAR_NAME, var_op_desc->GetName()); | |||
if (is_set_str) { | |||
GELOGD("Set node [%s] REF_VAR_SRC_VAR_NAME [%s]", var_ref_node->GetName().c_str(), var_op_desc->GetName().c_str()); | |||
GELOGD("Set node [%s] REF_VAR_SRC_VAR_NAME [%s]", variable_ref_node->GetName().c_str(), | |||
var_op_desc->GetName().c_str()); | |||
} | |||
return var_ref_node; | |||
return variable_ref_node; | |||
} | |||
int VariablePrepareOpPass::GetWritableNodeOutIndex(const NodePtr &node, int input_index) { | |||
@@ -240,16 +242,13 @@ int VariablePrepareOpPass::GetWritableNodeOutIndex(const NodePtr &node, int inpu | |||
} | |||
} | |||
auto node_iter = ref_input_output_map_.find(node_type); | |||
if (node_iter == ref_input_output_map_.end()) { | |||
return -1; | |||
} | |||
auto index_iter = node_iter->second.find(input_index); | |||
if (index_iter == node_iter->second.end()) { | |||
return -1; | |||
if (node_type == FRAMEWORKOP) { | |||
std::string original_type; | |||
GE_IF_BOOL_EXEC(GetOriginalType(node, original_type) != SUCCESS, GELOGW("Get node original type fail")); | |||
GELOGI("find frameworkop: [%s], original type is %s", node->GetName().c_str(), original_type.c_str()); | |||
return FindRefOutIndex(original_type, input_index, ref_node_without_prototype_map_); | |||
} | |||
return index_iter->second; | |||
return FindRefOutIndex(node_type, input_index, ref_input_output_map_); | |||
} | |||
void VariablePrepareOpPass::GenerateRefTypeAndInputOutputMap(const NodePtr &node) { | |||
@@ -301,4 +300,18 @@ Status VariablePrepareOpPass::UpdateAssignOpDesc(const ge::NodePtr &node) { | |||
} | |||
return SUCCESS; | |||
} | |||
int VariablePrepareOpPass::FindRefOutIndex(const std::string &node_type, int input_index, | |||
const std::map<std::string, std::map<int, int>> &ref_map) { | |||
auto node_iter = ref_map.find(node_type); | |||
if (node_iter == ref_map.end()) { | |||
return -1; | |||
} | |||
auto index_iter = node_iter->second.find(input_index); | |||
if (index_iter == node_iter->second.end()) { | |||
return -1; | |||
} | |||
return index_iter->second; | |||
} | |||
} // namespace ge |