Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Update python tests for pointers in emulation mode #1340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ RUN(NAME array_02_decl LABELS cpython llvm c)
RUN(NAME array_03_decl LABELS cpython llvm c)
RUN(NAME array_expr_01 LABELS cpython llvm)
RUN(NAME array_expr_02 LABELS cpython llvm)
RUN(NAME bindc_01 LABELS llvm c)
RUN(NAME bindc_02 LABELS llvm c)
RUN(NAME bindc_01 LABELS cpython llvm c)
RUN(NAME bindc_02 LABELS cpython llvm c)
RUN(NAME bindc_04 LABELS llvm c)
RUN(NAME exit_01 LABELS cpython llvm c)
RUN(NAME exit_02 FAIL LABELS cpython llvm c)
Expand Down Expand Up @@ -314,7 +314,7 @@ RUN(NAME test_unary_plus LABELS cpython llvm c)
RUN(NAME test_bool_binop LABELS cpython llvm c)
RUN(NAME test_issue_518 LABELS cpython llvm c)
RUN(NAME structs_01 LABELS cpython llvm c)
RUN(NAME structs_02 LABELS llvm c)
RUN(NAME structs_02 LABELS cpython llvm c)
RUN(NAME structs_03 LABELS llvm c)
RUN(NAME structs_04 LABELS cpython llvm c)
RUN(NAME structs_05 LABELS llvm c)
Expand All @@ -329,7 +329,7 @@ RUN(NAME structs_12 LABELS cpython llvm c)
RUN(NAME structs_13 LABELS llvm c
EXTRAFILES structs_13b.c)
RUN(NAME structs_15 LABELS cpython llvm c)
RUN(NAME sizeof_01 LABELS llvm c
RUN(NAME sizeof_01 LABELS llvm c
EXTRAFILES sizeof_01b.c)
RUN(NAME enum_01 LABELS cpython llvm c)
RUN(NAME enum_02 LABELS cpython llvm)
Expand Down
4 changes: 2 additions & 2 deletions integration_tests/bindc_01.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from ltypes import c_p_pointer, CPtr, i16, Pointer
from ltypes import c_p_pointer, CPtr, i16, Pointer, empty_c_void_p

queries: CPtr
queries: CPtr = empty_c_void_p()
x: Pointer[i16] = c_p_pointer(queries, i16)
print(queries, x)
9 changes: 5 additions & 4 deletions integration_tests/bindc_02.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from ltypes import c_p_pointer, CPtr, pointer, i16, Pointer
from ltypes import c_p_pointer, CPtr, pointer, i16, Pointer, empty_c_void_p
from numpy import empty, int16

queries: CPtr
queries: CPtr = empty_c_void_p()
x: Pointer[i16[:]] = c_p_pointer(queries, i16[:])
print(queries, x)

def f():
yq: CPtr
yq: CPtr = empty_c_void_p()
yptr1: Pointer[i16[:]]
y: i16[2]
y: i16[2] = empty(2, dtype=int16)
y[0] = i16(1)
y[1] = i16(2)
yptr1 = pointer(y)
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/bindc_05.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ltypes import CPtr, c_p_pointer, empty_c_void_p, i32, f32, dataclass, Pointer, ccall, p_c_pointer, pointer
from ltypes import CPtr, empty_c_void_p, i32, f32, dataclass, Pointer, ccall, p_c_pointer, pointer

@dataclass
class Void:
Expand Down
6 changes: 3 additions & 3 deletions integration_tests/structs_02.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ltypes import i32, f32, dataclass, CPtr, Pointer, c_p_pointer, pointer
from ltypes import i32, f32, dataclass, CPtr, Pointer, c_p_pointer, pointer, ccallable, empty_c_void_p, f64

@dataclass
class A:
Expand All @@ -18,11 +18,11 @@ def f(a: CPtr) -> None:
y = a2.y
assert x == 3
assert f64(y) == 3.25
c_p_pointer(a, a2)
a2 = c_p_pointer(a, A)
print(a, a2, pointer(a1))

def g():
b: CPtr
b: CPtr = empty_c_void_p()
f(b)

g()
8 changes: 3 additions & 5 deletions integration_tests/structs_13.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ltypes import i32, i16, i64, CPtr, dataclass, ccall, Pointer, c_p_pointer
from ltypes import i32, i16, i64, CPtr, dataclass, ccall, Pointer, c_p_pointer, sizeof

@dataclass
class A:
Expand All @@ -23,8 +23,7 @@ def add_Aptr_members(Ax: i32, Ay: i16) -> i32:
def test_A_member_passing():
array_cptr: CPtr = cmalloc(sizeof(A) * i64(10))
assert not bool(is_null(array_cptr)), "Failed to allocate array on memory"
array_ptr: Pointer[A[:]]
c_p_pointer(array_cptr, array_ptr)
array_ptr: Pointer[A[:]] = c_p_pointer(array_cptr, A[:])
i: i32; sum_A_members: i32
for i in range(10):
array_ptr[i] = A(i, i16(i + 1))
Expand All @@ -47,8 +46,7 @@ def test_A_member_passing():
def test_Aptr_member_passing():
a_cptr: CPtr = cmalloc(sizeof(A) * i64(1))
assert not bool(is_null(a_cptr)), "Failed to allocate array on memory"
a_ptr: Pointer[A]
c_p_pointer(a_cptr, a_ptr)
a_ptr: Pointer[A] = c_p_pointer(a_cptr, A)
print(add_A_members(a_ptr.x, a_ptr.y), add_Aptr_members(a_ptr.x, a_ptr.y))
assert add_A_members(a_ptr.x, a_ptr.y) == add_Aptr_members(a_ptr.x, a_ptr.y)

Expand Down
12 changes: 6 additions & 6 deletions integration_tests/test_c_interop_04.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
p_c_pointer, empty_c_void_p)
from numpy import empty, int32

