Signed-off-by: alex-yuyue <yue.yu1@huawei.com>pull/14579/head
| @@ -18,91 +18,22 @@ | |||||
| #include "pybind11/stl_bind.h" | #include "pybind11/stl_bind.h" | ||||
| #include "minddata/dataset/api/python/pybind_register.h" | #include "minddata/dataset/api/python/pybind_register.h" | ||||
| #include "minddata/dataset/core/tensor_helpers.h" | |||||
| #include "minddata/dataset/kernels/data/concatenate_op.h" | |||||
| #include "minddata/dataset/kernels/data/fill_op.h" | #include "minddata/dataset/kernels/data/fill_op.h" | ||||
| #include "minddata/dataset/kernels/data/mask_op.h" | |||||
| #include "minddata/dataset/kernels/data/pad_end_op.h" | |||||
| #include "minddata/dataset/kernels/data/slice_op.h" | |||||
| #include "minddata/dataset/kernels/data/to_float16_op.h" | #include "minddata/dataset/kernels/data/to_float16_op.h" | ||||
| namespace mindspore { | namespace mindspore { | ||||
| namespace dataset { | namespace dataset { | ||||
| PYBIND_REGISTER(ConcatenateOp, 1, ([](const py::module *m) { | |||||
| (void)py::class_<ConcatenateOp, TensorOp, std::shared_ptr<ConcatenateOp>>(*m, "ConcatenateOp") | |||||
| .def(py::init<int8_t, std::shared_ptr<Tensor>, std::shared_ptr<Tensor>>()); | |||||
| })); | |||||
| PYBIND_REGISTER( | PYBIND_REGISTER( | ||||
| FillOp, 1, ([](const py::module *m) { | FillOp, 1, ([](const py::module *m) { | ||||
| (void)py::class_<FillOp, TensorOp, std::shared_ptr<FillOp>>(*m, "FillOp").def(py::init<std::shared_ptr<Tensor>>()); | (void)py::class_<FillOp, TensorOp, std::shared_ptr<FillOp>>(*m, "FillOp").def(py::init<std::shared_ptr<Tensor>>()); | ||||
| })); | })); | ||||
| PYBIND_REGISTER(MaskOp, 1, ([](const py::module *m) { | |||||
| (void)py::class_<MaskOp, TensorOp, std::shared_ptr<MaskOp>>(*m, "MaskOp") | |||||
| .def(py::init<RelationalOp, std::shared_ptr<Tensor>, DataType>()); | |||||
| })); | |||||
| PYBIND_REGISTER(PadEndOp, 1, ([](const py::module *m) { | |||||
| (void)py::class_<PadEndOp, TensorOp, std::shared_ptr<PadEndOp>>(*m, "PadEndOp") | |||||
| .def(py::init<TensorShape, std::shared_ptr<Tensor>>()); | |||||
| })); | |||||
| PYBIND_REGISTER(SliceOption, 0, ([](const py::module *m) { | |||||
| (void)py::class_<SliceOption>(*m, "SliceOption") | |||||
| .def(py::init([](const py::slice &py_slice) { | |||||
| Slice c_slice; | |||||
| if (!py_slice.attr("start").is_none() && !py_slice.attr("stop").is_none() && | |||||
| !py_slice.attr("step").is_none()) { | |||||
| c_slice = Slice(py::reinterpret_borrow<py::int_>(py_slice.attr("start")), | |||||
| py::reinterpret_borrow<py::int_>(py_slice.attr("stop")), | |||||
| py::reinterpret_borrow<py::int_>(py_slice.attr("step"))); | |||||
| } else if (py_slice.attr("start").is_none() && py_slice.attr("step").is_none()) { | |||||
| c_slice = Slice(py::reinterpret_borrow<py::int_>(py_slice.attr("stop"))); | |||||
| } else if (!py_slice.attr("start").is_none() && !py_slice.attr("stop").is_none()) { | |||||
| c_slice = Slice(py::reinterpret_borrow<py::int_>(py_slice.attr("start")), | |||||
| py::reinterpret_borrow<py::int_>(py_slice.attr("stop"))); | |||||
| } | |||||
| if (!c_slice.valid()) { | |||||
| THROW_IF_ERROR( | |||||
| Status(StatusCode::kMDUnexpectedError, __LINE__, __FILE__, "Wrong slice object")); | |||||
| } | |||||
| return SliceOption(c_slice); | |||||
| })) | |||||
| .def(py::init([](const py::list &py_list) { | |||||
| std::vector<dsize_t> indices; | |||||
| for (auto l : py_list) { | |||||
| indices.push_back(py::reinterpret_borrow<py::int_>(l)); | |||||
| } | |||||
| return SliceOption(indices); | |||||
| })) | |||||
| .def(py::init<bool>()) | |||||
| .def(py::init<SliceOption>()); | |||||
| })); | |||||
| PYBIND_REGISTER(SliceOp, 1, ([](const py::module *m) { | |||||
| (void)py::class_<SliceOp, TensorOp, std::shared_ptr<SliceOp>>(*m, "SliceOp") | |||||
| .def(py::init<std::vector<SliceOption>>()); | |||||
| })); | |||||
| PYBIND_REGISTER(ToFloat16Op, 1, ([](const py::module *m) { | PYBIND_REGISTER(ToFloat16Op, 1, ([](const py::module *m) { | ||||
| (void)py::class_<ToFloat16Op, TensorOp, std::shared_ptr<ToFloat16Op>>(*m, "ToFloat16Op", | (void)py::class_<ToFloat16Op, TensorOp, std::shared_ptr<ToFloat16Op>>(*m, "ToFloat16Op", | ||||
| py::dynamic_attr()) | py::dynamic_attr()) | ||||
| .def(py::init<>()); | .def(py::init<>()); | ||||
| })); | })); | ||||
| PYBIND_REGISTER(RelationalOp, 0, ([](const py::module *m) { | |||||
| (void)py::enum_<RelationalOp>(*m, "RelationalOp", py::arithmetic()) | |||||
| .value("EQ", RelationalOp::kEqual) | |||||
| .value("NE", RelationalOp::kNotEqual) | |||||
| .value("LT", RelationalOp::kLess) | |||||
| .value("LE", RelationalOp::kLessEqual) | |||||
| .value("GT", RelationalOp::kGreater) | |||||
| .value("GE", RelationalOp::kGreaterEqual) | |||||
| .export_values(); | |||||
| })); | |||||
| } // namespace dataset | } // namespace dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -15,6 +15,7 @@ | |||||
| */ | */ | ||||
| #include "pybind11/pybind11.h" | #include "pybind11/pybind11.h" | ||||
| #include "mindspore/ccsrc/minddata/dataset/include/transforms.h" | |||||
| #include "minddata/dataset/api/python/pybind_register.h" | #include "minddata/dataset/api/python/pybind_register.h" | ||||
| #include "minddata/dataset/core/global_context.h" | #include "minddata/dataset/core/global_context.h" | ||||
| @@ -64,6 +65,16 @@ PYBIND_REGISTER( | |||||
| })); | })); | ||||
| })); | })); | ||||
| PYBIND_REGISTER(ConcatenateOperation, 1, ([](const py::module *m) { | |||||
| (void)py::class_<transforms::ConcatenateOperation, TensorOperation, | |||||
| std::shared_ptr<transforms::ConcatenateOperation>>(*m, "ConcatenateOperation") | |||||
| .def(py::init([](int8_t axis, std::shared_ptr<Tensor> prepend, std::shared_ptr<Tensor> append) { | |||||
| auto concatenate = std::make_shared<transforms::ConcatenateOperation>(axis, prepend, append); | |||||
| THROW_IF_ERROR(concatenate->ValidateParams()); | |||||
| return concatenate; | |||||
| })); | |||||
| })); | |||||
| PYBIND_REGISTER( | PYBIND_REGISTER( | ||||
| DuplicateOperation, 1, ([](const py::module *m) { | DuplicateOperation, 1, ([](const py::module *m) { | ||||
| (void)py::class_<transforms::DuplicateOperation, TensorOperation, std::shared_ptr<transforms::DuplicateOperation>>( | (void)py::class_<transforms::DuplicateOperation, TensorOperation, std::shared_ptr<transforms::DuplicateOperation>>( | ||||
| @@ -75,6 +86,17 @@ PYBIND_REGISTER( | |||||
| })); | })); | ||||
| })); | })); | ||||
| PYBIND_REGISTER(MaskOperation, 1, ([](const py::module *m) { | |||||
| (void) | |||||
| py::class_<transforms::MaskOperation, TensorOperation, std::shared_ptr<transforms::MaskOperation>>( | |||||
| *m, "MaskOperation") | |||||
| .def(py::init([](RelationalOp op, std::shared_ptr<Tensor> constant, DataType dtype) { | |||||
| auto mask = std::make_shared<transforms::MaskOperation>(op, constant, dtype); | |||||
| THROW_IF_ERROR(mask->ValidateParams()); | |||||
| return mask; | |||||
| })); | |||||
| })); | |||||
| PYBIND_REGISTER( | PYBIND_REGISTER( | ||||
| OneHotOperation, 1, ([](const py::module *m) { | OneHotOperation, 1, ([](const py::module *m) { | ||||
| (void)py::class_<transforms::OneHotOperation, TensorOperation, std::shared_ptr<transforms::OneHotOperation>>( | (void)py::class_<transforms::OneHotOperation, TensorOperation, std::shared_ptr<transforms::OneHotOperation>>( | ||||
| @@ -86,6 +108,17 @@ PYBIND_REGISTER( | |||||
| })); | })); | ||||
| })); | })); | ||||
| PYBIND_REGISTER( | |||||
| PadEndOperation, 1, ([](const py::module *m) { | |||||
| (void)py::class_<transforms::PadEndOperation, TensorOperation, std::shared_ptr<transforms::PadEndOperation>>( | |||||
| *m, "PadEndOperation") | |||||
| .def(py::init([](TensorShape pad_shape, std::shared_ptr<Tensor> pad_value) { | |||||
| auto pad_end = std::make_shared<transforms::PadEndOperation>(pad_shape, pad_value); | |||||
| THROW_IF_ERROR(pad_end->ValidateParams()); | |||||
| return pad_end; | |||||
| })); | |||||
| })); | |||||
| PYBIND_REGISTER(RandomChoiceOperation, 1, ([](const py::module *m) { | PYBIND_REGISTER(RandomChoiceOperation, 1, ([](const py::module *m) { | ||||
| (void)py::class_<transforms::RandomChoiceOperation, TensorOperation, | (void)py::class_<transforms::RandomChoiceOperation, TensorOperation, | ||||
| std::shared_ptr<transforms::RandomChoiceOperation>>(*m, "RandomChoiceOperation") | std::shared_ptr<transforms::RandomChoiceOperation>>(*m, "RandomChoiceOperation") | ||||
| @@ -110,6 +143,50 @@ PYBIND_REGISTER(RandomApplyOperation, 1, ([](const py::module *m) { | |||||
| })); | })); | ||||
| })); | })); | ||||
| PYBIND_REGISTER( | |||||
| SliceOperation, 1, ([](const py::module *m) { | |||||
| (void)py::class_<transforms::SliceOperation, TensorOperation, std::shared_ptr<transforms::SliceOperation>>( | |||||
| *m, "SliceOperation") | |||||
| .def(py::init([](std::vector<SliceOption> slice_input) { | |||||
| auto slice = std::make_shared<transforms::SliceOperation>(slice_input); | |||||
| THROW_IF_ERROR(slice->ValidateParams()); | |||||
| return slice; | |||||
| })); | |||||
| })); | |||||
| PYBIND_REGISTER(SliceOption, 0, ([](const py::module *m) { | |||||
| (void)py::class_<SliceOption>(*m, "SliceOption") | |||||
| .def(py::init([](const py::slice &py_slice) { | |||||
| Slice c_slice; | |||||
| if (!py_slice.attr("start").is_none() && !py_slice.attr("stop").is_none() && | |||||
| !py_slice.attr("step").is_none()) { | |||||
| c_slice = Slice(py::reinterpret_borrow<py::int_>(py_slice.attr("start")), | |||||
| py::reinterpret_borrow<py::int_>(py_slice.attr("stop")), | |||||
| py::reinterpret_borrow<py::int_>(py_slice.attr("step"))); | |||||
| } else if (py_slice.attr("start").is_none() && py_slice.attr("step").is_none()) { | |||||
| c_slice = Slice(py::reinterpret_borrow<py::int_>(py_slice.attr("stop"))); | |||||
| } else if (!py_slice.attr("start").is_none() && !py_slice.attr("stop").is_none()) { | |||||
| c_slice = Slice(py::reinterpret_borrow<py::int_>(py_slice.attr("start")), | |||||
| py::reinterpret_borrow<py::int_>(py_slice.attr("stop"))); | |||||
| } | |||||
| if (!c_slice.valid()) { | |||||
| THROW_IF_ERROR( | |||||
| Status(StatusCode::kMDUnexpectedError, __LINE__, __FILE__, "Wrong slice object")); | |||||
| } | |||||
| return SliceOption(c_slice); | |||||
| })) | |||||
| .def(py::init([](const py::list &py_list) { | |||||
| std::vector<dsize_t> indices; | |||||
| for (auto l : py_list) { | |||||
| indices.push_back(py::reinterpret_borrow<py::int_>(l)); | |||||
| } | |||||
| return SliceOption(indices); | |||||
| })) | |||||
| .def(py::init<bool>()) | |||||
| .def(py::init<SliceOption>()); | |||||
| })); | |||||
| PYBIND_REGISTER( | PYBIND_REGISTER( | ||||
| TypeCastOperation, 1, ([](const py::module *m) { | TypeCastOperation, 1, ([](const py::module *m) { | ||||
| (void)py::class_<transforms::TypeCastOperation, TensorOperation, std::shared_ptr<transforms::TypeCastOperation>>( | (void)py::class_<transforms::TypeCastOperation, TensorOperation, std::shared_ptr<transforms::TypeCastOperation>>( | ||||
| @@ -132,5 +209,16 @@ PYBIND_REGISTER( | |||||
| })); | })); | ||||
| })); | })); | ||||
| PYBIND_REGISTER(RelationalOp, 0, ([](const py::module *m) { | |||||
| (void)py::enum_<RelationalOp>(*m, "RelationalOp", py::arithmetic()) | |||||
| .value("EQ", RelationalOp::kEqual) | |||||
| .value("NE", RelationalOp::kNotEqual) | |||||
| .value("LT", RelationalOp::kLess) | |||||
| .value("LE", RelationalOp::kLessEqual) | |||||
| .value("GT", RelationalOp::kGreater) | |||||
| .value("GE", RelationalOp::kGreaterEqual) | |||||
| .export_values(); | |||||
| })); | |||||
| } // namespace dataset | } // namespace dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -18,6 +18,7 @@ | |||||
| #include <algorithm> | #include <algorithm> | ||||
| #include "mindspore/ccsrc/minddata/dataset/core/type_id.h" | |||||
| #include "minddata/dataset/kernels/ir/data/transforms_ir.h" | #include "minddata/dataset/kernels/ir/data/transforms_ir.h" | ||||
| namespace mindspore { | namespace mindspore { | ||||
| @@ -56,11 +57,52 @@ Compose::Compose(const std::vector<std::reference_wrapper<TensorTransform>> &tra | |||||
| std::shared_ptr<TensorOperation> Compose::Parse() { return std::make_shared<ComposeOperation>(data_->transforms_); } | std::shared_ptr<TensorOperation> Compose::Parse() { return std::make_shared<ComposeOperation>(data_->transforms_); } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // Constructor to Concatenate | |||||
| struct Concatenate::Data { | |||||
| explicit Data(int8_t axis, MSTensor prepend, MSTensor append) : axis_(axis), prepend_(prepend), append_(append) {} | |||||
| int8_t axis_; | |||||
| MSTensor prepend_; | |||||
| MSTensor append_; | |||||
| }; | |||||
| Concatenate::Concatenate(int8_t axis, MSTensor prepend, MSTensor append) | |||||
| : data_(std::make_shared<Data>(axis, prepend, append)) {} | |||||
| std::shared_ptr<TensorOperation> Concatenate::Parse() { | |||||
| std::shared_ptr<Tensor> out_prepend, out_append; | |||||
| Tensor::CreateFromMSTensor(data_->prepend_, &out_prepend); | |||||
| Tensor::CreateFromMSTensor(data_->append_, &out_append); | |||||
| return std::make_shared<ConcatenateOperation>(data_->axis_, out_prepend, out_append); | |||||
| } | |||||
| #endif // not ENABLE_ANDROID | |||||
| // Constructor to Duplicate | // Constructor to Duplicate | ||||
| Duplicate::Duplicate() {} | Duplicate::Duplicate() {} | ||||
| std::shared_ptr<TensorOperation> Duplicate::Parse() { return std::make_shared<DuplicateOperation>(); } | std::shared_ptr<TensorOperation> Duplicate::Parse() { return std::make_shared<DuplicateOperation>(); } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // Constructor to Mask | |||||
| struct Mask::Data { | |||||
| explicit Data(RelationalOp op, MSTensor constant, mindspore::DataType ms_type) | |||||
| : op_(op), constant_(constant), ms_type_(ms_type) {} | |||||
| RelationalOp op_; | |||||
| MSTensor constant_; | |||||
| mindspore::DataType ms_type_; | |||||
| }; | |||||
| Mask::Mask(RelationalOp op, MSTensor constant, mindspore::DataType ms_type) | |||||
| : data_(std::make_shared<Data>(op, constant, ms_type)) {} | |||||
| std::shared_ptr<TensorOperation> Mask::Parse() { | |||||
| std::shared_ptr<Tensor> out_constant; | |||||
| Tensor::CreateFromMSTensor(data_->constant_, &out_constant); | |||||
| DataType de_type = dataset::MSTypeToDEType(static_cast<TypeId>(data_->ms_type_)); | |||||
| return std::make_shared<MaskOperation>(data_->op_, out_constant, de_type); | |||||
| } | |||||
| #endif // not ENABLE_ANDROID | |||||
| // Constructor to OneHot | // Constructor to OneHot | ||||
| struct OneHot::Data { | struct OneHot::Data { | ||||
| explicit Data(int32_t num_classes) : num_classes_(num_classes) {} | explicit Data(int32_t num_classes) : num_classes_(num_classes) {} | ||||
| @@ -71,6 +113,25 @@ OneHot::OneHot(int32_t num_classes) : data_(std::make_shared<Data>(num_classes)) | |||||
| std::shared_ptr<TensorOperation> OneHot::Parse() { return std::make_shared<OneHotOperation>(data_->num_classes_); } | std::shared_ptr<TensorOperation> OneHot::Parse() { return std::make_shared<OneHotOperation>(data_->num_classes_); } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // Constructor to PadEnd | |||||
| struct PadEnd::Data { | |||||
| explicit Data(const std::vector<dsize_t> &pad_shape, MSTensor pad_value) | |||||
| : pad_shape_(pad_shape), pad_value_(pad_value) {} | |||||
| std::vector<dsize_t> pad_shape_; | |||||
| MSTensor pad_value_; | |||||
| }; | |||||
| PadEnd::PadEnd(const std::vector<dsize_t> &pad_shape, MSTensor pad_value) | |||||
| : data_(std::make_shared<Data>(pad_shape, pad_value)) {} | |||||
| std::shared_ptr<TensorOperation> PadEnd::Parse() { | |||||
| std::shared_ptr<Tensor> pad_value; | |||||
| Tensor::CreateFromMSTensor(data_->pad_value_, &pad_value); | |||||
| return std::make_shared<PadEndOperation>(TensorShape(data_->pad_shape_), pad_value); | |||||
| } | |||||
| #endif // not ENABLE_ANDROID | |||||
| // Constructor to RandomApply. | // Constructor to RandomApply. | ||||
| struct RandomApply::Data { | struct RandomApply::Data { | ||||
| std::vector<std::shared_ptr<TensorOperation>> transforms_; | std::vector<std::shared_ptr<TensorOperation>> transforms_; | ||||
| @@ -136,6 +197,18 @@ std::shared_ptr<TensorOperation> RandomChoice::Parse() { | |||||
| return std::make_shared<RandomChoiceOperation>(data_->transforms_); | return std::make_shared<RandomChoiceOperation>(data_->transforms_); | ||||
| } | } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // Constructor to Slice | |||||
| struct Slice::Data { | |||||
| explicit Data(const std::vector<SliceOption> &slice_input) : slice_input_(slice_input) {} | |||||
| std::vector<SliceOption> slice_input_; | |||||
| }; | |||||
| Slice::Slice(const std::vector<SliceOption> &slice_input) : data_(std::make_shared<Data>(slice_input)) {} | |||||
| std::shared_ptr<TensorOperation> Slice::Parse() { return std::make_shared<SliceOperation>(data_->slice_input_); } | |||||
| #endif // not ENABLE_ANDROID | |||||
| // Constructor to TypeCast | // Constructor to TypeCast | ||||
| struct TypeCast::Data { | struct TypeCast::Data { | ||||
| explicit Data(const std::vector<char> &data_type) : data_type_(CharToString(data_type)) {} | explicit Data(const std::vector<char> &data_type) : data_type_(CharToString(data_type)) {} | ||||
| @@ -19,43 +19,11 @@ | |||||
| #include <memory> | #include <memory> | ||||
| #include <vector> | #include <vector> | ||||
| #include "mindspore/ccsrc/minddata/dataset/include/transforms.h" | |||||
| #include "minddata/dataset/include/constants.h" | #include "minddata/dataset/include/constants.h" | ||||
| namespace mindspore { | namespace mindspore { | ||||
| namespace dataset { | namespace dataset { | ||||
| class Slice { | |||||
| public: | |||||
| Slice() : start_(0), stop_(0), step_(0) {} | |||||
| Slice(dsize_t start, dsize_t stop, dsize_t step) : start_(start), stop_(stop), step_(step) {} | |||||
| Slice(dsize_t start, dsize_t stop) : start_(start), stop_(stop), step_(1) {} | |||||
| explicit Slice(dsize_t stop) : start_(0), stop_(stop), step_(1) {} | |||||
| Slice(Slice const &slice) = default; | |||||
| ~Slice() = default; | |||||
| bool valid() const { return step_ != 0; } | |||||
| dsize_t start_; | |||||
| dsize_t stop_; | |||||
| dsize_t step_; | |||||
| }; | |||||
| class SliceOption { | |||||
| public: | |||||
| explicit SliceOption(bool all) : all_(all) {} | |||||
| explicit SliceOption(std::vector<dsize_t> indices) : indices_(indices) {} | |||||
| explicit SliceOption(Slice slice) : slice_(slice) {} | |||||
| SliceOption(SliceOption const &slice) = default; | |||||
| ~SliceOption() = default; | |||||
| // only one of the following will be valid | |||||
| // given indices to slice the Tensor. | |||||
| std::vector<dsize_t> indices_ = {}; | |||||
| // Slice object. All start, stop and step are 0 if invalid. | |||||
| Slice slice_; | |||||
| bool all_ = false; | |||||
| }; | |||||
| /// Recursive helper function to generate indices based on vector of SliceOptions. It recursively iterates through each | /// Recursive helper function to generate indices based on vector of SliceOptions. It recursively iterates through each | ||||
| /// range represented by slice_options to generate a list of indices to be sliced. | /// range represented by slice_options to generate a list of indices to be sliced. | ||||
| /// \param[out] matrix Generated nested vector of indices | /// \param[out] matrix Generated nested vector of indices | ||||
| @@ -71,6 +71,16 @@ enum class NormalizeForm { | |||||
| kNfkd, | kNfkd, | ||||
| }; | }; | ||||
| // Possible values for Mask | |||||
| enum class RelationalOp { | |||||
| kEqual = 0, // == | |||||
| kNotEqual, // != | |||||
| kLess, // < | |||||
| kLessEqual, // <= | |||||
| kGreater, // > | |||||
| kGreaterEqual, // >= | |||||
| }; | |||||
| // Possible values for SamplingStrategy | // Possible values for SamplingStrategy | ||||
| enum class SamplingStrategy { kRandom = 0, kEdgeWeight = 1 }; | enum class SamplingStrategy { kRandom = 0, kEdgeWeight = 1 }; | ||||
| @@ -75,6 +75,54 @@ class TensorTransform : public std::enable_shared_from_this<TensorTransform> { | |||||
| virtual std::shared_ptr<TensorOperation> Parse(const MapTargetDevice &env) { return nullptr; } | virtual std::shared_ptr<TensorOperation> Parse(const MapTargetDevice &env) { return nullptr; } | ||||
| }; | }; | ||||
| /// \brief Slice object used in SliceOption. | |||||
| class Slice { | |||||
| public: | |||||
| /// \brief Constructor, with start, stop and step default to 0. | |||||
| Slice() : start_(0), stop_(0), step_(0) {} | |||||
| /// \brief Constructor. | |||||
| /// \param[in] start Starting integer specifying where to start the slicing. | |||||
| /// \param[in] stop Ending integer specifying where to stop the slicing. | |||||
| /// \param[in] step An integer specifying the step of the slicing. | |||||
| Slice(dsize_t start, dsize_t stop, dsize_t step) : start_(start), stop_(stop), step_(step) {} | |||||
| /// \brief Constructor, with step=1 | |||||
| /// \param[in] start Starting integer specifying where to start the slicing. | |||||
| /// \param[in] stop Ending integer specifying where to stop the slicing. | |||||
| Slice(dsize_t start, dsize_t stop) : start_(start), stop_(stop), step_(1) {} | |||||
| /// \brief Constructor, with start=0 and step=1 | |||||
| /// \param[in] stop Ending integer specifying where to stop the slicing. | |||||
| explicit Slice(dsize_t stop) : start_(0), stop_(stop), step_(1) {} | |||||
| Slice(Slice const &slice) = default; | |||||
| ~Slice() = default; | |||||
| bool valid() const { return step_ != 0; } | |||||
| dsize_t start_; | |||||
| dsize_t stop_; | |||||
| dsize_t step_; | |||||
| }; | |||||
| /// \brief SliceOption used in Slice Op. | |||||
| class SliceOption { | |||||
| public: | |||||
| /// \param[in] all Slice the whole dimension | |||||
| explicit SliceOption(bool all) : all_(all) {} | |||||
| /// \param[in] indices Slice these indices along the dimension. Negative indices are supported. | |||||
| explicit SliceOption(std::vector<dsize_t> indices) : indices_(indices) {} | |||||
| /// \param[in] slice Slice the generated indices from the slice object along the dimension. | |||||
| explicit SliceOption(Slice slice) : slice_(slice) {} | |||||
| SliceOption(SliceOption const &slice) = default; | |||||
| ~SliceOption() = default; | |||||
| // only one of the following will be valid | |||||
| // given indices to slice the Tensor. | |||||
| std::vector<dsize_t> indices_ = {}; | |||||
| // Slice object. All start, stop and step are 0 if invalid. | |||||
| Slice slice_; | |||||
| bool all_ = false; | |||||
| }; | |||||
| // Transform operations for performing data transformation. | // Transform operations for performing data transformation. | ||||
| namespace transforms { | namespace transforms { | ||||
| @@ -105,6 +153,29 @@ class Compose final : public TensorTransform { | |||||
| std::shared_ptr<Data> data_; | std::shared_ptr<Data> data_; | ||||
| }; | }; | ||||
| /// \brief Concatenate Op. | |||||
| /// \notes Tensor operation that concatenates all columns into a single tensor. | |||||
| class Concatenate final : public TensorTransform { | |||||
| public: | |||||
| /// \brief Constructor. | |||||
| /// \param[in] axis Concatenate the tensors along given axis (Default=0). | |||||
| /// \param[in] prepend MSTensor to be prepended to the already concatenated tensors (Default={}). | |||||
| /// \param[in] append MSTensor to be appended to the already concatenated tensors (Default={}). | |||||
| explicit Concatenate(int8_t axis = 0, MSTensor prepend = {}, MSTensor append = {}); | |||||
| /// \brief Destructor | |||||
| ~Concatenate() = default; | |||||
| protected: | |||||
| /// \brief Function to convert TensorTransform object into a TensorOperation object. | |||||
| /// \return Shared pointer to TensorOperation object. | |||||
| std::shared_ptr<TensorOperation> Parse() override; | |||||
| private: | |||||
| struct Data; | |||||
| std::shared_ptr<Data> data_; | |||||
| }; | |||||
| /// \brief Duplicate Op. | /// \brief Duplicate Op. | ||||
| /// \notes Duplicate the input tensor to a new output tensor. | /// \notes Duplicate the input tensor to a new output tensor. | ||||
| /// The input tensor is carried over to the output list. | /// The input tensor is carried over to the output list. | ||||
| @@ -122,6 +193,32 @@ class Duplicate final : public TensorTransform { | |||||
| std::shared_ptr<TensorOperation> Parse() override; | std::shared_ptr<TensorOperation> Parse() override; | ||||
| }; | }; | ||||
| /// \brief Mask Op. | |||||
| /// \notes Mask content of the input tensor with the given predicate. | |||||
| /// Any element of the tensor that matches the predicate will be evaluated to True, otherwise False. | |||||
| class Mask final : public TensorTransform { | |||||
| public: | |||||
| /// \brief Constructor. | |||||
| /// \param[in] op One of the relational operators EQ, NE LT, GT, LE or GE. | |||||
| /// \param[in] constant Constant to be compared to. | |||||
| /// Can only be MSTensor of str, int, float, bool. | |||||
| /// \param[in] de_type Type of the generated mask (Default to be mindspore::DataType::kNumberTypeBool). | |||||
| explicit Mask(RelationalOp op, MSTensor constant, | |||||
| mindspore::DataType ms_type = mindspore::DataType(mindspore::DataType::kNumberTypeBool)); | |||||
| /// \brief Destructor | |||||
| ~Mask() = default; | |||||
| protected: | |||||
| /// \brief Function to convert TensorTransform object into a TensorOperation object. | |||||
| /// \return Shared pointer to TensorOperation object. | |||||
| std::shared_ptr<TensorOperation> Parse() override; | |||||
| private: | |||||
| struct Data; | |||||
| std::shared_ptr<Data> data_; | |||||
| }; | |||||
| /// \brief OneHot Op. | /// \brief OneHot Op. | ||||
| /// \notes Convert the labels into OneHot format. | /// \notes Convert the labels into OneHot format. | ||||
| class OneHot final : public TensorTransform { | class OneHot final : public TensorTransform { | ||||
| @@ -143,6 +240,30 @@ class OneHot final : public TensorTransform { | |||||
| std::shared_ptr<Data> data_; | std::shared_ptr<Data> data_; | ||||
| }; | }; | ||||
| /// \brief PadEnd Op. | |||||
| /// \notes Pad input tensor according to pad_shape, need to have same rank. | |||||
| class PadEnd final : public TensorTransform { | |||||
| public: | |||||
| /// \brief Constructor. | |||||
| /// \param[in] pad_shape List of integers representing the shape needed. | |||||
| /// Dimensions that set to `None` will not be padded (i.e., original dim will be used). | |||||
| /// Shorter dimensions will truncate the values. | |||||
| /// \param[in] pad_value Value used to pad. Default to be {}. | |||||
| explicit PadEnd(const std::vector<dsize_t> &pad_shape, MSTensor pad_value = {}); | |||||
| /// \brief Destructor | |||||
| ~PadEnd() = default; | |||||
| protected: | |||||
| /// \brief Function to convert TensorTransform object into a TensorOperation object. | |||||
| /// \return Shared pointer to TensorOperation object. | |||||
| std::shared_ptr<TensorOperation> Parse() override; | |||||
| private: | |||||
| struct Data; | |||||
| std::shared_ptr<Data> data_; | |||||
| }; | |||||
| /// \brief RandomApply Op. | /// \brief RandomApply Op. | ||||
| /// \notes Randomly perform a series of transforms with a given probability. | /// \notes Randomly perform a series of transforms with a given probability. | ||||
| class RandomApply final : public TensorTransform { | class RandomApply final : public TensorTransform { | ||||
| @@ -200,6 +321,29 @@ class RandomChoice final : public TensorTransform { | |||||
| std::shared_ptr<Data> data_; | std::shared_ptr<Data> data_; | ||||
| }; | }; | ||||
| /// \brief Slice Op. | |||||
| /// \notes Slice operation to extract a tensor out using the given n slices. | |||||
| /// The functionality of Slice is similar to NumPy's indexing feature. | |||||
| /// (Currently only rank-1 tensors are supported). | |||||
| class Slice final : public TensorTransform { | |||||
| public: | |||||
| /// \brief Constructor. | |||||
| /// \param[in] slice_input Vector of SliceOption | |||||
| explicit Slice(const std::vector<SliceOption> &slice_input); | |||||
| /// \brief Destructor | |||||
| ~Slice() = default; | |||||
| protected: | |||||
| /// \brief Function to convert TensorTransform object into a TensorOperation object. | |||||
| /// \return Shared pointer to TensorOperation object. | |||||
| std::shared_ptr<TensorOperation> Parse() override; | |||||
| private: | |||||
| struct Data; | |||||
| std::shared_ptr<Data> data_; | |||||
| }; | |||||
| /// \brief TypeCast Op. | /// \brief TypeCast Op. | ||||
| /// \notes Tensor operation to cast to a given MindSpore data type. | /// \notes Tensor operation to cast to a given MindSpore data type. | ||||
| class TypeCast final : public TensorTransform { | class TypeCast final : public TensorTransform { | ||||
| @@ -124,15 +124,6 @@ Status PadEndStringHelper(const std::shared_ptr<Tensor> &src, std::vector<std::s | |||||
| const TensorShape &dst_shape, std::vector<dsize_t> cur_ind, size_t cur_dim, | const TensorShape &dst_shape, std::vector<dsize_t> cur_ind, size_t cur_dim, | ||||
| const std::string &pad_value); | const std::string &pad_value); | ||||
| enum class RelationalOp { | |||||
| kEqual = 0, // == | |||||
| kNotEqual, // != | |||||
| kLess, // < | |||||
| kLessEqual, // <= | |||||
| kGreater, // > | |||||
| kGreaterEqual, // >= | |||||
| }; | |||||
| /// Helper method that masks the input tensor | /// Helper method that masks the input tensor | ||||
| /// @tparam T type of the tensor | /// @tparam T type of the tensor | ||||
| /// @param input[in] input tensor | /// @param input[in] input tensor | ||||
| @@ -20,10 +20,22 @@ | |||||
| // Kernel data headers (in alphabetical order) | // Kernel data headers (in alphabetical order) | ||||
| #include "minddata/dataset/kernels/data/compose_op.h" | #include "minddata/dataset/kernels/data/compose_op.h" | ||||
| #ifndef ENABLE_ANDROID | |||||
| #include "minddata/dataset/kernels/data/concatenate_op.h" | |||||
| #endif | |||||
| #include "minddata/dataset/kernels/data/duplicate_op.h" | #include "minddata/dataset/kernels/data/duplicate_op.h" | ||||
| #ifndef ENABLE_ANDROID | |||||
| #include "minddata/dataset/kernels/data/mask_op.h" | |||||
| #endif | |||||
| #include "minddata/dataset/kernels/data/one_hot_op.h" | #include "minddata/dataset/kernels/data/one_hot_op.h" | ||||
| #ifndef ENABLE_ANDROID | |||||
| #include "minddata/dataset/kernels/data/pad_end_op.h" | |||||
| #endif | |||||
| #include "minddata/dataset/kernels/data/random_apply_op.h" | #include "minddata/dataset/kernels/data/random_apply_op.h" | ||||
| #include "minddata/dataset/kernels/data/random_choice_op.h" | #include "minddata/dataset/kernels/data/random_choice_op.h" | ||||
| #ifndef ENABLE_ANDROID | |||||
| #include "minddata/dataset/kernels/data/slice_op.h" | |||||
| #endif | |||||
| #include "minddata/dataset/kernels/data/type_cast_op.h" | #include "minddata/dataset/kernels/data/type_cast_op.h" | ||||
| #ifndef ENABLE_ANDROID | #ifndef ENABLE_ANDROID | ||||
| #include "minddata/dataset/kernels/data/unique_op.h" | #include "minddata/dataset/kernels/data/unique_op.h" | ||||
| @@ -58,11 +70,55 @@ std::shared_ptr<TensorOp> ComposeOperation::Build() { | |||||
| return std::make_shared<ComposeOp>(tensor_ops); | return std::make_shared<ComposeOp>(tensor_ops); | ||||
| } | } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // ConcatenateOperation | |||||
| ConcatenateOperation::ConcatenateOperation(int8_t axis, const std::shared_ptr<Tensor> &prepend, | |||||
| const std::shared_ptr<Tensor> &append) | |||||
| : axis_(axis), prepend_(prepend), append_(append) {} | |||||
| Status ConcatenateOperation::ValidateParams() { | |||||
| if (axis_ != 0 && axis_ != -1) { | |||||
| std::string err_msg = "Concatenate: Only 1D concatenation supported."; | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| if (prepend_) { | |||||
| if (prepend_->shape().Size() != 1) { | |||||
| std::string err_msg = "Concatenate: Can only prepend 1D arrays."; | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| if (append_) { | |||||
| if (append_->shape().Size() != 1) { | |||||
| std::string err_msg = "Concatenate: Can only append 1D arrays."; | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| std::shared_ptr<TensorOp> ConcatenateOperation::Build() { | |||||
| return std::make_shared<ConcatenateOp>(axis_, prepend_, append_); | |||||
| } | |||||
| #endif | |||||
| // DuplicateOperation | // DuplicateOperation | ||||
| Status DuplicateOperation::ValidateParams() { return Status::OK(); } | Status DuplicateOperation::ValidateParams() { return Status::OK(); } | ||||
| std::shared_ptr<TensorOp> DuplicateOperation::Build() { return std::make_shared<DuplicateOp>(); } | std::shared_ptr<TensorOp> DuplicateOperation::Build() { return std::make_shared<DuplicateOp>(); } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // MaskOperation | |||||
| MaskOperation::MaskOperation(RelationalOp op, const std::shared_ptr<Tensor> &constant, DataType dtype) | |||||
| : op_(op), constant_(constant), dtype_(dtype) {} | |||||
| Status MaskOperation::ValidateParams() { return Status::OK(); } | |||||
| std::shared_ptr<TensorOp> MaskOperation::Build() { return std::make_shared<MaskOp>(op_, constant_, dtype_); } | |||||
| #endif | |||||
| // OneHotOperation | // OneHotOperation | ||||
| OneHotOperation::OneHotOperation(int32_t num_classes) : num_classes_(num_classes) {} | OneHotOperation::OneHotOperation(int32_t num_classes) : num_classes_(num_classes) {} | ||||
| @@ -85,6 +141,16 @@ Status OneHotOperation::to_json(nlohmann::json *out_json) { | |||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // PadEndOperation | |||||
| PadEndOperation::PadEndOperation(const TensorShape &pad_shape, const std::shared_ptr<Tensor> &pad_value) | |||||
| : pad_shape_(pad_shape), pad_value_(pad_value) {} | |||||
| Status PadEndOperation::ValidateParams() { return Status::OK(); } | |||||
| std::shared_ptr<TensorOp> PadEndOperation::Build() { return std::make_shared<PadEndOp>(pad_shape_, pad_value_); } | |||||
| #endif | |||||
| // PreBuiltOperation | // PreBuiltOperation | ||||
| PreBuiltOperation::PreBuiltOperation(std::shared_ptr<TensorOp> tensor_op) : op_(tensor_op) { | PreBuiltOperation::PreBuiltOperation(std::shared_ptr<TensorOp> tensor_op) : op_(tensor_op) { | ||||
| #ifdef ENABLE_PYTHON | #ifdef ENABLE_PYTHON | ||||
| @@ -137,6 +203,15 @@ std::shared_ptr<TensorOp> RandomChoiceOperation::Build() { | |||||
| return std::make_shared<RandomChoiceOp>(tensor_ops); | return std::make_shared<RandomChoiceOp>(tensor_ops); | ||||
| } | } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // SliceOperation | |||||
| SliceOperation::SliceOperation(const std::vector<SliceOption> &slice_input) : slice_input_(slice_input) {} | |||||
| Status SliceOperation::ValidateParams() { return Status::OK(); } | |||||
| std::shared_ptr<TensorOp> SliceOperation::Build() { return std::make_shared<SliceOp>(slice_input_); } | |||||
| #endif | |||||
| // TypeCastOperation | // TypeCastOperation | ||||
| TypeCastOperation::TypeCastOperation(std::string data_type) : data_type_(data_type) {} | TypeCastOperation::TypeCastOperation(std::string data_type) : data_type_(data_type) {} | ||||
| @@ -28,9 +28,13 @@ namespace mindspore { | |||||
| namespace dataset { | namespace dataset { | ||||
| // Char arrays storing name of corresponding classes (in alphabetical order) | // Char arrays storing name of corresponding classes (in alphabetical order) | ||||
| constexpr char kComposeOperation[] = "Compose"; | constexpr char kComposeOperation[] = "Compose"; | ||||
| constexpr char kConcatenateOperation[] = "Concatenate"; | |||||
| constexpr char kDuplicateOperation[] = "Duplicate"; | constexpr char kDuplicateOperation[] = "Duplicate"; | ||||
| constexpr char kMaskOperation[] = "Mask"; | |||||
| constexpr char kOneHotOperation[] = "OneHot"; | constexpr char kOneHotOperation[] = "OneHot"; | ||||
| constexpr char kPadEndOperation[] = "PadEnd"; | |||||
| constexpr char kPreBuiltOperation[] = "PreBuilt"; | constexpr char kPreBuiltOperation[] = "PreBuilt"; | ||||
| constexpr char kSliceOperation[] = "Slice"; | |||||
| constexpr char kRandomApplyOperation[] = "RandomApply"; | constexpr char kRandomApplyOperation[] = "RandomApply"; | ||||
| constexpr char kRandomChoiceOperation[] = "RandomChoice"; | constexpr char kRandomChoiceOperation[] = "RandomChoice"; | ||||
| constexpr char kTypeCastOperation[] = "TypeCast"; | constexpr char kTypeCastOperation[] = "TypeCast"; | ||||
| @@ -56,6 +60,25 @@ class ComposeOperation : public TensorOperation { | |||||
| std::vector<std::shared_ptr<TensorOperation>> transforms_; | std::vector<std::shared_ptr<TensorOperation>> transforms_; | ||||
| }; | }; | ||||
| class ConcatenateOperation : public TensorOperation { | |||||
| public: | |||||
| explicit ConcatenateOperation(int8_t axis, const std::shared_ptr<Tensor> &prepend, | |||||
| const std::shared_ptr<Tensor> &append); | |||||
| ~ConcatenateOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| std::string Name() const override { return kConcatenateOperation; } | |||||
| private: | |||||
| int8_t axis_; | |||||
| std::shared_ptr<Tensor> prepend_; | |||||
| std::shared_ptr<Tensor> append_; | |||||
| }; | |||||
| class DuplicateOperation : public TensorOperation { | class DuplicateOperation : public TensorOperation { | ||||
| public: | public: | ||||
| DuplicateOperation() = default; | DuplicateOperation() = default; | ||||
| @@ -69,6 +92,24 @@ class DuplicateOperation : public TensorOperation { | |||||
| std::string Name() const override { return kDuplicateOperation; } | std::string Name() const override { return kDuplicateOperation; } | ||||
| }; | }; | ||||
| class MaskOperation : public TensorOperation { | |||||
| public: | |||||
| explicit MaskOperation(RelationalOp op, const std::shared_ptr<Tensor> &constant, DataType dtype); | |||||
| ~MaskOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| std::string Name() const override { return kMaskOperation; } | |||||
| private: | |||||
| RelationalOp op_; | |||||
| std::shared_ptr<Tensor> constant_; | |||||
| DataType dtype_; | |||||
| }; | |||||
| class OneHotOperation : public TensorOperation { | class OneHotOperation : public TensorOperation { | ||||
| public: | public: | ||||
| explicit OneHotOperation(int32_t num_classes); | explicit OneHotOperation(int32_t num_classes); | ||||
| @@ -87,6 +128,23 @@ class OneHotOperation : public TensorOperation { | |||||
| int32_t num_classes_; | int32_t num_classes_; | ||||
| }; | }; | ||||
| class PadEndOperation : public TensorOperation { | |||||
| public: | |||||
| explicit PadEndOperation(const TensorShape &pad_shape, const std::shared_ptr<Tensor> &pad_value); | |||||
| ~PadEndOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| std::string Name() const override { return kPadEndOperation; } | |||||
| private: | |||||
| TensorShape pad_shape_; | |||||
| std::shared_ptr<Tensor> pad_value_; | |||||
| }; | |||||
| class PreBuiltOperation : public TensorOperation { | class PreBuiltOperation : public TensorOperation { | ||||
| public: | public: | ||||
| explicit PreBuiltOperation(std::shared_ptr<TensorOp> tensor_op); | explicit PreBuiltOperation(std::shared_ptr<TensorOp> tensor_op); | ||||
| @@ -137,6 +195,23 @@ class RandomChoiceOperation : public TensorOperation { | |||||
| private: | private: | ||||
| std::vector<std::shared_ptr<TensorOperation>> transforms_; | std::vector<std::shared_ptr<TensorOperation>> transforms_; | ||||
| }; | }; | ||||
| class SliceOperation : public TensorOperation { | |||||
| public: | |||||
| explicit SliceOperation(const std::vector<SliceOption> &slice_input); | |||||
| ~SliceOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| std::string Name() const override { return kSliceOperation; } | |||||
| private: | |||||
| std::vector<SliceOption> slice_input_; | |||||
| }; | |||||
| class TypeCastOperation : public TensorOperation { | class TypeCastOperation : public TensorOperation { | ||||
| public: | public: | ||||
| explicit TypeCastOperation(std::string data_type); | explicit TypeCastOperation(std::string data_type); | ||||
| @@ -160,7 +160,7 @@ class _SliceOption(cde.SliceOption): | |||||
| super().__init__(slice_option) | super().__init__(slice_option) | ||||
| class Slice(cde.SliceOp): | |||||
| class Slice(): | |||||
| """ | """ | ||||
| Slice operation to extract a tensor out using the given n slices. | Slice operation to extract a tensor out using the given n slices. | ||||
| @@ -200,7 +200,10 @@ class Slice(cde.SliceOp): | |||||
| def __init__(self, *slices): | def __init__(self, *slices): | ||||
| slice_input_ = list(slices) | slice_input_ = list(slices) | ||||
| slice_input_ = [_SliceOption(slice_dim) for slice_dim in slice_input_] | slice_input_ = [_SliceOption(slice_dim) for slice_dim in slice_input_] | ||||
| super().__init__(slice_input_) | |||||
| self.slice_input_ = slice_input_ | |||||
| def parse(self): | |||||
| return cde.SliceOperation(self.slice_input_) | |||||
| class Relational(IntEnum): | class Relational(IntEnum): | ||||
| @@ -220,7 +223,7 @@ DE_C_RELATIONAL = {Relational.EQ: cde.RelationalOp.EQ, | |||||
| Relational.LE: cde.RelationalOp.LE} | Relational.LE: cde.RelationalOp.LE} | ||||
| class Mask(cde.MaskOp): | |||||
| class Mask(): | |||||
| """ | """ | ||||
| Mask content of the input tensor with the given predicate. | Mask content of the input tensor with the given predicate. | ||||
| Any element of the tensor that matches the predicate will be evaluated to True, otherwise False. | Any element of the tensor that matches the predicate will be evaluated to True, otherwise False. | ||||
| @@ -250,12 +253,15 @@ class Mask(cde.MaskOp): | |||||
| @check_mask_op | @check_mask_op | ||||
| def __init__(self, operator, constant, dtype=mstype.bool_): | def __init__(self, operator, constant, dtype=mstype.bool_): | ||||
| dtype = mstype_to_detype(dtype) | |||||
| constant = cde.Tensor(np.array(constant)) | |||||
| super().__init__(DE_C_RELATIONAL[operator], constant, dtype) | |||||
| self.operator = operator | |||||
| self.dtype = mstype_to_detype(dtype) | |||||
| self.constant = cde.Tensor(np.array(constant)) | |||||
| def parse(self): | |||||
| return cde.MaskOperation(DE_C_RELATIONAL[self.operator], self.constant, self.dtype) | |||||
| class PadEnd(cde.PadEndOp): | |||||
| class PadEnd(): | |||||
| """ | """ | ||||
| Pad input tensor according to pad_shape, need to have same rank. | Pad input tensor according to pad_shape, need to have same rank. | ||||
| @@ -284,12 +290,14 @@ class PadEnd(cde.PadEndOp): | |||||
| @check_pad_end | @check_pad_end | ||||
| def __init__(self, pad_shape, pad_value=None): | def __init__(self, pad_shape, pad_value=None): | ||||
| if pad_value is not None: | |||||
| pad_value = cde.Tensor(np.array(pad_value)) | |||||
| super().__init__(cde.TensorShape(pad_shape), pad_value) | |||||
| self.pad_shape = cde.TensorShape(pad_shape) | |||||
| self.pad_value = cde.Tensor(np.array(pad_value)) if pad_value is not None else pad_value | |||||
| def parse(self): | |||||
| return cde.PadEndOperation(self.pad_shape, self.pad_value) | |||||
| class Concatenate(cde.ConcatenateOp): | |||||
| class Concatenate(): | |||||
| """ | """ | ||||
| Tensor operation that concatenates all columns into a single tensor. | Tensor operation that concatenates all columns into a single tensor. | ||||
| @@ -311,11 +319,12 @@ class Concatenate(cde.ConcatenateOp): | |||||
| @check_concat_type | @check_concat_type | ||||
| def __init__(self, axis=0, prepend=None, append=None): | def __init__(self, axis=0, prepend=None, append=None): | ||||
| if prepend is not None: | |||||
| prepend = cde.Tensor(np.array(prepend)) | |||||
| if append is not None: | |||||
| append = cde.Tensor(np.array(append)) | |||||
| super().__init__(axis, prepend, append) | |||||
| self.axis = axis | |||||
| self.prepend = cde.Tensor(np.array(prepend)) if prepend is not None else prepend | |||||
| self.append = cde.Tensor(np.array(append)) if append is not None else append | |||||
| def parse(self): | |||||
| return cde.ConcatenateOperation(self.axis, self.prepend, self.append) | |||||
| class Duplicate(TensorOperation): | class Duplicate(TensorOperation): | ||||
| @@ -137,6 +137,70 @@ TEST_F(MindDataTestPipeline, TestComposeFail3) { | |||||
| EXPECT_EQ(iter, nullptr); | EXPECT_EQ(iter, nullptr); | ||||
| } | } | ||||
| TEST_F(MindDataTestPipeline, TestConcatenateSuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestConcatenateSuccess."; | |||||
| // Create a RandomDataset | |||||
| u_int32_t curr_seed = GlobalContext::config_manager()->seed(); | |||||
| GlobalContext::config_manager()->set_seed(246); | |||||
| std::shared_ptr<SchemaObj> schema = Schema(); | |||||
| schema->add_column("col1", mindspore::DataType::kNumberTypeInt16, {1}); | |||||
| std::shared_ptr<Dataset> ds = RandomData(4, schema); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| ds = ds->SetNumWorkers(2); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create Concatenate op | |||||
| std::vector<std::int16_t> prepend_vector = {1, 2}; | |||||
| std::shared_ptr<Tensor> prepend_tensor; | |||||
| ASSERT_OK(Tensor::CreateFromVector(prepend_vector, &prepend_tensor)); | |||||
| mindspore::MSTensor prepend_MSTensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(prepend_tensor)); | |||||
| std::vector<std::int16_t> append_vector = {3}; | |||||
| std::shared_ptr<Tensor> append_tensor; | |||||
| ASSERT_OK(Tensor::CreateFromVector(append_vector, &append_tensor)); | |||||
| mindspore::MSTensor append_MSTensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(append_tensor)); | |||||
| transforms::Concatenate concatenate = transforms::Concatenate(0, prepend_MSTensor, append_MSTensor); | |||||
| // Create a Map operation on ds | |||||
| ds = ds->Map({concatenate}, {"col1"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, mindspore::MSTensor> row; | |||||
| iter->GetNextRow(&row); | |||||
| std::vector<std::vector<std::int16_t>> expected = { | |||||
| {1, 2, 31354, 3}, {1, 2, -5655, 3}, {1, 2, -17734, 3}, {1, 2, -17220, 3}}; | |||||
| // Check concatnate results | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| auto ind = row["col1"]; | |||||
| std::shared_ptr<Tensor> de_expected_tensor; | |||||
| ASSERT_OK(Tensor::CreateFromVector(expected[i], &de_expected_tensor)); | |||||
| mindspore::MSTensor expected_tensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_expected_tensor)); | |||||
| EXPECT_MSTENSOR_EQ(ind, expected_tensor); | |||||
| iter->GetNextRow(&row); | |||||
| i++; | |||||
| } | |||||
| EXPECT_EQ(i, 4); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| GlobalContext::config_manager()->set_seed(curr_seed); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestDuplicateSuccess) { | TEST_F(MindDataTestPipeline, TestDuplicateSuccess) { | ||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestDuplicateSuccess."; | MS_LOG(INFO) << "Doing MindDataTestPipeline-TestDuplicateSuccess."; | ||||
| @@ -177,6 +241,59 @@ TEST_F(MindDataTestPipeline, TestDuplicateSuccess) { | |||||
| iter->Stop(); | iter->Stop(); | ||||
| } | } | ||||
| TEST_F(MindDataTestPipeline, TestMaskSuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestMaskSuccess."; | |||||
| // Create a RandomDataset | |||||
| u_int32_t curr_seed = GlobalContext::config_manager()->seed(); | |||||
| GlobalContext::config_manager()->set_seed(246); | |||||
| std::shared_ptr<SchemaObj> schema = Schema(); | |||||
| schema->add_column("col1", mindspore::DataType::kNumberTypeInt16, {4}); | |||||
| std::shared_ptr<Dataset> ds = RandomData(4, schema); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| ds = ds->SetNumWorkers(2); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create Mask op | |||||
| std::shared_ptr<Tensor> constant_tensor; | |||||
| ASSERT_OK(Tensor::CreateScalar(0, &constant_tensor)); | |||||
| mindspore::MSTensor constant_MSTensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(constant_tensor)); | |||||
| transforms::Mask mask = transforms::Mask(RelationalOp::kGreater, constant_MSTensor); | |||||
| ds = ds->Map({mask}, {"col1"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, mindspore::MSTensor> row; | |||||
| iter->GetNextRow(&row); | |||||
| std::vector<std::vector<bool>> expected = { | |||||
| {true, true, true, true}, {false, false, false, false}, {false, false, false, false}, {false, false, false, false}}; | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| auto ind = row["col1"]; | |||||
| std::shared_ptr<Tensor> de_expected_tensor; | |||||
| ASSERT_OK(Tensor::CreateFromVector(expected[i], &de_expected_tensor)); | |||||
| mindspore::MSTensor expected_tensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_expected_tensor)); | |||||
| EXPECT_MSTENSOR_EQ(ind, expected_tensor); | |||||
| iter->GetNextRow(&row); | |||||
| i++; | |||||
| } | |||||
| EXPECT_EQ(i, 4); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| GlobalContext::config_manager()->set_seed(curr_seed); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestOneHotSuccess1) { | TEST_F(MindDataTestPipeline, TestOneHotSuccess1) { | ||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestOneHotSuccess1."; | MS_LOG(INFO) << "Doing MindDataTestPipeline-TestOneHotSuccess1."; | ||||
| // Testing CutMixBatch on a batch of CHW images | // Testing CutMixBatch on a batch of CHW images | ||||
| @@ -330,6 +447,59 @@ TEST_F(MindDataTestPipeline, TestOneHotFail2) { | |||||
| EXPECT_EQ(iter, nullptr); | EXPECT_EQ(iter, nullptr); | ||||
| } | } | ||||
| TEST_F(MindDataTestPipeline, TestPadEndSuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestPadEndSuccess."; | |||||
| // Create a RandomDataset | |||||
| u_int32_t curr_seed = GlobalContext::config_manager()->seed(); | |||||
| GlobalContext::config_manager()->set_seed(246); | |||||
| std::shared_ptr<SchemaObj> schema = Schema(); | |||||
| schema->add_column("col1", mindspore::DataType::kNumberTypeInt16, {1}); | |||||
| std::shared_ptr<Dataset> ds = RandomData(4, schema); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| ds = ds->SetNumWorkers(2); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create PadEnd op | |||||
| std::shared_ptr<Tensor> pad_value; | |||||
| ASSERT_OK(Tensor::CreateScalar(0, &pad_value)); | |||||
| mindspore::MSTensor pad_value_MSTensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(pad_value)); | |||||
| transforms::PadEnd pad_end = transforms::PadEnd({3}, pad_value_MSTensor); | |||||
| ds = ds->Map({pad_end}, {"col1"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, mindspore::MSTensor> row; | |||||
| iter->GetNextRow(&row); | |||||
| std::vector<std::vector<std::int16_t>> expected = {{31354, 0, 0}, {-5655, 0, 0}, {-17734, 0, 0}, {-17220, 0, 0}}; | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| auto ind = row["col1"]; | |||||
| std::shared_ptr<Tensor> de_expected_tensor; | |||||
| ASSERT_OK(Tensor::CreateFromVector(expected[i], &de_expected_tensor)); | |||||
| mindspore::MSTensor expected_tensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_expected_tensor)); | |||||
| EXPECT_MSTENSOR_EQ(ind, expected_tensor); | |||||
| iter->GetNextRow(&row); | |||||
| i++; | |||||
| } | |||||
| EXPECT_EQ(i, 4); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| GlobalContext::config_manager()->set_seed(curr_seed); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestRandomApplySuccess) { | TEST_F(MindDataTestPipeline, TestRandomApplySuccess) { | ||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomApplySuccess."; | MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomApplySuccess."; | ||||
| @@ -565,6 +735,69 @@ TEST_F(MindDataTestPipeline, TestRandomChoiceFail3) { | |||||
| EXPECT_EQ(iter, nullptr); | EXPECT_EQ(iter, nullptr); | ||||
| } | } | ||||
| TEST_F(MindDataTestPipeline, TestSliceSuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSliceSuccess."; | |||||
| // Create a RandomDataset | |||||
| u_int32_t curr_seed = GlobalContext::config_manager()->seed(); | |||||
| GlobalContext::config_manager()->set_seed(246); | |||||
| std::shared_ptr<SchemaObj> schema = Schema(); | |||||
| schema->add_column("col1", mindspore::DataType::kNumberTypeInt16, {1}); | |||||
| std::shared_ptr<Dataset> ds = RandomData(4, schema); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| ds = ds->SetNumWorkers(2); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create concatenate op | |||||
| std::vector<std::int16_t> prepend_vector = {1, 2, 3}; | |||||
| std::shared_ptr<Tensor> prepend_tensor; | |||||
| ASSERT_OK(Tensor::CreateFromVector(prepend_vector, &prepend_tensor)); | |||||
| mindspore::MSTensor prepend_MSTensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(prepend_tensor)); | |||||
| transforms::Concatenate concatenate = transforms::Concatenate(0, prepend_MSTensor); | |||||
| // Create a Map operation on ds | |||||
| ds = ds->Map({concatenate}, {"col1"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Apply Slice op on ds, get the first and third elements in each row. | |||||
| SliceOption slice_option = SliceOption(Slice(0, 3, 2)); | |||||
| transforms::Slice slice = transforms::Slice({slice_option}); | |||||
| ds = ds->Map({slice}, {"col1"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, mindspore::MSTensor> row; | |||||
| iter->GetNextRow(&row); | |||||
| std::vector<std::vector<std::int16_t>> expected = {{1, 3}, {1, 3}, {1, 3}, {1, 3}}; | |||||
| // Check slice results | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| auto ind = row["col1"]; | |||||
| std::shared_ptr<Tensor> de_expected_tensor; | |||||
| ASSERT_OK(Tensor::CreateFromVector(expected[i], &de_expected_tensor)); | |||||
| mindspore::MSTensor expected_tensor = | |||||
| mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_expected_tensor)); | |||||
| EXPECT_MSTENSOR_EQ(ind, expected_tensor); | |||||
| iter->GetNextRow(&row); | |||||
| i++; | |||||
| } | |||||
| EXPECT_EQ(i, 4); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| GlobalContext::config_manager()->set_seed(curr_seed); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestTypeCastSuccess) { | TEST_F(MindDataTestPipeline, TestTypeCastSuccess) { | ||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestTypeCastSuccess."; | MS_LOG(INFO) << "Doing MindDataTestPipeline-TestTypeCastSuccess."; | ||||