SWDEV-270198 - hip-hcc cleanup remove lpl_ca
Change-Id: I6cae9435397e9070efb4a953c7ba8bd3dcd98c0e
[ROCm/clr commit: 6e7ff3aaae]
Tá an tiomantas seo le fáil i:
tiomanta ag
Anusha Godavarthy Surya
tuismitheoir
53a0b62f82
tiomantas
3cd436f7a4
@@ -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)
|
||||
|
||||
@@ -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---------------------------------------#
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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 .)
|
||||
|
||||
#############################
|
||||
|
||||
Tagairt in Eagrán Nua
Cuir bac ar úsáideoir