У меня есть короткий фрагмент кода C ++, который теоретически должен работать для создания и возврата объекта torch.IntTensor, но когда я вызываю его из Torch, я получаю данные мусора.
Вот мой код (обратите внимание, что этот фрагмент пропускает регистрацию функции, но достаточно сказать, что она регистрируется нормально — я могу предоставить ее при необходимости):
static int ltest(lua_State* L)
{
std::vector<int> matches;
for (int i = 0; i < 10; i++)
{
matches.push_back(i);
}
performMatching(dist, matches, ratio_threshold);
THIntStorage* storage = THIntStorage_newWithData(&matches[0], matches.size());
THIntTensor* tensorMatches = THIntTensor_newWithStorage1d(storage, 0, matches.size(), 1);
// Push result to Lua stack
luaT_pushudata(L, (void*)tensorMatches, "torch.IntTensor");
return 1;
}
Когда я звоню из Lua, я должен получить [torch.IntTensor of size 10]
и я делаю. Тем не менее, данные кажутся либо адресами памяти, либо ненужными:
29677072
0
16712197
3
0
0
29677328
0
4387616
0
[torch.IntTensor of size 10]
Это должны были быть цифры [0,9].
Куда я иду не так?
Для записи, когда я тестирую это в C ++
for (int i = 0; i < storage->size; i++)
std::cout << *(storage->data+i) << std::endl;
печатает правильные значения.
Так же как и
for (int i = 0; i < tensorMatches->storage->size; i++)
std::cout << *(tensorMatches->storage->data+i) << std::endl;
так что мне кажется ясным, что проблема заключается в обмене между C ++ и Lua.
Так что я получил ответ в другом месте …группа Google для Torch7—но я скопирую и вставлю это сюда для всех, кому это может понадобиться.
От пользователя @alban desmaison:
Ваша проблема на самом деле управления памятью.
Когда ваша функция C ++ возвращается, вы
vector<int>
бесплатно, как и его содержание.
С этого момента тензор указывает на свободную память, и когда вы обращаетесь к ней, вы получаете доступ к свободной памяти.
Вам придется либо:
- Выделите память в куче с помощью
malloc
(как массивint
s) и использовать THIntStorage_newWithData, как вы это делаете в настоящее время (указатель, который вы дадите newWithData, будетfree
Ред, когда он больше не используется Факелом).- Использовать
vector<int>
как в настоящее время вы делаете, но создаете новый Tensor с заданным размером с THIntTensor_newWithSize1d (match.size ()), а затем копируете содержимое вектора в тензор.
Для справки, я не мог заставить его работать с malloc
но подход к копированию памяти работал просто отлично.
Других решений пока нет …