Thank you. I still haven’t gotten to the bottom of this issue. Maybe someone can see my mistake. So the generated code in TensorMethods.cpp is:
PyObject * THPTensor_(mul)(PyObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *__kw_value = NULL;
PyObject *__kw_other = NULL;
if (kwargs) {
__kw_value = PyDict_GetItemString(kwargs, “value”);
__kw_other = PyDict_GetItemString(kwargs, “other”);
}
HANDLE_TH_ERRORS
int __tuplecount = args ? PyTuple_Size(args) : 0;
int __dictcount = kwargs ? PyDict_Size(kwargs) : 0;
int __argcount = __tuplecount + __dictcount;
PyObject *__out;

__out = kwargs ? PyDict_GetItemString(kwargs, "out") : NULL;
if (__out == Py_None) { __out = NULL; __dictcount--; __argcount--; }



if (__out != NULL &&
      __argcount == 2 &&
      (PyObject*)Py_TYPE(__out) == THPTensorClass &&
      (__tuplecount > 0 || __kw_value) && THPUtils_(checkReal)((__tuplecount > 0 ? PyTuple_GET_ITEM(args, 0) : __kw_value))) {

[…]
} else if (__out != NULL &&
      __argcount == 2 &&
      (PyObject*)Py_TYPE(__out) == THPTensorClass &&
      (__tuplecount > 0 || __kw_value) && THPUtils_(checkPart)((__tuplecount > 0 ? PyTuple_GET_ITEM(args, 0) : __kw_value))) {
  [..]
} else if (__out != NULL &&
      __argcount == 2 &&
      (PyObject*)Py_TYPE(__out) == THPTensorClass &&
      (__tuplecount > 0 || __kw_other) && (PyObject*)Py_TYPE((__tuplecount > 0 ? PyTuple_GET_ITEM(args, 0) : __kw_other)) == THPTensorClass) {

[…]
} else if (__out == NULL &&
      __argcount == 1 &&
      (__tuplecount > 0 || __kw_value) && THPUtils_(checkReal)((__tuplecount > 0 ? PyTuple_GET_ITEM(args, 0) : __kw_value))) {
  [...]

} else if (__out == NULL &&
      __argcount == 1 &&
      (__tuplecount > 0 || __kw_value) && THPUtils_(checkPart)((__tuplecount > 0 ? PyTuple_GET_ITEM(args, 0) : __kw_value))) {
  [...]

} else if (__out == NULL &&
      __argcount == 1 &&
      (__tuplecount > 0 || __kw_other) && (PyObject*)Py_TYPE((__tuplecount > 0 ? PyTuple_GET_ITEM(args, 0) : __kw_other)) == THPTensorClass) {
  
  #if IS_CUDA
  THCPAutoGPU __autogpu_guard = THCPAutoGPU(args, (PyObject*)self);
  #endif
  
  THPTensorPtr _result_guard((THPTensor*) THPTensor_(NewEmpty)());
  if (!_result_guard.get()) return NULL;
  THPTensor* result = _result_guard.get();
  
  
  THTensor* arg_result = ((THPTensor*)result)->cdata;
  THTensor* arg_self = ((THPTensor*)self)->cdata;
  THTensor* arg_other = ((THPTensor*)(__tuplecount > 0 ? PyTuple_GET_ITEM(args, 0) : __kw_other))->cdata;
  
  THTensor *arg_self_save = arg_self;
  THTensorPtr arg_self_guard(nullptr);
  THTensor *arg_other_save = arg_other;
  THTensorPtr arg_other_guard(nullptr);
  
  bool try_expand = !THSize_isSameSizeAs(arg_self->size, arg_self->nDimension,
      arg_other->size, arg_other->nDimension);
  if (try_expand) {
    bool expand_success = false;
    try {
      arg_self_guard =
      THTensor_(new)(LIBRARY_STATE_NOARGS);
      
      arg_other_guard =
      THTensor_(new)(LIBRARY_STATE_NOARGS);
      
      expand_outplace2(LIBRARY_STATE arg_self_guard.get(), arg_other_guard.get(),
          arg_self, arg_other,
          "self", "other", !false);
      expand_success = true;
    }
  catch (std::exception &e) {}
    if(expand_success) {
      arg_self = arg_self_guard.get();
      arg_other = arg_other_guard.get();
    }
  }
  
  
  PyThreadState *_save = NULL;
  try {
    Py_UNBLOCK_THREADS;
    THTensor_(cmul)(LIBRARY_STATE arg_result, arg_self, arg_other);
    Py_BLOCK_THREADS;
    Py_INCREF(result);
    return (PyObject*)(result);
  } catch (...) {
    if (_save) {
      Py_BLOCK_THREADS;
    }
    throw;
  }
  arg_self = arg_self_save;
  arg_other = arg_other_save;
  
  

}

THPUtils_invalidArguments(args, kwargs, "mul", 3, "(" RealStr " value, #" THPTensorStr " out)", "(" PartStr " value, #" THPTensorStr " out)", "(" THPTensorStr " other, #" THPTensorStr " out)");
return NULL;
END_HANDLE_TH_ERRORS

}
And I here is the python stack trace of my call:
File “/home/philipp/projects/scikit-pr/skpr/core/p/models/x.py”, line 31, in forward
z = F.cmul(P, O_cropped)
File “/home/philipp/projects/scikit-pr/skpr/nn/functional.py”, line 12, in cmul
return CMul().forward(x,y)
File “/home/philipp/projects/scikit-pr/skpr/nn/_functions/CMul.py”, line 16, in forward
return x * y
File “/home/philipp/anaconda2/lib/python2.7/site-packages/torch/autograd/variable.py”, line 840, in mul
return self.mul(other)
File “/home/philipp/anaconda2/lib/python2.7/site-packages/torch/autograd/variable.py”, line 341, in mul
return Mul.apply(self, other)
File “/home/philipp/anaconda2/lib/python2.7/site-packages/torch/autograd/_functions/basic_ops.py”, line 66, in forward
return a.mul(b)
TypeError: mul received an invalid combination of arguments - got (torch.ZFloatTensor), but expected one of:

(float value)
didn’t match because some of the arguments have invalid types: (!torch.ZFloatTensor!)
(torch.cuda.ZFloatTensor other)
didn’t match because some of the arguments have invalid types: (!torch.ZFloatTensor!)

Now if I call mul with two tensors of type torch.cuda.ZFloatTensor, this means the code in the last [else if] statement should be executed.  Somehow one of the tensors is converted to OR recognized as torch.ZFloatTensor. Does anyone have an idea where this could happen or how.