Skip to content

Commit 55e7601

Browse files
authored
Add: Int8 (sbyte) overloads for C# (#552)
Closes #551
1 parent cfb5132 commit 55e7601

File tree

3 files changed

+385
-2
lines changed

3 files changed

+385
-2
lines changed

csharp/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ using Cloud.Unum.USearch;
1414

1515
using var index = new USearchIndex(
1616
metricKind: MetricKind.Cos, // Choose cosine metric
17-
quantization: ScalarKind.Float32, // Only quantization to Float32, Float64 is currently supported
17+
quantization: ScalarKind.Float32, // Only quantization to Float32, Float64, Int8 is currently supported
1818
dimensions: 3, // Define the number of dimensions in input vectors
1919
connectivity: 16, // How frequent should the connections in the graph be, optional
2020
expansionAdd: 128, // Control the recall of indexing, optional

csharp/src/Cloud.Unum.USearch.Tests/USearchIndexTests.cs

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,37 @@ public void Add_FloatVector_UpdatesIndexOptions()
165165
}
166166
}
167167

168+
[Fact]
169+
public void Add_ByteVector_UpdatesIndexOptions()
170+
{
171+
// Arrange
172+
const uint Dimensions = 10;
173+
const uint AddKey = 1;
174+
const uint NonExistentKey = 2;
175+
const uint ExpectedSize = 1;
176+
const uint ExpectedCapacity = 1;
177+
178+
var indexOptions = new IndexOptions(
179+
metricKind: MetricKind.Cos,
180+
quantization: ScalarKind.Int8,
181+
dimensions: Dimensions
182+
);
183+
184+
var inputVector = GenerateByteVector((int)Dimensions);
185+
186+
using (var index = new USearchIndex(indexOptions))
187+
{
188+
// Act
189+
index.Add(AddKey, inputVector);
190+
191+
// Assert
192+
Assert.True(index.Contains(AddKey));
193+
Assert.False(index.Contains(NonExistentKey));
194+
Assert.Equal(ExpectedSize, index.Size());
195+
Assert.True(ExpectedCapacity <= index.Capacity());
196+
}
197+
}
198+
168199
[Fact]
169200
public void Add_DoubleVector_UpdatesIndexOptions()
170201
{
@@ -228,6 +259,38 @@ public void Add_ManyFloatVectorsUnderSameKeySeparatelyInMultiKeyIndex_UpdatesInd
228259
}
229260
}
230261

262+
[Fact]
263+
public void Add_ManyByteVectorsUnderSameKeySeparatelyInMultiKeyIndex_UpdatesIndexOptions()
264+
{
265+
// Arrange
266+
const uint Dimensions = 10;
267+
const ulong AddKey = 1;
268+
const int AddFactor = 5;
269+
270+
var indexOptions = new IndexOptions(
271+
metricKind: MetricKind.Cos,
272+
quantization: ScalarKind.Int8,
273+
dimensions: Dimensions,
274+
multi: true
275+
);
276+
277+
var inputVector = GenerateByteVector((int)Dimensions);
278+
279+
using (var index = new USearchIndex(indexOptions))
280+
{
281+
// Act
282+
for (int i = 0; i < AddFactor; i++)
283+
{
284+
index.Add(AddKey, inputVector);
285+
}
286+
287+
// Assert
288+
Assert.True(index.Contains(AddKey));
289+
Assert.Equal((uint)AddFactor, index.Size());
290+
Assert.True((uint)AddFactor <= index.Capacity());
291+
}
292+
}
293+
231294
[Fact]
232295
public void Add_ManyDoubleVectorsUnderSameKeySeparatelyInMultiKeyIndex_UpdatesIndexOptions()
233296
{
@@ -293,6 +356,39 @@ public void Add_ManyFloatVectorsUnderSameKeyInBatchInMultiKeyIndex_UpdatesIndexO
293356
}
294357
}
295358

