[Numpy-svn] r3229 - trunk/numpy/core/src

numpy-svn at scipy.org numpy-svn at scipy.org
Thu Sep 28 07:49:04 CDT 2006


Author: oliphant
Date: 2006-09-28 07:49:01 -0500 (Thu, 28 Sep 2006)
New Revision: 3229

Modified:
   trunk/numpy/core/src/_sortmodule.c.src
   trunk/numpy/core/src/multiarraymodule.c
Log:
Fix merge argsort for strings. Code was not indexing correctly into the array of strings.  Add object-detection so future addition of an object MERGE sort doesn't cause lexsort and threading to die.

Modified: trunk/numpy/core/src/_sortmodule.c.src
===================================================================
--- trunk/numpy/core/src/_sortmodule.c.src	2006-09-28 11:23:18 UTC (rev 3228)
+++ trunk/numpy/core/src/_sortmodule.c.src	2006-09-28 12:49:01 UTC (rev 3229)
@@ -360,24 +360,24 @@
 /**begin repeat
 #TYPE=STRING,UNICODE#
 #comp=strncmp,PyArray_CompareUCS4#
-#type=char *, PyArray_UCS4 *#
+#type=char, PyArray_UCS4#
 */
 static void
- at TYPE@_amergesort0(intp *pl, intp *pr, @type@*v, intp *pw, int elsize)
+ at TYPE@_amergesort0(intp *pl, intp *pr, @type@ *v, intp *pw, int len)
 {
-	@type@ vp;
+	@type@ *vp;
         intp vi, *pi, *pj, *pk, *pm;
 
         if (pr - pl > SMALL_MERGESORT) {
                 /* merge sort */
                 pm = pl + ((pr - pl + 1)>>1);
-                @TYPE at _amergesort0(pl,pm-1,v,pw,elsize);
-                @TYPE at _amergesort0(pm,pr,v,pw,elsize);
+                @TYPE at _amergesort0(pl,pm-1,v,pw,len);
+                @TYPE at _amergesort0(pm,pr,v,pw,len);
                 for(pi = pw, pj = pl; pj < pm; ++pi, ++pj) {
                         *pi = *pj;
                 }
                 for(pk = pw, pm = pl; pk < pi && pj <= pr; ++pm) {
-                        if (@comp@(v[*pk],v[*pj],elsize)<=0) {
+                        if (@comp@(v+(*pk)*len,v+(*pj)*len,len)<=0) {
                                 *pm = *pk;
                                 ++pk;
                         }else{
@@ -392,9 +392,9 @@
                 /* insertion sort */
                 for(pi = pl + 1; pi <= pr; ++pi) {
                         vi = *pi;
-                        vp = v[vi];
-                        for(pj = pi, pk = pi - 1; 		\
-			    pj > pl && (@comp@(vp, v[*pk],elsize)<=0); \
+                        vp = v + vi*len;
+                        for(pj = pi, pk = pi - 1;                       \
+			    pj > pl && (@comp@(vp, v+(*pk)*len,len)<=0); \
 			    --pj, --pk) {
                                 *pj = *pk;
                         }
@@ -404,13 +404,15 @@
 }
 
 static int
- at TYPE@_amergesort(@type@*v, intp *tosort, intp num, PyArrayObject *arr)
+ at TYPE@_amergesort(@type@ *v, intp *tosort, intp num, PyArrayObject *arr)
 {
 	intp *pl, *pr, *pw;
-	int elsize;
+	int elsize, chars;
 
 	elsize = arr->descr->elsize;
 
+        chars = elsize / sizeof(@type@);
+
 	pl = tosort; pr = pl + num - 1;
 	pw = PyDimMem_NEW((1+num/2));
 
@@ -419,7 +421,7 @@
 		return -1;
 	}
 
-	@TYPE at _amergesort0(pl, pr, v, pw, elsize);
+	@TYPE at _amergesort0(pl, pr, v, pw, chars);
 	PyDimMem_FREE(pw);
 	return 0;
 }

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2006-09-28 11:23:18 UTC (rev 3228)
+++ trunk/numpy/core/src/multiarraymodule.c	2006-09-28 12:49:01 UTC (rev 3229)
@@ -2364,8 +2364,9 @@
 	int needcopy=0, i,j;
 	intp N, size;
 	int elsize;
-        int maxelsize;
+	int maxelsize;
 	intp astride, rstride, *iptr;
+	int object=0;
 	PyArray_ArgSortFunc *argsort;
 
 	NPY_BEGIN_THREADS_DEF
@@ -2402,6 +2403,7 @@
 				     "merge sort not available for item %d", i);
 			goto fail;
 		}
+		if (!object && mps[i]->descr->hasobject) object = 1;
 		its[i] = (PyArrayIterObject *)PyArray_IterAllButAxis	\
 			((PyObject *)mps[i], &axis);
 		if (its[i]==NULL) goto fail;
@@ -2414,10 +2416,10 @@
 						   mps[0]->dimensions,
 						   PyArray_INTP,
 						   NULL, NULL, 0, 0, NULL);
-                
+		
 		if (ret == NULL) goto fail;
 		*((intp *)(ret->data)) = 0;
-                goto finish;
+		goto finish;
 	}
 	if (axis < 0) axis += nd;
 	if ((axis < 0) || (axis >= nd)) {
@@ -2437,29 +2439,29 @@
 		PyArray_IterAllButAxis((PyObject *)ret, &axis);
 	if (rit == NULL) goto fail;
 
-	NPY_BEGIN_THREADS
+	if (!object) {NPY_BEGIN_THREADS}
 
 	size = rit->size;
 	N = mps[0]->dimensions[axis];
 	rstride = PyArray_STRIDE(ret,axis);
 
-        maxelsize = mps[0]->descr->elsize;
+	maxelsize = mps[0]->descr->elsize;
 	needcopy = (rstride != sizeof(intp));
 	for (j=0; j<n && !needcopy; j++) {
-		needcopy = PyArray_ISBYTESWAPPED(mps[j]) ||             \
-                        !(mps[j]->flags & ALIGNED) ||                   \
+		needcopy = PyArray_ISBYTESWAPPED(mps[j]) ||		\
+			!(mps[j]->flags & ALIGNED) ||			\
 			(mps[j]->strides[axis] != (intp)mps[j]->descr->elsize);
-                if (mps[j]->descr->elsize > maxelsize)
-                        maxelsize = mps[j]->descr->elsize;
+		if (mps[j]->descr->elsize > maxelsize)
+			maxelsize = mps[j]->descr->elsize;
 	}
 
 	if (needcopy) {
 		char *valbuffer, *indbuffer;
-                int *swaps;
+		int *swaps;
 		valbuffer = PyDataMem_NEW(N*maxelsize);
-                indbuffer = PyDataMem_NEW(N*sizeof(intp));
-                swaps = malloc(n*sizeof(int));
-                for (j=0; j<n; j++) swaps[j] = PyArray_ISBYTESWAPPED(mps[j]);
+		indbuffer = PyDataMem_NEW(N*sizeof(intp));
+		swaps = malloc(n*sizeof(int));
+		for (j=0; j<n; j++) swaps[j] = PyArray_ISBYTESWAPPED(mps[j]);
 		while (size--) {
 			iptr = (intp *)indbuffer;
 			for (i=0; i<N; i++) *iptr++ = i;
@@ -2468,24 +2470,24 @@
 				astride = mps[j]->strides[axis];
 				argsort = mps[j]->descr->f->argsort[PyArray_MERGESORT];
 				_unaligned_strided_byte_copy(valbuffer, (intp) elsize,
-                                                             its[j]->dataptr, astride, N, elsize);
-                                if (swaps[j])
-                                        _strided_byte_swap(valbuffer, (intp) elsize, N, elsize);
+							     its[j]->dataptr, astride, N, elsize);
+				if (swaps[j])
+					_strided_byte_swap(valbuffer, (intp) elsize, N, elsize);
 				if (argsort(valbuffer, (intp *)indbuffer, N, mps[j]) < 0) {
 					PyDataMem_FREE(valbuffer);
-                                        PyDataMem_FREE(indbuffer);
-                                        free(swaps);
-                                        goto fail;
+					PyDataMem_FREE(indbuffer);
+					free(swaps);
+					goto fail;
 				}
 				PyArray_ITER_NEXT(its[j]);
 			}
 			_unaligned_strided_byte_copy(rit->dataptr, rstride, indbuffer,
-                                                     sizeof(intp), N, sizeof(intp));
+						     sizeof(intp), N, sizeof(intp));
 			PyArray_ITER_NEXT(rit);
 		}
 		PyDataMem_FREE(valbuffer);
-                PyDataMem_FREE(indbuffer);
-                free(swaps);
+		PyDataMem_FREE(indbuffer);
+		free(swaps);
 	}
 	else {
 		while (size--) {
@@ -2501,7 +2503,7 @@
 		}
 	}
 
-	NPY_END_THREADS
+	if (!object) {NPY_END_THREADS}
 
  finish:
 	for (i=0; i<n; i++) {Py_XDECREF(mps[i]); Py_XDECREF(its[i]);}



More information about the Numpy-svn mailing list