MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / PermuteDimensions

Method PermuteDimensions

tensorflow/compiler/xla/shape_util.cc:930–986  ·  view source on GitHub ↗

static */

Source from the content-addressed store, hash-verified

928}
929
930/* static */ Shape ShapeUtil::PermuteDimensions(
931 absl::Span<const int64> permutation, const Shape& shape) {
932 Shape new_shape = shape;
933 new_shape.clear_dimensions();
934 for (auto dim : Permute(permutation, shape.dimensions())) {
935 new_shape.add_dimensions(dim);
936 }
937 for (int64 i = 0; i < shape.rank(); i++) {
938 new_shape.set_dynamic_dimension(permutation[i],
939 shape.is_dynamic_dimension(i));
940 }
941
942 // If `shape` has a layout, by contract we choose a new layout such that the
943 // transpose defined by this permutation is a bitcast.
944 //
945 // Some formalism helps to understand the correct way to do this. We're going
946 // to do algebra in the group of permutations of the dimensions of `shape`.
947 //
948 // Since the order of `shape`'s dimensions is not permuted relative to itself,
949 // `shape`'s list of dimensions is isomorphic to the identity I.
950 //
951 // Let `shape`'s layout be L. A layout is a permutation which maps a
952 // minor-to-major physical layout to the order of a shape's logical dims.
953 // Therefore inverse of a layout maps from logical to physical dims, and so
954 // the physical layout of I is simply L'.I = L', where L' is the inverse of L.
955 //
956 // Let the argument `permutation` be P. This is a permutation over `shape`'s
957 // dimensions, so our return value will be a shape with dims P.I = P. Our
958 // goal is to construct a layout permutation L* that we can apply to P such
959 // that the physical dimension ordering of the returned shape is the same
960 // as that of the original shape, namely L'.
961 //
962 // Our returned shape has dims P and layout L*, so its in-memory layout is
963 // L*'.P. Setting this equal to L' and solving for L*, we get:
964 //
965 // L*'.P = L' =>
966 // L*' = L'P' =>
967 // L* = P.L
968 //
969 if (shape.has_layout()) {
970 CHECK(LayoutUtil::IsDenseArray(shape));
971 Layout* new_layout = new_shape.mutable_layout();
972 new_layout->set_format(DENSE);
973 new_layout->clear_minor_to_major();
974 for (auto index : ComposePermutations(
975 permutation, AsInt64Slice(shape.layout().minor_to_major()))) {
976 new_layout->add_minor_to_major(index);
977 }
978 // The permutation accepted by TransposeIsBitcast is the inverse of the
979 // permutation here.
980 CHECK(TransposeIsBitcast(shape, new_shape, InversePermutation(permutation)))
981 << "shape=" << HumanStringWithLayout(shape)
982 << ", new_shape=" << HumanStringWithLayout(new_shape)
983 << ", permutation={" << absl::StrJoin(permutation, ",") << "}";
984 }
985 return new_shape;
986}
987

Callers

nothing calls this directly

Calls 15

ComposePermutationsFunction · 0.85
TransposeIsBitcastFunction · 0.85
InversePermutationFunction · 0.85
clear_dimensionsMethod · 0.80
add_dimensionsMethod · 0.80
set_dynamic_dimensionMethod · 0.80
is_dynamic_dimensionMethod · 0.80
has_layoutMethod · 0.80
mutable_layoutMethod · 0.80
minor_to_majorMethod · 0.80
PermuteFunction · 0.70
AsInt64SliceFunction · 0.70

Tested by

no test coverage detected