@@ -54,17 +54,23 @@ std::string num2str(T a) {
54
54
}
55
55
} // namespace
56
56
57
- bool NativePaddlePredictor::Init () {
57
+ bool NativePaddlePredictor::Init (std::shared_ptr<framework::Scope> scope ) {
58
58
VLOG (3 ) << " Predictor::init()" ;
59
59
60
60
if (config_.use_gpu ) {
61
61
place_ = paddle::platform::CUDAPlace (config_.device );
62
62
} else {
63
63
place_ = paddle::platform::CPUPlace ();
64
64
}
65
- paddle::framework::InitDevices (false );
65
+ if (scope) {
66
+ scope_ = scope;
67
+ sub_scope_ = &(scope->NewScope ());
68
+ } else {
69
+ paddle::framework::InitDevices (false );
70
+ scope_.reset (new paddle::framework::Scope ());
71
+ }
72
+
66
73
executor_.reset (new paddle::framework::Executor (place_));
67
- scope_.reset (new paddle::framework::Scope ());
68
74
69
75
// Initialize the inference program
70
76
if (!config_.model_dir .empty ()) {
@@ -83,20 +89,22 @@ bool NativePaddlePredictor::Init() {
83
89
return false ;
84
90
}
85
91
ctx_ = executor_->Prepare (*inference_program_, 0 );
86
-
87
- // Create temporary variables first, so that the first batch do not need to
88
- // create variables in the runtime. This is the logics of the old inference
89
- // API.
90
- // TODO(Superjomn) this should be modified when `Clone` is valid for
91
- // multi-thread application.
92
- executor_->CreateVariables (*inference_program_, scope_.get (), 0 );
92
+ executor_->CreateVariables (
93
+ *inference_program_, sub_scope_ ? sub_scope_ : scope_.get (), 0 );
93
94
94
95
// Get the feed_target_names and fetch_target_names
95
96
feed_target_names_ = inference_program_->GetFeedTargetNames ();
96
97
fetch_target_names_ = inference_program_->GetFetchTargetNames ();
97
98
return true ;
98
99
}
99
100
101
+ NativePaddlePredictor::~NativePaddlePredictor () {
102
+ if (sub_scope_) {
103
+ PADDLE_ENFORCE_NOT_NULL (scope_, " Should have parent scope!" );
104
+ scope_->DeleteScope (sub_scope_);
105
+ }
106
+ };
107
+
100
108
bool NativePaddlePredictor::Run (const std::vector<PaddleTensor> &inputs,
101
109
std::vector<PaddleTensor> *output_data) {
102
110
VLOG (3 ) << " Predictor::predict" ;
@@ -121,11 +129,12 @@ bool NativePaddlePredictor::Run(const std::vector<PaddleTensor> &inputs,
121
129
}
122
130
// Run the inference program
123
131
// if share variables, we need not create variables
124
- executor_->RunPreparedContext (ctx_.get (),
125
- scope_.get (),
126
- &feed_targets,
127
- &fetch_targets,
128
- false /* don't create variable eatch time */ );
132
+ executor_->RunPreparedContext (
133
+ ctx_.get (),
134
+ sub_scope_ != nullptr ? sub_scope_ : scope_.get (),
135
+ &feed_targets,
136
+ &fetch_targets,
137
+ false /* don't create variable eatch time */ );
129
138
if (!GetFetch (fetchs, output_data)) {
130
139
LOG (ERROR) << " fail to get fetchs" ;
131
140
return false ;
@@ -138,7 +147,7 @@ std::unique_ptr<PaddlePredictor> NativePaddlePredictor::Clone() {
138
147
VLOG (3 ) << " Predictor::clone" ;
139
148
std::unique_ptr<PaddlePredictor> cls (new NativePaddlePredictor (config_));
140
149
141
- if (!dynamic_cast <NativePaddlePredictor *>(cls.get ())->Init ()) {
150
+ if (!dynamic_cast <NativePaddlePredictor *>(cls.get ())->Init (scope_ )) {
142
151
LOG (ERROR) << " fail to call Init" ;
143
152
return nullptr ;
144
153
}
0 commit comments