载入中...
搜索中...
未找到
KernelGenWgslBindings.cpp
浏览该文件的文档.
1#include "common/Exception.h"
3
4#include <cctype>
5#include <map>
6
8namespace {
9int storageNode(const Graph &graph, int id) {
10 const auto &node = graph.node(id);
11 switch (node.type) {
12 case OpType::Reshape:
13 case OpType::Flatten:
14 case OpType::Cast: return storageNode(graph, node.in0);
15 default: return id;
16 }
17}
18
19// Specialize only our generated declarations and identifier tokens, never arbitrary user shaders.
20void specializeSource(std::string &source, const std::vector<int> &representatives, int inputCount) {
21 std::vector<std::string> names(static_cast<size_t>(inputCount));
22 std::map<std::string, std::string> aliases;
23 for (int i = 0; i < inputCount; ++i) {
24 const std::string prefix = "@group(0) @binding(" + std::to_string(i) + ") var<storage, read_write> ";
25 const auto begin = source.find(prefix);
26 if (begin == std::string::npos) throw eve::Exception("Tensor WGSL: missing input declaration");
27 const auto nameBegin = begin + prefix.size();
28 const auto nameEnd = source.find(':', nameBegin);
29 names[static_cast<size_t>(i)] = source.substr(nameBegin, nameEnd - nameBegin);
30 if (representatives[static_cast<size_t>(i)] == i) continue;
31 aliases.emplace(names[static_cast<size_t>(i)],
32 names[static_cast<size_t>(representatives[static_cast<size_t>(i)])]);
33 source.erase(begin, source.find('\n', nameEnd) + 1 - begin);
34 }
35 if (aliases.empty()) return;
36 std::string renamed;
37 for (size_t i = 0; i < source.size();) {
38 const unsigned char ch = static_cast<unsigned char>(source[i]);
39 if (std::isalpha(ch) || ch == '_') {
40 const auto begin = i++;
41 while (i < source.size() && (std::isalnum(static_cast<unsigned char>(source[i])) || source[i] == '_')) ++i;
42 const std::string word = source.substr(begin, i - begin);
43 const auto found = aliases.find(word);
44 renamed += found == aliases.end() ? word : found->second;
45 } else {
46 renamed += source[i++];
47 }
48 }
49 source = std::move(renamed);
50}
51} // namespace
52
54 std::map<int, int> first;
55 for (int i = 0; i < spec.inputCount; ++i) {
56 const auto [it, inserted] = first.emplace(storageNode(graph, group.inputs[static_cast<size_t>(i)]), i);
57 (void)inserted;
58 spec.inputRepresentatives.push_back(it->second);
59 }
60 if (spec.twoPass) specializeSource(spec.pass1, spec.inputRepresentatives, spec.inputsReadPass1);
61 if (!spec.pass2.empty()) specializeSource(spec.pass2, spec.inputRepresentatives, spec.inputCount);
62}
63} // namespace eve::tensor::wgsl_detail
building::EdgeCurveGroup group
std::int32_t first
std::map< std::string, std::vector< std::string > > graph
Definition Package.cpp:59
std::string id
Definition PlayHost.cpp:108
float begin
const RoadNode * node
bool found
const UnitySourceAsset & source
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
EVENGINE_API_DOMAINS public API.
Definition Graph.h:111
std::string word
void specializeInputBindings(const Graph &graph, const FusedGroup &group, KernelSpec &spec)
Specialize input bindings.
FusedGroup public API.
Definition Optimizer.h:46
KernelSpec public API.
Definition KernelGen.h:27
std::vector< int > inputRepresentatives
Input slot to representative slot; empty means identity. WGSL aliases repeated read inputs to one dec...
Definition KernelGen.h:34