Commit a861a730 authored by liucong's avatar liucong
Browse files

提交loadcopy为fasle的工程示例

parent 8510437f
...@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.5) ...@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.5)
project(ResNet50) project(ResNet50)
# 设置编译器 # 设置编译器
set(CMAKE_CXX_COMPILER g++) set(CMAKE_CXX_COMPILER hipcc)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=c++17) # 2.2版本以上需要c++17 set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=c++17) # 2.2版本以上需要c++17
set(CMAKE_BUILD_TYPE release) set(CMAKE_BUILD_TYPE release)
......
...@@ -50,11 +50,8 @@ if __name__ == '__main__': ...@@ -50,11 +50,8 @@ if __name__ == '__main__':
use_int8 = False use_int8 = False
use_fp16 = False use_fp16 = False
# 设置最大输入shape
maxInput={"data":[1,3,224,224]}
# 加载模型 # 加载模型
model = migraphx.parse_onnx("../Resource/Models/resnet50-v2-7.onnx", map_input_dims=maxInput) model = migraphx.parse_onnx("../Resource/Models/resnet50-v2-7.onnx")
# 获取模型输入/输出节点信息 # 获取模型输入/输出节点信息
print("inputs:") print("inputs:")
......
...@@ -57,11 +57,8 @@ if __name__ == '__main__': ...@@ -57,11 +57,8 @@ if __name__ == '__main__':
use_int8 = False use_int8 = False
use_fp16 = False use_fp16 = False
# 设置最大输入shape
maxInput={"data":[1,3,224,224]}
# 加载模型 # 加载模型
model = migraphx.parse_onnx("../Resource/Models/resnet50-v2-7.onnx", map_input_dims=maxInput) model = migraphx.parse_onnx("../Resource/Models/resnet50-v2-7.onnx")
# 获取模型输入/输出节点信息 # 获取模型输入/输出节点信息
print("inputs:") print("inputs:")
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <migraphx/onnx.hpp> #include <migraphx/onnx.hpp>
#include <migraphx/gpu/target.hpp> #include <migraphx/gpu/target.hpp>
#include <migraphx/quantization.hpp> #include <migraphx/quantization.hpp>
#include <migraphx/gpu/hip.hpp> #include <hip/hip_runtime_api.h>
#include <Filesystem.h> #include <Filesystem.h>
#include <SimpleLog.h> #include <SimpleLog.h>
#include <algorithm> #include <algorithm>
...@@ -21,16 +21,6 @@ Classifier::~Classifier() ...@@ -21,16 +21,6 @@ Classifier::~Classifier()
configurationFile.release(); configurationFile.release();
} }
std::unordered_map<std::string, migraphx::argument> Classifier::CreateOutputData(migraphx::program &p)
{
std::unordered_map<std::string, migraphx::argument> outputData;
for (auto x : p.get_outputs())
{
outputData[x.first] = migraphx::gpu::allocate_gpu(x.second);
}
return outputData;
}
ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializationParameterOfClassifier) ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializationParameterOfClassifier)
{ {
// 读取配置文件 // 读取配置文件
...@@ -54,17 +44,13 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat ...@@ -54,17 +44,13 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
useFP16=(bool)(int)netNode["UseFP16"]; useFP16=(bool)(int)netNode["UseFP16"];
useoffloadcopy=(bool)(int)netNode["Useoffloadcopy"]; useoffloadcopy=(bool)(int)netNode["Useoffloadcopy"];
// 设置最大输入shape
migraphx::onnx_options onnx_options;
onnx_options.map_input_dims["data"]={1,3,224,224};
// 加载模型 // 加载模型
if(Exists(modelPath)==false) if(Exists(modelPath)==false)
{ {
LOG_ERROR(stdout,"%s not exist!\n",modelPath.c_str()); LOG_ERROR(stdout,"%s not exist!\n",modelPath.c_str());
return MODEL_NOT_EXIST; return MODEL_NOT_EXIST;
} }
net = migraphx::parse_onnx(modelPath, onnx_options); net = migraphx::parse_onnx(modelPath);
LOG_INFO(stdout,"succeed to load model: %s\n",GetFileName(modelPath).c_str()); LOG_INFO(stdout,"succeed to load model: %s\n",GetFileName(modelPath).c_str());
// 获取模型输入/输出节点信息 // 获取模型输入/输出节点信息
...@@ -82,6 +68,8 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat ...@@ -82,6 +68,8 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
} }
inputName=inputs.begin()->first; inputName=inputs.begin()->first;
inputShape=inputs.begin()->second; inputShape=inputs.begin()->second;
outputName=outputs.begin()->first;
outputShape=outputs.begin()->second;
int N=inputShape.lens()[0]; int N=inputShape.lens()[0];
int C=inputShape.lens()[1]; int C=inputShape.lens()[1];
int H=inputShape.lens()[2]; int H=inputShape.lens()[2];
...@@ -163,6 +151,22 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat ...@@ -163,6 +151,22 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
} }
net.compile(gpuTarget,options); net.compile(gpuTarget,options);
LOG_INFO(stdout,"succeed to compile model: %s\n",GetFileName(modelPath).c_str()); LOG_INFO(stdout,"succeed to compile model: %s\n",GetFileName(modelPath).c_str());
// offloadcopy为false的时候,分配输入和输出内存
if(!useoffloadcopy)
{
// 分配device输入内存
inputBuffer_Device=nullptr;
hipMalloc(&inputBuffer_Device, inputShape.bytes());
programParameters[inputName] = migraphx::argument{inputShape, inputBuffer_Device};
// 分配device和host输出内存
outputBuffer_Device=nullptr;
hipMalloc(&outputBuffer_Device, outputShape.bytes());
programParameters[outputName] = migraphx::argument{outputShape, outputBuffer_Device};
outputBuffer_Host=nullptr; // host内存
outputBuffer_Host=malloc(outputShape.bytes());
}
// warm up // warm up
if(useoffloadcopy) if(useoffloadcopy)
...@@ -173,9 +177,9 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat ...@@ -173,9 +177,9 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
} }
else else
{ {
std::unordered_map<std::string, migraphx::argument> modelData_warm=CreateOutputData(net); migraphx::argument inputData= migraphx::argument{inputShape};
modelData_warm[inputName]=migraphx::gpu::to_gpu(migraphx::argument{inputShape}); hipMemcpy(inputBuffer_Device, inputData.data(), inputShape.bytes(), hipMemcpyHostToDevice);
net.eval(modelData_warm); net.eval(programParameters);
} }
// log // log
...@@ -232,8 +236,7 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector ...@@ -232,8 +236,7 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector
image2BlobParams.swapRB=false; image2BlobParams.swapRB=false;
blobFromImagesWithParams(image,inputBlob,image2BlobParams); blobFromImagesWithParams(image,inputBlob,image2BlobParams);
// 创建输入数据 // 当offload为true时,不需要内存拷贝
migraphx::argument result;
if(useoffloadcopy) if(useoffloadcopy)
{ {
std::unordered_map<std::string, migraphx::argument> inputData; std::unordered_map<std::string, migraphx::argument> inputData;
...@@ -243,55 +246,87 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector ...@@ -243,55 +246,87 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector
std::vector<std::string> outputNames={"resnetv24_dense0_fwd"}; // 设置返回的输出节点 std::vector<std::string> outputNames={"resnetv24_dense0_fwd"}; // 设置返回的输出节点
std::vector<migraphx::argument> results = net.eval(inputData,outputNames); std::vector<migraphx::argument> results = net.eval(inputData,outputNames);
result = results[0]; // 获取第一个输出节点的数据 // 获取输出节点的属性
migraphx::argument result = results[0]; // 获取第一个输出节点的数据
migraphx::shape outputShapes=result.get_shape(); // 输出节点的shape
std::vector<std::size_t> outputSize=outputShapes.lens(); // 每一维大小,维度顺序为(N,C,H,W)
int numberOfOutput=outputShapes.elements(); // 输出节点元素的个数
float *logits=(float *)result.data(); // 输出节点数据指针
// 获取每张图像的预测结果
int numberOfClasses=numberOfOutput/srcImages.size();
for(int i=0;i<srcImages.size();++i)
{
int startIndex=numberOfClasses*i;
std::vector<float> logit;
for(int j=0;j<numberOfClasses;++j)
{
logit.push_back(logits[startIndex+j]);
}
std::vector<ResultOfPrediction> resultOfPredictions;
for(int j=0;j<numberOfClasses;++j)
{
ResultOfPrediction prediction;
prediction.label=j;
prediction.confidence=logit[j];
resultOfPredictions.push_back(prediction);
}
predictions.push_back(resultOfPredictions);
}
} }
else else // 当offload为false时,需要内存拷贝
{ {
// 为输出节点分配device内存,用于保存输出数据
std::unordered_map<std::string, migraphx::argument> modelData=CreateOutputData(net);
// 将输入转换为device数据 migraphx::argument inputData= migraphx::argument{inputShape, (float*)inputBlob.data};
migraphx::argument inputData=migraphx::gpu::to_gpu(migraphx::argument{inputShape, (float*)inputBlob.data});
// 使用device数据作为输入数据,inputData.data()返回的是device地址 // 拷贝到device输入内存
modelData[inputName]= migraphx::argument{inputShape, inputData.data()}; hipMemcpy(inputBuffer_Device, inputData.data(), inputShape.bytes(), hipMemcpyHostToDevice);
// 推理 // 推理
std::vector<std::string> outputNames={"resnetv24_dense0_fwd"}; // 设置返回的输出节点 std::vector<std::string> outputNames={"resnetv24_dense0_fwd"}; // 设置返回的输出节点
std::vector<migraphx::argument> results = net.eval(modelData,outputNames); std::vector<migraphx::argument> results = net.eval(programParameters,outputNames);
result = migraphx::gpu::from_gpu(results[0]); // 将第一个输出节点的数据拷贝到host端 // 获取输出节点的属性
} migraphx::argument result = results[0]; // 获取第一个输出节点的数据
migraphx::shape outputShapes=result.get_shape(); // 输出节点的shape
// 获取输出节点的属性 std::vector<std::size_t> outputSize=outputShapes.lens(); // 每一维大小,维度顺序为(N,C,H,W)
migraphx::shape outputShape=result.get_shape(); // 输出节点的shape int numberOfOutput=outputShapes.elements(); // 输出节点元素的个数
std::vector<std::size_t> outputSize=outputShape.lens();// 每一维大小,维度顺序为(N,C,H,W)
int numberOfOutput=outputShape.elements();// 输出节点元素的个数
float *logits=(float *)result.data();// 输出节点数据指针
// 获取每张图像的预测结果 // 将device输出数据拷贝到分配好的host输出内存
int numberOfClasses=numberOfOutput/srcImages.size(); hipMemcpy(outputBuffer_Host, outputBuffer_Device, outputShapes.bytes(), hipMemcpyDeviceToHost); // 直接使用事先分配好的输出内存拷贝
for(int i=0;i<srcImages.size();++i)
{
int startIndex=numberOfClasses*i;
// 获取每张图像的预测结果
int numberOfClasses=numberOfOutput/srcImages.size();
std::vector<float> logit; std::vector<float> logit;
for(int j=0;j<numberOfClasses;++j) for(int i=0;i<srcImages.size();++i)
{ {
logit.push_back(logits[startIndex+j]); int startIndex=numberOfClasses*i;
} for(int j=0;j<numberOfClasses;++j)
{
std::vector<ResultOfPrediction> resultOfPredictions; logit.push_back(((float *)outputBuffer_Host)[startIndex+j]);
for(int j=0;j<numberOfClasses;++j) }
{
ResultOfPrediction prediction; std::vector<ResultOfPrediction> resultOfPredictions;
prediction.label=j; for(int j=0;j<numberOfClasses;++j)
prediction.confidence=logit[j]; {
ResultOfPrediction prediction;
prediction.label=j;
prediction.confidence=logit[j];
resultOfPredictions.push_back(prediction);
}
resultOfPredictions.push_back(prediction); predictions.push_back(resultOfPredictions);
} }
predictions.push_back(resultOfPredictions); // 释放
hipFree(inputBuffer_Device);
hipFree(outputBuffer_Device);
free(outputBuffer_Host);
} }
return SUCCESS; return SUCCESS;
......
...@@ -15,8 +15,6 @@ public: ...@@ -15,8 +15,6 @@ public:
~Classifier(); ~Classifier();
std::unordered_map<std::string, migraphx::argument> CreateOutputData(migraphx::program &p);
ErrorCode Initialize(InitializationParameterOfClassifier initializationParameterOfClassifier); ErrorCode Initialize(InitializationParameterOfClassifier initializationParameterOfClassifier);
ErrorCode Classify(const std::vector<cv::Mat> &srcImages,std::vector<std::vector<ResultOfPrediction>> &predictions); ErrorCode Classify(const std::vector<cv::Mat> &srcImages,std::vector<std::vector<ResultOfPrediction>> &predictions);
...@@ -28,6 +26,13 @@ private: ...@@ -28,6 +26,13 @@ private:
cv::Size inputSize; cv::Size inputSize;
std::string inputName; std::string inputName;
migraphx::shape inputShape; migraphx::shape inputShape;
std::string outputName;
migraphx::shape outputShape;
std::unordered_map<std::string, migraphx::argument> programParameters;
void *inputBuffer_Device;
void *outputBuffer_Device;
void *outputBuffer_Host;
bool useInt8; bool useInt8;
bool useFP16; bool useFP16;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment