SWDEV-270198 - hip-hcc cleanup remove lpl_ca

Change-Id: I6cae9435397e9070efb4a953c7ba8bd3dcd98c0e


[ROCm/clr commit: 6e7ff3aaae]
Tá an tiomantas seo le fáil i:
agodavar
2021-01-27 02:32:11 -05:00
tiomanta ag Anusha Godavarthy Surya
tuismitheoir 53a0b62f82
tiomantas 3cd436f7a4
D'athraigh 11 comhad le 1 breiseanna agus 3743 scriosta
+1 -6
Féach ar an gComhad
@@ -284,10 +284,6 @@ if(HIP_RUNTIME STREQUAL "rocclr")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${HIP_ROCclr_BUILD_FLAGS}")
endif()
if(HIP_PLATFORM STREQUAL "amd")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lpl_ca)
endif()
# Generate .hipInfo
file(WRITE "${PROJECT_BINARY_DIR}/.hipInfo" ${_buildInfo})
@@ -379,8 +375,7 @@ add_custom_target(pkg_hip_base COMMAND ${CMAKE_COMMAND} .
COMMAND cp *.deb ${PROJECT_BINARY_DIR}
COMMAND cp *.rpm ${PROJECT_BINARY_DIR}
COMMAND cp *.tar.gz ${PROJECT_BINARY_DIR}
WORKING_DIRECTORY ${BUILD_DIR}
DEPENDS lpl ca)
WORKING_DIRECTORY ${BUILD_DIR} )
# Packaging needs to wait for hipify-clang to build if it's enabled...
if (BUILD_HIPIFY_CLANG)
-48
Féach ar an gComhad
@@ -1,48 +0,0 @@
#-------------------------------------LPL--------------------------------------#
# Look for ROCclr which contains elfio
find_package(ROCclr REQUIRED CONFIG
PATHS
/opt/rocm
/opt/rocm/rocclr)
add_executable(lpl lpl.cpp)
set_target_properties(
lpl PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
target_include_directories(lpl
PRIVATE
$<TARGET_PROPERTY:amdrocclr_static,INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_options(lpl PUBLIC -Wall)
target_link_libraries(lpl PUBLIC pthread)
set_target_properties(lpl PROPERTIES LINK_FLAGS_RELEASE -s)
add_custom_command(TARGET lpl POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/lpl ${PROJECT_BINARY_DIR}/bin/lpl)
install(TARGETS lpl RUNTIME DESTINATION bin)
#-------------------------------------LPL--------------------------------------#
#-------------------------------------CA---------------------------------------#
add_executable(ca ca.cpp)
set_target_properties(
ca PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
target_include_directories(ca SYSTEM PUBLIC ${HSA_PATH}/include)
find_package(hsa-runtime64 REQUIRED CONFIG
PATHS
/opt/rocm/
PATH_SUFFIXES
cmake/hsa-runtime64)
target_link_libraries(ca PUBLIC hsa-runtime64::hsa-runtime64 )
target_compile_options(ca PUBLIC -DDISABLE_REDUCED_GPU_BLOB_COPY -Wall)
set_target_properties(ca PROPERTIES LINK_FLAGS_RELEASE -s)
add_custom_command(TARGET ca POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/ca ${PROJECT_BINARY_DIR}/bin/ca)
install(TARGETS ca RUNTIME DESTINATION bin)
#-------------------------------------CA---------------------------------------#
-48
Féach ar an gComhad
@@ -1,48 +0,0 @@
#include "ca.hpp"
#include <cstdlib>
#include <exception>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
using namespace clara;
using namespace hip_impl;
using namespace std;
int main(int argc, char** argv) {
try {
bool help = false;
vector<string> inputs;
string targets;
auto cmd = cmdline_parser(help, inputs, targets);
const auto r = cmd.parse(Args{argc, argv});
if (!r) throw runtime_error{r.errorMessage()};
if (help)
cout << cmd << endl;
else {
if (inputs.empty()) throw runtime_error{"No inputs specified."};
validate_inputs(inputs);
auto tmp = tokenize_targets(targets);
if (tmp.empty()) {
tmp.assign(amdgpu_targets().cbegin(), amdgpu_targets().cend());
} else
validate_targets(tmp);
extract_code_objects(inputs, tmp);
}
} catch (const exception& ex) {
cerr << ex.what() << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-78
Féach ar an gComhad
@@ -1,78 +0,0 @@
#pragma once
#include "common.hpp"
#include "code_object_bundle.inl"
#include "clara/clara.hpp"
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <stdexcept>
#include <string>
#include <vector>
namespace hip_impl {
inline clara::Parser cmdline_parser(bool& help, std::vector<std::string>& inputs,
std::string& targets) {
return clara::Help{help} |
clara::Arg{inputs, "a" + fat_binary_extension() + " etc."}(
"fat binaries which contain the code objects to be extracted; "
"the binary format of the file(s) is documented at: "
"https://reviews.llvm.org/D13909; "
"the code object format is documented at: "
"https://www.llvm.org/docs/AMDGPUUsage.html#code-object.") |
clara::Opt{targets, "gfx803,gfx900,gfx906,gfx908 etc."}["-t"]["--targets"](
"targets for which code objects are to be extracted from "
"the fat binary; must be included in the set of processors "
"with ROCm support from "
"https://www.llvm.org/docs/AMDGPUUsage.html#processors.");
}
inline std::string make_code_object_file_name(const std::string& input, const std::string& target) {
assert(!input.empty() && !target.empty());
auto r = input.substr(0, input.find(fat_binary_extension()));
r += '_' + target + code_object_extension();
return r;
}
inline void extract_code_objects(const std::vector<std::string>& inputs,
const std::vector<std::string>& targets) {
for (auto&& input : inputs) {
std::ifstream tmp{input};
std::vector<char> bundle{std::istreambuf_iterator<char>{tmp},
std::istreambuf_iterator<char>{}};
Bundled_code_header tmp1{bundle};
if (!valid(tmp1)) {
throw std::runtime_error{input + " is not a valid fat binary."};
}
for (auto&& target : targets) {
const auto it = std::find_if(
bundles(tmp1).cbegin(), bundles(tmp1).cend(),
[&](const Bundled_code& x) { return x.triple.find(target) != std::string::npos; });
if (it == bundles(tmp1).cend()) {
std::cerr << "Warning: " << input << " does not contain code for the " << target
<< " target.";
continue;
}
std::ofstream out{make_code_object_file_name(input, target)};
std::copy_n(it->blob.cbegin(), it->blob.size(), std::ostreambuf_iterator<char>{out});
}
}
}
inline void validate_inputs(const std::vector<std::string>& inputs) {
const auto it = std::find_if_not(inputs.cbegin(), inputs.cend(), file_exists);
if (it != inputs.cend()) {
throw std::runtime_error{"Non existent file " + *it + " passed as input."};
}
}
} // namespace hip_impl
Tá difríocht comhad cosc orthu toisc go bhfuil sé ró-mhór Difríocht Luchtaigh
-203
Féach ar an gComhad
@@ -1,203 +0,0 @@
/*
Copyright (c) 2015 - present Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#pragma once
#include <hsa/hsa.h>
#include <algorithm>
#include <cstdint>
#include <istream>
#include <iterator>
#include <string>
#include <utility>
#include <vector>
#include <unordered_set>
namespace hip_impl {
#if !defined(DISABLE_REDUCED_GPU_BLOB_COPY)
std::unordered_set<std::string>& get_all_gpuarch();
#endif
inline
std::string transmogrify_triple(const std::string& triple)
{
static constexpr const char old_prefix[]{"hcc-amdgcn--amdhsa-gfx"};
static constexpr const char new_prefix[]{"hcc-amdgcn-amd-amdhsa--gfx"};
if (triple.find(old_prefix) == 0) {
return new_prefix + triple.substr(sizeof(old_prefix) - 1);
}
return (triple.find(new_prefix) == 0) ? triple : "";
}
inline
std::string isa_name(std::string triple)
{
static constexpr const char offload_prefix[]{"hcc-"};
triple = transmogrify_triple(triple);
if (triple.empty()) return {};
triple.erase(0, sizeof(offload_prefix) - 1);
return triple;
}
inline
hsa_isa_t triple_to_hsa_isa(const std::string& triple) {
const std::string isa{isa_name(std::move(triple))};
if (isa.empty()) return hsa_isa_t({});
hsa_isa_t r{};
if(HSA_STATUS_SUCCESS != hsa_isa_from_name(isa.c_str(), &r)) {
r.handle = 0;
}
return r;
}
struct Bundled_code {
union Header {
struct {
std::uint64_t offset;
std::uint64_t bundle_sz;
std::uint64_t triple_sz;
};
char cbuf[sizeof(offset) + sizeof(bundle_sz) + sizeof(triple_sz)];
} header;
std::string triple;
std::string blob;
};
#define magic_string_ "__CLANG_OFFLOAD_BUNDLE__"
class Bundled_code_header {
// DATA - STATICS
static constexpr auto magic_string_sz_ = sizeof(magic_string_) - 1;
// DATA
union Header_ {
struct {
char bundler_magic_string_[magic_string_sz_];
std::uint64_t bundle_cnt_;
};
char cbuf_[sizeof(bundler_magic_string_) + sizeof(bundle_cnt_)];
} header_;
std::vector<Bundled_code> bundles_;
// FRIENDS - MANIPULATORS
template <typename RandomAccessIterator>
friend inline bool read(RandomAccessIterator f, RandomAccessIterator l,
Bundled_code_header& x) {
if (f == l) return false;
std::copy_n(f, sizeof(x.header_.cbuf_), x.header_.cbuf_);
if (valid(x)) {
x.bundles_.resize(x.header_.bundle_cnt_);
auto it = f + sizeof(x.header_.cbuf_);
for (auto&& y : x.bundles_) {
std::copy_n(it, sizeof(y.header.cbuf), y.header.cbuf);
it += sizeof(y.header.cbuf);
y.triple.assign(it, it + y.header.triple_sz);
#ifdef DISABLE_REDUCED_GPU_BLOB_COPY
std::copy_n(f + y.header.offset, y.header.bundle_sz, std::back_inserter(y.blob));
#else
auto& gpuArch = get_all_gpuarch();
auto itgpuArch = std::find(gpuArch.begin(),gpuArch.end(),y.triple);
if (itgpuArch != gpuArch.end()){
std::copy_n(f + y.header.offset, y.header.bundle_sz, std::back_inserter(y.blob));
}
#endif
it += y.header.triple_sz;
x.bundled_code_size = std::max(x.bundled_code_size,
y.header.offset + y.header.bundle_sz);
}
return true;
}
return false;
}
friend inline bool read(const std::vector<char>& blob, Bundled_code_header& x) {
return read(blob.cbegin(), blob.cend(), x);
}
friend inline bool read(std::istream& is, Bundled_code_header& x) {
return read(
std::vector<char>{std::istreambuf_iterator<char>{is}, std::istreambuf_iterator<char>{}},
x);
}
// FRIENDS - ACCESSORS
friend inline bool valid(const Bundled_code_header& x) {
const std::string ms = {magic_string_};
return std::equal(ms.begin(), ms.end(), x.header_.bundler_magic_string_);
}
friend inline const std::vector<Bundled_code>& bundles(const Bundled_code_header& x) {
return x.bundles_;
}
public:
// CREATORS
Bundled_code_header() = default;
template <typename RandomAccessIterator>
Bundled_code_header(RandomAccessIterator f, RandomAccessIterator l);
explicit Bundled_code_header(const std::vector<char>& blob)
: Bundled_code_header{blob.cbegin(), blob.cend()} {}
explicit Bundled_code_header(const void* maybe_blob) {
// This is a pretty terrible interface, useful only because
// hipLoadModuleData is so poorly specified (for no fault of its own).
if (!maybe_blob) return;
if (!valid(*static_cast<const Bundled_code_header*>(maybe_blob))) return;
auto ph = static_cast<const Header_*>(maybe_blob);
size_t sz = sizeof(Header_) + ph->bundle_cnt_ * sizeof(Bundled_code::Header);
auto pb = static_cast<const char*>(maybe_blob) + sizeof(Header_);
auto n = ph->bundle_cnt_;
while (n--) {
sz += reinterpret_cast<const Bundled_code::Header*>(pb)->bundle_sz;
pb += sizeof(Bundled_code::Header);
}
read(static_cast<const char*>(maybe_blob), static_cast<const char*>(maybe_blob) + sz, *this);
}
Bundled_code_header(const Bundled_code_header&) = default;
Bundled_code_header(Bundled_code_header&&) = default;
~Bundled_code_header() = default;
// MANIPULATORS
Bundled_code_header& operator=(const Bundled_code_header&) = default;
Bundled_code_header& operator=(Bundled_code_header&&) = default;
size_t bundled_code_size = 0;
};
// CREATORS
template <typename RandomAccessIterator>
Bundled_code_header::Bundled_code_header(RandomAccessIterator f, RandomAccessIterator l)
: Bundled_code_header{} {
read(f, l, *this);
}
} // Namespace hip_impl.
-82
Féach ar an gComhad
@@ -1,82 +0,0 @@
#pragma once
#include <algorithm>
#include <cassert>
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>
namespace hip_impl {
inline const std::unordered_set<std::string>& amdgpu_targets() { // The evolving list lives at:
// https://www.llvm.org/docs/AMDGPUUsage.html#processors.
static const std::unordered_set<std::string> r{
"gfx700", "gfx701", "gfx702", "gfx703", "gfx704", "gfx705",
"gfx801", "gfx802", "gfx803", "gfx805", "gfx810",
"gfx900", "gfx902", "gfx904", "gfx906", "gfx908", "gfx909",
"gfx1010", "gfx1011", "gfx1012", "gfx1030", "gfx1031", "gfx1032"};
return r;
}
inline const std::string& code_object_extension() {
static const std::string r{".ffa"};
return r;
}
inline const std::string& fat_binary_extension() {
static const std::string r{".adipose"};
return r;
}
inline bool file_exists(const std::string& path_to) {
return static_cast<bool>(std::ifstream{path_to});
}
inline std::vector<std::string> tokenize_targets(
const std::string&
x) { // TODO: move to regular expressions once we clarify the need to support
// ancient standard library implementations.
if (x.empty()) return {};
static constexpr const char valid_characters[] = "0123456789abcdefghijklmnopqrstuvwxyz,";
if (x.find_first_not_of(valid_characters) != std::string::npos) {
throw std::runtime_error{"Invalid target string: " + x};
}
std::vector<std::string> r;
auto it = x.cbegin();
do {
auto it1 = std::find(it, x.cend(), ',');
r.emplace_back(it, it1);
if (it1 == x.cend()) break;
it = ++it1;
} while (true);
return r;
}
inline void validate_targets(const std::vector<std::string>& x) {
assert(!x.empty());
for (auto&& t : x) {
static const std::string sufficies{"0123456789abcdefghijklmnopqrstuvwxyz"};
static const std::string prefix{"gfx"};
if (t.find(prefix) != 0 || t.find_first_not_of(sufficies, prefix.size()) != std::string::npos) {
throw std::runtime_error{"Invalid target: " + t};
}
if (amdgpu_targets().find(t) == amdgpu_targets().cend()) {
std::cerr << "Warning: target " << t
<< " has not been validated yet; it may be invalid." << std::endl;
}
}
}
} // Namespace hip_impl.
-55
Féach ar an gComhad
@@ -1,55 +0,0 @@
#include "lpl.hpp"
#include <cstdlib>
#include <exception>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
using namespace clara;
using namespace hip_impl;
using namespace std;
int main(int argc, char** argv) {
try {
if (!hipcc_and_lpl_colocated()) {
throw runtime_error{"The LPL executable and hipcc must be in the same directory."};
}
bool help = false;
string flags;
string output;
vector<string> sources;
string targets;
auto cmd = cmdline_parser(help, sources, targets, flags, output);
const auto r = cmd.parse(Args{argc, argv});
if (!r) throw runtime_error{r.errorMessage()};
if (help)
cout << cmd << endl;
else {
if (sources.empty()) throw runtime_error{"No inputs specified."};
auto tmp = tokenize_targets(targets);
if (tmp.empty()) {
tmp.assign(amdgpu_targets().cbegin(), amdgpu_targets().cend());
} else
validate_targets(tmp);
if (output.empty())
for (auto&& x : tmp) output += x;
generate_fat_binary(sources, tmp, flags, output);
}
} catch (const exception& ex) {
cerr << ex.what() << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-140
Féach ar an gComhad
@@ -1,140 +0,0 @@
#pragma once
#include "common.hpp"
#include "clara/clara.hpp"
#include "pstreams/pstream.h"
#include <elfio/elfio.hpp>
#include <unistd.h>
#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <mutex>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
namespace hip_impl {
inline const std::string& kernel_section() {
static const std::string r{".kernel"};
return r;
}
inline const std::string& path_to_self() {
static constexpr const char self[] = "/proc/self/exe";
static std::string r;
static std::once_flag f;
std::call_once(f, []() {
using N = decltype(readlink(self, &r.front(), r.size()));
constexpr decltype(r.size()) max_path_sz{PATH_MAX};
N read_cnt;
do {
r.resize(std::max(2 * r.size(), max_path_sz));
read_cnt = readlink(self, &r.front(), r.size());
} while (read_cnt == -1 && r.size() < r.max_size());
r.resize(std::max(read_cnt, N{0}));
});
return r;
}
inline const std::string& path_to_hipcc() {
assert(!path_to_self().empty());
static const auto r = path_to_self().substr(0, path_to_self().find_last_of('/')) += "/hipcc";
return r;
}
inline std::string make_hipcc_call(const std::vector<std::string>& sources,
const std::vector<std::string>& targets,
const std::string& flags, const std::string& hipcc_output) {
assert(!sources.empty() && !targets.empty() && !hipcc_output.empty());
std::string r{path_to_hipcc() + ' '};
for (auto&& x : sources) r += x + ' ';
r += "-o " + hipcc_output + ' ';
for (auto&& x : targets) r += "--amdgpu-target=" + x + ' ';
r += flags + " -fPIC -shared";
return r;
}
inline void copy_kernel_section_to_fat_binary(const std::string& tmp, const std::string& output) {
amd::ELFIO::elfio reader;
if (!reader.load(tmp)) {
throw std::runtime_error{"The result of the compilation is inaccessible."};
}
const auto it =
std::find_if(reader.sections.begin(), reader.sections.end(),
[](const amd::ELFIO::section* x) { return x->get_name() == kernel_section(); });
std::ofstream out{output};
if (it == reader.sections.end()) {
std::cerr << "Warning: no kernels were generated; fat binary shall "
"be empty."
<< std::endl;
} else {
std::copy_n((*it)->get_data(), (*it)->get_size(), std::ostreambuf_iterator<char>{out});
}
}
inline void generate_fat_binary(const std::vector<std::string>& sources,
const std::vector<std::string>& targets, const std::string& flags,
const std::string& output) {
static const auto d = [](const std::string* f) { remove(f->c_str()); };
std::string temp_str = output + ".tmp";
std::unique_ptr<const std::string, decltype(d)> tmp{&temp_str, d};
redi::ipstream hipcc{make_hipcc_call(sources, targets, flags, *tmp), redi::pstream::pstderr};
if (!hipcc.is_open()) {
throw std::runtime_error{"Compiler invocation failed."};
}
std::string log;
while (std::getline(hipcc, log)) std::cout << log << '\n';
hipcc.close();
if (hipcc.rdbuf()->exited() && hipcc.rdbuf()->status() != EXIT_SUCCESS) {
throw std::runtime_error{"Compilation failed."};
}
copy_kernel_section_to_fat_binary(*tmp, output);
}
inline bool hipcc_and_lpl_colocated() {
if (path_to_self().empty()) return false;
return file_exists(path_to_hipcc());
}
inline clara::Parser cmdline_parser(bool& help, std::vector<std::string>& sources,
std::string& targets, std::string& flags, std::string& output) {
return clara::Opt{flags, "\"-v -DMACRO etc.\""}["-f"]["--flags"](
"flags for compilation; must be valid for hipcc.") |
clara::Help{help} |
clara::Opt{output, "filename"}["-o"]["--output"](
"name of fat-binary output file; the binary format of the "
"file is documented at: https://reviews.llvm.org/D13909.") |
clara::Arg{sources,
"a.cpp b.cpp etc."}("inputs for compilation; must contain valid C++ code.") |
clara::Opt{targets, "gfx803,gfx900,gfx906,gfx908 etc."}["-t"]["--targets"](
"targets for AMDGPU lowering; must be included in the set "
"of processors with ROCm support from "
"https://www.llvm.org/docs/AMDGPUUsage.html#processors.");
}
} // namespace hip_impl
Tá difríocht comhad cosc orthu toisc go bhfuil sé ró-mhór Difríocht Luchtaigh
-2
Féach ar an gComhad
@@ -9,8 +9,6 @@ install(FILES @PROJECT_BINARY_DIR@/include/hip/amd_detail/hip_prof_str.h
install(FILES @PROJECT_BINARY_DIR@/include/hip/hip_version.h
DESTINATION include/hip)
install(FILES @PROJECT_BINARY_DIR@/.hipVersion DESTINATION bin)
install(PROGRAMS @PROJECT_BINARY_DIR@/lpl DESTINATION bin)
install(PROGRAMS @PROJECT_BINARY_DIR@/ca DESTINATION bin)
install(DIRECTORY @hip_SOURCE_DIR@/cmake DESTINATION .)
#############################