mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
fusion fix
This commit is contained in:
@@ -154,6 +154,9 @@ void Net::Impl::clear()
|
||||
|
||||
prepared = false;
|
||||
finalizeLayers = true;
|
||||
finalized = false;
|
||||
fusedSnapshotValid = false;
|
||||
fusedSnapshot.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -1419,6 +1422,9 @@ void Net::Impl::getLayerShapes(const ShapesVec& netInputShapes,
|
||||
LayerShapes& shapes)
|
||||
{
|
||||
if (mainGraph) {
|
||||
// Fusion emits block-layout layers; their TransformLayout conversions are
|
||||
// only inserted by finalize(), so shape inference must run post-finalize.
|
||||
finalize();
|
||||
std::vector<MatShape> shapeCache;
|
||||
std::vector<int> typeCache;
|
||||
CV_Assert(layerId == 0);
|
||||
@@ -2551,6 +2557,7 @@ int64 Net::Impl::getFLOPS(const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<MatType>& netInputTypes) /*const*/
|
||||
{
|
||||
if (mainGraph) {
|
||||
finalize();
|
||||
// The new graph engine executes in FP32 on CPU regardless of the requested
|
||||
// target, so FP16 input types (e.g. coming from an OpenCL FP16 target) would be
|
||||
// rejected by Layer::getTypes(). Normalize them to FP32 for shape/FLOPS inference.
|
||||
@@ -2584,6 +2591,7 @@ int64 Net::Impl::getFLOPS(
|
||||
const std::vector<MatType>& netInputTypes) /*const*/
|
||||
{
|
||||
if (mainGraph) {
|
||||
finalize();
|
||||
std::vector<MatType> inputTypes = filterFP16InputTypes(netInputTypes);
|
||||
LayerShapes shapes;
|
||||
std::vector<MatShape> shapeCache;
|
||||
|
||||
@@ -144,6 +144,18 @@ struct Net::Impl : public detail::NetImplBase
|
||||
bool prepared; // need to rerun graph transformations/optimizations
|
||||
bool finalizeLayers; // need to initialize each layer
|
||||
bool finalized = false; // executors have been selected for the current backend/target
|
||||
|
||||
// Post-fusion (pre block-layout) snapshot so finalize() can re-run from a clean
|
||||
// state on a backend/target change; useBlockLayout() is destructive and must
|
||||
// run after backend assignment (see deviceOp handling in graph_block_layout.cpp).
|
||||
struct FusedGraphSnapshot {
|
||||
Ptr<Graph> graph;
|
||||
std::vector<Ptr<LayerInfo> > prog;
|
||||
std::vector<std::vector<Arg> > inputs;
|
||||
std::vector<std::vector<Arg> > outputs;
|
||||
};
|
||||
bool fusedSnapshotValid = false;
|
||||
std::vector<FusedGraphSnapshot> fusedSnapshot;
|
||||
std::vector<Ptr<BackendWrapper> > argWrappers;
|
||||
std::vector<const void*> argWrapperData;
|
||||
TracingMode tracingMode;
|
||||
@@ -426,6 +438,9 @@ struct Net::Impl : public detail::NetImplBase
|
||||
void finalize();
|
||||
// Selects executors for a single graph (recursing into subgraphs).
|
||||
void finalizeGraph(const Ptr<Graph>& graph, bool useCUDA);
|
||||
// Save/restore the fused graph so finalize() is re-entrant across backend changes.
|
||||
void saveFusedSnapshot();
|
||||
void restoreFusedSnapshot();
|
||||
#ifdef HAVE_CUDA
|
||||
Ptr<BackendWrapper> getCudaArgWrapper(Arg arg, Mat& hostMat);
|
||||
#endif
|
||||
|
||||
@@ -624,6 +624,41 @@ void Net::Impl::finalizeGraph(const Ptr<Graph>& graph, bool useCUDA)
|
||||
}
|
||||
}
|
||||
|
||||
void Net::Impl::saveFusedSnapshot()
|
||||
{
|
||||
fusedSnapshot.clear();
|
||||
for (const Ptr<Graph>& g : allgraphs) {
|
||||
FusedGraphSnapshot snap;
|
||||
snap.graph = g;
|
||||
const std::vector<Ptr<LayerInfo> >& prog = g->prog();
|
||||
snap.prog = prog;
|
||||
snap.inputs.reserve(prog.size());
|
||||
snap.outputs.reserve(prog.size());
|
||||
for (const Ptr<LayerInfo>& op : prog) {
|
||||
snap.inputs.push_back(op ? op->inputs : std::vector<Arg>());
|
||||
snap.outputs.push_back(op ? op->outputs : std::vector<Arg>());
|
||||
}
|
||||
fusedSnapshot.push_back(std::move(snap));
|
||||
}
|
||||
}
|
||||
|
||||
void Net::Impl::restoreFusedSnapshot()
|
||||
{
|
||||
// Roll the graph back to its post-fusion state: undo the layer-input rewiring
|
||||
// and remove the TransformLayout ops inserted by a previous useBlockLayout().
|
||||
for (const FusedGraphSnapshot& snap : fusedSnapshot) {
|
||||
for (size_t i = 0; i < snap.prog.size(); i++) {
|
||||
const Ptr<LayerInfo>& op = snap.prog[i];
|
||||
if (!op)
|
||||
continue;
|
||||
op->inputs = snap.inputs[i];
|
||||
op->outputs = snap.outputs[i];
|
||||
}
|
||||
snap.graph->setProg(snap.prog);
|
||||
}
|
||||
totalLayers = updateGraphOfs(mainGraph, 0, true);
|
||||
}
|
||||
|
||||
void Net::Impl::finalize()
|
||||
{
|
||||
#ifdef HAVE_ONNXRUNTIME
|
||||
@@ -637,6 +672,15 @@ void Net::Impl::finalize()
|
||||
if (finalized)
|
||||
return;
|
||||
|
||||
// Snapshot the fused graph once so finalize() can re-run cleanly on a
|
||||
// backend/target change (block layout + buffer assignment are destructive).
|
||||
if (!fusedSnapshotValid) {
|
||||
saveFusedSnapshot();
|
||||
fusedSnapshotValid = true;
|
||||
} else {
|
||||
restoreFusedSnapshot();
|
||||
}
|
||||
|
||||
bool useCUDA = false;
|
||||
#ifdef HAVE_CUDA
|
||||
argWrappers.clear();
|
||||
|
||||
Reference in New Issue
Block a user