Skip to content

Commit

Permalink
Merge pull request lcompilers#1441 from czgdp1807/packed
Browse files Browse the repository at this point in the history
Support structs originating in C and read/modified in C/Python
  • Loading branch information
certik committed Jan 19, 2023
2 parents 7a43d1a + 99a2d17 commit f17d1ae
Show file tree
Hide file tree
Showing 8 changed files with 397 additions and 10 deletions.
4 changes: 4 additions & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ RUN(NAME structs_16 LABELS cpython llvm c)
RUN(NAME structs_17 LABELS cpython llvm c)
RUN(NAME structs_18 LABELS llvm c
EXTRAFILES structs_18b.c)
RUN(NAME structs_19 LABELS cpython llvm c
EXTRAFILES structs_19b.c)
RUN(NAME structs_20 LABELS cpython llvm c
EXTRAFILES structs_20b.c)
RUN(NAME sizeof_01 LABELS llvm c
EXTRAFILES sizeof_01b.c)
RUN(NAME enum_01 LABELS cpython llvm c)
Expand Down
130 changes: 130 additions & 0 deletions integration_tests/structs_19.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
from ltypes import (i8, dataclass, i32, f32, c32, f64, i16, i64, c64,
ccall, CPtr, c_p_pointer, Pointer, ccallable)
from numpy import empty, int32, int8, float32, float64, int16, int64, complex64, complex128

@ccallable
@dataclass
class buffer_struct:
buffer8: i8
buffer1: i32
buffer2: f32
buffer3: c32
buffer4: f64
buffer5: i16
buffer6: i64
buffer7: c64

@ccallable
@dataclass
class buffer_struct_array:
buffer8: i8[25]
buffer1: i32[16]
buffer2: f32[16]
buffer4: f64[16]
buffer5: i16[32]
buffer6: i64[8]
buffer3: c32[8]
buffer7: c64[4]

@ccall
def get_buffer() -> CPtr:
pass

@ccall
def fill_buffer(buffer_cptr: CPtr):
pass

@ccall
def get_buffer_array() -> CPtr:
pass

@ccall
def fill_buffer_array(buffer_cptr: CPtr):
pass

def f():
b: CPtr = get_buffer()
pb: Pointer[buffer_struct] = c_p_pointer(b, buffer_struct)
pb.buffer8 = i8(3)
pb.buffer1 = i32(4)
pb.buffer2 = f32(5)
pb.buffer3 = c32(9)
pb.buffer4 = f64(6)
pb.buffer5 = i16(7)
pb.buffer6 = i64(8)
pb.buffer7 = c64(10)
print(pb.buffer8)
print(pb.buffer1)
print(pb.buffer2)
print(pb.buffer3)
print(pb.buffer4)
print(pb.buffer5)
print(pb.buffer6)
print(pb.buffer7)
assert pb.buffer8 == i8(3)
assert pb.buffer1 == i32(4)
assert pb.buffer2 == f32(5)
assert pb.buffer3 == c32(9)
assert pb.buffer4 == f64(6)
assert pb.buffer5 == i16(7)
assert pb.buffer6 == i64(8)
assert pb.buffer7 == c64(10)

fill_buffer(b)
print(pb.buffer8)
print(pb.buffer1)
print(pb.buffer2)
print(pb.buffer3)
print(pb.buffer4)
print(pb.buffer5)
print(pb.buffer6)
print(pb.buffer7)
assert pb.buffer8 == i8(8)
assert pb.buffer1 == i32(9)
assert pb.buffer2 == f32(10)
assert pb.buffer3 == c32(14) + c32(15j)
assert pb.buffer4 == f64(11)
assert pb.buffer5 == i16(12)
assert pb.buffer6 == i64(13)
assert pb.buffer7 == c64(16) + c64(17j)

def f_array():
i: i32
b: CPtr = get_buffer_array()
pb: Pointer[buffer_struct_array] = c_p_pointer(b, buffer_struct_array)
pb.buffer8 = empty(25, dtype=int8)
pb.buffer1 = empty(16, dtype=int32)
pb.buffer2 = empty(16, dtype=float32)
pb.buffer4 = empty(16, dtype=float64)
pb.buffer5 = empty(32, dtype=int16)
pb.buffer6 = empty(8, dtype=int64)
pb.buffer3 = empty(8, dtype=complex64)
pb.buffer7 = empty(4, dtype=complex128)

fill_buffer_array(b)
for i in range(25):
print(pb.buffer8[i])
assert pb.buffer8[i] == i8(i + 8)

for i in range(16):
print(pb.buffer1[i], pb.buffer2[i], pb.buffer4[i])
assert pb.buffer1[i] == i32(i + 1)
assert pb.buffer2[i] == f32(i + 2)
assert pb.buffer4[i] == f64(i + 4)

for i in range(32):
print(pb.buffer5[i])
assert pb.buffer5[i] == i16(i + 5)

for i in range(8):
print(pb.buffer6[i], pb.buffer3[i])
assert pb.buffer6[i] == i64(i + 6)
assert pb.buffer3[i] == c32(i + 3)

for i in range(4):
print(pb.buffer7[i])
assert pb.buffer7[i] == c64(i + 7)


f()
f_array()
68 changes: 68 additions & 0 deletions integration_tests/structs_19b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <stdlib.h>
#include <complex.h>
#include "structs_19b.h"


struct buffer_c {
int8_t buffer8;
int32_t buffer1;
float buffer2;
float complex buffer3;
double buffer4;
int16_t buffer5;
int64_t buffer6;
double complex buffer7;
};

