MacPorts py-gsl installation failure

Jochen Küpper jochen at fhi-berlin.mpg.de
Mon Apr 16 08:26:48 PDT 2007


Hi Mark,

On 14.04.2007, at 22:35, markd at macports.org wrote:

> Jochen Küpper <jochen at 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,
			      &params.n_tries, &params.iters_fixed_T, &params.step_size,
			      &params.k, &params.t_initial, &params.mu_t, &params.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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
Url : http://lists.macosforge.org/pipermail/macports-users/attachments/20070416/bb0ead7d/PGP.bin


More information about the macports-users mailing list