@@ -349,4 +349,103 @@ MlasBitwiseSelectFloat16x4(MLAS_UINT16X4 select, MLAS_FLOAT16X4 ones, MLAS_FLOAT
349
349
return vbsl_f16 (select, ones, zeros);
350
350
}
351
351
352
+ MLAS_FORCEINLINE
353
+ void
354
+ Transpose8x8 (MLAS_FLOAT16X8& v0, MLAS_FLOAT16X8& v1, MLAS_FLOAT16X8& v2, MLAS_FLOAT16X8& v3,
355
+ MLAS_FLOAT16X8& v4, MLAS_FLOAT16X8& v5, MLAS_FLOAT16X8& v6, MLAS_FLOAT16X8& v7)
356
+ {
357
+ // |v00|v01|v02|v03|v04|v05|v06|v07|
358
+ // |v10|v11|v12|v13|v14|v15|v16|v17|
359
+ // |v20|v21|v22|v23|v24|v25|v26|v27|
360
+ // |v30|v31|v32|v33|v34|v35|v36|v37|
361
+ // |v40|v41|v42|v43|v44|v45|v46|v47|
362
+ // |v50|v51|v52|v53|v54|v55|v56|v57|
363
+ // |v60|v61|v62|v63|v64|v65|v66|v67|
364
+ // |v70|v71|v72|v73|v74|v75|v76|v77|
365
+ float16x8x2_t t01 = vtrnq_f16 (v0, v1);
366
+ float16x8x2_t t23 = vtrnq_f16 (v2, v3);
367
+ float16x8x2_t t45 = vtrnq_f16 (v4, v5);
368
+ float16x8x2_t t67 = vtrnq_f16 (v6, v7);
369
+ // |v00|v10|v02|v12|v04|v14|v06|v16|
370
+ // |v01|v11|v03|v13|v05|v15|v07|v17|
371
+ // |v20|v30|v22|v32|v24|v34|v26|v36|
372
+ // |v21|v31|v23|v33|v25|v35|v27|v37|
373
+ // |v40|v50|v42|v52|v44|v54|v46|v56|
374
+ // |v41|v51|v43|v53|v45|v55|v47|v57|
375
+ // |v60|v70|v62|v72|v64|v74|v66|v76|
376
+ // |v61|v71|v63|v73|v65|v75|v67|v77|
377
+ float32x4x2_t t02 = vtrnq_f32 (vreinterpretq_f32_f16 (t01.val [0 ]), vreinterpretq_f32_f16 (t23.val [0 ]));
378
+ float32x4x2_t t13 = vtrnq_f32 (vreinterpretq_f32_f16 (t01.val [1 ]), vreinterpretq_f32_f16 (t23.val [1 ]));
379
+ float32x4x2_t t46 = vtrnq_f32 (vreinterpretq_f32_f16 (t45.val [0 ]), vreinterpretq_f32_f16 (t67.val [0 ]));
380
+ float32x4x2_t t57 = vtrnq_f32 (vreinterpretq_f32_f16 (t45.val [1 ]), vreinterpretq_f32_f16 (t67.val [1 ]));
381
+ // |v00|v10|v20|v30|v04|v14|v24|v34|
382
+ // |v01|v11|v21|v31|v05|v15|v25|v35|
383
+ // |v02|v12|v22|v32|v06|v16|v26|v36|
384
+ // |v03|v13|v23|v33|v07|v17|v27|v37|
385
+ // |v40|v50|v60|v70|v44|v54|v64|v74|
386
+ // |v41|v51|v61|v71|v45|v55|v65|v75|
387
+ // |v42|v52|v62|v72|v46|v56|v66|v76|
388
+ // |v43|v53|v63|v73|v47|v57|v67|v77|
389
+ v0 = vreinterpretq_f16_f64 (vtrn1q_f64 (vreinterpretq_f64_f32 (t02.val [0 ]), vreinterpretq_f64_f32 (t46.val [0 ])));
390
+ v4 = vreinterpretq_f16_f64 (vtrn2q_f64 (vreinterpretq_f64_f32 (t02.val [0 ]), vreinterpretq_f64_f32 (t46.val [0 ])));
391
+ v2 = vreinterpretq_f16_f64 (vtrn1q_f64 (vreinterpretq_f64_f32 (t02.val [1 ]), vreinterpretq_f64_f32 (t46.val [1 ])));
392
+ v6 = vreinterpretq_f16_f64 (vtrn2q_f64 (vreinterpretq_f64_f32 (t02.val [1 ]), vreinterpretq_f64_f32 (t46.val [1 ])));
393
+ v1 = vreinterpretq_f16_f64 (vtrn1q_f64 (vreinterpretq_f64_f32 (t13.val [0 ]), vreinterpretq_f64_f32 (t57.val [0 ])));
394
+ v5 = vreinterpretq_f16_f64 (vtrn2q_f64 (vreinterpretq_f64_f32 (t13.val [0 ]), vreinterpretq_f64_f32 (t57.val [0 ])));
395
+ v3 = vreinterpretq_f16_f64 (vtrn1q_f64 (vreinterpretq_f64_f32 (t13.val [1 ]), vreinterpretq_f64_f32 (t57.val [1 ])));
396
+ v7 = vreinterpretq_f16_f64 (vtrn2q_f64 (vreinterpretq_f64_f32 (t13.val [1 ]), vreinterpretq_f64_f32 (t57.val [1 ])));
397
+ // |v00|v10|v20|v30|v40|v50|v60|v70|
398
+ // |v01|v11|v21|v31|v41|v51|v61|v71|
399
+ // |v02|v12|v22|v32|v42|v52|v62|v72|
400
+ // |v03|v13|v23|v33|v43|v53|v63|v73|
401
+ // |v04|v14|v24|v34|v44|v54|v64|v74|
402
+ // |v05|v15|v25|v35|v45|v55|v65|v75|
403
+ // |v06|v16|v26|v36|v46|v56|v66|v76|
404
+ // |v07|v17|v27|v37|v47|v57|v67|v77|
405
+ }
406
+
407
+ MLAS_FORCEINLINE
408
+ void
409
+ Transpose4x8 (MLAS_FLOAT16X8& v0, MLAS_FLOAT16X8& v1, MLAS_FLOAT16X8& v2, MLAS_FLOAT16X8& v3)
410
+ {
411
+ // |v00|v01|v02|v03|v04|v05|v06|v07|
412
+ // |v10|v11|v12|v13|v14|v15|v16|v17|
413
+ // |v20|v21|v22|v23|v24|v25|v26|v27|
414
+ // |v30|v31|v32|v33|v34|v35|v36|v37|
415
+ // =>
416
+ // |v00|v10|v20|v30|v04|v14|v24|v34|
417
+ // |v01|v11|v21|v31|v05|v15|v25|v35|
418
+ // |v02|v12|v22|v32|v06|v16|v26|v36|
419
+ // |v03|v13|v23|v33|v07|v17|v27|v37|
420
+ float16x8x2_t t01 = vtrnq_f16 (v0, v1);
421
+ float16x8x2_t t23 = vtrnq_f16 (v2, v3);
422
+
423
+ v0 = vreinterpretq_f16_f32 (vtrn1q_f32 (vreinterpretq_f32_f16 (t01.val [0 ]), vreinterpretq_f32_f16 (t23.val [0 ])));
424
+ v2 = vreinterpretq_f16_f32 (vtrn2q_f32 (vreinterpretq_f32_f16 (t01.val [0 ]), vreinterpretq_f32_f16 (t23.val [0 ])));
425
+ v1 = vreinterpretq_f16_f32 (vtrn1q_f32 (vreinterpretq_f32_f16 (t01.val [1 ]), vreinterpretq_f32_f16 (t23.val [1 ])));
426
+ v3 = vreinterpretq_f16_f32 (vtrn2q_f32 (vreinterpretq_f32_f16 (t01.val [1 ]), vreinterpretq_f32_f16 (t23.val [1 ])));
427
+ }
428
+
429
+ MLAS_FORCEINLINE
430
+ void
431
+ Transpose4x4 (MLAS_FLOAT16X4& v0, MLAS_FLOAT16X4& v1, MLAS_FLOAT16X4& v2, MLAS_FLOAT16X4& v3)
432
+ {
433
+ // |v00|v01|v02|v03|
434
+ // |v10|v11|v12|v13|
435
+ // |v20|v21|v22|v23|
436
+ // |v30|v31|v32|v33|
437
+ // =>
438
+ // |v00|v10|v20|v30|
439
+ // |v01|v11|v21|v31|
440
+ // |v02|v12|v22|v32|
441
+ // |v03|v13|v23|v33|
442
+ float16x4x2_t t01 = vtrn_f16 (v0, v1);
443
+ float16x4x2_t t23 = vtrn_f16 (v2, v3);
444
+
445
+ v0 = vreinterpret_f16_f32 (vtrn1_f32 (vreinterpret_f32_f16 (t01.val [0 ]), vreinterpret_f32_f16 (t23.val [0 ])));
446
+ v1 = vreinterpret_f16_f32 (vtrn1_f32 (vreinterpret_f32_f16 (t01.val [1 ]), vreinterpret_f32_f16 (t23.val [1 ])));
447
+ v2 = vreinterpret_f16_f32 (vtrn2_f32 (vreinterpret_f32_f16 (t01.val [0 ]), vreinterpret_f32_f16 (t23.val [0 ])));
448
+ v3 = vreinterpret_f16_f32 (vtrn2_f32 (vreinterpret_f32_f16 (t01.val [1 ]), vreinterpret_f32_f16 (t23.val [1 ])));
449
+ }
450
+
352
451
#endif // fp16 vector intrinsic supported
0 commit comments