Skip to content
Snippets Groups Projects
Commit 6ca9cc65 authored by lhausamm's avatar lhausamm
Browse files

Wrapper is working for unit_system, swift_params and phys_const.

parent 03d1b178
No related branches found
No related tags found
1 merge request!1Init
This commit is part of merge request !1. Comments created here will be created in the context of that merge request.
...@@ -2,6 +2,9 @@ import struct ...@@ -2,6 +2,9 @@ import struct
import numpy import numpy
from ctypes import * from ctypes import *
PARSER_MAX_LINE_SIZE = 256
PARSER_MAX_NO_OF_PARAMS = 256
PARSER_MAX_NO_OF_SECTIONS = 64
###################################################################### ######################################################################
# # # #
...@@ -58,6 +61,14 @@ class SwiftStruct(struct.Struct): ...@@ -58,6 +61,14 @@ class SwiftStruct(struct.Struct):
""" """
raise NotImplementedError("SwiftStruct should not be used") raise NotImplementedError("SwiftStruct should not be used")
@property
def struct_substruct(self):
"""
Dictionary containing the class of each substructure.
See for example SwiftParams
"""
return {}
def _getInfoFromName(self, name): def _getInfoFromName(self, name):
""" """
...@@ -115,28 +126,37 @@ class SwiftStruct(struct.Struct): ...@@ -115,28 +126,37 @@ class SwiftStruct(struct.Struct):
ii = 0 ii = 0
while ii < N: while ii < N:
v = form[ii] v = form[ii]
if v.isdigit(): count = ""
out_nber.append(int(v)) while v.isdigit():
out_form.append(form[ii+1]) count += v
# next value is the type => skip
ii += 1 ii += 1
else: v = form[ii]
out_nber.append(1)
out_form.append(v) if count == "":
count = 1
if v == "s":
count = 1
count = int(count)
out_nber.append(count)
out_form.append(v)
ii += 1 ii += 1
return out_nber, out_form return out_nber, out_form
def __str__(self): def __str__(self):
txt = "%s:\n" % type(self) tab = ""
print(len(self.data)) parent = self.parent
data = self.unpack(self.data) while parent is not None:
tab += "\t"
parent = parent.parent
txt = tab + "%s:\n" % type(self)
for name in self.struct_name: for name in self.struct_name:
i, form, n = self._getInfoFromName(name) d = getattr(self, name)
d = data[i] txt += tab + "\t%s: %s\n" % (name, d)
txt += "\t%s: %s\n" % (name, d)
return txt return txt
def __getattr__(self, name): def __getattr__(self, name):
...@@ -150,12 +170,24 @@ class SwiftStruct(struct.Struct): ...@@ -150,12 +170,24 @@ class SwiftStruct(struct.Struct):
data = self.unpack(self.data) data = self.unpack(self.data)
if n == 1: if n == 1:
return data[i] # if substruct
if name in self.struct_substruct:
d = self.struct_substruct[name]
cl = d["class"]
tmp = []
size = struct.calcsize(cl._format)
for j in range(d["size"]):
data_tmp = data[i][size*j:(j+1)*size]
tmp.append(cl(data_tmp, parent=self))
return tmp
# other case => array
else:
return data[i]
else: else:
# transform scalar -> vector # transform scalar -> vector
nform = str(n) + form nform = str(n) + form
i = slice(i.start, n) i = slice(i.start, i.start+n)
data = data[i] data = data[i]
# compress data and create return struct # compress data and create return struct
...@@ -199,6 +231,10 @@ class ArrayStruct(SwiftStruct): ...@@ -199,6 +231,10 @@ class ArrayStruct(SwiftStruct):
data = list(self.unpack(self.data)) data = list(self.unpack(self.data))
data[ii] = value data[ii] = value
setattr(self.parent, self._name, data) setattr(self.parent, self._name, data)
def __str__(self):
data = self.unpack(self.data)
return str(data)
def getArray(self): def getArray(self):
...@@ -273,3 +309,141 @@ class Part(SwiftStruct): ...@@ -273,3 +309,141 @@ class Part(SwiftStruct):
"time_bin" "time_bin"
] ]
######################################################################
# #
# Parameter #
# #
######################################################################
class Parameter(SwiftStruct):
_format = "{line_size}c{line_size}c".format(
line_size=PARSER_MAX_LINE_SIZE
)
_name = [
"name",
"value"
]
def __init__(self, data, parent=None):
super().__init__(self.struct_format, data, parent)
@property
def struct_format(self):
return Parameter._format
@property
def struct_name(self):
return Parameter._name
######################################################################
# #
# Section #
# #
######################################################################
class Section(SwiftStruct):
_format = "{line_size}c".format(
line_size=PARSER_MAX_LINE_SIZE
)
_name = [
"name"
]
def __init__(self, data, parent=None):
super().__init__(self.struct_format, data, parent)
@property
def struct_format(self):
return Section._format
@property
def struct_name(self):
return Section._name
######################################################################
# #
# SwiftParams #
# #
######################################################################
class SwiftParams(SwiftStruct):
_format = "{sec}s{data}sii{line_size}c".format(
sec=struct.calcsize(Section._format)*PARSER_MAX_NO_OF_SECTIONS,
data=struct.calcsize(Parameter._format)*PARSER_MAX_NO_OF_PARAMS,
line_size=PARSER_MAX_LINE_SIZE
)
_name = [
"section",
"data_params",
"sectionCount",
"paramCount",
"filename"
]
def __init__(self, data, parent=None):
super().__init__(self.struct_format, data, parent)
@property
def struct_format(self):
return SwiftParams._format
@property
def struct_name(self):
return SwiftParams._name
@property
def struct_substruct(self):
sec = {
"class": Section,
"size": PARSER_MAX_NO_OF_SECTIONS
}
param = {
"class": Parameter,
"size": PARSER_MAX_NO_OF_PARAMS
}
return {
"section": sec,
"data_params": param
}
######################################################################
# #
# PhysConst #
# #
######################################################################
class PhysConst(SwiftStruct):
_format = "dddddddddddddddd"
_name = [
"const_newton_G",
"const_speed_light_c",
"const_planck_h",
"const_planck_hbar",
"const_boltzmann_k",
"const_thomson_cross_section",
"const_electron_charge",
"const_electron_volt",
"const_electron_mass",
"const_proton_mass",
"const_year",
"const_astronomical_unit",
"const_parsec",
"const_light_year",
"const_solar_mass",
"const_earth_mass",
]
def __init__(self, data, parent=None):
super().__init__(self.struct_format, data, parent)
@property
def struct_format(self):
return PhysConst._format
@property
def struct_name(self):
return PhysConst._name
...@@ -58,20 +58,16 @@ if swift_path is not None: ...@@ -58,20 +58,16 @@ if swift_path is not None:
# C libraries # C libraries
lib = ["m", lib = ["m",
"swiftsim",
"hdf5"
] ]
if swift_path is not None: lib_dir = []
lib.insert(0, swift_path + "/src/.libs/libswiftsim")
# hdf5
lib.insert(0, hdf5_root + "/lib/libhdf5")
else:
lib.append("swiftsim")
lib.append("hdf5")
if swift_path is not None:
lib_dir.append(swift_path + "/src/.libs")
lib_dir.append(hdf5_root + "/lib")
# mpi
# src files # src files
c_src = [] c_src = []
...@@ -88,7 +84,8 @@ c_src = glob("src/*.c") ...@@ -88,7 +84,8 @@ c_src = glob("src/*.c")
ext_modules = Extension("pyswiftsim.wrapper", ext_modules = Extension("pyswiftsim.wrapper",
c_src, c_src,
include_dirs=include, include_dirs=include,
libraries=lib) libraries=lib,
library_dirs=lib_dir)
ext_modules = [ext_modules] ext_modules = [ext_modules]
......
#include "pyswiftsim_tools.h"
#include "cooling_wrapper.h"
#include <cooling.h>
#include <cooling_struct.h>
PyObject* pycooling_init(PyObject* self, PyObject* args) {
PyObject* pyparams;
PyObject* pyus;
PyObject* pypconst;
if (!PyArg_ParseTuple(args, "OOO", &pyparams, &pyus, &pypconst))
return NULL;
struct swift_params *params = pytools_construct(pyparams, class_swift_params);
if (params == NULL)
return NULL;
struct unit_system *us = pytools_construct(pyus, class_unit_system);
if (us == NULL)
return NULL;
struct phys_const *pconst = pytools_construct(pypconst, class_phys_const);
if (pconst == NULL)
return NULL;
struct cooling_function_data cooling;
cooling_init_backend(params, us, pconst, &cooling);
PyObject *pycooling = pytools_return(&cooling, class_cooling_function_data);
return pycooling;
}
PyObject* pycooling_rate(PyObject* self, PyObject* args) {
pyerror("Not implemented");
}
#ifndef __PYSWIFTSIM_COOLING_H__
#define __PYSWIFTSIM_COOLING_H__
#include "pyswiftsim_tools.h"
PyObject* pycooling_init(PyObject* self, PyObject* args);
PyObject* pycooling_rate(PyObject* self, PyObject* args);
#endif // __PYSWIFTSIM_COOLING_H__
#include "parser_wrapper.h"
#include "pyswiftsim_tools.h"
#include <parser.h>
PyObject* pyparser_read_file(PyObject *self, PyObject *args)
{
char *filename;
if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
struct swift_params params;
parser_read_file(filename, &params);
PyObject* obj = pytools_return(&params, class_swift_params);
return obj;
}
#ifndef __PYSWIFTSIM_PARSER_H__
#define __PYSWIFTSIM_PARSER_H__
#include <Python.h>
PyObject* pyparser_read_file(PyObject *self, PyObject *args);
#endif // __PYSWIFTSIM_PARSER_H__
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
PyObject* part_test_struct(PyObject *self, PyObject *args) PyObject* pypart_test_struct(PyObject *self, PyObject *args)
{ {
size_t N = sizeof(struct part); size_t N = sizeof(struct part);
...@@ -30,7 +30,9 @@ PyObject* part_test_struct(PyObject *self, PyObject *args) ...@@ -30,7 +30,9 @@ PyObject* part_test_struct(PyObject *self, PyObject *args)
hydro_init_part(p, NULL); hydro_init_part(p, NULL);
PyObject *object = tools_return(p, class_part); PyObject *object = pytools_return(p, class_part);
free(p);
return object; return object;
} }
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
#include <Python.h> #include <Python.h>
#include <part.h> #include <part.h>
PyObject* part_test_struct(PyObject *self, PyObject *args); PyObject* pypart_test_struct(PyObject *self, PyObject *args);
#endif // __PYSWIFTSIM_PART_H__ #endif // __PYSWIFTSIM_PART_H__
...@@ -3,21 +3,39 @@ ...@@ -3,21 +3,39 @@
/* include swift */ /* include swift */
#include <part.h> #include <part.h>
#include <units.h> #include <units.h>
#include <parser.h>
#include <physical_constants.h>
#include <cooling_struct.h>
#include <Python.h> #include <Python.h>
PyObject* tools_return(void *p, int class) const size_t class_size[class_count] = {
{ sizeof(struct unit_system),
sizeof(struct part),
sizeof(struct swift_params),
sizeof(struct phys_const),
sizeof(struct cooling_function_data)
};
const char *class_name[class_count] = {
"UnitSystem",
"Part",
"SwiftParams",
"PhysConst",
"CoolingFunctionData"
};
PyObject* pytools_import(char* module_name, char* object_name)
{
/* load module */ /* load module */
PyObject *module; PyObject *module;
module = PyImport_ImportModule("pyswiftsim.structure"); module = PyImport_ImportModule(module_name);
if (module == NULL) if (module == NULL)
{ {
PyErr_Print(); pyerror("Failed to import module '%s'.", module_name);
error("Failed to import module.");
} }
/* get module dictionary */ /* get module dictionary */
...@@ -28,38 +46,44 @@ PyObject* tools_return(void *p, int class) ...@@ -28,38 +46,44 @@ PyObject* tools_return(void *p, int class)
if (dict == NULL) if (dict == NULL)
{ {
PyErr_Print(); pyerror("Failed to get module '%s' dictionary", module_name);
error("Failed to get the module dictionary");
} }
/* get right class */ /* get right class */
PyObject *python_obj = PyDict_GetItemString(dict, object_name);
Py_DECREF(dict);
if (python_obj == NULL)
pyerror("Object %s does not exist in module %s", object_name, module_name);
return python_obj;
}
PyObject* pytools_return(void *p, int class)
{
PyObject *python_class; PyObject *python_class;
size_t nber_bytes; size_t nber_bytes;
switch(class)
{
case class_units:
python_class = PyDict_GetItemString(dict, "UnitSystem");
nber_bytes = sizeof(struct unit_system);
break;
case class_part:
python_class = PyDict_GetItemString(dict, "Part");
nber_bytes = sizeof(struct part);
break;
default:
Py_DECREF(dict);
error("Class not implemented");
break;
}
Py_DECREF(dict); char module_name[STRING_SIZE] = "pyswiftsim.structure";
char *class_pyname;
if (class >= class_count)
pyerror("Class %i does not exists", class);
nber_bytes = class_size[class];
class_pyname = class_name[class];
python_class = pytools_import(module_name, class_pyname);
if (python_class == NULL)
return NULL;
if (!PyCallable_Check(python_class)) if (!PyCallable_Check(python_class))
{ {
Py_DECREF(python_class); Py_DECREF(python_class);
error("Unable to create the return object"); pyerror("Unable to import class %s from %s", class_pyname, module_name);
} }
/* create object */ /* create object */
...@@ -76,3 +100,67 @@ PyObject* tools_return(void *p, int class) ...@@ -76,3 +100,67 @@ PyObject* tools_return(void *p, int class)
} }
char* pytools_get_type_name(PyObject *obj)
{
PyObject *type = PyObject_Type(obj);
if (type == NULL)
{
Py_DECREF(type);
pyerror("Unable to get type");
}
PyObject* recv = PyObject_Str(type);
Py_DECREF(type);
if (recv == NULL)
{
Py_DECREF(recv);
pyerror("Unable to get string representation");
}
size_t size;
char *name = PyUnicode_AsUTF8AndSize(recv, size);
Py_DECREF(recv);
if (name == NULL)
{
pyerror("Unable to convert string to char");
}
return name;
}
char* pytools_construct(PyObject* obj, int class)
{
char *module_name = "pyswiftsim.structure";
char *class_pyname;
if (class >= class_count)
pyerror("Class %i does not exists", class);
class_pyname = class_name[class];
PyObject *pyclass = pytools_import(module_name, class_pyname);
int test = !PyObject_IsInstance(obj, pyclass);
Py_DECREF(pyclass);
if (test)
{
char *recv = pytools_get_type_name(obj);
if (recv == NULL)
return NULL;
pyerror("Expecting class %s, received %s", class_pyname, recv);
}
PyObject* data = PyObject_GetAttrString(obj, "data");
if (data == NULL)
pyerror("Unable to get the attribute 'data'");
char *ret = PyBytes_AsString(data);
Py_DECREF(data);
return ret;
}
...@@ -9,10 +9,11 @@ ...@@ -9,10 +9,11 @@
#define STRING_SIZE 200 #define STRING_SIZE 200
/* Set the error message for python (still need to return NULL) */ /* Set the error message for python (still need to return NULL) */
#define error(s, ...) \ #define pyerror(s, ...) \
({ \ ({ \
char error_msg[STRING_SIZE]; \ char error_msg[STRING_SIZE]; \
sprintf(error_msg, "%s:%s():%i: " s, __FILE__, \ PyErr_Print(); \
sprintf(error_msg, "\n%s:%s():%i: " s, __FILE__, \
__FUNCTION__, __LINE__, ##__VA_ARGS__); \ __FUNCTION__, __LINE__, ##__VA_ARGS__); \
PyErr_SetString(PyExc_RuntimeError, error_msg); \ PyErr_SetString(PyExc_RuntimeError, error_msg); \
return FAIL; \ return FAIL; \
...@@ -20,16 +21,28 @@ ...@@ -20,16 +21,28 @@
enum class { enum class {
class_units, class_unit_system,
class_part, class_part,
class_swift_params,
class_phys_const,
class_cooling_function_data,
class_count /* should always be last! */
}; };
extern const size_t class_size[];
extern const char *class_name[];
enum error_code { enum error_code {
FAIL = 0, FAIL = 0, // ensure NULL == FAIL
SUCCESS, SUCCESS,
}; };
PyObject* tools_return(void* p, int class); PyObject* pytools_return(void* p, int class);
char* pytools_construct(PyObject* obj, int class);
PyObject* pytools_import(char* module, char* object_name);
char* pytools_get_type_name(PyObject *obj);
#endif // __PYSWIFTSIM_TOOLS_H__ #endif // __PYSWIFTSIM_TOOLS_H__
#include "pyswiftsim_tools.h" #include "pyswiftsim_tools.h"
#include <units.h> #include <units.h>
#include <parser.h>
#include <physical_constants.h>
#include <Python.h> #include <Python.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
PyObject* unit_system_test_struct(PyObject *self, PyObject *args) PyObject* pyunit_system_test_struct(PyObject *self, PyObject *args)
{ {
size_t N = sizeof(struct unit_system); size_t N = sizeof(struct unit_system);
...@@ -18,7 +20,41 @@ PyObject* unit_system_test_struct(PyObject *self, PyObject *args) ...@@ -18,7 +20,41 @@ PyObject* unit_system_test_struct(PyObject *self, PyObject *args)
us->UnitCurrent_in_cgs = 4.; us->UnitCurrent_in_cgs = 4.;
us->UnitTemperature_in_cgs = 5.; us->UnitTemperature_in_cgs = 5.;
PyObject *object = tools_return(us, class_units); PyObject *object = pytools_return(us, class_unit_system);
free(us);
if (object == NULL)
return NULL;
return object; return object;
} }
PyObject* pyunit_system_init(PyObject *self, PyObject *args)
{
PyObject* parser;
if (!PyArg_ParseTuple(args, "O", &parser))
return NULL;
struct swift_params *params = pytools_construct(parser, class_swift_params);
if (params == NULL)
return NULL;
struct unit_system us;
units_init(&us, params, "InternalUnitSystem");
struct phys_const pconst;
phys_const_init(&us, &pconst);
PyObject *pyus = pytools_return(&us, class_unit_system);
if (pyus == NULL)
return NULL;
PyObject *pypconst = pytools_return(&pconst, class_phys_const);
if (pypconst == NULL)
return NULL;
return PyTuple_Pack(2, pyus, pypconst);
}
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <Python.h> #include <Python.h>
PyObject* unit_system_test_struct(PyObject *self, PyObject *args); PyObject* pyunit_system_test_struct(PyObject *self, PyObject *args);
PyObject* pyunit_system_init(PyObject *self, PyObject *args);
#endif // __PYSWIFTSIM_UNITS_H__ #endif // __PYSWIFTSIM_UNITS_H__
#include "units_wrapper.h" #include "units_wrapper.h"
#include "part_wrapper.h" #include "part_wrapper.h"
#include "parser_wrapper.h"
#include "cooling_wrapper.h"
#include "pyswiftsim_tools.h" #include "pyswiftsim_tools.h"
...@@ -12,12 +14,21 @@ ...@@ -12,12 +14,21 @@
static PyMethodDef wrapper_methods[] = { static PyMethodDef wrapper_methods[] = {
{"partTestStruct", part_test_struct, METH_VARARGS, {"partTestStruct", pypart_test_struct, METH_VARARGS,
"Construct a part object and return it."}, "Construct a part object and return it."},
{"unitSystemTestStruct", pyunit_system_test_struct, METH_VARARGS,
"Construct a unit_system object and return it."},
{"parserReadFile", pyparser_read_file, METH_VARARGS,
"Read a swift params file."},
{"unitSystemInit", pyunit_system_init, METH_VARARGS,
"Construct a unit_system object and return it."},
{"coolingInit", pycooling_init, METH_VARARGS,
"Initialize cooling."},
{"unitSystemTestStruct", unit_system_test_struct, METH_VARARGS,
"Construct a unit_system object and return it."},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
}; };
......
#!/usr/bin/env python3
from pyswiftsim import wrapper
from pyswiftsim import structure
filename = "/home/loikki/swift_test/cooling_sedov/sedov.yml"
params = wrapper.parserReadFile(filename)
us, pconst = wrapper.unitSystemInit(params)
#print(us)
#print(pconst)
print(type(params), type(us), type(pconst))
cooling = wrapper.coolingInit(params, us, pconst)
print(cooling)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment