第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

返回多個(gè) py::array 而不在 pybind11 中復(fù)制

返回多個(gè) py::array 而不在 pybind11 中復(fù)制

茅侃侃 2022-06-07 17:55:08
我正在嘗試使用 pybind11 在 C++ 中構(gòu)建一個(gè) python 模塊。我有以下代碼:#include <pybind11/pybind11.h>#include <pybind11/stl.h>#include <pybind11/numpy.h>namespace py = pybind11;struct ContainerElement{    uint8_t i;    double d;    double d2;};class Container{private:    std::vector<uint8_t> ints;    std::vector<double> doubles;    std::vector<double> doubles2;public:    std::vector<uint8_t>& getInts() { return ints; }    std::vector<double>& getDoubles() { return doubles; }    std::vector<double>& getDoubles2() { return doubles2; }    void addElement(ContainerElement element)    {        ints.emplace_back(element.i);        doubles.emplace_back(element.d);        doubles2.emplace_back(element.d2);    }};void fillContainer(Container& container){    for (int i = 0; i < 1e6; ++i)    {        container.addElement({(uint8_t)i, (double)i,(double)i });    }}PYBIND11_MODULE(containerInterface, m) {    py::class_<Container>(m, "Container")        .def(py::init<>())        .def("getInts", [](Container& container)        {            return py::array_t<uint8_t>(                    { container.getInts().size() },                    { sizeof(uint8_t) },                    container.getInts().data());        })        .def("getDoubles", [](Container& container)        {            return py::array_t<double>(                    { container.getDoubles().size() },                    { sizeof(double) },                    container.getDoubles().data());        })這可行,但是當(dāng)我檢查程序的內(nèi)存使用情況(使用psutil.Process(os.getpid()).memory_info().rss)時(shí),當(dāng)我調(diào)用函數(shù)getInts, getDoubles和getDoubles2. 有沒有辦法避免這種情況?我嘗試過(guò)使用np.array(container.getInts(), copy=False),但它仍然會(huì)復(fù)制。我還嘗試使用py::buffer_protocol()此處提到的 Container 類:https ://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html 。但是,我只能對(duì) Ints 向量或 Doubles 向量進(jìn)行此操作,而不能同時(shí)對(duì)所有向量進(jìn)行操作。然后我可以使用i = np.array(container, copy=False),而無(wú)需制作副本。但是,正如我所說(shuō),它現(xiàn)在僅適用于Ints矢量。
查看完整描述

3 回答

?
胡說(shuō)叔叔

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超8個(gè)贊

我找到了一個(gè)可行的解決方案。雖然它可能不是最優(yōu)雅的。我創(chuàng)建了三個(gè)新類Ints,它們采用原始容器并通過(guò)函數(shù)調(diào)用公開各自的Doubles向量。使用這三個(gè)類,我可以為所有類指定三次緩沖區(qū)協(xié)議。Doubles2getValues()


#include <pybind11/pybind11.h>

#include <pybind11/stl.h>

#include <pybind11/numpy.h>

#include <pybind11/buffer_info.h>


namespace py = pybind11;


struct ContainerElement

{

    uint8_t i;

    double d;

    double d2;

};


class Container

{

private:

    std::vector<uint8_t> ints;

    std::vector<double> doubles;

    std::vector<double> doubles2;


public:


    std::vector<uint8_t>& getInts() { return ints; }

    std::vector<double>& getDoubles() { return doubles; }

    std::vector<double>& getDoubles2() { return doubles2; }


    void addElement(ContainerElement element)

    {

        ints.emplace_back(element.i);

        doubles.emplace_back(element.d);

        doubles2.emplace_back(element.d2);

    }

};


void fillContainer(Container& container)

{

    for (int i = 0; i < 1e6; ++i)

    {

        container.addElement({ (uint8_t)i, (double)i,(double)i });

    }

}


class Ints

{

private:

    Container& cont;

public:

    Ints(Container& cont) : cont(cont) {}

