Hi Mark, On 14.04.2007, at 22:35, markd@macports.org wrote:
Jochen Küpper <jochen@fhi-berlin.mpg.de> on Saturday, April 14, 2007 at 8:23 AM -0800 wrote:
sorry to come in with so many problems, I am generally quite please with MacPorts. However, it seems that the Python/Science ports I am trying to install these days somehow don't work for me...
I just tried it and it failed for me too (Intel), though I forgot to check to see if the errors were the same. Anyway, the version was pretty old (0.20) and since it has no maintainer I updated it to 0.3.2 and it builds for me now. There is a version 0.9.0 but I couldn't get it to work. So give it a half day or so and do a selfupdate and try again and hopefully 0.3.2 will install ok for you.
As I told you, the 0.3.2-port you prepared seems to work for me as well. However, in repsonse for above message I also got the following response from Pierre Schnizer:
Thanks for your report. Please could you insert the attached file to src/simanmodule.c and send me any remaining errors? Please which compiler version are you using.
Thus I downloaded the pygsl-0.9.0 tarball from sourceforge and run python setup.py build in there -- simply worked for me (This is on a PPC machine). Since 0.3.2 is quite old and also does not support numpy, IIUC, maybe we can get a 0.9.0 port? What was your problem with the 0.9.0 version? - Would the new simanmodule.c help? - Could it be you don't have py-numpy installed, but that y-numpy should be a dependency for py-gsl, instead of py-numeric? Maybe sending the output to Pierre or the pygsl ml would immediately show them the problem? Anyway, thank you all for your help! /* * Original Author: * * author: Jochen K"upper * * created: April 2002 * * author: Pierre Schnizer * created: December 2003 * file: pygsl/src/simanmodule.c * $Id: simanmodule.c,v 1.7 2005/01/13 17:54:53 schnizer Exp $ * * Jochen K"upper wrote the original version of this module. In December 2003 I * rewrote it. Now I only support the variable type as it is more pythonic. * */ #include <Python.h> #include <math.h> #include <stdlib.h> #include <stdio.h> #include <setjmp.h> #include <gsl/gsl_siman.h> #include <gsl/gsl_nan.h> #include <pygsl/error_helpers.h> #include <pygsl/general_helpers.h> #include <pygsl/rng.h> #include <pygsl/rng_helpers.h> /* * Common to all objects of one problem * Currently the individual method pointers are not used. Instead the method * is resolved every time. Do you know which method is faster? Is it advicable * to resolve it once and store it here? Pierre */ typedef struct{ /* PyObject * efunc; PyObject * step; PyObject * metric; PyObject * print; */ PyObject * rng; jmp_buf buffer; }pygsl_siman_func_t; /* * The Linked list keeping the reference to the individual objects. * * Necessary as I have to use longjmp as the current implementation does * not allow error propagation yet! */ struct _pygsl_siman_t{ pygsl_siman_func_t *func; PyObject * x; struct _pygsl_siman_t * prev; struct _pygsl_siman_t * next; }; typedef struct _pygsl_siman_t pygsl_siman_t; static const char module_doc[] = "C Implementation needed for the siman module."; static PyObject *module = NULL; static const char filename[] = __FILE__; /* * Naming of the various methods the object has provide as callbacks. */ static const char EFunc_name[] = "EFunc"; static const char Metric_name[] = "Metric"; static const char Step_name[] = "Step"; static const char Clone_name[] = "Clone"; static const char Print_name[] = "Print"; /* * Get a callable method from a object. * * Basically it is a flat wrapper around PyObject_GetAttrString but * checks if the method is callable and adds a Traceback frame * * Flag usage: * flag == 1 Must exist and must be callable * flag == 2 If it exists it must be callable * * For the traceback frame all arguments following the module are needed. * If you do not know the module, you can pass a NULL pointer. */ static PyObject * PyGSL_get_callable_method(PyObject *o, const char * attr, int flag, PyObject *module, const char * filename, const char * func_name, int lineno) { PyObject * method = NULL; FUNC_MESS_BEGIN(); method = PyObject_GetAttrString(o, (char *) attr); if(method == NULL){ if(flag == 1){ PyGSL_add_traceback(module, filename, func_name, lineno); }else if(flag == 2){ /* Clear the error otherwise it will show up later on! */ PyErr_Clear(); } return NULL; } if(!(PyCallable_Check(method))) { /* I must add the method name! I must change it to an more descriptive exception! */ PyGSL_add_traceback(module, (const char *) filename, func_name, lineno); PyErr_SetString(PyExc_TypeError, "Found a attribute which was not callable!" "XXX must add the method name!"); return NULL; } DEBUG_MESS(2, "Found a method at %p", (void *) method); FUNC_MESS_END(); return method; } /* This function type should return the energy of a configuration XP. */ static double PyGSL_siman_efunc(void *xp) { PyObject *result = NULL, *callback = NULL, *arglist = NULL; PyGSL_error_info info; pygsl_siman_t *x; int flag=GSL_EFAILED; double value; /* static char *functionname = __FUNCTION__; */ FUNC_MESS_BEGIN(); assert(xp); x = (pygsl_siman_t *) xp; DEBUG_MESS(2, "Found a pygsl_siman_t at %p and a pygsl_siman_func_t at %p and x at %p", (void *)x, (void *) x->func, (void *) x->x); assert(x); assert(x->func); callback = PyGSL_get_callable_method(x->x, EFunc_name, 1, module, filename, __FUNCTION__, __LINE__); if(callback == NULL) goto fail; info.callback = callback; info.message = __FUNCTION__; info.error_description = "and the description ???"; info.argnum = 1; arglist = PyTuple_New(0); result = PyEval_CallObject(callback, arglist); Py_DECREF(arglist); if((flag = PyGSL_CHECK_PYTHON_RETURN(result, 1, &info)) != GSL_SUCCESS){ PyGSL_add_traceback(module, filename, __FUNCTION__, __LINE__); goto fail; } if((flag = PyGSL_PYFLOAT_TO_DOUBLE(result, &value, &info)) != GSL_SUCCESS){ PyGSL_add_traceback(module, filename, __FUNCTION__, __LINE__); goto fail; } Py_DECREF(result); FUNC_MESS_END(); return value; fail: FUNC_MESS("In Fail"); Py_XDECREF(result); longjmp(x->func->buffer, flag); return GSL_NAN; } /* * This function type should modify the configuration XP using a random step * taken from the generator R, up to a maximum distance of STEP_SIZE. */ static void PyGSL_siman_step(const gsl_rng *r, void *xp, double step_size) { PyObject *result = NULL, *arglist = NULL, *callback = NULL; PyGSL_error_info info; pygsl_siman_t *x; int flag=GSL_EFAILED; /* static const char * functionname = __FUNCTION__; */ FUNC_MESS_BEGIN(); x = (pygsl_siman_t *) xp; DEBUG_MESS(2, "Found x at %p", xp); callback = PyGSL_get_callable_method(x->x, Step_name, 1, module, filename, __FUNCTION__, __LINE__); if(callback == NULL) goto fail; info.callback = callback; info.message = __FUNCTION__; info.error_description = "???"; info.argnum = 1; assert(PyGSL_RNG_Check(x->func->rng)); assert(((PyGSL_rng *) x->func->rng)->rng == r); /* create argument list */ arglist = PyTuple_New(2); PyTuple_SET_ITEM(arglist, 0, x->func->rng); Py_INCREF(x->func->rng); /* Don't forget tuple is owner! */ PyTuple_SET_ITEM(arglist, 1, PyFloat_FromDouble(step_size)); result = PyEval_CallObject(callback, arglist); Py_DECREF(arglist); if((flag = PyGSL_CHECK_PYTHON_RETURN(result, 0, &info)) != GSL_SUCCESS){ PyGSL_add_traceback(module, filename, __FUNCTION__, __LINE__); goto fail; } Py_DECREF(result); FUNC_MESS_END(); return; fail: FUNC_MESS("In Fail"); Py_XDECREF(result); longjmp(x->func->buffer, flag); return; } /* This function type should return the distance between two configurations XP and YP. */ static double PyGSL_siman_metric(void *xp, void *yp) { PyObject *result = NULL, *arglist = NULL, *callback = NULL; PyGSL_error_info info; pygsl_siman_t *x, *y; int flag=GSL_EFAILED; double value; /* static const char * functionname = __FUNCTION__; */ FUNC_MESS_BEGIN(); x = (pygsl_siman_t *) xp; y = (pygsl_siman_t *) yp; DEBUG_MESS(2, "Found x at (%p,%p) and y at (%p %p)", (void *) x, (void *)x->x, (void *) y, (void *) y->x); assert(x); assert(y); assert(x->x); assert(y->x); callback = PyGSL_get_callable_method(x->x, Metric_name, 1, module, filename, __FUNCTION__, __LINE__); if(callback == NULL) goto fail; info.callback = callback; info.message = __FUNCTION__; info.error_description = "???"; info.argnum = 1; arglist = PyTuple_New(1); PyTuple_SET_ITEM(arglist, 0, y->x); Py_INCREF(y->x); /* Tuple is owner! */ result = PyEval_CallObject(callback, arglist); Py_XDECREF(arglist); if((flag = PyGSL_CHECK_PYTHON_RETURN(result, 0, &info)) != GSL_SUCCESS){ PyGSL_add_traceback(module, filename, __FUNCTION__, __LINE__); goto fail; } if((flag = PyGSL_PYFLOAT_TO_DOUBLE(result, &value, &info)) != GSL_SUCCESS){ PyGSL_add_traceback(module, filename, __FUNCTION__, __LINE__); goto fail; } Py_DECREF(result); FUNC_MESS_END(); return value; fail: FUNC_MESS("In Fail"); Py_XDECREF(result); longjmp(x->func->buffer, flag); return GSL_NAN; } /* This function type should print the contents of the configuration XP. */ static void PyGSL_siman_print(void *xp) { PyObject *result = NULL, *callback=NULL, *arglist=NULL; PyGSL_error_info info; pygsl_siman_t *x; int flag=GSL_EFAILED; /* static const char * functionname = __FUNCTION__; */ FUNC_MESS_BEGIN(); x = (pygsl_siman_t *) xp; callback = PyGSL_get_callable_method(x->x, Print_name, 1, module, filename, __FUNCTION__, __LINE__); if(callback == NULL) goto fail; info.callback = callback; info.message = __FUNCTION__; info.error_description = "what goes here ???"; info.argnum = 1; arglist = PyTuple_New(0); result = PyEval_CallObject(callback, arglist); Py_DECREF(arglist); if((flag = PyGSL_CHECK_PYTHON_RETURN(result, 0, &info)) != GSL_SUCCESS){ PyGSL_add_traceback(module, (const char*)filename, __FUNCTION__, __LINE__); goto fail; } Py_DECREF(result); FUNC_MESS_END(); return; fail: FUNC_MESS("In Fail"); Py_XDECREF(result); longjmp(x->func->buffer, flag); return; } /* * As Python is generating the new objects I can not skip the reference * counting, but must add a reference for each object in construct and * depose it here and in the siman_destroy function. * * siman_solve will call siman_release_x anyway at the end to clear up * all objects. Necessary to non existing error propagation in the siman * module. */ static void PyGSL_siman_copy(void *src, void *dst) { PyObject *callback=NULL, *new = NULL, *arglist = NULL; PyGSL_error_info info; pygsl_siman_t *x, *y; int flag=GSL_EFAILED; /* static const char * functionname = __FUNCTION__; */ FUNC_MESS_BEGIN(); x = (pygsl_siman_t *) src; y = (pygsl_siman_t *) dst; DEBUG_MESS(2, "Got source at %p, Destination at %p", (void *) x, (void *) y); assert(x->x); callback = PyGSL_get_callable_method(x->x, Clone_name, 1, module, filename, __FUNCTION__, __LINE__); if(callback == NULL) goto fail; arglist = PyTuple_New(0); new = PyEval_CallObject(callback, arglist); Py_DECREF(arglist); info.callback = callback; info.message = __FUNCTION__; info.error_description = "???"; info.argnum = 1; if((flag = PyGSL_CHECK_PYTHON_RETURN(new, 1, &info)) != GSL_SUCCESS){ PyGSL_add_traceback(module, (const char*)filename, __FUNCTION__, __LINE__); goto fail; } Py_XDECREF(y->x); /* Py_INCREF(new); Necessary? I don't think so. */ y->x = new; FUNC_MESS_END(); return; fail: FUNC_MESS("Fail"); Py_XDECREF(new); longjmp(x->func->buffer, flag); } static void * PyGSL_siman_copy_construct(void *new) { pygsl_siman_t * ret, * n, *p; int flag = GSL_ENOMEM; FUNC_MESS_BEGIN(); n = (pygsl_siman_t *) new; /* The pointers next and prev are checked against NULL */ ret = (pygsl_siman_t *) calloc(1, sizeof(pygsl_siman_t)); DEBUG_MESS(2, "New was %p, Constructed a new object at %p", new, (void *) ret); if(ret == NULL){ gsl_error("Could not allocate the object for the linked list", filename, __LINE__ - 3, GSL_ENOMEM); goto fail; } /* Put the Link to the old object so that I can clone when I need to copy */ ret->x = n->x; /* Eventually I will dispose the object */ Py_INCREF(ret->x); /* Pointer to the func struct. This information is the same for all objects */ ret->func = n->func; /* Find the first open object in the linked list ... */ p = n; while(p->next != NULL){ p = p->next; } DEBUG_MESS(2, "I found a open object at %p", (void *) p); /* and connect the links */ p->next = ret; ret->prev = p; FUNC_MESS_END(); return ret; fail: FUNC_MESS("Fail"); longjmp(n->func->buffer, flag); return NULL; } static void PyGSL_siman_destroy(void * old) { pygsl_siman_t * o; FUNC_MESS_BEGIN(); o = (pygsl_siman_t *) old; assert(o); /* fprintf(stderr, "Destroying: Previous object = %p, Next Object = % p\n", (void *)o->prev, (void *)o->next); */ /* Reconnect the linked list */ if (o->prev && o->next){ /* Connect the both */ o->prev->next = o->next; o->next->prev = o->prev; } else if (o->prev && o->next == NULL){ /* Prev last element. Terminate the list */ o->prev->next = NULL; } else if (o->prev == NULL && o->next == NULL){ /* Last Element, better to leave it */ DEBUG_MESS(2, "I do not dispose the last element %p!", (void *) o); return; } /* Dispose the object */ Py_XDECREF(o->x); free(o); FUNC_MESS_END(); } /* Clean up of the linked list of objects */ int PyGSL_siman_release_x(pygsl_siman_t * myargs, pygsl_siman_t * x) { pygsl_siman_t *p=NULL; FUNC_MESS_BEGIN(); p = myargs; /* fprintf(stderr, "Releasing list!\n"); */ while(1){ /* fprintf(stderr, "Previous object = %p, Next Object = %p\n", (void *)p->prev, (void *)p->next); */ /* Don't delete the object containing the result! */ if(p != x){ /* fprintf(stderr, "Deleting object at %p\n", (void *) p); */ PyGSL_siman_destroy((void *) p); } if(p->next == NULL) break; p = p->next; } FUNC_MESS_END(); return GSL_SUCCESS; } static const char pygsl_siman_solve_doc[] = "Simulated annealing driver.\n\ \n\ Usage:\n\ result = solve(r, x0, ...)\n\ \n\ Input:\n\ r ... a random generator from pygsl.rng\n\ x0 ... a configuration. It must be an object providing the following\n\ methods:\n\ EFunc()\n\ Metric()\n\ Step()\n\ Clone()\n\ If you want to use the print functionality you must provide\n\ the following method:\n\ Print()\n\ \n\ Output:\n\ result ... a object of type x0 with the final value.\n\ \n\ Keywords:\n\ n_tries = 200 ... how many points to try for each step\n\ iters_fixed_T = 10 ... how many iterations at each temperature? \n\ step_size = 10 ... max step size in the random walk\n\ \n\ parameters for the Boltzmann distribution\n\ k = 1.0 ... Boltzmann constant\n\ t_initial = 0.002 ... initial temperature\n\ mu_t = 1.005 ... damping factor for the temperature\n\ t_min = 2.0e-6\n\ \n\ do_print = 0 ... print the status of the annealing process\n\ (== 0: do not print)\n\ ( > 0: print)\n\ "; /* wrapper functions */ static PyObject * PyGSL_siman_solve(PyObject *self, PyObject *args, PyObject *kw) { PyObject *result = NULL; PyObject *efunc = NULL, *step = NULL, *metric = NULL, *clone = NULL, *print = NULL, *r_o = NULL, *x_o=NULL; gsl_rng *rng = NULL; gsl_siman_print_t a_print= PyGSL_siman_print; gsl_siman_params_t params = {200, 10, 10.0, 1.0, 0.002, 1.005, 2.0e-6}; pygsl_siman_func_t myargs_func = {NULL}; pygsl_siman_t myargs = {NULL, NULL, NULL, NULL}; /* static const char * functionname = __FUNCTION__; */ int flag=GSL_EFAILED, do_print=0; void * x0 = NULL; static const char * kwlist[] = {"rng", "x0", "n_tries", "iters_fixed_T", "step_size", "k", "t_initial", "mu_t", "t_min", "do_print", NULL}; FUNC_MESS_BEGIN(); /* python arguments are (rng, x0, settings) */ if(! PyArg_ParseTupleAndKeywords(args, kw, "OO|iidddddi", (char **) kwlist, &r_o, &x_o, ¶ms.n_tries, ¶ms.iters_fixed_T, ¶ms.step_size, ¶ms.k, ¶ms.t_initial, ¶ms.mu_t, ¶ms.t_min, &do_print)) return NULL; /* The following methods must exist */ efunc = PyGSL_get_callable_method(x_o, EFunc_name, 1, module, filename, __FUNCTION__, __LINE__); step = PyGSL_get_callable_method(x_o, Step_name, 1, module, filename, __FUNCTION__, __LINE__); metric = PyGSL_get_callable_method(x_o, Metric_name, 1, module, filename, __FUNCTION__, __LINE__); clone = PyGSL_get_callable_method(x_o, Clone_name, 1, module, filename, __FUNCTION__, __LINE__); if( efunc == NULL || step == NULL || metric == NULL || clone == NULL){ return NULL; } /* optional print */ if(do_print == 0){ a_print = NULL; } else { print = PyGSL_get_callable_method(x_o, Print_name, 1, module, filename, __FUNCTION__, __LINE__); if(print == NULL){ DEBUG_MESS(2, "Did not get a print method! print = %p", print); a_print = NULL; return NULL; } } rng = PyGSL_gsl_rng_from_pyobject(r_o); if(rng == NULL){ return NULL; } /* initialize/assign functions */ Py_INCREF(x_o); /* myargs_func.efunc = efunc; myargs_func.step = step; myargs_func.metric = metric; myargs_func.print = print; */ myargs_func.rng = r_o; myargs.func = &myargs_func; myargs.x = x_o; myargs.prev = NULL; myargs.next = NULL; x0 = (void *) &myargs; DEBUG_MESS(2, "x0 @ %p; myargs at %p; myargs_func at %p", x0, (void *) &myargs, (void *) &myargs_func); DEBUG_MESS(2, "Found a pygsl_siman_t at %p and a pygsl_siman_func_t at %p", (void *) x0, (void *) (((pygsl_siman_t *) x0)->func)); if((flag = setjmp(myargs_func.buffer)) == 0){ FUNC_MESS("Starting siman"); gsl_siman_solve(rng, x0, PyGSL_siman_efunc, PyGSL_siman_step, PyGSL_siman_metric, a_print, PyGSL_siman_copy, PyGSL_siman_copy_construct, PyGSL_siman_destroy, 0, /* Only variable mode supported by this wrapper. */ params); FUNC_MESS("End siman"); }else{ PyGSL_add_traceback(module, filename, __FUNCTION__, __LINE__); goto fail; } Py_DECREF(x_o); DEBUG_MESS(2, "I found x0 at %p", x0); result = ((pygsl_siman_t *) x0)->x; PyGSL_siman_release_x(&myargs, x0); FUNC_MESS_END(); return result; fail: FUNC_MESS("In Fail"); PyGSL_siman_release_x(&myargs, x0); Py_XDECREF(x_o); PyGSL_error_flag(flag); return NULL; } /* module initialization */ static PyMethodDef simanMethods[] = { {"solve", (PyCFunction) PyGSL_siman_solve, METH_VARARGS | METH_KEYWORDS, (char *) pygsl_siman_solve_doc}, {NULL, NULL} /* Sentinel */ }; DL_EXPORT(void) init_siman(void) { PyObject *m = NULL; FUNC_MESS_BEGIN(); m = Py_InitModule("_siman", simanMethods); module = m; init_pygsl(); import_pygsl_rng(); FUNC_MESS_END(); return; } /* * Local Variables: * mode: C * c-file-style: "python" * End: */ Greetings, Jochen -- Fritz-Haber-Institut der MPG -- Department of Molecular Physics Faradayweg 4-6 (C1.03) D-14195 Berlin, Germany phone: +49-30-84135686 fax: +49-30-84135892