This is the mail archive of the guile@cygnus.com mailing list for the guile project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi, Sorry this is a bit long. I'm proposing a change to the gh_ interface to vectors. If this bores you to tears, please skip this message. I'm running a bit behind the times, but I've finally taken a look at the new gh_ interface to uniform arrays. Using the current gh_ interface, a gh_scm2doubles/gh_doubles2scm will create a second copy of the vector. With vectors (particularly large vectors) it's often desirable to have only one copy of the vector under scheme. I think that an interface that implements copy in/copy out would be quite useful. Here's my suggestion: ---------------------------------------- #define GH_COPY (0x01000000) double *gh_scm2doubles(SCM vect, double *result, int flag); #define GH_KEEP (0x00000000) #define GH_RELEASE (0x01000000) #define GH_MAKE_VECTOR (0x02000000) #define GH_VALUE_SIZE(v) (0x00ffffff & (v)) SCM gh_doubles2scm(SCM vect, double *result, int flag); ---------------------------------------- @defun gh_scm2doubles vector result flag Take an @var{vector} of type SCM and convert it into an array of doubles. If @var{result} is @code{NULL}, provide memory for a new one. The @var{flag} controls the internal actions. If @var{flag} is positive then it gives the maximum number of values that can be saved @var{result}. If @var{flag} is @var{GH_COPY} then it is assumed that @var{result} is NULL or points to memory that was allocated by a previous call to @code{gh_scm2doubles} with a vector with the same length as @var{vector}. This returns a pointer to the array of doubles containing the result. @end defun @defun gh_doubles2scm vector values flag Take the array of doubles @var{values} and convert the result to an SCM variable. If @var{vector} is a uniform array or vector, then copy the values into the existing vector; otherwise, create a new uniform array or vector. The @var{flag} is the bitwise or of the values: @table @code @item GH_RELEASE The memory pointed to by @var{values} may be freed. @item GH_KEEP Do not free the memory pointed to by @var{values}. @item GH_MAKE_VECTOR Create a vector instead of a uniform array. This only affects the result when @var{vector} is not a uniform array or vector. @item A positive integer The length of @var{values} array. If a non-zero value is used and @var{vector} is a vector or uniform array, then the value must match the length of @var{vector}. @end table @end defun These routines can be used to implement copyin/copyout semantics in a user routine. SCM example(SCM myvect) { double newvect; double *mem = NULL; mem = gh_scm2doubles(myvect,mem,GH_COPY); some_function(mem,gh_length(myvect)); newvect = gh_doubles2scm(myvect,mem,GH_RELEASE); return newvect; } In this example, newvect and myvect will be equal and mem will be allocated and then freed. SCM example(SCM myvect) { double newvect; double *mem = NULL; mem = gh_scm2doubles(myvect,mem,GH_COPY); some_function(mem,gh_length(myvect)); newvect = gh_doubles2scm(SCM_EOL,mem,GH_RELEASE); return newvect; } In this example, newvect will not be equal to myvect. Because of the way uniform arrays are implemented in GUILE it's also possible to use the uniform array memory directly. This removes the need to copy the values in and out of the array. To allow this, a new gh_scm2doubles flag GH_AVOID_COPY can be defined, then if the scm value is a scm_tc7_dvect (sorry for the reference to internals) the address can be returned directly. The gh_doubles2scm routine would need to be modified to check that the location of the values is different from SCM_CHARS(vector) before calling free. I believe that this captures all of the functionality of the current gh_scm2doubles, gh_doubles2scm, and gh_doubles2dvect interface. It also adds the ability to do copy in/copy out. If the GH_AVOID_COPY flag seems reasonable, it also allows the dvect memory to be directly accessed in cases where that's possible and transparently falls back to copy when it's not. If this seems like a good change to the gh_ vector interface then I'd be happy to write up an example implementation. I may write it just for my own edification. Cheers, Clark