Cpp extension IntList as function input

I’m not sure I fully understand how to use IntList as an input for a function. First off, in the extension-cpp example, only Tensors are used as inputs. It would be nice to see examples with IntList, Scalar, int64_t as inputs so people that aren’t so familiar with c++ could see those in use and apply those in their own extensions.

I was looking at the LossCTC file as an example for a cpp extension that uses IntList as an input. In this case, they’ve got IntList as the input and it accepts regular python lists as expected. But when I tried to write my own extension I run into the following error if I use IntList as an input:

Emitting ninja build file /tmp/torch_extensions/test_cpp_ext/build.ninja...
Building extension module test_cpp_ext...
Loading extension module test_cpp_ext...
Traceback (most recent call last):
  File "jit_intlist_input.py", line 9, in <module>
    print(test_cpp_ext.f(x))
TypeError: f(): incompatible function arguments. The following argument types are supported:
    1. (arg0: at::ArrayRef<long>) -> at::Tensor

Invoked with: [1, 2]

however, if I use std::vector<int64_t> then I get the desired output:

Emitting ninja build file /tmp/torch_extensions/test_cpp_ext/build.ninja...
Building extension module test_cpp_ext...
Loading extension module test_cpp_ext...
tensor([1., 2.])

Should I be using std::vector<int64_t> for function inputs if I want the input to be a python list or should IntList work and I’m doing something wrong? I feel like the second is correct, but can’t figure out how to get IntLists to work.

Below is some code to create a minimal example

**test.cpp**

#include <torch/torch.h>

namespace at {
Tensor f(IntList a) {
    return tensor(a, torch::CPU(kFloat));
}
Tensor g(std::vector<int64_t> a) {
    return tensor(a, torch::CPU(kFloat));
}

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
  m.def("f", &f, "function with IntList input");
  m.def("g", &g, "function without IntList input");
}

}
**jit_intlist_input.py**

import torch
from torch.utils.cpp_extension import load
test_cpp_ext = load(
    'test_cpp_ext', ['test.cpp'], verbose=True)

x = [1, 2]
y = torch.LongTensor(x)  # using y as an input doesn't work either

print(test_cpp_ext.f(x))
**jit_vector_input.py**

import torch
from torch.utils.cpp_extension import load
test_cpp_ext = load(
    'test_cpp_ext', ['test.cpp'], verbose=True)

x = [1, 2]

print(test_cpp_ext.g(x))

Please feel free to open a github issue requesting more comprehensive extension-cpp examples: https://github.com/pytorch/pytorch

@richard do you have any suggestions related to my question about IntList?

I’ll consider creating an issue about the examples but before creating an issue, if like to make sure that I’m not making a stupid mistake.

The intlist is a defined class, you can see two file

https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/core/ScalarType.h

typedef ArrayRef<int64_t> IntList;

https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/core/ArrayRef.h

class ArrayRef final {
 public:
  using iterator = const T*;
  using const_iterator = const T*;
  using size_type = size_t;

  using reverse_iterator = std::reverse_iterator<iterator>;
...

Since it’s a internal class of pytorch, i guess it cannot be parsed by pybind11. So you can use std::vector<int64_t> arg in the arguments, then convert it to IntList by IntList val(arg).

Thanks for the response @mingminzhen. Perhaps I’ll create an issue for this. It’s not high priority, but it’s just not clear in the docs that pybind11 won’t accept IntList as an input.

Hi David,

sorry, I forgot to report this here. After this came up again, we have an IntList conversion in master for a while:

Best regards

Thomas