MCPcopy Create free account
hub / github.com/numpy/numpy / pack_inner

Function pack_inner

numpy/core/src/multiarray/compiled_base.c:1529–1646  ·  view source on GitHub ↗

* 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. */

Source from the content-addressed store, hash-verified

1527 * else is true.
1528 */
1529static NPY_GCC_OPT_3 inline void
1530pack_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

Callers 1

pack_bitsFunction · 0.85

Calls 2

npy_is_alignedFunction · 0.85
npyv_rev64_u8Function · 0.50

Tested by

no test coverage detected