| 3970 | } |
| 3971 | |
| 3972 | bool MIOpenSupport::DoDepthConcatenate( |
| 3973 | Stream* stream, port::ArraySlice<dnn::BatchDescriptor> input_dimensions, |
| 3974 | port::ArraySlice<const DeviceMemory<float>*> input_data, |
| 3975 | DeviceMemory<float>* output_data) { |
| 3976 | CHECK_EQ(input_dimensions.size(), input_data.size()); |
| 3977 | |
| 3978 | for (const auto& dimensions : input_dimensions) { |
| 3979 | if (dimensions.layout() != dnn::DataLayout::kBatchDepthYX) { |
| 3980 | LOG(ERROR) << "MIOpenSupport::DoDepthConcatenate currently only " |
| 3981 | "supports the kBatchDepthYX layout."; |
| 3982 | return false; |
| 3983 | } |
| 3984 | } |
| 3985 | |
| 3986 | if (input_dimensions.empty()) { |
| 3987 | return true; // Nothing to do. |
| 3988 | } |
| 3989 | |
| 3990 | dnn::BatchDescriptor output_dimensions = |
| 3991 | dnn::BatchDescriptor::DepthConcatenateOutputDescriptor(input_dimensions); |
| 3992 | |
| 3993 | const int64 area = output_dimensions.width() * output_dimensions.height(); |
| 3994 | const auto index = [area](int64 batch, int64 depth, int64 yx, |
| 3995 | int64 max_depth) { |
| 3996 | return (batch * max_depth + depth) * area + yx; |
| 3997 | }; |
| 3998 | |
| 3999 | std::vector<float> output_host(output_dimensions.ElementCount()); |
| 4000 | std::vector<float> tmp; |
| 4001 | int64 depth_sum = 0; |
| 4002 | for (size_t i = 0; i < input_data.size(); ++i) { |
| 4003 | const auto& dimensions = input_dimensions[i]; |
| 4004 | tmp.resize(dimensions.ElementCount()); |
| 4005 | stream->ThenMemcpyD2H<float>(*input_data[i], absl::MakeSpan(tmp)); |
| 4006 | port::Status block_status = stream->BlockHostUntilDone(); |
| 4007 | if (!block_status.ok()) { |
| 4008 | LOG(ERROR) << "BlockHostUntilDone failed: " << block_status; |
| 4009 | return false; |
| 4010 | } |
| 4011 | |
| 4012 | for (int64 batch = 0; batch < output_dimensions.count(); ++batch) { |
| 4013 | for (int64 yx = 0; yx < area; ++yx) { |
| 4014 | for (int64 depth = 0; depth < dimensions.feature_map_count(); ++depth) { |
| 4015 | LOG(INFO) << output_dimensions.ElementCount() << ' ' << batch << ' ' |
| 4016 | << yx << ' ' << depth; |
| 4017 | output_host[index(batch, depth + depth_sum, yx, |
| 4018 | output_dimensions.feature_map_count())] = |
| 4019 | tmp[index(batch, depth, yx, dimensions.feature_map_count())]; |
| 4020 | } |
| 4021 | } |
| 4022 | } |
| 4023 | depth_sum += dimensions.feature_map_count(); |
| 4024 | } |
| 4025 | stream->ThenMemcpyH2D<float>(output_host, output_data); |
| 4026 | return true; |
| 4027 | } |
| 4028 | |
| 4029 | bool MIOpenSupport::DoElementwiseOperate( |
no test coverage detected