After further investigation it's not a name conflict issue.

This compiles
    
    
    import ../src/arraymancer
    import nimpy
    import nimpy/raw_buffers
    import sequtils
    
    proc `+`[T](p: ptr T, val: int) : ptr T {.inline.}=
      cast[ptr T](cast[uint](p) + cast[uint](val * sizeof(T)))
    
    proc pyBufToTensor[T](ndArray: PyObject): Tensor[T]=
      # Convert PyObject to RawPyBuffer
      var aBuf: RawPyBuffer
      ndArray.getBuffer(aBuf, PyBUF_WRITABLE or PyBUF_ND)
      aBuf.release()
      
      # Copy buffer into Tensor
      var shape: seq[int]
      for i in 0..<aBuf.ndim:
        shape.add((aBuf.shape+i)[])
      
      # Get memory asdress of buffer
      var bufPtr = cast[ptr UncheckedArray[T]](aBuf.buf)
      # Get underlying data buffer of Tensor
      result = newTensor[T](shape)
      var tensorDataPtr = cast[ptr UncheckedArray[T]](result.get_data_ptr)
      # Copy Buffer into Tensor
      var length = shape.foldl(a*b)
      copyMem(tensorDataPtr, bufPtr, length*sizeof(T))
    
    let np = pyImport("numpy")
    
    proc nimfftshift(t: Tensor[float32]): Tensor[float32]=
      ## Reshape PyObject to Arraymancer Tensor
      #var ndArray = wrappy.w_fftshift(t.toSeq, t.shape.toSeq)
      var shape = np.`array`(t.shape.toSeq)
      var ndArray = np.`array`(t.toSeq)
      ndArray = np.reshape(ndArray, shape)
      ndArray = np.fft.fftshift(ndArray)
      
      # Convert RawPyBuffer to Tensor
      result = pyBufToTensor[float32](ndArray)
    
    proc main() =
      let a = randomTensor([3, 3], 3).asType(float32)
      echo a
      let b = nimfftshift(a)
      echo b
    
    main()
    
    
    Run

The difference is that pyBufToTensor is not a generic proc.

The underlying reason is a very thorny problem in Nim. In generic proc, Nim 
tries to resolve symbols and statement early, including `untyped` symbol. But 
`nimpy` relies on untyped symbol to do its magic: 
[https://github.com/yglukhov/nimpy/blob/b5401247](https://github.com/yglukhov/nimpy/blob/b5401247)

/nimpy.nim#L1285-L1289|   
---|---  
      
    
    template `.()`*(o: PyObject, field: untyped, args: varargs[untyped]): 
PyObject =
      dotCall(o, field, args)
    
    template `.`*(o: PyObject, field: untyped): PyObject =
      getAttr(o, astToStr(field))
    
    
    Run

So it does not have the opportunity to transform `np.reshape` into a wrapped 
call before Nim compiler tries to check if the reshape symbol is valid in 
generic procs.

Unfortunately that is a bug that is very hard to solve.

Reply via email to