Merge "Execution and Debug trace support." into amd-staging-rome-2.2

This commit is contained in:
Vasanthakumar Rajagopal
2020-04-15 06:30:50 -04:00
committed by Gerrit Code Review
19 changed files with 1728 additions and 8 deletions

View File

@@ -112,6 +112,7 @@ BASE_OBJ_PATH := ./$(OBJ_DIR)/$(CONFIG_NAME)
# of source code.
BASE_OBJ_CONFIG_PATH := $(BASE_OBJ_PATH)/$(CONFIG_DIR)
BASE_OBJ_FRAME_PATH := $(BASE_OBJ_PATH)/$(FRAME_DIR)
BASE_OBJ_AOCLDTL_PATH := $(BASE_OBJ_PATH)/$(AOCLDTL_DIR)
BASE_OBJ_REFKERN_PATH := $(BASE_OBJ_PATH)/$(REFKERN_DIR)
BASE_OBJ_KERNELS_PATH := $(BASE_OBJ_PATH)/$(KERNELS_DIR)
BASE_OBJ_SANDBOX_PATH := $(BASE_OBJ_PATH)/$(SANDBOX_DIR)
@@ -209,6 +210,11 @@ MK_REFKERN_OBJS := $(foreach arch, $(CONFIG_LIST), \
# Generate object file paths for all of the portable framework source code.
MK_FRAME_OBJS := $(call gen-obj-paths-from-src,$(FRAME_SRC_SUFS),$(MK_FRAME_SRC),$(FRAME_PATH),$(BASE_OBJ_FRAME_PATH))
# Generate object file paths for all of the debgu and trace logger.
MK_AOCLDTL_OBJS := $(call gen-obj-paths-from-src,$(AOCLDTL_SRC_SUFS),$(MK_AOCLDTL_SRC),$(AOCLDTL_PATH),$(BASE_OBJ_AOCLDTL_PATH))
# Generate object file paths for the sandbox source code. If a sandbox was not
# enabled a configure-time, this variable will we empty.
MK_SANDBOX_OBJS := $(call gen-obj-paths-from-src,$(SANDBOX_SRC_SUFS),$(MK_SANDBOX_SRC),$(SANDBOX_PATH),$(BASE_OBJ_SANDBOX_PATH))
@@ -218,6 +224,7 @@ MK_BLIS_OBJS := $(MK_CONFIG_OBJS) \
$(MK_KERNELS_OBJS) \
$(MK_REFKERN_OBJS) \
$(MK_FRAME_OBJS) \
$(MK_AOCLDTL_OBJS) \
$(MK_SANDBOX_OBJS)
# Optionally filter out the BLAS and CBLAS compatibility layer object files.
@@ -508,6 +515,18 @@ else
endif
endef
# first argument: a configuration name from the union of config_list and
# config_name, used to look up the CFLAGS to use during compilation.
define make-aocldtl-rule
$(BASE_OBJ_AOCLDTL_PATH)/%.o: $(AOCLDTL_PATH)/%.c $(BLIS_H_FLAT) $(MAKE_DEFS_MK_PATHS)
ifeq ($(ENABLE_VERBOSE),yes)
$(CC) $(call get-aocldtl-cflags-for,$(1)) -c $$< -o $$@
else
@echo "Compiling $$@" $(call get-aocldtl-text-for,$(1))
@$(CC) $(call get-aocldtl-cflags-for,$(1)) -c $$< -o $$@
endif
endef
# first argument: a kernel set (name) being targeted (e.g. haswell).
define make-refinit-rule
$(BASE_OBJ_REFKERN_PATH)/$(1)/bli_cntx_$(1)_ref.o: $(REFKERN_PATH)/bli_cntx_ref.c $(BLIS_H_FLAT) $(MAKE_DEFS_MK_PATHS)
@@ -583,6 +602,14 @@ $(foreach conf, $(CONFIG_LIST), $(eval $(call make-config-rule,$(conf))))
# item.)
$(foreach conf, $(CONFIG_NAME), $(eval $(call make-frame-rule,$(conf))))
# Instantiate the build rule for debug and trace log. Use the CFLAGS for the
# configuration family, which exists in the directory whose name is equal to
# CONFIG_NAME. Note that this doesn't need to be in a loop since we expect
# CONFIG_NAME to only ever contain a single name. (BTW: If CONFIG_NAME refers
# to a singleton family, then CONFIG_LIST contains CONFIG_NAME as its only
# item.)
$(foreach conf, $(CONFIG_NAME), $(eval $(call make-aocldtl-rule,$(conf))))
# Instantiate the build rule for reference kernel initialization and
# reference kernels for each of the sub-configurations in CONFIG_LIST with
# the CFLAGS designated for that sub-configuration.
@@ -1053,6 +1080,7 @@ ifeq ($(IS_CONFIGURED),yes)
ifeq ($(ENABLE_VERBOSE),yes)
- $(FIND) $(CONFIG_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
- $(FIND) $(FRAME_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
- $(FIND) $(AOCLDTL_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
- $(FIND) $(REFKERN_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
- $(FIND) $(KERNELS_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
ifneq ($(SANDBOX),)
@@ -1063,6 +1091,8 @@ else
@- $(FIND) $(CONFIG_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
@echo "Removing makefile fragments from $(FRAME_FRAG_PATH)"
@- $(FIND) $(FRAME_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
@echo "Removing makefile fragments from $(AOCLDTL_FRAG_PATH)"
@- $(FIND) $(AOCLDTL_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
@echo "Removing makefile fragments from $(REFKERN_FRAG_PATH)"
@- $(FIND) $(REFKERN_FRAG_PATH) -name "$(FRAGMENT_MK)" | $(XARGS) $(RM_F)
@echo "Removing makefile fragments from $(KERNELS_FRAG_PATH)"

478
aocl_dtl/aocldtl.c Normal file
View File

@@ -0,0 +1,478 @@
/*===================================================================
* File Name : aocldtl.c
*
* Description : This file contains main logging functions.
* These functions are invoked though macros by
* end user.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#include "aocltpdef.h"
#include "aocldtl.h"
#include "aoclfal.h"
#include "aocldtlcf.h"
#include "aoclflist.h"
#include "aoclos.h"
#ifdef AOCL_DTL_AUTO_TRACE_ENABLE
#if defined(__linux__)
#define __USE_GNU
#include <dlfcn.h>
#endif
#endif
/* The user can configure the file name in which he wants to dump the data */
#if AOCL_DTL_TRACE_ENABLE
/* The file name for storing traced log added manually in the code */
static char *pchDTL_TRACE_FILE = AOCL_DTL_TRACE_FILE;
/* Global file pointer for trace logging */
AOCL_FLIST_Node *gpTraceFileList = NULL;
/* By default the trace level will be set to ALL User can configure this
parameter at run time using command line argument */
uint32 gui32TraceLogLevel = AOCL_DTL_LEVEL_ALL;
#endif
#if AOCL_DTL_LOG_ENABLE
/* The file name for storing log data */
static char *pchDTL_LOG_FILE = AOCL_DTL_LOG_FILE;
/* Global file pointer for logging the results */
AOCL_FLIST_Node *gpLogFileList = NULL;
#endif
#if AOCL_DTL_AUTO_TRACE_ENABLE
/* The file name for storing execution trace,
These files are used by compiler assisted execution testing */
static char *pchDTL_AUTO_TRACE_FILE = AOCL_DTL_AUTO_TRACE_FILE;
/* Global file pointer for logging the results */
AOCL_FLIST_Node *gpAutoTraceFileList = NULL;
#endif
/*===================================================================
* Function Name : DTL_Initialize
* Description : Creates/Opens log file and initializes the
* global trace log level
* Input Parameter(s) : ui32CurrentLogLevel - current log level
* which user can configure at run time
* Output Parameter(s) : None
* Return parameter(s) : None
*==================================================================*/
#ifdef AOCL_DTL_INITIALIZE_ENABLE
void DTL_Initialize(
uint32 ui32CurrentLogLevel)
{
/* If user selects invalid trace log level then the dafault trace log level
will be AOCL_DTL_LEVEL_ALL */
if ((ui32CurrentLogLevel < 1) || (ui32CurrentLogLevel > 4))
{
ui32CurrentLogLevel = AOCL_DTL_LEVEL_ALL;
}
#if AOCL_DTL_TRACE_ENABLE
/* Create/Open the file to log the traced data */
AOCL_FLIST_AddFile(pchDTL_TRACE_FILE, &gpTraceFileList, AOCL_gettid());
if (NULL == gpTraceFileList)
{
/* Unable to open the specified file.*/
AOCL_DEBUGPRINT("Unable to create the trace file %s\n", pchDTL_TRACE_FILE);
return;
}
/* Assign the user requested log level to the global trace log level */
gui32TraceLogLevel = ui32CurrentLogLevel;
#endif
#if AOCL_DTL_LOG_ENABLE
/* Create/Open the file to log the log data */
AOCL_FLIST_AddFile(pchDTL_LOG_FILE, &gpLogFileList, AOCL_gettid());
if (NULL == gpLogFileList)
{
/* Unable to open the specified file.*/
AOCL_DEBUGPRINT("Unable to create the log file %s\n", pchDTL_LOG_FILE);
return;
}
#endif
#if AOCL_DTL_AUTO_TRACE_ENABLE
/* Create/Open the file to log the log data */
AOCL_FLIST_AddFile(pchDTL_AUTO_TRACE_FILE, &gpAutoTraceFileList, AOCL_gettid());
if (NULL == gpAutoTraceFileList)
{
/* Unable to open the specified file.*/
AOCL_DEBUGPRINT("Unable to create the log file %s\n", pchDTL_AUTO_TRACE_FILE);
return;
}
#endif
} /* DTL_Initialize */
#endif
/*===================================================================
* Function Name : DTL_Uninitialize
* Description : Close all the log files
* Input Parameter(s) : void
* Output Parameter(s) : None
* Return parameter(s) : None
*==================================================================*/
#ifdef AOCL_DTL_INITIALIZE_ENABLE
void DTL_Uninitialize(void)
{
#if AOCL_DTL_TRACE_ENABLE
/* Close the trace file */
AOCL_FLIST_CloseAll(gpTraceFileList);
#endif
#if AOCL_DTL_LOG_ENABLE
/* Close the log file */
AOCL_FLIST_CloseAll(gpLogFileList);
#endif
#if AOCL_DTL_AUTO_TRACE_ENABLE
/* Close the log file */
AOCL_FLIST_CloseAll(gpAutoTraceFileList);
#endif
return;
} /* DTL_Uninitialise */
#endif
/*===================================================================
* Function Name : DTL_Trace
* Description : This is common lowest level function
* to log the event to a file, This function
* will take case of choosing correct file
* according to the current thread and
* log the event as per format requested.
* Input Parameter(s) : ui8LogLevel - Log Level
* ui8LogType - Identify log type (entry, exit etc)
* pi8FileName.- File name
* pi8FunctionName - Function Name
* ui32LineNumber - Line number
* pi8Message - Message to be printed
* Output Parameter(s) : None
* Return parameter(s) : None
*==================================================================*/
#if (AOCL_DTL_TRACE_ENABLE || AOCL_DTL_LOG_ENABLE)
void DTL_Trace(
uint8 ui8LogLevel,
uint8 ui8LogType,
const int8 *pi8FileName,
const int8 *pi8FunctionName,
uint32 ui32LineNumber,
const int8 *pi8Message)
{
uint8 i = 0;
AOCL_FAL_FILE *pOutFile = NULL;
if (ui8LogType == TRACE_TYPE_LOG || ui8LogType == TRACE_TYPE_RAW)
{
pOutFile = AOCL_FLIST_GetFile(gpLogFileList, AOCL_gettid());
/* If trace file pointer is equal to NULL then return with out dumping data
to the file */
if (NULL == pOutFile)
{
/* It might be the first call from the current thread, try to create
new trace for this thread. */
pOutFile = AOCL_FLIST_AddFile(pchDTL_LOG_FILE, &gpLogFileList, AOCL_gettid());
if (NULL == pOutFile)
{
AOCL_DEBUGPRINT("File does not exists to dump the trace data \n");
return;
}
}
}
else
{
pOutFile = AOCL_FLIST_GetFile(gpTraceFileList, AOCL_gettid());
/* If trace file pointer is equal to NULL then return with out dumping data
to file */
if (NULL == pOutFile)
{
/* It might be the first call from the current thread, try to create
new trace for this thread. */
pOutFile = AOCL_FLIST_AddFile(pchDTL_TRACE_FILE, &gpTraceFileList, AOCL_gettid());
if (NULL == pOutFile)
{
AOCL_DEBUGPRINT("File does not exists to dump the trace data \n");
return;
}
}
}
/* Log the message only if the log level is less than or equal to global log
level set while initialization */
if (ui8LogLevel <= gui32TraceLogLevel)
{
/* this loop is for formating the output log file */
for (i = 0; i < ui8LogLevel; i++)
{
/* print tabs in the output file */
fprintf(pOutFile, "\t");
}
switch (ui8LogType)
{
case TRACE_TYPE_FENTRY:
fprintf(pOutFile, "Entering %s()...\n", pi8FunctionName);
break;
case TRACE_TYPE_FEXIT:
if (pi8Message == NULL)
{ /* Function returned successfully */
fprintf(pOutFile, "Returning from %s()\n", pi8FunctionName);
}
else
{ /* Function failed to complete, use message to get error */
fprintf(pOutFile, "Returning from %s() with error %s\n", pi8FunctionName, pi8Message);
}
break;
case TRACE_TYPE_LOG:
fprintf(pOutFile, "%s:%d:%s\n", pi8FileName, ui32LineNumber, pi8Message);
break;
case TRACE_TYPE_RAW:
fprintf(pOutFile, "%s\n", pi8Message);
break;
}
}
} /* DTL_Data_Trace_Entry */
#endif
/*===================================================================
* Function Name : DTL_DumpData
* Description : This function is mainly used for dumping
* the data into the file
* Input Parameter(s) : pui8Buffer - the buffer to be dumped
* ui32BufferSize.- the no. of bytes to be dumped
* ui8DataType - the data type char/int32/int32
* Output Parameter(s) : None
* Return parameter(s) : None
*==================================================================*/
#if AOCL_DTL_DUMP_ENABLE
void DTL_DumpData(
uint8 ui8LogLevel,
void *pvBuffer,
uint32 ui32BufferSize,
uint8 ui8DataType,
int8 *pi8Message,
int8 i8OutputType)
{
uint32 j;
/* Pointer to store the buffer */
uint32 *pui32Array, ui32LocalData;
uint16 *pui16Array;
uint8 *pui8CharArray;
int8 *pi8CharString;
/* If dump (log) file pointer is equal to NULL return with out dumping data to file */
AOCL_FAL_FILE *pDumpFile = AOCL_FLIST_GetFile(gpLogFileList, AOCL_gettid());
/* Log the message only if the log level is less than or equal to global log
level set while initialization */
if (ui8LogLevel > gui32TraceLogLevel)
{
return;
}
/* The string message */
if (pi8Message != NULL)
{
fprintf(pDumpFile, "%s :", pi8Message);
}
/* Assuming that if the Data type for character = 1
* the Data type for uint32 = 2
* the data type for uint32 = 4
* the data type for string = 3
*/
if (ui8DataType == AOCL_STRING_DATA_TYPE)
{
/* Typecast the void buffer to character buffer */
pi8CharString = (int8 *)pvBuffer;
fprintf(pDumpFile, "%s", pi8CharString);
fprintf(pDumpFile, "\n");
}
if (ui8DataType == AOCL_CHAR_DATA_TYPE)
{
/* Typecast the void buffer to character buffer */
pui8CharArray = (uint8 *)pvBuffer;
for (j = 0; j < ui32BufferSize; j++)
{
if (i8OutputType == AOCL_LOG_HEX_VALUE)
{
fprintf(pDumpFile, "\n\t%5d:0x%x", j, pui8CharArray[j]);
}
else
{
fprintf(pDumpFile, "\n\t%5d:%u", j, pui8CharArray[j]);
}
}
fprintf(pDumpFile, "\n");
}
if (ui8DataType == AOCL_UINT16_DATA_TYPE)
{
/* Typecast the void buffer to uint32 bit buffer */
pui16Array = (uint16 *)pvBuffer;
/* dump the data in the file line by line */
for (j = 0; j < ui32BufferSize; j++)
{
if (i8OutputType == AOCL_LOG_HEX_VALUE)
{
fprintf(pDumpFile, "\n\t%5d:0x%x", j, pui16Array[j]);
}
else
{
fprintf(pDumpFile, "\n\t%5d:%u", j, pui16Array[j]);
}
}
fprintf(pDumpFile, "\n");
} /* End of if */
if (ui8DataType == AOCL_UINT32_DATA_TYPE)
{
/* Typecast the void buffer to uint32 buffer */
pui32Array = (uint32 *)pvBuffer;
/* dump the data in the file line by line */
for (j = 0; j < ui32BufferSize; j++)
{
ui32LocalData = pui32Array[j];
if (i8OutputType == AOCL_LOG_HEX_VALUE)
{
fprintf(pDumpFile, "\n\t%5d:0x%x", j, ui32LocalData);
}
else
{
fprintf(pDumpFile, "\n\t%5d:%u", j, ui32LocalData);
}
}
fprintf(pDumpFile, "\n");
} /* End of if */
} /* DTL_DumpData */
#endif
/* This is enabled by passing ETRACE_ENABLE=1 to make */
#ifdef AOCL_DTL_AUTO_TRACE_ENABLE
/*
Disable intrumentation for these functions as they will also be
called from compiler generated instumation code to trace
function execution.
It needs to be part of declration in the C file so can't be
moved to header file.
WARNING: These functions are automatically invoked. however any function
called from this should have instumtation disable to avoid recursive
calls which results in hang/crash.
*/
void __cyg_profile_func_enter(void *this_fn, void *call_site) __attribute__((no_instrument_function));
void __cyg_profile_func_exit(void *this_fn, void *call_site) __attribute__((no_instrument_function));
/*===================================================================
* Function Name : __cyg_profile_func_enter
* Description : This function is automatically invoked
* by compiler instrumntation when the flow
* enters a function.
* Input Parameter(s) : pvThisFunc - Address of function entered.
* call_site.- Address of the caller
* Output Parameter(s) : None
* Return parameter(s) : None
*==================================================================*/
void __cyg_profile_func_enter(void *pvThisFunc, void *pvCaller)
{
Dl_info info;
dladdr(pvThisFunc, &info);
AOCL_FAL_FILE *pOutFile = NULL;
pOutFile = AOCL_FLIST_GetFile(gpAutoTraceFileList, AOCL_gettid());
/* If trace file pointer is equal to NULL then return with out dumping data
to the file */
if (NULL == pOutFile)
{
/* It might be the first call from the current thread, try to create
new trace for this thread. */
pOutFile = AOCL_FLIST_AddFile(pchDTL_AUTO_TRACE_FILE, &gpAutoTraceFileList, AOCL_gettid());
if (NULL == pOutFile)
{
AOCL_DEBUGPRINT("File does not exists to dump the trace data \n");
return;
}
}
fprintf(pOutFile, "\n%u:%lu:+:%p",
AOCL_gettid(),
AOCL_getTimestamp(),
(void *)(pvThisFunc - info.dli_fbase));
}
/*===================================================================
* Function Name : __cyg_profile_func_exit
* Description : This function is automatically invoked
* by compiler before returing from a
* function.
* Input Parameter(s) : pvThisFunc - Address of function to be existed.
* call_site.- Address of the caller
* Output Parameter(s) : None
* Return parameter(s) : None
*==================================================================*/
void __cyg_profile_func_exit(void *pvThisFunc, void *pvCaller)
{
Dl_info info;
dladdr(pvThisFunc, &info);
AOCL_FAL_FILE *pOutFile = NULL;
pOutFile = AOCL_FLIST_GetFile(gpAutoTraceFileList, AOCL_gettid());
/* If trace file pointer is equal to NULL then return with out dumping data
to the file */
if (NULL == pOutFile)
{
/* It might be the first call from the current thread, try to create
new trace for this thread. */
pOutFile = AOCL_FLIST_AddFile(pchDTL_AUTO_TRACE_FILE, &gpAutoTraceFileList, AOCL_gettid());
if (NULL == pOutFile)
{
AOCL_DEBUGPRINT("File does not exists to dump the trace data \n");
return;
}
}
fprintf(pOutFile, "\n%u:%lu:-:%p",
AOCL_gettid(),
AOCL_getTimestamp(),
(void *)(pvThisFunc - info.dli_fbase));
}
#endif /* AOCL_AUTO_TRACE_ENABLE */
/* ------------------ End of aocldtl.c ---------------------- */

156
aocl_dtl/aocldtl.h Normal file
View File

@@ -0,0 +1,156 @@
/*===================================================================
* File Name : aocldtl.h
*
* Description : This is main interface file for the end user
* It provides defination for all macros to be
* used by user to add debug/trace information.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#ifndef _AOCLDTL_H_
#define _AOCLDTL_H_
#include "aocldtlcf.h"
#include "aocltpdef.h"
#include "aoclflist.h"
#define TRACE_TYPE_FENTRY (1)
#define TRACE_TYPE_FEXIT (2)
#define TRACE_TYPE_LOG (3)
#define TRACE_TYPE_RAW (4)
/* Type definition for printf */
#define AOCL_DEBUGPRINT printf
/* Define the AOCL_DTL_INITIALIZE_ENABLE if any of the debug macro
* are defined */
#if (AOCL_DTL_TRACE_ENABLE || AOCL_DTL_DUMP_ENABLE || AOCL_DTL_LOG_ENABLE)
#define AOCL_DTL_INITIALIZE_ENABLE
#endif
#if AOCL_DTL_TRACE_ENABLE
/* Entry macro to trace the flow of control The parameter LogLevel specifies
the log level String will preferably contains the function name in which
this macro is invoked */
#define AOCL_DTL_TRACE_ENTRY(LogLevel) \
DTL_Trace(LogLevel, \
TRACE_TYPE_FENTRY, \
__FILE__, \
__FUNCTION__, \
__LINE__, \
NULL);
#else
/* Dummy macro definition if the AOCL_DTL_TRACE_ENABLE macro is not enabled */
#define AOCL_DTL_TRACE_ENTRY(LogLevel)
#endif
#if AOCL_DTL_TRACE_ENABLE
/* Exit macro to trace the flow of control The parameter LogLevel specifies
log level String will preferably contains the function name in which this
macro is invoked */
#define AOCL_DTL_TRACE_EXIT(LogLevel) \
DTL_Trace(LogLevel, \
TRACE_TYPE_FEXIT, \
__FILE__, \
__FUNCTION__, \
__LINE__, \
NULL);
#define AOCL_DTL_TRACE_EXIT_ERR(LogLevel, Message) \
DTL_Trace(LogLevel, \
TRACE_TYPE_FEXIT, \
__FILE__, \
__FUNCTION__, \
__LINE__, \
Message);
#else
/* Dummy macro definition if the AOCL_DTL_TRACE_ENABLE macro is not enabled */
#define AOCL_DTL_TRACE_EXIT(LogLevel)
#define AOCL_DTL_TRACE_EXIT_ERR(LogLevel, Message)
#endif
#if AOCL_DTL_DUMP_ENABLE
/* Macro to Dump the DATA The parameters Buffer contains the data to be
dumped BufferSize specifies the no. of bytes to be dumped DataType
specifies the data type of Buffer */
#define AOCL_DTL_DUMP(LogLevel, Buffer, BufferSize, DataType, String, OutputType) \
/* Call the Dump function to Dump the DATA */ \
DTL_DumpData(LogLevel, \
Buffer, \
BufferSize, \
DataType, \
String, \
OutputType);
#else
/* Dummy macro definition if the AOCL_DTL_DUMP_ENABLE macro is not enabled */
#define AOCL_DTL_DUMP(Buffer, BufferSize, DataType, String, OutputType)
#endif
#if AOCL_DTL_LOG_ENABLE
/* Macro to log the Data */
#define AOCL_DTL_LOG(LogLevel, Message) \
DTL_Trace(LogLevel, \
TRACE_TYPE_LOG, \
__FILE__, \
__FUNCTION__, \
__LINE__, \
Message);
#else
/* Dummy macro definition if the AOCL_DTL_LOG_ENABLE macro is not enabled */
#define AOCL_DTL_LOG(LogLevel, Message)
#endif
/* Macro to initialize the prerequisite for debuging */
#ifdef AOCL_DTL_INITIALIZE_ENABLE
#define AOCL_DTL_INITIALIZE(CURRENT_LOG_LEVEL) \
DTL_Initialize(CURRENT_LOG_LEVEL);
#else
/* Dummy macro definition if the AOCL_DTL_INITIALIZE macro is not enabled */
#define AOCL_DTL_INITIALIZE(CURRENT_LOG_LEVEL)
#endif
/* Macro for uninitializing the prerequisite */
#ifdef AOCL_DTL_INITIALIZE_ENABLE
#define AOCL_DTL_UNINITIALIZE() \
DTL_Uninitialize();
#else
/* Dummy macro definition if the AOCL_DTL_INITIALIZE macro is not enabled */
#define AOCL_DTL_UNINITIALIZE()
#endif
#ifdef AOCL_DTL_INITIALIZE_ENABLE
/* Prototypes for initializing and uninitializing the debug functions */
void DTL_Initialize(
uint32 ui32CurrentLogLevel);
void DTL_Uninitialize(void);
#endif
#if (AOCL_DTL_TRACE_ENABLE || AOCL_DTL_LOG_ENABLE)
/* Debug trace Function protoypes */
void DTL_Trace(
uint8 ui8LogLevel,
uint8 ui8LogType,
const int8 *pi8FileName,
const int8 *pi8FunctionName,
uint32 ui32LineNumber,
const int8 *pi8Message);
#endif
#if AOCL_DTL_DUMP_ENABLE
/* Function Prototype for dumping the data */
void DTL_DumpData(
uint8 ui8LogLevel,
void *pvBuffer,
uint32 ui32BufferSize,
uint8 ui8DataType,
int8 *pi8Message,
int8 i8OutputType);
#endif
#endif /* _AOCLDTL_H_ */
/* --------------- End of aocldtl.h ----------------- */

61
aocl_dtl/aocldtlcf.h Normal file
View File

@@ -0,0 +1,61 @@
/*===================================================================
* File Name : aocldtlcf.h
*
* Description : This is configuration file for debug and trace
* libaray, all debug features (except auto trace)
* can be enabled/disabled in this file.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#ifndef _AOCLDTLCF_H_
#define _AOCLDTLCF_H_
/* Macro for tracing the log If the user wants to enable tracing he has to
enable this macro by making it to 1 else 0 */
#define AOCL_DTL_TRACE_ENABLE 1
/* Macro for dumping the log If the user wants to enable dumping he has to
enable this macro by making it to 1 else 0 */
#define AOCL_DTL_DUMP_ENABLE 1
/* Macro for logging the logs If the user wants to enable loging information he
has to enable this macro by making it to 1 else 0 */
#define AOCL_DTL_LOG_ENABLE 1
#define AOCL_DTL_TRACE_FILE "aocldtl_trace.wri"
#define AOCL_DTL_AUTO_TRACE_FILE "aocldtl_auto_trace.wri"
#define AOCL_DTL_LOG_FILE "aocldtl_log.wri"
/* The use can use below three macros for different data type while dumping data
* or specify the size of data type in bytes macro for character data type */
#define AOCL_CHAR_DATA_TYPE (1)
/* macro for short data type */
#define AOCL_UINT16_DATA_TYPE (2)
/* macro for String data type */
#define AOCL_STRING_DATA_TYPE (3)
/* macro for uint32 data type */
#define AOCL_UINT32_DATA_TYPE (4)
/* macro for printing Hex values */
#define AOCL_LOG_HEX_VALUE ('x')
/* macro for printing Decimal values */
#define AOCL_LOG_DECIMAL_VALUE ('d')
/* user has to explicitly use the below macros to identify
ciriticality of the logged message */
#define AOCL_DTL_LEVEL_ALL (6)
#define AOCL_DTL_LEVEL_VERBOSE (5)
#define AOCL_DTL_LEVEL_INFO (4)
#define AOCL_DTL_LEVEL_MINOR (3)
#define AOCL_DTL_LEVEL_MAJOR (2)
#define AOCL_DTL_LEVEL_CRITICAL (1)
#endif /* _AOCLDTLCF_H_ */
/* --------------- End of aocldtlcf.h ----------------- */

265
aocl_dtl/aoclfal.c Normal file
View File

@@ -0,0 +1,265 @@
/*===================================================================
* File Name : aoclfal.c
*
* Description : Platform/os independed file handling API's
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#include "aocltpdef.h"
#include "aocldtl.h"
#include "aoclfal.h"
/* Disable instrumentation for following function, since they are called from
* Auto Generated execution trace handlers. */
/* The FAL function declaration */
int32 AOCL_FAL_Close(
AOCL_FAL_FILE *fpFilePointer) __attribute__((no_instrument_function));
int32 AOCL_FAL_Error(
AOCL_FAL_FILE *fpFilePointer) __attribute__((no_instrument_function));
AOCL_FAL_FILE *AOCL_FAL_Open(
const int8 *pchFileName,
const int8 *pchMode) __attribute__((no_instrument_function));
int32 AOCL_FAL_Read(
void *pvBuffer,
int32 i32Size,
int32 i32Count,
AOCL_FAL_FILE *fpFilePointer) __attribute__((no_instrument_function));
int32 AOCL_FAL_Write(
const void *pvBuffer,
int32 i32Size,
int32 iCount,
AOCL_FAL_FILE *fpFilePointer) __attribute__((no_instrument_function));
/*=============================================================================
* Function Name : AOCL_FAL_Open
* Description : Used for opening a file specified by name
* Input Parameter(s) : int8 *pchFileName - Stores the file name (path)
* int8 *pchMode - Specify the mode for opening file
* Output Parameter(s) : None
* Return parameter(s) : AOCL_FAL_FILE - If the file is opened successfully
* NULL - If there is any error while opening file
*============================================================================*/
AOCL_FAL_FILE *AOCL_FAL_Open(
const int8 *pchFileName,
const int8 *pchMode)
{
AOCL_FAL_FILE *fpFileOpen = NULL;
/* Open the file with provided by specified path and mode in which it should
be opened. Refer to FILE I/O operation help for getting mode types */
fpFileOpen = fopen(pchFileName, pchMode);
/* If the file is not opened then NULL value should be returned */
if (NULL == fpFileOpen)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Cannot open file: AOCL_FAL_Open()");
}
return fpFileOpen;
} /* end of AOCL_FAL_Open */
/*=============================================================================
* Function Name : AOCL_FAL_Close
* Description : Used for closing a file specified by file pointer
* Input Parameter(s) : AOCL_FAL_FILE *fpFilePointer - File pointer
* Output Parameter(s) : None
* Return parameter(s) : 0 - If the file is closed successfully
* AOCL_FAL_CLOSE_ERROR - For any error while closing file
*
*============================================================================*/
int32 AOCL_FAL_Close(
AOCL_FAL_FILE *fpFilePointer)
{
/* Return value for the file close */
int32 i32RetVal;
i32RetVal = AOCL_FAL_CLOSE_ERROR;
/* Check whether the file pointer passed is valid or not */
if (NULL == fpFilePointer)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Can not close file: AOCL_FAL_Close()");
return i32RetVal;
}
/* Close the file using the FILE pointer passed */
i32RetVal = fclose(fpFilePointer);
/* If the return value is non zero then it indicates an error */
if (i32RetVal)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR,
"Can't close file, Invalid file pointer passed");
return i32RetVal;
}
/* On successful closing of the file, function should return 0 */
return i32RetVal;
} /* End of AOCL_FAL_Close */
/*=============================================================================
* Function Name : AOCL_FAL_Read
* Description : Used for reading a file specified by file pointer.
* This function reads the specified number of bytes
* from the file into the buffer specified. The bytes
* read are returned by this function.
* Input Parameter(s) : int32 i32Size - Item size in bytes
* int32 i32Count - Maximum number of items to be read
* AOCL_FAL_FILE *fpFilePointer - File ptr to read from
* Output Parameter(s) : void *pvBuffer - Storage location of data
* Return parameter(s) : i32RetVal - Number of bytes read if successful
* AOCL_FAL_READ_ERROR - In case of error while reading
*============================================================================*/
int32 AOCL_FAL_Read(
void *pvBuffer,
int32 i32Size,
int32 i32Count,
AOCL_FAL_FILE *fpFilePointer)
{
/* Return value for the file read */
int32 i32RetVal;
i32RetVal = AOCL_FAL_READ_ERROR;
/* Check pointer used for pointing the storage location data is valid */
if (NULL == pvBuffer)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR,
"Can not read the file, Buffer pointer is NULL");
return i32RetVal;
}
/* Check whether file pointer passed is valid */
if (NULL == fpFilePointer)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR,
"Can not read the file, Buffer pointer is NULL");
return i32RetVal;
}
/* Read the file using file pointer */
i32RetVal = fread(pvBuffer, i32Size, i32Count, fpFilePointer);
if (i32RetVal != i32Count)
{
/* Check whether this is an end of file The AOCL_FAL_Error() will return
non-zero value to indicate an error */
if (AOCL_FAL_Error(fpFilePointer)) /* AOCL_FAL_EndOfFile (fpFilePointer) */
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR,
"There is an error condition while file read");
i32RetVal = AOCL_FAL_READ_ERROR;
}
/* This is condition where file read has encountered an end of file */
else
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "End of file...");
}
}
/* The number of bytes read by the file read operation.
* This value may be less than the actual count, due to end of file
* or an error while reading the file */
return i32RetVal;
} /* End of AOCL_FAL_Read */
/*=============================================================================
* Function Name : AOCL_FAL_Write
* Description : Used for writing data to a file specified by file
* pointer. The number of bytes written to file are
* written by this function.
* Input Parameter(s) : const void *pvBuffer - Pointer to data location from
* where the data to be copied
int32 i32Size - Item size in bytes
* int32 i32Count - Maximum number of items to be
* written
* AOCL_FAL_FILE *fpFilePointer - File pointer to write to
* Output Parameter(s) : None
* Return parameter(s) : i32RetVal - Number of bytes written if successful
* AOCL_FAL_WRITE_ERROR - In case of error while writing
*============================================================================*/
int32 AOCL_FAL_Write(
const void *pvBuffer,
int32 i32Size,
int32 iCount,
AOCL_FAL_FILE *fpFilePointer)
{
/* Return value for write operation */
int32 i32RetVal;
i32RetVal = AOCL_FAL_WRITE_ERROR;
/* Check pointer used for pointing the storage location data is valid */
if (NULL == pvBuffer)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Can not perform file write");
return i32RetVal;
}
/* Check whether the file pointer passed is valid or not */
if (NULL == fpFilePointer)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Can not perform file write");
return i32RetVal;
}
/* Write into the file specified by the file pointer */
i32RetVal = fwrite(pvBuffer, i32Size, iCount, fpFilePointer);
/* If the number of bytes written into the file are less than specified
* bytes then it is an error while file writing */
if (i32RetVal != iCount)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "File write operation error");
i32RetVal = AOCL_FAL_WRITE_ERROR;
}
/* The return value of the file write operation */
return i32RetVal;
} /* End of AOCL_FAL_Write */
/*=============================================================================
* Function Name : AOCL_FAL_Error
* Description : Used for testing an error on the file specified
* Input Parameter(s) : AOCL_FAL_FILE *fpFilePointer - File pointer
* Output Parameter(s) : None
* Return parameter(s) : non-zero - Indicates an end of file
* 0 - Indicates that function is successful
* non-zero - Indicates that there is some error
* AOCL_FAL_ERROR - Indicates error during the operation
*============================================================================*/
int32 AOCL_FAL_Error(
AOCL_FAL_FILE *fpFilePointer)
{
/* Used for storing the return value for ferror function */
int32 i32RetVal;
i32RetVal = AOCL_FAL_FERROR;
/* Check whether the file pointer is NULL */
if (NULL == fpFilePointer)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Invalid file pointer is passed");
return i32RetVal;
}
/* Call the ferror function to get an error on the file */
i32RetVal = ferror(fpFilePointer);
/* Check for the return value, it non-zero there is an error */
if (i32RetVal)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "The file has some error");
i32RetVal = AOCL_FAL_FERROR;
}
/* In case of success, this function should return 0 */
return i32RetVal;
} /* End of AOCL_FAL_Error */
/* ------------------- End of aoclfal.c ----------------------- */

50
aocl_dtl/aoclfal.h Normal file
View File

@@ -0,0 +1,50 @@
/*===================================================================
* File Name : aoclfal.h
*
* Description : Interfaces for platform/os independed file
* handling API's
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#ifndef _AOCL_FAL_H_
#define _AOCL_FAL_H_
/* The possible error values of FAL */
#define AOCL_FAL_SUCCESS 0
#define AOCL_FAL_CLOSE_ERROR -1
#define AOCL_FAL_READ_ERROR -2
#define AOCL_FAL_WRITE_ERROR -3
#define AOCL_FAL_EOF_ERROR -6
#define AOCL_FAL_FERROR -7
/* The type definition for FILE */
#define AOCL_FAL_FILE FILE
/* The FAL function declaration */
int32 AOCL_FAL_Close(
AOCL_FAL_FILE *fpFilePointer);
int32 AOCL_FAL_Error(
AOCL_FAL_FILE *fpFilePointer);
AOCL_FAL_FILE *AOCL_FAL_Open(
const int8 *pchFileName,
const int8 *pchMode);
int32 AOCL_FAL_Read(
void *pvBuffer,
int32 i32Size,
int32 i32Count,
AOCL_FAL_FILE *fpFilePointer);
int32 AOCL_FAL_Write(
const void *pvBuffer,
int32 i32Size,
int32 iCount,
AOCL_FAL_FILE *fpFilePointer);
#endif /* _AOCL_FAL_H_ */
/* --------------- End of aoclfal.h ----------------- */

150
aocl_dtl/aoclflist.c Normal file
View File

@@ -0,0 +1,150 @@
#include "aocltpdef.h"
#include "aocldtl.h"
#include "aoclfal.h"
#include "aoclflist.h"
#include "aoclos.h"
/* Disable instrumentation for following function, since they are called from
* Auto Generated execution trace handlers. */
Bool AOCL_FLIST_IsEmpty(
AOCL_FLIST_Node *plist) __attribute__((no_instrument_function));
AOCL_FAL_FILE *AOCL_FLIST_GetFile(
AOCL_FLIST_Node *plist,
AOCL_TID tid) __attribute__((no_instrument_function));
AOCL_FAL_FILE *AOCL_FLIST_AddFile(
const int8 *pchFilePrefix,
AOCL_FLIST_Node **plist,
AOCL_TID tid) __attribute__((no_instrument_function));
void AOCL_FLIST_CloseFile(
AOCL_FLIST_Node *plist,
AOCL_TID tid) __attribute__((no_instrument_function));
void AOCL_FLIST_CloseAll(
AOCL_FLIST_Node *plist) __attribute__((no_instrument_function));
Bool AOCL_FLIST_IsEmpty(AOCL_FLIST_Node *plist)
{
return (plist == NULL);
} /* AOCL_FLIST_IsEmpty */
AOCL_FAL_FILE *AOCL_FLIST_GetFile(AOCL_FLIST_Node *plist, AOCL_TID tid)
{
AOCL_FLIST_Node *temp;
if (AOCL_FLIST_IsEmpty(plist) == 1)
{
return NULL;
}
temp = plist;
/* if list is not empty search for the file handle in all nodes */
while (temp != NULL)
{
if (temp->tid == tid)
{
if (temp->fp == NULL)
{
AOCL_DEBUGPRINT("File associated with this thread id %d does not exists or closed", tid);
}
return temp->fp;
}
temp = temp->pNext;
}
return NULL;
} /* AOCL_FLIST_GetFile */
AOCL_FAL_FILE *AOCL_FLIST_AddFile(const int8 *pchFilePrefix, AOCL_FLIST_Node **plist, AOCL_TID tid)
{
AOCL_FLIST_Node *newNode = NULL, *temp = NULL;
AOCL_FAL_FILE *file = NULL;
int8 pchFileName[40];
/* We don't want duplicates so we will check if the file already opened for this thread */
file = AOCL_FLIST_GetFile(*plist, tid);
if (file != NULL)
{
AOCL_DEBUGPRINT("Open file alread exits for this key.");
return file;
}
/* We don't have exiting file, lets try to open new one */
sprintf(pchFileName, "%d_%s", tid, pchFilePrefix);
file = AOCL_FAL_Open(pchFileName, "wb");
if (file == NULL)
{
return NULL;
}
/* Now allocate new node as we are sure we will need it */
newNode = AOCL_malloc(sizeof(AOCL_FLIST_Node));
if (newNode == NULL)
{
AOCL_FAL_Close(file);
AOCL_DEBUGPRINT("Out of memory while opening new log file");
return NULL;
}
newNode->pNext = NULL;
newNode->tid = tid;
newNode->fp = file;
if (AOCL_FLIST_IsEmpty(*plist) == 1)
{
*plist = newNode;
}
else
{
/* go to the end of the list */
for (temp = *plist; temp->pNext != NULL; temp = temp->pNext)
;
temp->pNext = newNode;
}
AOCL_DEBUGPRINT("Created file for tid = %d", tid);
return newNode->fp;
} /* AOCL_FLIST_AddFile */
void AOCL_FLIST_CloseFile(AOCL_FLIST_Node *plist, AOCL_TID tid)
{
AOCL_FAL_FILE *pfile = AOCL_FLIST_GetFile(plist, tid);
AOCL_FAL_Close(pfile);
return;
} /* AOCL_FLIST_CloseFile */
void AOCL_FLIST_CloseAll(AOCL_FLIST_Node *plist)
{
AOCL_FLIST_Node *temp;
if (AOCL_FLIST_IsEmpty(plist) == 1)
{
return;
}
temp = plist;
/* if list is not iterate over all nodes and close the assocaited files*/
while (temp != NULL)
{
AOCL_FAL_Close(temp->fp);
temp = temp->pNext;
}
} /* AOCL_FLIST_CloseAll */
/* ------------------- End of aoclflist.c ----------------------- */

46
aocl_dtl/aoclflist.h Normal file
View File

@@ -0,0 +1,46 @@
/*===================================================================
* File Name : aoclflist.h
*
* Description : Linked list of open files assocaited with
* each thread. This is used to log the deta
* to correct file as per the current thread id.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#ifndef _AOCL_FLIST_H_
#define _AOCL_FLIST_H_
#include "aocltpdef.h"
#include "aoclfal.h"
typedef struct AOCL_FLIST_Node_t
{
AOCL_TID tid;
AOCL_FAL_FILE *fp;
struct AOCL_FLIST_Node_t *pNext;
} AOCL_FLIST_Node;
Bool AOCL_FLIST_IsEmpty(
AOCL_FLIST_Node *plist);
AOCL_FAL_FILE *AOCL_FLIST_GetFile(
AOCL_FLIST_Node *plist,
AOCL_TID tid);
AOCL_FAL_FILE *AOCL_FLIST_AddFile(
const int8 *pchFilePrefix,
AOCL_FLIST_Node **plist,
AOCL_TID tid);
void AOCL_FLIST_CloseFile(
AOCL_FLIST_Node *plist,
AOCL_TID tid);
void AOCL_FLIST_CloseAll(
AOCL_FLIST_Node *plist);
#endif /* _AOCL_FLIST_H_ */
/* --------------- End of aoclfist.h ----------------- */

73
aocl_dtl/aoclos.c Normal file
View File

@@ -0,0 +1,73 @@
/*===================================================================
* File Name : aoclos.c
*
* Description : Abstraction for os services used by DTL.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#include "aocltpdef.h"
#include "aocldtl.h"
#include "aoclfal.h"
#include "aocldtlcf.h"
#if defined(__linux__)
#include <time.h>
#include <sys/syscall.h>
#endif
#if defined(__linux__)
/*
Disable intrumentation for these functions as they will also be
called from compiler generated instumation code to trace
function execution.
It needs to be part of declration in the C file so can't be
moved to header file.
*/
uint32 AOCL_gettid(void) __attribute__((no_instrument_function));
uint64 AOCL_getTimestamp(void) __attribute__((no_instrument_function));
uint32 AOCL_gettid(void)
{
return syscall(__NR_gettid);
}
uint64 AOCL_getTimestamp(void)
{
struct timespec tms;
/* The C11 way */
if (clock_gettime(CLOCK_REALTIME, &tms))
{
return -1;
}
/* seconds, multiplied with 1 million */
uint64 micros = tms.tv_sec * 1000000;
/* Add full microseconds */
micros += tms.tv_nsec / 1000;
/* round up if necessary */
if (tms.tv_nsec % 1000 >= 500)
{
++micros;
}
return micros;
}
#else /* Non linux support */
uint32 AOCL_gettid(void)
{
/* stub for other os's */
return 0;
}
uint64 AOCL_getTimestamp(void)
{
/* stub for other os's */
return 0;
}
#endif

27
aocl_dtl/aoclos.h Normal file
View File

@@ -0,0 +1,27 @@
/*===================================================================
* File Name : aoclos.c
*
* Description : Abstraction for os services used by DTL.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#ifndef _AOCL_OS_H_
#define _AOCL_OS_H_
#include "aocltpdef.h"
#include "malloc.h"
/* The OS Services function declaration */
/* Alias for memory mangement functions. */
#define AOCL_malloc malloc
#define AOCL_free free
uint32 AOCL_gettid(void);
uint64 AOCL_getTimestamp(void);
#endif /* _AOCL_OS_H_ */
/* --------------- End of aoclOS.h ----------------- */

38
aocl_dtl/aocltpdef.h Normal file
View File

@@ -0,0 +1,38 @@
/*===================================================================
* File Name : aocltpdef.h
*
* Description : Abstraction for various datatypes used by DTL.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#ifndef AOCL_TYPEDEF_H_
#define AOCL_TYPEDEF_H_
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <math.h>
#include <sys/types.h>
typedef double Double;
typedef float Float;
typedef void Void;
typedef unsigned char uint8;
typedef unsigned short int uint16;
typedef unsigned int uint32;
typedef unsigned long uint64;
typedef uint8 *STRING;
typedef unsigned char Bool;
typedef char int8;
typedef signed long int int32;
typedef short int int16;
typedef Void *AOCL_HANDLE;
typedef pid_t AOCL_TID;
#endif /*AOCL_TYPEDEF_H_ */
/* --------------- End of aocltpdef.h ----------------- */

175
aocl_dtl/etrace_decoder.py Executable file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/python
"""
BLIS
An object-based framework for developing high-performance BLAS-like
libraries.
Copyright (C) 2014, The University of Texas at Austin
Copyright (C) 2018 - 2019, Advanced Micro Devices, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name(s) of the copyright holder(s) nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
import argparse
import subprocess
import re
import os
binary_filename = ""
trace_filename = ""
missing_symbols = 0
call_only = False
lookup = {}
def check_args():
global binary_filename, call_only, trace_filename
parser = argparse.ArgumentParser(description='Decoder for BLIS execution trace. '\
"Before running this utility ensure that BLIS library is built with execution trace enabled. "
"Run the application to create the trace data, after that only run this decoder")
parser.add_argument("--rawfile", required=True, type=str, help="Path to auto trace file generated by application")
parser.add_argument("--binary", required=True, type=str, help="Path to application binary")
parser.add_argument("--calls", action="store_true", help="Display only calls (no returns)")
args = parser.parse_args()
binary_filename = args.binary
trace_filename = args.rawfile
call_only = args.calls
def check_files():
binary_path = os.path.join(os.getcwd(), binary_filename)
trace_path = os.path.join(os.getcwd(), trace_filename)
if not os.path.isfile(binary_path):
print ("\nBinary %s not found" % binary_path)
exit()
if not os.path.isfile(trace_path):
print ("\nExecutation trace data (file blis.etrace) not found in current dirctory \
\nPlease check the directory and ensure that application is built and ran \
\nwith execution traces enabled.")
exit()
binary_mtime = os.path.getmtime(binary_path)
trace_mtime = os.path.getmtime(trace_path)
if binary_mtime > trace_mtime:
print ("\n************************************************************************")
print ("\n* WARNING: Binary is latest than trace file, trace data may not match. *")
print ("\n************************************************************************")
print ("Using binary file: %s" % binary_path)
print ("Using trace file: %s" % trace_path)
def create_symbol_table_lookup():
temp = subprocess.Popen(["objdump", "-t" , binary_filename], stdout = subprocess.PIPE)
output = str(temp.communicate())
output = output.split('\\n')
regex_lookup = re.compile(r'.text')
for line in range(len(output)):
count = regex_lookup.findall(output[line])
if len(count) > 0:
current_line = output[line].split()
key, value = int(current_line[0], 16), current_line[4]
lookup[key] = value
def decode_symbols_from_trace():
global missing_symbols
raw_contents = []
with open(trace_filename, "r") as f:
raw_contents = f.read()
raw_contents = raw_contents.split("\n")
level = []
first_timestamp = 0
last_timestamp = 0
for line in range(len(raw_contents)):
current_line = raw_contents[line].split(":")
if len(current_line) != 4:
continue
print_string = current_line[0] + " "
print_string += current_line[2]
if current_line[2] == "+":
last_level = "+"
level.append(1)
else:
last_level = "-"
if len(level) > 0:
level.pop()
if last_level == "-":
for i in range(len(level) + 1) :
print_string += "."
else:
for i in range(len(level)) :
print_string += "."
try:
print_string += lookup[int(current_line[3], 16)]
except KeyError:
missing_symbols += 1
print_string += current_line[3]
if line == 1:
first_timestamp = int(current_line[1])
print_string += "(+0us)"
else:
delta_last = int(current_line[1]) - last_timestamp
delta_total = int(current_line[1]) - first_timestamp
print_string += "(+" + str(delta_last) + "us, " + str(delta_total) + "us)"
if last_level == "-" and call_only:
continue
else:
last_timestamp = int(current_line[1])
print (print_string)
if __name__ == "__main__":
check_args()
check_files()
create_symbol_table_lookup()
decode_symbols_from_trace()
if missing_symbols > 0:
print("\nWARNING: Some symbols are not found, this can happen if binary is not matching \
\nor symbols are stripped from it.")

101
aocl_dtl/test_dtl.c Normal file
View File

@@ -0,0 +1,101 @@
/*===================================================================
* File Name : test_dtl.c
*
* Description : Unit test cases for dtl.
*
* Copyright (C) 2020, Advanced Micro Devices, Inc
*
*==================================================================*/
#if 0 // Disable this for normal build.
#include "aocltpdef.h"
#include "aocldtl.h"
int aocl_allocate(double**A, double** B, double** C, int N)
{
AOCL_DTL_TRACE_ENTRY(AOCL_DTL_LEVEL_INFO, " aocl_allocate()");
*A = (double*)malloc(sizeof(double) * N);
if (*A == NULL)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Error allocating memory to A");
AOCL_DTL_TRACE_EXIT(AOCL_DTL_LEVEL_INFO, " aocl_allocate()");
return 1;
}
*B = (double*)malloc(sizeof(double) * N);
if (*B == NULL)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Error allocating memory to B");
AOCL_DTL_TRACE_EXIT(AOCL_DTL_LEVEL_INFO, " aocl_allocate()");
return 1;
}
*C = (double*)malloc(sizeof(double) * N);
if (*C == NULL)
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Error allocating memory to C");
AOCL_DTL_TRACE_EXIT(AOCL_DTL_LEVEL_INFO, " aocl_allocate()");
return 1;
}
for (int i = 0; i < N; i++)
{
(*A)[i] = (double)((i + 1) * 1.0);
(*B)[i] = (double)((i - 1) * 1.0);
(*C)[i] = (double)((i) * 1.0);
}
AOCL_DTL_TRACE_EXIT(AOCL_DTL_LEVEL_INFO, " aocl_allocate()");
return 0;
}
void sumV(double* A, double* B, double* C, int N)
{
AOCL_DTL_TRACE_ENTRY(AOCL_DTL_LEVEL_INFO, "sumV()");
if ((A == NULL) || (B == NULL) || (C == NULL))
{
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Invalid Pointers");
AOCL_DTL_TRACE_EXIT(AOCL_DTL_LEVEL_INFO, " sumV()");
return;
}
for (int i = 0; i < N; i++)
{
C[i] += A[i] + B[i];
}
AOCL_DTL_TRACE_EXIT(AOCL_DTL_LEVEL_INFO, "sumV()");
}
int main(void)
{
int status = 0;
double* A = NULL;
double* B = NULL;
double* C = NULL;
printf("Initializing\n");
AOCL_DTL_INITIALIZE(AOCL_DTL_LEVEL_ALL);
AOCL_DTL_TRACE_ENTRY(AOCL_TRACE_LEVEL_1, "Main function()");
status = aocl_allocate(&A, &B, &C, 120);
if (status != 0)
{
printf("Error allocating memory\n");
AOCL_DTL_LOG(AOCL_DTL_LEVEL_MAJOR, "Error in function aocl_allocate()");
AOCL_DTL_TRACE_EXIT(AOCL_TRACE_LEVEL_1, "Main function()");
AOCL_DTL_UNINITIALIZE();
exit(1);
}
sumV(A, B, C, 120);
AOCL_DTL_TRACE_EXIT(AOCL_TRACE_LEVEL_1, "Main function()");
AOCL_DTL_UNINITIALIZE();
return 0;
}
#endif

View File

@@ -143,6 +143,13 @@ get-frame-cflags-for = $(strip $(call load-var-for,COPTFLAGS,$(1)) \
$(BUILD_SYMFLAGS) \
)
get-aocldtl-cflags-for = $(strip $(call load-var-for,COPTFLAGS,$(1)) \
$(call get-noopt-cflags-for,$(1)) \
$(BUILD_CPPFLAGS) \
$(BUILD_SYMFLAGS) \
)
get-kernel-cflags-for = $(strip $(call load-var-for,CKOPTFLAGS,$(1)) \
$(call load-var-for,CKVECFLAGS,$(1)) \
$(call get-noopt-cflags-for,$(1)) \
@@ -187,6 +194,7 @@ get-refinit-text-for = "('$(1)' CFLAGS for ref. kernel init)"
get-refkern-text-for = "('$(1)' CFLAGS for ref. kernels)"
get-config-text-for = "('$(1)' CFLAGS for config code)"
get-frame-text-for = "('$(1)' CFLAGS for framework code)"
get-aocldtl-text-for = "('$(1)' CFLAGS for AOCL debug and trace code)"
get-kernel-text-for = "('$(1)' CFLAGS for kernels)"
get-sandbox-c99text-for = "('$(1)' CFLAGS for sandboxes)"
get-sandbox-cxxtext-for = "('$(1)' CXXFLAGS for sandboxes)"
@@ -285,6 +293,7 @@ FRAGMENT_MK := .fragment.mk
BUILD_DIR := build
CONFIG_DIR := config
FRAME_DIR := frame
AOCLDTL_DIR := aocl_dtl
REFKERN_DIR := ref_kernels
KERNELS_DIR := kernels
SANDBOX_DIR := sandbox
@@ -306,6 +315,8 @@ KERNELS_SRC_SUFS := c s S
FRAME_SRC_SUFS := c
AOCLDTL_SRC_SUFS := c
SANDBOX_C99_SUFS := c
SANDBOX_CXX_SUFS := cc cpp cxx
SANDBOX_SRC_SUFS := $(SANDBOX_C99_SUFS) $(SANDBOX_CXX_SUFS)
@@ -313,16 +324,20 @@ SANDBOX_SRC_SUFS := $(SANDBOX_C99_SUFS) $(SANDBOX_CXX_SUFS)
# Header suffixes.
FRAME_HDR_SUFS := h
AOCLDTL_HDR_SUFS := h
SANDBOX_H99_SUFS := h
SANDBOX_HXX_SUFS := hh hpp hxx
SANDBOX_HDR_SUFS := $(SANDBOX_H99_SUFS) $(SANDBOX_HXX_SUFS)
# Combine all header suffixes and remove duplicates via sort().
ALL_HDR_SUFS := $(sort $(FRAME_HDR_SUFS) \
$(SANDBOX_HDR_SUFS) )
ALL_HDR_SUFS := $(sort $(FRAME_HDR_SUFS) \
$(SANDBOX_HDR_SUFS) \
$(AOCLDTL_HDR_SUFS))
ALL_H99_SUFS := $(sort $(FRAME_HDR_SUFS) \
$(SANDBOX_H99_SUFS) )
ALL_H99_SUFS := $(sort $(FRAME_HDR_SUFS) \
$(SANDBOX_H99_SUFS) \
$(AOCLDTL_HDR_SUFS))
# The names of scripts that check output from the BLAS test drivers and
# BLIS test suite.
@@ -351,6 +366,7 @@ SHELL := bash
# and optimized kernel code.
CONFIG_PATH := $(DIST_PATH)/$(CONFIG_DIR)
FRAME_PATH := $(DIST_PATH)/$(FRAME_DIR)
AOCLDTL_PATH := $(DIST_PATH)/$(AOCLDTL_DIR)
REFKERN_PATH := $(DIST_PATH)/$(REFKERN_DIR)
KERNELS_PATH := $(DIST_PATH)/$(KERNELS_DIR)
SANDBOX_PATH := $(DIST_PATH)/$(SANDBOX_DIR)
@@ -360,6 +376,7 @@ SANDBOX_PATH := $(DIST_PATH)/$(SANDBOX_DIR)
# kernel code, and optimized kernel code.
CONFIG_FRAG_PATH := ./obj/$(CONFIG_NAME)/$(CONFIG_DIR)
FRAME_FRAG_PATH := ./obj/$(CONFIG_NAME)/$(FRAME_DIR)
AOCLDTL_FRAG_PATH := ./obj/$(CONFIG_NAME)/$(AOCLDTL_DIR)
REFKERN_FRAG_PATH := ./obj/$(CONFIG_NAME)/$(REFKERN_DIR)
KERNELS_FRAG_PATH := ./obj/$(CONFIG_NAME)/$(KERNELS_DIR)
SANDBOX_FRAG_PATH := ./obj/$(CONFIG_NAME)/$(SANDBOX_DIR)
@@ -800,8 +817,6 @@ ENABLE_VERBOSE := no
BLIS_ENABLE_TEST_OUTPUT := no
endif
#
# --- Append OS-specific libraries to LDFLAGS ----------------------------------
#
@@ -838,6 +853,7 @@ MK_CONFIG_SRC :=
MK_KERNELS_SRC :=
MK_REFKERN_SRC :=
MK_FRAME_SRC :=
MK_AOCLDTL_SRC :=
MK_SANDBOX_SRC :=
# -- config --
@@ -887,6 +903,7 @@ PARENT_PATH := $(OBJ_DIR)/$(CONFIG_NAME)
# reference kernels and portable framework.
-include $(addsuffix /$(FRAGMENT_MK), $(REFKERN_FRAG_PATH))
-include $(addsuffix /$(FRAGMENT_MK), $(FRAME_FRAG_PATH))
-include $(addsuffix /$(FRAGMENT_MK), $(AOCLDTL_FRAG_PATH))
# -- sandbox --

View File

@@ -52,6 +52,16 @@ else
COPTFLAGS := -O3
endif
#
# --- Enable ETRACE across the library if enabled ETRACE_ENABLE=[0,1] -----------------------
#
ifeq ($(ETRACE_ENABLE),1)
CDBGFLAGS += -pg -finstrument-functions -DAOCL_DTL_AUTO_TRACE_ENABLE
LDFLAGS += -ldl
endif
# Flags specific to optimized kernels.
CKOPTFLAGS := $(COPTFLAGS)
ifeq ($(CC_VENDOR),gcc)

View File

@@ -61,8 +61,23 @@ endif
ifeq ($(DEBUG_TYPE),noopt)
COPTFLAGS := -O0
else
#frame pointers are needed to execution tracing
ifeq ($(ETRACE_ENABLE),1)
COPTFLAGS := -O3
else
COPTFLAGS := -O3 -fomit-frame-pointer
endif
endif
#
# --- Enable ETRACE across the library if enabled ETRACE_ENABLE=[0,1] -----------------------
#
ifeq ($(ETRACE_ENABLE),1)
CDBGFLAGS += -pg -finstrument-functions -DAOCL_DTL_AUTO_TRACE_ENABLE
LDFLAGS += -ldl
endif
# Flags specific to optimized kernels.
CKOPTFLAGS := $(COPTFLAGS)

27
configure vendored
View File

@@ -1844,6 +1844,10 @@ main()
frame_dir='frame'
frame_dirpath="${dist_path}/${frame_dir}"
# The root directory of the BLIS framework.
aocldtl_dir='aocl_dtl'
aocldtl_dirpath="${dist_path}/${aocldtl_dir}"
# The name of the sandbox directory.
sandbox_dir='sandbox'
sandbox_dirpath="${dist_path}/${sandbox_dir}"
@@ -3199,12 +3203,17 @@ main()
done
obj_aocldtl_dirpath="${base_obj_dirpath}/${aocldtl_dir}"
echo "${script_name}: creating ${obj_aocldtl_dirpath}"
mkdir -p ${obj_aocldtl_dirpath}
obj_frame_dirpath="${base_obj_dirpath}/${frame_dir}"
echo "${script_name}: creating ${obj_frame_dirpath}"
mkdir -p ${obj_frame_dirpath}
if [ -n "${sandbox_flag}" ]; then
obj_sandbox_dirpath="${base_obj_dirpath}/${sandbox_dir}"
@@ -3286,6 +3295,10 @@ main()
echo "${script_name}: mirroring ${frame_dirpath} to ${obj_frame_dirpath}"
${mirror_tree_sh} ${frame_dirpath} ${obj_frame_dirpath}
# Mirror framework source tree to its object sub-directory.
echo "${script_name}: mirroring ${aocldtl_dirpath} to ${obj_aocldtl_dirpath}"
${mirror_tree_sh} ${aocldtl_dirpath} ${obj_aocldtl_dirpath}
# Mirror the chosen sandbox source tree to its object sub-directory.
if [ -n "${sandbox_flag}" ]; then
@@ -3360,6 +3373,18 @@ main()
${gen_make_frags_dirpath}/suffix_list \
${gen_make_frags_dirpath}/ignore_list
# Generate makefile fragments in the DTL directory.
echo "${script_name}: creating makefile fragments in ${obj_aocldtl_dirpath}"
${gen_make_frags_sh} \
-h -r -v0 \
-o ${script_name} \
-p 'AOCLDTL' \
${aocldtl_dirpath} \
${obj_aocldtl_dirpath} \
${gen_make_frags_dirpath}/fragment.mk \
${gen_make_frags_dirpath}/suffix_list \
${gen_make_frags_dirpath}/ignore_list
# Generate makefile fragments in the framework directory.
echo "${script_name}: creating makefile fragments in ${obj_frame_dirpath}"
${gen_make_frags_sh} \

View File

@@ -74,6 +74,7 @@ void bli_finalize_auto( void )
void bli_init_apis( void )
{
AOCL_DTL_INITIALIZE(AOCL_DTL_LEVEL_ALL);
// Initialize various sub-APIs.
bli_gks_init();
bli_ind_init();
@@ -90,6 +91,7 @@ void bli_finalize_apis( void )
bli_thread_finalize();
bli_ind_finalize();
bli_gks_finalize();
AOCL_DTL_UNINITIALIZE();
}
// -----------------------------------------------------------------------------

View File

@@ -203,7 +203,8 @@ extern "C" {
#include "bli_winsys.h"
#include "aocldtl.h"
// End extern "C" construct block.
#ifdef __cplusplus
}