У меня есть класс C ++ RF с двумя функциями-членами: load () для загрузки сохраненной модели (.pb) и detect () для многократного запуска модели для вывода. У меня есть еще один класс C ++ IMPL с двумя функциями: одна initialize (), а другая create (). Один объект РФ является участником IMPL. Когда я запускаю RF :: load () и RF :: detect () в одной и той же функции IMPL, он работает нормально. Однако, когда я вызываю RF :: load () в IMPL :: initialize () и RF :: detect () в IMPL :: create (), TF_SessionRun () зависает без генерации каких-либо выходных данных или ошибок. Что не так с моим кодом или TF_SessionRun ()?
class RF
{
public:
RF(){}
~RF();
int load();
int detect(cv::Mat Image&);
const char* saved_model_dir = "path/";// set model path
const char* tags = "serve";
int ntags = 1;
private:
const int NumInputs = 1;
const int NumOutputs = 1;
const unsigned short int LengthFV = 16;
TF_Graph* Graph;
TF_Status* Status;
TF_Session* Session;
TF_SessionOptions* SessionOpts;
TF_Buffer* RunOpts;
TF_Output* Input;
TF_Output* Output;
TF_Tensor** InputValues;
TF_Tensor** OutputValues;
TF_Tensor* vecTensor;
TF_Tensor * imgTensor;
};
RF::~RF()
{
// release memory;
}
int RF::load()
{
Graph = TF_NewGraph();
Status = TF_NewStatus();
SessionOpts = TF_NewSessionOptions();
RunOpts = NULL;
Session = TF_LoadSessionFromSavedModel(SessionOpts, RunOpts, saved_model_dir, &tags, ntags, Graph, NULL, Status);
if(TF_GetCode(Status) != TF_OK) {
std::cout << "\nERROR: Failed to load SavedModel." << TF_Message(Status);
return -1; }
// prepare input and output tensors
Input = new TF_Output[NumInputs];// input tensor
Output = new TF_Output[NumOutputs];// output tensor
TF_Output t0 = {TF_GraphOperationByName(Graph, "serving_default_input_image"), 0};
if(t0.oper == NULL) {
std::cout << "\nERROR: Failed TF_GraphOperationByName serving_default_input_image.";
return -1; }
Input[0] = t0;
TF_Output t2 = {TF_GraphOperationByName(Graph, "StatefulPartitionedCall"), 0};
if(t2.oper == NULL) {
std::cout << "\nERROR: Failed TF_GraphOperationByName StatefulPartitionedCall.";
return -1; }
Output[0] = t2;
// allocate data for input and output tensors
InputValues = (TF_Tensor**)new TF_Tensor*[NumInputs];
OutputValues = (TF_Tensor**)new TF_Tensor*[NumOutputs];
int64_t dims_vector[] = {1, LengthFV};// depends on the output of retinaface
unsigned short int dim = 2;
std::vector<float> output_buffer(LengthFV);
vecTensor = TF_NewTensor(TF_FLOAT, dims_vector, dim, output_buffer.data(), LengthFV*sizeof(float), &NoOpDeallocator, 0);
if (vecTensor == NULL) {
std::cout << "\nERROR: Failed generation of TF_Tensor* vecTensor.";
return -1; }
OutputValues[0] = vecTensor;
return 0;
}
int RF::detect(cv::Mat& img)
{
int iro = img.height;
int ico = img.width;
int ich = 3;// channels
unsigned short int batches = 1;
unsigned short int dims = 4;
int64_t dims_img[] = {batches, iro, ico, ich};// {1, rows, cols, 3}
unsigned int isi = iro * ico * ich;// size
std::vector<float> ppm_buffer(isi);
float* ppm_data=ppm_buffer.data();
for(int i=0; i<isi; i++)
ppm_data[i] = img.data.get()[i];// copy img.data to ppm_buffer
// create new tensor and assign to InputValues
//std::vector<float> input_buffer(this->input_size);
imgTensor = TF_NewTensor(TF_FLOAT, dims_img, dims, ppm_buffer.data(), isi*sizeof(float), &NoOpDeallocator, 0);
if (imgTensor == NULL) {
std::cout << "\nERROR: Failed generation of TF_Tensor* imgTensor.";
return -1; }
InputValues[0] = imgTensor;
// run session
std::cout << "\nRunning TF_SessionRun...";
TF_SessionRun(Session, NULL, Input, InputValues, NumInputs, Output, OutputValues, NumOutputs, NULL, 0,NULL , Status);
if(TF_GetCode(Status) == TF_OK)
std::cout << "\nSUCCESS: TF_SessionRun is OK.";
else
{
std::cout << "\nERROR: " << TF_Message(Status);
return -1;
}
return 0;
}
class IMPL
{
private:
RF rf;
public:
int initialize(int status)
{
if (rf.load() != 0 );
return -1;
else
return 0;
}
int create(cv::Mat& image)
{
if( rf.detect(image) != 0 )
return -1;
else
return 0;
}
};
main()
{
IMPL impl;
impl.initialize();
impl.create();
}