• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020-2023 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_DATASET_TRANSFORMS_H_
18 #define MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_DATASET_TRANSFORMS_H_
19 
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include "include/api/dual_abi_helper.h"
26 #include "include/api/status.h"
27 #include "include/api/types.h"
28 #include "include/dataset/constants.h"
29 
30 namespace mindspore {
31 namespace dataset {
32 class TensorOperation;
33 
34 // We need the following two groups of forward declaration to friend the class in class TensorTransform.
35 namespace transforms {
36 class Compose;
37 class RandomApply;
38 class RandomChoice;
39 }  // namespace transforms
40 
41 namespace vision {
42 class BoundingBoxAugment;
43 class RandomSelectSubpolicy;
44 class UniformAugment;
45 }  // namespace vision
46 
47 // Abstract class to represent a tensor transform operation in the data pipeline.
48 /// \class TensorTransform transforms.h
49 /// \brief A base class to represent a tensor transform operation in the data pipeline.
50 class DATASET_API TensorTransform : public std::enable_shared_from_this<TensorTransform> {
51   friend class Dataset;
52   friend class Execute;
53   friend class transforms::Compose;
54   friend class transforms::RandomApply;
55   friend class transforms::RandomChoice;
56   friend class vision::BoundingBoxAugment;
57   friend class vision::RandomSelectSubpolicy;
58   friend class vision::UniformAugment;
59 
60  public:
61   /// \brief Constructor
62   TensorTransform() = default;
63 
64   /// \brief Destructor
65   virtual ~TensorTransform() = default;
66 
67  protected:
68   /// \brief Pure virtual function to convert a TensorTransform class into a IR TensorOperation object.
69   /// \return shared pointer to the newly created TensorOperation.
70   virtual std::shared_ptr<TensorOperation> Parse() = 0;
71 
72   /// \brief Virtual function to convert a TensorTransform class into a IR TensorOperation object.
73   /// \param[in] env A string to determine the running environment
74   /// \return shared pointer to the newly created TensorOperation.
Parse(const MapTargetDevice & env)75   virtual std::shared_ptr<TensorOperation> Parse(const MapTargetDevice &env) { return nullptr; }
76 };
77 
78 /// \brief Slice object used in SliceOption.
79 class DATASET_API Slice {
80  public:
81   /// \brief Constructor, with start, stop and step default to 0.
Slice()82   Slice() : start_(0), stop_(0), step_(0) {}
83 
84   /// \brief Constructor.
85   /// \param[in] start Starting integer specifying where to start the slicing.
86   /// \param[in] stop Ending integer specifying where to stop the slicing.
87   /// \param[in] step An integer specifying the step of the slicing.
88   /// \par Example
89   /// \code
90   ///     /* Slice dimension from 2 to 10 with step 2. */
91   ///     Slice(0, 10, 2);
92   /// \endcode
Slice(dsize_t start,dsize_t stop,dsize_t step)93   Slice(dsize_t start, dsize_t stop, dsize_t step) : start_(start), stop_(stop), step_(step) {}
94 
95   /// \brief Constructor, with step=1
96   /// \param[in] start Starting integer specifying where to start the slicing.
97   /// \param[in] stop Ending integer specifying where to stop the slicing.
98   /// \par Example
99   /// \code
100   ///     /* Slice dimension from 5 to 10 with step 1. */
101   ///     Slice(5, 10);
102   /// \endcode
Slice(dsize_t start,dsize_t stop)103   Slice(dsize_t start, dsize_t stop) : start_(start), stop_(stop), step_(1) {}
104 
105   /// \brief Constructor, with start=0 and step=1
106   /// \param[in] stop Ending integer specifying where to stop the slicing.
107   /// \par Example
108   /// \code
109   ///     /* Slice dimension from 0 to 5 with step 1. */
110   ///     Slice(5);
111   /// \endcode
Slice(dsize_t stop)112   explicit Slice(dsize_t stop) : start_(0), stop_(stop), step_(1) {}
113 
114   Slice(Slice const &slice) = default;
115 
116   Slice &operator=(const Slice &slice) = default;
117 
118   ~Slice() = default;
119 
valid()120   bool valid() const { return step_ != 0; }
121   dsize_t start_;
122   dsize_t stop_;
123   dsize_t step_;
124 };
125 
126 /// \brief SliceOption used in Slice TensorTransform.
127 class DATASET_API SliceOption {
128  public:
129   /// \param[in] all Slice the whole dimension
130   /// \par Example
131   /// \code
132   ///     /* Slice all the data. */
133   ///     SliceOption slice_option = SliceOption(True);
134   /// \endcode
SliceOption(bool all)135   explicit SliceOption(bool all) : all_(all) {}
136 
137   /// \param[in] indices Slice these indices along the dimension. Negative indices are supported.
138   /// \par Example
139   /// \code
140   ///     /* Slice the given dimensions. */
141   ///     std::vector<int64_t> indices = {0, 3, 6, 7};
142   ///     SliceOption slice_option = SliceOption(indices);
143   /// \endcode
SliceOption(const std::vector<dsize_t> & indices)144   explicit SliceOption(const std::vector<dsize_t> &indices) : indices_(indices) {}
145 
146   /// \param[in] slice Slice the generated indices from the slice object along the dimension.
147   /// \par Example
148   /// \code
149   ///     /* Slice dimension from 2 to 10 with step 2. */
150   ///     SliceOption slice_option = SliceOption(Slice(0, 10, 2));
151   ///     transforms::Slice slice_op = transforms::Slice({slice_option});
152   /// \endcode
SliceOption(const Slice & slice)153   explicit SliceOption(const Slice &slice) : slice_(slice) {}
154 
155   SliceOption(SliceOption const &slice) = default;
156 
157   SliceOption &operator=(const SliceOption &slice) = default;
158 
159   ~SliceOption() = default;
160 
161   // only one of the following will be valid
162   // given indices to slice the Tensor.
163   std::vector<dsize_t> indices_ = {};
164   // Slice object. All start, stop and step are 0 if invalid.
165   Slice slice_;
166   bool all_ = false;
167 };
168 
169 // Transform operations for performing data transformation.
170 namespace transforms {
171 
172 /// \brief Compose a list of transforms into a single transform.
173 class DATASET_API Compose final : public TensorTransform {
174  public:
175   /// \brief Constructor.
176   /// \param[in] transforms A vector of raw pointers to TensorTransform objects to be applied.
177   /// \par Example
178   /// \code
179   ///     /* Define operations */
180   ///     auto resize_op(new vision::Resize({30, 30}));
181   ///     auto center_crop_op(new vision::CenterCrop({16, 16}));
182   ///     auto compose_op(new transforms::Compose({resize_op, center_crop_op}));
183   ///
184   ///     /* dataset is an instance of Dataset object */
185   ///     dataset = dataset->Map({compose_op},  // operations
186   ///                            {"image"});    // input columns
187   /// \endcode
188   explicit Compose(const std::vector<TensorTransform *> &transforms);
189 
190   /// \brief Constructor.
191   /// \param[in] transforms A vector of shared pointers to TensorTransform objects to be applied.
192   /// \par Example
193   /// \code
194   ///     /* Define operations */
195   ///     std::shared_ptr<TensorTransform> resize_op(new vision::Resize({30, 30}));
196   ///     std::shared_ptr<TensorTransform> center_crop_op(new vision::CenterCrop({16, 16}));
197   ///     std::shared_ptr<TensorTransform> compose_op(new transforms::Compose({resize_op, center_crop_op}));
198   ///
199   ///     /* dataset is an instance of Dataset object */
200   ///     dataset = dataset->Map({compose_op},  // operations
201   ///                            {"image"});    // input columns
202   /// \endcode
203   explicit Compose(const std::vector<std::shared_ptr<TensorTransform>> &transforms);
204 
205   /// \brief Constructor.
206   /// \param[in] transforms A vector of TensorTransform objects to be applied.
207   /// \par Example
208   /// \code
209   ///     /* Define operations */
210   ///     vision::Resize resize_op = vision::Resize({30, 30});
211   ///     vision::CenterCrop center_crop_op = vision::CenterCrop({16, 16});
212   ///     transforms::Compose compose_op = transforms::Compose({resize_op, center_crop_op});
213   ///
214   ///     /* dataset is an instance of Dataset object */
215   ///     dataset = dataset->Map({compose_op},  // operations
216   ///                            {"image"});    // input columns
217   /// \endcode
218   explicit Compose(const std::vector<std::reference_wrapper<TensorTransform>> &transforms);
219 
220   /// \brief Destructor
221   ~Compose() override = default;
222 
223  protected:
224   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
225   /// \return Shared pointer to TensorOperation object.
226   std::shared_ptr<TensorOperation> Parse() override;
227 
228  private:
229   struct Data;
230   std::shared_ptr<Data> data_;
231 };
232 
233 /// \brief Concatenate all tensors into a single tensor.
234 class DATASET_API Concatenate final : public TensorTransform {
235  public:
236   /// \brief Constructor.
237   /// \param[in] axis Concatenate the tensors along given axis, only support 0 or -1 so far (default=0).
238   /// \param[in] prepend MSTensor to be prepended to the concatenated tensors (default={}).
239   /// \param[in] append MSTensor to be appended to the concatenated tensors (default={}).
240   /// \par Example
241   /// \code
242   ///     /* Define operations */
243   ///     mindspore::MSTensor append_MSTensor;
244   ///     mindspore::MSTensor prepend_MSTensor;
245   ///     auto concatenate_op = transforms::Concatenate(0, append_MSTensor, prepend_MSTensor);
246   ///
247   ///     /* dataset is an instance of Dataset object */
248   ///     dataset = dataset->Map({concatenate_op},   // operations
249   ///                            {"column"});        // input columns
250   /// \endcode
251   explicit Concatenate(int8_t axis = 0, const MSTensor &prepend = {}, const MSTensor &append = {});
252 
253   /// \brief Destructor
254   ~Concatenate() override = default;
255 
256  protected:
257   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
258   /// \return Shared pointer to TensorOperation object.
259   std::shared_ptr<TensorOperation> Parse() override;
260 
261  private:
262   struct Data;
263   std::shared_ptr<Data> data_;
264 };
265 
266 /// \brief Duplicate the input tensor to a new output tensor.
267 ///     The input tensor is carried over to the output list.
268 class DATASET_API Duplicate final : public TensorTransform {
269  public:
270   /// \brief Constructor.
271   /// \par Example
272   /// \code
273   ///     /* Define operations */
274   ///     auto duplicate_op = transforms::Duplicate();
275   ///
276   ///     /* dataset is an instance of Dataset object */
277   ///     dataset = dataset->Map({duplicate_op},               // operations
278   ///                            {"column"},                   // input columns
279   ///                            {"column", "column_copy"});   // output columns
280   /// \endcode
281   Duplicate();
282 
283   /// \brief Destructor
284   ~Duplicate() override = default;
285 
286  protected:
287   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
288   /// \return Shared pointer to TensorOperation object.
289   std::shared_ptr<TensorOperation> Parse() override;
290 };
291 
292 /// \brief Fill all elements in the tensor with the specified value.
293 ///    The output tensor will have the same shape and type as the input tensor.
294 class DATASET_API Fill final : public TensorTransform {
295  public:
296   /// \brief Constructor.
297   /// \param[in] fill_value Scalar value to fill the tensor with.
298   ///               It can only be MSTensor of the following types from mindspore::DataType:
299   ///               String, Bool, Int8/16/32/64, UInt8/16/32/64, Float16/32/64.
300   /// \par Example
301   /// \code
302   ///     /* Define operations */
303   ///     mindspore::MSTensor tensor;
304   ///     auto fill_op = transforms::Fill(tensor);
305   ///
306   ///     /* dataset is an instance of Dataset object */
307   ///     dataset = dataset->Map({fill_op},     // operations
308   ///                            {"column"});   // input columns
309   /// \endcode
310   explicit Fill(const MSTensor &fill_value);
311 
312   /// \brief Destructor
313   ~Fill() override = default;
314 
315  protected:
316   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
317   /// \return Shared pointer to TensorOperation object.
318   std::shared_ptr<TensorOperation> Parse() override;
319 
320  private:
321   struct Data;
322   std::shared_ptr<Data> data_;
323 };
324 
325 /// \brief Mask content of the input tensor with the given predicate.
326 ///     Any element of the tensor that matches the predicate will be evaluated to True, otherwise False.
327 class DATASET_API Mask final : public TensorTransform {
328  public:
329   /// \brief Constructor.
330   /// \param[in] op One of the relational operators: EQ, NE LT, GT, LE or GE.
331   /// \param[in] constant Constant to be compared to. It can only be MSTensor of the following types
332   ///                from mindspore::DataType: String, Int, Float, Bool.
333   /// \param[in] ms_type Type of the generated mask. It can only be numeric or boolean datatype.
334   ///               (default=mindspore::DataType::kNumberTypeBool)
335   /// \par Example
336   /// \code
337   ///     /* Define operations */
338   ///     mindspore::MSTensor constant;
339   ///     auto mask_op = transforms::Mask(RelationalOp::kEqual, constant);
340   ///
341   ///     /* dataset is an instance of Dataset object */
342   ///     dataset = dataset->Map({mask_op},     // operations
343   ///                            {"column"});   // input columns
344   /// \endcode
345   explicit Mask(RelationalOp op, const MSTensor &constant,
346                 mindspore::DataType ms_type = mindspore::DataType(mindspore::DataType::kNumberTypeBool));
347 
348   /// \brief Destructor
349   ~Mask() override = default;
350 
351  protected:
352   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
353   /// \return Shared pointer to TensorOperation object.
354   std::shared_ptr<TensorOperation> Parse() override;
355 
356  private:
357   struct Data;
358   std::shared_ptr<Data> data_;
359 };
360 
361 /// \brief Convert the labels into OneHot format.
362 class DATASET_API OneHot final : public TensorTransform {
363  public:
364   /// \brief Constructor.
365   /// \param[in] num_classes number of classes.
366   /// \param[in] smoothing_rate smoothing rate default(0.0).
367   /// \par Example
368   /// \code
369   ///     /* Define operations */
370   ///     mindspore::MSTensor constant;
371   ///     auto one_hot_op = transforms::OneHot(10);
372   ///
373   ///     /* dataset is an instance of Dataset object */
374   ///     dataset = dataset->Map({one_hot_op},    // operations
375   ///                            {"column"});     // input columns
376   /// \endcode
377   explicit OneHot(int32_t num_classes, double smoothing_rate = 0.0);
378 
379   /// \brief Destructor
380   ~OneHot() override = default;
381 
382  protected:
383   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
384   /// \return Shared pointer to TensorOperation object.
385   std::shared_ptr<TensorOperation> Parse() override;
386 
387  private:
388   struct Data;
389   std::shared_ptr<Data> data_;
390 };
391 
392 /// \brief Pad input tensor according to pad_shape
393 class DATASET_API PadEnd final : public TensorTransform {
394  public:
395   /// \brief Constructor.
396   /// \param[in] pad_shape List of integers representing the shape needed, need to have same rank with input tensor.
397   ///               Dimensions that set to `-1` will not be padded (i.e., original dim will be used).
398   ///               Shorter dimensions will truncate the values.
399   /// \param[in] pad_value Value used to pad (default={}).
400   /// \par Example
401   /// \code
402   ///     /* Define operations */
403   ///     mindspore::MSTensor constant;
404   ///     auto pad_end_op = transforms::PadEnd({224, 224, 1}, {constant});
405   ///
406   ///     /* dataset is an instance of Dataset object */
407   ///     dataset = dataset->Map({pad_end_op},    // operations
408   ///                            {"column"});     // input columns
409   /// \endcode
410   explicit PadEnd(const std::vector<dsize_t> &pad_shape, const MSTensor &pad_value = {});
411 
412   /// \brief Destructor
413   ~PadEnd() override = default;
414 
415  protected:
416   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
417   /// \return Shared pointer to TensorOperation object.
418   std::shared_ptr<TensorOperation> Parse() override;
419 
420  private:
421   struct Data;
422   std::shared_ptr<Data> data_;
423 };
424 
425 /// \brief Randomly perform a series of transforms with a given probability.
426 class DATASET_API RandomApply final : public TensorTransform {
427  public:
428   /// \brief Constructor.
429   /// \param[in] transforms A vector of raw pointers to TensorTransform objects to be applied.
430   /// \param[in] prob The probability to apply the transformation list (default=0.5).
431   /// \par Example
432   /// \code
433   ///     /* Define operations */
434   ///     auto resize_op(new vision::Resize({30, 30}));
435   ///     auto center_crop_op(new vision::CenterCrop({16, 16}));
436   ///     auto random_op(new transforms::RandomApply({resize_op, center_crop_op}));
437   ///
438   ///     /* dataset is an instance of Dataset object */
439   ///     dataset = dataset->Map({random_op},   // operations
440   ///                            {"image"});    // input columns
441   /// \endcode
442   explicit RandomApply(const std::vector<TensorTransform *> &transforms, double prob = 0.5);
443 
444   /// \brief Constructor.
445   /// \param[in] transforms A vector of shared pointers to TensorTransform objects to be applied.
446   /// \param[in] prob The probability to apply the transformation list (default=0.5).
447   /// \par Example
448   /// \code
449   ///     /* Define operations */
450   ///     std::shared_ptr<TensorTransform> resize_op(new vision::Resize({30, 30}));
451   ///     std::shared_ptr<TensorTransform> center_crop_op(new vision::CenterCrop({16, 16}));
452   ///     std::shared_ptr<TensorTransform> random_op(new transforms::RandomApply({resize_op, center_crop_op}));
453   ///
454   ///     /* dataset is an instance of Dataset object */
455   ///     dataset = dataset->Map({random_op},   // operations
456   ///                            {"image"});    // input columns
457   /// \endcode
458   explicit RandomApply(const std::vector<std::shared_ptr<TensorTransform>> &transforms, double prob = 0.5);
459 
460   /// \brief Constructor.
461   /// \param[in] transforms A vector of TensorTransform objects to be applied.
462   /// \param[in] prob The probability to apply the transformation list (default=0.5).
463   /// \par Example
464   /// \code
465   ///     /* Define operations */
466   ///     vision::Resize resize_op = vision::Resize({30, 30});
467   ///     vision::CenterCrop center_crop_op = vision::CenterCrop({16, 16});
468   ///     transforms::RandomApply random_op = transforms::RandomApply({resize_op, center_crop_op});
469   ///
470   ///     /* dataset is an instance of Dataset object */
471   ///     dataset = dataset->Map({random_op},   // operations
472   ///                            {"image"});    // input columns
473   /// \endcode
474   explicit RandomApply(const std::vector<std::reference_wrapper<TensorTransform>> &transforms, double prob = 0.5);
475 
476   /// \brief Destructor
477   ~RandomApply() override = default;
478 
479  protected:
480   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
481   /// \return Shared pointer to TensorOperation object.
482   std::shared_ptr<TensorOperation> Parse() override;
483 
484  private:
485   struct Data;
486   std::shared_ptr<Data> data_;
487 };
488 
489 /// \brief Randomly select one transform from a list of transforms to perform on the input tensor.
490 class DATASET_API RandomChoice final : public TensorTransform {
491  public:
492   /// \brief Constructor.
493   /// \param[in] transforms A vector of raw pointers to TensorTransform objects to be applied.
494   /// \par Example
495   /// \code
496   ///     /* Define operations */
497   ///     auto resize_op(new vision::Resize({30, 30}));
498   ///     auto center_crop_op(new vision::CenterCrop({16, 16}));
499   ///     auto random_op(new transforms::RandomChoice({resize_op, center_crop_op}));
500   ///
501   ///     /* dataset is an instance of Dataset object */
502   ///     dataset = dataset->Map({random_op},   // operations
503   ///                            {"image"});    // input columns
504   /// \endcode
505   explicit RandomChoice(const std::vector<TensorTransform *> &transforms);
506 
507   /// \brief Constructor.
508   /// \param[in] transforms A vector of shared pointers to TensorTransform objects to be applied.
509   /// \par Example
510   /// \code
511   ///     /* Define operations */
512   ///     std::shared_ptr<TensorTransform> resize_op(new vision::Resize({30, 30}));
513   ///     std::shared_ptr<TensorTransform> center_crop_op(new vision::CenterCrop({16, 16}));
514   ///     std::shared_ptr<TensorTransform> random_op(new transforms::RandomChoice({resize_op, center_crop_op}));
515   ///
516   ///     /* dataset is an instance of Dataset object */
517   ///     dataset = dataset->Map({random_op},   // operations
518   ///                            {"image"});    // input columns
519   /// \endcode
520   explicit RandomChoice(const std::vector<std::shared_ptr<TensorTransform>> &transforms);
521 
522   /// \brief Constructor.
523   /// \param[in] transforms A vector of TensorTransform objects to be applied.
524   /// \par Example
525   /// \code
526   ///     /* Define operations */
527   ///     vision::Resize resize_op = vision::Resize({30, 30});
528   ///     vision::CenterCrop center_crop_op = vision::CenterCrop({16, 16});
529   ///     transforms::RandomChoice random_op = transforms::RandomChoice({resize_op, center_crop_op});
530   ///
531   ///     /* dataset is an instance of Dataset object */
532   ///     dataset = dataset->Map({random_op},   // operations
533   ///                            {"image"});    // input columns
534   /// \endcode
535   explicit RandomChoice(const std::vector<std::reference_wrapper<TensorTransform>> &transforms);
536 
537   /// \brief Destructor
538   ~RandomChoice() override = default;
539 
540  protected:
541   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
542   /// \return Shared pointer to TensorOperation object.
543   std::shared_ptr<TensorOperation> Parse() override;
544 
545  private:
546   struct Data;
547   std::shared_ptr<Data> data_;
548 };
549 
550 /// \brief Extract a tensor out using the given n slices.
551 ///     The functionality of Slice is similar to the feature of indexing of NumPy.
552 ///     (Currently only rank-1 tensors are supported).
553 class DATASET_API Slice final : public TensorTransform {
554  public:
555   /// \brief Constructor.
556   /// \param[in] slice_input Vector of SliceOption.
557   /// \par Example
558   /// \code
559   ///     /* Define operations */
560   ///     SliceOption slice_option = SliceOption(Slice(0, 3, 2));
561   ///     transforms::Slice slice_op = transforms::Slice({slice_option});
562   ///
563   ///     /* dataset is an instance of Dataset object */
564   ///     dataset = dataset->Map({slice_op},      // operations
565   ///                            {"column"});     // input columns
566   /// \endcode
567   explicit Slice(const std::vector<SliceOption> &slice_input);
568 
569   /// \brief Destructor
570   ~Slice() override = default;
571 
572  protected:
573   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
574   /// \return Shared pointer to TensorOperation object.
575   std::shared_ptr<TensorOperation> Parse() override;
576 
577  private:
578   struct Data;
579   std::shared_ptr<Data> data_;
580 };
581 
582 /// \brief Cast the MindSpore data type of a tensor to another.
583 class DATASET_API TypeCast final : public TensorTransform {
584  public:
585   /// \brief Constructor.
586   /// \param[in] data_type mindspore::DataType to be cast to.
587   /// \par Example
588   /// \code
589   ///     /* Define operations */
590   ///     auto typecast_op = transforms::TypeCast(mindspore::DataType::kNumberTypeUInt8);
591   ///
592   ///     /* dataset is an instance of Dataset object */
593   ///     dataset = dataset->Map({typecast_op},      // operations
594   ///                            {"column"});        // input columns
595   /// \endcode
596   explicit TypeCast(mindspore::DataType data_type);
597 
598   /// \brief Destructor
599   ~TypeCast() override = default;
600 
601  protected:
602   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
603   /// \return Shared pointer to TensorOperation object.
604   std::shared_ptr<TensorOperation> Parse() override;
605 
606  private:
607   struct Data;
608   std::shared_ptr<Data> data_;
609 };
610 
611 /// \brief Return an output tensor that contains all the unique elements of the input tensor in
612 ///     the same order as they appear in the input tensor.
613 class DATASET_API Unique final : public TensorTransform {
614  public:
615   /// \brief Constructor.
616   /// \par Example
617   /// \code
618   ///     /* Define operations */
619   ///     auto unique_op = transforms::Unique();
620   ///
621   ///     /* dataset is an instance of Dataset object */
622   ///     dataset = dataset->Map({unique_op},      // operations
623   ///                            {"column"});      // input columns
624   /// \endcode
625   Unique();
626 
627   /// \brief Destructor
628   ~Unique() override = default;
629 
630  protected:
631   /// \brief The function to convert a TensorTransform object into a TensorOperation object.
632   /// \return Shared pointer to TensorOperation object.
633   std::shared_ptr<TensorOperation> Parse() override;
634 };
635 }  // namespace transforms
636 }  // namespace dataset
637 }  // namespace mindspore
638 #endif  // MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_DATASET_TRANSFORMS_H_
639