void fill_buffer(void* buffer_cptr) {
struct buffer_c* buffer_clink_ = (struct buffer_c*) buffer_cptr;
buffer_clink_->buffer8 = 8;
buffer_clink_->buffer1 = 9;
buffer_clink_->buffer2 = 10.0;
buffer_clink_->buffer3 = CMPLXF(14.0, 15.0);
buffer_clink_->buffer4 = 11.0;
buffer_clink_->buffer5 = 12;
buffer_clink_->buffer6 = 13;
buffer_clink_->buffer7 = CMPLXL(16.0, 17.0);
}

struct buffer_c_array {
int8_t buffer8[25];
int32_t buffer1[16];
float buffer2[16];
double buffer4[16];
int16_t buffer5[32];
int64_t buffer6[8];
float complex buffer3[8];
double complex buffer7[4];
};

void fill_buffer_array(void* buffer_cptr) {
struct buffer_c_array* buffer_clink_ = (struct buffer_c_array*) buffer_cptr;
for( int i = 0; i < 25; i++ ) {
buffer_clink_->buffer8[i] = i + 8;
}
for( int i = 0; i < 16; i++ ) {
buffer_clink_->buffer1[i] = i + 1;
buffer_clink_->buffer2[i] = i + 2;
buffer_clink_->buffer4[i] = i + 4;
}
for( int i = 0; i < 32; i++ ) {
buffer_clink_->buffer5[i] = i + 5;
}
for( int i = 0; i < 8; i++ ) {
buffer_clink_->buffer6[i] = i + 6;
buffer_clink_->buffer3[i] = CMPLXF(i + 3, 0.0);
}
for( int i = 0; i < 4; i++ ) {
buffer_clink_->buffer7[i] = CMPLXL(i + 7, 0.0);
}
}

void* get_buffer() {
return malloc(sizeof(struct buffer_c));
}

void* get_buffer_array() {
return malloc(sizeof(struct buffer_c_array));
}
6 changes: 6 additions & 0 deletions integration_tests/structs_19b.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <inttypes.h>

void fill_buffer(void* buffer_cptr);
void fill_buffer_array(void* buffer_cptr);
void* get_buffer();
void* get_buffer_array();
58 changes: 58 additions & 0 deletions integration_tests/structs_20.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from ltypes import (i8, dataclass, i32, f32, c32, f64, i16, i64, c64,
ccall, CPtr, c_p_pointer, Pointer, packed, ccallable)
from numpy import empty, int8, int16, float32, complex64

@ccallable
@packed
@dataclass
class buffer_struct_packed:
buffer8: i8[32]
buffer1: i16[32]
buffer2: i32
buffer3: f32[32]
buffer4: f64
buffer5: c32[32]
buffer6: c64

@ccall
def get_buffer() -> CPtr:
pass

@ccall
def fill_buffer(buffer_cptr: CPtr):
pass

def f():
i: i32
b: CPtr = get_buffer()
pb: Pointer[buffer_struct_packed] = c_p_pointer(b, buffer_struct_packed)
pb.buffer8 = empty(32, dtype=int8)
pb.buffer1 = empty(32, dtype=int16)
pb.buffer2 = i32(5)
pb.buffer3 = empty(32, dtype=float32)
pb.buffer4 = f64(6)
pb.buffer5 = empty(32, dtype=complex64)
pb.buffer6 = c64(8)
print(pb.buffer2)
print(pb.buffer4)
print(pb.buffer6)
assert pb.buffer2 == i32(5)
assert pb.buffer4 == f64(6)
assert pb.buffer6 == c64(8)

fill_buffer(b)
print(pb.buffer2)
print(pb.buffer4)
print(pb.buffer6)
assert pb.buffer2 == i32(3)
assert pb.buffer4 == f64(5)
assert pb.buffer6 == c64(7)

for i in range(32):
print(pb.buffer8[i], pb.buffer1[i], pb.buffer3[i], pb.buffer5[i])
assert pb.buffer8[i] == i8(i + 8)
assert pb.buffer1[i] == i16(i + 1)
assert pb.buffer3[i] == f32(i + 3)
assert pb.buffer5[i] == c32(i + 5)

f()
37 changes: 37 additions & 0 deletions integration_tests/structs_20b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <stdlib.h>
#include <complex.h>
#include "structs_20b.h"


struct __attribute__((packed)) buffer_c_packed {
int8_t buffer8[32];
int16_t buffer1[32];
int32_t buffer2;
float buffer3[32];
double buffer4;
float complex buffer5[32];
double complex buffer6;
};

void fill_buffer(void* buffer_cptr) {
struct buffer_c_packed* buffer_clink_ = (struct buffer_c_packed*) buffer_cptr;
for( int i = 0; i < 32; i++ ) {
buffer_clink_->buffer8[i] = i + 8;
}
for( int i = 0; i < 32; i++ ) {
buffer_clink_->buffer1[i] = i + 1;
}
buffer_clink_->buffer2 = 3;
for( int i = 0; i < 32; i++ ) {
buffer_clink_->buffer3[i] = i + 3;
}
buffer_clink_->buffer4 = 5;
for( int i = 0; i < 32; i++ ) {
buffer_clink_->buffer5[i] = CMPLXF(i + 5, 0.0);
}
buffer_clink_->buffer6 = CMPLXL(7, 0.0);
}

void* get_buffer() {
return malloc(sizeof(struct buffer_c_packed));
}
4 changes: 4 additions & 0 deletions integration_tests/structs_20b.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <inttypes.h>

void fill_buffer(void* buffer_cptr);
void* get_buffer();
Loading

0 comments on commit f17d1ae

Please sign in to comment.