Skip to content

Instantly share code, notes, and snippets.

@emfomenk
Last active November 28, 2018 12:19
Show Gist options
  • Save emfomenk/f6ffe2cb2be1aced27c10d12db2f4dc9 to your computer and use it in GitHub Desktop.
Save emfomenk/f6ffe2cb2be1aced27c10d12db2f4dc9 to your computer and use it in GitHub Desktop.
simple deconv w/ groups
#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
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>)
#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