0

I am trying to get Chapel to return an integer to Python. I'd like to call it with python call.py.

call.py

import os
from pych.extern import Chapel

currentloc = os.path.dirname(os.path.realpath(__file__))


@Chapel(sfile=os.path.join(currentloc + '/response.chpl'))
def flip_bit(v=int):
    return int

if __name__=="__main__":
    u = 71
    w = flip_bit(u)
    print(w)

And response.chpl

export
proc flip_bit(v: int) :int {
  v = -v;
  return v;
}

This returns the error

/tmp/temp-7afvL9.chpl:2: In function 'flip_bit':
/tmp/temp-7afvL9.chpl:3: error: illegal lvalue in assignment
g++: error: /tmp/tmpvmKeSi.a: No such file or directory
Traceback (most recent call last):
  File "call.py", line 15, in <module>
    w = flip_bit(u)
  File "/home/buddha314/.virtualenvs/pychapel/local/lib/python2.7/site-packages/pych/extern.py", line 212, in wrapped_f
    raise MaterializationError(self)
pych.exceptions.MaterializationError: Failed materializing ({'anames': ['v'],
 'atypes': [<type 'int'>],
 'bfile': None,
 'dec_fp': '/home/buddha314/pychapel/tmp/response.chpl',
 'dec_hs': '7ecfac2d168f3423f7104eeb38057ac3',
 'dec_ts': 1502208246,
 'doc': None,
 'efunc': None,
 'ename': 'flip_bit',
 'lib': 'sfile-chapel-7ecfac2d168f3423f7104eeb38057ac3-1502208246.so',
 'module_dirs': [],
 'pfunc': <function flip_bit at 0x7fa4d72bd938>,
 'pname': 'flip_bit',
 'rtype': <type 'int'>,
 'sfile': '/home/buddha314/pychapel/tmp/response.chpl',
 'slang': 'chapel',
 'source': None}).

UPDATE

Based on Lydia's response, I did

export
proc flip_bit(v: int) :int {
  var w: int;
  w = -v;
  return w;
}

And that worked! WOO-HOOO!!!!


UPDATE 2

Based on Brad's comments, this also works

export
proc flip_bit(in v: int) :int {
  return -v;
}

Perhaps he can add a comment on benefits of each approach.

user3666197
  • 1
  • 6
  • 50
  • 92
Brian Dolan
  • 3,086
  • 2
  • 24
  • 35
  • 2
    Another option rather than using a local variable `w` in `flip_bit()` would be to use an explicit intent like `in` which means "copy the actual argument into the formal argument when the function is called" (similar to how C passes integers). That is: `proc flip_bit(in v: int): int { ... }` – Brad Aug 08 '17 at 17:52
  • Cool! That worked, too. Can you explain benefits of each approach? – Brian Dolan Aug 08 '17 at 17:56
  • 1
    Mostly just style: Both versions will make a copy of the actual into the formal at the call, but the default intent won't let you modify it (primarily because it seemed the best way to avoid surprises for users coming from various languages in defining Chapel). So the question comes down to whether you prefer to introduce the local variable or re-use the formal argument symbol. – Brad Aug 08 '17 at 17:57
  • 3
    Also, note that this question is independent of Python / PyChapel—i.e., if I compile your Chapel code using the Chapel compiler directly, I get the same error. To that end, you might take the approach of getting your Chapel code compiling cleanly first, and then integrating it into Python. This would also make for more precise/targeted SO questions (e.g., all of the Python-related code and errors above could be omitted). – Brad Aug 08 '17 at 18:00

1 Answers1

2

It looks like your issue is that you're trying to modify the argument before returning it. Chapel's default argument intent for integers is const in ( see the Chapel spec http://chapel.cray.com/docs/latest/language/spec.html, section 13.5 ), which means it can't be modified within the body of the function and is a copy of the value passed to it. If you store the result in a local variable and return that instead, that should solve your compilation failure and give you the behavior you desire.

user3666197
  • 1
  • 6
  • 50
  • 92
Lydia Duncan
  • 595
  • 2
  • 8