@ccall
def sum_pi32_i32(x: CPtr) -> i32:
pass
# @ccall
# def sum_pi32_i32(x: CPtr) -> i32:
# pass

def test_c_callbacks():
xi32: i32[4]
Expand All @@ -19,8 +19,8 @@ def test_c_callbacks():
p = empty_c_void_p()
p_c_pointer(pointer(xi32), p)
print(pointer(xi32), p)
sumi32 = sum_pi32_i32(p)
print(sumi32)
assert sumi32 == 18
# sumi32 = sum_pi32_i32(p)
# print(sumi32)
# assert sumi32 == 18

test_c_callbacks()
23 changes: 13 additions & 10 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5607,18 +5607,25 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
}

void visit_Call(const AST::Call_t &x) {
std::string call_name;
std::string call_name = "";
Vec<ASR::call_arg_t> args;
if (AST::is_a<AST::Name_t>(*x.m_func)) {
AST::Name_t *n = AST::down_cast<AST::Name_t>(x.m_func);
call_name = n->m_id;
}
if (call_name == "c_p_pointer" &&
!current_scope->resolve_symbol(call_name)) {
is_c_p_pointer_call = true;
tmp = nullptr;
return ;
}
// Keyword arguments handled in make_call_helper
if( x.n_keywords == 0 ) {
args.reserve(al, x.n_args);
visit_expr_list(x.m_args, x.n_args, args);
}

if (AST::is_a<AST::Name_t>(*x.m_func)) {
AST::Name_t *n = AST::down_cast<AST::Name_t>(x.m_func);
call_name = n->m_id;
} else if (AST::is_a<AST::Attribute_t>(*x.m_func)) {
if (AST::is_a<AST::Attribute_t>(*x.m_func)) {
AST::Attribute_t *at = AST::down_cast<AST::Attribute_t>(x.m_func);
if (AST::is_a<AST::Name_t>(*at->m_value)) {
AST::Name_t *n = AST::down_cast<AST::Name_t>(at->m_value);
Expand Down Expand Up @@ -5689,7 +5696,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
throw SemanticError("Only Name type and constant integers supported in Call",
x.base.base.loc);
}
} else {
} else if( call_name == "" ) {
throw SemanticError("Only Name or Attribute type supported in Call",
x.base.base.loc);
}
Expand Down Expand Up @@ -5858,10 +5865,6 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
tmp = intrinsic_node_handler.get_intrinsic_node(call_name, al,
x.base.base.loc, args);
return;
} else if (call_name == "c_p_pointer") {
is_c_p_pointer_call = true;
tmp = nullptr;
return ;
} else {
// The function was not found and it is not intrinsic
throw SemanticError("Function '" + call_name + "' is not declared and not intrinsic",
Expand Down
55 changes: 43 additions & 12 deletions src/runtime/ltypes/ltypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "CPtr",
"overload", "ccall", "TypeVar", "pointer", "c_p_pointer", "Pointer",
"p_c_pointer", "vectorize", "inline", "Union", "static", "with_goto",
"packed", "Const", "sizeof"]
"packed", "Const", "sizeof", "ccallable"]

# data-types

Expand All @@ -23,7 +23,7 @@ def __getitem__(self, params):
def __call__(self, arg):
return arg

class Pointer:
class PointerType(Type):
def __getitem__(self, type):
if is_dataclass(type):
return convert_to_ctypes_Structure(type)
Expand All @@ -49,6 +49,7 @@ def __init__(self, type, dims):
CPtr = Type("c_ptr")
Const = ConstType("Const")
Union = ctypes.Union
Pointer = PointerType("Pointer")

# Generics

Expand Down Expand Up @@ -181,6 +182,27 @@ def convert_type_to_ctype(arg):
else:
raise NotImplementedError("Type %r not implemented" % arg)

def convert_numpy_dtype_to_ctype(arg):
import numpy as np
if arg == np.float64:
return ctypes.c_double
elif arg == np.float32:
return ctypes.c_float
elif arg == np.int64:
return ctypes.c_int64
elif arg == np.int32:
return ctypes.c_int32
elif arg == np.int16:
return ctypes.c_int16
elif arg == np.int8:
return ctypes.c_int8
elif arg == np.void:
return ctypes.c_void_p
elif arg is None:
raise NotImplementedError("Type cannot be None")
else:
raise NotImplementedError("Type %r not implemented" % arg)

class CTypes:
"""
A wrapper class for interfacing C via ctypes.
Expand Down Expand Up @@ -274,26 +296,27 @@ def union(f):
f.__annotations__ = {}
return f

def pointer(x, type=None):
def pointer(x, type_=None):
if type_ is None:
type_ = type(x)
from numpy import ndarray
if isinstance(x, ndarray):
return ctypes.c_void_p(x.ctypes.data)
#return x.ctypes.data_as(ctypes.POINTER(ctypes.c_int32))
return x.ctypes.data_as(ctypes.POINTER(convert_numpy_dtype_to_ctype(x.dtype)))
else:
if type == i32:
#return ctypes.c_void_p(ctypes.pointer(ctypes.c_int32(x)))
#return ctypes.pointer(ctypes.c_int32(x))
if type_ == i32:
return ctypes.cast(ctypes.pointer(ctypes.c_int32(x)),
ctypes.c_void_p)
elif type == i64:
elif type_ == i64:
return ctypes.cast(ctypes.pointer(ctypes.c_int64(x)),
ctypes.c_void_p)
elif type == f32:
elif type_ == f32:
return ctypes.cast(ctypes.pointer(ctypes.c_float(x)),
ctypes.c_void_p)
elif type == f64:
elif type_ == f64:
return ctypes.cast(ctypes.pointer(ctypes.c_double(x)),
ctypes.c_void_p)
elif is_dataclass(type_):
return x
else:
raise Exception("Type not supported in pointer()")

Expand All @@ -319,10 +342,18 @@ def c_p_pointer(cptr, targettype):
return newa

def p_c_pointer(ptr, cptr):
cptr.value = ptr.value
if isinstance(ptr, ctypes.c_void_p):
cptr.value = ptr.value
else:
# assign the address of ptr in memory to cptr.value
# the case for numpy arrays converted to a pointer
cptr.value = id(ptr)

def empty_c_void_p():
return ctypes.c_void_p()

def sizeof(arg):
return ctypes.sizeof(convert_type_to_ctype(arg))

def ccallable(f):
return f
2 changes: 1 addition & 1 deletion tests/reference/asr-bindc_01-6d521a9.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"basename": "asr-bindc_01-6d521a9",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/../integration_tests/bindc_01.py",
"infile_hash": "ce44dc48f31bcf876253727ca139210d99193565be1cf9b5fd3dea40",
"infile_hash": "3402ae1e5ed454e63ac3105da5d7264c880b666ac0ae672bf6b2dcfe",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-bindc_01-6d521a9.stdout",
Expand Down
4 changes: 2 additions & 2 deletions tests/reference/asr-bindc_02-bc1a7ea.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"basename": "asr-bindc_02-bc1a7ea",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/../integration_tests/bindc_02.py",
"infile_hash": "f7a7faa22c2440be545994170ef21f451ce95960c7c7c217db5221fb",
"infile_hash": "b63020f2df6e1cdbc6bd3fd8ef551b6b62fda00345bbeb12c7b94305",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-bindc_02-bc1a7ea.stdout",
"stdout_hash": "3165b2da8871ec50f1243662d58fe93d7b92c3166ef180eca07d2152",
"stdout_hash": "2017ce7ad8eb4648d2694de7fce0551975d37d2357f65d9f132c961d",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/asr-bindc_02-bc1a7ea.stdout

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tests/reference/asr-structs_02-2ab459a.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"basename": "asr-structs_02-2ab459a",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/../integration_tests/structs_02.py",
"infile_hash": "f18e545de56936a4906c0d46d9ecb80472bd4d69ecdfe98cd4d6b09f",
"infile_hash": "de732ccae77457ef2eb696bd3501e6623d437573974df4281b09dc97",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-structs_02-2ab459a.stdout",
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/llvm-bindc_01-c984f09.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"basename": "llvm-bindc_01-c984f09",
"cmd": "lpython --no-color --show-llvm {infile} -o {outfile}",
"infile": "tests/../integration_tests/bindc_01.py",
"infile_hash": "ce44dc48f31bcf876253727ca139210d99193565be1cf9b5fd3dea40",
"infile_hash": "3402ae1e5ed454e63ac3105da5d7264c880b666ac0ae672bf6b2dcfe",
"outfile": null,
"outfile_hash": null,
"stdout": "llvm-bindc_01-c984f09.stdout",
Expand Down
13 changes: 0 additions & 13 deletions tests/reference/llvm-bindc_02-3cf74e9.json

This file was deleted.

Loading