Repository: pytorch/pytorch

Issue:
Segmentation fault with cpp_extensions example
## Issue description
Running the C++ extensions example from the Pytorch 0.4.0 release notes results in a segmentation fault.

## Code example
### C++ code
(Code was copied directly from the release notes)
```c++
// my_implementation.cpp
#include <torch/torch.h>
#include <unordered_set>

// can use templates as well. But let's keep it
// simple
using scalar_t = float;

at::Tensor unique_float(at::Tensor input_) {
  // only works for floats
  AT_ASSERT(input_.type().scalarType() == at::ScalarType::Float, "input must be a float tensor");
  // and CPU tensors
  AT_ASSERT(!input_.type().is_cuda(), "input must be a CPU tensor");
  
  // make the input contiguous, to simplify the implementation
  at::Tensor input = input_.contiguous();
  
  // get the pointer that holds the data
  scalar_t* input_data = input.data<scalar_t>();
  // let's use a function from the std library to implement
  // the unique function
  std::unordered_set<scalar_t> set(input_data, input_data + input.numel());
  
  // create the output tensor, with size set.size()
  at::Tensor output = input.type().tensor({static_cast<int64_t>(set.size())});
  scalar_t* output_data = output.data<scalar_t>();
  // copy the content of the set to the output tensor
  std::copy(set.begin(), set.end(), output_data);
  
  return output;
}

// this defines the functions exposed to Python
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
  m.def("unique_float", &unique_float, "Unique for float tensors");
}
```

### Python code
```python
# test_ext.py
import torch
from torch.utils.cpp_extension import load as load_ext
# pass the source files, they will be compiled on the fly 
# and will return a python module
_C = load_ext('my_unique_lib', sources=['my_implementation.cpp'])

# now can use the functions implemented in C++
unique = _C.unique_float

a = torch.tensor([1.0, 2.0, 1.0])
print(unique(a))
```

### Stack trace from GDB
```
Program received signal SIGSEGV, Segmentation fault.
#0  0x00007fffabdea0ae in void __gnu_cxx::new_allocator<_object*>::construct<_object*, _object*>(_object**, _object*&&) () from /tmp/torch_extensions/my_unique_lib/my_unique_lib.so
#1  0x00007fffabde69aa in std::enable_if<std::allocator_traits<std::allocator<_object*> >::__construct_helper<_object*, _object*>::value, void>::type std::allocator_traits<std::allocator<_object*> >::_S_construct<_object*, _object*>(std::allocator<_object*>&, _object**, _object*&&) () from /tmp/torch_extensions/my_unique_lib/my_unique_lib.so
#2  0x00007fffabde21c6 in decltype (_S_construct({parm#1}, {parm#2}, (forward<_object*>)({parm#3}))) std::allocator_traits<std::allocator<_object*> >::construct<_object*, _object*>(std::allocator<_object*>&, _object**, _object*&&) () from /tmp/torch_extensions/my_unique_lib/my_unique_lib.so
#3  0x00007fffabdde355 in void std::vector<_object*, std::allocator<_object*> >::emplace_back<_object*>(_object*&&) () from /tmp/torch_extensions/my_unique_lib/my_unique_lib.so
#4  0x00007fffabddaa8a in std::vector<_object*, std::allocator<_object*> >::push_back(_object*&&) () from /tmp/torch_extensions/my_unique_lib/my_unique_lib.so
#5  0x00007fffabdd155d in pybind11::detail::loader_life_support::loader_life_support() () from /tmp/torch_extensions/my_unique_lib/my_unique_lib.so
#6  0x00007fffabdd6c99 in pybind11::cpp_function::dispatcher(_object*, _object*, _object*) () from /tmp/torch_extensions/my_unique_lib/my_unique_lib.so
#7  0x00007ffff7997902 in _PyCFunction_FastCallDict (func_obj=0x7fffac35d360, args=0x7ffff7f75ba8, nargs=<optimised out>, kwargs=0x0) at Objects/methodobject.c:231
#8  0x00007ffff7a1cf4c in call_function (pp_stack=0x7fffffffdaa8, oparg=<optimised out>, kwnames=0x0) at Python/ceval.c:4788
#9  0x00007ffff7a1fbbd in _PyEval_EvalFrameDefault (f=<optimised out>, throwflag=<optimised out>) at Python/ceval.c:3275
#10 0x00007ffff7a1b4c0 in _PyEval_EvalCodeWithName (_co=0x7ffff7f018a0, globals=<optimised out>, locals=<optimised out>, args=<optimised out>, argcount=0, kwnames=0x0, kwargs=0x8,
    kwcount=0, kwstep=2, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x0, qualname=0x0) at Python/ceval.c:4119
#11 0x00007ffff7a1b943 in PyEval_EvalCodeEx (_co=<optimised out>, globals=<optimised out>, locals=<optimised out>, args=<optimised out>, argcount=<optimised out>, kws=<optimised out>,
    kwcount=0, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0) at Python/ceval.c:4140
#12 0x00007ffff7a1b98b in PyEval_EvalCode (co=<optimised out>, globals=<optimised out>, locals=<optimised out>) at Python/ceval.c:695
#13 0x00007ffff7a4e100 in run_mod (arena=0x7ffff7f5f2d0, flags=0x7fffffffde00, locals=0x7ffff7f46090, globals=0x7ffff7f46090, filename=0x7ffff66c1bb0, mod=0x6a70a0)
---Type <return> to continue, or q <return> to quit---
    at Python/pythonrun.c:980
#14 PyRun_FileExFlags (fp=0x6926c0, filename_str=<optimised out>, start=<optimised out>, globals=0x7ffff7f46090, locals=0x7ffff7f46090, closeit=<optimised out>, flags=0x7fffffffde00)
    at Python/pythonrun.c:933
#15 0x00007ffff7a4f6f3 in PyRun_SimpleFileExFlags (fp=0x6926c0, filename=<optimised out>, closeit=1, flags=0x7fffffffde00) at Python/pythonrun.c:396
#16 0x00007ffff7a6aa41 in run_file (p_cf=0x7fffffffde00, filename=0x6032d0 L"test_ext.py", fp=0x6926c0) at Modules/main.c:320
#17 Py_Main (argc=<optimised out>, argv=<optimised out>) at Modules/main.c:781
#18 0x0000000000400c1d in main (argc=2, argv=<optimised out>) at ./Programs/python.c:69
```



