Commit a861a730 authored by liucong's avatar liucong
Browse files

提交loadcopy为fasle的工程示例

parent 8510437f
......@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.5)
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_BUILD_TYPE release)
......
......@@ -50,11 +50,8 @@ if __name__ == '__main__':
use_int8 = 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:")
......
......@@ -57,11 +57,8 @@ if __name__ == '__main__':
use_int8 = 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:")
......
......@@ -3,7 +3,7 @@
#include <migraphx/onnx.hpp>
#include <migraphx/gpu/target.hpp>
#include <migraphx/quantization.hpp>
#include <migraphx/gpu/hip.hpp>
#include <hip/hip_runtime_api.h>
#include <Filesystem.h>
#include <SimpleLog.h>
#include <algorithm>
......@@ -21,16 +21,6 @@ Classifier::~Classifier()
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)
{
// 读取配置文件
......@@ -54,17 +44,13 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
useFP16=(bool)(int)netNode["UseFP16"];
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)
{
LOG_ERROR(stdout,"%s not exist!\n",modelPath.c_str());
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());
// 获取模型输入/输出节点信息
......@@ -82,6 +68,8 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
}
inputName=inputs.begin()->first;
inputShape=inputs.begin()->second;
outputName=outputs.begin()->first;
outputShape=outputs.begin()->second;
int N=inputShape.lens()[0];
int C=inputShape.lens()[1];
int H=inputShape.lens()[2];
......@@ -163,6 +151,22 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
}
net.compile(gpuTarget,options);
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
if(useoffloadcopy)
......@@ -173,9 +177,9 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
}
else
{
std::unordered_map<std::string, migraphx::argument> modelData_warm=CreateOutputData(net);
modelData_warm[inputName]=migraphx::gpu::to_gpu(migraphx::argument{inputShape});
net.eval(modelData_warm);
migraphx::argument inputData= migraphx::argument{inputShape};
hipMemcpy(inputBuffer_Device, inputData.data(), inputShape.bytes(), hipMemcpyHostToDevice);
net.eval(programParameters);
}
// log
......@@ -232,8 +236,7 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector
image2BlobParams.swapRB=false;
blobFromImagesWithParams(image,inputBlob,image2BlobParams);
// 创建输入数据
migraphx::argument result;
// 当offload为true时,不需要内存拷贝
if(useoffloadcopy)
{
std::unordered_map<std::string, migraphx::argument> inputData;
......@@ -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<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::gpu::to_gpu(migraphx::argument{inputShape, (float*)inputBlob.data});
migraphx::argument inputData= migraphx::argument{inputShape, (float*)inputBlob.data};
// 使用device数据作为输入数据,inputData.data()返回的是device地址
modelData[inputName]= migraphx::argument{inputShape, inputData.data()};
// 拷贝到device输入内存
hipMemcpy(inputBuffer_Device, inputData.data(), inputShape.bytes(), hipMemcpyHostToDevice);
// 推理
std::vector<std::string> outputNames={"resnetv24_dense0_fwd"}; // 设置返回的输出节点
std::vector<migraphx::argument> results = net.eval(modelData,outputNames);
std::vector<std::string> outputNames={"resnetv24_dense0_fwd"}; // 设置返回的输出节点
std::vector<migraphx::argument> results = net.eval(programParameters,outputNames);
result = migraphx::gpu::from_gpu(results[0]); // 将第一个输出节点的数据拷贝到host端
}
// 获取输出节点的属性
migraphx::shape outputShape=result.get_shape(); // 输出节点的shape
std::vector<std::size_t> outputSize=outputShape.lens();// 每一维大小,维度顺序为(N,C,H,W)
int numberOfOutput=outputShape.elements();// 输出节点元素的个数
float *logits=(float *)result.data();// 输出节点数据指针
// 获取输出节点的属性
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(); // 输出节点元素的个数
// 获取每张图像的预测结果
int numberOfClasses=numberOfOutput/srcImages.size();
for(int i=0;i<srcImages.size();++i)
{
int startIndex=numberOfClasses*i;
// 将device输出数据拷贝到分配好的host输出内存
hipMemcpy(outputBuffer_Host, outputBuffer_Device, outputShapes.bytes(), hipMemcpyDeviceToHost); // 直接使用事先分配好的输出内存拷贝
// 获取每张图像的预测结果
int numberOfClasses=numberOfOutput/srcImages.size();
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]);
}
std::vector<ResultOfPrediction> resultOfPredictions;
for(int j=0;j<numberOfClasses;++j)
{
ResultOfPrediction prediction;
prediction.label=j;
prediction.confidence=logit[j];
int startIndex=numberOfClasses*i;
for(int j=0;j<numberOfClasses;++j)
{
logit.push_back(((float *)outputBuffer_Host)[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);
}
resultOfPredictions.push_back(prediction);
predictions.push_back(resultOfPredictions);
}
predictions.push_back(resultOfPredictions);
// 释放
hipFree(inputBuffer_Device);
hipFree(outputBuffer_Device);
free(outputBuffer_Host);
}
return SUCCESS;
......
......@@ -15,8 +15,6 @@ public:
~Classifier();
std::unordered_map<std::string, migraphx::argument> CreateOutputData(migraphx::program &p);
ErrorCode Initialize(InitializationParameterOfClassifier initializationParameterOfClassifier);
ErrorCode Classify(const std::vector<cv::Mat> &srcImages,std::vector<std::vector<ResultOfPrediction>> &predictions);
......@@ -28,6 +26,13 @@ private:
cv::Size inputSize;
std::string inputName;
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 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