Skip to content

Commit

Permalink
readme changes, versioning
Browse files Browse the repository at this point in the history
  • Loading branch information
jweinst1 committed Nov 28, 2021
1 parent 0468c4e commit 62bf99f
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

.DS_Store

# User-specific files
*.suo
*.user
Expand Down
27 changes: 27 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
PySIMD
======

.. image:: images/pysimd.png
:width: 800
:alt: PySimd logo

``simd`` is the python module for SIMD computing and programming. It
prodives an extensive interface to SIMD instruction sets on several different
architectures, and fallback scalar implementations when no SIMD instructions
Expand Down Expand Up @@ -129,3 +133,26 @@ The data inside a vector can also be retrieved as a collection type, like a ``tu
The above example shows the pure ``__repr__`` method of ``Vec`` only depicts a hexadecimal, byte level representation of the vector data, but a method like ``as_tuple`` allows the viewing of data with different types. One unique aspect of the ``simd`` module is it treats data and memory similar to that of C, where a chunk of 16 bytes could be two 64 bit integers, four 32 bit integers, and so on.
Math
~~~~
The ``simd`` module supports simd operations that involve artihmetic and math on integers and floating point numbers. Operations like ``add`` or ``sub`` work off another vector and a ``width``. The ``width`` indicates the width of the data lane the simd instruction applies to, such as ``8`` for 64 bit operations. Here are a few examples:
.. code:: py
>>> v = simd.Vec(size=16, repeat_value=5, repeat_size=4)
>>> v2 = simd.Vec(size=16, repeat_value=10, repeat_size=4)
>>> v.add(v2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function missing required argument 'width' (pos 2)
>>> v.add(v2, width=4)
>>> v.as_tuple(type=int, width=4)
(15, 15, 15, 15)
>>> v.sub(v2, width=4)
>>> v.sub(v2, width=4)
>>> v.as_tuple(type=int, width=4)
(-5, -5, -5, -5)
Binary file removed images/logo.png
Binary file not shown.
Binary file added images/pysimd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 115 additions & 0 deletions include/simd_vec_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "simd_vec_type.h"
#include "vec_macros.h"


static int pysimd_vec_filter_32(struct pysimd_vec_t* vec, int* gt,
int* lt,
int* eq) {
Expand Down Expand Up @@ -118,4 +119,118 @@ static int pysimd_vec_filter_32(struct pysimd_vec_t* vec, int* gt,
return 1;
}

static int pysimd_vec_filter_64(struct pysimd_vec_t* vec, long long* gt,
long long* lt,
long long* eq) {
#if defined(PYSIMD_X86_SSE2)
// pass
unsigned char* ptr = vec->data;
const unsigned char* ptr_end = ptr + vec->size;
while (ptr < ptr_end) {
__m128i loaded = _mm_load_si128((__m128i const*)ptr);
__m128i mask = _mm_set1_epi8(0xff);
if (gt != NULL) {
__m128i gtnum = _mm_set1_epi64(*gt);
__m128i gtres = _mm_cmpgt_epi64(loaded, gtnum);
mask = _mm_and_si128(mask, gtres);
}
if (lt != NULL) {
__m128i ltnum = _mm_set1_epi64(*lt);
__m128i ltres = _mm_cmplt_epi64(loaded, ltnum);
mask = _mm_and_si128(mask, ltres);
}
if (eq != NULL) {
__m128i eqnum = _mm_set1_epi64(*eq);
__m128i eqres = _mm_cmpeq_epi64(loaded, eqnum);
mask = _mm_and_si128(mask, eqres);
}
__m128i final_result = _mm_and_si128(mask, loaded);
int mask_result = _mm_movemask_epi8 (final_result);
size_t to_advance = 0;
switch (mask_result) {
case 0xFFFF:
case 0x0FFF:
case 0x00FF:
case 0x000F:
case 0x0:
// no filtering needed
to_advance = 16;
break;
case 0xFF0F:
final_result = _mm_shuffle_epi32(final_result, 0x78);
to_advance = 12;
break;
case 0xF00F:
// shuffle, reverse order of 0b10101100
final_result = _mm_shuffle_epi32(final_result, 0xac);
to_advance = 8;
break;
case 0x0FF0:
// shuffle, reverse order of 0b11001001
final_result = _mm_shuffle_epi32(final_result, 0xc9);
to_advance = 8;
break;
case 0xF0F0:
// shuffle, reverse order of 0b10001101
final_result = _mm_shuffle_epi32(final_result, 0x8d);
to_advance = 8;
break;
case 0x0F0F:
// shuffle, reverse order of 0b11011000
final_result = _mm_shuffle_epi32(final_result, 0xd8);
to_advance = 8;
break;
case 0xF0FF:
final_result = _mm_shuffle_epi32(final_result, 0xb4);
to_advance = 12;
break;
case 0xFFF0:
// shuffle, reversed order of 00011011
final_result = _mm_shuffle_epi32(final_result, 0x1b);
to_advance = 12;
break;
case 0xFF00:
// shuffle, reversed order of 00001110
final_result = _mm_shuffle_epi32(final_result, 0xe);
to_advance = 8;
break;
case 0xF000:
// shuffle, reversed order of 00000011
final_result = _mm_shuffle_epi32(final_result, 0x3);
to_advance = 4;
break;
case 0x0F00:
// shuffle, reversed order of 0b00000010
final_result = _mm_shuffle_epi32(final_result, 0x2);
to_advance = 4;
break;
case 0x00F0:
// shuffle, reversed order of 0b00000001
final_result = _mm_shuffle_epi32(final_result, 0x1);
to_advance = 4;
break;
default:
fprintf(stderr, "Got impossible mask value: 0x%x, aborting ...\n", mask_result);
abort();
}
_mm_store_si128 ((__m128i*)ptr, final_result);
ptr += to_advance;
}
#else
const unsigned char* reader = vec->data;
const unsigned char* read_end = reader + vec->size;
void* new_buf = calloc(1, vec->size);
unsigned char* writer = new_buf;
while (reader < read_end) {
if (*reader) {
*writer++ = *reader;
}
++reader;
}
free(vec->data);
vec->data = new_buf;
#endif
return 1;
}

#endif // PYSIMD_VEC_FILTER_H
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
# on vector object without needing to check the length/size of it
pysimd_minimum_align = 8

pysimd_patch_version = 4
pysimd_minor_version = 0
pysimd_patch_version = 0
pysimd_minor_version = 1
pysimd_major_version = 0

pysimd_version = [pysimd_major_version,
Expand Down
2 changes: 1 addition & 1 deletion src/pymain.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "core_simd_info.h"
#include "simd_vec.h"
#include "simd_vec_arith.h"
#include "simd_vec_filter.h"
//#include "simd_vec_filter.h"
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "structmember.h"
Expand Down

0 comments on commit 62bf99f

Please sign in to comment.