Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python's multiple illegal destructions of classes in C++[BUG]: #5453

Open
3 tasks done
laogonggong847 opened this issue Nov 26, 2024 · 0 comments
Open
3 tasks done

python's multiple illegal destructions of classes in C++[BUG]: #5453

laogonggong847 opened this issue Nov 26, 2024 · 0 comments
Labels
triage New bug, unverified

Comments

@laogonggong847
Copy link

laogonggong847 commented Nov 26, 2024

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

latest

Problem description

The python call to the pybind11 wrapped so file comes up with multiple destructions of my custom class。

// class 1:
class QnnModelLoader
{
public:
    QnnModelLoader();
    ~QnnModelLoader();

    std::shared_ptr<qnnInferenceEngine>load_model_from_qnn(std::string input_model_path, std::string backend_path, bool loadFromCachedBinary);
}

// class 2:
class qnnInferenceEngine
{
public:
    qnnInferenceEngine(std::shared_ptr<qnn::tools::sample_app::QnnSampleApp> sampleApp, bool loadFromCachedBinary);
    ~qnnInferenceEngine();
    std::vector<std::vector<float>> infer_model();
}

My code for Pybind11 is as follows:


PYBIND11_MODULE(qnn_loader, m) {
    py::class_<qnnInferenceEngine>(m, "qnnInferenceEngine")
        .def(py::init<std::shared_ptr<QnnSampleApp>, bool>())
        .def("infer_model", &qnnInferenceEngine::infer_model);

    py::class_<QnnModelLoader>(m, "QnnModelLoader")
        .def(py::init<>())
        .def("load_model_from_qnn", &QnnModelLoader::load_model_from_qnn);
}

My python call code is as follows:

def test_6(model_path, backend_path):

    Loader = qnn_inference_engine.QnnModelLoader()
    inferEngine = Loader.load_model_from_qnn(model_path, backend_path, False)
    print("Hello World")

A strange thing came up at this point, I was printing the information of the call in the constructor and destructor functions I added in C++ in these two classes. python prints the information when called as follows:

The constructor of QnnModelLoader is called
The constructor of qnnInferenceEngine is called
The destructor of qnnInferenceEngine is called
Hello World
The destructor of QnnModelLoader is called
The destructor of qnnInferenceEngine is called

It makes me wonder why the destructor is called before Hello World.
Below I will provide a concrete implementation of the function load_model_from_qnn

std::shared_ptr<qnnInferenceEngine> QnnModelLoader::load_model_from_qnn(std::string model_path, std::string backend_path, bool loadFromCachedBinary)
{
    // .......
    m_sampleApp = std::make_shared<QnnSampleApp>(std::string{""});
    return std::make_shared<qnnInferenceEngine>(m_sampleApp, m_loadFromCachedBinary);

}

For Load_model_from_qnn I tried using all the return mechanisms. But when I use it in Python all the print messages suggest me the same error, I don't know if I'm not using it correctly, my specific use is:

.def("load_model_from_qnn", &QnnModelLoader::load_model_from_qnn, return_value_policy::move);

I tried all of the following:

return_value_policy::take_ownership
return_value_policy::copy
return_value_policy::move
return_value_policy::reference
return_value_policy::reference_internal
return_value_policy::automatic
return_value_policy::automatic_reference

My core question is as follows.
1:In the PYBIND11_MODULE function, although the class QnnSampleApp appears, I don't want to expose it, and I don't know if I'm writing it this way correctly

2: Why the qnnInferenceEngine will be destructed in python directly after the creation of qnnInferenceEngine (the destruct message is printed in Hello World), is it because my PYBIND11_MODULE is not correct? If not, what should I do to change it?

If PYBIND11_MODULE is OK, is my load_model_from_qnn wrong? I've given the core details of the exact implementation, but it's fine in C++, and I know there are differences in the management mechanism between C++ and python, so how should I modify it?

Very much looking forward to your help, thanks!

Reproducible example code

Please refer to Problem description

Is this a regression? Put the last known working version here if it is.

Not a regression

@laogonggong847 laogonggong847 added the triage New bug, unverified label Nov 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage New bug, unverified
Projects
None yet
Development

No branches or pull requests

1 participant