diff options
Diffstat (limited to 'PyGan/src')
| -rw-r--r-- | PyGan/src/Makefile | 195 | ||||
| -rw-r--r-- | PyGan/src/Makefile_pip | 150 | ||||
| -rw-r--r-- | PyGan/src/cle2000module.c | 344 | ||||
| -rw-r--r-- | PyGan/src/lcmmodule.c | 1036 | ||||
| -rw-r--r-- | PyGan/src/lifomodule.c | 528 | ||||
| -rw-r--r-- | PyGan/src/pylcm.h | 35 | ||||
| -rw-r--r-- | PyGan/src/setup_cle2000.py | 166 | ||||
| -rw-r--r-- | PyGan/src/setup_lcm.py | 49 | ||||
| -rw-r--r-- | PyGan/src/setup_lifo.py | 36 |
9 files changed, 2539 insertions, 0 deletions
diff --git a/PyGan/src/Makefile b/PyGan/src/Makefile new file mode 100644 index 0000000..f48c98a --- /dev/null +++ b/PyGan/src/Makefile @@ -0,0 +1,195 @@ +#--------------------------------------------------------------------------- +# +# Makefile for building the PyGan extension modules +# Author : A. Hebert (2020-7-3) +# +#--------------------------------------------------------------------------- +# +OS = $(shell uname -s | cut -d"_" -f1) +ifeq ($(OS),AIX) + DIRNAME = AIX +else + DIRNAME = $(shell uname -sm | sed 's/[ ]/_/') +endif +pylib = $(shell python3 ../../script/find_pylib.py) +PYTHONPATH = $(pylib)/python +$(info set PYTHONPATH="$(PYTHONPATH)") +export PYTHONPATH + +ifeq ($(intel),1) + ifeq ($(INTELTOOLS),) + $(error INTELTOOLS is not set) + endif + COMPILER = INTELTOOLS + lib = ../lib/$(DIRNAME)_intel + libGan = ../../Ganlib/lib/$(DIRNAME)_intel +else + ifeq ($(nvidia),1) + ifeq ($(NVTOOLS),) + $(error NVTOOLS is not set) + endif + COMPILER = NVTOOLS + lib = ../lib/$(DIRNAME)_nvidia + libGan = ../../Ganlib/lib/$(DIRNAME)_nvidia + else + ifeq ($(llvm),1) + ifeq ($(LLVMTOOLS),) + $(error LLVMTOOLS is not set) + endif + COMPILER = LLVMTOOLS + lib = ../lib/$(DIRNAME)_llvm + libGan = ../../Ganlib/lib/$(DIRNAME)_llvm + else + ifeq ($(FORTRANPATH),) + $(error FORTRANPATH is not set) + endif + COMPILER = FORTRANPATH + lib = ../lib/$(DIRNAME) + libGan = ../../Ganlib/lib/$(DIRNAME) + endif + endif +endif +export COMPILER + +all: + $(MAKE) donjon +checkPython: ; @which python3 > /dev/null +ganlib: clean sub-make-ganlib pygan-ganlib +ifeq ($(openmp),1) + @echo 'pygan_ganlib: openmp is defined' +endif +ifeq ($(intel),1) + @echo 'pygan_ganlib: intel is defined' +endif +ifeq ($(nvidia),1) + @echo 'pygan_ganlib: nvidia is defined' +endif +ifeq ($(llvm),1) + @echo 'pygan_ganlib: llvm is defined' +endif +ifeq ($(hdf5),1) + @echo 'pygan_ganlib: hdf5 is defined' +endif +trivac: clean sub-make-trivac pygan-trivac +ifeq ($(openmp),1) + @echo 'pygan_trivac: openmp is defined' +endif +ifeq ($(intel),1) + @echo 'pygan_trivac: intel is defined' +endif +ifeq ($(nvidia),1) + @echo 'pygan_trivac: nvidia is defined' +endif +ifeq ($(llvm),1) + @echo 'pygan_trivac: llvm is defined' +endif +ifeq ($(hdf5),1) + @echo 'pygan_trivac: hdf5 is defined' +endif +dragon: clean sub-make-dragon pygan-dragon +ifeq ($(openmp),1) + @echo 'pygan_dragon: openmp is defined' +endif +ifeq ($(intel),1) + @echo 'pygan_dragon: intel is defined' +endif +ifeq ($(nvidia),1) + @echo 'pygan_dragon: nvidia is defined' +endif +ifeq ($(llvm),1) + @echo 'pygan_dragon: llvm is defined' +endif +ifeq ($(hdf5),1) + @echo 'pygan_dragon: hdf5 is defined' +endif +donjon: clean sub-make-donjon pygan-donjon +ifeq ($(openmp),1) + @echo 'pygan_donjon: openmp is defined' +endif +ifeq ($(intel),1) + @echo 'pygan_donjon: intel is defined' +endif +ifeq ($(nvidia),1) + @echo 'pygan_donjon: nvidia is defined' +endif +ifeq ($(llvm),1) + @echo 'pygan_donjon: llvm is defined' +endif +ifeq ($(hdf5),1) + @echo 'pygan_donjon: hdf5 is defined' +endif +sub-make-ganlib: + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Ganlib/src +sub-make-trivac: sub-make-ganlib + $(MAKE) openmp=$(openmp) -C ../../Utilib/src + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Trivac/src +sub-make-dragon: sub-make-trivac + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Dragon/src +sub-make-donjon: sub-make-dragon + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Donjon/src +libGanlib.a: $(lib)/ sub-make-ganlib + cp $(libGan)/libGanlib.a . + ar -d libGanlib.a xabort_c.o + mv libGanlib.a $(lib) +$(lib)/: + mkdir -p $(lib)/ +pygan-ganlib: libGanlib.a sub-make-ganlib checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); python3 setup_lcm.py install --home=. + cd $(DIRNAME); python3 setup_lifo.py install --home=. +ifeq ($(openmp),1) + export CODE_EMBEDDED=GANLIB_OMP; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +else + export CODE_EMBEDDED=GANLIB; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +endif + mv $(DIRNAME)/$(pylib)/* $(lib)/ + /bin/rm -r $(DIRNAME) +pygan-trivac: libGanlib.a sub-make-trivac checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); python3 setup_lcm.py install --home=. + cd $(DIRNAME); python3 setup_lifo.py install --home=. +ifeq ($(openmp),1) + export CODE_EMBEDDED=TRIVAC_OMP; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +else + export CODE_EMBEDDED=TRIVAC; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +endif + mv $(DIRNAME)/$(pylib)/* $(lib)/ + /bin/rm -r $(DIRNAME) +pygan-dragon: libGanlib.a sub-make-dragon checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); python3 setup_lcm.py install --home=. + cd $(DIRNAME); python3 setup_lifo.py install --home=. +ifeq ($(openmp),1) + export CODE_EMBEDDED=DRAGON_OMP; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +else + export CODE_EMBEDDED=DRAGON; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +endif + mv $(DIRNAME)/$(pylib)/* $(lib)/ + /bin/rm -r $(DIRNAME) +pygan-donjon: libGanlib.a sub-make-donjon checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); python3 setup_lcm.py install --home=. + cd $(DIRNAME); python3 setup_lifo.py install --home=. +ifeq ($(openmp),1) + export CODE_EMBEDDED=DONJON_OMP; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +else + export CODE_EMBEDDED=DONJON; cd $(DIRNAME); python3 setup_cle2000.py install --home=. +endif + mv $(DIRNAME)/$(pylib)/* $(lib)/ + /bin/rm -r $(DIRNAME) + @echo 'makefile PYTHONPATH=' $(PYTHONPATH) +clean: + @echo 'clean PyGan' + @echo '**********************************************' + @echo '*** You should also clean Dragon or Donjon ***' + @echo '**********************************************' + /bin/rm -r -f ../lib + /bin/rm -f sub-make* diff --git a/PyGan/src/Makefile_pip b/PyGan/src/Makefile_pip new file mode 100644 index 0000000..a052cbc --- /dev/null +++ b/PyGan/src/Makefile_pip @@ -0,0 +1,150 @@ +#--------------------------------------------------------------------------- +# +# Makefile for building the PyGan extension modules with pip +# Author : A. Hebert (2024-1-7) +# +#--------------------------------------------------------------------------- +# +OS = $(shell uname -s | cut -d"_" -f1) +ifeq ($(OS),AIX) + DIRNAME = AIX +else + DIRNAME = $(shell uname -sm | sed 's/[ ]/_/') +endif + +ifeq ($(intel),1) + ifeq ($(INTELTOOLS),) + $(error INTELTOOLS is not set) + endif + COMPILER = INTELTOOLS + lib = ../lib/$(DIRNAME)_intel + libGan = ../../Ganlib/lib/$(DIRNAME)_intel +else + ifeq ($(nvidia),1) + ifeq ($(NVTOOLS),) + $(error NVTOOLS is not set) + endif + COMPILER = NVTOOLS + lib = ../lib/$(DIRNAME)_nvidia + libGan = ../../Ganlib/lib/$(DIRNAME)_nvidia + else + ifeq ($(llvm),1) + ifeq ($(LLVMTOOLS),) + $(error LLVMTOOLS is not set) + endif + COMPILER = LLVMTOOLS + lib = ../lib/$(DIRNAME)_llvm + libGan = ../../Ganlib/lib/$(DIRNAME)_llvm + else + ifeq ($(FORTRANPATH),) + $(error FORTRANPATH is not set) + endif + COMPILER = FORTRANPATH + lib = ../lib/$(DIRNAME) + libGan = ../../Ganlib/lib/$(DIRNAME) + endif + endif +endif +export COMPILER + +all: + $(MAKE) donjon +checkPython: ; @which python3 > /dev/null +ganlib: clean sub-make-ganlib pygan-ganlib +ifdef openmp + @echo 'pygan_ganlib: openmp is defined' +endif +ifdef hdf5 + @echo 'pygan_ganlib: hdf5 is defined' +endif +trivac: clean sub-make-trivac pygan-trivac +ifdef openmp + @echo 'pygan_trivac: openmp is defined' +endif +ifdef hdf5 + @echo 'pygan_trivac: hdf5 is defined' +endif +dragon: clean sub-make-dragon pygan-dragon +ifdef openmp + @echo 'pygan_dragon: openmp is defined' +endif +ifdef hdf5 + @echo 'pygan_dragon: hdf5 is defined' +endif +donjon: clean sub-make-donjon pygan-donjon +ifdef openmp + @echo 'pygan_donjon: openmp is defined' +endif +ifdef hdf5 + @echo 'pygan_donjon: hdf5 is defined' +endif +sub-make-ganlib: + $(MAKE) openmp=$(openmp) -C ../../Utilib/src + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Ganlib/src +sub-make-trivac: sub-make-ganlib + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Trivac/src +sub-make-dragon: sub-make-trivac + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Dragon/src +sub-make-donjon: sub-make-dragon + $(MAKE) openmp=$(openmp) hdf5=$(hdf5) -C ../../Donjon/src +libGanlib.a: $(lib)/ sub-make-ganlib + cp $(libGan)/libGanlib.a . + ar -d libGanlib.a xabort_c.o + mv libGanlib.a $(lib) +$(lib)/: + mkdir -p $(lib)/ +pygan-ganlib: libGanlib.a sub-make-ganlib checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); ln -s setup_lcm.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py + cd $(DIRNAME); ln -s setup_lifo.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py +ifdef openmp + export CODE_EMBEDDED=GANLIB_OMP; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +else + export CODE_EMBEDDED=GANLIB; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +endif + /bin/rm -r $(DIRNAME) +pygan-trivac: libGanlib.a sub-make-trivac checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); ln -s setup_lcm.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py + cd $(DIRNAME); ln -s setup_lifo.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py +ifdef openmp + export CODE_EMBEDDED=TRIVAC_OMP; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +else + export CODE_EMBEDDED=TRIVAC; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +endif + /bin/rm -r $(DIRNAME) +pygan-dragon: libGanlib.a sub-make-dragon checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); ln -s setup_lcm.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py + cd $(DIRNAME); ln -s setup_lifo.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py +ifdef openmp + export CODE_EMBEDDED=DRAGON_OMP; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +else + export CODE_EMBEDDED=DRAGON; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +endif + /bin/rm -r $(DIRNAME) +pygan-donjon: libGanlib.a sub-make-donjon checkPython + mkdir -p $(DIRNAME) + cp *.[ch] $(DIRNAME) + cp *.py $(DIRNAME) + cd $(DIRNAME); ln -s setup_lcm.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py + cd $(DIRNAME); ln -s setup_lifo.py setup.py; python3 -m pip install . --break-system-packages; rm setup.py +ifdef openmp + export CODE_EMBEDDED=DONJON_OMP; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +else + export CODE_EMBEDDED=DONJON; cd $(DIRNAME); ln -s setup_cle2000.py setup.py; python3 -m pip install . --break-system-packages +endif + /bin/rm -r $(DIRNAME) +clean: + @echo 'clean PyGan' + @echo '**********************************************' + @echo '*** You should also clean Dragon or Donjon ***' + @echo '**********************************************' + /bin/rm -r -f ../lib + /bin/rm -f sub-make* diff --git a/PyGan/src/cle2000module.c b/PyGan/src/cle2000module.c new file mode 100644 index 0000000..8c3ddde --- /dev/null +++ b/PyGan/src/cle2000module.c @@ -0,0 +1,344 @@ + +/*--------------------------------*/ +/* Python3-Cle2000 bindings */ +/* author: A. Hebert (03/07/2020) */ +/*--------------------------------*/ + +/* +Copyright (C) 2020 Ecole Polytechnique de Montreal + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. +*/ +#include <stdio.h> +#include <Python.h> +#include <structmember.h> +#include <setjmp.h> +#include "pylcm.h" +jmp_buf buf; + +typedef struct { + PyObject_HEAD + /* Type-specific fields go here. */ + lifo *stack; /* internal structure */ + int_32 impx_cle2000; /* print flag */ + char name_cle2000[13]; /* procedure name */ +} cle2000object; + +static char AbortString[132]; +static PyObject *PyCle2000Error = NULL; +static PyTypeObject Cle2000Type; /* shared type-descriptor */ + +void xabort_c(char *msg){ + printf(" %s\n",msg); + fflush(stdout); fflush(stderr); + PyErr_SetString(PyCle2000Error, msg); + longjmp(buf, 1); +} + +static PyObject *cle2000_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + char *nomsub="cle2000_new"; + PyObject *stacklist=NULL; + char *procname; + long impx = 0; + + /* Parse arguments */ + static char *kwlist[] = {"procname", "stack", "impx", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|l", kwlist, + &procname, &stacklist, &impx)) { + return NULL; + } + Py_INCREF(stacklist); + + cle2000object *self = (cle2000object*)PyObject_New(cle2000object, type); + self->impx_cle2000 = impx; + + if (strlen(procname) > 12) { + sprintf(AbortString,"%s: character procname overflow",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + strcpy(self->name_cle2000,procname); + + PyObject *module = PyImport_ImportModule("lifo"); + if (module == NULL) { + sprintf(AbortString,"%s: module lifo should be installed first",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + PyObject *moduleDict = PyModule_GetDict(module); + PyObject *protocolClass = PyDict_GetItemString(moduleDict, "new"); + if (protocolClass == NULL) { + sprintf(AbortString,"%s: unable to find class new in module lifo",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + + /* Set the Lifo stack */ + lifo *my_lifo; + lifo_node *my_node; + if (PyObject_IsInstance(stacklist, protocolClass)) { /* stacklist is a lifo stack object */ + lifoobject *lifo_object = (lifoobject *)stacklist; + my_lifo = lifo_object->stack; + } else { /* stacklist is a unique readonly PyObject */ + cleopn(&my_lifo); + my_node = (lifo_node *) malloc(sizeof(lifo_node)); + strcpy(my_node->name, "inpu_val0001"); + if (PyObject_IsInstance(stacklist, (PyObject *)&PyLong_Type)) { + long my_int = (long)PyLong_AsLong(stacklist); + if (impx > 0) printf("%s: unique item is an integer --> %ld\n", nomsub, my_int); + my_node->type = 11; my_node->value.ival = my_int; + } else if (PyObject_IsInstance(stacklist, (PyObject *)&PyFloat_Type)) { + double my_double = (double)PyFloat_AsDouble(stacklist); + if (impx > 0) printf("%s: unique item is a floating point number --> %e\n", nomsub, my_double); + my_node->type = 14; my_node->value.dval = my_double; + } else if (PyObject_IsInstance(stacklist, (PyObject *)&PyBool_Type)) { + long my_int = 1; + if (stacklist == Py_False) my_int = 0; + if (impx > 0) printf("%s: unique item is a boolean number --> %ld\n", nomsub, my_int); + my_node->type = 15; my_node->value.ival = my_int; + } else if (PyObject_IsInstance(stacklist, (PyObject *)&PyUnicode_Type)) { + int len = PyUnicode_GET_LENGTH(stacklist); + if (len > 72) { + sprintf(AbortString,"%s: character data overflow",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + int kind = PyUnicode_KIND(stacklist); + void *data = PyUnicode_DATA(stacklist); + char* my_string; + my_string = (char *)malloc(len+1); + int n; + for (n=0; n<len; n++) { + my_string[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + my_string[len] = '\0'; + if (impx > 0) printf("%s: unique item is a string --> %s\n", nomsub, my_string); + my_node->type = 13; + strcpy(my_node->value.hval, my_string); + free(my_string); + } else { + sprintf(AbortString,"%s: use a list or a Lifo object as second argument to cle2000.new", nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + clepush(&my_lifo, my_node); + } + Py_DECREF(stacklist); + self->stack = my_lifo; + return (PyObject *)self; +} + +static void cle2000_dealloc(cle2000object *self) +{ + char *nomsub="cle2000_dealloc"; + if (self->impx_cle2000 > 0) printf("%s: deallocate a cle2000 object\n", nomsub); + PyObject_DEL(self); +} + +static PyObject *cle2000_exec(cle2000object *self) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="cle2000_exec"; + lifo *my_lifo; + int ipos; + int_32 ganmod(char *cmodul, int_32 nentry, char (*hentry)[13], int_32 *ientry, + int_32 *jentry, lcm **kentry, char (*hparam)[73]); + int_32 trimod(char *cmodul, int_32 nentry, char (*hentry)[13], int_32 *ientry, + int_32 *jentry, lcm **kentry, char (*hparam)[73]); + int_32 dramod(char *cmodul, int_32 nentry, char (*hentry)[13], int_32 *ientry, + int_32 *jentry, lcm **kentry, char (*hparam)[73]); + int_32 donmod(char *cmodul, int_32 nentry, char (*hentry)[13], int_32 *ientry, + int_32 *jentry, lcm **kentry, char (*hparam)[73]); + + /* Assign the code entry point */ +#if (defined __trivac__) + int_32 (*dummod)() = &trimod; + if (self->impx_cle2000 > 0) printf("%s: install trivac library\n", nomsub); +#elif (defined __dragon__) + int_32 (*dummod)() = &dramod; + if (self->impx_cle2000 > 0) printf("%s: install dragon library\n", nomsub); +#elif (defined __donjon__) + int_32 (*dummod)() = &donmod; + if (self->impx_cle2000 > 0) printf("%s: install donjon library\n", nomsub); +#else + int_32 (*dummod)() = &ganmod; + if (self->impx_cle2000 > 0) printf("%s: install ganlib library\n", nomsub); +#endif + + my_lifo = self->stack; + int nstack = (int)my_lifo->nup; + /* close the LCM objects */ + for (ipos=0; ipos<nstack; ++ipos) { + lifo_node *my_node = clepos(&my_lifo, ipos); + if ((my_node->type == 3) || (my_node->type == 4)) { + if (my_node->access > 0) lcmcl_c(&(my_node->value.mylcm), 1); + } + } + + /* call the parametrized procedure */ + int_32 ier, ilevel = 1; + ier = cle2000_c(ilevel, dummod, self->name_cle2000, self->impx_cle2000-1, my_lifo); + if (ier != 0) { + sprintf(AbortString,"%s: cle2000 failure (%s.c2m). ier=%d", nomsub, self->name_cle2000, ier); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + + /* reopen the LCM objects */ + for (ipos=0; ipos<nstack; ++ipos) { + lifo_node *my_node = clepos(&my_lifo, ipos); + if ((my_node->type == 3) || (my_node->type == 4)) { + if (my_node->access == 0) my_node->access = 1; + lcmop_c(&(my_node->value.mylcm), my_node->OSname, my_node->access, my_node->type-2, 0); + } + } + if (self->impx_cle2000 > 0) clelib(&my_lifo); + clecls(&my_lifo); + fflush(stdout); + return Py_BuildValue("O",Py_None); + } +} + +static PyObject *cle2000_getLifo(cle2000object *self) { + char *nomsub="getLifo"; + + PyObject *module = PyImport_ImportModule("lifo"); + if (module == NULL) { + sprintf(AbortString,"%s: module lifo should be installed first",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + PyObject *moduleDict = PyModule_GetDict(module); + PyTypeObject *protocolClass = (PyTypeObject *)PyDict_GetItemString(moduleDict, "new"); + if (protocolClass == NULL) { + sprintf(AbortString,"%s: unable to find class new in module lifo",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + + lifoobject *rv = (lifoobject*)PyObject_New(lifoobject, protocolClass); + rv->stack = self->stack; + rv->impx_lifo = self->impx_cle2000; + Py_INCREF(rv); + return (PyObject *)rv; +} + +static PyObject *cle2000_putLifo(cle2000object *self, PyObject *args) { + char *nomsub="putLifo"; + PyObject *item=NULL; + + /* Parse arguments */ + if(!PyArg_ParseTuple(args, "O", &item)) { + return NULL; + } + + PyObject *module = PyImport_ImportModule("lifo"); + if (module == NULL) { + sprintf(AbortString,"%s: module lifo should be installed first",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + PyObject *moduleDict = PyModule_GetDict(module); + PyObject *protocolClass = PyDict_GetItemString(moduleDict, "new"); + if (protocolClass == NULL) { + sprintf(AbortString,"%s: unable to find class new in module lifo",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + if (!PyObject_IsInstance(item, protocolClass)) { + sprintf(AbortString,"%s: the argument is not a lifo instance",nomsub); + PyErr_SetString(PyCle2000Error, AbortString); + return NULL; + } + + lifoobject *rv = (lifoobject*)item; + Py_DECREF(self->stack); + self->stack = rv->stack; + return Py_BuildValue("O",Py_None); +} + +static PyMethodDef cle2000_methods[] = { + {"exec", (PyCFunction) cle2000_exec, METH_NOARGS, "Execute the cle-2000 procedure"}, + {"getLifo", (PyCFunction) cle2000_getLifo, METH_NOARGS, "Recover the embedded Lifo stack"}, + {"putLifo", (PyCFunction) cle2000_putLifo, METH_VARARGS, "Replace the embedded Lifo stack"}, + {NULL, NULL, 0, NULL} +}; + +static PyMemberDef cle2000_members[] = { + {"_impx", T_INT, offsetof(cle2000object, impx_cle2000), 0, "print index"}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject Cle2000Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "cle2000.new", /*tp_name*/ + sizeof(cle2000object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)cle2000_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "Custom objects", /*tp_doc*/ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + cle2000_methods, /* tp_methods */ + cle2000_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + cle2000_new, /* tp_new */ +}; + +// Module definition +static struct PyModuleDef cle2000module = { + PyModuleDef_HEAD_INIT, + "cle2000", + "A Python module that provides support to the Ganlib API", + -1, + NULL, NULL, NULL, NULL, NULL +}; + +// Module initialization +PyMODINIT_FUNC PyInit_cle2000(void) { + PyObject* m; + + Py_Initialize(); + if (PyType_Ready(&Cle2000Type) < 0) return NULL; + + m = PyModule_Create(&cle2000module); + if (m == NULL) return NULL; + + PyModule_AddObject(m, "new", (PyObject *)&Cle2000Type); + + /* Initialize new exception object */ + PyCle2000Error = PyErr_NewException("cle2000.PyCle2000Error", NULL, NULL); + + /* Add exception object to your module */ + PyModule_AddObject(m, "PyCle2000Error", PyCle2000Error); + return m; +} diff --git a/PyGan/src/lcmmodule.c b/PyGan/src/lcmmodule.c new file mode 100644 index 0000000..d083639 --- /dev/null +++ b/PyGan/src/lcmmodule.c @@ -0,0 +1,1036 @@ + +/*--------------------------------*/ +/* Python3-LCM bindings */ +/* author: A. Hebert (03/07/2020) */ +/*--------------------------------*/ + +/* +Copyright (C) 2020 Ecole Polytechnique de Montreal + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. +*/ +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include <Python.h> +#include <structmember.h> +#include <setjmp.h> +#include <string.h> +#include "numpy/arrayobject.h" +#include "pylcm.h" +#define TRUE 1 +jmp_buf buf; +enum Tydata {TAB = 0, ENTIER = 1, REEL_SP = 2, STRING_4C = 3, REEL_DP = 4, BOOLEEN = 5, COMPLEX = 6, LIS = 10, INDEF = 99 }; + +static char AbortString[132]; +static PyObject *PyLcmError = NULL; +static PyTypeObject PyLcmType; /* shared type-descriptor */ + +void xabort_c(char *msg){ + printf(" %s\n",msg); + fflush(stdout); fflush(stderr); + PyErr_SetString(PyLcmError, msg); + longjmp(buf, 1); +} + +char *filled_string_with_blank(int nbmots, char *nomchaine) { + char *chaine_cptee = NULL; + int i,j; + chaine_cptee= (char *)malloc(nbmots*4+1); + strcpy(chaine_cptee, nomchaine); + for (i = 0; i < (nbmots*4+1); i++) { + if (chaine_cptee[i] == '\0') { + for (j = i; j < (nbmots*4+1); j++) { + chaine_cptee[j] = ' '; + } + break; + } + } + return chaine_cptee; +} + +static PyObject *lcm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="lcm_new"; + char *pytype = NULL; + char *name = NULL; + char s[73]; + int_32 iact = 0; + PyObject *pyobj = NULL; + int_32 lrda = 128; + int_32 impx = 0; + + /* Parse arguments */ + static char *kwlist[] = {"pytype", "name", "iact", "pyobj", "lrda", "impx", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|slOll", kwlist, + &pytype, &name, &iact, &pyobj, &lrda, &impx)) { + return NULL; + } + + pylcmobject *self = (pylcmobject*)PyObject_New(pylcmobject, type); + + if (name == NULL) { + long iii=(long)((PyObject_Hash((PyObject *)self)-1)%1000000000000 + 1); + sprintf(s,"LCM_%12ld",iii); + } else { + int len = strlen(name); + if (len > 72) { + sprintf(AbortString,"%s: character name overflow",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + strcpy(s,name); + } + if (impx > 1) { + printf("%s: new lcm type=%s iact=%d impx=%d\n", nomsub, pytype, iact, impx); + if (strcmp(pytype,"DA") == 0) printf("%s: lrda=%d\n", nomsub, lrda); + } + if (iact < 0 || iact > 2) { + sprintf(AbortString,"%s: invalid iact=%d (0, 1, 2 expected)",nomsub,iact); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + + self->impx_lcm = impx; + self->iact_lcm = iact; + strcpy(self->type_lcm, pytype); + self->isopen = 0; + if (pyobj == NULL) { + if (impx > 0) { + printf("%s: create PyObject of type= %s with name=%s\n", nomsub, pytype, s); + } + if (strcmp(pytype,"LCM") == 0) { + int_32 medium = 1; + lcmop_c(&(self->iplist), s, iact, medium, impx); + if (impx > 0) printf("%s: call lcmop_c for object %s (1)\n", nomsub, s); + self->isopen = 1; + } else if (strcmp(pytype,"XSM") == 0) { + int_32 medium = 2; + lcmop_c(&(self->iplist), s, iact, medium, impx); + if (impx > 0) printf("%s: call lcmop_c for object %s (2)\n", nomsub, s); + self->isopen = 1; + } else if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0)) { + } else if (strcmp(pytype,"DA")== 0) { + self->lrda_lcm = lrda; + } else if (strcmp(pytype,"HDF5")== 0) { + } else if (strcmp(pytype,"LCM_INP") == 0) { + strcpy(self->type_lcm, "LCM"); + int_32 medium = 1; /* create a lcm file */ + int_32 imode = 2; /* from ascii file */ + int_32 idir = 2; /* to import */ + if (iact != 0) { + sprintf(AbortString,"%s: invalid iact=%d (0 expected)",nomsub,iact); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + char *ext = strrchr(s, '.'); + if (ext) { + if (strcmp(ext+1,"bin") == 0) imode = 1; /* from binary file */ + } + char s2[74]; + sprintf(s2,"_%s",s); + FILE *fp = fopen(s2, "r"); + lcmop_c(&(self->iplist), s, iact, medium, impx); + if (impx > 0) printf("%s: call lcmop_c for object %s (3)\n", nomsub, s); + self->isopen = 1; + lcmexp_c(&(self->iplist), impx, fp, imode, idir); + fclose(fp); + } else if (strcmp(pytype,"XSM_INP") == 0) { + strcpy(self->type_lcm, "XSM"); + int_32 medium = 2; /* create a xsm file */ + int_32 imode = 2; /* from ascii file */ + int_32 idir = 2; /* to import */ + if (iact != 0) { + sprintf(AbortString,"%s: invalid iact=%d (0 expected)",nomsub,iact); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + char *ext = strrchr(s, '.'); + if (ext) { + if (strcmp(ext+1,"bin") == 0) imode = 1; /* from binary file */ + } + char s2[74]; + sprintf(s2,"_%s",s); + FILE *fp = fopen(s2, "r"); + lcmop_c(&(self->iplist), s, iact, medium, impx); + if (impx > 0) printf("%s: call lcmop_c for object %s (4)\n", nomsub, s); + self->isopen = 1; + lcmexp_c(&(self->iplist), impx, fp, imode, idir); + fclose(fp); + } else { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + } else { + /* deep copy and export logic */ + long medium, imode; + long idir = 1; /* exportation */ + char nameobj[73], namedir[13]; + int_32 vide, longueur, memoire, access; + Py_INCREF(pyobj); + if (!PyObject_IsInstance(pyobj, (PyObject *)&PyLcmType)) { + sprintf(AbortString,"%s: invalid object type as argument. PyLcmType expected",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } else if (iact != 0) { + sprintf(AbortString,"%s: invalid iact=%d (0 expected)",nomsub,iact); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + pylcmobject *lcm_object = (pylcmobject *)pyobj; + char *pytype_rhs = lcm_object->type_lcm; + if ((strcmp(pytype_rhs,"LCM") != 0) && (strcmp(pytype_rhs,"XSM") != 0)) { + sprintf(AbortString,"%s: invalid pyobj type=%s (LCM, XSM expected)",nomsub,pytype_rhs); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + if (strcmp(pytype,"LCM_INP") == 0) { + medium = 1; + imode = 0; + } else if (strcmp(pytype,"XSM_INP") == 0) { + medium = 2; + imode = 0; + } else if (strcmp(pytype,"BINARY") == 0) { + medium = 0; + imode = 1; /* binary */ + } else if (strcmp(pytype,"ASCII") == 0) { + medium = 0; + imode = 2; /* ascii */ + } else { + sprintf(AbortString,"%s: invalid ptype=%s (LCM, XSM, BINARY, ASCII expected)",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + lcminf_c(&(lcm_object->iplist), nameobj, namedir, &vide, &longueur, &memoire, &access); + if (longueur != -1) { + sprintf(AbortString,"%s: associative table expected for copy or export",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + self->isopen = 0; + if (imode == 0) { + if (impx > 0) { + printf("%s: copy PyObject from type=%s to type= %s with name=%s\n", nomsub, pytype_rhs, + pytype, s); + } + lcmop_c(&(self->iplist), s, iact, medium, impx); + if (impx > 0) printf("%s: call lcmop_c for object %s (5)\n", nomsub, s); + self->isopen = 1; + lcmequ_c(&(lcm_object->iplist), &(self->iplist)); + } else if (medium == 0) { + char s2[74]; + FILE *file = NULL; + if (name == NULL) sprintf(s2, "_%s", lcm_object->name_lcm); + if (strncmp(s2,"_",1) != 0) { + sprintf(AbortString,"%s: leading '_' expected in file name %s",nomsub,s2); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + if (impx > 0) { + printf("%s: export PyObject from type=%s to type= %s with name=%s\n", nomsub, pytype_rhs, + pytype, s2); + } + file = fopen(s2, "w"); + lcmexp_c(&(lcm_object->iplist), impx, file, imode, idir); + self->iplist = NULL; + fclose(file); + } + Py_DECREF(pyobj); + } + strcpy(self->name_lcm, s); + return (PyObject *)self; + } +} + +static void PyLCM_dealloc(pylcmobject *self) { + if (!setjmp(buf)) { + char *nomsub="PyLCM_dealloc"; + if ((strncmp(self->type_lcm,"LCM",3)==0) || (strncmp(self->type_lcm,"XSM",3)==0)) { + if(self->isopen == 0) return; + char nameobj[73], namedir[13]; + int_32 vide, longueur, nature, access; + lcminf_c(&(self->iplist), nameobj, namedir, &vide, &longueur, &nature, &access); + if (strcmp(namedir,"/") == 0) { + int_32 iact; + if (self->iact_lcm == 2) { + iact = 1; + } else { + iact = 2; + } + if (self->impx_lcm > 0) printf("%s: call lcmcl_c(iact=%d) for object %s of type %s\n", + nomsub,iact,self->name_lcm,self->type_lcm); + lcmcl_c(&(self->iplist), iact); + } else { + if (self->impx_lcm > 0) printf("%s: deallocate pylcm handle for object %s of type %s\n", + nomsub,self->name_lcm,self->type_lcm); + } + } + } +} + +static PyObject *PyLCM_lib(pylcmobject *self) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="PyLCM_lib"; + char *pytype = self->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + fflush(stdout); + lcmlib_c(&(self->iplist)); + fflush(stdout); + return Py_BuildValue("O",Py_None); + } +} + +static PyObject *PyLCM_val(pylcmobject *self) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="PyLCM_val"; + char *pytype = self->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + lcmval_c(&(self->iplist)," "); + return Py_BuildValue("O",Py_None); + } +} + +static PyObject *PyLCM_close(pylcmobject *self) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="PyLCM_close"; + char *pytype = self->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + if (self->impx_lcm > 0) printf("%s: call lcmcl_c(iact=1) for object %s of type %s\n", + nomsub,self->name_lcm,self->type_lcm); + int_32 iact = 1; + lcmcl_c(&(self->iplist), iact); + return Py_BuildValue("O",Py_None); + } +} + +static PyObject *PyLCM_erase(pylcmobject *self) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="PyLCM_erase"; + char *pytype = self->type_lcm; + char nameobj[73], namedir[13]; + int_32 medium, vide, longueur, nature, access; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + if (self->impx_lcm > 0) printf("%s: call lcmcl_c(iact=3) for object %s of type %s\n", + nomsub,self->name_lcm,self->type_lcm); + int_32 iact = 3; + int_32 impx = 0; + lcminf_c(&(self->iplist), nameobj, namedir, &vide, &longueur, &nature, &access); + lcmcl_c(&(self->iplist), iact); + if (nature == TRUE) { + medium = 1; + } else { + medium = 2; + } + lcmop_c(&(self->iplist), nameobj, access, medium, impx); + if (impx > 0) printf("%s: call lcmop_c for object %s (6)\n", nomsub, nameobj); + return Py_BuildValue("O",Py_None); + } +} + +static PyObject *PyLCM_keys(pylcmobject *self) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="PyLCM_keys"; + PyObject *ret = NULL; + PyObject *keys = NULL; + PyObject *cle = NULL; + char nom[13], nameobj[73], namedir[13], name[13]; + int_32 vide, longueur, nature, access; + + keys=PyList_New(0); + lcminf_c(&(self->iplist), nameobj, namedir, &vide, &longueur, &nature, &access); + if (longueur == -1) { /* associative table */ + if(!vide) { + strcpy(name," "); + lcmnxt_c(&(self->iplist),name); + strcpy(nom,name); + do { + lcmnxt_c(&(self->iplist),nom); + cle = Py_BuildValue("s", nom); + PyList_Append(keys,cle); + Py_DECREF(cle); + } while(strcmp(nom,name) != 0); + } + ret = keys; + } else { + sprintf(AbortString,"%s: associative table expected (nature=%d)",nomsub,nature); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + return ret; + } +} + +static PyObject *PyLCM_len(pylcmobject *self) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="pylcm_len"; + char nameobj[73], namedir[13]; + int_32 vide, longueur, memoire, access; + char *pytype = self->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + lcminf_c(&(self->iplist), nameobj, namedir, &vide, &longueur, &memoire, &access); + return Py_BuildValue("i", longueur); + } +} + +static PyObject *PyLCM_rep(pylcmobject *self, PyObject *args) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="pylcm_rep"; + pylcmobject *ret = NULL; + lcm *lcm_object; + char nameobj[73], namedir[13]; + int_32 vide, longueur, memoire, access; + char *pytype = self->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + lcminf_c(&(self->iplist), nameobj, namedir, &vide, &longueur, &memoire, &access); + if (longueur == -1) { + char *nomcle = NULL; + if (!PyArg_ParseTuple(args, "s", &nomcle)) { + return NULL; + } + if (strlen(nomcle) > 12) { + sprintf(AbortString,"%s: character name overflow",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + if (self->impx_lcm > 0) { + printf("%s: create daughter associative table (key=%s)\n", nomsub, nomcle); + } + lcm_object = lcmdid_c(&(self->iplist), nomcle); + } else { + int_32 iset; + if (!PyArg_ParseTuple(args, "l", &iset)) { + return NULL; + } + if (self->impx_lcm > 0) { + printf("%s: create daughter associative table (key=%d)\n", nomsub, iset); + } + lcm_object = lcmdil_c(&(self->iplist), iset); + } + ret = (pylcmobject *)PyObject_New(pylcmobject, &PyLcmType); + ret->iplist = lcm_object; + ret->impx_lcm = self->impx_lcm; + strcpy(ret->type_lcm, self->type_lcm); + strcpy(ret->name_lcm, namedir); + ret->isopen = 0; + return (PyObject *)ret; + } +} + +static PyObject *PyLCM_lis(pylcmobject *self, PyObject *args) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="pylcm_lis"; + pylcmobject *ret = NULL; + lcm *lcm_object; + char nameobj[73], namedir[13]; + int_32 vide, longueur, memoire, access; + char *pytype = self->type_lcm; + long list_length = 0; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + lcminf_c(&(self->iplist), nameobj, namedir, &vide, &longueur, &memoire, &access); + if (longueur == -1) { + char *nomcle = NULL; + if (!PyArg_ParseTuple(args, "sl", &nomcle, &list_length)) { + return NULL; + } + if (strlen(nomcle) > 12) { + sprintf(AbortString,"%s: character name overflow",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + if (self->impx_lcm > 0) { + printf("%s: create daughter heterogeneous list (key=%s)\n", nomsub, nomcle); + } + lcm_object = lcmlid_c(&(self->iplist), nomcle, list_length); + } else { + int_32 iset; + if (!PyArg_ParseTuple(args, "ll", &iset, &list_length)) { + return NULL; + } + if (self->impx_lcm > 0) { + printf("%s: create daughter heterogeneous list (key=%d)\n", nomsub, iset); + } + lcm_object = lcmlil_c(&(self->iplist), iset, list_length); + } + ret = (pylcmobject *)PyObject_New(pylcmobject, &PyLcmType); + ret->iplist = lcm_object; + ret->impx_lcm = self->impx_lcm; + strcpy(ret->type_lcm, self->type_lcm); + strcpy(ret->name_lcm, namedir); + ret->isopen = 0; + return (PyObject *)ret; + } +} + +static PyObject *pylcm_dict(pylcmobject *self, PyObject *key) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="pylcm_dict"; + PyObject *ret = NULL; + char namekey[13], nameobj[73], namedir[13]; + int i; + lcm *objet; + int_32 *ndata =NULL; + int_32 nbmots = 0; + int_32 tydata = -1; + char *chaine = NULL; + int_32 vide, longueur, memoire, access; + pylcmobject *rv = NULL; + int D_1 = 1; + long taille[1]; + + int len = PyUnicode_GET_LENGTH(key); + if (len > 12) { + sprintf(AbortString,"%s: character data overflow",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + long kind = PyUnicode_KIND(key); + void *data = PyUnicode_DATA(key); + int n; + for (n=0; n<len; n++) { + namekey[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + namekey[len] = '\0'; + if (self->impx_lcm > 1) printf("%s: dictionary key --> %s\n", nomsub, namekey); + + lcmlen_c(&(self->iplist), namekey, &nbmots, &tydata); + switch (tydata) { + case INDEF : + sprintf(AbortString,"%s: wrong key",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + case TAB : + case LIS : /* creation of a daughter pylcm object */ + objet = lcmgid_c(&(self->iplist), namekey); + lcminf_c(&objet, nameobj, namedir, &vide, &longueur, &memoire, &access); + rv = (pylcmobject*)PyObject_New(pylcmobject, &PyLcmType); + rv->iplist = objet; + rv->impx_lcm = self->impx_lcm; + rv->lrda_lcm = 0; + rv->iact_lcm = self->iact_lcm; + strcpy(rv->type_lcm,self->type_lcm); + strcpy(rv->name_lcm,namedir); + rv->isopen = 0; + ret = (PyObject *)rv; + break; + case STRING_4C : /* string */ + ndata = (int_32 *) malloc(nbmots*(sizeof(*ndata))); + lcmget_c(&(self->iplist), namekey, ndata); + chaine = (char *) malloc((int)nbmots*4 + 1); /* +1 pour \0 */ + for (i=0;i<nbmots;i++) strncpy ((chaine+4*i),(char *) (ndata + i), 4); + chaine[nbmots*4] = '\0'; + ret = Py_BuildValue("s", chaine); + free(chaine); + free(ndata); + ndata = NULL; + chaine = NULL; + break; + default : + taille[0] = (int)nbmots; + switch (tydata) { + case ENTIER : + ret = PyArray_SimpleNew(D_1, taille, NPY_INT32); + break; + case REEL_SP : + ret = PyArray_SimpleNew(D_1, taille, NPY_FLOAT); + break; + case REEL_DP : + ret = PyArray_SimpleNew(D_1, taille, NPY_DOUBLE); + break; + case BOOLEEN : + ret = PyArray_SimpleNew(D_1, taille, NPY_BOOL); + break; + case COMPLEX : + ret = PyArray_SimpleNew(D_1, taille, NPY_CFLOAT); + break; + } + int_32 *tabdata = (int_32 *)PyArray_DATA((PyArrayObject *)ret); + lcmget_c(&(self->iplist), namekey, tabdata); + } + return ret; + } +} + +static long pylcm_assign_dict(pylcmobject *self, PyObject *key, PyObject *v) { + if (setjmp(buf)) { + return -1; + } else { + char *nomsub="pylcm_assign_dict"; + long ret = 0; + int_32 nbmots = 0; + int_32 tydata = 99; /* undefined */ + int_32 *tabdata = NULL; + char namekey[13]; + + int len = PyUnicode_GET_LENGTH(key); + if (len > 12) { + sprintf(AbortString,"%s: character data overflow",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + long kind = PyUnicode_KIND(key); + void *data = PyUnicode_DATA(key); + int n; + for (n=0; n<len; n++) { + namekey[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + namekey[len] = '\0'; + if (self->impx_lcm > 1) printf("%s: dictionary key --> %s\n", nomsub, namekey); + + if(PyUnicode_Check(v)){ + char *filled_string = NULL; + tydata = STRING_4C; + + int len = PyUnicode_GET_LENGTH(v); + int kind = PyUnicode_KIND(v); + void *data = PyUnicode_DATA(v); + char* my_string; + my_string = (char *)malloc(len+1); + int n; + for (n=0; n<len; n++) { + my_string[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + my_string[len] = '\0'; + nbmots = len/4 + (len%4+3)/4; + + filled_string = filled_string_with_blank(nbmots,my_string); + free(my_string); + tabdata = (int_32 *) filled_string; + lcmput_c(&(self->iplist), namekey, nbmots, tydata, tabdata); + free(filled_string); + filled_string = NULL; + } else if(PyArray_Check(v)){ + long type_num = PyArray_TYPE((PyArrayObject *)v); + long nb_elts = PyArray_SIZE((PyArrayObject *)v); + nbmots = nb_elts; + tabdata = (int_32 *)PyArray_DATA((PyArrayObject *)v); + switch (type_num) { + case NPY_INT32 : + tydata = ENTIER; + break; + case NPY_FLOAT : + tydata = REEL_SP; + break; + case NPY_DOUBLE : + tydata = REEL_DP; + break; + case NPY_BOOL : + tydata = BOOLEEN; + break; + case NPY_CFLOAT : + tydata = COMPLEX; + break; + default : + sprintf(AbortString,"%s: numerical array type %ld is not implemented",nomsub, type_num); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + lcmput_c(&(self->iplist), namekey, nbmots, tydata, tabdata); + } else { + if (((PyObject *)v)->ob_type == &PyLcmType) { + lcm *rep_vide; + int_32 vide, longueur, memoire, access; + char nameobj[73], namedir[13]; + pylcmobject *new_pylcm = (pylcmobject *)v; + char *pytype = new_pylcm->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + rep_vide = lcmgid_c(&(self->iplist), namekey); + lcminf_c(&rep_vide,nameobj,namedir,&vide, &longueur, &memoire, &access); + if (longueur == -1 && memoire) { + lcmequ_c(&(new_pylcm->iplist),&rep_vide); + } else { + sprintf(AbortString,"%s: use rep method before making a copy",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + } else { + sprintf(AbortString,"%s: cannot assign this object type",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + } + return ret; + } +} + +static PyObject *pylcm_list(pylcmobject *self, PyObject *indice) { + if (setjmp(buf)) { + return NULL; + } else { + char *nomsub="pylcm__list"; + char nameobj[73], namedir[13]; + int i; + int_32 *ndata =NULL; + PyObject *ret = NULL; + int_32 ind = -1; + int_32 nbmots = 0; + int_32 tydata = -1; + lcm *objet; + char *chaine = NULL; + int_32 vide, longueur, memoire, access; + pylcmobject *rv = NULL; + int D_1 = 1; + long taille[1]; + + ind = PyLong_AsLong(indice); + if (ind < 0) { + sprintf(AbortString,"%s: key=%d < 0",nomsub,ind); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } else if (ind >= self->iplist->listlen) { + sprintf(AbortString,"%s: key=%d >= length=%d",nomsub,ind,self->iplist->listlen); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + lcmlel_c(&(self->iplist), ind, &nbmots, &tydata); + switch (tydata) { + case INDEF : + sprintf(AbortString,"%s: wrong key",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + case TAB : + case LIS : + objet = lcmgil_c(&(self->iplist), ind); + lcminf_c(&objet, nameobj, namedir, &vide, &longueur, &memoire, &access); + rv = (pylcmobject*)PyObject_New(pylcmobject, &PyLcmType); + rv->iplist = objet; + rv->impx_lcm = self->impx_lcm; + rv->lrda_lcm = 0; + rv->iact_lcm = self->iact_lcm; + strcpy(rv->type_lcm,self->type_lcm); + strcpy(rv->name_lcm,namedir); + rv->isopen = 0; + ret = (PyObject *)rv; + break; + case STRING_4C : /* type chaine */ + ndata = (int_32 *) malloc(nbmots*(sizeof(*ndata))); + lcmgdl_c(&(self->iplist), ind, ndata); + chaine = (char *) malloc((int)nbmots*4 + 1); /* +1 for \0 */ + for (i=0;i<nbmots;i++) strncpy ((chaine+4*i),(char *) (ndata + i), 4); + chaine[nbmots*4] = '\0'; + ret = Py_BuildValue("s", chaine); + free(chaine); + free(ndata); + ndata = NULL; + chaine = NULL; + break; + default : + taille[0] = (int)nbmots; + switch (tydata) { + case ENTIER : + ret = PyArray_SimpleNew(D_1, taille, NPY_INT32); + break; + case REEL_SP : + ret = PyArray_SimpleNew(D_1, taille, NPY_FLOAT); + break; + case REEL_DP : + ret = PyArray_SimpleNew(D_1, taille, NPY_DOUBLE); + break; + case BOOLEEN : + ret = PyArray_SimpleNew(D_1, taille, NPY_BOOL); + break; + case COMPLEX : + ret = PyArray_SimpleNew(D_1, taille, NPY_CFLOAT); + break; + } + int_32 *tabdata = (int_32 *)PyArray_DATA((PyArrayObject *)ret); + lcmgdl_c(&(self->iplist), ind, tabdata); + } + return ret; + } +} + +static long pylcm_assign_list(pylcmobject *self, PyObject* i, PyObject *v) { + if (setjmp(buf)) { + return -1; + } else { + char *nomsub="pylcm_assign_list"; + long ret = 0; + int_32 nbmots = 0; + int_32 tydata = 99; /* undefined */ + int_32 *tabdata = NULL; + int_32 pos = PyLong_AsLong(i); + + if(PyUnicode_Check(v)){ + char *filled_string = NULL; + tydata = STRING_4C; + + int len = PyUnicode_GET_LENGTH(v); + int kind = PyUnicode_KIND(v); + void *data = PyUnicode_DATA(v); + char* my_string; + my_string = (char *)malloc(len+1); + int n; + for (n=0; n<len; n++) { + my_string[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + my_string[len] = '\0'; + nbmots = len/4 + (len%4+3)/4; + + filled_string = filled_string_with_blank(nbmots,my_string); + free(my_string); + tabdata = (int_32 *) filled_string; + lcmpdl_c(&(self->iplist), pos, nbmots, tydata, tabdata); + free(filled_string); + filled_string=NULL; + } else if(PyArray_Check(v)) { + long type_num = PyArray_TYPE((PyArrayObject *)v); + long nb_elts = PyArray_SIZE((PyArrayObject *)v); + nbmots = nb_elts; + tabdata = (int_32 *)PyArray_DATA((PyArrayObject *)v); + switch (type_num) { + case NPY_INT32 : + tydata = ENTIER; + break; + case NPY_FLOAT : + tydata = REEL_SP; + break; + case NPY_DOUBLE : + tydata = REEL_DP; + break; + case NPY_BOOL : + tydata = BOOLEEN; + break; + case NPY_CFLOAT : + tydata = COMPLEX; + break; + default : + sprintf(AbortString,"%s: numerical array type %ld is not implemented",nomsub, type_num); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + lcmpdl_c(&(self->iplist), pos, nbmots, tydata, tabdata); + } else { + if (((PyObject *)v)->ob_type == &PyLcmType) { + lcm *rep_vide; + int_32 vide, longueur, memoire, access; + char nameobj[73], namedir[13]; + pylcmobject *new_pylcm = (pylcmobject *)v; + char *pytype = new_pylcm->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + rep_vide = lcmgil_c(&(self->iplist), pos); + lcminf_c(&rep_vide, nameobj, namedir, &vide, &longueur, &memoire, &access); + if (longueur == -1 && memoire){ + lcmequ_c(&(new_pylcm->iplist),&rep_vide); + } else { + sprintf(AbortString,"%s: use rep method before making a copy",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + } else { + sprintf(AbortString,"%s: cannot assign this object type",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + } + return ret; + } +} + +static PyObject *PyLCM_subscript(pylcmobject *self, PyObject *index) { + char *nomsub="PyLCM_subscript"; + PyObject *ret = NULL; + char *pytype = self->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + if(PyUnicode_Check(index)) { /* dictionary */ + ret = pylcm_dict(self, index); + } else if (PyLong_Check(index)) { /* list */ + ret = pylcm_list(self, index); + } else { + sprintf(AbortString,"%s: invalid index type",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return NULL; + } + return ret; +} + +static long PyLCM_assign_subscript(pylcmobject *self, PyObject *index, PyObject *v) { + char *nomsub="PyLCM_assign_subscript"; + long ret = 0; + char *pytype = self->type_lcm; + if ((strcmp(pytype,"BINARY") == 0) || (strcmp(pytype,"ASCII") == 0) || + (strcmp(pytype,"DA") == 0) || (strcmp(pytype,"HDF5") == 0)) { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + if(PyUnicode_Check(index)) { + ret = pylcm_assign_dict(self, index, v); + } else if (PyLong_Check(index)) { + ret = pylcm_assign_list(self, index, v); + } else { + sprintf(AbortString,"%s: invalid index type",nomsub); + PyErr_SetString(PyLcmError, AbortString); + return -1; + } + return ret; +} + +int PyLCM_length(PyObject *self) { + return 0; +} + +static PyMethodDef lcm_methods[] = { + {"lib", (PyCFunction)PyLCM_lib, METH_NOARGS, "Print the table-of-content of the lcm object"}, + {"val", (PyCFunction)PyLCM_val, METH_NOARGS, "Validate a lcm object"}, + {"close", (PyCFunction)PyLCM_close, METH_NOARGS, "Close a lcm object without erasing its contents"}, + {"erase", (PyCFunction)PyLCM_erase, METH_NOARGS, "Erase the contents of a lcm object"}, + {"keys", (PyCFunction)PyLCM_keys, METH_NOARGS, "Set the keys content of an associative table"}, + {"len", (PyCFunction)PyLCM_len, METH_NOARGS, "Return the length of a lcm object"}, + {"rep", (PyCFunction)PyLCM_rep, METH_VARARGS, "Create a daughter associative table"}, + {"lis", (PyCFunction)PyLCM_lis, METH_VARARGS, "Create a daughter heterogeneous list"}, + {NULL} /* Sentinel */ +}; + +static PyMemberDef lcm_members[] = { + {"_impx", T_INT, offsetof(pylcmobject, impx_lcm), 0, "print index"}, + {"_access", T_INT, offsetof(pylcmobject, iact_lcm), READONLY, "access index"}, + {"_type", T_STRING_INPLACE, offsetof(pylcmobject, type_lcm), READONLY, "object type"}, + {"_name", T_STRING_INPLACE, offsetof(pylcmobject, name_lcm), READONLY, "object name"}, + {NULL} /* Sentinel */ +}; + +static PyMappingMethods PyLCM_as_mapping = { + (lenfunc)PyLCM_length, /* mp_length */ + (binaryfunc)PyLCM_subscript, /* mp_subscript */ + (objobjargproc)PyLCM_assign_subscript, /* mp_assign_subscript */ +}; + +static PyTypeObject PyLcmType = { + PyVarObject_HEAD_INIT(NULL, 0) + "lcm.new", /*tp_name*/ + sizeof(pylcmobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyLCM_dealloc, /*tp_dealloc*/ + (printfunc) PyLCM_lib, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + &PyLCM_as_mapping, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "Custom objects", /*tp_doc*/ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + lcm_methods, /* tp_methods */ + lcm_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + lcm_new, /* tp_new */ +}; + +static PyModuleDef lcmmodule = { + PyModuleDef_HEAD_INIT, + "lcm", + "A Python module for accessing LCM objects from C code.", + -1, + NULL, NULL, NULL, NULL, NULL +}; +PyMODINIT_FUNC PyInit_lcm(void) { + PyObject* m; + + Py_Initialize(); + import_array(); + if (PyType_Ready(&PyLcmType) < 0) return NULL; + + m = PyModule_Create(&lcmmodule); + if (m == NULL) return NULL; + + PyModule_AddObject(m, "new", (PyObject *)&PyLcmType); + + /* Initialize new exception object */ + PyLcmError = PyErr_NewException("lcm.PyLcmError", NULL, NULL); + + /* Add exception object to your module */ + PyModule_AddObject(m, "PyLcmError", PyLcmError); + return m; +} diff --git a/PyGan/src/lifomodule.c b/PyGan/src/lifomodule.c new file mode 100644 index 0000000..a71f949 --- /dev/null +++ b/PyGan/src/lifomodule.c @@ -0,0 +1,528 @@ + +/*--------------------------------*/ +/* Python3-Lifo bindings */ +/* author: A. Hebert (03/07/2020) */ +/*--------------------------------*/ + +/* +Copyright (C) 2020 Ecole Polytechnique de Montreal + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. +*/ +#include <Python.h> +#include <structmember.h> +#include "pylcm.h" + +static char AbortString[132]; +static PyObject *PyLifoError = NULL; +static PyTypeObject LifoType; /* shared type-descriptor */ + +static PyObject *lifo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + int_32 impx = 0; + + /* Parse arguments */ + static char *kwlist[] = {"impx", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|l", kwlist, &impx)) { + return NULL; + } + + lifoobject *self = (lifoobject*)PyObject_New(lifoobject, type); + self->impx_lifo = impx; + cleopn(&(self->stack)); + return (PyObject *)self; +} + +static void lifo_dealloc(lifoobject *self) +{ + char *nomsub="lifo_dealloc"; + if (self->impx_lifo > 0) printf("%s: deallocate a lifo object\n",nomsub); + PyObject_DEL(self); +} + +static PyObject *lifo_lib(lifoobject *self) { + fflush(stdout); + clelib(&(self->stack)); + fflush(stdout); + return Py_BuildValue("O",Py_None); +} + +static PyObject *lifo_push(lifoobject *self, PyObject *args) { + char *nomsub="lifo_push"; + PyObject *item=NULL; + lifo_node *my_node; + + /* Parse arguments */ + if(!PyArg_ParseTuple(args, "O", &item)) { + return NULL; + } + + PyObject *module = PyImport_ImportModule("lcm"); + if (module == NULL) { + sprintf(AbortString,"%s: module lcm should be installed first",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + PyObject *moduleDict = PyModule_GetDict(module); + PyObject *protocolClass = PyDict_GetItemString(moduleDict, "new"); + if (protocolClass == NULL) { + sprintf(AbortString,"%s: unable to find class new in module lcm",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + + lifo *my_lifo = self->stack; + int ipos = my_lifo->nup; + my_node = (lifo_node *) malloc(sizeof(lifo_node)); + sprintf(my_node->name,"inpu_val%04d", ipos+1); + if (PyObject_IsInstance(item, (PyObject *)&PyLong_Type)) { + long my_int = (long)PyLong_AsLong(item); + if (self->impx_lifo > 1) printf("item %d is an integer --> %ld\n", ipos, my_int); + my_node->type = 11; my_node->value.ival = my_int; + } else if (PyObject_IsInstance(item, (PyObject *)&PyFloat_Type)) { + double my_double = (double)PyFloat_AsDouble(item); + if (self->impx_lifo > 1) printf("item %d is a double floating point number --> %e\n", ipos, my_double); + my_node->type = 14; my_node->value.dval = my_double; + } else if (PyObject_IsInstance(item, (PyObject *)&PyBool_Type)) { + long my_int = 1; + if (item == Py_False) my_int = -1; + if (self->impx_lifo > 0) printf("%s: unique item is a boolean number --> %ld\n", nomsub, my_int); + my_node->type = 15; my_node->value.ival = my_int; + } else if (PyObject_IsInstance(item, (PyObject *)&PyUnicode_Type)) { + int len = PyUnicode_GET_LENGTH(item); + if (len > 72) { + sprintf(AbortString,"%s: character data overflow",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + int kind = PyUnicode_KIND(item); + void *data = PyUnicode_DATA(item); + char* my_string; + my_string = (char *)malloc(len+1); + int n; + for (n=0; n<len; n++) { + my_string[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + my_string[len] = '\0'; + if (self->impx_lifo > 1) printf("item %d is a string --> %s\n", ipos, my_string); + my_node->type = 13; + strcpy(my_node->value.hval, my_string); + free(my_string); + } else if (PyObject_IsInstance(item, protocolClass)) { + pylcmobject *lcm_object = (pylcmobject *)item; + char *pytype = lcm_object->type_lcm; + if (strcmp(pytype,"LCM") == 0) { + my_node->type = 3; + } else if (strcmp(pytype,"XSM") == 0) { + my_node->type = 4; + } else if (strcmp(pytype,"BINARY") == 0) { + my_node->type = 5; + } else if (strcmp(pytype,"ASCII") == 0) { + my_node->type = 6; + } else if (strcmp(pytype,"DA")== 0) { + my_node->type = 7; + my_node->lparam = lcm_object->lrda_lcm; + } else if (strcmp(pytype,"HDF5") == 0) { + my_node->type = 8; + } else { + sprintf(AbortString,"%s: invalid type=%s",nomsub,pytype); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + if (self->impx_lifo > 1) printf("item %d is a lcm object named %s (type=%d)\n", ipos, lcm_object->name_lcm, my_node->type); + strcpy(my_node->OSname, lcm_object->name_lcm); + my_node->access = lcm_object->iact_lcm; + my_node->value.mylcm = lcm_object->iplist; + } else { + /* Create an empty slot in the lifo */ + sprintf(my_node->name,"outp_val%04d", ipos+1); + PyObject* objectsRepresentation = PyObject_Repr(item); + int len = PyUnicode_GET_LENGTH(objectsRepresentation); + int kind = PyUnicode_KIND(objectsRepresentation); + void *data = PyUnicode_DATA(objectsRepresentation); + char* my_string; + my_string = (char *)malloc(len+1); + int n; + for (n=0; n<len; n++) { + my_string[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + my_string[len] = '\0'; + if (self->impx_lifo > 1) printf("item %d is a %s\n", ipos, my_string); + if (strcmp(my_string, "<class 'int'>") == 0) { + my_node->type = -11; + } else if (strcmp(my_string, "<class 'str'>") == 0) { + my_node->type = -13; + } else if (strcmp(my_string, "<class 'float'>") == 0) { + my_node->type = -14; + } else if (strcmp(my_string, "<class 'bool'>") == 0) { + my_node->type = -15; + } + free(my_string); + } + clepush(&my_lifo, my_node); + return Py_BuildValue("O",Py_None); +} + +static PyObject *lifo_pushEmpty(lifoobject *self, PyObject *args) { + char *nomsub="lifo_pushEmpty"; + lifo_node *my_node; + char *OSname = NULL; + char *htype = NULL; + + /* Parse arguments */ + if(!PyArg_ParseTuple(args, "s|s", &OSname, &htype)) { + return NULL; + } + + lifo *my_lifo = self->stack; + int ipos = my_lifo->nup; + my_node = (lifo_node *) malloc(sizeof(lifo_node)); + if (self->impx_lifo > 1) printf("item %d is an empty %s object\n", ipos, htype); + if (strlen(OSname) > 72) { + sprintf(AbortString,"%s: character OSname overflow",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + strcpy(my_node->OSname, OSname); + sprintf(my_node->name,"outp_val%04d", ipos+1); + my_node->access = 0; + if (htype == NULL) { + my_node->type = -3; + } else { + if (strcmp(htype,"LCM") == 0) { + my_node->type = -3; + } else if (strcmp(htype,"XSM") == 0) { + my_node->type = -4; + } else if (strcmp(htype,"BINARY") == 0) { + my_node->type = -5; + } else if (strcmp(htype,"ASCII") == 0) { + my_node->type = -6; + } else if (strcmp(htype,"DA")== 0) { + my_node->type = -7; + } else if (strcmp(htype,"HDF5")== 0) { + my_node->type = -8; + } else if (strcmp(htype,"I")== 0) { + my_node->type = -11; + } else if (strcmp(htype,"S")== 0) { + my_node->type = -13; + } else if (strcmp(htype,"D")== 0) { + my_node->type = -14; + } else if (strcmp(htype,"B")== 0) { + my_node->type = -15; + } else { + sprintf(AbortString,"%s: invalid type=%s",nomsub,htype); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + } + clepush(&my_lifo, my_node); + return Py_BuildValue("O",Py_None); +} + +static PyObject *lifo_pop(lifoobject *self) { + char *nomsub="lifo_pop"; + PyObject *item=NULL; + pylcmobject *rv = NULL; + char lcm_type[8]; + lifo *my_lifo = self->stack; + + PyObject *module = PyImport_ImportModule("lcm"); + if (module == NULL) { + sprintf(AbortString,"%s: module lcm should be installed first",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + PyObject *moduleDict = PyModule_GetDict(module); + PyTypeObject *protocolClass = (PyTypeObject *)PyDict_GetItemString(moduleDict, "new"); + if (protocolClass == NULL) { + sprintf(AbortString,"%s: unable to find class new in module lcm",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + + lifo_node *my_node = clepop(&my_lifo); + if(!my_node) { + sprintf(AbortString,"%s: empty stack",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + if(my_node->type < 0) { + free(my_node); + return Py_BuildValue("O",Py_None); + } + switch (my_node->type) { + case 3 : + strcpy(lcm_type, "LCM"); + goto c37; + case 4 : + strcpy(lcm_type, "XSM"); + goto c37; + case 5 : + strcpy(lcm_type, "BINARY"); + goto c37; + case 6 : + strcpy(lcm_type, "ASCII"); + goto c37; + case 7 : + strcpy(lcm_type, "DA"); + goto c37; + case 8 : + strcpy(lcm_type, "HDF5"); + c37: + rv = (pylcmobject*)PyObject_New(pylcmobject, protocolClass); + rv->iplist = my_node->value.mylcm; + rv->impx_lcm = self->impx_lifo; + strcpy(rv->type_lcm, lcm_type); + strcpy(rv->name_lcm, my_node->OSname); + rv->iact_lcm = my_node->access; + rv->lrda_lcm = my_node->lparam; + item = (PyObject *) rv; + Py_INCREF(item); + break; + case 11 : + item = Py_BuildValue("i", my_node->value.ival); + break; + case 13 : + item = Py_BuildValue("s", my_node->value.hval); + break; + case 14 : + item = Py_BuildValue("d", my_node->value.dval); + break; + case 15 : + if (my_node->value.ival == -1) { + item = Py_False; + } else { + item = Py_True; + } + break; + default : + sprintf(AbortString,"%s: undefined node (%d) - use node method",nomsub,my_node->type); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + free(my_node); + return item; +} + +static PyObject *lifo_pos(lifoobject *self, PyObject *args) { + char *nomsub="lifo_pos"; + PyObject *item=NULL; + pylcmobject *rv = NULL; + long ipos = 0; + char lcm_type[8]; + /* Parse arguments */ + if(!PyArg_ParseTuple(args, "O", &item)) { + return NULL; + } + lifo *my_lifo = self->stack; + if (PyObject_IsInstance(item, (PyObject *)&PyLong_Type)) { + ipos = (long)PyLong_AsLong(item); + if (self->impx_lifo > 0) printf("%s: recover node at position %ld\n", nomsub, ipos); + } else if (PyObject_IsInstance(item, (PyObject *)&PyUnicode_Type)) { + int len = PyUnicode_GET_LENGTH(item); + if (len > 72) { + sprintf(AbortString,"%s: CHARACTER DATA OVERFLOW.",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + int kind = PyUnicode_KIND(item); + void *data = PyUnicode_DATA(item); + char* my_string; + my_string = (char *)malloc(len+1); + int n; + for (n=0; n<len; n++) { + my_string[n] = (Py_UCS4)PyUnicode_READ(kind, data, n); + } + my_string[len] = '\0'; + for (n=0; n<my_lifo->nup; n++) { + lifo_node *my_node = clepos(&my_lifo, n); + if (strcmp(my_string, my_node->OSname) == 0) { + ipos = n; + goto findit; + } + } + sprintf(AbortString,"%s: unable to find a node with OSname=%s",nomsub, my_string); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + + findit: + if (self->impx_lifo > 0) printf("%s: recover node %s at position %ld\n", nomsub, my_string, ipos); + free(my_string); + } + if (ipos+1 > my_lifo->nup) { + sprintf(AbortString,"%s: node index %ld overflow the stack length=%d",nomsub, ipos, my_lifo->nup); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + + PyObject *module = PyImport_ImportModule("lcm"); + if (module == NULL) { + sprintf(AbortString,"%s: module lcm should be installed first",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + PyObject *moduleDict = PyModule_GetDict(module); + PyTypeObject *protocolClass = (PyTypeObject *)PyDict_GetItemString(moduleDict, "new"); + if (protocolClass == NULL) { + sprintf(AbortString,"%s: unable to find class new in module lcm",nomsub); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + + lifo_node *my_node = clepos(&my_lifo, ipos); + switch (my_node->type) { + case 3 : + strcpy(lcm_type, "LCM"); + goto c37; + case 4 : + strcpy(lcm_type, "XSM"); + goto c37; + case 5 : + strcpy(lcm_type, "BINARY"); + goto c37; + case 6 : + strcpy(lcm_type, "ASCII"); + goto c37; + case 7 : + strcpy(lcm_type, "DA"); + goto c37; + case 8 : + strcpy(lcm_type, "HDF5"); + c37: + rv = (pylcmobject*)PyObject_New(pylcmobject, protocolClass); + rv->iplist = my_node->value.mylcm; + rv->impx_lcm = self->impx_lifo; + strcpy(rv->type_lcm, lcm_type); + strcpy(rv->name_lcm, my_node->OSname); + rv->iact_lcm = my_node->access; + rv->lrda_lcm = my_node->lparam; + item = (PyObject *) rv; + Py_INCREF(item); + break; + case 11 : + item = Py_BuildValue("i", my_node->value.ival); + break; + case 13 : + item = Py_BuildValue("s", my_node->value.hval); + break; + case 14 : + item = Py_BuildValue("d", my_node->value.dval); + break; + case 15 : + if (my_node->value.ival == -1) { + item = Py_False; + } else { + item = Py_True; + } + break; + default : + sprintf(AbortString,"%s: node %ld is undefined",nomsub, ipos); + PyErr_SetString(PyLifoError, AbortString); + return NULL; + } + return item; +} + +static PyObject *lifo_len(lifoobject *self) { + lifo *my_lifo = self->stack; + return Py_BuildValue("i", my_lifo->nup); +} + +static PyObject *lifo_osname(lifoobject *self, PyObject *args) { + char *nomsub="lifo_osname"; + long ipos = 0; + /* Parse arguments */ + if(!PyArg_ParseTuple(args, "l", &ipos)) { + return NULL; + } + if (self->impx_lifo > 0) printf("%s: recover node OSname at position %ld\n", nomsub, ipos); + + lifo *my_lifo = self->stack; + lifo_node *my_node = clepos(&my_lifo, ipos); + return Py_BuildValue("s", my_node->OSname); +} + +static PyMethodDef lifo_methods[] = { + {"lib", (PyCFunction)lifo_lib, METH_NOARGS, "Print the table-of-content of the stack"}, + {"push", (PyCFunction)lifo_push, METH_VARARGS, "Push an entry in the stack"}, + {"pushEmpty", (PyCFunction)lifo_pushEmpty, METH_VARARGS, "Push an empty Lcm object in the stack"}, + {"pop", (PyCFunction)lifo_pop, METH_NOARGS, "Pop an entry from the stack"}, + {"node", (PyCFunction)lifo_pos, METH_VARARGS, "Recover an entry from the stack"}, + {"getMax", (PyCFunction)lifo_len, METH_NOARGS, "Return the length of the stack"}, + {"OSName", (PyCFunction)lifo_osname, METH_VARARGS, "Return the OSname of a node"}, + {NULL} /* Sentinel */ +}; + +static PyMemberDef lifo_members[] = { + {"_impx", T_INT, offsetof(lifoobject, impx_lifo), 0, "print index"}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject LifoType = { + PyVarObject_HEAD_INIT(NULL, 0) + "lifo.new", /*tp_name*/ + sizeof(lifoobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)lifo_dealloc, /*tp_dealloc*/ + (printfunc) lifo_lib, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "Custom objects", /*tp_doc*/ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + lifo_methods, /* tp_methods */ + lifo_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + lifo_new, /* tp_new */ +}; + +static PyModuleDef lifomodule = { + PyModuleDef_HEAD_INIT, + "lifo", + "A Python module for accessing the lifo stack from C code.", + -1, + NULL, NULL, NULL, NULL, NULL +}; +PyMODINIT_FUNC PyInit_lifo(void) { + PyObject* m; + + Py_Initialize(); + if (PyType_Ready(&LifoType) < 0) return NULL; + + m = PyModule_Create(&lifomodule); + if (m == NULL) return NULL; + + PyModule_AddObject(m, "new", (PyObject *)&LifoType); + + /* Initialize new exception object */ + PyLifoError = PyErr_NewException("lifo.PyLifoError", NULL, NULL); + + /* Add exception object to your module */ + PyModule_AddObject(m, "PyLifoError", PyLifoError); + return m; +} diff --git a/PyGan/src/pylcm.h b/PyGan/src/pylcm.h new file mode 100644 index 0000000..784b5cf --- /dev/null +++ b/PyGan/src/pylcm.h @@ -0,0 +1,35 @@ + +/*--------------------------------*/ +/* Python3-LCM bindings */ +/* author: A. Hebert (03/07/2020) */ +/*--------------------------------*/ + +/* +Copyright (C) 2020 Ecole Polytechnique de Montreal + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. +*/ +#include "lcm.h" +#include "cle2000.h" + +typedef struct { + PyObject_HEAD + /* Type-specific fields go here. */ + lifo *stack; /* internal structure */ + int_32 impx_lifo; /* print flag */ +} lifoobject; + +typedef struct { + PyObject_HEAD + /* Type-specific fields go here. */ + lcm *iplist; /* lcm/xsm/file object handle */ + int_32 impx_lcm; /* print flag */ + int_32 lrda_lcm; /* da size */ + int_32 iact_lcm; /* access mode */ + char type_lcm[13]; /* object type */ + char name_lcm[73]; /* object name */ + int isopen; /* lcmop is called */ +} pylcmobject; diff --git a/PyGan/src/setup_cle2000.py b/PyGan/src/setup_cle2000.py new file mode 100644 index 0000000..d416245 --- /dev/null +++ b/PyGan/src/setup_cle2000.py @@ -0,0 +1,166 @@ +# +# python3 setup_cle2000.py install --home=. +# +from sys import version_info +if version_info[0] == 3 and version_info[1] >= 12: + from setuptools import setup, Extension +elif version_info[0] > 3: + from setuptools import setup, Extension +else: + from distutils.core import setup, Extension +import sysconfig + +def main(): + import os + from sysconfig import get_config_var + mach = os.path.basename(os.getcwd()) + Code = os.environ.get("CODE_EMBEDDED", None) # Code selection + Compiler = os.environ.get("COMPILER", None) # Compiler selection + FortranLib = os.environ.get(Compiler, None) # directory with libfortran.a + HDF5Lib = os.environ.get("HDF5_API", None) # directory with libhdf5.a + pylib = os.path.basename(get_config_var("LIBDIR")) # get lib or lib64 + print("install Cle2000 binding to", Code, "on directory",mach, "pylib=",pylib, "Compiler=",Compiler) + if Compiler == "NVTOOLS": + libdir="../../lib/"+mach+"_nvidia" + libUtl="../../../Utilib/lib/"+mach+"_nvidia" + libTri="../../../Trivac/lib/"+mach+"_nvidia" + libDra="../../../Dragon/lib/"+mach+"_nvidia" + libDon="../../../Donjon/lib/"+mach+"_nvidia" + extralink=["-lnvcpumath","-lnvf","-lnvc"] + elif Compiler == "LLVMTOOLS": + libdir="../../lib/"+mach+"_llvm" + libUtl="../../../Utilib/lib/"+mach+"_llvm" + libTri="../../../Trivac/lib/"+mach+"_llvm" + libDra="../../../Dragon/lib/"+mach+"_llvm" + libDon="../../../Donjon/lib/"+mach+"_llvm" + extralink=["-lFortranRuntime", "-lFortranDecimal", "-lclang_rt.osx"] + elif Compiler == "INTELTOOLS": + libdir="../../lib/"+mach+"_intel" + libUtl="../../../Utilib/lib/"+mach+"_intel" + libTri="../../../Trivac/lib/"+mach+"_intel" + libDra="../../../Dragon/lib/"+mach+"_intel" + libDon="../../../Donjon/lib/"+mach+"_intel" + extralink=[ ] + else: + libdir="../../lib/"+mach + libUtl="../../../Utilib/lib/"+mach + libTri="../../../Trivac/lib/"+mach + libDra="../../../Dragon/lib/"+mach + libDon="../../../Donjon/lib/"+mach + extralink=["-lgfortran", ] + print("debug Compiler=",Compiler,"libdir=",libdir,"Code=",Code) + + if Code == "GANLIB": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with GANLIB", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + extra_link_args = extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Ganlib","hdf5"] ) ]) + elif Code == "TRIVAC": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with TRIVAC", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + define_macros=[('__trivac__', None)], + extra_link_args = extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib,libUtl,libTri], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Trivac","Utilib","Ganlib","hdf5"] ) ]) + elif Code == "DRAGON": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with DRAGON", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + define_macros=[('__dragon__', None)], + extra_link_args = extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib,libUtl,libTri,libDra], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Dragon","Trivac","Utilib","Ganlib","hdf5"] ) ]) + elif Code == "DONJON": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with DONJON", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + define_macros=[('__donjon__', None)], + extra_link_args = extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib,libUtl,libTri,libDra,libDon], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Donjon","Dragon","Trivac","Utilib","Ganlib","hdf5"] ) ]) + elif Code == "GANLIB_OMP": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with GANLIB_OMP", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + extra_link_args = ["-lgomp"]+extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Ganlib","hdf5"] ) ]) + elif Code == "TRIVAC_OMP": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with TRIVAC_OMP", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + define_macros=[('__trivac__', None)], + extra_link_args = ["-lgomp"]+extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib,libUtl,libTri], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Trivac","Utilib","Ganlib","hdf5"] ) ]) + elif Code == "DRAGON_OMP": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with DRAGON_OMP", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + define_macros=[('__dragon__', None)], + extra_link_args = ["-lgomp"]+extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib,libUtl,libTri,libDra], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Dragon","Trivac","Utilib","Ganlib","hdf5"] ) ]) + elif Code == "DONJON_OMP": + setup (name="Cle2000", + version="5.0", + description="Python bindings for Cle-2000 with DONJON_OMP", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension('cle2000',sources=['cle2000module.c'], + define_macros=[('__donjon__', None)], + extra_link_args = ["-lgomp"]+extralink, + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir,FortranLib,HDF5Lib,libUtl,libTri,libDra,libDon], + runtime_library_dirs=[FortranLib,HDF5Lib], + libraries=["Donjon","Dragon","Trivac","Utilib","Ganlib","hdf5"] ) ]) + else: + raise ValueError(Code+" is not implemented for setup.py bindings") +if __name__ == "__main__": + main() diff --git a/PyGan/src/setup_lcm.py b/PyGan/src/setup_lcm.py new file mode 100644 index 0000000..79e7891 --- /dev/null +++ b/PyGan/src/setup_lcm.py @@ -0,0 +1,49 @@ +# +# python3 setup_lcm.py install --home=. +# +from sys import version_info +if version_info[0] == 3 and version_info[1] >= 12: + from setuptools import setup, Extension +elif version_info[0] > 3: + from setuptools import setup, Extension +else: + from distutils.core import setup, Extension +import sysconfig +import numpy + +def main(): + import os + incdir = numpy.get_include() + mach = os.path.basename(os.getcwd()) + Compiler = os.environ.get("COMPILER", None) # Compiler selection + if Compiler == "NVTOOLS": + libdir="../../lib/"+mach+"_nvidia" + libNv=os.environ.get("NVTOOLS", None)+"/../lib" + extralink=["-lnvc","-lnvcpumath"] + elif Compiler == "LLVMTOOLS": + libdir="../../lib/"+mach+"_llvm" + libNv=" " + extralink=[ ] + elif Compiler == "INTELTOOLS": + libdir="../../lib/"+mach+"_intel" + libNv=" " + extralink=[ ] + else: + libdir="../../lib/"+mach + libNv=" " + extralink=[ ] + setup(name="Lcm", + version="5.0", + description="Python interface for the lcm C library API", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension("lcm", ["lcmmodule.c"], + extra_link_args = extralink, + include_dirs=["../../../Ganlib/src",incdir], + library_dirs=[libdir,libNv], + runtime_library_dirs=[libNv], + libraries=["Ganlib"] ) ]) + +if __name__ == "__main__": + main() diff --git a/PyGan/src/setup_lifo.py b/PyGan/src/setup_lifo.py new file mode 100644 index 0000000..731001e --- /dev/null +++ b/PyGan/src/setup_lifo.py @@ -0,0 +1,36 @@ +# +# python3 setup_lifo.py install --home=. +# +from sys import version_info +if version_info[0] == 3 and version_info[1] >= 12: + from setuptools import setup, Extension +elif version_info[0] > 3: + from setuptools import setup, Extension +else: + from distutils.core import setup, Extension + +def main(): + import os + mach = os.path.basename(os.getcwd()) + Compiler = os.environ.get("COMPILER", None) # Compiler selection + if Compiler == "NVTOOLS": + libdir="../../lib/"+mach+"_nvidia" + elif Compiler == "LLVMTOOLS": + libdir="../../lib/"+mach+"_llvm" + elif Compiler == "INTELTOOLS": + libdir="../../lib/"+mach+"_intel" + else: + libdir="../../lib/"+mach + setup(name="Lifo", + version="5.0", + description="Python interface for the lifo C library function", + author="Alain Hebert", + author_email="alain.hebert@polymtl.ca", + license="LGPL", + ext_modules=[Extension("lifo", ["lifomodule.c"], + include_dirs=["../../../Ganlib/src"], + library_dirs=[libdir], + libraries=["Ganlib"] ) ]) + +if __name__ == "__main__": + main() |