359+
[Fact]
360+
public void Add_ManyByteVectorsUnderSameKeyInBatchInMultiKeyIndex_UpdatesIndexOptions()
361+
{
362+
// Arrange
363+
const uint Dimensions = 10;
364+
const ulong AddKey = 1;
365+
const uint BatchSize = 5;
366+
367+
var indexOptions = new IndexOptions(
368+
metricKind: MetricKind.Cos,
369+
quantization: ScalarKind.Int8,
370+
dimensions: Dimensions,
371+
multi: true
372+
);
373+
374+
(var inputKeys, var inputVectors) = (
375+
Enumerable.Repeat(AddKey, (int)BatchSize).ToArray(),
376+
GenerateManyByteVectors((int)BatchSize, (int)Dimensions)
377+
);
378+
379+
using (var index = new USearchIndex(indexOptions))
380+
{
381+
// Act
382+
index.Add(inputKeys, inputVectors);
383+
384+
// Assert
385+
Assert.True(index.Contains(AddKey));
386+
Assert.Equal(BatchSize, index.Size());
387+
Assert.True(BatchSize <= index.Capacity());
388+
Assert.Equal((int)BatchSize, index.Count(AddKey));
389+
}
390+
}
391+
296392
[Fact]
297393
public void Add_ManyDoubleVectorsUnderSameKeyInBatchInMultiKeyIndex_UpdatesIndexOptions()
298394
{
@@ -359,6 +455,39 @@ public void Get_ManyFloatVectorsUnderSameKeyInMultiKeyIndex_ReturnsCorrectValue(
359455
}
360456
}
361457

458+
[Fact]
459+
public void Get_ManyByteVectorsUnderSameKeyInMultiKeyIndex_ReturnsCorrectValue()
460+
{
461+
// Arrange
462+
const uint Dimensions = 10;
463+
const ulong AddKey = 1;
464+
const int RetrieveCount = 5;
465+
const int BatchSize = 10;
466+
467+
var indexOptions = new IndexOptions(
468+
metricKind: MetricKind.Cos,
469+
quantization: ScalarKind.Int8,
470+
dimensions: Dimensions,
471+
multi: true
472+
);
473+
474+
(var inputKeys, var inputVectors) = (
475+
Enumerable.Repeat(AddKey, BatchSize).ToArray(),
476+
GenerateManyByteVectors(BatchSize, (int)Dimensions)
477+
);
478+
479+
using (var index = new USearchIndex(indexOptions))
480+
{
481+
index.Add(inputKeys, inputVectors);
482+
483+
// Act
484+
int foundVectorsCount = index.Get(AddKey, RetrieveCount, out float[][] retrievedVectors);
485+
486+
// Assert
487+
Assert.Equal(RetrieveCount, foundVectorsCount);
488+
}
489+
}
490+
362491
[Fact]
363492
public void Get_ManyDoubleVectorsUnderSameKeyInMultiKeyIndex_ReturnsCorrectCountValue()
364493
{
@@ -419,6 +548,33 @@ public void Get_AfterAddingFloatVector_ReturnsEqualVector()
419548
}
420549
}
421550

551+
[Fact]
552+
public void Get_AfterAddingByteVector_ReturnsEqualVector()
553+
{
554+
// Arrange
555+
const uint Dimensions = 10;
556+
const ulong AddKey = 1;
557+
558+
var indexOptions = new IndexOptions(
559+
metricKind: MetricKind.Cos,
560+
quantization: ScalarKind.Int8,
561+
dimensions: Dimensions
562+
);
563+
564+
(var inputKey, var inputVector) = (AddKey, GenerateByteVector((int)Dimensions));
565+
566+
using (var index = new USearchIndex(indexOptions))
567+
{
568+
index.Add(inputKey, inputVector);
569+
570+
// Act
571+
index.Get(inputKey, out sbyte[] retrievedVector);
572+
573+
// Assert
574+
Assert.Equal(inputVector, retrievedVector);
575+
}
576+
}
577+
422578
[Fact]
423579
public void Get_AfterAddingDoubleVector_ReturnsEqualVector()
424580
{
@@ -473,6 +629,33 @@ public void Add_AddingTwoFloatVectorsUnderSameKey_ThrowsException()
473629
}
474630
}
475631

