clover: add CL_KERNEL_ATTRIBUTES for clGetKernelInfo
Reviewed-by: Francisco Jerez <currojerez@riseup.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4974>
This commit is contained in:
@@ -134,6 +134,10 @@ clGetKernelInfo(cl_kernel d_kern, cl_kernel_info param,
|
|||||||
buf.as_scalar<cl_program>() = desc(kern.program());
|
buf.as_scalar<cl_program>() = desc(kern.program());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CL_KERNEL_ATTRIBUTES:
|
||||||
|
buf.as_string() = find(name_equals(kern.name()), kern.program().symbols()).attributes;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw error(CL_INVALID_VALUE);
|
throw error(CL_INVALID_VALUE);
|
||||||
}
|
}
|
||||||
|
@@ -190,6 +190,7 @@ namespace {
|
|||||||
static void
|
static void
|
||||||
proc(S &s, QT &x) {
|
proc(S &s, QT &x) {
|
||||||
_proc(s, x.name);
|
_proc(s, x.name);
|
||||||
|
_proc(s, x.attributes);
|
||||||
_proc(s, x.section);
|
_proc(s, x.section);
|
||||||
_proc(s, x.offset);
|
_proc(s, x.offset);
|
||||||
_proc(s, x.args);
|
_proc(s, x.args);
|
||||||
|
@@ -128,12 +128,16 @@ namespace clover {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct symbol {
|
struct symbol {
|
||||||
symbol(const std::string &name, resource_id section,
|
symbol(const std::string &name, const std::string &attributes,
|
||||||
size_t offset, const std::vector<argument> &args) :
|
resource_id section, size_t offset,
|
||||||
name(name), section(section), offset(offset), args(args) { }
|
const std::vector<argument> &args) :
|
||||||
symbol() : name(), section(0), offset(0), args() { }
|
name(name), attributes(attributes),
|
||||||
|
section(section),
|
||||||
|
offset(offset), args(args) { }
|
||||||
|
symbol() : name(), attributes(), section(0), offset(0), args() { }
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string attributes;
|
||||||
resource_id section;
|
resource_id section;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
std::vector<argument> args;
|
std::vector<argument> args;
|
||||||
|
@@ -103,6 +103,39 @@ namespace {
|
|||||||
cl_address_qualifier, cl_access_qualifier);
|
cl_address_qualifier, cl_access_qualifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
kernel_attributes(const Module &mod, const std::string &kernel_name) {
|
||||||
|
std::vector<std::string> attributes;
|
||||||
|
|
||||||
|
const Function &f = *mod.getFunction(kernel_name);
|
||||||
|
|
||||||
|
auto vec_type_hint = get_type_kernel_metadata(f, "vec_type_hint");
|
||||||
|
if (!vec_type_hint.empty())
|
||||||
|
attributes.emplace_back("vec_type_hint(" + vec_type_hint + ")");
|
||||||
|
|
||||||
|
auto work_group_size_hint = get_uint_vector_kernel_metadata(f, "work_group_size_hint");
|
||||||
|
if (!work_group_size_hint.empty()) {
|
||||||
|
std::string s = "work_group_size_hint(";
|
||||||
|
s += detokenize(work_group_size_hint, ",");
|
||||||
|
s += ")";
|
||||||
|
attributes.emplace_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reqd_work_group_size = get_uint_vector_kernel_metadata(f, "reqd_work_group_size");
|
||||||
|
if (!reqd_work_group_size.empty()) {
|
||||||
|
std::string s = "reqd_work_group_size(";
|
||||||
|
s += detokenize(reqd_work_group_size, ",");
|
||||||
|
s += ")";
|
||||||
|
attributes.emplace_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto nosvm = get_str_kernel_metadata(f, "nosvm");
|
||||||
|
if (!nosvm.empty())
|
||||||
|
attributes.emplace_back("nosvm");
|
||||||
|
|
||||||
|
return detokenize(attributes, " ");
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<module::argument>
|
std::vector<module::argument>
|
||||||
make_kernel_args(const Module &mod, const std::string &kernel_name,
|
make_kernel_args(const Module &mod, const std::string &kernel_name,
|
||||||
const clang::CompilerInstance &c) {
|
const clang::CompilerInstance &c) {
|
||||||
@@ -251,7 +284,8 @@ clover::llvm::build_module_common(const Module &mod,
|
|||||||
get_kernels(mod))) {
|
get_kernels(mod))) {
|
||||||
const ::std::string name(llvm_name);
|
const ::std::string name(llvm_name);
|
||||||
if (offsets.count(name))
|
if (offsets.count(name))
|
||||||
m.syms.emplace_back(name, 0, offsets.at(name),
|
m.syms.emplace_back(name, kernel_attributes(mod, name),
|
||||||
|
0, offsets.at(name),
|
||||||
make_kernel_args(mod, name, c));
|
make_kernel_args(mod, name, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -55,6 +55,94 @@ namespace clover {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Extract the string metadata node \p name.
|
||||||
|
///
|
||||||
|
inline std::string
|
||||||
|
get_str_kernel_metadata(const ::llvm::Function &f,
|
||||||
|
const std::string &name) {
|
||||||
|
auto operands = detail::get_kernel_metadata_operands(f, name);
|
||||||
|
if (operands.size()) {
|
||||||
|
return ::llvm::cast< ::llvm::MDString>(
|
||||||
|
detail::get_kernel_metadata_operands(f, name)[0])
|
||||||
|
->getString().str();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Extract the string metadata node \p name.
|
||||||
|
///
|
||||||
|
inline std::vector<size_t>
|
||||||
|
get_uint_vector_kernel_metadata(const ::llvm::Function &f,
|
||||||
|
const std::string &name) {
|
||||||
|
auto operands = detail::get_kernel_metadata_operands(f, name);
|
||||||
|
if (operands.size()) {
|
||||||
|
return map([=](const ::llvm::MDOperand& o) {
|
||||||
|
auto value = ::llvm::cast< ::llvm::ConstantAsMetadata>(o)
|
||||||
|
->getValue();
|
||||||
|
return ::llvm::cast< ::llvm::ConstantInt>(value)
|
||||||
|
->getLimitedValue(UINT_MAX);
|
||||||
|
}, operands);
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Extract the string metadata node \p name.
|
||||||
|
///
|
||||||
|
inline std::string
|
||||||
|
get_type_kernel_metadata(const ::llvm::Function &f,
|
||||||
|
const std::string &name) {
|
||||||
|
auto operands = detail::get_kernel_metadata_operands(f, name);
|
||||||
|
if (operands.size()) {
|
||||||
|
auto value = ::llvm::cast< ::llvm::ConstantAsMetadata>(operands[0])
|
||||||
|
->getValue();
|
||||||
|
auto type = ::llvm::cast< ::llvm::UndefValue>(value)
|
||||||
|
->getType();
|
||||||
|
|
||||||
|
value = ::llvm::cast< ::llvm::ConstantAsMetadata>(operands[1])
|
||||||
|
->getValue();
|
||||||
|
bool is_signed = ::llvm::cast< ::llvm::ConstantInt>(value)
|
||||||
|
->getLimitedValue(UINT_MAX);
|
||||||
|
|
||||||
|
std::string data;
|
||||||
|
if (type->isIntOrIntVectorTy()) {
|
||||||
|
if (!is_signed)
|
||||||
|
data = "unsigned ";
|
||||||
|
|
||||||
|
const auto size = type->getScalarSizeInBits();
|
||||||
|
switch(size) {
|
||||||
|
case 8:
|
||||||
|
data += "char";
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
data += "short";
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
data += "int";
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
data += "long";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (type->isVectorTy())
|
||||||
|
data += std::to_string(((::llvm::VectorType*)type)->getNumElements());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
::llvm::raw_string_ostream os { data };
|
||||||
|
type->print(os);
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Extract the string metadata node \p name corresponding to the kernel
|
/// Extract the string metadata node \p name corresponding to the kernel
|
||||||
/// argument given by \p arg.
|
/// argument given by \p arg.
|
||||||
|
@@ -390,7 +390,7 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev,
|
|||||||
reinterpret_cast<const char *>(&header) + sizeof(header));
|
reinterpret_cast<const char *>(&header) + sizeof(header));
|
||||||
text.data.insert(text.data.end(), blob.data, blob.data + blob.size);
|
text.data.insert(text.data.end(), blob.data, blob.data + blob.size);
|
||||||
|
|
||||||
m.syms.emplace_back(sym.name, section_id, 0, args);
|
m.syms.emplace_back(sym.name, std::string(), section_id, 0, args);
|
||||||
m.secs.push_back(text);
|
m.secs.push_back(text);
|
||||||
section_id++;
|
section_id++;
|
||||||
}
|
}
|
||||||
|
@@ -346,7 +346,7 @@ namespace {
|
|||||||
case SpvOpFunctionEnd:
|
case SpvOpFunctionEnd:
|
||||||
if (kernel_name.empty())
|
if (kernel_name.empty())
|
||||||
break;
|
break;
|
||||||
m.syms.emplace_back(kernel_name, 0, kernel_nb, args);
|
m.syms.emplace_back(kernel_name, std::string(), 0, kernel_nb, args);
|
||||||
++kernel_nb;
|
++kernel_nb;
|
||||||
kernel_name.clear();
|
kernel_name.clear();
|
||||||
args.clear();
|
args.clear();
|
||||||
|
@@ -213,6 +213,34 @@ namespace clover {
|
|||||||
|
|
||||||
r.erase(i, e);
|
r.erase(i, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Build a \a sep separated string from a vector of T
|
||||||
|
///
|
||||||
|
template<typename T>
|
||||||
|
std::string
|
||||||
|
detokenize(const std::vector<T> &ss, const std::string &sep) {
|
||||||
|
std::string r;
|
||||||
|
|
||||||
|
for (const auto &s : ss)
|
||||||
|
r += (r.empty() ? "" : sep) + std::to_string(s);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Build a \a sep separated string from a vector of string
|
||||||
|
///
|
||||||
|
template <>
|
||||||
|
inline std::string
|
||||||
|
detokenize(const std::vector<std::string> &ss, const std::string &sep) {
|
||||||
|
std::string r;
|
||||||
|
|
||||||
|
for (const auto &s : ss)
|
||||||
|
r += (r.empty() || s.empty() ? "" : sep) + s;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user