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:
Serge Martin
2020-08-23 08:50:54 +02:00
committed by Marge Bot
parent ef0f8ec03b
commit aadd134081
8 changed files with 166 additions and 7 deletions

View File

@@ -134,6 +134,10 @@ clGetKernelInfo(cl_kernel d_kern, cl_kernel_info param,
buf.as_scalar<cl_program>() = desc(kern.program());
break;
case CL_KERNEL_ATTRIBUTES:
buf.as_string() = find(name_equals(kern.name()), kern.program().symbols()).attributes;
break;
default:
throw error(CL_INVALID_VALUE);
}

View File

@@ -190,6 +190,7 @@ namespace {
static void
proc(S &s, QT &x) {
_proc(s, x.name);
_proc(s, x.attributes);
_proc(s, x.section);
_proc(s, x.offset);
_proc(s, x.args);

View File

@@ -128,12 +128,16 @@ namespace clover {
};
struct symbol {
symbol(const std::string &name, resource_id section,
size_t offset, const std::vector<argument> &args) :
name(name), section(section), offset(offset), args(args) { }
symbol() : name(), section(0), offset(0), args() { }
symbol(const std::string &name, const std::string &attributes,
resource_id section, size_t offset,
const std::vector<argument> &args) :
name(name), attributes(attributes),
section(section),
offset(offset), args(args) { }
symbol() : name(), attributes(), section(0), offset(0), args() { }
std::string name;
std::string attributes;
resource_id section;
size_t offset;
std::vector<argument> args;

View File

@@ -103,6 +103,39 @@ namespace {
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>
make_kernel_args(const Module &mod, const std::string &kernel_name,
const clang::CompilerInstance &c) {
@@ -251,7 +284,8 @@ clover::llvm::build_module_common(const Module &mod,
get_kernels(mod))) {
const ::std::string name(llvm_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));
}

View File

@@ -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
/// argument given by \p arg.

View File

@@ -390,7 +390,7 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev,
reinterpret_cast<const char *>(&header) + sizeof(header));
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);
section_id++;
}

View File

@@ -346,7 +346,7 @@ namespace {
case SpvOpFunctionEnd:
if (kernel_name.empty())
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_name.clear();
args.clear();

View File

@@ -213,6 +213,34 @@ namespace clover {
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