* This function packs boolean values in the input array into the bits of a * byte array. Truth values are determined as usual: 0 is false, everything * else is true. */
| 1527 | * else is true. |
| 1528 | */ |
| 1529 | static NPY_GCC_OPT_3 inline void |
| 1530 | pack_inner(const char *inptr, |
| 1531 | npy_intp element_size, /* in bytes */ |
| 1532 | npy_intp n_in, |
| 1533 | npy_intp in_stride, |
| 1534 | char *outptr, |
| 1535 | npy_intp n_out, |
| 1536 | npy_intp out_stride, |
| 1537 | PACK_ORDER order) |
| 1538 | { |
| 1539 | /* |
| 1540 | * Loop through the elements of inptr. |
| 1541 | * Determine whether or not it is nonzero. |
| 1542 | * Yes: set corresponding bit (and adjust build value) |
| 1543 | * No: move on |
| 1544 | * Every 8th value, set the value of build and increment the outptr |
| 1545 | */ |
| 1546 | npy_intp index = 0; |
| 1547 | int remain = n_in % 8; /* uneven bits */ |
| 1548 | |
| 1549 | #if NPY_SIMD |
| 1550 | if (in_stride == 1 && element_size == 1 && n_out > 2) { |
| 1551 | npyv_u8 v_zero = npyv_zero_u8(); |
| 1552 | /* don't handle non-full 8-byte remainder */ |
| 1553 | npy_intp vn_out = n_out - (remain ? 1 : 0); |
| 1554 | const int vstep = npyv_nlanes_u64; |
| 1555 | const int vstepx4 = vstep * 4; |
| 1556 | const int isAligned = npy_is_aligned(outptr, sizeof(npy_uint64)); |
| 1557 | vn_out -= (vn_out & (vstep - 1)); |
| 1558 | for (; index <= vn_out - vstepx4; index += vstepx4, inptr += npyv_nlanes_u8 * 4) { |
| 1559 | npyv_u8 v0 = npyv_load_u8((const npy_uint8*)inptr); |
| 1560 | npyv_u8 v1 = npyv_load_u8((const npy_uint8*)inptr + npyv_nlanes_u8 * 1); |
| 1561 | npyv_u8 v2 = npyv_load_u8((const npy_uint8*)inptr + npyv_nlanes_u8 * 2); |
| 1562 | npyv_u8 v3 = npyv_load_u8((const npy_uint8*)inptr + npyv_nlanes_u8 * 3); |
| 1563 | if (order == PACK_ORDER_BIG) { |
| 1564 | v0 = npyv_rev64_u8(v0); |
| 1565 | v1 = npyv_rev64_u8(v1); |
| 1566 | v2 = npyv_rev64_u8(v2); |
| 1567 | v3 = npyv_rev64_u8(v3); |
| 1568 | } |
| 1569 | npy_uint64 bb[4]; |
| 1570 | bb[0] = npyv_tobits_b8(npyv_cmpneq_u8(v0, v_zero)); |
| 1571 | bb[1] = npyv_tobits_b8(npyv_cmpneq_u8(v1, v_zero)); |
| 1572 | bb[2] = npyv_tobits_b8(npyv_cmpneq_u8(v2, v_zero)); |
| 1573 | bb[3] = npyv_tobits_b8(npyv_cmpneq_u8(v3, v_zero)); |
| 1574 | if(out_stride == 1 && |
| 1575 | (!NPY_ALIGNMENT_REQUIRED || isAligned)) { |
| 1576 | npy_uint64 *ptr64 = (npy_uint64*)outptr; |
| 1577 | #if NPY_SIMD_WIDTH == 16 |
| 1578 | npy_uint64 bcomp = bb[0] | (bb[1] << 16) | (bb[2] << 32) | (bb[3] << 48); |
| 1579 | ptr64[0] = bcomp; |
| 1580 | #elif NPY_SIMD_WIDTH == 32 |
| 1581 | ptr64[0] = bb[0] | (bb[1] << 32); |
| 1582 | ptr64[1] = bb[2] | (bb[3] << 32); |
| 1583 | #else |
| 1584 | ptr64[0] = bb[0]; ptr64[1] = bb[1]; |
| 1585 | ptr64[2] = bb[2]; ptr64[3] = bb[3]; |
| 1586 | #endif |
no test coverage detected