@@ -202,7 +202,7 @@ function createQuickSort(order, dtype, insertionSort) {
202
202
var funcName = [ "ndarrayQuickSort" , order . join ( "d" ) , dtype ] . join ( "" )
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
@@ -241,7 +241,18 @@ function createQuickSort(order, dtype, insertionSort) {
241
241
ele_size . push ( "n" + i )
242
242
vars . push ( "i" + i )
243
243
}
244
- vars . push ( "elementSize=" + ele_size . join ( "*" ) )
244
+ for ( var i = 0 ; i < 8 ; ++ i ) {
245
+ vars . push ( "b_ptr" + i )
246
+ }
247
+ vars . push (
248
+ "ptr3" ,
249
+ "ptr4" ,
250
+ "ptr5" ,
251
+ "ptr6" ,
252
+ "ptr7" ,
253
+ "pivot_ptr" ,
254
+ "ptr_shift" ,
255
+ "elementSize=" + ele_size . join ( "*" ) )
245
256
if ( allocator ) {
246
257
vars . push ( "pivot1=malloc(elementSize)" ,
247
258
"pivot2=malloc(elementSize)" )
@@ -273,6 +284,85 @@ function createQuickSort(order, dtype, insertionSort) {
273
284
return [ "data[" , ptr , "]=" , v ] . join ( "" )
274
285
}
275
286
287
+ function cacheLoop ( ptrs , usePivot , body ) {
288
+ if ( ptrs . length === 1 ) {
289
+ code . push ( "ptr0=" + toPointer ( ptrs [ 0 ] ) )
290
+ } else {
291
+ for ( var i = 0 ; i < ptrs . length ; ++ i ) {
292
+ code . push ( [ "b_ptr" , i , "=s0*" , ptrs [ i ] ] . join ( "" ) )
293
+ }
294
+ }
295
+ if ( usePivot ) {
296
+ code . push ( "pivot_ptr=0" )
297
+ }
298
+ code . push ( "ptr_shift=offset" )
299
+ for ( var i = order . length - 1 ; i >= 0 ; -- i ) {
300
+ var j = order [ i ]
301
+ if ( j === 0 ) {
302
+ continue
303
+ }
304
+ code . push ( [ "for(i" , j , "=0;i" , j , "<n" , j , ";++i" , j , "){" ] . join ( "" ) )
305
+ }
306
+ if ( ptrs . length > 1 ) {
307
+ for ( var i = 0 ; i < ptrs . length ; ++ i ) {
308
+ code . push ( [ "ptr" , i , "=b_ptr" , i , "+ptr_shift" ] . join ( "" ) )
309
+ }
310
+ }
311
+ code . push ( body )
312
+ if ( usePivot ) {
313
+ code . push ( "++pivot_ptr" )
314
+ }
315
+ for ( var i = 0 ; i < order . length ; ++ i ) {
316
+ var j = order [ i ]
317
+ if ( j === 0 ) {
318
+ continue
319
+ }
320
+ if ( ptrs . length > 1 ) {
321
+ code . push ( "ptr_shift+=d" + j )
322
+ } else {
323
+ code . push ( "ptr0+=d" + j )
324
+ }
325
+ code . push ( "}" )
326
+ }
327
+ }
328
+
329
+ function lexicoLoop ( label , ptrs , usePivot , body ) {
330
+ if ( ptrs . length === 1 ) {
331
+ code . push ( "ptr0=" + toPointer ( ptrs [ 0 ] ) )
332
+ } else {
333
+ for ( var i = 0 ; i < ptrs . length ; ++ i ) {
334
+ code . push ( [ "b_ptr" , i , "=s0*" , ptrs [ i ] ] . join ( "" ) )
335
+ }
336
+ code . push ( "ptr_shift=offset" )
337
+ }
338
+ if ( usePivot ) {
339
+ code . push ( "pivot_ptr=0" )
340
+ }
341
+ if ( label ) {
342
+ code . push ( label + ":" )
343
+ }
344
+ for ( var i = 1 ; i < order . length ; ++ i ) {
345
+ code . push ( [ "for(i" , i , "=0;i" , i , "<n" , i , ";++i" , i , "){" ] . join ( "" ) )
346
+ }
347
+ if ( ptrs . length > 1 ) {
348
+ for ( var i = 0 ; i < ptrs . length ; ++ i ) {
349
+ code . push ( [ "ptr" , i , "=b_ptr" , i , "+ptr_shift" ] . join ( "" ) )
350
+ }
351
+ }
352
+ code . push ( body )
353
+ for ( var i = order . length - 1 ; i >= 1 ; -- i ) {
354
+ if ( usePivot ) {
355
+ code . push ( "pivot_ptr+=f" + i )
356
+ }
357
+ if ( ptrs . length > 1 ) {
358
+ code . push ( "ptr_shift+=e" + i )
359
+ } else {
360
+ code . push ( "ptr0+=e" + i )
361
+ }
362
+ code . push ( "}" )
363
+ }
364
+ }
365
+
276
366
function cleanUp ( ) {
277
367
if ( order . length > 1 && allocator ) {
278
368
code . push ( "free(pivot1)" , "free(pivot2)" )
@@ -283,8 +373,12 @@ function createQuickSort(order, dtype, insertionSort) {
283
373
var a = "el" + a_id
284
374
var b = "el" + b_id
285
375
if ( order . length > 1 ) {
286
- //TODO:
287
- // if (compare(el1, el2) > 0) { var t = el1; el1 = el2; el2 = t; }
376
+ var lbl = "__l" + ( ++ labelCounter )
377
+ lexicoLoop ( lbl , [ a , b ] , false , [
378
+ "comp=" , dataRead ( "ptr0" ) , "-" , dataRead ( "ptr1" ) , "\n" ,
379
+ "if(comp>0){tmp0=" , a , ";" , a , "=" , b , ";" , b , "=tmp0;break " , lbl , "}\n" ,
380
+ "if(comp<0){break " , lbl , "}"
381
+ ] . join ( "" ) )
288
382
} else {
289
383
code . push ( [ "if(" , dataRead ( toPointer ( a ) ) , ">" , dataRead ( toPointer ( b ) ) , "){tmp0=" , a , ";" , a , "=" , b , ";" , b , "=tmp0}" ] . join ( "" ) )
290
384
}
@@ -300,18 +394,18 @@ function createQuickSort(order, dtype, insertionSort) {
300
394
compareSwap ( 2 , 3 )
301
395
compareSwap ( 4 , 5 )
302
396
303
- if ( order . length > 1 ) {
304
- //TODO:
305
- // pivot1 = a[el2]
306
- // pivot2 = a[el4]
307
- // pivots_are_equal = pivot1 == pivot2
308
- // x = a[el1]
309
- // y = a[el3]
310
- // z = a[el5]
311
- // a[index1] = x
312
- // a[index3] = y
313
- // a[index5] = z
314
- //
397
+ if ( order . length > 1 ) {
398
+ cacheLoop ( [ "el1" , "el2" , "el3" , "el4" , "el5" , "index1" , "index3" , "index5" ] , true , [
399
+ " pivot1[pivot_ptr]=" , dataRead ( "ptr1" ) , "\n" ,
400
+ " pivot2[pivot_ptr]=" , dataRead ( "ptr3" ) , "\n" ,
401
+ " pivots_are_equal=pivots_are_equal&&( pivot1[pivot_ptr]=== pivot2[pivot_ptr])\n" ,
402
+ "x=" , dataRead ( "ptr0" ) , "\n" ,
403
+ "y=" , dataRead ( "ptr2" ) , "\n" ,
404
+ "z=" , dataRead ( "ptr4" ) , "\n" ,
405
+ dataWrite ( "ptr5" , "x" ) , "\n" ,
406
+ dataWrite ( "ptr6" , "y" ) , "\n" ,
407
+ dataWrite ( "ptr7" , "z" )
408
+ ] . join ( "" ) )
315
409
} else {
316
410
code . push ( [
317
411
"pivot1=" , dataRead ( toPointer ( "el2" ) ) , "\n" ,
@@ -329,31 +423,36 @@ function createQuickSort(order, dtype, insertionSort) {
329
423
330
424
function moveElement ( dst , src ) {
331
425
if ( order . length > 1 ) {
332
- //TODO:
333
- // a[dst] = a[src]
426
+ cacheLoop ( [ dst , src ] , false ,
427
+ dataWrite ( "ptr0" , dataRead ( "ptr1" ) )
428
+ )
334
429
} else {
335
430
code . push ( dataWrite ( toPointer ( dst ) , dataRead ( toPointer ( src ) ) ) )
336
431
}
337
432
}
338
433
339
434
moveElement ( "index2" , "left" )
340
435
moveElement ( "index4" , "right" )
341
-
342
436
343
437
function comparePivot ( result , ptr , n ) {
344
438
if ( order . length > 1 ) {
345
- //TODO:
346
- // result=compare(a[ptr], pivot[n])
439
+ var lbl = "__l" + ( ++ labelCounter )
440
+ lexicoLoop ( lbl , [ ptr ] , true , [
441
+ result , "=" , dataRead ( "ptr0" ) , "-pivot" , n , "[pivot_ptr]\n" ,
442
+ "if(" , result , "!==0){break " , lbl , "}"
443
+ ] . join ( "" ) )
347
444
} else {
348
445
code . push ( [ result , "=" , dataRead ( toPointer ( ptr ) ) , "-pivot" , n ] . join ( "" ) )
349
446
}
350
447
}
351
448
352
449
function swapElements ( a , b ) {
353
450
if ( order . length > 1 ) {
354
- //TODO:
355
- // a[k] = a[less];
356
- // a[less] = ak;
451
+ cacheLoop ( [ a , b ] , false , [
452
+ "tmp=" , dataRead ( "ptr0" ) , "\n" ,
453
+ dataWrite ( "ptr0" , dataRead ( "ptr1" ) ) , "\n" ,
454
+ dataWrite ( "ptr1" , "tmp" )
455
+ ] . join ( "" ) )
357
456
} else {
358
457
code . push ( [
359
458
"ptr0=" , toPointer ( a ) , "\n" ,
@@ -367,10 +466,13 @@ function createQuickSort(order, dtype, insertionSort) {
367
466
368
467
function tripleSwap ( k , less , great ) {
369
468
if ( order . length > 1 ) {
370
- //TODO:
371
- // a[k] = a[less];
372
- // a[less++] = a[great];
373
- // a[great--] = ak;
469
+ cacheLoop ( [ k , less , great ] , false , [
470
+ "tmp=" , dataRead ( "ptr0" ) , "\n" ,
471
+ dataWrite ( "ptr0" , dataRead ( "ptr1" ) ) , "\n" ,
472
+ dataWrite ( "ptr1" , dataRead ( "ptr2" ) ) , "\n" ,
473
+ dataWrite ( "ptr2" , "tmp" )
474
+ ] . join ( "" ) )
475
+ code . push ( "++" + less , "--" + great )
374
476
} else {
375
477
code . push ( [
376
478
"ptr0=" , toPointer ( k ) , "\n" ,
@@ -450,10 +552,11 @@ function createQuickSort(order, dtype, insertionSort) {
450
552
451
553
//Move pivots to correct place
452
554
function storePivot ( mem_dest , pivot_dest , pivot ) {
453
- if ( order > 1 ) {
454
- //TODO:
455
- // a[left] = a[less - 1];
456
- // a[less - 1] = pivot1;
555
+ if ( order . length > 1 ) {
556
+ cacheLoop ( [ mem_dest , pivot_dest ] , true , [
557
+ dataWrite ( "ptr0" , dataRead ( "ptr1" ) ) , "\n" ,
558
+ dataWrite ( "ptr1" , [ "pivot" , pivot , "[pivot_ptr]" ] . join ( "" ) )
559
+ ] . join ( "" ) )
457
560
} else {
458
561
code . push (
459
562
dataWrite ( toPointer ( mem_dest ) , dataRead ( toPointer ( pivot_dest ) ) ) ,
@@ -483,11 +586,13 @@ function createQuickSort(order, dtype, insertionSort) {
483
586
code . push ( "return" )
484
587
code . push ( "}" )
485
588
486
-
487
589
function walkPointer ( ptr , pivot , body ) {
488
590
if ( order . length > 1 ) {
489
- //TODO:
490
- //while (compare(a[less], pivot1) == 0) { less++; }
591
+ code . push ( [ "__l" , ++ labelCounter , ":while(true){" ] . join ( "" ) )
592
+ cacheLoop ( [ ptr ] , true , [
593
+ "if(" , dataRead ( "ptr0" ) , "!==pivot" , pivot , "[pivot_ptr]){break __l" , labelCounter , "}"
594
+ ] . join ( "" ) )
595
+ code . push ( body , "}" )
491
596
} else {
492
597
code . push ( [ "while(" , dataRead ( toPointer ( ptr ) ) , "===pivot" , pivot , "){" , body , "}" ] . join ( "" ) )
493
598
}
@@ -541,7 +646,7 @@ function createQuickSort(order, dtype, insertionSort) {
541
646
//Compile and link
542
647
if ( order . length > 1 && allocator ) {
543
648
var compiled = new Function ( "insertionSort" , "malloc" , "free" , code . join ( "\n" ) )
544
- return compiled ( insertionSort , allocator . malloc , allocator . free )
649
+ return compiled ( insertionSort , allocator [ 0 ] , allocator [ 1 ] )
545
650
}
546
651
var compiled = new Function ( "insertionSort" , code . join ( "\n" ) )
547
652
return compiled ( insertionSort )
0 commit comments