提交 2ed38f45 编写于 作者: M Megvii Engine Team

feat(test): add some comment and test in imperative

GitOrigin-RevId: c2363abe29d230af584604bbfb2961deba074dd1
上级 0ebd4400
......@@ -27,6 +27,11 @@ struct InterpreterImpl : Interpreter {
std::unique_ptr<Channel> create_channel() override;
};
/*!
* \brief implement Channel to execute the commands asynchronously,
* almost commands are executed by the worker threads, commands are sent
* by the interface
*/
struct ChannelImpl : Interpreter::Channel, NonCopyableObj, NonMoveableObj {
ChannelImpl();
~ChannelImpl() override;
......@@ -304,3 +309,5 @@ private:
};
} // namespace mgb::imperative::interpreter::intl
// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}
......@@ -7,6 +7,7 @@
namespace mgb::imperative::interpreter {
//! nested throw the stored exceptions
struct AsyncError : std::nested_exception, std::exception {
const char* what() const noexcept {
try {
......@@ -20,9 +21,16 @@ struct AsyncError : std::nested_exception, std::exception {
};
struct Interpreter {
/*!
* HandleImpl* just act as a key to represent TensorInfo
*/
struct HandleImpl {};
using Handle = HandleImpl*;
/*!
* \brief the base command execution interface, Channel is similar to channel in
* golang, it executes the commands put into asynchronously.
*/
struct Channel {
virtual ~Channel() = default;
......@@ -66,3 +74,5 @@ protected:
};
} // namespace mgb::imperative::interpreter
// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}
#include "megbrain/imperative/interpreter.h"
#include "../impl/interpreter/tensor_info.h"
#include "./helper.h"
#include "megbrain/comp_node_env.h"
#include "megbrain/imperative/blob_manager.h"
#include "megbrain/imperative/ops/opr_attr.h"
#include "megbrain/imperative/physical_tensor.h"
#include "megbrain/opr/basic_arith.h"
#include "megbrain/opr/basic_arith_wrapper.h"
#include "megbrain/opr/dnn/batch_norm.h"
#include "megbrain/opr/dnn/convolution.h"
#include "megbrain/opr/tensor_manip.h"
#include "megbrain/opr/utility.h"
using namespace mgb;
using namespace cg;
using namespace imperative;
using namespace interpreter;
TEST(TestImperative, InterpreterPut) {
HostTensorGenerator<> gen;
auto h0 = gen({3});
auto&& channel = Interpreter::inst().create_channel();
auto tensor_handle = channel->put(*h0, true);
auto tensor_info = reinterpret_cast<intl::TensorInfo*>(tensor_handle);
channel->sync();
ASSERT_TRUE(tensor_info->status == intl::TensorInfo::Produced);
//! because tensor elems is less than TensorShape::MAX_NDIM, stored it
//! directly
ASSERT_EQ(tensor_info->ptr->get_value().raw_ptr(), h0->raw_ptr());
auto shape = channel->get_shape(tensor_handle);
ASSERT_TRUE(shape.ndim == 1);
ASSERT_TRUE(shape.total_nr_elems() == 3);
auto h2 = gen({10});
auto tensor_handle2 = channel->put(*h2, false);
auto tensor_handle2_once = channel->put(*h2, false);
channel->sync();
ASSERT_NE(tensor_handle2_once, tensor_handle2);
auto finded = MultiCNConstTensorCache::inst().lookup(*h2);
ASSERT_TRUE(finded.get());
//! Device tensor ptr is not equal host tensor ptr
ASSERT_NE(finded->raw_ptr_not_for_readwrite(), h2->raw_ptr());
channel->del(tensor_handle);
channel->del(tensor_handle2);
channel->del(tensor_handle2_once);
}
TEST(TestImperative, InterpreterApplyOp) {
HostTensorGenerator<> gen;
size_t add = 2, dim0 = 5, dim1 = 10;
auto h0 = gen({1});
h0->ptr<float>()[0] = add;
auto h1 = gen({dim0, dim1});
for (size_t i = 0; i < dim0 * dim1; i++) {
h1->ptr<float>()[i] = i;
}
auto&& channel = Interpreter::inst().create_channel();
auto tensor_handle0 = channel->put(*h0, false);
auto tensor_handle1 = channel->put(*h1, false);
SmallVector<Interpreter::Handle> inputs{tensor_handle0, tensor_handle1};
auto op = OprAttr::make("Elemwise");
auto&& attr = op->cast_final_safe<OprAttr>();
using Param = opr::Elemwise::Param;
Param param{Param::Mode::ADD};
attr.param.write_pod(param);
auto outputs = channel->apply_op(op, inputs);
channel->sync();
auto out_tensor = reinterpret_cast<intl::TensorInfo*>(outputs[0])->ptr->get_value();
ASSERT_EQ(out_tensor.layout().ndim, 2);
ASSERT_EQ(out_tensor.shape(0), dim0);
ASSERT_EQ(out_tensor.shape(1), dim1);
float* output = out_tensor.ptr<float>();
for (size_t i = 0; i < dim0 * dim1; i++) {
ASSERT_EQ(output[i], i + add);
}
}
// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册