Skip to content
Snippets Groups Projects
Commit 94b47b27 authored by lhausamm's avatar lhausamm
Browse files

Structure wrapper is working (except from pointers)

parent 89670bb9
No related branches found
No related tags found
1 merge request!1Init
from pyswiftsim import *
import struct
import numpy
######################################################################
# #
# SwiftStruct #
# #
######################################################################
class SwiftStruct(struct.Struct):
"""
Abstract class constructing a wrapper around a C structure
Parameters
----------
struct_format: str
Text defining the data type in the structure (see struct module for
more informations)
data: str, list
Bytes string containing all the data of a structure or
dictionary of attribute (all the attribute should be present)
parent: :class:`SwiftStruct`
Parent containing the data (usefull for :class:`ArrayStruct`)
"""
def __init__(self, struct_format, data, parent):
super().__init__(struct_format)
self.parent = parent # parent for ArrayStruct
if isinstance(data, bytes):
self.data = data # bytes string data
elif isinstance(data, dict):
tmp = []
for i in self.struct_name:
tmp.append(data[i])
self.data = self.pack(*tmp)
else:
raise ValueError("Data should be either bytes or dict, "
"received ", type(data))
@property
def struct_name(self):
"""
List of the structure attribute names.
Should be implemented for each sub class
"""
raise NotImplementedError("SwiftStruct should not be used")
@property
def struct_format(self):
"""
String containing the data type of each attribute
"""
raise NotImplementedError("SwiftStruct should not be used")
def _getInfoFromName(self, name):
"""
Compute index, format and size from an attribute name.
Parameters
----------
name: str
Name of an attribute
Returns
-------
i: int, slice
index of the attribute
form: char
data type (see module struct for more information)
n: int
number of element in attribute
"""
struct_size, form = self.struct_size_format
i = self.struct_name.index(name)
form = form[i]
n = struct_size[i]
i = sum(struct_size[:i])
if n > 1:
i = slice(i, i+n)
return i, form, n
@property
def struct_size_format(self):
"""
Compute size and format for each field
Returns
-------
out_nber: list
number of element for each attribute
out_form: list
format for each attribute
"""
out_nber = []
out_form = []
form = self.struct_format
N = len(form)
ii = 0
while ii < N:
v = form[ii]
if v.isdigit():
out_nber.append(int(v))
out_form.append(form[ii+1])
# next value is the type => skip
ii += 1
else:
out_nber.append(1)
out_form.append(v)
ii += 1
return out_nber, out_form
def __str__(self):
txt = "%s:\n" % type(self)
data = self.unpack(self.data)
for name in self.struct_name:
i, form, n = self._getInfoFromName(name)
d = data[i]
txt += "\t%s: %s\n" % (name, d)
return txt
def __getattr__(self, name):
# case where the attribute is not in the structure
if name not in self.struct_name:
return object.__getattribute__(self, name)
# case where the attribute is in the structure
else:
print("get", type(self))
i, form, n = self._getInfoFromName(name)
data = self.unpack(self.data)
if n == 1:
return data[i]
else:
# transform scalar -> vector
nform = str(n) + form
i = slice(i.start, n)
data = data[i]
# compress data and create return struct
data = struct.pack(nform, *data)
return ArrayStruct(nform, data, self, name)
def __setattr__(self, name, value):
# case where the attribute is not in the structure
if name not in self.struct_name:
object.__setattr__(self, name, value)
# case where the attribute is in the structure
else:
print("set", type(self))
data = list(self.unpack(self.data))
i, form, n = self._getInfoFromName(name)
if isinstance(value, ArrayStruct):
value = value.getArray()
data[i] = value
self.data = self.pack(*data)
######################################################################
# #
# ArrayStruct #
# #
######################################################################
class ArrayStruct(SwiftStruct):
def __init__(self, struct_format, data, parent, name):
super().__init__(struct_format, data, parent)
self._name = name
self._format = struct_format
def __getitem__(self, ii):
print("getitem")
data = self.unpack(self.data)
return data[ii]
def __setitem__(self, ii, value):
print("setitem")
data = list(self.unpack(self.data))
data[ii] = value
setattr(self.parent, self._name, data)
def getArray(self):
return self.unpack(self.data)
@property
def struct_name(self):
return [
"array_data"
]
@property
def struct_format(self):
return self._format
######################################################################
# #
# UnitSystem #
# #
######################################################################
class UnitSystem(SwiftStruct):
def __init__(self, data, parent=None):
super().__init__(self.struct_format, data, parent)
@property
def struct_format(self):
return "ddddd"
@property
def struct_name(self):
return [
"UnitMass_in_cgs",
"UnitLength_in_cgs",
"UnitTime_in_cgs",
"UnitCurrent_in_cgs",
"UnitTemperature_in_cgs",
]
######################################################################
# #
# Part #
# #
######################################################################
class Part(SwiftStruct):
def __init__(self, data, parent=None):
super().__init__(self.struct_format, data, parent)
@property
def struct_format(self):
return "3d3ffP"
@property
def struct_name(self):
return [
"pos",
"vel",
"entropy",
"test"
]
......@@ -42,7 +42,7 @@ data_files = []
##############
c_src = glob("src/*.c")
ext_modules = Extension("pyswiftsim",
ext_modules = Extension("pyswiftsim.wrapper",
c_src,
include_dirs=include,
libraries=lib)
......
#include "units.h"
#include "tools.h"
#include "part.h"
#include <Python.h>
#include <stdlib.h>
#include <string.h>
PyObject* test(PyObject *self, PyObject *args) {
PyObject* test(PyObject *self, PyObject *args)
{
/*
size_t N = sizeof(struct unit_system);
struct unit_system *us = malloc(N);
us->UnitMass_in_cgs = 1.;
us->UnitLength_in_cgs = 1.;
us->UnitTime_in_cgs = 1.;
us->UnitCurrent_in_cgs = 1.;
us->UnitTemperature_in_cgs = 1.;
us->UnitLength_in_cgs = 2.;
us->UnitTime_in_cgs = 3.;
us->UnitCurrent_in_cgs = 4.;
us->UnitTemperature_in_cgs = 5.;
//char *tmp = malloc(N);
//memcpy(tmp, us, N);
return PyBytes_FromStringAndSize((char*) us, N);
PyObject *object = tools_return(us, class_units);
*/
size_t N = sizeof(struct part);
struct part *p = malloc(N);
p->pos[0] = 1.;
p->pos[1] = 2.;
p->pos[2] = 3.;
p->vel[0] = 5.;
p->vel[1] = 6.;
p->vel[2] = 7.;
p->entropy = 8.;
p->test = p;
PyObject *object = tools_return(p, class_part);
return object;
}
......@@ -9,7 +9,7 @@
/* definition of the method table */
static PyMethodDef pyswiftsim_methods[] = {
static PyMethodDef wrapper_methods[] = {
{"test", test, METH_VARARGS,
"Test."},
......@@ -19,22 +19,22 @@ static PyMethodDef pyswiftsim_methods[] = {
static struct PyModuleDef pyswiftsim_cmodule = {
static struct PyModuleDef wrapper_cmodule = {
PyModuleDef_HEAD_INIT,
"pyswiftsim",
"wrapper",
"Wrapper around the SPH cosmological simulation code SWIFT",
-1,
pyswiftsim_methods
wrapper_methods
};
PyMODINIT_FUNC PyInit_pyswiftsim(void)
PyMODINIT_FUNC PyInit_wrapper(void)
{
PyObject *m;
Py_Initialize();
import_array();
m = PyModule_Create(&pyswiftsim_cmodule);
m = PyModule_Create(&wrapper_cmodule);
if (m == NULL)
return NULL;
......
#!/usr/bin/env python3
import pyswiftsim
print(dir(pyswiftsim))
print(pyswiftsim.__file__)
from pyswiftsim import wrapper
from pyswiftsim import structure
t = pyswiftsim.test()
us = wrapper.test()
import struct
#us = structure.Units(t)
#print(len(t), t)
#print(type(us), us.struct_name)
#print(us.struct_size_format)
print(t)
data = struct.unpack("ddddd", t)
#for i in us.struct_name:
# print(i, getattr(us, i))
print(data)
print(us.pos)
us.pos = [12., 16., 11.]
#us.pos[0] = 10.
print(us)
print(us.pos)
print("setitem")
us.pos[2] = 20.
print(us.pos)
print(us)
d = {}
d["UnitMass_in_cgs"] = 1.
d["UnitLength_in_cgs"] = 2.
d["UnitTime_in_cgs"] = 3.
d["UnitCurrent_in_cgs"] = 4.
d["UnitTemperature_in_cgs"] = 5.
us = structure.UnitSystem(d)
print(us)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment