mirror of
https://github.com/amd/blis.git
synced 2026-05-12 01:59:59 +00:00
Merge "Execution and Debug trace support." into amd-staging-rome-2.2
This commit is contained in:
committed by
Gerrit Code Review
commit
489d501f2e
30
Makefile
30
Makefile
@@ -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
478
aocl_dtl/aocldtl.c
Normal 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
156
aocl_dtl/aocldtl.h
Normal 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
61
aocl_dtl/aocldtlcf.h
Normal 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
265
aocl_dtl/aoclfal.c
Normal 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
50
aocl_dtl/aoclfal.h
Normal 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
150
aocl_dtl/aoclflist.c
Normal 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
46
aocl_dtl/aoclflist.h
Normal 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
73
aocl_dtl/aoclos.c
Normal 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
27
aocl_dtl/aoclos.h
Normal 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
38
aocl_dtl/aocltpdef.h
Normal 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
175
aocl_dtl/etrace_decoder.py
Executable 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
101
aocl_dtl/test_dtl.c
Normal 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
|
||||
29
common.mk
29
common.mk
@@ -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 --
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
27
configure
vendored
@@ -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} \
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -203,7 +203,8 @@ extern "C" {
|
||||
|
||||
#include "bli_winsys.h"
|
||||
|
||||
|
||||
#include "aocldtl.h"
|
||||
|
||||
// End extern "C" construct block.
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user