-
Notifications
You must be signed in to change notification settings - Fork 477
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a new metadata section in xclbin to support AIE profiling/debug (#…
…8304) * add a new metadata section in xclbin to support AIE profiling/debug Signed-off-by: xvijaysri <[email protected]> * added unit test for AIE TRACE METADATA Signed-off-by: xvijaysri <[email protected]> * fixed formatting issue Signed-off-by: xvijaysri <[email protected]> * addressed the review comments Signed-off-by: xvijaysri <[email protected]> --------- Signed-off-by: xvijaysri <[email protected]>
- Loading branch information
Showing
7 changed files
with
748 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/runtime_src/tools/xclbinutil/SectionAIETraceMetadata.cxx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). You may | ||
* not use this file except in compliance with the License. A copy of the | ||
* License is located at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
#include "SectionAIETraceMetadata.h" | ||
|
||
#include "XclBinUtilities.h" | ||
#include <boost/functional/factory.hpp> | ||
#include <boost/property_tree/json_parser.hpp> | ||
|
||
namespace XUtil = XclBinUtilities; | ||
|
||
// Static Variables / Classes | ||
// ---------------------------------------------------------------------------- | ||
SectionAIETraceMetadata::init SectionAIETraceMetadata::initializer; | ||
|
||
SectionAIETraceMetadata::init::init() | ||
{ | ||
auto sectionInfo = std::make_unique<SectionInfo>(AIE_TRACE_METADATA, "AIE_TRACE_METADATA", boost::factory<SectionAIETraceMetadata*>()); | ||
|
||
sectionInfo->supportedAddFormats.push_back(FormatType::json); | ||
sectionInfo->supportedAddFormats.push_back(FormatType::raw); | ||
|
||
sectionInfo->supportedDumpFormats.push_back(FormatType::json); | ||
sectionInfo->supportedDumpFormats.push_back(FormatType::raw); | ||
|
||
addSectionType(std::move(sectionInfo)); | ||
} | ||
|
||
// ---------------------------------------------------------------------------- | ||
|
||
void | ||
SectionAIETraceMetadata::marshalToJSON(char* _pDataSection, | ||
unsigned int _sectionSize, | ||
boost::property_tree::ptree& _ptree) const | ||
{ | ||
XUtil::TRACE(""); | ||
XUtil::TRACE("Extracting: AIE_TRACE_METADATA"); | ||
|
||
std::vector<unsigned char> memBuffer(_sectionSize + 1); // Extra byte for "null terminate" char | ||
memcpy((char*)memBuffer.data(), _pDataSection, _sectionSize); | ||
memBuffer[_sectionSize] = '\0'; | ||
|
||
std::stringstream ss((char*)memBuffer.data()); | ||
|
||
// TODO: Catch the exception (if any) from this call and produce a nice message | ||
XUtil::TRACE_BUF("AIE_TRACE_METADATA", (const char*)memBuffer.data(), _sectionSize + 1); | ||
try { | ||
boost::property_tree::ptree pt; | ||
boost::property_tree::read_json(ss, pt); | ||
boost::property_tree::ptree& buildMetaData = pt.get_child("aie_metadata"); | ||
_ptree.add_child("aie_trace_metadata", buildMetaData); | ||
} catch (const std::exception& e) { | ||
std::string msg("ERROR: Bad JSON format detected while marshaling AIE trace metadata ("); | ||
msg += e.what(); | ||
msg += ")."; | ||
throw std::runtime_error(msg); | ||
} | ||
} | ||
|
||
void | ||
SectionAIETraceMetadata::marshalFromJSON(const boost::property_tree::ptree& _ptSection, | ||
std::ostringstream& _buf) const | ||
{ | ||
XUtil::TRACE("AIE_TRACE_METADATA"); | ||
boost::property_tree::ptree ptWritable = _ptSection; | ||
boost::property_tree::write_json(_buf, ptWritable, false); | ||
} | ||
|
||
|
37 changes: 37 additions & 0 deletions
37
src/runtime_src/tools/xclbinutil/SectionAIETraceMetadata.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). You may | ||
* not use this file except in compliance with the License. A copy of the | ||
* License is located at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
#ifndef __SectionAIETraceMetadata_h_ | ||
#define __SectionAIETraceMetadata_h_ | ||
|
||
// ----------------------- I N C L U D E S ----------------------------------- | ||
#include "Section.h" | ||
|
||
// ------ C L A S S : S e c t i o n A I E T r a c e M e t a d a t a ------------------ | ||
class SectionAIETraceMetadata : public Section { | ||
protected: | ||
void marshalToJSON(char* _pDataSection, unsigned int _sectionSize, boost::property_tree::ptree& _ptree) const override; | ||
void marshalFromJSON(const boost::property_tree::ptree& _ptSection, std::ostringstream& _buf) const override; | ||
|
||
private: | ||
// Static initializer helper class | ||
static class init { | ||
public: | ||
init(); | ||
} initializer; | ||
}; | ||
|
||
#endif |
124 changes: 124 additions & 0 deletions
124
src/runtime_src/tools/xclbinutil/unittests/AieTraceMetadata/SectionAieTraceMetadata.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
from argparse import RawDescriptionHelpFormatter | ||
import argparse | ||
import os | ||
import subprocess | ||
import json | ||
|
||
# Start of our unit test | ||
# -- main() ------------------------------------------------------------------- | ||
# | ||
# The entry point to this script. | ||
# | ||
# Note: It is called at the end of this script so that the other functions | ||
# and classes have been defined and the syntax validated | ||
def main(): | ||
# -- Configure the argument parser | ||
parser = argparse.ArgumentParser(formatter_class=RawDescriptionHelpFormatter, description='description:\n Unit test wrapper for the AIE TRACE METADATA section') | ||
parser.add_argument('--resource-dir', nargs='?', default=".", help='directory containing data to be used by this unit test') | ||
args = parser.parse_args() | ||
|
||
# Validate that the resource directory is valid | ||
if not os.path.exists(args.resource_dir): | ||
raise Exception("Error: The resource-dir '" + args.resource_dir +"' does not exist") | ||
|
||
if not os.path.isdir(args.resource_dir): | ||
raise Exception("Error: The resource-dir '" + args.resource_dir +"' is not a directory") | ||
|
||
# Prepare for testing | ||
xclbinutil = "xclbinutil" | ||
|
||
# Start the tests | ||
print ("Starting test") | ||
|
||
# --------------------------------------------------------------------------- | ||
|
||
step = "1) Read in the AIE TRACE METADATA section" | ||
|
||
inputJSON = os.path.join(args.resource_dir, "aie_trace_config.json") | ||
outputXCLBIN = "output.xclbin" | ||
|
||
cmd = [xclbinutil, "--add-section", "AIE_TRACE_METADATA:JSON:" + inputJSON, "--output", outputXCLBIN, "--force"] | ||
execCmd(step, cmd) | ||
|
||
# --------------------------------------------------------------------------- | ||
|
||
step = "2) Validate the AIE_TRACE_METADATA section" | ||
|
||
expectedJSON = os.path.join(args.resource_dir, "expected_aie_trace_config.json") | ||
actualJSON = "actual_aie_trace_config.json" | ||
|
||
cmd = [xclbinutil, "--input", outputXCLBIN, "--dump-section", "AIE_TRACE_METADATA:JSON:" + actualJSON, "--force"] | ||
execCmd(step, cmd) | ||
jsonFileCompare(actualJSON, expectedJSON) | ||
|
||
|
||
# --------------------------------------------------------------------------- | ||
|
||
# If the code gets this far, all is good. | ||
return False | ||
|
||
def jsonFileCompare(file1, file2): | ||
|
||
if not os.path.isfile(file1): | ||
raise Exception("Error: The following json file does not exist: '" + file1 +"'") | ||
|
||
with open(file1) as f: | ||
data1 = json.dumps(json.load(f), indent=2) | ||
|
||
if not os.path.isfile(file2): | ||
raise Exception("Error: The following json file does not exist: '" + file2 +"'") | ||
|
||
with open(file2) as f: | ||
data2 = json.dumps(json.load(f), indent=2) | ||
|
||
if data1 != data2: | ||
# Print out the contents of file 1 | ||
print ("\nFile1 : "+ file1) | ||
print ("vvvvv") | ||
print (data1) | ||
print ("^^^^^") | ||
|
||
# Print out the contents of file 1 | ||
print ("\nFile2 : "+ file2) | ||
print ("vvvvv") | ||
print (data2) | ||
print ("^^^^^") | ||
|
||
raise Exception("Error: The given files are not the same") | ||
|
||
def testDivider(): | ||
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") | ||
|
||
|
||
def execCmd(pretty_name, cmd): | ||
testDivider() | ||
print(pretty_name) | ||
testDivider() | ||
cmdLine = ' '.join(cmd) | ||
print(cmdLine) | ||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
o, e = proc.communicate() | ||
print(o.decode('ascii')) | ||
print(e.decode('ascii')) | ||
errorCode = proc.returncode | ||
|
||
if errorCode != 0: | ||
raise Exception("Operation failed with the return code: " + str(errorCode)) | ||
|
||
# -- Start executing the script functions | ||
if __name__ == '__main__': | ||
try: | ||
if main() == True: | ||
print ("\nError(s) occurred.") | ||
print("Test Status: FAILED") | ||
exit(1) | ||
except Exception as error: | ||
print(repr(error)) | ||
print("Test Status: FAILED") | ||
exit(1) | ||
|
||
|
||
# If the code get this far then no errors occured | ||
print("Test Status: PASSED") | ||
exit(0) | ||
|
Oops, something went wrong.