## System Info
PyTorch version: 0.4.0
Is debug build: No
CUDA used to build PyTorch: 8.0.61

OS: Ubuntu 14.04.5 LTS
GCC version: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
CMake version: version 3.2.2

Python version: 3.6
Is CUDA available: Yes
CUDA runtime version: 8.0.44
GPU models and configuration: GPU 0: GeForce GTX 980
Nvidia driver version: 384.111
cuDNN version: Probably one of the following:
/usr/local/cuda-8.0/lib64/libcudnn.so.5.1.10
/usr/local/cuda-8.0/lib64/libcudnn.so.5.1.5
/usr/local/cuda-8.0/lib64/libcudnn_static.a
/usr/local/lib/python2.7/dist-packages/torch/lib/libcudnn-900fef33.so.7.0.5

Versions of relevant libraries:
[pip3] numpy (1.14.2)
[pip3] numpydoc (0.6.0)
[pip3] torch (0.4.0)
[pip3] torchvision (0.2.0, ~/packages/vision)
[conda] cuda80                    1.0                           0    soumith
[conda] torch                     0.4.0                     <pip>
[conda] torchvision               0.2.0                     <pip>



Discussion:
It seems that you are using GCC 4.8
Didn't you get the following message from `cpp_extensions`?
```
Your compiler (g++ 4.8) may be ABI-incompatible with PyTorch!
Please use a compiler that is ABI-compatible with GCC 4.9 and above.
See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html.

See https://gist.github.com/goldsborough/d466f43e8ffc948ff92de7486c5216d6
for instructions on how to install GCC 4.9 or higher.
```

Could you try updating gcc to 4.9 or higher?
Hi @fmassa! Upgrading gcc and then reinstalling Pytorch seemed to fix it! Many thanks. No sign of the error message though, when should I have expected to see it? When installing Pytorch or when running the example?
Hum, I just realized that the JIT compilation step doesn't emit the warning, only when we compile it using `setuptools.Extension`. The `abi` check should also be present in the `load` function call if possible.
I'm keeping this issue open until we add the abi checks in `load` as well.

cc @goldsborough 

Resolving patch:
diff --git a/torch/utils/cpp_extension.py b/torch/utils/cpp_extension.py
--- a/torch/utils/cpp_extension.py
+++ b/torch/utils/cpp_extension.py
@@ -475,6 +475,7 @@ def load(name,
 
     if baton.try_acquire():
         try:
+            check_compiler_abi_compatibility(os.environ.get('CXX', 'c++'))
             with_cuda = any(map(_is_cuda_file, sources))
             extra_ldflags = _prepare_ldflags(
                 extra_ldflags or [],


Test patch: