Repository navigation
Initial implementation of Deformable Convolution workload #168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
a595aea
2963944
809047d
7d39e0e
0de01b1
0e1b858
ff457c0
95fa4a9
00a0944
46d90dc
5badbc4
a1a88a5
bce5efa
2642393
a85dcf4
4e2b42b
909d103
e7face2
c5bddb3
0c4f1f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| add_subdirectory(deformable_convolution_sycl_native_ext) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Copyright 2022 Intel Corporation | ||
| # | ||
| # SPDX-License-Identifier: Apache 2.0 | ||
|
|
||
| from .deformable_convolution_initialize import initialize | ||
| from .deformable_convolution_numba_npr import deformable_convolution as deformable_convolution_numba_npr | ||
| from .deformable_convolution_numpy import deformable_convolution as deformable_convolution_numpy | ||
| from .deformable_convolution_sycl_native_ext import deformable_convolution_sycl | ||
|
|
||
| __all__ = [ | ||
| "initialize", | ||
| "deformable_convolution_numba_npr", | ||
| "deformable_convolution_numba_numpy", | ||
| "deformable_convolution_sycl", | ||
| ] | ||
|
|
||
| """l2-norm calculation of n vectors | ||
|
|
||
| Input | ||
| --------- | ||
| npoints: int | ||
| number of vectors | ||
| dims: int | ||
| dimension of single vector | ||
| seed: int | ||
| random seed to generate random number | ||
|
|
||
| Output | ||
| ------- | ||
| d: array | ||
| l2 norm of each vector | ||
|
|
||
| Method | ||
| ------ | ||
| ||Vj||2=sqrt(sum(Xj[i]*Xj[i])) | ||
| here i is 0->dims, j is 0->npoints | ||
| """ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Copyright 2022 Intel Corp. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
|
|
||
| def initialize(batch, | ||
| in_channels, in_height, in_width, | ||
| out_channels, out_height, out_width, | ||
| kernel_height, kernel_width, | ||
| stride_y, stride_x, | ||
| dilation_y, dilation_x, | ||
| pad_y, pad_x, | ||
| groups, | ||
| deformable_groups, | ||
| dtype, | ||
| seed): | ||
| import numpy as np | ||
| import numpy.random as default_rng | ||
| default_rng.seed(seed) | ||
|
|
||
| return ( | ||
| default_rng.random((batch, in_channels, in_height, in_width)).astype(dtype), | ||
| # np.ones((batch, in_channels, in_height, in_width)).astype(dtype), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please cleanup commented out code. |
||
| np.zeros((batch, out_channels, out_height, out_width)).astype(dtype), | ||
| # np.zeros((kernel_height, kernel_width, 2, out_height, out_width)).astype(dtype), | ||
| 2*default_rng.random((kernel_height, kernel_width, 2, out_height, out_width)).astype(dtype) - 1, | ||
| # default_rng.random((out_channels, in_channels, kernel_height, kernel_width)).astype(dtype), | ||
| np.ones((out_channels, in_channels, kernel_height, kernel_width)).astype(dtype), | ||
| default_rng.random(out_channels).astype(dtype), | ||
| # np.ones((out_channels,)).astype(dtype), | ||
| np.zeros((in_channels, kernel_height, kernel_width, out_height, out_width)).astype(dtype) | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Copyright 2022 Intel Corp. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import math | ||
| import numpy as np | ||
| from numba import njit, prange | ||
|
|
||
| @njit(parallel=True, inline='always', fastmath=True) | ||
| def bilinear(input, offset_y, offset_x): | ||
| height, width = input.shape | ||
| start_x = int(math.floor(offset_x)) | ||
| start_x_weight = 1 - (offset_x - start_x) | ||
| start_y = int(math.floor(offset_y)) | ||
| start_y_weight = 1 - (offset_y - start_y) | ||
|
|
||
| output = 0 | ||
| if offset_x >= width or offset_y >= height or offset_x <= -1 or offset_y <= -1: | ||
| return output | ||
|
|
||
| if start_x >= 0 and start_y >= 0: | ||
| w = start_x_weight*start_y_weight | ||
| output += w*input[start_y, start_x] | ||
|
|
||
| if start_x + 1 < width and start_y >= 0: | ||
| w = (1 - start_x_weight)*start_y_weight | ||
| output += w*input[start_y, start_x + 1] | ||
|
|
||
| if start_x >=0 and start_y + 1 < height: | ||
| w = start_x_weight*(1 - start_y_weight) | ||
| output += w*input[start_y + 1, start_x] | ||
|
|
||
| if start_x + 1 < width and start_y + 1 < height: | ||
| w = (1 - start_x_weight)*(1 - start_y_weight) | ||
| output += w*input[start_y + 1, start_x + 1] | ||
|
|
||
| return output | ||
|
|
||
| @njit(parallel=True, fastmath=True) | ||
| def deform(input, offset, output, stride, pad, dilation, groups, deformable_groups): | ||
| k_height, k_width, _, out_height, out_width = offset.shape | ||
| channels, _, _ = input.shape | ||
|
|
||
| k_h_m = (k_height - 1)//2 | ||
| k_w_m = (k_width - 1)//2 | ||
|
|
||
| for ckhkw in prange(channels*k_height*k_width): | ||
| for h in prange(out_height): | ||
| for w in prange(out_width): | ||
| c = ckhkw//(k_height*k_width) | ||
| khkw = ckhkw%(k_height*k_width) | ||
| kh = khkw//k_width | ||
| kw = khkw%k_width | ||
|
|
||
| offset_y = offset[kh, kw, 1, h, w] + h*stride[0] + (kh - k_h_m)*dilation[0] - (pad[0] - k_h_m) | ||
| offset_x = offset[kh, kw, 0, h, w] + w*stride[1] + (kw - k_w_m)*dilation[1] - (pad[1] - k_w_m) | ||
|
|
||
| output[c, kh, kw, h, w] = bilinear(input[c], offset_y, offset_x) | ||
|
|
||
| @njit(parallel=True, fastmath=True) | ||
| def deformable_convolution_b1(input, output, offset, weights, bias, tmp, stride, pad, dilation, groups, deformable_groups): | ||
| out_channels, height, width = output.shape | ||
| _, in_channels, k_height, k_width = weights.shape | ||
|
|
||
| deform(input, offset, tmp, stride, pad, dilation, groups, deformable_groups) | ||
|
|
||
| tmp = tmp.reshape((in_channels*k_height*k_width, height*width)) | ||
|
|
||
| _weights = weights.reshape((out_channels, in_channels*k_height*k_width)) | ||
| _output = output.reshape((out_channels, height*width)) | ||
| np.dot(_weights, tmp, _output) | ||
|
|
||
| _bias = bias.reshape((out_channels, 1)) | ||
| _output[:] = _output + _bias | ||
|
|
||
| @njit(parallel=True) | ||
| def deformable_convolution(input, output, offset, weights, bias, tmp, stride_y, stride_x, pad_y, pad_x, dilation_y, dilation_x, groups, deformable_groups): | ||
| batch, _, _, _ = input.shape | ||
| for b in range(batch): | ||
| deformable_convolution_b1(input[b], output[b], offset, weights, bias, tmp, (stride_y, stride_x), (pad_y, pad_x), (dilation_y, dilation_x), groups, deformable_groups) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Copyright 2022 Intel Corp. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this _numpy implementation is the same as the _numba_npr version. If so, we should not be adding this. |
||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import math | ||
| import numpy as np | ||
| from numba import njit, prange | ||
|
|
||
| @njit(parallel=True, inline='always', fastmath=True) | ||
| def bilinear(input, offset_y, offset_x): | ||
| height, width = input.shape | ||
| start_x = int(math.floor(offset_x)) | ||
| start_x_weight = 1 - (offset_x - start_x) | ||
| start_y = int(math.floor(offset_y)) | ||
| start_y_weight = 1 - (offset_y - start_y) | ||
|
|
||
| output = 0 | ||
| if start_x >= width or start_y >= height or start_x < -1 or start_y < -1: | ||
| return output | ||
|
|
||
| if start_x >= 0 and start_y >= 0: | ||
| w = start_x_weight*start_y_weight | ||
| output += w*input[start_y, start_x] | ||
|
|
||
| if start_x + 1 < width and start_y >= 0: | ||
| w = (1 - start_x_weight)*start_y_weight | ||
| output += w*input[start_y, start_x + 1] | ||
|
|
||
| if start_x >=0 and start_y + 1 < height: | ||
| w = start_x_weight*(1 - start_y_weight) | ||
| output += w*input[start_y + 1, start_x] | ||
|
|
||
| if start_x + 1 < width and start_y + 1 < height: | ||
| w = (1 - start_x_weight)*(1 - start_y_weight) | ||
| output += w*input[start_y + 1, start_x + 1] | ||
|
|
||
| return output | ||
|
|
||
| @njit(parallel=True, fastmath=True) | ||
| def deform(input, offset, output, stride, pad, dilation, groups, deformable_groups): | ||
| k_height, k_width, _, out_height, out_width = offset.shape | ||
| channels, _, _ = input.shape | ||
|
|
||
| k_h_m = (k_height - 1)//2 | ||
| k_w_m = (k_width - 1)//2 | ||
|
|
||
| for ckhkw in prange(channels*k_height*k_width): | ||
| for h in prange(out_height): | ||
| for w in prange(out_width): | ||
| c = ckhkw//(k_height*k_width) | ||
| khkw = ckhkw%(k_height*k_width) | ||
| kh = khkw//k_width | ||
| kw = khkw%k_width | ||
|
|
||
| offset_y = offset[kh, kw, 1, h, w] + h*stride[0] + (kh - k_h_m)*dilation[0] - (pad[0] - k_h_m) | ||
| offset_x = offset[kh, kw, 0, h, w] + w*stride[1] + (kw - k_w_m)*dilation[1] - (pad[1] - k_w_m) | ||
|
|
||
| output[c, kh, kw, h, w] = bilinear(input[c], offset_y, offset_x) | ||
|
|
||
| # @njit(parallel=True, fastmath=True) | ||
| def deformable_convolution_b1(input, output, offset, weights, bias, tmp, stride, pad, dilation, groups, deformable_groups): | ||
| out_channels, height, width = output.shape | ||
| _, in_channels, k_height, k_width = weights.shape | ||
|
|
||
| deform(input, offset, tmp, stride, pad, dilation, groups, deformable_groups) | ||
|
|
||
| tmp = tmp.reshape((in_channels*k_height*k_width, height*width)) | ||
|
|
||
| _weights = weights.reshape((out_channels, in_channels*k_height*k_width)) | ||
| _output = output.reshape((out_channels, height*width)) | ||
| np.dot(_weights, tmp, _output) | ||
|
|
||
| _bias = bias.reshape((out_channels, 1)) | ||
| _output[:] = _output + _bias | ||
|
|
||
| # @njit(parallel=True) | ||
| def deformable_convolution(input, output, offset, weights, bias, tmp, stride_y, stride_x, pad_y, pad_x, dilation_y, dilation_x, groups, deformable_groups): | ||
| batch, _, _, _ = input.shape | ||
| for b in range(batch): | ||
| deformable_convolution_b1(input[b], output[b], offset, weights, bias, tmp, (stride_y, stride_x), (pad_y, pad_x), (dilation_y, dilation_x), groups, deformable_groups) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| set(py_module_name _deformable_convolution_sycl) | ||
| pybind11_add_module(${py_module_name} | ||
| MODULE | ||
| deformable_convolution_sycl/impl.cpp | ||
| ) | ||
| find_package(MKL CONFIG REQUIRED) | ||
|
|
||
| # target_include_directories(${py_module_name} PUBLIC ${Dpctl_INCLUDE_DIRS} $) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove commented out lines |
||
| target_compile_options(${py_module_name} PUBLIC $<TARGET_PROPERTY:MKL::MKL,INTERFACE_COMPILE_OPTIONS>) | ||
| target_include_directories(${py_module_name} PUBLIC ${Dpctl_INCLUDE_DIRS} $<TARGET_PROPERTY:MKL::MKL,INTERFACE_INCLUDE_DIRECTORIES>) | ||
| target_link_libraries(${py_module_name} PUBLIC $<LINK_ONLY:MKL::MKL> ${MKL_SYCL}) | ||
|
|
||
| message(STATUS "${MKL_IMPORTED_TARGETS}") | ||
| message(STATUS "${INTERFACE_COMPILE_OPTIONS}") | ||
| message(STATUS "${INTERFACE_INCLUDE_DIRECTORIES}") | ||
|
|
||
| file(RELATIVE_PATH py_module_dest ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| install(TARGETS ${py_module_name} | ||
| DESTINATION ${py_module_dest}/deformable_convolution_sycl | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Copyright 2022 Intel Corporation | ||
| # | ||
| # SPDX-License-Identifier: Apache 2.0 | ||
|
|
||
| from .deformable_convolution_sycl._deformable_convolution_sycl import deformable_convolution as deformable_convolution_sycl | ||
|
|
||
| __all__ = ["deformable_convolution_sycl"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments need to be added for this workload