1 /** 2 * Copyright 2019 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_FRONTEND_PARALLEL_TENSOR_LAYOUT_SHAPE_UTIL_H_ 18 #define MINDSPORE_CCSRC_FRONTEND_PARALLEL_TENSOR_LAYOUT_SHAPE_UTIL_H_ 19 20 #include "frontend/parallel/status.h" 21 #include "frontend/parallel/device_matrix.h" 22 23 namespace mindspore { 24 namespace parallel { 25 /* 26 * compute the accumulating product of all the values in shape from left to right, 27 * the accumulating results are saved in shape_accum from left to right 28 * 29 * given a shape = [d_n-1, d_n-2, ..., d_0](d_i > 0, i=0,1,...,n-1, elements of shape must be larger than zero), 30 * then *shape_accum = [d_n-1, d_n-1 * d_n-2, d_n-1 * d_n-2 * d_n-3, ..., d_n-1 * d_n-2 * ... *d_0] 31 * 32 * example: 33 * shape = [2, 8, 32] 34 * shape_accum = [2, 2 * 8, 2 * 8 * 32] 35 * 36 */ 37 Status ShapeToAccumulateProduct(const Shape &shape, Shape *shape_accum); 38 39 /* 40 * compute the accumulating product of all the values in shape from right to left, 41 * the accumulating results are saved in shape_accum from right to left 42 * 43 * given a shape = [d_n-1, d_n-2, ..., d_0](d_i > 0, i=0,1,...,n-1, elements of shape must be larger than zero), 44 * then *shape_accum = [d_n-1 * d_n-2 * ... *d_0, d_n-2 * d_n-3 * ... *d_0, ..., d_0] 45 * 46 * example: 47 * shape = [2, 8, 32] 48 * shape_accum = [2 * 8 * 32, 8 * 32, 32] 49 * 50 */ 51 Status ShapeToAccumulateProductReverse(const Shape &shape, Shape *shape_accum); 52 53 /* 54 * compute the original shape from the accumulating product shape_accum, 55 * elements of shape_accum is saved from left to right, 56 * given shape_accum = [accum_n-1, accum_n-2, accum_n-3, ..., accum_0] 57 * (accum_i > 0, i=0,1,...,n-1, elements of shape_accum must be larger than zero), 58 * (accum_i-1 % accum_i == 0, i=1,...,n-1) 59 * then *shape = [accum_n-2/accum_n-1, accum_n-3/accum_n-2, ..., accum_0/accum_1] 60 * 61 * example: 62 * shape_accum = [2, 2 * 8, 2 * 8 * 32] 63 * shape = [2, 8, 32] 64 * 65 */ 66 Status AccumulateProductToShape(const Shape &shape_accum, Shape *shape); 67 68 /* 69 * compute the original shape from the accumulating product shape_accum, 70 * elements of shape_accum is saved from right to left, 71 * given shape_accum_reverse = [accum_n-1, accum_n-2, accum_n-3, ..., accum_0] 72 * (accum_i > 0, i=0,1,...,n-1, elements of shape_accum must be larger than zero), 73 * (accum_i % accum_i-1 == 0, i=1,...,n-1) 74 * then *shape = [accum_n-1/accum_n-2, accum_n-2/accum_n-1, ..., accum_1/accum_0] 75 * 76 * example: 77 * shape_accum_reverse = [2 * 8 * 32, 8 * 32, 32] 78 * shape = [2, 8, 32] 79 * 80 */ 81 Status AccumulateProductReverseToShape(const Shape &shape_accum_reverse, Shape *shape); 82 83 /* 84 * given two accumulate product in1_accum and in2_accum, compute the union of in1_accum and in2_accum, 85 * results are saved in out. 86 * i.e. *out_accum = in1_accum U in2_accum 87 * elements of out are saved in increasing order 88 * 89 * example1: 90 * in1_accum = [2, 8] 91 * in2_accum = [4, 8] 92 * out_accum = [2, 4, 8] 93 * 94 * example2: 95 * in1_accum = [2, 4, 16] 96 * in2_accum = [8, 16] 97 * out_accum = [2, 4, 8, 16] 98 */ 99 Status UnifyAccumulateProduct(const Shape &in1_accum, const Shape &in2_accum, Shape *out_accum); 100 101 /* 102 * given two shape in1 = [din1_n-1, din1_n-2, ..., din1_0] and in2 = [din2_m-1, din2_m-2, ..., din2_m] 103 * size = din1_n-1 * din1n-2 * ... * din1_0 = din2_m-1 * din2_m-2 * ... * din2_0 104 * find *out = [dout_k-1, dout_k-2, ..., dout_0], s.t. dout_k-1 * dout_k-2 * ... * dout_0 = size and 105 * suppose in1_accum, in2_accum, and *out_accum is the ShapeToAccumulateProduct result of in1, in2, and *out 106 * then for each din1_i in in1_accum, din1_i is in *out_accumulate, 107 * for each din2_i in in2_accum, din2_i is in *out_accumulate 108 * 109 * example: 110 * in1 = [8, 4] 111 * in2 = [2, 16] 112 * out = [2, 4, 4] 113 */ 114 Status UnifyShape(const Shape &in1, const Shape &in2, Shape *out); 115 116 /* 117 * given two accumulate product in reverse order of in and expand, 118 * in_accum_reverse = [din_n-1, din_n-2, ..., din_0] and expand_pos_reverse = [dexp_n-1, dexp_n-2, ..., dexp_0], 119 * i.e. in_accum_reverse is the ShapeToAccumulateProductReverse result of a shape in, 120 * expand_accum_reverse is the ShapeToAccumulateProductReverse result of a shape expand, 121 * compute the accumulate product in reverse order out_accum_reverse = [dout_k-1, dout_k-2, ..., dout_0], 122 * s.t. elements in out_accum_reverse are union of elements in in_accum_reverse and expand_accum_reverse 123 * (out_accum_reverse = in_accum_reverse U expand_accum_reverse), and 124 * out_accum_reverse is the ShapeToAccumulateProductReverse result of shape expand, 125 * i.e. dout_i > 0, i=0,1,...,k-1, elements of out_accum_reverse must be larger than zero, 126 * dout_i-1 % dout_i == 0, i=1,...,k-1 127 * 128 * example1: 129 * in_accum_reverse = [2 * 8 * 32, 8 * 32, 32] 130 * expand_accum_reverse = [2 * 8 * 32, 32, 8] 131 * out_accum_reverse = [2 * 8 * 4 * 8, 8 * 4 * 8, 4 * 8, 8] 132 * 133 * example2: 134 * in_accum_reverse = [2 * 8 * 32, 8 * 32, 32] 135 * expand_accum_reverse = [2 * 4 * 8, 4 * 8, 8] 136 * out_accum_reverse = [2 * 4 * 2 * 4 * 8, 4 * 2 * 4 * 8, 2 * 4 * 8, 4 * 8, 8] 137 */ 138 Status ExpandAccumulateProduct(const Shape &in_accum_reverse, const Shape &expand_accum_reverse, 139 Shape *out_accum_reverse); 140 141 /* 142 * given a shape in = [din_n-1, din_n-2, ..., d_0], and the expand shape expand= [dexp_m-1, dexp_m-2, ..., dexp_0], 143 * compute the expended shape out = [dout_k-1, dout_k-2, ..., dout_0], 144 * s.t. dout_k-1 * dout_k-2 * ...* dout_0 = din_n-1 * din_n-2 * ... * d_0 145 * suppose in_accum_reverse is the ShapeToAccumulateProductReverse result of in, 146 * expand_accum_reverse is the ShapeToAccumulateProductReverse result of expand, 147 * out_accum_reverse is the ShapeToAccumulateProductReverse result of out, 148 * then out_accum_reverse is the union of in_accum_reverse and expand_accum_reverse 149 * (out_accum_reverse = in_accum_reverse U expand_accum_reverse) 150 * 151 * example1: 152 * in = [2, 8, 32] 153 * expand = [16, 4, 8] 154 * out = [2, 8, 4, 8] 155 * 156 * example2: 157 * in = [2, 8, 32] 158 * expand = [2, 4, 8] 159 * out = [2, 4, 2, 4, 8] 160 */ 161 Status ExpandShape(const Shape &in, const Shape &expand, Shape *out); 162 } // namespace parallel 163 } // namespace mindspore 164 165 #endif // MINDSPORE_CCSRC_FRONTEND_PARALLEL_TENSOR_LAYOUT_SHAPE_UTIL_H_ 166