#ifndef CAFFE2_OPERATORS_ELEMENTWISE_OP_TEST_H_ #define CAFFE2_OPERATORS_ELEMENTWISE_OP_TEST_H_ #include "caffe2/operators/elementwise_ops.h" #include #include #include #include template void CopyVector(const int N, const T* x, T* y); template void FillTensor( caffe2::Workspace* ws, const std::string& name, const std::vector& shape, const std::vector& values) { auto* blob = ws->CreateBlob(name); auto* tensor = BlobGetMutableTensor(blob, Context::GetDeviceType()); tensor->Resize(shape); auto* mutable_data = tensor->template mutable_data(); const O_Type* data = reinterpret_cast(values.data()); CopyVector(values.size(), data, mutable_data); } template caffe2::OperatorDef CreateOperatorDef() { caffe2::OperatorDef def; return def; } template caffe2::OperatorDef DefineOperator(const std::string& op_type) { caffe2::OperatorDef def = CreateOperatorDef(); def.set_name("test"); def.set_type(op_type); def.add_input("X"); def.add_input("Y"); def.add_output("Z"); return def; } template void elementwiseAnd() { const int N = 4; const int M = 2; caffe2::Workspace ws; auto def = DefineOperator("And"); { // equal size FillTensor( &ws, "X", {N}, {true, false, true, false}); FillTensor( &ws, "Y", {N}, {true, true, false, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), N); std::vector result{true, false, false, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } { // broadcast auto* arg = def.add_arg(); arg->set_name("broadcast"); arg->set_i(1); FillTensor( &ws, "X", {M, N}, {true, false, true, false, true, false, true, false}); FillTensor( &ws, "Y", {N}, {true, true, false, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), M * N); std::vector result{ true, false, false, false, true, false, false, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } } template void elementwiseOr() { const int N = 4; const int M = 2; caffe2::Workspace ws; auto def = DefineOperator("Or"); { // equal size FillTensor( &ws, "X", {N}, {true, false, true, false}); FillTensor( &ws, "Y", {N}, {true, true, false, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), N); std::vector result{true, true, true, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } { // broadcast auto* arg = def.add_arg(); arg->set_name("broadcast"); arg->set_i(1); FillTensor( &ws, "X", {M, N}, {true, false, true, false, true, false, true, false}); FillTensor( &ws, "Y", {N}, {true, true, false, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), M * N); std::vector result{true, true, true, false, true, true, true, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } } template void elementwiseXor() { const int N = 4; const int M = 2; caffe2::Workspace ws; auto def = DefineOperator("Xor"); { // equal size FillTensor( &ws, "X", {N}, {true, false, true, false}); FillTensor( &ws, "Y", {N}, {true, true, false, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), N); std::vector result{false, true, true, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } { // broadcast auto* arg = def.add_arg(); arg->set_name("broadcast"); arg->set_i(1); FillTensor( &ws, "X", {M, N}, {true, false, true, false, true, false, true, false}); FillTensor( &ws, "Y", {N}, {true, true, false, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), M * N); std::vector result{ false, true, true, false, false, true, true, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } } template void elementwiseNot() { const int N = 2; caffe2::Workspace ws; caffe2::OperatorDef def = CreateOperatorDef(); def.set_name("test"); def.set_type("Not"); def.add_input("X"); def.add_output("Y"); FillTensor(&ws, "X", {N}, {true, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Y"); EXPECT_NE(nullptr, blob); caffe2::Tensor Y(blob->Get(), caffe2::CPU); EXPECT_EQ(Y.numel(), N); std::vector result{false, true}; for (size_t i = 0; i < Y.numel(); ++i) { EXPECT_EQ(Y.template data()[i], result[i]); } } template void elementwiseEQ() { const int N = 4; const int M = 2; caffe2::Workspace ws; auto def = DefineOperator("EQ"); { // equal size FillTensor(&ws, "X", {N}, {1, 100, 5, -10}); FillTensor(&ws, "Y", {N}, {0, 100, 4, -10}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), N); std::vector result{false, true, false, true}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } { // boolean FillTensor( &ws, "X", {N}, {true, false, false, true}); FillTensor( &ws, "Y", {N}, {true, false, true, false}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), N); std::vector result{true, true, false, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } { // broadcast auto* arg = def.add_arg(); arg->set_name("broadcast"); arg->set_i(1); FillTensor( &ws, "X", {M, N}, {1, 100, 5, -10, 3, 6, -1000, 33}); FillTensor(&ws, "Y", {N}, {1, 6, -1000, -10}); std::unique_ptr op(caffe2::CreateOperator(def, &ws)); EXPECT_NE(nullptr, op.get()); EXPECT_TRUE(op->Run()); auto* blob = ws.GetBlob("Z"); EXPECT_NE(nullptr, blob); caffe2::Tensor Z(blob->Get(), caffe2::CPU); EXPECT_EQ(Z.numel(), M * N); std::vector result{ true, false, false, true, false, true, true, false}; for (size_t i = 0; i < Z.numel(); ++i) { EXPECT_EQ(Z.template data()[i], result[i]); } } } #endif // CAFFE2_OPERATORS_ELEMENTWISE_OP_TEST_H_