[PT FE]: support aten::log, aten::log2 (#15184)

This commit is contained in:
Ekaterina Aidova 2023-01-21 00:42:49 +04:00 committed by GitHub
parent 8f8e79bb15
commit 595d447f2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 93 additions and 0 deletions

View File

@ -0,0 +1,39 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "openvino/op/log.hpp"
#include "openvino/frontend/pytorch/node_context.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/convert.hpp"
#include "openvino/op/divide.hpp"
namespace ov {
namespace frontend {
namespace pytorch {
namespace op {
OutputVector translate_log(NodeContext& context) {
// torch.log returns a tensor with the natural logarithm of the elements of input.
auto x = context.get_input(0);
x = context.mark_node(std::make_shared<ov::op::v0::Convert>(x, element::f32));
auto log = context.mark_node(std::make_shared<ov::op::v0::Log>(x));
return {log};
};
OutputVector translate_log2(NodeContext& context) {
// torch.log2 returns a tensor with the logarithm to the base 2 of the elements of input.
auto x = context.get_input(0);
auto two = context.mark_node(ov::op::v0::Constant::create(element::f32, Shape{}, {2}));
x = context.mark_node(std::make_shared<ov::op::v0::Convert>(x, element::f32));
auto log2 = context.mark_node(std::make_shared<ov::op::v0::Log>(two));
auto log = context.mark_node(std::make_shared<ov::op::v0::Log>(x));
auto res = context.mark_node(std::make_shared<ov::op::v1::Divide>(log, log2));
return {res};
};
} // namespace op
} // namespace pytorch
} // namespace frontend
} // namespace ov

View File

@ -50,6 +50,8 @@ OP_CONVERTER(translate_layer_norm);
OP_CONVERTER(translate_len);
OP_CONVERTER(translate_linear);
OP_CONVERTER(translate_list_construct);
OP_CONVERTER(translate_log);
OP_CONVERTER(translate_log2);
OP_CONVERTER(translate_loop);
OP_CONVERTER(translate_max_poolnd);
OP_CONVERTER(translate_max);
@ -184,6 +186,10 @@ const std::map<std::string, CreatorFunction> get_supported_ops() {
{"aten::linear", op::translate_linear},
{"aten::le", op::translate_1to1_match_2_inputs<opset10::LessEqual>},
{"aten::lt", op::translate_1to1_match_2_inputs<opset10::Less>},
{"aten::log", op::translate_log},
{"aten::log_", op::inplace_op<op::translate_log>},
{"aten::log2", op::translate_log2},
{"aten::log2_", op::inplace_op<op::translate_log2>},
{"aten::matmul", op::translate_1to1_match_2_inputs<opset10::MatMul>},
{"aten::masked_fill", op::translate_masked_fill},
{"aten::masked_fill_", op::inplace_op<op::translate_masked_fill>},

View File

@ -0,0 +1,48 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytorch_layer_test_class import PytorchLayerTest
class TestLog(PytorchLayerTest):
def _prepare_input(self, dtype):
import numpy as np
return (np.random.uniform(2, 16, (1, 10)).astype(dtype),)
def create_model(self, op):
import torch
ops = {
"log": torch.log,
"log_": torch.log_,
"log2": torch.log2,
"log2_": torch.log2_
}
op_fn = ops[op]
class aten_log(torch.nn.Module):
def __init__(self, op):
super(aten_log, self).__init__()
self.op = op
def forward(self, x):
return self.op(x)
ref_net = None
return aten_log(op_fn), ref_net, f"aten::{op}"
@pytest.mark.nightly
@pytest.mark.precomit
@pytest.mark.parametrize(("op", "input_dtype"),
[["log", "float32"],
["log", "int32"],
["log_", "float32"],
["log2", "float32"],
["log2", "int32"],
["log2_", "float32"]])
def test_log(self, op, input_dtype, ie_device, precision, ir_version):
self._test(*self.create_model(op), ie_device, precision,
ir_version, kwargs_to_prepare_input={"dtype": input_dtype})