"...gpu/git@developer.sourcefind.cn:gaoqiong/migraphx.git" did not exist on "ebfe973572ee47a7b9f01ef1473c765d21a6541e"
Commit f9a06df3 authored by Cagri Eryilmaz's avatar Cagri Eryilmaz
Browse files

Merge branch 'develop' into unet

parents 07189c21 0b04fc80
#include "test.hpp"
int main() {} int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -3584,7 +3584,7 @@ def slice_5arg_reverse_test(): ...@@ -3584,7 +3584,7 @@ def slice_5arg_reverse_test():
outputs=['arg_axis'], outputs=['arg_axis'],
value=axis_tensor) value=axis_tensor)
end = np.array([-1, -1]) end = np.array([-5, -1])
end_tensor = helper.make_tensor(name="end", end_tensor = helper.make_tensor(name="end",
data_type=TensorProto.INT32, data_type=TensorProto.INT32,
dims=end.shape, dims=end.shape,
...@@ -3594,7 +3594,60 @@ def slice_5arg_reverse_test(): ...@@ -3594,7 +3594,60 @@ def slice_5arg_reverse_test():
outputs=['arg_end'], outputs=['arg_end'],
value=end_tensor) value=end_tensor)
start = np.array([-5, -3]) start = np.array([-1, -3])
start_tensor = helper.make_tensor(name="start",
data_type=TensorProto.INT32,
dims=start.shape,
vals=start.astype(int))
arg_start = helper.make_node("Constant",
inputs=[],
outputs=['arg_start'],
value=start_tensor)
x = helper.make_tensor_value_info('0', TensorProto.FLOAT, [5, 5])
y = helper.make_tensor_value_info('1', TensorProto.FLOAT, [4, 2])
node = onnx.helper.make_node(
'Slice',
inputs=['0', 'arg_start', 'arg_end', 'arg_axis', 'arg_step'],
outputs=['1'])
return ([arg_step, arg_axis, arg_end, arg_start, node], [x], [y])
@onnx_test
def slice_5arg_step_test():
step = np.array([-2, 2])
step_tensor = helper.make_tensor(name="step",
data_type=TensorProto.INT32,
dims=step.shape,
vals=step.astype(int))
arg_step = helper.make_node("Constant",
inputs=[],
outputs=['arg_step'],
value=step_tensor)
axis = np.array([-1, -2])
axis_tensor = helper.make_tensor(name="axis",
data_type=TensorProto.INT32,
dims=axis.shape,
vals=axis.astype(int))
arg_axis = helper.make_node("Constant",
inputs=[],
outputs=['arg_axis'],
value=axis_tensor)
end = np.array([-5, -1])
end_tensor = helper.make_tensor(name="end",
data_type=TensorProto.INT32,
dims=end.shape,
vals=end.astype(int))
arg_end = helper.make_node("Constant",
inputs=[],
outputs=['arg_end'],
value=end_tensor)
start = np.array([-1, -3])
start_tensor = helper.make_tensor(name="start", start_tensor = helper.make_tensor(name="start",
data_type=TensorProto.INT32, data_type=TensorProto.INT32,
dims=start.shape, dims=start.shape,
......
...@@ -3314,10 +3314,11 @@ TEST_CASE(slice_5arg_reverse_test) ...@@ -3314,10 +3314,11 @@ TEST_CASE(slice_5arg_reverse_test)
auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {5, 5}}); auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {5, 5}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, 1}}); mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, 1}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -2}}); mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -2}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -1}}); mm->add_literal({{migraphx::shape::int32_type, {2}}, {-5, -1}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-5, -3}}); mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -3}});
auto slice_out = mm->add_instruction( auto slice_out = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {-1, -2}}, {"starts", {0, -3}}, {"ends", {-4, -1}}}), migraphx::make_op("slice",
{{"axes", {-1, -2}}, {"starts", {-4, -3}}, {"ends", {2147483647, -1}}}),
l0); l0);
auto ret = mm->add_instruction(migraphx::make_op("reverse", {{"axes", {-1}}}), slice_out); auto ret = mm->add_instruction(migraphx::make_op("reverse", {{"axes", {-1}}}), slice_out);
mm->add_return({ret}); mm->add_return({ret});
...@@ -3327,6 +3328,30 @@ TEST_CASE(slice_5arg_reverse_test) ...@@ -3327,6 +3328,30 @@ TEST_CASE(slice_5arg_reverse_test)
EXPECT(p == prog); EXPECT(p == prog);
} }
TEST_CASE(slice_5arg_step_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {5, 5}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-2, 2}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -2}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-5, -1}});
mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -3}});
auto slice_out = mm->add_instruction(
migraphx::make_op("slice",
{{"axes", {-1, -2}}, {"starts", {-4, -3}}, {"ends", {2147483647, -1}}}),
l0);
auto reverse_out =
mm->add_instruction(migraphx::make_op("reverse", {{"axes", {-1}}}), slice_out);
auto step_out = mm->add_instruction(
migraphx::make_op("step", {{"axes", {-1, -2}}, {"steps", {2, 2}}}), reverse_out);
mm->add_return({step_out});
auto prog = migraphx::parse_onnx("slice_5arg_step_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(slice_max_end_test) TEST_CASE(slice_max_end_test)
{ {
migraphx::program p; migraphx::program p;
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
Barg_axis"Constant*, Barg_axis"Constant*,
value* *Baxis value* *Baxis
@arg_end"Constant*+ @arg_end"Constant*+
value**Bend value**Bend
D arg_start"Constant*- D arg_start"Constant*-
value*!*Bstart value*!*Bstart
5 5
0 0
arg_start arg_start
......
slice_5arg_step_test:
9arg_step"Constant*#
value** Bstep
Barg_axis"Constant*,
value* *Baxis
@arg_end"Constant*+
value**Bend
D arg_start"Constant*-
value*!*Bstart
5
0
arg_start
arg_end
arg_axis
arg_step1"Sliceslice_5arg_step_testZ
0


b
1


B
\ No newline at end of file
slice_5arg_test: slice_5arg_test:
0arg_step"Constant* 0arg_step"Constant*
value**Bstep value**Bstep
Barg_axis"Constant*, Barg_axis"Constant*,
...@@ -20,4 +20,4 @@ D arg_start"Constant*- ...@@ -20,4 +20,4 @@ D arg_start"Constant*-
1 1
 
 
B B
\ No newline at end of file \ No newline at end of file
...@@ -408,6 +408,85 @@ TEST_CASE(selu_test) ...@@ -408,6 +408,85 @@ TEST_CASE(selu_test)
EXPECT(migraphx::verify_range(result_vector, gold)); EXPECT(migraphx::verify_range(result_vector, gold));
} }
TEST_CASE(slice_test)
{
migraphx::program p = migraphx::parse_onnx("slice_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape sh_data{migraphx::shape::float_type, {3, 2}};
std::vector<float> data = {0, 1, 2, 3, 4, 5};
migraphx::parameter_map pp;
pp["0"] = migraphx::argument(sh_data, data.data());
auto result = p.eval(pp).back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> gold = {2, 3};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(slice_5arg_test)
{
migraphx::program p = migraphx::parse_onnx("slice_5arg_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape sh_data{migraphx::shape::float_type, {5, 5}}; // start
std::vector<float> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
migraphx::parameter_map pp;
pp["0"] = migraphx::argument(sh_data, data.data());
auto result = p.eval(pp).back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> gold = {10, 11, 12, 13, 15, 16, 17, 18};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(slice_reverse_test)
{
migraphx::program p = migraphx::parse_onnx("slice_5arg_reverse_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape sh_data{migraphx::shape::float_type, {5, 5}}; // start
std::vector<float> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
migraphx::parameter_map pp;
pp["0"] = migraphx::argument(sh_data, data.data());
auto result = p.eval(pp).back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> gold = {14, 13, 12, 11, 19, 18, 17, 16};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(slice_step_test)
{
migraphx::program p = migraphx::parse_onnx("slice_5arg_step_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape sh_data{migraphx::shape::float_type, {5, 5}}; // start
std::vector<float> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
migraphx::parameter_map pp;
pp["0"] = migraphx::argument(sh_data, data.data());
auto result = p.eval(pp).back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> gold = {14, 12};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(upsample_test) TEST_CASE(upsample_test)
{ {
migraphx::program p = migraphx::parse_onnx("upsample_test.onnx"); migraphx::program p = migraphx::parse_onnx("upsample_test.onnx");
......
...@@ -51,6 +51,7 @@ def disabled_tests_onnx_1_7_0(backend_test): ...@@ -51,6 +51,7 @@ def disabled_tests_onnx_1_7_0(backend_test):
def disabled_tests_onnx_1_8_1(backend_test): def disabled_tests_onnx_1_8_1(backend_test):
backend_test.exclude(r'test_if_seq_cpu')
backend_test.exclude(r'test_if_seq_cpu') backend_test.exclude(r'test_if_seq_cpu')
backend_test.exclude(r'test_reduce_sum_default_axes_keepdims_example_cpu') backend_test.exclude(r'test_reduce_sum_default_axes_keepdims_example_cpu')
backend_test.exclude(r'test_reduce_sum_default_axes_keepdims_random_cpu') backend_test.exclude(r'test_reduce_sum_default_axes_keepdims_random_cpu')
...@@ -237,6 +238,8 @@ def create_backend_test(testname=None, target_device=None): ...@@ -237,6 +238,8 @@ def create_backend_test(testname=None, target_device=None):
backend_test.exclude(r'test_lrn_cpu') backend_test.exclude(r'test_lrn_cpu')
backend_test.exclude(r'test_lrn_default_cpu') backend_test.exclude(r'test_lrn_default_cpu')
backend_test.exclude(r'test_maxpool_2d_dilations_cpu') backend_test.exclude(r'test_maxpool_2d_dilations_cpu')
backend_test.exclude(r'test_MaxPool2d_stride_padding_dilation_cpu')
backend_test.exclude(r'test_MaxPool1d_stride_padding_dilation_cpu')
backend_test.exclude( backend_test.exclude(
r'test_maxpool_with_argmax_2d_precomputed_pads_cpu') r'test_maxpool_with_argmax_2d_precomputed_pads_cpu')
backend_test.exclude( backend_test.exclude(
...@@ -267,6 +270,7 @@ def create_backend_test(testname=None, target_device=None): ...@@ -267,6 +270,7 @@ def create_backend_test(testname=None, target_device=None):
backend_test.exclude(r'test_hardsigmoid_cpu') backend_test.exclude(r'test_hardsigmoid_cpu')
backend_test.exclude(r'test_hardsigmoid_default_cpu') backend_test.exclude(r'test_hardsigmoid_default_cpu')
backend_test.exclude(r'test_hardsigmoid_example_cpu') backend_test.exclude(r'test_hardsigmoid_example_cpu')
backend_test.exclude(r'test_identity_sequence_cpu')
backend_test.exclude(r'test_maxpool_2d_uint8_cpu') backend_test.exclude(r'test_maxpool_2d_uint8_cpu')
backend_test.exclude(r'test_mean_example_cpu') backend_test.exclude(r'test_mean_example_cpu')
backend_test.exclude(r'test_mean_one_input_cpu') backend_test.exclude(r'test_mean_one_input_cpu')
......
...@@ -44,3 +44,23 @@ void auto_print::set_terminate_handler(const std::string& name) ...@@ -44,3 +44,23 @@ void auto_print::set_terminate_handler(const std::string& name)
get_handler(tname)(); get_handler(tname)();
}); });
} }
static bool in_exception()
{
#if __cplusplus >= 201703L
return std::uncaught_exceptions() > 0;
#else
return std::uncaught_exception();
#endif
}
auto_print::~auto_print()
{
if(in_exception())
{
std::cout << std::endl;
for(const auto& tname : migraphx::get_targets())
get_handler(tname)();
}
get_handler(name) = [] {};
}
...@@ -15,10 +15,7 @@ struct auto_print ...@@ -15,10 +15,7 @@ struct auto_print
get_handler(name) = [&x] { std::cout << x << std::endl; }; get_handler(name) = [&x] { std::cout << x << std::endl; };
} }
~auto_print() ~auto_print();
{
get_handler(name) = [] {};
}
}; };
#endif #endif
#include "run_verify.hpp" #include "run_verify.hpp"
#include "auto_print.hpp" #include "auto_print.hpp"
#include "verify_program.hpp" #include "verify_program.hpp"
#include "test.hpp"
#include <migraphx/env.hpp> #include <migraphx/env.hpp>
#include <migraphx/ref/target.hpp> #include <migraphx/ref/target.hpp>
#include <migraphx/ranges.hpp> #include <migraphx/ranges.hpp>
...@@ -26,7 +27,7 @@ std::future<typename std::result_of<Function()>::type> detach_async(Function&& f ...@@ -26,7 +27,7 @@ std::future<typename std::result_of<Function()>::type> detach_async(Function&& f
std::packaged_task<result_type()> task(std::forward<Function>(f)); std::packaged_task<result_type()> task(std::forward<Function>(f));
auto fut = task.get_future(); auto fut = task.get_future();
std::thread(std::move(task)).detach(); std::thread(std::move(task)).detach();
return std::move(fut); return fut;
} }
return std::async(std::launch::deferred, std::forward<Function>(f)); return std::async(std::launch::deferred, std::forward<Function>(f));
} }
...@@ -108,7 +109,7 @@ std::pair<migraphx::program, std::vector<migraphx::argument>> run_verify::run_ta ...@@ -108,7 +109,7 @@ std::pair<migraphx::program, std::vector<migraphx::argument>> run_verify::run_ta
std::transform( std::transform(
tres.begin(), tres.end(), res.begin(), [&](auto& argu) { return t.copy_from(argu); }); tres.begin(), tres.end(), res.begin(), [&](auto& argu) { return t.copy_from(argu); });
return std::make_pair(p, res); return std::make_pair(std::move(p), res);
} }
template <class T> template <class T>
...@@ -121,7 +122,6 @@ void run_verify::verify(const std::string& name, const migraphx::program& p) con ...@@ -121,7 +122,6 @@ void run_verify::verify(const std::string& name, const migraphx::program& p) con
{ {
using result_future = using result_future =
std::future<std::pair<migraphx::program, std::vector<migraphx::argument>>>; std::future<std::pair<migraphx::program, std::vector<migraphx::argument>>>;
std::cout << "[ RUN ] " << name << std::endl;
auto_print::set_terminate_handler(name); auto_print::set_terminate_handler(name);
std::vector<std::pair<std::string, result_future>> results; std::vector<std::pair<std::string, result_future>> results;
std::vector<std::string> target_names; std::vector<std::string> target_names;
...@@ -180,25 +180,27 @@ void run_verify::verify(const std::string& name, const migraphx::program& p) con ...@@ -180,25 +180,27 @@ void run_verify::verify(const std::string& name, const migraphx::program& p) con
std::cout << tname << ":\n" << cp << std::endl; std::cout << tname << ":\n" << cp << std::endl;
std::cout << std::endl; std::cout << std::endl;
} }
EXPECT(passed);
} }
} }
std::set_terminate(nullptr); std::set_terminate(nullptr);
std::cout << "[ COMPLETE ] " << name << std::endl;
} }
void run_verify::run(int argc, const char* argv[]) const void run_verify::run(int argc, const char* argv[]) const
{ {
std::set<std::string> args(argv + 1, argv + argc); std::unordered_map<std::string, std::vector<std::string>> labels;
const auto& ps = get_programs(); for(auto&& p : get_programs())
for(auto&& p : ps)
{ {
if(not args.empty()) labels[p.section].push_back(p.name);
{ test::add_test_case(p.name, [=] { verify(p.name, p.get_program()); });
if(args.count(p.name) == 0 and args.count(p.section) == 0)
continue;
}
verify(p.name, p.get_program());
} }
test::driver d{};
d.get_case_names = [&](const std::string& name) -> std::vector<std::string> {
if(labels.count(name) > 0)
return labels.at(name);
return {name};
};
d.run(argc, argv);
} }
void run_verify::disable_parallel_for(const std::string& name) { info[name].parallel = false; } void run_verify::disable_parallel_for(const std::string& name) { info[name].parallel = false; }
......
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/make_op.hpp>
struct test_prefix_scan_sum_2d_small : verify_program<test_prefix_scan_sum_2d_small>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::float_type, {3, 3}};
auto x = mm->add_parameter("x", s);
mm->add_instruction(
migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), x);
return p;
}
};
struct test_prefix_scan_sum_2d_large : verify_program<test_prefix_scan_sum_2d_large>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::float_type, {3, 1000}};
auto x = mm->add_parameter("x", s);
mm->add_instruction(
migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), x);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/make_op.hpp>
struct test_slice_reverse : verify_program<test_slice_reverse>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::int32_type, {3, 5}};
auto x = mm->add_parameter("x", s);
auto slice_out = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0, 1}}, {"starts", {0, 2}}, {"ends", {2, -1}}}),
x);
mm->add_instruction(migraphx::make_op("reverse", {{"axes", {0}}}), slice_out);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/make_op.hpp>
struct test_slice_reverse_step : verify_program<test_slice_reverse_step>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::int32_type, {7, 5}};
auto x = mm->add_parameter("x", s);
auto slice_out = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0, 1}}, {"starts", {0, 2}}, {"ends", {2, -1}}}),
x);
auto step_out =
mm->add_instruction(migraphx::make_op("reverse", {{"axes", {0, 1}}}), slice_out);
mm->add_instruction(migraphx::make_op("step", {{"axes", {0, 1}}, {"steps", {2, 2}}}),
step_out);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/make_op.hpp>
struct test_slice_step_reverse : verify_program<test_slice_step_reverse>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::int32_type, {7, 5}};
auto x = mm->add_parameter("x", s);
auto slice_out = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0, 1}}, {"starts", {0, 2}}, {"ends", {2, -1}}}),
x);
auto step_out = mm->add_instruction(
migraphx::make_op("step", {{"axes", {0, 1}}, {"steps", {2, 2}}}), slice_out);
mm->add_instruction(migraphx::make_op("reverse", {{"axes", {0}}}), step_out);
return p;
}
};
...@@ -26,6 +26,8 @@ struct allocation_model ...@@ -26,6 +26,8 @@ struct allocation_model
std::string copy() const; std::string copy() const;
/// Create an allocation operator for the given shape /// Create an allocation operator for the given shape
operation allocate(const shape& s) const; operation allocate(const shape& s) const;
/// Create a preallocated operator for the given shape
operation preallocate(const shape& s, const std::string& id) const;
}; };
#else #else
...@@ -34,7 +36,8 @@ struct allocation_model ...@@ -34,7 +36,8 @@ struct allocation_model
interface('allocation_model', interface('allocation_model',
virtual('name', returns='std::string', const=True), virtual('name', returns='std::string', const=True),
virtual('copy', returns='std::string', const=True), virtual('copy', returns='std::string', const=True),
virtual('allocate', s='const shape&', returns='operation', const=True) virtual('allocate', s='const shape&', returns='operation', const=True),
virtual('preallocate', s='const shape&', id='std::string', returns='operation', const=True)
) )
%> %>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <migraphx/module_ref.hpp> #include <migraphx/module_ref.hpp>
#include <migraphx/serialize.hpp> #include <migraphx/serialize.hpp>
#include <migraphx/auto_any_cast.hpp> #include <migraphx/auto_any_cast.hpp>
#include <migraphx/lifetime.hpp>
#include <migraphx/config.hpp> #include <migraphx/config.hpp>
namespace migraphx { namespace migraphx {
...@@ -435,9 +436,9 @@ void from_value_op(T& x, const value& v) ...@@ -435,9 +436,9 @@ void from_value_op(T& x, const value& v)
} }
template <class T> template <class T>
bool is_borrowed_op(const T&) lifetime get_lifetime_op(const T&)
{ {
return false; return lifetime::local;
} }
} // namespace detail } // namespace detail
...@@ -453,7 +454,8 @@ bool is_borrowed_op(const T&) ...@@ -453,7 +454,8 @@ bool is_borrowed_op(const T&)
const = True, const = True,
default = 'detail::need_normalization_op'), default = 'detail::need_normalization_op'),
virtual('has_finalize', returns = 'bool', const = True, default = 'detail::has_finalize_op'), virtual('has_finalize', returns = 'bool', const = True, default = 'detail::has_finalize_op'),
virtual('is_borrowed', returns = 'bool', const = True, default = 'detail::is_borrowed_op'), virtual(
'get_lifetime', returns = 'lifetime', const = True, default = 'detail::get_lifetime_op'),
virtual('output_alias', virtual('output_alias',
returns = 'std::ptrdiff_t', returns = 'std::ptrdiff_t',
input = 'const std::vector<shape>&', input = 'const std::vector<shape>&',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment