/*
 * Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
 *
 * This source code and/or documentation ("Licensed Deliverables") are
 * subject to NVIDIA intellectual property rights under U.S. and
 * international Copyright laws.
 */

#pragma once

#include <cugraph-ops/test/graph/format_mfg.hpp>

#include <cuda_runtime.h>

#include <cstdint>

namespace cugraph::ops::graph {

/**
 * @brief Computes the unique elements of the input array
 *
 * @param[out]   in_nodes       the uniquified input nodes of this MFG.
 *                              [on device] [len = `mfg.n_in_nodes`]
 * @param[out]   n_in_nodes     Intermediate buffer for the number of input
 *                              nodes of the MFG. `mfg.n_in_nodes` will be set
 *                              to a valid value after calling this function,
 *                              and the buffer can be re-used.
 *                              [on host, pinned] [len = `1`]
 * @param[in]    mfg            the (ELLPACK/CSR) MFG to uniquify.
 *                              In particular, we use the `mfg.neighbors` /
 *                              `mfg.indices` and `add_nodes` arrays and output
 *                              all their unique values to the `in_nodes`
 *                              array.
 * @param[in]    add_nodes      additional node IDs to uniquify.
 *                              Ignored if `nullptr`.
 *                              [on device] [len = `mfg.n_add`]
 * @param[in]    n_add          Number of additional nodes.
 * @param[in]    max_uniqs      maximum possible unique numbers. Usually the
 *                              number of node IDs from the entire graph.
 * @param[in]    workspace      scratch buffer. [on device]
 *                              [len = `workspace_size`] Pass a `nullptr` in
 *                              order to get to know its size.
 * @param[inout] workspace_size workspace size in bytes. If `workspace` is a
 *                              `nullptr`, then this will be computed and the
 *                              caller is expected to allocate the workspace
 *                              buffer of this size.
 * @param[in]    stream         cuda stream
 *
 * @{
 */
void uniquify(int32_t* in_nodes,
              int32_t* n_in_nodes,
              const mfg_ellpack_s32_t& graph,
              const int32_t* add_nodes,
              int32_t n_add,
              int32_t max_uniqs,
              void* workspace,
              size_t& workspace_size,
              cudaStream_t stream);
void uniquify(int64_t* in_nodes,
              int64_t* n_in_nodes,
              const mfg_ellpack_s64_t& graph,
              const int64_t* add_nodes,
              int64_t n_add,
              int64_t max_uniqs,
              void* workspace,
              size_t& workspace_size,
              cudaStream_t stream);
void uniquify(int32_t* in_nodes,
              int32_t* n_in_nodes,
              const mfg_csc_s32_t& graph,
              const int32_t* add_nodes,
              int32_t n_add,
              int32_t max_uniqs,
              void* workspace,
              size_t& workspace_size,
              cudaStream_t stream);
void uniquify(int64_t* in_nodes,
              int64_t* n_in_nodes,
              const mfg_csc_s64_t& graph,
              const int64_t* add_nodes,
              int64_t n_add,
              int64_t max_uniqs,
              void* workspace,
              size_t& workspace_size,
              cudaStream_t stream);
/** @} */

}  // namespace cugraph::ops::graph
