/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "paddle/phi/common/scalar.h" #include "test/cpp/auto_parallel/spmd_rule_test_util.h" namespace paddle { namespace distributed { namespace auto_parallel { TEST(MatmulSPMDRule, Ctor) { // build input data class std::vector x_shape = {64, 32}; std::vector y_shape = {32, 48}; std::vector mesh_shape = {2, 4}; std::vector process_ids = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr y_dist_attr = TensorDistAttr(); y_dist_attr.set_process_mesh(process_mesh); y_dist_attr.set_dims_mapping(std::vector({-1, -1})); y_dist_attr.set_dynamic_dims(std::vector({false, false})); size_t input_size = 2; size_t output_size = 1; phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor y(common::make_ddim(y_shape), y_dist_attr); auto matmul_spmd_rule = phi::distributed::SpmdRuleFactory::Instance().GetSpmdRule("matmul"); // mk[1, -1],kn[-1, -1] --> mk[1, -1],kn[-1, -1] = nm[1, -1] partial[] phi::distributed::InferSpmdContext ctx( {x, y}, {/*trans_x=*/false, /*trans_y=*/false}); auto inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); EXPECT_EQ(inferred_dist_attrs.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs.second.size(), output_size); check_dim_mapping(inferred_dist_attrs.first[0], {1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); VLOG(4) << "test1 done." << std::endl << std::endl << std::endl; // mk[-1,-1],kn[-1,0] --> mk[-1,-1],kn[-1,0] = nm[-1,0] partial[] x_dist_attr.set_dims_mapping({-1, -1}); y_dist_attr.set_dims_mapping({-1, 0}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/false, /*trans_x=*/false}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, 0}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, 0}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); VLOG(4) << "test2 done." << std::endl << std::endl << std::endl; // mk[1, 0],kn[-1,-1] --> mk[1, 0],kn[0, -1] = nm[1, -1] partial[0]: done x_dist_attr.set_dims_mapping({1, 0}); y_dist_attr.set_dims_mapping({-1, -1}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/false, /*trans_x=*/false}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {1, 0}); check_dim_mapping(inferred_dist_attrs.first[1], {0, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); check_partial_dims(inferred_dist_attrs.second[0], {0}); VLOG(4) << "test3 done." << std::endl << std::endl << std::endl; // mk[-1,-1],kn[1,0] --> mk[-1, 1],kn[1, 0] = nm[-1, 0] partial[1]: done x_dist_attr.set_dims_mapping({-1, -1}); y_dist_attr.set_dims_mapping({1, 0}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/false, /*trans_x=*/false}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {-1, 1}); check_dim_mapping(inferred_dist_attrs.first[1], {1, 0}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, 0}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); check_partial_dims(inferred_dist_attrs.second[0], {1}); VLOG(4) << "test4 done." << std::endl << std::endl << std::endl; // abcmk[1, 0, -1, -1],kn[-1, -1] --> abcmk[1, 0, -1, -1],kn[-1, -1] = // abcmn[1, 0, -1, -1] partial[]: done x_shape = {512, 48, 64, 32}; x_dist_attr.set_dims_mapping({0, 1, -1, -1}); y_dist_attr.set_dims_mapping({-1, -1}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/false, /*trans_x=*/false}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {0, 1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, 1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); VLOG(4) << "test5 done." << std::endl << std::endl << std::endl; // abcmk[1, -1, -1, 0],kn[-1, -1] --> abcmk[1, -1, -1, 0],kn[0, -1] = abcmn[1, // -1, -1, -1] partial[0]: done x_dist_attr.set_dims_mapping({1, -1, -1, 0}); y_dist_attr.set_dims_mapping({-1, -1}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/false, /*trans_x=*/false}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {1, -1, -1, 0}); check_dim_mapping(inferred_dist_attrs.first[1], {0, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {1, -1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); check_partial_dims(inferred_dist_attrs.second[0], {0}); VLOG(4) << "test6 done." << std::endl << std::endl << std::endl; // abcmk[1, -1, -1, 0], kn[-1, -1] --> abcmk[1, -1, -1, 0],kn[-1, -1] = // abcmn[1, -1, 0, -1] partial[]: done x_dist_attr.set_dims_mapping({1, -1, -1, 0}); y_dist_attr.set_dims_mapping({-1, -1}); y_shape = {64, 48}; x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/true, /*trans_x=*/false}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {1, -1, -1, 0}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {1, -1, 0, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); VLOG(4) << "test7 done." << std::endl << std::endl << std::endl; // abcmk[-1, -1, -1, -1], kn[1, 0] --> abcmk[-1, -1, -1, 0],kn[1, 0] = // abcmn[-1, -1, -1, 1] partial[0]: done x_dist_attr.set_dims_mapping({-1, -1, -1, -1}); y_dist_attr.set_dims_mapping({1, 0}); y_shape = {48, 32}; x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/false, /*trans_x=*/true}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1, -1, 0}); check_dim_mapping(inferred_dist_attrs.first[1], {1, 0}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, -1, 1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); check_partial_dims(inferred_dist_attrs.second[0], {0}); clean_partial_dims(&inferred_dist_attrs.second[0], {0}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); VLOG(4) << "test8 done." << std::endl << std::endl << std::endl; // abcmk[-1, -1, 0, 1]+trans_x=true, kn[1, 0]+trans_y=true --> abcmk[-1, -1, // 0, -1],kn[-1, 0] = abcmn[-1, -1, 1, -1] partial[0]: done x_dist_attr.set_dims_mapping({-1, -1, 0, 1}); y_dist_attr.set_dims_mapping({1, 0}); y_shape = {48, 64}; x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/true, /*trans_x=*/true}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1, 0, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {1, 0}); // conflict and should be changed to [1, 0] check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, -1, 1}); check_partial_dims(inferred_dist_attrs.second[0], {0}); clean_partial_status(&inferred_dist_attrs.second[0]); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); EXPECT_ANY_THROW(set_partial_status(&inferred_dist_attrs.second[0], {1})); VLOG(4) << "test9 done." << std::endl << std::endl << std::endl; // abcmk[-1, -1, 1, 0], kn[1, 0] --> abcmk[-1, -1, -1, 0],kn[1, 0] = // abcmn[-1, -1, -1, 1] partial[0]: done x_dist_attr.set_dims_mapping({-1, -1, 1, 0}); y_dist_attr.set_dims_mapping({1, 0}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/true, /*trans_x=*/true}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1, -1, 0}); check_dim_mapping(inferred_dist_attrs.first[1], {1, -1}); // conflict and should be changed to [1, -1] check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, 0, 1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); VLOG(4) << "test10 done." << std::endl << std::endl << std::endl; // abcmk[-1, -1, 1, 0], kn[0, 1] --> abcmk[-1, -1, 1, 0],kn[0, 1] = // abcmn[-1, -1, 1, -1] partial[0]: x_dist_attr.set_dims_mapping({-1, -1, 0, 1}); y_dist_attr.set_dims_mapping({1, 0}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); ctx = phi::distributed::InferSpmdContext( {x, y}, {/*trans_x=*/true, /*trans_x=*/true}); inferred_dist_attrs = matmul_spmd_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, -1, 1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); check_partial_dims(inferred_dist_attrs.second[0], {0}); // try to clean partial on a dim which is not partial EXPECT_ANY_THROW(clean_partial_dims(&inferred_dist_attrs.second[0], {1})); // try to clean partial on a dims which is sharded EXPECT_ANY_THROW(set_partial_status(&inferred_dist_attrs.second[0], {1})); // clean partial and then re-set again clean_partial_dims(&inferred_dist_attrs.second[0], {0}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), false); set_partial_status(&inferred_dist_attrs.second[0], {0}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); check_partial_dims(inferred_dist_attrs.second[0], {0}); VLOG(4) << "test11 done." << std::endl << std::endl << std::endl; } TEST(IndexPut, Ctor) { // build input data class std::vector x_shape = {64, 64, 64}; std::vector indice_shape = {32}; std::vector value_shape = {32, 64}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({-1, 0, 1})); x_dist_attr.set_dynamic_dims(std::vector({false, false, false})); TensorDistAttr value_dist_attr = TensorDistAttr(); value_dist_attr.set_process_mesh(process_mesh); value_dist_attr.set_dims_mapping(std::vector({-1, -1})); value_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr indice_dist_attr = TensorDistAttr(); indice_dist_attr.set_process_mesh(process_mesh); indice_dist_attr.set_dims_mapping(std::vector({-1})); indice_dist_attr.set_dynamic_dims(std::vector({false})); // Test forward. // [-1,0, 1], [[-1],[-1]], [-1,-1] --> [-1,-1, 1] // infer input:[-1,-1, 1], [[-1],[-1]], [-1,1] phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor value(common::make_ddim(value_shape), value_dist_attr); std::vector indices; for (int i = 0; i < 2; ++i) { phi::distributed::DistMetaTensor indice(common::make_ddim(indice_shape), indice_dist_attr); indices.push_back(indice); } phi::distributed::SpmdInfo forward_info = phi::distributed::IndexPutInferSpmd(x, indices, value); size_t input_size = 3; size_t output_size = 1; EXPECT_EQ(forward_info.first.size(), input_size); EXPECT_EQ(forward_info.second.size(), output_size); check_dim_mapping(forward_info.first[0], {-1, -1, 1}); std::vector indices_dist_attr = paddle::get<1>(forward_info.first[1]); for (auto& attr : indices_dist_attr) { check_dim_mapping(attr, {-1}); } check_dim_mapping(forward_info.first[2], {-1, 1}); check_dim_mapping(forward_info.second[0], {-1, -1, 1}); VLOG(4) << "test forward done."; // Test backward. // [-1,0, 1], [[-1],[-1]], [-1,-1],[-1,0, 1] --> [-1,-1, 1], [-1,1] // infer input:[-1,-1, 1], [[-1],[-1]], [-1,1],[-1,-1, 1] phi::distributed::DistMetaTensor out_grad(common::make_ddim(x_shape), x_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::IndexPutGradInferSpmd(x, indices, value, out_grad); input_size = 4; output_size = 2; EXPECT_EQ(backward_info.first.size(), input_size); EXPECT_EQ(backward_info.second.size(), output_size); check_dim_mapping(backward_info.first[0], {-1, -1, 1}); indices_dist_attr = paddle::get<1>(backward_info.first[1]); for (auto& attr : indices_dist_attr) { check_dim_mapping(attr, {-1}); } check_dim_mapping(backward_info.first[2], {-1, 1}); check_dim_mapping(backward_info.first[3], {-1, -1, 1}); check_dim_mapping(backward_info.second[0], {-1, -1, 1}); check_dim_mapping(backward_info.second[1], {-1, 1}); VLOG(4) << "test backward done."; } TEST(InstanceNorm, Ctor) { // build input data class std::vector x_shape = {64, 64, 64, 64}; // N,C,H,W std::vector scale_shape = {64}; std::vector bias_shape = {64}; std::vector mean_and_variance_shape = {64, 64}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false, false, false})); TensorDistAttr scale_dist_attr = TensorDistAttr(); scale_dist_attr.set_process_mesh(process_mesh); scale_dist_attr.set_dims_mapping(std::vector({-1})); scale_dist_attr.set_dynamic_dims(std::vector({false})); TensorDistAttr bias_dist_attr = TensorDistAttr(); bias_dist_attr.set_process_mesh(process_mesh); bias_dist_attr.set_dims_mapping(std::vector({-1})); bias_dist_attr.set_dynamic_dims(std::vector({false})); float epsilon = 1e-5; // Test forward. // [-1,0, 1, -1], [-1], [-1] --> [-1,0, -1, -1], [-1,0], [-1,0] x_dist_attr.set_dims_mapping({-1, 0, 1, -1}); scale_dist_attr.set_dims_mapping(std::vector{-1}); bias_dist_attr.set_dims_mapping(std::vector{-1}); phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor scale(common::make_ddim(scale_shape), scale_dist_attr); phi::distributed::DistMetaTensor bias(common::make_ddim(bias_shape), bias_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::InstanceNormInferSpmd(x, scale, bias, epsilon); size_t input_size = 3; size_t output_size = 3; EXPECT_EQ(forward_info.first.size(), input_size); EXPECT_EQ(forward_info.second.size(), output_size); check_dim_mapping(forward_info.first[0], {-1, 0, -1, -1}); check_dim_mapping(forward_info.first[1], {-1}); check_dim_mapping(forward_info.first[2], {-1}); check_dim_mapping(forward_info.second[0], {-1, 0, -1, -1}); check_dim_mapping(forward_info.second[1], {-1, 0}); check_dim_mapping(forward_info.second[2], {-1, 0}); VLOG(4) << "test forward done."; // Test backward. // [-1,0, 1, -1], [-1], [-1,-1], [-1,-1], [-1,0, 1, // -1]-->[-1,0,-1,-1],[-1],[-1] TensorDistAttr mean_and_variance_dist_attr = TensorDistAttr(); mean_and_variance_dist_attr.set_process_mesh(process_mesh); mean_and_variance_dist_attr.set_dims_mapping(std::vector({-1, -1})); mean_and_variance_dist_attr.set_dynamic_dims( std::vector({false, false})); phi::distributed::DistMetaTensor y_grad(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor saved_mean( common::make_ddim(mean_and_variance_shape), mean_and_variance_dist_attr); phi::distributed::DistMetaTensor saved_variance( common::make_ddim(mean_and_variance_shape), mean_and_variance_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::InstanceNormGradInferSpmd( x, scale, bias, saved_mean, saved_variance, y_grad, epsilon); input_size = 5; output_size = 3; EXPECT_EQ(backward_info.first.size(), input_size); EXPECT_EQ(backward_info.second.size(), output_size); check_dim_mapping(backward_info.first[0], {-1, 0, -1, -1}); check_dim_mapping(backward_info.first[1], {-1}); check_dim_mapping(backward_info.first[2], {-1, 0}); check_dim_mapping(backward_info.first[3], {-1, 0}); check_dim_mapping(backward_info.first[4], {-1, 0, -1, -1}); check_dim_mapping(backward_info.second[0], {-1, 0, -1, -1}); check_dim_mapping(backward_info.second[1], {-1}); check_dim_mapping(backward_info.second[2], {-1}); VLOG(4) << "test backward done."; } TEST(LayerNormSPMDRule, Ctor) { // build input data class std::vector x_shape = {64, 32, 1024}; std::vector scale_shape = {1024}; std::vector bias_shape = {1024}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({1, -1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false, false})); TensorDistAttr scale_dist_attr = TensorDistAttr(); scale_dist_attr.set_process_mesh(process_mesh); scale_dist_attr.set_dims_mapping(std::vector({-1})); scale_dist_attr.set_dynamic_dims(std::vector({false})); TensorDistAttr bias_dist_attr = TensorDistAttr(); bias_dist_attr.set_process_mesh(process_mesh); bias_dist_attr.set_dims_mapping(std::vector({-1})); bias_dist_attr.set_dynamic_dims(std::vector({false})); double epsilon = 1e-5; int begin_norm_axis = 2; auto layer_norm_rule = phi::distributed::SpmdRuleFactory::Instance().GetSpmdRule("layer_norm"); // ijk[1, -1, -1], k[-1], k[-1] --> ijk[1, -1, -1], z[1], z[1], z=ij, // begin_norm_axis=2 begin_norm_axis = 2; x_dist_attr.set_dims_mapping({1, -1, -1}); scale_dist_attr.set_dims_mapping(std::vector{-1}); bias_dist_attr.set_dims_mapping(std::vector{-1}); phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor scale(common::make_ddim(scale_shape), scale_dist_attr); phi::distributed::DistMetaTensor bias(common::make_ddim(bias_shape), bias_dist_attr); phi::distributed::InferSpmdContext ctx({x, scale, bias}, {epsilon, begin_norm_axis}); auto inferred_dist_attrs = layer_norm_rule.InferForward(ctx); size_t input_size = 3; size_t output_size = 3; EXPECT_EQ(inferred_dist_attrs.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs.second.size(), output_size); check_dim_mapping(inferred_dist_attrs.first[0], {1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1}); check_dim_mapping(inferred_dist_attrs.first[2], {-1}); check_dim_mapping(inferred_dist_attrs.second[0], {1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {1, -1}); check_dim_mapping(inferred_dist_attrs.second[2], {1, -1}); VLOG(4) << "test1 done."; // ijk[1, 0, -1],k[0],k[0] --> ijk[1, -1, -1],z[1, 0],z[1, 0], // begin_norm_axis=2 begin_norm_axis = 2; x_dist_attr.set_dims_mapping({1, 0, -1}); scale_dist_attr.set_dims_mapping(std::vector{0}); bias_dist_attr.set_dims_mapping(std::vector{0}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); scale = phi::distributed::DistMetaTensor(common::make_ddim(scale_shape), scale_dist_attr); bias = phi::distributed::DistMetaTensor(common::make_ddim(bias_shape), bias_dist_attr); ctx = phi::distributed::InferSpmdContext({x, scale, bias}, {epsilon, begin_norm_axis}); inferred_dist_attrs = layer_norm_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {1, 0, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1}); check_dim_mapping(inferred_dist_attrs.first[2], {-1}); check_dim_mapping(inferred_dist_attrs.second[0], {1, 0, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {1, 0}); check_dim_mapping(inferred_dist_attrs.second[2], {1, 0}); VLOG(4) << "test2 done."; // ijk[0, -1, -1],y[-1],y[1] --> ijk[0, -1, -1], i[0], i[0], y=jk, // begin_norm_axis=1 begin_norm_axis = 1; x_dist_attr.set_dims_mapping({0, -1, -1}); scale_dist_attr.set_dims_mapping(std::vector{-1}); bias_dist_attr.set_dims_mapping(std::vector{1}); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); scale = phi::distributed::DistMetaTensor(common::make_ddim(scale_shape), scale_dist_attr); bias = phi::distributed::DistMetaTensor(common::make_ddim(bias_shape), bias_dist_attr); ctx = phi::distributed::InferSpmdContext({x, scale, bias}, {epsilon, begin_norm_axis}); inferred_dist_attrs = layer_norm_rule.InferForward(ctx); check_dim_mapping(inferred_dist_attrs.first[0], {0, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1}); check_dim_mapping(inferred_dist_attrs.first[2], {-1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {0}); check_dim_mapping(inferred_dist_attrs.second[2], {0}); VLOG(4) << "test3 done."; } TEST(MatmulSPMDRuleInferBackward, Ctor) { // build input data class std::vector x_shape = {512, 1024, 64, 32}; std::vector y_shape = {512, 1, 32, 48}; std::vector out_shape = {512, 1024, 64, 48}; std::vector mesh_shape = {2, 4}; std::vector process_ids = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping( std::vector({-1, 1, 0, -1})); // no affect x_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr y_dist_attr = TensorDistAttr(); y_dist_attr.set_process_mesh(process_mesh); y_dist_attr.set_dims_mapping( std::vector({0, 1, -1, -1})); // no affect y_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr out_dist_attr = TensorDistAttr(); out_dist_attr.set_process_mesh(process_mesh); out_dist_attr.set_dims_mapping(std::vector({-1, -1, 1, -1})); out_dist_attr.set_dynamic_dims(std::vector({false, false})); out_dist_attr.set_partial_status(std::vector({0})); phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor y(common::make_ddim(y_shape), y_dist_attr); phi::distributed::DistMetaTensor out(common::make_ddim(out_shape), out_dist_attr); auto matmul_spmd_rule = phi::distributed::SpmdRuleFactory::Instance().GetSpmdRule("matmul"); // TODO(zyc) update in future: propagate the partial in inferbackward // abmn[-1, -1, 1, -1] + partial[0] --> abmk[-1, -1, 1, -1], a1kn[-1, -1, -1, // -1] phi::distributed::InferSpmdContext ctx( {x, y, out}, {/*trans_x=*/false, /*trans_x=*/false}); auto inferred_dist_attrs = matmul_spmd_rule.InferBackward(ctx); size_t input_size = 2; size_t output_size = 1; EXPECT_EQ(inferred_dist_attrs.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs.second.size(), output_size); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1, 1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, 1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.first[0]), false); EXPECT_EQ(is_partial(inferred_dist_attrs.first[1]), false); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); VLOG(4) << "test1 done." << std::endl << std::endl << std::endl; } TEST(GroupNorm, Ctor) { // build input data class std::vector x_shape = {64, 64, 64, 64}; // N,C,H,W std::vector scale_shape = {64}; std::vector bias_shape = {64}; std::vector mean_and_variance_shape = {64, 64}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false, false, false})); TensorDistAttr scale_dist_attr = TensorDistAttr(); scale_dist_attr.set_process_mesh(process_mesh); scale_dist_attr.set_dims_mapping(std::vector({-1})); scale_dist_attr.set_dynamic_dims(std::vector({false})); TensorDistAttr bias_dist_attr = TensorDistAttr(); bias_dist_attr.set_process_mesh(process_mesh); bias_dist_attr.set_dims_mapping(std::vector({-1})); bias_dist_attr.set_dynamic_dims(std::vector({false})); float epsilon = 1e-5; int groups = -1; std::string data_format = "NCHW"; // Test forward. // [0, 1, -1, -1], [-1], [-1] --> input: [0, -1, -1, -1], [-1], [-1] // output:[0,-1, -1, -1], [0], [0] x_dist_attr.set_dims_mapping({0, 1, -1, -1}); scale_dist_attr.set_dims_mapping(std::vector{-1}); bias_dist_attr.set_dims_mapping(std::vector{-1}); phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor scale(common::make_ddim(scale_shape), scale_dist_attr); phi::distributed::DistMetaTensor bias(common::make_ddim(bias_shape), bias_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::GroupNormInferSpmd( x, scale, bias, epsilon, groups, data_format); size_t input_size = 3; size_t output_size = 3; EXPECT_EQ(forward_info.first.size(), input_size); EXPECT_EQ(forward_info.second.size(), output_size); check_dim_mapping(forward_info.first[0], {0, -1, -1, -1}); check_dim_mapping(forward_info.first[1], {-1}); check_dim_mapping(forward_info.first[2], {-1}); check_dim_mapping(forward_info.second[0], {0, -1, -1, -1}); check_dim_mapping(forward_info.second[1], {0, -1}); check_dim_mapping(forward_info.second[2], {0, -1}); VLOG(4) << "test forward done."; // Test backward. // [0, 1, -1, -1], [-1],[-1], [0, 1, -1, -1],[-1], [-1], [0, 1, -1, -1] // infer input:[0, -1, -1, -1], [-1],[-1], [0, -1, -1, -1],[0], [0], [0, -1, // -1, -1] // infer output:[0, 1, -1, -1], [-1],[-1] TensorDistAttr mean_and_variance_dist_attr = TensorDistAttr(); mean_and_variance_dist_attr.set_process_mesh(process_mesh); mean_and_variance_dist_attr.set_dims_mapping(std::vector({-1, -1})); mean_and_variance_dist_attr.set_dynamic_dims(std::vector({false})); phi::distributed::DistMetaTensor y(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor y_grad(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor mean( common::make_ddim(mean_and_variance_shape), mean_and_variance_dist_attr); phi::distributed::DistMetaTensor variance( common::make_ddim(mean_and_variance_shape), mean_and_variance_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::GroupNormGradInferSpmd(x, scale, bias, y, mean, variance, y_grad, epsilon, groups, data_format); input_size = 7; output_size = 3; EXPECT_EQ(backward_info.first.size(), input_size); EXPECT_EQ(backward_info.second.size(), output_size); check_dim_mapping(backward_info.first[0], {0, -1, -1, -1}); check_dim_mapping(backward_info.first[1], {-1}); check_dim_mapping(backward_info.first[2], {-1}); check_dim_mapping(backward_info.first[3], {0, -1, -1, -1}); check_dim_mapping(backward_info.first[4], {0, -1}); check_dim_mapping(backward_info.first[5], {0, -1}); check_dim_mapping(backward_info.first[6], {0, -1, -1, -1}); check_dim_mapping(backward_info.second[0], {0, -1, -1, -1}); check_dim_mapping(backward_info.second[1], {-1}); check_dim_mapping(backward_info.second[2], {-1}); VLOG(4) << "test backward done."; } TEST(ReplicatedSPMDRule, Ctor) { // build input data class std::vector x_shape = {10, 10, 32, 48}; std::vector y_shape = {32, 48}; std::vector out1_shape = {10, 10, 32, 48}; std::vector out2_shape = {10, 32, 48}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({-1, 1, -1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr y_dist_attr = TensorDistAttr(); y_dist_attr.set_process_mesh(process_mesh); y_dist_attr.set_dims_mapping(std::vector({0, -1})); // no affect y_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr out1_dist_attr = TensorDistAttr(); out1_dist_attr.set_process_mesh(process_mesh); out1_dist_attr.set_dims_mapping(std::vector({-1, -1, 1, -1})); out1_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr out2_dist_attr = TensorDistAttr(); out2_dist_attr.set_process_mesh(process_mesh); out2_dist_attr.set_dims_mapping(std::vector({-1, 1, -1})); out2_dist_attr.set_dynamic_dims(std::vector({false, false})); phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor y(common::make_ddim(y_shape), y_dist_attr); phi::distributed::DistMetaTensor out1(common::make_ddim(out1_shape), out1_dist_attr); phi::distributed::DistMetaTensor out2(common::make_ddim(out2_shape), out2_dist_attr); // 2 inputs 2 outputs // call in vector arguments format auto inferred_dist_attrs_st = phi::distributed::ReplicatedInferSpmd({&x, &y}, {&out1, &out2}); // call in variadic arguments format auto inferred_dist_attrs_dy = phi::distributed::VariadicReplicatedInferSpmd(x, y, &out1, &out2); size_t input_size = 2; size_t output_size = 2; EXPECT_EQ(inferred_dist_attrs_st.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_st.second.size(), output_size); EXPECT_EQ(inferred_dist_attrs_dy.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_dy.second.size(), output_size); check_dim_mapping(inferred_dist_attrs_st.first[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_st.first[1], {-1, -1}); check_dim_mapping(inferred_dist_attrs_st.second[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_st.second[1], {-1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs_st.first[0]), false); EXPECT_EQ(is_partial(inferred_dist_attrs_st.first[1]), false); EXPECT_EQ(is_partial(inferred_dist_attrs_st.second[0]), false); EXPECT_EQ(is_partial(inferred_dist_attrs_st.second[1]), false); EXPECT_EQ(inferred_dist_attrs_st.first, inferred_dist_attrs_dy.first); EXPECT_EQ(inferred_dist_attrs_st.second, inferred_dist_attrs_dy.second); VLOG(4) << "test1 done." << std::endl << std::endl << std::endl; // 3 inputs 1 outputs // call in vector arguments format inferred_dist_attrs_st = phi::distributed::ReplicatedInferSpmd({&x, &y, &out1}, {&out2}); // call in variadic arguments format inferred_dist_attrs_dy = phi::distributed::VariadicReplicatedInferSpmd(x, y, out1, &out2); input_size = 3; output_size = 1; EXPECT_EQ(inferred_dist_attrs_st.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_st.second.size(), output_size); EXPECT_EQ(inferred_dist_attrs_dy.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_dy.second.size(), output_size); check_dim_mapping(inferred_dist_attrs_dy.first[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.first[1], {-1, -1}); check_dim_mapping(inferred_dist_attrs_dy.first[2], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[0], {-1, -1, -1}); EXPECT_EQ(inferred_dist_attrs_st.first, inferred_dist_attrs_dy.first); EXPECT_EQ(inferred_dist_attrs_st.second, inferred_dist_attrs_dy.second); VLOG(4) << "test2 done." << std::endl << std::endl << std::endl; // 1 inputs 3 outputs backward // call in vector arguments format inferred_dist_attrs_st = phi::distributed::ReplicatedInferSpmdReverse({&x}, {&y, &out1, &out2}); // call in variadic arguments format inferred_dist_attrs_dy = phi::distributed::VariadicReplicatedInferSpmdReverse(x, &y, &out1, &out2); input_size = 1; output_size = 3; EXPECT_EQ(inferred_dist_attrs_st.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_st.second.size(), output_size); EXPECT_EQ(inferred_dist_attrs_dy.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_dy.second.size(), output_size); check_dim_mapping(inferred_dist_attrs_dy.first[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[0], {-1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[1], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[2], {-1, -1, -1}); EXPECT_EQ(inferred_dist_attrs_st.first, inferred_dist_attrs_dy.first); EXPECT_EQ(inferred_dist_attrs_st.second, inferred_dist_attrs_dy.second); VLOG(4) << "test3 done." << std::endl << std::endl << std::endl; } TEST(DefaultDataParallelSPMDRule, Ctor) { // build input data class std::vector x_shape = {10, 10, 32, 48}; std::vector y_shape = {32, 48}; std::vector out1_shape = {10, 10, 32, 48}; std::vector out2_shape = {10, 32, 48}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, 1})); x_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr y_dist_attr = TensorDistAttr(); y_dist_attr.set_process_mesh(process_mesh); y_dist_attr.set_dims_mapping(std::vector({0, 1})); y_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr out1_dist_attr = TensorDistAttr(); out1_dist_attr.set_process_mesh(process_mesh); out1_dist_attr.set_dims_mapping(std::vector({-1, -1, 1, -1})); out1_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr out2_dist_attr = TensorDistAttr(); out2_dist_attr.set_process_mesh(process_mesh); out2_dist_attr.set_dims_mapping(std::vector({-1, 1, -1})); out2_dist_attr.set_dynamic_dims(std::vector({false, false})); phi::distributed::DistMetaTensor x(common::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor y(common::make_ddim(y_shape), y_dist_attr); phi::distributed::DistMetaTensor out1(common::make_ddim(out1_shape), out1_dist_attr); phi::distributed::DistMetaTensor out2(common::make_ddim(out2_shape), out2_dist_attr); // 2 inputs 2 outputs, batch axis sharding is propagated while other axes are // replicated call in vector arguments format auto inferred_dist_attrs_st = phi::distributed::DefaultDataParallelInferSpmd({&x, &y}, {&out1, &out2}); // call in variadic arguments format auto inferred_dist_attrs_dy = phi::distributed::VariadicDefaultDataParallelInferSpmd( x, y, &out1, &out2); size_t input_size = 2; size_t output_size = 2; EXPECT_EQ(inferred_dist_attrs_st.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_st.second.size(), output_size); EXPECT_EQ(inferred_dist_attrs_dy.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_dy.second.size(), output_size); check_dim_mapping(inferred_dist_attrs_st.first[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_st.first[1], {0, -1}); check_dim_mapping(inferred_dist_attrs_st.second[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_st.second[1], {0, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs_st.first[0]), false); EXPECT_EQ(is_partial(inferred_dist_attrs_st.first[1]), false); EXPECT_EQ(is_partial(inferred_dist_attrs_st.second[0]), false); EXPECT_EQ(is_partial(inferred_dist_attrs_st.second[1]), false); EXPECT_EQ(inferred_dist_attrs_st.first, inferred_dist_attrs_dy.first); EXPECT_EQ(inferred_dist_attrs_st.second, inferred_dist_attrs_dy.second); VLOG(4) << "test1 done." << std::endl << std::endl << std::endl; // 1 inputs 3 outputs, batch axis is un-sharded // call in vector arguments format inferred_dist_attrs_st = phi::distributed::DefaultDataParallelInferSpmd({&x}, {&y, &out1, &out2}); // call in variadic arguments format inferred_dist_attrs_dy = phi::distributed::VariadicDefaultDataParallelInferSpmd( x, &y, &out1, &out2); input_size = 1; output_size = 3; EXPECT_EQ(inferred_dist_attrs_st.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_st.second.size(), output_size); EXPECT_EQ(inferred_dist_attrs_dy.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_dy.second.size(), output_size); check_dim_mapping(inferred_dist_attrs_dy.first[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[0], {-1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[1], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[2], {-1, -1, -1}); EXPECT_EQ(inferred_dist_attrs_st.first, inferred_dist_attrs_dy.first); EXPECT_EQ(inferred_dist_attrs_st.second, inferred_dist_attrs_dy.second); VLOG(4) << "test2 done." << std::endl << std::endl << std::endl; // conflict on batch axis x_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); y_dist_attr.set_dims_mapping(std::vector({-1, -1})); out1_dist_attr.set_dims_mapping(std::vector({1, -1, -1, -1})); x = phi::distributed::DistMetaTensor(common::make_ddim(x_shape), x_dist_attr); y = phi::distributed::DistMetaTensor(common::make_ddim(y_shape), y_dist_attr); out1 = phi::distributed::DistMetaTensor(common::make_ddim(out1_shape), out1_dist_attr); EXPECT_ANY_THROW(inferred_dist_attrs_st = phi::distributed::DefaultDataParallelInferSpmd( {&x, &y, &out1}, {&out2})); // call in variadic arguments format EXPECT_ANY_THROW(inferred_dist_attrs_dy = phi::distributed::VariadicDefaultDataParallelInferSpmd( x, y, out1, &out2)); VLOG(4) << "test3 done." << std::endl << std::endl << std::endl; // 2 inputs 2 outputs, backward // call in vector arguments format out1_dist_attr.set_dims_mapping(std::vector({-1, 0, 1, -1})); out2_dist_attr.set_dims_mapping(std::vector({0, 1, -1})); out1 = phi::distributed::DistMetaTensor(common::make_ddim(out1_shape), out1_dist_attr); out2 = phi::distributed::DistMetaTensor(common::make_ddim(out2_shape), out2_dist_attr); inferred_dist_attrs_st = phi::distributed::DefaultDataParallelInferSpmdReverse({&x, &y}, {&out1, &out2}); // call in variadic arguments format inferred_dist_attrs_dy = phi::distributed::VariadicDefaultDataParallelInferSpmdReverse( x, y, &out1, &out2); input_size = 2; output_size = 2; EXPECT_EQ(inferred_dist_attrs_st.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_st.second.size(), output_size); EXPECT_EQ(inferred_dist_attrs_dy.first.size(), input_size); EXPECT_EQ(inferred_dist_attrs_dy.second.size(), output_size); check_dim_mapping(inferred_dist_attrs_dy.first[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.first[1], {0, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs_dy.second[1], {0, -1, -1}); EXPECT_EQ(inferred_dist_attrs_st.first, inferred_dist_attrs_dy.first); EXPECT_EQ(inferred_dist_attrs_st.second, inferred_dist_attrs_dy.second); VLOG(4) << "test4 done." << std::endl << std::endl << std::endl; } TEST(ConcatRule, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); std::vector> shapes = { {16, 16, 16}, {4, 16, 16}, {2, 16, 16}}; std::vector> dim_mappings = { {-1, 0, 1}, {-1, 1, 0}, {-1, -1, 0}}; std::vector> partial_status = {{}, {}, {1}}; auto build_inputs = [&] { std::vector inputs; for (int i = 0; i < 3; i++) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mappings[i]); t_dist_attr.set_dynamic_dims({false, false, false}); auto input = phi::distributed::DistMetaTensor( common::make_ddim(shapes[i]), t_dist_attr); inputs.push_back(input); } return inputs; }; // test 1, inputs are aligned according to cost, and partial status is cleared auto inputs = build_inputs(); auto inferred_dist_attrs = phi::distributed::ConcatInferSpmd(inputs, 0); // list of tensor => single tensor EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(1)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(1)); EXPECT_TRUE( paddle::holds_alternative>( inferred_dist_attrs.first[0])); EXPECT_TRUE(paddle::holds_alternative( inferred_dist_attrs.second[0])); auto& inputs_infer1 = PADDLE_GET_CONST(std::vector, inferred_dist_attrs.first[0]); for (auto e : inputs_infer1) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } check_dim_mapping(inferred_dist_attrs.second[0], {-1, 1, 0}); check_partial_dims(inferred_dist_attrs.second[0], {}); auto build_output = [&](const TensorDistAttr& t_dist_attr, const std::vector& shape) { return phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); }; auto& output_dist_attr = PADDLE_GET_CONST(TensorDistAttr, inferred_dist_attrs.second[0]); auto output = build_output(output_dist_attr, {22, 16, 16}); // test reverse auto inferred_reverse_attrs = phi::distributed::ConcatInferSpmdReverse(inputs, output, 0); auto& inputs_infer1_reverse = PADDLE_GET_CONST( std::vector, inferred_reverse_attrs.first[0]); for (auto e : inputs_infer1_reverse) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } check_dim_mapping(inferred_reverse_attrs.second[0], output_dist_attr.dims_mapping()); // test grad auto inferred_grad_attrs = phi::distributed::ConcatGradInferSpmdDynamic(inputs, output, 0); auto& inputs_infer1_grad = PADDLE_GET_CONST(std::vector, inferred_grad_attrs.first[0]); for (auto e : inputs_infer1_grad) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } check_dim_mapping(inferred_grad_attrs.first[1], output_dist_attr.dims_mapping()); auto& inferred_grad = PADDLE_GET_CONST(std::vector, inferred_grad_attrs.second[0]); for (auto e : inferred_grad) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } // test 2,force replicate along concat axis inputs = build_inputs(); inferred_dist_attrs = phi::distributed::ConcatInferSpmd(inputs, 1); // list of tensor => single tensor EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(1)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(1)); EXPECT_TRUE( paddle::holds_alternative>( inferred_dist_attrs.first[0])); EXPECT_TRUE(paddle::holds_alternative( inferred_dist_attrs.second[0])); auto& inputs_infer2 = PADDLE_GET_CONST(std::vector, inferred_dist_attrs.first[0]); for (auto e : inputs_infer2) { check_dim_mapping(e, {1, -1, 0}); check_partial_dims(e, {}); } check_dim_mapping(inferred_dist_attrs.second[0], {1, -1, 0}); check_partial_dims(inferred_dist_attrs.second[0], {}); // test 3,special case: concat one dimensional tensor shapes = {{16}, {32}, {64}}; dim_mappings = {{0}, {1}, {-1}}; partial_status = {{}, {}, {1}}; inputs = build_inputs(); inferred_dist_attrs = phi::distributed::ConcatInferSpmd(inputs, 0); // list of tensor => single tensor EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(1)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(1)); EXPECT_TRUE( paddle::holds_alternative>( inferred_dist_attrs.first[0])); EXPECT_TRUE(paddle::holds_alternative( inferred_dist_attrs.second[0])); auto& inputs_infer3 = PADDLE_GET_CONST(std::vector, inferred_dist_attrs.first[0]); for (auto e : inputs_infer3) { check_dim_mapping(e, {-1}); check_partial_dims(e, {}); } check_dim_mapping(inferred_dist_attrs.second[0], {-1}); check_partial_dims(inferred_dist_attrs.second[0], {}); } TEST(StackRule, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); int input_size = 3; std::vector input_shape = {16, 8, 4}; std::vector> dim_mappings = { {-1, 0, 1}, {-1, 1, 0}, {-1, -1, 0}}; std::vector> partial_status = {{}, {}, {1}}; auto build_inputs = [&] { std::vector inputs; for (int i = 0; i < input_size; i++) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mappings[i]); t_dist_attr.set_dynamic_dims({false, false, false}); auto input = phi::distributed::DistMetaTensor( common::make_ddim(input_shape), t_dist_attr); inputs.push_back(input); } return inputs; }; auto build_output = [&](const TensorDistAttr& t_dist_attr, int stack_dim) { std::vector output_shape; std::transform(input_shape.begin(), input_shape.begin() + stack_dim, std::back_inserter(output_shape), [](int64_t x) { return x; }); output_shape.push_back(input_size); std::transform(input_shape.begin() + stack_dim, input_shape.end(), std::back_inserter(output_shape), [](int64_t x) { return x; }); return phi::distributed::DistMetaTensor(common::make_ddim(output_shape), t_dist_attr); }; // test 1, inputs are aligned according to cost. auto inputs = build_inputs(); auto inferred_dist_attrs = phi::distributed::StackInferSpmd(inputs, 0); // list of tensor => single tensor EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(1)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(1)); EXPECT_TRUE( paddle::holds_alternative>( inferred_dist_attrs.first[0])); EXPECT_TRUE(paddle::holds_alternative( inferred_dist_attrs.second[0])); auto& inputs_infer1 = PADDLE_GET_CONST(std::vector, inferred_dist_attrs.first[0]); for (auto e : inputs_infer1) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, 1, 0}); check_partial_dims(inferred_dist_attrs.second[0], {}); auto output_dist_attr = PADDLE_GET_CONST(TensorDistAttr, inferred_dist_attrs.second[0]); auto output = build_output(output_dist_attr, 0); // test reverse auto inferred_reverse_attrs = phi::distributed::StackInferSpmdReverse(inputs, output, 0); auto& inputs_infer1_reverse = PADDLE_GET_CONST( std::vector, inferred_reverse_attrs.first[0]); for (auto e : inputs_infer1_reverse) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } check_dim_mapping(inferred_reverse_attrs.second[0], output_dist_attr.dims_mapping()); // test grad auto inferred_grad_attrs = phi::distributed::StackGradInferSpmd(output, 0); check_dim_mapping(inferred_grad_attrs.first[0], output_dist_attr.dims_mapping()); auto& inferred_grad = PADDLE_GET_CONST(std::vector, inferred_grad_attrs.second[0]); for (auto e : inferred_grad) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } // test 2,force replicate along concat axis inputs = build_inputs(); inferred_dist_attrs = phi::distributed::StackInferSpmd(inputs, 1); // list of tensor => single tensor EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(1)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(1)); EXPECT_TRUE( paddle::holds_alternative>( inferred_dist_attrs.first[0])); EXPECT_TRUE(paddle::holds_alternative( inferred_dist_attrs.second[0])); auto& inputs_infer2 = PADDLE_GET_CONST(std::vector, inferred_dist_attrs.first[0]); for (auto e : inputs_infer2) { check_dim_mapping(e, {-1, 1, 0}); check_partial_dims(e, {}); } check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, 1, 0}); check_partial_dims(inferred_dist_attrs.second[0], {}); } TEST(WhereRule, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); std::vector> shapes = {{16, 16, 16}, {16, 16}, {16}}; std::vector> dim_mappings = {{-1, 0, -1}, {-1, 0}, {-1}}; auto build_inputs = [&] { std::vector inputs; for (int i = 0; i < 3; i++) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mappings[i]); t_dist_attr.set_dynamic_dims({false, false, false}); auto input = phi::distributed::DistMetaTensor( common::make_ddim(shapes[i]), t_dist_attr); inputs.push_back(input); } return inputs; }; auto inputs = build_inputs(); auto inferred_dist_attrs = phi::distributed::WhereGradInferSpmd( inputs[0], inputs[1], inputs[2], inputs[0]); EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(4)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(2)); check_dim_mapping(inferred_dist_attrs.first[0], {-1, 0, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {0, -1}); check_dim_mapping(inferred_dist_attrs.first[2], {-1}); check_dim_mapping(inferred_dist_attrs.first[3], {-1, 0, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, -1}); check_partial_dims(inferred_dist_attrs.second[0], {}); check_dim_mapping(inferred_dist_attrs.second[1], {-1}); check_partial_dims(inferred_dist_attrs.second[1], {0}); } TEST(ArgminRule, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping({0, 1, -1}); t_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({4, 6, 8}), t_dist_attr); phi::Scalar axis(1); bool keep_dim = false; bool flatten = false; phi::distributed::SpmdInfo forward_info = phi::distributed::ArgMinInferSpmdDynamic( x, axis, keep_dim, flatten, phi::DataType::FLOAT32); check_dim_mapping(forward_info.first[0], {0, -1, -1}); check_partial_dims(forward_info.first[0], {}); check_dim_mapping(forward_info.second[0], {0, -1}); check_partial_dims(forward_info.second[0], {}); } TEST(ReduceMaxRule, Ctor) { std::vector mesh_shape = {2}; std::vector process_ids = {0, 1}; std::vector dim_names = {"x"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping({-1, 0, -1}); t_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({4, 6, 8}), t_dist_attr); phi::IntArray axis = {1}; bool keep_dim = false; phi::distributed::SpmdInfo forward_info = phi::distributed::ReductionMaxInferSpmdDynamic(x, axis, keep_dim); check_dim_mapping(forward_info.second[0], {-1, -1}); check_partial_dims(forward_info.second[0], {0}); // test backward phi::distributed::DistMetaTensor out = phi::distributed::DistMetaTensor( common::make_ddim({4, 8}), PADDLE_GET_CONST(TensorDistAttr, forward_info.second[0])); phi::distributed::DistMetaTensor out_grad = out; phi::distributed::SpmdInfo backward_info = phi::distributed::ReductionGradInferSpmd( x, out, out_grad, {1}, false, false); check_partial_dims(backward_info.first[1], {}); check_dim_mapping(backward_info.second[0], {-1, -1, -1}); check_partial_dims(backward_info.second[0], {}); } TEST(ReduceMinRule, Ctor) { std::vector mesh_shape = {2}; std::vector process_ids = {0, 1}; std::vector dim_names = {"x"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping({-1, 0, -1}); t_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({4, 6, 8}), t_dist_attr); phi::IntArray axis = {1}; bool keep_dim = false; phi::distributed::SpmdInfo forward_info = phi::distributed::ReductionMinInferSpmdDynamic(x, axis, keep_dim); check_dim_mapping(forward_info.second[0], {-1, -1}); check_partial_dims(forward_info.second[0], {0}); } TEST(ReduceAllRule, Ctor) { std::vector mesh_shape = {2}; std::vector process_ids = {0, 1}; std::vector dim_names = {"x"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping({-1, 0, -1}); t_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor(phi::make_ddim({4, 6, 8}), t_dist_attr); phi::IntArray axis = {1}; bool keep_dim = false; phi::distributed::SpmdInfo forward_info = phi::distributed::ReductionAllInferSpmdDynamic(x, axis, keep_dim); check_dim_mapping(forward_info.second[0], {-1, -1}); check_partial_dims(forward_info.second[0], {0}); } TEST(ReduceAnyRule, Ctor) { std::vector mesh_shape = {2}; std::vector process_ids = {0, 1}; std::vector dim_names = {"x"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping({-1, 0, -1}); t_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor(phi::make_ddim({4, 6, 8}), t_dist_attr); phi::IntArray axis = {1}; bool keep_dim = false; phi::distributed::SpmdInfo forward_info = phi::distributed::ReductionAnyInferSpmdDynamic(x, axis, keep_dim); check_dim_mapping(forward_info.second[0], {-1, -1}); check_partial_dims(forward_info.second[0], {0}); } TEST(Numel, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); std::vector shape = {16, 16, 16}; std::vector dims_mapping = {-1, 0, -1}; auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dims_mapping); t_dist_attr.set_dynamic_dims({false, false, false}); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); auto inferred_dist_attrs = phi::distributed::NumelInferSpmd(input); EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(1)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(1)); check_dim_mapping(inferred_dist_attrs.first[0], dims_mapping); check_dim_mapping(inferred_dist_attrs.second[0], {}); check_partial_dims(inferred_dist_attrs.second[0], {0}); } TEST(Triu, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); std::vector shape = {16, 16, 16}; std::vector dims_mapping = {0, -1, 1}; auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dims_mapping); t_dist_attr.set_dynamic_dims({false, false, false}); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); auto inferred_dist_attrs = phi::distributed::TriuGradInferSpmd(input, 0); EXPECT_EQ(inferred_dist_attrs.first.size(), static_cast(1)); EXPECT_EQ(inferred_dist_attrs.second.size(), static_cast(1)); check_dim_mapping(inferred_dist_attrs.first[0], {0, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, -1, -1}); check_partial_dims(inferred_dist_attrs.second[0], {}); } TEST(LayerNorm, Ctor) { using phi::distributed::PartialStatus; std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); std::vector x_shapes = {16, 32, 32}; auto build_input = [&](const std::vector& shape, const std::vector& dim_mapping) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mapping); t_dist_attr.set_dynamic_dims({false, false, false}); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); return input; }; // test 1 auto x = build_input(x_shapes, {0, 1, -1}); auto out_grad = build_input(x_shapes, {0, 1, -1}); auto mean = build_input({16, 32}, {0, 1}); auto variance = build_input({16, 32}, {0, 1}); auto scale = build_input({32}, {0}); auto bias = build_input({32}, {0}); auto spmd1 = LayerNormGradInferSpmd(x, scale, bias, mean, variance, out_grad, 1.0, 2); EXPECT_EQ(spmd1.first.size(), static_cast(6)); EXPECT_EQ(spmd1.second.size(), static_cast(3)); check_dim_mapping(spmd1.first[0], {0, 1, -1}); check_dim_mapping(spmd1.first[1], {-1}); check_dim_mapping(spmd1.first[2], {-1}); check_dim_mapping(spmd1.first[3], {0, 1}); check_dim_mapping(spmd1.first[4], {0, 1}); check_dim_mapping(spmd1.first[5], {0, 1, -1}); check_dim_mapping(spmd1.second[0], {0, 1, -1}); check_dim_mapping(spmd1.second[1], {-1}); check_dim_mapping(spmd1.second[2], {-1}); check_partial_dims(spmd1.second[1], {0, 1}); check_partial_dims(spmd1.second[2], {0, 1}); // test 2 mean = build_input({16}, {0}); variance = build_input({16}, {0}); scale = build_input({32, 32}, {0, 1}); bias = build_input({32, 32}, {0, 1}); auto spmd2 = LayerNormGradInferSpmd(x, scale, bias, mean, variance, out_grad, 1.0, 1); EXPECT_EQ(spmd2.first.size(), static_cast(6)); EXPECT_EQ(spmd2.second.size(), static_cast(3)); check_dim_mapping(spmd2.first[0], {0, -1, -1}); check_dim_mapping(spmd2.first[1], {-1, -1}); check_dim_mapping(spmd2.first[2], {-1, -1}); check_dim_mapping(spmd2.first[3], {0}); check_dim_mapping(spmd2.first[4], {0}); check_dim_mapping(spmd2.first[5], {0, -1, -1}); check_dim_mapping(spmd2.second[0], {0, -1, -1}); check_dim_mapping(spmd2.second[1], {-1, -1}); check_dim_mapping(spmd2.second[2], {-1, -1}); check_partial_dims(spmd2.second[1], {0}); check_partial_dims(spmd2.second[2], {0}); } TEST(FlashAtt, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); auto build_input = [&](const std::vector& shape, const std::vector& dim_mapping) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mapping); t_dist_attr.set_dynamic_dims(std::vector(shape.size(), false)); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); return input; }; // b, s, m, h std::vector qkv_shape = {2, 256, 2, 128}; std::vector dim_mapping = {0, 1, -1, -1}; auto qkv = build_input(qkv_shape, dim_mapping); auto mask = build_input({}, {}); auto seed_offset = build_input({}, {}); auto spmd1 = FlashAttInferSpmd( qkv, qkv, qkv, seed_offset, mask, 0.5, false, false, false, ""); EXPECT_EQ(spmd1.first.size(), static_cast(5)); EXPECT_EQ(spmd1.second.size(), static_cast(4)); check_dim_mapping(spmd1.first[0], {0, -1, -1, -1}); check_dim_mapping(spmd1.first[1], {0, -1, -1, -1}); check_dim_mapping(spmd1.first[2], {0, -1, -1, -1}); check_dim_mapping(spmd1.first[3], {}); check_dim_mapping(spmd1.first[4], {}); check_dim_mapping(spmd1.second[0], {0, -1, -1, -1}); check_dim_mapping(spmd1.second[1], {0, -1, -1, -1}); check_dim_mapping(spmd1.second[2], {0, -1, -1}); check_dim_mapping(spmd1.second[3], {-1}); auto out = build_input(qkv_shape, {0, -1, 1, -1}); auto softmax_lse = build_input({2, 2, 256}, {0, 1, -1}); auto out_grad = build_input(qkv_shape, {-1, -1, -1, -1}); auto spmd2 = FlashAttGradInferSpmd( qkv, qkv, qkv, out, softmax_lse, seed_offset, mask, out_grad, 0.5, false); EXPECT_EQ(spmd2.first.size(), static_cast(8)); EXPECT_EQ(spmd2.second.size(), static_cast(3)); check_dim_mapping(spmd2.first[0], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[1], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[2], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[3], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[4], {0, 1, -1}); check_dim_mapping(spmd2.first[5], {}); check_dim_mapping(spmd2.first[6], {}); check_dim_mapping(spmd2.first[7], {0, -1, 1, -1}); check_dim_mapping(spmd2.second[0], {0, -1, 1, -1}); check_dim_mapping(spmd2.second[1], {0, -1, 1, -1}); check_dim_mapping(spmd2.second[2], {0, -1, 1, -1}); } TEST(FlashMask, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); auto build_input = [&](const std::vector& shape, const std::vector& dim_mapping) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mapping); t_dist_attr.set_dynamic_dims(std::vector(shape.size(), false)); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); return input; }; // b, s, m, h std::vector qkv_shape = {2, 256, 2, 128}; std::vector dim_mapping = {0, 1, -1, -1}; auto qkv = build_input(qkv_shape, dim_mapping); auto mask = build_input({}, {}); auto seed_offset = build_input({}, {}); auto spmd1 = FlashMaskInferSpmd( qkv, qkv, qkv, seed_offset, mask, 0.5, false, false, false, ""); EXPECT_EQ(spmd1.first.size(), static_cast(5)); EXPECT_EQ(spmd1.second.size(), static_cast(4)); check_dim_mapping(spmd1.first[0], {0, -1, -1, -1}); check_dim_mapping(spmd1.first[1], {0, -1, -1, -1}); check_dim_mapping(spmd1.first[2], {0, -1, -1, -1}); check_dim_mapping(spmd1.first[3], {}); check_dim_mapping(spmd1.first[4], {}); check_dim_mapping(spmd1.second[0], {0, -1, -1, -1}); check_dim_mapping(spmd1.second[1], {0, -1, -1, -1}); check_dim_mapping(spmd1.second[2], {0, -1, -1}); check_dim_mapping(spmd1.second[3], {-1}); auto out = build_input(qkv_shape, {0, -1, 1, -1}); auto softmax_lse = build_input({2, 2, 256}, {0, 1, -1}); auto out_grad = build_input(qkv_shape, {-1, -1, -1, -1}); auto spmd2 = FlashMaskGradInferSpmd( qkv, qkv, qkv, mask, out, softmax_lse, seed_offset, out_grad, 0.5, false); EXPECT_EQ(spmd2.first.size(), static_cast(8)); EXPECT_EQ(spmd2.second.size(), static_cast(3)); check_dim_mapping(spmd2.first[0], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[1], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[2], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[3], {}); check_dim_mapping(spmd2.first[4], {0, -1, 1, -1}); check_dim_mapping(spmd2.first[5], {0, 1, -1}); check_dim_mapping(spmd2.first[6], {}); check_dim_mapping(spmd2.first[7], {0, -1, 1, -1}); check_dim_mapping(spmd2.second[0], {0, -1, 1, -1}); check_dim_mapping(spmd2.second[1], {0, -1, 1, -1}); check_dim_mapping(spmd2.second[2], {0, -1, 1, -1}); } TEST(Util, Ctor) { // test equal test not equal using phi::distributed::PartialStatus; using phi::distributed::PlacementEqual; using phi::distributed::ReplicatedStatus; using phi::distributed::ShardStatus; auto a = std::make_shared(phi::ReduceType::kRedSum); auto b = std::make_shared(phi::ReduceType::kRedMin); EXPECT_TRUE(PlacementEqual(a, a)); EXPECT_TRUE(!PlacementEqual(a, b)); auto c = std::make_shared(0); auto d = std::make_shared(1); EXPECT_TRUE(!PlacementEqual(a, c)); EXPECT_TRUE(!PlacementEqual(b, c)); EXPECT_TRUE(PlacementEqual(c, c)); EXPECT_TRUE(!PlacementEqual(c, d)); auto e = std::make_shared(); EXPECT_TRUE(PlacementEqual(e, e)); EXPECT_TRUE(!PlacementEqual(a, e)); EXPECT_TRUE(!PlacementEqual(b, e)); EXPECT_TRUE(!PlacementEqual(c, e)); EXPECT_TRUE(!PlacementEqual(d, e)); } TEST(Transpose, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); std::vector shape = {6, 8, 10}; std::vector dims_mapping = {0, -1, 1}; TensorDistAttr t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dims_mapping); t_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); std::vector perm = {1, 2, -3}; // test forward phi::distributed::SpmdInfo forward_spmd_info = phi::distributed::TransposeInferSpmd(x, perm); EXPECT_EQ(forward_spmd_info.first.size(), static_cast(1)); EXPECT_EQ(forward_spmd_info.second.size(), static_cast(1)); check_dim_mapping(forward_spmd_info.first[0], {0, -1, 1}); check_dim_mapping(forward_spmd_info.second[0], {-1, 1, 0}); check_partial_dims(forward_spmd_info.second[0], {}); // test backward phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({8, 10, 6}), PADDLE_GET_CONST(TensorDistAttr, forward_spmd_info.second[0])); phi::distributed::SpmdInfo backward_spmd_info = TransposeGradInferSpmd(out_grad, perm); EXPECT_EQ(backward_spmd_info.first.size(), static_cast(1)); EXPECT_EQ(backward_spmd_info.second.size(), static_cast(1)); check_dim_mapping(backward_spmd_info.first[0], {-1, 1, 0}); check_dim_mapping(backward_spmd_info.second[0], {0, -1, 1}); check_partial_dims(backward_spmd_info.second[0], {}); } TEST(FusedRope, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); auto build_input = [&](const std::vector& shape, const std::vector& dim_mapping) { TensorDistAttr t_dist_attr; t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mapping); t_dist_attr.set_dynamic_dims(std::vector(shape.size(), false)); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); return input; }; phi::distributed::DistMetaTensor q = build_input({16, 2048, 64, 128}, {0, 1, -1, -1}); phi::distributed::DistMetaTensor none; // 1. test forward // 1.1 only q input phi::distributed::SpmdInfo forward_spmd_info = phi::distributed::FusedRopeInferSpmd( q, none, none, none, none, none, false, false); EXPECT_EQ(forward_spmd_info.first.size(), static_cast(6)); EXPECT_EQ(forward_spmd_info.second.size(), static_cast(3)); check_dim_mapping(forward_spmd_info.first[0], {0, -1, -1, -1}); check_dim_mapping(forward_spmd_info.first[1], {}); check_dim_mapping(forward_spmd_info.first[2], {}); check_dim_mapping(forward_spmd_info.first[3], {}); check_dim_mapping(forward_spmd_info.first[4], {}); check_dim_mapping(forward_spmd_info.first[5], {}); check_dim_mapping(forward_spmd_info.second[0], {0, -1, -1, -1}); check_dim_mapping(forward_spmd_info.second[1], {}); check_dim_mapping(forward_spmd_info.second[2], {}); check_partial_dims(forward_spmd_info.second[0], {}); // 1.2 q, k, sin, cos, position_ids phi::distributed::DistMetaTensor k = build_input({16, 2048, 64, 128}, {-1, 1, -1, 0}); phi::distributed::DistMetaTensor sin = build_input({1, 2048, 1, 128}, {-1, 0, -1, 1}); phi::distributed::DistMetaTensor cos = build_input({1, 2048, 1, 128}, {-1, 1, -1, -1}); phi::distributed::DistMetaTensor position_ids = build_input({16, 2048}, {0, 1}); forward_spmd_info = phi::distributed::FusedRopeInferSpmd( q, k, none, sin, cos, position_ids, false, false); EXPECT_EQ(forward_spmd_info.first.size(), static_cast(6)); EXPECT_EQ(forward_spmd_info.second.size(), static_cast(3)); check_dim_mapping(forward_spmd_info.first[0], {0, -1, -1, -1}); check_dim_mapping(forward_spmd_info.first[1], {0, -1, -1, -1}); check_dim_mapping(forward_spmd_info.first[2], {}); check_dim_mapping(forward_spmd_info.first[3], {-1, -1, -1, -1}); check_dim_mapping(forward_spmd_info.first[4], {-1, -1, -1, -1}); check_dim_mapping(forward_spmd_info.first[5], {0, -1}); check_dim_mapping(forward_spmd_info.second[0], {0, -1, -1, -1}); check_dim_mapping(forward_spmd_info.second[1], {0, -1, -1, -1}); check_dim_mapping(forward_spmd_info.second[2], {}); check_partial_dims(forward_spmd_info.second[0], {}); check_partial_dims(forward_spmd_info.second[1], {}); // 2. test backward phi::distributed::SpmdInfo backward_spmd_info = FusedRopeGradInferSpmd(sin, cos, position_ids, q, k, none, false, false); EXPECT_EQ(backward_spmd_info.first.size(), static_cast(6)); EXPECT_EQ(backward_spmd_info.second.size(), static_cast(3)); check_dim_mapping(backward_spmd_info.first[0], {-1, -1, -1, -1}); check_dim_mapping(backward_spmd_info.first[1], {-1, -1, -1, -1}); check_dim_mapping(backward_spmd_info.first[2], {0, -1}); check_dim_mapping(backward_spmd_info.first[3], {0, -1, -1, -1}); check_dim_mapping(backward_spmd_info.first[4], {0, -1, -1, -1}); check_dim_mapping(backward_spmd_info.first[5], {}); check_dim_mapping(backward_spmd_info.second[0], {0, -1, -1, -1}); check_dim_mapping(backward_spmd_info.second[1], {0, -1, -1, -1}); check_dim_mapping(backward_spmd_info.second[2], {}); check_partial_dims(backward_spmd_info.second[0], {}); check_partial_dims(backward_spmd_info.second[1], {}); // 3. test reverse phi::distributed::DistMetaTensor out_q = build_input({16, 2048, 64, 128}, {0, 1, -1, -1}); phi::distributed::DistMetaTensor out_k = build_input({16, 2048, 64, 128}, {-1, 1, -1, 0}); phi::distributed::SpmdInfo reverse_spmd_info = FusedRopeInferSpmdReverse( q, k, none, sin, cos, position_ids, out_q, out_k, none, false, false); EXPECT_EQ(reverse_spmd_info.first.size(), static_cast(6)); EXPECT_EQ(reverse_spmd_info.second.size(), static_cast(3)); check_dim_mapping(reverse_spmd_info.first[0], {0, -1, -1, -1}); check_dim_mapping(reverse_spmd_info.first[1], {0, -1, -1, -1}); check_dim_mapping(reverse_spmd_info.first[2], {}); check_dim_mapping(reverse_spmd_info.first[3], {-1, -1, -1, -1}); check_dim_mapping(reverse_spmd_info.first[4], {-1, -1, -1, -1}); check_dim_mapping(reverse_spmd_info.first[5], {0, -1}); check_dim_mapping(reverse_spmd_info.second[0], {0, -1, -1, -1}); check_dim_mapping(reverse_spmd_info.second[1], {0, -1, -1, -1}); check_dim_mapping(reverse_spmd_info.second[2], {}); } TEST(Reshape, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); auto build_input = [&](const std::vector& shape, const std::vector& dim_mapping) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mapping); t_dist_attr.set_dynamic_dims(std::vector(shape.size(), false)); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); return input; }; // b s h; dp , mp auto input = build_input({2, 1024, 1024}, {0, 1, -1}); // [b, s, h] => [b, s, nh, h/nh] auto spmd = ReshapeInferSpmd(input, {2, 1024, 4, -1}); EXPECT_EQ(spmd.first.size(), static_cast(1)); EXPECT_EQ(spmd.second.size(), static_cast(1)); check_dim_mapping(spmd.first[0], {0, 1, -1}); check_dim_mapping(spmd.second[0], {0, 1, -1, -1}); auto out_grad = build_input({2, 1024, 4, 1024 / 4}, {-1, -1, -1, -1}); auto x = build_input({2, 1024, 1024}, {0, 1, -1}); auto spmd_grad = ReshapeGradInferSpmd(x, out_grad); EXPECT_EQ(spmd_grad.first.size(), static_cast(2)); EXPECT_EQ(spmd_grad.second.size(), static_cast(1)); check_dim_mapping(spmd_grad.first[0], {0, 1, -1}); check_dim_mapping(spmd_grad.first[1], {0, 1, -1, -1}); check_dim_mapping(spmd_grad.second[0], {0, 1, -1}); } TEST(ElementwiseUnaryLike, Ctor) { std::vector mesh_shape = {2, 2, 2}; std::vector process_ids = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector dim_names = {"x", "y", "z"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); std::vector shape = {16, 16, 16}; std::vector> dims_mapping = {{0, 1}, {}, {2}}; auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dims_mapping); t_dist_attr.set_dynamic_dims({false, false, false}); auto check_element_unary_like = [&dims_mapping](auto& spmd_info) { EXPECT_EQ(spmd_info.first.size(), static_cast(1)); EXPECT_EQ(spmd_info.second.size(), static_cast(1)); check_multi_dims_mapping(spmd_info.first[0], dims_mapping); check_multi_dims_mapping(spmd_info.second[0], dims_mapping); check_partial_dims(spmd_info.second[0], {}); }; auto check_element_unary_like_backward = [&dims_mapping](auto& spmd_info) { EXPECT_GT(spmd_info.first.size(), static_cast(1)); EXPECT_EQ(spmd_info.second.size(), static_cast(1)); for (auto& dim_mapping : spmd_info.first) { check_multi_dims_mapping(dim_mapping, dims_mapping); } check_multi_dims_mapping(spmd_info.second[0], dims_mapping); check_partial_dims(spmd_info.second[0], {}); }; // cast auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); auto inferred_dist_attrs = phi::distributed::CastInferSpmd(input, phi::DataType::FLOAT32); check_element_unary_like(inferred_dist_attrs); // ElementwiseUnaryGradInferSpmd input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::ElementwiseUnaryGradInferSpmd(input); check_element_unary_like(inferred_dist_attrs); // full like input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::FullLikeInferSpmd(input, 1.0, phi::DataType::FLOAT32); check_element_unary_like(inferred_dist_attrs); // empty like input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::EmptyLikeInferSpmd(input, phi::DataType::FLOAT32); check_element_unary_like(inferred_dist_attrs); // pow input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::PowInferSpmd(input, 2); check_element_unary_like(inferred_dist_attrs); // pow backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::PowGradInferSpmd(input, input, 2); check_element_unary_like_backward(inferred_dist_attrs); // scale input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::ScaleInferSpmd(input, 1.0, 1.0, false); check_element_unary_like(inferred_dist_attrs); // round input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::RoundInfoSpmd(input, 0); check_element_unary_like(inferred_dist_attrs); // mish input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::MishInfoSpmd(input, 1.0); check_element_unary_like(inferred_dist_attrs); // mish backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::MishGradInfoSpmd(input, input, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // elu input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::EluInfoSpmd(input, 1.0); check_element_unary_like(inferred_dist_attrs); // elu backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::EluGradInfoSpmd(input, input, input, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // selu input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::SeluInfoSpmd(input, 1.0, 1.0); check_element_unary_like(inferred_dist_attrs); // selu backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::SeluGradInfoSpmd(input, input, 1.0, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // celu input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::CeluInfoSpmd(input, 1.0); check_element_unary_like(inferred_dist_attrs); // celu backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::CeluGradInfoSpmd(input, input, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // stanh input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::StanhInfoSpmd(input, 1.0, 1.0); check_element_unary_like(inferred_dist_attrs); // stanh backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::StanhGradInfoSpmd(input, input, 1.0, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // softplus input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::SoftplusInfoSpmd(input, 1.0, 1.0); check_element_unary_like(inferred_dist_attrs); // softplus backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::SoftplusGradInfoSpmd(input, input, 1.0, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // softshrink input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::SoftshrinkInfoSpmd(input, 1.0); check_element_unary_like(inferred_dist_attrs); // softshrink backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::SoftshrinkGradInfoSpmd(input, input, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // thresholded_relu input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::ThresholdedReluInfoSpmd(input, 1.0, 1.0); check_element_unary_like(inferred_dist_attrs); // thresholded_relu backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::ThresholdedReluGradInfoSpmd(input, input, 1.0, 1.0); check_element_unary_like_backward(inferred_dist_attrs); // logit input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::LogitInfoSpmd(input, 1.0); check_element_unary_like(inferred_dist_attrs); // logit backward input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); inferred_dist_attrs = phi::distributed::LogitGradInfoSpmd(input, input, 1.0); check_element_unary_like_backward(inferred_dist_attrs); } TEST(EmbeddingGradInferSpmd, Ctor) { // build input data class std::vector x_shape = {4, 5}; std::vector w_shape = {10, 3}; std::vector out_grad_shape = {4, 5, 3}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // indices is shard, embedding table is replicated, TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr w_dist_attr = TensorDistAttr(); w_dist_attr.set_process_mesh(process_mesh); w_dist_attr.set_dims_mapping(std::vector({-1, -1})); w_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping(std::vector({-1, -1, -1})); out_grad_dist_attr.set_dynamic_dims(std::vector({false, false})); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor w(phi::make_ddim(w_shape), w_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(out_grad_shape), out_grad_dist_attr); auto spmdinfo = EmbeddingGradInferSpmd(x, w, out_grad, -1, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, -1})); EXPECT_EQ( PADDLE_GET_CONST(phi::distributed::TensorDistAttr, spmdinfo.second[0]) .is_partial(), true); VLOG(4) << "Test EmbeddingGradInferSpmd with sharding indices and " "replicating weight" << std::endl << std::endl << std::endl; // Indices' rank is greater than 1, x and weight is replicated, out_grad is // sharded along axis 1 x_dist_attr.set_dims_mapping({-1, -1}); w_dist_attr.set_dims_mapping({-1, 1}); out_grad_dist_attr.set_dims_mapping({-1, 1, -1}); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); w = phi::distributed::DistMetaTensor(phi::make_ddim(w_shape), w_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = EmbeddingGradInferSpmd(x, w, out_grad, -1, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({-1, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, -1})); EXPECT_EQ( PADDLE_GET_CONST(phi::distributed::TensorDistAttr, spmdinfo.second[0]) .is_partial(), true); VLOG(4) << "Test EmbeddingGradInferSpmd with replicating indices and " "sharding weight along col axis." << std::endl << std::endl << std::endl; // Indices' rank equals 1, indices and out_grad is sharded. x_shape = {5}; w_shape = {10, 3}; out_grad_shape = {5, 3}; x_dist_attr.set_dims_mapping(std::vector({0})); w_dist_attr.set_dims_mapping(std::vector({-1, -1})); out_grad_dist_attr.set_dims_mapping(std::vector({-1, 1})); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); w = phi::distributed::DistMetaTensor(phi::make_ddim(w_shape), w_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = EmbeddingGradInferSpmd(x, w, out_grad, -1, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({0, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, 1})); EXPECT_EQ( PADDLE_GET_CONST(phi::distributed::TensorDistAttr, spmdinfo.second[0]) .is_partial(), true); VLOG(4) << "Test EmbeddingGradInferSpmd with sharding weight and out_grad." << std::endl << std::endl << std::endl; x_shape = {12, 16}; w_shape = {10, 4}; out_grad_shape = {12, 16, 4}; x_dist_attr.set_dims_mapping(std::vector({-1, -1})); w_dist_attr.set_dims_mapping(std::vector({-1, -0})); out_grad_dist_attr.set_dims_mapping(std::vector({-1, -1, 0})); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); w = phi::distributed::DistMetaTensor(phi::make_ddim(w_shape), w_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = EmbeddingGradInferSpmd(x, w, out_grad, -1, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, 0})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({-1, -1, 0})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, 0})); EXPECT_EQ( PADDLE_GET_CONST(phi::distributed::TensorDistAttr, spmdinfo.second[0]) .is_partial(), false); VLOG(4) << "Test EmbeddingGradInferSpmd with sharding weight and out_grad." << std::endl << std::endl << std::endl; } TEST(SqueezeGradInferSpmd, Ctor) { std::vector x_shape = {1, 32, 1, 48}; std::vector out_grad_shape = {32, 48}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({-1, 1, -1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false, false, false})); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping(std::vector({-1, 1})); out_grad_dist_attr.set_dynamic_dims(std::vector({false, false})); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(out_grad_shape), out_grad_dist_attr); auto spmdinfo = SqueezeGradInferSpmd(x, out_grad); EXPECT_EQ(spmdinfo.first.size(), 2UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1, 1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, -1, -1, 1})); EXPECT_DOUBLE_EQ( PADDLE_GET_CONST(TensorDistAttr, spmdinfo.second[0]).is_partial(), false); x_dist_attr.set_dims_mapping({-1, 0, -1, 1}); out_grad_dist_attr.set_dims_mapping({0, 1}); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = SqueezeGradInferSpmd(x, out_grad); EXPECT_EQ(spmdinfo.first.size(), 2UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1, 0, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({0, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, 0, -1, 1})); EXPECT_DOUBLE_EQ( PADDLE_GET_CONST(TensorDistAttr, spmdinfo.second[0]).is_partial(), false); } TEST(UnsqueezeGradInferSpmd, Ctor) { std::vector x_shape = {32, 48}; std::vector out_grad_shape = {1, 32, 1, 48}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false})); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping(std::vector({-1, 1, -1, -1})); out_grad_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(out_grad_shape), out_grad_dist_attr); auto spmdinfo = UnsqueezeGradInferSpmd(x, out_grad); EXPECT_EQ(spmdinfo.first.size(), 2UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, 1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({1, -1})); EXPECT_DOUBLE_EQ( PADDLE_GET_CONST(TensorDistAttr, spmdinfo.second[0]).is_partial(), false); x_dist_attr.set_dims_mapping({0, 1}); out_grad_dist_attr.set_dims_mapping({-1, 0, -1, 1}); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = UnsqueezeGradInferSpmd(x, out_grad); EXPECT_EQ(spmdinfo.first.size(), 2UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, 0, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, 1})); EXPECT_DOUBLE_EQ( PADDLE_GET_CONST(TensorDistAttr, spmdinfo.second[0]).is_partial(), false); } TEST(ScatterGradInferSpmd, Ctor) { std::vector index_shape = {16}; std::vector updates_shape = {32, 32, 48}; std::vector out_grad_shape = {64, 32, 48}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr index_dist_attr = TensorDistAttr(); index_dist_attr.set_process_mesh(process_mesh); TensorDistAttr updates_dist_attr = TensorDistAttr(); updates_dist_attr.set_process_mesh(process_mesh); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); // [0], [-1, -1, 1], [0, -1, 1] --> // inputs: [-1], [-1, -1, 1], [-1, -1, 1] // x_grad: [-1, -1, 1], updates_grad: [-1, -1, 1] index_dist_attr.set_dims_mapping(std::vector{0}); updates_dist_attr.set_dims_mapping({-1, -1, 1}); out_grad_dist_attr.set_dims_mapping({0, -1, 1}); phi::distributed::DistMetaTensor index(phi::make_ddim(index_shape), index_dist_attr); phi::distributed::DistMetaTensor updates(phi::make_ddim(updates_shape), updates_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(out_grad_shape), out_grad_dist_attr); auto spmdinfo = ScatterGradInferSpmd(index, updates, out_grad, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 2UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({-1, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[1]), std::vector({-1, -1, 1})); // [0], [0, -1, 1], [-1, 0, 1] --> // inputs: [-1], [-1, -1, 1], [-1, 0, 1] // x_grad: [-1, 0, 1], updates_grad: [-1, 0, 1] index_dist_attr.set_dims_mapping(std::vector{0}); updates_dist_attr.set_dims_mapping({0, -1, 1}); out_grad_dist_attr.set_dims_mapping({-1, 0, 1}); index = phi::distributed::DistMetaTensor(phi::make_ddim(index_shape), index_dist_attr); updates = phi::distributed::DistMetaTensor(phi::make_ddim(updates_shape), updates_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = ScatterGradInferSpmd(index, updates, out_grad, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 2UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({-1, 0, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, 0, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[1]), std::vector({-1, 0, 1})); } TEST(GatherGradInferSpmd, Ctor) { std::vector x_shape = {64, 32, 48}; std::vector index_shape = {16}; std::vector out_grad_shape = {16, 32, 48}; phi::Scalar axis(0); std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); TensorDistAttr index_dist_attr = TensorDistAttr(); index_dist_attr.set_process_mesh(process_mesh); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); // axis = 0 // [0, -1, 1], [0], [0, -1, 1] --> // inputs: [0, -1, 1], [-1], [-1, -1, 1] // x_grad: [-1, -1, 1] axis = 0; x_dist_attr.set_dims_mapping({0, -1, 1}); index_dist_attr.set_dims_mapping(std::vector{0}); out_grad_dist_attr.set_dims_mapping({0, -1, 1}); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor index(phi::make_ddim(index_shape), index_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(out_grad_shape), out_grad_dist_attr); auto spmdinfo = GatherGradInferSpmd(x, index, out_grad, axis); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({-1, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, -1, 1})); // 0-d tensor // axis = 1 // [0, -1, 1], [-1], [0, 1] --> // inputs: [0, -1, 1], [-1], [0, 1] // x_grad: [0, -1, 1] axis = 1; index_shape = {}; out_grad_shape = {64, 48}; x_dist_attr.set_dims_mapping({0, -1, 1}); index_dist_attr.set_dims_mapping(std::vector{-1}); out_grad_dist_attr.set_dims_mapping({0, 1}); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); index = phi::distributed::DistMetaTensor(phi::make_ddim(index_shape), index_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = GatherGradInferSpmd(x, index, out_grad, axis); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, -1, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({0, 1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, -1, 1})); } TEST(GatherNdGradInferSpmd, Ctor) { std::vector x_shape = {32}; std::vector index_shape = {16}; std::vector out_grad_shape = {16}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); TensorDistAttr index_dist_attr = TensorDistAttr(); index_dist_attr.set_process_mesh(process_mesh); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); // inputs: [-1], [0] --> [0] // x_grad: [-1] x_dist_attr.set_dims_mapping(std::vector{-1}); index_dist_attr.set_dims_mapping(std::vector{0}); out_grad_dist_attr.set_dims_mapping(std::vector{0}); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor index(phi::make_ddim(index_shape), index_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(out_grad_shape), out_grad_dist_attr); auto spmdinfo = GatherNdGradInferSpmd(x, index, out_grad); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({0})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({0})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1})); // inputs: [-1, -1], [0, -1, -1] --> [0, -1, -1] // x_grad: [-1, -1] x_shape = {64, 32}; index_shape = {16, 16, 1}; out_grad_shape = {16, 16, 32}; x_dist_attr.set_dims_mapping({-1, -1}); index_dist_attr.set_dims_mapping({0, -1, -1}); out_grad_dist_attr.set_dims_mapping({0, -1, -1}); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); index = phi::distributed::DistMetaTensor(phi::make_ddim(index_shape), index_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(out_grad_shape), out_grad_dist_attr); spmdinfo = GatherNdGradInferSpmd(x, index, out_grad); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({-1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, -1})); } TEST(CumSumGradInferSpmd, Ctor) { std::vector x_shape = {64, 32, 48}; std::vector out_grad_shape = {64, 32, 48}; std::vector mesh_shape = {2, 4}; std::vector process_ids = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); // axis = 1 // [0, 1, -1], [0, 1, -1] --> // inputs: [0, 1, -1], [0, -1, -1] // x_grad: [0, -1, -1] x_dist_attr.set_dims_mapping({0, 1, -1}); out_grad_dist_attr.set_dims_mapping({0, 1, -1}); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(out_grad_shape), out_grad_dist_attr); auto spmdinfo = CumSumGradInferSpmd(x, out_grad, 1, false, false, false); EXPECT_EQ(spmdinfo.first.size(), 2UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, -1, -1})); // axis = -1 // flatten = true // [0, 1, -1], [-1] --> // inputs: [0, 1, -1], [-1] // x_grad: [-1, -1, -1] x_dist_attr.set_dims_mapping({0, 1, -1}); out_grad_dist_attr.set_dims_mapping(std::vector{-1}); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim({64 * 32 * 48}), out_grad_dist_attr); spmdinfo = CumSumGradInferSpmd(x, out_grad, -1, true, false, false); EXPECT_EQ(spmdinfo.first.size(), 2UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({-1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({-1, -1, -1})); } TEST(Flatten, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); auto build_input = [&](const std::vector& shape, const std::vector& dim_mapping) { auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping(dim_mapping); t_dist_attr.set_dynamic_dims(std::vector(shape.size(), false)); auto input = phi::distributed::DistMetaTensor(common::make_ddim(shape), t_dist_attr); return input; }; // [b, h/ph, w/pw, c, ph, pw]; dp auto input1 = build_input({4, 16, 16, 4, 2, 2}, {0, -1, -1, -1, -1, -1}); // [b, h/ph, w/pw, c, ph, pw] => [b, h/ph, w/pw, hidden_size] auto spmd1 = FlattenInferSpmd(input1, -3, -1); EXPECT_EQ(spmd1.first.size(), static_cast(1)); EXPECT_EQ(spmd1.second.size(), static_cast(1)); check_dim_mapping(spmd1.first[0], {0, -1, -1, -1, -1, -1}); check_dim_mapping(spmd1.second[0], {0, -1, -1, -1}); // [b, h/ph, w/pw, c, ph, pw]; dp, mp auto input2 = build_input({4, 16, 16, 4, 2, 2}, {-1, 0, -1, 1, -1, -1}); auto spmd2 = FlattenInferSpmd(input2, 1, 4); EXPECT_EQ(spmd2.first.size(), static_cast(1)); EXPECT_EQ(spmd2.second.size(), static_cast(1)); check_dim_mapping(spmd2.first[0], {-1, 0, -1, -1, -1, -1}); check_dim_mapping(spmd2.second[0], {-1, 0, -1}); // [b, s, nh, h/nh]; dp , mp auto input3 = build_input({2, 1024, 32, 32}, {0, -1, 1, -1}); // [b, s, nh, h/nh] => [b, s, h] auto spmd3 = FlattenInferSpmd(input3, 2, 3); EXPECT_EQ(spmd3.first.size(), static_cast(1)); EXPECT_EQ(spmd3.second.size(), static_cast(1)); check_dim_mapping(spmd3.first[0], {0, -1, 1, -1}); check_dim_mapping(spmd3.second[0], {0, -1, 1}); // [b, c, d, h, w]; dp, mp auto input4 = build_input({4, 16, 16, 4, 16}, {-1, -1, 0, 1, -1}); auto spmd4 = FlattenInferSpmd(input4, 1, 4); EXPECT_EQ(spmd4.first.size(), static_cast(1)); EXPECT_EQ(spmd4.second.size(), static_cast(1)); check_dim_mapping(spmd4.first[0], {-1, -1, -1, -1, -1}); check_dim_mapping(spmd4.second[0], {-1, -1}); auto out_grad = build_input({2, 1024, 1024}, {0, -1, 1}); auto x = build_input({2, 1024, 4, 1024 / 4}, {0, -1, 1, -1}); auto spmd_grad = FlattenGradInferSpmd(x, out_grad); EXPECT_EQ(spmd_grad.first.size(), static_cast(2)); EXPECT_EQ(spmd_grad.second.size(), static_cast(1)); check_dim_mapping(spmd_grad.first[0], {0, -1, 1, -1}); check_dim_mapping(spmd_grad.first[1], {0, -1, 1}); check_dim_mapping(spmd_grad.second[0], {0, -1, 1, -1}); } TEST(Conv2dSPMDRuleInferForward, Ctor) { // build input data class std::vector input_shape = {2, 4, 8, 8}; std::vector filter_shape = {10, 4, 3, 3}; std::vector mesh_shape = {2, 2, 2}; std::vector process_ids = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector dim_names = {"dp", "mp", "pp"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr input_dist_attr = TensorDistAttr(); input_dist_attr.set_process_mesh(process_mesh); input_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); input_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); TensorDistAttr filter_dist_attr = TensorDistAttr(); filter_dist_attr.set_process_mesh(process_mesh); filter_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); filter_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); phi::distributed::DistMetaTensor input(common::make_ddim(input_shape), input_dist_attr); phi::distributed::DistMetaTensor filter(common::make_ddim(filter_shape), filter_dist_attr); // test 1 input_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); auto inferred_dist_attrs = phi::distributed::Conv2dInferSpmd(input, filter); check_dim_mapping(inferred_dist_attrs.first[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, -1, -1, -1}); // test 2 input_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dInferSpmd(input, filter); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, 0, -1, -1}); // test 3 input_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({1, -1, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dInferSpmd(input, filter); check_dim_mapping(inferred_dist_attrs.first[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, 1, -1, -1}); // test 4 input_dist_attr.set_dims_mapping(std::vector({-1, 0, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({-1, 0, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dInferSpmd(input, filter); check_dim_mapping(inferred_dist_attrs.first[0], {-1, 0, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, 0, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); // test 5 input_dist_attr.set_dims_mapping(std::vector({0, 2, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({1, 2, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dInferSpmd(input, filter); check_dim_mapping(inferred_dist_attrs.first[0], {0, 2, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {1, 2, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, 1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); } TEST(Conv2dSPMDRuleInferBackward, Ctor) { // build input data class std::vector input_shape = {2, 4, 8, 8}; std::vector filter_shape = {10, 4, 3, 3}; std::vector output_shape = {2, 10, 6, 6}; std::vector mesh_shape = {2, 2, 2}; std::vector process_ids = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector dim_names = {"dp", "mp", "pp"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr input_dist_attr = TensorDistAttr(); input_dist_attr.set_process_mesh(process_mesh); input_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); input_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); TensorDistAttr filter_dist_attr = TensorDistAttr(); filter_dist_attr.set_process_mesh(process_mesh); filter_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); filter_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); TensorDistAttr output_dist_attr = TensorDistAttr(); output_dist_attr.set_process_mesh(process_mesh); output_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); output_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); phi::distributed::DistMetaTensor input(common::make_ddim(input_shape), input_dist_attr); phi::distributed::DistMetaTensor filter(common::make_ddim(filter_shape), filter_dist_attr); phi::distributed::DistMetaTensor output(common::make_ddim(output_shape), output_dist_attr); auto inferred_dist_attrs = phi::distributed::Conv2dInferSpmdReverse(input, filter, output); check_dim_mapping(inferred_dist_attrs.first[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, 1, -1, -1}); } TEST(Conv2dGradSPMDRule, Ctor) { // build input data class std::vector input_shape = {2, 4, 8, 8}; std::vector filter_shape = {10, 4, 3, 3}; std::vector output_grad_shape = {2, 10, 6, 6}; std::vector mesh_shape = {2, 2, 2}; std::vector process_ids = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector dim_names = {"dp", "mp", "pp"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr input_dist_attr = TensorDistAttr(); input_dist_attr.set_process_mesh(process_mesh); input_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); input_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); TensorDistAttr filter_dist_attr = TensorDistAttr(); filter_dist_attr.set_process_mesh(process_mesh); filter_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); filter_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); TensorDistAttr output_grad_dist_attr = TensorDistAttr(); output_grad_dist_attr.set_process_mesh(process_mesh); output_grad_dist_attr.set_dims_mapping( std::vector({-1, -1, -1, -1})); output_grad_dist_attr.set_dynamic_dims( std::vector({false, false, false, false})); phi::distributed::DistMetaTensor input(common::make_ddim(input_shape), input_dist_attr); phi::distributed::DistMetaTensor filter(common::make_ddim(filter_shape), filter_dist_attr); phi::distributed::DistMetaTensor output_grad( common::make_ddim(output_grad_shape), output_grad_dist_attr); // test 1 auto inferred_dist_attrs = phi::distributed::Conv2dGradInferSpmd(input, filter, output_grad); EXPECT_EQ(inferred_dist_attrs.first.size(), (size_t)3); EXPECT_EQ(inferred_dist_attrs.second.size(), (size_t)2); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[2], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {-1, -1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.first[2]), false); VLOG(4) << "test 1 done"; // test 2 input_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); output_grad_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); output_grad = phi::distributed::DistMetaTensor( common::make_ddim(output_grad_shape), output_grad_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dGradInferSpmd(input, filter, output_grad); check_dim_mapping(inferred_dist_attrs.first[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[2], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {-1, -1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.first[2]), false); EXPECT_EQ(is_partial(inferred_dist_attrs.second[1]), true); // test 3 input_dist_attr.set_dims_mapping(std::vector({-1, -1, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); output_grad_dist_attr.set_dims_mapping(std::vector({-1, 0, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); output_grad = phi::distributed::DistMetaTensor( common::make_ddim(output_grad_shape), output_grad_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dGradInferSpmd(input, filter, output_grad); check_dim_mapping(inferred_dist_attrs.first[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[2], {-1, 0, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {-1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {0, -1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.first[2]), false); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); // test 4 input_dist_attr.set_dims_mapping(std::vector({0, -1, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({1, -1, -1, -1})); output_grad_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); output_grad = phi::distributed::DistMetaTensor( common::make_ddim(output_grad_shape), output_grad_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dGradInferSpmd(input, filter, output_grad); check_dim_mapping(inferred_dist_attrs.first[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {1, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[2], {0, 1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, -1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {1, -1, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.first[2]), false); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); EXPECT_EQ(is_partial(inferred_dist_attrs.second[1]), true); // test 5 input_dist_attr.set_dims_mapping(std::vector({0, 2, -1, -1})); filter_dist_attr.set_dims_mapping(std::vector({1, 2, -1, -1})); output_grad_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); output_grad_dist_attr.set_partial_status(std::vector({2})); input = phi::distributed::DistMetaTensor(common::make_ddim(input_shape), input_dist_attr); filter = phi::distributed::DistMetaTensor(common::make_ddim(filter_shape), filter_dist_attr); output_grad = phi::distributed::DistMetaTensor( common::make_ddim(output_grad_shape), output_grad_dist_attr); inferred_dist_attrs = phi::distributed::Conv2dGradInferSpmd(input, filter, output_grad); check_dim_mapping(inferred_dist_attrs.first[0], {0, 2, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[1], {1, 2, -1, -1}); check_dim_mapping(inferred_dist_attrs.first[2], {0, 1, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[0], {0, 2, -1, -1}); check_dim_mapping(inferred_dist_attrs.second[1], {1, 2, -1, -1}); EXPECT_EQ(is_partial(inferred_dist_attrs.first[2]), true); EXPECT_EQ(is_partial(inferred_dist_attrs.second[0]), true); EXPECT_EQ(is_partial(inferred_dist_attrs.second[1]), true); } TEST(Dropout, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"dp", "mp"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping({0, -1, -1}); t_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({4, 6, 8}), t_dist_attr); phi::distributed::DistMetaTensor seed_tensor; phi::distributed::SpmdInfo forward_info = phi::distributed::DropoutFwdInferSpmd( x, seed_tensor, 0.5, false, "", 0, true); check_dim_mapping(forward_info.first[0], {0, -1, -1}); check_dim_mapping(forward_info.first[1], {}); check_dim_mapping(forward_info.second[0], {0, -1, -1}); check_dim_mapping(forward_info.second[1], {0, -1, -1}); // test backward phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({4, 6, 8}), t_dist_attr); phi::distributed::DistMetaTensor mask = out_grad; phi::distributed::SpmdInfo backward_info = phi::distributed::DropoutBwdInferSpmd(mask, out_grad, 0.5, false, ""); check_dim_mapping(backward_info.first[0], {0, -1, -1}); check_dim_mapping(backward_info.first[1], {0, -1, -1}); check_dim_mapping(backward_info.second[0], {0, -1, -1}); } TEST(MeanAll, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward // [0, -1] --> [], partial_on_dim:[0] auto t_dist_attr = TensorDistAttr(); t_dist_attr.set_process_mesh(process_mesh); t_dist_attr.set_dims_mapping({0, -1}); t_dist_attr.set_dynamic_dims({false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor(common::make_ddim({4, 8}), t_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::MeanAllInferSpmd(x); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {0, -1}); check_dim_mapping(forward_info.second[0], {}); check_partial_dims(forward_info.second[0], {0}); // test backward // [] --> [-1, -1], [] auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping(std::vector{}); out_grad_dist_attr.set_dynamic_dims({}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::MeanAllGradInferSpmd(x, out_grad); EXPECT_EQ(backward_info.first.size(), 2UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {-1, -1}); check_dim_mapping(backward_info.first[1], {}); check_dim_mapping(backward_info.second[0], {-1, -1}); } TEST(BatchNorm, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); // test forward // data_format = NCHW // [0, 1, -1, -1],[-1],[-1],[-1],[-1] ->[-1 , 1, -1, -1],[1],[1],[1],[1],[-1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({0, 1, -1, -1}); x_dist_attr.set_dynamic_dims({false, false, false, false}); auto one_dim_dist_attr = TensorDistAttr(); one_dim_dist_attr.set_process_mesh(process_mesh); one_dim_dist_attr.set_dims_mapping(std::vector{-1}); one_dim_dist_attr.set_dynamic_dims({false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16, 16}), x_dist_attr); phi::distributed::DistMetaTensor mean = phi::distributed::DistMetaTensor( common::make_ddim({16}), one_dim_dist_attr); phi::distributed::DistMetaTensor variance = phi::distributed::DistMetaTensor( common::make_ddim({16}), one_dim_dist_attr); phi::distributed::DistMetaTensor scale = phi::distributed::DistMetaTensor( common::make_ddim({16}), one_dim_dist_attr); phi::distributed::DistMetaTensor bias = phi::distributed::DistMetaTensor( common::make_ddim({16}), one_dim_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::BatchNormInferSpmdStatic( x, mean, variance, scale, bias); EXPECT_EQ(forward_info.first.size(), 5UL); EXPECT_EQ(forward_info.second.size(), 6UL); check_dim_mapping(forward_info.first[0], {-1, 1, -1, -1}); check_dim_mapping(forward_info.first[1], {1}); check_dim_mapping(forward_info.first[2], {1}); check_dim_mapping(forward_info.first[3], {-1}); check_dim_mapping(forward_info.first[4], {-1}); check_dim_mapping(forward_info.second[0], {-1, 1, -1, -1}); check_dim_mapping(forward_info.second[1], {1}); check_dim_mapping(forward_info.second[2], {1}); check_dim_mapping(forward_info.second[3], {1}); check_dim_mapping(forward_info.second[4], {1}); check_dim_mapping(forward_info.second[5], {-1}); // test backward // data_format = NCHW // [0, 1, -1, -1],[-1],[-1],[-1],[-1],[-1],[-1],[-1],[0, 1, -1, -1] // ->[-1,1,-1,-1],[-1],[-1] // dst_input: [-1, 1, -1, -1],[-1],[-1],[1],[1],[1],[1],[-1],[-1, 1, -1, -1] x = phi::distributed::DistMetaTensor(common::make_ddim({16, 16, 16, 16}), x_dist_attr); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16, 16}), x_dist_attr); phi::distributed::DistMetaTensor mean_out = phi::distributed::DistMetaTensor( common::make_ddim({16}), one_dim_dist_attr); phi::distributed::DistMetaTensor variance_out = phi::distributed::DistMetaTensor(common::make_ddim({16}), one_dim_dist_attr); scale = phi::distributed::DistMetaTensor(common::make_ddim({16}), one_dim_dist_attr); bias = phi::distributed::DistMetaTensor(common::make_ddim({16}), one_dim_dist_attr); phi::distributed::DistMetaTensor saved_mean = phi::distributed::DistMetaTensor(common::make_ddim({16}), one_dim_dist_attr); phi::distributed::DistMetaTensor saved_variance = phi::distributed::DistMetaTensor(common::make_ddim({16}), one_dim_dist_attr); phi::distributed::DistMetaTensor reserve_space = phi::distributed::DistMetaTensor(common::make_ddim({16}), one_dim_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::BatchNormGradInferSpmd(x, scale, bias, mean_out, variance_out, saved_mean, saved_variance, reserve_space, out_grad, 0.9, 0.1, "NCHW", false, false, false); EXPECT_EQ(backward_info.first.size(), 9UL); EXPECT_EQ(backward_info.second.size(), 3UL); check_dim_mapping(backward_info.first[0], {-1, 1, -1, -1}); check_dim_mapping(backward_info.first[1], {-1}); check_dim_mapping(backward_info.first[2], {-1}); check_dim_mapping(backward_info.first[3], {1}); check_dim_mapping(backward_info.first[4], {1}); check_dim_mapping(backward_info.first[5], {1}); check_dim_mapping(backward_info.first[6], {1}); check_dim_mapping(backward_info.first[7], {-1}); check_dim_mapping(backward_info.first[8], {-1, 1, -1, -1}); check_dim_mapping(backward_info.second[0], {-1, 1, -1, -1}); check_dim_mapping(backward_info.second[1], {-1}); check_dim_mapping(backward_info.second[2], {-1}); } TEST(Topk, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); phi::Scalar k(2); // test forward // axis = 1 // [0, 1, -1] -> [0, -1, -1], [0, -1, -1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({0, 1, -1}); x_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), x_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::TopkInferSpmdDynamic(x, k, 1, true, true); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 2UL); check_dim_mapping(forward_info.first[0], {0, -1, -1}); check_dim_mapping(forward_info.second[0], {0, -1, -1}); check_dim_mapping(forward_info.second[1], {0, -1, -1}); // test backward // axis = 1 // [0, -1, 1], [0, -1, 1], [-1, 1, -1]-> [0, -1, 1], [0, -1, 1], [0, -1, // 1], [0, -1, 1] x_dist_attr.set_dims_mapping({0, -1, 1}); x = phi::distributed::DistMetaTensor(common::make_ddim({16, 16, 16}), x_dist_attr); auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping({-1, 1, -1}); out_grad_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({16, 2, 16}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::TopkGradInferSpmdDynamic( x, x, out_grad, k, 1, true, true); EXPECT_EQ(backward_info.first.size(), 3UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {0, -1, 1}); check_dim_mapping(backward_info.first[1], {0, -1, 1}); check_dim_mapping(backward_info.first[2], {0, -1, 1}); check_dim_mapping(backward_info.second[0], {0, -1, 1}); } TEST(Cummax, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); int axis = 1; // test forward // axis = 1 // [0, 1, -1] -> [0, -1, -1], [0, -1, -1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({0, 1, -1}); x_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), x_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::CummaxInferSpmd(x, axis, phi::DataType::INT64); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 2UL); check_dim_mapping(forward_info.first[0], {0, -1, -1}); check_dim_mapping(forward_info.second[0], {0, -1, -1}); check_dim_mapping(forward_info.second[1], {0, -1, -1}); // test backward // axis = 1 // [0, -1, 1], [0, -1, 1], [-1, 1, -1]-> [0, -1, 1], [0, -1, 1], [0, -1, // 1], [0, -1, 1] x_dist_attr.set_dims_mapping({0, -1, 1}); x = phi::distributed::DistMetaTensor(common::make_ddim({16, 16, 16}), x_dist_attr); auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping({-1, 1, -1}); out_grad_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::CummaxGradInferSpmd( x, x, out_grad, axis, phi::DataType::INT64); EXPECT_EQ(backward_info.first.size(), 3UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {0, -1, 1}); check_dim_mapping(backward_info.first[1], {0, -1, 1}); check_dim_mapping(backward_info.first[2], {0, -1, 1}); check_dim_mapping(backward_info.second[0], {0, -1, 1}); } TEST(Cummin, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); int axis = 1; // test forward // axis = 1 // [0, 1, -1] -> [0, -1, -1], [0, -1, -1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({0, 1, -1}); x_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), x_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::CumminInferSpmd(x, axis, phi::DataType::INT64); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 2UL); check_dim_mapping(forward_info.first[0], {0, -1, -1}); check_dim_mapping(forward_info.second[0], {0, -1, -1}); check_dim_mapping(forward_info.second[1], {0, -1, -1}); // test backward // axis = 1 // [0, -1, 1], [0, -1, 1], [-1, 1, -1]-> [0, -1, 1], [0, -1, 1], [0, -1, // 1], [0, -1, 1] x_dist_attr.set_dims_mapping({0, -1, 1}); x = phi::distributed::DistMetaTensor(common::make_ddim({16, 16, 16}), x_dist_attr); auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping({-1, 1, -1}); out_grad_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::CumminGradInferSpmd( x, x, out_grad, axis, phi::DataType::INT64); EXPECT_EQ(backward_info.first.size(), 3UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {0, -1, 1}); check_dim_mapping(backward_info.first[1], {0, -1, 1}); check_dim_mapping(backward_info.first[2], {0, -1, 1}); check_dim_mapping(backward_info.second[0], {0, -1, 1}); } TEST(ArgSortGradInferSpmd, Ctor) { // Sharding along axes besides argsort axis. std::vector x_shape = {16, 32, 48}; std::vector indices_shape = {16, 32, 48}; std::vector out_grad_shape = {16, 32, 48}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({0, 1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false, false})); TensorDistAttr indices_dist_attr = TensorDistAttr(); indices_dist_attr.set_process_mesh(process_mesh); indices_dist_attr.set_dims_mapping(std::vector({0, 1, -1})); indices_dist_attr.set_dynamic_dims(std::vector({false, false, false})); TensorDistAttr out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping(std::vector({0, 1, -1})); out_grad_dist_attr.set_dynamic_dims(std::vector({false, false, false})); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); phi::distributed::DistMetaTensor indices(phi::make_ddim(x_shape), indices_dist_attr); phi::distributed::DistMetaTensor out_grad(phi::make_ddim(x_shape), out_grad_dist_attr); int axis = -1; auto spmdinfo = ArgSortGradInferSpmd(indices, x, out_grad, axis, false, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({0, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({0, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, 1, -1})); VLOG(4) << "Test ArgSortGradInferSpmd sharding on other axes." << std::endl << std::endl << std::endl; // Sharding along argsort axis. x_dist_attr.set_dims_mapping(std::vector({0, -1, 1})); indices_dist_attr.set_dims_mapping(std::vector({0, -1, 1})); out_grad_dist_attr.set_dims_mapping(std::vector({0, -1, 1})); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); indices = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), indices_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), out_grad_dist_attr); axis = 2; spmdinfo = ArgSortGradInferSpmd(indices, x, out_grad, axis, false, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, -1, -1})); VLOG(4) << "Test ArgSortGradInferSpmd sharding on softmax axis." << std::endl << std::endl << std::endl; // Sharding on multi axes. x_shape = {10, 32, 48, 24}; indices_shape = {10, 32, 48, 24}; out_grad_shape = {10, 32, 48, 24}; x_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); indices_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); out_grad_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); indices = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), indices_dist_attr); out_grad = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), out_grad_dist_attr); axis = 1; spmdinfo = ArgSortGradInferSpmd(indices, x, out_grad, axis, false, false); EXPECT_EQ(spmdinfo.first.size(), 3UL); EXPECT_EQ(spmdinfo.second.size(), 1UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, -1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[1]), std::vector({0, -1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.first[2]), std::vector({0, -1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, -1, -1, -1})); VLOG(4) << "Test ArgSortGradInferSpmd sharding on multi axes." << std::endl << std::endl << std::endl; } TEST(ArgSortInferSpmd, Ctor) { // Sharding along axes besides argsort axis. std::vector x_shape = {16, 32, 48}; std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); TensorDistAttr x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping(std::vector({0, 1, -1})); x_dist_attr.set_dynamic_dims(std::vector({false, false, false})); phi::distributed::DistMetaTensor x(phi::make_ddim(x_shape), x_dist_attr); int axis = -1; auto spmdinfo = ArgSortInferSpmd(x, axis, false, false); EXPECT_EQ(spmdinfo.first.size(), 1UL); EXPECT_EQ(spmdinfo.second.size(), 2UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, 1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[1]), std::vector({0, 1, -1})); VLOG(4) << "Test ArgSortGradInferSpmd sharding on other axes." << std::endl << std::endl << std::endl; // Sharding along argsort axis. x_dist_attr.set_dims_mapping(std::vector({0, -1, 1})); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); axis = 2; spmdinfo = ArgSortInferSpmd(x, axis, false, false); EXPECT_EQ(spmdinfo.first.size(), 1UL); EXPECT_EQ(spmdinfo.second.size(), 2UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[1]), std::vector({0, -1, -1})); VLOG(4) << "Test ArgSortGradInferSpmd sharding on softmax axis." << std::endl << std::endl << std::endl; // Sharding on multi axes. x_shape = {10, 32, 48, 24}; x_dist_attr.set_dims_mapping(std::vector({0, 1, -1, -1})); x = phi::distributed::DistMetaTensor(phi::make_ddim(x_shape), x_dist_attr); axis = 1; spmdinfo = ArgSortInferSpmd(x, axis, false, false); EXPECT_EQ(spmdinfo.first.size(), 1UL); EXPECT_EQ(spmdinfo.second.size(), 2UL); EXPECT_EQ(get_dims_mapping(spmdinfo.first[0]), std::vector({0, -1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[0]), std::vector({0, -1, -1, -1})); EXPECT_EQ(get_dims_mapping(spmdinfo.second[1]), std::vector({0, -1, -1, -1})); VLOG(4) << "Test ArgSortGradInferSpmd sharding on multi axes." << std::endl << std::endl << std::endl; } TEST(Roll, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); phi::IntArray shifts = {1}; std::vector axis = {}; // test forward // axis = [], shifts = [1] // [0, 1, -1] --> [-1, -1, -1], [-1, -1, -1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({0, 1, -1}); x_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), x_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::RollInferSpmdDynamic(x, shifts, axis); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {-1, -1, -1}); check_dim_mapping(forward_info.second[0], {-1, -1, -1}); // axis = [0, 2], shifts = [1, 2] // [0, 1, -1] --> [-1, 1, -1], [-1, 1, -1] shifts = {1, 2}; axis = {0, 2}; forward_info = phi::distributed::RollInferSpmdDynamic(x, shifts, axis); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {-1, 1, -1}); check_dim_mapping(forward_info.second[0], {-1, 1, -1}); // test backward // axis = [], shifts = [1] // [0, 1, -1], [-1, -1, -1] --> [-1, -1, -1], [-1, -1, -1], [-1, -1, -1] shifts = {1}; axis = {}; x_dist_attr.set_dims_mapping({-1, -1, -1}); x = phi::distributed::DistMetaTensor(common::make_ddim({16, 16, 16}), x_dist_attr); auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping({0, 1, -1}); out_grad_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::RollGradInferSpmdDynamic(x, out_grad, shifts, axis); EXPECT_EQ(backward_info.first.size(), 2UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {-1, -1, -1}); check_dim_mapping(backward_info.first[1], {-1, -1, -1}); check_dim_mapping(backward_info.second[0], {-1, -1, -1}); // axis = [0, 2], shifts = [1, 2] // [-1, -1, -1], [0, 1, -1] --> [-1, 1, -1], [-1, 1, -1], [-1, 1, -1] shifts = {1, 2}; axis = {0, 2}; backward_info = phi::distributed::RollGradInferSpmdDynamic(x, out_grad, shifts, axis); EXPECT_EQ(backward_info.first.size(), 2UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {-1, 1, -1}); check_dim_mapping(backward_info.first[1], {-1, 1, -1}); check_dim_mapping(backward_info.second[0], {-1, 1, -1}); } TEST(IndexSelect, Ctor) { std::vector mesh_shape = {2, 3}; std::vector process_ids = {0, 1, 2, 3, 4, 5}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); int axis = 1; // test forward // axis = 1 // [-1, -1, -1], [0] --> [-1, -1, -1], [0], [-1, 0, -1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({-1, -1, -1}); x_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), x_dist_attr); auto index_dist_attr = TensorDistAttr(); index_dist_attr.set_process_mesh(process_mesh); index_dist_attr.set_dims_mapping(std::vector{0}); index_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor index = phi::distributed::DistMetaTensor(common::make_ddim({3}), index_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::IndexSelectInferSpmd(x, index, axis); EXPECT_EQ(forward_info.first.size(), 2UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {-1, -1, -1}); check_dim_mapping(forward_info.first[1], {0}); check_dim_mapping(forward_info.second[0], {-1, 0, -1}); // test backward // axis = 1 // [-1, -1, -1], [0], [-1, 0, -1], axis=1 --> [-1, -1, -1], [0], [-1, 0, -1], // [-1, -1, -1](partial on axis=1 with 0) auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping({-1, 0, -1}); out_grad_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({16, 3, 16}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::IndexSelectGradInferSpmd(x, index, out_grad, axis); EXPECT_EQ(backward_info.first.size(), 3UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {-1, -1, -1}); check_dim_mapping(backward_info.first[1], {0}); check_dim_mapping(backward_info.first[2], {-1, 0, -1}); check_dim_mapping(backward_info.second[0], {-1, -1, -1}); EXPECT_EQ(is_partial(backward_info.second[0]), true); check_partial_dims(backward_info.second[0], {0}); } TEST(Unique, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); bool return_index = true; bool return_inverse = true; bool return_counts = true; std::vector axis = {}; // test forward // return_index=True, return_inverse=True, return_counts=True, axis={} // [0, -1] --> [-1,-1], [-1], [-1], [-1], [-1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({0, -1}); x_dist_attr.set_dynamic_dims({false, false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor(common::make_ddim({4, 8}), x_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::UniqueInferSpmd(x, return_index, return_inverse, return_counts, axis, phi::DataType::FLOAT32); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 4UL); check_dim_mapping(forward_info.first[0], {-1, -1}); check_dim_mapping(forward_info.second[0], {-1}); check_dim_mapping(forward_info.second[1], {-1}); check_dim_mapping(forward_info.second[2], {-1}); check_dim_mapping(forward_info.second[3], {-1}); // return_index=True, return_inverse=True, return_counts=True, axis={0} // [0, -1] --> [-1, -1], [-1, -1], [-1], [-1], [-1] axis = {0}; forward_info = phi::distributed::UniqueInferSpmd(x, return_index, return_inverse, return_counts, axis, phi::DataType::FLOAT32); EXPECT_EQ(forward_info.first.size(), 1UL); EXPECT_EQ(forward_info.second.size(), 4UL); check_dim_mapping(forward_info.first[0], {-1, -1}); check_dim_mapping(forward_info.second[0], {-1, -1}); check_dim_mapping(forward_info.second[1], {-1}); check_dim_mapping(forward_info.second[2], {-1}); check_dim_mapping(forward_info.second[3], {-1}); } TEST(LabelSmooth, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); float epsilon = 0.1; // test forward // [0, 1, -1], [Fake] --> [0, 1, -1], [Fake], [0, 1, -1] auto label_dist_attr = TensorDistAttr(); label_dist_attr.set_process_mesh(process_mesh); label_dist_attr.set_dims_mapping({0, 1, -1}); label_dist_attr.set_dynamic_dims({false, false, false}); auto prior_dist_dist_attr = TensorDistAttr(); prior_dist_dist_attr.set_process_mesh(process_mesh); prior_dist_dist_attr.set_dims_mapping({-1, -1}); prior_dist_dist_attr.set_dynamic_dims({false, false}); phi::distributed::DistMetaTensor label = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), label_dist_attr); phi::distributed::DistMetaTensor prior_dist = phi::distributed::DistMetaTensor(common::make_ddim({1, 16}), prior_dist_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::LabelSmoothInferSpmd( label, phi::distributed::DistMetaTensor(), epsilon); EXPECT_EQ(forward_info.first.size(), 2UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {0, 1, -1}); check_empty_dist_attr(forward_info.first[1]); check_dim_mapping(forward_info.second[0], {0, 1, -1}); // shape: [16, 16, 16], [1, 16]. [0, 1, -1], [-1, -1] --> [0, 1, -1], [-1, // -1], [0, 1, -1] forward_info = phi::distributed::LabelSmoothInferSpmd(label, prior_dist, epsilon); EXPECT_EQ(forward_info.first.size(), 2UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {0, 1, -1}); check_dim_mapping(forward_info.first[1], {-1, -1}); check_dim_mapping(forward_info.second[0], {0, 1, -1}); // test backward // [0, -1, 1] --> [0, -1, 1], [0, -1, 1] auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping({0, -1, 1}); out_grad_dist_attr.set_dynamic_dims({false, false, false}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({16, 16, 16}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::LabelSmoothGradInferSpmd(out_grad, epsilon); EXPECT_EQ(backward_info.first.size(), 1UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {0, -1, 1}); check_dim_mapping(backward_info.second[0], {0, -1, 1}); } TEST(RolAlign, Ctor) { std::vector mesh_shape = {2, 2}; std::vector process_ids = {0, 1, 2, 3}; std::vector dim_names = {"x", "y"}; ProcessMesh process_mesh(mesh_shape, process_ids, dim_names); int pooled_height = 3; int pooled_width = 3; float spatial_scale = 0.5; int sampling_ratio = -1; bool aligned = true; // test forward // [0, 1, -1, -1], [-1, 1], [0] --> [-1, 1, -1, -1],[-1, -1],[-1],[-1,1,-1,-1] auto x_dist_attr = TensorDistAttr(); x_dist_attr.set_process_mesh(process_mesh); x_dist_attr.set_dims_mapping({0, 1, -1, -1}); x_dist_attr.set_dynamic_dims({false, false, false, false}); auto boxes_dist_attr = TensorDistAttr(); boxes_dist_attr.set_process_mesh(process_mesh); boxes_dist_attr.set_dims_mapping({-1, 1}); boxes_dist_attr.set_dynamic_dims({false, false}); auto boxes_num_dist_attr = TensorDistAttr(); boxes_num_dist_attr.set_process_mesh(process_mesh); boxes_num_dist_attr.set_dims_mapping(std::vector{0}); boxes_num_dist_attr.set_dynamic_dims({false}); phi::distributed::DistMetaTensor x = phi::distributed::DistMetaTensor( common::make_ddim({2, 4, 16, 16}), x_dist_attr); phi::distributed::DistMetaTensor boxes = phi::distributed::DistMetaTensor( common::make_ddim({6, 6}), boxes_dist_attr); phi::distributed::DistMetaTensor boxes_num = phi::distributed::DistMetaTensor( common::make_ddim({2}), boxes_num_dist_attr); phi::distributed::SpmdInfo forward_info = phi::distributed::RoiAlignInferSpmd(x, boxes, boxes_num, pooled_height, pooled_width, spatial_scale, sampling_ratio, aligned); EXPECT_EQ(forward_info.first.size(), 3UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {-1, 1, -1, -1}); check_dim_mapping(forward_info.first[1], {-1, -1}); check_dim_mapping(forward_info.first[2], {-1}); check_dim_mapping(forward_info.second[0], {-1, 1, -1, -1}); forward_info = phi::distributed::RoiAlignInferSpmd(x, boxes, phi::distributed::DistMetaTensor(), pooled_height, pooled_width, spatial_scale, sampling_ratio, aligned); EXPECT_EQ(forward_info.first.size(), 3UL); EXPECT_EQ(forward_info.second.size(), 1UL); check_dim_mapping(forward_info.first[0], {-1, 1, -1, -1}); check_dim_mapping(forward_info.first[1], {-1, -1}); check_empty_dist_attr(forward_info.first[2]); check_dim_mapping(forward_info.second[0], {-1, 1, -1, -1}); // test backward // [0, 1, -1, -1], [-1, 1], [0], [0, -1, -1, -1] --> [-1, 1, -1, -1],[-1, // -1],[-1],[-1,1,-1,-1],[-1, 1, -1, -1] auto out_grad_dist_attr = TensorDistAttr(); out_grad_dist_attr.set_process_mesh(process_mesh); out_grad_dist_attr.set_dims_mapping({0, -1, -1, -1}); out_grad_dist_attr.set_dynamic_dims({false, false, false, false}); phi::distributed::DistMetaTensor out_grad = phi::distributed::DistMetaTensor( common::make_ddim({6, 2, 3, 3}), out_grad_dist_attr); phi::distributed::SpmdInfo backward_info = phi::distributed::RoiAlignGradInferSpmd(x, boxes, boxes_num, out_grad, pooled_height, pooled_width, spatial_scale, sampling_ratio, aligned); EXPECT_EQ(backward_info.first.size(), 4UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {-1, 1, -1, -1}); check_dim_mapping(backward_info.first[1], {-1, -1}); check_dim_mapping(backward_info.first[2], {-1}); check_dim_mapping(backward_info.first[3], {-1, 1, -1, -1}); check_dim_mapping(backward_info.second[0], {-1, 1, -1, -1}); backward_info = phi::distributed::RoiAlignGradInferSpmd( x, boxes, phi::distributed::DistMetaTensor(), out_grad, pooled_height, pooled_width, spatial_scale, sampling_ratio, aligned); EXPECT_EQ(backward_info.first.size(), 4UL); EXPECT_EQ(backward_info.second.size(), 1UL); check_dim_mapping(backward_info.first[0], {-1, 1, -1, -1}); check_dim_mapping(backward_info.first[1], {-1, -1}); check_empty_dist_attr(backward_info.first[2]); check_dim_mapping(backward_info.first[3], {-1, 1, -1, -1}); check_dim_mapping(backward_info.first[0], {-1, 1, -1, -1}); } } // namespace auto_parallel } // namespace distributed } // namespace paddle