/*
 * Copyright (c) 2023-2024, NVIDIA CORPORATION.  All rights reserved.
 *
 * NVIDIA CORPORATION and its licensors retain all intellectual property
 * and proprietary rights in and to this software, related documentation
 * and any modifications thereto.  Any use, reproduction, disclosure or
 * distribution of this software and related documentation without an express
 * license agreement from NVIDIA CORPORATION is strictly prohibited.
 */

/*
 * cudlaExternalEtbl.hpp - Exports external cuDLA interfaces.
 */

#if !defined __CUDLA_EXTERNAL_ETBL_HPP__
#define __CUDLA_EXTERNAL_ETBL_HPP__

#include "cudla.h"

#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */

/**
 * Translate csv attribute types.
 */
enum cudlaTranslateAttributeType {
    /**
     * Flag to retrieve csv stream length.
     */
    CUDLA_GET_CSV_LENGTH = 0,
    /**
     * Flag to retrieve csv stream statistics.
     */
    CUDLA_GET_CSV_STATS = 1,
};

typedef enum cudlaTranslateAttributeType cudlaTranslateAttributeType;

/**
 * Translate csv attribute.
 */
typedef union cudlaTranslateCsvAttribute_t {
    /**
     * Returns the length of csv stream.
     */
    uint64_t csvStreamLength;
    /**
     * Returns the statistics of csv stream.
     */
    void* csvStreamStats;
} cudlaTranslateCsvAttribute;

typedef struct cudlaExernalEtbl_t
{
  /**
   * \brief Get buffer attribute.
   *
   * The output task statistics buffer will be available to user once DLA
   * task execution has completed. This buffer will be in raw format. In order 
   * to convert it into a csv stream format, the user needs to perform below steps:
   * - Query the size of the resultant csv stream using the current API.
   * - Allocate sufficient memory in the application using the size from Step 1.
   * - Request for the csv stream in the allocated buffer using the current API. 
   *
   * The valid value of \p csvAttrType can be one of the following:
   * - ::CUDLA_GET_CSV_LENGTH, specifies that the application is querying for 
   *                           translated csv stream length.
   * - ::CUDLA_GET_CSV_STATS, specifies that the application is querying for 
   *                          translated csv stream statistics.
   *
   * This function can return ::cudlaErrorInvalidParam if
   * - device handle passed is NULL.
   * - input buffer passed is NULL.
   * - idx is less than 0.
   * - dlaFreqMHz is less than or equal to 0.
   *
   * This function can return ::cudlaErrorUmd in certain cases when the
   * underlying DLA operation fails.
   *
   * \param[in] devHandle - A valid device handle.
   * \param[in] input - Buffer containing raw statistics data which needs to be translated into
   *                    csv stream.
   * \param[in] dlaFreqMHz - DLA freq in MHz that was used to run the corresponding DLA task.
   * \param[in] idx - Index corresponding to statistics descriptor for which profiling is requested.
   *                  This should be less than total number of statistics descriptors.
   * \param[in] csvAttrType - The attribute type that is being requested.
   * \param[in] csvAttribute - The output pointer where the attribute will be available.
   *
   * \return
   * ::cudlaSuccess,
   * ::cudlaErrorInvalidParam,
   * ::cudlaErrorUmd
   * 
   * If effectively there is only one module loaded on the devHandle then this API will consider
   * that module otherwise it would throw error.
   */
    cudlaStatus (*etiTranslateStats)(cudlaDevHandle const devHandle,
                                     unsigned char* input,
                                     uint32_t const dlaFreqMHz,
                                     uint32_t idx,
                                     cudlaTranslateAttributeType const csvAttrType,
                                     cudlaTranslateCsvAttribute* const csvAttribute);


  /**
   * \brief Get buffer attribute.
   *
   * The output task statistics buffer will be available to user once DLA
   * task execution has completed. This buffer will be in raw format. In order 
   * to convert it into a csv stream format, the user needs to perform below steps:
   * - Query the size of the resultant csv stream using the current API.
   * - Allocate sufficient memory in the application using the size from Step 1.
   * - Request for the csv stream in the allocated buffer using the current API. 
   *
   * The valid value of \p csvAttrType can be one of the following:
   * - ::CUDLA_GET_CSV_LENGTH, specifies that the application is querying for 
   *                           translated csv stream length.
   * - ::CUDLA_GET_CSV_STATS, specifies that the application is querying for 
   *                          translated csv stream statistics.
   *
   * This function can return ::cudlaErrorInvalidParam if
   * - device handle passed is NULL.
   * - input buffer passed is NULL.
   * - idx is less than 0.
   * - dlaFreqMHz is less than or equal to 0.
   *
   * This function can return ::cudlaErrorUmd in certain cases when the
   * underlying DLA operation fails.
   *
   * \param[in] devHandle - A valid device handle.
   * \param[in] hModule - A valid module handle.
   * \param[in] input - Buffer containing raw statistics data which needs to be translated into
   *                    csv stream.
   * \param[in] dlaFreqMHz - DLA freq in MHz that was used to run the corresponding DLA task.
   * \param[in] idx - Index corresponding to statistics descriptor for which profiling is requested.
   *                  This should be less than total number of statistics descriptors.
   * \param[in] csvAttrType - The attribute type that is being requested.
   * \param[in] csvAttribute - The output pointer where the attribute will be available.
   *
   * \return
   * ::cudlaSuccess,
   * ::cudlaErrorInvalidParam,
   * ::cudlaErrorUmd
   */
    cudlaStatus (*etiTranslateStatsForMultiModule)(cudlaDevHandle const devHandle,
                                     cudlaModule const hModule,
                                     unsigned char* input,
                                     uint32_t const dlaFreqMHz,
                                     uint32_t idx,
                                     cudlaTranslateAttributeType const csvAttrType,
                                     cudlaTranslateCsvAttribute* const csvAttribute);
    
} cudlaExternalEtbl;

/**
 * \brief Get function pointer table to access the functions present inside cudlaExternalEtbl.
 *
 * \param[in] flags - Reserved for future. Must be set to 0.
 * \param[out] exportTable - The output pointer which can be used to access the 
 *                           functions present inside cudlaExternalEtbl.
 * \return
 * ::cudlaSuccess,
 * ::cudlaErrorInvalidParam
 */
cudlaStatus cudlaGetExternalExportTable(const cudlaExternalEtbl** const exportTable,
                                        uint32_t const flags);
#if defined(__cplusplus)
}

#endif /* __cplusplus */
#endif // __CUDLA_EXTERNAL_ETBL_HPP__

