Last active
November 28, 2018 12:19
-
-
Save emfomenk/f6ffe2cb2be1aced27c10d12db2f4dc9 to your computer and use it in GitHub Desktop.
simple deconv w/ groups
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <mkldnn.hpp> | |
using namespace mkldnn; | |
int main() { | |
auto cpu_engine = engine(engine::cpu, 0); | |
std::vector<float> src = {1, 2, -1, -2}; | |
std::vector<float> wei = {10, 2, 1, 10, 100, 1, 3, 100}; | |
std::vector<float> dst(4); | |
memory::dims src_tz = { 1, 4, 1, 1 }; | |
memory::dims wei_tz = { 2, 2, 2, 1, 1 }; | |
memory::dims dst_tz = src_tz; | |
auto u_src_md = memory::desc({src_tz}, memory::data_type::f32, memory::format::nchw); | |
auto u_wei_md = memory::desc({wei_tz}, memory::data_type::f32, memory::format::GWEI_FMT); | |
auto u_dst_md = memory::desc({dst_tz}, memory::data_type::f32, memory::format::nchw); | |
auto src_m = memory({u_src_md, cpu_engine }, src.data()); | |
auto wei_m = memory({u_wei_md, cpu_engine }, wei.data()); | |
auto dst_m = memory({u_dst_md, cpu_engine }, dst.data()); | |
auto deconv_d = deconvolution_forward::desc(prop_kind::forward_inference, | |
deconvolution_direct, u_src_md, u_wei_md, u_dst_md, | |
{1, 1}, {0, 0}, {0, 0}, padding_kind::zero); | |
auto deconv_pd = deconvolution_forward::primitive_desc(deconv_d, cpu_engine); | |
std::vector<primitive> net; | |
net.push_back(deconvolution_forward(deconv_pd, src_m, wei_m, dst_m)); | |
stream(stream::kind::eager).submit(net).wait(); | |
for (int i = 0; i < dst.size(); ++i) | |
printf("%g, ", dst[i]); | |
printf("\n"); | |
return 0; | |
} | |
// Incosistent with PyTorch if wrong weights format (goihw). PyTorch uses (giohw) | |
// $ g++ -DGWEI_FMT=goihw deconv.cpp -lmkldnn -lgomp -lpthread && ./a.out | |
// 14, 21, -102, -203, # expect: 12, 22, -106, -201, | |
// | |
// $ g++ -DGWEI_FMT=giohw deconv.cpp -lmkldnn -lgomp -lpthread && ./a.out | |
// 12, 22, -106, -201, # YES! just as expect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import torch | |
import numpy as np | |
inp = np.array([1, 2, -1, -2]).astype(np.float32).reshape(1, 4, 1, 1) | |
wei = np.array([10, 2, 1, 10, 100, 1, 3, 100]).astype(np.float32).reshape(4, 2, 1, 1) | |
deconv = torch.nn.ConvTranspose2d(4, 4, 1, groups = 2) | |
deconv.input = torch.from_numpy(inp) | |
deconv.weight.data = torch.from_numpy(wei) | |
torch.nn.init.constant_(deconv.bias.data, 0) | |
print(deconv(deconv.input)) | |
# $ python deconv.py | |
# tensor([[[[ 12.]], [[ 22.]], [[-106.]], [[-201.]]]], grad_fn=<CatBackward>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <mkldnn.hpp> | |
using namespace mkldnn; | |
int main() { | |
auto cpu_engine = engine(engine::cpu, 0); | |
std::vector<float> src = {1, 2, -1, -2}; | |
std::vector<float> wei = {10, 2, 1, 10, 100, 1, 3, 100}; | |
std::vector<float> dst(4); | |
memory::dims src_tz = { 1, 4, 1, 1 }; | |
memory::dims wei_tz = { 2, 2, 2, 1, 1 }; | |
memory::dims dst_tz = src_tz; | |
auto u_src_md = memory::desc({src_tz}, memory::data_type::f32, memory::format::nchw); | |
auto u_wei_md = memory::desc({wei_tz}, memory::data_type::f32, memory::format::giohw); | |
auto u_dst_md = memory::desc({dst_tz}, memory::data_type::f32, memory::format::nchw); | |
auto u_src_m = memory({u_src_md, cpu_engine}, src.data()); | |
auto u_wei_m = memory({u_wei_md, cpu_engine}, wei.data()); | |
auto u_dst_m = memory({u_dst_md, cpu_engine}, dst.data()); | |
auto d_src_md = memory::desc({src_tz}, memory::data_type::f32, memory::format::any); | |
auto d_wei_md = memory::desc({wei_tz}, memory::data_type::f32, memory::format::any); | |
auto d_dst_md = memory::desc({dst_tz}, memory::data_type::f32, memory::format::any); | |
auto deconv_d = deconvolution_forward::desc(prop_kind::forward_inference, | |
deconvolution_direct, d_src_md, d_wei_md, d_dst_md, | |
{1, 1}, {0, 0}, {0, 0}, padding_kind::zero); | |
auto deconv_pd = deconvolution_forward::primitive_desc(deconv_d, cpu_engine); | |
auto d_src_m = memory(deconv_pd.src_primitive_desc()); | |
auto d_wei_m = memory(deconv_pd.weights_primitive_desc()); | |
auto d_dst_m = memory(deconv_pd.dst_primitive_desc()); | |
std::vector<primitive> net; | |
// note that some of the reorders might be redundant | |
// create and execute all of them just for simplicity | |
net.push_back(reorder(u_src_m, d_src_m)); | |
net.push_back(reorder(u_wei_m, d_wei_m)); | |
net.push_back(deconvolution_forward(deconv_pd, d_src_m, d_wei_m, d_dst_m)); | |
net.push_back(reorder(d_dst_m, u_dst_m)); | |
stream(stream::kind::eager).submit(net).wait(); | |
for (int i = 0; i < dst.size(); ++i) | |
printf("%g, ", dst[i]); | |
printf("\n"); | |
return 0; | |
} | |
// $ g++ deconv_with_any.cpp -lmkldnn -lgomp -lpthread && ./a.out | |
// 12, 22, -106, -201, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment