return ker_fused;
}
-// Will be deprecated
-moco::tf::TFConst *create_kernal_from_fuse_mulparam(loco::Graph *graph, moco::tf::TFConst *ker,
- moco::tf::TFConst *mulparam)
-{
- auto ker_shape_inf = ker->annot<moco::tf::ShapeInferenceData>();
- assert(ker_shape_inf);
- auto ker_shape = ker_shape_inf->tensor_shape();
-
- auto mulparam_shape_inf = mulparam->annot<moco::tf::ShapeInferenceData>();
- assert(mulparam_shape_inf != nullptr);
- auto mulparam_shape = mulparam_shape_inf->tensor_shape();
-
- assert(ker_shape.rank() == 4);
- assert(mulparam_shape.rank() == 1);
- assert(ker_shape.dim(3).value() == mulparam_shape.dim(0).value());
-
- // create new ker_fused with same size of ker
- auto ker_fused = graph->nodes()->create<moco::tf::TFConst>();
- ker_fused->dtype(loco::DataType::FLOAT32);
- copy_shape(ker, ker_fused);
- auto ker_num_elements = ker->size<loco::DataType::FLOAT32>();
- ker_fused->size<loco::DataType::FLOAT32>(ker_num_elements);
-
- // TensorFlow Kernel has HWIO format
- // Broadcast Mul vector to Kernel tensor by the Output
- const uint32_t ker_height = ker_shape.dim(0).value();
- const uint32_t ker_width = ker_shape.dim(1).value();
- const uint32_t ker_input = ker_shape.dim(2).value();
- const uint32_t ker_output = ker_shape.dim(3).value();
-
- for (uint32_t ker_y = 0; ker_y < ker_height; ++ker_y)
- {
- for (uint32_t ker_x = 0; ker_x < ker_width; ++ker_x)
- {
- for (uint32_t in_ch = 0; in_ch < ker_input; ++in_ch)
- {
- uint32_t num_items = ((ker_y * ker_width + ker_x) * ker_input + in_ch) * ker_output;
- for (uint32_t out_ch = 0; out_ch < ker_output; ++out_ch)
- {
- auto mulparam_v = mulparam->at<loco::DataType::FLOAT32>(out_ch);
- auto ker_v = ker->at<loco::DataType::FLOAT32>(num_items + out_ch);
- ker_fused->at<loco::DataType::FLOAT32>(num_items + out_ch) = ker_v * mulparam_v;
- }
- }
- }
- }
-
- return ker_fused;
-}
-
/**
* @brief Create a fused convolution opertion from kernel of fused mulparam
* @return Fused convolution operation
moco::tf::TFConst *mulparam = nullptr;
moco::tf::TFNode *precedingOp = nullptr;
- // TODO support FullyConnected
if (xc != nullptr)
{
assert(mulparam->dtype() == loco::DataType::FLOAT32);
+ // TODO support FullyConnected
moco::tf::TFNode *fused_node = nullptr;
if (auto conv2d = dynamic_cast<moco::tf::TFConv2D *>(precedingOp))
fused_node = fused_conv_node<FuseType::Conv2D, moco::tf::TFConv2D>(graph, mulparam, conv2d);
// TODO check if need to disconnect
// node->x(nullptr);
// node->y(nullptr);
- // conv2d->ifm(nullptr);
- // conv2d->ker(nullptr);
+ // fused_node->ifm(nullptr);
+ // fused_node->ker(nullptr);
return true;
}
moco::tf::TFConst *addparam = nullptr;
moco::tf::TFNode *precedingOp = nullptr;
- moco::tf::TFBiasAdd *biasadd = nullptr;
- // TODO support FullyConnected
if (xc != nullptr)
{
return false;
}
+ // TODO support FullyConnected
+ moco::tf::TFBiasAdd *biasadd = nullptr;
if (auto conv2d = dynamic_cast<moco::tf::TFConv2D *>(precedingOp))
- {
biasadd = create_biasadd_node<moco::tf::TFConv2D>(graph, addparam, conv2d);
- }
else if (auto dw_conv2d = dynamic_cast<moco::tf::TFDepthwiseConv2dNative *>(precedingOp))
- {
biasadd = create_biasadd_node<moco::tf::TFDepthwiseConv2dNative>(graph, addparam, dw_conv2d);
- }
else if (auto old_bias_add = dynamic_cast<moco::tf::TFBiasAdd *>(precedingOp))
- {
biasadd = old_bias_add;
- }
if (biasadd == nullptr)
{