Skip to content

Commit

Permalink
Add: Hyper-param configs in C
Browse files Browse the repository at this point in the history
  • Loading branch information
ashvardanian committed Apr 6, 2024
1 parent 4b1a630 commit c7ed1d4
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 23 deletions.
94 changes: 71 additions & 23 deletions c/lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ extern "C" {
#include "usearch.h"
}

// Check if NDEBUG is defined to determine if it's a release build
#ifdef NDEBUG
#define USEARCH_ASSERT(expression) (void)(expression)
#else
#define USEARCH_ASSERT(expression) assert(expression)
#endif

using namespace unum::usearch;
using namespace unum;

Expand Down Expand Up @@ -106,7 +113,7 @@ extern "C" {

USEARCH_EXPORT usearch_index_t usearch_init(usearch_init_options_t* options, usearch_error_t* error) {

assert(options && error && "Missing arguments");
USEARCH_ASSERT(options && error && "Missing arguments");

index_dense_config_t config(options->connectivity, options->expansion_add, options->expansion_search);
config.multi = options->multi;
Expand Down Expand Up @@ -136,37 +143,37 @@ USEARCH_EXPORT void usearch_free(usearch_index_t index, usearch_error_t*) {
}

USEARCH_EXPORT size_t usearch_serialized_length(usearch_index_t index, usearch_error_t*) {
assert(index && "Missing arguments");
USEARCH_ASSERT(index && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->serialized_length();
}

USEARCH_EXPORT void usearch_save(usearch_index_t index, char const* path, usearch_error_t* error) {

assert(index && path && error && "Missing arguments");
USEARCH_ASSERT(index && path && error && "Missing arguments");
serialization_result_t result = reinterpret_cast<index_dense_t*>(index)->save(path);
if (!result)
*error = result.error.release();
}

USEARCH_EXPORT void usearch_load(usearch_index_t index, char const* path, usearch_error_t* error) {

assert(index && path && error && "Missing arguments");
USEARCH_ASSERT(index && path && error && "Missing arguments");
serialization_result_t result = reinterpret_cast<index_dense_t*>(index)->load(path);
if (!result)
*error = result.error.release();
}

USEARCH_EXPORT void usearch_view(usearch_index_t index, char const* path, usearch_error_t* error) {

assert(index && path && error && "Missing arguments");
USEARCH_ASSERT(index && path && error && "Missing arguments");
serialization_result_t result = reinterpret_cast<index_dense_t*>(index)->view(path);
if (!result)
*error = result.error.release();
}

USEARCH_EXPORT void usearch_metadata(char const* path, usearch_init_options_t* options, usearch_error_t* error) {

assert(path && options && error && "Missing arguments");
USEARCH_ASSERT(path && options && error && "Missing arguments");
index_dense_metadata_result_t result = index_dense_metadata_from_path(path);
if (!result)
*error = result.error.release();
Expand All @@ -184,7 +191,7 @@ USEARCH_EXPORT void usearch_metadata(char const* path, usearch_init_options_t* o

USEARCH_EXPORT void usearch_save_buffer(usearch_index_t index, void* buffer, size_t length, usearch_error_t* error) {

assert(index && buffer && length && error && "Missing arguments");
USEARCH_ASSERT(index && buffer && length && error && "Missing arguments");
memory_mapped_file_t memory_map((byte_t*)buffer, length);
serialization_result_t result = reinterpret_cast<index_dense_t*>(index)->save(std::move(memory_map));
if (!result)
Expand All @@ -194,7 +201,7 @@ USEARCH_EXPORT void usearch_save_buffer(usearch_index_t index, void* buffer, siz
USEARCH_EXPORT void usearch_load_buffer(usearch_index_t index, void const* buffer, size_t length,
usearch_error_t* error) {

assert(index && buffer && length && error && "Missing arguments");
USEARCH_ASSERT(index && buffer && length && error && "Missing arguments");
memory_mapped_file_t memory_map((byte_t*)buffer, length);
serialization_result_t result = reinterpret_cast<index_dense_t*>(index)->load(std::move(memory_map));
if (!result)
Expand All @@ -204,7 +211,7 @@ USEARCH_EXPORT void usearch_load_buffer(usearch_index_t index, void const* buffe
USEARCH_EXPORT void usearch_view_buffer(usearch_index_t index, void const* buffer, size_t length,
usearch_error_t* error) {

assert(index && buffer && length && error && "Missing arguments");
USEARCH_ASSERT(index && buffer && length && error && "Missing arguments");
memory_mapped_file_t memory_map((byte_t*)buffer, length);
serialization_result_t result = reinterpret_cast<index_dense_t*>(index)->view(std::move(memory_map));
if (!result)
Expand All @@ -214,7 +221,7 @@ USEARCH_EXPORT void usearch_view_buffer(usearch_index_t index, void const* buffe
USEARCH_EXPORT void usearch_metadata_buffer(void const* buffer, size_t length, usearch_init_options_t* options,
usearch_error_t* error) {

assert(buffer && length && options && error && "Missing arguments");
USEARCH_ASSERT(buffer && length && options && error && "Missing arguments");
index_dense_metadata_result_t result =
index_dense_metadata_from_buffer(memory_mapped_file_t((byte_t*)(buffer), length));
if (!result)
Expand All @@ -231,24 +238,65 @@ USEARCH_EXPORT void usearch_metadata_buffer(void const* buffer, size_t length, u
options->metric = NULL;
}

USEARCH_EXPORT size_t usearch_size(usearch_index_t index, usearch_error_t*) { //
USEARCH_EXPORT size_t usearch_size(usearch_index_t index, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->size();
}

USEARCH_EXPORT size_t usearch_capacity(usearch_index_t index, usearch_error_t*) {
USEARCH_EXPORT size_t usearch_capacity(usearch_index_t index, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->capacity();
}

USEARCH_EXPORT size_t usearch_dimensions(usearch_index_t index, usearch_error_t*) {
USEARCH_EXPORT size_t usearch_dimensions(usearch_index_t index, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->dimensions();
}

USEARCH_EXPORT size_t usearch_connectivity(usearch_index_t index, usearch_error_t*) {
USEARCH_EXPORT size_t usearch_connectivity(usearch_index_t index, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->connectivity();
}

USEARCH_EXPORT size_t usearch_expansion_add(usearch_index_t index, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->expansion_add();
}

USEARCH_EXPORT size_t usearch_expansion_search(usearch_index_t index, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->expansion_search();
}

USEARCH_EXPORT void usearch_change_expansion_add(usearch_index_t index, size_t expansion, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
reinterpret_cast<index_dense_t*>(index)->change_expansion_add(expansion);
}

USEARCH_EXPORT void usearch_change_expansion_search(usearch_index_t index, size_t expansion, usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
reinterpret_cast<index_dense_t*>(index)->change_expansion_search(expansion);
}

USEARCH_EXPORT void usearch_change_metric_kind(usearch_index_t index, usearch_metric_kind_t kind,
usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
auto& index_dense = *reinterpret_cast<index_dense_t*>(index);
index_dense.change_metric(
metric_punned_t(index_dense.dimensions(), metric_kind_to_cpp(kind), index_dense.scalar_kind()));
}

USEARCH_EXPORT void usearch_change_metric(usearch_index_t index, usearch_metric_t metric, usearch_metric_kind_t kind,
usearch_error_t* error) {
USEARCH_ASSERT(index && error && "Missing arguments");
auto& index_dense = *reinterpret_cast<index_dense_t*>(index);
index_dense.change_metric(metric_punned_t(index_dense.dimensions(), reinterpret_cast<std::uintptr_t>(metric),
metric_punned_signature_t::array_array_k, metric_kind_to_cpp(kind),
index_dense.scalar_kind()));
}

USEARCH_EXPORT void usearch_reserve(usearch_index_t index, size_t capacity, usearch_error_t* error) {
assert(index && error && "Missing arguments");
USEARCH_ASSERT(index && error && "Missing arguments");
if (!reinterpret_cast<index_dense_t*>(index)->reserve(capacity))
*error = "Out of memory!";
}
Expand All @@ -257,27 +305,27 @@ USEARCH_EXPORT void usearch_add(
usearch_index_t index, usearch_key_t key, void const* vector, usearch_scalar_kind_t kind, //
usearch_error_t* error) {

assert(index && vector && error && "Missing arguments");
USEARCH_ASSERT(index && vector && error && "Missing arguments");
add_result_t result = add_(reinterpret_cast<index_dense_t*>(index), key, vector, scalar_kind_to_cpp(kind));
if (!result)
*error = result.error.release();
}

USEARCH_EXPORT bool usearch_contains(usearch_index_t index, usearch_key_t key, usearch_error_t*) {
assert(index && "Missing arguments");
USEARCH_ASSERT(index && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->contains(key);
}

USEARCH_EXPORT size_t usearch_count(usearch_index_t index, usearch_key_t key, usearch_error_t*) {
assert(index && "Missing arguments");
USEARCH_ASSERT(index && "Missing arguments");
return reinterpret_cast<index_dense_t*>(index)->count(key);
}

USEARCH_EXPORT size_t usearch_search( //
usearch_index_t index, void const* vector, usearch_scalar_kind_t kind, size_t results_limit, //
usearch_key_t* found_keys, usearch_distance_t* found_distances, usearch_error_t* error) {

assert(index && vector && error && "Missing arguments");
USEARCH_ASSERT(index && vector && error && "Missing arguments");
search_result_t result =
search_(reinterpret_cast<index_dense_t*>(index), vector, scalar_kind_to_cpp(kind), results_limit);
if (!result) {
Expand All @@ -292,13 +340,13 @@ USEARCH_EXPORT size_t usearch_get( //
usearch_index_t index, usearch_key_t key, size_t count, //
void* vectors, usearch_scalar_kind_t kind, usearch_error_t*) {

assert(index && vectors);
USEARCH_ASSERT(index && vectors);
return get_(reinterpret_cast<index_dense_t*>(index), key, count, vectors, scalar_kind_to_cpp(kind));
}

USEARCH_EXPORT size_t usearch_remove(usearch_index_t index, usearch_key_t key, usearch_error_t* error) {

assert(index && error && "Missing arguments");
USEARCH_ASSERT(index && error && "Missing arguments");
labeling_result_t result = reinterpret_cast<index_dense_t*>(index)->remove(key);
if (!result)
*error = result.error.release();
Expand All @@ -308,7 +356,7 @@ USEARCH_EXPORT size_t usearch_remove(usearch_index_t index, usearch_key_t key, u
USEARCH_EXPORT size_t usearch_rename( //
usearch_index_t index, usearch_key_t from, usearch_key_t to, usearch_error_t* error) {

assert(index && error && "Missing arguments");
USEARCH_ASSERT(index && error && "Missing arguments");
labeling_result_t result = reinterpret_cast<index_dense_t*>(index)->rename(from, to);
if (!result)
*error = result.error.release();
Expand All @@ -334,7 +382,7 @@ USEARCH_EXPORT void usearch_exact_search( //
usearch_distance_t* distances, size_t distances_stride, //
usearch_error_t* error) {

assert(dataset && queries && keys && distances && error && "Missing arguments");
USEARCH_ASSERT(dataset && queries && keys && distances && error && "Missing arguments");

metric_punned_t metric(dimensions, metric_kind_to_cpp(metric_kind), scalar_kind_to_cpp(scalar_kind));
executor_default_t executor(threads);
Expand Down
51 changes: 51 additions & 0 deletions c/usearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,57 @@ USEARCH_EXPORT size_t usearch_connectivity(usearch_index_t index, usearch_error_
*/
USEARCH_EXPORT void usearch_reserve(usearch_index_t index, size_t capacity, usearch_error_t* error);

/**
* @brief Retrieves the expansion value used during index creation.
* @param[in] index The handle to the USearch index to be queried.
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
* @return The expansion value used during index creation.
*/
USEARCH_EXPORT size_t usearch_expansion_add(usearch_index_t index, usearch_error_t* error);

/**
* @brief Retrieves the expansion value used during search.
* @param[in] index The handle to the USearch index to be queried.
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
* @return The expansion value used during search.
*/
USEARCH_EXPORT size_t usearch_expansion_search(usearch_index_t index, usearch_error_t* error);

/**
* @brief Updates the expansion value used during index creation. Rarely used.
* @param[in] index The handle to the USearch index to be queried.
* @param[in] expansion The new expansion value.
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
*/
USEARCH_EXPORT void usearch_change_expansion_add(usearch_index_t index, size_t expansion, usearch_error_t* error);

/**
* @brief Updates the expansion value used during search. Rarely used.
* @param[in] index The handle to the USearch index to be queried.
* @param[in] expansion The new expansion value.
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
*/
USEARCH_EXPORT void usearch_change_expansion_search(usearch_index_t index, size_t expansion, usearch_error_t* error);

/**
* @brief Updates the metric kind used for distance calculation between vectors.
* @param[in] index The handle to the USearch index to be queried.
* @param[in] kind The metric kind used for distance calculation between vectors.
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
*/
USEARCH_EXPORT void usearch_change_metric_kind(usearch_index_t index, usearch_metric_kind_t kind,
usearch_error_t* error);

/**
* @brief Updates the custom metric function used for distance calculation between vectors.
* @param[in] index The handle to the USearch index to be queried.
* @param[in] metric The custom metric function used for distance calculation between vectors.
* @param[in] kind The metric kind used for distance calculation between vectors. Needed for serialization.
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
*/
USEARCH_EXPORT void usearch_change_metric(usearch_index_t index, usearch_metric_t metric, usearch_metric_kind_t kind,
usearch_error_t* error);

/**
* @brief Adds a vector with a key to the index.
* @param[inout] index The handle to the USearch index to be populated.
Expand Down

0 comments on commit c7ed1d4

Please sign in to comment.