티스토리 뷰
[OnnxRuntime C++] GetInputNameAllocated 와 GetOutputNameAllocated
developer0hye 2023. 2. 28. 21:10음... onnxruntime 1.13 부터인가 정확히는 모르겠는데 onnxruntime을 1.13으로 올리니
GetInputName 과 GetOutputName 이 없다고 오류난다.
api가 변경됐다.
Name뒤에 Allocated가 붙었다.
찾아보니 기존의 GetInputName 과 GetOutputName 이 메모리 leak 나기 쉬워서 변경됐다는 거 같다.
그래서 기존의 코드에서 GetInputName 과 GetOutputName 을 GetInputNameAllocated 과 GetOutputNameAllocated 로 바꿨는데 빌드 안된다.
반환형도 살짝 바뀌었고 또 이에 맞춰 수정은 해서 빌드는 됐는데 실행해보니 input name이랑 output name을 출력해보니 엉뚱한 값들이 출력됐다.
이슈가 역시나 제기돼있었다.
https://github.com/microsoft/onnxruntime/issues/14157
해결 방법
input name 담을때 std::vector<const char*> 에 저장한다. 주의할 점은 GetInputNameAllocated 와 GetOutputNameAllocated 를 사용할때 std::vector<const char*> 에 저장되는 const char* 가 엉뚱한 값을 가리키지 않도록 만들어줘야한다는 점이다.
이를 위해 std::vector<AllocatedStringPtr> 에 GetInputNameAllocated 혹은 GetOutputNameAllocated 로부터 반환되는 AllocatedStringPtr 값(의 소유권)을 별도로 생성한 std::vector<AllocatedStringPtr> 에 move 시키고 input name이 저장된 std::vector<const char*> 가 소멸되기 이전까지 std::vector<AllocatedStringPtr> 가 소멸되지 않도록 해주면 된다. std::vector<AllocatedStringPtr> 가 먼저 소멸되면 std::vector<const char*> 의 const char* 가 가리키던 값이 메모리가 해제되는지 엉뚱한 값을 출력하게된다.
위 방법을 코드로 구현하면 아래와 같다.
아래 코드는 위에 이슈에서 나온 방법이다.
inputNodeNameAllocatedStrings 를 만들어주지 않고 직접해보면 문제가 발생함을 관측할 수 있을 것이다.
std::vector<const char*> inputNodeNames; //
std::vector<AllocatedStringPtr> inputNodeNameAllocatedStrings; // <-- newly added
...
auto inputNodesNum = session->GetInputCount();
for (int i = 0; i < inputNodesNum; i++) {
auto input_name = session->GetInputNameAllocated(i, allocator);
inputNodeNameAllocatedStrings.push_back(std::move(input_name));
inputNodeNames.push_back(inputNodeNameAllocatedStrings.back().get());
}
onnxruntime 프로젝트에서는 아래처럼 쓰고있다.
std::vector<AllocatedStringPtr> 에 따로 std::move를 안해주고 input node name만 받게 끔 구현하는 것은 아래 처럼 코드를 작성하는 느낌이다.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::vector<const char *> v;
{
std::string s1 = "hdasdsadasdasdasdasdsai";
std::string s2 = "hellasdsadasdasdasdsadasdasdasdsado";
std::string s3 = "bysadsadsadasdsadasdsadsadsae";
v.push_back(s1.c_str());
v.push_back(s2.c_str());
v.push_back(s3.c_str());
for(auto e:v)
{
std::cout<< e << std::endl;
}
}
for(auto e:v)
{
std::cout<< e << std::endl;
}
return 0;
}
main 문안에 존재하는 block 을 벗어나면 v에 저장된 값들의 출력값이 의도하지 않은 값으로 출력된다.
아래처럼 수정해보자. string이 block내에서 소멸되면서 const char* 값이 맛탱이 가지 않도록 vector하나 더 만들고 그 vector에다가 string 을 move 시켜주자.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::vector<const char *> v;
std::vector<string> v_s;
{
std::string s1 = "hdasdsadasdasdasdasdsai";
std::string s2 = "hellasdsadasdasdasdsadasdasdasdsado";
std::string s3 = "bysadsadsadasdsadasdsadsadsae";
v.push_back(s1.c_str());
v.push_back(s2.c_str());
v.push_back(s3.c_str());
v_s.push_back(std::move(s1)); //newly added
v_s.push_back(std::move(s2)); //newly added
v_s.push_back(std::move(s3)); //newly added
for(auto e:v)
{
std::cout<< e << std::endl;
}
}
for(auto e:v)
{
std::cout<< e << std::endl;
}
return 0;
}
main 문안에 존재하는 block 을 벗어나도 의도대로 잘 출력된다.
결론
모델 input, output node 이름 저장하려는건데 이렇게까지 해야하나 싶다.
'Deep Learning' 카테고리의 다른 글
[Deep Learning] COCO pre-trained YOLOv8 모델의 최적의 confidence threshold 탐색 (0) | 2023.04.29 |
---|---|
[Deep Learning] Windows 에서 COCO Pretrained DINO Object Detector Inference 방법 (2) | 2023.04.17 |
[PyTorch,YOLO, hub] YOLOv5 torch hub 로 인터넷 연결 없이 Load하기 (0) | 2022.12.10 |
CLIP Nan 문제 해결 방법 및 Finetuning(=Transfer Learning) 시 팁 (0) | 2022.12.02 |
자동 백본 탐색 중 (0) | 2022.11.19 |
- Total
- Today
- Yesterday
- 이분탐색
- LCA
- 순열
- 위상 정렬 알고리즘
- 문제집
- 조합
- 자료구조
- ㅂ
- 백준 1766
- FairMOT
- 백트래킹
- cosine
- 단축키
- 백준
- MOT
- 인공지능을 위한 선형대수
- 백준 11437
- 가장 긴 증가하는 부분 수열
- 파이참
- 백준 11053
- C++ Deploy
- Lowest Common Ancestor
- PyCharm
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |