7
7
#include < algorithm>
8
8
9
9
#include " base/numerics/checked_math.h"
10
- #include " third_party/abseil-cpp/absl/types/optional.h"
11
10
#include " third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
12
11
#include " third_party/blink/renderer/bindings/modules/v8/v8_ml_clamp_options.h"
13
12
#include " third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_options.h"
@@ -133,53 +132,6 @@ MLOperand* BuildElementWiseBinary(MLGraphBuilder* builder,
133
132
return output;
134
133
}
135
134
136
- struct PaddingSizes {
137
- uint32_t begin;
138
- uint32_t end;
139
- };
140
-
141
- // Calculate the padding given auto pad, input size, filter size, stride and
142
- // dilation. Return the calculated padding sizes if no error.
143
- absl::optional<PaddingSizes> CalculatePaddingForAutoPad (
144
- V8MLAutoPad::Enum auto_pad,
145
- const uint32_t input_size,
146
- const uint32_t filter_size,
147
- const uint32_t stride,
148
- const uint32_t dilation) {
149
- auto checked_output_size =
150
- (base::MakeCheckedNum<uint32_t >(input_size) + stride - 1 ) / stride;
151
- auto checked_dilated_filter_size =
152
- (base::MakeCheckedNum<uint32_t >(filter_size) - 1 ) * dilation + 1 ;
153
- auto checked_needed_input_size =
154
- (checked_output_size - 1 ) * stride + checked_dilated_filter_size;
155
- if (!checked_needed_input_size.IsValid ()) {
156
- return absl::nullopt;
157
- }
158
- auto checked_total_padding =
159
- checked_needed_input_size.ValueOrDie () > input_size
160
- ? checked_needed_input_size - input_size
161
- : base::MakeCheckedNum<uint32_t >(0 );
162
- base::CheckedNumeric<uint32_t > checked_padding_begin, checked_padding_end;
163
- switch (auto_pad) {
164
- case V8MLAutoPad::Enum::kSameUpper :
165
- checked_padding_begin = checked_total_padding / 2 ;
166
- checked_padding_end = (checked_total_padding + 1 ) / 2 ;
167
- break ;
168
- case V8MLAutoPad::Enum::kSameLower :
169
- checked_padding_begin = (checked_total_padding + 1 ) / 2 ;
170
- checked_padding_end = checked_total_padding / 2 ;
171
- break ;
172
- default :
173
- NOTREACHED ();
174
- }
175
- uint32_t padding_begin, padding_end;
176
- if (!checked_padding_begin.AssignIfValid (&padding_begin) ||
177
- !checked_padding_end.AssignIfValid (&padding_end)) {
178
- return absl::nullopt;
179
- }
180
- return PaddingSizes ({.begin = padding_begin, .end = padding_end});
181
- }
182
-
183
135
// Calculate the output size for conv2d based on WebNN spec:
184
136
// https://www.w3.org/TR/webnn/#api-mlgraphbuilder-conv2d
185
137
// Return the calculated output size if no error.
@@ -315,7 +267,7 @@ absl::optional<FloatSize2D> ValidateAndCalculateConv2dOutputSizes(
315
267
// options.padding array are ignored and the explicit padding values need to
316
268
// be calculated.
317
269
if (auto_pad != V8MLAutoPad::Enum::kExplicit ) {
318
- auto padding_sizes_height = CalculatePaddingForAutoPad (
270
+ auto padding_sizes_height = MLGraphBuilder:: CalculatePaddingForAutoPad (
319
271
auto_pad.AsEnum (), input_height, filter_height, stride_height,
320
272
dilation_height);
321
273
if (!padding_sizes_height) {
@@ -327,9 +279,9 @@ absl::optional<FloatSize2D> ValidateAndCalculateConv2dOutputSizes(
327
279
}
328
280
padding_beginning_height = padding_sizes_height.value ().begin ;
329
281
padding_ending_height = padding_sizes_height.value ().end ;
330
- auto padding_sizes_width =
331
- CalculatePaddingForAutoPad ( auto_pad.AsEnum (), input_width, filter_width,
332
- stride_width, dilation_width);
282
+ auto padding_sizes_width = MLGraphBuilder::CalculatePaddingForAutoPad (
283
+ auto_pad.AsEnum (), input_width, filter_width, stride_width ,
284
+ dilation_width);
333
285
if (!padding_sizes_width) {
334
286
exception_state.ThrowDOMException (
335
287
DOMExceptionCode::kDataError ,
@@ -561,6 +513,47 @@ MLContext* MLGraphBuilder::GetContext() const {
561
513
return ml_context_;
562
514
}
563
515
516
+ // static
517
+ absl::optional<MLGraphBuilder::PaddingSizes>
518
+ MLGraphBuilder::CalculatePaddingForAutoPad (V8MLAutoPad::Enum auto_pad,
519
+ const uint32_t input_size,
520
+ const uint32_t filter_size,
521
+ const uint32_t stride,
522
+ const uint32_t dilation) {
523
+ auto checked_output_size =
524
+ (base::MakeCheckedNum<uint32_t >(input_size) + stride - 1 ) / stride;
525
+ auto checked_dilated_filter_size =
526
+ (base::MakeCheckedNum<uint32_t >(filter_size) - 1 ) * dilation + 1 ;
527
+ auto checked_needed_input_size =
528
+ (checked_output_size - 1 ) * stride + checked_dilated_filter_size;
529
+ if (!checked_needed_input_size.IsValid ()) {
530
+ return absl::nullopt;
531
+ }
532
+ auto checked_total_padding =
533
+ checked_needed_input_size.ValueOrDie () > input_size
534
+ ? checked_needed_input_size - input_size
535
+ : base::MakeCheckedNum<uint32_t >(0 );
536
+ base::CheckedNumeric<uint32_t > checked_padding_begin, checked_padding_end;
537
+ switch (auto_pad) {
538
+ case V8MLAutoPad::Enum::kSameUpper :
539
+ checked_padding_begin = checked_total_padding / 2 ;
540
+ checked_padding_end = (checked_total_padding + 1 ) / 2 ;
541
+ break ;
542
+ case V8MLAutoPad::Enum::kSameLower :
543
+ checked_padding_begin = (checked_total_padding + 1 ) / 2 ;
544
+ checked_padding_end = checked_total_padding / 2 ;
545
+ break ;
546
+ default :
547
+ NOTREACHED ();
548
+ }
549
+ uint32_t padding_begin, padding_end;
550
+ if (!checked_padding_begin.AssignIfValid (&padding_begin) ||
551
+ !checked_padding_end.AssignIfValid (&padding_end)) {
552
+ return absl::nullopt;
553
+ }
554
+ return PaddingSizes ({.begin = padding_begin, .end = padding_end});
555
+ }
556
+
564
557
MLOperand* MLGraphBuilder::input (String name,
565
558
const MLOperandDescriptor* desc,
566
559
ExceptionState& exception_state) {
0 commit comments