系列文章目录
MNN createFromBuffer(一)
MNN createRuntime(二)
MNN createSession 之 Schedule(三)
MNN createSession 之创建流水线后端(四)
MNN Session::resize 之流水线编码(五)
MNN Session 创建执行器(六)
文章目录
- 系列文章目录
- 1、createSession
- 1.1 createMultiPathSession
- 1.1.1 Session::resize
1、createSession
依据 ScheduleConfig 和 RuntimeInfo 创建会话。
// source/core/Interpreter.cpp
Session* Interpreter::createSession(const ScheduleConfig& config, const RuntimeInfo& runtime) {
return createMultiPathSession({config}, runtime);
}
1.1 createMultiPathSession
// source/core/Interpreter.cpp
Session* Interpreter::createMultiPathSession(const std::vector<ScheduleConfig>& configs, const RuntimeInfo& runtime) {
// ...
auto result = newSession.get();
auto validForResize = info.validForResize;
if (validForResize && mNet->modes.inputMode == Session_Input_Inside && mNet->modes.resizeMode == Session_Resize_Direct) {
result->resize();
}
if ((!mNet->cacheFile.empty()) && (!valid) && mNet->modes.backendMode == Session_Backend_Fix) {
// Try to save extra cache
auto buffer = result->getCache();
if (buffer.first != nullptr && buffer.second > 0) {
MNN_PRINT("Write cache to %s, size = %zu\n", mNet->cacheFile.c_str(), buffer.second);
writeCacheFile(mNet, buffer);
mNet->lastCacheSize = buffer.second;
// Write Cache
cacheMode = cacheMode | 2;
}
}
// Reset cache
result->loadCache(nullptr, 0);
mNet->sessions.emplace_back(std::move(newSession));
#ifdef MNN_INTERNAL_ENABLED
int precision = BackendConfig::Precision_Normal;
if (nullptr != configs[0].backendConfig) {
precision = configs[0].backendConfig->precision;
}
int mode = configs[0].mode;
mNet->sessionInfo.insert(std::make_pair(result, std::make_tuple(precision, mode)));
if (shouldLog(FREQ_HIGH)) {
std::map<std::string, std::string> metrics = mNet->basicLogginData;
metrics.emplace("UUID", mNet->uuid);
metrics.emplace("Time", std::to_string((float)_timer.durationInUs() / 1024.0f));
metrics.emplace("Backend", std::to_string(configs[0].type));
metrics.emplace("Precision", std::to_string(precision));
metrics.emplace("Mode", std::to_string(mode));
metrics.emplace("Cache", std::to_string(cacheMode));
metrics.emplace("CacheSize", std::to_string((float)(mNet->lastCacheSize / 1024.0f)));
metrics.emplace("ModelSize", std::to_string ((float)mNet->buffer.size() / 1024.0f / 1024.0f));
metrics.emplace("Usage", std::to_string((int) mNet->net->usage()));
metrics.emplace("API", "Interpreter::createMultiPathSession");
logAsync(metrics);
}
#endif // MNN_INTERNAL_ENABLED
return result;
}
1.1.1 Session::resize
// source/core/Session.cpp
ErrorCode Session::resize() {
// ...
if (mNeedMalloc) {
// Set needResize = true for easy for judge in runSession when error
mNeedResize = true;
// Turn Pipeline to Command Buffer and Malloc resource
// TODO: Separate Schedule and Malloc
bool forbidReplace = permitCodegen;
if (mInfo.constReplaceBackend != nullptr) {
forbidReplace = true;
}
for (auto& iter : mPipelines) {
auto error = iter->allocMemory(firstMalloc, forbidReplace);
if (NO_ERROR != error) {
return error;
}
}
if(mMemoryUsageMode == Interpreter::Session_Memory_Collect) {
#ifdef LOG_VERBOSE
float memory = 0.0f;
#endif
for (auto& iter : mRuntime.first) {
iter.second->onGabageCollect(0);
#ifdef LOG_VERBOSE
memory += iter.second->onGetMemoryInMB();
#endif
}
#ifdef LOG_VERBOSE
FUNC_PRINT_ALL(memory, f);
#endif
}
mNeedMalloc = false;
mNeedResize = false;
}
#ifdef LOG_VERBOSE
MNN_PRINT("session after resize\n");
for (auto& iter : mOutputs) {
auto& outputTensor = iter.second;
MNN_PRINT("output name:%s, ptr:%p,shape:", iter.first.c_str(), outputTensor);
outputTensor->printShape();
MNN_PRINT("\n");
}
#endif
return NO_ERROR;
}