@@ -53,9 +53,9 @@ function createInsertionSort(order, dtype) {
53
53
var funcName = [ "ndarrayInsertionSort" , order . join ( "d" ) , dtype ] . join ( "" )
54
54
var funcArgs = [ "left" , "right" , "data" , "offset" ] . concat ( shapeArgs ( order . length ) )
55
55
var allocator = getMallocFree ( dtype )
56
-
56
+
57
57
var vars = [ "i,j,cptr,ptr=left*s0+offset" ]
58
-
58
+
59
59
if ( order . length > 1 ) {
60
60
var scratch_shape = [ ]
61
61
for ( var i = 1 ; i < order . length ; ++ i ) {
@@ -71,31 +71,31 @@ function createInsertionSort(order, dtype) {
71
71
} else {
72
72
vars . push ( "scratch" )
73
73
}
74
-
74
+
75
75
function dataRead ( ptr ) {
76
76
if ( dtype === "generic" ) {
77
77
return [ "data.get(" , ptr , ")" ] . join ( "" )
78
78
}
79
79
return [ "data[" , ptr , "]" ] . join ( "" )
80
80
}
81
-
81
+
82
82
function dataWrite ( ptr , v ) {
83
83
if ( dtype === "generic" ) {
84
84
return [ "data.set(" , ptr , "," , v , ")" ] . join ( "" )
85
85
}
86
86
return [ "data[" , ptr , "]=" , v ] . join ( "" )
87
87
}
88
-
88
+
89
89
//Create function header
90
90
code . push (
91
91
[ "function " , funcName , "(" , funcArgs . join ( "," ) , "){var " , vars . join ( "," ) ] . join ( "" ) ,
92
92
"for(i=left+1;i<=right;++i){" ,
93
93
"j=i;ptr+=s0" ,
94
94
"cptr=ptr" )
95
-
96
-
95
+
96
+
97
97
if ( order . length > 1 ) {
98
-
98
+
99
99
//Copy data into scratch
100
100
code . push ( "dptr=0;sptr=ptr" )
101
101
for ( var i = order . length - 1 ; i >= 0 ; -- i ) {
@@ -114,7 +114,7 @@ function createInsertionSort(order, dtype) {
114
114
code . push ( "sptr+=d" + j , "}" )
115
115
}
116
116
117
-
117
+
118
118
//Compare items in outer loop
119
119
code . push ( "__g:while(j-->left){" ,
120
120
"dptr=0" ,
@@ -132,7 +132,7 @@ function createInsertionSort(order, dtype) {
132
132
"dptr+=f" + i ,
133
133
"}" )
134
134
}
135
-
135
+
136
136
//Copy data back
137
137
code . push ( "dptr=cptr;sptr=cptr-s0" )
138
138
for ( var i = order . length - 1 ; i >= 0 ; -- i ) {
@@ -150,7 +150,7 @@ function createInsertionSort(order, dtype) {
150
150
}
151
151
code . push ( [ "dptr+=d" , j , ";sptr+=d" , j ] . join ( "" ) , "}" )
152
152
}
153
-
153
+
154
154
//Close while loop
155
155
code . push ( "cptr-=s0\n}" )
156
156
@@ -179,14 +179,14 @@ function createInsertionSort(order, dtype) {
179
179
"}" ,
180
180
dataWrite ( "cptr" , "scratch" ) )
181
181
}
182
-
182
+
183
183
//Close outer loop body
184
184
code . push ( "}" )
185
185
if ( order . length > 1 && allocator ) {
186
186
code . push ( "free(scratch)" )
187
187
}
188
188
code . push ( "} return " + funcName )
189
-
189
+
190
190
//Compile and link function
191
191
if ( allocator ) {
192
192
var result = new Function ( "malloc" , "free" , code . join ( "\n" ) )
@@ -203,9 +203,9 @@ function createQuickSort(order, dtype, insertionSort) {
203
203
var funcArgs = [ "left" , "right" , "data" , "offset" ] . concat ( shapeArgs ( order . length ) )
204
204
var allocator = getMallocFree ( dtype )
205
205
var labelCounter = 0
206
-
206
+
207
207
code . push ( [ "function " , funcName , "(" , funcArgs . join ( "," ) , "){" ] . join ( "" ) )
208
-
208
+
209
209
var vars = [
210
210
"sixth=((right-left+1)/6)|0" ,
211
211
"index1=left+sixth" ,
@@ -234,7 +234,7 @@ function createQuickSort(order, dtype, insertionSort) {
234
234
"comp_pivot2=0" ,
235
235
"comp=0"
236
236
]
237
-
237
+
238
238
if ( order . length > 1 ) {
239
239
var ele_size = [ ]
240
240
for ( var i = 1 ; i < order . length ; ++ i ) {
@@ -262,28 +262,28 @@ function createQuickSort(order, dtype, insertionSort) {
262
262
} else {
263
263
vars . push ( "pivot1" , "pivot2" )
264
264
}
265
-
265
+
266
266
//Initialize local variables
267
267
code . push ( "var " + vars . join ( "," ) )
268
-
268
+
269
269
function toPointer ( v ) {
270
270
return [ "(offset+" , v , "*s0)" ] . join ( "" )
271
271
}
272
-
272
+
273
273
function dataRead ( ptr ) {
274
274
if ( dtype === "generic" ) {
275
275
return [ "data.get(" , ptr , ")" ] . join ( "" )
276
276
}
277
277
return [ "data[" , ptr , "]" ] . join ( "" )
278
278
}
279
-
279
+
280
280
function dataWrite ( ptr , v ) {
281
281
if ( dtype === "generic" ) {
282
282
return [ "data.set(" , ptr , "," , v , ")" ] . join ( "" )
283
283
}
284
284
return [ "data[" , ptr , "]=" , v ] . join ( "" )
285
285
}
286
-
286
+
287
287
function cacheLoop ( ptrs , usePivot , body ) {
288
288
if ( ptrs . length === 1 ) {
289
289
code . push ( "ptr0=" + toPointer ( ptrs [ 0 ] ) )
@@ -325,7 +325,7 @@ function createQuickSort(order, dtype, insertionSort) {
325
325
code . push ( "}" )
326
326
}
327
327
}
328
-
328
+
329
329
function lexicoLoop ( label , ptrs , usePivot , body ) {
330
330
if ( ptrs . length === 1 ) {
331
331
code . push ( "ptr0=" + toPointer ( ptrs [ 0 ] ) )
@@ -362,13 +362,13 @@ function createQuickSort(order, dtype, insertionSort) {
362
362
code . push ( "}" )
363
363
}
364
364
}
365
-
365
+
366
366
function cleanUp ( ) {
367
367
if ( order . length > 1 && allocator ) {
368
368
code . push ( "free(pivot1)" , "free(pivot2)" )
369
369
}
370
370
}
371
-
371
+
372
372
function compareSwap ( a_id , b_id ) {
373
373
var a = "el" + a_id
374
374
var b = "el" + b_id
@@ -383,7 +383,7 @@ function createQuickSort(order, dtype, insertionSort) {
383
383
code . push ( [ "if(" , dataRead ( toPointer ( a ) ) , ">" , dataRead ( toPointer ( b ) ) , "){tmp0=" , a , ";" , a , "=" , b , ";" , b , "=tmp0}" ] . join ( "" ) )
384
384
}
385
385
}
386
-
386
+
387
387
compareSwap ( 1 , 2 )
388
388
compareSwap ( 4 , 5 )
389
389
compareSwap ( 1 , 3 )
@@ -393,7 +393,7 @@ function createQuickSort(order, dtype, insertionSort) {
393
393
compareSwap ( 2 , 5 )
394
394
compareSwap ( 2 , 3 )
395
395
compareSwap ( 4 , 5 )
396
-
396
+
397
397
if ( order . length > 1 ) {
398
398
cacheLoop ( [ "el1" , "el2" , "el3" , "el4" , "el5" , "index1" , "index3" , "index5" ] , true , [
399
399
"pivot1[pivot_ptr]=" , dataRead ( "ptr1" ) , "\n" ,
@@ -419,7 +419,7 @@ function createQuickSort(order, dtype, insertionSort) {
419
419
dataWrite ( toPointer ( "index5" ) , "z" )
420
420
] . join ( "" ) )
421
421
}
422
-
422
+
423
423
424
424
function moveElement ( dst , src ) {
425
425
if ( order . length > 1 ) {
@@ -430,10 +430,10 @@ function createQuickSort(order, dtype, insertionSort) {
430
430
code . push ( dataWrite ( toPointer ( dst ) , dataRead ( toPointer ( src ) ) ) )
431
431
}
432
432
}
433
-
433
+
434
434
moveElement ( "index2" , "left" )
435
435
moveElement ( "index4" , "right" )
436
-
436
+
437
437
function comparePivot ( result , ptr , n ) {
438
438
if ( order . length > 1 ) {
439
439
var lbl = "__l" + ( ++ labelCounter )
@@ -445,7 +445,7 @@ function createQuickSort(order, dtype, insertionSort) {
445
445
code . push ( [ result , "=" , dataRead ( toPointer ( ptr ) ) , "-pivot" , n ] . join ( "" ) )
446
446
}
447
447
}
448
-
448
+
449
449
function swapElements ( a , b ) {
450
450
if ( order . length > 1 ) {
451
451
cacheLoop ( [ a , b ] , false , [
@@ -463,7 +463,7 @@ function createQuickSort(order, dtype, insertionSort) {
463
463
] . join ( "" ) )
464
464
}
465
465
}
466
-
466
+
467
467
function tripleSwap ( k , less , great ) {
468
468
if ( order . length > 1 ) {
469
469
cacheLoop ( [ k , less , great ] , false , [
@@ -487,12 +487,12 @@ function createQuickSort(order, dtype, insertionSort) {
487
487
] . join ( "" ) )
488
488
}
489
489
}
490
-
490
+
491
491
function swapAndDecrement ( k , great ) {
492
492
swapElements ( k , great )
493
493
code . push ( "--" + great )
494
494
}
495
-
495
+
496
496
code . push ( "if(pivots_are_equal){" )
497
497
//Pivots are equal case
498
498
code . push ( "for(k=less;k<=great;++k){" )
@@ -549,7 +549,7 @@ function createQuickSort(order, dtype, insertionSort) {
549
549
code . push ( "}" )
550
550
code . push ( "}" )
551
551
code . push ( "}" )
552
-
552
+
553
553
//Move pivots to correct place
554
554
function storePivot ( mem_dest , pivot_dest , pivot ) {
555
555
if ( order . length > 1 ) {
@@ -563,7 +563,7 @@ function createQuickSort(order, dtype, insertionSort) {
563
563
dataWrite ( toPointer ( pivot_dest ) , "pivot" + pivot ) )
564
564
}
565
565
}
566
-
566
+
567
567
storePivot ( "left" , "(less-1)" , 1 )
568
568
storePivot ( "right" , "(great+1)" , 2 )
569
569
@@ -579,13 +579,13 @@ function createQuickSort(order, dtype, insertionSort) {
579
579
}
580
580
doSort ( "left" , "(less-2)" )
581
581
doSort ( "(great+2)" , "right" )
582
-
582
+
583
583
//If pivots are equal, then early out
584
584
code . push ( "if(pivots_are_equal){" )
585
585
cleanUp ( )
586
586
code . push ( "return" )
587
587
code . push ( "}" )
588
-
588
+
589
589
function walkPointer ( ptr , pivot , body ) {
590
590
if ( order . length > 1 ) {
591
591
code . push ( [ "__l" , ++ labelCounter , ":while(true){" ] . join ( "" ) )
@@ -597,13 +597,13 @@ function createQuickSort(order, dtype, insertionSort) {
597
597
code . push ( [ "while(" , dataRead ( toPointer ( ptr ) ) , "===pivot" , pivot , "){" , body , "}" ] . join ( "" ) )
598
598
}
599
599
}
600
-
600
+
601
601
//Check bounds
602
602
code . push ( "if(less<index1&&great>index5){" )
603
-
603
+
604
604
walkPointer ( "less" , 1 , "++less" )
605
605
walkPointer ( "great" , 2 , "--great" )
606
-
606
+
607
607
code . push ( "for(k=less;k<=great;++k){" )
608
608
comparePivot ( "comp_pivot1" , "k" , 1 )
609
609
code . push ( "if(comp_pivot1===0){" )
@@ -633,14 +633,14 @@ function createQuickSort(order, dtype, insertionSort) {
633
633
code . push ( "}" )
634
634
code . push ( "}" )
635
635
code . push ( "}" )
636
-
636
+
637
637
//Clean up and do a final sorting pass
638
638
cleanUp ( )
639
639
doSort ( "less" , "great" )
640
-
640
+
641
641
//Close off main loop
642
642
code . push ( "}return " + funcName )
643
-
643
+
644
644
//Compile and link
645
645
if ( order . length > 1 && allocator ) {
646
646
var compiled = new Function ( "insertionSort" , "malloc" , "free" , code . join ( "\n" ) )
@@ -654,15 +654,15 @@ function compileSort(order, dtype) {
654
654
var code = [ "'use strict'" ]
655
655
var funcName = [ "ndarraySortWrapper" , order . join ( "d" ) , dtype ] . join ( "" )
656
656
var funcArgs = [ "array" ]
657
-
657
+
658
658
code . push ( [ "function " , funcName , "(" , funcArgs . join ( "," ) , "){" ] . join ( "" ) )
659
-
659
+
660
660
//Unpack local variables from array
661
661
var vars = [ "data=array.data,offset=array.offset|0,shape=array.shape,stride=array.stride" ]
662
662
for ( var i = 0 ; i < order . length ; ++ i ) {
663
663
vars . push ( [ "s" , i , "=stride[" , i , "]|0,n" , i , "=shape[" , i , "]|0" ] . join ( "" ) )
664
664
}
665
-
665
+
666
666
var scratch_stride = new Array ( order . length )
667
667
var nprod = [ ]
668
668
for ( var i = 0 ; i < order . length ; ++ i ) {
@@ -677,7 +677,7 @@ function compileSort(order, dtype) {
677
677
}
678
678
nprod . push ( "n" + k )
679
679
}
680
-
680
+
681
681
var p = - 1 , q = - 1
682
682
for ( var i = 0 ; i < order . length ; ++ i ) {
683
683
var j = order [ i ]
@@ -700,24 +700,24 @@ function compileSort(order, dtype) {
700
700
q = k
701
701
}
702
702
}
703
-
703
+
704
704
//Declare local variables
705
705
code . push ( "var " + vars . join ( "," ) )
706
-
706
+
707
707
//Create arguments for subroutine
708
708
var sortArgs = [ "0" , "n0-1" , "data" , "offset" ] . concat ( shapeArgs ( order . length ) )
709
-
709
+
710
710
//Call main sorting routine
711
711
code . push ( [
712
712
"if(n0<=" , INSERTION_SORT_THRESHOLD , "){" ,
713
713
"insertionSort(" , sortArgs . join ( "," ) , ")}else{" ,
714
714
"quickSort(" , sortArgs . join ( "," ) ,
715
715
")}"
716
716
] . join ( "" ) )
717
-
717
+
718
718
//Return
719
719
code . push ( "}return " + funcName )
720
-
720
+
721
721
//Link everything together
722
722
var result = new Function ( "insertionSort" , "quickSort" , code . join ( "\n" ) )
723
723
var insertionSort = createInsertionSort ( order , dtype )
0 commit comments