632+
[Fact]
633+
public void Add_AddingTwoByteVectorsUnderSameKey_ThrowsException()
634+
{
635+
// Arrange
636+
const uint Dimensions = 10;
637+
const ulong AddKey = 1;
638+
639+
var indexOptions = new IndexOptions(
640+
metricKind: MetricKind.Cos,
641+
quantization: ScalarKind.Int8,
642+
dimensions: Dimensions
643+
);
644+
645+
(var inputKey, var inputVector) = (AddKey, GenerateByteVector((int)Dimensions));
646+
647+
using (var index = new USearchIndex(indexOptions))
648+
{
649+
index.Add(inputKey, inputVector);
650+
651+
// Act
652+
Action actual = () => index.Add(inputKey, inputVector);
653+
654+
// Assert
655+
Assert.Throws<USearchException>(actual);
656+
}
657+
}
658+
476659
[Fact]
477660
public void Add_AddingTwoDoubleVectorsUnderSameKey_ThrowsException()
478661
{
@@ -529,6 +712,35 @@ public void Remove_InsertedFloatVector_ReturnsInsertedVectorsCount()
529712
}
530713
}
531714

715+
[Fact]
716+
public void Remove_InsertedByteVector_ReturnsInsertedVectorsCount()
717+
{
718+
// Arrange
719+
const uint Dimensions = 10;
720+
const ulong AddKey = 1;
721+
const int ExpectedRemoveReturn = 1;
722+
723+
var indexOptions = new IndexOptions(
724+
metricKind: MetricKind.Cos,
725+
quantization: ScalarKind.Int8,
726+
dimensions: Dimensions
727+
);
728+
729+
(var inputKey, var inputVector) = (AddKey, GenerateByteVector((int)Dimensions));
730+
731+
732+
using (var index = new USearchIndex(indexOptions))
733+
{
734+
index.Add(inputKey, inputVector);
735+
736+
// Act
737+
var removedCount = index.Remove(AddKey);
738+
739+
// Assert
740+
Assert.Equal(ExpectedRemoveReturn, removedCount);
741+
}
742+
}
743+
532744
[Fact]
533745
public void Remove_InsertedDoubleVector_ReturnsInsertedVectorsCount()
534746
{
@@ -589,6 +801,38 @@ public void Remove_InsertedManyFloatVectorsUnderSameKeyInMultiKeyIndex_ReturnsIn
589801
}
590802
}
591803

804+
[Fact]
805+
public void Remove_InsertedManyByteVectorsUnderSameKeyInMultiKeyIndex_ReturnsInsertedVectorsCount()
806+
{
807+
// Arrange
808+
const uint Dimensions = 10;
809+
const ulong AddKey = 1;
810+
const int BatchSize = 2;
811+
812+
var indexOptions = new IndexOptions(
813+
metricKind: MetricKind.Cos,
814+
quantization: ScalarKind.Int8,
815+
dimensions: Dimensions,
816+
multi: true
817+
);
818+
819+
(var inputKeys, var inputVectors) = (
820+
Enumerable.Repeat(AddKey, BatchSize).ToArray(),
821+
GenerateManyByteVectors(BatchSize, (int)Dimensions)
822+
);
823+
824+
using (var index = new USearchIndex(indexOptions))
825+
{
826+
index.Add(inputKeys, inputVectors);
827+
828+
// Act
829+
var removedCount = index.Remove(AddKey);
830+
831+
// Assert
832+
Assert.Equal(BatchSize, removedCount);
833+
}
834+
}
835+
592836
[Fact]
593837
public void Remove_InsertedManyDoubleVectorUnderSameKeyInMultiKeyIndex_ReturnsInsertedVectorsCount()
594838
{
@@ -964,6 +1208,21 @@ private static float[][] GenerateManyFloatVectors(int n, int vectorLength)
9641208
return result;
9651209
}
9661210

1211+
private static sbyte[] GenerateByteVector(int vectorLength)
1212+
{
1213+
return Enumerable.Range(0, vectorLength).Select(i => (sbyte)i).ToArray();
1214+
}
1215+
1216+
private static sbyte[][] GenerateManyByteVectors(int n, int vectorLength)
1217+
{
1218+
var result = new sbyte[n][];
1219+
for (int i = 0; i < n; i++)
1220+
{
1221+
result[i] = Enumerable.Range(0, vectorLength).Select(i => (sbyte)i).ToArray();
1222+
}
1223+
return result;
1224+
}
1225+
9671226
private static double[] GenerateDoubleVector(int n)
9681227
{
9691228
return Enumerable.Range(0, n).Select(i => (double)i).ToArray();

0 commit comments

Comments
 (0)