Skip to content

Commit

Permalink
Fixed set() function
Browse files Browse the repository at this point in the history
  • Loading branch information
wjcunningham7 committed Oct 20, 2016
1 parent 9c3c4d7 commit 5ea2da6
Show file tree
Hide file tree
Showing 20 changed files with 324 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ install-sh
Makefile.in
missing
NEWS
.deps/**
src/.deps/**
src/.dirstamp
src/Makefile
Expand All @@ -56,3 +57,4 @@ inc/Makefile.in
nint/.deps/**
nint/Makefile
nint/Makefile.in
test/.deps/**
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4 --install

SUBDIRS = nint src inc
SUBDIRS = nint src inc test

lib_LIBRARIES = libfastmath.a
libfastmath_a_LIBADD = nint/nint.o src/FastMath.o src/FastNumInt.o src/stopwatch.o
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ CXXFLAGS="$CXXFLAGS $ax_cv_gcc_archflag"
xtra=($(for file in $(find inc/intrinsics -type f) ; do echo intrinsics/$(basename $file) ; done))
AC_SUBST([xtra], ["${xtra[[@]]}"])

AC_CONFIG_FILES([Makefile nint/Makefile src/Makefile inc/Makefile])
AC_CONFIG_FILES([Makefile nint/Makefile src/Makefile inc/Makefile test/Makefile])
AC_OUTPUT
40 changes: 24 additions & 16 deletions inc/FastBitset.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,31 @@ class FastBitset
// Reset Bits to Zero //
//--------------------//

//Reset all bits to zero
inline void reset()
{
memset(bits, 0, sizeof(BlockType) * nb);
}

//Reset all bits to one
inline void set()
{
BlockType s = n >> BLOCK_SHIFT;
memset(bits, ~0, sizeof(BlockType) * s);

unsigned int idx = static_cast<unsigned int>(n & (bits_per_block - 1));
BlockType mask = idx ? get_bitmask(idx) : (BlockType)(-1);
s -= !idx;
bits[s] |= mask;
}

//Reset bits in a range
//NOTE: the offset and length refer to blocks, not bits!
inline void reset(const uint64_t offset, const uint64_t length)
{
memset(bits+offset, 0, sizeof(BlockType) * length);
}

//--------------------//
// Cloning Operations //
//--------------------//
Expand Down Expand Up @@ -257,7 +277,7 @@ class FastBitset
unsigned int idx1 = static_cast<unsigned int>((offset + length) & (bits_per_block - 1));
BlockType lower_mask = idx0 ? ~get_bitmask(idx0) : (BlockType)(-1);
BlockType upper_mask = idx1 ? get_bitmask(idx1) : (BlockType)(-1);

if (length <= bits_per_block && (idx0 < idx1 || idx0 + idx1 == 0 || (idx0 > idx1 && idx1 == 0)))
fb.bits[block_idx] = (fb.bits[block_idx] & ~lower_mask) | (bits[block_idx] & lower_mask & upper_mask) | (fb.bits[block_idx] & ~upper_mask);
else {
Expand All @@ -274,6 +294,9 @@ class FastBitset
// Counting Operations //
//---------------------//

//Alias to be used externally
#define count_bits() count_v3()

//Computes the Hamming weight
//Make sure to compile with the flag -mpopcnt to use this
inline uint64_t count_v1() const
Expand Down Expand Up @@ -327,20 +350,11 @@ class FastBitset
inline uint64_t partial_count(uint64_t offset, uint64_t length)
{
uint64_t block_idx = offset >> BLOCK_SHIFT;
//idx0 and idx1 lie between 0 and 63
unsigned int idx0 = static_cast<unsigned int>(offset & (bits_per_block - 1));
unsigned int idx1 = static_cast<unsigned int>((offset + length) & (bits_per_block - 1));
BlockType lower_mask = idx0 ? ~get_bitmask(idx0) : (BlockType)(-1);
BlockType upper_mask = idx1 ? get_bitmask(idx1) : (BlockType)(-1);

/*printf("\noffset: %" PRIu64 "\n", offset);
printf("length: %" PRIu64 "\n", length);
printf("block_idx: %" PRIu64 "\n", block_idx);
printf("idx0: %u\n", idx0);
printf("idx1: %u\n", idx1);
printf("lower_mask:\t\t%s\n", toString(lower_mask).c_str());
printf("upper_mask:\t\t%s\n", toString(upper_mask).c_str());*/

uint64_t cnt[4] = { 0, 0, 0, 0 };
uint64_t nmid, rem, max;

Expand All @@ -352,10 +366,6 @@ class FastBitset
rem = nmid & 3;
max = nmid - rem;

/*printf("\nnmid: %" PRIu64 "\n", nmid);
printf("rem: %" PRIu64 "\n", rem);
printf("max: %" PRIu64 "\n", max);*/

for (uint64_t i = 1; i <= max; i += 4) {
asm volatile(
"popcntq %4, %4 \n\t"
Expand All @@ -373,8 +383,6 @@ class FastBitset
if (rem)
cnt[0] += do_count((bits + block_idx + max + 1), rem);

//printf("\nCount of interior: %" PRIu64 "\n", cnt[0] + cnt[1] + cnt[2] + cnt[3]);

cnt[0] += popcount(bits[block_idx] & lower_mask) + popcount(bits[block_idx + nmid + 1] & upper_mask);
}

Expand Down
13 changes: 13 additions & 0 deletions test/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4 --install

bin_PROGRAMS = general clone count intersection union disjointunion difference
general_SOURCES = general.cpp
clone_SOURCES = clone.cpp
count_SOURCES = count.cpp
intersection_SOURCES = intersection.cpp
union_SOURCES = union.cpp
disjointunion_SOURCES = disjointunion.cpp
difference_SOURCES = difference.cpp

AM_CXXFLAGS = -I $(top_builddir) -I $(top_builddir)/inc
Binary file added test/clone
Binary file not shown.
44 changes: 44 additions & 0 deletions test/clone.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "FastBitset.h"

int main(int argc, char **argv)
{
FastBitset f(128);
f.set(1);
printf("Initial bitset:\n");
f.printBitset();

FastBitset g = f;
printf("Testing assignment:\n");
g.printBitset();

f.reset();
g.reset();
if (f.any() || g.any()) printf("Reset failed.\n");
else printf("Reset succeeded.\n");

for (int i = 1; i < f.size(); i += 2)
f.set(i);
printf("\nTesting clone:\n");
f.printBitset();
f.clone(g);
g.printBitset();

if (f == g) printf("Equality operation succeeded.\n");
else printf("Equality failed.\n");

printf("\nTesting Partial Clone (1).\n");
for (int i = 0; i < f.size() >> 1; i++)
f.unset(i);
f.printBitset();
g.reset();
f.clone(g, 1, 1);
g.printBitset();

printf("\nTesting Partial Clone (2).\n");
for (int i = 0; i < f.size() >> 1; i++)
f.set(i);
f.printBitset();
FastBitset h(f.size());
f.partial_clone(h, 16, 64);
h.printBitset();
}
Binary file added test/count
Binary file not shown.
47 changes: 47 additions & 0 deletions test/count.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "FastBitset.h"

void countAll(FastBitset &f)
{
printf("Version 1: %" PRIu64 "\n", f.count_v1());
printf("Version 2: %" PRIu64 "\n", f.count_v2());
printf("Version 3: %" PRIu64 "\n", f.count_v3());
}

int main(int argc, char **argv)
{
FastBitset f(128);
for (int i = 0; i < f.size(); i += 2)
f.set(i);

printf("Testing bit counting.\n");
f.printBitset();
countAll(f);

for (int i = f.size() * 3 / 4; i < f.size(); i++)
f.unset(i);
f.printBitset();
countAll(f);

for (int i = 0; i < f.size() >> 2; i++)
f.set(i);
f.printBitset();
countAll(f);

printf("\nTesting partial count.\n");
f.reset();
for (int i = 0; i < f.size() >> 1; i++)
f.set(i);
for (int i = f.size() >> 1; i < f.size(); i += 4)
f.set(i);
f.printBitset();
printf("First half: %" PRIu64 "\n", f.partial_count(0, 64));
printf("Middle half: %" PRIu64 "\n", f.partial_count(32, 64));
printf("Final half: %" PRIu64 "\n", f.partial_count(64, 64));

FastBitset g(300);
g.set();

printf("\nTesting set().\n");
printf("Blocks used: %" PRIu64 "\n", g.getNumBlocks());
printf("Bits set: %" PRIu64 "\n", g.count_bits());
}
Binary file added test/difference
Binary file not shown.
35 changes: 35 additions & 0 deletions test/difference.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "FastBitset.h"

void initialize(FastBitset &f, FastBitset &g)
{
f.reset(); g.reset();
for (int i = 0; i < f.size() >> 1; i += 2)
f.set(i);
for (int i = f.size() >> 1; i < f.size(); i++)
f.set(i);
for (int i = 1; i < g.size(); i += 2)
g.set(i);
}

int main(int argc, char **argv)
{
FastBitset f(128);
FastBitset g(128);
initialize(f, g);

printf("Testing set difference.\n");
printf("Version 1:\n");
f.printBitset();
g.printBitset();
f.setDifference_v1(g);
f.printBitset();

#ifdef AVX2_ENABLED
printf("\nVersion 2:\n");
initialize(f, g);
f.printBitset();
g.printBitset();
f.setDifference_v2(g);
f.printBitset();
#endif
}
Binary file added test/disjointunion
Binary file not shown.
33 changes: 33 additions & 0 deletions test/disjointunion.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "FastBitset.h"

void initialize(FastBitset &f, FastBitset &g)
{
f.reset(); g.reset();
for (int i = 0; i < f.size() >> 1; i += 2)
f.set(i);
for (int i = 1; i < g.size(); i += 2)
g.set(i);
}

int main(int argc, char **argv)
{
FastBitset f(128);
FastBitset g(128);
initialize(f, g);

printf("Testing set disjoint union.\n");
printf("Version 1:\n");
f.printBitset();
g.printBitset();
f.setDisjointUnion_v1(g);
f.printBitset();

#ifdef AVX2_ENABLED
printf("\nVersion 2:\n");
initialize(f, g);
f.printBitset();
g.printBitset();
f.setDisjointUnion_v2(g);
f.printBitset();
#endif
}
Binary file added test/general
Binary file not shown.
15 changes: 15 additions & 0 deletions test/general.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "FastBitset.h"

int main(int argc, char **argv)
{
FastBitset f(128);
f.set(1);
f.printBitset();
printf("Size: %" PRIu64 "\n", f.size());
printf("Number of Blocks: %" PRIu64 "\n", f.getNumBlocks());
printf("Block Size: %" PRIu64 "\n", f.getBlockSize());

printf("Any set? %s\n", f.any() ? "Yes" : "No");
printf("Any in first block? %s\n", f.any_in_range(0, 64) ? "Yes" : "No");
printf("Any in second block? %s\n", f.any_in_range(65, 64) ? "Yes" : "No");
}
Binary file added test/intersection
Binary file not shown.
57 changes: 57 additions & 0 deletions test/intersection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "FastBitset.h"

void initialize(FastBitset &f, FastBitset &g)
{
f.reset(); g.reset();
for (int i = 0; i < f.size() >> 1; i += 2)
f.set(i);
for (int i = f.size() >> 1; i < f.size(); i++)
f.set(i);
for (int i = 1; i < g.size(); i += 2)
g.set(i);
}

int main(int argc, char **argv)
{
FastBitset f(128);
FastBitset g(128);
initialize(f, g);

printf("Testing set intersection.\n");
printf("Version 1:\n");
f.printBitset();
g.printBitset();
f.setIntersection_v1(g);
f.printBitset();

#ifdef AVX2_ENABLED
printf("\nVersion 2:\n");
initialize(f, g);
f.printBitset();
g.printBitset();
f.setIntersection_v2(g);
f.printBitset();
#endif

printf("\nTesting partial intersection.\n");
printf("First half:\n");
initialize(f, g);
f.printBitset();
g.printBitset();
f.partial_intersection(g, 0, 64);
f.printBitset();

printf("\nMiddle half:\n");
initialize(f, g);
f.printBitset();
g.printBitset();
f.partial_intersection(g, 32, 64);
f.printBitset();

printf("\nFinal half:\n");
initialize(f, g);
f.printBitset();
g.printBitset();
f.partial_intersection(g, 64, 64);
f.printBitset();
}
19 changes: 19 additions & 0 deletions test/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/sh

set -eu -o pipefail

./general
echo -e '\n'
./clone
echo -e '\n'
./count
echo -e '\n'
./intersection
echo -e '\n'
./union
echo -e '\n'
./disjointunion
echo -e '\n'
./difference
echo -e '\n'
echo 'Completed all tests on FastBitset.'
Binary file added test/union
Binary file not shown.
Loading

0 comments on commit 5ea2da6

Please sign in to comment.