I have a short clip of C++ code that should theoretically work to create and return a torch.IntTensor object, but when I call it from Torch I get garbage data.
Here is my code (note this snippet leaves out the function registering, but suffice it to say that it registers fine--I can provide it if necessary):
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;
}
When I call this from Lua, I should get a [torch.IntTensor of size 10]
and I do. However, the data appears to be either memory addresses or junk:
29677072
0
16712197
3
0
0
29677328
0
4387616
0
[torch.IntTensor of size 10]
It should have been the numbers [0,9].
Where am I going wrong?
For the record, when I test it in C++
for (int i = 0; i < storage->size; i++)
std::cout << *(storage->data+i) << std::endl;
prints the proper values.
As does
for (int i = 0; i < tensorMatches->storage->size; i++)
std::cout << *(tensorMatches->storage->data+i) << std::endl;
so it seems clear to me that the problem lies in the exchange between C++ and Lua.
So I got an answer elsewhere--the Google group for Torch7--but I'll copy and paste it here for anyone who may need it.
From user @alban desmaison:
Your problem is actually memory management.
When your C++ function return, you
vector<int>
is free, and so is its content. From that point onward, the tensor is pointing to free memory and when you access it, you access freed memory. You will have to either:
- Allocate memory on the heap with
malloc
(as an array ofint
s) and use THIntStorage_newWithData as you currently do (the pointer that you give to newWithData will befree
ed when it is not used anymore by Torch).- Use a
vector<int>
the way you currently do but create a new Tensor with a given size with THIntTensor_newWithSize1d(matches.size()) and then copy the content of the vector into the tensor.
For the record, I couldn't get it to work with malloc
but the copying memory approach worked just fine.