From 14808d4fb2d29f25defec94400ef91a848b7c3e0 Mon Sep 17 00:00:00 2001 From: Shaikh Ubaid Date: Thu, 20 Jul 2023 15:43:16 +0530 Subject: [PATCH 1/4] TEST: Fix req import in symbolics_07.py --- integration_tests/symbolics_07.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/symbolics_07.py b/integration_tests/symbolics_07.py index 52b3a3902a..1b7e0261b0 100644 --- a/integration_tests/symbolics_07.py +++ b/integration_tests/symbolics_07.py @@ -1,4 +1,4 @@ -from lpython import ccall +from lpython import ccall, CPtr @ccall(header="symengine/cwrapper.h") def basic_new_heap() -> CPtr: From e1cdd782d6109c0bef7cea5dc75b9bd534333e4e Mon Sep 17 00:00:00 2001 From: Shaikh Ubaid Date: Thu, 20 Jul 2023 15:44:12 +0530 Subject: [PATCH 2/4] lpython.py: Support ccall() for symengine and other libs --- src/runtime/lpython/lpython.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/runtime/lpython/lpython.py b/src/runtime/lpython/lpython.py index 499083cdbc..871ddec4ad 100644 --- a/src/runtime/lpython/lpython.py +++ b/src/runtime/lpython/lpython.py @@ -335,7 +335,7 @@ class CTypes: A wrapper class for interfacing C via ctypes. """ - def __init__(self, f): + def __init__(self, f, py_mod = None, py_mod_path = None): def get_rtlib_dir(): current_dir = os.path.dirname(os.path.abspath(__file__)) return os.path.join(current_dir, "..") @@ -349,17 +349,20 @@ def get_lib_name(name): else: raise NotImplementedError("Platform not implemented") def get_crtlib_path(): - py_mod = os.environ.get("LPYTHON_PY_MOD_NAME", "") + nonlocal py_mod, py_mod_path + if py_mod is None: + py_mod = os.environ.get("LPYTHON_PY_MOD_NAME", "") if py_mod == "": return os.path.join(get_rtlib_dir(), get_lib_name("lpython_runtime")) else: - py_mod_path = os.environ["LPYTHON_PY_MOD_PATH"] + if py_mod_path is None: + py_mod_path = os.environ["LPYTHON_PY_MOD_PATH"] return os.path.join(py_mod_path, get_lib_name(py_mod)) self.name = f.__name__ self.args = f.__code__.co_varnames self.annotations = f.__annotations__ - if "LPYTHON_PY_MOD_NAME" in os.environ: + if ("LPYTHON_PY_MOD_NAME" in os.environ) or (py_mod is not None): crtlib = get_crtlib_path() self.library = ctypes.CDLL(crtlib) self.cf = self.library[self.name] @@ -465,10 +468,14 @@ def __init__(self, *args): return ctypes_Structure -def ccall(f): - if isclass(f) and issubclass(f, Union): - return f - return CTypes(f) +def ccall(f=None, header=None, c_shared_lib=None, c_shared_lib_path=None): + def wrap(func): + if not isclass(func) or not issubclass(func, Union): + func = CTypes(func, c_shared_lib, c_shared_lib_path) + return func + if f: + return wrap(f) + return wrap def pythoncall(*args, **kwargs): def inner(fn): From 3746ffd8f4138e316cf31609172130392bcc9c39 Mon Sep 17 00:00:00 2001 From: Shaikh Ubaid Date: Thu, 20 Jul 2023 15:51:51 +0530 Subject: [PATCH 3/4] TEST: Update test to specify symengine in ccall() --- integration_tests/symbolics_07.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/integration_tests/symbolics_07.py b/integration_tests/symbolics_07.py index 1b7e0261b0..f6d9ea947f 100644 --- a/integration_tests/symbolics_07.py +++ b/integration_tests/symbolics_07.py @@ -1,14 +1,15 @@ from lpython import ccall, CPtr +import os -@ccall(header="symengine/cwrapper.h") +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") def basic_new_heap() -> CPtr: pass -@ccall(header="symengine/cwrapper.h") +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") def basic_const_pi(x: CPtr) -> None: pass -@ccall(header="symengine/cwrapper.h") +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") def basic_str(x: CPtr) -> str: pass From f6eab9cf62aad18cdb25f75d7014e78ed429fa1e Mon Sep 17 00:00:00 2001 From: Shaikh Ubaid Date: Thu, 20 Jul 2023 21:01:53 +0530 Subject: [PATCH 4/4] lpython.py: Decode ctypes strings before returning --- src/runtime/lpython/lpython.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/runtime/lpython/lpython.py b/src/runtime/lpython/lpython.py index 871ddec4ad..4ec0faad4a 100644 --- a/src/runtime/lpython/lpython.py +++ b/src/runtime/lpython/lpython.py @@ -391,7 +391,10 @@ def __call__(self, *args, **kwargs): new_args.append(arg.ctypes.data_as(ctypes.POINTER(convert_numpy_dtype_to_ctype(arg.dtype)))) else: new_args.append(arg) - return self.cf(*new_args) + res = self.cf(*new_args) + if self.cf.restype == ctypes.c_char_p: + res = res.decode("utf-8") + return res def convert_to_ctypes_Union(f): fields = []