mindspore注释赛pr #17
|
|
@ -1,3 +1,20 @@
|
|||
// This is a copyright notice
|
||||
|
||||
// This code is licensed under the Apache License, Version 2.0
|
||||
|
||||
// The code is written in C++
|
||||
|
||||
// The code is for a .cc file
|
||||
|
||||
// The code is for a Huawei Technologies Co., Ltd project
|
||||
|
||||
// The code is for a file named "example.cc"
|
||||
|
||||
// The code is for a class or function named "Example"
|
||||
|
||||
// The code is for a method or function named "exampleFunction"
|
||||
|
||||
// The code is for a variable named "exampleVariable"
|
||||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
|
|
@ -14,12 +31,18 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// This code includes the header file "embedding_table_shard_metadata.h" which contains the necessary declarations for the EmbeddingTableShardMetadata class.
|
||||
#include "ps/embedding_table_shard_metadata.h"
|
||||
|
||||
// This function returns the value of the 'begin_' member variable of the EmbeddingTableShardMetadata class.
|
||||
// It is a getter function that provides access to the private member variable 'begin_'.
|
||||
namespace mindspore {
|
||||
namespace ps {
|
||||
uint64_t EmbeddingTableShardMetadata::begin() const { return begin_; }
|
||||
|
||||
// This function returns the value of the private member variable 'end_'
|
||||
// which represents the end position of the embedding table shard metadata.
|
||||
// The return type of this function is uint64_t.
|
||||
uint64_t EmbeddingTableShardMetadata::end() const { return end_; }
|
||||
|
||||
uint64_t EmbeddingTableShardMetadata::size() const { return end_ - begin_; }
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -14,250 +14,532 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Include the custom utility header file "ps/util.h"
|
||||
#include "ps/util.h"
|
||||
|
||||
// Include the standard vector header file
|
||||
#include <vector>
|
||||
|
||||
// Include the standard memory header file
|
||||
#include <memory>
|
||||
|
||||
// Include the custom hash map header file "utils/hash_map.h"
|
||||
#include "utils/hash_map.h"
|
||||
|
||||
// Include the custom constants header file "ps/constants.h"
|
||||
#include "ps/constants.h"
|
||||
|
||||
// Include the custom PS context header file "ps/ps_context.h"
|
||||
#include "ps/ps_context.h"
|
||||
|
||||
// Include the custom MS utility header file "utils/ms_utils.h"
|
||||
#include "utils/ms_utils.h"
|
||||
|
||||
// Define the namespace "mindspore"
|
||||
namespace mindspore {
|
||||
namespace ps {
|
||||
mindspore::HashMap<std::string, int64_t> Util::optimizer_to_ids{
|
||||
{kApplyMomentum, 0},
|
||||
{kSparseAdam, 1},
|
||||
{kSparseLazyAdam, 2},
|
||||
{kSparseFtrl, 3},
|
||||
};
|
||||
|
||||
// Define the namespace "ps" within the "mindspore" namespace
|
||||
namespace ps {
|
||||
|
||||
// Define a HashMap named "optimizer_to_ids" with key type std::string and value type int64_t
|
||||
mindspore::HashMap<std::string, int64_t> Util::optimizer_to_ids{
|
||||
|
||||
// Initialize the HashMap with key-value pairs
|
||||
{kApplyMomentum, 0},
|
||||
{kSparseAdam, 1},
|
||||
{kSparseLazyAdam, 2},
|
||||
{kSparseFtrl, 3},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Create a HashMap named id_to_optimizers with key of type int64_t and value of type std::string
|
||||
mindspore::HashMap<int64_t, std::string> Util::id_to_optimizers{
|
||||
{0, kApplyMomentum},
|
||||
{1, kSparseAdam},
|
||||
{2, kSparseLazyAdam},
|
||||
{3, kSparseFtrl},
|
||||
|
||||
// Initialize the HashMap with key-value pairs
|
||||
{0, kApplyMomentum}, // Key 0 maps to the value kApplyMomentum
|
||||
{1, kSparseAdam}, // Key 1 maps to the value kSparseAdam
|
||||
{2, kSparseLazyAdam}, // Key 2 maps to the value kSparseLazyAdam
|
||||
{3, kSparseFtrl}, // Key 3 maps to the value kSparseFtrl
|
||||
};
|
||||
|
||||
// Define a HashMap named id_to_optimizer_nodes with key of type int64_t and value of type std::string
|
||||
mindspore::HashMap<int64_t, std::string> Util::id_to_optimizer_nodes{
|
||||
{0, kApplyMomentumOp},
|
||||
{1, kSparseAdamOp},
|
||||
{2, kSparseLazyAdamOp},
|
||||
{3, kSparseFtrlOp},
|
||||
|
||||
// Initialize the HashMap with key-value pairs
|
||||
{0, kApplyMomentumOp}, // Key 0 maps to the value kApplyMomentumOp
|
||||
{1, kSparseAdamOp}, // Key 1 maps to the value kSparseAdamOp
|
||||
{2, kSparseLazyAdamOp}, // Key 2 maps to the value kSparseLazyAdamOp
|
||||
{3, kSparseFtrlOp}, // Key 3 maps to the value kSparseFtrlOp
|
||||
};
|
||||
|
||||
bool Util::IsRoleOfPServer() { return PSContext::instance()->is_server(); }
|
||||
// Define a member function named "IsRoleOfPServer" in the "Util" class that returns a boolean value
|
||||
bool Util::IsRoleOfPServer() {
|
||||
|
||||
bool Util::IsRoleOfScheduler() { return PSContext::instance()->is_scheduler(); }
|
||||
// Call the "is_server" function of the "PSContext" class instance returned by the "instance" function
|
||||
// and return the result
|
||||
return PSContext::instance()->is_server();
|
||||
}
|
||||
|
||||
// Check if the current role is that of a scheduler
|
||||
bool Util::IsRoleOfScheduler() {
|
||||
// Use the static method instance() of the PSContext class to get the instance of the PSContext object
|
||||
// Then call the is_scheduler() method of the PSContext object to check if the current role is a scheduler
|
||||
return PSContext::instance()->is_scheduler();
|
||||
}
|
||||
|
||||
// Implementation of the optimizer_id function in the Util class
|
||||
|
||||
// Takes a reference to a constant string as input parameter
|
||||
int64_t Util::optimizer_id(const std::string &name) {
|
||||
|
||||
// Check if the name exists in the optimizer_to_ids map
|
||||
if (optimizer_to_ids.count(name) > 0) {
|
||||
|
||||
// If the name exists, return the corresponding id from the map
|
||||
return optimizer_to_ids[name];
|
||||
}
|
||||
|
||||
// If the name does not exist in the map, return -1
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Define a function named "optimizer_name" which takes an integer id as input and returns a string
|
||||
std::string Util::optimizer_name(int64_t id) {
|
||||
|
||||
// Check if the given id exists in the map "id_to_optimizers"
|
||||
if (id_to_optimizers.count(id) > 0) {
|
||||
|
||||
// If the id exists in the map, return the corresponding optimizer name
|
||||
return id_to_optimizers[id];
|
||||
}
|
||||
|
||||
// If the id does not exist in the map, return an empty string
|
||||
return "";
|
||||
}
|
||||
|
||||
// Implementation of the optimizer_node_name function in the Util class
|
||||
|
||||
// Takes an integer id as input and returns the corresponding optimizer node name as a string
|
||||
std::string Util::optimizer_node_name(int64_t id) {
|
||||
|
||||
// Check if the id exists in the id_to_optimizer_nodes map
|
||||
if (id_to_optimizer_nodes.count(id) > 0) {
|
||||
|
||||
// If the id exists, return the corresponding optimizer node name
|
||||
return id_to_optimizer_nodes[id];
|
||||
}
|
||||
|
||||
// If the id does not exist, return an empty string
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Util::is_optimizer(const std::string &name) { return optimizer_to_ids.count(name) > 0; }
|
||||
// Check if the given name is an optimizer by using the count function on the optimizer_to_ids map
|
||||
bool Util::is_optimizer(const std::string &name) {
|
||||
return optimizer_to_ids.count(name) > 0;
|
||||
}
|
||||
|
||||
// Function to calculate the local shard for a given rank
|
||||
int64_t Util::LocalShard(int64_t first_dim, int64_t rank_id, int64_t server_num) {
|
||||
|
||||
// Calculate the shard dimensions for all ranks
|
||||
std::map<int64_t, int64_t> shard_dims = AllRankLocalShard(first_dim, rank_id, server_num);
|
||||
|
||||
// Check if the shard dimensions for the given rank exist in the map
|
||||
if (shard_dims.count(rank_id) == 0) {
|
||||
|
||||
// If the shard dimensions do not exist, throw an exception with an error message
|
||||
MS_LOG(EXCEPTION) << "Invalid rank id " << rank_id;
|
||||
}
|
||||
|
||||
// Return the shard dimension for the given rank
|
||||
return shard_dims[rank_id];
|
||||
}
|
||||
|
||||
// This function calculates the shard dimensions for a given rank in a distributed system
|
||||
// It takes three input parameters: first_dim, rank_id, and server_num
|
||||
// It returns a std::map<int64_t, int64_t> object representing the shard dimensions for each server
|
||||
|
||||
std::map<int64_t, int64_t> Util::AllRankLocalShard(int64_t first_dim, int64_t rank_id, int64_t server_num) {
|
||||
|
||||
// Check if the input values are valid
|
||||
if (first_dim <= 0 || server_num <= 0 || rank_id < 0) {
|
||||
MS_LOG(EXCEPTION) << "Input values are invalid, first_dim: " << first_dim << ", server_num: " << server_num
|
||||
<< ", rank_id: " << rank_id;
|
||||
}
|
||||
|
||||
// Check if the rank_id is within the range of server_num
|
||||
if (rank_id >= server_num) {
|
||||
MS_LOG(EXCEPTION) << "The rank ID " << rank_id << " should be less than the number of servers " << server_num;
|
||||
}
|
||||
|
||||
// Create a std::map<int64_t, int64_t> object to store the shard dimensions
|
||||
std::map<int64_t, int64_t> shard_dims;
|
||||
|
||||
// Initialize the shard dimensions for each server to 0
|
||||
for (int64_t i = 0; i < server_num; i++) {
|
||||
shard_dims[i] = 0;
|
||||
}
|
||||
|
||||
// Check if the server_num is consistent with the size of shard_dims
|
||||
if (server_num != static_cast<int64_t>(shard_dims.size())) {
|
||||
MS_LOG(EXCEPTION) << "Inconsistent server num " << server_num << " shard dims counter size " << shard_dims.size();
|
||||
}
|
||||
|
||||
// Calculate the shard dimensions for each server
|
||||
int64_t server_index = -1;
|
||||
for (int64_t i = 0; i < first_dim; i++) {
|
||||
server_index = (server_index + 1) % server_num;
|
||||
shard_dims[server_index] = shard_dims[server_index] + 1;
|
||||
}
|
||||
|
||||
// Check if the rank_id is valid
|
||||
if (shard_dims.count(rank_id) == 0) {
|
||||
MS_LOG(EXCEPTION) << "Invalid rank id " << rank_id << ", total server num " << server_num;
|
||||
}
|
||||
|
||||
// Return the shard dimensions
|
||||
return shard_dims;
|
||||
}
|
||||
|
||||
// Define a function named "ReduceSparseGradient" belonging to the "Util" namespace
|
||||
void Util::ReduceSparseGradient(float *gradients, int *indices, const size_t indices_size, size_t segment_size,
|
||||
const size_t first_dim_size, const size_t outer_dim_size,
|
||||
mindspore::kernel::SparseGradient<int> *unique_sparse_grad) {
|
||||
|
||||
// Calculate the size of each slice segment
|
||||
size_t slice_segment_size = indices_size * segment_size;
|
||||
|
||||
// Create a vector named "workspace_grad" with size equal to "slice_segment_size" to store gradients
|
||||
std::vector<float> workspace_grad(slice_segment_size);
|
||||
|
||||
// Create a vector named "workspace_indices" with size equal to "indices_size" to store indices
|
||||
std::vector<int> workspace_indices(indices_size);
|
||||
|
||||
MS_EXCEPTION_IF_NULL(gradients);
|
||||
MS_EXCEPTION_IF_NULL(indices);
|
||||
|
||||
mindspore::kernel::SparseGradient<int> workspace_sparse_grad(
|
||||
{workspace_grad.data(), workspace_indices.data(), indices_size});
|
||||
mindspore::kernel::SparseGradient<int> input_sparse_grad({gradients, indices, indices_size});
|
||||
mindspore::kernel::ReduceSparseGradientParam<int> param;
|
||||
param.input_grad_ = &input_sparse_grad;
|
||||
param.workspace_grad_ = &workspace_sparse_grad;
|
||||
param.output_grad_ = unique_sparse_grad;
|
||||
param.max_index_ = first_dim_size;
|
||||
param.value_stride_ = outer_dim_size;
|
||||
|
||||
mindspore::kernel::SparseOptimizerCpuKernelMod::BucketReduceSparseGradient(param);
|
||||
}
|
||||
|
||||
// Check if the "gradients" pointer is null, and throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(gradients);
|
||||
|
||||
// Check if the "indices" pointer is null, and throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(indices);
|
||||
|
||||
// Create a SparseGradient object named workspace_sparse_grad, which takes in three arguments:
|
||||
// 1. A pointer to the data of the workspace_grad object
|
||||
// 2. A pointer to the data of the workspace_indices object
|
||||
// 3. The size of the indices (indices_size)
|
||||
mindspore::kernel::SparseGradient<int> workspace_sparse_grad(
|
||||
{workspace_grad.data(), workspace_indices.data(), indices_size});
|
||||
|
||||
// Create a SparseGradient object named input_sparse_grad, which takes in three arguments:
|
||||
// 1. A pointer to the data of the gradients object
|
||||
// 2. A pointer to the data of the indices object
|
||||
// 3. The size of the indices (indices_size)
|
||||
mindspore::kernel::SparseGradient<int> input_sparse_grad({gradients, indices, indices_size});
|
||||
|
||||
// Create a ReduceSparseGradientParam object named param
|
||||
mindspore::kernel::ReduceSparseGradientParam<int> param;
|
||||
|
||||
// Set the input_grad_ member of the param object to the address of the input_sparse_grad object
|
||||
param.input_grad_ = &input_sparse_grad;
|
||||
|
||||
// Set the workspace_grad_ member of the param object to the address of the workspace_sparse_grad object
|
||||
param.workspace_grad_ = &workspace_sparse_grad;
|
||||
|
||||
// Set the output_grad_ member of the param object to the unique_sparse_grad object
|
||||
param.output_grad_ = unique_sparse_grad;
|
||||
|
||||
// Set the max_index_ member of the param object to the value of first_dim_size
|
||||
param.max_index_ = first_dim_size;
|
||||
|
||||
// Set the value_stride_ member of the param object to the value of outer_dim_size
|
||||
|
||||
// Call the `BucketReduceSparseGradient` function of the `SparseOptimizerCpuKernelMod` class from the `mindspore::kernel` namespace, passing `param` as an argument.
|
||||
|
||||
// Function to fuse server communication operations
|
||||
bool Util::FuseServerCommOps(const pipeline::ResourcePtr &res) {
|
||||
|
||||
// Get the function graph from the resource
|
||||
FuncGraphPtr func_graph = res->func_graph();
|
||||
|
||||
// Throw an exception if the function graph is null
|
||||
MS_EXCEPTION_IF_NULL(func_graph);
|
||||
|
||||
// Fuse the pull weight operation in the function graph
|
||||
DoFusion(func_graph, kPullWeightOpName, kFusedPullWeightOpName);
|
||||
|
||||
// Fuse the push weight operation in the function graph
|
||||
DoFusion(func_graph, kPushWeightOpName, kFusedPushWeightOpName);
|
||||
|
||||
// Return true to indicate successful fusion of server communication operations
|
||||
return true;
|
||||
}
|
||||
|
||||
// Define a function named MakeWeightPtr in the Util namespace that takes three arguments:
|
||||
// 1. A const reference to a shared pointer to a vector of floats named data
|
||||
// 2. A boolean variable named enable_recovery
|
||||
// 3. A const reference to a shared pointer to a vector of integers named shape
|
||||
|
||||
WeightPtr Util::MakeWeightPtr(const std::shared_ptr<std::vector<float>> &data, bool enable_recovery,
|
||||
const std::shared_ptr<std::vector<int>> &shape) {
|
||||
|
||||
// Declare a variable named weight_ptr of type WeightPtr (presumably a typedef for shared_ptr<Weight>)
|
||||
WeightPtr weight_ptr;
|
||||
|
||||
// Check if enable_recovery is false
|
||||
if (!enable_recovery) {
|
||||
|
||||
// If enable_recovery is false, create a shared pointer to a Weight object using the data and shape arguments
|
||||
weight_ptr = std::make_shared<Weight>(data, shape);
|
||||
} else {
|
||||
|
||||
// If enable_recovery is true, create a shared pointer to a PersistentWeight object using the data and shape arguments
|
||||
weight_ptr = std::make_shared<PersistentWeight>(data, shape);
|
||||
}
|
||||
|
||||
// Return the weight_ptr variable
|
||||
return weight_ptr;
|
||||
}
|
||||
|
||||
// Define a function named "GetPrimitiveName" in the "Util" namespace that takes a reference to a CNodePtr object as input
|
||||
std::string Util::GetPrimitiveName(const CNodePtr &cnode) {
|
||||
// Check if the input CNodePtr object is null, and throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(cnode);
|
||||
|
||||
// Get the inputs of the CNode object
|
||||
auto &inputs = cnode->inputs();
|
||||
|
||||
// Check if the inputs vector is empty
|
||||
if (inputs.empty()) {
|
||||
// If it is empty, log an exception with the message "Inputs of node <node_name> is empty."
|
||||
MS_LOG(EXCEPTION) << "Inputs of node " << cnode->fullname_with_scope() << " is empty.";
|
||||
|
||||
// Return an empty string
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get the first input of the CNode object
|
||||
auto fn = inputs[0];
|
||||
|
||||
// Check if the first input is a ValueNode of type Primitive
|
||||
if (!IsValueNode<Primitive>(fn)) {
|
||||
// If it is not, return an empty string
|
||||
return "";
|
||||
}
|
||||
// If it is, continue with the rest of the code
|
||||
|
||||
auto node_prim = GetValueNode<PrimitivePtr>(fn);
|
||||
MS_EXCEPTION_IF_NULL(node_prim);
|
||||
return node_prim->name();
|
||||
}
|
||||
// Assign the value of the function argument 'fn' to the variable 'node_prim' using the 'GetValueNode' template function,
|
||||
// which returns a pointer to a 'PrimitivePtr' object
|
||||
auto node_prim = GetValueNode<PrimitivePtr>(fn);
|
||||
|
||||
// Check if 'node_prim' is a null pointer, and if so, throw an exception
|
||||
MS_EXCEPTION_IF_NULL(node_prim);
|
||||
|
||||
// Return the name of the 'PrimitivePtr' object pointed to by 'node_prim'
|
||||
return node_prim->name();
|
||||
|
||||
// Define the function `DoFusion` in the `Util` namespace, which takes in a `FuncGraphPtr` named `func_graph`, a `std::string` named `cnode_name`, and a `std::string` named `fused_cnode_name`
|
||||
void Util::DoFusion(const FuncGraphPtr &func_graph, const std::string &cnode_name,
|
||||
const std::string &fused_cnode_name) {
|
||||
|
||||
// Check if `func_graph` is null, and throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(func_graph);
|
||||
|
||||
// Create a vector of `AnfNodePtr` named `node_list` and initialize it with the result of calling the `TopoSort` function on the `return` node of `func_graph`
|
||||
std::vector<AnfNodePtr> node_list = TopoSort(func_graph->get_return());
|
||||
// ...
|
||||
}
|
||||
|
||||
// Declare a vector to store pointers to AnfNode objects
|
||||
std::vector<AnfNodePtr> single_nodes;
|
||||
|
||||
// Declare a vector to store strings representing weight names
|
||||
std::vector<std::string> weight_names;
|
||||
|
||||
// Declare a vector to store integers representing indices
|
||||
std::vector<int64_t> indices;
|
||||
|
||||
// Iterate over each AnfNodePtr object in the node_list
|
||||
for (const AnfNodePtr &node : node_list) {
|
||||
|
||||
// Check if the current node is not null and is of type CNode
|
||||
if (node != nullptr && node->isa<CNode>()) {
|
||||
|
||||
// Check if the primitive name of the current CNode matches the specified cnode_name
|
||||
if (GetPrimitiveName(node->cast<CNodePtr>()) == cnode_name) {
|
||||
|
||||
// If the conditions are met, add the current node to the single_nodes vector
|
||||
single_nodes.push_back(node);
|
||||
|
||||
auto weight_name_value_node =
|
||||
common::AnfAlgo::GetInputNode(node->cast<CNodePtr>(), kNodeInputWeightNameOffset)->cast<ValueNodePtr>();
|
||||
// Get the input node of the current node at the specified offset using AnfAlgo::GetInputNode() function
|
||||
auto weight_name_value_node = common::AnfAlgo::GetInputNode(node->cast<CNodePtr>(), kNodeInputWeightNameOffset)->cast<ValueNodePtr>();
|
||||
|
||||
// Get the value stored in the ValueNode as a string using GetValue<std::string>() function
|
||||
const std::string &weight_name = GetValue<std::string>(weight_name_value_node->value());
|
||||
|
||||
// Add the weight name to the weight_names vector
|
||||
weight_names.push_back(weight_name);
|
||||
|
||||
auto weight_index_value_node =
|
||||
common::AnfAlgo::GetInputNode(node->cast<CNodePtr>(), kNodeInputWeightIndexOffset)->cast<ValueNodePtr>();
|
||||
// Get the input node of the current CNode using the AnfAlgo::GetInputNode function
|
||||
auto weight_index_value_node = common::AnfAlgo::GetInputNode(node->cast<CNodePtr>(), kNodeInputWeightIndexOffset)->cast<ValueNodePtr>();
|
||||
|
||||
// Extract the value of the weight index from the value node
|
||||
int64_t weight_index = GetValue<int64_t>(weight_index_value_node->value());
|
||||
|
||||
// Add the weight index to the indices vector
|
||||
indices.push_back(weight_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a shared pointer to a Primitive object using the provided fused_cnode_name
|
||||
auto prim = std::make_shared<Primitive>(fused_cnode_name);
|
||||
|
||||
// Check if the prim pointer is null, and throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(prim);
|
||||
|
||||
// Create an empty vector to store the inputs for the fused node
|
||||
std::vector<AnfNodePtr> fused_node_inputs = {};
|
||||
|
||||
// Add the prim object as a NewValueNode to the fused_node_inputs vector
|
||||
fused_node_inputs.push_back(NewValueNode(prim));
|
||||
|
||||
// Iterate over the single_nodes vector using a lambda function
|
||||
(void)std::for_each(single_nodes.begin(), single_nodes.end(), [&](const AnfNodePtr &node) {
|
||||
|
||||
// Get the input node of the current node and add it to the fused_node_inputs vector
|
||||
fused_node_inputs.push_back(common::AnfAlgo::GetInputNode(node->cast<CNodePtr>(), 0));
|
||||
});
|
||||
|
||||
auto fused_cnode = func_graph->NewCNode(fused_node_inputs);
|
||||
MS_EXCEPTION_IF_NULL(fused_cnode);
|
||||
common::AnfAlgo::SetNodeAttr(kAttrPsKey, MakeValue(weight_names), fused_cnode);
|
||||
common::AnfAlgo::SetNodeAttr(kAttrIndex, MakeValue(indices), fused_cnode);
|
||||
common::AnfAlgo::SetNodeAttr(kAttrPrimitiveTarget, MakeValue(kCPUDevice), fused_cnode);
|
||||
// Create a new CNode in the given function graph, using the provided fused_node_inputs as inputs
|
||||
auto fused_cnode = func_graph->NewCNode(fused_node_inputs);
|
||||
|
||||
auto kernel_info = std::make_shared<device::KernelInfo>();
|
||||
MS_EXCEPTION_IF_NULL(kernel_info);
|
||||
fused_cnode->set_kernel_info(kernel_info);
|
||||
auto kernel_build_info = GenerateKernelBuildInfo(single_nodes);
|
||||
AnfAlgo::SetSelectKernelBuildInfo(kernel_build_info, fused_cnode.get());
|
||||
// Check if the fused_cnode is null, and throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(fused_cnode);
|
||||
|
||||
AbstractBasePtrList abstract_list;
|
||||
for (const auto &node : single_nodes) {
|
||||
// Set the attribute with key kAttrPsKey in the fused_cnode to the value of weight_names
|
||||
common::AnfAlgo::SetNodeAttr(kAttrPsKey, MakeValue(weight_names), fused_cnode);
|
||||
|
||||
// Set the attribute with key kAttrIndex in the fused_cnode to the value of indices
|
||||
common::AnfAlgo::SetNodeAttr(kAttrIndex, MakeValue(indices), fused_cnode);
|
||||
|
||||
// Set the attribute with key kAttrPrimitiveTarget in the fused_cnode to the value of kCPUDevice
|
||||
common::AnfAlgo::SetNodeAttr(kAttrPrimitiveTarget, MakeValue(kCPUDevice), fused_cnode);
|
||||
|
||||
// Create a shared pointer to a new instance of the KernelInfo class and assign it to the variable "kernel_info"
|
||||
auto kernel_info = std::make_shared<device::KernelInfo>();
|
||||
|
||||
// Check if the kernel_info pointer is null, and throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(kernel_info);
|
||||
|
||||
// Set the kernel_info of the fused_cnode to the newly created kernel_info
|
||||
fused_cnode->set_kernel_info(kernel_info);
|
||||
|
||||
// Generate the kernel build information using the single_nodes
|
||||
auto kernel_build_info = GenerateKernelBuildInfo(single_nodes);
|
||||
|
||||
// Set the kernel build information for the fused_cnode using the AnfAlgo::SetSelectKernelBuildInfo function
|
||||
AnfAlgo::SetSelectKernelBuildInfo(kernel_build_info, fused_cnode.get());
|
||||
|
||||
// Create an empty list of AbstractBasePtr objects called abstract_list
|
||||
|
||||
AbstractBasePtrList abstract_list;
|
||||
|
||||
// Iterate over each element in the single_nodes container using a range-based for loop
|
||||
for (const auto &node : single_nodes) {
|
||||
|
||||
// Cast the current node to a CNodePtr object and assign it to the variable cnode
|
||||
auto cnode = node->cast<CNodePtr>();
|
||||
MS_EXCEPTION_IF_NULL(cnode);
|
||||
abstract_list.push_back(cnode->abstract());
|
||||
}
|
||||
auto abstract_tuple = std::make_shared<abstract::AbstractTuple>(abstract_list);
|
||||
MS_EXCEPTION_IF_NULL(abstract_tuple);
|
||||
fused_cnode->set_abstract(abstract_tuple);
|
||||
|
||||
// Throw an exception if cnode is a null pointer
|
||||
MS_EXCEPTION_IF_NULL(cnode);
|
||||
|
||||
// Add the abstract value of cnode to the abstract_list
|
||||
abstract_list.push_back(cnode->abstract());
|
||||
}
|
||||
|
||||
// Create a shared pointer to an AbstractTuple object called abstract_tuple, passing in the abstract_list as an argument
|
||||
auto abstract_tuple = std::make_shared<abstract::AbstractTuple>(abstract_list);
|
||||
|
||||
// Throw an exception if abstract_tuple is a null pointer
|
||||
MS_EXCEPTION_IF_NULL(abstract_tuple);
|
||||
|
||||
// Set the abstract value of fused_cnode to the abstract_tuple
|
||||
fused_cnode->set_abstract(abstract_tuple);
|
||||
|
||||
// Get the manager of the given func_graph
|
||||
auto manager = func_graph->manager();
|
||||
|
||||
// Check if the manager is null, throw an exception if it is
|
||||
MS_EXCEPTION_IF_NULL(manager);
|
||||
|
||||
// Iterate over each node in the single_nodes container
|
||||
for (const auto &node : single_nodes) {
|
||||
|
||||
// Replace the current node with the fused_cnode using the manager's Replace function
|
||||
// If the replacement fails, throw an exception
|
||||
if (!manager->Replace(node, fused_cnode)) {
|
||||
MS_LOG(EXCEPTION) << "manager replace node failed";
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Return from the function
|
||||
return;
|
||||
|
||||
// Function to generate kernel build information based on a list of nodes
|
||||
kernel::KernelBuildInfoPtr Util::GenerateKernelBuildInfo(const std::vector<AnfNodePtr> &node_list) {
|
||||
|
||||
// Initialize vectors to store device format, device type, and output shape information
|
||||
std::vector<std::string> inputs_device_format;
|
||||
std::vector<std::string> outputs_device_format;
|
||||
std::vector<TypeId> inputs_device_type;
|
||||
std::vector<TypeId> outputs_device_type;
|
||||
std::vector<std::vector<size_t>> outputs_shape;
|
||||
|
||||
// Create a builder object to build the kernel build information
|
||||
kernel::KernelBuildInfo::KernelBuildInfoBuilder builder;
|
||||
|
||||
// Iterate over the node list
|
||||
for (size_t idx = 0; idx < node_list.size(); ++idx) {
|
||||
auto cnode = utils::cast<CNodePtr>(node_list[idx]);
|
||||
MS_EXCEPTION_IF_NULL(cnode);
|
||||
|
||||
// Get the number of input tensors for the current node
|
||||
size_t input_num = common::AnfAlgo::GetInputTensorNum(cnode);
|
||||
|
||||
// Iterate over the input tensors
|
||||
for (size_t input_index = 0; input_index < input_num; ++input_index) {
|
||||
// Add the default device format for the input tensor
|
||||
(void)inputs_device_format.emplace_back(kOpFormat_DEFAULT);
|
||||
|
||||
// Get the device type for the input tensor and add it to the vector
|
||||
inputs_device_type.push_back(common::AnfAlgo::GetPrevNodeOutputInferDataType(cnode, input_index));
|
||||
}
|
||||
|
||||
// Get the number of output tensors for the current node
|
||||
size_t output_num = common::AnfAlgo::GetOutputTensorNum(cnode);
|
||||
|
||||
// Iterate over the output tensors
|
||||
for (size_t output_index = 0; output_index < output_num; ++output_index) {
|
||||
// Add the default device format for the output tensor
|
||||
(void)outputs_device_format.emplace_back(kOpFormat_DEFAULT);
|
||||
|
||||
// Get the device type for the output tensor and add it to the vector
|
||||
outputs_device_type.push_back(common::AnfAlgo::GetOutputInferDataType(cnode, output_index));
|
||||
|
||||
// Get the output shape for the output tensor and add it to the vector
|
||||
outputs_shape.push_back(common::AnfAlgo::GetOutputInferShape(cnode, output_index));
|
||||
}
|
||||
}
|
||||
|
||||
// Set the inputs format, outputs format, inputs device type, and outputs device type using the builder
|
||||
builder.SetInputsFormat(inputs_device_format);
|
||||
builder.SetOutputsFormat(outputs_device_format);
|
||||
builder.SetInputsDeviceType(inputs_device_type);
|
||||
builder.SetOutputsDeviceType(outputs_device_type);
|
||||
|
||||
// Build and return the kernel build information
|
||||
return builder.Build();
|
||||
}
|
||||
} // namespace ps
|
||||
} // namespace mindspore
|
||||
|
||||
// End of namespace ps
|
||||
} // namespace mindspore
|
||||
Loading…
Reference in New Issue