Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #include "XLSnnInputLayer.h"
24 : #include "XLSnnVkInputLayer.h"
25 : #include "XLSnnAttachment.h"
26 :
27 : namespace stappler::xenolith::shadernn {
28 :
29 0 : bool InputLayer::init(Model *m, StringView tag, size_t idx, const Value &data) {
30 0 : if (!Layer::init(m, tag, idx, data)) {
31 0 : return false;
32 : }
33 :
34 0 : _inputWidth = uint32_t(data.getInteger("Input Width", 1));
35 0 : _inputHeight = uint32_t(data.getInteger("Input Height", 1));
36 0 : _inputChannels = uint32_t(data.getInteger("outputPlanes", 1));
37 0 : if (data.hasValue("inputIndex")) {
38 0 : _inputIndex = uint32_t(data.getInteger("inputIndex", 0));
39 : }
40 :
41 0 : _isInputLayer = true;
42 :
43 0 : return true;
44 : }
45 :
46 0 : const core::QueuePassData *InputLayer::prepare(core::Queue::Builder &builder,
47 : Map<Layer *, const core::AttachmentData *> inputs,
48 : Map<Attachment *, const core::AttachmentData *> attachments) {
49 :
50 0 : auto inputIt = inputs.find(this);
51 0 : auto outputIt = attachments.find(getOutput());
52 :
53 0 : if (inputIt == inputs.end() || outputIt == attachments.end()) {
54 0 : log::error("snn::InputLayer", "No attachments specified");
55 0 : return nullptr;
56 : }
57 :
58 0 : return builder.addPass(getName(), core::PassType::Compute, core::RenderOrdering(_inputIndex),
59 0 : [&] (core::QueuePassBuilder &passBuilder) -> Rc<core::QueuePass> {
60 0 : return Rc<vk::shadernn::InputLayer>::create(builder, passBuilder, inputIt->second, outputIt->second);
61 0 : });
62 : }
63 :
64 0 : const core::AttachmentData *InputLayer::makeInputAttachment(core::Queue::Builder &builder) {
65 0 : return builder.addAttachemnt(toString(getName(), "_input"),
66 0 : [&] (core::AttachmentBuilder &attachmentBuilder) -> Rc<core::Attachment> {
67 0 : return Rc<vk::ImageAttachment>::create(attachmentBuilder,
68 0 : core::ImageInfo(Extent2(getOutputExtent().width, getOutputExtent().height),
69 0 : core::ImageUsage::Storage | core::ImageUsage::TransferSrc,
70 0 : core::ImageTiling::Optimal, core::ImageFormat::R8G8B8A8_UNORM, core::PassType::Compute),
71 0 : core::ImageAttachment::AttachmentInfo{
72 : .initialLayout = core::AttachmentLayout::Ignored,
73 : .finalLayout = core::AttachmentLayout::Ignored,
74 : .clearOnLoad = true,
75 : .clearColor = Color4F(0.0f, 0.0f, 0.0f, 0.0f)}
76 0 : );
77 0 : });
78 : }
79 :
80 0 : const core::AttachmentData *InputLayer::makeOutputAttachment(core::Queue::Builder &builder, bool isGlobalOutput) {
81 0 : auto modelFormat = _model->isHalfPrecision() ? core::ImageFormat::R16G16B16A16_SFLOAT : core::ImageFormat::R32G32B32A32_SFLOAT;
82 :
83 0 : auto output = getOutput();
84 0 : auto attachment = builder.addAttachemnt(output->getName(),
85 0 : [&] (core::AttachmentBuilder &attachmentBuilder) -> Rc<core::Attachment> {
86 0 : if (isGlobalOutput) {
87 0 : attachmentBuilder.defineAsOutput();
88 : }
89 0 : return Rc<vk::ImageAttachment>::create(attachmentBuilder,
90 0 : core::ImageInfo(output->getExtent(), core::ImageType::Image3D,
91 0 : core::ImageUsage::Storage | core::ImageUsage::TransferSrc,
92 0 : core::ImageTiling::Optimal, modelFormat, core::PassType::Compute),
93 0 : core::ImageAttachment::AttachmentInfo{
94 : .initialLayout = core::AttachmentLayout::Ignored,
95 : .finalLayout = core::AttachmentLayout::Ignored }
96 0 : );
97 : });
98 0 : return attachment;
99 : }
100 :
101 2 : bool InputBufferLayer::init(Model *m, StringView tag, size_t idx, const Value &data) {
102 2 : if (!Layer::init(m, tag, idx, data)) {
103 0 : return false;
104 : }
105 :
106 2 : _inputWidth = uint32_t(data.getInteger("Input Width", 1));
107 2 : _inputHeight = uint32_t(data.getInteger("Input Height", 1));
108 2 : _inputObjects = uint32_t(data.getInteger("Input Batch", 1));
109 :
110 2 : _isInputLayer = true;
111 :
112 2 : return true;
113 : }
114 :
115 2 : const core::QueuePassData *InputBufferLayer::prepare(core::Queue::Builder &builder,
116 : Map<Layer *, const core::AttachmentData *> inputs,
117 : Map<Attachment *, const core::AttachmentData *> attachments) {
118 :
119 2 : auto inputIt = inputs.find(this);
120 2 : auto outputIt = attachments.find(getOutput());
121 :
122 2 : if (inputIt == inputs.end() || outputIt == attachments.end()) {
123 0 : log::error("snn::InputLayer", "No attachments specified");
124 0 : return nullptr;
125 : }
126 :
127 4 : return builder.addPass(getName(), core::PassType::Compute, core::RenderOrdering(_inputIndex),
128 2 : [&] (core::QueuePassBuilder &passBuilder) -> Rc<core::QueuePass> {
129 4 : return Rc<vk::shadernn::InputBufferLayer>::create(builder, passBuilder, this, inputIt->second, outputIt->second);
130 2 : });
131 : }
132 :
133 2 : const core::AttachmentData *InputBufferLayer::makeInputAttachment(core::Queue::Builder &builder) {
134 4 : return builder.addAttachemnt(toString(getName(), "_input"),
135 2 : [&] (core::AttachmentBuilder &attachmentBuilder) -> Rc<core::Attachment> {
136 4 : return Rc<vk::BufferAttachment>::create(attachmentBuilder,
137 2 : core::BufferInfo(size_t(_inputWidth * _inputHeight * _inputObjects * sizeof(float)),
138 4 : core::BufferUsage::StorageBuffer | core::BufferUsage::TransferDst, core::PassType::Compute)
139 4 : );
140 4 : });
141 : }
142 :
143 2 : const core::AttachmentData *InputBufferLayer::makeOutputAttachment(core::Queue::Builder &builder, bool isGlobalOutput) {
144 4 : return builder.addAttachemnt(toString(getName(), "_output"),
145 2 : [&] (core::AttachmentBuilder &attachmentBuilder) -> Rc<core::Attachment> {
146 2 : if (isGlobalOutput) {
147 0 : attachmentBuilder.defineAsOutput();
148 : }
149 4 : return Rc<vk::BufferAttachment>::create(attachmentBuilder,
150 2 : core::BufferInfo(size_t(_inputWidth * _inputHeight * _inputObjects * sizeof(float)),
151 4 : core::BufferUsage::StorageBuffer, core::PassType::Compute)
152 4 : );
153 4 : });
154 : }
155 :
156 0 : bool InputCsvIntLayer::init(Model *m, StringView tag, size_t idx, const Value &data) {
157 0 : if (!Layer::init(m, tag, idx, data)) {
158 0 : return false;
159 : }
160 :
161 0 : _inputObjects = data.getInteger("inputObjects");
162 :
163 0 : for (auto &it : data.getArray("fields")) {
164 0 : _fields.emplace_back(it.getInteger());
165 : }
166 :
167 0 : _isInputLayer = true;
168 :
169 0 : for (auto &it : data.getArray("norm")) {
170 0 : _norm.emplace_back(NormData{uint64_t(it.getInteger(0)), uint64_t(it.getInteger(1))});
171 : }
172 :
173 0 : return true;
174 : }
175 :
176 0 : const core::QueuePassData *InputCsvIntLayer::prepare(core::Queue::Builder &builder,
177 : Map<Layer *, const core::AttachmentData *> inputs,
178 : Map<Attachment *, const core::AttachmentData *> attachments) {
179 0 : auto inputIt = inputs.find(this);
180 0 : auto outputIt = attachments.find(getOutput());
181 :
182 0 : if (inputIt == inputs.end() || outputIt == attachments.end()) {
183 0 : log::error("snn::InputLayer", "No attachments specified");
184 0 : return nullptr;
185 : }
186 :
187 0 : return builder.addPass(getName(), core::PassType::Compute, core::RenderOrdering(_inputIndex),
188 0 : [&] (core::QueuePassBuilder &passBuilder) -> Rc<core::QueuePass> {
189 0 : return Rc<vk::shadernn::InputCsvIntLayer>::create(builder, passBuilder, this, inputIt->second, outputIt->second);
190 0 : });
191 : }
192 :
193 0 : const core::AttachmentData *InputCsvIntLayer::makeInputAttachment(core::Queue::Builder &builder) {
194 0 : return builder.addAttachemnt(toString(getName(), "_input"),
195 0 : [&] (core::AttachmentBuilder &attachmentBuilder) -> Rc<core::Attachment> {
196 0 : return Rc<vk::BufferAttachment>::create(attachmentBuilder,
197 0 : core::BufferInfo(size_t(_inputObjects * sizeof(uint64_t)),
198 0 : core::BufferUsage::StorageBuffer | core::BufferUsage::TransferDst, core::PassType::Compute)
199 0 : );
200 0 : });
201 : }
202 :
203 0 : const core::AttachmentData *InputCsvIntLayer::makeOutputAttachment(core::Queue::Builder &builder, bool isGlobalOutput) {
204 0 : return builder.addAttachemnt(toString(getName(), "_output"),
205 0 : [&] (core::AttachmentBuilder &attachmentBuilder) -> Rc<core::Attachment> {
206 0 : if (isGlobalOutput) {
207 0 : attachmentBuilder.defineAsOutput();
208 : }
209 0 : return Rc<vk::BufferAttachment>::create(attachmentBuilder,
210 0 : core::BufferInfo(size_t(_inputObjects * sizeof(uint64_t)),
211 0 : core::BufferUsage::StorageBuffer | core::BufferUsage::TransferDst, core::PassType::Compute)
212 0 : );
213 0 : });
214 : }
215 :
216 : }
|