mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
incremental circle vectors work
This commit is contained in:
parent
13b81cd955
commit
d3fc3f8ffc
@ -30,11 +30,12 @@ public class DocForFunc implements DocFuncData {
|
||||
private String inType;
|
||||
private String outType;
|
||||
private final ArrayList<DocCtorData> ctors = new ArrayList<>();
|
||||
private Category[] categories = new Category[] { };
|
||||
private Category[] categories = new Category[]{};
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPackageName() {
|
||||
return this.packageName;
|
||||
@ -48,6 +49,7 @@ public class DocForFunc implements DocFuncData {
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return className;
|
||||
@ -56,6 +58,7 @@ public class DocForFunc implements DocFuncData {
|
||||
public void setClassJavadoc(String classJavadoc) {
|
||||
this.classJavadoc = classJavadoc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassJavadoc() {
|
||||
return classJavadoc;
|
||||
@ -64,6 +67,7 @@ public class DocForFunc implements DocFuncData {
|
||||
public void setInType(String inType) {
|
||||
this.inType = inType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInType() {
|
||||
return inType;
|
||||
@ -72,13 +76,14 @@ public class DocForFunc implements DocFuncData {
|
||||
public void setOutType(String outType) {
|
||||
this.outType = outType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutType() {
|
||||
return outType;
|
||||
}
|
||||
|
||||
public void addCtor(String ctorDoc, LinkedHashMap<String, String> args, List<List<String>> examples) {
|
||||
if (this.className==null || this.className.isEmpty()) {
|
||||
if (this.className == null || this.className.isEmpty()) {
|
||||
throw new RuntimeException("Unable to document ctor without known class name first.");
|
||||
}
|
||||
DocForFuncCtor ctor = new DocForFuncCtor(getClassName(), ctorDoc, args, examples);
|
||||
@ -93,16 +98,19 @@ public class DocForFunc implements DocFuncData {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DocForFunction{" +
|
||||
"packageName='" + packageName + '\'' +
|
||||
", className='" + className + '\'' +
|
||||
", classJavadoc='" + classJavadoc + '\'' +
|
||||
", inType='" + inType + '\'' +
|
||||
", outType='" + outType + '\'' +
|
||||
", ctors=" + ctors +
|
||||
'}';
|
||||
"(" + className + ")" +
|
||||
"packageName='" + packageName + '\'' +
|
||||
", className='" + className + '\'' +
|
||||
", classJavadoc='" + classJavadoc + '\'' +
|
||||
", inType='" + inType + '\'' +
|
||||
", outType='" + outType + '\'' +
|
||||
", ctors=" + ctors +
|
||||
'}';
|
||||
}
|
||||
|
||||
public void addCategories(Category[] categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import java.util.function.LongFunction;
|
||||
|
||||
@ThreadSafeMapper
|
||||
@Categories(Category.experimental)
|
||||
public class DNN_angular1_v implements LongFunction<float[]> {
|
||||
public class DnnAngular1V implements LongFunction<float[]> {
|
||||
|
||||
private final int d;
|
||||
private final long n;
|
||||
@ -39,7 +39,7 @@ public class DNN_angular1_v implements LongFunction<float[]> {
|
||||
* @param M
|
||||
* The modulo which is used to construct equivalence classes
|
||||
*/
|
||||
public DNN_angular1_v(int D, long N, long M) {
|
||||
public DnnAngular1V(int D, long N, long M) {
|
||||
d = D;
|
||||
n = N;
|
||||
m = M;
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.circlefield;
|
||||
|
||||
import io.nosqlbench.virtdata.lib.vectors.util.BitFields;
|
||||
|
||||
public class CFVectorMapper {
|
||||
private final CFVectorSpace space;
|
||||
private final int bits;
|
||||
|
||||
public CFVectorMapper(CFVectorSpace space) {
|
||||
this.space = space;
|
||||
this.bits = space.bits();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ord
|
||||
* The ordinal value which is the stable enumeration of a vector
|
||||
* @return
|
||||
*/
|
||||
public double[] vectorForOrdinal(int ord) {
|
||||
int offset = BitFields.reverseIntBitsUnsigned(ord);
|
||||
double unitFraction = unitFraction(offset, 0x4FFF_FFFF);
|
||||
return vecOnCircle(unitFraction);
|
||||
}
|
||||
|
||||
private double unitFraction(int offset, int maxvalue) {
|
||||
int[] fraction = BitFields.alignReducedBits(new int[]{offset, space.maxExcluded()});
|
||||
double unitFraction = ((double) fraction[0]) / ((double) fraction[1]);
|
||||
return unitFraction;
|
||||
}
|
||||
|
||||
public double[] vecOnCircle(double unit) {
|
||||
double radians = 2.0d * Math.PI * unit;
|
||||
return new double[]{Math.cos(radians), Math.sin(radians)};
|
||||
}
|
||||
|
||||
public int[] neighbors(int center, int k) {
|
||||
if (center >= space.maxExcluded()) {
|
||||
throw new RuntimeException("Ordinal value " + center + " must fall within interval [" +
|
||||
space.minIncluded() + "," + space.maxExcluded() + ")" +
|
||||
" for vector space " + space.toString());
|
||||
}
|
||||
int neighborhoodSize = Math.min(space.size, k);
|
||||
if ((neighborhoodSize & 1) == 1) {
|
||||
throw new RuntimeException("neighborhood size must be an even number for now, not " + neighborhoodSize);
|
||||
}
|
||||
int[] neighborhood = new int[neighborhoodSize];
|
||||
|
||||
for (int i = 0; i < neighborhood.length/2; i++) {
|
||||
int ccw = BitFields.rotateBitspace(center, i,30-(space.bits));
|
||||
neighborhood[i<<1]=BitFields.reverseIntBitsUnsigned(ccw);
|
||||
int cw = BitFields.rotateBitspace(center, -i,30-(space.bits));
|
||||
neighborhood[(i<<1)+1]=BitFields.reverseIntBitsUnsigned(cw);
|
||||
}
|
||||
return neighborhood;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.circlefield;
|
||||
|
||||
import io.nosqlbench.virtdata.lib.vectors.util.BitFields;
|
||||
|
||||
public class CFVectorSpace {
|
||||
|
||||
/**
|
||||
* The size determines the cardinality of unique vectors within this space.
|
||||
* It is the maximum value exclusive, or the next value after the maximum
|
||||
* value included in the set of ordinals.
|
||||
*/
|
||||
public final int size;
|
||||
/**
|
||||
* The number of bits which are needed to represent the maximum value.
|
||||
*/
|
||||
public final int bits;
|
||||
|
||||
/**
|
||||
* A mask which is used to limit the counting resolution to the bit size;
|
||||
*/
|
||||
public final int mask;
|
||||
|
||||
public CFVectorSpace(int size) {
|
||||
if (size>0x4000_0000) {
|
||||
throw new RuntimeException("Size must be less than or equal to " + 0x4000_0000 + "(0x4000_0000)" +
|
||||
", since all values must fall at perfect divisions of 0x4000_0000");
|
||||
}
|
||||
this.size = size;
|
||||
this.bits = BitFields.getMsbPosition(size);
|
||||
this.mask = 0xFFFFFFFF >> (32-bits);
|
||||
}
|
||||
public int mask() {
|
||||
return this.mask;
|
||||
}
|
||||
public int bits() {
|
||||
return this.bits;
|
||||
}
|
||||
public int minIncluded() {
|
||||
return 0;
|
||||
}
|
||||
public int maxExcluded() {
|
||||
return 1<<30;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("CFVectorSpace{");
|
||||
sb.append("size=").append(size);
|
||||
sb.append(" bits=").append(bits());
|
||||
sb.append(" [").append(minIncluded()).append(",").append(maxExcluded()).append(")");
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.circlefield;
|
@ -16,6 +16,8 @@
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.circular;
|
||||
|
||||
import io.nosqlbench.virtdata.lib.vectors.util.BitFields;
|
||||
|
||||
/**
|
||||
* <hr/>
|
||||
* <H2>Examples</H2>
|
||||
@ -70,7 +72,7 @@ public class CircularPartitioner {
|
||||
|
||||
public CircularPartitioner(int maxOrdinalExcluded) {
|
||||
this.maxOrdinalExcluded = maxOrdinalExcluded;
|
||||
this.msb = getMsbPosition(maxOrdinalExcluded - 1);
|
||||
this.msb = BitFields.getMsbPosition(maxOrdinalExcluded - 1);
|
||||
this.mask = (1<<msb) - 1;
|
||||
}
|
||||
|
||||
@ -86,7 +88,7 @@ public class CircularPartitioner {
|
||||
|
||||
public int ordinalToOffset(int ordinal) {
|
||||
|
||||
int ordMsb = getMsbPosition(ordinal);
|
||||
int ordMsb = BitFields.getMsbPosition(ordinal);
|
||||
int phaseBits = ordMsb - 1;
|
||||
int phaseMask = ((1 << phaseBits) - 1) & mask;
|
||||
int floorShift = msb - ordMsb;
|
||||
@ -105,6 +107,7 @@ public class CircularPartitioner {
|
||||
|
||||
public double ordinalToUnitInterval(int ordinal) {
|
||||
int remapped = ordinalToOffset(ordinal);
|
||||
|
||||
return ((double) remapped) / (double) maxOrdinalExcluded;
|
||||
}
|
||||
|
||||
@ -113,29 +116,4 @@ public class CircularPartitioner {
|
||||
return new double[]{Math.cos(radians), Math.sin(radians)};
|
||||
}
|
||||
|
||||
private static final int[] msbs = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
|
||||
|
||||
public static int getMsbPosition(int value) {
|
||||
if (value < 0) {
|
||||
throw new RuntimeException("Only values between 1 and " + Integer.MAX_VALUE +
|
||||
" are supported, and you tried to get the MSB position for value " + value +
|
||||
" or possible overflowed to a negative value."
|
||||
);
|
||||
}
|
||||
int r = 0;
|
||||
if ((value & 0x00000000FFFF0000L) > 0) {
|
||||
r += 16;
|
||||
value >>= 16;
|
||||
}
|
||||
if ((value & 0x000000000000FF00L) > 0) {
|
||||
r += 8;
|
||||
value >>= 8;
|
||||
}
|
||||
if ((value & 0x00000000000000F0) > 0) {
|
||||
r += 4;
|
||||
value >>= 4;
|
||||
}
|
||||
return r + msbs[(int) value];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors;
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.types;
|
||||
|
||||
import io.nosqlbench.virtdata.api.annotations.Categories;
|
||||
import io.nosqlbench.virtdata.api.annotations.Category;
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.util;
|
||||
|
||||
public class BitFields {
|
||||
|
||||
/**
|
||||
* Reduce the discrete magnitude of values by the same amount,
|
||||
* to allow any IEEE floating point values to remain closer to
|
||||
* the higher-precision part of the value space. This will reduce
|
||||
* rounding error for downstream operations which are based on
|
||||
* floating point casts of integer values.
|
||||
* @param values An array of integers
|
||||
* @return A scaled-down array of integers
|
||||
*/
|
||||
public static int[] alignReducedBits(int[] values) {
|
||||
int bits=32;
|
||||
for (int value : values) {
|
||||
bits=Math.min(bits,getLsbZeroBits(value));
|
||||
}
|
||||
int[] shifted = new int[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
shifted[i]=values[i]>>bits;
|
||||
}
|
||||
return shifted;
|
||||
}
|
||||
|
||||
private static final int[] zeros = {
|
||||
8, 0, 1, 0,
|
||||
2, 0, 1, 0,
|
||||
3, 0, 1, 0,
|
||||
2, 0, 1, 0
|
||||
};
|
||||
|
||||
/**
|
||||
* @return The number of lower-order bits which are zero in the value
|
||||
*/
|
||||
public static int getLsbZeroBits(int value) {
|
||||
int b = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((value & 0xF)>0) {
|
||||
b+=zeros[value&0xF];
|
||||
break;
|
||||
}
|
||||
b+=4;
|
||||
value>>=4;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The position of the most significant bit, with the lsb
|
||||
* represented as 1.
|
||||
*/
|
||||
public static int getMsbPosition(int value) {
|
||||
if (value < 0) {
|
||||
throw new RuntimeException("Only values between 1 and " + Integer.MAX_VALUE +
|
||||
" are supported, and you tried to get the MSB position for value " + value +
|
||||
" or possible overflowed to a negative value."
|
||||
);
|
||||
}
|
||||
int r = 0;
|
||||
if ((value & 0x00000000FFFF0000L) > 0) {
|
||||
r += 16;
|
||||
value >>= 16;
|
||||
}
|
||||
if ((value & 0x000000000000FF00L) > 0) {
|
||||
r += 8;
|
||||
value >>= 8;
|
||||
}
|
||||
if ((value & 0x00000000000000F0) > 0) {
|
||||
r += 4;
|
||||
value >>= 4;
|
||||
}
|
||||
return r + msbs[(int) value];
|
||||
}
|
||||
private static final int[] msbs = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
|
||||
|
||||
public static int reverseBits(int x) {
|
||||
return reverseBits2(x);
|
||||
}
|
||||
public static int reverseIntBitsUnsigned(int x) {
|
||||
return reverseBitsSave2(x);
|
||||
}
|
||||
|
||||
static int reverseBits1(int x, int bits) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < bits; i++) {
|
||||
result = (result << 1) | (x & 1);
|
||||
x >>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int reverseBitsSave2(int v) {
|
||||
if (v>=0x4000_0000) {
|
||||
throw new RuntimeException("unsigned bit reversal must remain in lower 31 bits. input=" + v);
|
||||
}
|
||||
long x = (long)v;
|
||||
// Masks for bit swapping
|
||||
|
||||
x = ((x >>> 1) & MASK1) | ((x & MASK1) << 1);
|
||||
x = ((x >>> 2) & MASK2) | ((x & MASK2) << 2);
|
||||
x = ((x >>> 4) & MASK3) | ((x & MASK3) << 4);
|
||||
x = ((x >>> 8) & MASK4) | ((x & MASK4) << 8);
|
||||
int signed = (int) ((x >>> 16) | (x << 16));
|
||||
return signed>>>2;
|
||||
}
|
||||
final static int MASK1 = 0x55555555; // 0b01010101010101010101010101010101
|
||||
final static int MASK2 = 0x33333333; // 0b00110011001100110011001100110011
|
||||
final static int MASK3 = 0x0F0F0F0F; // 0b00001111000011110000111100001111
|
||||
final static int MASK4 = 0x00FF00FF; // 0b00000000111111110000000011111111
|
||||
static int reverseBits2(int x) {
|
||||
// Masks for bit swapping
|
||||
|
||||
x = ((x >>> 1) & MASK1) | ((x & MASK1) << 1);
|
||||
x = ((x >>> 2) & MASK2) | ((x & MASK2) << 2);
|
||||
x = ((x >>> 4) & MASK3) | ((x & MASK3) << 4);
|
||||
x = ((x >>> 8) & MASK4) | ((x & MASK4) << 8);
|
||||
return (x >>> 16) | (x << 16);
|
||||
}
|
||||
|
||||
static int reverseBits3(int x) {
|
||||
return (BIT_REVERSE_TABLE[x & 0xFF] << 24) |
|
||||
(BIT_REVERSE_TABLE[(x >>> 8) & 0xFF] << 16) |
|
||||
(BIT_REVERSE_TABLE[(x >>> 16) & 0xFF] << 8) |
|
||||
BIT_REVERSE_TABLE[(x >>> 24) & 0xFF];
|
||||
}
|
||||
private static final int[] BIT_REVERSE_TABLE = buildReverseTable(8); // For byte reversal
|
||||
private static int[] buildReverseTable(int bits) {
|
||||
int size = 1 << bits;
|
||||
int[] table = new int[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
table[i] = reverseBits1(i, bits);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment or decrement the initial bitfield value by some amount,
|
||||
* offset into higher 2^scale resolution.
|
||||
* @param initial The initial bitfield image
|
||||
* @param amount The value to add (positive or negative) to the initial value
|
||||
* @param shift The number of bits to shift left before, and right after the increment
|
||||
* @return The initial value incremented by the amount at some scale determined by shift
|
||||
*/
|
||||
public static int rotateBitspace(int initial, int amount, int shift) {
|
||||
return ((initial<<shift)+amount)>>shift;
|
||||
}
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ class DNNAngular1VTest {
|
||||
|
||||
@Test
|
||||
public void testSimpleGeneration() {
|
||||
DNN_angular1_v vs = new DNN_angular1_v(2, 100, 3);
|
||||
DnnAngular1V vs = new DnnAngular1V(2, 100, 3);
|
||||
assertThat(vs.apply(0)).isEqualTo(new float[]{1, 0});
|
||||
assertThat(vs.apply(1)).isEqualTo(new float[]{2, 2});
|
||||
assertThat(vs.apply(2)).isEqualTo(new float[]{3, 6});
|
||||
@ -43,7 +43,7 @@ class DNNAngular1VTest {
|
||||
@Test
|
||||
public void testBasicAngularVectors() {
|
||||
int M = 7;
|
||||
DNN_angular1_v vf = new DNN_angular1_v(10, 100, M);
|
||||
DnnAngular1V vf = new DnnAngular1V(10, 100, M);
|
||||
// populate 100 training cycles of DNN angular
|
||||
float[][] vectors = new float[100][];
|
||||
for (int i = 0; i < 100; i++) {
|
||||
|
@ -25,7 +25,7 @@ public class DNN_angular_distance_decimalTest {
|
||||
@Test
|
||||
public void testBigDecimalDotProduct() {
|
||||
DNN_angular_v_decimal v_dec = new DNN_angular_v_decimal(10, 100_000, 100);
|
||||
DNN_angular1_v v_fp = new DNN_angular1_v(10, 100_000, 100);
|
||||
DnnAngular1V v_fp = new DnnAngular1V(10, 100_000, 100);
|
||||
|
||||
var v1d = v_dec.apply(90000);
|
||||
var v1f = v_fp.apply(90000);
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.circlefield;
|
||||
|
||||
import org.assertj.core.data.Offset;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class CFVectorMapperTest {
|
||||
|
||||
private final static CFVectorSpace vs32 = new CFVectorSpace(32);
|
||||
private final static CFVectorMapper vm32 = new CFVectorMapper(vs32);
|
||||
|
||||
private final static CFVectorSpace vs16bits = new CFVectorSpace(65536);
|
||||
private final static CFVectorMapper vm16bits = new CFVectorMapper(vs16bits);
|
||||
|
||||
|
||||
@Test
|
||||
public void testBasicIndex() {
|
||||
CFVectorSpace vs32 = new CFVectorSpace(32);
|
||||
CFVectorMapper vm32 = new CFVectorMapper(vs32);
|
||||
|
||||
double[] v_1_0 = vm32.vectorForOrdinal(0);
|
||||
isCloseTo(v_1_0,new double[]{1.0d,0.0d},Offset.offset(0.000001d));
|
||||
|
||||
double[] v_n1_0 = vm32.vectorForOrdinal(1);
|
||||
isCloseTo(v_n1_0,new double[]{-1.0d,0.0d},Offset.offset(0.000001d));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeighborhoods() {
|
||||
int[] neighbors = vm16bits.neighbors(0, 10);
|
||||
assertThat(neighbors).containsExactly(new int[]{32768});
|
||||
// TODO continue here
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void isCloseTo(double[] values, double[] expected, Offset<Double> offset) {
|
||||
for (int i = 0; i < expected.length; i++) {
|
||||
assertThat(values[i]).isCloseTo(expected[i],offset);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.circular;
|
||||
|
||||
import io.nosqlbench.virtdata.lib.vectors.CircleVectors;
|
||||
import io.nosqlbench.virtdata.lib.vectors.dnn.types.CircleVectors;
|
||||
import io.nosqlbench.virtdata.lib.vectors.algorithms.GoldenAngle;
|
||||
import io.nosqlbench.virtdata.lib.vectors.algorithms.LatLonBased;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.dnn.circular;
|
||||
|
||||
import io.nosqlbench.virtdata.lib.vectors.util.BitFields;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.util.Arrays;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -25,17 +26,17 @@ class CircularPartitionerTest {
|
||||
|
||||
@Test
|
||||
public void testMsbPositions() {
|
||||
assertThat(CircularPartitioner.getMsbPosition(1)).isEqualTo(1);
|
||||
assertThat(CircularPartitioner.getMsbPosition(2)).isEqualTo(2);
|
||||
assertThat(CircularPartitioner.getMsbPosition(7)).isEqualTo(3);
|
||||
assertThat(CircularPartitioner.getMsbPosition(8)).isEqualTo(4);
|
||||
assertThat(CircularPartitioner.getMsbPosition(Integer.MAX_VALUE)).isEqualTo(31);
|
||||
assertThat(BitFields.getMsbPosition(1)).isEqualTo(1);
|
||||
assertThat(BitFields.getMsbPosition(2)).isEqualTo(2);
|
||||
assertThat(BitFields.getMsbPosition(7)).isEqualTo(3);
|
||||
assertThat(BitFields.getMsbPosition(8)).isEqualTo(4);
|
||||
assertThat(BitFields.getMsbPosition(Integer.MAX_VALUE)).isEqualTo(31);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertBoundaryErrors() {
|
||||
assertThat(CircularPartitioner.getMsbPosition(0)).isEqualTo(0);
|
||||
assertThrows(RuntimeException.class, () -> CircularPartitioner.getMsbPosition(-1));
|
||||
assertThat(BitFields.getMsbPosition(0)).isEqualTo(0);
|
||||
assertThrows(RuntimeException.class, () -> BitFields.getMsbPosition(-1));
|
||||
}
|
||||
|
||||
private int[] remap(CircularPartitioner cp, int[] inputs) {
|
||||
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.util;
|
||||
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public class BitFieldsJMHTest {
|
||||
|
||||
@Param({"1"})
|
||||
public int inputs;
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode({Mode.AverageTime})
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Threads(1)
|
||||
@Warmup(iterations=1, timeUnit= TimeUnit.SECONDS,time=10)
|
||||
@Measurement(iterations=1,timeUnit=TimeUnit.SECONDS,time=10)
|
||||
public void reverseBits1() {
|
||||
inputs*=37;
|
||||
BitFields.reverseBits1(inputs,32);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode({Mode.AverageTime})
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Threads(1)
|
||||
@Warmup(iterations=1, timeUnit= TimeUnit.SECONDS,time=10)
|
||||
@Measurement(iterations=1,timeUnit=TimeUnit.SECONDS,time=10)
|
||||
public void reverseBits2() {
|
||||
inputs*=37;
|
||||
BitFields.reverseBits2(inputs);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode({Mode.AverageTime})
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Threads(1)
|
||||
@Warmup(iterations=1, timeUnit= TimeUnit.SECONDS,time=10)
|
||||
@Measurement(iterations=1,timeUnit=TimeUnit.SECONDS,time=10)
|
||||
public void reverseBits3() {
|
||||
inputs*=37;
|
||||
BitFields.reverseBits3(inputs);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.lib.vectors.util;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class BitFieldsTest {
|
||||
|
||||
@Test
|
||||
public void testZeros() {
|
||||
assertThat(BitFields.getLsbZeroBits(0)).isEqualTo(32);
|
||||
assertThat(BitFields.getLsbZeroBits(1)).isEqualTo(0);
|
||||
assertThat(BitFields.getLsbZeroBits(2)).isEqualTo(1);
|
||||
assertThat(BitFields.getLsbZeroBits(6)).isEqualTo(1);
|
||||
assertThat(BitFields.getLsbZeroBits(16)).isEqualTo(4);
|
||||
assertThat(BitFields.getLsbZeroBits(32)).isEqualTo(5);
|
||||
assertThat(BitFields.getLsbZeroBits(128)).isEqualTo(7);
|
||||
assertThat(BitFields.getLsbZeroBits(512)).isEqualTo(9);
|
||||
assertThat(BitFields.getLsbZeroBits(2049)).isEqualTo(0);
|
||||
assertThat(BitFields.getLsbZeroBits(8192)).isEqualTo(13);
|
||||
assertThat(BitFields.getLsbZeroBits(16384)).isEqualTo(14);
|
||||
assertThat(BitFields.getLsbZeroBits(4_000_000)).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAligned() {
|
||||
assertThat(BitFields.alignReducedBits(new int[]{0,0})).isEqualTo(new int[]{0,0});
|
||||
assertThat(BitFields.alignReducedBits(new int[]{8,16})).isEqualTo(new int[]{1,2});
|
||||
assertThat(BitFields.alignReducedBits(new int[]{8,15})).isEqualTo(new int[]{8,15});
|
||||
assertThat(BitFields.alignReducedBits(new int[]{32768,16384})).isEqualTo(new int[]{2,1});
|
||||
assertThat(BitFields.alignReducedBits(new int[]{0,15})).isEqualTo(new int[]{0,15});
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user