    std::vector<uint8_t>& getValues() { return cont.getInts(); }

};


class Doubles

{

private:

    Container& cont;

public:

    Doubles(Container& cont) : cont(cont) {}

    std::vector<double>& getValues() { return cont.getDoubles(); }

};


class Doubles2

{

private:

    Container& cont;

public:

    Doubles2(Container& cont) : cont(cont) {}

    std::vector<double>& getValues() { return cont.getDoubles2(); }

};


PYBIND11_MODULE(newInterface, m) {

    py::class_<Container>(m, "Container")

        .def(py::init<>());


    py::class_<Ints>(m, "Ints", py::buffer_protocol())

        .def(py::init<Container&>(), py::keep_alive<1, 2>())

        .def_buffer([](Ints& ints) -> py::buffer_info {

            return py::buffer_info(

                ints.getValues().data(),

                sizeof(uint8_t),

                py::format_descriptor<uint8_t>::format(),

                ints.getValues().size()

            );

        });


    py::class_<Doubles>(m, "Doubles", py::buffer_protocol())

        .def(py::init<Container&>(), py::keep_alive<1, 2>())

        .def_buffer([](Doubles& doubles) -> py::buffer_info {

        return py::buffer_info(

            doubles.getValues().data(),

            sizeof(double),

            py::format_descriptor<double>::format(),

            doubles.getValues().size()

            );

        });


    py::class_<Doubles2>(m, "Doubles2", py::buffer_protocol())

        .def(py::init<Container&>(), py::keep_alive<1, 2>())

        .def_buffer([](Doubles2& doubles2) -> py::buffer_info {

        return py::buffer_info(

            doubles2.getValues().data(),

            sizeof(double),

            py::format_descriptor<double>::format(),

            doubles2.getValues().size()

            );

        });


    m.def("fillContainer", &fillContainer);

}

這樣我就可以在 Python 中按以下方式使用代碼:


import newInterface as ci

import numpy as np


container = ci.Container()

ci.fillContainer(container)


i = np.array(ci.Ints(container), copy=False)   

d = np.array(ci.Doubles(container), copy=False)    

d2 = np.array(ci.Doubles2(container), copy=False)

一旦fillContainer填充了容器,numpy 數(shù)組的構(gòu)造就不會(huì)從這個(gè)容器中復(fù)制值。


查看完整回答
反對(duì) 回復(fù) 2022-06-07
?
慕的地8271018

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊

我猜您必須指定訪問(wèn)函數(shù)返回引用而不是副本,這可能是默認(rèn)值。我不知道你是如何用 pybind 做到這一點(diǎn)的,但我已經(jīng)用 boost::python 和Ponder做到了這一點(diǎn)。

即您需要指定退貨政策。


查看完整回答
反對(duì) 回復(fù) 2022-06-07
?
月關(guān)寶盒

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超5個(gè)贊

這并不能直接解決問(wèn)題,但仍然允許在不進(jìn)行復(fù)制的情況下返回?cái)?shù)組緩沖區(qū)。靈感來(lái)自這個(gè)線程: https ://github.com/pybind/pybind11/issues/1042


基本上,只需向 py::array() 構(gòu)造函數(shù)提供一個(gè) py::capsule。這樣,py::array() 構(gòu)造函數(shù)就不會(huì)分配單獨(dú)的緩沖區(qū)和副本。例如:


// Use this if the C++ buffer should NOT be deallocated

// once Python no longer has a reference to it

py::capsule buffer_handle([](){});


// Use this if the C++ buffer SHOULD be deallocated

// once the Python no longer has a reference to it

// py::capsule buffer_handle(data_buffer, [](void* p){ free(p); });


return py::array(py::buffer_info(

        data_buffer,

        element_size,

        data_type,

        dims_length,

        dims,

        strides

), buffer_handle);


查看完整回答
反對(duì) 回復(fù) 2022-06-07
  • 3 回答
  • 0 關(guān)注
  • 287 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)