/*========================== begin_copyright_notice ============================
Copyright (C) 2021-2024 Intel Corporation

SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/

#ifndef _GTREPLAY_CALLBACKS_H
#define _GTREPLAY_CALLBACKS_H

#include <stdint.h>
#include "gtreplay_types.h"

/*!
\typedef GTReplayOnKernelBuildCallbackFunc
\ingroup GTREPLAY_CALLBACK
callback function invoked during kernel compilation

\typedef GTReplayOnKernelCompleteCallbackFunc
\ingroup GTREPLAY_CALLBACK
callback function invoked after kernel completes its execution

\typedef GTReplayOnKernelEventCallbackFunc
\ingroup GTREPLAY_CALLBACK
callback function invoked before the kernel begins running or after the kernel ends

\typedef GTReplayOnSwThreadEventCallbackFunc
\ingroup GTREPLAY_CALLBACK
callback function invoked before a kernel instance (SW thread) is dispatched to any of HW threads or after it ends

\typedef GTReplayInstrumentationCallbackFunc
\ingroup GTREPLAY_CALLBACK
callback function invoked before or after any instruction of the kernel
*/

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

typedef void(*GTReplayOnKernelBuildCallbackFunc)(GTReplayKernel kernel);
typedef void(*GTReplayOnKernelCompleteCallbackFunc)(GTReplayKernel kernel);
typedef void(*GTReplayOnKernelEventCallbackFunc)(void*);
typedef void(*GTReplayOnSwThreadEventCallbackFunc)(uint32_t tileId, uint32_t tid, GTReplayState state, void*);
typedef void(*GTReplayInstrumentationCallbackFunc)(uint32_t tileId, uint32_t tid, GTReplayIns ins, GTReplayState state, void*);

/*************************************************************************
 *
 * Callback registration API
 *
 ************************************************************************/

/*!
 * Register a callback that will be invoked before GTReplay builds any kernel
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   func  the function to be invoked
 */
GTREPLAY_API
void GTReplay_RegisterOnKernelBuildCallback(GTReplayOnKernelBuildCallbackFunc func);

/*!
 * Register a callback that will be invoked after any kernel was completed
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   func  the function to be invoked
 */
GTREPLAY_API
void GTReplay_RegisterOnKernelCompleteCallback(GTReplayOnKernelCompleteCallbackFunc func);

/*!
 * Register a callback that will be invoked before GTReplay begins execution of a specific kernel
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterOnKernelBeginCallback(GTReplayKernel kernel, GTReplayOnKernelEventCallbackFunc func, void* data);

/*!
 * Register a callback that will be invoked after GTReplay ends execution of a specific kernel
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterOnKernelEndCallback(GTReplayKernel kernel, GTReplayOnKernelEventCallbackFunc func, void* data);

/*!
 * Register a callback that will be invoked before a given kernel begins
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterCallbackKernelBegin(GTReplayKernel kernel, GTReplayOnKernelEventCallbackFunc func, void* data);

/*!
 * Register a callback that will be invoked after a given kernel ends
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterCallbackOnKernelEnd(GTReplayKernel kernel, GTReplayOnKernelEventCallbackFunc func, void* data);

/*!
 * Register a callback that will be invoked before any SW thread (dispatch) of a given kernel begins
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterCallbackOnSwThreadBegin(GTReplayKernel kernel, GTReplayOnSwThreadEventCallbackFunc func, void* data);

/*!
 * Register a callback that will be invoked after any SW thread (dispatch) of a given kernel ends
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterCallbackOnSwThreadEnd(GTReplayKernel kernel, GTReplayOnSwThreadEventCallbackFunc func, void* data);


/*!
 * Register a callback that will be invoked before a given instruction of a given kernel
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   ins     an instruction handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterCallbackBeforeIns(GTReplayKernel kernel, GTReplayIns ins, GTReplayInstrumentationCallbackFunc func, void* data);

/*!
 * Register a callback that will be invoked after a given instruction of a given kernel
 * \ingroup GTREPLAY_CALLBACK
 * \param[in]   kernel  a kernel handle
 * \param[in]   ins     an instruction handle
 * \param[in]   func    the function to be invoked
 * \param[in]   data    additional arg
 */
GTREPLAY_API
void GTReplay_RegisterCallbackAfterIns(GTReplayKernel kernel, GTReplayIns ins, GTReplayInstrumentationCallbackFunc func, void* data);

#if defined(__cplusplus)
}
#endif

#endif // _GTREPLAY_CALLBACKS_H
