From 836183e60acac3e58a025026f6526522ca9c4b58 Mon Sep 17 00:00:00 2001 From: Akira Naruse Date: Thu, 30 Jan 2025 19:50:15 +0900 Subject: [PATCH 1/3] Improve multi-CTA algorithm (#492) It has been reported that when the number of search results is large, for example 100, using the multi-CTA algorithm can cause a decrease in recall. This PR is intended to alleviate this low recall issue. close #208 Authors: - Akira Naruse (https://github.com/anaruse) - Tamas Bela Feher (https://github.com/tfeher) - Artem M. Chirkin (https://github.com/achirkin) - Corey J. Nolet (https://github.com/cjnolet) Approvers: - Tamas Bela Feher (https://github.com/tfeher) - tsuki (https://github.com/enp1s0) - Artem M. Chirkin (https://github.com/achirkin) URL: https://github.com/rapidsai/cuvs/pull/492 --- cpp/src/neighbors/detail/cagra/add_nodes.cuh | 62 +++- .../neighbors/detail/cagra/cagra_search.cuh | 2 +- .../neighbors/detail/cagra/device_common.hpp | 64 +++- cpp/src/neighbors/detail/cagra/factory.cuh | 9 +- cpp/src/neighbors/detail/cagra/hashmap.hpp | 87 ++++- .../detail/cagra/search_multi_cta.cuh | 24 +- .../detail/cagra/search_multi_cta_inst.cuh | 1 + .../cagra/search_multi_cta_kernel-inl.cuh | 348 +++++++++++------- .../detail/cagra/search_multi_cta_kernel.cuh | 5 +- .../detail/cagra/search_multi_kernel.cuh | 3 +- .../neighbors/detail/cagra/search_plan.cuh | 175 +++++---- .../detail/cagra/search_single_cta.cuh | 3 +- .../cagra/search_single_cta_kernel-inl.cuh | 6 +- 13 files changed, 532 insertions(+), 257 deletions(-) diff --git a/cpp/src/neighbors/detail/cagra/add_nodes.cuh b/cpp/src/neighbors/detail/cagra/add_nodes.cuh index 453928992..913094e2a 100644 --- a/cpp/src/neighbors/detail/cagra/add_nodes.cuh +++ b/cpp/src/neighbors/detail/cagra/add_nodes.cuh @@ -137,6 +137,31 @@ void add_node_core( raft::resource::get_cuda_stream(handle)); raft::resource::sync_stream(handle); + // Check search results + constexpr int max_warnings = 3; + int num_warnings = 0; + for (std::size_t vec_i = 0; vec_i < batch.size(); vec_i++) { + std::uint32_t invalid_edges = 0; + for (std::uint32_t i = 0; i < base_degree; i++) { + if (host_neighbor_indices(vec_i, i) >= old_size) { invalid_edges++; } + } + if (invalid_edges > 0) { + if (num_warnings < max_warnings) { + RAFT_LOG_WARN( + "Invalid edges found in search results " + "(vec_i:%lu, invalid_edges:%lu, degree:%lu, base_degree:%lu)", + (uint64_t)vec_i, + (uint64_t)invalid_edges, + (uint64_t)degree, + (uint64_t)base_degree); + } + num_warnings += 1; + } + } + if (num_warnings > max_warnings) { + RAFT_LOG_WARN("The number of queries that contain invalid search results: %d", num_warnings); + } + // Step 2: rank-based reordering #pragma omp parallel { @@ -147,9 +172,16 @@ void add_node_core( for (std::uint32_t i = 0; i < base_degree; i++) { std::uint32_t detourable_node_count = 0; const auto a_id = host_neighbor_indices(vec_i, i); + if (a_id >= idx.size()) { + // If the node ID is not valid, the number of detours is increased + // to a value greater than the maximum, so that the edge to that + // node is not selected as much as possible. + detourable_node_count_list[i] = std::make_pair(a_id, base_degree + 1); + continue; + } for (std::uint32_t j = 0; j < i; j++) { const auto b0_id = host_neighbor_indices(vec_i, j); - assert(b0_id < idx.size()); + if (b0_id >= idx.size()) { continue; } for (std::uint32_t k = 0; k < degree; k++) { const auto b1_id = updated_graph(b0_id, k); if (a_id == b1_id) { @@ -160,6 +192,7 @@ void add_node_core( } detourable_node_count_list[i] = std::make_pair(a_id, detourable_node_count); } + std::sort(detourable_node_count_list.begin(), detourable_node_count_list.end(), [&](const std::pair a, const std::pair b) { @@ -181,13 +214,18 @@ void add_node_core( const auto target_new_node_id = old_size + batch.offset() + vec_i; for (std::size_t i = 0; i < num_rev_edges; i++) { const auto target_node_id = updated_graph(old_size + batch.offset() + vec_i, i); - + if (target_node_id >= new_size) { + RAFT_FAIL("Invalid node ID found in updated_graph (%u)\n", target_node_id); + } IdxT replace_id = new_size; IdxT replace_id_j = 0; std::size_t replace_num_incoming_edges = 0; for (std::int32_t j = degree - 1; j >= static_cast(rev_edge_search_range); j--) { - const auto neighbor_id = updated_graph(target_node_id, j); + const auto neighbor_id = updated_graph(target_node_id, j); + if (neighbor_id >= new_size) { + RAFT_FAIL("Invalid node ID found in updated_graph (%u)\n", neighbor_id); + } const std::size_t num_incoming_edges = host_num_incoming_edges(neighbor_id); if (num_incoming_edges > replace_num_incoming_edges) { // Check duplication @@ -206,10 +244,6 @@ void add_node_core( replace_id_j = j; } } - if (replace_id >= new_size) { - std::fprintf(stderr, "Invalid rev edge index (%u)\n", replace_id); - return; - } updated_graph(target_node_id, replace_id_j) = target_new_node_id; rev_edges[i] = replace_id; } @@ -221,13 +255,15 @@ void add_node_core( const auto rank_based_list_ptr = updated_graph.data_handle() + (old_size + batch.offset() + vec_i) * degree; const auto rev_edges_return_list_ptr = rev_edges.data(); - while (num_add < degree) { + while ((num_add < degree) && + ((rank_base_i < degree) || (rev_edges_return_i < num_rev_edges))) { const auto node_list_ptr = interleave_switch == 0 ? rank_based_list_ptr : rev_edges_return_list_ptr; auto& node_list_index = interleave_switch == 0 ? rank_base_i : rev_edges_return_i; const auto max_node_list_index = interleave_switch == 0 ? degree : num_rev_edges; for (; node_list_index < max_node_list_index; node_list_index++) { const auto candidate = node_list_ptr[node_list_index]; + if (candidate >= new_size) { continue; } // Check duplication bool dup = false; for (std::uint32_t j = 0; j < num_add; j++) { @@ -244,6 +280,12 @@ void add_node_core( } interleave_switch = 1 - interleave_switch; } + if (num_add < degree) { + RAFT_FAIL("Number of edges is not enough (target_new_node_id:%lu, num_add:%lu, degree:%lu)", + (uint64_t)target_new_node_id, + (uint64_t)num_add, + (uint64_t)degree); + } for (std::uint32_t i = 0; i < degree; i++) { updated_graph(target_new_node_id, i) = temp[i]; } @@ -259,7 +301,9 @@ void add_graph_nodes( raft::host_matrix_view updated_graph_view, const cagra::extend_params& params) { - assert(input_updated_dataset_view.extent(0) >= index.size()); + if (input_updated_dataset_view.extent(0) < index.size()) { + RAFT_FAIL("Updated dataset must be not smaller than the previous index state."); + } const std::size_t initial_dataset_size = index.size(); const std::size_t new_dataset_size = input_updated_dataset_view.extent(0); diff --git a/cpp/src/neighbors/detail/cagra/cagra_search.cuh b/cpp/src/neighbors/detail/cagra/cagra_search.cuh index 5778d85a6..b4f701819 100644 --- a/cpp/src/neighbors/detail/cagra/cagra_search.cuh +++ b/cpp/src/neighbors/detail/cagra/cagra_search.cuh @@ -75,7 +75,7 @@ void search_main_core(raft::resources const& res, using CagraSampleFilterT_s = typename CagraSampleFilterT_Selector::type; std::unique_ptr> plan = factory::create( - res, params, dataset_desc, queries.extent(1), graph.extent(1), topk); + res, params, dataset_desc, queries.extent(1), graph.extent(0), graph.extent(1), topk); plan->check(topk); diff --git a/cpp/src/neighbors/detail/cagra/device_common.hpp b/cpp/src/neighbors/detail/cagra/device_common.hpp index 7ec3d4d9e..e5886582d 100644 --- a/cpp/src/neighbors/detail/cagra/device_common.hpp +++ b/cpp/src/neighbors/detail/cagra/device_common.hpp @@ -109,7 +109,9 @@ RAFT_DEVICE_INLINE_FUNCTION void compute_distance_to_random_nodes( const IndexT* __restrict__ seed_ptr, // [num_seeds] const uint32_t num_seeds, IndexT* __restrict__ visited_hash_ptr, - const uint32_t hash_bitlen, + const uint32_t visited_hash_bitlen, + IndexT* __restrict__ traversed_hash_ptr, + const uint32_t traversed_hash_bitlen, const uint32_t block_id = 0, const uint32_t num_blocks = 1) { @@ -145,19 +147,29 @@ RAFT_DEVICE_INLINE_FUNCTION void compute_distance_to_random_nodes( const unsigned lane_id = threadIdx.x & ((1u << team_size_bits) - 1u); if (valid_i && lane_id == 0) { - if (best_index_team_local != raft::upper_bound() && - hashmap::insert(visited_hash_ptr, hash_bitlen, best_index_team_local)) { - result_distances_ptr[i] = best_norm2_team_local; - result_indices_ptr[i] = best_index_team_local; - } else { - result_distances_ptr[i] = raft::upper_bound(); - result_indices_ptr[i] = raft::upper_bound(); + if (best_index_team_local != raft::upper_bound()) { + if (hashmap::insert(visited_hash_ptr, visited_hash_bitlen, best_index_team_local) == 0) { + // Deactivate this entry as insertion into visited hash table has failed. + best_norm2_team_local = raft::upper_bound(); + best_index_team_local = raft::upper_bound(); + } else if ((traversed_hash_ptr != nullptr) && + hashmap::search( + traversed_hash_ptr, traversed_hash_bitlen, best_index_team_local)) { + // Deactivate this entry as it has been already used by others. + best_norm2_team_local = raft::upper_bound(); + best_index_team_local = raft::upper_bound(); + } } + result_distances_ptr[i] = best_norm2_team_local; + result_indices_ptr[i] = best_index_team_local; } } } -template +template RAFT_DEVICE_INLINE_FUNCTION void compute_distance_to_child_nodes( IndexT* __restrict__ result_child_indices_ptr, DistanceT* __restrict__ result_child_distances_ptr, @@ -168,13 +180,17 @@ RAFT_DEVICE_INLINE_FUNCTION void compute_distance_to_child_nodes( const uint32_t knn_k, // hashmap IndexT* __restrict__ visited_hashmap_ptr, - const uint32_t hash_bitlen, + const uint32_t visited_hash_bitlen, + IndexT* __restrict__ traversed_hashmap_ptr, + const uint32_t traversed_hash_bitlen, const IndexT* __restrict__ parent_indices, const IndexT* __restrict__ internal_topk_list, - const uint32_t search_width) + const uint32_t search_width, + int* __restrict__ result_position = nullptr, + const int max_result_position = 0) { constexpr IndexT index_msb_1_mask = utils::gen_index_msb_1_mask::value; - constexpr IndexT invalid_index = raft::upper_bound(); + constexpr IndexT invalid_index = ~static_cast(0); // Read child indices of parents from knn graph and check if the distance // computaiton is necessary. @@ -186,11 +202,22 @@ RAFT_DEVICE_INLINE_FUNCTION void compute_distance_to_child_nodes( child_id = knn_graph[(i % knn_k) + (static_cast(knn_k) * parent_id)]; } if (child_id != invalid_index) { - if (hashmap::insert(visited_hashmap_ptr, hash_bitlen, child_id) == 0) { + if (hashmap::insert(visited_hashmap_ptr, visited_hash_bitlen, child_id) == 0) { + // Deactivate this entry as insertion into visited hash table has failed. + child_id = invalid_index; + } else if ((traversed_hashmap_ptr != nullptr) && + hashmap::search( + traversed_hashmap_ptr, traversed_hash_bitlen, child_id)) { + // Deactivate this entry as this has been already used by others. child_id = invalid_index; } } - result_child_indices_ptr[i] = child_id; + if (STATIC_RESULT_POSITION) { + result_child_indices_ptr[i] = child_id; + } else if (child_id != invalid_index) { + int j = atomicSub(result_position, 1) - 1; + result_child_indices_ptr[j] = child_id; + } } __syncthreads(); @@ -201,9 +228,11 @@ RAFT_DEVICE_INLINE_FUNCTION void compute_distance_to_child_nodes( const auto compute_distance = dataset_desc.compute_distance_impl; const auto args = dataset_desc.args.load(); const bool lead_lane = (threadIdx.x & ((1u << team_size_bits) - 1u)) == 0; + const uint32_t ofst = STATIC_RESULT_POSITION ? 0 : result_position[0]; for (uint32_t i = threadIdx.x >> team_size_bits; i < max_i; i += blockDim.x >> team_size_bits) { - const bool valid_i = i < num_k; - const auto child_id = valid_i ? result_child_indices_ptr[i] : invalid_index; + const auto j = i + ofst; + const bool valid_i = STATIC_RESULT_POSITION ? (j < num_k) : (j < max_result_position); + const auto child_id = valid_i ? result_child_indices_ptr[j] : invalid_index; // We should be calling `dataset_desc.compute_distance(..)` here as follows: // > const auto child_dist = dataset_desc.compute_distance(child_id, child_id != invalid_index); @@ -213,9 +242,10 @@ RAFT_DEVICE_INLINE_FUNCTION void compute_distance_to_child_nodes( (child_id != invalid_index) ? compute_distance(args, child_id) : (lead_lane ? raft::upper_bound() : 0), team_size_bits); + __syncwarp(); // Store the distance - if (valid_i && lead_lane) { result_child_distances_ptr[i] = child_dist; } + if (valid_i && lead_lane) { result_child_distances_ptr[j] = child_dist; } } } diff --git a/cpp/src/neighbors/detail/cagra/factory.cuh b/cpp/src/neighbors/detail/cagra/factory.cuh index e6e7ff64f..d2ae5c55b 100644 --- a/cpp/src/neighbors/detail/cagra/factory.cuh +++ b/cpp/src/neighbors/detail/cagra/factory.cuh @@ -40,10 +40,11 @@ class factory { search_params const& params, const dataset_descriptor_host& dataset_desc, int64_t dim, + int64_t dataset_size, int64_t graph_degree, uint32_t topk) { - search_plan_impl_base plan(params, dim, graph_degree, topk); + search_plan_impl_base plan(params, dim, dataset_size, graph_degree, topk); return dispatch_kernel(res, plan, dataset_desc); } @@ -56,15 +57,15 @@ class factory { if (plan.algo == search_algo::SINGLE_CTA) { return std::make_unique< single_cta_search::search>( - res, plan, dataset_desc, plan.dim, plan.graph_degree, plan.topk); + res, plan, dataset_desc, plan.dim, plan.dataset_size, plan.graph_degree, plan.topk); } else if (plan.algo == search_algo::MULTI_CTA) { return std::make_unique< multi_cta_search::search>( - res, plan, dataset_desc, plan.dim, plan.graph_degree, plan.topk); + res, plan, dataset_desc, plan.dim, plan.dataset_size, plan.graph_degree, plan.topk); } else { return std::make_unique< multi_kernel_search::search>( - res, plan, dataset_desc, plan.dim, plan.graph_degree, plan.topk); + res, plan, dataset_desc, plan.dim, plan.dataset_size, plan.graph_degree, plan.topk); } } }; diff --git a/cpp/src/neighbors/detail/cagra/hashmap.hpp b/cpp/src/neighbors/detail/cagra/hashmap.hpp index 2c62dda90..652e1db22 100644 --- a/cpp/src/neighbors/detail/cagra/hashmap.hpp +++ b/cpp/src/neighbors/detail/cagra/hashmap.hpp @@ -23,6 +23,8 @@ #include +#define HASHMAP_LINEAR_PROBING + // #pragma GCC diagnostic push // #pragma GCC diagnostic ignored // #pragma GCC diagnostic pop @@ -38,11 +40,11 @@ RAFT_DEVICE_INLINE_FUNCTION void init(IdxT* const table, { if (threadIdx.x < FIRST_TID) return; for (unsigned i = threadIdx.x - FIRST_TID; i < get_size(bitlen); i += blockDim.x - FIRST_TID) { - table[i] = utils::get_max_value(); + table[i] = ~static_cast(0); } } -template +template RAFT_DEVICE_INLINE_FUNCTION uint32_t insert(IdxT* const table, const uint32_t bitlen, const IdxT key) @@ -50,7 +52,7 @@ RAFT_DEVICE_INLINE_FUNCTION uint32_t insert(IdxT* const table, // Open addressing is used for collision resolution const uint32_t size = get_size(bitlen); const uint32_t bit_mask = size - 1; -#if 1 +#ifdef HASHMAP_LINEAR_PROBING // Linear probing IdxT index = (key ^ (key >> bitlen)) & bit_mask; constexpr uint32_t stride = 1; @@ -59,32 +61,89 @@ RAFT_DEVICE_INLINE_FUNCTION uint32_t insert(IdxT* const table, uint32_t index = key & bit_mask; const uint32_t stride = (key >> bitlen) * 2 + 1; #endif + constexpr IdxT hashval_empty = ~static_cast(0); + const IdxT removed_key = key | utils::gen_index_msb_1_mask::value; for (unsigned i = 0; i < size; i++) { - const IdxT old = atomicCAS(&table[index], ~static_cast(0), key); - if (old == ~static_cast(0)) { + const IdxT old = atomicCAS(&table[index], hashval_empty, key); + if (old == hashval_empty) { return 1; } else if (old == key) { return 0; + } else if (SUPPORT_REMOVE) { + // Checks if this key has been removed before. + const uint32_t old = atomicCAS(&table[index], removed_key, key); + if (old == removed_key) { + return 1; + } else if (old == key) { + return 0; + } } index = (index + stride) & bit_mask; } return 0; } -template -RAFT_DEVICE_INLINE_FUNCTION uint32_t insert(IdxT* const table, - const uint32_t bitlen, - const IdxT key) +template +RAFT_DEVICE_INLINE_FUNCTION uint32_t search(IdxT* table, const uint32_t bitlen, const IdxT key) { - IdxT ret = 0; - if (threadIdx.x % TEAM_SIZE == 0) { ret = insert(table, bitlen, key); } - for (unsigned offset = 1; offset < TEAM_SIZE; offset *= 2) { - ret |= __shfl_xor_sync(0xffffffff, ret, offset); + const uint32_t size = get_size(bitlen); + const uint32_t bit_mask = size - 1; +#ifdef HASHMAP_LINEAR_PROBING + // Linear probing + IdxT index = (key ^ (key >> bitlen)) & bit_mask; + constexpr uint32_t stride = 1; +#else + // Double hashing + IdxT index = key & bit_mask; + const uint32_t stride = (key >> bitlen) * 2 + 1; +#endif + constexpr IdxT hashval_empty = ~static_cast(0); + const IdxT removed_key = key | utils::gen_index_msb_1_mask::value; + for (unsigned i = 0; i < size; i++) { + const IdxT val = table[index]; + if (val == key) { + return 1; + } else if (val == hashval_empty) { + return 0; + } else if (SUPPORT_REMOVE) { + // Check if this key has been removed. + if (val == removed_key) { return 0; } + } + index = (index + stride) & bit_mask; } - return ret; + return 0; } template +RAFT_DEVICE_INLINE_FUNCTION uint32_t remove(IdxT* table, const uint32_t bitlen, const IdxT key) +{ + const uint32_t size = get_size(bitlen); + const uint32_t bit_mask = size - 1; +#ifdef HASHMAP_LINEAR_PROBING + // Linear probing + IdxT index = (key ^ (key >> bitlen)) & bit_mask; + constexpr uint32_t stride = 1; +#else + // Double hashing + IdxT index = key & bit_mask; + const uint32_t stride = (key >> bitlen) * 2 + 1; +#endif + constexpr IdxT hashval_empty = ~static_cast(0); + const IdxT removed_key = key | utils::gen_index_msb_1_mask::value; + for (unsigned i = 0; i < size; i++) { + // To remove a key, set the MSB to 1. + const uint32_t old = atomicCAS(&table[index], key, removed_key); + if (old == key) { + return 1; + } else if (old == hashval_empty) { + return 0; + } + index = (index + stride) & bit_mask; + } + return 0; +} + +template RAFT_DEVICE_INLINE_FUNCTION uint32_t insert(unsigned team_size, IdxT* const table, const uint32_t bitlen, const IdxT key) { diff --git a/cpp/src/neighbors/detail/cagra/search_multi_cta.cuh b/cpp/src/neighbors/detail/cagra/search_multi_cta.cuh index 9cb432bcb..2f1c0332a 100644 --- a/cpp/src/neighbors/detail/cagra/search_multi_cta.cuh +++ b/cpp/src/neighbors/detail/cagra/search_multi_cta.cuh @@ -102,33 +102,36 @@ struct search : public search_plan_impl& dataset_desc, int64_t dim, + int64_t dataset_size, int64_t graph_degree, uint32_t topk) - : base_type(res, params, dataset_desc, dim, graph_degree, topk), + : base_type(res, params, dataset_desc, dim, dataset_size, graph_degree, topk), intermediate_indices(res), intermediate_distances(res), topk_workspace(res) - { set_params(res, params); } void set_params(raft::resources const& res, const search_params& params) { - constexpr unsigned muti_cta_itopk_size = 32; - this->itopk_size = muti_cta_itopk_size; - search_width = 1; + constexpr unsigned multi_cta_itopk_size = 32; + this->itopk_size = multi_cta_itopk_size; + search_width = 1; num_cta_per_query = - max(params.search_width, raft::ceildiv(params.itopk_size, (size_t)muti_cta_itopk_size)); - result_buffer_size = itopk_size + search_width * graph_degree; + max(params.search_width, raft::ceildiv(params.itopk_size, (size_t)multi_cta_itopk_size)); + result_buffer_size = itopk_size + (search_width * graph_degree); typedef raft::Pow2<32> AlignBytes; unsigned result_buffer_size_32 = AlignBytes::roundUp(result_buffer_size); // constexpr unsigned max_result_buffer_size = 256; RAFT_EXPECTS(result_buffer_size_32 <= 256, "Result buffer size cannot exceed 256"); - smem_size = dataset_desc.smem_ws_size_in_bytes + - (sizeof(INDEX_T) + sizeof(DISTANCE_T)) * result_buffer_size_32 + - sizeof(uint32_t) * search_width + sizeof(uint32_t); + smem_size = + dataset_desc.smem_ws_size_in_bytes + + (sizeof(INDEX_T) + sizeof(DISTANCE_T)) * (result_buffer_size_32) + + sizeof(INDEX_T) * hashmap::get_size(small_hash_bitlen) + // local_visited_hashmap_ptr + sizeof(INDEX_T) * search_width + // parent_indices_buffer + sizeof(int); // result_position RAFT_LOG_DEBUG("# smem_size: %u", smem_size); // @@ -222,6 +225,7 @@ struct search : public search_plan_impl -RAFT_DEVICE_INLINE_FUNCTION void pickup_next_parents( - INDEX_T* const next_parent_indices, // [search_width] - const uint32_t search_width, - INDEX_T* const itopk_indices, // [num_itopk] - const size_t num_itopk, - uint32_t* const terminate_flag) +template +RAFT_DEVICE_INLINE_FUNCTION void pickup_next_parent( + INDEX_T* const next_parent_indices, + INDEX_T* const itopk_indices, // [itopk_size * 2] + DISTANCE_T* const itopk_distances, // [itopk_size * 2] + INDEX_T* const hash_ptr, + const uint32_t hash_bitlen) { + constexpr uint32_t itopk_size = 32; constexpr INDEX_T index_msb_1_mask = utils::gen_index_msb_1_mask::value; - const unsigned warp_id = threadIdx.x / 32; + constexpr INDEX_T invalid_index = ~static_cast(0); + + const unsigned warp_id = threadIdx.x / 32; if (warp_id > 0) { return; } - const unsigned lane_id = threadIdx.x % 32; - for (uint32_t i = lane_id; i < search_width; i += 32) { - next_parent_indices[i] = utils::get_max_value(); - } - uint32_t max_itopk = num_itopk; - if (max_itopk % 32) { max_itopk += 32 - (max_itopk % 32); } - uint32_t num_new_parents = 0; - for (uint32_t j = lane_id; j < max_itopk; j += 32) { - INDEX_T index; - int new_parent = 0; - if (j < num_itopk) { - index = itopk_indices[j]; - if ((index & index_msb_1_mask) == 0) { // check if most significant bit is set - new_parent = 1; - } + if (threadIdx.x == 0) { next_parent_indices[0] = invalid_index; } + __syncwarp(); + + int j = -1; + for (unsigned i = threadIdx.x; i < itopk_size * 2; i += 32) { + INDEX_T index = itopk_indices[i]; + int is_invalid = 0; + int is_candidate = 0; + if (index == invalid_index) { + is_invalid = 1; + } else if (index & index_msb_1_mask) { + } else { + is_candidate = 1; } - const uint32_t ballot_mask = __ballot_sync(0xffffffff, new_parent); - if (new_parent) { - const auto i = __popc(ballot_mask & ((1 << lane_id) - 1)) + num_new_parents; - if (i < search_width) { - next_parent_indices[i] = j; - itopk_indices[j] |= index_msb_1_mask; // set most significant bit as used node + + const auto ballot_mask = __ballot_sync(0xffffffff, is_candidate); + const auto candidate_id = __popc(ballot_mask & ((1 << threadIdx.x) - 1)); + for (int k = 0; k < __popc(ballot_mask); k++) { + int flag_done = 0; + if (is_candidate && candidate_id == k) { + is_candidate = 0; + if (hashmap::insert(hash_ptr, hash_bitlen, index)) { + // Use this candidate as next parent + index |= index_msb_1_mask; // set most significant bit as used node + if (i < itopk_size) { + next_parent_indices[0] = i; + itopk_indices[i] = index; + } else { + next_parent_indices[0] = j; + // Move the next parent node from i-th position to j-th position + itopk_indices[j] = index; + itopk_distances[j] = itopk_distances[i]; + itopk_indices[i] = invalid_index; + itopk_distances[i] = utils::get_max_value(); + } + flag_done = 1; + } else { + // Deactivate the node since it has been used by other CTA. + itopk_indices[i] = invalid_index; + itopk_distances[i] = utils::get_max_value(); + is_invalid = 1; + } } + if (__any_sync(0xffffffff, (flag_done > 0))) { return; } + } + if (i < itopk_size) { + j = 31 - __clz(__ballot_sync(0xffffffff, is_invalid)); + if (j < 0) { return; } } - num_new_parents += __popc(ballot_mask); - if (num_new_parents >= search_width) { break; } } - if (threadIdx.x == 0 && (num_new_parents == 0)) { *terminate_flag = 1; } } template -RAFT_DEVICE_INLINE_FUNCTION void topk_by_bitonic_sort( - float* distances, // [num_elements] - INDEX_T* indices, // [num_elements] - const uint32_t num_elements, - const uint32_t num_itopk // num_itopk <= num_elements -) +RAFT_DEVICE_INLINE_FUNCTION void topk_by_bitonic_sort(float* distances, // [num_elements] + INDEX_T* indices, // [num_elements] + const uint32_t num_elements) { const unsigned warp_id = threadIdx.x / 32; if (warp_id > 0) { return; } @@ -116,15 +138,15 @@ RAFT_DEVICE_INLINE_FUNCTION void topk_by_bitonic_sort( val[i] = indices[j]; } else { key[i] = utils::get_max_value(); - val[i] = utils::get_max_value(); + val[i] = ~static_cast(0); } } /* Warp Sort */ bitonic::warp_sort(key, val); - /* Store itopk sorted results */ + /* Store sorted results */ for (unsigned i = 0; i < N; i++) { unsigned j = (N * lane_id) + i; - if (j < num_itopk) { + if (j < num_elements) { distances[j] = key[i]; indices[j] = val[i]; } @@ -148,11 +170,11 @@ RAFT_KERNEL __launch_bounds__(1024, 1) search_kernel( const uint64_t rand_xor_mask, const typename DATASET_DESCRIPTOR_T::INDEX_T* seed_ptr, // [num_queries, num_seeds] const uint32_t num_seeds, + const uint32_t visited_hash_bitlen, typename DATASET_DESCRIPTOR_T::INDEX_T* const - visited_hashmap_ptr, // [num_queries, 1 << hash_bitlen] - const uint32_t hash_bitlen, + traversed_hashmap_ptr, // [num_queries, 1 << traversed_hash_bitlen] + const uint32_t traversed_hash_bitlen, const uint32_t itopk_size, - const uint32_t search_width, const uint32_t min_iteration, const uint32_t max_iteration, uint32_t* const num_executed_iterations, /* stats */ @@ -185,12 +207,12 @@ RAFT_KERNEL __launch_bounds__(1024, 1) search_kernel( extern __shared__ uint8_t smem[]; // Layout of result_buffer - // +----------------+------------------------------+---------+ - // | internal_top_k | neighbors of parent nodes | padding | - // | | | upto 32 | - // +----------------+------------------------------+---------+ - // |<--- result_buffer_size --->| - const auto result_buffer_size = itopk_size + (search_width * graph_degree); + // +----------------+---------+---------------------------+ + // | internal_top_k | padding | neighbors of parent nodes | + // | | upto 32 | | + // +----------------+---------+---------------------------+ + // |<--- result_buffer_size_32 --->| + const auto result_buffer_size = itopk_size + graph_degree; const auto result_buffer_size_32 = raft::round_up_safe(result_buffer_size, 32); assert(result_buffer_size_32 <= MAX_ELEMENTS); @@ -201,22 +223,23 @@ RAFT_KERNEL __launch_bounds__(1024, 1) search_kernel( reinterpret_cast(smem + dataset_desc->smem_ws_size_in_bytes()); auto* __restrict__ result_distances_buffer = reinterpret_cast(result_indices_buffer + result_buffer_size_32); - auto* __restrict__ parent_indices_buffer = + auto* __restrict__ local_visited_hashmap_ptr = reinterpret_cast(result_distances_buffer + result_buffer_size_32); - auto* __restrict__ terminate_flag = - reinterpret_cast(parent_indices_buffer + search_width); + auto* __restrict__ parent_indices_buffer = + reinterpret_cast(local_visited_hashmap_ptr + hashmap::get_size(visited_hash_bitlen)); + auto* __restrict__ result_position = reinterpret_cast(parent_indices_buffer + 1); -#if 0 - /* debug */ - for (unsigned i = threadIdx.x; i < result_buffer_size_32; i += blockDim.x) { - result_indices_buffer[i] = utils::get_max_value(); - result_distances_buffer[i] = utils::get_max_value(); - } -#endif + INDEX_T* const local_traversed_hashmap_ptr = + traversed_hashmap_ptr + (hashmap::get_size(traversed_hash_bitlen) * query_id); - if (threadIdx.x == 0) { terminate_flag[0] = 0; } - INDEX_T* const local_visited_hashmap_ptr = - visited_hashmap_ptr + (hashmap::get_size(hash_bitlen) * query_id); + constexpr INDEX_T invalid_index = ~static_cast(0); + constexpr INDEX_T index_msb_1_mask = utils::gen_index_msb_1_mask::value; + + for (unsigned i = threadIdx.x; i < result_buffer_size_32; i += blockDim.x) { + result_indices_buffer[i] = invalid_index; + result_distances_buffer[i] = utils::get_max_value(); + } + hashmap::init(local_visited_hashmap_ptr, visited_hash_bitlen); __syncthreads(); _CLK_REC(clk_init); @@ -229,13 +252,15 @@ RAFT_KERNEL __launch_bounds__(1024, 1) search_kernel( device::compute_distance_to_random_nodes(result_indices_buffer, result_distances_buffer, *dataset_desc, - result_buffer_size, + graph_degree, num_distilation, rand_xor_mask, local_seed_ptr, num_seeds, local_visited_hashmap_ptr, - hash_bitlen, + visited_hash_bitlen, + local_traversed_hashmap_ptr, + traversed_hash_bitlen, block_id, num_blocks); __syncthreads(); @@ -243,50 +268,90 @@ RAFT_KERNEL __launch_bounds__(1024, 1) search_kernel( uint32_t iter = 0; while (1) { - // topk with bitonic sort _CLK_START(); - topk_by_bitonic_sort(result_distances_buffer, - result_indices_buffer, - itopk_size + (search_width * graph_degree), - itopk_size); + if (threadIdx.x < 32) { + // [1st warp] Topk with bitonic sort + topk_by_bitonic_sort( + result_distances_buffer, result_indices_buffer, result_buffer_size_32); + } + __syncthreads(); _CLK_REC(clk_topk); - if (iter + 1 == max_iteration) { - __syncthreads(); - break; - } + if (iter + 1 >= max_iteration) { break; } - // pick up next parents _CLK_START(); - pickup_next_parents( - parent_indices_buffer, search_width, result_indices_buffer, itopk_size, terminate_flag); + if (threadIdx.x < 32) { + // [1st warp] Pick up a next parent + pickup_next_parent(parent_indices_buffer, + result_indices_buffer, + result_distances_buffer, + local_traversed_hashmap_ptr, + traversed_hash_bitlen); + } else { + // [Other warps] Reset visited hashmap + hashmap::init(local_visited_hashmap_ptr, visited_hash_bitlen, 32); + } + __syncthreads(); _CLK_REC(clk_pickup_parents); - __syncthreads(); - if (*terminate_flag && iter >= min_iteration) { break; } + if ((parent_indices_buffer[0] == invalid_index) && (iter >= min_iteration)) { break; } - // compute the norms between child nodes and query node _CLK_START(); - device::compute_distance_to_child_nodes(result_indices_buffer + itopk_size, - result_distances_buffer + itopk_size, - *dataset_desc, - knn_graph, - graph_degree, - local_visited_hashmap_ptr, - hash_bitlen, - parent_indices_buffer, - result_indices_buffer, - search_width); - _CLK_REC(clk_compute_distance); + for (unsigned i = threadIdx.x; i < result_buffer_size_32; i += blockDim.x) { + INDEX_T index = result_indices_buffer[i]; + if (index == invalid_index) { continue; } + if ((i >= itopk_size) && (index & index_msb_1_mask)) { + // Remove nodes kicked out of the itopk list from the traversed hash table. + hashmap::remove( + local_traversed_hashmap_ptr, traversed_hash_bitlen, index & ~index_msb_1_mask); + result_indices_buffer[i] = invalid_index; + result_distances_buffer[i] = utils::get_max_value(); + } else { + // Restore visited hashmap by putting nodes on result buffer in it. + index &= ~index_msb_1_mask; + hashmap::insert(local_visited_hashmap_ptr, visited_hash_bitlen, index); + } + } + // Initialize buffer for compute_distance_to_child_nodes. + if (threadIdx.x == blockDim.x - 1) { result_position[0] = result_buffer_size_32; } + __syncthreads(); + + // Compute the norms between child nodes and query node + device::compute_distance_to_child_nodes( + result_indices_buffer, + result_distances_buffer, + *dataset_desc, + knn_graph, + graph_degree, + local_visited_hashmap_ptr, + visited_hash_bitlen, + local_traversed_hashmap_ptr, + traversed_hash_bitlen, + parent_indices_buffer, + result_indices_buffer, + 1, + result_position, + result_buffer_size_32); + // __syncthreads(); + + // Check the state of the nodes in the result buffer which were not updated + // by the compute_distance_to_child_nodes above, and if it cannot be used as + // a parent node, it is deactivated. + for (uint32_t i = threadIdx.x; i < result_position[0]; i += blockDim.x) { + INDEX_T index = result_indices_buffer[i]; + if (index == invalid_index || index & index_msb_1_mask) { continue; } + if (hashmap::search(local_traversed_hashmap_ptr, traversed_hash_bitlen, index)) { + result_indices_buffer[i] = invalid_index; + result_distances_buffer[i] = utils::get_max_value(); + } + } __syncthreads(); + _CLK_REC(clk_compute_distance); // Filtering if constexpr (!std::is_same::value) { - constexpr INDEX_T index_msb_1_mask = utils::gen_index_msb_1_mask::value; - const INDEX_T invalid_index = utils::get_max_value(); - - for (unsigned p = threadIdx.x; p < search_width; p += blockDim.x) { + for (unsigned p = threadIdx.x; p < 1; p += blockDim.x) { if (parent_indices_buffer[p] != invalid_index) { const auto parent_id = result_indices_buffer[parent_indices_buffer[p]] & ~index_msb_1_mask; @@ -303,36 +368,64 @@ RAFT_KERNEL __launch_bounds__(1024, 1) search_kernel( iter++; } - // Post process for filtering + // Filtering if constexpr (!std::is_same::value) { - constexpr INDEX_T index_msb_1_mask = utils::gen_index_msb_1_mask::value; - const INDEX_T invalid_index = utils::get_max_value(); - - for (unsigned i = threadIdx.x; i < itopk_size + search_width * graph_degree; i += blockDim.x) { - const auto node_id = result_indices_buffer[i] & ~index_msb_1_mask; - if (node_id != (invalid_index & ~index_msb_1_mask) && !sample_filter(query_id, node_id)) { - // If the parent must not be in the resulting top-k list, remove from the parent list - result_distances_buffer[i] = utils::get_max_value(); + for (uint32_t i = threadIdx.x; i < result_buffer_size_32; i += blockDim.x) { + INDEX_T index = result_indices_buffer[i]; + if (index == invalid_index) { continue; } + index &= ~index_msb_1_mask; + if (!sample_filter(query_id, index)) { result_indices_buffer[i] = invalid_index; + result_distances_buffer[i] = utils::get_max_value(); } } - - __syncthreads(); - topk_by_bitonic_sort(result_distances_buffer, - result_indices_buffer, - itopk_size + (search_width * graph_degree), - itopk_size); __syncthreads(); } - for (uint32_t i = threadIdx.x; i < itopk_size; i += blockDim.x) { - uint32_t j = i + (itopk_size * (cta_id + (num_cta_per_query * query_id))); - if (result_distances_ptr != nullptr) { result_distances_ptr[j] = result_distances_buffer[i]; } - constexpr INDEX_T index_msb_1_mask = utils::gen_index_msb_1_mask::value; - - result_indices_ptr[j] = - result_indices_buffer[i] & ~index_msb_1_mask; // clear most significant bit + // Output search results (1st warp only). + if (threadIdx.x < 32) { + uint32_t offset = 0; + for (uint32_t i = threadIdx.x; i < result_buffer_size_32; i += 32) { + INDEX_T index = result_indices_buffer[i]; + bool is_valid = false; + if (index != invalid_index) { + if (index & index_msb_1_mask) { + is_valid = true; + index &= ~index_msb_1_mask; + } else if ((offset < itopk_size) && + hashmap::insert( + local_traversed_hashmap_ptr, traversed_hash_bitlen, index)) { + // If a node that is not used as a parent can be inserted into + // the traversed hash table, it is considered a valid result. + is_valid = true; + } + } + const auto mask = __ballot_sync(0xffffffff, is_valid); + if (is_valid) { + const auto j = offset + __popc(mask & ((1 << threadIdx.x) - 1)); + if (j < itopk_size) { + uint32_t k = j + (itopk_size * (cta_id + (num_cta_per_query * query_id))); + result_indices_ptr[k] = index & ~index_msb_1_mask; + if (result_distances_ptr != nullptr) { + result_distances_ptr[k] = result_distances_buffer[i]; + } + } else { + // If it is valid and registered in the traversed hash table but is + // not output as a result, it is removed from the hash table. + hashmap::remove(local_traversed_hashmap_ptr, traversed_hash_bitlen, index); + } + } + offset += __popc(mask); + } + // If the number of outputs is insufficient, fill in with invalid results. + for (uint32_t i = offset + threadIdx.x; i < itopk_size; i += 32) { + uint32_t k = i + (itopk_size * (cta_id + (num_cta_per_query * query_id))); + result_indices_ptr[k] = invalid_index; + if (result_distances_ptr != nullptr) { + result_distances_ptr[k] = utils::get_max_value(); + } + } } if (threadIdx.x == 0 && cta_id == 0 && num_executed_iterations != nullptr) { @@ -427,8 +520,9 @@ void select_and_run(const dataset_descriptor_host& dat uint32_t block_size, // uint32_t result_buffer_size, uint32_t smem_size, - int64_t hash_bitlen, - IndexT* hashmap_ptr, + uint32_t visited_hash_bitlen, + int64_t traversed_hash_bitlen, + IndexT* traversed_hashmap_ptr, uint32_t num_cta_per_query, uint32_t num_seeds, SampleFilterT sample_filter, @@ -441,9 +535,13 @@ void select_and_run(const dataset_descriptor_host& dat RAFT_CUDA_TRY( cudaFuncSetAttribute(kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, smem_size)); // Initialize hash table - const uint32_t hash_size = hashmap::get_size(hash_bitlen); - set_value_batch( - hashmap_ptr, hash_size, utils::get_max_value(), hash_size, num_queries, stream); + const uint32_t traversed_hash_size = hashmap::get_size(traversed_hash_bitlen); + set_value_batch(traversed_hashmap_ptr, + traversed_hash_size, + ~static_cast(0), + traversed_hash_size, + num_queries, + stream); dim3 block_dims(block_size, 1, 1); dim3 grid_dims(num_cta_per_query, num_queries, 1); @@ -463,10 +561,10 @@ void select_and_run(const dataset_descriptor_host& dat ps.rand_xor_mask, dev_seed_ptr, num_seeds, - hashmap_ptr, - hash_bitlen, + visited_hash_bitlen, + traversed_hashmap_ptr, + traversed_hash_bitlen, ps.itopk_size, - ps.search_width, ps.min_iterations, ps.max_iterations, num_executed_iterations, diff --git a/cpp/src/neighbors/detail/cagra/search_multi_cta_kernel.cuh b/cpp/src/neighbors/detail/cagra/search_multi_cta_kernel.cuh index 1a1dcd579..e5dc29f27 100644 --- a/cpp/src/neighbors/detail/cagra/search_multi_cta_kernel.cuh +++ b/cpp/src/neighbors/detail/cagra/search_multi_cta_kernel.cuh @@ -36,8 +36,9 @@ void select_and_run(const dataset_descriptor_host& dat uint32_t block_size, // uint32_t result_buffer_size, uint32_t smem_size, - int64_t hash_bitlen, - IndexT* hashmap_ptr, + uint32_t visited_hash_bitlen, + int64_t traversed_hash_bitlen, + IndexT* traversed_hashmap_ptr, uint32_t num_cta_per_query, uint32_t num_seeds, SampleFilterT sample_filter, diff --git a/cpp/src/neighbors/detail/cagra/search_multi_kernel.cuh b/cpp/src/neighbors/detail/cagra/search_multi_kernel.cuh index 469c80a08..cb3e819c9 100644 --- a/cpp/src/neighbors/detail/cagra/search_multi_kernel.cuh +++ b/cpp/src/neighbors/detail/cagra/search_multi_kernel.cuh @@ -635,9 +635,10 @@ struct search : search_plan_impl { search_params params, const dataset_descriptor_host& dataset_desc, int64_t dim, + int64_t dataset_size, int64_t graph_degree, uint32_t topk) - : base_type(res, params, dataset_desc, dim, graph_degree, topk), + : base_type(res, params, dataset_desc, dim, dataset_size, graph_degree, topk), result_indices(res), result_distances(res), parent_node_list(res), diff --git a/cpp/src/neighbors/detail/cagra/search_plan.cuh b/cpp/src/neighbors/detail/cagra/search_plan.cuh index 99254aa50..5fe5b0903 100644 --- a/cpp/src/neighbors/detail/cagra/search_plan.cuh +++ b/cpp/src/neighbors/detail/cagra/search_plan.cuh @@ -108,11 +108,17 @@ struct lightweight_uvector { }; struct search_plan_impl_base : public search_params { + int64_t dataset_size; int64_t dim; int64_t graph_degree; uint32_t topk; - search_plan_impl_base(search_params params, int64_t dim, int64_t graph_degree, uint32_t topk) - : search_params(params), dim(dim), graph_degree(graph_degree), topk(topk) + search_plan_impl_base( + search_params params, int64_t dim, int64_t dataset_size, int64_t graph_degree, uint32_t topk) + : search_params(params), + dim(dim), + dataset_size(dataset_size), + graph_degree(graph_degree), + topk(topk) { if (algo == search_algo::AUTO) { const size_t num_sm = raft::getMultiProcessorCount(); @@ -141,7 +147,6 @@ struct search_plan_impl : public search_plan_impl_base { size_t small_hash_bitlen; size_t small_hash_reset_interval; size_t hashmap_size; - uint32_t dataset_size; uint32_t result_buffer_size; uint32_t smem_size; @@ -157,9 +162,10 @@ struct search_plan_impl : public search_plan_impl_base { search_params params, const dataset_descriptor_host& dataset_desc, int64_t dim, + int64_t dataset_size, int64_t graph_degree, uint32_t topk) - : search_plan_impl_base(params, dim, graph_degree, topk), + : search_plan_impl_base(params, dim, dataset_size, graph_degree, topk), hashmap(res), num_executed_iterations(res), dev_seed(res), @@ -193,10 +199,16 @@ struct search_plan_impl : public search_plan_impl_base { uint32_t _max_iterations = max_iterations; if (max_iterations == 0) { if (algo == search_algo::MULTI_CTA) { - _max_iterations = 1 + std::min(32 * 1.1, 32 + 10.0); // TODO(anaruse) + constexpr uint32_t mc_itopk_size = 32; + constexpr uint32_t mc_search_width = 1; + _max_iterations = mc_itopk_size / mc_search_width; } else { - _max_iterations = - 1 + std::min((itopk_size / search_width) * 1.1, (itopk_size / search_width) + 10.0); + _max_iterations = itopk_size / search_width; + } + int64_t num_reachable_nodes = 1; + while (num_reachable_nodes < dataset_size) { + num_reachable_nodes *= max((int64_t)2, graph_degree / 2); + _max_iterations += 1; } } if (max_iterations < min_iterations) { _max_iterations = min_iterations; } @@ -219,88 +231,107 @@ struct search_plan_impl : public search_plan_impl_base { // defines hash_bitlen, small_hash_bitlen, small_hash_reset interval, hash_size inline void calc_hashmap_params(raft::resources const& res) { - // for multiple CTA search - uint32_t mc_num_cta_per_query = 0; - uint32_t mc_search_width = 0; - uint32_t mc_itopk_size = 0; - if (algo == search_algo::MULTI_CTA) { - mc_itopk_size = 32; - mc_search_width = 1; - mc_num_cta_per_query = max(search_width, raft::ceildiv(itopk_size, (size_t)32)); - RAFT_LOG_DEBUG("# mc_itopk_size: %u", mc_itopk_size); - RAFT_LOG_DEBUG("# mc_search_width: %u", mc_search_width); - RAFT_LOG_DEBUG("# mc_num_cta_per_query: %u", mc_num_cta_per_query); - } - // Determine hash size (bit length) hashmap_size = 0; hash_bitlen = 0; small_hash_bitlen = 0; small_hash_reset_interval = 1024 * 1024; float max_fill_rate = hashmap_max_fill_rate; - while (hashmap_mode == hash_mode::AUTO || hashmap_mode == hash_mode::SMALL) { - // - // The small-hash reduces hash table size by initializing the hash table - // for each iteration and re-registering only the nodes that should not be - // re-visited in that iteration. Therefore, the size of small-hash should - // be determined based on the internal topk size and the number of nodes - // visited per iteration. - // - const auto max_visited_nodes = itopk_size + (search_width * graph_degree * 1); - unsigned min_bitlen = 8; // 256 - unsigned max_bitlen = 13; // 8K - if (min_bitlen < hashmap_min_bitlen) { min_bitlen = hashmap_min_bitlen; } - hash_bitlen = min_bitlen; - while (max_visited_nodes > hashmap::get_size(hash_bitlen) * max_fill_rate) { - hash_bitlen += 1; - } - if (hash_bitlen > max_bitlen) { - // Switch to normal hash if hashmap_mode is AUTO, otherwise exit. - if (hashmap_mode == hash_mode::AUTO) { - hash_bitlen = 0; - break; - } else { - RAFT_FAIL( - "small-hash cannot be used because the required hash size exceeds the limit (%u)", - hashmap::get_size(max_bitlen)); - } - } - small_hash_bitlen = hash_bitlen; + if (algo == search_algo::MULTI_CTA) { + const uint32_t mc_itopk_size = 32; + const uint32_t mc_num_cta_per_query = + max(search_width, raft::ceildiv(itopk_size, (size_t)mc_itopk_size)); + RAFT_LOG_DEBUG("# mc_itopk_size: %u", mc_itopk_size); + RAFT_LOG_DEBUG("# mc_num_cta_per_query: %u", mc_num_cta_per_query); // - // Sincc the hash table size is limited to a power of 2, the requirement, - // the maximum fill rate, may be satisfied even if the frequency of hash - // table reset is reduced to once every 2 or more iterations without - // changing the hash table size. In that case, reduce the reset frequency. + // [visited_hash_table] + // In the multi CTA algo, which node has been visited is managed in a hash + // table that each CTA has in the shared memory. This hash table is not + // shared among CTAs. This hash table is reset and restored in each iteration. // - small_hash_reset_interval = 1; - while (1) { - const auto max_visited_nodes = - itopk_size + (search_width * graph_degree * (small_hash_reset_interval + 1)); - if (max_visited_nodes > hashmap::get_size(hash_bitlen) * max_fill_rate) { break; } - small_hash_reset_interval += 1; + const uint32_t max_visited_nodes = mc_itopk_size + (graph_degree * 2); + small_hash_bitlen = 8; // 256 + while (max_visited_nodes > hashmap::get_size(small_hash_bitlen) * max_fill_rate) { + small_hash_bitlen += 1; } - break; - } - if (hash_bitlen == 0) { + RAFT_EXPECTS(small_hash_bitlen <= 14, "small_hash_bitlen cannot be largen than 14 (16K)"); // - // The size of hash table is determined based on the maximum number of - // nodes that may be visited before the search is completed and the - // maximum fill rate of the hash table. + // [traversed_hash_table] + // Whether a node has ever been used as the starting point for a traversal + // in each iteration is managed in a separate hash table, which is shared + // among the CTAs. // - uint32_t max_visited_nodes = itopk_size + (search_width * graph_degree * max_iterations); - if (algo == search_algo::MULTI_CTA) { - max_visited_nodes = mc_itopk_size + (mc_search_width * graph_degree * max_iterations); - max_visited_nodes *= mc_num_cta_per_query; - } + const auto max_traversed_nodes = + mc_num_cta_per_query * max((size_t)mc_itopk_size, max_iterations); unsigned min_bitlen = 11; // 2K if (min_bitlen < hashmap_min_bitlen) { min_bitlen = hashmap_min_bitlen; } hash_bitlen = min_bitlen; - while (max_visited_nodes > hashmap::get_size(hash_bitlen) * max_fill_rate) { + while (max_traversed_nodes > hashmap::get_size(hash_bitlen) * max_fill_rate) { hash_bitlen += 1; } - RAFT_EXPECTS(hash_bitlen <= 20, "hash_bitlen cannot be largen than 20 (1M)"); + RAFT_EXPECTS(hash_bitlen <= 25, "hash_bitlen cannot be largen than 25 (32M)"); + } else { + while (hashmap_mode == hash_mode::AUTO || hashmap_mode == hash_mode::SMALL) { + // + // The small-hash reduces hash table size by initializing the hash table + // for each iteration and re-registering only the nodes that should not be + // re-visited in that iteration. Therefore, the size of small-hash should + // be determined based on the internal topk size and the number of nodes + // visited per iteration. + // + const auto max_visited_nodes = itopk_size + (search_width * graph_degree * 1); + unsigned min_bitlen = 8; // 256 + unsigned max_bitlen = 13; // 8K + if (min_bitlen < hashmap_min_bitlen) { min_bitlen = hashmap_min_bitlen; } + hash_bitlen = min_bitlen; + while (max_visited_nodes > hashmap::get_size(hash_bitlen) * max_fill_rate) { + hash_bitlen += 1; + } + if (hash_bitlen > max_bitlen) { + // Switch to normal hash if hashmap_mode is AUTO, otherwise exit. + if (hashmap_mode == hash_mode::AUTO) { + hash_bitlen = 0; + break; + } else { + RAFT_FAIL( + "small-hash cannot be used because the required hash size exceeds the limit (%u)", + hashmap::get_size(max_bitlen)); + } + } + small_hash_bitlen = hash_bitlen; + // + // Sincc the hash table size is limited to a power of 2, the requirement, + // the maximum fill rate, may be satisfied even if the frequency of hash + // table reset is reduced to once every 2 or more iterations without + // changing the hash table size. In that case, reduce the reset frequency. + // + small_hash_reset_interval = 1; + while (1) { + const auto max_visited_nodes = + itopk_size + (search_width * graph_degree * (small_hash_reset_interval + 1)); + if (max_visited_nodes > hashmap::get_size(hash_bitlen) * max_fill_rate) { break; } + small_hash_reset_interval += 1; + } + break; + } + if (hash_bitlen == 0) { + // + // The size of hash table is determined based on the maximum number of + // nodes that may be visited before the search is completed and the + // maximum fill rate of the hash table. + // + uint32_t max_visited_nodes = itopk_size + (search_width * graph_degree * max_iterations); + unsigned min_bitlen = 11; // 2K + if (min_bitlen < hashmap_min_bitlen) { min_bitlen = hashmap_min_bitlen; } + hash_bitlen = min_bitlen; + while (max_visited_nodes > hashmap::get_size(hash_bitlen) * max_fill_rate) { + hash_bitlen += 1; + } + RAFT_EXPECTS(hash_bitlen <= 20, + "hash_bitlen cannot be largen than 20 (1M). You can decrease itopk_size, " + "search_width or max_iterations to reduce the required hashmap size."); + } } - RAFT_LOG_DEBUG("# internal topK = %lu", itopk_size); RAFT_LOG_DEBUG("# parent size = %lu", search_width); RAFT_LOG_DEBUG("# min_iterations = %lu", min_iterations); diff --git a/cpp/src/neighbors/detail/cagra/search_single_cta.cuh b/cpp/src/neighbors/detail/cagra/search_single_cta.cuh index 161aa8c4a..20070487b 100644 --- a/cpp/src/neighbors/detail/cagra/search_single_cta.cuh +++ b/cpp/src/neighbors/detail/cagra/search_single_cta.cuh @@ -94,9 +94,10 @@ struct search : search_plan_impl { search_params params, const dataset_descriptor_host& dataset_desc, int64_t dim, + int64_t dataset_size, int64_t graph_degree, uint32_t topk) - : base_type(res, params, dataset_desc, dim, graph_degree, topk) + : base_type(res, params, dataset_desc, dim, dataset_size, graph_degree, topk) { set_params(res); } diff --git a/cpp/src/neighbors/detail/cagra/search_single_cta_kernel-inl.cuh b/cpp/src/neighbors/detail/cagra/search_single_cta_kernel-inl.cuh index 188862fbb..1e072f540 100644 --- a/cpp/src/neighbors/detail/cagra/search_single_cta_kernel-inl.cuh +++ b/cpp/src/neighbors/detail/cagra/search_single_cta_kernel-inl.cuh @@ -621,7 +621,9 @@ __device__ void search_core( local_seed_ptr, num_seeds, local_visited_hashmap_ptr, - hash_bitlen); + hash_bitlen, + (INDEX_T*)nullptr, + 0); __syncthreads(); _CLK_REC(clk_compute_1st_distance); @@ -748,6 +750,8 @@ __device__ void search_core( graph_degree, local_visited_hashmap_ptr, hash_bitlen, + (INDEX_T*)nullptr, + 0, parent_list_buffer, result_indices_buffer, search_width); From 0dd7bde8c16d3eb8da9a2fd546f540fbf7e40c81 Mon Sep 17 00:00:00 2001 From: Tamas Bela Feher Date: Thu, 30 Jan 2025 17:04:48 +0100 Subject: [PATCH 2/3] Fix cagra_hnsw serialization when dataset is not part of index (#591) After calling `build()`, ideally the CAGRA index contains both the dataset and the graph. But when we do not have sufficient device memory, then only the graph is returned. In such case we need to pass the dataset explicitly to the serialization routines. For serialization in HNSW format, in case we have flat hierarchy, the dataset was not passed. This PR fixes this problem by adding an optional `dataset` argument to `cagra::serialize_to_hnswlib`. Furthermore, to improve execution time, we change from writing a single element to writing a single row of the graph and dataset at time. Additionally, debug messages for tracking data saving time are added. Authors: - Tamas Bela Feher (https://github.com/tfeher) - Corey J. Nolet (https://github.com/cjnolet) Approvers: - Divye Gala (https://github.com/divyegala) URL: https://github.com/rapidsai/cuvs/pull/591 --- .../ann/src/cuvs/cuvs_cagra_hnswlib_wrapper.h | 9 +- cpp/include/cuvs/neighbors/cagra.hpp | 66 ++++++++--- cpp/src/neighbors/cagra_serialize.cuh | 95 ++++++++-------- .../detail/cagra/cagra_serialize.cuh | 105 ++++++++++++------ cpp/src/neighbors/detail/hnsw.hpp | 18 ++- 5 files changed, 191 insertions(+), 102 deletions(-) diff --git a/cpp/bench/ann/src/cuvs/cuvs_cagra_hnswlib_wrapper.h b/cpp/bench/ann/src/cuvs/cuvs_cagra_hnswlib_wrapper.h index e4169f6f8..6670ed892 100644 --- a/cpp/bench/ann/src/cuvs/cuvs_cagra_hnswlib_wrapper.h +++ b/cpp/bench/ann/src/cuvs/cuvs_cagra_hnswlib_wrapper.h @@ -17,7 +17,9 @@ #include "cuvs_cagra_wrapper.h" #include +#include +#include #include namespace cuvs::bench { @@ -90,8 +92,13 @@ void cuvs_cagra_hnswlib::build(const T* dataset, size_t nrow) auto host_dataset_view = raft::make_host_matrix_view(dataset, nrow, this->dim_); auto opt_dataset_view = std::optional>(std::move(host_dataset_view)); - hnsw_index_ = cuvs::neighbors::hnsw::from_cagra( + const auto start_clock = std::chrono::system_clock::now(); + hnsw_index_ = cuvs::neighbors::hnsw::from_cagra( handle_, build_param_.hnsw_index_params, *cagra_index, opt_dataset_view); + int time = + std::chrono::duration_cast(std::chrono::system_clock::now() - start_clock) + .count(); + RAFT_LOG_DEBUG("Graph saved to HNSW format in %d:%d min", time / 60, time % 60); } template diff --git a/cpp/include/cuvs/neighbors/cagra.hpp b/cpp/include/cuvs/neighbors/cagra.hpp index a4684ce26..597e186d7 100644 --- a/cpp/include/cuvs/neighbors/cagra.hpp +++ b/cpp/include/cuvs/neighbors/cagra.hpp @@ -1599,11 +1599,16 @@ void deserialize(raft::resources const& handle, * @param[in] handle the raft handle * @param[in] os output stream * @param[in] index CAGRA index + * @param[in] dataset [optional] host array that stores the dataset, required if the index + * does not contain the dataset. * */ -void serialize_to_hnswlib(raft::resources const& handle, - std::ostream& os, - const cuvs::neighbors::cagra::index& index); +void serialize_to_hnswlib( + raft::resources const& handle, + std::ostream& os, + const cuvs::neighbors::cagra::index& index, + std::optional> dataset = + std::nullopt); /** * Save a CAGRA build index in hnswlib base-layer-only serialized format @@ -1628,11 +1633,16 @@ void serialize_to_hnswlib(raft::resources const& handle, * @param[in] handle the raft handle * @param[in] filename the file name for saving the index * @param[in] index CAGRA index + * @param[in] dataset [optional] host array that stores the dataset, required if the index + * does not contain the dataset. * */ -void serialize_to_hnswlib(raft::resources const& handle, - const std::string& filename, - const cuvs::neighbors::cagra::index& index); +void serialize_to_hnswlib( + raft::resources const& handle, + const std::string& filename, + const cuvs::neighbors::cagra::index& index, + std::optional> dataset = + std::nullopt); /** * Write the CAGRA built index as a base layer HNSW index to an output stream @@ -1656,11 +1666,16 @@ void serialize_to_hnswlib(raft::resources const& handle, * @param[in] handle the raft handle * @param[in] os output stream * @param[in] index CAGRA index + * @param[in] dataset [optional] host array that stores the dataset, required if the index + * does not contain the dataset. * */ -void serialize_to_hnswlib(raft::resources const& handle, - std::ostream& os, - const cuvs::neighbors::cagra::index& index); +void serialize_to_hnswlib( + raft::resources const& handle, + std::ostream& os, + const cuvs::neighbors::cagra::index& index, + std::optional> dataset = + std::nullopt); /** * Save a CAGRA build index in hnswlib base-layer-only serialized format @@ -1685,11 +1700,16 @@ void serialize_to_hnswlib(raft::resources const& handle, * @param[in] handle the raft handle * @param[in] filename the file name for saving the index * @param[in] index CAGRA index + * @param[in] dataset [optional] host array that stores the dataset, required if the index + * does not contain the dataset. * */ -void serialize_to_hnswlib(raft::resources const& handle, - const std::string& filename, - const cuvs::neighbors::cagra::index& index); +void serialize_to_hnswlib( + raft::resources const& handle, + const std::string& filename, + const cuvs::neighbors::cagra::index& index, + std::optional> dataset = + std::nullopt); /** * Write the CAGRA built index as a base layer HNSW index to an output stream @@ -1713,11 +1733,16 @@ void serialize_to_hnswlib(raft::resources const& handle, * @param[in] handle the raft handle * @param[in] os output stream * @param[in] index CAGRA index + * @param[in] dataset [optional] host array that stores the dataset, required if the index + * does not contain the dataset. * */ -void serialize_to_hnswlib(raft::resources const& handle, - std::ostream& os, - const cuvs::neighbors::cagra::index& index); +void serialize_to_hnswlib( + raft::resources const& handle, + std::ostream& os, + const cuvs::neighbors::cagra::index& index, + std::optional> dataset = + std::nullopt); /** * Save a CAGRA build index in hnswlib base-layer-only serialized format @@ -1742,11 +1767,16 @@ void serialize_to_hnswlib(raft::resources const& handle, * @param[in] handle the raft handle * @param[in] filename the file name for saving the index * @param[in] index CAGRA index + * @param[in] dataset [optional] host array that stores the dataset, required if the index + * does not contain the dataset. * */ -void serialize_to_hnswlib(raft::resources const& handle, - const std::string& filename, - const cuvs::neighbors::cagra::index& index); +void serialize_to_hnswlib( + raft::resources const& handle, + const std::string& filename, + const cuvs::neighbors::cagra::index& index, + std::optional> dataset = + std::nullopt); /** * @} diff --git a/cpp/src/neighbors/cagra_serialize.cuh b/cpp/src/neighbors/cagra_serialize.cuh index e193c0630..1b153b2ce 100644 --- a/cpp/src/neighbors/cagra_serialize.cuh +++ b/cpp/src/neighbors/cagra_serialize.cuh @@ -20,51 +20,56 @@ namespace cuvs::neighbors::cagra { -#define CUVS_INST_CAGRA_SERIALIZE(DTYPE) \ - void serialize(raft::resources const& handle, \ - const std::string& filename, \ - const cuvs::neighbors::cagra::index& index, \ - bool include_dataset) \ - { \ - cuvs::neighbors::cagra::detail::serialize( \ - handle, filename, index, include_dataset); \ - }; \ - \ - void deserialize(raft::resources const& handle, \ - const std::string& filename, \ - cuvs::neighbors::cagra::index* index) \ - { \ - cuvs::neighbors::cagra::detail::deserialize(handle, filename, index); \ - }; \ - void serialize(raft::resources const& handle, \ - std::ostream& os, \ - const cuvs::neighbors::cagra::index& index, \ - bool include_dataset) \ - { \ - cuvs::neighbors::cagra::detail::serialize( \ - handle, os, index, include_dataset); \ - } \ - \ - void deserialize(raft::resources const& handle, \ - std::istream& is, \ - cuvs::neighbors::cagra::index* index) \ - { \ - cuvs::neighbors::cagra::detail::deserialize(handle, is, index); \ - } \ - \ - void serialize_to_hnswlib(raft::resources const& handle, \ - std::ostream& os, \ - const cuvs::neighbors::cagra::index& index) \ - { \ - cuvs::neighbors::cagra::detail::serialize_to_hnswlib(handle, os, index); \ - } \ - \ - void serialize_to_hnswlib(raft::resources const& handle, \ - const std::string& filename, \ - const cuvs::neighbors::cagra::index& index) \ - { \ - cuvs::neighbors::cagra::detail::serialize_to_hnswlib( \ - handle, filename, index); \ +#define CUVS_INST_CAGRA_SERIALIZE(DTYPE) \ + void serialize(raft::resources const& handle, \ + const std::string& filename, \ + const cuvs::neighbors::cagra::index& index, \ + bool include_dataset) \ + { \ + cuvs::neighbors::cagra::detail::serialize( \ + handle, filename, index, include_dataset); \ + }; \ + \ + void deserialize(raft::resources const& handle, \ + const std::string& filename, \ + cuvs::neighbors::cagra::index* index) \ + { \ + cuvs::neighbors::cagra::detail::deserialize(handle, filename, index); \ + }; \ + void serialize(raft::resources const& handle, \ + std::ostream& os, \ + const cuvs::neighbors::cagra::index& index, \ + bool include_dataset) \ + { \ + cuvs::neighbors::cagra::detail::serialize( \ + handle, os, index, include_dataset); \ + } \ + \ + void deserialize(raft::resources const& handle, \ + std::istream& is, \ + cuvs::neighbors::cagra::index* index) \ + { \ + cuvs::neighbors::cagra::detail::deserialize(handle, is, index); \ + } \ + \ + void serialize_to_hnswlib( \ + raft::resources const& handle, \ + std::ostream& os, \ + const cuvs::neighbors::cagra::index& index, \ + std::optional> dataset) \ + { \ + cuvs::neighbors::cagra::detail::serialize_to_hnswlib( \ + handle, os, index, dataset); \ + } \ + \ + void serialize_to_hnswlib( \ + raft::resources const& handle, \ + const std::string& filename, \ + const cuvs::neighbors::cagra::index& index, \ + std::optional> dataset) \ + { \ + cuvs::neighbors::cagra::detail::serialize_to_hnswlib( \ + handle, filename, index, dataset); \ } } // namespace cuvs::neighbors::cagra diff --git a/cpp/src/neighbors/detail/cagra/cagra_serialize.cuh b/cpp/src/neighbors/detail/cagra/cagra_serialize.cuh index c83da7bb1..4bd761dc6 100644 --- a/cpp/src/neighbors/detail/cagra/cagra_serialize.cuh +++ b/cpp/src/neighbors/detail/cagra/cagra_serialize.cuh @@ -30,6 +30,7 @@ #include #include #include +#include #include namespace cuvs::neighbors::cagra::detail { @@ -96,16 +97,19 @@ void serialize(raft::resources const& res, } template -void serialize_to_hnswlib(raft::resources const& res, - std::ostream& os, - const cuvs::neighbors::cagra::index& index_) +void serialize_to_hnswlib( + raft::resources const& res, + std::ostream& os, + const cuvs::neighbors::cagra::index& index_, + std::optional> dataset) { // static_assert(std::is_same_v or std::is_same_v, // "An hnswlib index can only be trained with int32 or uint32 IdxT"); + int dim = (dataset) ? dataset->extent(1) : index_.dim(); raft::common::nvtx::range fun_scope("cagra::serialize"); RAFT_LOG_DEBUG("Saving CAGRA index to hnswlib format, size %zu, dim %u", static_cast(index_.size()), - index_.dim()); + dim); // offset_level_0 std::size_t offset_level_0 = 0; @@ -119,8 +123,8 @@ void serialize_to_hnswlib(raft::resources const& res, // Example:M: 16, dim = 128, data_t = float, index_t = uint32_t, list_size_type = uint32_t, // labeltype: size_t size_data_per_element_ = M * 2 * sizeof(index_t) + sizeof(list_size_type) + // dim * sizeof(T) + sizeof(labeltype) - auto size_data_per_element = static_cast(index_.graph_degree() * sizeof(IdxT) + 4 + - index_.dim() * sizeof(T) + 8); + auto size_data_per_element = + static_cast(index_.graph_degree() * sizeof(IdxT) + 4 + dim * sizeof(T) + 8); os.write(reinterpret_cast(&size_data_per_element), sizeof(std::size_t)); // label_offset std::size_t label_offset = size_data_per_element - 8; @@ -150,19 +154,29 @@ void serialize_to_hnswlib(raft::resources const& res, std::size_t efConstruction = 500; os.write(reinterpret_cast(&efConstruction), sizeof(std::size_t)); - auto dataset = index_.dataset(); // Remove padding before saving the dataset - auto host_dataset = raft::make_host_matrix(dataset.extent(0), dataset.extent(1)); - RAFT_CUDA_TRY(cudaMemcpy2DAsync(host_dataset.data_handle(), - sizeof(T) * host_dataset.extent(1), - dataset.data_handle(), - sizeof(T) * dataset.stride(0), - sizeof(T) * host_dataset.extent(1), - dataset.extent(0), - cudaMemcpyDefault, - raft::resource::get_cuda_stream(res))); - raft::resource::sync_stream(res); - + raft::host_matrix host_dataset = raft::make_host_matrix(0, 0); + raft::host_matrix_view host_dataset_view; + if (dataset) { + host_dataset_view = *dataset; + } else { + auto dataset = index_.dataset(); + RAFT_EXPECTS(dataset.size() > 0, + "Invalid CAGRA dataset of size 0 during serialization, shape %zux%zu", + static_cast(dataset.extent(0)), + static_cast(dataset.extent(1))); + host_dataset = raft::make_host_matrix(dataset.extent(0), dataset.extent(1)); + RAFT_CUDA_TRY(cudaMemcpy2DAsync(host_dataset.data_handle(), + sizeof(T) * host_dataset.extent(1), + dataset.data_handle(), + sizeof(T) * dataset.stride(0), + sizeof(T) * host_dataset.extent(1), + dataset.extent(0), + cudaMemcpyDefault, + raft::resource::get_cuda_stream(res))); + raft::resource::sync_stream(res); + host_dataset_view = raft::make_const_mdspan(host_dataset.view()); + } auto graph = index_.graph(); auto host_graph = raft::make_host_matrix(graph.extent(0), graph.extent(1)); @@ -172,23 +186,48 @@ void serialize_to_hnswlib(raft::resources const& res, raft::resource::get_cuda_stream(res)); raft::resource::sync_stream(res); + size_t d_report_offset = index_.size() / 10; // Report progress in 10% steps. + size_t next_report_offset = d_report_offset; + const auto start_clock = std::chrono::system_clock::now(); // Write one dataset and graph row at a time + RAFT_EXPECTS(host_graph.stride(1) == 1, "serialize_to_hnswlib expects row_major graph"); + RAFT_EXPECTS(host_dataset_view.stride(1) == 1, "serialize_to_hnswlib expects row_major dataset"); + + size_t bytes_written = 0; + float GiB = 1 << 30; for (std::size_t i = 0; i < index_.size(); i++) { auto graph_degree = static_cast(index_.graph_degree()); os.write(reinterpret_cast(&graph_degree), sizeof(int)); - for (std::size_t j = 0; j < index_.graph_degree(); ++j) { - auto graph_elem = host_graph(i, j); - os.write(reinterpret_cast(&graph_elem), sizeof(IdxT)); - } - - auto data_row = host_dataset.data_handle() + (index_.dim() * i); - for (std::size_t j = 0; j < index_.dim(); ++j) { - auto data_elem = static_cast(host_dataset(i, j)); - os.write(reinterpret_cast(&data_elem), sizeof(T)); - } + IdxT* graph_row = &host_graph(i, 0); + os.write(reinterpret_cast(graph_row), sizeof(IdxT) * index_.graph_degree()); + const T* data_row = &host_dataset_view(i, 0); + os.write(reinterpret_cast(data_row), sizeof(T) * dim); os.write(reinterpret_cast(&i), sizeof(std::size_t)); + + bytes_written += + dim * sizeof(T) + index_.graph_degree() * sizeof(IdxT) + sizeof(int) + sizeof(size_t); + const auto end_clock = std::chrono::system_clock::now(); + if (!os.good()) { RAFT_FAIL("Error writing HNSW file, row %zu", i); } + if (i > next_report_offset) { + next_report_offset += d_report_offset; + const auto time = + std::chrono::duration_cast(end_clock - start_clock).count() * + 1e-6; + float throughput = bytes_written / GiB / time; + float rows_throughput = i / time; + float ETA = (index_.size() - i) / rows_throughput; + RAFT_LOG_DEBUG( + "# Writing rows %12lu / %12lu (%3.2f %%), %3.2f GiB/sec, ETA %d:%3.1f, written %3.2f GiB\r", + i, + index_.size(), + i / static_cast(index_.size()) * 100, + throughput, + int(ETA / 60), + std::fmod(ETA, 60.0f), + bytes_written / GiB); + } } for (std::size_t i = 0; i < index_.size(); i++) { @@ -199,14 +238,16 @@ void serialize_to_hnswlib(raft::resources const& res, } template -void serialize_to_hnswlib(raft::resources const& res, - const std::string& filename, - const cuvs::neighbors::cagra::index& index_) +void serialize_to_hnswlib( + raft::resources const& res, + const std::string& filename, + const cuvs::neighbors::cagra::index& index_, + std::optional> dataset) { std::ofstream of(filename, std::ios::out | std::ios::binary); if (!of) { RAFT_FAIL("Cannot open file %s", filename.c_str()); } - detail::serialize_to_hnswlib(res, of, index_); + detail::serialize_to_hnswlib(res, of, index_, dataset); of.close(); if (!of) { RAFT_FAIL("Error writing output %s", filename.c_str()); } diff --git a/cpp/src/neighbors/detail/hnsw.hpp b/cpp/src/neighbors/detail/hnsw.hpp index e129d23e8..5447ae07a 100644 --- a/cpp/src/neighbors/detail/hnsw.hpp +++ b/cpp/src/neighbors/detail/hnsw.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -163,14 +164,15 @@ template std::enable_if_t>> from_cagra( raft::resources const& res, const index_params& params, - const cuvs::neighbors::cagra::index& cagra_index) + const cuvs::neighbors::cagra::index& cagra_index, + std::optional> dataset) { std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0); auto uuid = std::to_string(dist(rng)); std::string filepath = "/tmp/" + uuid + ".bin"; - cuvs::neighbors::cagra::serialize_to_hnswlib(res, filepath, cagra_index); + cuvs::neighbors::cagra::serialize_to_hnswlib(res, filepath, cagra_index, dataset); index* hnsw_index = nullptr; cuvs::neighbors::hnsw::deserialize( @@ -195,6 +197,10 @@ std::enable_if_t>> fro } else { // move dataset to host, remove padding auto cagra_dataset = cagra_index.dataset(); + RAFT_EXPECTS(cagra_dataset.size() > 0, + "Invalid CAGRA dataset of size 0, shape %zux%zu", + static_cast(cagra_dataset.extent(0)), + static_cast(cagra_dataset.extent(1))); host_dataset = raft::make_host_matrix(cagra_dataset.extent(0), cagra_dataset.extent(1)); RAFT_CUDA_TRY(cudaMemcpy2DAsync(host_dataset.data_handle(), @@ -209,9 +215,9 @@ std::enable_if_t>> fro host_dataset_view = host_dataset.view(); } // build upper layers of hnsw index - auto hnsw_index = - std::make_unique>(cagra_index.dim(), cagra_index.metric(), hierarchy); - auto appr_algo = std::make_unique::type>>( + int dim = host_dataset_view.extent(1); + auto hnsw_index = std::make_unique>(dim, cagra_index.metric(), hierarchy); + auto appr_algo = std::make_unique::type>>( hnsw_index->get_space(), host_dataset_view.extent(0), cagra_index.graph().extent(1) / 2, @@ -256,7 +262,7 @@ std::unique_ptr> from_cagra( std::optional> dataset) { if (params.hierarchy == HnswHierarchy::NONE) { - return from_cagra(res, params, cagra_index); + return from_cagra(res, params, cagra_index, dataset); } else if (params.hierarchy == HnswHierarchy::CPU) { return from_cagra(res, params, cagra_index, dataset); } From 4ca47c92b03856e7d4ae328aabf6ee3e853a137e Mon Sep 17 00:00:00 2001 From: Ishan Chattopadhyaya Date: Thu, 30 Jan 2025 23:12:55 +0530 Subject: [PATCH 3/3] Initial cut for a cuVS Java API (#450) A Java API for cuVS for easy integration into Apache Lucene or other Java based projects. Try: ``` ./build.sh libcuvs ./build.sh java ``` For generating docs, ```mvn javadoc:javadoc``` Prerequisites: * JDK 22 * Maven 3.9.6+ Todo: * Generate project panama classes using jextract on every build * Algorithms other than Cagra * Prefiltering in cagra Authors: - Ishan Chattopadhyaya (https://github.com/chatman) - Vivek Narang (https://github.com/narangvivek10) - Chris Hegarty (https://github.com/ChrisHegarty) Approvers: - Corey J. Nolet (https://github.com/cjnolet) - Mike Sarahan (https://github.com/msarahan) URL: https://github.com/rapidsai/cuvs/pull/450 --- .gitignore | 3 + build.sh | 15 +- ci/release/update-version.sh | 8 + cpp/include/cuvs/neighbors/hnsw.h | 2 +- java/README.md | 14 + java/build.sh | 14 + java/cuvs-java/.gitignore | 1 + java/cuvs-java/pom.xml | 159 + .../java/com/nvidia/cuvs/BruteForceIndex.java | 364 ++ .../nvidia/cuvs/BruteForceIndexParams.java | 71 + .../java/com/nvidia/cuvs/BruteForceQuery.java | 156 + .../nvidia/cuvs/BruteForceSearchResults.java | 61 + .../nvidia/cuvs/CagraCompressionParams.java | 266 ++ .../main/java/com/nvidia/cuvs/CagraIndex.java | 517 +++ .../com/nvidia/cuvs/CagraIndexParams.java | 344 ++ .../main/java/com/nvidia/cuvs/CagraQuery.java | 165 + .../com/nvidia/cuvs/CagraSearchParams.java | 505 +++ .../com/nvidia/cuvs/CagraSearchResults.java | 61 + .../java/com/nvidia/cuvs/CuVSResources.java | 152 + .../main/java/com/nvidia/cuvs/GPUInfo.java | 56 + .../main/java/com/nvidia/cuvs/HnswIndex.java | 263 ++ .../java/com/nvidia/cuvs/HnswIndexParams.java | 211 ++ .../main/java/com/nvidia/cuvs/HnswQuery.java | 156 + .../com/nvidia/cuvs/HnswSearchParams.java | 137 + .../com/nvidia/cuvs/HnswSearchResults.java | 61 + .../com/nvidia/cuvs/LibraryException.java | 18 + .../com/nvidia/cuvs/common/SearchResults.java | 53 + .../java/com/nvidia/cuvs/common/Util.java | 265 ++ .../com/nvidia/cuvs/panama/BruteForceH.java | 1912 ++++++++++ .../java/com/nvidia/cuvs/panama/CagraH.java | 2298 ++++++++++++ .../cuvs/panama/CuVSBruteForceIndex.java | 183 + .../panama/CuVSCagraCompressionParams.java | 352 ++ .../nvidia/cuvs/panama/CuVSCagraIndex.java | 183 + .../cuvs/panama/CuVSCagraIndexParams.java | 354 ++ .../cuvs/panama/CuVSCagraSearchParams.java | 644 ++++ .../com/nvidia/cuvs/panama/CuVSFilter.java | 188 + .../cuvs/panama/CuVSHnswExtendParams.java | 142 + .../com/nvidia/cuvs/panama/CuVSHnswIndex.java | 183 + .../cuvs/panama/CuVSHnswIndexParams.java | 224 ++ .../cuvs/panama/CuVSHnswSearchParams.java | 183 + .../com/nvidia/cuvs/panama/DLDataType.java | 233 ++ .../java/com/nvidia/cuvs/panama/DLDevice.java | 186 + .../nvidia/cuvs/panama/DLManagedTensor.java | 288 ++ .../cuvs/panama/DLManagedTensorVersioned.java | 381 ++ .../com/nvidia/cuvs/panama/DLPackVersion.java | 186 + .../java/com/nvidia/cuvs/panama/DLTensor.java | 418 +++ .../com/nvidia/cuvs/panama/DistanceH.java | 274 ++ .../java/com/nvidia/cuvs/panama/DlpackH.java | 1898 ++++++++++ .../java/com/nvidia/cuvs/panama/Fsidt.java | 175 + .../java/com/nvidia/cuvs/panama/GpuInfo.java | 342 ++ .../java/com/nvidia/cuvs/panama/GpuInfoH.java | 86 + .../java/com/nvidia/cuvs/panama/HnswH.java | 2350 ++++++++++++ .../java/com/nvidia/cuvs/panama/IvfFlatH.java | 2845 +++++++++++++++ .../java/com/nvidia/cuvs/panama/IvfPqH.java | 3182 +++++++++++++++++ .../com/nvidia/cuvs/panama/MaxAlignT.java | 142 + java/cuvs-java/src/main/java/module-info.java | 19 + .../nvidia/cuvs/BruteForceAndSearchTest.java | 129 + .../nvidia/cuvs/BruteForceRandomizedTest.java | 99 + .../nvidia/cuvs/CagraBuildAndSearchTest.java | 137 + .../com/nvidia/cuvs/CagraRandomizedTest.java | 101 + .../java/com/nvidia/cuvs/CuVSTestCase.java | 88 + .../nvidia/cuvs/HnswBuildAndSearchTest.java | 132 + .../com/nvidia/cuvs/HnswRandomizedTest.java | 136 + java/examples/.gitignore | 1 + java/examples/README.md | 8 + java/examples/pom.xml | 105 + .../cuvs/examples/BruteForceExample.java | 90 + .../nvidia/cuvs/examples/CagraExample.java | 100 + .../com/nvidia/cuvs/examples/HnswExample.java | 99 + java/examples/src/main/resources/log4j2.xml | 14 + java/internal/CMakeLists.txt | 62 + java/internal/VERSION | 1 + java/internal/get_dlpack.cmake | 1 + java/internal/rapids_config.cmake | 1 + java/internal/src/cuvs_java.c | 464 +++ 75 files changed, 25714 insertions(+), 3 deletions(-) create mode 100644 java/README.md create mode 100755 java/build.sh create mode 100644 java/cuvs-java/.gitignore create mode 100644 java/cuvs-java/pom.xml create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceSearchResults.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchResults.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfo.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchResults.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/LibraryException.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/common/SearchResults.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/common/Util.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/BruteForceH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CagraH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSBruteForceIndex.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraCompressionParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndex.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndexParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraSearchParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSFilter.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswExtendParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndex.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndexParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswSearchParams.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDataType.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDevice.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensor.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensorVersioned.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLPackVersion.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLTensor.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DistanceH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DlpackH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/Fsidt.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfo.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfoH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/HnswH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfFlatH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfPqH.java create mode 100644 java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/MaxAlignT.java create mode 100644 java/cuvs-java/src/main/java/module-info.java create mode 100644 java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceAndSearchTest.java create mode 100644 java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceRandomizedTest.java create mode 100644 java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraBuildAndSearchTest.java create mode 100644 java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraRandomizedTest.java create mode 100644 java/cuvs-java/src/test/java/com/nvidia/cuvs/CuVSTestCase.java create mode 100644 java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswBuildAndSearchTest.java create mode 100644 java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswRandomizedTest.java create mode 100644 java/examples/.gitignore create mode 100644 java/examples/README.md create mode 100644 java/examples/pom.xml create mode 100644 java/examples/src/main/java/com/nvidia/cuvs/examples/BruteForceExample.java create mode 100644 java/examples/src/main/java/com/nvidia/cuvs/examples/CagraExample.java create mode 100644 java/examples/src/main/java/com/nvidia/cuvs/examples/HnswExample.java create mode 100644 java/examples/src/main/resources/log4j2.xml create mode 100644 java/internal/CMakeLists.txt create mode 120000 java/internal/VERSION create mode 120000 java/internal/get_dlpack.cmake create mode 120000 java/internal/rapids_config.cmake create mode 100644 java/internal/src/cuvs_java.c diff --git a/.gitignore b/.gitignore index da6eb07f6..a70ca197f 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,6 @@ ivf_pq_index # cuvs_bench datasets/ /*.json + +# java +.classpath diff --git a/build.sh b/build.sh index 3b9a9a3a8..89e1b5a33 100755 --- a/build.sh +++ b/build.sh @@ -18,7 +18,7 @@ ARGS=$* # scripts, and that this script resides in the repo dir! REPODIR=$(cd $(dirname $0); pwd) -VALIDARGS="clean libcuvs python rust docs tests bench-ann examples --uninstall -v -g -n --compile-static-lib --allgpuarch --no-mg --no-cpu --cpu-only --no-shared-libs --no-nvtx --show_depr_warn --incl-cache-stats --time -h" +VALIDARGS="clean libcuvs python rust java docs tests bench-ann examples --uninstall -v -g -n --compile-static-lib --allgpuarch --no-mg --no-cpu --cpu-only --no-shared-libs --no-nvtx --show_depr_warn --incl-cache-stats --time -h" HELP="$0 [ ...] [ ...] [--cmake-args=\"\"] [--cache-tool=] [--limit-tests=] [--limit-bench-ann=] [--build-metrics=] where is: clean - remove all existing build artifacts and configuration (start over) @@ -26,6 +26,7 @@ HELP="$0 [ ...] [ ...] [--cmake-args=\"\"] [--cache-tool= $NEXT_FULL_TAG" @@ -96,3 +97,10 @@ find .devcontainer/ -type f -name devcontainer.json -print0 | while IFS= read -r sed_runner "s@rapidsai/devcontainers/features/rapids-build-utils:[0-9.]*@rapidsai/devcontainers/features/rapids-build-utils:${NEXT_SHORT_TAG_PEP440}@" "${filename}" sed_runner "s@rapids-\${localWorkspaceFolderBasename}-${CURRENT_SHORT_TAG}@rapids-\${localWorkspaceFolderBasename}-${NEXT_SHORT_TAG}@g" "${filename}" done + +# Update Java API version +NEXT_FULL_JAVA_TAG="${NEXT_SHORT_TAG}.${PATCH_PEP440}" +sed_runner "s/VERSION=\".*\"/VERSION=\"${NEXT_FULL_JAVA_TAG}\"/g" java/build.sh +for FILE in java/*/pom.xml; do + sed_runner "/.*/s//${NEXT_FULL_JAVA_TAG}<\/version>/g" "${FILE}" +done diff --git a/cpp/include/cuvs/neighbors/hnsw.h b/cpp/include/cuvs/neighbors/hnsw.h index b7eda54b8..a7597a939 100644 --- a/cpp/include/cuvs/neighbors/hnsw.h +++ b/cpp/include/cuvs/neighbors/hnsw.h @@ -47,7 +47,7 @@ enum cuvsHnswHierarchy { struct cuvsHnswIndexParams { /* hierarchy of the hnsw index */ - cuvsHnswHierarchy hierarchy; + enum cuvsHnswHierarchy hierarchy; /** Size of the candidate list during hierarchy construction when hierarchy is `CPU`*/ int ef_construction; /** Number of host threads to use to construct hierarchy when hierarchy is `CPU` diff --git a/java/README.md b/java/README.md new file mode 100644 index 000000000..e5676146a --- /dev/null +++ b/java/README.md @@ -0,0 +1,14 @@ +Prerequisites +------------- + +* JDK 22 +* Maven 3.9.6 or later + +To build this API, please do `./build.sh java` in the top level directory. Since this API is dependent on `libcuvs` it must be noted that `libcuvs` gets built automatically before building this API. + +Alternatively, please build libcuvs (`./build.sh libcuvs` from top level directory) before building the Java API with `./build.sh` from this directory. + +Building +-------- + +`./build.sh` will generate the `libcuvs_java.so` file in the `internal/` directory, and then build the final jar file for the cuVS Java API in the `cuvs-java/` directory. diff --git a/java/build.sh b/java/build.sh new file mode 100755 index 000000000..05b47de77 --- /dev/null +++ b/java/build.sh @@ -0,0 +1,14 @@ +VERSION="25.02.0" # Note: The version is updated automatically when ci/release/update-version.sh is invoked +GROUP_ID="com.nvidia.cuvs" +SO_FILE_PATH="./internal" + +if [ -z "$CMAKE_PREFIX_PATH" ]; then + export CMAKE_PREFIX_PATH=`pwd`/../cpp/build +fi + +cd internal && cmake . && cmake --build . \ + && cd .. \ + && mvn install:install-file -DgroupId=$GROUP_ID -DartifactId=cuvs-java-internal -Dversion=$VERSION -Dpackaging=so -Dfile=$SO_FILE_PATH/libcuvs_java.so \ + && cd cuvs-java \ + && mvn package \ + && mvn install:install-file -Dfile=./target/cuvs-java-$VERSION-jar-with-dependencies.jar -DgroupId=$GROUP_ID -DartifactId=cuvs-java -Dversion=$VERSION -Dpackaging=jar diff --git a/java/cuvs-java/.gitignore b/java/cuvs-java/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/java/cuvs-java/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/java/cuvs-java/pom.xml b/java/cuvs-java/pom.xml new file mode 100644 index 000000000..c8d31638c --- /dev/null +++ b/java/cuvs-java/pom.xml @@ -0,0 +1,159 @@ + + + 4.0.0 + com.nvidia.cuvs + cuvs-java + + 25.02.0 + cuvs-java + jar + + + 22 + 22 + UTF-8 + UTF-8 + + + + + + org.slf4j + slf4j-api + 1.7.36 + test + + + + org.slf4j + slf4j-simple + 1.7.36 + test + + + + com.carrotsearch.randomizedtesting + randomizedtesting-runner + 2.8.2 + test + + + + junit + junit + 4.13.1 + test + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + suites + 1 + false + + ${project.build.directory}/classes + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + copy + compile + + copy + + + + + com.nvidia.cuvs + cuvs-java-internal + + 25.02.0 + so + false + + ${project.build.directory}/classes + libcuvs_java.so + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.4.2 + + + jar-with-dependencies + + + add + + + + + assemble-all + package + + single + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + true + + com.nvidia.cuvs.examples.CagraExample + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.2 + + com.nvidia.cuvs.examples,com.nvidia.cuvs.panama + ${project.build.directory} + + + + + diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java new file mode 100644 index 000000000..30ffca1cd --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.UUID; + +import com.nvidia.cuvs.common.Util; +import com.nvidia.cuvs.panama.CuVSBruteForceIndex; + +/** + * + * {@link BruteForceIndex} encapsulates a BRUTEFORCE index, along with methods + * to interact with it. + * + * @since 25.02 + */ +public class BruteForceIndex { + + private final float[][] dataset; + private final CuVSResources resources; + private MethodHandle indexMethodHandle; + private MethodHandle searchMethodHandle; + private MethodHandle destroyIndexMethodHandle; + private MethodHandle serializeMethodHandle; + private MethodHandle deserializeMethodHandle; + private IndexReference bruteForceIndexReference; + private BruteForceIndexParams bruteForceIndexParams; + private MemoryLayout longMemoryLayout; + private MemoryLayout intMemoryLayout; + private MemoryLayout floatMemoryLayout; + + /** + * Constructor for building the index using specified dataset + * + * @param dataset the dataset used for creating the BRUTEFORCE + * index + * @param resources an instance of {@link CuVSResources} + * @param bruteForceIndexParams an instance of {@link BruteForceIndexParams} + * holding the index parameters + */ + private BruteForceIndex(float[][] dataset, CuVSResources resources, BruteForceIndexParams bruteForceIndexParams) + throws Throwable { + this.dataset = dataset; + this.resources = resources; + this.bruteForceIndexParams = bruteForceIndexParams; + + longMemoryLayout = resources.linker.canonicalLayouts().get("long"); + intMemoryLayout = resources.linker.canonicalLayouts().get("int"); + floatMemoryLayout = resources.linker.canonicalLayouts().get("float"); + + initializeMethodHandles(); + this.bruteForceIndexReference = build(); + } + + /** + * Constructor for loading the index from an {@link InputStream} + * + * @param inputStream an instance of stream to read the index bytes from + * @param resources an instance of {@link CuVSResources} + */ + private BruteForceIndex(InputStream inputStream, CuVSResources resources) throws Throwable { + this.bruteForceIndexParams = null; + this.dataset = null; + this.resources = resources; + + longMemoryLayout = resources.linker.canonicalLayouts().get("long"); + intMemoryLayout = resources.linker.canonicalLayouts().get("int"); + floatMemoryLayout = resources.linker.canonicalLayouts().get("float"); + + initializeMethodHandles(); + this.bruteForceIndexReference = deserialize(inputStream); + } + + /** + * Initializes the {@link MethodHandles} for invoking native methods. + * + * @throws IOException @{@link IOException} is unable to load the native library + */ + private void initializeMethodHandles() throws IOException { + indexMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("build_brute_force_index").get(), + FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS, longMemoryLayout, longMemoryLayout, + ValueLayout.ADDRESS, ValueLayout.ADDRESS, intMemoryLayout)); + + searchMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("search_brute_force_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, intMemoryLayout, longMemoryLayout, + intMemoryLayout, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, + ValueLayout.ADDRESS, longMemoryLayout, longMemoryLayout)); + + destroyIndexMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("destroy_brute_force_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + serializeMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("serialize_brute_force_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + deserializeMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("deserialize_brute_force_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + } + + /** + * Invokes the native destroy_brute_force_index function to de-allocate + * BRUTEFORCE index + */ + public void destroyIndex() throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + destroyIndexMethodHandle.invokeExact(bruteForceIndexReference.getMemorySegment(), returnValueMemorySegment); + } + + /** + * Invokes the native build_brute_force_index function via the Panama API to + * build the {@link BruteForceIndex} + * + * @return an instance of {@link IndexReference} that holds the pointer to the + * index + */ + private IndexReference build() throws Throwable { + long rows = dataset.length; + long cols = rows > 0 ? dataset[0].length : 0; + + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + + IndexReference indexReference = new IndexReference((MemorySegment) indexMethodHandle.invokeExact( + Util.buildMemorySegment(resources.linker, resources.arena, dataset), rows, cols, resources.getMemorySegment(), + returnValueMemorySegment, bruteForceIndexParams.getNumWriterThreads())); + + return indexReference; + } + + /** + * Invokes the native search_brute_force_index via the Panama API for searching + * a BRUTEFORCE index. + * + * @param cuvsQuery an instance of {@link BruteForceQuery} holding the query + * vectors and other parameters + * @return an instance of {@link BruteForceSearchResults} containing the results + */ + public BruteForceSearchResults search(BruteForceQuery cuvsQuery) throws Throwable { + long numQueries = cuvsQuery.getQueryVectors().length; + long numBlocks = cuvsQuery.getTopK() * numQueries; + int vectorDimension = numQueries > 0 ? cuvsQuery.getQueryVectors()[0].length : 0; + long prefilterDataLength = cuvsQuery.getPrefilter() != null ? cuvsQuery.getPrefilter().length : 0; + long numRows = dataset != null ? dataset.length : 0; + + SequenceLayout neighborsSequenceLayout = MemoryLayout.sequenceLayout(numBlocks, longMemoryLayout); + SequenceLayout distancesSequenceLayout = MemoryLayout.sequenceLayout(numBlocks, floatMemoryLayout); + MemorySegment neighborsMemorySegment = resources.arena.allocate(neighborsSequenceLayout); + MemorySegment distancesMemorySegment = resources.arena.allocate(distancesSequenceLayout); + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + MemorySegment prefilterDataMemorySegment = cuvsQuery.getPrefilter() != null + ? Util.buildMemorySegment(resources.linker, resources.arena, cuvsQuery.getPrefilter()) + : MemorySegment.NULL; + + searchMethodHandle.invokeExact(bruteForceIndexReference.getMemorySegment(), + Util.buildMemorySegment(resources.linker, resources.arena, cuvsQuery.getQueryVectors()), cuvsQuery.getTopK(), + numQueries, vectorDimension, resources.getMemorySegment(), neighborsMemorySegment, distancesMemorySegment, + returnValueMemorySegment, prefilterDataMemorySegment, prefilterDataLength, numRows); + + return new BruteForceSearchResults(neighborsSequenceLayout, distancesSequenceLayout, neighborsMemorySegment, + distancesMemorySegment, cuvsQuery.getTopK(), cuvsQuery.getMapping(), numQueries); + } + + /** + * A method to persist a BRUTEFORCE index using an instance of + * {@link OutputStream} for writing index bytes. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes into + */ + public void serialize(OutputStream outputStream) throws Throwable { + serialize(outputStream, File.createTempFile(UUID.randomUUID().toString(), ".bf")); + } + + /** + * A method to persist a BRUTEFORCE index using an instance of + * {@link OutputStream} and path to the intermediate temporary file. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes to + * @param tempFile an intermediate {@link File} where BRUTEFORCE index is + * written temporarily + */ + public void serialize(OutputStream outputStream, File tempFile) throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + serializeMethodHandle.invokeExact(resources.getMemorySegment(), bruteForceIndexReference.getMemorySegment(), + returnValueMemorySegment, + Util.buildMemorySegment(resources.linker, resources.arena, tempFile.getAbsolutePath())); + FileInputStream fileInputStream = new FileInputStream(tempFile); + byte[] chunk = new byte[1024]; // TODO: Make this configurable + int chunkLength = 0; + while ((chunkLength = fileInputStream.read(chunk)) != -1) { + outputStream.write(chunk, 0, chunkLength); + } + fileInputStream.close(); + tempFile.delete(); + } + + /** + * Gets an instance of {@link IndexReference} by deserializing a BRUTEFORCE + * index using an {@link InputStream}. + * + * @param inputStream an instance of {@link InputStream} + * @return an instance of {@link IndexReference}. + */ + private IndexReference deserialize(InputStream inputStream) throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + String tmpIndexFile = "/tmp/" + UUID.randomUUID().toString() + ".bf"; + IndexReference indexReference = new IndexReference(resources); + + File tempFile = new File(tmpIndexFile); + FileOutputStream fileOutputStream = new FileOutputStream(tempFile); + byte[] chunk = new byte[1024]; + int chunkLength = 0; + while ((chunkLength = inputStream.read(chunk)) != -1) { + fileOutputStream.write(chunk, 0, chunkLength); + } + deserializeMethodHandle.invokeExact(resources.getMemorySegment(), indexReference.getMemorySegment(), + returnValueMemorySegment, Util.buildMemorySegment(resources.linker, resources.arena, tmpIndexFile)); + + inputStream.close(); + fileOutputStream.close(); + tempFile.delete(); + + return indexReference; + } + + /** + * Builder helps configure and create an instance of {@link BruteForceIndex}. + */ + public static class Builder { + + private float[][] dataset; + private CuVSResources cuvsResources; + private BruteForceIndexParams bruteForceIndexParams; + private InputStream inputStream; + + /** + * Constructs this Builder with an instance of {@link CuVSResources}. + * + * @param cuvsResources an instance of {@link CuVSResources} + */ + public Builder(CuVSResources cuvsResources) { + this.cuvsResources = cuvsResources; + } + + /** + * Registers an instance of configured {@link BruteForceIndexParams} with this + * Builder. + * + * @param bruteForceIndexParams An instance of BruteForceIndexParams + * @return An instance of this Builder + */ + public Builder withIndexParams(BruteForceIndexParams bruteForceIndexParams) { + this.bruteForceIndexParams = bruteForceIndexParams; + return this; + } + + /** + * Sets an instance of InputStream typically used when index deserialization is + * needed. + * + * @param inputStream an instance of {@link InputStream} + * @return an instance of this Builder + */ + public Builder from(InputStream inputStream) { + this.inputStream = inputStream; + return this; + } + + /** + * Sets the dataset for building the {@link BruteForceIndex}. + * + * @param dataset a two-dimensional float array + * @return an instance of this Builder + */ + public Builder withDataset(float[][] dataset) { + this.dataset = dataset; + return this; + } + + /** + * Builds and returns an instance of {@link BruteForceIndex}. + * + * @return an instance of {@link BruteForceIndex} + */ + public BruteForceIndex build() throws Throwable { + if (inputStream != null) { + return new BruteForceIndex(inputStream, cuvsResources); + } else { + return new BruteForceIndex(dataset, cuvsResources, bruteForceIndexParams); + } + } + } + + /** + * Holds the memory reference to a BRUTEFORCE index. + */ + protected static class IndexReference { + + private final MemorySegment memorySegment; + + /** + * Constructs CagraIndexReference and allocate the MemorySegment. + */ + protected IndexReference(CuVSResources resources) { + memorySegment = CuVSBruteForceIndex.allocate(resources.arena); + } + + /** + * Constructs BruteForceIndexReference with an instance of MemorySegment passed + * as a parameter. + * + * @param indexMemorySegment the MemorySegment instance to use for containing + * index reference + */ + protected IndexReference(MemorySegment indexMemorySegment) { + this.memorySegment = indexMemorySegment; + } + + /** + * Gets the instance of index MemorySegment. + * + * @return index MemorySegment + */ + protected MemorySegment getMemorySegment() { + return memorySegment; + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java new file mode 100644 index 000000000..832edf51a --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +/** + * Supplemental parameters to build BRUTEFORCE index. + * + * @since 25.02 + */ +public class BruteForceIndexParams { + + private final int numWriterThreads; + + private BruteForceIndexParams(int writerThreads) { + this.numWriterThreads = writerThreads; + } + + @Override + public String toString() { + return "BruteForceIndexParams [numWriterThreads=" + numWriterThreads + "]"; + } + + /** + * Gets the number of threads used to build the index. + */ + public int getNumWriterThreads() { + return numWriterThreads; + } + + /** + * Builder configures and creates an instance of {@link BruteForceIndexParams}. + */ + public static class Builder { + + private int numWriterThreads = 2; + + /** + * Sets the number of writer threads to use for indexing. + * + * @param numWriterThreads number of writer threads to use + * @return an instance of Builder + */ + public Builder withNumWriterThreads(int numWriterThreads) { + this.numWriterThreads = numWriterThreads; + return this; + } + + /** + * Builds an instance of {@link BruteForceIndexParams}. + * + * @return an instance of {@link BruteForceIndexParams} + */ + public BruteForceIndexParams build() { + return new BruteForceIndexParams(numWriterThreads); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java new file mode 100644 index 000000000..7febc3ba3 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.util.Arrays; +import java.util.List; + +/** + * BruteForceQuery holds the query vectors to be used while invoking search. + * + * @since 25.02 + */ +public class BruteForceQuery { + + private List mapping; + private float[][] queryVectors; + private long[] prefilter; + private int topK; + + /** + * Constructs an instance of {@link BruteForceQuery} using queryVectors, + * mapping, and topK. + * + * @param queryVectors 2D float query vector array + * @param mapping an instance of ID mapping + * @param topK the top k results to return + * @param prefilter the prefilter data to use while searching the BRUTEFORCE + * index + */ + public BruteForceQuery(float[][] queryVectors, List mapping, int topK, long[] prefilter) { + this.queryVectors = queryVectors; + this.mapping = mapping; + this.topK = topK; + this.prefilter = prefilter; + } + + /** + * Gets the query vector 2D float array. + * + * @return 2D float array + */ + public float[][] getQueryVectors() { + return queryVectors; + } + + /** + * Gets the passed map instance. + * + * @return a map of ID mappings + */ + public List getMapping() { + return mapping; + } + + /** + * Gets the topK value. + * + * @return an integer + */ + public int getTopK() { + return topK; + } + + /** + * Gets the prefilter long array + * + * @return a long array + */ + public long[] getPrefilter() { + return prefilter; + } + + @Override + public String toString() { + return "BruteForceQuery [mapping=" + mapping + ", queryVectors=" + Arrays.toString(queryVectors) + ", prefilter=" + + Arrays.toString(prefilter) + ", topK=" + topK + "]"; + } + + /** + * Builder helps configure and create an instance of BruteForceQuery. + */ + public static class Builder { + + private float[][] queryVectors; + private long[] prefilter; + private List mapping; + private int topK = 2; + + /** + * Registers the query vectors to be passed in the search call. + * + * @param queryVectors 2D float query vector array + * @return an instance of this Builder + */ + public Builder withQueryVectors(float[][] queryVectors) { + this.queryVectors = queryVectors; + return this; + } + + /** + * Sets the instance of mapping to be used for ID mapping. + * + * @param mapping the ID mapping instance + * @return an instance of this Builder + */ + public Builder withMapping(List mapping) { + this.mapping = mapping; + return this; + } + + /** + * Registers the topK value. + * + * @param topK the topK value used to retrieve the topK results + * @return an instance of this Builder + */ + public Builder withTopK(int topK) { + this.topK = topK; + return this; + } + + /** + * Sets the prefilter data for building the {@link BruteForceQuery}. + * + * @param prefilter a one-dimensional long array + * @return an instance of this Builder + */ + public Builder withPrefilter(long[] prefilter) { + this.prefilter = prefilter; + return this; + } + + /** + * Builds an instance of {@link BruteForceQuery} + * + * @return an instance of {@link BruteForceQuery} + */ + public BruteForceQuery build() { + return new BruteForceQuery(queryVectors, mapping, topK, prefilter); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceSearchResults.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceSearchResults.java new file mode 100644 index 000000000..b87e1f601 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceSearchResults.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.nvidia.cuvs.common.SearchResults; + +/** + * SearchResult encapsulates the logic for reading and holding search results. + * + * @since 25.02 + */ +public class BruteForceSearchResults extends SearchResults { + + protected BruteForceSearchResults(SequenceLayout neighboursSequenceLayout, SequenceLayout distancesSequenceLayout, + MemorySegment neighboursMemorySegment, MemorySegment distancesMemorySegment, int topK, List mapping, + long numberOfQueries) { + super(neighboursSequenceLayout, distancesSequenceLayout, neighboursMemorySegment, distancesMemorySegment, topK, + mapping, numberOfQueries); + readResultMemorySegments(); + } + + /** + * Reads neighbors and distances {@link MemorySegment} and loads the values + * internally + */ + protected void readResultMemorySegments() { + Map intermediateResultMap = new LinkedHashMap(); + int count = 0; + for (long i = 0; i < topK * numberOfQueries; i++) { + long id = (long) neighboursVarHandle.get(neighboursMemorySegment, 0L, i); + float dst = (float) distancesVarHandle.get(distancesMemorySegment, 0L, i); + intermediateResultMap.put(mapping != null ? mapping.get((int) id) : (int) id, dst); + count += 1; + if (count == topK) { + results.add(intermediateResultMap); + intermediateResultMap = new LinkedHashMap(); + count = 0; + } + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java new file mode 100644 index 000000000..09f6bae8b --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; + +import com.nvidia.cuvs.panama.CuVSCagraCompressionParams; + +/** + * Supplemental compression parameters to build CAGRA Index. + * + * @since 25.02 + */ +public class CagraCompressionParams { + + private final MemorySegment memorySegment; + private CuVSResources resources; + private final int pqBits; + private final int pqDim; + private final int vqNCenters; + private final int kmeansNIters; + private final double vqKmeansTrainsetFraction; + private final double pqKmeansTrainsetFraction; + + /** + * Constructs an instance of CagraCompressionParams with passed search + * parameters. + * + * @param resources the resources instance to use + * @param pqBits the bit length of the vector element after + * compression by PQ + * @param pqDim the dimensionality of the vector after + * compression by PQ + * @param vqNCenters the vector quantization (VQ) codebook size - + * number of “coarse cluster centers” + * @param kmeansNIters the number of iterations searching for kmeans + * centers (both VQ and PQ phases) + * @param vqKmeansTrainsetFraction the fraction of data to use during iterative + * kmeans building (VQ phase) + * @param pqKmeansTrainsetFraction the fraction of data to use during iterative + * kmeans building (PQ phase) + */ + private CagraCompressionParams(CuVSResources resources, int pqBits, int pqDim, int vqNCenters, int kmeansNIters, + double vqKmeansTrainsetFraction, double pqKmeansTrainsetFraction) { + this.resources = resources; + this.pqBits = pqBits; + this.pqDim = pqDim; + this.vqNCenters = vqNCenters; + this.kmeansNIters = kmeansNIters; + this.vqKmeansTrainsetFraction = vqKmeansTrainsetFraction; + this.pqKmeansTrainsetFraction = pqKmeansTrainsetFraction; + this.memorySegment = initMemorySegment(); + } + + /** + * Allocates the configured compression parameters in the MemorySegment. + */ + private MemorySegment initMemorySegment() { + MemorySegment compressionParamsMemorySegment = CuVSCagraCompressionParams.allocate(resources.arena); + CuVSCagraCompressionParams.pq_bits(compressionParamsMemorySegment, pqBits); + CuVSCagraCompressionParams.pq_dim(compressionParamsMemorySegment, pqDim); + CuVSCagraCompressionParams.vq_n_centers(compressionParamsMemorySegment, vqNCenters); + CuVSCagraCompressionParams.kmeans_n_iters(compressionParamsMemorySegment, kmeansNIters); + CuVSCagraCompressionParams.vq_kmeans_trainset_fraction(compressionParamsMemorySegment, vqKmeansTrainsetFraction); + CuVSCagraCompressionParams.pq_kmeans_trainset_fraction(compressionParamsMemorySegment, pqKmeansTrainsetFraction); + return compressionParamsMemorySegment; + } + + /** + * Gets the memory segment instance containing the compression parameters. + * + * @return the memory segment instance containing the compression parameters. + */ + protected MemorySegment getMemorySegment() { + return memorySegment; + } + + /** + * Gets the bit length of the vector element after compression by PQ. + * + * @return the bit length of the vector element after compression by PQ. + */ + public int getPqBits() { + return pqBits; + } + + /** + * Gets the dimensionality of the vector after compression by PQ. + * + * @return the dimensionality of the vector after compression by PQ. + */ + public int getPqDim() { + return pqDim; + } + + /** + * Gets the vector quantization (VQ) codebook size - number of “coarse cluster + * centers”. + * + * @return the vector quantization (VQ) codebook size - number of “coarse + * cluster centers”. + */ + public int getVqNCenters() { + return vqNCenters; + } + + /** + * Gets the number of iterations searching for kmeans centers (both VQ and PQ + * phases). + * + * @return the number of iterations searching for kmeans centers (both VQ and PQ + * phases). + */ + public int getKmeansNIters() { + return kmeansNIters; + } + + /** + * Gets the fraction of data to use during iterative kmeans building (VQ phase). + * + * @return the fraction of data to use during iterative kmeans building (VQ + * phase). + */ + public double getVqKmeansTrainsetFraction() { + return vqKmeansTrainsetFraction; + } + + /** + * Gets the fraction of data to use during iterative kmeans building (PQ phase). + * + * @return the fraction of data to use during iterative kmeans building (PQ + * phase). + */ + public double getPqKmeansTrainsetFraction() { + return pqKmeansTrainsetFraction; + } + + @Override + public String toString() { + return "CagraCompressionParams [pqBits=" + pqBits + ", pqDim=" + pqDim + ", vqNCenters=" + vqNCenters + + ", kmeansNIters=" + kmeansNIters + ", vqKmeansTrainsetFraction=" + vqKmeansTrainsetFraction + + ", pqKmeansTrainsetFraction=" + pqKmeansTrainsetFraction + "]"; + } + + /** + * Builder configures and creates an instance of {@link CagraCompressionParams}. + */ + public static class Builder { + + private CuVSResources resources; + private int pqBits = 8; + private int pqDim = 0; + private int vqNCenters = 0; + private int kmeansNIters = 25; + private double vqKmeansTrainsetFraction = 0; + private double pqKmeansTrainsetFraction = 0; + + public Builder(CuVSResources resources) { + this.resources = resources; + } + + /** + * Sets the bit length of the vector element after compression by PQ. + * + * Possible values: [4, 5, 6, 7, 8]. Hint: the smaller the ‘pq_bits’, the + * smaller the index size and the better the search performance, but the lower + * the recall. + * + * @param pqBits + * @return an instance of Builder + */ + public Builder withPqBits(int pqBits) { + this.pqBits = pqBits; + return this; + } + + /** + * Sets the dimensionality of the vector after compression by PQ. + * + * When zero, an optimal value is selected using a heuristic. + * + * @param pqDim + * @return an instance of Builder + */ + public Builder withPqDim(int pqDim) { + this.pqDim = pqDim; + return this; + } + + /** + * Sets the vector quantization (VQ) codebook size - number of “coarse cluster + * centers”. + * + * When zero, an optimal value is selected using a heuristic. + * + * @param vqNCenters + * @return an instance of Builder + */ + public Builder withVqNCenters(int vqNCenters) { + this.vqNCenters = vqNCenters; + return this; + } + + /** + * Sets the number of iterations searching for kmeans centers (both VQ and PQ + * phases). + * + * @param kmeansNIters + * @return an instance of Builder + */ + public Builder withKmeansNIters(int kmeansNIters) { + this.kmeansNIters = kmeansNIters; + return this; + } + + /** + * Sets the fraction of data to use during iterative kmeans building (VQ phase). + * + * When zero, an optimal value is selected using a heuristic. + * + * @param vqKmeansTrainsetFraction + * @return an instance of Builder + */ + public Builder withVqKmeansTrainsetFraction(double vqKmeansTrainsetFraction) { + this.vqKmeansTrainsetFraction = vqKmeansTrainsetFraction; + return this; + } + + /** + * Sets the fraction of data to use during iterative kmeans building (PQ phase). + * + * When zero, an optimal value is selected using a heuristic. + * + * @param pqKmeansTrainsetFraction + * @return an instance of Builder + */ + public Builder withPqKmeansTrainsetFraction(double pqKmeansTrainsetFraction) { + this.pqKmeansTrainsetFraction = pqKmeansTrainsetFraction; + return this; + } + + /** + * Builds an instance of {@link CagraCompressionParams}. + * + * @return an instance of {@link CagraCompressionParams} + */ + public CagraCompressionParams build() { + return new CagraCompressionParams(resources, pqBits, pqDim, vqNCenters, kmeansNIters, vqKmeansTrainsetFraction, + pqKmeansTrainsetFraction); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java new file mode 100644 index 000000000..21eea9783 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.UUID; + +import com.nvidia.cuvs.common.Util; +import com.nvidia.cuvs.panama.CuVSCagraIndex; + +/** + * {@link CagraIndex} encapsulates a CAGRA index, along with methods to interact + * with it. + *

+ * CAGRA is a graph-based nearest neighbors algorithm that was built from the + * ground up for GPU acceleration. CAGRA demonstrates state-of-the art index + * build and query performance for both small and large-batch sized search. Know + * more about this algorithm + * here + * + * @since 25.02 + */ +public class CagraIndex { + + private final float[][] dataset; + private final CuVSResources resources; + private MethodHandle indexMethodHandle; + private MethodHandle searchMethodHandle; + private MethodHandle serializeMethodHandle; + private MethodHandle deserializeMethodHandle; + private MethodHandle destroyIndexMethodHandle; + private MethodHandle serializeCAGRAIndexToHNSWMethodHandle; + private CagraIndexParams cagraIndexParameters; + private CagraCompressionParams cagraCompressionParams; + private IndexReference cagraIndexReference; + private MemoryLayout longMemoryLayout; + private MemoryLayout intMemoryLayout; + private MemoryLayout floatMemoryLayout; + + /** + * Constructor for building the index using specified dataset + * + * @param indexParameters an instance of {@link CagraIndexParams} holding + * the index parameters + * @param cagraCompressionParams an instance of {@link CagraCompressionParams} + * holding the compression parameters + * @param dataset the dataset for indexing + * @param resources an instance of {@link CuVSResources} + */ + private CagraIndex(CagraIndexParams indexParameters, CagraCompressionParams cagraCompressionParams, float[][] dataset, + CuVSResources resources) throws Throwable { + this.cagraIndexParameters = indexParameters; + this.cagraCompressionParams = cagraCompressionParams; + this.dataset = dataset; + this.resources = resources; + + longMemoryLayout = resources.linker.canonicalLayouts().get("long"); + intMemoryLayout = resources.linker.canonicalLayouts().get("int"); + floatMemoryLayout = resources.linker.canonicalLayouts().get("float"); + + initializeMethodHandles(); + this.cagraIndexReference = build(); + } + + /** + * Constructor for loading the index from an {@link InputStream} + * + * @param inputStream an instance of stream to read the index bytes from + * @param resources an instance of {@link CuVSResources} + */ + private CagraIndex(InputStream inputStream, CuVSResources resources) throws Throwable { + this.cagraIndexParameters = null; + this.cagraCompressionParams = null; + this.dataset = null; + this.resources = resources; + + longMemoryLayout = resources.linker.canonicalLayouts().get("long"); + intMemoryLayout = resources.linker.canonicalLayouts().get("int"); + floatMemoryLayout = resources.linker.canonicalLayouts().get("float"); + + initializeMethodHandles(); + this.cagraIndexReference = deserialize(inputStream); + } + + /** + * Initializes the {@link MethodHandles} for invoking native methods. + * + * @throws IOException @{@link IOException} is unable to load the native library + */ + private void initializeMethodHandles() throws IOException { + indexMethodHandle = resources.linker.downcallHandle(resources.getSymbolLookup().find("build_cagra_index").get(), + FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS, longMemoryLayout, longMemoryLayout, + ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, intMemoryLayout)); + + searchMethodHandle = resources.linker.downcallHandle(resources.getSymbolLookup().find("search_cagra_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, intMemoryLayout, longMemoryLayout, + intMemoryLayout, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, + ValueLayout.ADDRESS)); + + serializeMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("serialize_cagra_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + deserializeMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("deserialize_cagra_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + destroyIndexMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("destroy_cagra_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + serializeCAGRAIndexToHNSWMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("serialize_cagra_index_to_hnsw").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + } + + /** + * Invokes the native destroy_cagra_index to de-allocate the CAGRA index + */ + public void destroyIndex() throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + destroyIndexMethodHandle.invokeExact(cagraIndexReference.getMemorySegment(), returnValueMemorySegment); + } + + /** + * Invokes the native build_cagra_index function via the Panama API to build the + * {@link CagraIndex} + * + * @return an instance of {@link IndexReference} that holds the pointer to the + * index + */ + private IndexReference build() throws Throwable { + long rows = dataset.length; + long cols = rows > 0 ? dataset[0].length : 0; + + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + + MemorySegment indexParamsMemorySegment = cagraIndexParameters != null ? cagraIndexParameters.getMemorySegment() + : MemorySegment.NULL; + + int numWriterThreads = cagraIndexParameters != null ? cagraIndexParameters.getNumWriterThreads() : 1; + + MemorySegment compressionParamsMemorySegment = cagraCompressionParams != null + ? cagraCompressionParams.getMemorySegment() + : MemorySegment.NULL; + + IndexReference indexReference = new IndexReference((MemorySegment) indexMethodHandle.invokeExact( + Util.buildMemorySegment(resources.linker, resources.arena, dataset), rows, cols, resources.getMemorySegment(), + returnValueMemorySegment, indexParamsMemorySegment, compressionParamsMemorySegment, numWriterThreads)); + + return indexReference; + } + + /** + * Invokes the native search_cagra_index via the Panama API for searching a + * CAGRA index. + * + * @param query an instance of {@link CagraQuery} holding the query vectors and + * other parameters + * @return an instance of {@link CagraSearchResults} containing the results + */ + public CagraSearchResults search(CagraQuery query) throws Throwable { + int topK = query.getMapping() != null ? Math.min(query.getMapping().size(), query.getTopK()) : query.getTopK(); + long numQueries = query.getQueryVectors().length; + long numBlocks = topK * numQueries; + int vectorDimension = numQueries > 0 ? query.getQueryVectors()[0].length : 0; + + SequenceLayout neighborsSequenceLayout = MemoryLayout.sequenceLayout(numBlocks, intMemoryLayout); + SequenceLayout distancesSequenceLayout = MemoryLayout.sequenceLayout(numBlocks, floatMemoryLayout); + MemorySegment neighborsMemorySegment = resources.arena.allocate(neighborsSequenceLayout); + MemorySegment distancesMemorySegment = resources.arena.allocate(distancesSequenceLayout); + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + + searchMethodHandle.invokeExact(cagraIndexReference.getMemorySegment(), + Util.buildMemorySegment(resources.linker, resources.arena, query.getQueryVectors()), topK, numQueries, + vectorDimension, resources.getMemorySegment(), neighborsMemorySegment, distancesMemorySegment, + returnValueMemorySegment, query.getCagraSearchParameters().getMemorySegment()); + + return new CagraSearchResults(neighborsSequenceLayout, distancesSequenceLayout, neighborsMemorySegment, + distancesMemorySegment, topK, query.getMapping(), numQueries); + } + + /** + * A method to persist a CAGRA index using an instance of {@link OutputStream} + * for writing index bytes. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes into + */ + public void serialize(OutputStream outputStream) throws Throwable { + serialize(outputStream, File.createTempFile(UUID.randomUUID().toString(), ".cag"), 1024); + } + + /** + * A method to persist a CAGRA index using an instance of {@link OutputStream} + * for writing index bytes. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes into + * @param bufferLength the length of buffer to use for writing bytes. Default + * value is 1024 + */ + public void serialize(OutputStream outputStream, int bufferLength) throws Throwable { + serialize(outputStream, File.createTempFile(UUID.randomUUID().toString(), ".cag"), bufferLength); + } + + /** + * A method to persist a CAGRA index using an instance of {@link OutputStream} + * for writing index bytes. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes into + * @param tempFile an intermediate {@link File} where CAGRA index is written + * temporarily + */ + public void serialize(OutputStream outputStream, File tempFile) throws Throwable { + serialize(outputStream, tempFile, 1024); + } + + /** + * A method to persist a CAGRA index using an instance of {@link OutputStream} + * and path to the intermediate temporary file. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes to + * @param tempFile an intermediate {@link File} where CAGRA index is written + * temporarily + * @param bufferLength the length of buffer to use for writing bytes. Default + * value is 1024 + */ + public void serialize(OutputStream outputStream, File tempFile, int bufferLength) throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + serializeMethodHandle.invokeExact(resources.getMemorySegment(), cagraIndexReference.getMemorySegment(), + returnValueMemorySegment, + Util.buildMemorySegment(resources.linker, resources.arena, tempFile.getAbsolutePath())); + FileInputStream fileInputStream = new FileInputStream(tempFile); + byte[] chunk = new byte[bufferLength]; + int chunkLength = 0; + while ((chunkLength = fileInputStream.read(chunk)) != -1) { + outputStream.write(chunk, 0, chunkLength); + } + fileInputStream.close(); + tempFile.delete(); + } + + /** + * A method to create and persist HNSW index from CAGRA index using an instance + * of {@link OutputStream} and path to the intermediate temporary file. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes to + */ + public void serializeToHNSW(OutputStream outputStream) throws Throwable { + serializeToHNSW(outputStream, File.createTempFile(UUID.randomUUID().toString(), ".hnsw"), 1024); + } + + /** + * A method to create and persist HNSW index from CAGRA index using an instance + * of {@link OutputStream} and path to the intermediate temporary file. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes to + * @param bufferLength the length of buffer to use for writing bytes. Default + * value is 1024 + */ + public void serializeToHNSW(OutputStream outputStream, int bufferLength) throws Throwable { + serializeToHNSW(outputStream, File.createTempFile(UUID.randomUUID().toString(), ".hnsw"), bufferLength); + } + + /** + * A method to create and persist HNSW index from CAGRA index using an instance + * of {@link OutputStream} and path to the intermediate temporary file. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes to + * @param tempFile an intermediate {@link File} where CAGRA index is written + * temporarily + */ + public void serializeToHNSW(OutputStream outputStream, File tempFile) throws Throwable { + serializeToHNSW(outputStream, tempFile, 1024); + } + + /** + * A method to create and persist HNSW index from CAGRA index using an instance + * of {@link OutputStream} and path to the intermediate temporary file. + * + * @param outputStream an instance of {@link OutputStream} to write the index + * bytes to + * @param tempFile an intermediate {@link File} where CAGRA index is written + * temporarily + * @param bufferLength the length of buffer to use for writing bytes. Default + * value is 1024 + */ + public void serializeToHNSW(OutputStream outputStream, File tempFile, int bufferLength) throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + serializeCAGRAIndexToHNSWMethodHandle.invokeExact(resources.getMemorySegment(), + Util.buildMemorySegment(resources.linker, resources.arena, tempFile.getAbsolutePath()), + cagraIndexReference.getMemorySegment(), returnValueMemorySegment); + FileInputStream fileInputStream = new FileInputStream(tempFile); + byte[] chunk = new byte[bufferLength]; + int chunkLength = 0; + while ((chunkLength = fileInputStream.read(chunk)) != -1) { + outputStream.write(chunk, 0, chunkLength); + } + fileInputStream.close(); + tempFile.delete(); + } + + /** + * Gets an instance of {@link IndexReference} by deserializing a CAGRA index + * using an {@link InputStream}. + * + * @param inputStream an instance of {@link InputStream} + * @return an instance of {@link IndexReference}. + */ + private IndexReference deserialize(InputStream inputStream) throws Throwable { + return deserialize(inputStream, 1024); + } + + /** + * Gets an instance of {@link IndexReference} by deserializing a CAGRA index + * using an {@link InputStream}. + * + * @param inputStream an instance of {@link InputStream} + * @param bufferLength the length of the buffer to use while reading the bytes + * from the stream. Default value is 1024. + * @return an instance of {@link IndexReference}. + */ + private IndexReference deserialize(InputStream inputStream, int bufferLength) throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + String tmpIndexFile = "/tmp/" + UUID.randomUUID().toString() + ".cag"; + IndexReference indexReference = new IndexReference(resources); + + File tempFile = new File(tmpIndexFile); + FileOutputStream fileOutputStream = new FileOutputStream(tempFile); + byte[] chunk = new byte[bufferLength]; + int chunkLength = 0; + while ((chunkLength = inputStream.read(chunk)) != -1) { + fileOutputStream.write(chunk, 0, chunkLength); + } + deserializeMethodHandle.invokeExact(resources.getMemorySegment(), indexReference.getMemorySegment(), + returnValueMemorySegment, Util.buildMemorySegment(resources.linker, resources.arena, tmpIndexFile)); + + inputStream.close(); + fileOutputStream.close(); + tempFile.delete(); + + return indexReference; + } + + /** + * Gets an instance of {@link CagraIndexParams} + * + * @return an instance of {@link CagraIndexParams} + */ + public CagraIndexParams getCagraIndexParameters() { + return cagraIndexParameters; + } + + /** + * Gets an instance of {@link CuVSResources} + * + * @return an instance of {@link CuVSResources} + */ + public CuVSResources getCuVSResources() { + return resources; + } + + /** + * Builder helps configure and create an instance of {@link CagraIndex}. + */ + public static class Builder { + + private float[][] dataset; + private CagraIndexParams cagraIndexParams; + private CagraCompressionParams cagraCompressionParams; + private CuVSResources cuvsResources; + private InputStream inputStream; + + /** + * Constructs this Builder with an instance of {@link CuVSResources}. + * + * @param cuvsResources an instance of {@link CuVSResources} + */ + public Builder(CuVSResources cuvsResources) { + this.cuvsResources = cuvsResources; + } + + /** + * Sets an instance of InputStream typically used when index deserialization is + * needed. + * + * @param inputStream an instance of {@link InputStream} + * @return an instance of this Builder + */ + public Builder from(InputStream inputStream) { + this.inputStream = inputStream; + return this; + } + + /** + * Sets the dataset for building the {@link CagraIndex}. + * + * @param dataset a two-dimensional float array + * @return an instance of this Builder + */ + public Builder withDataset(float[][] dataset) { + this.dataset = dataset; + return this; + } + + /** + * Registers an instance of configured {@link CagraIndexParams} with this + * Builder. + * + * @param cagraIndexParameters An instance of CagraIndexParams. + * @return An instance of this Builder. + */ + public Builder withIndexParams(CagraIndexParams cagraIndexParameters) { + this.cagraIndexParams = cagraIndexParameters; + return this; + } + + /** + * Registers an instance of configured {@link CagraCompressionParams} with this + * Builder. + * + * @param cagraCompressionParams An instance of CagraCompressionParams. + * @return An instance of this Builder. + */ + public Builder withCompressionParams(CagraCompressionParams cagraCompressionParams) { + this.cagraCompressionParams = cagraCompressionParams; + return this; + } + + /** + * Builds and returns an instance of CagraIndex. + * + * @return an instance of CagraIndex + */ + public CagraIndex build() throws Throwable { + if (inputStream != null) { + return new CagraIndex(inputStream, cuvsResources); + } else { + return new CagraIndex(cagraIndexParams, cagraCompressionParams, dataset, cuvsResources); + } + } + } + + /** + * Holds the memory reference to a CAGRA index. + */ + protected static class IndexReference { + + private final MemorySegment memorySegment; + + /** + * Constructs CagraIndexReference and allocate the MemorySegment. + */ + protected IndexReference(CuVSResources resources) { + memorySegment = CuVSCagraIndex.allocate(resources.arena); + } + + /** + * Constructs CagraIndexReference with an instance of MemorySegment passed as a + * parameter. + * + * @param indexMemorySegment the MemorySegment instance to use for containing + * index reference + */ + protected IndexReference(MemorySegment indexMemorySegment) { + this.memorySegment = indexMemorySegment; + } + + /** + * Gets the instance of index MemorySegment. + * + * @return index MemorySegment + */ + protected MemorySegment getMemorySegment() { + return memorySegment; + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java new file mode 100644 index 000000000..767ee281b --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; + +import com.nvidia.cuvs.panama.CuVSCagraIndexParams; + +/** + * Supplemental parameters to build CAGRA Index. + * + * @since 25.02 + */ +public class CagraIndexParams { + + private final CagraGraphBuildAlgo cuvsCagraGraphBuildAlgo; + private final CuvsDistanceType cuvsDistanceType; + private final MemorySegment memorySegment; + private CuVSResources resources; + private final int intermediateGraphDegree; + private final int graphDegree; + private final int nnDescentNiter; + private final int numWriterThreads; + + /** + * Enum that denotes which ANN algorithm is used to build CAGRA graph. + */ + public enum CagraGraphBuildAlgo { + /** + * Select build algorithm automatically + */ + AUTO_SELECT(0), + /** + * Use IVF-PQ to build all-neighbors knn graph + */ + IVF_PQ(1), + /** + * Experimental, use NN-Descent to build all-neighbors knn graph + */ + NN_DESCENT(2); + + /** + * The value for the enum choice. + */ + public final int value; + + private CagraGraphBuildAlgo(int value) { + this.value = value; + } + } + + /** + * Enum that denotes how to compute distance. + */ + public enum CuvsDistanceType { + + /** + * evaluate as dist_ij = sum(x_ik^2) + sum(y_ij)^2 - 2*sum(x_ik * y_jk) + */ + L2Expanded(0), + /** + * same as above, but inside the epilogue, perform square root operation + */ + L2SqrtExpanded(1), + /** + * cosine distance + */ + CosineExpanded(2), + /** + * L1 distance * + */ + L1(3), + /** + * evaluate as dist_ij += (x_ik - y-jk)^2 * + */ + L2Unexpanded(4), + /** + * same as above, but inside the epilogue, perform square root operation + */ + L2SqrtUnexpanded(5), + /** + * basic inner product + */ + InnerProduct(6), + /** + * Chebyshev (Linf) distance + */ + Linf(7), + /** + * Canberra distance + */ + Canberra(8), + /** + * Generalized Minkowski distance + */ + LpUnexpanded(9), + /** + * Correlation distance + */ + CorrelationExpanded(10), + /** + * Jaccard distance + */ + JaccardExpanded(11), + /** + * Hellinger distance + */ + HellingerExpanded(12), + /** + * Haversine distance + */ + Haversine(13), + /** + * Bray-Curtis distance + */ + BrayCurtis(14), + /** + * Jensen-Shannon distance + */ + JensenShannon(15), + /** + * Hamming distance + */ + HammingUnexpanded(16), + /** + * KLDivergence + */ + KLDivergence(17), + /** + * RusselRao + */ + RusselRaoExpanded(18), + /** + * Dice-Sorensen distance + */ + DiceExpanded(19), + /** + * Precomputed (special value) + */ + Precomputed(100); + + /** + * The value for the enum choice. + */ + public final int value; + + private CuvsDistanceType(int value) { + this.value = value; + } + + } + + private CagraIndexParams(CuVSResources resources, int intermediateGraphDegree, int graphDegree, + CagraGraphBuildAlgo CuvsCagraGraphBuildAlgo, int nnDescentNiter, int writerThreads, + CuvsDistanceType cuvsDistanceType) { + this.resources = resources; + this.intermediateGraphDegree = intermediateGraphDegree; + this.graphDegree = graphDegree; + this.cuvsCagraGraphBuildAlgo = CuvsCagraGraphBuildAlgo; + this.nnDescentNiter = nnDescentNiter; + this.numWriterThreads = writerThreads; + this.cuvsDistanceType = cuvsDistanceType; + + this.memorySegment = initMemorySegment(); + } + + private MemorySegment initMemorySegment() { + MemorySegment indexParamsMemorySegment = CuVSCagraIndexParams.allocate(resources.arena); + CuVSCagraIndexParams.intermediate_graph_degree(indexParamsMemorySegment, intermediateGraphDegree); + CuVSCagraIndexParams.graph_degree(indexParamsMemorySegment, graphDegree); + CuVSCagraIndexParams.build_algo(indexParamsMemorySegment, cuvsCagraGraphBuildAlgo.value); + CuVSCagraIndexParams.nn_descent_niter(indexParamsMemorySegment, nnDescentNiter); + CuVSCagraIndexParams.metric(indexParamsMemorySegment, cuvsDistanceType.value); + return indexParamsMemorySegment; + } + + /** + * Gets the degree of input graph for pruning. + * + * @return the degree of input graph + */ + public int getIntermediateGraphDegree() { + return intermediateGraphDegree; + } + + /** + * Gets the degree of output graph. + * + * @return the degree of output graph + */ + public int getGraphDegree() { + return graphDegree; + } + + /** + * Gets the {@link CagraGraphBuildAlgo} used to build the index. + */ + public CagraGraphBuildAlgo getCagraGraphBuildAlgo() { + return cuvsCagraGraphBuildAlgo; + } + + /** + * Gets the number of iterations to run if building with + * {@link CagraGraphBuildAlgo#NN_DESCENT} + */ + public int getNNDescentNumIterations() { + return nnDescentNiter; + } + + protected MemorySegment getMemorySegment() { + return memorySegment; + } + + /** + * Gets the {@link CuvsDistanceType} used to build the index. + */ + public CuvsDistanceType getCuvsDistanceType() { + return cuvsDistanceType; + } + + /** + * Gets the number of threads used to build the index. + */ + public int getNumWriterThreads() { + return numWriterThreads; + } + + @Override + public String toString() { + return "CagraIndexParams [cuvsCagraGraphBuildAlgo=" + cuvsCagraGraphBuildAlgo + ", cuvsDistanceType=" + + cuvsDistanceType + ", intermediateGraphDegree=" + intermediateGraphDegree + ", graphDegree=" + graphDegree + + ", nnDescentNiter=" + nnDescentNiter + ", numWriterThreads=" + numWriterThreads + "]"; + } + + /** + * Builder configures and creates an instance of {@link CagraIndexParams}. + */ + public static class Builder { + + private CuVSResources resources; + private CagraGraphBuildAlgo cuvsCagraGraphBuildAlgo = CagraGraphBuildAlgo.NN_DESCENT; + private CuvsDistanceType cuvsDistanceType = CuvsDistanceType.L2Expanded; + private int intermediateGraphDegree = 128; + private int graphDegree = 64; + private int nnDescentNumIterations = 20; + private int numWriterThreads = 2; + + public Builder(CuVSResources resources) { + this.resources = resources; + } + + /** + * Sets the degree of input graph for pruning. + * + * @param intermediateGraphDegree degree of input graph for pruning + * @return an instance of Builder + */ + public Builder withIntermediateGraphDegree(int intermediateGraphDegree) { + this.intermediateGraphDegree = intermediateGraphDegree; + return this; + } + + /** + * Sets the degree of output graph. + * + * @param graphDegree degree of output graph + * @return an instance to Builder + */ + public Builder withGraphDegree(int graphDegree) { + this.graphDegree = graphDegree; + return this; + } + + /** + * Sets the CuvsCagraGraphBuildAlgo to use. + * + * @param cuvsCagraGraphBuildAlgo the CuvsCagraGraphBuildAlgo to use + * @return an instance of Builder + */ + public Builder withCagraGraphBuildAlgo(CagraGraphBuildAlgo cuvsCagraGraphBuildAlgo) { + this.cuvsCagraGraphBuildAlgo = cuvsCagraGraphBuildAlgo; + return this; + } + + /** + * Sets the metric to use. + * + * @param cuvsDistanceType the {@link CuvsDistanceType} to use + * @return an instance of Builder + */ + public Builder withMetric(CuvsDistanceType cuvsDistanceType) { + this.cuvsDistanceType = cuvsDistanceType; + return this; + } + + /** + * Sets the Number of Iterations to run if building with + * {@link CagraGraphBuildAlgo#NN_DESCENT}. + * + * @param nnDescentNiter number of Iterations to run if building with + * {@link CagraGraphBuildAlgo#NN_DESCENT} + * @return an instance of Builder + */ + public Builder withNNDescentNumIterations(int nnDescentNiter) { + this.nnDescentNumIterations = nnDescentNiter; + return this; + } + + /** + * Sets the number of writer threads to use for indexing. + * + * @param numWriterThreads number of writer threads to use + * @return an instance of Builder + */ + public Builder withNumWriterThreads(int numWriterThreads) { + this.numWriterThreads = numWriterThreads; + return this; + } + + /** + * Builds an instance of {@link CagraIndexParams}. + * + * @return an instance of {@link CagraIndexParams} + */ + public CagraIndexParams build() { + return new CagraIndexParams(resources, intermediateGraphDegree, graphDegree, cuvsCagraGraphBuildAlgo, + nnDescentNumIterations, numWriterThreads, cuvsDistanceType); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java new file mode 100644 index 000000000..de2fc3f41 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.util.Arrays; +import java.util.List; + +/** + * CagraQuery holds the CagraSearchParams and the query vectors to be used while + * invoking search. + * + * @since 25.02 + */ +public class CagraQuery { + + private CagraSearchParams cagraSearchParameters; + private List mapping; + private float[][] queryVectors; + private int topK; + + /** + * Constructs an instance of {@link CagraQuery} using cagraSearchParameters, + * preFilter, queryVectors, mapping, and topK. + * + * @param cagraSearchParameters an instance of {@link CagraSearchParams} holding + * the search parameters + * @param queryVectors 2D float query vector array + * @param mapping an instance of ID mapping + * @param topK the top k results to return + */ + public CagraQuery(CagraSearchParams cagraSearchParameters, float[][] queryVectors, List mapping, int topK) { + super(); + this.cagraSearchParameters = cagraSearchParameters; + this.queryVectors = queryVectors; + this.mapping = mapping; + this.topK = topK; + } + + /** + * Gets the instance of CagraSearchParams initially set. + * + * @return an instance CagraSearchParams + */ + public CagraSearchParams getCagraSearchParameters() { + return cagraSearchParameters; + } + + /** + * Gets the query vector 2D float array. + * + * @return 2D float array + */ + public float[][] getQueryVectors() { + return queryVectors; + } + + /** + * Gets the passed map instance. + * + * @return a map of ID mappings + */ + public List getMapping() { + return mapping; + } + + /** + * Gets the topK value. + * + * @return the topK value + */ + public int getTopK() { + return topK; + } + + @Override + public String toString() { + return "CuVSQuery [cagraSearchParameters=" + cagraSearchParameters + ", queryVectors=" + + Arrays.toString(queryVectors) + ", mapping=" + mapping + ", topK=" + topK + "]"; + } + + /** + * Builder helps configure and create an instance of CagraQuery. + */ + public static class Builder { + + private CagraSearchParams cagraSearchParams; + private float[][] queryVectors; + private List mapping; + private int topK = 2; + + /** + * Default constructor. + */ + public Builder() { + } + + /** + * Sets the instance of configured CagraSearchParams to be passed for search. + * + * @param cagraSearchParams an instance of the configured CagraSearchParams to + * be used for this query + * @return an instance of this Builder + */ + public Builder withSearchParams(CagraSearchParams cagraSearchParams) { + this.cagraSearchParams = cagraSearchParams; + return this; + } + + /** + * Registers the query vectors to be passed in the search call. + * + * @param queryVectors 2D float query vector array + * @return an instance of this Builder + */ + public Builder withQueryVectors(float[][] queryVectors) { + this.queryVectors = queryVectors; + return this; + } + + /** + * Sets the instance of mapping to be used for ID mapping. + * + * @param mapping the ID mapping instance + * @return an instance of this Builder + */ + public Builder withMapping(List mapping) { + this.mapping = mapping; + return this; + } + + /** + * Registers the topK value. + * + * @param topK the topK value used to retrieve the topK results + * @return an instance of this Builder + */ + public Builder withTopK(int topK) { + this.topK = topK; + return this; + } + + /** + * Builds an instance of CuVSQuery. + * + * @return an instance of CuVSQuery + */ + public CagraQuery build() { + return new CagraQuery(cagraSearchParams, queryVectors, mapping, topK); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java new file mode 100644 index 000000000..54dbb548e --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; + +import com.nvidia.cuvs.panama.CuVSCagraSearchParams; + +/** + * CagraSearchParams encapsulates the logic for configuring and holding search + * parameters. + * + * @since 25.02 + */ +public class CagraSearchParams { + + private CuVSResources resources; + private int maxQueries; + private int iTopKSize; + private int maxIterations; + private int teamSize; + private int searchWidth; + private int minIterations; + private int threadBlockSize; + private int hashmapMinBitlen; + private int numRandomSamplings; + private float hashMapMaxFillRate; + private long randXORMask; + private MemorySegment memorySegment; + private SearchAlgo searchAlgo; + private HashMapMode hashMapMode; + + /** + * Enum to denote algorithm used to search CAGRA Index. + */ + public enum SearchAlgo { + /** + * for large batch sizes + */ + SINGLE_CTA(0), + /** + * for small batch sizes + */ + MULTI_CTA(1), + /** + * MULTI_KERNEL + */ + MULTI_KERNEL(2), + /** + * AUTO + */ + AUTO(3); + + /** + * The value for the enum choice. + */ + public final int value; + + private SearchAlgo(int value) { + this.value = value; + } + } + + /** + * Enum to denote Hash Mode used while searching CAGRA index. + */ + public enum HashMapMode { + /** + * HASH + */ + HASH(0), + /** + * SMALL + */ + SMALL(1), + /** + * AUTO_HASH + */ + AUTO_HASH(2); + + /** + * The value for the enum choice. + */ + public final int value; + + private HashMapMode(int value) { + this.value = value; + } + } + + /** + * Constructs an instance of CagraSearchParams with passed search parameters. + * + * @param resources the resources instance to use + * @param maxQueries the maximum number of queries to search at the same + * time (batch size) + * @param iTopKSize the number of intermediate search results retained + * during the search + * @param maxIterations the upper limit of search iterations + * @param searchAlgo the search implementation is configured + * @param teamSize the number of threads used to calculate a single + * distance + * @param searchWidth the number of graph nodes to select as the starting + * point for the search in each iteration + * @param minIterations the lower limit of search iterations + * @param threadBlockSize the thread block size + * @param hashmapMode the hash map type configured + * @param hashmapMinBitlen the lower limit of hash map bit length + * @param hashmapMaxFillRate the upper limit of hash map fill rate + * @param numRandomSamplings the number of iterations of initial random seed + * node selection + * @param randXORMask the bit mask used for initial random seed node + * selection + */ + private CagraSearchParams(CuVSResources resources, int maxQueries, int iTopKSize, int maxIterations, + SearchAlgo searchAlgo, int teamSize, int searchWidth, int minIterations, int threadBlockSize, + HashMapMode hashmapMode, int hashmapMinBitlen, float hashmapMaxFillRate, int numRandomSamplings, + long randXORMask) { + this.maxQueries = maxQueries; + this.iTopKSize = iTopKSize; + this.maxIterations = maxIterations; + this.searchAlgo = searchAlgo; + this.teamSize = teamSize; + this.searchWidth = searchWidth; + this.minIterations = minIterations; + this.threadBlockSize = threadBlockSize; + this.hashMapMode = hashmapMode; + this.hashmapMinBitlen = hashmapMinBitlen; + this.hashMapMaxFillRate = hashmapMaxFillRate; + this.numRandomSamplings = numRandomSamplings; + this.randXORMask = randXORMask; + this.resources = resources; + + this.memorySegment = allocateMemorySegment(); + } + + /** + * Allocates the configured search parameters in the MemorySegment. + */ + private MemorySegment allocateMemorySegment() { + MemorySegment memorySegment = CuVSCagraSearchParams.allocate(resources.arena); + CuVSCagraSearchParams.max_queries(memorySegment, maxQueries); + CuVSCagraSearchParams.itopk_size(memorySegment, iTopKSize); + CuVSCagraSearchParams.max_iterations(memorySegment, maxIterations); + if (searchAlgo != null) { + CuVSCagraSearchParams.algo(memorySegment, searchAlgo.value); + } + CuVSCagraSearchParams.team_size(memorySegment, teamSize); + CuVSCagraSearchParams.search_width(memorySegment, searchWidth); + CuVSCagraSearchParams.min_iterations(memorySegment, minIterations); + CuVSCagraSearchParams.thread_block_size(memorySegment, threadBlockSize); + if (hashMapMode != null) { + CuVSCagraSearchParams.hashmap_mode(memorySegment, hashMapMode.value); + } + CuVSCagraSearchParams.hashmap_min_bitlen(memorySegment, hashmapMinBitlen); + CuVSCagraSearchParams.hashmap_max_fill_rate(memorySegment, hashMapMaxFillRate); + CuVSCagraSearchParams.num_random_samplings(memorySegment, numRandomSamplings); + CuVSCagraSearchParams.rand_xor_mask(memorySegment, randXORMask); + return memorySegment; + } + + /** + * Gets the maximum number of queries to search at the same time (batch size). + * + * @return the maximum number of queries + */ + public int getMaxQueries() { + return maxQueries; + } + + /** + * Gets the number of intermediate search results retained during the search. + * + * @return the number of intermediate search results + */ + public int getITopKSize() { + return iTopKSize; + } + + /** + * Gets the upper limit of search iterations. + * + * @return the upper limit value + */ + public int getMaxIterations() { + return maxIterations; + } + + /** + * Gets the number of threads used to calculate a single distance. + * + * @return the number of threads configured + */ + public int getTeamSize() { + return teamSize; + } + + /** + * Gets the number of graph nodes to select as the starting point for the search + * in each iteration. + * + * @return the number of graph nodes + */ + public int getSearchWidth() { + return searchWidth; + } + + /** + * Gets the lower limit of search iterations. + * + * @return the lower limit value + */ + public int getMinIterations() { + return minIterations; + } + + /** + * Gets the thread block size. + * + * @return the thread block size + */ + public int getThreadBlockSize() { + return threadBlockSize; + } + + /** + * Gets the lower limit of hash map bit length. + * + * @return the lower limit value + */ + public int getHashmapMinBitlen() { + return hashmapMinBitlen; + } + + /** + * Gets the number of iterations of initial random seed node selection. + * + * @return the number of iterations + */ + public int getNumRandomSamplings() { + return numRandomSamplings; + } + + /** + * Gets the upper limit of hash map fill rate. + * + * @return the upper limit of hash map fill rate + */ + public float getHashMapMaxFillRate() { + return hashMapMaxFillRate; + } + + /** + * Gets the bit mask used for initial random seed node selection. + * + * @return the bit mask value + */ + public long getRandXORMask() { + return randXORMask; + } + + /** + * Gets the MemorySegment holding CagraSearchParams. + * + * @return the MemorySegment holding CagraSearchParams + */ + protected MemorySegment getMemorySegment() { + return memorySegment; + } + + /** + * Gets which search implementation is configured. + * + * @return the configured {@link SearchAlgo} + */ + public SearchAlgo getCagraSearchAlgo() { + return searchAlgo; + } + + /** + * Gets the hash map mode configured. + * + * @return the configured {@link HashMapMode} + */ + public HashMapMode getHashMapMode() { + return hashMapMode; + } + + @Override + public String toString() { + return "CagraSearchParams [resources=" + resources + ", maxQueries=" + maxQueries + ", itopkSize=" + iTopKSize + + ", maxIterations=" + maxIterations + ", cuvsCagraSearchAlgo=" + searchAlgo + ", teamSize=" + teamSize + + ", searchWidth=" + searchWidth + ", minIterations=" + minIterations + ", threadBlockSize=" + threadBlockSize + + ", hashMapMode=" + hashMapMode + ", hashMapMinBitlen=" + hashmapMinBitlen + ", hashMapMaxFillRate=" + + hashMapMaxFillRate + ", numRandomSamplings=" + numRandomSamplings + ", randXORMask=" + randXORMask + + ", memorySegment=" + memorySegment + "]"; + } + + /** + * Builder configures and creates an instance of CagraSearchParams. + */ + public static class Builder { + + private CuVSResources resources; + private int maxQueries; + private int iTopKSize = 64; + private int maxIterations; + private int teamSize; + private int searchWidth = 1; + private int minIterations; + private int threadBlockSize; + private int hashMapMinBitlen; + private int numRandomSamplings = 1; + private float hashMapMaxFillRate = 0.5f; + private long randXORMask = 0x128394; + private SearchAlgo searchAlgo; + private HashMapMode hashMapMode; + + /** + * Constructs this Builder with an instance of Arena. + * + * @param resources the {@link CuVSResources} instance to use + */ + public Builder(CuVSResources resources) { + this.resources = resources; + } + + /** + * Sets the maximum number of queries to search at the same time (batch size). + * Auto select when 0. + * + * @param maxQueries the maximum number of queries + * @return an instance of this Builder + */ + public Builder withMaxQueries(int maxQueries) { + this.maxQueries = maxQueries; + return this; + } + + /** + * Sets the number of intermediate search results retained during the search. + * This is the main knob to adjust trade off between accuracy and search speed. + * Higher values improve the search accuracy. + * + * @param iTopKSize the number of intermediate search results + * @return an instance of this Builder + */ + public Builder withItopkSize(int iTopKSize) { + this.iTopKSize = iTopKSize; + return this; + } + + /** + * Sets the upper limit of search iterations. Auto select when 0. + * + * @param maxIterations the upper limit of search iterations + * @return an instance of this Builder + */ + public Builder withMaxIterations(int maxIterations) { + this.maxIterations = maxIterations; + return this; + } + + /** + * Sets which search implementation to use. + * + * @param cuvsCagraSearchAlgo the {@link SearchAlgo} to use + * @return an instance of this Builder + */ + public Builder withAlgo(SearchAlgo cuvsCagraSearchAlgo) { + this.searchAlgo = cuvsCagraSearchAlgo; + return this; + } + + /** + * Sets the number of threads used to calculate a single distance. 4, 8, 16, or + * 32. + * + * @param teamSize the number of threads used to calculate a single distance + * @return an instance of this Builder + */ + public Builder withTeamSize(int teamSize) { + this.teamSize = teamSize; + return this; + } + + /** + * Sets the number of graph nodes to select as the starting point for the search + * in each iteration. + * + * @param searchWidth the number of graph nodes to select + * @return an instance of this Builder + */ + public Builder withSearchWidth(int searchWidth) { + this.searchWidth = searchWidth; + return this; + } + + /** + * Sets the lower limit of search iterations. + * + * @param minIterations the lower limit of search iterations + * @return an instance of this Builder + */ + public Builder withMinIterations(int minIterations) { + this.minIterations = minIterations; + return this; + } + + /** + * Sets the thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when + * 0. + * + * @param threadBlockSize the thread block size + * @return an instance of this Builder + */ + public Builder withThreadBlockSize(int threadBlockSize) { + this.threadBlockSize = threadBlockSize; + return this; + } + + /** + * Sets the hash map type. Auto selection when AUTO. + * + * @param hashMapMode the {@link HashMapMode} + * @return an instance of this Builder + */ + public Builder withHashMapMode(HashMapMode hashMapMode) { + this.hashMapMode = hashMapMode; + return this; + } + + /** + * Sets the lower limit of hash map bit length. More than 8. + * + * @param hashMapMinBitlen the lower limit of hash map bit length + * @return an instance of this Builder + */ + public Builder withHashMapMinBitlen(int hashMapMinBitlen) { + this.hashMapMinBitlen = hashMapMinBitlen; + return this; + } + + /** + * Sets the upper limit of hash map fill rate. More than 0.1, less than 0.9. + * + * @param hashMapMaxFillRate the upper limit of hash map fill rate + * @return an instance of this Builder + */ + public Builder withHashMapMaxFillRate(float hashMapMaxFillRate) { + this.hashMapMaxFillRate = hashMapMaxFillRate; + return this; + } + + /** + * Sets the number of iterations of initial random seed node selection. 1 or + * more. + * + * @param numRandomSamplings the number of iterations of initial random seed + * node selection + * @return an instance of this Builder + */ + public Builder withNumRandomSamplings(int numRandomSamplings) { + this.numRandomSamplings = numRandomSamplings; + return this; + } + + /** + * Sets the bit mask used for initial random seed node selection. + * + * @param randXORMask the bit mask used for initial random seed node selection + * @return an instance of this Builder + */ + public Builder withRandXorMask(long randXORMask) { + this.randXORMask = randXORMask; + return this; + } + + /** + * Builds an instance of {@link CagraSearchParams} with passed search + * parameters. + * + * @return an instance of CagraSearchParams + */ + public CagraSearchParams build() { + return new CagraSearchParams(resources, maxQueries, iTopKSize, maxIterations, searchAlgo, teamSize, searchWidth, + minIterations, threadBlockSize, hashMapMode, hashMapMinBitlen, hashMapMaxFillRate, numRandomSamplings, + randXORMask); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchResults.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchResults.java new file mode 100644 index 000000000..3473facce --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchResults.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.nvidia.cuvs.common.SearchResults; + +/** + * SearchResult encapsulates the logic for reading and holding search results. + * + * @since 25.02 + */ +public class CagraSearchResults extends SearchResults { + + protected CagraSearchResults(SequenceLayout neighboursSequenceLayout, SequenceLayout distancesSequenceLayout, + MemorySegment neighboursMemorySegment, MemorySegment distancesMemorySegment, int topK, List mapping, + long numberOfQueries) { + super(neighboursSequenceLayout, distancesSequenceLayout, neighboursMemorySegment, distancesMemorySegment, topK, + mapping, numberOfQueries); + readResultMemorySegments(); + } + + /** + * Reads neighbors and distances {@link MemorySegment} and loads the values + * internally + */ + protected void readResultMemorySegments() { + Map intermediateResultMap = new LinkedHashMap(); + int count = 0; + for (long i = 0; i < topK * numberOfQueries; i++) { + int id = (int) neighboursVarHandle.get(neighboursMemorySegment, 0L, i); + float dst = (float) distancesVarHandle.get(distancesMemorySegment, 0L, i); + intermediateResultMap.put(mapping != null ? mapping.get(id) : id, dst); + count += 1; + if (count == topK) { + results.add(intermediateResultMap); + intermediateResultMap = new LinkedHashMap(); + count = 0; + } + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java new file mode 100644 index 000000000..dbaba3ebb --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.io.File; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; + +import com.nvidia.cuvs.common.Util; + +/** + * Used for allocating resources for cuVS + * + * @since 25.02 + */ +public class CuVSResources implements AutoCloseable { + + public final Arena arena; + public final Linker linker; + public final SymbolLookup symbolLookup; + protected File nativeLibrary; + private final MethodHandle createResourcesMethodHandle; + private final MethodHandle destroyResourcesMethodHandle; + private MemorySegment resourcesMemorySegment; + private MemoryLayout intMemoryLayout; + + /** + * Constructor that allocates the resources needed for cuVS + * + * @throws Throwable exception thrown when native function is invoked + */ + public CuVSResources() throws Throwable { + linker = Linker.nativeLinker(); + arena = Arena.ofShared(); + + nativeLibrary = Util.loadNativeLibrary(); + symbolLookup = SymbolLookup.libraryLookup(nativeLibrary.getAbsolutePath(), arena); + intMemoryLayout = linker.canonicalLayouts().get("int"); + + createResourcesMethodHandle = linker.downcallHandle(symbolLookup.find("create_resources").get(), + FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + destroyResourcesMethodHandle = linker.downcallHandle(symbolLookup.find("destroy_resources").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + + createResources(); + } + + /** + * Creates the resources used internally and returns its reference. + * + * @throws Throwable exception thrown when native function is invoked + */ + public void createResources() throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = arena.allocate(returnValueMemoryLayout); + resourcesMemorySegment = (MemorySegment) createResourcesMethodHandle.invokeExact(returnValueMemorySegment); + } + + @Override + public void close() { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = arena.allocate(returnValueMemoryLayout); + try { + destroyResourcesMethodHandle.invokeExact(resourcesMemorySegment, returnValueMemorySegment); + } catch (Throwable e) { + e.printStackTrace(); + } + if (!arena.scope().isAlive()) { + arena.close(); + } + nativeLibrary.delete(); + } + + /** + * Gets the reference to the cuvsResources MemorySegment. + * + * @return cuvsResources MemorySegment + */ + protected MemorySegment getMemorySegment() { + return resourcesMemorySegment; + } + + /** + * Returns the loaded libcuvs_java_cagra.so as a {@link SymbolLookup} + */ + protected SymbolLookup getSymbolLookup() { + return symbolLookup; + } + + /** + * Container for GPU information + */ + public class GPUInfo { + + private final int gpuId; + private final long freeMemory; + private final long totalMemory; + private final float computeCapability; + + public GPUInfo(int gpuId, long freeMemory, long totalMemory, float computeCapability) { + super(); + this.gpuId = gpuId; + this.freeMemory = freeMemory; + this.totalMemory = totalMemory; + this.computeCapability = computeCapability; + } + + public int getGpuId() { + return gpuId; + } + + public long getFreeMemory() { + return freeMemory; + } + + public long getTotalMemory() { + return totalMemory; + } + + public float getComputeCapability() { + return computeCapability; + } + + @Override + public String toString() { + return "GPUInfo [gpuId=" + gpuId + ", freeMemory=" + freeMemory + ", totalMemory=" + totalMemory + + ", computeCapability=" + computeCapability + "]"; + } + + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfo.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfo.java new file mode 100644 index 000000000..48cade179 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfo.java @@ -0,0 +1,56 @@ +package com.nvidia.cuvs; + +/** + * Contains GPU information + */ +public class GPUInfo { + private final int gpuId; + private final String name; + private final long freeMemory; + private final long totalMemory; + private final float computeCapability; + + /** + * Constructor for GPUInfo + * + * @param gpuId id of the GPU starting from 0 + * @param name ASCII string identifying device + * @param freeMemory returned free memory in bytes + * @param totalMemory returned total memory in bytes + * @param computeCapability the compute capability of the device + */ + public GPUInfo(int gpuId, String name, long freeMemory, long totalMemory, float computeCapability) { + super(); + this.gpuId = gpuId; + this.name = name; + this.freeMemory = freeMemory; + this.totalMemory = totalMemory; + this.computeCapability = computeCapability; + } + + public int getGpuId() { + return gpuId; + } + + public String getName() { + return name; + } + + public long getFreeMemory() { + return freeMemory; + } + + public long getTotalMemory() { + return totalMemory; + } + + public float getComputeCapability() { + return computeCapability; + } + + @Override + public String toString() { + return "GPUInfo [gpuId=" + gpuId + ", name=" + name + ", freeMemory=" + freeMemory + ", totalMemory=" + totalMemory + + ", computeCapability=" + computeCapability + "]"; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java new file mode 100644 index 000000000..d55308a1b --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.UUID; + +import com.nvidia.cuvs.common.Util; +import com.nvidia.cuvs.panama.CuVSHnswIndex; + +/** + * {@link HnswIndex} encapsulates a HNSW index, along with methods to interact + * with it. + * + * @since 25.02 + */ +public class HnswIndex { + + private final CuVSResources resources; + private MethodHandle deserializeHnswIndexMethodHandle; + private MethodHandle searchHnswIndexMethodHandle; + private MethodHandle destroyHnswIndexMethodHandle; + private HnswIndexParams hnswIndexParams; + private IndexReference hnswIndexReference; + private MemoryLayout longMemoryLayout; + private MemoryLayout intMemoryLayout; + private MemoryLayout floatMemoryLayout; + + /** + * Constructor for loading the index from an {@link InputStream} + * + * @param inputStream an instance of stream to read the index bytes from + * @param resources an instance of {@link CuVSResources} + */ + private HnswIndex(InputStream inputStream, CuVSResources resources, HnswIndexParams hnswIndexParams) + throws Throwable { + this.hnswIndexParams = hnswIndexParams; + this.resources = resources; + + longMemoryLayout = resources.linker.canonicalLayouts().get("long"); + intMemoryLayout = resources.linker.canonicalLayouts().get("int"); + floatMemoryLayout = resources.linker.canonicalLayouts().get("float"); + + initializeMethodHandles(); + this.hnswIndexReference = deserialize(inputStream); + } + + /** + * Initializes the {@link MethodHandles} for invoking native methods. + * + * @throws IOException @{@link IOException} is unable to load the native library + */ + private void initializeMethodHandles() throws IOException { + deserializeHnswIndexMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("deserialize_hnsw_index").get(), FunctionDescriptor.of(ValueLayout.ADDRESS, + ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, intMemoryLayout)); + + searchHnswIndexMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("search_hnsw_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, + ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, intMemoryLayout, intMemoryLayout, + longMemoryLayout)); + + destroyHnswIndexMethodHandle = resources.linker.downcallHandle( + resources.getSymbolLookup().find("destroy_hnsw_index").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + } + + /** + * Invokes the native destroy_hnsw_index to de-allocate the HNSW index + */ + public void destroyIndex() throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + destroyHnswIndexMethodHandle.invokeExact(hnswIndexReference.getMemorySegment(), returnValueMemorySegment); + } + + /** + * Invokes the native search_hnsw_index via the Panama API for searching a HNSW + * index. + * + * @param query an instance of {@link HnswQuery} holding the query vectors and + * other parameters + * @return an instance of {@link HnswSearchResults} containing the results + */ + public HnswSearchResults search(HnswQuery query) throws Throwable { + long numQueries = query.getQueryVectors().length; + long numBlocks = query.getTopK() * numQueries; + int vectorDimension = numQueries > 0 ? query.getQueryVectors()[0].length : 0; + + SequenceLayout neighborsSequenceLayout = MemoryLayout.sequenceLayout(numBlocks, longMemoryLayout); + SequenceLayout distancesSequenceLayout = MemoryLayout.sequenceLayout(numBlocks, floatMemoryLayout); + MemorySegment neighborsMemorySegment = resources.arena.allocate(neighborsSequenceLayout); + MemorySegment distancesMemorySegment = resources.arena.allocate(distancesSequenceLayout); + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + + searchHnswIndexMethodHandle.invokeExact(resources.getMemorySegment(), hnswIndexReference.getMemorySegment(), + query.getHnswSearchParams().getHnswSearchParamsMemorySegment(), returnValueMemorySegment, + neighborsMemorySegment, distancesMemorySegment, + Util.buildMemorySegment(resources.linker, resources.arena, query.getQueryVectors()), query.getTopK(), + vectorDimension, numQueries); + + return new HnswSearchResults(neighborsSequenceLayout, distancesSequenceLayout, neighborsMemorySegment, + distancesMemorySegment, query.getTopK(), query.getMapping(), numQueries); + } + + /** + * Gets an instance of {@link IndexReference} by deserializing a HNSW index + * using an {@link InputStream}. + * + * @param inputStream an instance of {@link InputStream} + * @return an instance of {@link IndexReference}. + */ + private IndexReference deserialize(InputStream inputStream) throws Throwable { + return deserialize(inputStream, 1024); + } + + /** + * Gets an instance of {@link IndexReference} by deserializing a HNSW index + * using an {@link InputStream}. + * + * @param inputStream an instance of {@link InputStream} + * @param bufferLength the length of the buffer to use while reading the bytes + * from the stream. Default value is 1024. + * @return an instance of {@link IndexReference}. + */ + private IndexReference deserialize(InputStream inputStream, int bufferLength) throws Throwable { + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = resources.arena.allocate(returnValueMemoryLayout); + String tmpIndexFile = "/tmp/" + UUID.randomUUID().toString() + ".hnsw"; + + File tempFile = new File(tmpIndexFile); + FileOutputStream fileOutputStream = new FileOutputStream(tempFile); + byte[] chunk = new byte[bufferLength]; + int chunkLength = 0; + while ((chunkLength = inputStream.read(chunk)) != -1) { + fileOutputStream.write(chunk, 0, chunkLength); + } + + IndexReference indexReference = new IndexReference((MemorySegment) deserializeHnswIndexMethodHandle.invokeExact( + resources.getMemorySegment(), Util.buildMemorySegment(resources.linker, resources.arena, tmpIndexFile), + hnswIndexParams.getHnswIndexParamsMemorySegment(), returnValueMemorySegment, + hnswIndexParams.getVectorDimension())); + + inputStream.close(); + fileOutputStream.close(); + tempFile.delete(); + + return indexReference; + } + + /** + * Builder helps configure and create an instance of {@link HnswIndex}. + */ + public static class Builder { + + private CuVSResources cuvsResources; + private InputStream inputStream; + private HnswIndexParams hnswIndexParams; + + /** + * Constructs this Builder with an instance of {@link CuVSResources}. + * + * @param cuvsResources an instance of {@link CuVSResources} + */ + public Builder(CuVSResources cuvsResources) { + this.cuvsResources = cuvsResources; + } + + /** + * Sets an instance of InputStream typically used when index deserialization is + * needed. + * + * @param inputStream an instance of {@link InputStream} + * @return an instance of this Builder + */ + public Builder from(InputStream inputStream) { + this.inputStream = inputStream; + return this; + } + + /** + * Registers an instance of configured {@link HnswIndexParams} with this + * Builder. + * + * @param hnswIndexParameters An instance of HnswIndexParams. + * @return An instance of this Builder. + */ + public Builder withIndexParams(HnswIndexParams hnswIndexParameters) { + this.hnswIndexParams = hnswIndexParameters; + return this; + } + + /** + * Builds and returns an instance of CagraIndex. + * + * @return an instance of CagraIndex + */ + public HnswIndex build() throws Throwable { + return new HnswIndex(inputStream, cuvsResources, hnswIndexParams); + } + } + + /** + * Holds the memory reference to a HNSW index. + */ + protected static class IndexReference { + + private final MemorySegment memorySegment; + + /** + * Constructs CagraIndexReference and allocate the MemorySegment. + */ + protected IndexReference(CuVSResources resources) { + memorySegment = CuVSHnswIndex.allocate(resources.arena); + } + + /** + * Constructs CagraIndexReference with an instance of MemorySegment passed as a + * parameter. + * + * @param indexMemorySegment the MemorySegment instance to use for containing + * index reference + */ + protected IndexReference(MemorySegment indexMemorySegment) { + this.memorySegment = indexMemorySegment; + } + + /** + * Gets the instance of index MemorySegment. + * + * @return index MemorySegment + */ + protected MemorySegment getMemorySegment() { + return memorySegment; + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java new file mode 100644 index 000000000..ef06adf61 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; + +import com.nvidia.cuvs.panama.CuVSHnswIndexParams; + +/** + * Supplemental parameters to build HNSW index. + * + * @since 25.02 + */ +public class HnswIndexParams { + + /** + * Hierarchy for HNSW index when converting from CAGRA index + * + * NOTE: When the value is `NONE`, the HNSW index is built as a base-layer-only + * index. + */ + public enum CuvsHnswHierarchy { + + /** + * Flat hierarchy, search is base-layer only + */ + NONE(0), + + /** + * Full hierarchy is built using the CPU + */ + CPU(1); + + /** + * The value for the enum choice. + */ + public final int value; + + private CuvsHnswHierarchy(int value) { + this.value = value; + } + }; + + private CuVSResources resources; + private MemorySegment memorySegment; + private CuvsHnswHierarchy hierarchy = CuvsHnswHierarchy.NONE; + private int efConstruction = 200; + private int numThreads = 2; + private int vectorDimension; + + private HnswIndexParams(CuVSResources resources, CuvsHnswHierarchy hierarchy, int efConstruction, int numThreads, + int vectorDimension) { + this.resources = resources; + this.hierarchy = hierarchy; + this.efConstruction = efConstruction; + this.numThreads = numThreads; + this.vectorDimension = vectorDimension; + this.memorySegment = allocateMemorySegment(); + } + + /** + * Allocates the configured search parameters in the MemorySegment. + */ + private MemorySegment allocateMemorySegment() { + MemorySegment memorySegment = CuVSHnswIndexParams.allocate(resources.arena); + CuVSHnswIndexParams.ef_construction(memorySegment, efConstruction); + CuVSHnswIndexParams.num_threads(memorySegment, numThreads); + return memorySegment; + } + + public MemorySegment getHnswIndexParamsMemorySegment() { + return memorySegment; + } + + /** + * + * @return + */ + public CuvsHnswHierarchy getHierarchy() { + return hierarchy; + } + + /** + * + * @return + */ + public int getEfConstruction() { + return efConstruction; + } + + /** + * + * @return + */ + public int getNumThreads() { + return numThreads; + } + + /** + * + * @return + */ + public int getVectorDimension() { + return vectorDimension; + } + + public CuVSResources getResources() { + return resources; + } + + @Override + public String toString() { + return "HnswIndexParams [hierarchy=" + hierarchy + ", efConstruction=" + efConstruction + ", numThreads=" + + numThreads + ", vectorDimension=" + vectorDimension + "]"; + } + + /** + * Builder configures and creates an instance of {@link HnswIndexParams}. + */ + public static class Builder { + + private CuVSResources resources; + private CuvsHnswHierarchy hierarchy = CuvsHnswHierarchy.NONE; + private int efConstruction = 200; + private int numThreads = 2; + private int vectorDimension; + + /** + * Constructs this Builder with an instance of Arena. + * + * @param resources the {@link CuVSResources} instance to use + */ + public Builder(CuVSResources resources) { + this.resources = resources; + } + + /** + * Sets the hierarchy for HNSW index when converting from CAGRA index. + * + * NOTE: When the value is `NONE`, the HNSW index is built as a base-layer-only + * index. + * + * @param hierarchy the hierarchy for HNSW index when converting from CAGRA + * index + * @return an instance of Builder + */ + public Builder withHierarchy(CuvsHnswHierarchy hierarchy) { + this.hierarchy = hierarchy; + return this; + } + + /** + * Sets the size of the candidate list during hierarchy construction when + * hierarchy is `CPU`. + * + * @param efConstruction the size of the candidate list during hierarchy + * construction when hierarchy is `CPU` + * @return an instance of Builder + */ + public Builder withEfConstruction(int efConstruction) { + this.efConstruction = efConstruction; + return this; + } + + /** + * Sets the number of host threads to use to construct hierarchy when hierarchy + * is `CPU`. + * + * @param numThreads the number of threads + * @return an instance of Builder + */ + public Builder withNumThreads(int numThreads) { + this.numThreads = numThreads; + return this; + } + + /** + * Sets the vector dimension + * + * @param vectorDimension the vector dimension + * @return an instance of Builder + */ + public Builder withVectorDimension(int vectorDimension) { + this.vectorDimension = vectorDimension; + return this; + } + + /** + * Builds an instance of {@link HnswIndexParams}. + * + * @return an instance of {@link HnswIndexParams} + */ + public HnswIndexParams build() { + return new HnswIndexParams(resources, hierarchy, efConstruction, numThreads, vectorDimension); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java new file mode 100644 index 000000000..2575bbde4 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.util.Arrays; +import java.util.List; + +/** + * HnswQuery holds the query vectors to be used while invoking search on the + * HNSW index. + * + * @since 25.02 + */ +public class HnswQuery { + + private HnswSearchParams hnswSearchParams; + private List mapping; + private float[][] queryVectors; + private int topK; + + /** + * Constructs an instance of {@link HnswQuery} using queryVectors, mapping, and + * topK. + * + * @param hnswSearchParams the search parameters to use + * @param queryVectors 2D float query vector array + * @param mapping an instance of ID mapping + * @param topK the top k results to return + */ + private HnswQuery(HnswSearchParams hnswSearchParams, float[][] queryVectors, List mapping, int topK) { + this.hnswSearchParams = hnswSearchParams; + this.queryVectors = queryVectors; + this.mapping = mapping; + this.topK = topK; + } + + /** + * Gets the instance of HnswSearchParams. + * + * @return the instance of {@link HnswSearchParams} + */ + public HnswSearchParams getHnswSearchParams() { + return hnswSearchParams; + } + + /** + * Gets the query vector 2D float array. + * + * @return 2D float array + */ + public float[][] getQueryVectors() { + return queryVectors; + } + + /** + * Gets the passed map instance. + * + * @return a map of ID mappings + */ + public List getMapping() { + return mapping; + } + + /** + * Gets the topK value. + * + * @return an integer + */ + public int getTopK() { + return topK; + } + + @Override + public String toString() { + return "HnswQuery [mapping=" + mapping + ", queryVectors=" + Arrays.toString(queryVectors) + ", topK=" + topK + "]"; + } + + /** + * Builder helps configure and create an instance of BruteForceQuery. + */ + public static class Builder { + + private HnswSearchParams hnswSearchParams; + private float[][] queryVectors; + private List mapping; + private int topK = 2; + + /** + * Sets the instance of configured HnswSearchParams to be passed for search. + * + * @param hnswSearchParams an instance of the configured HnswSearchParams to be + * used for this query + * @return an instance of this Builder + */ + public Builder withSearchParams(HnswSearchParams hnswSearchParams) { + this.hnswSearchParams = hnswSearchParams; + return this; + } + + /** + * Registers the query vectors to be passed in the search call. + * + * @param queryVectors 2D float query vector array + * @return an instance of this Builder + */ + public Builder withQueryVectors(float[][] queryVectors) { + this.queryVectors = queryVectors; + return this; + } + + /** + * Sets the instance of mapping to be used for ID mapping. + * + * @param mapping the ID mapping instance + * @return an instance of this Builder + */ + public Builder withMapping(List mapping) { + this.mapping = mapping; + return this; + } + + /** + * Registers the topK value. + * + * @param topK the topK value used to retrieve the topK results + * @return an instance of this Builder + */ + public Builder withTopK(int topK) { + this.topK = topK; + return this; + } + + /** + * Builds an instance of {@link HnswQuery} + * + * @return an instance of {@link HnswQuery} + */ + public HnswQuery build() { + return new HnswQuery(hnswSearchParams, queryVectors, mapping, topK); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java new file mode 100644 index 000000000..a2725e6de --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; + +import com.nvidia.cuvs.panama.CuVSHnswSearchParams; + +/** + * HnswSearchParams encapsulates the logic for configuring and holding search + * parameters for HNSW index. + * + * @since 25.02 + */ +public class HnswSearchParams { + + private CuVSResources resources; + private MemorySegment memorySegment; + private int ef = 200; + private int numThreads = 0; + + /** + * Constructs an instance of HnswSearchParams with passed search parameters. + * + * @param resources the resources instance to use + * @param ef the ef value + * @param numThreads the number of threads + * + */ + private HnswSearchParams(CuVSResources resources, int ef, int numThreads) { + this.resources = resources; + this.ef = ef; + this.numThreads = numThreads; + this.memorySegment = allocateMemorySegment(); + } + + /** + * Allocates the configured search parameters in the MemorySegment. + */ + private MemorySegment allocateMemorySegment() { + MemorySegment memorySegment = CuVSHnswSearchParams.allocate(resources.arena); + CuVSHnswSearchParams.ef(memorySegment, ef); + CuVSHnswSearchParams.num_threads(memorySegment, numThreads); + return memorySegment; + } + + public MemorySegment getHnswSearchParamsMemorySegment() { + return memorySegment; + } + + /** + * Gets the ef value + * + * @return the integer ef value + */ + public int getEf() { + return ef; + } + + /** + * Gets the number of threads + * + * @return the number of threads + */ + public int getNumThreads() { + return numThreads; + } + + @Override + public String toString() { + return "HnswSearchParams [ef=" + ef + ", numThreads=" + numThreads + "]"; + } + + /** + * Builder configures and creates an instance of HnswSearchParams. + */ + public static class Builder { + + private CuVSResources resources; + private int ef = 200; + private int numThreads = 0; + + /** + * Constructs this Builder with an instance of Arena. + * + * @param resources the {@link CuVSResources} instance to use + */ + public Builder(CuVSResources resources) { + this.resources = resources; + } + + /** + * Sets the ef value + * + * @param ef the ef value + * @return an instance of this Builder + */ + public Builder withEF(int ef) { + this.ef = ef; + return this; + } + + /** + * Sets the number of threads + * + * @param numThreads the number of threads + * @return an instance of this Builder + */ + public Builder withNumThreads(int numThreads) { + this.numThreads = numThreads; + return this; + } + + /** + * Builds an instance of {@link HnswSearchParams} with passed search parameters. + * + * @return an instance of HnswSearchParams + */ + public HnswSearchParams build() { + return new HnswSearchParams(resources, ef, numThreads); + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchResults.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchResults.java new file mode 100644 index 000000000..8cb4d89e0 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchResults.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.nvidia.cuvs.common.SearchResults; + +/** + * SearchResult encapsulates the logic for reading and holding search results. + * + * @since 25.02 + */ +public class HnswSearchResults extends SearchResults { + + protected HnswSearchResults(SequenceLayout neighboursSequenceLayout, SequenceLayout distancesSequenceLayout, + MemorySegment neighboursMemorySegment, MemorySegment distancesMemorySegment, int topK, List mapping, + long numberOfQueries) { + super(neighboursSequenceLayout, distancesSequenceLayout, neighboursMemorySegment, distancesMemorySegment, topK, + mapping, numberOfQueries); + readResultMemorySegments(); + } + + /** + * Reads neighbors and distances {@link MemorySegment} and loads the values + * internally + */ + protected void readResultMemorySegments() { + Map intermediateResultMap = new LinkedHashMap(); + int count = 0; + for (long i = 0; i < topK * numberOfQueries; i++) { + long id = (long) neighboursVarHandle.get(neighboursMemorySegment, 0L, i); + float dst = (float) distancesVarHandle.get(distancesMemorySegment, 0L, i); + intermediateResultMap.put(mapping != null ? mapping.get((int) id) : (int) id, dst); + count += 1; + if (count == topK) { + results.add(intermediateResultMap); + intermediateResultMap = new LinkedHashMap(); + count = 0; + } + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/LibraryException.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/LibraryException.java new file mode 100644 index 000000000..40018be92 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/LibraryException.java @@ -0,0 +1,18 @@ +package com.nvidia.cuvs; + +public class LibraryException extends RuntimeException { + + private static final long serialVersionUID = -2311171907713571455L; + + public LibraryException(Exception ex) { + super(ex); + } + + public LibraryException(String message) { + super(message); + } + + public LibraryException(String message, Exception e) { + super(message, e); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/common/SearchResults.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/common/SearchResults.java new file mode 100644 index 000000000..83e98cb8e --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/common/SearchResults.java @@ -0,0 +1,53 @@ +package com.nvidia.cuvs.common; + +import java.lang.foreign.MemoryLayout.PathElement; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SequenceLayout; +import java.lang.invoke.VarHandle; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public abstract class SearchResults { + + protected final List> results; + protected final List mapping; // TODO: Is this performant in a user application? + protected final SequenceLayout neighboursSequenceLayout; + protected final SequenceLayout distancesSequenceLayout; + protected final MemorySegment neighboursMemorySegment; + protected final MemorySegment distancesMemorySegment; + protected final int topK; + protected final long numberOfQueries; + protected final VarHandle neighboursVarHandle; + protected final VarHandle distancesVarHandle; + + protected SearchResults(SequenceLayout neighboursSequenceLayout, SequenceLayout distancesSequenceLayout, + MemorySegment neighboursMemorySegment, MemorySegment distancesMemorySegment, int topK, List mapping, + long numberOfQueries) { + this.topK = topK; + this.numberOfQueries = numberOfQueries; + this.neighboursSequenceLayout = neighboursSequenceLayout; + this.distancesSequenceLayout = distancesSequenceLayout; + this.neighboursMemorySegment = neighboursMemorySegment; + this.distancesMemorySegment = distancesMemorySegment; + this.mapping = mapping; + results = new LinkedList>(); + neighboursVarHandle = neighboursSequenceLayout.varHandle(PathElement.sequenceElement()); + distancesVarHandle = distancesSequenceLayout.varHandle(PathElement.sequenceElement()); + } + + /** + * Reads neighbors and distances {@link MemorySegment} and loads the values + * internally + */ + protected abstract void readResultMemorySegments(); + + /** + * Gets a list results as a map of neighbor IDs to distances. + * + * @return a list of results for each query as a map of neighbor IDs to distance + */ + public List> getResults() { + return results; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/common/Util.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/common/Util.java new file mode 100644 index 000000000..163ef3a84 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/common/Util.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.common; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemoryLayout.PathElement; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.util.ArrayList; +import java.util.List; + +import com.nvidia.cuvs.GPUInfo; +import com.nvidia.cuvs.LibraryException; +import com.nvidia.cuvs.panama.GpuInfo; + +public class Util { + + private static Arena arena = null; + private static Linker linker = null; + private static SymbolLookup symbolLookup = null; + private static MemoryLayout intMemoryLayout; + private static MethodHandle getGpuInfoMethodHandle = null; + protected static File nativeLibrary; + + static { + try { + linker = Linker.nativeLinker(); + arena = Arena.ofShared(); + nativeLibrary = Util.loadLibraryFromJar("/libcuvs_java.so"); + symbolLookup = SymbolLookup.libraryLookup(nativeLibrary.getAbsolutePath(), arena); + intMemoryLayout = linker.canonicalLayouts().get("int"); + getGpuInfoMethodHandle = linker.downcallHandle(symbolLookup.find("get_gpu_info").get(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS)); + } catch (Exception e) { + throw new LibraryException("LibCuVS Java Library Not Loaded", e); + } + } + + /** + * Get the list of compatible GPUs based on compute capability >= 7.0 and total + * memory >= 8GB + * + * @return a list of compatible GPUs. See {@link GPUInfo} + */ + public static List compatibleGPUs() throws Throwable { + return compatibleGPUs(7.0, 8192); + } + + /** + * Get the list of compatible GPUs based on given compute capability and total + * memory + * + * @param minComputeCapability the minimum compute capability + * @param minDeviceMemoryMB the minimum total available memory in MB + * @return a list of compatible GPUs. See {@link GPUInfo} + */ + public static List compatibleGPUs(double minComputeCapability, int minDeviceMemoryMB) throws Throwable { + List compatibleGPUs = new ArrayList(); + double minDeviceMemoryB = Math.pow(2, 20) * minDeviceMemoryMB; + for (GPUInfo gpuInfo : availableGPUs()) { + if (gpuInfo.getComputeCapability() >= minComputeCapability && gpuInfo.getTotalMemory() >= minDeviceMemoryB) { + compatibleGPUs.add(gpuInfo); + } + } + return compatibleGPUs; + } + + /** + * Gets all the available GPUs + * + * @return a list of {@link GPUInfo} objects with GPU details + */ + public static List availableGPUs() throws Throwable { + List results = new ArrayList(); + MemoryLayout returnValueMemoryLayout = intMemoryLayout; + MemorySegment returnValueMemorySegment = arena.allocate(returnValueMemoryLayout); + MemoryLayout numGpuMemoryLayout = intMemoryLayout; + MemorySegment numGpuMemorySegment = arena.allocate(numGpuMemoryLayout); + + /* + * Setting a value of 1024 because we cannot predict how much memory to allocate + * before the function is invoked as cudaGetDeviceCount is inside the + * get_gpu_info function. + */ + MemorySegment GpuInfoArrayMemorySegment = GpuInfo.allocateArray(1024, arena); + getGpuInfoMethodHandle.invokeExact(returnValueMemorySegment, numGpuMemorySegment, GpuInfoArrayMemorySegment); + int numGPUs = numGpuMemorySegment.get(ValueLayout.JAVA_INT, 0); + MemoryLayout ml = MemoryLayout.sequenceLayout(numGPUs, GpuInfo.layout()); + for (int i = 0; i < numGPUs; i++) { + VarHandle gpuIdVarHandle = ml.varHandle(PathElement.sequenceElement(i), PathElement.groupElement("gpu_id")); + VarHandle freeMemoryVarHandle = ml.varHandle(PathElement.sequenceElement(i), + PathElement.groupElement("free_memory")); + VarHandle totalMemoryVarHandle = ml.varHandle(PathElement.sequenceElement(i), + PathElement.groupElement("total_memory")); + VarHandle ComputeCapabilityVarHandle = ml.varHandle(PathElement.sequenceElement(i), + PathElement.groupElement("compute_capability")); + StringBuilder gpuName = new StringBuilder(); + char b = 1; + int p = 0; + while (b != 0x00) { + VarHandle gpuNameVarHandle = ml.varHandle(PathElement.sequenceElement(i), PathElement.groupElement("name"), + PathElement.sequenceElement(p++)); + b = (char) (byte) gpuNameVarHandle.get(GpuInfoArrayMemorySegment, 0L); + gpuName.append(b); + } + results.add(new GPUInfo((int) gpuIdVarHandle.get(GpuInfoArrayMemorySegment, 0L), gpuName.toString().trim(), + (long) freeMemoryVarHandle.get(GpuInfoArrayMemorySegment, 0L), + (long) totalMemoryVarHandle.get(GpuInfoArrayMemorySegment, 0L), + (float) ComputeCapabilityVarHandle.get(GpuInfoArrayMemorySegment, 0L))); + } + return results; + } + + /** + * A utility method for getting an instance of {@link MemorySegment} for a + * {@link String}. + * + * @param str the string for the expected {@link MemorySegment} + * @return an instance of {@link MemorySegment} + */ + public static MemorySegment buildMemorySegment(Linker linker, Arena arena, String str) { + MemoryLayout charMemoryLayout = linker.canonicalLayouts().get("char"); + StringBuilder sb = new StringBuilder(str).append('\0'); + MemoryLayout stringMemoryLayout = MemoryLayout.sequenceLayout(sb.length(), charMemoryLayout); + MemorySegment stringMemorySegment = arena.allocate(stringMemoryLayout); + + for (int i = 0; i < sb.length(); i++) { + VarHandle varHandle = stringMemoryLayout.varHandle(PathElement.sequenceElement(i)); + varHandle.set(stringMemorySegment, 0L, (byte) sb.charAt(i)); + } + return stringMemorySegment; + } + + /** + * A utility method for building a {@link MemorySegment} for a 1D long array. + * + * @param data The 1D long array for which the {@link MemorySegment} is needed + * @return an instance of {@link MemorySegment} + */ + public static MemorySegment buildMemorySegment(Linker linker, Arena arena, long[] data) { + int cells = data.length; + MemoryLayout longMemoryLayout = linker.canonicalLayouts().get("long"); + MemoryLayout dataMemoryLayout = MemoryLayout.sequenceLayout(cells, longMemoryLayout); + MemorySegment dataMemorySegment = arena.allocate(dataMemoryLayout); + MemorySegment.copy(data, 0, dataMemorySegment, (ValueLayout) longMemoryLayout, 0, cells); + return dataMemorySegment; + } + + /** + * A utility method for building a {@link MemorySegment} for a 2D float array. + * + * @param data The 2D float array for which the {@link MemorySegment} is needed + * @return an instance of {@link MemorySegment} + */ + public static MemorySegment buildMemorySegment(Linker linker, Arena arena, float[][] data) { + long rows = data.length; + long cols = rows > 0 ? data[0].length : 0; + MemoryLayout floatMemoryLayout = linker.canonicalLayouts().get("float"); + MemoryLayout dataMemoryLayout = MemoryLayout.sequenceLayout(rows * cols, floatMemoryLayout); + MemorySegment dataMemorySegment = arena.allocate(dataMemoryLayout); + long floatByteSize = floatMemoryLayout.byteSize(); + + for (int r = 0; r < rows; r++) { + MemorySegment.copy(data[r], 0, dataMemorySegment, (ValueLayout) floatMemoryLayout, (r * cols * floatByteSize), + (int) cols); + } + + return dataMemorySegment; + } + + /** + * Load the CuVS .so file from environment variable CUVS_JAVA_SO_PATH. If not + * found there, try to load it from the classpath to a temporary file. + */ + public static File loadNativeLibrary() throws IOException { + String libraryPathFromEnvironment = System.getenv("CUVS_JAVA_SO_PATH"); + if (libraryPathFromEnvironment != null) { + File file = new File(libraryPathFromEnvironment); + if (!file.exists()) + throw new RuntimeException( + "Environment variable CUVS_JAVA_SO_PATH points to non-existent file: " + libraryPathFromEnvironment); + return file; + } + return loadLibraryFromJar("/libcuvs_java.so"); + } + + private static File loadLibraryFromJar(String path) throws IOException { + if (!path.startsWith("/")) { + throw new IllegalArgumentException("The path has to be absolute (start with '/')."); + } + // Obtain filename from path + String[] parts = path.split("/"); + String filename = (parts.length > 1) ? parts[parts.length - 1] : null; + + // Split filename to prefix and suffix (extension) + String prefix = ""; + String suffix = null; + if (filename != null) { + parts = filename.split("\\.", 2); + prefix = parts[0]; + suffix = (parts.length > 1) ? "." + parts[parts.length - 1] : null; + } + // Prepare temporary file + File temp = File.createTempFile(prefix, suffix); + InputStream libraryStream = Util.class.getModule().getResourceAsStream(path); // Util.class.getResourceAsStream(path); + streamCopy(libraryStream, new FileOutputStream(temp)); + + return temp; + } + + private static void streamCopy(InputStream is, OutputStream os) throws LibraryException { + if (is == null) { + throw new LibraryException("CuVS Library Not Found in ClassPath"); + } + byte[] buffer = new byte[1024]; + int readBytes; + + try { + while ((readBytes = is.read(buffer)) != -1) { + os.write(buffer, 0, readBytes); + } + } catch (IOException e) { + throw new LibraryException(e); + } finally { + // If read/write fails, close streams safely before throwing an exception + if (os != null) + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + if (is != null) + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/BruteForceH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/BruteForceH.java new file mode 100644 index 000000000..16603606b --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/BruteForceH.java @@ -0,0 +1,1912 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.foreign.ValueLayout.OfByte; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.foreign.ValueLayout.OfShort; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.stream.Collectors; + +public class BruteForceH { + + BruteForceH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol).orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream().map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? MemoryLayout.structLayout(alignedMembers) + : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int DLPACK_VERSION = (int) 80L; + + /** + * {@snippet lang = c : * #define DLPACK_VERSION 80 + * } + */ + public static int DLPACK_VERSION() { + return DLPACK_VERSION; + } + + private static final int DLPACK_ABI_VERSION = (int) 1L; + + /** + * {@snippet lang = c : * #define DLPACK_ABI_VERSION 1 + * } + */ + public static int DLPACK_ABI_VERSION() { + return DLPACK_ABI_VERSION; + } + + private static final int _STDINT_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDINT_H 1 + * } + */ + public static int _STDINT_H() { + return _STDINT_H; + } + + private static final int _FEATURES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _FEATURES_H 1 + * } + */ + public static int _FEATURES_H() { + return _FEATURES_H; + } + + private static final int _DEFAULT_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _DEFAULT_SOURCE 1 + * } + */ + public static int _DEFAULT_SOURCE() { + return _DEFAULT_SOURCE; + } + + private static final int __GLIBC_USE_ISOC2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_ISOC2X 0 + * } + */ + public static int __GLIBC_USE_ISOC2X() { + return __GLIBC_USE_ISOC2X; + } + + private static final int __USE_ISOC11 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC11 1 + * } + */ + public static int __USE_ISOC11() { + return __USE_ISOC11; + } + + private static final int __USE_ISOC99 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC99 1 + * } + */ + public static int __USE_ISOC99() { + return __USE_ISOC99; + } + + private static final int __USE_ISOC95 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC95 1 + * } + */ + public static int __USE_ISOC95() { + return __USE_ISOC95; + } + + private static final int __USE_POSIX_IMPLICITLY = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX_IMPLICITLY 1 + * } + */ + public static int __USE_POSIX_IMPLICITLY() { + return __USE_POSIX_IMPLICITLY; + } + + private static final int _POSIX_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _POSIX_SOURCE 1 + * } + */ + public static int _POSIX_SOURCE() { + return _POSIX_SOURCE; + } + + private static final int __USE_POSIX = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX 1 + * } + */ + public static int __USE_POSIX() { + return __USE_POSIX; + } + + private static final int __USE_POSIX2 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX2 1 + * } + */ + public static int __USE_POSIX2() { + return __USE_POSIX2; + } + + private static final int __USE_POSIX199309 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199309 1 + * } + */ + public static int __USE_POSIX199309() { + return __USE_POSIX199309; + } + + private static final int __USE_POSIX199506 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199506 1 + * } + */ + public static int __USE_POSIX199506() { + return __USE_POSIX199506; + } + + private static final int __USE_XOPEN2K = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K 1 + * } + */ + public static int __USE_XOPEN2K() { + return __USE_XOPEN2K; + } + + private static final int __USE_XOPEN2K8 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K8 1 + * } + */ + public static int __USE_XOPEN2K8() { + return __USE_XOPEN2K8; + } + + private static final int _ATFILE_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _ATFILE_SOURCE 1 + * } + */ + public static int _ATFILE_SOURCE() { + return _ATFILE_SOURCE; + } + + private static final int __WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __WORDSIZE 64 + * } + */ + public static int __WORDSIZE() { + return __WORDSIZE; + } + + private static final int __WORDSIZE_TIME64_COMPAT32 = (int) 1L; + + /** + * {@snippet lang = c : * #define __WORDSIZE_TIME64_COMPAT32 1 + * } + */ + public static int __WORDSIZE_TIME64_COMPAT32() { + return __WORDSIZE_TIME64_COMPAT32; + } + + private static final int __SYSCALL_WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __SYSCALL_WORDSIZE 64 + * } + */ + public static int __SYSCALL_WORDSIZE() { + return __SYSCALL_WORDSIZE; + } + + private static final int __USE_MISC = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_MISC 1 + * } + */ + public static int __USE_MISC() { + return __USE_MISC; + } + + private static final int __USE_ATFILE = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ATFILE 1 + * } + */ + public static int __USE_ATFILE() { + return __USE_ATFILE; + } + + private static final int __USE_FORTIFY_LEVEL = (int) 0L; + + /** + * {@snippet lang = c : * #define __USE_FORTIFY_LEVEL 0 + * } + */ + public static int __USE_FORTIFY_LEVEL() { + return __USE_FORTIFY_LEVEL; + } + + private static final int __GLIBC_USE_DEPRECATED_GETS = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_GETS 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_GETS() { + return __GLIBC_USE_DEPRECATED_GETS; + } + + private static final int __GLIBC_USE_DEPRECATED_SCANF = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_SCANF 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_SCANF() { + return __GLIBC_USE_DEPRECATED_SCANF; + } + + private static final int _STDC_PREDEF_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDC_PREDEF_H 1 + * } + */ + public static int _STDC_PREDEF_H() { + return _STDC_PREDEF_H; + } + + private static final int __STDC_IEC_559__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559__ 1 + * } + */ + public static int __STDC_IEC_559__() { + return __STDC_IEC_559__; + } + + private static final int __STDC_IEC_559_COMPLEX__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559_COMPLEX__ 1 + * } + */ + public static int __STDC_IEC_559_COMPLEX__() { + return __STDC_IEC_559_COMPLEX__; + } + + private static final int __GNU_LIBRARY__ = (int) 6L; + + /** + * {@snippet lang = c : * #define __GNU_LIBRARY__ 6 + * } + */ + public static int __GNU_LIBRARY__() { + return __GNU_LIBRARY__; + } + + private static final int __GLIBC__ = (int) 2L; + + /** + * {@snippet lang = c : * #define __GLIBC__ 2 + * } + */ + public static int __GLIBC__() { + return __GLIBC__; + } + + private static final int __GLIBC_MINOR__ = (int) 35L; + + /** + * {@snippet lang = c : * #define __GLIBC_MINOR__ 35 + * } + */ + public static int __GLIBC_MINOR__() { + return __GLIBC_MINOR__; + } + + private static final int _SYS_CDEFS_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _SYS_CDEFS_H 1 + * } + */ + public static int _SYS_CDEFS_H() { + return _SYS_CDEFS_H; + } + + private static final int __glibc_c99_flexarr_available = (int) 1L; + + /** + * {@snippet lang = c : * #define __glibc_c99_flexarr_available 1 + * } + */ + public static int __glibc_c99_flexarr_available() { + return __glibc_c99_flexarr_available; + } + + private static final int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = (int) 0L; + + /** + * {@snippet lang = c : * #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 + * } + */ + public static int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI() { + return __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI; + } + + private static final int __HAVE_GENERIC_SELECTION = (int) 1L; + + /** + * {@snippet lang = c : * #define __HAVE_GENERIC_SELECTION 1 + * } + */ + public static int __HAVE_GENERIC_SELECTION() { + return __HAVE_GENERIC_SELECTION; + } + + private static final int __GLIBC_USE_LIB_EXT2 = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_LIB_EXT2 0 + * } + */ + public static int __GLIBC_USE_LIB_EXT2() { + return __GLIBC_USE_LIB_EXT2; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT() { + return __GLIBC_USE_IEC_60559_BFP_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT_C2X() { + return __GLIBC_USE_IEC_60559_BFP_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_EXT() { + return __GLIBC_USE_IEC_60559_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_TYPES_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_TYPES_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_TYPES_EXT() { + return __GLIBC_USE_IEC_60559_TYPES_EXT; + } + + private static final int _BITS_TYPES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPES_H 1 + * } + */ + public static int _BITS_TYPES_H() { + return _BITS_TYPES_H; + } + + private static final int _BITS_TYPESIZES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPESIZES_H 1 + * } + */ + public static int _BITS_TYPESIZES_H() { + return _BITS_TYPESIZES_H; + } + + private static final int __OFF_T_MATCHES_OFF64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __OFF_T_MATCHES_OFF64_T 1 + * } + */ + public static int __OFF_T_MATCHES_OFF64_T() { + return __OFF_T_MATCHES_OFF64_T; + } + + private static final int __INO_T_MATCHES_INO64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __INO_T_MATCHES_INO64_T 1 + * } + */ + public static int __INO_T_MATCHES_INO64_T() { + return __INO_T_MATCHES_INO64_T; + } + + private static final int __RLIM_T_MATCHES_RLIM64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __RLIM_T_MATCHES_RLIM64_T 1 + * } + */ + public static int __RLIM_T_MATCHES_RLIM64_T() { + return __RLIM_T_MATCHES_RLIM64_T; + } + + private static final int __STATFS_MATCHES_STATFS64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __STATFS_MATCHES_STATFS64 1 + * } + */ + public static int __STATFS_MATCHES_STATFS64() { + return __STATFS_MATCHES_STATFS64; + } + + private static final int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 + * } + */ + public static int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64() { + return __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64; + } + + private static final int __FD_SETSIZE = (int) 1024L; + + /** + * {@snippet lang = c : * #define __FD_SETSIZE 1024 + * } + */ + public static int __FD_SETSIZE() { + return __FD_SETSIZE; + } + + private static final int _BITS_TIME64_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TIME64_H 1 + * } + */ + public static int _BITS_TIME64_H() { + return _BITS_TIME64_H; + } + + private static final int _BITS_WCHAR_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_WCHAR_H 1 + * } + */ + public static int _BITS_WCHAR_H() { + return _BITS_WCHAR_H; + } + + private static final int _BITS_STDINT_INTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_INTN_H 1 + * } + */ + public static int _BITS_STDINT_INTN_H() { + return _BITS_STDINT_INTN_H; + } + + private static final int _BITS_STDINT_UINTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_UINTN_H 1 + * } + */ + public static int _BITS_STDINT_UINTN_H() { + return _BITS_STDINT_UINTN_H; + } + + /** + * {@snippet lang = c : * typedef unsigned char __u_char + * } + */ + public static final OfByte __u_char = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned short __u_short + * } + */ + public static final OfShort __u_short = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned int __u_int + * } + */ + public static final OfInt __u_int = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __u_long + * } + */ + public static final OfLong __u_long = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char __int8_t + * } + */ + public static final OfByte __int8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned char __uint8_t + * } + */ + public static final OfByte __uint8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef short __int16_t + * } + */ + public static final OfShort __int16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned short __uint16_t + * } + */ + public static final OfShort __uint16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef int __int32_t + * } + */ + public static final OfInt __int32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __uint32_t + * } + */ + public static final OfInt __uint32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef long __int64_t + * } + */ + public static final OfLong __int64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uint64_t + * } + */ + public static final OfLong __uint64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __int8_t __int_least8_t + * } + */ + public static final OfByte __int_least8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint8_t __uint_least8_t + * } + */ + public static final OfByte __uint_least8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t __int_least16_t + * } + */ + public static final OfShort __int_least16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint16_t __uint_least16_t + * } + */ + public static final OfShort __uint_least16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t __int_least32_t + * } + */ + public static final OfInt __int_least32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef __uint32_t __uint_least32_t + * } + */ + public static final OfInt __uint_least32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t __int_least64_t + * } + */ + public static final OfLong __int_least64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint64_t __uint_least64_t + * } + */ + public static final OfLong __uint_least64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __quad_t + * } + */ + public static final OfLong __quad_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __u_quad_t + * } + */ + public static final OfLong __u_quad_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __intmax_t + * } + */ + public static final OfLong __intmax_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uintmax_t + * } + */ + public static final OfLong __uintmax_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __dev_t + * } + */ + public static final OfLong __dev_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __uid_t + * } + */ + public static final OfInt __uid_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __gid_t + * } + */ + public static final OfInt __gid_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __ino_t + * } + */ + public static final OfLong __ino_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __ino64_t + * } + */ + public static final OfLong __ino64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __mode_t + * } + */ + public static final OfInt __mode_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __nlink_t + * } + */ + public static final OfLong __nlink_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off_t + * } + */ + public static final OfLong __off_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off64_t + * } + */ + public static final OfLong __off64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef int __pid_t + * } + */ + public static final OfInt __pid_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef long __clock_t + * } + */ + public static final OfLong __clock_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim_t + * } + */ + public static final OfLong __rlim_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim64_t + * } + */ + public static final OfLong __rlim64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __id_t + * } + */ + public static final OfInt __id_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef long __time_t + * } + */ + public static final OfLong __time_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __useconds_t + * } + */ + public static final OfInt __useconds_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef long __suseconds_t + * } + */ + public static final OfLong __suseconds_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __suseconds64_t + * } + */ + public static final OfLong __suseconds64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef int __daddr_t + * } + */ + public static final OfInt __daddr_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef int __key_t + * } + */ + public static final OfInt __key_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef int __clockid_t + * } + */ + public static final OfInt __clockid_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef void *__timer_t + * } + */ + public static final AddressLayout __timer_t = BruteForceH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __blksize_t + * } + */ + public static final OfLong __blksize_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt_t + * } + */ + public static final OfLong __blkcnt_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt64_t + * } + */ + public static final OfLong __blkcnt64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt_t + * } + */ + public static final OfLong __fsblkcnt_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt64_t + * } + */ + public static final OfLong __fsblkcnt64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt_t + * } + */ + public static final OfLong __fsfilcnt_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt64_t + * } + */ + public static final OfLong __fsfilcnt64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __fsword_t + * } + */ + public static final OfLong __fsword_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __ssize_t + * } + */ + public static final OfLong __ssize_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long __syscall_slong_t + * } + */ + public static final OfLong __syscall_slong_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __syscall_ulong_t + * } + */ + public static final OfLong __syscall_ulong_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __off64_t __loff_t + * } + */ + public static final OfLong __loff_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef char *__caddr_t + * } + */ + public static final AddressLayout __caddr_t = BruteForceH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __intptr_t + * } + */ + public static final OfLong __intptr_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __socklen_t + * } + */ + public static final OfInt __socklen_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef int __sig_atomic_t + * } + */ + public static final OfInt __sig_atomic_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef __int8_t int8_t + * } + */ + public static final OfByte int8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t int16_t + * } + */ + public static final OfShort int16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t int32_t + * } + */ + public static final OfInt int32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t int64_t + * } + */ + public static final OfLong int64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint8_t uint8_t + * } + */ + public static final OfByte uint8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint16_t uint16_t + * } + */ + public static final OfShort uint16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint32_t uint32_t + * } + */ + public static final OfInt uint32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef __uint64_t uint64_t + * } + */ + public static final OfLong uint64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __int_least8_t int_least8_t + * } + */ + public static final OfByte int_least8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int_least16_t int_least16_t + * } + */ + public static final OfShort int_least16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int_least32_t int_least32_t + * } + */ + public static final OfInt int_least32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef __int_least64_t int_least64_t + * } + */ + public static final OfLong int_least64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint_least8_t uint_least8_t + * } + */ + public static final OfByte uint_least8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint_least16_t uint_least16_t + * } + */ + public static final OfShort uint_least16_t = BruteForceH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint_least32_t uint_least32_t + * } + */ + public static final OfInt uint_least32_t = BruteForceH.C_INT; + /** + * {@snippet lang = c : * typedef __uint_least64_t uint_least64_t + * } + */ + public static final OfLong uint_least64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char int_fast8_t + * } + */ + public static final OfByte int_fast8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef long int_fast16_t + * } + */ + public static final OfLong int_fast16_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast32_t + * } + */ + public static final OfLong int_fast32_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast64_t + * } + */ + public static final OfLong int_fast64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned char uint_fast8_t + * } + */ + public static final OfByte uint_fast8_t = BruteForceH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast16_t + * } + */ + public static final OfLong uint_fast16_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast32_t + * } + */ + public static final OfLong uint_fast32_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast64_t + * } + */ + public static final OfLong uint_fast64_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long intptr_t + * } + */ + public static final OfLong intptr_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uintptr_t + * } + */ + public static final OfLong uintptr_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __intmax_t intmax_t + * } + */ + public static final OfLong intmax_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef __uintmax_t uintmax_t + * } + */ + public static final OfLong uintmax_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef long ptrdiff_t + * } + */ + public static final OfLong ptrdiff_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long size_t + * } + */ + public static final OfLong size_t = BruteForceH.C_LONG; + /** + * {@snippet lang = c : * typedef int wchar_t + * } + */ + public static final OfInt wchar_t = BruteForceH.C_INT; + private static final int kDLCPU = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLCPU = 1 + * } + */ + public static int kDLCPU() { + return kDLCPU; + } + + private static final int kDLCUDA = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLCUDA = 2 + * } + */ + public static int kDLCUDA() { + return kDLCUDA; + } + + private static final int kDLCUDAHost = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLCUDAHost = 3 + * } + */ + public static int kDLCUDAHost() { + return kDLCUDAHost; + } + + private static final int kDLOpenCL = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLOpenCL = 4 + * } + */ + public static int kDLOpenCL() { + return kDLOpenCL; + } + + private static final int kDLVulkan = (int) 7L; + + /** + * {@snippet lang = c : * enum .kDLVulkan = 7 + * } + */ + public static int kDLVulkan() { + return kDLVulkan; + } + + private static final int kDLMetal = (int) 8L; + + /** + * {@snippet lang = c : * enum .kDLMetal = 8 + * } + */ + public static int kDLMetal() { + return kDLMetal; + } + + private static final int kDLVPI = (int) 9L; + + /** + * {@snippet lang = c : * enum .kDLVPI = 9 + * } + */ + public static int kDLVPI() { + return kDLVPI; + } + + private static final int kDLROCM = (int) 10L; + + /** + * {@snippet lang = c : * enum .kDLROCM = 10 + * } + */ + public static int kDLROCM() { + return kDLROCM; + } + + private static final int kDLROCMHost = (int) 11L; + + /** + * {@snippet lang = c : * enum .kDLROCMHost = 11 + * } + */ + public static int kDLROCMHost() { + return kDLROCMHost; + } + + private static final int kDLExtDev = (int) 12L; + + /** + * {@snippet lang = c : * enum .kDLExtDev = 12 + * } + */ + public static int kDLExtDev() { + return kDLExtDev; + } + + private static final int kDLCUDAManaged = (int) 13L; + + /** + * {@snippet lang = c : * enum .kDLCUDAManaged = 13 + * } + */ + public static int kDLCUDAManaged() { + return kDLCUDAManaged; + } + + private static final int kDLOneAPI = (int) 14L; + + /** + * {@snippet lang = c : * enum .kDLOneAPI = 14 + * } + */ + public static int kDLOneAPI() { + return kDLOneAPI; + } + + private static final int kDLWebGPU = (int) 15L; + + /** + * {@snippet lang = c : * enum .kDLWebGPU = 15 + * } + */ + public static int kDLWebGPU() { + return kDLWebGPU; + } + + private static final int kDLHexagon = (int) 16L; + + /** + * {@snippet lang = c : * enum .kDLHexagon = 16 + * } + */ + public static int kDLHexagon() { + return kDLHexagon; + } + + private static final int kDLInt = (int) 0L; + + /** + * {@snippet lang = c : * enum .kDLInt = 0 + * } + */ + public static int kDLInt() { + return kDLInt; + } + + private static final int kDLUInt = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLUInt = 1 + * } + */ + public static int kDLUInt() { + return kDLUInt; + } + + private static final int kDLFloat = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLFloat = 2 + * } + */ + public static int kDLFloat() { + return kDLFloat; + } + + private static final int kDLOpaqueHandle = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLOpaqueHandle = 3 + * } + */ + public static int kDLOpaqueHandle() { + return kDLOpaqueHandle; + } + + private static final int kDLBfloat = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLBfloat = 4 + * } + */ + public static int kDLBfloat() { + return kDLBfloat; + } + + private static final int kDLComplex = (int) 5L; + + /** + * {@snippet lang = c : * enum .kDLComplex = 5 + * } + */ + public static int kDLComplex() { + return kDLComplex; + } + + private static final int kDLBool = (int) 6L; + + /** + * {@snippet lang = c : * enum .kDLBool = 6 + * } + */ + public static int kDLBool() { + return kDLBool; + } + + /** + * {@snippet lang = c : * typedef cuvsBruteForceIndex *cuvsBruteForceIndex_t + * } + */ + public static final AddressLayout cuvsBruteForceIndex_t = BruteForceH.C_POINTER; + private static final long _POSIX_C_SOURCE = 200809L; + + /** + * {@snippet lang = c : * #define _POSIX_C_SOURCE 200809 + * } + */ + public static long _POSIX_C_SOURCE() { + return _POSIX_C_SOURCE; + } + + private static final int __TIMESIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __TIMESIZE 64 + * } + */ + public static int __TIMESIZE() { + return __TIMESIZE; + } + + private static final long __STDC_IEC_60559_BFP__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_BFP__ 201404 + * } + */ + public static long __STDC_IEC_60559_BFP__() { + return __STDC_IEC_60559_BFP__; + } + + private static final long __STDC_IEC_60559_COMPLEX__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_COMPLEX__ 201404 + * } + */ + public static long __STDC_IEC_60559_COMPLEX__() { + return __STDC_IEC_60559_COMPLEX__; + } + + private static final long __STDC_ISO_10646__ = 201706L; + + /** + * {@snippet lang = c : * #define __STDC_ISO_10646__ 201706 + * } + */ + public static long __STDC_ISO_10646__() { + return __STDC_ISO_10646__; + } + + private static final int __WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define __WCHAR_MAX 2147483647 + * } + */ + public static int __WCHAR_MAX() { + return __WCHAR_MAX; + } + + private static final int __WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define __WCHAR_MIN -2147483648 + * } + */ + public static int __WCHAR_MIN() { + return __WCHAR_MIN; + } + + private static final int INT8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT8_MIN -128 + * } + */ + public static int INT8_MIN() { + return INT8_MIN; + } + + private static final int INT16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT16_MIN -32768 + * } + */ + public static int INT16_MIN() { + return INT16_MIN; + } + + private static final int INT32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT32_MIN -2147483648 + * } + */ + public static int INT32_MIN() { + return INT32_MIN; + } + + private static final long INT64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT64_MIN -9223372036854775808 + * } + */ + public static long INT64_MIN() { + return INT64_MIN; + } + + private static final int INT8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT8_MAX 127 + * } + */ + public static int INT8_MAX() { + return INT8_MAX; + } + + private static final int INT16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT16_MAX 32767 + * } + */ + public static int INT16_MAX() { + return INT16_MAX; + } + + private static final int INT32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT32_MAX 2147483647 + * } + */ + public static int INT32_MAX() { + return INT32_MAX; + } + + private static final long INT64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT64_MAX 9223372036854775807 + * } + */ + public static long INT64_MAX() { + return INT64_MAX; + } + + private static final int UINT8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT8_MAX 255 + * } + */ + public static int UINT8_MAX() { + return UINT8_MAX; + } + + private static final int UINT16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT16_MAX 65535 + * } + */ + public static int UINT16_MAX() { + return UINT16_MAX; + } + + private static final int UINT32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT32_MAX 4294967295 + * } + */ + public static int UINT32_MAX() { + return UINT32_MAX; + } + + private static final long UINT64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT64_MAX -1 + * } + */ + public static long UINT64_MAX() { + return UINT64_MAX; + } + + private static final int INT_LEAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MIN -128 + * } + */ + public static int INT_LEAST8_MIN() { + return INT_LEAST8_MIN; + } + + private static final int INT_LEAST16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MIN -32768 + * } + */ + public static int INT_LEAST16_MIN() { + return INT_LEAST16_MIN; + } + + private static final int INT_LEAST32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MIN -2147483648 + * } + */ + public static int INT_LEAST32_MIN() { + return INT_LEAST32_MIN; + } + + private static final long INT_LEAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MIN -9223372036854775808 + * } + */ + public static long INT_LEAST64_MIN() { + return INT_LEAST64_MIN; + } + + private static final int INT_LEAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MAX 127 + * } + */ + public static int INT_LEAST8_MAX() { + return INT_LEAST8_MAX; + } + + private static final int INT_LEAST16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MAX 32767 + * } + */ + public static int INT_LEAST16_MAX() { + return INT_LEAST16_MAX; + } + + private static final int INT_LEAST32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MAX 2147483647 + * } + */ + public static int INT_LEAST32_MAX() { + return INT_LEAST32_MAX; + } + + private static final long INT_LEAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MAX 9223372036854775807 + * } + */ + public static long INT_LEAST64_MAX() { + return INT_LEAST64_MAX; + } + + private static final int UINT_LEAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_LEAST8_MAX 255 + * } + */ + public static int UINT_LEAST8_MAX() { + return UINT_LEAST8_MAX; + } + + private static final int UINT_LEAST16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT_LEAST16_MAX 65535 + * } + */ + public static int UINT_LEAST16_MAX() { + return UINT_LEAST16_MAX; + } + + private static final int UINT_LEAST32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT_LEAST32_MAX 4294967295 + * } + */ + public static int UINT_LEAST32_MAX() { + return UINT_LEAST32_MAX; + } + + private static final long UINT_LEAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_LEAST64_MAX -1 + * } + */ + public static long UINT_LEAST64_MAX() { + return UINT_LEAST64_MAX; + } + + private static final int INT_FAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MIN -128 + * } + */ + public static int INT_FAST8_MIN() { + return INT_FAST8_MIN; + } + + private static final long INT_FAST16_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MIN -9223372036854775808 + * } + */ + public static long INT_FAST16_MIN() { + return INT_FAST16_MIN; + } + + private static final long INT_FAST32_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MIN -9223372036854775808 + * } + */ + public static long INT_FAST32_MIN() { + return INT_FAST32_MIN; + } + + private static final long INT_FAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MIN -9223372036854775808 + * } + */ + public static long INT_FAST64_MIN() { + return INT_FAST64_MIN; + } + + private static final int INT_FAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MAX 127 + * } + */ + public static int INT_FAST8_MAX() { + return INT_FAST8_MAX; + } + + private static final long INT_FAST16_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MAX 9223372036854775807 + * } + */ + public static long INT_FAST16_MAX() { + return INT_FAST16_MAX; + } + + private static final long INT_FAST32_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MAX 9223372036854775807 + * } + */ + public static long INT_FAST32_MAX() { + return INT_FAST32_MAX; + } + + private static final long INT_FAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MAX 9223372036854775807 + * } + */ + public static long INT_FAST64_MAX() { + return INT_FAST64_MAX; + } + + private static final int UINT_FAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_FAST8_MAX 255 + * } + */ + public static int UINT_FAST8_MAX() { + return UINT_FAST8_MAX; + } + + private static final long UINT_FAST16_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST16_MAX -1 + * } + */ + public static long UINT_FAST16_MAX() { + return UINT_FAST16_MAX; + } + + private static final long UINT_FAST32_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST32_MAX -1 + * } + */ + public static long UINT_FAST32_MAX() { + return UINT_FAST32_MAX; + } + + private static final long UINT_FAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST64_MAX -1 + * } + */ + public static long UINT_FAST64_MAX() { + return UINT_FAST64_MAX; + } + + private static final long INTPTR_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTPTR_MIN -9223372036854775808 + * } + */ + public static long INTPTR_MIN() { + return INTPTR_MIN; + } + + private static final long INTPTR_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTPTR_MAX 9223372036854775807 + * } + */ + public static long INTPTR_MAX() { + return INTPTR_MAX; + } + + private static final long UINTPTR_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTPTR_MAX -1 + * } + */ + public static long UINTPTR_MAX() { + return UINTPTR_MAX; + } + + private static final long INTMAX_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTMAX_MIN -9223372036854775808 + * } + */ + public static long INTMAX_MIN() { + return INTMAX_MIN; + } + + private static final long INTMAX_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTMAX_MAX 9223372036854775807 + * } + */ + public static long INTMAX_MAX() { + return INTMAX_MAX; + } + + private static final long UINTMAX_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTMAX_MAX -1 + * } + */ + public static long UINTMAX_MAX() { + return UINTMAX_MAX; + } + + private static final long PTRDIFF_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MIN -9223372036854775808 + * } + */ + public static long PTRDIFF_MIN() { + return PTRDIFF_MIN; + } + + private static final long PTRDIFF_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MAX 9223372036854775807 + * } + */ + public static long PTRDIFF_MAX() { + return PTRDIFF_MAX; + } + + private static final int SIG_ATOMIC_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MIN -2147483648 + * } + */ + public static int SIG_ATOMIC_MIN() { + return SIG_ATOMIC_MIN; + } + + private static final int SIG_ATOMIC_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MAX 2147483647 + * } + */ + public static int SIG_ATOMIC_MAX() { + return SIG_ATOMIC_MAX; + } + + private static final long SIZE_MAX = -1L; + + /** + * {@snippet lang = c : * #define SIZE_MAX -1 + * } + */ + public static long SIZE_MAX() { + return SIZE_MAX; + } + + private static final int WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define WCHAR_MIN -2147483648 + * } + */ + public static int WCHAR_MIN() { + return WCHAR_MIN; + } + + private static final int WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define WCHAR_MAX 2147483647 + * } + */ + public static int WCHAR_MAX() { + return WCHAR_MAX; + } + + private static final int WINT_MIN = (int) 0L; + + /** + * {@snippet lang = c : * #define WINT_MIN 0 + * } + */ + public static int WINT_MIN() { + return WINT_MIN; + } + + private static final int WINT_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define WINT_MAX 4294967295 + * } + */ + public static int WINT_MAX() { + return WINT_MAX; + } + + private static final MemorySegment NULL = MemorySegment.ofAddress(0L); + + /** + * {@snippet lang = c : * #define NULL (void*) 0 + * } + */ + public static MemorySegment NULL() { + return NULL; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CagraH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CagraH.java new file mode 100644 index 000000000..88ddeb6fe --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CagraH.java @@ -0,0 +1,2298 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.foreign.ValueLayout.OfByte; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.foreign.ValueLayout.OfShort; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.stream.Collectors; + +public class CagraH { + + CagraH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol).orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream().map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? MemoryLayout.structLayout(alignedMembers) + : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int DLPACK_VERSION = (int) 80L; + + /** + * {@snippet lang = c : * #define DLPACK_VERSION 80 + * } + */ + public static int DLPACK_VERSION() { + return DLPACK_VERSION; + } + + private static final int DLPACK_ABI_VERSION = (int) 1L; + + /** + * {@snippet lang = c : * #define DLPACK_ABI_VERSION 1 + * } + */ + public static int DLPACK_ABI_VERSION() { + return DLPACK_ABI_VERSION; + } + + private static final int _STDINT_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDINT_H 1 + * } + */ + public static int _STDINT_H() { + return _STDINT_H; + } + + private static final int _FEATURES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _FEATURES_H 1 + * } + */ + public static int _FEATURES_H() { + return _FEATURES_H; + } + + private static final int _DEFAULT_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _DEFAULT_SOURCE 1 + * } + */ + public static int _DEFAULT_SOURCE() { + return _DEFAULT_SOURCE; + } + + private static final int __GLIBC_USE_ISOC2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_ISOC2X 0 + * } + */ + public static int __GLIBC_USE_ISOC2X() { + return __GLIBC_USE_ISOC2X; + } + + private static final int __USE_ISOC11 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC11 1 + * } + */ + public static int __USE_ISOC11() { + return __USE_ISOC11; + } + + private static final int __USE_ISOC99 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC99 1 + * } + */ + public static int __USE_ISOC99() { + return __USE_ISOC99; + } + + private static final int __USE_ISOC95 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC95 1 + * } + */ + public static int __USE_ISOC95() { + return __USE_ISOC95; + } + + private static final int __USE_POSIX_IMPLICITLY = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX_IMPLICITLY 1 + * } + */ + public static int __USE_POSIX_IMPLICITLY() { + return __USE_POSIX_IMPLICITLY; + } + + private static final int _POSIX_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _POSIX_SOURCE 1 + * } + */ + public static int _POSIX_SOURCE() { + return _POSIX_SOURCE; + } + + private static final int __USE_POSIX = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX 1 + * } + */ + public static int __USE_POSIX() { + return __USE_POSIX; + } + + private static final int __USE_POSIX2 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX2 1 + * } + */ + public static int __USE_POSIX2() { + return __USE_POSIX2; + } + + private static final int __USE_POSIX199309 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199309 1 + * } + */ + public static int __USE_POSIX199309() { + return __USE_POSIX199309; + } + + private static final int __USE_POSIX199506 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199506 1 + * } + */ + public static int __USE_POSIX199506() { + return __USE_POSIX199506; + } + + private static final int __USE_XOPEN2K = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K 1 + * } + */ + public static int __USE_XOPEN2K() { + return __USE_XOPEN2K; + } + + private static final int __USE_XOPEN2K8 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K8 1 + * } + */ + public static int __USE_XOPEN2K8() { + return __USE_XOPEN2K8; + } + + private static final int _ATFILE_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _ATFILE_SOURCE 1 + * } + */ + public static int _ATFILE_SOURCE() { + return _ATFILE_SOURCE; + } + + private static final int __WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __WORDSIZE 64 + * } + */ + public static int __WORDSIZE() { + return __WORDSIZE; + } + + private static final int __WORDSIZE_TIME64_COMPAT32 = (int) 1L; + + /** + * {@snippet lang = c : * #define __WORDSIZE_TIME64_COMPAT32 1 + * } + */ + public static int __WORDSIZE_TIME64_COMPAT32() { + return __WORDSIZE_TIME64_COMPAT32; + } + + private static final int __SYSCALL_WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __SYSCALL_WORDSIZE 64 + * } + */ + public static int __SYSCALL_WORDSIZE() { + return __SYSCALL_WORDSIZE; + } + + private static final int __USE_MISC = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_MISC 1 + * } + */ + public static int __USE_MISC() { + return __USE_MISC; + } + + private static final int __USE_ATFILE = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ATFILE 1 + * } + */ + public static int __USE_ATFILE() { + return __USE_ATFILE; + } + + private static final int __USE_FORTIFY_LEVEL = (int) 0L; + + /** + * {@snippet lang = c : * #define __USE_FORTIFY_LEVEL 0 + * } + */ + public static int __USE_FORTIFY_LEVEL() { + return __USE_FORTIFY_LEVEL; + } + + private static final int __GLIBC_USE_DEPRECATED_GETS = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_GETS 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_GETS() { + return __GLIBC_USE_DEPRECATED_GETS; + } + + private static final int __GLIBC_USE_DEPRECATED_SCANF = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_SCANF 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_SCANF() { + return __GLIBC_USE_DEPRECATED_SCANF; + } + + private static final int _STDC_PREDEF_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDC_PREDEF_H 1 + * } + */ + public static int _STDC_PREDEF_H() { + return _STDC_PREDEF_H; + } + + private static final int __STDC_IEC_559__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559__ 1 + * } + */ + public static int __STDC_IEC_559__() { + return __STDC_IEC_559__; + } + + private static final int __STDC_IEC_559_COMPLEX__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559_COMPLEX__ 1 + * } + */ + public static int __STDC_IEC_559_COMPLEX__() { + return __STDC_IEC_559_COMPLEX__; + } + + private static final int __GNU_LIBRARY__ = (int) 6L; + + /** + * {@snippet lang = c : * #define __GNU_LIBRARY__ 6 + * } + */ + public static int __GNU_LIBRARY__() { + return __GNU_LIBRARY__; + } + + private static final int __GLIBC__ = (int) 2L; + + /** + * {@snippet lang = c : * #define __GLIBC__ 2 + * } + */ + public static int __GLIBC__() { + return __GLIBC__; + } + + private static final int __GLIBC_MINOR__ = (int) 35L; + + /** + * {@snippet lang = c : * #define __GLIBC_MINOR__ 35 + * } + */ + public static int __GLIBC_MINOR__() { + return __GLIBC_MINOR__; + } + + private static final int _SYS_CDEFS_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _SYS_CDEFS_H 1 + * } + */ + public static int _SYS_CDEFS_H() { + return _SYS_CDEFS_H; + } + + private static final int __glibc_c99_flexarr_available = (int) 1L; + + /** + * {@snippet lang = c : * #define __glibc_c99_flexarr_available 1 + * } + */ + public static int __glibc_c99_flexarr_available() { + return __glibc_c99_flexarr_available; + } + + private static final int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = (int) 0L; + + /** + * {@snippet lang = c : * #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 + * } + */ + public static int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI() { + return __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI; + } + + private static final int __HAVE_GENERIC_SELECTION = (int) 1L; + + /** + * {@snippet lang = c : * #define __HAVE_GENERIC_SELECTION 1 + * } + */ + public static int __HAVE_GENERIC_SELECTION() { + return __HAVE_GENERIC_SELECTION; + } + + private static final int __GLIBC_USE_LIB_EXT2 = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_LIB_EXT2 0 + * } + */ + public static int __GLIBC_USE_LIB_EXT2() { + return __GLIBC_USE_LIB_EXT2; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT() { + return __GLIBC_USE_IEC_60559_BFP_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT_C2X() { + return __GLIBC_USE_IEC_60559_BFP_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_EXT() { + return __GLIBC_USE_IEC_60559_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_TYPES_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_TYPES_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_TYPES_EXT() { + return __GLIBC_USE_IEC_60559_TYPES_EXT; + } + + private static final int _BITS_TYPES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPES_H 1 + * } + */ + public static int _BITS_TYPES_H() { + return _BITS_TYPES_H; + } + + private static final int _BITS_TYPESIZES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPESIZES_H 1 + * } + */ + public static int _BITS_TYPESIZES_H() { + return _BITS_TYPESIZES_H; + } + + private static final int __OFF_T_MATCHES_OFF64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __OFF_T_MATCHES_OFF64_T 1 + * } + */ + public static int __OFF_T_MATCHES_OFF64_T() { + return __OFF_T_MATCHES_OFF64_T; + } + + private static final int __INO_T_MATCHES_INO64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __INO_T_MATCHES_INO64_T 1 + * } + */ + public static int __INO_T_MATCHES_INO64_T() { + return __INO_T_MATCHES_INO64_T; + } + + private static final int __RLIM_T_MATCHES_RLIM64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __RLIM_T_MATCHES_RLIM64_T 1 + * } + */ + public static int __RLIM_T_MATCHES_RLIM64_T() { + return __RLIM_T_MATCHES_RLIM64_T; + } + + private static final int __STATFS_MATCHES_STATFS64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __STATFS_MATCHES_STATFS64 1 + * } + */ + public static int __STATFS_MATCHES_STATFS64() { + return __STATFS_MATCHES_STATFS64; + } + + private static final int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 + * } + */ + public static int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64() { + return __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64; + } + + private static final int __FD_SETSIZE = (int) 1024L; + + /** + * {@snippet lang = c : * #define __FD_SETSIZE 1024 + * } + */ + public static int __FD_SETSIZE() { + return __FD_SETSIZE; + } + + private static final int _BITS_TIME64_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TIME64_H 1 + * } + */ + public static int _BITS_TIME64_H() { + return _BITS_TIME64_H; + } + + private static final int _BITS_WCHAR_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_WCHAR_H 1 + * } + */ + public static int _BITS_WCHAR_H() { + return _BITS_WCHAR_H; + } + + private static final int _BITS_STDINT_INTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_INTN_H 1 + * } + */ + public static int _BITS_STDINT_INTN_H() { + return _BITS_STDINT_INTN_H; + } + + private static final int _BITS_STDINT_UINTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_UINTN_H 1 + * } + */ + public static int _BITS_STDINT_UINTN_H() { + return _BITS_STDINT_UINTN_H; + } + + private static final int true_ = (int) 1L; + + /** + * {@snippet lang = c : * #define true 1 + * } + */ + public static int true_() { + return true_; + } + + private static final int false_ = (int) 0L; + + /** + * {@snippet lang = c : * #define false 0 + * } + */ + public static int false_() { + return false_; + } + + private static final int __bool_true_false_are_defined = (int) 1L; + + /** + * {@snippet lang = c : * #define __bool_true_false_are_defined 1 + * } + */ + public static int __bool_true_false_are_defined() { + return __bool_true_false_are_defined; + } + + private static final int L2Expanded = (int) 0L; + + /** + * {@snippet lang = c : * enum .L2Expanded = 0 + * } + */ + public static int L2Expanded() { + return L2Expanded; + } + + private static final int L2SqrtExpanded = (int) 1L; + + /** + * {@snippet lang = c : * enum .L2SqrtExpanded = 1 + * } + */ + public static int L2SqrtExpanded() { + return L2SqrtExpanded; + } + + private static final int CosineExpanded = (int) 2L; + + /** + * {@snippet lang = c : * enum .CosineExpanded = 2 + * } + */ + public static int CosineExpanded() { + return CosineExpanded; + } + + private static final int L1 = (int) 3L; + + /** + * {@snippet lang = c : * enum .L1 = 3 + * } + */ + public static int L1() { + return L1; + } + + private static final int L2Unexpanded = (int) 4L; + + /** + * {@snippet lang = c : * enum .L2Unexpanded = 4 + * } + */ + public static int L2Unexpanded() { + return L2Unexpanded; + } + + private static final int L2SqrtUnexpanded = (int) 5L; + + /** + * {@snippet lang = c : * enum .L2SqrtUnexpanded = 5 + * } + */ + public static int L2SqrtUnexpanded() { + return L2SqrtUnexpanded; + } + + private static final int InnerProduct = (int) 6L; + + /** + * {@snippet lang = c : * enum .InnerProduct = 6 + * } + */ + public static int InnerProduct() { + return InnerProduct; + } + + private static final int Linf = (int) 7L; + + /** + * {@snippet lang = c : * enum .Linf = 7 + * } + */ + public static int Linf() { + return Linf; + } + + private static final int Canberra = (int) 8L; + + /** + * {@snippet lang = c : * enum .Canberra = 8 + * } + */ + public static int Canberra() { + return Canberra; + } + + private static final int LpUnexpanded = (int) 9L; + + /** + * {@snippet lang = c : * enum .LpUnexpanded = 9 + * } + */ + public static int LpUnexpanded() { + return LpUnexpanded; + } + + private static final int CorrelationExpanded = (int) 10L; + + /** + * {@snippet lang = c : * enum .CorrelationExpanded = 10 + * } + */ + public static int CorrelationExpanded() { + return CorrelationExpanded; + } + + private static final int JaccardExpanded = (int) 11L; + + /** + * {@snippet lang = c : * enum .JaccardExpanded = 11 + * } + */ + public static int JaccardExpanded() { + return JaccardExpanded; + } + + private static final int HellingerExpanded = (int) 12L; + + /** + * {@snippet lang = c : * enum .HellingerExpanded = 12 + * } + */ + public static int HellingerExpanded() { + return HellingerExpanded; + } + + private static final int Haversine = (int) 13L; + + /** + * {@snippet lang = c : * enum .Haversine = 13 + * } + */ + public static int Haversine() { + return Haversine; + } + + private static final int BrayCurtis = (int) 14L; + + /** + * {@snippet lang = c : * enum .BrayCurtis = 14 + * } + */ + public static int BrayCurtis() { + return BrayCurtis; + } + + private static final int JensenShannon = (int) 15L; + + /** + * {@snippet lang = c : * enum .JensenShannon = 15 + * } + */ + public static int JensenShannon() { + return JensenShannon; + } + + private static final int HammingUnexpanded = (int) 16L; + + /** + * {@snippet lang = c : * enum .HammingUnexpanded = 16 + * } + */ + public static int HammingUnexpanded() { + return HammingUnexpanded; + } + + private static final int KLDivergence = (int) 17L; + + /** + * {@snippet lang = c : * enum .KLDivergence = 17 + * } + */ + public static int KLDivergence() { + return KLDivergence; + } + + private static final int RusselRaoExpanded = (int) 18L; + + /** + * {@snippet lang = c : * enum .RusselRaoExpanded = 18 + * } + */ + public static int RusselRaoExpanded() { + return RusselRaoExpanded; + } + + private static final int DiceExpanded = (int) 19L; + + /** + * {@snippet lang = c : * enum .DiceExpanded = 19 + * } + */ + public static int DiceExpanded() { + return DiceExpanded; + } + + private static final int Precomputed = (int) 100L; + + /** + * {@snippet lang = c : * enum .Precomputed = 100 + * } + */ + public static int Precomputed() { + return Precomputed; + } + + /** + * {@snippet lang = c : * typedef unsigned char __u_char + * } + */ + public static final OfByte __u_char = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned short __u_short + * } + */ + public static final OfShort __u_short = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned int __u_int + * } + */ + public static final OfInt __u_int = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __u_long + * } + */ + public static final OfLong __u_long = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char __int8_t + * } + */ + public static final OfByte __int8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned char __uint8_t + * } + */ + public static final OfByte __uint8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef short __int16_t + * } + */ + public static final OfShort __int16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned short __uint16_t + * } + */ + public static final OfShort __uint16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef int __int32_t + * } + */ + public static final OfInt __int32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __uint32_t + * } + */ + public static final OfInt __uint32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef long __int64_t + * } + */ + public static final OfLong __int64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uint64_t + * } + */ + public static final OfLong __uint64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __int8_t __int_least8_t + * } + */ + public static final OfByte __int_least8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint8_t __uint_least8_t + * } + */ + public static final OfByte __uint_least8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t __int_least16_t + * } + */ + public static final OfShort __int_least16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint16_t __uint_least16_t + * } + */ + public static final OfShort __uint_least16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t __int_least32_t + * } + */ + public static final OfInt __int_least32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef __uint32_t __uint_least32_t + * } + */ + public static final OfInt __uint_least32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t __int_least64_t + * } + */ + public static final OfLong __int_least64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint64_t __uint_least64_t + * } + */ + public static final OfLong __uint_least64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __quad_t + * } + */ + public static final OfLong __quad_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __u_quad_t + * } + */ + public static final OfLong __u_quad_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __intmax_t + * } + */ + public static final OfLong __intmax_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uintmax_t + * } + */ + public static final OfLong __uintmax_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __dev_t + * } + */ + public static final OfLong __dev_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __uid_t + * } + */ + public static final OfInt __uid_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __gid_t + * } + */ + public static final OfInt __gid_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __ino_t + * } + */ + public static final OfLong __ino_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __ino64_t + * } + */ + public static final OfLong __ino64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __mode_t + * } + */ + public static final OfInt __mode_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __nlink_t + * } + */ + public static final OfLong __nlink_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off_t + * } + */ + public static final OfLong __off_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off64_t + * } + */ + public static final OfLong __off64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef int __pid_t + * } + */ + public static final OfInt __pid_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef long __clock_t + * } + */ + public static final OfLong __clock_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim_t + * } + */ + public static final OfLong __rlim_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim64_t + * } + */ + public static final OfLong __rlim64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __id_t + * } + */ + public static final OfInt __id_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef long __time_t + * } + */ + public static final OfLong __time_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __useconds_t + * } + */ + public static final OfInt __useconds_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef long __suseconds_t + * } + */ + public static final OfLong __suseconds_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __suseconds64_t + * } + */ + public static final OfLong __suseconds64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef int __daddr_t + * } + */ + public static final OfInt __daddr_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef int __key_t + * } + */ + public static final OfInt __key_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef int __clockid_t + * } + */ + public static final OfInt __clockid_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef void *__timer_t + * } + */ + public static final AddressLayout __timer_t = CagraH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __blksize_t + * } + */ + public static final OfLong __blksize_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt_t + * } + */ + public static final OfLong __blkcnt_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt64_t + * } + */ + public static final OfLong __blkcnt64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt_t + * } + */ + public static final OfLong __fsblkcnt_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt64_t + * } + */ + public static final OfLong __fsblkcnt64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt_t + * } + */ + public static final OfLong __fsfilcnt_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt64_t + * } + */ + public static final OfLong __fsfilcnt64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __fsword_t + * } + */ + public static final OfLong __fsword_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __ssize_t + * } + */ + public static final OfLong __ssize_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long __syscall_slong_t + * } + */ + public static final OfLong __syscall_slong_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __syscall_ulong_t + * } + */ + public static final OfLong __syscall_ulong_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __off64_t __loff_t + * } + */ + public static final OfLong __loff_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef char *__caddr_t + * } + */ + public static final AddressLayout __caddr_t = CagraH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __intptr_t + * } + */ + public static final OfLong __intptr_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __socklen_t + * } + */ + public static final OfInt __socklen_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef int __sig_atomic_t + * } + */ + public static final OfInt __sig_atomic_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef __int8_t int8_t + * } + */ + public static final OfByte int8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t int16_t + * } + */ + public static final OfShort int16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t int32_t + * } + */ + public static final OfInt int32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t int64_t + * } + */ + public static final OfLong int64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint8_t uint8_t + * } + */ + public static final OfByte uint8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint16_t uint16_t + * } + */ + public static final OfShort uint16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint32_t uint32_t + * } + */ + public static final OfInt uint32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef __uint64_t uint64_t + * } + */ + public static final OfLong uint64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __int_least8_t int_least8_t + * } + */ + public static final OfByte int_least8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int_least16_t int_least16_t + * } + */ + public static final OfShort int_least16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int_least32_t int_least32_t + * } + */ + public static final OfInt int_least32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef __int_least64_t int_least64_t + * } + */ + public static final OfLong int_least64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint_least8_t uint_least8_t + * } + */ + public static final OfByte uint_least8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint_least16_t uint_least16_t + * } + */ + public static final OfShort uint_least16_t = CagraH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint_least32_t uint_least32_t + * } + */ + public static final OfInt uint_least32_t = CagraH.C_INT; + /** + * {@snippet lang = c : * typedef __uint_least64_t uint_least64_t + * } + */ + public static final OfLong uint_least64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char int_fast8_t + * } + */ + public static final OfByte int_fast8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef long int_fast16_t + * } + */ + public static final OfLong int_fast16_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast32_t + * } + */ + public static final OfLong int_fast32_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast64_t + * } + */ + public static final OfLong int_fast64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned char uint_fast8_t + * } + */ + public static final OfByte uint_fast8_t = CagraH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast16_t + * } + */ + public static final OfLong uint_fast16_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast32_t + * } + */ + public static final OfLong uint_fast32_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast64_t + * } + */ + public static final OfLong uint_fast64_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long intptr_t + * } + */ + public static final OfLong intptr_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uintptr_t + * } + */ + public static final OfLong uintptr_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __intmax_t intmax_t + * } + */ + public static final OfLong intmax_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef __uintmax_t uintmax_t + * } + */ + public static final OfLong uintmax_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef long ptrdiff_t + * } + */ + public static final OfLong ptrdiff_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long size_t + * } + */ + public static final OfLong size_t = CagraH.C_LONG; + /** + * {@snippet lang = c : * typedef int wchar_t + * } + */ + public static final OfInt wchar_t = CagraH.C_INT; + private static final int kDLCPU = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLCPU = 1 + * } + */ + public static int kDLCPU() { + return kDLCPU; + } + + private static final int kDLCUDA = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLCUDA = 2 + * } + */ + public static int kDLCUDA() { + return kDLCUDA; + } + + private static final int kDLCUDAHost = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLCUDAHost = 3 + * } + */ + public static int kDLCUDAHost() { + return kDLCUDAHost; + } + + private static final int kDLOpenCL = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLOpenCL = 4 + * } + */ + public static int kDLOpenCL() { + return kDLOpenCL; + } + + private static final int kDLVulkan = (int) 7L; + + /** + * {@snippet lang = c : * enum .kDLVulkan = 7 + * } + */ + public static int kDLVulkan() { + return kDLVulkan; + } + + private static final int kDLMetal = (int) 8L; + + /** + * {@snippet lang = c : * enum .kDLMetal = 8 + * } + */ + public static int kDLMetal() { + return kDLMetal; + } + + private static final int kDLVPI = (int) 9L; + + /** + * {@snippet lang = c : * enum .kDLVPI = 9 + * } + */ + public static int kDLVPI() { + return kDLVPI; + } + + private static final int kDLROCM = (int) 10L; + + /** + * {@snippet lang = c : * enum .kDLROCM = 10 + * } + */ + public static int kDLROCM() { + return kDLROCM; + } + + private static final int kDLROCMHost = (int) 11L; + + /** + * {@snippet lang = c : * enum .kDLROCMHost = 11 + * } + */ + public static int kDLROCMHost() { + return kDLROCMHost; + } + + private static final int kDLExtDev = (int) 12L; + + /** + * {@snippet lang = c : * enum .kDLExtDev = 12 + * } + */ + public static int kDLExtDev() { + return kDLExtDev; + } + + private static final int kDLCUDAManaged = (int) 13L; + + /** + * {@snippet lang = c : * enum .kDLCUDAManaged = 13 + * } + */ + public static int kDLCUDAManaged() { + return kDLCUDAManaged; + } + + private static final int kDLOneAPI = (int) 14L; + + /** + * {@snippet lang = c : * enum .kDLOneAPI = 14 + * } + */ + public static int kDLOneAPI() { + return kDLOneAPI; + } + + private static final int kDLWebGPU = (int) 15L; + + /** + * {@snippet lang = c : * enum .kDLWebGPU = 15 + * } + */ + public static int kDLWebGPU() { + return kDLWebGPU; + } + + private static final int kDLHexagon = (int) 16L; + + /** + * {@snippet lang = c : * enum .kDLHexagon = 16 + * } + */ + public static int kDLHexagon() { + return kDLHexagon; + } + + private static final int kDLInt = (int) 0L; + + /** + * {@snippet lang = c : * enum .kDLInt = 0 + * } + */ + public static int kDLInt() { + return kDLInt; + } + + private static final int kDLUInt = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLUInt = 1 + * } + */ + public static int kDLUInt() { + return kDLUInt; + } + + private static final int kDLFloat = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLFloat = 2 + * } + */ + public static int kDLFloat() { + return kDLFloat; + } + + private static final int kDLOpaqueHandle = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLOpaqueHandle = 3 + * } + */ + public static int kDLOpaqueHandle() { + return kDLOpaqueHandle; + } + + private static final int kDLBfloat = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLBfloat = 4 + * } + */ + public static int kDLBfloat() { + return kDLBfloat; + } + + private static final int kDLComplex = (int) 5L; + + /** + * {@snippet lang = c : * enum .kDLComplex = 5 + * } + */ + public static int kDLComplex() { + return kDLComplex; + } + + private static final int kDLBool = (int) 6L; + + /** + * {@snippet lang = c : * enum .kDLBool = 6 + * } + */ + public static int kDLBool() { + return kDLBool; + } + + private static final int AUTO_SELECT = (int) 0L; + + /** + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo.AUTO_SELECT = 0 + * } + */ + public static int AUTO_SELECT() { + return AUTO_SELECT; + } + + private static final int IVF_PQ = (int) 1L; + + /** + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo.IVF_PQ = 1 + * } + */ + public static int IVF_PQ() { + return IVF_PQ; + } + + private static final int NN_DESCENT = (int) 2L; + + /** + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo.NN_DESCENT = 2 + * } + */ + public static int NN_DESCENT() { + return NN_DESCENT; + } + + /** + * {@snippet lang = c : + * typedef struct cuvsCagraCompressionParams { + * uint32_t pq_bits; + * uint32_t pq_dim; + * uint32_t vq_n_centers; + * uint32_t kmeans_n_iters; + * double vq_kmeans_trainset_fraction; + * double pq_kmeans_trainset_fraction; + * } *cuvsCagraCompressionParams_t + * } + */ + public static final AddressLayout cuvsCagraCompressionParams_t = CagraH.C_POINTER; + /** + * {@snippet lang = c : + * typedef struct cuvsCagraIndexParams { + * cuvsDistanceType metric; + * long intermediate_graph_degree; + * long graph_degree; + * enum cuvsCagraGraphBuildAlgo build_algo; + * long nn_descent_niter; + * cuvsCagraCompressionParams_t compression; + * } *cuvsCagraIndexParams_t + * } + */ + public static final AddressLayout cuvsCagraIndexParams_t = CagraH.C_POINTER; + private static final int SINGLE_CTA = (int) 0L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.SINGLE_CTA = 0 + * } + */ + public static int SINGLE_CTA() { + return SINGLE_CTA; + } + + private static final int MULTI_CTA = (int) 1L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.MULTI_CTA = 1 + * } + */ + public static int MULTI_CTA() { + return MULTI_CTA; + } + + private static final int MULTI_KERNEL = (int) 2L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.MULTI_KERNEL = 2 + * } + */ + public static int MULTI_KERNEL() { + return MULTI_KERNEL; + } + + private static final int AUTO = (int) 3L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.AUTO = 3 + * } + */ + public static int AUTO() { + return AUTO; + } + + private static final int HASH = (int) 0L; + + /** + * {@snippet lang = c : * enum cuvsCagraHashMode.HASH = 0 + * } + */ + public static int HASH() { + return HASH; + } + + private static final int SMALL = (int) 1L; + + /** + * {@snippet lang = c : * enum cuvsCagraHashMode.SMALL = 1 + * } + */ + public static int SMALL() { + return SMALL; + } + + private static final int AUTO_HASH = (int) 2L; + + /** + * {@snippet lang = c : * enum cuvsCagraHashMode.AUTO_HASH = 2 + * } + */ + public static int AUTO_HASH() { + return AUTO_HASH; + } + + /** + * {@snippet lang = c : + * typedef struct cuvsCagraSearchParams { + * long max_queries; + * long itopk_size; + * long max_iterations; + * enum cuvsCagraSearchAlgo algo; + * long team_size; + * long search_width; + * long min_iterations; + * long thread_block_size; + * enum cuvsCagraHashMode hashmap_mode; + * long hashmap_min_bitlen; + * float hashmap_max_fill_rate; + * uint32_t num_random_samplings; + * uint64_t rand_xor_mask; + * } *cuvsCagraSearchParams_t + * } + */ + public static final AddressLayout cuvsCagraSearchParams_t = CagraH.C_POINTER; + /** + * {@snippet lang = c : * typedef cuvsCagraIndex *cuvsCagraIndex_t + * } + */ + public static final AddressLayout cuvsCagraIndex_t = CagraH.C_POINTER; + private static final long _POSIX_C_SOURCE = 200809L; + + /** + * {@snippet lang = c : * #define _POSIX_C_SOURCE 200809 + * } + */ + public static long _POSIX_C_SOURCE() { + return _POSIX_C_SOURCE; + } + + private static final int __TIMESIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __TIMESIZE 64 + * } + */ + public static int __TIMESIZE() { + return __TIMESIZE; + } + + private static final long __STDC_IEC_60559_BFP__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_BFP__ 201404 + * } + */ + public static long __STDC_IEC_60559_BFP__() { + return __STDC_IEC_60559_BFP__; + } + + private static final long __STDC_IEC_60559_COMPLEX__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_COMPLEX__ 201404 + * } + */ + public static long __STDC_IEC_60559_COMPLEX__() { + return __STDC_IEC_60559_COMPLEX__; + } + + private static final long __STDC_ISO_10646__ = 201706L; + + /** + * {@snippet lang = c : * #define __STDC_ISO_10646__ 201706 + * } + */ + public static long __STDC_ISO_10646__() { + return __STDC_ISO_10646__; + } + + private static final int __WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define __WCHAR_MAX 2147483647 + * } + */ + public static int __WCHAR_MAX() { + return __WCHAR_MAX; + } + + private static final int __WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define __WCHAR_MIN -2147483648 + * } + */ + public static int __WCHAR_MIN() { + return __WCHAR_MIN; + } + + private static final int INT8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT8_MIN -128 + * } + */ + public static int INT8_MIN() { + return INT8_MIN; + } + + private static final int INT16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT16_MIN -32768 + * } + */ + public static int INT16_MIN() { + return INT16_MIN; + } + + private static final int INT32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT32_MIN -2147483648 + * } + */ + public static int INT32_MIN() { + return INT32_MIN; + } + + private static final long INT64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT64_MIN -9223372036854775808 + * } + */ + public static long INT64_MIN() { + return INT64_MIN; + } + + private static final int INT8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT8_MAX 127 + * } + */ + public static int INT8_MAX() { + return INT8_MAX; + } + + private static final int INT16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT16_MAX 32767 + * } + */ + public static int INT16_MAX() { + return INT16_MAX; + } + + private static final int INT32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT32_MAX 2147483647 + * } + */ + public static int INT32_MAX() { + return INT32_MAX; + } + + private static final long INT64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT64_MAX 9223372036854775807 + * } + */ + public static long INT64_MAX() { + return INT64_MAX; + } + + private static final int UINT8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT8_MAX 255 + * } + */ + public static int UINT8_MAX() { + return UINT8_MAX; + } + + private static final int UINT16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT16_MAX 65535 + * } + */ + public static int UINT16_MAX() { + return UINT16_MAX; + } + + private static final int UINT32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT32_MAX 4294967295 + * } + */ + public static int UINT32_MAX() { + return UINT32_MAX; + } + + private static final long UINT64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT64_MAX -1 + * } + */ + public static long UINT64_MAX() { + return UINT64_MAX; + } + + private static final int INT_LEAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MIN -128 + * } + */ + public static int INT_LEAST8_MIN() { + return INT_LEAST8_MIN; + } + + private static final int INT_LEAST16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MIN -32768 + * } + */ + public static int INT_LEAST16_MIN() { + return INT_LEAST16_MIN; + } + + private static final int INT_LEAST32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MIN -2147483648 + * } + */ + public static int INT_LEAST32_MIN() { + return INT_LEAST32_MIN; + } + + private static final long INT_LEAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MIN -9223372036854775808 + * } + */ + public static long INT_LEAST64_MIN() { + return INT_LEAST64_MIN; + } + + private static final int INT_LEAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MAX 127 + * } + */ + public static int INT_LEAST8_MAX() { + return INT_LEAST8_MAX; + } + + private static final int INT_LEAST16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MAX 32767 + * } + */ + public static int INT_LEAST16_MAX() { + return INT_LEAST16_MAX; + } + + private static final int INT_LEAST32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MAX 2147483647 + * } + */ + public static int INT_LEAST32_MAX() { + return INT_LEAST32_MAX; + } + + private static final long INT_LEAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MAX 9223372036854775807 + * } + */ + public static long INT_LEAST64_MAX() { + return INT_LEAST64_MAX; + } + + private static final int UINT_LEAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_LEAST8_MAX 255 + * } + */ + public static int UINT_LEAST8_MAX() { + return UINT_LEAST8_MAX; + } + + private static final int UINT_LEAST16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT_LEAST16_MAX 65535 + * } + */ + public static int UINT_LEAST16_MAX() { + return UINT_LEAST16_MAX; + } + + private static final int UINT_LEAST32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT_LEAST32_MAX 4294967295 + * } + */ + public static int UINT_LEAST32_MAX() { + return UINT_LEAST32_MAX; + } + + private static final long UINT_LEAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_LEAST64_MAX -1 + * } + */ + public static long UINT_LEAST64_MAX() { + return UINT_LEAST64_MAX; + } + + private static final int INT_FAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MIN -128 + * } + */ + public static int INT_FAST8_MIN() { + return INT_FAST8_MIN; + } + + private static final long INT_FAST16_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MIN -9223372036854775808 + * } + */ + public static long INT_FAST16_MIN() { + return INT_FAST16_MIN; + } + + private static final long INT_FAST32_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MIN -9223372036854775808 + * } + */ + public static long INT_FAST32_MIN() { + return INT_FAST32_MIN; + } + + private static final long INT_FAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MIN -9223372036854775808 + * } + */ + public static long INT_FAST64_MIN() { + return INT_FAST64_MIN; + } + + private static final int INT_FAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MAX 127 + * } + */ + public static int INT_FAST8_MAX() { + return INT_FAST8_MAX; + } + + private static final long INT_FAST16_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MAX 9223372036854775807 + * } + */ + public static long INT_FAST16_MAX() { + return INT_FAST16_MAX; + } + + private static final long INT_FAST32_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MAX 9223372036854775807 + * } + */ + public static long INT_FAST32_MAX() { + return INT_FAST32_MAX; + } + + private static final long INT_FAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MAX 9223372036854775807 + * } + */ + public static long INT_FAST64_MAX() { + return INT_FAST64_MAX; + } + + private static final int UINT_FAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_FAST8_MAX 255 + * } + */ + public static int UINT_FAST8_MAX() { + return UINT_FAST8_MAX; + } + + private static final long UINT_FAST16_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST16_MAX -1 + * } + */ + public static long UINT_FAST16_MAX() { + return UINT_FAST16_MAX; + } + + private static final long UINT_FAST32_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST32_MAX -1 + * } + */ + public static long UINT_FAST32_MAX() { + return UINT_FAST32_MAX; + } + + private static final long UINT_FAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST64_MAX -1 + * } + */ + public static long UINT_FAST64_MAX() { + return UINT_FAST64_MAX; + } + + private static final long INTPTR_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTPTR_MIN -9223372036854775808 + * } + */ + public static long INTPTR_MIN() { + return INTPTR_MIN; + } + + private static final long INTPTR_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTPTR_MAX 9223372036854775807 + * } + */ + public static long INTPTR_MAX() { + return INTPTR_MAX; + } + + private static final long UINTPTR_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTPTR_MAX -1 + * } + */ + public static long UINTPTR_MAX() { + return UINTPTR_MAX; + } + + private static final long INTMAX_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTMAX_MIN -9223372036854775808 + * } + */ + public static long INTMAX_MIN() { + return INTMAX_MIN; + } + + private static final long INTMAX_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTMAX_MAX 9223372036854775807 + * } + */ + public static long INTMAX_MAX() { + return INTMAX_MAX; + } + + private static final long UINTMAX_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTMAX_MAX -1 + * } + */ + public static long UINTMAX_MAX() { + return UINTMAX_MAX; + } + + private static final long PTRDIFF_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MIN -9223372036854775808 + * } + */ + public static long PTRDIFF_MIN() { + return PTRDIFF_MIN; + } + + private static final long PTRDIFF_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MAX 9223372036854775807 + * } + */ + public static long PTRDIFF_MAX() { + return PTRDIFF_MAX; + } + + private static final int SIG_ATOMIC_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MIN -2147483648 + * } + */ + public static int SIG_ATOMIC_MIN() { + return SIG_ATOMIC_MIN; + } + + private static final int SIG_ATOMIC_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MAX 2147483647 + * } + */ + public static int SIG_ATOMIC_MAX() { + return SIG_ATOMIC_MAX; + } + + private static final long SIZE_MAX = -1L; + + /** + * {@snippet lang = c : * #define SIZE_MAX -1 + * } + */ + public static long SIZE_MAX() { + return SIZE_MAX; + } + + private static final int WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define WCHAR_MIN -2147483648 + * } + */ + public static int WCHAR_MIN() { + return WCHAR_MIN; + } + + private static final int WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define WCHAR_MAX 2147483647 + * } + */ + public static int WCHAR_MAX() { + return WCHAR_MAX; + } + + private static final int WINT_MIN = (int) 0L; + + /** + * {@snippet lang = c : * #define WINT_MIN 0 + * } + */ + public static int WINT_MIN() { + return WINT_MIN; + } + + private static final int WINT_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define WINT_MAX 4294967295 + * } + */ + public static int WINT_MAX() { + return WINT_MAX; + } + + private static final MemorySegment NULL = MemorySegment.ofAddress(0L); + + /** + * {@snippet lang = c : * #define NULL (void*) 0 + * } + */ + public static MemorySegment NULL() { + return NULL; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSBruteForceIndex.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSBruteForceIndex.java new file mode 100644 index 000000000..8bf29027e --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSBruteForceIndex.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct { + * uintptr_t addr; + * DLDataType dtype; + * } + * } + */ +public class CuVSBruteForceIndex { + + CuVSBruteForceIndex() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(BruteForceH.C_LONG.withName("addr"), + DLDataType.layout().withName("dtype"), MemoryLayout.paddingLayout(4)).withName("$anon$22:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfLong addr$LAYOUT = (OfLong) $LAYOUT.select(groupElement("addr")); + + /** + * Layout for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static final OfLong addr$layout() { + return addr$LAYOUT; + } + + private static final long addr$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static final long addr$offset() { + return addr$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static long addr(MemorySegment struct) { + return struct.get(addr$LAYOUT, addr$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static void addr(MemorySegment struct, long fieldValue) { + struct.set(addr$LAYOUT, addr$OFFSET, fieldValue); + } + + private static final GroupLayout dtype$LAYOUT = (GroupLayout) $LAYOUT.select(groupElement("dtype")); + + /** + * Layout for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static final GroupLayout dtype$layout() { + return dtype$LAYOUT; + } + + private static final long dtype$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static final long dtype$offset() { + return dtype$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static MemorySegment dtype(MemorySegment struct) { + return struct.asSlice(dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static void dtype(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraCompressionParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraCompressionParams.java new file mode 100644 index 000000000..1fe8eca76 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraCompressionParams.java @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfDouble; +import java.lang.foreign.ValueLayout.OfInt; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct cuvsCagraCompressionParams { + * uint32_t pq_bits; + * uint32_t pq_dim; + * uint32_t vq_n_centers; + * uint32_t kmeans_n_iters; + * double vq_kmeans_trainset_fraction; + * double pq_kmeans_trainset_fraction; + * } + * } + */ +public class CuVSCagraCompressionParams { + + CuVSCagraCompressionParams() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(CagraH.C_INT.withName("pq_bits"), + CagraH.C_INT.withName("pq_dim"), CagraH.C_INT.withName("vq_n_centers"), + CagraH.C_INT.withName("kmeans_n_iters"), CagraH.C_DOUBLE.withName("vq_kmeans_trainset_fraction"), + CagraH.C_DOUBLE.withName("pq_kmeans_trainset_fraction")).withName("cuvsCagraCompressionParams"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt pq_bits$LAYOUT = (OfInt) $LAYOUT.select(groupElement("pq_bits")); + + /** + * Layout for field: + * {@snippet lang = c : * uint32_t pq_bits + * } + */ + public static final OfInt pq_bits$layout() { + return pq_bits$LAYOUT; + } + + private static final long pq_bits$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * uint32_t pq_bits + * } + */ + public static final long pq_bits$offset() { + return pq_bits$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uint32_t pq_bits + * } + */ + public static int pq_bits(MemorySegment struct) { + return struct.get(pq_bits$LAYOUT, pq_bits$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uint32_t pq_bits + * } + */ + public static void pq_bits(MemorySegment struct, int fieldValue) { + struct.set(pq_bits$LAYOUT, pq_bits$OFFSET, fieldValue); + } + + private static final OfInt pq_dim$LAYOUT = (OfInt) $LAYOUT.select(groupElement("pq_dim")); + + /** + * Layout for field: + * {@snippet lang = c : * uint32_t pq_dim + * } + */ + public static final OfInt pq_dim$layout() { + return pq_dim$LAYOUT; + } + + private static final long pq_dim$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang = c : * uint32_t pq_dim + * } + */ + public static final long pq_dim$offset() { + return pq_dim$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uint32_t pq_dim + * } + */ + public static int pq_dim(MemorySegment struct) { + return struct.get(pq_dim$LAYOUT, pq_dim$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uint32_t pq_dim + * } + */ + public static void pq_dim(MemorySegment struct, int fieldValue) { + struct.set(pq_dim$LAYOUT, pq_dim$OFFSET, fieldValue); + } + + private static final OfInt vq_n_centers$LAYOUT = (OfInt) $LAYOUT.select(groupElement("vq_n_centers")); + + /** + * Layout for field: + * {@snippet lang = c : * uint32_t vq_n_centers + * } + */ + public static final OfInt vq_n_centers$layout() { + return vq_n_centers$LAYOUT; + } + + private static final long vq_n_centers$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang = c : * uint32_t vq_n_centers + * } + */ + public static final long vq_n_centers$offset() { + return vq_n_centers$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uint32_t vq_n_centers + * } + */ + public static int vq_n_centers(MemorySegment struct) { + return struct.get(vq_n_centers$LAYOUT, vq_n_centers$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uint32_t vq_n_centers + * } + */ + public static void vq_n_centers(MemorySegment struct, int fieldValue) { + struct.set(vq_n_centers$LAYOUT, vq_n_centers$OFFSET, fieldValue); + } + + private static final OfInt kmeans_n_iters$LAYOUT = (OfInt) $LAYOUT.select(groupElement("kmeans_n_iters")); + + /** + * Layout for field: + * {@snippet lang = c : * uint32_t kmeans_n_iters + * } + */ + public static final OfInt kmeans_n_iters$layout() { + return kmeans_n_iters$LAYOUT; + } + + private static final long kmeans_n_iters$OFFSET = 12; + + /** + * Offset for field: + * {@snippet lang = c : * uint32_t kmeans_n_iters + * } + */ + public static final long kmeans_n_iters$offset() { + return kmeans_n_iters$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uint32_t kmeans_n_iters + * } + */ + public static int kmeans_n_iters(MemorySegment struct) { + return struct.get(kmeans_n_iters$LAYOUT, kmeans_n_iters$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uint32_t kmeans_n_iters + * } + */ + public static void kmeans_n_iters(MemorySegment struct, int fieldValue) { + struct.set(kmeans_n_iters$LAYOUT, kmeans_n_iters$OFFSET, fieldValue); + } + + private static final OfDouble vq_kmeans_trainset_fraction$LAYOUT = (OfDouble) $LAYOUT + .select(groupElement("vq_kmeans_trainset_fraction")); + + /** + * Layout for field: + * {@snippet lang = c : * double vq_kmeans_trainset_fraction + * } + */ + public static final OfDouble vq_kmeans_trainset_fraction$layout() { + return vq_kmeans_trainset_fraction$LAYOUT; + } + + private static final long vq_kmeans_trainset_fraction$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang = c : * double vq_kmeans_trainset_fraction + * } + */ + public static final long vq_kmeans_trainset_fraction$offset() { + return vq_kmeans_trainset_fraction$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * double vq_kmeans_trainset_fraction + * } + */ + public static double vq_kmeans_trainset_fraction(MemorySegment struct) { + return struct.get(vq_kmeans_trainset_fraction$LAYOUT, vq_kmeans_trainset_fraction$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * double vq_kmeans_trainset_fraction + * } + */ + public static void vq_kmeans_trainset_fraction(MemorySegment struct, double fieldValue) { + struct.set(vq_kmeans_trainset_fraction$LAYOUT, vq_kmeans_trainset_fraction$OFFSET, fieldValue); + } + + private static final OfDouble pq_kmeans_trainset_fraction$LAYOUT = (OfDouble) $LAYOUT + .select(groupElement("pq_kmeans_trainset_fraction")); + + /** + * Layout for field: + * {@snippet lang = c : * double pq_kmeans_trainset_fraction + * } + */ + public static final OfDouble pq_kmeans_trainset_fraction$layout() { + return pq_kmeans_trainset_fraction$LAYOUT; + } + + private static final long pq_kmeans_trainset_fraction$OFFSET = 24; + + /** + * Offset for field: + * {@snippet lang = c : * double pq_kmeans_trainset_fraction + * } + */ + public static final long pq_kmeans_trainset_fraction$offset() { + return pq_kmeans_trainset_fraction$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * double pq_kmeans_trainset_fraction + * } + */ + public static double pq_kmeans_trainset_fraction(MemorySegment struct) { + return struct.get(pq_kmeans_trainset_fraction$LAYOUT, pq_kmeans_trainset_fraction$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * double pq_kmeans_trainset_fraction + * } + */ + public static void pq_kmeans_trainset_fraction(MemorySegment struct, double fieldValue) { + struct.set(pq_kmeans_trainset_fraction$LAYOUT, pq_kmeans_trainset_fraction$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndex.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndex.java new file mode 100644 index 000000000..ec15f6729 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndex.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct { + * uintptr_t addr; + * DLDataType dtype; + * } + * } + */ +public class CuVSCagraIndex { + + CuVSCagraIndex() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(CagraH.C_LONG.withName("addr"), + DLDataType.layout().withName("dtype"), MemoryLayout.paddingLayout(4)).withName("$anon$175:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfLong addr$LAYOUT = (OfLong) $LAYOUT.select(groupElement("addr")); + + /** + * Layout for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static final OfLong addr$layout() { + return addr$LAYOUT; + } + + private static final long addr$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static final long addr$offset() { + return addr$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static long addr(MemorySegment struct) { + return struct.get(addr$LAYOUT, addr$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static void addr(MemorySegment struct, long fieldValue) { + struct.set(addr$LAYOUT, addr$OFFSET, fieldValue); + } + + private static final GroupLayout dtype$LAYOUT = (GroupLayout) $LAYOUT.select(groupElement("dtype")); + + /** + * Layout for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static final GroupLayout dtype$layout() { + return dtype$LAYOUT; + } + + private static final long dtype$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static final long dtype$offset() { + return dtype$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static MemorySegment dtype(MemorySegment struct) { + return struct.asSlice(dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static void dtype(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndexParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndexParams.java new file mode 100644 index 000000000..1823eacfe --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraIndexParams.java @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct cuvsCagraIndexParams { + * cuvsDistanceType metric; + * long intermediate_graph_degree; + * long graph_degree; + * enum cuvsCagraGraphBuildAlgo build_algo; + * long nn_descent_niter; + * cuvsCagraCompressionParams_t compression; + * } + * } + */ +public class CuVSCagraIndexParams { + + CuVSCagraIndexParams() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout + .structLayout(CagraH.C_INT.withName("metric"), MemoryLayout.paddingLayout(4), + CagraH.C_LONG.withName("intermediate_graph_degree"), CagraH.C_LONG.withName("graph_degree"), + CagraH.C_INT.withName("build_algo"), MemoryLayout.paddingLayout(4), + CagraH.C_LONG.withName("nn_descent_niter"), CagraH.C_POINTER.withName("compression")) + .withName("cuvsCagraIndexParams"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt metric$LAYOUT = (OfInt) $LAYOUT.select(groupElement("metric")); + + /** + * Layout for field: + * {@snippet lang = c : * cuvsDistanceType metric + * } + */ + public static final OfInt metric$layout() { + return metric$LAYOUT; + } + + private static final long metric$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * cuvsDistanceType metric + * } + */ + public static final long metric$offset() { + return metric$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * cuvsDistanceType metric + * } + */ + public static int metric(MemorySegment struct) { + return struct.get(metric$LAYOUT, metric$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * cuvsDistanceType metric + * } + */ + public static void metric(MemorySegment struct, int fieldValue) { + struct.set(metric$LAYOUT, metric$OFFSET, fieldValue); + } + + private static final OfLong intermediate_graph_degree$LAYOUT = (OfLong) $LAYOUT + .select(groupElement("intermediate_graph_degree")); + + /** + * Layout for field: + * {@snippet lang = c : * long intermediate_graph_degree + * } + */ + public static final OfLong intermediate_graph_degree$layout() { + return intermediate_graph_degree$LAYOUT; + } + + private static final long intermediate_graph_degree$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang = c : * long intermediate_graph_degree + * } + */ + public static final long intermediate_graph_degree$offset() { + return intermediate_graph_degree$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long intermediate_graph_degree + * } + */ + public static long intermediate_graph_degree(MemorySegment struct) { + return struct.get(intermediate_graph_degree$LAYOUT, intermediate_graph_degree$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long intermediate_graph_degree + * } + */ + public static void intermediate_graph_degree(MemorySegment struct, long fieldValue) { + struct.set(intermediate_graph_degree$LAYOUT, intermediate_graph_degree$OFFSET, fieldValue); + } + + private static final OfLong graph_degree$LAYOUT = (OfLong) $LAYOUT.select(groupElement("graph_degree")); + + /** + * Layout for field: + * {@snippet lang = c : * long graph_degree + * } + */ + public static final OfLong graph_degree$layout() { + return graph_degree$LAYOUT; + } + + private static final long graph_degree$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang = c : * long graph_degree + * } + */ + public static final long graph_degree$offset() { + return graph_degree$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long graph_degree + * } + */ + public static long graph_degree(MemorySegment struct) { + return struct.get(graph_degree$LAYOUT, graph_degree$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long graph_degree + * } + */ + public static void graph_degree(MemorySegment struct, long fieldValue) { + struct.set(graph_degree$LAYOUT, graph_degree$OFFSET, fieldValue); + } + + private static final OfInt build_algo$LAYOUT = (OfInt) $LAYOUT.select(groupElement("build_algo")); + + /** + * Layout for field: + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo build_algo + * } + */ + public static final OfInt build_algo$layout() { + return build_algo$LAYOUT; + } + + private static final long build_algo$OFFSET = 24; + + /** + * Offset for field: + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo build_algo + * } + */ + public static final long build_algo$offset() { + return build_algo$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo build_algo + * } + */ + public static int build_algo(MemorySegment struct) { + return struct.get(build_algo$LAYOUT, build_algo$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo build_algo + * } + */ + public static void build_algo(MemorySegment struct, int fieldValue) { + struct.set(build_algo$LAYOUT, build_algo$OFFSET, fieldValue); + } + + private static final OfLong nn_descent_niter$LAYOUT = (OfLong) $LAYOUT.select(groupElement("nn_descent_niter")); + + /** + * Layout for field: + * {@snippet lang = c : * long nn_descent_niter + * } + */ + public static final OfLong nn_descent_niter$layout() { + return nn_descent_niter$LAYOUT; + } + + private static final long nn_descent_niter$OFFSET = 32; + + /** + * Offset for field: + * {@snippet lang = c : * long nn_descent_niter + * } + */ + public static final long nn_descent_niter$offset() { + return nn_descent_niter$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long nn_descent_niter + * } + */ + public static long nn_descent_niter(MemorySegment struct) { + return struct.get(nn_descent_niter$LAYOUT, nn_descent_niter$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long nn_descent_niter + * } + */ + public static void nn_descent_niter(MemorySegment struct, long fieldValue) { + struct.set(nn_descent_niter$LAYOUT, nn_descent_niter$OFFSET, fieldValue); + } + + private static final AddressLayout compression$LAYOUT = (AddressLayout) $LAYOUT.select(groupElement("compression")); + + /** + * Layout for field: + * {@snippet lang = c : * cuvsCagraCompressionParams_t compression + * } + */ + public static final AddressLayout compression$layout() { + return compression$LAYOUT; + } + + private static final long compression$OFFSET = 40; + + /** + * Offset for field: + * {@snippet lang = c : * cuvsCagraCompressionParams_t compression + * } + */ + public static final long compression$offset() { + return compression$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * cuvsCagraCompressionParams_t compression + * } + */ + public static MemorySegment compression(MemorySegment struct) { + return struct.get(compression$LAYOUT, compression$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * cuvsCagraCompressionParams_t compression + * } + */ + public static void compression(MemorySegment struct, MemorySegment fieldValue) { + struct.set(compression$LAYOUT, compression$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraSearchParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraSearchParams.java new file mode 100644 index 000000000..ec59284d9 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSCagraSearchParams.java @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfFloat; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct cuvsCagraSearchParams { + * long max_queries; + * long itopk_size; + * long max_iterations; + * enum cuvsCagraSearchAlgo algo; + * long team_size; + * long search_width; + * long min_iterations; + * long thread_block_size; + * enum cuvsCagraHashMode hashmap_mode; + * long hashmap_min_bitlen; + * float hashmap_max_fill_rate; + * uint32_t num_random_samplings; + * uint64_t rand_xor_mask; + * } + * } + */ +public class CuVSCagraSearchParams { + + CuVSCagraSearchParams() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout + .structLayout(CagraH.C_LONG.withName("max_queries"), CagraH.C_LONG.withName("itopk_size"), + CagraH.C_LONG.withName("max_iterations"), CagraH.C_INT.withName("algo"), MemoryLayout.paddingLayout(4), + CagraH.C_LONG.withName("team_size"), CagraH.C_LONG.withName("search_width"), + CagraH.C_LONG.withName("min_iterations"), CagraH.C_LONG.withName("thread_block_size"), + CagraH.C_INT.withName("hashmap_mode"), MemoryLayout.paddingLayout(4), + CagraH.C_LONG.withName("hashmap_min_bitlen"), CagraH.C_FLOAT.withName("hashmap_max_fill_rate"), + CagraH.C_INT.withName("num_random_samplings"), CagraH.C_LONG.withName("rand_xor_mask")) + .withName("cuvsCagraSearchParams"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfLong max_queries$LAYOUT = (OfLong) $LAYOUT.select(groupElement("max_queries")); + + /** + * Layout for field: + * {@snippet lang = c : * long max_queries + * } + */ + public static final OfLong max_queries$layout() { + return max_queries$LAYOUT; + } + + private static final long max_queries$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * long max_queries + * } + */ + public static final long max_queries$offset() { + return max_queries$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long max_queries + * } + */ + public static long max_queries(MemorySegment struct) { + return struct.get(max_queries$LAYOUT, max_queries$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long max_queries + * } + */ + public static void max_queries(MemorySegment struct, long fieldValue) { + struct.set(max_queries$LAYOUT, max_queries$OFFSET, fieldValue); + } + + private static final OfLong itopk_size$LAYOUT = (OfLong) $LAYOUT.select(groupElement("itopk_size")); + + /** + * Layout for field: + * {@snippet lang = c : * long itopk_size + * } + */ + public static final OfLong itopk_size$layout() { + return itopk_size$LAYOUT; + } + + private static final long itopk_size$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang = c : * long itopk_size + * } + */ + public static final long itopk_size$offset() { + return itopk_size$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long itopk_size + * } + */ + public static long itopk_size(MemorySegment struct) { + return struct.get(itopk_size$LAYOUT, itopk_size$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long itopk_size + * } + */ + public static void itopk_size(MemorySegment struct, long fieldValue) { + struct.set(itopk_size$LAYOUT, itopk_size$OFFSET, fieldValue); + } + + private static final OfLong max_iterations$LAYOUT = (OfLong) $LAYOUT.select(groupElement("max_iterations")); + + /** + * Layout for field: + * {@snippet lang = c : * long max_iterations + * } + */ + public static final OfLong max_iterations$layout() { + return max_iterations$LAYOUT; + } + + private static final long max_iterations$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang = c : * long max_iterations + * } + */ + public static final long max_iterations$offset() { + return max_iterations$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long max_iterations + * } + */ + public static long max_iterations(MemorySegment struct) { + return struct.get(max_iterations$LAYOUT, max_iterations$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long max_iterations + * } + */ + public static void max_iterations(MemorySegment struct, long fieldValue) { + struct.set(max_iterations$LAYOUT, max_iterations$OFFSET, fieldValue); + } + + private static final OfInt algo$LAYOUT = (OfInt) $LAYOUT.select(groupElement("algo")); + + /** + * Layout for field: + * {@snippet lang = c : * enum cuvsCagraSearchAlgo algo + * } + */ + public static final OfInt algo$layout() { + return algo$LAYOUT; + } + + private static final long algo$OFFSET = 24; + + /** + * Offset for field: + * {@snippet lang = c : * enum cuvsCagraSearchAlgo algo + * } + */ + public static final long algo$offset() { + return algo$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * enum cuvsCagraSearchAlgo algo + * } + */ + public static int algo(MemorySegment struct) { + return struct.get(algo$LAYOUT, algo$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * enum cuvsCagraSearchAlgo algo + * } + */ + public static void algo(MemorySegment struct, int fieldValue) { + struct.set(algo$LAYOUT, algo$OFFSET, fieldValue); + } + + private static final OfLong team_size$LAYOUT = (OfLong) $LAYOUT.select(groupElement("team_size")); + + /** + * Layout for field: + * {@snippet lang = c : * long team_size + * } + */ + public static final OfLong team_size$layout() { + return team_size$LAYOUT; + } + + private static final long team_size$OFFSET = 32; + + /** + * Offset for field: + * {@snippet lang = c : * long team_size + * } + */ + public static final long team_size$offset() { + return team_size$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long team_size + * } + */ + public static long team_size(MemorySegment struct) { + return struct.get(team_size$LAYOUT, team_size$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long team_size + * } + */ + public static void team_size(MemorySegment struct, long fieldValue) { + struct.set(team_size$LAYOUT, team_size$OFFSET, fieldValue); + } + + private static final OfLong search_width$LAYOUT = (OfLong) $LAYOUT.select(groupElement("search_width")); + + /** + * Layout for field: + * {@snippet lang = c : * long search_width + * } + */ + public static final OfLong search_width$layout() { + return search_width$LAYOUT; + } + + private static final long search_width$OFFSET = 40; + + /** + * Offset for field: + * {@snippet lang = c : * long search_width + * } + */ + public static final long search_width$offset() { + return search_width$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long search_width + * } + */ + public static long search_width(MemorySegment struct) { + return struct.get(search_width$LAYOUT, search_width$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long search_width + * } + */ + public static void search_width(MemorySegment struct, long fieldValue) { + struct.set(search_width$LAYOUT, search_width$OFFSET, fieldValue); + } + + private static final OfLong min_iterations$LAYOUT = (OfLong) $LAYOUT.select(groupElement("min_iterations")); + + /** + * Layout for field: + * {@snippet lang = c : * long min_iterations + * } + */ + public static final OfLong min_iterations$layout() { + return min_iterations$LAYOUT; + } + + private static final long min_iterations$OFFSET = 48; + + /** + * Offset for field: + * {@snippet lang = c : * long min_iterations + * } + */ + public static final long min_iterations$offset() { + return min_iterations$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long min_iterations + * } + */ + public static long min_iterations(MemorySegment struct) { + return struct.get(min_iterations$LAYOUT, min_iterations$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long min_iterations + * } + */ + public static void min_iterations(MemorySegment struct, long fieldValue) { + struct.set(min_iterations$LAYOUT, min_iterations$OFFSET, fieldValue); + } + + private static final OfLong thread_block_size$LAYOUT = (OfLong) $LAYOUT.select(groupElement("thread_block_size")); + + /** + * Layout for field: + * {@snippet lang = c : * long thread_block_size + * } + */ + public static final OfLong thread_block_size$layout() { + return thread_block_size$LAYOUT; + } + + private static final long thread_block_size$OFFSET = 56; + + /** + * Offset for field: + * {@snippet lang = c : * long thread_block_size + * } + */ + public static final long thread_block_size$offset() { + return thread_block_size$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long thread_block_size + * } + */ + public static long thread_block_size(MemorySegment struct) { + return struct.get(thread_block_size$LAYOUT, thread_block_size$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long thread_block_size + * } + */ + public static void thread_block_size(MemorySegment struct, long fieldValue) { + struct.set(thread_block_size$LAYOUT, thread_block_size$OFFSET, fieldValue); + } + + private static final OfInt hashmap_mode$LAYOUT = (OfInt) $LAYOUT.select(groupElement("hashmap_mode")); + + /** + * Layout for field: + * {@snippet lang = c : * enum cuvsCagraHashMode hashmap_mode + * } + */ + public static final OfInt hashmap_mode$layout() { + return hashmap_mode$LAYOUT; + } + + private static final long hashmap_mode$OFFSET = 64; + + /** + * Offset for field: + * {@snippet lang = c : * enum cuvsCagraHashMode hashmap_mode + * } + */ + public static final long hashmap_mode$offset() { + return hashmap_mode$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * enum cuvsCagraHashMode hashmap_mode + * } + */ + public static int hashmap_mode(MemorySegment struct) { + return struct.get(hashmap_mode$LAYOUT, hashmap_mode$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * enum cuvsCagraHashMode hashmap_mode + * } + */ + public static void hashmap_mode(MemorySegment struct, int fieldValue) { + struct.set(hashmap_mode$LAYOUT, hashmap_mode$OFFSET, fieldValue); + } + + private static final OfLong hashmap_min_bitlen$LAYOUT = (OfLong) $LAYOUT.select(groupElement("hashmap_min_bitlen")); + + /** + * Layout for field: + * {@snippet lang = c : * long hashmap_min_bitlen + * } + */ + public static final OfLong hashmap_min_bitlen$layout() { + return hashmap_min_bitlen$LAYOUT; + } + + private static final long hashmap_min_bitlen$OFFSET = 72; + + /** + * Offset for field: + * {@snippet lang = c : * long hashmap_min_bitlen + * } + */ + public static final long hashmap_min_bitlen$offset() { + return hashmap_min_bitlen$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long hashmap_min_bitlen + * } + */ + public static long hashmap_min_bitlen(MemorySegment struct) { + return struct.get(hashmap_min_bitlen$LAYOUT, hashmap_min_bitlen$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long hashmap_min_bitlen + * } + */ + public static void hashmap_min_bitlen(MemorySegment struct, long fieldValue) { + struct.set(hashmap_min_bitlen$LAYOUT, hashmap_min_bitlen$OFFSET, fieldValue); + } + + private static final OfFloat hashmap_max_fill_rate$LAYOUT = (OfFloat) $LAYOUT + .select(groupElement("hashmap_max_fill_rate")); + + /** + * Layout for field: + * {@snippet lang = c : * float hashmap_max_fill_rate + * } + */ + public static final OfFloat hashmap_max_fill_rate$layout() { + return hashmap_max_fill_rate$LAYOUT; + } + + private static final long hashmap_max_fill_rate$OFFSET = 80; + + /** + * Offset for field: + * {@snippet lang = c : * float hashmap_max_fill_rate + * } + */ + public static final long hashmap_max_fill_rate$offset() { + return hashmap_max_fill_rate$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * float hashmap_max_fill_rate + * } + */ + public static float hashmap_max_fill_rate(MemorySegment struct) { + return struct.get(hashmap_max_fill_rate$LAYOUT, hashmap_max_fill_rate$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * float hashmap_max_fill_rate + * } + */ + public static void hashmap_max_fill_rate(MemorySegment struct, float fieldValue) { + struct.set(hashmap_max_fill_rate$LAYOUT, hashmap_max_fill_rate$OFFSET, fieldValue); + } + + private static final OfInt num_random_samplings$LAYOUT = (OfInt) $LAYOUT.select(groupElement("num_random_samplings")); + + /** + * Layout for field: + * {@snippet lang = c : * uint32_t num_random_samplings + * } + */ + public static final OfInt num_random_samplings$layout() { + return num_random_samplings$LAYOUT; + } + + private static final long num_random_samplings$OFFSET = 84; + + /** + * Offset for field: + * {@snippet lang = c : * uint32_t num_random_samplings + * } + */ + public static final long num_random_samplings$offset() { + return num_random_samplings$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uint32_t num_random_samplings + * } + */ + public static int num_random_samplings(MemorySegment struct) { + return struct.get(num_random_samplings$LAYOUT, num_random_samplings$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uint32_t num_random_samplings + * } + */ + public static void num_random_samplings(MemorySegment struct, int fieldValue) { + struct.set(num_random_samplings$LAYOUT, num_random_samplings$OFFSET, fieldValue); + } + + private static final OfLong rand_xor_mask$LAYOUT = (OfLong) $LAYOUT.select(groupElement("rand_xor_mask")); + + /** + * Layout for field: + * {@snippet lang = c : * uint64_t rand_xor_mask + * } + */ + public static final OfLong rand_xor_mask$layout() { + return rand_xor_mask$LAYOUT; + } + + private static final long rand_xor_mask$OFFSET = 88; + + /** + * Offset for field: + * {@snippet lang = c : * uint64_t rand_xor_mask + * } + */ + public static final long rand_xor_mask$offset() { + return rand_xor_mask$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uint64_t rand_xor_mask + * } + */ + public static long rand_xor_mask(MemorySegment struct) { + return struct.get(rand_xor_mask$LAYOUT, rand_xor_mask$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uint64_t rand_xor_mask + * } + */ + public static void rand_xor_mask(MemorySegment struct, long fieldValue) { + struct.set(rand_xor_mask$LAYOUT, rand_xor_mask$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSFilter.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSFilter.java new file mode 100644 index 000000000..9385660dc --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSFilter.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct { + * uintptr_t addr; + * enum cuvsFilterType type; + * } + * } + */ +public class CuVSFilter { + + CuVSFilter() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + BruteForceH.C_LONG.withName("addr"), + BruteForceH.C_INT.withName("type"), + MemoryLayout.paddingLayout(4) + ).withName("$anon$50:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfLong addr$LAYOUT = (OfLong)$LAYOUT.select(groupElement("addr")); + + /** + * Layout for field: + * {@snippet lang=c : + * uintptr_t addr + * } + */ + public static final OfLong addr$layout() { + return addr$LAYOUT; + } + + private static final long addr$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * uintptr_t addr + * } + */ + public static final long addr$offset() { + return addr$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uintptr_t addr + * } + */ + public static long addr(MemorySegment struct) { + return struct.get(addr$LAYOUT, addr$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uintptr_t addr + * } + */ + public static void addr(MemorySegment struct, long fieldValue) { + struct.set(addr$LAYOUT, addr$OFFSET, fieldValue); + } + + private static final OfInt type$LAYOUT = (OfInt)$LAYOUT.select(groupElement("type")); + + /** + * Layout for field: + * {@snippet lang=c : + * enum cuvsFilterType type + * } + */ + public static final OfInt type$layout() { + return type$LAYOUT; + } + + private static final long type$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * enum cuvsFilterType type + * } + */ + public static final long type$offset() { + return type$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * enum cuvsFilterType type + * } + */ + public static int type(MemorySegment struct) { + return struct.get(type$LAYOUT, type$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * enum cuvsFilterType type + * } + */ + public static void type(MemorySegment struct, int fieldValue) { + struct.set(type$LAYOUT, type$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswExtendParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswExtendParams.java new file mode 100644 index 000000000..8d750d02e --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswExtendParams.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct cuvsHnswExtendParams { + * int num_threads; + * } + * } + */ +public class CuVSHnswExtendParams { + + CuVSHnswExtendParams() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(HnswH.C_INT.withName("num_threads")) + .withName("cuvsHnswExtendParams"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt num_threads$LAYOUT = (OfInt) $LAYOUT.select(groupElement("num_threads")); + + /** + * Layout for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static final OfInt num_threads$layout() { + return num_threads$LAYOUT; + } + + private static final long num_threads$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static final long num_threads$offset() { + return num_threads$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static int num_threads(MemorySegment struct) { + return struct.get(num_threads$LAYOUT, num_threads$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static void num_threads(MemorySegment struct, int fieldValue) { + struct.set(num_threads$LAYOUT, num_threads$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndex.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndex.java new file mode 100644 index 000000000..1f879462b --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndex.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct { + * uintptr_t addr; + * DLDataType dtype; + * } + * } + */ +public class CuVSHnswIndex { + + CuVSHnswIndex() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(HnswH.C_LONG.withName("addr"), + DLDataType.layout().withName("dtype"), MemoryLayout.paddingLayout(4)).withName("$anon$66:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfLong addr$LAYOUT = (OfLong) $LAYOUT.select(groupElement("addr")); + + /** + * Layout for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static final OfLong addr$layout() { + return addr$LAYOUT; + } + + private static final long addr$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static final long addr$offset() { + return addr$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static long addr(MemorySegment struct) { + return struct.get(addr$LAYOUT, addr$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * uintptr_t addr + * } + */ + public static void addr(MemorySegment struct, long fieldValue) { + struct.set(addr$LAYOUT, addr$OFFSET, fieldValue); + } + + private static final GroupLayout dtype$LAYOUT = (GroupLayout) $LAYOUT.select(groupElement("dtype")); + + /** + * Layout for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static final GroupLayout dtype$layout() { + return dtype$LAYOUT; + } + + private static final long dtype$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static final long dtype$offset() { + return dtype$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static MemorySegment dtype(MemorySegment struct) { + return struct.asSlice(dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang = c : * DLDataType dtype + * } + */ + public static void dtype(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndexParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndexParams.java new file mode 100644 index 000000000..3e6e45a09 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswIndexParams.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct cuvsHnswIndexParams { + * cuvsHnswHierarchy hierarchy; + * int ef_construction; + * int num_threads; + * } + * } + */ +public class CuVSHnswIndexParams { + + CuVSHnswIndexParams() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(HnswH.C_INT.withName("hierarchy"), + HnswH.C_INT.withName("ef_construction"), HnswH.C_INT.withName("num_threads")).withName("cuvsHnswIndexParams"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt hierarchy$LAYOUT = (OfInt) $LAYOUT.select(groupElement("hierarchy")); + + /** + * Layout for field: + * {@snippet lang = c : * cuvsHnswHierarchy hierarchy + * } + */ + public static final OfInt hierarchy$layout() { + return hierarchy$LAYOUT; + } + + private static final long hierarchy$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * cuvsHnswHierarchy hierarchy + * } + */ + public static final long hierarchy$offset() { + return hierarchy$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * cuvsHnswHierarchy hierarchy + * } + */ + public static int hierarchy(MemorySegment struct) { + return struct.get(hierarchy$LAYOUT, hierarchy$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * cuvsHnswHierarchy hierarchy + * } + */ + public static void hierarchy(MemorySegment struct, int fieldValue) { + struct.set(hierarchy$LAYOUT, hierarchy$OFFSET, fieldValue); + } + + private static final OfInt ef_construction$LAYOUT = (OfInt) $LAYOUT.select(groupElement("ef_construction")); + + /** + * Layout for field: + * {@snippet lang = c : * int ef_construction + * } + */ + public static final OfInt ef_construction$layout() { + return ef_construction$LAYOUT; + } + + private static final long ef_construction$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang = c : * int ef_construction + * } + */ + public static final long ef_construction$offset() { + return ef_construction$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * int ef_construction + * } + */ + public static int ef_construction(MemorySegment struct) { + return struct.get(ef_construction$LAYOUT, ef_construction$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * int ef_construction + * } + */ + public static void ef_construction(MemorySegment struct, int fieldValue) { + struct.set(ef_construction$LAYOUT, ef_construction$OFFSET, fieldValue); + } + + private static final OfInt num_threads$LAYOUT = (OfInt) $LAYOUT.select(groupElement("num_threads")); + + /** + * Layout for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static final OfInt num_threads$layout() { + return num_threads$LAYOUT; + } + + private static final long num_threads$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static final long num_threads$offset() { + return num_threads$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static int num_threads(MemorySegment struct) { + return struct.get(num_threads$LAYOUT, num_threads$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * int num_threads + * } + */ + public static void num_threads(MemorySegment struct, int fieldValue) { + struct.set(num_threads$LAYOUT, num_threads$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswSearchParams.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswSearchParams.java new file mode 100644 index 000000000..4a5941a3c --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/CuVSHnswSearchParams.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct cuvsHnswSearchParams { + * int32_t ef; + * int32_t num_threads; + * } + * } + */ +public class CuVSHnswSearchParams { + + CuVSHnswSearchParams() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout + .structLayout(HnswH.C_INT.withName("ef"), HnswH.C_INT.withName("num_threads")).withName("cuvsHnswSearchParams"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt ef$LAYOUT = (OfInt) $LAYOUT.select(groupElement("ef")); + + /** + * Layout for field: + * {@snippet lang = c : * int32_t ef + * } + */ + public static final OfInt ef$layout() { + return ef$LAYOUT; + } + + private static final long ef$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * int32_t ef + * } + */ + public static final long ef$offset() { + return ef$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * int32_t ef + * } + */ + public static int ef(MemorySegment struct) { + return struct.get(ef$LAYOUT, ef$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * int32_t ef + * } + */ + public static void ef(MemorySegment struct, int fieldValue) { + struct.set(ef$LAYOUT, ef$OFFSET, fieldValue); + } + + private static final OfInt num_threads$LAYOUT = (OfInt) $LAYOUT.select(groupElement("num_threads")); + + /** + * Layout for field: + * {@snippet lang = c : * int32_t num_threads + * } + */ + public static final OfInt num_threads$layout() { + return num_threads$LAYOUT; + } + + private static final long num_threads$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang = c : * int32_t num_threads + * } + */ + public static final long num_threads$offset() { + return num_threads$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * int32_t num_threads + * } + */ + public static int num_threads(MemorySegment struct) { + return struct.get(num_threads$LAYOUT, num_threads$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * int32_t num_threads + * } + */ + public static void num_threads(MemorySegment struct, int fieldValue) { + struct.set(num_threads$LAYOUT, num_threads$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDataType.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDataType.java new file mode 100644 index 000000000..c7c588676 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDataType.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfByte; +import java.lang.foreign.ValueLayout.OfShort; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct { + * uint8_t code; + * uint8_t bits; + * uint16_t lanes; + * } + * } + */ +public class DLDataType { + + DLDataType() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + DlpackH.C_CHAR.withName("code"), + DlpackH.C_CHAR.withName("bits"), + DlpackH.C_SHORT.withName("lanes") + ).withName("$anon$174:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfByte code$LAYOUT = (OfByte)$LAYOUT.select(groupElement("code")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint8_t code + * } + */ + public static final OfByte code$layout() { + return code$LAYOUT; + } + + private static final long code$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * uint8_t code + * } + */ + public static final long code$offset() { + return code$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint8_t code + * } + */ + public static byte code(MemorySegment struct) { + return struct.get(code$LAYOUT, code$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint8_t code + * } + */ + public static void code(MemorySegment struct, byte fieldValue) { + struct.set(code$LAYOUT, code$OFFSET, fieldValue); + } + + private static final OfByte bits$LAYOUT = (OfByte)$LAYOUT.select(groupElement("bits")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint8_t bits + * } + */ + public static final OfByte bits$layout() { + return bits$LAYOUT; + } + + private static final long bits$OFFSET = 1; + + /** + * Offset for field: + * {@snippet lang=c : + * uint8_t bits + * } + */ + public static final long bits$offset() { + return bits$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint8_t bits + * } + */ + public static byte bits(MemorySegment struct) { + return struct.get(bits$LAYOUT, bits$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint8_t bits + * } + */ + public static void bits(MemorySegment struct, byte fieldValue) { + struct.set(bits$LAYOUT, bits$OFFSET, fieldValue); + } + + private static final OfShort lanes$LAYOUT = (OfShort)$LAYOUT.select(groupElement("lanes")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint16_t lanes + * } + */ + public static final OfShort lanes$layout() { + return lanes$LAYOUT; + } + + private static final long lanes$OFFSET = 2; + + /** + * Offset for field: + * {@snippet lang=c : + * uint16_t lanes + * } + */ + public static final long lanes$offset() { + return lanes$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint16_t lanes + * } + */ + public static short lanes(MemorySegment struct) { + return struct.get(lanes$LAYOUT, lanes$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint16_t lanes + * } + */ + public static void lanes(MemorySegment struct, short fieldValue) { + struct.set(lanes$LAYOUT, lanes$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDevice.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDevice.java new file mode 100644 index 000000000..a0d5d89ea --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLDevice.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct { + * DLDeviceType device_type; + * int32_t device_id; + * } + * } + */ +public class DLDevice { + + DLDevice() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + DlpackH.C_INT.withName("device_type"), + DlpackH.C_INT.withName("device_id") + ).withName("$anon$126:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt device_type$LAYOUT = (OfInt)$LAYOUT.select(groupElement("device_type")); + + /** + * Layout for field: + * {@snippet lang=c : + * DLDeviceType device_type + * } + */ + public static final OfInt device_type$layout() { + return device_type$LAYOUT; + } + + private static final long device_type$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * DLDeviceType device_type + * } + */ + public static final long device_type$offset() { + return device_type$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * DLDeviceType device_type + * } + */ + public static int device_type(MemorySegment struct) { + return struct.get(device_type$LAYOUT, device_type$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * DLDeviceType device_type + * } + */ + public static void device_type(MemorySegment struct, int fieldValue) { + struct.set(device_type$LAYOUT, device_type$OFFSET, fieldValue); + } + + private static final OfInt device_id$LAYOUT = (OfInt)$LAYOUT.select(groupElement("device_id")); + + /** + * Layout for field: + * {@snippet lang=c : + * int32_t device_id + * } + */ + public static final OfInt device_id$layout() { + return device_id$LAYOUT; + } + + private static final long device_id$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang=c : + * int32_t device_id + * } + */ + public static final long device_id$offset() { + return device_id$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * int32_t device_id + * } + */ + public static int device_id(MemorySegment struct) { + return struct.get(device_id$LAYOUT, device_id$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * int32_t device_id + * } + */ + public static void device_id(MemorySegment struct, int fieldValue) { + struct.set(device_id$LAYOUT, device_id$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensor.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensor.java new file mode 100644 index 000000000..71bba9fe5 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensor.java @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.MethodHandle; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct DLManagedTensor { + * DLTensor dl_tensor; + * void *manager_ctx; + * void (*deleter)(struct DLManagedTensor *); + * } + * } + */ +public class DLManagedTensor { + + DLManagedTensor() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + DLTensor.layout().withName("dl_tensor"), + DlpackH.C_POINTER.withName("manager_ctx"), + DlpackH.C_POINTER.withName("deleter") + ).withName("DLManagedTensor"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final GroupLayout dl_tensor$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("dl_tensor")); + + /** + * Layout for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static final GroupLayout dl_tensor$layout() { + return dl_tensor$LAYOUT; + } + + private static final long dl_tensor$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static final long dl_tensor$offset() { + return dl_tensor$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static MemorySegment dl_tensor(MemorySegment struct) { + return struct.asSlice(dl_tensor$OFFSET, dl_tensor$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static void dl_tensor(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, dl_tensor$OFFSET, dl_tensor$LAYOUT.byteSize()); + } + + private static final AddressLayout manager_ctx$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("manager_ctx")); + + /** + * Layout for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static final AddressLayout manager_ctx$layout() { + return manager_ctx$LAYOUT; + } + + private static final long manager_ctx$OFFSET = 48; + + /** + * Offset for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static final long manager_ctx$offset() { + return manager_ctx$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static MemorySegment manager_ctx(MemorySegment struct) { + return struct.get(manager_ctx$LAYOUT, manager_ctx$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static void manager_ctx(MemorySegment struct, MemorySegment fieldValue) { + struct.set(manager_ctx$LAYOUT, manager_ctx$OFFSET, fieldValue); + } + + /** + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensor *) + * } + */ + public static class deleter { + + deleter() { + // Should not be called directly + } + + /** + * The function pointer signature, expressed as a functional interface + */ + public interface Function { + void apply(MemorySegment _x0); + } + + private static final FunctionDescriptor $DESC = FunctionDescriptor.ofVoid( + DlpackH.C_POINTER + ); + + /** + * The descriptor of this function pointer + */ + public static FunctionDescriptor descriptor() { + return $DESC; + } + + private static final MethodHandle UP$MH = DlpackH.upcallHandle(deleter.Function.class, "apply", $DESC); + + /** + * Allocates a new upcall stub, whose implementation is defined by {@code fi}. + * The lifetime of the returned segment is managed by {@code arena} + */ + public static MemorySegment allocate(deleter.Function fi, Arena arena) { + return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); + } + + private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); + + /** + * Invoke the upcall stub {@code funcPtr}, with given parameters + */ + public static void invoke(MemorySegment funcPtr,MemorySegment _x0) { + try { + DOWN$MH.invokeExact(funcPtr, _x0); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + } + + private static final AddressLayout deleter$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("deleter")); + + /** + * Layout for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensor *) + * } + */ + public static final AddressLayout deleter$layout() { + return deleter$LAYOUT; + } + + private static final long deleter$OFFSET = 56; + + /** + * Offset for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensor *) + * } + */ + public static final long deleter$offset() { + return deleter$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensor *) + * } + */ + public static MemorySegment deleter(MemorySegment struct) { + return struct.get(deleter$LAYOUT, deleter$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensor *) + * } + */ + public static void deleter(MemorySegment struct, MemorySegment fieldValue) { + struct.set(deleter$LAYOUT, deleter$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensorVersioned.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensorVersioned.java new file mode 100644 index 000000000..efdcf9043 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLManagedTensorVersioned.java @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.invoke.MethodHandle; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct DLManagedTensorVersioned { + * DLPackVersion version; + * void *manager_ctx; + * void (*deleter)(struct DLManagedTensorVersioned *); + * uint64_t flags; + * DLTensor dl_tensor; + * } + * } + */ +public class DLManagedTensorVersioned { + + DLManagedTensorVersioned() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + DLPackVersion.layout().withName("version"), + DlpackH.C_POINTER.withName("manager_ctx"), + DlpackH.C_POINTER.withName("deleter"), + DlpackH.C_LONG.withName("flags"), + DLTensor.layout().withName("dl_tensor") + ).withName("DLManagedTensorVersioned"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final GroupLayout version$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("version")); + + /** + * Layout for field: + * {@snippet lang=c : + * DLPackVersion version + * } + */ + public static final GroupLayout version$layout() { + return version$LAYOUT; + } + + private static final long version$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * DLPackVersion version + * } + */ + public static final long version$offset() { + return version$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * DLPackVersion version + * } + */ + public static MemorySegment version(MemorySegment struct) { + return struct.asSlice(version$OFFSET, version$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * DLPackVersion version + * } + */ + public static void version(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, version$OFFSET, version$LAYOUT.byteSize()); + } + + private static final AddressLayout manager_ctx$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("manager_ctx")); + + /** + * Layout for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static final AddressLayout manager_ctx$layout() { + return manager_ctx$LAYOUT; + } + + private static final long manager_ctx$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static final long manager_ctx$offset() { + return manager_ctx$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static MemorySegment manager_ctx(MemorySegment struct) { + return struct.get(manager_ctx$LAYOUT, manager_ctx$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void *manager_ctx + * } + */ + public static void manager_ctx(MemorySegment struct, MemorySegment fieldValue) { + struct.set(manager_ctx$LAYOUT, manager_ctx$OFFSET, fieldValue); + } + + /** + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensorVersioned *) + * } + */ + public static class deleter { + + deleter() { + // Should not be called directly + } + + /** + * The function pointer signature, expressed as a functional interface + */ + public interface Function { + void apply(MemorySegment _x0); + } + + private static final FunctionDescriptor $DESC = FunctionDescriptor.ofVoid( + DlpackH.C_POINTER + ); + + /** + * The descriptor of this function pointer + */ + public static FunctionDescriptor descriptor() { + return $DESC; + } + + private static final MethodHandle UP$MH = DlpackH.upcallHandle(deleter.Function.class, "apply", $DESC); + + /** + * Allocates a new upcall stub, whose implementation is defined by {@code fi}. + * The lifetime of the returned segment is managed by {@code arena} + */ + public static MemorySegment allocate(deleter.Function fi, Arena arena) { + return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); + } + + private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); + + /** + * Invoke the upcall stub {@code funcPtr}, with given parameters + */ + public static void invoke(MemorySegment funcPtr,MemorySegment _x0) { + try { + DOWN$MH.invokeExact(funcPtr, _x0); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + } + + private static final AddressLayout deleter$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("deleter")); + + /** + * Layout for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensorVersioned *) + * } + */ + public static final AddressLayout deleter$layout() { + return deleter$LAYOUT; + } + + private static final long deleter$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensorVersioned *) + * } + */ + public static final long deleter$offset() { + return deleter$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensorVersioned *) + * } + */ + public static MemorySegment deleter(MemorySegment struct) { + return struct.get(deleter$LAYOUT, deleter$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void (*deleter)(struct DLManagedTensorVersioned *) + * } + */ + public static void deleter(MemorySegment struct, MemorySegment fieldValue) { + struct.set(deleter$LAYOUT, deleter$OFFSET, fieldValue); + } + + private static final OfLong flags$LAYOUT = (OfLong)$LAYOUT.select(groupElement("flags")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint64_t flags + * } + */ + public static final OfLong flags$layout() { + return flags$LAYOUT; + } + + private static final long flags$OFFSET = 24; + + /** + * Offset for field: + * {@snippet lang=c : + * uint64_t flags + * } + */ + public static final long flags$offset() { + return flags$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint64_t flags + * } + */ + public static long flags(MemorySegment struct) { + return struct.get(flags$LAYOUT, flags$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint64_t flags + * } + */ + public static void flags(MemorySegment struct, long fieldValue) { + struct.set(flags$LAYOUT, flags$OFFSET, fieldValue); + } + + private static final GroupLayout dl_tensor$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("dl_tensor")); + + /** + * Layout for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static final GroupLayout dl_tensor$layout() { + return dl_tensor$LAYOUT; + } + + private static final long dl_tensor$OFFSET = 32; + + /** + * Offset for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static final long dl_tensor$offset() { + return dl_tensor$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static MemorySegment dl_tensor(MemorySegment struct) { + return struct.asSlice(dl_tensor$OFFSET, dl_tensor$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * DLTensor dl_tensor + * } + */ + public static void dl_tensor(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, dl_tensor$OFFSET, dl_tensor$LAYOUT.byteSize()); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLPackVersion.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLPackVersion.java new file mode 100644 index 000000000..bc8050766 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLPackVersion.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct { + * uint32_t major; + * uint32_t minor; + * } + * } + */ +public class DLPackVersion { + + DLPackVersion() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + DlpackH.C_INT.withName("major"), + DlpackH.C_INT.withName("minor") + ).withName("$anon$61:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt major$LAYOUT = (OfInt)$LAYOUT.select(groupElement("major")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t major + * } + */ + public static final OfInt major$layout() { + return major$LAYOUT; + } + + private static final long major$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t major + * } + */ + public static final long major$offset() { + return major$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t major + * } + */ + public static int major(MemorySegment struct) { + return struct.get(major$LAYOUT, major$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t major + * } + */ + public static void major(MemorySegment struct, int fieldValue) { + struct.set(major$LAYOUT, major$OFFSET, fieldValue); + } + + private static final OfInt minor$LAYOUT = (OfInt)$LAYOUT.select(groupElement("minor")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t minor + * } + */ + public static final OfInt minor$layout() { + return minor$LAYOUT; + } + + private static final long minor$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t minor + * } + */ + public static final long minor$offset() { + return minor$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t minor + * } + */ + public static int minor(MemorySegment struct) { + return struct.get(minor$LAYOUT, minor$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t minor + * } + */ + public static void minor(MemorySegment struct, int fieldValue) { + struct.set(minor$LAYOUT, minor$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLTensor.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLTensor.java new file mode 100644 index 000000000..63082b35a --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DLTensor.java @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct { + * void *data; + * DLDevice device; + * int32_t ndim; + * DLDataType dtype; + * int64_t *shape; + * int64_t *strides; + * uint64_t byte_offset; + * } + * } + */ +public class DLTensor { + + DLTensor() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + DlpackH.C_POINTER.withName("data"), + DLDevice.layout().withName("device"), + DlpackH.C_INT.withName("ndim"), + DLDataType.layout().withName("dtype"), + DlpackH.C_POINTER.withName("shape"), + DlpackH.C_POINTER.withName("strides"), + DlpackH.C_LONG.withName("byte_offset") + ).withName("$anon$192:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final AddressLayout data$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("data")); + + /** + * Layout for field: + * {@snippet lang=c : + * void *data + * } + */ + public static final AddressLayout data$layout() { + return data$LAYOUT; + } + + private static final long data$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * void *data + * } + */ + public static final long data$offset() { + return data$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void *data + * } + */ + public static MemorySegment data(MemorySegment struct) { + return struct.get(data$LAYOUT, data$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void *data + * } + */ + public static void data(MemorySegment struct, MemorySegment fieldValue) { + struct.set(data$LAYOUT, data$OFFSET, fieldValue); + } + + private static final GroupLayout device$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("device")); + + /** + * Layout for field: + * {@snippet lang=c : + * DLDevice device + * } + */ + public static final GroupLayout device$layout() { + return device$LAYOUT; + } + + private static final long device$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * DLDevice device + * } + */ + public static final long device$offset() { + return device$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * DLDevice device + * } + */ + public static MemorySegment device(MemorySegment struct) { + return struct.asSlice(device$OFFSET, device$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * DLDevice device + * } + */ + public static void device(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, device$OFFSET, device$LAYOUT.byteSize()); + } + + private static final OfInt ndim$LAYOUT = (OfInt)$LAYOUT.select(groupElement("ndim")); + + /** + * Layout for field: + * {@snippet lang=c : + * int32_t ndim + * } + */ + public static final OfInt ndim$layout() { + return ndim$LAYOUT; + } + + private static final long ndim$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang=c : + * int32_t ndim + * } + */ + public static final long ndim$offset() { + return ndim$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * int32_t ndim + * } + */ + public static int ndim(MemorySegment struct) { + return struct.get(ndim$LAYOUT, ndim$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * int32_t ndim + * } + */ + public static void ndim(MemorySegment struct, int fieldValue) { + struct.set(ndim$LAYOUT, ndim$OFFSET, fieldValue); + } + + private static final GroupLayout dtype$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("dtype")); + + /** + * Layout for field: + * {@snippet lang=c : + * DLDataType dtype + * } + */ + public static final GroupLayout dtype$layout() { + return dtype$LAYOUT; + } + + private static final long dtype$OFFSET = 20; + + /** + * Offset for field: + * {@snippet lang=c : + * DLDataType dtype + * } + */ + public static final long dtype$offset() { + return dtype$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * DLDataType dtype + * } + */ + public static MemorySegment dtype(MemorySegment struct) { + return struct.asSlice(dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * DLDataType dtype + * } + */ + public static void dtype(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, dtype$OFFSET, dtype$LAYOUT.byteSize()); + } + + private static final AddressLayout shape$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("shape")); + + /** + * Layout for field: + * {@snippet lang=c : + * int64_t *shape + * } + */ + public static final AddressLayout shape$layout() { + return shape$LAYOUT; + } + + private static final long shape$OFFSET = 24; + + /** + * Offset for field: + * {@snippet lang=c : + * int64_t *shape + * } + */ + public static final long shape$offset() { + return shape$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * int64_t *shape + * } + */ + public static MemorySegment shape(MemorySegment struct) { + return struct.get(shape$LAYOUT, shape$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * int64_t *shape + * } + */ + public static void shape(MemorySegment struct, MemorySegment fieldValue) { + struct.set(shape$LAYOUT, shape$OFFSET, fieldValue); + } + + private static final AddressLayout strides$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("strides")); + + /** + * Layout for field: + * {@snippet lang=c : + * int64_t *strides + * } + */ + public static final AddressLayout strides$layout() { + return strides$LAYOUT; + } + + private static final long strides$OFFSET = 32; + + /** + * Offset for field: + * {@snippet lang=c : + * int64_t *strides + * } + */ + public static final long strides$offset() { + return strides$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * int64_t *strides + * } + */ + public static MemorySegment strides(MemorySegment struct) { + return struct.get(strides$LAYOUT, strides$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * int64_t *strides + * } + */ + public static void strides(MemorySegment struct, MemorySegment fieldValue) { + struct.set(strides$LAYOUT, strides$OFFSET, fieldValue); + } + + private static final OfLong byte_offset$LAYOUT = (OfLong)$LAYOUT.select(groupElement("byte_offset")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint64_t byte_offset + * } + */ + public static final OfLong byte_offset$layout() { + return byte_offset$LAYOUT; + } + + private static final long byte_offset$OFFSET = 40; + + /** + * Offset for field: + * {@snippet lang=c : + * uint64_t byte_offset + * } + */ + public static final long byte_offset$offset() { + return byte_offset$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint64_t byte_offset + * } + */ + public static long byte_offset(MemorySegment struct) { + return struct.get(byte_offset$LAYOUT, byte_offset$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint64_t byte_offset + * } + */ + public static void byte_offset(MemorySegment struct, long fieldValue) { + struct.set(byte_offset$LAYOUT, byte_offset$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DistanceH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DistanceH.java new file mode 100644 index 000000000..3949e1089 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DistanceH.java @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +public class DistanceH { + + DistanceH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args) + .map(Object::toString) + .collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream() + .map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? + MemoryLayout.structLayout(alignedMembers) : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup() + .or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int L2Expanded = (int)0L; + /** + * {@snippet lang=c : + * enum .L2Expanded = 0 + * } + */ + public static int L2Expanded() { + return L2Expanded; + } + private static final int L2SqrtExpanded = (int)1L; + /** + * {@snippet lang=c : + * enum .L2SqrtExpanded = 1 + * } + */ + public static int L2SqrtExpanded() { + return L2SqrtExpanded; + } + private static final int CosineExpanded = (int)2L; + /** + * {@snippet lang=c : + * enum .CosineExpanded = 2 + * } + */ + public static int CosineExpanded() { + return CosineExpanded; + } + private static final int L1 = (int)3L; + /** + * {@snippet lang=c : + * enum .L1 = 3 + * } + */ + public static int L1() { + return L1; + } + private static final int L2Unexpanded = (int)4L; + /** + * {@snippet lang=c : + * enum .L2Unexpanded = 4 + * } + */ + public static int L2Unexpanded() { + return L2Unexpanded; + } + private static final int L2SqrtUnexpanded = (int)5L; + /** + * {@snippet lang=c : + * enum .L2SqrtUnexpanded = 5 + * } + */ + public static int L2SqrtUnexpanded() { + return L2SqrtUnexpanded; + } + private static final int InnerProduct = (int)6L; + /** + * {@snippet lang=c : + * enum .InnerProduct = 6 + * } + */ + public static int InnerProduct() { + return InnerProduct; + } + private static final int Linf = (int)7L; + /** + * {@snippet lang=c : + * enum .Linf = 7 + * } + */ + public static int Linf() { + return Linf; + } + private static final int Canberra = (int)8L; + /** + * {@snippet lang=c : + * enum .Canberra = 8 + * } + */ + public static int Canberra() { + return Canberra; + } + private static final int LpUnexpanded = (int)9L; + /** + * {@snippet lang=c : + * enum .LpUnexpanded = 9 + * } + */ + public static int LpUnexpanded() { + return LpUnexpanded; + } + private static final int CorrelationExpanded = (int)10L; + /** + * {@snippet lang=c : + * enum .CorrelationExpanded = 10 + * } + */ + public static int CorrelationExpanded() { + return CorrelationExpanded; + } + private static final int JaccardExpanded = (int)11L; + /** + * {@snippet lang=c : + * enum .JaccardExpanded = 11 + * } + */ + public static int JaccardExpanded() { + return JaccardExpanded; + } + private static final int HellingerExpanded = (int)12L; + /** + * {@snippet lang=c : + * enum .HellingerExpanded = 12 + * } + */ + public static int HellingerExpanded() { + return HellingerExpanded; + } + private static final int Haversine = (int)13L; + /** + * {@snippet lang=c : + * enum .Haversine = 13 + * } + */ + public static int Haversine() { + return Haversine; + } + private static final int BrayCurtis = (int)14L; + /** + * {@snippet lang=c : + * enum .BrayCurtis = 14 + * } + */ + public static int BrayCurtis() { + return BrayCurtis; + } + private static final int JensenShannon = (int)15L; + /** + * {@snippet lang=c : + * enum .JensenShannon = 15 + * } + */ + public static int JensenShannon() { + return JensenShannon; + } + private static final int HammingUnexpanded = (int)16L; + /** + * {@snippet lang=c : + * enum .HammingUnexpanded = 16 + * } + */ + public static int HammingUnexpanded() { + return HammingUnexpanded; + } + private static final int KLDivergence = (int)17L; + /** + * {@snippet lang=c : + * enum .KLDivergence = 17 + * } + */ + public static int KLDivergence() { + return KLDivergence; + } + private static final int RusselRaoExpanded = (int)18L; + /** + * {@snippet lang=c : + * enum .RusselRaoExpanded = 18 + * } + */ + public static int RusselRaoExpanded() { + return RusselRaoExpanded; + } + private static final int DiceExpanded = (int)19L; + /** + * {@snippet lang=c : + * enum .DiceExpanded = 19 + * } + */ + public static int DiceExpanded() { + return DiceExpanded; + } + private static final int Precomputed = (int)100L; + /** + * {@snippet lang=c : + * enum .Precomputed = 100 + * } + */ + public static int Precomputed() { + return Precomputed; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DlpackH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DlpackH.java new file mode 100644 index 000000000..d459dd3bf --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/DlpackH.java @@ -0,0 +1,1898 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.foreign.ValueLayout.OfByte; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.foreign.ValueLayout.OfShort; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.stream.Collectors; + +public class DlpackH { + + DlpackH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args) + .map(Object::toString) + .collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream() + .map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? + MemoryLayout.structLayout(alignedMembers) : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup() + .or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int DLPACK_MAJOR_VERSION = (int)1L; + /** + * {@snippet lang=c : + * #define DLPACK_MAJOR_VERSION 1 + * } + */ + public static int DLPACK_MAJOR_VERSION() { + return DLPACK_MAJOR_VERSION; + } + private static final int DLPACK_MINOR_VERSION = (int)0L; + /** + * {@snippet lang=c : + * #define DLPACK_MINOR_VERSION 0 + * } + */ + public static int DLPACK_MINOR_VERSION() { + return DLPACK_MINOR_VERSION; + } + private static final int _STDINT_H = (int)1L; + /** + * {@snippet lang=c : + * #define _STDINT_H 1 + * } + */ + public static int _STDINT_H() { + return _STDINT_H; + } + private static final int _FEATURES_H = (int)1L; + /** + * {@snippet lang=c : + * #define _FEATURES_H 1 + * } + */ + public static int _FEATURES_H() { + return _FEATURES_H; + } + private static final int _DEFAULT_SOURCE = (int)1L; + /** + * {@snippet lang=c : + * #define _DEFAULT_SOURCE 1 + * } + */ + public static int _DEFAULT_SOURCE() { + return _DEFAULT_SOURCE; + } + private static final int __GLIBC_USE_ISOC2X = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_ISOC2X 0 + * } + */ + public static int __GLIBC_USE_ISOC2X() { + return __GLIBC_USE_ISOC2X; + } + private static final int __USE_ISOC11 = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_ISOC11 1 + * } + */ + public static int __USE_ISOC11() { + return __USE_ISOC11; + } + private static final int __USE_ISOC99 = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_ISOC99 1 + * } + */ + public static int __USE_ISOC99() { + return __USE_ISOC99; + } + private static final int __USE_ISOC95 = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_ISOC95 1 + * } + */ + public static int __USE_ISOC95() { + return __USE_ISOC95; + } + private static final int __USE_POSIX_IMPLICITLY = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_POSIX_IMPLICITLY 1 + * } + */ + public static int __USE_POSIX_IMPLICITLY() { + return __USE_POSIX_IMPLICITLY; + } + private static final int _POSIX_SOURCE = (int)1L; + /** + * {@snippet lang=c : + * #define _POSIX_SOURCE 1 + * } + */ + public static int _POSIX_SOURCE() { + return _POSIX_SOURCE; + } + private static final int __USE_POSIX = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_POSIX 1 + * } + */ + public static int __USE_POSIX() { + return __USE_POSIX; + } + private static final int __USE_POSIX2 = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_POSIX2 1 + * } + */ + public static int __USE_POSIX2() { + return __USE_POSIX2; + } + private static final int __USE_POSIX199309 = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_POSIX199309 1 + * } + */ + public static int __USE_POSIX199309() { + return __USE_POSIX199309; + } + private static final int __USE_POSIX199506 = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_POSIX199506 1 + * } + */ + public static int __USE_POSIX199506() { + return __USE_POSIX199506; + } + private static final int __USE_XOPEN2K = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_XOPEN2K 1 + * } + */ + public static int __USE_XOPEN2K() { + return __USE_XOPEN2K; + } + private static final int __USE_XOPEN2K8 = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_XOPEN2K8 1 + * } + */ + public static int __USE_XOPEN2K8() { + return __USE_XOPEN2K8; + } + private static final int _ATFILE_SOURCE = (int)1L; + /** + * {@snippet lang=c : + * #define _ATFILE_SOURCE 1 + * } + */ + public static int _ATFILE_SOURCE() { + return _ATFILE_SOURCE; + } + private static final int __WORDSIZE = (int)64L; + /** + * {@snippet lang=c : + * #define __WORDSIZE 64 + * } + */ + public static int __WORDSIZE() { + return __WORDSIZE; + } + private static final int __WORDSIZE_TIME64_COMPAT32 = (int)1L; + /** + * {@snippet lang=c : + * #define __WORDSIZE_TIME64_COMPAT32 1 + * } + */ + public static int __WORDSIZE_TIME64_COMPAT32() { + return __WORDSIZE_TIME64_COMPAT32; + } + private static final int __SYSCALL_WORDSIZE = (int)64L; + /** + * {@snippet lang=c : + * #define __SYSCALL_WORDSIZE 64 + * } + */ + public static int __SYSCALL_WORDSIZE() { + return __SYSCALL_WORDSIZE; + } + private static final int __USE_MISC = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_MISC 1 + * } + */ + public static int __USE_MISC() { + return __USE_MISC; + } + private static final int __USE_ATFILE = (int)1L; + /** + * {@snippet lang=c : + * #define __USE_ATFILE 1 + * } + */ + public static int __USE_ATFILE() { + return __USE_ATFILE; + } + private static final int __USE_FORTIFY_LEVEL = (int)0L; + /** + * {@snippet lang=c : + * #define __USE_FORTIFY_LEVEL 0 + * } + */ + public static int __USE_FORTIFY_LEVEL() { + return __USE_FORTIFY_LEVEL; + } + private static final int __GLIBC_USE_DEPRECATED_GETS = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_DEPRECATED_GETS 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_GETS() { + return __GLIBC_USE_DEPRECATED_GETS; + } + private static final int __GLIBC_USE_DEPRECATED_SCANF = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_DEPRECATED_SCANF 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_SCANF() { + return __GLIBC_USE_DEPRECATED_SCANF; + } + private static final int _STDC_PREDEF_H = (int)1L; + /** + * {@snippet lang=c : + * #define _STDC_PREDEF_H 1 + * } + */ + public static int _STDC_PREDEF_H() { + return _STDC_PREDEF_H; + } + private static final int __STDC_IEC_559__ = (int)1L; + /** + * {@snippet lang=c : + * #define __STDC_IEC_559__ 1 + * } + */ + public static int __STDC_IEC_559__() { + return __STDC_IEC_559__; + } + private static final int __STDC_IEC_559_COMPLEX__ = (int)1L; + /** + * {@snippet lang=c : + * #define __STDC_IEC_559_COMPLEX__ 1 + * } + */ + public static int __STDC_IEC_559_COMPLEX__() { + return __STDC_IEC_559_COMPLEX__; + } + private static final int __GNU_LIBRARY__ = (int)6L; + /** + * {@snippet lang=c : + * #define __GNU_LIBRARY__ 6 + * } + */ + public static int __GNU_LIBRARY__() { + return __GNU_LIBRARY__; + } + private static final int __GLIBC__ = (int)2L; + /** + * {@snippet lang=c : + * #define __GLIBC__ 2 + * } + */ + public static int __GLIBC__() { + return __GLIBC__; + } + private static final int __GLIBC_MINOR__ = (int)35L; + /** + * {@snippet lang=c : + * #define __GLIBC_MINOR__ 35 + * } + */ + public static int __GLIBC_MINOR__() { + return __GLIBC_MINOR__; + } + private static final int _SYS_CDEFS_H = (int)1L; + /** + * {@snippet lang=c : + * #define _SYS_CDEFS_H 1 + * } + */ + public static int _SYS_CDEFS_H() { + return _SYS_CDEFS_H; + } + private static final int __glibc_c99_flexarr_available = (int)1L; + /** + * {@snippet lang=c : + * #define __glibc_c99_flexarr_available 1 + * } + */ + public static int __glibc_c99_flexarr_available() { + return __glibc_c99_flexarr_available; + } + private static final int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = (int)0L; + /** + * {@snippet lang=c : + * #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 + * } + */ + public static int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI() { + return __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI; + } + private static final int __HAVE_GENERIC_SELECTION = (int)1L; + /** + * {@snippet lang=c : + * #define __HAVE_GENERIC_SELECTION 1 + * } + */ + public static int __HAVE_GENERIC_SELECTION() { + return __HAVE_GENERIC_SELECTION; + } + private static final int __GLIBC_USE_LIB_EXT2 = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_LIB_EXT2 0 + * } + */ + public static int __GLIBC_USE_LIB_EXT2() { + return __GLIBC_USE_LIB_EXT2; + } + private static final int __GLIBC_USE_IEC_60559_BFP_EXT = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_IEC_60559_BFP_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT() { + return __GLIBC_USE_IEC_60559_BFP_EXT; + } + private static final int __GLIBC_USE_IEC_60559_BFP_EXT_C2X = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_IEC_60559_BFP_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT_C2X() { + return __GLIBC_USE_IEC_60559_BFP_EXT_C2X; + } + private static final int __GLIBC_USE_IEC_60559_EXT = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_IEC_60559_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_EXT() { + return __GLIBC_USE_IEC_60559_EXT; + } + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_IEC_60559_FUNCS_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT; + } + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X; + } + private static final int __GLIBC_USE_IEC_60559_TYPES_EXT = (int)0L; + /** + * {@snippet lang=c : + * #define __GLIBC_USE_IEC_60559_TYPES_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_TYPES_EXT() { + return __GLIBC_USE_IEC_60559_TYPES_EXT; + } + private static final int _BITS_TYPES_H = (int)1L; + /** + * {@snippet lang=c : + * #define _BITS_TYPES_H 1 + * } + */ + public static int _BITS_TYPES_H() { + return _BITS_TYPES_H; + } + private static final int _BITS_TYPESIZES_H = (int)1L; + /** + * {@snippet lang=c : + * #define _BITS_TYPESIZES_H 1 + * } + */ + public static int _BITS_TYPESIZES_H() { + return _BITS_TYPESIZES_H; + } + private static final int __OFF_T_MATCHES_OFF64_T = (int)1L; + /** + * {@snippet lang=c : + * #define __OFF_T_MATCHES_OFF64_T 1 + * } + */ + public static int __OFF_T_MATCHES_OFF64_T() { + return __OFF_T_MATCHES_OFF64_T; + } + private static final int __INO_T_MATCHES_INO64_T = (int)1L; + /** + * {@snippet lang=c : + * #define __INO_T_MATCHES_INO64_T 1 + * } + */ + public static int __INO_T_MATCHES_INO64_T() { + return __INO_T_MATCHES_INO64_T; + } + private static final int __RLIM_T_MATCHES_RLIM64_T = (int)1L; + /** + * {@snippet lang=c : + * #define __RLIM_T_MATCHES_RLIM64_T 1 + * } + */ + public static int __RLIM_T_MATCHES_RLIM64_T() { + return __RLIM_T_MATCHES_RLIM64_T; + } + private static final int __STATFS_MATCHES_STATFS64 = (int)1L; + /** + * {@snippet lang=c : + * #define __STATFS_MATCHES_STATFS64 1 + * } + */ + public static int __STATFS_MATCHES_STATFS64() { + return __STATFS_MATCHES_STATFS64; + } + private static final int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = (int)1L; + /** + * {@snippet lang=c : + * #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 + * } + */ + public static int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64() { + return __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64; + } + private static final int __FD_SETSIZE = (int)1024L; + /** + * {@snippet lang=c : + * #define __FD_SETSIZE 1024 + * } + */ + public static int __FD_SETSIZE() { + return __FD_SETSIZE; + } + private static final int _BITS_TIME64_H = (int)1L; + /** + * {@snippet lang=c : + * #define _BITS_TIME64_H 1 + * } + */ + public static int _BITS_TIME64_H() { + return _BITS_TIME64_H; + } + private static final int _BITS_WCHAR_H = (int)1L; + /** + * {@snippet lang=c : + * #define _BITS_WCHAR_H 1 + * } + */ + public static int _BITS_WCHAR_H() { + return _BITS_WCHAR_H; + } + private static final int _BITS_STDINT_INTN_H = (int)1L; + /** + * {@snippet lang=c : + * #define _BITS_STDINT_INTN_H 1 + * } + */ + public static int _BITS_STDINT_INTN_H() { + return _BITS_STDINT_INTN_H; + } + private static final int _BITS_STDINT_UINTN_H = (int)1L; + /** + * {@snippet lang=c : + * #define _BITS_STDINT_UINTN_H 1 + * } + */ + public static int _BITS_STDINT_UINTN_H() { + return _BITS_STDINT_UINTN_H; + } + /** + * {@snippet lang=c : + * typedef unsigned char __u_char + * } + */ + public static final OfByte __u_char = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef unsigned short __u_short + * } + */ + public static final OfShort __u_short = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef unsigned int __u_int + * } + */ + public static final OfInt __u_int = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef unsigned long __u_long + * } + */ + public static final OfLong __u_long = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef signed char __int8_t + * } + */ + public static final OfByte __int8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef unsigned char __uint8_t + * } + */ + public static final OfByte __uint8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef short __int16_t + * } + */ + public static final OfShort __int16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef unsigned short __uint16_t + * } + */ + public static final OfShort __uint16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef int __int32_t + * } + */ + public static final OfInt __int32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef unsigned int __uint32_t + * } + */ + public static final OfInt __uint32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef long __int64_t + * } + */ + public static final OfLong __int64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __uint64_t + * } + */ + public static final OfLong __uint64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __int8_t __int_least8_t + * } + */ + public static final OfByte __int_least8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef __uint8_t __uint_least8_t + * } + */ + public static final OfByte __uint_least8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef __int16_t __int_least16_t + * } + */ + public static final OfShort __int_least16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef __uint16_t __uint_least16_t + * } + */ + public static final OfShort __uint_least16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef __int32_t __int_least32_t + * } + */ + public static final OfInt __int_least32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef __uint32_t __uint_least32_t + * } + */ + public static final OfInt __uint_least32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef __int64_t __int_least64_t + * } + */ + public static final OfLong __int_least64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __uint64_t __uint_least64_t + * } + */ + public static final OfLong __uint_least64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __quad_t + * } + */ + public static final OfLong __quad_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __u_quad_t + * } + */ + public static final OfLong __u_quad_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __intmax_t + * } + */ + public static final OfLong __intmax_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __uintmax_t + * } + */ + public static final OfLong __uintmax_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __dev_t + * } + */ + public static final OfLong __dev_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned int __uid_t + * } + */ + public static final OfInt __uid_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef unsigned int __gid_t + * } + */ + public static final OfInt __gid_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef unsigned long __ino_t + * } + */ + public static final OfLong __ino_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __ino64_t + * } + */ + public static final OfLong __ino64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned int __mode_t + * } + */ + public static final OfInt __mode_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef unsigned long __nlink_t + * } + */ + public static final OfLong __nlink_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __off_t + * } + */ + public static final OfLong __off_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __off64_t + * } + */ + public static final OfLong __off64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef int __pid_t + * } + */ + public static final OfInt __pid_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef long __clock_t + * } + */ + public static final OfLong __clock_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __rlim_t + * } + */ + public static final OfLong __rlim_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __rlim64_t + * } + */ + public static final OfLong __rlim64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned int __id_t + * } + */ + public static final OfInt __id_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef long __time_t + * } + */ + public static final OfLong __time_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned int __useconds_t + * } + */ + public static final OfInt __useconds_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef long __suseconds_t + * } + */ + public static final OfLong __suseconds_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __suseconds64_t + * } + */ + public static final OfLong __suseconds64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef int __daddr_t + * } + */ + public static final OfInt __daddr_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef int __key_t + * } + */ + public static final OfInt __key_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef int __clockid_t + * } + */ + public static final OfInt __clockid_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef void *__timer_t + * } + */ + public static final AddressLayout __timer_t = DlpackH.C_POINTER; + /** + * {@snippet lang=c : + * typedef long __blksize_t + * } + */ + public static final OfLong __blksize_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __blkcnt_t + * } + */ + public static final OfLong __blkcnt_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __blkcnt64_t + * } + */ + public static final OfLong __blkcnt64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __fsblkcnt_t + * } + */ + public static final OfLong __fsblkcnt_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __fsblkcnt64_t + * } + */ + public static final OfLong __fsblkcnt64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __fsfilcnt_t + * } + */ + public static final OfLong __fsfilcnt_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __fsfilcnt64_t + * } + */ + public static final OfLong __fsfilcnt64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __fsword_t + * } + */ + public static final OfLong __fsword_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __ssize_t + * } + */ + public static final OfLong __ssize_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long __syscall_slong_t + * } + */ + public static final OfLong __syscall_slong_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long __syscall_ulong_t + * } + */ + public static final OfLong __syscall_ulong_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __off64_t __loff_t + * } + */ + public static final OfLong __loff_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef char *__caddr_t + * } + */ + public static final AddressLayout __caddr_t = DlpackH.C_POINTER; + /** + * {@snippet lang=c : + * typedef long __intptr_t + * } + */ + public static final OfLong __intptr_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned int __socklen_t + * } + */ + public static final OfInt __socklen_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef int __sig_atomic_t + * } + */ + public static final OfInt __sig_atomic_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef __int8_t int8_t + * } + */ + public static final OfByte int8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef __int16_t int16_t + * } + */ + public static final OfShort int16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef __int32_t int32_t + * } + */ + public static final OfInt int32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef __int64_t int64_t + * } + */ + public static final OfLong int64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __uint8_t uint8_t + * } + */ + public static final OfByte uint8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef __uint16_t uint16_t + * } + */ + public static final OfShort uint16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef __uint32_t uint32_t + * } + */ + public static final OfInt uint32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef __uint64_t uint64_t + * } + */ + public static final OfLong uint64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __int_least8_t int_least8_t + * } + */ + public static final OfByte int_least8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef __int_least16_t int_least16_t + * } + */ + public static final OfShort int_least16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef __int_least32_t int_least32_t + * } + */ + public static final OfInt int_least32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef __int_least64_t int_least64_t + * } + */ + public static final OfLong int_least64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __uint_least8_t uint_least8_t + * } + */ + public static final OfByte uint_least8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef __uint_least16_t uint_least16_t + * } + */ + public static final OfShort uint_least16_t = DlpackH.C_SHORT; + /** + * {@snippet lang=c : + * typedef __uint_least32_t uint_least32_t + * } + */ + public static final OfInt uint_least32_t = DlpackH.C_INT; + /** + * {@snippet lang=c : + * typedef __uint_least64_t uint_least64_t + * } + */ + public static final OfLong uint_least64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef signed char int_fast8_t + * } + */ + public static final OfByte int_fast8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef long int_fast16_t + * } + */ + public static final OfLong int_fast16_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long int_fast32_t + * } + */ + public static final OfLong int_fast32_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long int_fast64_t + * } + */ + public static final OfLong int_fast64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned char uint_fast8_t + * } + */ + public static final OfByte uint_fast8_t = DlpackH.C_CHAR; + /** + * {@snippet lang=c : + * typedef unsigned long uint_fast16_t + * } + */ + public static final OfLong uint_fast16_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long uint_fast32_t + * } + */ + public static final OfLong uint_fast32_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long uint_fast64_t + * } + */ + public static final OfLong uint_fast64_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long intptr_t + * } + */ + public static final OfLong intptr_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long uintptr_t + * } + */ + public static final OfLong uintptr_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __intmax_t intmax_t + * } + */ + public static final OfLong intmax_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef __uintmax_t uintmax_t + * } + */ + public static final OfLong uintmax_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef long ptrdiff_t + * } + */ + public static final OfLong ptrdiff_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef unsigned long size_t + * } + */ + public static final OfLong size_t = DlpackH.C_LONG; + /** + * {@snippet lang=c : + * typedef int wchar_t + * } + */ + public static final OfInt wchar_t = DlpackH.C_INT; + private static final int kDLCPU = (int)1L; + /** + * {@snippet lang=c : + * enum .kDLCPU = 1 + * } + */ + public static int kDLCPU() { + return kDLCPU; + } + private static final int kDLCUDA = (int)2L; + /** + * {@snippet lang=c : + * enum .kDLCUDA = 2 + * } + */ + public static int kDLCUDA() { + return kDLCUDA; + } + private static final int kDLCUDAHost = (int)3L; + /** + * {@snippet lang=c : + * enum .kDLCUDAHost = 3 + * } + */ + public static int kDLCUDAHost() { + return kDLCUDAHost; + } + private static final int kDLOpenCL = (int)4L; + /** + * {@snippet lang=c : + * enum .kDLOpenCL = 4 + * } + */ + public static int kDLOpenCL() { + return kDLOpenCL; + } + private static final int kDLVulkan = (int)7L; + /** + * {@snippet lang=c : + * enum .kDLVulkan = 7 + * } + */ + public static int kDLVulkan() { + return kDLVulkan; + } + private static final int kDLMetal = (int)8L; + /** + * {@snippet lang=c : + * enum .kDLMetal = 8 + * } + */ + public static int kDLMetal() { + return kDLMetal; + } + private static final int kDLVPI = (int)9L; + /** + * {@snippet lang=c : + * enum .kDLVPI = 9 + * } + */ + public static int kDLVPI() { + return kDLVPI; + } + private static final int kDLROCM = (int)10L; + /** + * {@snippet lang=c : + * enum .kDLROCM = 10 + * } + */ + public static int kDLROCM() { + return kDLROCM; + } + private static final int kDLROCMHost = (int)11L; + /** + * {@snippet lang=c : + * enum .kDLROCMHost = 11 + * } + */ + public static int kDLROCMHost() { + return kDLROCMHost; + } + private static final int kDLExtDev = (int)12L; + /** + * {@snippet lang=c : + * enum .kDLExtDev = 12 + * } + */ + public static int kDLExtDev() { + return kDLExtDev; + } + private static final int kDLCUDAManaged = (int)13L; + /** + * {@snippet lang=c : + * enum .kDLCUDAManaged = 13 + * } + */ + public static int kDLCUDAManaged() { + return kDLCUDAManaged; + } + private static final int kDLOneAPI = (int)14L; + /** + * {@snippet lang=c : + * enum .kDLOneAPI = 14 + * } + */ + public static int kDLOneAPI() { + return kDLOneAPI; + } + private static final int kDLWebGPU = (int)15L; + /** + * {@snippet lang=c : + * enum .kDLWebGPU = 15 + * } + */ + public static int kDLWebGPU() { + return kDLWebGPU; + } + private static final int kDLHexagon = (int)16L; + /** + * {@snippet lang=c : + * enum .kDLHexagon = 16 + * } + */ + public static int kDLHexagon() { + return kDLHexagon; + } + private static final int kDLMAIA = (int)17L; + /** + * {@snippet lang=c : + * enum .kDLMAIA = 17 + * } + */ + public static int kDLMAIA() { + return kDLMAIA; + } + private static final int kDLInt = (int)0L; + /** + * {@snippet lang=c : + * enum .kDLInt = 0 + * } + */ + public static int kDLInt() { + return kDLInt; + } + private static final int kDLUInt = (int)1L; + /** + * {@snippet lang=c : + * enum .kDLUInt = 1 + * } + */ + public static int kDLUInt() { + return kDLUInt; + } + private static final int kDLFloat = (int)2L; + /** + * {@snippet lang=c : + * enum .kDLFloat = 2 + * } + */ + public static int kDLFloat() { + return kDLFloat; + } + private static final int kDLOpaqueHandle = (int)3L; + /** + * {@snippet lang=c : + * enum .kDLOpaqueHandle = 3 + * } + */ + public static int kDLOpaqueHandle() { + return kDLOpaqueHandle; + } + private static final int kDLBfloat = (int)4L; + /** + * {@snippet lang=c : + * enum .kDLBfloat = 4 + * } + */ + public static int kDLBfloat() { + return kDLBfloat; + } + private static final int kDLComplex = (int)5L; + /** + * {@snippet lang=c : + * enum .kDLComplex = 5 + * } + */ + public static int kDLComplex() { + return kDLComplex; + } + private static final int kDLBool = (int)6L; + /** + * {@snippet lang=c : + * enum .kDLBool = 6 + * } + */ + public static int kDLBool() { + return kDLBool; + } + private static final long _POSIX_C_SOURCE = 200809L; + /** + * {@snippet lang=c : + * #define _POSIX_C_SOURCE 200809 + * } + */ + public static long _POSIX_C_SOURCE() { + return _POSIX_C_SOURCE; + } + private static final int __TIMESIZE = (int)64L; + /** + * {@snippet lang=c : + * #define __TIMESIZE 64 + * } + */ + public static int __TIMESIZE() { + return __TIMESIZE; + } + private static final long __STDC_IEC_60559_BFP__ = 201404L; + /** + * {@snippet lang=c : + * #define __STDC_IEC_60559_BFP__ 201404 + * } + */ + public static long __STDC_IEC_60559_BFP__() { + return __STDC_IEC_60559_BFP__; + } + private static final long __STDC_IEC_60559_COMPLEX__ = 201404L; + /** + * {@snippet lang=c : + * #define __STDC_IEC_60559_COMPLEX__ 201404 + * } + */ + public static long __STDC_IEC_60559_COMPLEX__() { + return __STDC_IEC_60559_COMPLEX__; + } + private static final long __STDC_ISO_10646__ = 201706L; + /** + * {@snippet lang=c : + * #define __STDC_ISO_10646__ 201706 + * } + */ + public static long __STDC_ISO_10646__() { + return __STDC_ISO_10646__; + } + private static final int __WCHAR_MAX = (int)2147483647L; + /** + * {@snippet lang=c : + * #define __WCHAR_MAX 2147483647 + * } + */ + public static int __WCHAR_MAX() { + return __WCHAR_MAX; + } + private static final int __WCHAR_MIN = (int)-2147483648L; + /** + * {@snippet lang=c : + * #define __WCHAR_MIN -2147483648 + * } + */ + public static int __WCHAR_MIN() { + return __WCHAR_MIN; + } + private static final int INT8_MIN = (int)-128L; + /** + * {@snippet lang=c : + * #define INT8_MIN -128 + * } + */ + public static int INT8_MIN() { + return INT8_MIN; + } + private static final int INT16_MIN = (int)-32768L; + /** + * {@snippet lang=c : + * #define INT16_MIN -32768 + * } + */ + public static int INT16_MIN() { + return INT16_MIN; + } + private static final int INT32_MIN = (int)-2147483648L; + /** + * {@snippet lang=c : + * #define INT32_MIN -2147483648 + * } + */ + public static int INT32_MIN() { + return INT32_MIN; + } + private static final long INT64_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define INT64_MIN -9223372036854775808 + * } + */ + public static long INT64_MIN() { + return INT64_MIN; + } + private static final int INT8_MAX = (int)127L; + /** + * {@snippet lang=c : + * #define INT8_MAX 127 + * } + */ + public static int INT8_MAX() { + return INT8_MAX; + } + private static final int INT16_MAX = (int)32767L; + /** + * {@snippet lang=c : + * #define INT16_MAX 32767 + * } + */ + public static int INT16_MAX() { + return INT16_MAX; + } + private static final int INT32_MAX = (int)2147483647L; + /** + * {@snippet lang=c : + * #define INT32_MAX 2147483647 + * } + */ + public static int INT32_MAX() { + return INT32_MAX; + } + private static final long INT64_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define INT64_MAX 9223372036854775807 + * } + */ + public static long INT64_MAX() { + return INT64_MAX; + } + private static final int UINT8_MAX = (int)255L; + /** + * {@snippet lang=c : + * #define UINT8_MAX 255 + * } + */ + public static int UINT8_MAX() { + return UINT8_MAX; + } + private static final int UINT16_MAX = (int)65535L; + /** + * {@snippet lang=c : + * #define UINT16_MAX 65535 + * } + */ + public static int UINT16_MAX() { + return UINT16_MAX; + } + private static final int UINT32_MAX = (int)4294967295L; + /** + * {@snippet lang=c : + * #define UINT32_MAX 4294967295 + * } + */ + public static int UINT32_MAX() { + return UINT32_MAX; + } + private static final long UINT64_MAX = -1L; + /** + * {@snippet lang=c : + * #define UINT64_MAX -1 + * } + */ + public static long UINT64_MAX() { + return UINT64_MAX; + } + private static final int INT_LEAST8_MIN = (int)-128L; + /** + * {@snippet lang=c : + * #define INT_LEAST8_MIN -128 + * } + */ + public static int INT_LEAST8_MIN() { + return INT_LEAST8_MIN; + } + private static final int INT_LEAST16_MIN = (int)-32768L; + /** + * {@snippet lang=c : + * #define INT_LEAST16_MIN -32768 + * } + */ + public static int INT_LEAST16_MIN() { + return INT_LEAST16_MIN; + } + private static final int INT_LEAST32_MIN = (int)-2147483648L; + /** + * {@snippet lang=c : + * #define INT_LEAST32_MIN -2147483648 + * } + */ + public static int INT_LEAST32_MIN() { + return INT_LEAST32_MIN; + } + private static final long INT_LEAST64_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define INT_LEAST64_MIN -9223372036854775808 + * } + */ + public static long INT_LEAST64_MIN() { + return INT_LEAST64_MIN; + } + private static final int INT_LEAST8_MAX = (int)127L; + /** + * {@snippet lang=c : + * #define INT_LEAST8_MAX 127 + * } + */ + public static int INT_LEAST8_MAX() { + return INT_LEAST8_MAX; + } + private static final int INT_LEAST16_MAX = (int)32767L; + /** + * {@snippet lang=c : + * #define INT_LEAST16_MAX 32767 + * } + */ + public static int INT_LEAST16_MAX() { + return INT_LEAST16_MAX; + } + private static final int INT_LEAST32_MAX = (int)2147483647L; + /** + * {@snippet lang=c : + * #define INT_LEAST32_MAX 2147483647 + * } + */ + public static int INT_LEAST32_MAX() { + return INT_LEAST32_MAX; + } + private static final long INT_LEAST64_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define INT_LEAST64_MAX 9223372036854775807 + * } + */ + public static long INT_LEAST64_MAX() { + return INT_LEAST64_MAX; + } + private static final int UINT_LEAST8_MAX = (int)255L; + /** + * {@snippet lang=c : + * #define UINT_LEAST8_MAX 255 + * } + */ + public static int UINT_LEAST8_MAX() { + return UINT_LEAST8_MAX; + } + private static final int UINT_LEAST16_MAX = (int)65535L; + /** + * {@snippet lang=c : + * #define UINT_LEAST16_MAX 65535 + * } + */ + public static int UINT_LEAST16_MAX() { + return UINT_LEAST16_MAX; + } + private static final int UINT_LEAST32_MAX = (int)4294967295L; + /** + * {@snippet lang=c : + * #define UINT_LEAST32_MAX 4294967295 + * } + */ + public static int UINT_LEAST32_MAX() { + return UINT_LEAST32_MAX; + } + private static final long UINT_LEAST64_MAX = -1L; + /** + * {@snippet lang=c : + * #define UINT_LEAST64_MAX -1 + * } + */ + public static long UINT_LEAST64_MAX() { + return UINT_LEAST64_MAX; + } + private static final int INT_FAST8_MIN = (int)-128L; + /** + * {@snippet lang=c : + * #define INT_FAST8_MIN -128 + * } + */ + public static int INT_FAST8_MIN() { + return INT_FAST8_MIN; + } + private static final long INT_FAST16_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define INT_FAST16_MIN -9223372036854775808 + * } + */ + public static long INT_FAST16_MIN() { + return INT_FAST16_MIN; + } + private static final long INT_FAST32_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define INT_FAST32_MIN -9223372036854775808 + * } + */ + public static long INT_FAST32_MIN() { + return INT_FAST32_MIN; + } + private static final long INT_FAST64_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define INT_FAST64_MIN -9223372036854775808 + * } + */ + public static long INT_FAST64_MIN() { + return INT_FAST64_MIN; + } + private static final int INT_FAST8_MAX = (int)127L; + /** + * {@snippet lang=c : + * #define INT_FAST8_MAX 127 + * } + */ + public static int INT_FAST8_MAX() { + return INT_FAST8_MAX; + } + private static final long INT_FAST16_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define INT_FAST16_MAX 9223372036854775807 + * } + */ + public static long INT_FAST16_MAX() { + return INT_FAST16_MAX; + } + private static final long INT_FAST32_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define INT_FAST32_MAX 9223372036854775807 + * } + */ + public static long INT_FAST32_MAX() { + return INT_FAST32_MAX; + } + private static final long INT_FAST64_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define INT_FAST64_MAX 9223372036854775807 + * } + */ + public static long INT_FAST64_MAX() { + return INT_FAST64_MAX; + } + private static final int UINT_FAST8_MAX = (int)255L; + /** + * {@snippet lang=c : + * #define UINT_FAST8_MAX 255 + * } + */ + public static int UINT_FAST8_MAX() { + return UINT_FAST8_MAX; + } + private static final long UINT_FAST16_MAX = -1L; + /** + * {@snippet lang=c : + * #define UINT_FAST16_MAX -1 + * } + */ + public static long UINT_FAST16_MAX() { + return UINT_FAST16_MAX; + } + private static final long UINT_FAST32_MAX = -1L; + /** + * {@snippet lang=c : + * #define UINT_FAST32_MAX -1 + * } + */ + public static long UINT_FAST32_MAX() { + return UINT_FAST32_MAX; + } + private static final long UINT_FAST64_MAX = -1L; + /** + * {@snippet lang=c : + * #define UINT_FAST64_MAX -1 + * } + */ + public static long UINT_FAST64_MAX() { + return UINT_FAST64_MAX; + } + private static final long INTPTR_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define INTPTR_MIN -9223372036854775808 + * } + */ + public static long INTPTR_MIN() { + return INTPTR_MIN; + } + private static final long INTPTR_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define INTPTR_MAX 9223372036854775807 + * } + */ + public static long INTPTR_MAX() { + return INTPTR_MAX; + } + private static final long UINTPTR_MAX = -1L; + /** + * {@snippet lang=c : + * #define UINTPTR_MAX -1 + * } + */ + public static long UINTPTR_MAX() { + return UINTPTR_MAX; + } + private static final long INTMAX_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define INTMAX_MIN -9223372036854775808 + * } + */ + public static long INTMAX_MIN() { + return INTMAX_MIN; + } + private static final long INTMAX_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define INTMAX_MAX 9223372036854775807 + * } + */ + public static long INTMAX_MAX() { + return INTMAX_MAX; + } + private static final long UINTMAX_MAX = -1L; + /** + * {@snippet lang=c : + * #define UINTMAX_MAX -1 + * } + */ + public static long UINTMAX_MAX() { + return UINTMAX_MAX; + } + private static final long PTRDIFF_MIN = -9223372036854775808L; + /** + * {@snippet lang=c : + * #define PTRDIFF_MIN -9223372036854775808 + * } + */ + public static long PTRDIFF_MIN() { + return PTRDIFF_MIN; + } + private static final long PTRDIFF_MAX = 9223372036854775807L; + /** + * {@snippet lang=c : + * #define PTRDIFF_MAX 9223372036854775807 + * } + */ + public static long PTRDIFF_MAX() { + return PTRDIFF_MAX; + } + private static final int SIG_ATOMIC_MIN = (int)-2147483648L; + /** + * {@snippet lang=c : + * #define SIG_ATOMIC_MIN -2147483648 + * } + */ + public static int SIG_ATOMIC_MIN() { + return SIG_ATOMIC_MIN; + } + private static final int SIG_ATOMIC_MAX = (int)2147483647L; + /** + * {@snippet lang=c : + * #define SIG_ATOMIC_MAX 2147483647 + * } + */ + public static int SIG_ATOMIC_MAX() { + return SIG_ATOMIC_MAX; + } + private static final long SIZE_MAX = -1L; + /** + * {@snippet lang=c : + * #define SIZE_MAX -1 + * } + */ + public static long SIZE_MAX() { + return SIZE_MAX; + } + private static final int WCHAR_MIN = (int)-2147483648L; + /** + * {@snippet lang=c : + * #define WCHAR_MIN -2147483648 + * } + */ + public static int WCHAR_MIN() { + return WCHAR_MIN; + } + private static final int WCHAR_MAX = (int)2147483647L; + /** + * {@snippet lang=c : + * #define WCHAR_MAX 2147483647 + * } + */ + public static int WCHAR_MAX() { + return WCHAR_MAX; + } + private static final int WINT_MIN = (int)0L; + /** + * {@snippet lang=c : + * #define WINT_MIN 0 + * } + */ + public static int WINT_MIN() { + return WINT_MIN; + } + private static final int WINT_MAX = (int)4294967295L; + /** + * {@snippet lang=c : + * #define WINT_MAX 4294967295 + * } + */ + public static int WINT_MAX() { + return WINT_MAX; + } + private static final MemorySegment NULL = MemorySegment.ofAddress(0L); + /** + * {@snippet lang=c : + * #define NULL (void*) 0 + * } + */ + public static MemorySegment NULL() { + return NULL; + } + private static final long DLPACK_FLAG_BITMASK_READ_ONLY = 1L; + /** + * {@snippet lang=c : + * #define DLPACK_FLAG_BITMASK_READ_ONLY 1 + * } + */ + public static long DLPACK_FLAG_BITMASK_READ_ONLY() { + return DLPACK_FLAG_BITMASK_READ_ONLY; + } + private static final long DLPACK_FLAG_BITMASK_IS_COPIED = 2L; + /** + * {@snippet lang=c : + * #define DLPACK_FLAG_BITMASK_IS_COPIED 2 + * } + */ + public static long DLPACK_FLAG_BITMASK_IS_COPIED() { + return DLPACK_FLAG_BITMASK_IS_COPIED; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/Fsidt.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/Fsidt.java new file mode 100644 index 000000000..07f2849a5 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/Fsidt.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; +import static java.lang.foreign.MemoryLayout.PathElement.sequenceElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.SequenceLayout; +import java.lang.invoke.VarHandle; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct { + * int __val[2]; + * } + * } + */ +public class Fsidt { + + Fsidt() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout + .structLayout(MemoryLayout.sequenceLayout(2, CagraH.C_INT).withName("__val")).withName("$anon$155:12"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final SequenceLayout __val$LAYOUT = (SequenceLayout) $LAYOUT.select(groupElement("__val")); + + /** + * Layout for field: + * {@snippet lang = c : * int __val[2] + * } + */ + public static final SequenceLayout __val$layout() { + return __val$LAYOUT; + } + + private static final long __val$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * int __val[2] + * } + */ + public static final long __val$offset() { + return __val$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * int __val[2] + * } + */ + public static MemorySegment __val(MemorySegment struct) { + return struct.asSlice(__val$OFFSET, __val$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang = c : * int __val[2] + * } + */ + public static void __val(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, __val$OFFSET, __val$LAYOUT.byteSize()); + } + + private static long[] __val$DIMS = { 2 }; + + /** + * Dimensions for array field: + * {@snippet lang = c : * int __val[2] + * } + */ + public static long[] __val$dimensions() { + return __val$DIMS; + } + + private static final VarHandle __val$ELEM_HANDLE = __val$LAYOUT.varHandle(sequenceElement()); + + /** + * Indexed getter for field: + * {@snippet lang = c : * int __val[2] + * } + */ + public static int __val(MemorySegment struct, long index0) { + return (int) __val$ELEM_HANDLE.get(struct, 0L, index0); + } + + /** + * Indexed setter for field: + * {@snippet lang = c : * int __val[2] + * } + */ + public static void __val(MemorySegment struct, long index0, int fieldValue) { + __val$ELEM_HANDLE.set(struct, 0L, index0, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfo.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfo.java new file mode 100644 index 000000000..c1d13575c --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfo.java @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; +import static java.lang.foreign.MemoryLayout.PathElement.sequenceElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.ValueLayout.OfFloat; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.invoke.VarHandle; +import java.util.function.Consumer; + +/** + * {@snippet lang = c : + * struct gpuInfo { + * int gpu_id; + * char name[256]; + * long free_memory; + * long total_memory; + * float compute_capability; + * } + * } + */ +public class GpuInfo { + GpuInfo() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout(GpuInfoH.C_INT.withName("gpu_id"), + MemoryLayout.sequenceLayout(256, GpuInfoH.C_CHAR).withName("name"), MemoryLayout.paddingLayout(4), + GpuInfoH.C_LONG.withName("free_memory"), GpuInfoH.C_LONG.withName("total_memory"), + GpuInfoH.C_FLOAT.withName("compute_capability"), MemoryLayout.paddingLayout(4)).withName("gpuInfo"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt gpu_id$LAYOUT = (OfInt) $LAYOUT.select(groupElement("gpu_id")); + + /** + * Layout for field: + * {@snippet lang = c : * int gpu_id + * } + */ + public static final OfInt gpu_id$layout() { + return gpu_id$LAYOUT; + } + + private static final long gpu_id$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang = c : * int gpu_id + * } + */ + public static final long gpu_id$offset() { + return gpu_id$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * int gpu_id + * } + */ + public static int gpu_id(MemorySegment struct) { + return struct.get(gpu_id$LAYOUT, gpu_id$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * int gpu_id + * } + */ + public static void gpu_id(MemorySegment struct, int fieldValue) { + struct.set(gpu_id$LAYOUT, gpu_id$OFFSET, fieldValue); + } + + private static final SequenceLayout name$LAYOUT = (SequenceLayout) $LAYOUT.select(groupElement("name")); + + /** + * Layout for field: + * {@snippet lang = c : * char name[256] + * } + */ + public static final SequenceLayout name$layout() { + return name$LAYOUT; + } + + private static final long name$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang = c : * char name[256] + * } + */ + public static final long name$offset() { + return name$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * char name[256] + * } + */ + public static MemorySegment name(MemorySegment struct) { + return struct.asSlice(name$OFFSET, name$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang = c : * char name[256] + * } + */ + public static void name(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, name$OFFSET, name$LAYOUT.byteSize()); + } + + private static long[] name$DIMS = { 256 }; + + /** + * Dimensions for array field: + * {@snippet lang = c : * char name[256] + * } + */ + public static long[] name$dimensions() { + return name$DIMS; + } + + private static final VarHandle name$ELEM_HANDLE = name$LAYOUT.varHandle(sequenceElement()); + + /** + * Indexed getter for field: + * {@snippet lang = c : * char name[256] + * } + */ + public static byte name(MemorySegment struct, long index0) { + return (byte) name$ELEM_HANDLE.get(struct, 0L, index0); + } + + /** + * Indexed setter for field: + * {@snippet lang = c : * char name[256] + * } + */ + public static void name(MemorySegment struct, long index0, byte fieldValue) { + name$ELEM_HANDLE.set(struct, 0L, index0, fieldValue); + } + + private static final OfLong free_memory$LAYOUT = (OfLong) $LAYOUT.select(groupElement("free_memory")); + + /** + * Layout for field: + * {@snippet lang = c : * long free_memory + * } + */ + public static final OfLong free_memory$layout() { + return free_memory$LAYOUT; + } + + private static final long free_memory$OFFSET = 264; + + /** + * Offset for field: + * {@snippet lang = c : * long free_memory + * } + */ + public static final long free_memory$offset() { + return free_memory$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long free_memory + * } + */ + public static long free_memory(MemorySegment struct) { + return struct.get(free_memory$LAYOUT, free_memory$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long free_memory + * } + */ + public static void free_memory(MemorySegment struct, long fieldValue) { + struct.set(free_memory$LAYOUT, free_memory$OFFSET, fieldValue); + } + + private static final OfLong total_memory$LAYOUT = (OfLong) $LAYOUT.select(groupElement("total_memory")); + + /** + * Layout for field: + * {@snippet lang = c : * long total_memory + * } + */ + public static final OfLong total_memory$layout() { + return total_memory$LAYOUT; + } + + private static final long total_memory$OFFSET = 272; + + /** + * Offset for field: + * {@snippet lang = c : * long total_memory + * } + */ + public static final long total_memory$offset() { + return total_memory$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * long total_memory + * } + */ + public static long total_memory(MemorySegment struct) { + return struct.get(total_memory$LAYOUT, total_memory$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * long total_memory + * } + */ + public static void total_memory(MemorySegment struct, long fieldValue) { + struct.set(total_memory$LAYOUT, total_memory$OFFSET, fieldValue); + } + + private static final OfFloat compute_capability$LAYOUT = (OfFloat) $LAYOUT.select(groupElement("compute_capability")); + + /** + * Layout for field: + * {@snippet lang = c : * float compute_capability + * } + */ + public static final OfFloat compute_capability$layout() { + return compute_capability$LAYOUT; + } + + private static final long compute_capability$OFFSET = 280; + + /** + * Offset for field: + * {@snippet lang = c : * float compute_capability + * } + */ + public static final long compute_capability$offset() { + return compute_capability$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang = c : * float compute_capability + * } + */ + public static float compute_capability(MemorySegment struct) { + return struct.get(compute_capability$LAYOUT, compute_capability$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang = c : * float compute_capability + * } + */ + public static void compute_capability(MemorySegment struct, float fieldValue) { + struct.set(compute_capability$LAYOUT, compute_capability$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at + * {@code index}. The returned segment has address + * {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { + return layout().byteSize(); + } + + /** + * Allocate a segment of size {@code layout().byteSize()} using + * {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. The + * returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and + * {@code cleanupAction} (if any). The returned segment has size + * {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, + Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfoH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfoH.java new file mode 100644 index 000000000..ad37e37ec --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/GpuInfoH.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.stream.Collectors; + +public class GpuInfoH { + GpuInfoH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol).orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream().map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? MemoryLayout.structLayout(alignedMembers) + : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup()); + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/HnswH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/HnswH.java new file mode 100644 index 000000000..32945c432 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/HnswH.java @@ -0,0 +1,2350 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.foreign.ValueLayout.OfByte; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.foreign.ValueLayout.OfShort; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.stream.Collectors; + +public class HnswH { + + HnswH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol).orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream().map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? MemoryLayout.structLayout(alignedMembers) + : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int DLPACK_VERSION = (int) 80L; + + /** + * {@snippet lang = c : * #define DLPACK_VERSION 80 + * } + */ + public static int DLPACK_VERSION() { + return DLPACK_VERSION; + } + + private static final int DLPACK_ABI_VERSION = (int) 1L; + + /** + * {@snippet lang = c : * #define DLPACK_ABI_VERSION 1 + * } + */ + public static int DLPACK_ABI_VERSION() { + return DLPACK_ABI_VERSION; + } + + private static final int _STDINT_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDINT_H 1 + * } + */ + public static int _STDINT_H() { + return _STDINT_H; + } + + private static final int _FEATURES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _FEATURES_H 1 + * } + */ + public static int _FEATURES_H() { + return _FEATURES_H; + } + + private static final int _DEFAULT_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _DEFAULT_SOURCE 1 + * } + */ + public static int _DEFAULT_SOURCE() { + return _DEFAULT_SOURCE; + } + + private static final int __GLIBC_USE_ISOC2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_ISOC2X 0 + * } + */ + public static int __GLIBC_USE_ISOC2X() { + return __GLIBC_USE_ISOC2X; + } + + private static final int __USE_ISOC11 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC11 1 + * } + */ + public static int __USE_ISOC11() { + return __USE_ISOC11; + } + + private static final int __USE_ISOC99 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC99 1 + * } + */ + public static int __USE_ISOC99() { + return __USE_ISOC99; + } + + private static final int __USE_ISOC95 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC95 1 + * } + */ + public static int __USE_ISOC95() { + return __USE_ISOC95; + } + + private static final int __USE_POSIX_IMPLICITLY = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX_IMPLICITLY 1 + * } + */ + public static int __USE_POSIX_IMPLICITLY() { + return __USE_POSIX_IMPLICITLY; + } + + private static final int _POSIX_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _POSIX_SOURCE 1 + * } + */ + public static int _POSIX_SOURCE() { + return _POSIX_SOURCE; + } + + private static final int __USE_POSIX = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX 1 + * } + */ + public static int __USE_POSIX() { + return __USE_POSIX; + } + + private static final int __USE_POSIX2 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX2 1 + * } + */ + public static int __USE_POSIX2() { + return __USE_POSIX2; + } + + private static final int __USE_POSIX199309 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199309 1 + * } + */ + public static int __USE_POSIX199309() { + return __USE_POSIX199309; + } + + private static final int __USE_POSIX199506 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199506 1 + * } + */ + public static int __USE_POSIX199506() { + return __USE_POSIX199506; + } + + private static final int __USE_XOPEN2K = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K 1 + * } + */ + public static int __USE_XOPEN2K() { + return __USE_XOPEN2K; + } + + private static final int __USE_XOPEN2K8 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K8 1 + * } + */ + public static int __USE_XOPEN2K8() { + return __USE_XOPEN2K8; + } + + private static final int _ATFILE_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _ATFILE_SOURCE 1 + * } + */ + public static int _ATFILE_SOURCE() { + return _ATFILE_SOURCE; + } + + private static final int __WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __WORDSIZE 64 + * } + */ + public static int __WORDSIZE() { + return __WORDSIZE; + } + + private static final int __WORDSIZE_TIME64_COMPAT32 = (int) 1L; + + /** + * {@snippet lang = c : * #define __WORDSIZE_TIME64_COMPAT32 1 + * } + */ + public static int __WORDSIZE_TIME64_COMPAT32() { + return __WORDSIZE_TIME64_COMPAT32; + } + + private static final int __SYSCALL_WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __SYSCALL_WORDSIZE 64 + * } + */ + public static int __SYSCALL_WORDSIZE() { + return __SYSCALL_WORDSIZE; + } + + private static final int __USE_MISC = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_MISC 1 + * } + */ + public static int __USE_MISC() { + return __USE_MISC; + } + + private static final int __USE_ATFILE = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ATFILE 1 + * } + */ + public static int __USE_ATFILE() { + return __USE_ATFILE; + } + + private static final int __USE_FORTIFY_LEVEL = (int) 0L; + + /** + * {@snippet lang = c : * #define __USE_FORTIFY_LEVEL 0 + * } + */ + public static int __USE_FORTIFY_LEVEL() { + return __USE_FORTIFY_LEVEL; + } + + private static final int __GLIBC_USE_DEPRECATED_GETS = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_GETS 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_GETS() { + return __GLIBC_USE_DEPRECATED_GETS; + } + + private static final int __GLIBC_USE_DEPRECATED_SCANF = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_SCANF 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_SCANF() { + return __GLIBC_USE_DEPRECATED_SCANF; + } + + private static final int _STDC_PREDEF_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDC_PREDEF_H 1 + * } + */ + public static int _STDC_PREDEF_H() { + return _STDC_PREDEF_H; + } + + private static final int __STDC_IEC_559__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559__ 1 + * } + */ + public static int __STDC_IEC_559__() { + return __STDC_IEC_559__; + } + + private static final int __STDC_IEC_559_COMPLEX__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559_COMPLEX__ 1 + * } + */ + public static int __STDC_IEC_559_COMPLEX__() { + return __STDC_IEC_559_COMPLEX__; + } + + private static final int __GNU_LIBRARY__ = (int) 6L; + + /** + * {@snippet lang = c : * #define __GNU_LIBRARY__ 6 + * } + */ + public static int __GNU_LIBRARY__() { + return __GNU_LIBRARY__; + } + + private static final int __GLIBC__ = (int) 2L; + + /** + * {@snippet lang = c : * #define __GLIBC__ 2 + * } + */ + public static int __GLIBC__() { + return __GLIBC__; + } + + private static final int __GLIBC_MINOR__ = (int) 35L; + + /** + * {@snippet lang = c : * #define __GLIBC_MINOR__ 35 + * } + */ + public static int __GLIBC_MINOR__() { + return __GLIBC_MINOR__; + } + + private static final int _SYS_CDEFS_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _SYS_CDEFS_H 1 + * } + */ + public static int _SYS_CDEFS_H() { + return _SYS_CDEFS_H; + } + + private static final int __glibc_c99_flexarr_available = (int) 1L; + + /** + * {@snippet lang = c : * #define __glibc_c99_flexarr_available 1 + * } + */ + public static int __glibc_c99_flexarr_available() { + return __glibc_c99_flexarr_available; + } + + private static final int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = (int) 0L; + + /** + * {@snippet lang = c : * #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 + * } + */ + public static int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI() { + return __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI; + } + + private static final int __HAVE_GENERIC_SELECTION = (int) 1L; + + /** + * {@snippet lang = c : * #define __HAVE_GENERIC_SELECTION 1 + * } + */ + public static int __HAVE_GENERIC_SELECTION() { + return __HAVE_GENERIC_SELECTION; + } + + private static final int __GLIBC_USE_LIB_EXT2 = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_LIB_EXT2 0 + * } + */ + public static int __GLIBC_USE_LIB_EXT2() { + return __GLIBC_USE_LIB_EXT2; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT() { + return __GLIBC_USE_IEC_60559_BFP_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT_C2X() { + return __GLIBC_USE_IEC_60559_BFP_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_EXT() { + return __GLIBC_USE_IEC_60559_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_TYPES_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_TYPES_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_TYPES_EXT() { + return __GLIBC_USE_IEC_60559_TYPES_EXT; + } + + private static final int _BITS_TYPES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPES_H 1 + * } + */ + public static int _BITS_TYPES_H() { + return _BITS_TYPES_H; + } + + private static final int _BITS_TYPESIZES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPESIZES_H 1 + * } + */ + public static int _BITS_TYPESIZES_H() { + return _BITS_TYPESIZES_H; + } + + private static final int __OFF_T_MATCHES_OFF64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __OFF_T_MATCHES_OFF64_T 1 + * } + */ + public static int __OFF_T_MATCHES_OFF64_T() { + return __OFF_T_MATCHES_OFF64_T; + } + + private static final int __INO_T_MATCHES_INO64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __INO_T_MATCHES_INO64_T 1 + * } + */ + public static int __INO_T_MATCHES_INO64_T() { + return __INO_T_MATCHES_INO64_T; + } + + private static final int __RLIM_T_MATCHES_RLIM64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __RLIM_T_MATCHES_RLIM64_T 1 + * } + */ + public static int __RLIM_T_MATCHES_RLIM64_T() { + return __RLIM_T_MATCHES_RLIM64_T; + } + + private static final int __STATFS_MATCHES_STATFS64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __STATFS_MATCHES_STATFS64 1 + * } + */ + public static int __STATFS_MATCHES_STATFS64() { + return __STATFS_MATCHES_STATFS64; + } + + private static final int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 + * } + */ + public static int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64() { + return __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64; + } + + private static final int __FD_SETSIZE = (int) 1024L; + + /** + * {@snippet lang = c : * #define __FD_SETSIZE 1024 + * } + */ + public static int __FD_SETSIZE() { + return __FD_SETSIZE; + } + + private static final int _BITS_TIME64_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TIME64_H 1 + * } + */ + public static int _BITS_TIME64_H() { + return _BITS_TIME64_H; + } + + private static final int _BITS_WCHAR_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_WCHAR_H 1 + * } + */ + public static int _BITS_WCHAR_H() { + return _BITS_WCHAR_H; + } + + private static final int _BITS_STDINT_INTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_INTN_H 1 + * } + */ + public static int _BITS_STDINT_INTN_H() { + return _BITS_STDINT_INTN_H; + } + + private static final int _BITS_STDINT_UINTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_UINTN_H 1 + * } + */ + public static int _BITS_STDINT_UINTN_H() { + return _BITS_STDINT_UINTN_H; + } + + private static final int true_ = (int) 1L; + + /** + * {@snippet lang = c : * #define true 1 + * } + */ + public static int true_() { + return true_; + } + + private static final int false_ = (int) 0L; + + /** + * {@snippet lang = c : * #define false 0 + * } + */ + public static int false_() { + return false_; + } + + private static final int __bool_true_false_are_defined = (int) 1L; + + /** + * {@snippet lang = c : * #define __bool_true_false_are_defined 1 + * } + */ + public static int __bool_true_false_are_defined() { + return __bool_true_false_are_defined; + } + + private static final int L2Expanded = (int) 0L; + + /** + * {@snippet lang = c : * enum .L2Expanded = 0 + * } + */ + public static int L2Expanded() { + return L2Expanded; + } + + private static final int L2SqrtExpanded = (int) 1L; + + /** + * {@snippet lang = c : * enum .L2SqrtExpanded = 1 + * } + */ + public static int L2SqrtExpanded() { + return L2SqrtExpanded; + } + + private static final int CosineExpanded = (int) 2L; + + /** + * {@snippet lang = c : * enum .CosineExpanded = 2 + * } + */ + public static int CosineExpanded() { + return CosineExpanded; + } + + private static final int L1 = (int) 3L; + + /** + * {@snippet lang = c : * enum .L1 = 3 + * } + */ + public static int L1() { + return L1; + } + + private static final int L2Unexpanded = (int) 4L; + + /** + * {@snippet lang = c : * enum .L2Unexpanded = 4 + * } + */ + public static int L2Unexpanded() { + return L2Unexpanded; + } + + private static final int L2SqrtUnexpanded = (int) 5L; + + /** + * {@snippet lang = c : * enum .L2SqrtUnexpanded = 5 + * } + */ + public static int L2SqrtUnexpanded() { + return L2SqrtUnexpanded; + } + + private static final int InnerProduct = (int) 6L; + + /** + * {@snippet lang = c : * enum .InnerProduct = 6 + * } + */ + public static int InnerProduct() { + return InnerProduct; + } + + private static final int Linf = (int) 7L; + + /** + * {@snippet lang = c : * enum .Linf = 7 + * } + */ + public static int Linf() { + return Linf; + } + + private static final int Canberra = (int) 8L; + + /** + * {@snippet lang = c : * enum .Canberra = 8 + * } + */ + public static int Canberra() { + return Canberra; + } + + private static final int LpUnexpanded = (int) 9L; + + /** + * {@snippet lang = c : * enum .LpUnexpanded = 9 + * } + */ + public static int LpUnexpanded() { + return LpUnexpanded; + } + + private static final int CorrelationExpanded = (int) 10L; + + /** + * {@snippet lang = c : * enum .CorrelationExpanded = 10 + * } + */ + public static int CorrelationExpanded() { + return CorrelationExpanded; + } + + private static final int JaccardExpanded = (int) 11L; + + /** + * {@snippet lang = c : * enum .JaccardExpanded = 11 + * } + */ + public static int JaccardExpanded() { + return JaccardExpanded; + } + + private static final int HellingerExpanded = (int) 12L; + + /** + * {@snippet lang = c : * enum .HellingerExpanded = 12 + * } + */ + public static int HellingerExpanded() { + return HellingerExpanded; + } + + private static final int Haversine = (int) 13L; + + /** + * {@snippet lang = c : * enum .Haversine = 13 + * } + */ + public static int Haversine() { + return Haversine; + } + + private static final int BrayCurtis = (int) 14L; + + /** + * {@snippet lang = c : * enum .BrayCurtis = 14 + * } + */ + public static int BrayCurtis() { + return BrayCurtis; + } + + private static final int JensenShannon = (int) 15L; + + /** + * {@snippet lang = c : * enum .JensenShannon = 15 + * } + */ + public static int JensenShannon() { + return JensenShannon; + } + + private static final int HammingUnexpanded = (int) 16L; + + /** + * {@snippet lang = c : * enum .HammingUnexpanded = 16 + * } + */ + public static int HammingUnexpanded() { + return HammingUnexpanded; + } + + private static final int KLDivergence = (int) 17L; + + /** + * {@snippet lang = c : * enum .KLDivergence = 17 + * } + */ + public static int KLDivergence() { + return KLDivergence; + } + + private static final int RusselRaoExpanded = (int) 18L; + + /** + * {@snippet lang = c : * enum .RusselRaoExpanded = 18 + * } + */ + public static int RusselRaoExpanded() { + return RusselRaoExpanded; + } + + private static final int DiceExpanded = (int) 19L; + + /** + * {@snippet lang = c : * enum .DiceExpanded = 19 + * } + */ + public static int DiceExpanded() { + return DiceExpanded; + } + + private static final int Precomputed = (int) 100L; + + /** + * {@snippet lang = c : * enum .Precomputed = 100 + * } + */ + public static int Precomputed() { + return Precomputed; + } + + /** + * {@snippet lang = c : * typedef unsigned char __u_char + * } + */ + public static final OfByte __u_char = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned short __u_short + * } + */ + public static final OfShort __u_short = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned int __u_int + * } + */ + public static final OfInt __u_int = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __u_long + * } + */ + public static final OfLong __u_long = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char __int8_t + * } + */ + public static final OfByte __int8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned char __uint8_t + * } + */ + public static final OfByte __uint8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef short __int16_t + * } + */ + public static final OfShort __int16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned short __uint16_t + * } + */ + public static final OfShort __uint16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef int __int32_t + * } + */ + public static final OfInt __int32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __uint32_t + * } + */ + public static final OfInt __uint32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef long __int64_t + * } + */ + public static final OfLong __int64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uint64_t + * } + */ + public static final OfLong __uint64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __int8_t __int_least8_t + * } + */ + public static final OfByte __int_least8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint8_t __uint_least8_t + * } + */ + public static final OfByte __uint_least8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t __int_least16_t + * } + */ + public static final OfShort __int_least16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint16_t __uint_least16_t + * } + */ + public static final OfShort __uint_least16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t __int_least32_t + * } + */ + public static final OfInt __int_least32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef __uint32_t __uint_least32_t + * } + */ + public static final OfInt __uint_least32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t __int_least64_t + * } + */ + public static final OfLong __int_least64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint64_t __uint_least64_t + * } + */ + public static final OfLong __uint_least64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __quad_t + * } + */ + public static final OfLong __quad_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __u_quad_t + * } + */ + public static final OfLong __u_quad_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __intmax_t + * } + */ + public static final OfLong __intmax_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uintmax_t + * } + */ + public static final OfLong __uintmax_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __dev_t + * } + */ + public static final OfLong __dev_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __uid_t + * } + */ + public static final OfInt __uid_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __gid_t + * } + */ + public static final OfInt __gid_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __ino_t + * } + */ + public static final OfLong __ino_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __ino64_t + * } + */ + public static final OfLong __ino64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __mode_t + * } + */ + public static final OfInt __mode_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __nlink_t + * } + */ + public static final OfLong __nlink_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off_t + * } + */ + public static final OfLong __off_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off64_t + * } + */ + public static final OfLong __off64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef int __pid_t + * } + */ + public static final OfInt __pid_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef long __clock_t + * } + */ + public static final OfLong __clock_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim_t + * } + */ + public static final OfLong __rlim_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim64_t + * } + */ + public static final OfLong __rlim64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __id_t + * } + */ + public static final OfInt __id_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef long __time_t + * } + */ + public static final OfLong __time_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __useconds_t + * } + */ + public static final OfInt __useconds_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef long __suseconds_t + * } + */ + public static final OfLong __suseconds_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __suseconds64_t + * } + */ + public static final OfLong __suseconds64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef int __daddr_t + * } + */ + public static final OfInt __daddr_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef int __key_t + * } + */ + public static final OfInt __key_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef int __clockid_t + * } + */ + public static final OfInt __clockid_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef void *__timer_t + * } + */ + public static final AddressLayout __timer_t = HnswH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __blksize_t + * } + */ + public static final OfLong __blksize_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt_t + * } + */ + public static final OfLong __blkcnt_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt64_t + * } + */ + public static final OfLong __blkcnt64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt_t + * } + */ + public static final OfLong __fsblkcnt_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt64_t + * } + */ + public static final OfLong __fsblkcnt64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt_t + * } + */ + public static final OfLong __fsfilcnt_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt64_t + * } + */ + public static final OfLong __fsfilcnt64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __fsword_t + * } + */ + public static final OfLong __fsword_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __ssize_t + * } + */ + public static final OfLong __ssize_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long __syscall_slong_t + * } + */ + public static final OfLong __syscall_slong_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __syscall_ulong_t + * } + */ + public static final OfLong __syscall_ulong_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __off64_t __loff_t + * } + */ + public static final OfLong __loff_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef char *__caddr_t + * } + */ + public static final AddressLayout __caddr_t = HnswH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __intptr_t + * } + */ + public static final OfLong __intptr_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __socklen_t + * } + */ + public static final OfInt __socklen_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef int __sig_atomic_t + * } + */ + public static final OfInt __sig_atomic_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef __int8_t int8_t + * } + */ + public static final OfByte int8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t int16_t + * } + */ + public static final OfShort int16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t int32_t + * } + */ + public static final OfInt int32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t int64_t + * } + */ + public static final OfLong int64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint8_t uint8_t + * } + */ + public static final OfByte uint8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint16_t uint16_t + * } + */ + public static final OfShort uint16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint32_t uint32_t + * } + */ + public static final OfInt uint32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef __uint64_t uint64_t + * } + */ + public static final OfLong uint64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __int_least8_t int_least8_t + * } + */ + public static final OfByte int_least8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int_least16_t int_least16_t + * } + */ + public static final OfShort int_least16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int_least32_t int_least32_t + * } + */ + public static final OfInt int_least32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef __int_least64_t int_least64_t + * } + */ + public static final OfLong int_least64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint_least8_t uint_least8_t + * } + */ + public static final OfByte uint_least8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint_least16_t uint_least16_t + * } + */ + public static final OfShort uint_least16_t = HnswH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint_least32_t uint_least32_t + * } + */ + public static final OfInt uint_least32_t = HnswH.C_INT; + /** + * {@snippet lang = c : * typedef __uint_least64_t uint_least64_t + * } + */ + public static final OfLong uint_least64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char int_fast8_t + * } + */ + public static final OfByte int_fast8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef long int_fast16_t + * } + */ + public static final OfLong int_fast16_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast32_t + * } + */ + public static final OfLong int_fast32_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast64_t + * } + */ + public static final OfLong int_fast64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned char uint_fast8_t + * } + */ + public static final OfByte uint_fast8_t = HnswH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast16_t + * } + */ + public static final OfLong uint_fast16_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast32_t + * } + */ + public static final OfLong uint_fast32_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast64_t + * } + */ + public static final OfLong uint_fast64_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long intptr_t + * } + */ + public static final OfLong intptr_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uintptr_t + * } + */ + public static final OfLong uintptr_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __intmax_t intmax_t + * } + */ + public static final OfLong intmax_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef __uintmax_t uintmax_t + * } + */ + public static final OfLong uintmax_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef long ptrdiff_t + * } + */ + public static final OfLong ptrdiff_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long size_t + * } + */ + public static final OfLong size_t = HnswH.C_LONG; + /** + * {@snippet lang = c : * typedef int wchar_t + * } + */ + public static final OfInt wchar_t = HnswH.C_INT; + private static final int kDLCPU = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLCPU = 1 + * } + */ + public static int kDLCPU() { + return kDLCPU; + } + + private static final int kDLCUDA = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLCUDA = 2 + * } + */ + public static int kDLCUDA() { + return kDLCUDA; + } + + private static final int kDLCUDAHost = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLCUDAHost = 3 + * } + */ + public static int kDLCUDAHost() { + return kDLCUDAHost; + } + + private static final int kDLOpenCL = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLOpenCL = 4 + * } + */ + public static int kDLOpenCL() { + return kDLOpenCL; + } + + private static final int kDLVulkan = (int) 7L; + + /** + * {@snippet lang = c : * enum .kDLVulkan = 7 + * } + */ + public static int kDLVulkan() { + return kDLVulkan; + } + + private static final int kDLMetal = (int) 8L; + + /** + * {@snippet lang = c : * enum .kDLMetal = 8 + * } + */ + public static int kDLMetal() { + return kDLMetal; + } + + private static final int kDLVPI = (int) 9L; + + /** + * {@snippet lang = c : * enum .kDLVPI = 9 + * } + */ + public static int kDLVPI() { + return kDLVPI; + } + + private static final int kDLROCM = (int) 10L; + + /** + * {@snippet lang = c : * enum .kDLROCM = 10 + * } + */ + public static int kDLROCM() { + return kDLROCM; + } + + private static final int kDLROCMHost = (int) 11L; + + /** + * {@snippet lang = c : * enum .kDLROCMHost = 11 + * } + */ + public static int kDLROCMHost() { + return kDLROCMHost; + } + + private static final int kDLExtDev = (int) 12L; + + /** + * {@snippet lang = c : * enum .kDLExtDev = 12 + * } + */ + public static int kDLExtDev() { + return kDLExtDev; + } + + private static final int kDLCUDAManaged = (int) 13L; + + /** + * {@snippet lang = c : * enum .kDLCUDAManaged = 13 + * } + */ + public static int kDLCUDAManaged() { + return kDLCUDAManaged; + } + + private static final int kDLOneAPI = (int) 14L; + + /** + * {@snippet lang = c : * enum .kDLOneAPI = 14 + * } + */ + public static int kDLOneAPI() { + return kDLOneAPI; + } + + private static final int kDLWebGPU = (int) 15L; + + /** + * {@snippet lang = c : * enum .kDLWebGPU = 15 + * } + */ + public static int kDLWebGPU() { + return kDLWebGPU; + } + + private static final int kDLHexagon = (int) 16L; + + /** + * {@snippet lang = c : * enum .kDLHexagon = 16 + * } + */ + public static int kDLHexagon() { + return kDLHexagon; + } + + private static final int kDLInt = (int) 0L; + + /** + * {@snippet lang = c : * enum .kDLInt = 0 + * } + */ + public static int kDLInt() { + return kDLInt; + } + + private static final int kDLUInt = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLUInt = 1 + * } + */ + public static int kDLUInt() { + return kDLUInt; + } + + private static final int kDLFloat = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLFloat = 2 + * } + */ + public static int kDLFloat() { + return kDLFloat; + } + + private static final int kDLOpaqueHandle = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLOpaqueHandle = 3 + * } + */ + public static int kDLOpaqueHandle() { + return kDLOpaqueHandle; + } + + private static final int kDLBfloat = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLBfloat = 4 + * } + */ + public static int kDLBfloat() { + return kDLBfloat; + } + + private static final int kDLComplex = (int) 5L; + + /** + * {@snippet lang = c : * enum .kDLComplex = 5 + * } + */ + public static int kDLComplex() { + return kDLComplex; + } + + private static final int kDLBool = (int) 6L; + + /** + * {@snippet lang = c : * enum .kDLBool = 6 + * } + */ + public static int kDLBool() { + return kDLBool; + } + + private static final int AUTO_SELECT = (int) 0L; + + /** + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo.AUTO_SELECT = 0 + * } + */ + public static int AUTO_SELECT() { + return AUTO_SELECT; + } + + private static final int IVF_PQ = (int) 1L; + + /** + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo.IVF_PQ = 1 + * } + */ + public static int IVF_PQ() { + return IVF_PQ; + } + + private static final int NN_DESCENT = (int) 2L; + + /** + * {@snippet lang = c : * enum cuvsCagraGraphBuildAlgo.NN_DESCENT = 2 + * } + */ + public static int NN_DESCENT() { + return NN_DESCENT; + } + + /** + * {@snippet lang = c : + * typedef struct cuvsCagraCompressionParams { + * uint32_t pq_bits; + * uint32_t pq_dim; + * uint32_t vq_n_centers; + * uint32_t kmeans_n_iters; + * double vq_kmeans_trainset_fraction; + * double pq_kmeans_trainset_fraction; + * } *cuvsCagraCompressionParams_t + * } + */ + public static final AddressLayout cuvsCagraCompressionParams_t = HnswH.C_POINTER; + /** + * {@snippet lang = c : + * typedef struct cuvsCagraIndexParams { + * cuvsDistanceType metric; + * long intermediate_graph_degree; + * long graph_degree; + * enum cuvsCagraGraphBuildAlgo build_algo; + * long nn_descent_niter; + * cuvsCagraCompressionParams_t compression; + * } *cuvsCagraIndexParams_t + * } + */ + public static final AddressLayout cuvsCagraIndexParams_t = HnswH.C_POINTER; + private static final int SINGLE_CTA = (int) 0L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.SINGLE_CTA = 0 + * } + */ + public static int SINGLE_CTA() { + return SINGLE_CTA; + } + + private static final int MULTI_CTA = (int) 1L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.MULTI_CTA = 1 + * } + */ + public static int MULTI_CTA() { + return MULTI_CTA; + } + + private static final int MULTI_KERNEL = (int) 2L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.MULTI_KERNEL = 2 + * } + */ + public static int MULTI_KERNEL() { + return MULTI_KERNEL; + } + + private static final int AUTO = (int) 3L; + + /** + * {@snippet lang = c : * enum cuvsCagraSearchAlgo.AUTO = 3 + * } + */ + public static int AUTO() { + return AUTO; + } + + private static final int HASH = (int) 0L; + + /** + * {@snippet lang = c : * enum cuvsCagraHashMode.HASH = 0 + * } + */ + public static int HASH() { + return HASH; + } + + private static final int SMALL = (int) 1L; + + /** + * {@snippet lang = c : * enum cuvsCagraHashMode.SMALL = 1 + * } + */ + public static int SMALL() { + return SMALL; + } + + private static final int AUTO_HASH = (int) 2L; + + /** + * {@snippet lang = c : * enum cuvsCagraHashMode.AUTO_HASH = 2 + * } + */ + public static int AUTO_HASH() { + return AUTO_HASH; + } + + /** + * {@snippet lang = c : + * typedef struct cuvsCagraSearchParams { + * long max_queries; + * long itopk_size; + * long max_iterations; + * enum cuvsCagraSearchAlgo algo; + * long team_size; + * long search_width; + * long min_iterations; + * long thread_block_size; + * enum cuvsCagraHashMode hashmap_mode; + * long hashmap_min_bitlen; + * float hashmap_max_fill_rate; + * uint32_t num_random_samplings; + * uint64_t rand_xor_mask; + * } *cuvsCagraSearchParams_t + * } + */ + public static final AddressLayout cuvsCagraSearchParams_t = HnswH.C_POINTER; + /** + * {@snippet lang = c : * typedef cuvsCagraIndex *cuvsCagraIndex_t + * } + */ + public static final AddressLayout cuvsCagraIndex_t = HnswH.C_POINTER; + private static final int NONE = (int) 0L; + + /** + * {@snippet lang = c : * enum cuvsHnswHierarchy.NONE = 0 + * } + */ + public static int NONE() { + return NONE; + } + + private static final int CPU = (int) 1L; + + /** + * {@snippet lang = c : * enum cuvsHnswHierarchy.CPU = 1 + * } + */ + public static int CPU() { + return CPU; + } + + /** + * {@snippet lang = c : + * typedef struct cuvsHnswIndexParams { + * cuvsHnswHierarchy hierarchy; + * int ef_construction; + * int num_threads; + * } *cuvsHnswIndexParams_t + * } + */ + public static final AddressLayout cuvsHnswIndexParams_t = HnswH.C_POINTER; + /** + * {@snippet lang = c : * typedef cuvsHnswIndex *cuvsHnswIndex_t + * } + */ + public static final AddressLayout cuvsHnswIndex_t = HnswH.C_POINTER; + /** + * {@snippet lang = c : + * typedef struct cuvsHnswExtendParams { + * int num_threads; + * } *cuvsHnswExtendParams_t + * } + */ + public static final AddressLayout cuvsHnswExtendParams_t = HnswH.C_POINTER; + /** + * {@snippet lang = c : + * typedef struct cuvsHnswSearchParams { + * int32_t ef; + * int32_t num_threads; + * } *cuvsHnswSearchParams_t + * } + */ + public static final AddressLayout cuvsHnswSearchParams_t = HnswH.C_POINTER; + private static final long _POSIX_C_SOURCE = 200809L; + + /** + * {@snippet lang = c : * #define _POSIX_C_SOURCE 200809 + * } + */ + public static long _POSIX_C_SOURCE() { + return _POSIX_C_SOURCE; + } + + private static final int __TIMESIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __TIMESIZE 64 + * } + */ + public static int __TIMESIZE() { + return __TIMESIZE; + } + + private static final long __STDC_IEC_60559_BFP__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_BFP__ 201404 + * } + */ + public static long __STDC_IEC_60559_BFP__() { + return __STDC_IEC_60559_BFP__; + } + + private static final long __STDC_IEC_60559_COMPLEX__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_COMPLEX__ 201404 + * } + */ + public static long __STDC_IEC_60559_COMPLEX__() { + return __STDC_IEC_60559_COMPLEX__; + } + + private static final long __STDC_ISO_10646__ = 201706L; + + /** + * {@snippet lang = c : * #define __STDC_ISO_10646__ 201706 + * } + */ + public static long __STDC_ISO_10646__() { + return __STDC_ISO_10646__; + } + + private static final int __WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define __WCHAR_MAX 2147483647 + * } + */ + public static int __WCHAR_MAX() { + return __WCHAR_MAX; + } + + private static final int __WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define __WCHAR_MIN -2147483648 + * } + */ + public static int __WCHAR_MIN() { + return __WCHAR_MIN; + } + + private static final int INT8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT8_MIN -128 + * } + */ + public static int INT8_MIN() { + return INT8_MIN; + } + + private static final int INT16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT16_MIN -32768 + * } + */ + public static int INT16_MIN() { + return INT16_MIN; + } + + private static final int INT32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT32_MIN -2147483648 + * } + */ + public static int INT32_MIN() { + return INT32_MIN; + } + + private static final long INT64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT64_MIN -9223372036854775808 + * } + */ + public static long INT64_MIN() { + return INT64_MIN; + } + + private static final int INT8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT8_MAX 127 + * } + */ + public static int INT8_MAX() { + return INT8_MAX; + } + + private static final int INT16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT16_MAX 32767 + * } + */ + public static int INT16_MAX() { + return INT16_MAX; + } + + private static final int INT32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT32_MAX 2147483647 + * } + */ + public static int INT32_MAX() { + return INT32_MAX; + } + + private static final long INT64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT64_MAX 9223372036854775807 + * } + */ + public static long INT64_MAX() { + return INT64_MAX; + } + + private static final int UINT8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT8_MAX 255 + * } + */ + public static int UINT8_MAX() { + return UINT8_MAX; + } + + private static final int UINT16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT16_MAX 65535 + * } + */ + public static int UINT16_MAX() { + return UINT16_MAX; + } + + private static final int UINT32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT32_MAX 4294967295 + * } + */ + public static int UINT32_MAX() { + return UINT32_MAX; + } + + private static final long UINT64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT64_MAX -1 + * } + */ + public static long UINT64_MAX() { + return UINT64_MAX; + } + + private static final int INT_LEAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MIN -128 + * } + */ + public static int INT_LEAST8_MIN() { + return INT_LEAST8_MIN; + } + + private static final int INT_LEAST16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MIN -32768 + * } + */ + public static int INT_LEAST16_MIN() { + return INT_LEAST16_MIN; + } + + private static final int INT_LEAST32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MIN -2147483648 + * } + */ + public static int INT_LEAST32_MIN() { + return INT_LEAST32_MIN; + } + + private static final long INT_LEAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MIN -9223372036854775808 + * } + */ + public static long INT_LEAST64_MIN() { + return INT_LEAST64_MIN; + } + + private static final int INT_LEAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MAX 127 + * } + */ + public static int INT_LEAST8_MAX() { + return INT_LEAST8_MAX; + } + + private static final int INT_LEAST16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MAX 32767 + * } + */ + public static int INT_LEAST16_MAX() { + return INT_LEAST16_MAX; + } + + private static final int INT_LEAST32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MAX 2147483647 + * } + */ + public static int INT_LEAST32_MAX() { + return INT_LEAST32_MAX; + } + + private static final long INT_LEAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MAX 9223372036854775807 + * } + */ + public static long INT_LEAST64_MAX() { + return INT_LEAST64_MAX; + } + + private static final int UINT_LEAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_LEAST8_MAX 255 + * } + */ + public static int UINT_LEAST8_MAX() { + return UINT_LEAST8_MAX; + } + + private static final int UINT_LEAST16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT_LEAST16_MAX 65535 + * } + */ + public static int UINT_LEAST16_MAX() { + return UINT_LEAST16_MAX; + } + + private static final int UINT_LEAST32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT_LEAST32_MAX 4294967295 + * } + */ + public static int UINT_LEAST32_MAX() { + return UINT_LEAST32_MAX; + } + + private static final long UINT_LEAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_LEAST64_MAX -1 + * } + */ + public static long UINT_LEAST64_MAX() { + return UINT_LEAST64_MAX; + } + + private static final int INT_FAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MIN -128 + * } + */ + public static int INT_FAST8_MIN() { + return INT_FAST8_MIN; + } + + private static final long INT_FAST16_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MIN -9223372036854775808 + * } + */ + public static long INT_FAST16_MIN() { + return INT_FAST16_MIN; + } + + private static final long INT_FAST32_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MIN -9223372036854775808 + * } + */ + public static long INT_FAST32_MIN() { + return INT_FAST32_MIN; + } + + private static final long INT_FAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MIN -9223372036854775808 + * } + */ + public static long INT_FAST64_MIN() { + return INT_FAST64_MIN; + } + + private static final int INT_FAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MAX 127 + * } + */ + public static int INT_FAST8_MAX() { + return INT_FAST8_MAX; + } + + private static final long INT_FAST16_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MAX 9223372036854775807 + * } + */ + public static long INT_FAST16_MAX() { + return INT_FAST16_MAX; + } + + private static final long INT_FAST32_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MAX 9223372036854775807 + * } + */ + public static long INT_FAST32_MAX() { + return INT_FAST32_MAX; + } + + private static final long INT_FAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MAX 9223372036854775807 + * } + */ + public static long INT_FAST64_MAX() { + return INT_FAST64_MAX; + } + + private static final int UINT_FAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_FAST8_MAX 255 + * } + */ + public static int UINT_FAST8_MAX() { + return UINT_FAST8_MAX; + } + + private static final long UINT_FAST16_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST16_MAX -1 + * } + */ + public static long UINT_FAST16_MAX() { + return UINT_FAST16_MAX; + } + + private static final long UINT_FAST32_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST32_MAX -1 + * } + */ + public static long UINT_FAST32_MAX() { + return UINT_FAST32_MAX; + } + + private static final long UINT_FAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST64_MAX -1 + * } + */ + public static long UINT_FAST64_MAX() { + return UINT_FAST64_MAX; + } + + private static final long INTPTR_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTPTR_MIN -9223372036854775808 + * } + */ + public static long INTPTR_MIN() { + return INTPTR_MIN; + } + + private static final long INTPTR_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTPTR_MAX 9223372036854775807 + * } + */ + public static long INTPTR_MAX() { + return INTPTR_MAX; + } + + private static final long UINTPTR_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTPTR_MAX -1 + * } + */ + public static long UINTPTR_MAX() { + return UINTPTR_MAX; + } + + private static final long INTMAX_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTMAX_MIN -9223372036854775808 + * } + */ + public static long INTMAX_MIN() { + return INTMAX_MIN; + } + + private static final long INTMAX_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTMAX_MAX 9223372036854775807 + * } + */ + public static long INTMAX_MAX() { + return INTMAX_MAX; + } + + private static final long UINTMAX_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTMAX_MAX -1 + * } + */ + public static long UINTMAX_MAX() { + return UINTMAX_MAX; + } + + private static final long PTRDIFF_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MIN -9223372036854775808 + * } + */ + public static long PTRDIFF_MIN() { + return PTRDIFF_MIN; + } + + private static final long PTRDIFF_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MAX 9223372036854775807 + * } + */ + public static long PTRDIFF_MAX() { + return PTRDIFF_MAX; + } + + private static final int SIG_ATOMIC_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MIN -2147483648 + * } + */ + public static int SIG_ATOMIC_MIN() { + return SIG_ATOMIC_MIN; + } + + private static final int SIG_ATOMIC_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MAX 2147483647 + * } + */ + public static int SIG_ATOMIC_MAX() { + return SIG_ATOMIC_MAX; + } + + private static final long SIZE_MAX = -1L; + + /** + * {@snippet lang = c : * #define SIZE_MAX -1 + * } + */ + public static long SIZE_MAX() { + return SIZE_MAX; + } + + private static final int WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define WCHAR_MIN -2147483648 + * } + */ + public static int WCHAR_MIN() { + return WCHAR_MIN; + } + + private static final int WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define WCHAR_MAX 2147483647 + * } + */ + public static int WCHAR_MAX() { + return WCHAR_MAX; + } + + private static final int WINT_MIN = (int) 0L; + + /** + * {@snippet lang = c : * #define WINT_MIN 0 + * } + */ + public static int WINT_MIN() { + return WINT_MIN; + } + + private static final int WINT_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define WINT_MAX 4294967295 + * } + */ + public static int WINT_MAX() { + return WINT_MAX; + } + + private static final MemorySegment NULL = MemorySegment.ofAddress(0L); + + /** + * {@snippet lang = c : * #define NULL (void*) 0 + * } + */ + public static MemorySegment NULL() { + return NULL; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfFlatH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfFlatH.java new file mode 100644 index 000000000..47353cc9e --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfFlatH.java @@ -0,0 +1,2845 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.foreign.ValueLayout.OfByte; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.foreign.ValueLayout.OfShort; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.stream.Collectors; + +public class IvfFlatH { + + IvfFlatH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol).orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream().map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? MemoryLayout.structLayout(alignedMembers) + : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int _STDINT_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDINT_H 1 + * } + */ + public static int _STDINT_H() { + return _STDINT_H; + } + + private static final int _FEATURES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _FEATURES_H 1 + * } + */ + public static int _FEATURES_H() { + return _FEATURES_H; + } + + private static final int _DEFAULT_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _DEFAULT_SOURCE 1 + * } + */ + public static int _DEFAULT_SOURCE() { + return _DEFAULT_SOURCE; + } + + private static final int __GLIBC_USE_ISOC2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_ISOC2X 0 + * } + */ + public static int __GLIBC_USE_ISOC2X() { + return __GLIBC_USE_ISOC2X; + } + + private static final int __USE_ISOC11 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC11 1 + * } + */ + public static int __USE_ISOC11() { + return __USE_ISOC11; + } + + private static final int __USE_ISOC99 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC99 1 + * } + */ + public static int __USE_ISOC99() { + return __USE_ISOC99; + } + + private static final int __USE_ISOC95 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC95 1 + * } + */ + public static int __USE_ISOC95() { + return __USE_ISOC95; + } + + private static final int __USE_POSIX_IMPLICITLY = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX_IMPLICITLY 1 + * } + */ + public static int __USE_POSIX_IMPLICITLY() { + return __USE_POSIX_IMPLICITLY; + } + + private static final int _POSIX_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _POSIX_SOURCE 1 + * } + */ + public static int _POSIX_SOURCE() { + return _POSIX_SOURCE; + } + + private static final int __USE_POSIX = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX 1 + * } + */ + public static int __USE_POSIX() { + return __USE_POSIX; + } + + private static final int __USE_POSIX2 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX2 1 + * } + */ + public static int __USE_POSIX2() { + return __USE_POSIX2; + } + + private static final int __USE_POSIX199309 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199309 1 + * } + */ + public static int __USE_POSIX199309() { + return __USE_POSIX199309; + } + + private static final int __USE_POSIX199506 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199506 1 + * } + */ + public static int __USE_POSIX199506() { + return __USE_POSIX199506; + } + + private static final int __USE_XOPEN2K = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K 1 + * } + */ + public static int __USE_XOPEN2K() { + return __USE_XOPEN2K; + } + + private static final int __USE_XOPEN2K8 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K8 1 + * } + */ + public static int __USE_XOPEN2K8() { + return __USE_XOPEN2K8; + } + + private static final int _ATFILE_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _ATFILE_SOURCE 1 + * } + */ + public static int _ATFILE_SOURCE() { + return _ATFILE_SOURCE; + } + + private static final int __WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __WORDSIZE 64 + * } + */ + public static int __WORDSIZE() { + return __WORDSIZE; + } + + private static final int __WORDSIZE_TIME64_COMPAT32 = (int) 1L; + + /** + * {@snippet lang = c : * #define __WORDSIZE_TIME64_COMPAT32 1 + * } + */ + public static int __WORDSIZE_TIME64_COMPAT32() { + return __WORDSIZE_TIME64_COMPAT32; + } + + private static final int __SYSCALL_WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __SYSCALL_WORDSIZE 64 + * } + */ + public static int __SYSCALL_WORDSIZE() { + return __SYSCALL_WORDSIZE; + } + + private static final int __USE_MISC = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_MISC 1 + * } + */ + public static int __USE_MISC() { + return __USE_MISC; + } + + private static final int __USE_ATFILE = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ATFILE 1 + * } + */ + public static int __USE_ATFILE() { + return __USE_ATFILE; + } + + private static final int __USE_FORTIFY_LEVEL = (int) 0L; + + /** + * {@snippet lang = c : * #define __USE_FORTIFY_LEVEL 0 + * } + */ + public static int __USE_FORTIFY_LEVEL() { + return __USE_FORTIFY_LEVEL; + } + + private static final int __GLIBC_USE_DEPRECATED_GETS = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_GETS 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_GETS() { + return __GLIBC_USE_DEPRECATED_GETS; + } + + private static final int __GLIBC_USE_DEPRECATED_SCANF = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_SCANF 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_SCANF() { + return __GLIBC_USE_DEPRECATED_SCANF; + } + + private static final int _STDC_PREDEF_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDC_PREDEF_H 1 + * } + */ + public static int _STDC_PREDEF_H() { + return _STDC_PREDEF_H; + } + + private static final int __STDC_IEC_559__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559__ 1 + * } + */ + public static int __STDC_IEC_559__() { + return __STDC_IEC_559__; + } + + private static final int __STDC_IEC_559_COMPLEX__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559_COMPLEX__ 1 + * } + */ + public static int __STDC_IEC_559_COMPLEX__() { + return __STDC_IEC_559_COMPLEX__; + } + + private static final int __GNU_LIBRARY__ = (int) 6L; + + /** + * {@snippet lang = c : * #define __GNU_LIBRARY__ 6 + * } + */ + public static int __GNU_LIBRARY__() { + return __GNU_LIBRARY__; + } + + private static final int __GLIBC__ = (int) 2L; + + /** + * {@snippet lang = c : * #define __GLIBC__ 2 + * } + */ + public static int __GLIBC__() { + return __GLIBC__; + } + + private static final int __GLIBC_MINOR__ = (int) 35L; + + /** + * {@snippet lang = c : * #define __GLIBC_MINOR__ 35 + * } + */ + public static int __GLIBC_MINOR__() { + return __GLIBC_MINOR__; + } + + private static final int _SYS_CDEFS_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _SYS_CDEFS_H 1 + * } + */ + public static int _SYS_CDEFS_H() { + return _SYS_CDEFS_H; + } + + private static final int __glibc_c99_flexarr_available = (int) 1L; + + /** + * {@snippet lang = c : * #define __glibc_c99_flexarr_available 1 + * } + */ + public static int __glibc_c99_flexarr_available() { + return __glibc_c99_flexarr_available; + } + + private static final int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = (int) 0L; + + /** + * {@snippet lang = c : * #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 + * } + */ + public static int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI() { + return __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI; + } + + private static final int __HAVE_GENERIC_SELECTION = (int) 1L; + + /** + * {@snippet lang = c : * #define __HAVE_GENERIC_SELECTION 1 + * } + */ + public static int __HAVE_GENERIC_SELECTION() { + return __HAVE_GENERIC_SELECTION; + } + + private static final int __GLIBC_USE_LIB_EXT2 = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_LIB_EXT2 0 + * } + */ + public static int __GLIBC_USE_LIB_EXT2() { + return __GLIBC_USE_LIB_EXT2; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT() { + return __GLIBC_USE_IEC_60559_BFP_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT_C2X() { + return __GLIBC_USE_IEC_60559_BFP_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_EXT() { + return __GLIBC_USE_IEC_60559_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_TYPES_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_TYPES_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_TYPES_EXT() { + return __GLIBC_USE_IEC_60559_TYPES_EXT; + } + + private static final int _BITS_TYPES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPES_H 1 + * } + */ + public static int _BITS_TYPES_H() { + return _BITS_TYPES_H; + } + + private static final int _BITS_TYPESIZES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPESIZES_H 1 + * } + */ + public static int _BITS_TYPESIZES_H() { + return _BITS_TYPESIZES_H; + } + + private static final int __OFF_T_MATCHES_OFF64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __OFF_T_MATCHES_OFF64_T 1 + * } + */ + public static int __OFF_T_MATCHES_OFF64_T() { + return __OFF_T_MATCHES_OFF64_T; + } + + private static final int __INO_T_MATCHES_INO64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __INO_T_MATCHES_INO64_T 1 + * } + */ + public static int __INO_T_MATCHES_INO64_T() { + return __INO_T_MATCHES_INO64_T; + } + + private static final int __RLIM_T_MATCHES_RLIM64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __RLIM_T_MATCHES_RLIM64_T 1 + * } + */ + public static int __RLIM_T_MATCHES_RLIM64_T() { + return __RLIM_T_MATCHES_RLIM64_T; + } + + private static final int __STATFS_MATCHES_STATFS64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __STATFS_MATCHES_STATFS64 1 + * } + */ + public static int __STATFS_MATCHES_STATFS64() { + return __STATFS_MATCHES_STATFS64; + } + + private static final int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 + * } + */ + public static int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64() { + return __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64; + } + + private static final int __FD_SETSIZE = (int) 1024L; + + /** + * {@snippet lang = c : * #define __FD_SETSIZE 1024 + * } + */ + public static int __FD_SETSIZE() { + return __FD_SETSIZE; + } + + private static final int _BITS_TIME64_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TIME64_H 1 + * } + */ + public static int _BITS_TIME64_H() { + return _BITS_TIME64_H; + } + + private static final int _BITS_WCHAR_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_WCHAR_H 1 + * } + */ + public static int _BITS_WCHAR_H() { + return _BITS_WCHAR_H; + } + + private static final int _BITS_STDINT_INTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_INTN_H 1 + * } + */ + public static int _BITS_STDINT_INTN_H() { + return _BITS_STDINT_INTN_H; + } + + private static final int _BITS_STDINT_UINTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_UINTN_H 1 + * } + */ + public static int _BITS_STDINT_UINTN_H() { + return _BITS_STDINT_UINTN_H; + } + + private static final int DLPACK_MAJOR_VERSION = (int) 1L; + + /** + * {@snippet lang = c : * #define DLPACK_MAJOR_VERSION 1 + * } + */ + public static int DLPACK_MAJOR_VERSION() { + return DLPACK_MAJOR_VERSION; + } + + private static final int DLPACK_MINOR_VERSION = (int) 0L; + + /** + * {@snippet lang = c : * #define DLPACK_MINOR_VERSION 0 + * } + */ + public static int DLPACK_MINOR_VERSION() { + return DLPACK_MINOR_VERSION; + } + + private static final int true_ = (int) 1L; + + /** + * {@snippet lang = c : * #define true 1 + * } + */ + public static int true_() { + return true_; + } + + private static final int false_ = (int) 0L; + + /** + * {@snippet lang = c : * #define false 0 + * } + */ + public static int false_() { + return false_; + } + + private static final int __bool_true_false_are_defined = (int) 1L; + + /** + * {@snippet lang = c : * #define __bool_true_false_are_defined 1 + * } + */ + public static int __bool_true_false_are_defined() { + return __bool_true_false_are_defined; + } + + /** + * {@snippet lang = c : * typedef unsigned char __u_char + * } + */ + public static final OfByte __u_char = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned short __u_short + * } + */ + public static final OfShort __u_short = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned int __u_int + * } + */ + public static final OfInt __u_int = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __u_long + * } + */ + public static final OfLong __u_long = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char __int8_t + * } + */ + public static final OfByte __int8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned char __uint8_t + * } + */ + public static final OfByte __uint8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef short __int16_t + * } + */ + public static final OfShort __int16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned short __uint16_t + * } + */ + public static final OfShort __uint16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef int __int32_t + * } + */ + public static final OfInt __int32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __uint32_t + * } + */ + public static final OfInt __uint32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef long __int64_t + * } + */ + public static final OfLong __int64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uint64_t + * } + */ + public static final OfLong __uint64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __int8_t __int_least8_t + * } + */ + public static final OfByte __int_least8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint8_t __uint_least8_t + * } + */ + public static final OfByte __uint_least8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t __int_least16_t + * } + */ + public static final OfShort __int_least16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint16_t __uint_least16_t + * } + */ + public static final OfShort __uint_least16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t __int_least32_t + * } + */ + public static final OfInt __int_least32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef __uint32_t __uint_least32_t + * } + */ + public static final OfInt __uint_least32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t __int_least64_t + * } + */ + public static final OfLong __int_least64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint64_t __uint_least64_t + * } + */ + public static final OfLong __uint_least64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __quad_t + * } + */ + public static final OfLong __quad_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __u_quad_t + * } + */ + public static final OfLong __u_quad_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __intmax_t + * } + */ + public static final OfLong __intmax_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uintmax_t + * } + */ + public static final OfLong __uintmax_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __dev_t + * } + */ + public static final OfLong __dev_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __uid_t + * } + */ + public static final OfInt __uid_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __gid_t + * } + */ + public static final OfInt __gid_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __ino_t + * } + */ + public static final OfLong __ino_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __ino64_t + * } + */ + public static final OfLong __ino64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __mode_t + * } + */ + public static final OfInt __mode_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __nlink_t + * } + */ + public static final OfLong __nlink_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off_t + * } + */ + public static final OfLong __off_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off64_t + * } + */ + public static final OfLong __off64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef int __pid_t + * } + */ + public static final OfInt __pid_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef long __clock_t + * } + */ + public static final OfLong __clock_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim_t + * } + */ + public static final OfLong __rlim_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim64_t + * } + */ + public static final OfLong __rlim64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __id_t + * } + */ + public static final OfInt __id_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef long __time_t + * } + */ + public static final OfLong __time_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __useconds_t + * } + */ + public static final OfInt __useconds_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef long __suseconds_t + * } + */ + public static final OfLong __suseconds_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __suseconds64_t + * } + */ + public static final OfLong __suseconds64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef int __daddr_t + * } + */ + public static final OfInt __daddr_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef int __key_t + * } + */ + public static final OfInt __key_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef int __clockid_t + * } + */ + public static final OfInt __clockid_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef void *__timer_t + * } + */ + public static final AddressLayout __timer_t = IvfFlatH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __blksize_t + * } + */ + public static final OfLong __blksize_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt_t + * } + */ + public static final OfLong __blkcnt_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt64_t + * } + */ + public static final OfLong __blkcnt64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt_t + * } + */ + public static final OfLong __fsblkcnt_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt64_t + * } + */ + public static final OfLong __fsblkcnt64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt_t + * } + */ + public static final OfLong __fsfilcnt_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt64_t + * } + */ + public static final OfLong __fsfilcnt64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __fsword_t + * } + */ + public static final OfLong __fsword_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __ssize_t + * } + */ + public static final OfLong __ssize_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long __syscall_slong_t + * } + */ + public static final OfLong __syscall_slong_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __syscall_ulong_t + * } + */ + public static final OfLong __syscall_ulong_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __off64_t __loff_t + * } + */ + public static final OfLong __loff_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef char *__caddr_t + * } + */ + public static final AddressLayout __caddr_t = IvfFlatH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __intptr_t + * } + */ + public static final OfLong __intptr_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __socklen_t + * } + */ + public static final OfInt __socklen_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef int __sig_atomic_t + * } + */ + public static final OfInt __sig_atomic_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef __int8_t int8_t + * } + */ + public static final OfByte int8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t int16_t + * } + */ + public static final OfShort int16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t int32_t + * } + */ + public static final OfInt int32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t int64_t + * } + */ + public static final OfLong int64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint8_t uint8_t + * } + */ + public static final OfByte uint8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint16_t uint16_t + * } + */ + public static final OfShort uint16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint32_t uint32_t + * } + */ + public static final OfInt uint32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef __uint64_t uint64_t + * } + */ + public static final OfLong uint64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __int_least8_t int_least8_t + * } + */ + public static final OfByte int_least8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int_least16_t int_least16_t + * } + */ + public static final OfShort int_least16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int_least32_t int_least32_t + * } + */ + public static final OfInt int_least32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef __int_least64_t int_least64_t + * } + */ + public static final OfLong int_least64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint_least8_t uint_least8_t + * } + */ + public static final OfByte uint_least8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint_least16_t uint_least16_t + * } + */ + public static final OfShort uint_least16_t = IvfFlatH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint_least32_t uint_least32_t + * } + */ + public static final OfInt uint_least32_t = IvfFlatH.C_INT; + /** + * {@snippet lang = c : * typedef __uint_least64_t uint_least64_t + * } + */ + public static final OfLong uint_least64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char int_fast8_t + * } + */ + public static final OfByte int_fast8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef long int_fast16_t + * } + */ + public static final OfLong int_fast16_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast32_t + * } + */ + public static final OfLong int_fast32_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast64_t + * } + */ + public static final OfLong int_fast64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned char uint_fast8_t + * } + */ + public static final OfByte uint_fast8_t = IvfFlatH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast16_t + * } + */ + public static final OfLong uint_fast16_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast32_t + * } + */ + public static final OfLong uint_fast32_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast64_t + * } + */ + public static final OfLong uint_fast64_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef long intptr_t + * } + */ + public static final OfLong intptr_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uintptr_t + * } + */ + public static final OfLong uintptr_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __intmax_t intmax_t + * } + */ + public static final OfLong intmax_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef __uintmax_t uintmax_t + * } + */ + public static final OfLong uintmax_t = IvfFlatH.C_LONG; + private static final int CUVS_ERROR = (int) 0L; + + /** + * {@snippet lang = c : * enum .CUVS_ERROR = 0 + * } + */ + public static int CUVS_ERROR() { + return CUVS_ERROR; + } + + private static final int CUVS_SUCCESS = (int) 1L; + + /** + * {@snippet lang = c : * enum .CUVS_SUCCESS = 1 + * } + */ + public static int CUVS_SUCCESS() { + return CUVS_SUCCESS; + } + + /** + * {@snippet lang = c : * typedef uintptr_t cuvsResources_t + * } + */ + public static final OfLong cuvsResources_t = IvfFlatH.C_LONG; + private static final int L2Expanded = (int) 0L; + + /** + * {@snippet lang = c : * enum .L2Expanded = 0 + * } + */ + public static int L2Expanded() { + return L2Expanded; + } + + private static final int L2SqrtExpanded = (int) 1L; + + /** + * {@snippet lang = c : * enum .L2SqrtExpanded = 1 + * } + */ + public static int L2SqrtExpanded() { + return L2SqrtExpanded; + } + + private static final int CosineExpanded = (int) 2L; + + /** + * {@snippet lang = c : * enum .CosineExpanded = 2 + * } + */ + public static int CosineExpanded() { + return CosineExpanded; + } + + private static final int L1 = (int) 3L; + + /** + * {@snippet lang = c : * enum .L1 = 3 + * } + */ + public static int L1() { + return L1; + } + + private static final int L2Unexpanded = (int) 4L; + + /** + * {@snippet lang = c : * enum .L2Unexpanded = 4 + * } + */ + public static int L2Unexpanded() { + return L2Unexpanded; + } + + private static final int L2SqrtUnexpanded = (int) 5L; + + /** + * {@snippet lang = c : * enum .L2SqrtUnexpanded = 5 + * } + */ + public static int L2SqrtUnexpanded() { + return L2SqrtUnexpanded; + } + + private static final int InnerProduct = (int) 6L; + + /** + * {@snippet lang = c : * enum .InnerProduct = 6 + * } + */ + public static int InnerProduct() { + return InnerProduct; + } + + private static final int Linf = (int) 7L; + + /** + * {@snippet lang = c : * enum .Linf = 7 + * } + */ + public static int Linf() { + return Linf; + } + + private static final int Canberra = (int) 8L; + + /** + * {@snippet lang = c : * enum .Canberra = 8 + * } + */ + public static int Canberra() { + return Canberra; + } + + private static final int LpUnexpanded = (int) 9L; + + /** + * {@snippet lang = c : * enum .LpUnexpanded = 9 + * } + */ + public static int LpUnexpanded() { + return LpUnexpanded; + } + + private static final int CorrelationExpanded = (int) 10L; + + /** + * {@snippet lang = c : * enum .CorrelationExpanded = 10 + * } + */ + public static int CorrelationExpanded() { + return CorrelationExpanded; + } + + private static final int JaccardExpanded = (int) 11L; + + /** + * {@snippet lang = c : * enum .JaccardExpanded = 11 + * } + */ + public static int JaccardExpanded() { + return JaccardExpanded; + } + + private static final int HellingerExpanded = (int) 12L; + + /** + * {@snippet lang = c : * enum .HellingerExpanded = 12 + * } + */ + public static int HellingerExpanded() { + return HellingerExpanded; + } + + private static final int Haversine = (int) 13L; + + /** + * {@snippet lang = c : * enum .Haversine = 13 + * } + */ + public static int Haversine() { + return Haversine; + } + + private static final int BrayCurtis = (int) 14L; + + /** + * {@snippet lang = c : * enum .BrayCurtis = 14 + * } + */ + public static int BrayCurtis() { + return BrayCurtis; + } + + private static final int JensenShannon = (int) 15L; + + /** + * {@snippet lang = c : * enum .JensenShannon = 15 + * } + */ + public static int JensenShannon() { + return JensenShannon; + } + + private static final int HammingUnexpanded = (int) 16L; + + /** + * {@snippet lang = c : * enum .HammingUnexpanded = 16 + * } + */ + public static int HammingUnexpanded() { + return HammingUnexpanded; + } + + private static final int KLDivergence = (int) 17L; + + /** + * {@snippet lang = c : * enum .KLDivergence = 17 + * } + */ + public static int KLDivergence() { + return KLDivergence; + } + + private static final int RusselRaoExpanded = (int) 18L; + + /** + * {@snippet lang = c : * enum .RusselRaoExpanded = 18 + * } + */ + public static int RusselRaoExpanded() { + return RusselRaoExpanded; + } + + private static final int DiceExpanded = (int) 19L; + + /** + * {@snippet lang = c : * enum .DiceExpanded = 19 + * } + */ + public static int DiceExpanded() { + return DiceExpanded; + } + + private static final int Precomputed = (int) 100L; + + /** + * {@snippet lang = c : * enum .Precomputed = 100 + * } + */ + public static int Precomputed() { + return Precomputed; + } + + /** + * {@snippet lang = c : * typedef long ptrdiff_t + * } + */ + public static final OfLong ptrdiff_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long size_t + * } + */ + public static final OfLong size_t = IvfFlatH.C_LONG; + /** + * {@snippet lang = c : * typedef int wchar_t + * } + */ + public static final OfInt wchar_t = IvfFlatH.C_INT; + private static final int kDLCPU = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLCPU = 1 + * } + */ + public static int kDLCPU() { + return kDLCPU; + } + + private static final int kDLCUDA = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLCUDA = 2 + * } + */ + public static int kDLCUDA() { + return kDLCUDA; + } + + private static final int kDLCUDAHost = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLCUDAHost = 3 + * } + */ + public static int kDLCUDAHost() { + return kDLCUDAHost; + } + + private static final int kDLOpenCL = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLOpenCL = 4 + * } + */ + public static int kDLOpenCL() { + return kDLOpenCL; + } + + private static final int kDLVulkan = (int) 7L; + + /** + * {@snippet lang = c : * enum .kDLVulkan = 7 + * } + */ + public static int kDLVulkan() { + return kDLVulkan; + } + + private static final int kDLMetal = (int) 8L; + + /** + * {@snippet lang = c : * enum .kDLMetal = 8 + * } + */ + public static int kDLMetal() { + return kDLMetal; + } + + private static final int kDLVPI = (int) 9L; + + /** + * {@snippet lang = c : * enum .kDLVPI = 9 + * } + */ + public static int kDLVPI() { + return kDLVPI; + } + + private static final int kDLROCM = (int) 10L; + + /** + * {@snippet lang = c : * enum .kDLROCM = 10 + * } + */ + public static int kDLROCM() { + return kDLROCM; + } + + private static final int kDLROCMHost = (int) 11L; + + /** + * {@snippet lang = c : * enum .kDLROCMHost = 11 + * } + */ + public static int kDLROCMHost() { + return kDLROCMHost; + } + + private static final int kDLExtDev = (int) 12L; + + /** + * {@snippet lang = c : * enum .kDLExtDev = 12 + * } + */ + public static int kDLExtDev() { + return kDLExtDev; + } + + private static final int kDLCUDAManaged = (int) 13L; + + /** + * {@snippet lang = c : * enum .kDLCUDAManaged = 13 + * } + */ + public static int kDLCUDAManaged() { + return kDLCUDAManaged; + } + + private static final int kDLOneAPI = (int) 14L; + + /** + * {@snippet lang = c : * enum .kDLOneAPI = 14 + * } + */ + public static int kDLOneAPI() { + return kDLOneAPI; + } + + private static final int kDLWebGPU = (int) 15L; + + /** + * {@snippet lang = c : * enum .kDLWebGPU = 15 + * } + */ + public static int kDLWebGPU() { + return kDLWebGPU; + } + + private static final int kDLHexagon = (int) 16L; + + /** + * {@snippet lang = c : * enum .kDLHexagon = 16 + * } + */ + public static int kDLHexagon() { + return kDLHexagon; + } + + private static final int kDLMAIA = (int) 17L; + + /** + * {@snippet lang = c : * enum .kDLMAIA = 17 + * } + */ + public static int kDLMAIA() { + return kDLMAIA; + } + + private static final int kDLInt = (int) 0L; + + /** + * {@snippet lang = c : * enum .kDLInt = 0 + * } + */ + public static int kDLInt() { + return kDLInt; + } + + private static final int kDLUInt = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLUInt = 1 + * } + */ + public static int kDLUInt() { + return kDLUInt; + } + + private static final int kDLFloat = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLFloat = 2 + * } + */ + public static int kDLFloat() { + return kDLFloat; + } + + private static final int kDLOpaqueHandle = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLOpaqueHandle = 3 + * } + */ + public static int kDLOpaqueHandle() { + return kDLOpaqueHandle; + } + + private static final int kDLBfloat = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLBfloat = 4 + * } + */ + public static int kDLBfloat() { + return kDLBfloat; + } + + private static final int kDLComplex = (int) 5L; + + /** + * {@snippet lang = c : * enum .kDLComplex = 5 + * } + */ + public static int kDLComplex() { + return kDLComplex; + } + + private static final int kDLBool = (int) 6L; + + /** + * {@snippet lang = c : * enum .kDLBool = 6 + * } + */ + public static int kDLBool() { + return kDLBool; + } + + /** + * {@snippet lang = c : + * typedef struct cuvsIvfFlatIndexParams { + * cuvsDistanceType metric; + * float metric_arg; + * _Bool add_data_on_build; + * uint32_t n_lists; + * uint32_t kmeans_n_iters; + * double kmeans_trainset_fraction; + * _Bool adaptive_centers; + * _Bool conservative_memory_allocation; + * } *cuvsIvfFlatIndexParams_t + * } + */ + public static final AddressLayout cuvsIvfFlatIndexParams_t = IvfFlatH.C_POINTER; + + private static class cuvsIvfFlatIndexParamsCreate { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatIndexParamsCreate"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsCreate(cuvsIvfFlatIndexParams_t *index_params) + * } + */ + public static FunctionDescriptor cuvsIvfFlatIndexParamsCreate$descriptor() { + return cuvsIvfFlatIndexParamsCreate.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsCreate(cuvsIvfFlatIndexParams_t *index_params) + * } + */ + public static MethodHandle cuvsIvfFlatIndexParamsCreate$handle() { + return cuvsIvfFlatIndexParamsCreate.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsCreate(cuvsIvfFlatIndexParams_t *index_params) + * } + */ + public static MemorySegment cuvsIvfFlatIndexParamsCreate$address() { + return cuvsIvfFlatIndexParamsCreate.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsCreate(cuvsIvfFlatIndexParams_t *index_params) + * } + */ + public static int cuvsIvfFlatIndexParamsCreate(MemorySegment index_params) { + var mh$ = cuvsIvfFlatIndexParamsCreate.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatIndexParamsCreate", index_params); + } + return (int) mh$.invokeExact(index_params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatIndexParamsDestroy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatIndexParamsDestroy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsDestroy(cuvsIvfFlatIndexParams_t index_params) + * } + */ + public static FunctionDescriptor cuvsIvfFlatIndexParamsDestroy$descriptor() { + return cuvsIvfFlatIndexParamsDestroy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsDestroy(cuvsIvfFlatIndexParams_t index_params) + * } + */ + public static MethodHandle cuvsIvfFlatIndexParamsDestroy$handle() { + return cuvsIvfFlatIndexParamsDestroy.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsDestroy(cuvsIvfFlatIndexParams_t index_params) + * } + */ + public static MemorySegment cuvsIvfFlatIndexParamsDestroy$address() { + return cuvsIvfFlatIndexParamsDestroy.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexParamsDestroy(cuvsIvfFlatIndexParams_t index_params) + * } + */ + public static int cuvsIvfFlatIndexParamsDestroy(MemorySegment index_params) { + var mh$ = cuvsIvfFlatIndexParamsDestroy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatIndexParamsDestroy", index_params); + } + return (int) mh$.invokeExact(index_params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + /** + * {@snippet lang = c : + * typedef struct cuvsIvfFlatSearchParams { + * uint32_t n_probes; + * } *cuvsIvfFlatSearchParams_t + * } + */ + public static final AddressLayout cuvsIvfFlatSearchParams_t = IvfFlatH.C_POINTER; + + private static class cuvsIvfFlatSearchParamsCreate { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatSearchParamsCreate"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsCreate(cuvsIvfFlatSearchParams_t *params) + * } + */ + public static FunctionDescriptor cuvsIvfFlatSearchParamsCreate$descriptor() { + return cuvsIvfFlatSearchParamsCreate.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsCreate(cuvsIvfFlatSearchParams_t *params) + * } + */ + public static MethodHandle cuvsIvfFlatSearchParamsCreate$handle() { + return cuvsIvfFlatSearchParamsCreate.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsCreate(cuvsIvfFlatSearchParams_t *params) + * } + */ + public static MemorySegment cuvsIvfFlatSearchParamsCreate$address() { + return cuvsIvfFlatSearchParamsCreate.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsCreate(cuvsIvfFlatSearchParams_t *params) + * } + */ + public static int cuvsIvfFlatSearchParamsCreate(MemorySegment params) { + var mh$ = cuvsIvfFlatSearchParamsCreate.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatSearchParamsCreate", params); + } + return (int) mh$.invokeExact(params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatSearchParamsDestroy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatSearchParamsDestroy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsDestroy(cuvsIvfFlatSearchParams_t params) + * } + */ + public static FunctionDescriptor cuvsIvfFlatSearchParamsDestroy$descriptor() { + return cuvsIvfFlatSearchParamsDestroy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsDestroy(cuvsIvfFlatSearchParams_t params) + * } + */ + public static MethodHandle cuvsIvfFlatSearchParamsDestroy$handle() { + return cuvsIvfFlatSearchParamsDestroy.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsDestroy(cuvsIvfFlatSearchParams_t params) + * } + */ + public static MemorySegment cuvsIvfFlatSearchParamsDestroy$address() { + return cuvsIvfFlatSearchParamsDestroy.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearchParamsDestroy(cuvsIvfFlatSearchParams_t params) + * } + */ + public static int cuvsIvfFlatSearchParamsDestroy(MemorySegment params) { + var mh$ = cuvsIvfFlatSearchParamsDestroy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatSearchParamsDestroy", params); + } + return (int) mh$.invokeExact(params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + /** + * {@snippet lang = c : * typedef cuvsIvfFlatIndex *cuvsIvfFlatIndex_t + * } + */ + public static final AddressLayout cuvsIvfFlatIndex_t = IvfFlatH.C_POINTER; + + private static class cuvsIvfFlatIndexCreate { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatIndexCreate"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexCreate(cuvsIvfFlatIndex_t *index) + * } + */ + public static FunctionDescriptor cuvsIvfFlatIndexCreate$descriptor() { + return cuvsIvfFlatIndexCreate.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexCreate(cuvsIvfFlatIndex_t *index) + * } + */ + public static MethodHandle cuvsIvfFlatIndexCreate$handle() { + return cuvsIvfFlatIndexCreate.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexCreate(cuvsIvfFlatIndex_t *index) + * } + */ + public static MemorySegment cuvsIvfFlatIndexCreate$address() { + return cuvsIvfFlatIndexCreate.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexCreate(cuvsIvfFlatIndex_t *index) + * } + */ + public static int cuvsIvfFlatIndexCreate(MemorySegment index) { + var mh$ = cuvsIvfFlatIndexCreate.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatIndexCreate", index); + } + return (int) mh$.invokeExact(index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatIndexDestroy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatIndexDestroy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexDestroy(cuvsIvfFlatIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfFlatIndexDestroy$descriptor() { + return cuvsIvfFlatIndexDestroy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexDestroy(cuvsIvfFlatIndex_t index) + * } + */ + public static MethodHandle cuvsIvfFlatIndexDestroy$handle() { + return cuvsIvfFlatIndexDestroy.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexDestroy(cuvsIvfFlatIndex_t index) + * } + */ + public static MemorySegment cuvsIvfFlatIndexDestroy$address() { + return cuvsIvfFlatIndexDestroy.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatIndexDestroy(cuvsIvfFlatIndex_t index) + * } + */ + public static int cuvsIvfFlatIndexDestroy(MemorySegment index) { + var mh$ = cuvsIvfFlatIndexDestroy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatIndexDestroy", index); + } + return (int) mh$.invokeExact(index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatBuild { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_LONG, + IvfFlatH.C_POINTER, IvfFlatH.C_POINTER, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatBuild"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatBuild(cuvsResources_t res, cuvsIvfFlatIndexParams_t index_params, DLManagedTensor *dataset, cuvsIvfFlatIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfFlatBuild$descriptor() { + return cuvsIvfFlatBuild.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatBuild(cuvsResources_t res, cuvsIvfFlatIndexParams_t index_params, DLManagedTensor *dataset, cuvsIvfFlatIndex_t index) + * } + */ + public static MethodHandle cuvsIvfFlatBuild$handle() { + return cuvsIvfFlatBuild.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatBuild(cuvsResources_t res, cuvsIvfFlatIndexParams_t index_params, DLManagedTensor *dataset, cuvsIvfFlatIndex_t index) + * } + */ + public static MemorySegment cuvsIvfFlatBuild$address() { + return cuvsIvfFlatBuild.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatBuild(cuvsResources_t res, cuvsIvfFlatIndexParams_t index_params, DLManagedTensor *dataset, cuvsIvfFlatIndex_t index) + * } + */ + public static int cuvsIvfFlatBuild(long res, MemorySegment index_params, MemorySegment dataset, MemorySegment index) { + var mh$ = cuvsIvfFlatBuild.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatBuild", res, index_params, dataset, index); + } + return (int) mh$.invokeExact(res, index_params, dataset, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatSearch { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_LONG, + IvfFlatH.C_POINTER, IvfFlatH.C_POINTER, IvfFlatH.C_POINTER, IvfFlatH.C_POINTER, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatSearch"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearch(cuvsResources_t res, cuvsIvfFlatSearchParams_t search_params, cuvsIvfFlatIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static FunctionDescriptor cuvsIvfFlatSearch$descriptor() { + return cuvsIvfFlatSearch.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearch(cuvsResources_t res, cuvsIvfFlatSearchParams_t search_params, cuvsIvfFlatIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static MethodHandle cuvsIvfFlatSearch$handle() { + return cuvsIvfFlatSearch.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearch(cuvsResources_t res, cuvsIvfFlatSearchParams_t search_params, cuvsIvfFlatIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static MemorySegment cuvsIvfFlatSearch$address() { + return cuvsIvfFlatSearch.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSearch(cuvsResources_t res, cuvsIvfFlatSearchParams_t search_params, cuvsIvfFlatIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static int cuvsIvfFlatSearch(long res, MemorySegment search_params, MemorySegment index, MemorySegment queries, + MemorySegment neighbors, MemorySegment distances) { + var mh$ = cuvsIvfFlatSearch.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatSearch", res, search_params, index, queries, neighbors, distances); + } + return (int) mh$.invokeExact(res, search_params, index, queries, neighbors, distances); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatSerialize { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_LONG, + IvfFlatH.C_POINTER, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatSerialize"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSerialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfFlatSerialize$descriptor() { + return cuvsIvfFlatSerialize.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSerialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static MethodHandle cuvsIvfFlatSerialize$handle() { + return cuvsIvfFlatSerialize.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSerialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static MemorySegment cuvsIvfFlatSerialize$address() { + return cuvsIvfFlatSerialize.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatSerialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static int cuvsIvfFlatSerialize(long res, MemorySegment filename, MemorySegment index) { + var mh$ = cuvsIvfFlatSerialize.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatSerialize", res, filename, index); + } + return (int) mh$.invokeExact(res, filename, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatDeserialize { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_LONG, + IvfFlatH.C_POINTER, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatDeserialize"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatDeserialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfFlatDeserialize$descriptor() { + return cuvsIvfFlatDeserialize.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatDeserialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static MethodHandle cuvsIvfFlatDeserialize$handle() { + return cuvsIvfFlatDeserialize.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatDeserialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static MemorySegment cuvsIvfFlatDeserialize$address() { + return cuvsIvfFlatDeserialize.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatDeserialize(cuvsResources_t res, const char *filename, cuvsIvfFlatIndex_t index) + * } + */ + public static int cuvsIvfFlatDeserialize(long res, MemorySegment filename, MemorySegment index) { + var mh$ = cuvsIvfFlatDeserialize.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatDeserialize", res, filename, index); + } + return (int) mh$.invokeExact(res, filename, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfFlatExtend { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfFlatH.C_INT, IvfFlatH.C_LONG, + IvfFlatH.C_POINTER, IvfFlatH.C_POINTER, IvfFlatH.C_POINTER); + + public static final MemorySegment ADDR = IvfFlatH.findOrThrow("cuvsIvfFlatExtend"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfFlatIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfFlatExtend$descriptor() { + return cuvsIvfFlatExtend.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfFlatIndex_t index) + * } + */ + public static MethodHandle cuvsIvfFlatExtend$handle() { + return cuvsIvfFlatExtend.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfFlatIndex_t index) + * } + */ + public static MemorySegment cuvsIvfFlatExtend$address() { + return cuvsIvfFlatExtend.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfFlatExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfFlatIndex_t index) + * } + */ + public static int cuvsIvfFlatExtend(long res, MemorySegment new_vectors, MemorySegment new_indices, + MemorySegment index) { + var mh$ = cuvsIvfFlatExtend.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfFlatExtend", res, new_vectors, new_indices, index); + } + return (int) mh$.invokeExact(res, new_vectors, new_indices, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static final long _POSIX_C_SOURCE = 200809L; + + /** + * {@snippet lang = c : * #define _POSIX_C_SOURCE 200809 + * } + */ + public static long _POSIX_C_SOURCE() { + return _POSIX_C_SOURCE; + } + + private static final int __TIMESIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __TIMESIZE 64 + * } + */ + public static int __TIMESIZE() { + return __TIMESIZE; + } + + private static final long __STDC_IEC_60559_BFP__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_BFP__ 201404 + * } + */ + public static long __STDC_IEC_60559_BFP__() { + return __STDC_IEC_60559_BFP__; + } + + private static final long __STDC_IEC_60559_COMPLEX__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_COMPLEX__ 201404 + * } + */ + public static long __STDC_IEC_60559_COMPLEX__() { + return __STDC_IEC_60559_COMPLEX__; + } + + private static final long __STDC_ISO_10646__ = 201706L; + + /** + * {@snippet lang = c : * #define __STDC_ISO_10646__ 201706 + * } + */ + public static long __STDC_ISO_10646__() { + return __STDC_ISO_10646__; + } + + private static final int __WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define __WCHAR_MAX 2147483647 + * } + */ + public static int __WCHAR_MAX() { + return __WCHAR_MAX; + } + + private static final int __WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define __WCHAR_MIN -2147483648 + * } + */ + public static int __WCHAR_MIN() { + return __WCHAR_MIN; + } + + private static final int INT8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT8_MIN -128 + * } + */ + public static int INT8_MIN() { + return INT8_MIN; + } + + private static final int INT16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT16_MIN -32768 + * } + */ + public static int INT16_MIN() { + return INT16_MIN; + } + + private static final int INT32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT32_MIN -2147483648 + * } + */ + public static int INT32_MIN() { + return INT32_MIN; + } + + private static final long INT64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT64_MIN -9223372036854775808 + * } + */ + public static long INT64_MIN() { + return INT64_MIN; + } + + private static final int INT8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT8_MAX 127 + * } + */ + public static int INT8_MAX() { + return INT8_MAX; + } + + private static final int INT16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT16_MAX 32767 + * } + */ + public static int INT16_MAX() { + return INT16_MAX; + } + + private static final int INT32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT32_MAX 2147483647 + * } + */ + public static int INT32_MAX() { + return INT32_MAX; + } + + private static final long INT64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT64_MAX 9223372036854775807 + * } + */ + public static long INT64_MAX() { + return INT64_MAX; + } + + private static final int UINT8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT8_MAX 255 + * } + */ + public static int UINT8_MAX() { + return UINT8_MAX; + } + + private static final int UINT16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT16_MAX 65535 + * } + */ + public static int UINT16_MAX() { + return UINT16_MAX; + } + + private static final int UINT32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT32_MAX 4294967295 + * } + */ + public static int UINT32_MAX() { + return UINT32_MAX; + } + + private static final long UINT64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT64_MAX -1 + * } + */ + public static long UINT64_MAX() { + return UINT64_MAX; + } + + private static final int INT_LEAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MIN -128 + * } + */ + public static int INT_LEAST8_MIN() { + return INT_LEAST8_MIN; + } + + private static final int INT_LEAST16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MIN -32768 + * } + */ + public static int INT_LEAST16_MIN() { + return INT_LEAST16_MIN; + } + + private static final int INT_LEAST32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MIN -2147483648 + * } + */ + public static int INT_LEAST32_MIN() { + return INT_LEAST32_MIN; + } + + private static final long INT_LEAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MIN -9223372036854775808 + * } + */ + public static long INT_LEAST64_MIN() { + return INT_LEAST64_MIN; + } + + private static final int INT_LEAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MAX 127 + * } + */ + public static int INT_LEAST8_MAX() { + return INT_LEAST8_MAX; + } + + private static final int INT_LEAST16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MAX 32767 + * } + */ + public static int INT_LEAST16_MAX() { + return INT_LEAST16_MAX; + } + + private static final int INT_LEAST32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MAX 2147483647 + * } + */ + public static int INT_LEAST32_MAX() { + return INT_LEAST32_MAX; + } + + private static final long INT_LEAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MAX 9223372036854775807 + * } + */ + public static long INT_LEAST64_MAX() { + return INT_LEAST64_MAX; + } + + private static final int UINT_LEAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_LEAST8_MAX 255 + * } + */ + public static int UINT_LEAST8_MAX() { + return UINT_LEAST8_MAX; + } + + private static final int UINT_LEAST16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT_LEAST16_MAX 65535 + * } + */ + public static int UINT_LEAST16_MAX() { + return UINT_LEAST16_MAX; + } + + private static final int UINT_LEAST32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT_LEAST32_MAX 4294967295 + * } + */ + public static int UINT_LEAST32_MAX() { + return UINT_LEAST32_MAX; + } + + private static final long UINT_LEAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_LEAST64_MAX -1 + * } + */ + public static long UINT_LEAST64_MAX() { + return UINT_LEAST64_MAX; + } + + private static final int INT_FAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MIN -128 + * } + */ + public static int INT_FAST8_MIN() { + return INT_FAST8_MIN; + } + + private static final long INT_FAST16_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MIN -9223372036854775808 + * } + */ + public static long INT_FAST16_MIN() { + return INT_FAST16_MIN; + } + + private static final long INT_FAST32_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MIN -9223372036854775808 + * } + */ + public static long INT_FAST32_MIN() { + return INT_FAST32_MIN; + } + + private static final long INT_FAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MIN -9223372036854775808 + * } + */ + public static long INT_FAST64_MIN() { + return INT_FAST64_MIN; + } + + private static final int INT_FAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MAX 127 + * } + */ + public static int INT_FAST8_MAX() { + return INT_FAST8_MAX; + } + + private static final long INT_FAST16_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MAX 9223372036854775807 + * } + */ + public static long INT_FAST16_MAX() { + return INT_FAST16_MAX; + } + + private static final long INT_FAST32_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MAX 9223372036854775807 + * } + */ + public static long INT_FAST32_MAX() { + return INT_FAST32_MAX; + } + + private static final long INT_FAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MAX 9223372036854775807 + * } + */ + public static long INT_FAST64_MAX() { + return INT_FAST64_MAX; + } + + private static final int UINT_FAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_FAST8_MAX 255 + * } + */ + public static int UINT_FAST8_MAX() { + return UINT_FAST8_MAX; + } + + private static final long UINT_FAST16_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST16_MAX -1 + * } + */ + public static long UINT_FAST16_MAX() { + return UINT_FAST16_MAX; + } + + private static final long UINT_FAST32_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST32_MAX -1 + * } + */ + public static long UINT_FAST32_MAX() { + return UINT_FAST32_MAX; + } + + private static final long UINT_FAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST64_MAX -1 + * } + */ + public static long UINT_FAST64_MAX() { + return UINT_FAST64_MAX; + } + + private static final long INTPTR_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTPTR_MIN -9223372036854775808 + * } + */ + public static long INTPTR_MIN() { + return INTPTR_MIN; + } + + private static final long INTPTR_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTPTR_MAX 9223372036854775807 + * } + */ + public static long INTPTR_MAX() { + return INTPTR_MAX; + } + + private static final long UINTPTR_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTPTR_MAX -1 + * } + */ + public static long UINTPTR_MAX() { + return UINTPTR_MAX; + } + + private static final long INTMAX_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTMAX_MIN -9223372036854775808 + * } + */ + public static long INTMAX_MIN() { + return INTMAX_MIN; + } + + private static final long INTMAX_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTMAX_MAX 9223372036854775807 + * } + */ + public static long INTMAX_MAX() { + return INTMAX_MAX; + } + + private static final long UINTMAX_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTMAX_MAX -1 + * } + */ + public static long UINTMAX_MAX() { + return UINTMAX_MAX; + } + + private static final long PTRDIFF_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MIN -9223372036854775808 + * } + */ + public static long PTRDIFF_MIN() { + return PTRDIFF_MIN; + } + + private static final long PTRDIFF_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MAX 9223372036854775807 + * } + */ + public static long PTRDIFF_MAX() { + return PTRDIFF_MAX; + } + + private static final int SIG_ATOMIC_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MIN -2147483648 + * } + */ + public static int SIG_ATOMIC_MIN() { + return SIG_ATOMIC_MIN; + } + + private static final int SIG_ATOMIC_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MAX 2147483647 + * } + */ + public static int SIG_ATOMIC_MAX() { + return SIG_ATOMIC_MAX; + } + + private static final long SIZE_MAX = -1L; + + /** + * {@snippet lang = c : * #define SIZE_MAX -1 + * } + */ + public static long SIZE_MAX() { + return SIZE_MAX; + } + + private static final int WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define WCHAR_MIN -2147483648 + * } + */ + public static int WCHAR_MIN() { + return WCHAR_MIN; + } + + private static final int WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define WCHAR_MAX 2147483647 + * } + */ + public static int WCHAR_MAX() { + return WCHAR_MAX; + } + + private static final int WINT_MIN = (int) 0L; + + /** + * {@snippet lang = c : * #define WINT_MIN 0 + * } + */ + public static int WINT_MIN() { + return WINT_MIN; + } + + private static final int WINT_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define WINT_MAX 4294967295 + * } + */ + public static int WINT_MAX() { + return WINT_MAX; + } + + private static final MemorySegment NULL = MemorySegment.ofAddress(0L); + + /** + * {@snippet lang = c : * #define NULL (void*) 0 + * } + */ + public static MemorySegment NULL() { + return NULL; + } + + private static final long DLPACK_FLAG_BITMASK_READ_ONLY = 1L; + + /** + * {@snippet lang = c : * #define DLPACK_FLAG_BITMASK_READ_ONLY 1 + * } + */ + public static long DLPACK_FLAG_BITMASK_READ_ONLY() { + return DLPACK_FLAG_BITMASK_READ_ONLY; + } + + private static final long DLPACK_FLAG_BITMASK_IS_COPIED = 2L; + + /** + * {@snippet lang = c : * #define DLPACK_FLAG_BITMASK_IS_COPIED 2 + * } + */ + public static long DLPACK_FLAG_BITMASK_IS_COPIED() { + return DLPACK_FLAG_BITMASK_IS_COPIED; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfPqH.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfPqH.java new file mode 100644 index 000000000..d5f1e3cee --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/IvfPqH.java @@ -0,0 +1,3182 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.foreign.ValueLayout.OfByte; +import java.lang.foreign.ValueLayout.OfInt; +import java.lang.foreign.ValueLayout.OfLong; +import java.lang.foreign.ValueLayout.OfShort; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.stream.Collectors; + +public class IvfPqH { + + IvfPqH() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol).orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream().map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? MemoryLayout.structLayout(alignedMembers) + : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int _STDINT_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDINT_H 1 + * } + */ + public static int _STDINT_H() { + return _STDINT_H; + } + + private static final int _FEATURES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _FEATURES_H 1 + * } + */ + public static int _FEATURES_H() { + return _FEATURES_H; + } + + private static final int _DEFAULT_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _DEFAULT_SOURCE 1 + * } + */ + public static int _DEFAULT_SOURCE() { + return _DEFAULT_SOURCE; + } + + private static final int __GLIBC_USE_ISOC2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_ISOC2X 0 + * } + */ + public static int __GLIBC_USE_ISOC2X() { + return __GLIBC_USE_ISOC2X; + } + + private static final int __USE_ISOC11 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC11 1 + * } + */ + public static int __USE_ISOC11() { + return __USE_ISOC11; + } + + private static final int __USE_ISOC99 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC99 1 + * } + */ + public static int __USE_ISOC99() { + return __USE_ISOC99; + } + + private static final int __USE_ISOC95 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ISOC95 1 + * } + */ + public static int __USE_ISOC95() { + return __USE_ISOC95; + } + + private static final int __USE_POSIX_IMPLICITLY = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX_IMPLICITLY 1 + * } + */ + public static int __USE_POSIX_IMPLICITLY() { + return __USE_POSIX_IMPLICITLY; + } + + private static final int _POSIX_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _POSIX_SOURCE 1 + * } + */ + public static int _POSIX_SOURCE() { + return _POSIX_SOURCE; + } + + private static final int __USE_POSIX = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX 1 + * } + */ + public static int __USE_POSIX() { + return __USE_POSIX; + } + + private static final int __USE_POSIX2 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX2 1 + * } + */ + public static int __USE_POSIX2() { + return __USE_POSIX2; + } + + private static final int __USE_POSIX199309 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199309 1 + * } + */ + public static int __USE_POSIX199309() { + return __USE_POSIX199309; + } + + private static final int __USE_POSIX199506 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_POSIX199506 1 + * } + */ + public static int __USE_POSIX199506() { + return __USE_POSIX199506; + } + + private static final int __USE_XOPEN2K = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K 1 + * } + */ + public static int __USE_XOPEN2K() { + return __USE_XOPEN2K; + } + + private static final int __USE_XOPEN2K8 = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_XOPEN2K8 1 + * } + */ + public static int __USE_XOPEN2K8() { + return __USE_XOPEN2K8; + } + + private static final int _ATFILE_SOURCE = (int) 1L; + + /** + * {@snippet lang = c : * #define _ATFILE_SOURCE 1 + * } + */ + public static int _ATFILE_SOURCE() { + return _ATFILE_SOURCE; + } + + private static final int __WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __WORDSIZE 64 + * } + */ + public static int __WORDSIZE() { + return __WORDSIZE; + } + + private static final int __WORDSIZE_TIME64_COMPAT32 = (int) 1L; + + /** + * {@snippet lang = c : * #define __WORDSIZE_TIME64_COMPAT32 1 + * } + */ + public static int __WORDSIZE_TIME64_COMPAT32() { + return __WORDSIZE_TIME64_COMPAT32; + } + + private static final int __SYSCALL_WORDSIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __SYSCALL_WORDSIZE 64 + * } + */ + public static int __SYSCALL_WORDSIZE() { + return __SYSCALL_WORDSIZE; + } + + private static final int __USE_MISC = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_MISC 1 + * } + */ + public static int __USE_MISC() { + return __USE_MISC; + } + + private static final int __USE_ATFILE = (int) 1L; + + /** + * {@snippet lang = c : * #define __USE_ATFILE 1 + * } + */ + public static int __USE_ATFILE() { + return __USE_ATFILE; + } + + private static final int __USE_FORTIFY_LEVEL = (int) 0L; + + /** + * {@snippet lang = c : * #define __USE_FORTIFY_LEVEL 0 + * } + */ + public static int __USE_FORTIFY_LEVEL() { + return __USE_FORTIFY_LEVEL; + } + + private static final int __GLIBC_USE_DEPRECATED_GETS = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_GETS 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_GETS() { + return __GLIBC_USE_DEPRECATED_GETS; + } + + private static final int __GLIBC_USE_DEPRECATED_SCANF = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_DEPRECATED_SCANF 0 + * } + */ + public static int __GLIBC_USE_DEPRECATED_SCANF() { + return __GLIBC_USE_DEPRECATED_SCANF; + } + + private static final int _STDC_PREDEF_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _STDC_PREDEF_H 1 + * } + */ + public static int _STDC_PREDEF_H() { + return _STDC_PREDEF_H; + } + + private static final int __STDC_IEC_559__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559__ 1 + * } + */ + public static int __STDC_IEC_559__() { + return __STDC_IEC_559__; + } + + private static final int __STDC_IEC_559_COMPLEX__ = (int) 1L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_559_COMPLEX__ 1 + * } + */ + public static int __STDC_IEC_559_COMPLEX__() { + return __STDC_IEC_559_COMPLEX__; + } + + private static final int __GNU_LIBRARY__ = (int) 6L; + + /** + * {@snippet lang = c : * #define __GNU_LIBRARY__ 6 + * } + */ + public static int __GNU_LIBRARY__() { + return __GNU_LIBRARY__; + } + + private static final int __GLIBC__ = (int) 2L; + + /** + * {@snippet lang = c : * #define __GLIBC__ 2 + * } + */ + public static int __GLIBC__() { + return __GLIBC__; + } + + private static final int __GLIBC_MINOR__ = (int) 35L; + + /** + * {@snippet lang = c : * #define __GLIBC_MINOR__ 35 + * } + */ + public static int __GLIBC_MINOR__() { + return __GLIBC_MINOR__; + } + + private static final int _SYS_CDEFS_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _SYS_CDEFS_H 1 + * } + */ + public static int _SYS_CDEFS_H() { + return _SYS_CDEFS_H; + } + + private static final int __glibc_c99_flexarr_available = (int) 1L; + + /** + * {@snippet lang = c : * #define __glibc_c99_flexarr_available 1 + * } + */ + public static int __glibc_c99_flexarr_available() { + return __glibc_c99_flexarr_available; + } + + private static final int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = (int) 0L; + + /** + * {@snippet lang = c : * #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 + * } + */ + public static int __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI() { + return __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI; + } + + private static final int __HAVE_GENERIC_SELECTION = (int) 1L; + + /** + * {@snippet lang = c : * #define __HAVE_GENERIC_SELECTION 1 + * } + */ + public static int __HAVE_GENERIC_SELECTION() { + return __HAVE_GENERIC_SELECTION; + } + + private static final int __GLIBC_USE_LIB_EXT2 = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_LIB_EXT2 0 + * } + */ + public static int __GLIBC_USE_LIB_EXT2() { + return __GLIBC_USE_LIB_EXT2; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT() { + return __GLIBC_USE_IEC_60559_BFP_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_BFP_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_BFP_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_BFP_EXT_C2X() { + return __GLIBC_USE_IEC_60559_BFP_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_EXT() { + return __GLIBC_USE_IEC_60559_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT; + } + + private static final int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X() { + return __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X; + } + + private static final int __GLIBC_USE_IEC_60559_TYPES_EXT = (int) 0L; + + /** + * {@snippet lang = c : * #define __GLIBC_USE_IEC_60559_TYPES_EXT 0 + * } + */ + public static int __GLIBC_USE_IEC_60559_TYPES_EXT() { + return __GLIBC_USE_IEC_60559_TYPES_EXT; + } + + private static final int _BITS_TYPES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPES_H 1 + * } + */ + public static int _BITS_TYPES_H() { + return _BITS_TYPES_H; + } + + private static final int _BITS_TYPESIZES_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TYPESIZES_H 1 + * } + */ + public static int _BITS_TYPESIZES_H() { + return _BITS_TYPESIZES_H; + } + + private static final int __OFF_T_MATCHES_OFF64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __OFF_T_MATCHES_OFF64_T 1 + * } + */ + public static int __OFF_T_MATCHES_OFF64_T() { + return __OFF_T_MATCHES_OFF64_T; + } + + private static final int __INO_T_MATCHES_INO64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __INO_T_MATCHES_INO64_T 1 + * } + */ + public static int __INO_T_MATCHES_INO64_T() { + return __INO_T_MATCHES_INO64_T; + } + + private static final int __RLIM_T_MATCHES_RLIM64_T = (int) 1L; + + /** + * {@snippet lang = c : * #define __RLIM_T_MATCHES_RLIM64_T 1 + * } + */ + public static int __RLIM_T_MATCHES_RLIM64_T() { + return __RLIM_T_MATCHES_RLIM64_T; + } + + private static final int __STATFS_MATCHES_STATFS64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __STATFS_MATCHES_STATFS64 1 + * } + */ + public static int __STATFS_MATCHES_STATFS64() { + return __STATFS_MATCHES_STATFS64; + } + + private static final int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = (int) 1L; + + /** + * {@snippet lang = c : * #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 + * } + */ + public static int __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64() { + return __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64; + } + + private static final int __FD_SETSIZE = (int) 1024L; + + /** + * {@snippet lang = c : * #define __FD_SETSIZE 1024 + * } + */ + public static int __FD_SETSIZE() { + return __FD_SETSIZE; + } + + private static final int _BITS_TIME64_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_TIME64_H 1 + * } + */ + public static int _BITS_TIME64_H() { + return _BITS_TIME64_H; + } + + private static final int _BITS_WCHAR_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_WCHAR_H 1 + * } + */ + public static int _BITS_WCHAR_H() { + return _BITS_WCHAR_H; + } + + private static final int _BITS_STDINT_INTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_INTN_H 1 + * } + */ + public static int _BITS_STDINT_INTN_H() { + return _BITS_STDINT_INTN_H; + } + + private static final int _BITS_STDINT_UINTN_H = (int) 1L; + + /** + * {@snippet lang = c : * #define _BITS_STDINT_UINTN_H 1 + * } + */ + public static int _BITS_STDINT_UINTN_H() { + return _BITS_STDINT_UINTN_H; + } + + private static final int DLPACK_MAJOR_VERSION = (int) 1L; + + /** + * {@snippet lang = c : * #define DLPACK_MAJOR_VERSION 1 + * } + */ + public static int DLPACK_MAJOR_VERSION() { + return DLPACK_MAJOR_VERSION; + } + + private static final int DLPACK_MINOR_VERSION = (int) 0L; + + /** + * {@snippet lang = c : * #define DLPACK_MINOR_VERSION 0 + * } + */ + public static int DLPACK_MINOR_VERSION() { + return DLPACK_MINOR_VERSION; + } + + private static final int true_ = (int) 1L; + + /** + * {@snippet lang = c : * #define true 1 + * } + */ + public static int true_() { + return true_; + } + + private static final int false_ = (int) 0L; + + /** + * {@snippet lang = c : * #define false 0 + * } + */ + public static int false_() { + return false_; + } + + private static final int __bool_true_false_are_defined = (int) 1L; + + /** + * {@snippet lang = c : * #define __bool_true_false_are_defined 1 + * } + */ + public static int __bool_true_false_are_defined() { + return __bool_true_false_are_defined; + } + + /** + * {@snippet lang = c : * typedef unsigned char __u_char + * } + */ + public static final OfByte __u_char = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned short __u_short + * } + */ + public static final OfShort __u_short = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned int __u_int + * } + */ + public static final OfInt __u_int = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __u_long + * } + */ + public static final OfLong __u_long = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char __int8_t + * } + */ + public static final OfByte __int8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned char __uint8_t + * } + */ + public static final OfByte __uint8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef short __int16_t + * } + */ + public static final OfShort __int16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef unsigned short __uint16_t + * } + */ + public static final OfShort __uint16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef int __int32_t + * } + */ + public static final OfInt __int32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __uint32_t + * } + */ + public static final OfInt __uint32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef long __int64_t + * } + */ + public static final OfLong __int64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uint64_t + * } + */ + public static final OfLong __uint64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __int8_t __int_least8_t + * } + */ + public static final OfByte __int_least8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint8_t __uint_least8_t + * } + */ + public static final OfByte __uint_least8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t __int_least16_t + * } + */ + public static final OfShort __int_least16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint16_t __uint_least16_t + * } + */ + public static final OfShort __uint_least16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t __int_least32_t + * } + */ + public static final OfInt __int_least32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef __uint32_t __uint_least32_t + * } + */ + public static final OfInt __uint_least32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t __int_least64_t + * } + */ + public static final OfLong __int_least64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint64_t __uint_least64_t + * } + */ + public static final OfLong __uint_least64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __quad_t + * } + */ + public static final OfLong __quad_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __u_quad_t + * } + */ + public static final OfLong __u_quad_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __intmax_t + * } + */ + public static final OfLong __intmax_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __uintmax_t + * } + */ + public static final OfLong __uintmax_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __dev_t + * } + */ + public static final OfLong __dev_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __uid_t + * } + */ + public static final OfInt __uid_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned int __gid_t + * } + */ + public static final OfInt __gid_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __ino_t + * } + */ + public static final OfLong __ino_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __ino64_t + * } + */ + public static final OfLong __ino64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __mode_t + * } + */ + public static final OfInt __mode_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef unsigned long __nlink_t + * } + */ + public static final OfLong __nlink_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off_t + * } + */ + public static final OfLong __off_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __off64_t + * } + */ + public static final OfLong __off64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef int __pid_t + * } + */ + public static final OfInt __pid_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef long __clock_t + * } + */ + public static final OfLong __clock_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim_t + * } + */ + public static final OfLong __rlim_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __rlim64_t + * } + */ + public static final OfLong __rlim64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __id_t + * } + */ + public static final OfInt __id_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef long __time_t + * } + */ + public static final OfLong __time_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __useconds_t + * } + */ + public static final OfInt __useconds_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef long __suseconds_t + * } + */ + public static final OfLong __suseconds_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __suseconds64_t + * } + */ + public static final OfLong __suseconds64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef int __daddr_t + * } + */ + public static final OfInt __daddr_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef int __key_t + * } + */ + public static final OfInt __key_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef int __clockid_t + * } + */ + public static final OfInt __clockid_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef void *__timer_t + * } + */ + public static final AddressLayout __timer_t = IvfPqH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __blksize_t + * } + */ + public static final OfLong __blksize_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt_t + * } + */ + public static final OfLong __blkcnt_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __blkcnt64_t + * } + */ + public static final OfLong __blkcnt64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt_t + * } + */ + public static final OfLong __fsblkcnt_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsblkcnt64_t + * } + */ + public static final OfLong __fsblkcnt64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt_t + * } + */ + public static final OfLong __fsfilcnt_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __fsfilcnt64_t + * } + */ + public static final OfLong __fsfilcnt64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __fsword_t + * } + */ + public static final OfLong __fsword_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __ssize_t + * } + */ + public static final OfLong __ssize_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long __syscall_slong_t + * } + */ + public static final OfLong __syscall_slong_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long __syscall_ulong_t + * } + */ + public static final OfLong __syscall_ulong_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __off64_t __loff_t + * } + */ + public static final OfLong __loff_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef char *__caddr_t + * } + */ + public static final AddressLayout __caddr_t = IvfPqH.C_POINTER; + /** + * {@snippet lang = c : * typedef long __intptr_t + * } + */ + public static final OfLong __intptr_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned int __socklen_t + * } + */ + public static final OfInt __socklen_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef int __sig_atomic_t + * } + */ + public static final OfInt __sig_atomic_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef __int8_t int8_t + * } + */ + public static final OfByte int8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int16_t int16_t + * } + */ + public static final OfShort int16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int32_t int32_t + * } + */ + public static final OfInt int32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef __int64_t int64_t + * } + */ + public static final OfLong int64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint8_t uint8_t + * } + */ + public static final OfByte uint8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint16_t uint16_t + * } + */ + public static final OfShort uint16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint32_t uint32_t + * } + */ + public static final OfInt uint32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef __uint64_t uint64_t + * } + */ + public static final OfLong uint64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __int_least8_t int_least8_t + * } + */ + public static final OfByte int_least8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef __int_least16_t int_least16_t + * } + */ + public static final OfShort int_least16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef __int_least32_t int_least32_t + * } + */ + public static final OfInt int_least32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef __int_least64_t int_least64_t + * } + */ + public static final OfLong int_least64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __uint_least8_t uint_least8_t + * } + */ + public static final OfByte uint_least8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef __uint_least16_t uint_least16_t + * } + */ + public static final OfShort uint_least16_t = IvfPqH.C_SHORT; + /** + * {@snippet lang = c : * typedef __uint_least32_t uint_least32_t + * } + */ + public static final OfInt uint_least32_t = IvfPqH.C_INT; + /** + * {@snippet lang = c : * typedef __uint_least64_t uint_least64_t + * } + */ + public static final OfLong uint_least64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef signed char int_fast8_t + * } + */ + public static final OfByte int_fast8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef long int_fast16_t + * } + */ + public static final OfLong int_fast16_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast32_t + * } + */ + public static final OfLong int_fast32_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long int_fast64_t + * } + */ + public static final OfLong int_fast64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned char uint_fast8_t + * } + */ + public static final OfByte uint_fast8_t = IvfPqH.C_CHAR; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast16_t + * } + */ + public static final OfLong uint_fast16_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast32_t + * } + */ + public static final OfLong uint_fast32_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uint_fast64_t + * } + */ + public static final OfLong uint_fast64_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef long intptr_t + * } + */ + public static final OfLong intptr_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long uintptr_t + * } + */ + public static final OfLong uintptr_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __intmax_t intmax_t + * } + */ + public static final OfLong intmax_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef __uintmax_t uintmax_t + * } + */ + public static final OfLong uintmax_t = IvfPqH.C_LONG; + private static final int CUVS_ERROR = (int) 0L; + + /** + * {@snippet lang = c : * enum .CUVS_ERROR = 0 + * } + */ + public static int CUVS_ERROR() { + return CUVS_ERROR; + } + + private static final int CUVS_SUCCESS = (int) 1L; + + /** + * {@snippet lang = c : * enum .CUVS_SUCCESS = 1 + * } + */ + public static int CUVS_SUCCESS() { + return CUVS_SUCCESS; + } + + /** + * {@snippet lang = c : * typedef uintptr_t cuvsResources_t + * } + */ + public static final OfLong cuvsResources_t = IvfPqH.C_LONG; + private static final int L2Expanded = (int) 0L; + + /** + * {@snippet lang = c : * enum .L2Expanded = 0 + * } + */ + public static int L2Expanded() { + return L2Expanded; + } + + private static final int L2SqrtExpanded = (int) 1L; + + /** + * {@snippet lang = c : * enum .L2SqrtExpanded = 1 + * } + */ + public static int L2SqrtExpanded() { + return L2SqrtExpanded; + } + + private static final int CosineExpanded = (int) 2L; + + /** + * {@snippet lang = c : * enum .CosineExpanded = 2 + * } + */ + public static int CosineExpanded() { + return CosineExpanded; + } + + private static final int L1 = (int) 3L; + + /** + * {@snippet lang = c : * enum .L1 = 3 + * } + */ + public static int L1() { + return L1; + } + + private static final int L2Unexpanded = (int) 4L; + + /** + * {@snippet lang = c : * enum .L2Unexpanded = 4 + * } + */ + public static int L2Unexpanded() { + return L2Unexpanded; + } + + private static final int L2SqrtUnexpanded = (int) 5L; + + /** + * {@snippet lang = c : * enum .L2SqrtUnexpanded = 5 + * } + */ + public static int L2SqrtUnexpanded() { + return L2SqrtUnexpanded; + } + + private static final int InnerProduct = (int) 6L; + + /** + * {@snippet lang = c : * enum .InnerProduct = 6 + * } + */ + public static int InnerProduct() { + return InnerProduct; + } + + private static final int Linf = (int) 7L; + + /** + * {@snippet lang = c : * enum .Linf = 7 + * } + */ + public static int Linf() { + return Linf; + } + + private static final int Canberra = (int) 8L; + + /** + * {@snippet lang = c : * enum .Canberra = 8 + * } + */ + public static int Canberra() { + return Canberra; + } + + private static final int LpUnexpanded = (int) 9L; + + /** + * {@snippet lang = c : * enum .LpUnexpanded = 9 + * } + */ + public static int LpUnexpanded() { + return LpUnexpanded; + } + + private static final int CorrelationExpanded = (int) 10L; + + /** + * {@snippet lang = c : * enum .CorrelationExpanded = 10 + * } + */ + public static int CorrelationExpanded() { + return CorrelationExpanded; + } + + private static final int JaccardExpanded = (int) 11L; + + /** + * {@snippet lang = c : * enum .JaccardExpanded = 11 + * } + */ + public static int JaccardExpanded() { + return JaccardExpanded; + } + + private static final int HellingerExpanded = (int) 12L; + + /** + * {@snippet lang = c : * enum .HellingerExpanded = 12 + * } + */ + public static int HellingerExpanded() { + return HellingerExpanded; + } + + private static final int Haversine = (int) 13L; + + /** + * {@snippet lang = c : * enum .Haversine = 13 + * } + */ + public static int Haversine() { + return Haversine; + } + + private static final int BrayCurtis = (int) 14L; + + /** + * {@snippet lang = c : * enum .BrayCurtis = 14 + * } + */ + public static int BrayCurtis() { + return BrayCurtis; + } + + private static final int JensenShannon = (int) 15L; + + /** + * {@snippet lang = c : * enum .JensenShannon = 15 + * } + */ + public static int JensenShannon() { + return JensenShannon; + } + + private static final int HammingUnexpanded = (int) 16L; + + /** + * {@snippet lang = c : * enum .HammingUnexpanded = 16 + * } + */ + public static int HammingUnexpanded() { + return HammingUnexpanded; + } + + private static final int KLDivergence = (int) 17L; + + /** + * {@snippet lang = c : * enum .KLDivergence = 17 + * } + */ + public static int KLDivergence() { + return KLDivergence; + } + + private static final int RusselRaoExpanded = (int) 18L; + + /** + * {@snippet lang = c : * enum .RusselRaoExpanded = 18 + * } + */ + public static int RusselRaoExpanded() { + return RusselRaoExpanded; + } + + private static final int DiceExpanded = (int) 19L; + + /** + * {@snippet lang = c : * enum .DiceExpanded = 19 + * } + */ + public static int DiceExpanded() { + return DiceExpanded; + } + + private static final int Precomputed = (int) 100L; + + /** + * {@snippet lang = c : * enum .Precomputed = 100 + * } + */ + public static int Precomputed() { + return Precomputed; + } + + /** + * {@snippet lang = c : * typedef long ptrdiff_t + * } + */ + public static final OfLong ptrdiff_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef unsigned long size_t + * } + */ + public static final OfLong size_t = IvfPqH.C_LONG; + /** + * {@snippet lang = c : * typedef int wchar_t + * } + */ + public static final OfInt wchar_t = IvfPqH.C_INT; + private static final int kDLCPU = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLCPU = 1 + * } + */ + public static int kDLCPU() { + return kDLCPU; + } + + private static final int kDLCUDA = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLCUDA = 2 + * } + */ + public static int kDLCUDA() { + return kDLCUDA; + } + + private static final int kDLCUDAHost = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLCUDAHost = 3 + * } + */ + public static int kDLCUDAHost() { + return kDLCUDAHost; + } + + private static final int kDLOpenCL = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLOpenCL = 4 + * } + */ + public static int kDLOpenCL() { + return kDLOpenCL; + } + + private static final int kDLVulkan = (int) 7L; + + /** + * {@snippet lang = c : * enum .kDLVulkan = 7 + * } + */ + public static int kDLVulkan() { + return kDLVulkan; + } + + private static final int kDLMetal = (int) 8L; + + /** + * {@snippet lang = c : * enum .kDLMetal = 8 + * } + */ + public static int kDLMetal() { + return kDLMetal; + } + + private static final int kDLVPI = (int) 9L; + + /** + * {@snippet lang = c : * enum .kDLVPI = 9 + * } + */ + public static int kDLVPI() { + return kDLVPI; + } + + private static final int kDLROCM = (int) 10L; + + /** + * {@snippet lang = c : * enum .kDLROCM = 10 + * } + */ + public static int kDLROCM() { + return kDLROCM; + } + + private static final int kDLROCMHost = (int) 11L; + + /** + * {@snippet lang = c : * enum .kDLROCMHost = 11 + * } + */ + public static int kDLROCMHost() { + return kDLROCMHost; + } + + private static final int kDLExtDev = (int) 12L; + + /** + * {@snippet lang = c : * enum .kDLExtDev = 12 + * } + */ + public static int kDLExtDev() { + return kDLExtDev; + } + + private static final int kDLCUDAManaged = (int) 13L; + + /** + * {@snippet lang = c : * enum .kDLCUDAManaged = 13 + * } + */ + public static int kDLCUDAManaged() { + return kDLCUDAManaged; + } + + private static final int kDLOneAPI = (int) 14L; + + /** + * {@snippet lang = c : * enum .kDLOneAPI = 14 + * } + */ + public static int kDLOneAPI() { + return kDLOneAPI; + } + + private static final int kDLWebGPU = (int) 15L; + + /** + * {@snippet lang = c : * enum .kDLWebGPU = 15 + * } + */ + public static int kDLWebGPU() { + return kDLWebGPU; + } + + private static final int kDLHexagon = (int) 16L; + + /** + * {@snippet lang = c : * enum .kDLHexagon = 16 + * } + */ + public static int kDLHexagon() { + return kDLHexagon; + } + + private static final int kDLMAIA = (int) 17L; + + /** + * {@snippet lang = c : * enum .kDLMAIA = 17 + * } + */ + public static int kDLMAIA() { + return kDLMAIA; + } + + private static final int kDLInt = (int) 0L; + + /** + * {@snippet lang = c : * enum .kDLInt = 0 + * } + */ + public static int kDLInt() { + return kDLInt; + } + + private static final int kDLUInt = (int) 1L; + + /** + * {@snippet lang = c : * enum .kDLUInt = 1 + * } + */ + public static int kDLUInt() { + return kDLUInt; + } + + private static final int kDLFloat = (int) 2L; + + /** + * {@snippet lang = c : * enum .kDLFloat = 2 + * } + */ + public static int kDLFloat() { + return kDLFloat; + } + + private static final int kDLOpaqueHandle = (int) 3L; + + /** + * {@snippet lang = c : * enum .kDLOpaqueHandle = 3 + * } + */ + public static int kDLOpaqueHandle() { + return kDLOpaqueHandle; + } + + private static final int kDLBfloat = (int) 4L; + + /** + * {@snippet lang = c : * enum .kDLBfloat = 4 + * } + */ + public static int kDLBfloat() { + return kDLBfloat; + } + + private static final int kDLComplex = (int) 5L; + + /** + * {@snippet lang = c : * enum .kDLComplex = 5 + * } + */ + public static int kDLComplex() { + return kDLComplex; + } + + private static final int kDLBool = (int) 6L; + + /** + * {@snippet lang = c : * enum .kDLBool = 6 + * } + */ + public static int kDLBool() { + return kDLBool; + } + + private static final int CUDA_R_16F = (int) 2L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_16F = 2 + * } + */ + public static int CUDA_R_16F() { + return CUDA_R_16F; + } + + private static final int CUDA_C_16F = (int) 6L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_16F = 6 + * } + */ + public static int CUDA_C_16F() { + return CUDA_C_16F; + } + + private static final int CUDA_R_16BF = (int) 14L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_16BF = 14 + * } + */ + public static int CUDA_R_16BF() { + return CUDA_R_16BF; + } + + private static final int CUDA_C_16BF = (int) 15L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_16BF = 15 + * } + */ + public static int CUDA_C_16BF() { + return CUDA_C_16BF; + } + + private static final int CUDA_R_32F = (int) 0L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_32F = 0 + * } + */ + public static int CUDA_R_32F() { + return CUDA_R_32F; + } + + private static final int CUDA_C_32F = (int) 4L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_32F = 4 + * } + */ + public static int CUDA_C_32F() { + return CUDA_C_32F; + } + + private static final int CUDA_R_64F = (int) 1L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_64F = 1 + * } + */ + public static int CUDA_R_64F() { + return CUDA_R_64F; + } + + private static final int CUDA_C_64F = (int) 5L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_64F = 5 + * } + */ + public static int CUDA_C_64F() { + return CUDA_C_64F; + } + + private static final int CUDA_R_4I = (int) 16L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_4I = 16 + * } + */ + public static int CUDA_R_4I() { + return CUDA_R_4I; + } + + private static final int CUDA_C_4I = (int) 17L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_4I = 17 + * } + */ + public static int CUDA_C_4I() { + return CUDA_C_4I; + } + + private static final int CUDA_R_4U = (int) 18L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_4U = 18 + * } + */ + public static int CUDA_R_4U() { + return CUDA_R_4U; + } + + private static final int CUDA_C_4U = (int) 19L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_4U = 19 + * } + */ + public static int CUDA_C_4U() { + return CUDA_C_4U; + } + + private static final int CUDA_R_8I = (int) 3L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_8I = 3 + * } + */ + public static int CUDA_R_8I() { + return CUDA_R_8I; + } + + private static final int CUDA_C_8I = (int) 7L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_8I = 7 + * } + */ + public static int CUDA_C_8I() { + return CUDA_C_8I; + } + + private static final int CUDA_R_8U = (int) 8L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_8U = 8 + * } + */ + public static int CUDA_R_8U() { + return CUDA_R_8U; + } + + private static final int CUDA_C_8U = (int) 9L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_8U = 9 + * } + */ + public static int CUDA_C_8U() { + return CUDA_C_8U; + } + + private static final int CUDA_R_16I = (int) 20L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_16I = 20 + * } + */ + public static int CUDA_R_16I() { + return CUDA_R_16I; + } + + private static final int CUDA_C_16I = (int) 21L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_16I = 21 + * } + */ + public static int CUDA_C_16I() { + return CUDA_C_16I; + } + + private static final int CUDA_R_16U = (int) 22L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_16U = 22 + * } + */ + public static int CUDA_R_16U() { + return CUDA_R_16U; + } + + private static final int CUDA_C_16U = (int) 23L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_16U = 23 + * } + */ + public static int CUDA_C_16U() { + return CUDA_C_16U; + } + + private static final int CUDA_R_32I = (int) 10L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_32I = 10 + * } + */ + public static int CUDA_R_32I() { + return CUDA_R_32I; + } + + private static final int CUDA_C_32I = (int) 11L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_32I = 11 + * } + */ + public static int CUDA_C_32I() { + return CUDA_C_32I; + } + + private static final int CUDA_R_32U = (int) 12L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_32U = 12 + * } + */ + public static int CUDA_R_32U() { + return CUDA_R_32U; + } + + private static final int CUDA_C_32U = (int) 13L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_32U = 13 + * } + */ + public static int CUDA_C_32U() { + return CUDA_C_32U; + } + + private static final int CUDA_R_64I = (int) 24L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_64I = 24 + * } + */ + public static int CUDA_R_64I() { + return CUDA_R_64I; + } + + private static final int CUDA_C_64I = (int) 25L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_64I = 25 + * } + */ + public static int CUDA_C_64I() { + return CUDA_C_64I; + } + + private static final int CUDA_R_64U = (int) 26L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_R_64U = 26 + * } + */ + public static int CUDA_R_64U() { + return CUDA_R_64U; + } + + private static final int CUDA_C_64U = (int) 27L; + + /** + * {@snippet lang = c : * enum cudaDataType_t.CUDA_C_64U = 27 + * } + */ + public static int CUDA_C_64U() { + return CUDA_C_64U; + } + + private static final int MAJOR_VERSION = (int) 0L; + + /** + * {@snippet lang = c : * enum libraryPropertyType_t.MAJOR_VERSION = 0 + * } + */ + public static int MAJOR_VERSION() { + return MAJOR_VERSION; + } + + private static final int MINOR_VERSION = (int) 1L; + + /** + * {@snippet lang = c : * enum libraryPropertyType_t.MINOR_VERSION = 1 + * } + */ + public static int MINOR_VERSION() { + return MINOR_VERSION; + } + + private static final int PATCH_LEVEL = (int) 2L; + + /** + * {@snippet lang = c : * enum libraryPropertyType_t.PATCH_LEVEL = 2 + * } + */ + public static int PATCH_LEVEL() { + return PATCH_LEVEL; + } + + private static final int PER_SUBSPACE = (int) 0L; + + /** + * {@snippet lang = c : * enum codebook_gen.PER_SUBSPACE = 0 + * } + */ + public static int PER_SUBSPACE() { + return PER_SUBSPACE; + } + + private static final int PER_CLUSTER = (int) 1L; + + /** + * {@snippet lang = c : * enum codebook_gen.PER_CLUSTER = 1 + * } + */ + public static int PER_CLUSTER() { + return PER_CLUSTER; + } + + /** + * {@snippet lang = c : + * typedef struct cuvsIvfPqIndexParams { + * cuvsDistanceType metric; + * float metric_arg; + * _Bool add_data_on_build; + * uint32_t n_lists; + * uint32_t kmeans_n_iters; + * double kmeans_trainset_fraction; + * uint32_t pq_bits; + * uint32_t pq_dim; + * enum codebook_gen codebook_kind; + * _Bool force_random_rotation; + * _Bool conservative_memory_allocation; + * uint32_t max_train_points_per_pq_code; + * } *cuvsIvfPqIndexParams_t + * } + */ + public static final AddressLayout cuvsIvfPqIndexParams_t = IvfPqH.C_POINTER; + + private static class cuvsIvfPqIndexParamsCreate { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqIndexParamsCreate"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsCreate(cuvsIvfPqIndexParams_t *index_params) + * } + */ + public static FunctionDescriptor cuvsIvfPqIndexParamsCreate$descriptor() { + return cuvsIvfPqIndexParamsCreate.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsCreate(cuvsIvfPqIndexParams_t *index_params) + * } + */ + public static MethodHandle cuvsIvfPqIndexParamsCreate$handle() { + return cuvsIvfPqIndexParamsCreate.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsCreate(cuvsIvfPqIndexParams_t *index_params) + * } + */ + public static MemorySegment cuvsIvfPqIndexParamsCreate$address() { + return cuvsIvfPqIndexParamsCreate.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsCreate(cuvsIvfPqIndexParams_t *index_params) + * } + */ + public static int cuvsIvfPqIndexParamsCreate(MemorySegment index_params) { + var mh$ = cuvsIvfPqIndexParamsCreate.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqIndexParamsCreate", index_params); + } + return (int) mh$.invokeExact(index_params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqIndexParamsDestroy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqIndexParamsDestroy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsDestroy(cuvsIvfPqIndexParams_t index_params) + * } + */ + public static FunctionDescriptor cuvsIvfPqIndexParamsDestroy$descriptor() { + return cuvsIvfPqIndexParamsDestroy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsDestroy(cuvsIvfPqIndexParams_t index_params) + * } + */ + public static MethodHandle cuvsIvfPqIndexParamsDestroy$handle() { + return cuvsIvfPqIndexParamsDestroy.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsDestroy(cuvsIvfPqIndexParams_t index_params) + * } + */ + public static MemorySegment cuvsIvfPqIndexParamsDestroy$address() { + return cuvsIvfPqIndexParamsDestroy.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexParamsDestroy(cuvsIvfPqIndexParams_t index_params) + * } + */ + public static int cuvsIvfPqIndexParamsDestroy(MemorySegment index_params) { + var mh$ = cuvsIvfPqIndexParamsDestroy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqIndexParamsDestroy", index_params); + } + return (int) mh$.invokeExact(index_params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + /** + * {@snippet lang = c : + * typedef struct cuvsIvfPqSearchParams { + * uint32_t n_probes; + * cudaDataType_t lut_dtype; + * cudaDataType_t internal_distance_dtype; + * double preferred_shmem_carveout; + * } *cuvsIvfPqSearchParams_t + * } + */ + public static final AddressLayout cuvsIvfPqSearchParams_t = IvfPqH.C_POINTER; + + private static class cuvsIvfPqSearchParamsCreate { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqSearchParamsCreate"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsCreate(cuvsIvfPqSearchParams_t *params) + * } + */ + public static FunctionDescriptor cuvsIvfPqSearchParamsCreate$descriptor() { + return cuvsIvfPqSearchParamsCreate.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsCreate(cuvsIvfPqSearchParams_t *params) + * } + */ + public static MethodHandle cuvsIvfPqSearchParamsCreate$handle() { + return cuvsIvfPqSearchParamsCreate.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsCreate(cuvsIvfPqSearchParams_t *params) + * } + */ + public static MemorySegment cuvsIvfPqSearchParamsCreate$address() { + return cuvsIvfPqSearchParamsCreate.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsCreate(cuvsIvfPqSearchParams_t *params) + * } + */ + public static int cuvsIvfPqSearchParamsCreate(MemorySegment params) { + var mh$ = cuvsIvfPqSearchParamsCreate.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqSearchParamsCreate", params); + } + return (int) mh$.invokeExact(params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqSearchParamsDestroy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqSearchParamsDestroy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsDestroy(cuvsIvfPqSearchParams_t params) + * } + */ + public static FunctionDescriptor cuvsIvfPqSearchParamsDestroy$descriptor() { + return cuvsIvfPqSearchParamsDestroy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsDestroy(cuvsIvfPqSearchParams_t params) + * } + */ + public static MethodHandle cuvsIvfPqSearchParamsDestroy$handle() { + return cuvsIvfPqSearchParamsDestroy.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsDestroy(cuvsIvfPqSearchParams_t params) + * } + */ + public static MemorySegment cuvsIvfPqSearchParamsDestroy$address() { + return cuvsIvfPqSearchParamsDestroy.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearchParamsDestroy(cuvsIvfPqSearchParams_t params) + * } + */ + public static int cuvsIvfPqSearchParamsDestroy(MemorySegment params) { + var mh$ = cuvsIvfPqSearchParamsDestroy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqSearchParamsDestroy", params); + } + return (int) mh$.invokeExact(params); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + /** + * {@snippet lang = c : * typedef cuvsIvfPq *cuvsIvfPqIndex_t + * } + */ + public static final AddressLayout cuvsIvfPqIndex_t = IvfPqH.C_POINTER; + + private static class cuvsIvfPqIndexCreate { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqIndexCreate"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexCreate(cuvsIvfPqIndex_t *index) + * } + */ + public static FunctionDescriptor cuvsIvfPqIndexCreate$descriptor() { + return cuvsIvfPqIndexCreate.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexCreate(cuvsIvfPqIndex_t *index) + * } + */ + public static MethodHandle cuvsIvfPqIndexCreate$handle() { + return cuvsIvfPqIndexCreate.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexCreate(cuvsIvfPqIndex_t *index) + * } + */ + public static MemorySegment cuvsIvfPqIndexCreate$address() { + return cuvsIvfPqIndexCreate.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexCreate(cuvsIvfPqIndex_t *index) + * } + */ + public static int cuvsIvfPqIndexCreate(MemorySegment index) { + var mh$ = cuvsIvfPqIndexCreate.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqIndexCreate", index); + } + return (int) mh$.invokeExact(index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqIndexDestroy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqIndexDestroy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexDestroy(cuvsIvfPqIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfPqIndexDestroy$descriptor() { + return cuvsIvfPqIndexDestroy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexDestroy(cuvsIvfPqIndex_t index) + * } + */ + public static MethodHandle cuvsIvfPqIndexDestroy$handle() { + return cuvsIvfPqIndexDestroy.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexDestroy(cuvsIvfPqIndex_t index) + * } + */ + public static MemorySegment cuvsIvfPqIndexDestroy$address() { + return cuvsIvfPqIndexDestroy.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqIndexDestroy(cuvsIvfPqIndex_t index) + * } + */ + public static int cuvsIvfPqIndexDestroy(MemorySegment index) { + var mh$ = cuvsIvfPqIndexDestroy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqIndexDestroy", index); + } + return (int) mh$.invokeExact(index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqBuild { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_LONG, + IvfPqH.C_POINTER, IvfPqH.C_POINTER, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqBuild"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqBuild(cuvsResources_t res, cuvsIvfPqIndexParams_t params, DLManagedTensor *dataset, cuvsIvfPqIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfPqBuild$descriptor() { + return cuvsIvfPqBuild.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqBuild(cuvsResources_t res, cuvsIvfPqIndexParams_t params, DLManagedTensor *dataset, cuvsIvfPqIndex_t index) + * } + */ + public static MethodHandle cuvsIvfPqBuild$handle() { + return cuvsIvfPqBuild.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqBuild(cuvsResources_t res, cuvsIvfPqIndexParams_t params, DLManagedTensor *dataset, cuvsIvfPqIndex_t index) + * } + */ + public static MemorySegment cuvsIvfPqBuild$address() { + return cuvsIvfPqBuild.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqBuild(cuvsResources_t res, cuvsIvfPqIndexParams_t params, DLManagedTensor *dataset, cuvsIvfPqIndex_t index) + * } + */ + public static int cuvsIvfPqBuild(long res, MemorySegment params, MemorySegment dataset, MemorySegment index) { + var mh$ = cuvsIvfPqBuild.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqBuild", res, params, dataset, index); + } + return (int) mh$.invokeExact(res, params, dataset, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqSearch { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_LONG, + IvfPqH.C_POINTER, IvfPqH.C_POINTER, IvfPqH.C_POINTER, IvfPqH.C_POINTER, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqSearch"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearch(cuvsResources_t res, cuvsIvfPqSearchParams_t search_params, cuvsIvfPqIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static FunctionDescriptor cuvsIvfPqSearch$descriptor() { + return cuvsIvfPqSearch.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearch(cuvsResources_t res, cuvsIvfPqSearchParams_t search_params, cuvsIvfPqIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static MethodHandle cuvsIvfPqSearch$handle() { + return cuvsIvfPqSearch.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearch(cuvsResources_t res, cuvsIvfPqSearchParams_t search_params, cuvsIvfPqIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static MemorySegment cuvsIvfPqSearch$address() { + return cuvsIvfPqSearch.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSearch(cuvsResources_t res, cuvsIvfPqSearchParams_t search_params, cuvsIvfPqIndex_t index, DLManagedTensor *queries, DLManagedTensor *neighbors, DLManagedTensor *distances) + * } + */ + public static int cuvsIvfPqSearch(long res, MemorySegment search_params, MemorySegment index, MemorySegment queries, + MemorySegment neighbors, MemorySegment distances) { + var mh$ = cuvsIvfPqSearch.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqSearch", res, search_params, index, queries, neighbors, distances); + } + return (int) mh$.invokeExact(res, search_params, index, queries, neighbors, distances); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqSerialize { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_LONG, + IvfPqH.C_POINTER, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqSerialize"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSerialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfPqSerialize$descriptor() { + return cuvsIvfPqSerialize.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSerialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static MethodHandle cuvsIvfPqSerialize$handle() { + return cuvsIvfPqSerialize.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSerialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static MemorySegment cuvsIvfPqSerialize$address() { + return cuvsIvfPqSerialize.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqSerialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static int cuvsIvfPqSerialize(long res, MemorySegment filename, MemorySegment index) { + var mh$ = cuvsIvfPqSerialize.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqSerialize", res, filename, index); + } + return (int) mh$.invokeExact(res, filename, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqDeserialize { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_LONG, + IvfPqH.C_POINTER, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqDeserialize"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqDeserialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfPqDeserialize$descriptor() { + return cuvsIvfPqDeserialize.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqDeserialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static MethodHandle cuvsIvfPqDeserialize$handle() { + return cuvsIvfPqDeserialize.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqDeserialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static MemorySegment cuvsIvfPqDeserialize$address() { + return cuvsIvfPqDeserialize.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqDeserialize(cuvsResources_t res, const char *filename, cuvsIvfPqIndex_t index) + * } + */ + public static int cuvsIvfPqDeserialize(long res, MemorySegment filename, MemorySegment index) { + var mh$ = cuvsIvfPqDeserialize.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqDeserialize", res, filename, index); + } + return (int) mh$.invokeExact(res, filename, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class cuvsIvfPqExtend { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(IvfPqH.C_INT, IvfPqH.C_LONG, + IvfPqH.C_POINTER, IvfPqH.C_POINTER, IvfPqH.C_POINTER); + + public static final MemorySegment ADDR = IvfPqH.findOrThrow("cuvsIvfPqExtend"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfPqIndex_t index) + * } + */ + public static FunctionDescriptor cuvsIvfPqExtend$descriptor() { + return cuvsIvfPqExtend.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfPqIndex_t index) + * } + */ + public static MethodHandle cuvsIvfPqExtend$handle() { + return cuvsIvfPqExtend.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfPqIndex_t index) + * } + */ + public static MemorySegment cuvsIvfPqExtend$address() { + return cuvsIvfPqExtend.ADDR; + } + + /** + * {@snippet lang = c + * : * cuvsError_t cuvsIvfPqExtend(cuvsResources_t res, DLManagedTensor *new_vectors, DLManagedTensor *new_indices, cuvsIvfPqIndex_t index) + * } + */ + public static int cuvsIvfPqExtend(long res, MemorySegment new_vectors, MemorySegment new_indices, + MemorySegment index) { + var mh$ = cuvsIvfPqExtend.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("cuvsIvfPqExtend", res, new_vectors, new_indices, index); + } + return (int) mh$.invokeExact(res, new_vectors, new_indices, index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static final long _POSIX_C_SOURCE = 200809L; + + /** + * {@snippet lang = c : * #define _POSIX_C_SOURCE 200809 + * } + */ + public static long _POSIX_C_SOURCE() { + return _POSIX_C_SOURCE; + } + + private static final int __TIMESIZE = (int) 64L; + + /** + * {@snippet lang = c : * #define __TIMESIZE 64 + * } + */ + public static int __TIMESIZE() { + return __TIMESIZE; + } + + private static final long __STDC_IEC_60559_BFP__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_BFP__ 201404 + * } + */ + public static long __STDC_IEC_60559_BFP__() { + return __STDC_IEC_60559_BFP__; + } + + private static final long __STDC_IEC_60559_COMPLEX__ = 201404L; + + /** + * {@snippet lang = c : * #define __STDC_IEC_60559_COMPLEX__ 201404 + * } + */ + public static long __STDC_IEC_60559_COMPLEX__() { + return __STDC_IEC_60559_COMPLEX__; + } + + private static final long __STDC_ISO_10646__ = 201706L; + + /** + * {@snippet lang = c : * #define __STDC_ISO_10646__ 201706 + * } + */ + public static long __STDC_ISO_10646__() { + return __STDC_ISO_10646__; + } + + private static final int __WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define __WCHAR_MAX 2147483647 + * } + */ + public static int __WCHAR_MAX() { + return __WCHAR_MAX; + } + + private static final int __WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define __WCHAR_MIN -2147483648 + * } + */ + public static int __WCHAR_MIN() { + return __WCHAR_MIN; + } + + private static final int INT8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT8_MIN -128 + * } + */ + public static int INT8_MIN() { + return INT8_MIN; + } + + private static final int INT16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT16_MIN -32768 + * } + */ + public static int INT16_MIN() { + return INT16_MIN; + } + + private static final int INT32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT32_MIN -2147483648 + * } + */ + public static int INT32_MIN() { + return INT32_MIN; + } + + private static final long INT64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT64_MIN -9223372036854775808 + * } + */ + public static long INT64_MIN() { + return INT64_MIN; + } + + private static final int INT8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT8_MAX 127 + * } + */ + public static int INT8_MAX() { + return INT8_MAX; + } + + private static final int INT16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT16_MAX 32767 + * } + */ + public static int INT16_MAX() { + return INT16_MAX; + } + + private static final int INT32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT32_MAX 2147483647 + * } + */ + public static int INT32_MAX() { + return INT32_MAX; + } + + private static final long INT64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT64_MAX 9223372036854775807 + * } + */ + public static long INT64_MAX() { + return INT64_MAX; + } + + private static final int UINT8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT8_MAX 255 + * } + */ + public static int UINT8_MAX() { + return UINT8_MAX; + } + + private static final int UINT16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT16_MAX 65535 + * } + */ + public static int UINT16_MAX() { + return UINT16_MAX; + } + + private static final int UINT32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT32_MAX 4294967295 + * } + */ + public static int UINT32_MAX() { + return UINT32_MAX; + } + + private static final long UINT64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT64_MAX -1 + * } + */ + public static long UINT64_MAX() { + return UINT64_MAX; + } + + private static final int INT_LEAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MIN -128 + * } + */ + public static int INT_LEAST8_MIN() { + return INT_LEAST8_MIN; + } + + private static final int INT_LEAST16_MIN = (int) -32768L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MIN -32768 + * } + */ + public static int INT_LEAST16_MIN() { + return INT_LEAST16_MIN; + } + + private static final int INT_LEAST32_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MIN -2147483648 + * } + */ + public static int INT_LEAST32_MIN() { + return INT_LEAST32_MIN; + } + + private static final long INT_LEAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MIN -9223372036854775808 + * } + */ + public static long INT_LEAST64_MIN() { + return INT_LEAST64_MIN; + } + + private static final int INT_LEAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_LEAST8_MAX 127 + * } + */ + public static int INT_LEAST8_MAX() { + return INT_LEAST8_MAX; + } + + private static final int INT_LEAST16_MAX = (int) 32767L; + + /** + * {@snippet lang = c : * #define INT_LEAST16_MAX 32767 + * } + */ + public static int INT_LEAST16_MAX() { + return INT_LEAST16_MAX; + } + + private static final int INT_LEAST32_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define INT_LEAST32_MAX 2147483647 + * } + */ + public static int INT_LEAST32_MAX() { + return INT_LEAST32_MAX; + } + + private static final long INT_LEAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_LEAST64_MAX 9223372036854775807 + * } + */ + public static long INT_LEAST64_MAX() { + return INT_LEAST64_MAX; + } + + private static final int UINT_LEAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_LEAST8_MAX 255 + * } + */ + public static int UINT_LEAST8_MAX() { + return UINT_LEAST8_MAX; + } + + private static final int UINT_LEAST16_MAX = (int) 65535L; + + /** + * {@snippet lang = c : * #define UINT_LEAST16_MAX 65535 + * } + */ + public static int UINT_LEAST16_MAX() { + return UINT_LEAST16_MAX; + } + + private static final int UINT_LEAST32_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define UINT_LEAST32_MAX 4294967295 + * } + */ + public static int UINT_LEAST32_MAX() { + return UINT_LEAST32_MAX; + } + + private static final long UINT_LEAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_LEAST64_MAX -1 + * } + */ + public static long UINT_LEAST64_MAX() { + return UINT_LEAST64_MAX; + } + + private static final int INT_FAST8_MIN = (int) -128L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MIN -128 + * } + */ + public static int INT_FAST8_MIN() { + return INT_FAST8_MIN; + } + + private static final long INT_FAST16_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MIN -9223372036854775808 + * } + */ + public static long INT_FAST16_MIN() { + return INT_FAST16_MIN; + } + + private static final long INT_FAST32_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MIN -9223372036854775808 + * } + */ + public static long INT_FAST32_MIN() { + return INT_FAST32_MIN; + } + + private static final long INT_FAST64_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MIN -9223372036854775808 + * } + */ + public static long INT_FAST64_MIN() { + return INT_FAST64_MIN; + } + + private static final int INT_FAST8_MAX = (int) 127L; + + /** + * {@snippet lang = c : * #define INT_FAST8_MAX 127 + * } + */ + public static int INT_FAST8_MAX() { + return INT_FAST8_MAX; + } + + private static final long INT_FAST16_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST16_MAX 9223372036854775807 + * } + */ + public static long INT_FAST16_MAX() { + return INT_FAST16_MAX; + } + + private static final long INT_FAST32_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST32_MAX 9223372036854775807 + * } + */ + public static long INT_FAST32_MAX() { + return INT_FAST32_MAX; + } + + private static final long INT_FAST64_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INT_FAST64_MAX 9223372036854775807 + * } + */ + public static long INT_FAST64_MAX() { + return INT_FAST64_MAX; + } + + private static final int UINT_FAST8_MAX = (int) 255L; + + /** + * {@snippet lang = c : * #define UINT_FAST8_MAX 255 + * } + */ + public static int UINT_FAST8_MAX() { + return UINT_FAST8_MAX; + } + + private static final long UINT_FAST16_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST16_MAX -1 + * } + */ + public static long UINT_FAST16_MAX() { + return UINT_FAST16_MAX; + } + + private static final long UINT_FAST32_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST32_MAX -1 + * } + */ + public static long UINT_FAST32_MAX() { + return UINT_FAST32_MAX; + } + + private static final long UINT_FAST64_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINT_FAST64_MAX -1 + * } + */ + public static long UINT_FAST64_MAX() { + return UINT_FAST64_MAX; + } + + private static final long INTPTR_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTPTR_MIN -9223372036854775808 + * } + */ + public static long INTPTR_MIN() { + return INTPTR_MIN; + } + + private static final long INTPTR_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTPTR_MAX 9223372036854775807 + * } + */ + public static long INTPTR_MAX() { + return INTPTR_MAX; + } + + private static final long UINTPTR_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTPTR_MAX -1 + * } + */ + public static long UINTPTR_MAX() { + return UINTPTR_MAX; + } + + private static final long INTMAX_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define INTMAX_MIN -9223372036854775808 + * } + */ + public static long INTMAX_MIN() { + return INTMAX_MIN; + } + + private static final long INTMAX_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define INTMAX_MAX 9223372036854775807 + * } + */ + public static long INTMAX_MAX() { + return INTMAX_MAX; + } + + private static final long UINTMAX_MAX = -1L; + + /** + * {@snippet lang = c : * #define UINTMAX_MAX -1 + * } + */ + public static long UINTMAX_MAX() { + return UINTMAX_MAX; + } + + private static final long PTRDIFF_MIN = -9223372036854775808L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MIN -9223372036854775808 + * } + */ + public static long PTRDIFF_MIN() { + return PTRDIFF_MIN; + } + + private static final long PTRDIFF_MAX = 9223372036854775807L; + + /** + * {@snippet lang = c : * #define PTRDIFF_MAX 9223372036854775807 + * } + */ + public static long PTRDIFF_MAX() { + return PTRDIFF_MAX; + } + + private static final int SIG_ATOMIC_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MIN -2147483648 + * } + */ + public static int SIG_ATOMIC_MIN() { + return SIG_ATOMIC_MIN; + } + + private static final int SIG_ATOMIC_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define SIG_ATOMIC_MAX 2147483647 + * } + */ + public static int SIG_ATOMIC_MAX() { + return SIG_ATOMIC_MAX; + } + + private static final long SIZE_MAX = -1L; + + /** + * {@snippet lang = c : * #define SIZE_MAX -1 + * } + */ + public static long SIZE_MAX() { + return SIZE_MAX; + } + + private static final int WCHAR_MIN = (int) -2147483648L; + + /** + * {@snippet lang = c : * #define WCHAR_MIN -2147483648 + * } + */ + public static int WCHAR_MIN() { + return WCHAR_MIN; + } + + private static final int WCHAR_MAX = (int) 2147483647L; + + /** + * {@snippet lang = c : * #define WCHAR_MAX 2147483647 + * } + */ + public static int WCHAR_MAX() { + return WCHAR_MAX; + } + + private static final int WINT_MIN = (int) 0L; + + /** + * {@snippet lang = c : * #define WINT_MIN 0 + * } + */ + public static int WINT_MIN() { + return WINT_MIN; + } + + private static final int WINT_MAX = (int) 4294967295L; + + /** + * {@snippet lang = c : * #define WINT_MAX 4294967295 + * } + */ + public static int WINT_MAX() { + return WINT_MAX; + } + + private static final MemorySegment NULL = MemorySegment.ofAddress(0L); + + /** + * {@snippet lang = c : * #define NULL (void*) 0 + * } + */ + public static MemorySegment NULL() { + return NULL; + } + + private static final long DLPACK_FLAG_BITMASK_READ_ONLY = 1L; + + /** + * {@snippet lang = c : * #define DLPACK_FLAG_BITMASK_READ_ONLY 1 + * } + */ + public static long DLPACK_FLAG_BITMASK_READ_ONLY() { + return DLPACK_FLAG_BITMASK_READ_ONLY; + } + + private static final long DLPACK_FLAG_BITMASK_IS_COPIED = 2L; + + /** + * {@snippet lang = c : * #define DLPACK_FLAG_BITMASK_IS_COPIED 2 + * } + */ + public static long DLPACK_FLAG_BITMASK_IS_COPIED() { + return DLPACK_FLAG_BITMASK_IS_COPIED; + } +} diff --git a/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/MaxAlignT.java b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/MaxAlignT.java new file mode 100644 index 000000000..1216df6f7 --- /dev/null +++ b/java/cuvs-java/src/main/java/com/nvidia/cuvs/panama/MaxAlignT.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs.panama; + +import static java.lang.foreign.MemoryLayout.PathElement.groupElement; + +import java.lang.foreign.Arena; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.ValueLayout.OfLong; +import java.util.function.Consumer; + +/** + * {@snippet lang=c : + * struct { + * long long __clang_max_align_nonce1; + * long double __clang_max_align_nonce2; + * } + * } + */ +public class MaxAlignT { + + MaxAlignT() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + DlpackH.C_LONG_LONG.withName("__clang_max_align_nonce1"), + MemoryLayout.paddingLayout(24) + ).withName("$anon$19:9"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfLong __clang_max_align_nonce1$LAYOUT = (OfLong)$LAYOUT.select(groupElement("__clang_max_align_nonce1")); + + /** + * Layout for field: + * {@snippet lang=c : + * long long __clang_max_align_nonce1 + * } + */ + public static final OfLong __clang_max_align_nonce1$layout() { + return __clang_max_align_nonce1$LAYOUT; + } + + private static final long __clang_max_align_nonce1$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * long long __clang_max_align_nonce1 + * } + */ + public static final long __clang_max_align_nonce1$offset() { + return __clang_max_align_nonce1$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * long long __clang_max_align_nonce1 + * } + */ + public static long __clang_max_align_nonce1(MemorySegment struct) { + return struct.get(__clang_max_align_nonce1$LAYOUT, __clang_max_align_nonce1$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * long long __clang_max_align_nonce1 + * } + */ + public static void __clang_max_align_nonce1(MemorySegment struct, long fieldValue) { + struct.set(__clang_max_align_nonce1$LAYOUT, __clang_max_align_nonce1$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} diff --git a/java/cuvs-java/src/main/java/module-info.java b/java/cuvs-java/src/main/java/module-info.java new file mode 100644 index 000000000..468252f22 --- /dev/null +++ b/java/cuvs-java/src/main/java/module-info.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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. + */ + +module com.nvidia.cuvs { + exports com.nvidia.cuvs; +} diff --git a/java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceAndSearchTest.java b/java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceAndSearchTest.java new file mode 100644 index 000000000..91e6825bc --- /dev/null +++ b/java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceAndSearchTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nvidia.cuvs.common.SearchResults; + +public class BruteForceAndSearchTest { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + /** + * A basic test that checks the whole flow - from indexing to search. + * + * @throws Throwable + */ + @Test + public void testIndexingAndSearchingFlow() throws Throwable { + + // Sample data and query + float[][] dataset = { + { 0.74021935f, 0.9209938f }, + { 0.03902049f, 0.9689629f }, + { 0.92514056f, 0.4463501f }, + { 0.6673192f, 0.10993068f } + }; + List map = List.of(0, 1, 2, 3); + float[][] queries = { + { 0.48216683f, 0.0428398f }, + { 0.5084142f, 0.6545497f }, + { 0.51260436f, 0.2643005f }, + { 0.05198065f, 0.5789965f } + }; + + // Expected search results + List> expectedResults = Arrays.asList( + Map.of(3, 0.038782537f, 2, 0.35904616f, 0, 0.83774555f), + Map.of(0, 0.12472606f, 2, 0.21700788f, 1, 0.3191862f), + Map.of(3, 0.047766685f, 2, 0.20332813f, 0, 0.48305476f), + Map.of(1, 0.15224183f, 0, 0.5906347f, 3, 0.5986643f) + ); + + for (int j = 0; j < 10; j++) { + + try (CuVSResources resources = new CuVSResources()) { + + // Create a query object with the query vectors + BruteForceQuery cuvsQuery = new BruteForceQuery.Builder() + .withTopK(3) + .withQueryVectors(queries) + .withMapping(map) + .build(); + + // Set index parameters + BruteForceIndexParams indexParams = new BruteForceIndexParams.Builder() + .withNumWriterThreads(32) + .build(); + + // Create the index with the dataset + BruteForceIndex index = new BruteForceIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + // Saving the index on to the disk. + String indexFileName = UUID.randomUUID().toString() + ".bf"; + index.serialize(new FileOutputStream(indexFileName)); + + // Loading a BRUTEFORCE index from disk. + File indexFile = new File(indexFileName); + InputStream inputStream = new FileInputStream(indexFile); + BruteForceIndex loadedIndex = new BruteForceIndex.Builder(resources) + .from(inputStream) + .build(); + + // Perform the search + SearchResults resultsFromLoadedIndex = loadedIndex.search(cuvsQuery); + + // Check results + log.info(resultsFromLoadedIndex.getResults().toString()); + assertEquals(expectedResults, resultsFromLoadedIndex.getResults()); + + // Perform the search + SearchResults results = index.search(cuvsQuery); + + // Check results + log.info(results.getResults().toString()); + assertEquals(expectedResults, results.getResults()); + + // Cleanup + index.destroyIndex(); + loadedIndex.destroyIndex(); + + if (indexFile.exists()) { + indexFile.delete(); + } + } + } + } +} diff --git a/java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceRandomizedTest.java b/java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceRandomizedTest.java new file mode 100644 index 000000000..64d1eb86e --- /dev/null +++ b/java/cuvs-java/src/test/java/com/nvidia/cuvs/BruteForceRandomizedTest.java @@ -0,0 +1,99 @@ +package com.nvidia.cuvs; + +import java.lang.invoke.MethodHandles; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.carrotsearch.randomizedtesting.RandomizedRunner; + +@RunWith(RandomizedRunner.class) +public class BruteForceRandomizedTest extends CuVSTestCase { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Before + public void setup() { + initializeRandom(); + log.info("Random context initialized for test."); + } + + @Test + public void testResultsTopKWithRandomValues() throws Throwable { + for (int i = 0; i < 10; i++) { + tmpResultsTopKWithRandomValues(); + } + } + + private void tmpResultsTopKWithRandomValues() throws Throwable { + int DATASET_SIZE_LIMIT = 10_000; + int DIMENSIONS_LIMIT = 2048; + int NUM_QUERIES_LIMIT = 10; + int TOP_K_LIMIT = 64; // nocommit This fails beyond 64 + + int datasetSize = random.nextInt(DATASET_SIZE_LIMIT) + 1; + int dimensions = random.nextInt(DIMENSIONS_LIMIT) + 1; + int numQueries = random.nextInt(NUM_QUERIES_LIMIT) + 1; + int topK = Math.min(random.nextInt(TOP_K_LIMIT) + 1, datasetSize); + + if (datasetSize < topK) + datasetSize = topK; + + // Generate a random dataset + float[][] dataset = generateData(random, datasetSize, dimensions); + + // Generate random query vectors + float[][] queries = generateData(random, numQueries, dimensions); + + log.info("Dataset size: {}x{}", datasetSize, dimensions); + log.info("Query size: {}x{}", numQueries, dimensions); + log.info("TopK: {}", topK); + + // Debugging: Log dataset and queries + if (log.isDebugEnabled()) { + log.debug("Dataset:"); + for (float[] row : dataset) { + log.debug(java.util.Arrays.toString(row)); + } + log.debug("Queries:"); + for (float[] query : queries) { + log.debug(java.util.Arrays.toString(query)); + } + } + // Sanity checks + assert dataset.length > 0 : "Dataset is empty."; + assert queries.length > 0 : "Queries are empty."; + assert dimensions > 0 : "Invalid dimensions."; + assert topK > 0 && topK <= datasetSize : "Invalid topK value."; + + // Generate expected results using brute force + List> expected = generateExpectedResults(topK, dataset, queries, log); + + // Create CuVS index and query + try (CuVSResources resources = new CuVSResources()) { + + BruteForceQuery query = new BruteForceQuery.Builder() + .withTopK(topK) + .withQueryVectors(queries) + .build(); + + BruteForceIndexParams indexParams = new BruteForceIndexParams.Builder() + .withNumWriterThreads(32) + .build(); + + BruteForceIndex index = new BruteForceIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + log.info("Index built successfully. Executing search..."); + BruteForceSearchResults results = index.search(query); + + compareResults(results, expected, topK, datasetSize, numQueries); + } + } +} diff --git a/java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraBuildAndSearchTest.java b/java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraBuildAndSearchTest.java new file mode 100644 index 000000000..934e60b1c --- /dev/null +++ b/java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraBuildAndSearchTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo; +import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType; +import com.nvidia.cuvs.common.SearchResults; + +public class CagraBuildAndSearchTest { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + /** + * A basic test that checks the whole flow - from indexing to search. + * + * @throws Throwable + */ + @Test + public void testIndexingAndSearchingFlow() throws Throwable { + + // Sample data and query + float[][] dataset = { + { 0.74021935f, 0.9209938f }, + { 0.03902049f, 0.9689629f }, + { 0.92514056f, 0.4463501f }, + { 0.6673192f, 0.10993068f } + }; + List map = List.of(0, 1, 2, 3); + float[][] queries = { + { 0.48216683f, 0.0428398f }, + { 0.5084142f, 0.6545497f }, + { 0.51260436f, 0.2643005f }, + { 0.05198065f, 0.5789965f } + }; + + // Expected search results + List> expectedResults = Arrays.asList( + Map.of(3, 0.038782578f, 2, 0.3590463f, 0, 0.83774555f), + Map.of(0, 0.12472608f, 2, 0.21700792f, 1, 0.31918612f), + Map.of(3, 0.047766715f, 2, 0.20332818f, 0, 0.48305473f), + Map.of(1, 0.15224178f, 0, 0.59063464f, 3, 0.5986642f)); + + for (int j = 0; j < 10; j++) { + + try (CuVSResources resources = new CuVSResources()) { + + // Configure index parameters + CagraIndexParams indexParams = new CagraIndexParams.Builder(resources) + .withCagraGraphBuildAlgo(CagraGraphBuildAlgo.NN_DESCENT) + .withGraphDegree(1) + .withIntermediateGraphDegree(2) + .withNumWriterThreads(32) + .withMetric(CuvsDistanceType.L2Expanded) + .build(); + + // Create the index with the dataset + CagraIndex index = new CagraIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + // Saving the index on to the disk. + String indexFileName = UUID.randomUUID().toString() + ".cag"; + index.serialize(new FileOutputStream(indexFileName)); + + // Loading a CAGRA index from disk. + File indexFile = new File(indexFileName); + InputStream inputStream = new FileInputStream(indexFile); + CagraIndex loadedIndex = new CagraIndex.Builder(resources) + .from(inputStream) + .build(); + + // Configure search parameters + CagraSearchParams searchParams = new CagraSearchParams.Builder(resources) + .build(); + + // Create a query object with the query vectors + CagraQuery cuvsQuery = new CagraQuery.Builder() + .withTopK(3) + .withSearchParams(searchParams) + .withQueryVectors(queries) + .withMapping(map) + .build(); + + // Perform the search + SearchResults results = index.search(cuvsQuery); + + // Check results + log.info(results.getResults().toString()); + assertEquals(expectedResults, results.getResults()); + + // Search from deserialized index + results = loadedIndex.search(cuvsQuery); + + // Check results + log.info(results.getResults().toString()); + assertEquals(expectedResults, results.getResults()); + + // Cleanup + if (indexFile.exists()) { + indexFile.delete(); + } + index.destroyIndex(); + } + } + } +} diff --git a/java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraRandomizedTest.java b/java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraRandomizedTest.java new file mode 100644 index 000000000..fc7570133 --- /dev/null +++ b/java/cuvs-java/src/test/java/com/nvidia/cuvs/CagraRandomizedTest.java @@ -0,0 +1,101 @@ +package com.nvidia.cuvs; + +import java.lang.invoke.MethodHandles; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.carrotsearch.randomizedtesting.RandomizedRunner; +import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo; + +@RunWith(RandomizedRunner.class) +public class CagraRandomizedTest extends CuVSTestCase { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Before + public void setup() { + initializeRandom(); + log.info("Random context initialized for test."); + } + + @Test + public void testResultsTopKWithRandomValues() throws Throwable { + for (int i = 0; i < 10; i++) { + tmpResultsTopKWithRandomValues(); + } + } + + private void tmpResultsTopKWithRandomValues() throws Throwable { + int DATASET_SIZE_LIMIT = 10_000; + int DIMENSIONS_LIMIT = 2048; + int NUM_QUERIES_LIMIT = 10; + int TOP_K_LIMIT = 64; // nocommit This fails beyond 64 + + int datasetSize = random.nextInt(DATASET_SIZE_LIMIT) + 1; + int dimensions = random.nextInt(DIMENSIONS_LIMIT) + 1; + int numQueries = random.nextInt(NUM_QUERIES_LIMIT) + 1; + int topK = Math.min(random.nextInt(TOP_K_LIMIT) + 1, datasetSize); + + if (datasetSize < topK) + datasetSize = topK; + + // Generate a random dataset + float[][] dataset = generateData(random, datasetSize, dimensions); + + // Generate random query vectors + float[][] queries = generateData(random, numQueries, dimensions); + + log.info("Dataset size: {}x{}", datasetSize, dimensions); + log.info("Query size: {}x{}", numQueries, dimensions); + log.info("TopK: {}", topK); + + // Debugging: Log dataset and queries + if (log.isDebugEnabled()) { + log.debug("Dataset:"); + for (float[] row : dataset) { + log.debug(java.util.Arrays.toString(row)); + } + log.debug("Queries:"); + for (float[] query : queries) { + log.debug(java.util.Arrays.toString(query)); + } + } + // Sanity checks + assert dataset.length > 0 : "Dataset is empty."; + assert queries.length > 0 : "Queries are empty."; + assert dimensions > 0 : "Invalid dimensions."; + assert topK > 0 && topK <= datasetSize : "Invalid topK value."; + + // Generate expected results using brute force + List> expected = generateExpectedResults(topK, dataset, queries, log); + + // Create CuVS index and query + try (CuVSResources resources = new CuVSResources()) { + CagraIndexParams indexParams = new CagraIndexParams.Builder(resources) + .withCagraGraphBuildAlgo(CagraGraphBuildAlgo.NN_DESCENT) + .build(); + CagraIndex index = new CagraIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + log.info("Index built successfully."); + + // Execute search and retrieve results + CagraQuery query = new CagraQuery.Builder() + .withQueryVectors(queries) + .withTopK(topK) + .withSearchParams(new CagraSearchParams.Builder(resources) + .build()) + .build(); + log.info("Query built successfully. Executing search..."); + CagraSearchResults results = index.search(query); + + compareResults(results, expected, topK, datasetSize, numQueries); + } + } +} diff --git a/java/cuvs-java/src/test/java/com/nvidia/cuvs/CuVSTestCase.java b/java/cuvs-java/src/test/java/com/nvidia/cuvs/CuVSTestCase.java new file mode 100644 index 000000000..bd50dc759 --- /dev/null +++ b/java/cuvs-java/src/test/java/com/nvidia/cuvs/CuVSTestCase.java @@ -0,0 +1,88 @@ +package com.nvidia.cuvs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.TreeMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.carrotsearch.randomizedtesting.RandomizedContext; +import com.nvidia.cuvs.common.SearchResults; + +public abstract class CuVSTestCase { + protected Random random; + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + protected void initializeRandom() { + random = RandomizedContext.current().getRandom(); + log.info("Test seed: " + RandomizedContext.current().getRunnerSeedAsString()); + } + + protected float[][] generateData(Random random, int rows, int cols) { + float[][] data = new float[rows][cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + data[i][j] = random.nextFloat() * 100; + } + } + return data; + } + + protected List> generateExpectedResults(int topK, float[][] dataset, float[][] queries, Logger log) { + List> neighborsResult = new ArrayList<>(); + int dimensions = dataset[0].length; + + for (float[] query : queries) { + Map distances = new TreeMap<>(); + for (int j = 0; j < dataset.length; j++) { + double distance = 0; + for (int k = 0; k < dimensions; k++) { + distance += (query[k] - dataset[j][k]) * (query[k] - dataset[j][k]); + } + distances.put(j, Math.sqrt(distance)); + } + + // Sort by distance and select the topK nearest neighbors + List neighbors = distances.entrySet().stream().sorted(Map.Entry.comparingByValue()) + .map(Map.Entry::getKey).toList(); + neighborsResult.add(neighbors.subList(0, Math.min(topK * 2, dataset.length))); + } + + log.info("Expected results generated successfully."); + return neighborsResult; + } + + protected void compareResults(SearchResults results, List> expected, int topK, int datasetSize, + int numQueries) { + + for (int i = 0; i < numQueries; i++) { + log.info("Results returned for query " + i + ": " + results.getResults().get(i).keySet()); + log.info("Expected results for query " + i + ": " + expected.get(i).subList(0, Math.min(topK, datasetSize))); + } + + // actual vs. expected results + for (int i = 0; i < results.getResults().size(); i++) { + Map result = results.getResults().get(i); + assertEquals("TopK mismatch for query.", Math.min(topK, datasetSize), result.size()); + + // Sort result by values (distances) and extract keys + List sortedResultKeys = result.entrySet().stream().sorted(Map.Entry.comparingByValue()) + .map(Map.Entry::getKey) // Extract sorted keys + .toList(); + + // just make sure that the first 5 results are in the expected list (which + // comprises of 2*topK results) + for (int j = 0; j < Math.min(5, sortedResultKeys.size()); j++) { + assertTrue("Not found in expected list: " + sortedResultKeys.get(j), + expected.get(i).contains(sortedResultKeys.get(j))); + } + } + } +} diff --git a/java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswBuildAndSearchTest.java b/java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswBuildAndSearchTest.java new file mode 100644 index 000000000..712e7edf9 --- /dev/null +++ b/java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswBuildAndSearchTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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 com.nvidia.cuvs; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo; +import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType; + +public class HnswBuildAndSearchTest { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + /** + * A basic test that checks the whole flow - from indexing to search. + * + * @throws Throwable + */ + @Test + public void testIndexingAndSearchingFlow() throws Throwable { + + // Sample data and query + float[][] dataset = { + { 0.74021935f, 0.9209938f }, + { 0.03902049f, 0.9689629f }, + { 0.92514056f, 0.4463501f }, + { 0.6673192f, 0.10993068f } + }; + List map = List.of(0, 1, 2, 3); + float[][] queries = { + { 0.48216683f, 0.0428398f }, + { 0.5084142f, 0.6545497f }, + { 0.51260436f, 0.2643005f }, + { 0.05198065f, 0.5789965f } + }; + + // Expected search results + List> expectedResults = Arrays.asList( + Map.of(3, 0.038782578f, 2, 0.35904628f, 0, 0.8377455f), + Map.of(0, 0.12472608f, 2, 0.21700794f, 1, 0.31918612f), + Map.of(3, 0.047766715f, 2, 0.20332818f, 0, 0.48305473f), + Map.of(1, 0.15224178f, 0, 0.59063464f, 3, 0.59866416f) + ); + + for (int j = 0; j < 10; j++) { + + try (CuVSResources resources = new CuVSResources()) { + + // Configure index parameters + CagraIndexParams indexParams = new CagraIndexParams.Builder(resources) + .withCagraGraphBuildAlgo(CagraGraphBuildAlgo.IVF_PQ) + .withGraphDegree(64) + .withIntermediateGraphDegree(128) + .withNumWriterThreads(32) + .withMetric(CuvsDistanceType.L2Expanded) + .build(); + + // Create the index with the dataset + CagraIndex index = new CagraIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + // Saving the HNSW index on to the disk. + String hnswIndexFileName = UUID.randomUUID().toString() + ".hnsw"; + index.serializeToHNSW(new FileOutputStream(hnswIndexFileName)); + + HnswIndexParams hnswIndexParams = new HnswIndexParams.Builder(resources) + .withVectorDimension(2) + .build(); + InputStream inputStreamHNSW = new FileInputStream(hnswIndexFileName); + File hnswIndexFile = new File(hnswIndexFileName); + + HnswIndex hnswIndex = new HnswIndex.Builder(resources) + .from(inputStreamHNSW) + .withIndexParams(hnswIndexParams) + .build(); + + HnswSearchParams hnswSearchParams = new HnswSearchParams.Builder(resources) + .build(); + + HnswQuery hnswQuery = new HnswQuery.Builder() + .withMapping(map) + .withQueryVectors(queries) + .withSearchParams(hnswSearchParams) + .withTopK(3) + .build(); + + HnswSearchResults results = hnswIndex.search(hnswQuery); + + // Check results + log.info(results.getResults().toString()); + assertEquals(expectedResults, results.getResults()); + + // Cleanup + if (hnswIndexFile.exists()) { + hnswIndexFile.delete(); + } + index.destroyIndex(); + hnswIndex.destroyIndex(); + } + } + } +} diff --git a/java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswRandomizedTest.java b/java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswRandomizedTest.java new file mode 100644 index 000000000..c292309f7 --- /dev/null +++ b/java/cuvs-java/src/test/java/com/nvidia/cuvs/HnswRandomizedTest.java @@ -0,0 +1,136 @@ +package com.nvidia.cuvs; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.util.List; +import java.util.UUID; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.carrotsearch.randomizedtesting.RandomizedRunner; +import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo; +import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType; + +@RunWith(RandomizedRunner.class) +public class HnswRandomizedTest extends CuVSTestCase { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Before + public void setup() { + initializeRandom(); + log.info("Random context initialized for test."); + } + + @Test + public void testResultsTopKWithRandomValues() throws Throwable { + for (int i = 0; i < 10; i++) { + tmpResultsTopKWithRandomValues(); + } + } + + private void tmpResultsTopKWithRandomValues() throws Throwable { + int DATASET_SIZE_LIMIT = 10_000; + int DIMENSIONS_LIMIT = 2048; + int NUM_QUERIES_LIMIT = 10; + int TOP_K_LIMIT = 64; // nocommit This fails beyond 64 + + int datasetSize = random.nextInt(DATASET_SIZE_LIMIT) + 1; + int dimensions = random.nextInt(DIMENSIONS_LIMIT) + 1; + int numQueries = random.nextInt(NUM_QUERIES_LIMIT) + 1; + int topK = Math.min(random.nextInt(TOP_K_LIMIT) + 1, datasetSize); + + if (datasetSize < topK) + datasetSize = topK; + + // Generate a random dataset + float[][] dataset = generateData(random, datasetSize, dimensions); + + // Generate random query vectors + float[][] queries = generateData(random, numQueries, dimensions); + + log.info("Dataset size: {}x{}", datasetSize, dimensions); + log.info("Query size: {}x{}", numQueries, dimensions); + log.info("TopK: {}", topK); + + // Debugging: Log dataset and queries + if (log.isDebugEnabled()) { + log.debug("Dataset:"); + for (float[] row : dataset) { + log.debug(java.util.Arrays.toString(row)); + } + log.debug("Queries:"); + for (float[] query : queries) { + log.debug(java.util.Arrays.toString(query)); + } + } + // Sanity checks + assert dataset.length > 0 : "Dataset is empty."; + assert queries.length > 0 : "Queries are empty."; + assert dimensions > 0 : "Invalid dimensions."; + assert topK > 0 && topK <= datasetSize : "Invalid topK value."; + + // Generate expected results using brute force + List> expected = generateExpectedResults(topK, dataset, queries, log); + + // Create CuVS index and query + try (CuVSResources resources = new CuVSResources()) { + + // Configure index parameters + CagraIndexParams indexParams = new CagraIndexParams.Builder(resources) + .withCagraGraphBuildAlgo(CagraGraphBuildAlgo.NN_DESCENT) + .withGraphDegree(64) + .withIntermediateGraphDegree(128) + .withNumWriterThreads(32) + .withMetric(CuvsDistanceType.L2Expanded) + .build(); + + // Create the index with the dataset + CagraIndex index = new CagraIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + // Saving the HNSW index on to the disk. + String hnswIndexFileName = UUID.randomUUID().toString() + ".hnsw"; + index.serializeToHNSW(new FileOutputStream(hnswIndexFileName)); + + HnswIndexParams hnswIndexParams = new HnswIndexParams.Builder(resources) + .withVectorDimension(dimensions) + .build(); + InputStream inputStreamHNSW = new FileInputStream(hnswIndexFileName); + File hnswIndexFile = new File(hnswIndexFileName); + + HnswIndex hnswIndex = new HnswIndex.Builder(resources) + .from(inputStreamHNSW) + .withIndexParams(hnswIndexParams) + .build(); + + HnswSearchParams hnswSearchParams = new HnswSearchParams.Builder(resources) + .withNumThreads(32) + .build(); + + HnswQuery hnswQuery = new HnswQuery.Builder() + .withQueryVectors(queries) + .withSearchParams(hnswSearchParams) + .withTopK(topK) + .build(); + + log.info("Index built successfully. Executing search..."); + HnswSearchResults results = hnswIndex.search(hnswQuery); + + if (hnswIndexFile.exists()) { + hnswIndexFile.delete(); + } + + compareResults(results, expected, topK, datasetSize, numQueries); + } + } +} diff --git a/java/examples/.gitignore b/java/examples/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/java/examples/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/java/examples/README.md b/java/examples/README.md new file mode 100644 index 000000000..d05d7b911 --- /dev/null +++ b/java/examples/README.md @@ -0,0 +1,8 @@ +Building and Running +-------------------- + +Make sure to have JDK 22 and Maven 3.9.6+. + + mvn clean compile assembly:single + + java --enable-native-access=ALL-UNNAMED -jar ./target/cagra-sample-1.0-SNAPSHOT-jar-with-dependencies.jar diff --git a/java/examples/pom.xml b/java/examples/pom.xml new file mode 100644 index 000000000..58ebef84e --- /dev/null +++ b/java/examples/pom.xml @@ -0,0 +1,105 @@ + + + 4.0.0 + com.nvidia.cuvs.examples + cuvs-java-examples + + 25.02.0 + cuvs-java-examples + + + UTF-8 + 22 + + + + + com.nvidia.cuvs + cuvs-java + + 25.02.0 + + + org.slf4j + slf4j-api + 2.0.13 + + + org.slf4j + slf4j-simple + 2.0.13 + runtime + + + + + + + + + maven-clean-plugin + 3.4.0 + + + + maven-resources-plugin + 3.3.1 + + + maven-compiler-plugin + 3.13.0 + + + maven-surefire-plugin + 3.3.0 + + + maven-jar-plugin + 3.4.2 + + + maven-install-plugin + 3.1.2 + + + maven-deploy-plugin + 3.1.2 + + + + maven-site-plugin + 3.12.1 + + + maven-project-info-reports-plugin + 3.6.1 + + + maven-assembly-plugin + + + make-jar-with-dependencies + + package + + + single + + + + + + + com.nvidia.cuvs.examples.CagraExample + + + + jar-with-dependencies + + + + + + + diff --git a/java/examples/src/main/java/com/nvidia/cuvs/examples/BruteForceExample.java b/java/examples/src/main/java/com/nvidia/cuvs/examples/BruteForceExample.java new file mode 100644 index 000000000..5f72d92fc --- /dev/null +++ b/java/examples/src/main/java/com/nvidia/cuvs/examples/BruteForceExample.java @@ -0,0 +1,90 @@ +package com.nvidia.cuvs.examples; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nvidia.cuvs.BruteForceIndex; +import com.nvidia.cuvs.BruteForceIndexParams; +import com.nvidia.cuvs.BruteForceQuery; +import com.nvidia.cuvs.CuVSResources; +import com.nvidia.cuvs.common.SearchResults; + +public class BruteForceExample { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + public static void main(String[] args) throws Throwable { + + // Sample data and query + float[][] dataset = { + { 0.74021935f, 0.9209938f }, + { 0.03902049f, 0.9689629f }, + { 0.92514056f, 0.4463501f }, + { 0.6673192f, 0.10993068f } + }; + + float[][] queries = { + { 0.48216683f, 0.0428398f }, + { 0.5084142f, 0.6545497f }, + { 0.51260436f, 0.2643005f }, + { 0.05198065f, 0.5789965f } + }; + + try (CuVSResources resources = new CuVSResources()) { + + // Create a query object with the query vectors + BruteForceQuery cuvsQuery = new BruteForceQuery.Builder() + .withTopK(3) + .withQueryVectors(queries) + .build(); + + // Set index parameters + BruteForceIndexParams indexParams = new BruteForceIndexParams.Builder() + .build(); + + // Create the index with the dataset + BruteForceIndex index = new BruteForceIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + // Saving the index on to the disk. + String indexFileName = UUID.randomUUID().toString() + ".bf"; + index.serialize(new FileOutputStream(indexFileName)); + + // Loading a BRUTEFORCE index from disk. + File indexFile = new File(indexFileName); + InputStream inputStream = new FileInputStream(indexFile); + BruteForceIndex loadedIndex = new BruteForceIndex.Builder(resources) + .from(inputStream) + .build(); + + // Perform the search + SearchResults resultsFromLoadedIndex = loadedIndex.search(cuvsQuery); + + // Check results + log.info(resultsFromLoadedIndex.getResults().toString()); + + // Perform the search + SearchResults results = index.search(cuvsQuery); + + // Check results + log.info(results.getResults().toString()); + + // Cleanup + index.destroyIndex(); + loadedIndex.destroyIndex(); + + if (indexFile.exists()) { + indexFile.delete(); + } + } + } +} diff --git a/java/examples/src/main/java/com/nvidia/cuvs/examples/CagraExample.java b/java/examples/src/main/java/com/nvidia/cuvs/examples/CagraExample.java new file mode 100644 index 000000000..f561ce69d --- /dev/null +++ b/java/examples/src/main/java/com/nvidia/cuvs/examples/CagraExample.java @@ -0,0 +1,100 @@ +package com.nvidia.cuvs.examples; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nvidia.cuvs.CagraIndex; +import com.nvidia.cuvs.CagraIndexParams; +import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo; +import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType; +import com.nvidia.cuvs.CagraQuery; +import com.nvidia.cuvs.CagraSearchParams; +import com.nvidia.cuvs.CuVSResources; +import com.nvidia.cuvs.common.SearchResults; + +public class CagraExample { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + public static void main(String[] args) throws Throwable { + + // Sample data and query + float[][] dataset = { + { 0.74021935f, 0.9209938f }, + { 0.03902049f, 0.9689629f }, + { 0.92514056f, 0.4463501f }, + { 0.6673192f, 0.10993068f } + }; + + float[][] queries = { + { 0.48216683f, 0.0428398f }, + { 0.5084142f, 0.6545497f }, + { 0.51260436f, 0.2643005f }, + { 0.05198065f, 0.5789965f } + }; + + try (CuVSResources resources = new CuVSResources()) { + + // Configure index parameters + CagraIndexParams indexParams = new CagraIndexParams.Builder(resources) + .withCagraGraphBuildAlgo(CagraGraphBuildAlgo.NN_DESCENT) + .withGraphDegree(1) + .withIntermediateGraphDegree(2) + .withMetric(CuvsDistanceType.L2Expanded) + .build(); + + // Create the index with the dataset + CagraIndex index = new CagraIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + // Saving the index on to the disk. + String indexFileName = UUID.randomUUID().toString() + ".cag"; + index.serialize(new FileOutputStream(indexFileName)); + + // Loading a CAGRA index from disk. + File indexFile = new File(indexFileName); + InputStream inputStream = new FileInputStream(indexFile); + CagraIndex loadedIndex = new CagraIndex.Builder(resources) + .from(inputStream) + .build(); + + // Configure search parameters + CagraSearchParams searchParams = new CagraSearchParams.Builder(resources) + .build(); + + // Create a query object with the query vectors + CagraQuery cuvsQuery = new CagraQuery.Builder() + .withTopK(3) + .withSearchParams(searchParams) + .withQueryVectors(queries) + .build(); + + // Perform the search + SearchResults results = index.search(cuvsQuery); + + // Check results + log.info(results.getResults().toString()); + + // Search from deserialized index + results = loadedIndex.search(cuvsQuery); + + // Check results + log.info(results.getResults().toString()); + + // Cleanup + if (indexFile.exists()) { + indexFile.delete(); + } + index.destroyIndex(); + } + } +} diff --git a/java/examples/src/main/java/com/nvidia/cuvs/examples/HnswExample.java b/java/examples/src/main/java/com/nvidia/cuvs/examples/HnswExample.java new file mode 100644 index 000000000..0f13be3bc --- /dev/null +++ b/java/examples/src/main/java/com/nvidia/cuvs/examples/HnswExample.java @@ -0,0 +1,99 @@ +package com.nvidia.cuvs.examples; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nvidia.cuvs.CagraIndex; +import com.nvidia.cuvs.CagraIndexParams; +import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo; +import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType; +import com.nvidia.cuvs.CuVSResources; +import com.nvidia.cuvs.HnswIndex; +import com.nvidia.cuvs.HnswIndexParams; +import com.nvidia.cuvs.HnswQuery; +import com.nvidia.cuvs.HnswSearchParams; +import com.nvidia.cuvs.HnswSearchResults; + +public class HnswExample { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + public static void main(String[] args) throws Throwable { + + // Sample data and query + float[][] dataset = { + { 0.74021935f, 0.9209938f }, + { 0.03902049f, 0.9689629f }, + { 0.92514056f, 0.4463501f }, + { 0.6673192f, 0.10993068f } + }; + + float[][] queries = { + { 0.48216683f, 0.0428398f }, + { 0.5084142f, 0.6545497f }, + { 0.51260436f, 0.2643005f }, + { 0.05198065f, 0.5789965f } + }; + + try (CuVSResources resources = new CuVSResources()) { + + // Configure index parameters + CagraIndexParams indexParams = new CagraIndexParams.Builder(resources) + .withCagraGraphBuildAlgo(CagraGraphBuildAlgo.IVF_PQ) + .withGraphDegree(64) + .withIntermediateGraphDegree(128) + .withNumWriterThreads(32) + .withMetric(CuvsDistanceType.L2Expanded) + .build(); + + // Create the index with the dataset + CagraIndex index = new CagraIndex.Builder(resources) + .withDataset(dataset) + .withIndexParams(indexParams) + .build(); + + // Saving the HNSW index on to the disk. + String hnswIndexFileName = UUID.randomUUID().toString() + ".hnsw"; + index.serializeToHNSW(new FileOutputStream(hnswIndexFileName)); + + HnswIndexParams hnswIndexParams = new HnswIndexParams.Builder(resources) + .withVectorDimension(2) + .build(); + InputStream inputStreamHNSW = new FileInputStream(hnswIndexFileName); + File hnswIndexFile = new File(hnswIndexFileName); + + HnswIndex hnswIndex = new HnswIndex.Builder(resources) + .from(inputStreamHNSW) + .withIndexParams(hnswIndexParams) + .build(); + + HnswSearchParams hnswSearchParams = new HnswSearchParams.Builder(resources) + .build(); + + HnswQuery hnswQuery = new HnswQuery.Builder() + .withQueryVectors(queries) + .withSearchParams(hnswSearchParams) + .withTopK(3) + .build(); + + HnswSearchResults results = hnswIndex.search(hnswQuery); + + // Check results + log.info(results.getResults().toString()); + + // Cleanup + if (hnswIndexFile.exists()) { + hnswIndexFile.delete(); + } + index.destroyIndex(); + hnswIndex.destroyIndex(); + } + } +} diff --git a/java/examples/src/main/resources/log4j2.xml b/java/examples/src/main/resources/log4j2.xml new file mode 100644 index 000000000..bf0eb598c --- /dev/null +++ b/java/examples/src/main/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/java/internal/CMakeLists.txt b/java/internal/CMakeLists.txt new file mode 100644 index 000000000..3bd316e2d --- /dev/null +++ b/java/internal/CMakeLists.txt @@ -0,0 +1,62 @@ +# ============================================================================= +# Copyright (c) 2025, NVIDIA CORPORATION. +# +# 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. +# ============================================================================= + +cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR) + +include(rapids_config.cmake) +include(rapids-cmake) +include(rapids-cpm) +include(rapids-export) +include(rapids-find) +rapids_cpm_init() + +project( + cuvs-java + VERSION "${RAPIDS_VERSION}" + LANGUAGES CXX C +) + +find_package(OpenMP) +find_package(Threads) + +option(FIND_CUVS_CPP "Search for existing CUVS C++ installations before defaulting to local files" + ON +) + +if(FIND_CUVS_CPP) + find_package(cuvs "${RAPIDS_VERSION}" REQUIRED COMPONENTS c_api) + if(NOT TARGET cuvs::c_api) + message( + FATAL_ERROR + "Building against a preexisting libcuvs library requires the compiled libcuvs to have been built!" + ) + endif() +else() + set(cuvs_FOUND OFF) +endif() + +if(NOT cuvs_FOUND) + set(BUILD_TESTS OFF) + set(BUILD_C_LIBRARY ON) + add_subdirectory(../../cpp cuvs-cpp EXCLUDE_FROM_ALL) +endif() + +include(get_dlpack.cmake) + +ADD_LIBRARY(cuvs_java SHARED src/cuvs_java.c) +target_include_directories(cuvs_java PUBLIC "$") +target_link_libraries( + cuvs_java PRIVATE cuvs::c_api $ OpenMP::OpenMP_CXX + Threads::Threads +) diff --git a/java/internal/VERSION b/java/internal/VERSION new file mode 120000 index 000000000..558194c5a --- /dev/null +++ b/java/internal/VERSION @@ -0,0 +1 @@ +../../VERSION \ No newline at end of file diff --git a/java/internal/get_dlpack.cmake b/java/internal/get_dlpack.cmake new file mode 120000 index 000000000..93a54ca4d --- /dev/null +++ b/java/internal/get_dlpack.cmake @@ -0,0 +1 @@ +../../cpp/cmake/thirdparty/get_dlpack.cmake \ No newline at end of file diff --git a/java/internal/rapids_config.cmake b/java/internal/rapids_config.cmake new file mode 120000 index 000000000..398eea52d --- /dev/null +++ b/java/internal/rapids_config.cmake @@ -0,0 +1 @@ +../../rapids_config.cmake \ No newline at end of file diff --git a/java/internal/src/cuvs_java.c b/java/internal/src/cuvs_java.c new file mode 100644 index 000000000..febde8463 --- /dev/null +++ b/java/internal/src/cuvs_java.c @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define try bool __HadError=false; +#define catch(x) ExitJmp:if(__HadError) +#define throw(x) {__HadError=true;goto ExitJmp;} + +/** + * @brief Create an Initialized opaque C handle + * + * @param[out] return_value return value for cuvsResourcesCreate function call + * @return cuvsResources_t + */ +cuvsResources_t create_resources(int *return_value) { + cuvsResources_t cuvs_resources; + *return_value = cuvsResourcesCreate(&cuvs_resources); + return cuvs_resources; +} + +/** + * @brief Destroy and de-allocate opaque C handle + * + * @param[in] cuvs_resources an opaque C handle + * @param[out] return_value return value for cuvsResourcesDestroy function call + */ +void destroy_resources(cuvsResources_t cuvs_resources, int *return_value) { + *return_value = cuvsResourcesDestroy(cuvs_resources); +} + +/** + * @brief Helper function for creating DLManagedTensor instance + * + * @param[in] data the data pointer points to the allocated data + * @param[in] shape the shape of the tensor + * @param[in] code the type code of base types + * @param[in] bits the shape of the tensor + * @param[in] ndim the number of dimensions + * @return DLManagedTensor + */ +DLManagedTensor prepare_tensor(void *data, int64_t shape[], DLDataTypeCode code, int bits, int ndim, DLDeviceType device_type) { + DLManagedTensor tensor; + + tensor.dl_tensor.data = data; + tensor.dl_tensor.device.device_type = device_type; //kDLCUDA; + tensor.dl_tensor.ndim = ndim; + tensor.dl_tensor.dtype.code = code; + tensor.dl_tensor.dtype.bits = bits; + tensor.dl_tensor.dtype.lanes = 1; + tensor.dl_tensor.shape = shape; + tensor.dl_tensor.strides = NULL; + + return tensor; +} + +/** + * @brief Function for building CAGRA index + * + * @param[in] dataset index dataset + * @param[in] rows number of dataset rows + * @param[in] dimensions vector dimension of the dataset + * @param[in] cuvs_resources reference of the underlying opaque C handle + * @param[out] return_value return value for cuvsCagraBuild function call + * @param[in] index_params a reference to the index parameters + * @param[in] compression_params a reference to the compression parameters + * @param[in] n_writer_threads number of omp threads to use + * @return cuvsCagraIndex_t + */ +cuvsCagraIndex_t build_cagra_index(float *dataset, long rows, long dimensions, cuvsResources_t cuvs_resources, int *return_value, + cuvsCagraIndexParams_t index_params, cuvsCagraCompressionParams_t compression_params, int n_writer_threads) { + + cudaStream_t stream; + cuvsStreamGet(cuvs_resources, &stream); + + omp_set_num_threads(n_writer_threads); + cuvsRMMPoolMemoryResourceEnable(95, 95, false); + + int64_t dataset_shape[2] = {rows, dimensions}; + DLManagedTensor dataset_tensor = prepare_tensor(dataset, dataset_shape, kDLFloat, 32, 2, kDLCUDA); + + cuvsCagraIndex_t index; + cuvsCagraIndexCreate(&index); + + index_params->compression = compression_params; + cuvsStreamSync(cuvs_resources); + *return_value = cuvsCagraBuild(cuvs_resources, index_params, &dataset_tensor, index); + + omp_set_num_threads(1); + + return index; +} + +/** + * @brief A function to de-allocate CAGRA index + * + * @param[in] index cuvsCagraIndex_t to de-allocate + * @param[out] return_value return value for cuvsCagraIndexDestroy function call + */ +void destroy_cagra_index(cuvsCagraIndex_t index, int *return_value) { + *return_value = cuvsCagraIndexDestroy(index); +} + +/** + * @brief A function to serialize a CAGRA index + * + * @param[in] cuvs_resources reference of the underlying opaque C handle + * @param[in] index cuvsCagraIndex_t reference + * @param[out] return_value return value for cuvsCagraSerialize function call + * @param[in] filename the filename of the index file + */ +void serialize_cagra_index(cuvsResources_t cuvs_resources, cuvsCagraIndex_t index, int *return_value, char* filename) { + *return_value = cuvsCagraSerialize(cuvs_resources, filename, index, true); +} + +/** + * @brief A function to de-serialize a CAGRA index + * + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[in] index cuvsCagraIndex_t reference + * @param[out] return_value return value for cuvsCagraDeserialize function call + * @param[in] filename the filename of the index file + */ +void deserialize_cagra_index(cuvsResources_t cuvs_resources, cuvsCagraIndex_t index, int *return_value, char* filename) { + *return_value = cuvsCagraDeserialize(cuvs_resources, filename, index); +} + +/** + * @brief A function to search a CAGRA index and return results + * + * @param[in] index reference to a CAGRA index to search on + * @param[in] queries query vectors + * @param[in] topk topK results to return + * @param[in] n_queries number of queries + * @param[in] dimensions vector dimension + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[out] neighbors_h reference to the neighbor results on the host memory + * @param[out] distances_h reference to the distance results on the host memory + * @param[out] return_value return value for cuvsCagraSearch function call + * @param[in] search_params reference to cuvsCagraSearchParams_t holding the search parameters + */ +void search_cagra_index(cuvsCagraIndex_t index, float *queries, int topk, long n_queries, int dimensions, + cuvsResources_t cuvs_resources, int *neighbors_h, float *distances_h, int *return_value, cuvsCagraSearchParams_t search_params) { + + cudaStream_t stream; + cuvsStreamGet(cuvs_resources, &stream); + + uint32_t *neighbors; + float *distances, *queries_d; + cuvsRMMAlloc(cuvs_resources, (void**) &queries_d, sizeof(float) * n_queries * dimensions); + cuvsRMMAlloc(cuvs_resources, (void**) &neighbors, sizeof(uint32_t) * n_queries * topk); + cuvsRMMAlloc(cuvs_resources, (void**) &distances, sizeof(float) * n_queries * topk); + + cudaMemcpy(queries_d, queries, sizeof(float) * n_queries * dimensions, cudaMemcpyDefault); + + int64_t queries_shape[2] = {n_queries, dimensions}; + DLManagedTensor queries_tensor = prepare_tensor(queries_d, queries_shape, kDLFloat, 32, 2, kDLCUDA); + + int64_t neighbors_shape[2] = {n_queries, topk}; + DLManagedTensor neighbors_tensor = prepare_tensor(neighbors, neighbors_shape, kDLUInt, 32, 2, kDLCUDA); + + int64_t distances_shape[2] = {n_queries, topk}; + DLManagedTensor distances_tensor = prepare_tensor(distances, distances_shape, kDLFloat, 32, 2, kDLCUDA); + + cuvsStreamSync(cuvs_resources); + + cuvsFilter filter; // TODO: Implement Cagra Pre-Filtering, but leave it as no-op for now + filter.type = NO_FILTER; + filter.addr = (uintptr_t)NULL; + + *return_value = cuvsCagraSearch(cuvs_resources, search_params, index, &queries_tensor, &neighbors_tensor, + &distances_tensor, filter); + + cudaMemcpy(neighbors_h, neighbors, sizeof(uint32_t) * n_queries * topk, cudaMemcpyDefault); + cudaMemcpy(distances_h, distances, sizeof(float) * n_queries * topk, cudaMemcpyDefault); + + cuvsRMMFree(cuvs_resources, distances, sizeof(float) * n_queries * topk); + cuvsRMMFree(cuvs_resources, neighbors, sizeof(uint32_t) * n_queries * topk); + cuvsRMMFree(cuvs_resources, queries_d, sizeof(float) * n_queries * dimensions); +} + +/** + * @brief De-allocate BRUTEFORCE index + * + * @param[in] index reference to BRUTEFORCE index + * @param[out] return_value return value for cuvsBruteForceIndexDestroy function call + */ +void destroy_brute_force_index(cuvsBruteForceIndex_t index, int *return_value) { + *return_value = cuvsBruteForceIndexDestroy(index); +} + +/** + * @brief A function to build BRUTEFORCE index + * + * @param[in] dataset the dataset to be indexed + * @param[in] rows the number of rows in the dataset + * @param[in] dimensions the vector dimension + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[out] return_value return value for cuvsBruteForceBuild function call + * @param[in] n_writer_threads number of threads to use while indexing + * @return cuvsBruteForceIndex_t + */ +cuvsBruteForceIndex_t build_brute_force_index(float *dataset, long rows, long dimensions, cuvsResources_t cuvs_resources, + int *return_value, int n_writer_threads) { + + omp_set_num_threads(n_writer_threads); + cuvsRMMPoolMemoryResourceEnable(95, 95, false); + + cudaStream_t stream; + cuvsStreamGet(cuvs_resources, &stream); + + float *dataset_d; + cuvsRMMAlloc(cuvs_resources, (void**) &dataset_d, sizeof(float) * rows * dimensions); + cudaMemcpy(dataset_d, dataset, sizeof(float) * rows * dimensions, cudaMemcpyDefault); + + int64_t dataset_shape[2] = {rows, dimensions}; + DLManagedTensor dataset_tensor = prepare_tensor(dataset_d, dataset_shape, kDLFloat, 32, 2, kDLCUDA); + + cuvsBruteForceIndex_t index; + cuvsError_t index_create_status = cuvsBruteForceIndexCreate(&index); + + cuvsStreamSync(cuvs_resources); + *return_value = cuvsBruteForceBuild(cuvs_resources, &dataset_tensor, L2Expanded, 0.0f, index); + + omp_set_num_threads(1); + + return index; +} + +/** + * @brief A function to search the BRUTEFORCE index + * + * @param[in] index reference to a BRUTEFORCE index to search on + * @param[in] queries reference to query vectors + * @param[in] topk the top k results to return + * @param[in] n_queries number of queries + * @param[in] dimensions vector dimension + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[out] neighbors_h reference to the neighbor results on the host memory + * @param[out] distances_h reference to the distance results on the host memory + * @param[out] return_value return value for cuvsBruteForceSearch function call + * @param[in] prefilter_data cuvsFilter input prefilter that can be used to filter queries and neighbors based on the given bitmap + * @param[in] prefilter_data_length prefilter length input + * @param[in] n_rows number of rows in the dataset + */ +void search_brute_force_index(cuvsBruteForceIndex_t index, float *queries, int topk, long n_queries, int dimensions, + cuvsResources_t cuvs_resources, int64_t *neighbors_h, float *distances_h, int *return_value, long *prefilter_data, + long prefilter_data_length, long n_rows) { + + cudaStream_t stream; + cuvsStreamGet(cuvs_resources, &stream); + + int64_t *neighbors; + float *distances, *queries_d; + long *prefilter_data_d; + + long prefilter_data_32_size = sizeof(uint32_t) * prefilter_data_length * 2; + uint32_t *prefilter_data_32 = (uint32_t *)malloc(prefilter_data_32_size); + + cuvsRMMAlloc(cuvs_resources, (void**) &queries_d, sizeof(float) * n_queries * dimensions); + cuvsRMMAlloc(cuvs_resources, (void**) &neighbors, sizeof(int64_t) * n_queries * topk); + cuvsRMMAlloc(cuvs_resources, (void**) &distances, sizeof(float) * n_queries * topk); + cuvsRMMAlloc(cuvs_resources, (void**) &prefilter_data_d, prefilter_data_32_size); + + cudaMemcpy(queries_d, queries, sizeof(float) * n_queries * dimensions, cudaMemcpyDefault); + cudaMemcpy(prefilter_data_d, prefilter_data_32, prefilter_data_32_size, cudaMemcpyDefault); + + int64_t queries_shape[2] = {n_queries, dimensions}; + DLManagedTensor queries_tensor = prepare_tensor(queries_d, queries_shape, kDLFloat, 32, 2, kDLCUDA); + + int64_t neighbors_shape[2] = {n_queries, topk}; + DLManagedTensor neighbors_tensor = prepare_tensor(neighbors, neighbors_shape, kDLInt, 64, 2, kDLCUDA); + + int64_t distances_shape[2] = {n_queries, topk}; + DLManagedTensor distances_tensor = prepare_tensor(distances, distances_shape, kDLFloat, 32, 2, kDLCUDA); + + // unpack the incoming long into two 32bit ints + for (long i = 0; i < prefilter_data_length; i++) { + *(prefilter_data_32 + (2 * i)) = (int)(*(prefilter_data + i) >> 32); + *(prefilter_data_32 + ((2 * i) + 1)) = (int)*(prefilter_data + i); + //long l = (((long)*(prefilter_data_32 + (2 * i))) << 32) | (*(prefilter_data_32 + ((2 * i) + 1)) & 0xffffffffL); + } + + cuvsFilter prefilter; + if (prefilter_data == NULL) { + prefilter.type = NO_FILTER; + prefilter.addr = (uintptr_t)NULL; + } else { + int64_t prefilter_shape[1] = {(n_queries * n_rows + 31) / 32}; + DLManagedTensor prefilter_tensor = prepare_tensor(prefilter_data_d, prefilter_shape, kDLUInt, 32, 1, kDLCUDA); + prefilter.type = BITMAP; + prefilter.addr = (uintptr_t)&prefilter_tensor; + } + + cuvsStreamSync(cuvs_resources); + *return_value = cuvsBruteForceSearch(cuvs_resources, index, &queries_tensor, &neighbors_tensor, &distances_tensor, prefilter); + + cudaMemcpy(neighbors_h, neighbors, sizeof(int64_t) * n_queries * topk, cudaMemcpyDefault); + cudaMemcpy(distances_h, distances, sizeof(float) * n_queries * topk, cudaMemcpyDefault); + + cuvsRMMFree(cuvs_resources, neighbors, sizeof(int64_t) * n_queries * topk); + cuvsRMMFree(cuvs_resources, distances, sizeof(float) * n_queries * topk); + cuvsRMMFree(cuvs_resources, queries_d, sizeof(float) * n_queries * dimensions); +} + +/** + * @brief A function to serialize a BRUTEFORCE index + * + * @param[in] cuvs_resources reference of the underlying opaque C handle + * @param[in] index cuvsBruteForceIndex_t reference + * @param[out] return_value return value for cuvsBruteForceSerialize function call + * @param[in] filename the filename of the index file + */ +void serialize_brute_force_index(cuvsResources_t cuvs_resources, cuvsBruteForceIndex_t index, int *return_value, char* filename) { + *return_value = cuvsBruteForceSerialize(cuvs_resources, filename, index); +} + +/** + * @brief A function to de-serialize a BRUTEFORCE index + * + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[in] index cuvsBruteForceIndex_t reference + * @param[out] return_value return value for cuvsBruteForceDeserialize function call + * @param[in] filename the filename of the index file + */ +void deserialize_brute_force_index(cuvsResources_t cuvs_resources, cuvsBruteForceIndex_t index, int *return_value, char* filename) { + *return_value = cuvsBruteForceDeserialize(cuvs_resources, filename, index); +} + +/** + * @brief A function to create and serialize an HNSW index from CAGRA index + * + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[in] file_path the path to the file of the created HNSW index + * @param[in] index cuvsCagraIndex_t reference to the existing CAGRA index + * @param[out] return_value return value for cuvsCagraSerializeToHnswlib function call + */ +void serialize_cagra_index_to_hnsw(cuvsResources_t cuvs_resources, char *file_path, cuvsCagraIndex_t index, int *return_value) { + *return_value = cuvsCagraSerializeToHnswlib(cuvs_resources, file_path, index); +} + +/** + * @brief A function to deserialize the persisted HNSW index + * + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[in] file_path the path to the persisted HNSW index file + * @param[in] hnsw_params reference to the HNSW index params + * @param[out] return_value return value for cuvsHnswDeserialize function call + * @param[in] vector_dimension the dimension of the vectors in the HNSW index + * @returns cuvsHnswIndex_t reference to the created HNSW index + */ +cuvsHnswIndex_t deserialize_hnsw_index(cuvsResources_t cuvs_resources, char *file_path, + cuvsHnswIndexParams_t hnsw_params, int *return_value, int vector_dimension) { + cuvsHnswIndex_t hnsw_index; + cuvsError_t rv = cuvsHnswIndexCreate(&hnsw_index); + hnsw_index->dtype.bits = 32; + hnsw_index->dtype.code = kDLFloat; + hnsw_index->dtype.lanes = 1; + *return_value = cuvsHnswDeserialize(cuvs_resources, hnsw_params, file_path, vector_dimension, L2Expanded, hnsw_index); + return hnsw_index; +} + +/** + * @brief A Function to search in the HNSW index + * + * @param[in] cuvs_resources reference to the underlying opaque C handle + * @param[in] hnsw_index the HNSW index reference + * @param[in] search_params reference to the HNSW search parameters + * @param[out] return_value return value for cuvsHnswSearch function call + * @param[out] neighbors_h result container on host holding the neighbor ids + * @param[out] distances_h result container on host holding the distances + * @param[in] queries reference to the queries + * @param[in] topk the top k results to return + * @param[in] query_dimension the dimension of the query vectors + * @param[in] n_queries the number of queries passed to the function + */ +void search_hnsw_index(cuvsResources_t cuvs_resources, cuvsHnswIndex_t hnsw_index, cuvsHnswSearchParams_t search_params, + int *return_value, uint64_t *neighbors_h, float *distances_h, float *queries, int topk, int query_dimension, int n_queries) { + + int64_t queries_shape[2] = {n_queries, query_dimension}; + DLManagedTensor queries_tensor = prepare_tensor(queries, queries_shape, kDLFloat, 32, 2, kDLCPU); + + int64_t neighbors_shape[2] = {n_queries, topk}; + DLManagedTensor neighbors_tensor = prepare_tensor(neighbors_h, neighbors_shape, kDLUInt, 64, 2, kDLCPU); + + int64_t distances_shape[2] = {n_queries, topk}; + DLManagedTensor distances_tensor = prepare_tensor(distances_h, distances_shape, kDLFloat, 32, 2, kDLCPU); + + *return_value = cuvsHnswSearch( + cuvs_resources, search_params, hnsw_index, &queries_tensor, &neighbors_tensor, &distances_tensor); +} + +/** + * @brief A function to destroy the HNSW index + * + * @param[in] hnsw_index the HNSW index reference + * @param[out] return_value return value for cuvsHnswIndexDestroy function call + */ +void destroy_hnsw_index(cuvsHnswIndex_t hnsw_index, int *return_value) { + *return_value = cuvsHnswIndexDestroy(hnsw_index); +} + +/** + * @brief struct for containing gpu information + */ +typedef struct gpuInfo { + int gpu_id; + char name[256]; + long free_memory; + long total_memory; + float compute_capability; +} gpuInfo; + +/** + * @brief A function to get GPU details + * + * @param[out] return_value return value for cudaMemGetInfo function call + * @param[out] num_gpus the number of devices found + * @param[out] gpu_info_arr reference to the array of gpuInfo objects + */ +void get_gpu_info(int *return_value, int *num_gpus, gpuInfo *gpu_info_arr) { + cudaGetDeviceCount(num_gpus); + // Limiting the num_gpus to 1024. For more details please see comments in Util.availableGPUs() + *num_gpus = (*num_gpus > 1024) ? 1024 : *num_gpus; + struct gpuInfo gpuInfos[*num_gpus]; + size_t free, total; + // https://docs.nvidia.com/cuda/cuda-runtime-api/structcudaDeviceProp.html#structcudaDeviceProp + struct cudaDeviceProp deviceProp; + for (int i = 0; i < *num_gpus; i++) { + cudaSetDevice(i); + cudaGetDeviceProperties(&deviceProp, i); + char buffer[10]; + sprintf(buffer, "%d.%d", deviceProp.major, deviceProp.minor); + *return_value = cudaMemGetInfo(&free, &total); + gpuInfos[i].gpu_id = i; + strcpy(gpuInfos[i].name, deviceProp.name); + gpuInfos[i].free_memory = free; + gpuInfos[i].total_memory = total; + gpuInfos[i].compute_capability = atof(buffer); + *(gpu_info_arr + i) = gpuInfos[i]; + } +}