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

Method DoMatMul

tensorflow/stream_executor/cuda/cuda_dnn.cc:5848–5981  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5846}
5847
5848bool CudnnSupport::DoMatMul(Stream* stream,
5849 const DeviceMemory<float>& input_data,
5850 const DeviceMemory<float>& weights,
5851 const dnn::BatchDescriptor& input_dimensions,
5852 const dnn::BatchDescriptor& output_dimensions,
5853 DeviceMemory<float>* output_data) {
5854 if (input_dimensions.count() != output_dimensions.count()) {
5855 LOG(ERROR) << "MatMul input and output dimensions are not compatible.";
5856 return false;
5857 }
5858
5859 // We do not permute the input or output, instead we just
5860 // reinterpret the layout. We are working with row-major matrices
5861 // and the rows of the input and output correspond to batch, so
5862 // batch has to be outermost in both the input and output.
5863 //
5864 // By adding transposes to the BLAS gemm call we could perhaps make
5865 // the kYXDepthBatch layout work as well, but there has been no need
5866 // for that so far.
5867 if (input_dimensions.layout() != dnn::DataLayout::kBatchYXDepth &&
5868 input_dimensions.layout() != dnn::DataLayout::kBatchDepthYX) {
5869 LOG(ERROR) << "Unsupported MatMul input layout.";
5870 return false;
5871 }
5872 if (output_dimensions.layout() != dnn::DataLayout::kBatchYXDepth &&
5873 output_dimensions.layout() != dnn::DataLayout::kBatchDepthYX) {
5874 LOG(ERROR) << "Unsupported MatMul output layout.";
5875 return false;
5876 }
5877
5878 if (output_dimensions.width() == 1 && output_dimensions.height() == 1) {
5879 // This is a fast path that also supports the kBatchYXDepth layout.
5880
5881 // The matrices here are in row-major format while BLAS expects
5882 // column-major, i.e. our matrices are transposed as far as BLAS
5883 // is concerned. So we need to compute output^T =
5884 // input^T*weights^T. There is no parameter for transposing the
5885 // output in BLAS gemm, but instead we can transpose both sides of
5886 // the equality to see that this is equivalent to
5887 // output=weights*input. So we only need to swap the order of
5888 // weights and input in the matrix product to correct for the
5889 // row-major versus column-major difference.
5890 const float alpha = 1.0f; // Take the matrix product without scaling it.
5891 const float beta = 0.0f; // Ignore the original values in output_data.
5892 const int64 m = output_dimensions.NodesAcrossFeatureMaps();
5893 const int64 n = input_dimensions.count();
5894 const int64 k = input_dimensions.NodesAcrossFeatureMaps();
5895 stream->ThenBlasGemm(blas::Transpose::kNoTranspose,
5896 blas::Transpose::kNoTranspose, m, n, k, alpha, weights,
5897 m, input_data, k, beta, output_data, m);
5898 } else {
5899 // This is a slower and more complex path that supports output
5900 // width() * height() > 1, though it only supports the
5901 // kBatchYXDepth layout. Does support kBatchDepthYX if output
5902 // feature_map_count() == 1, as then there is no difference
5903 // between the two layouts.
5904 //
5905 // The operation here is the same as above, except that we have to

Callers

nothing calls this directly

Calls 13

feature_map_countMethod · 0.80
NodesPerFeatureMapMethod · 0.80
opaqueMethod · 0.80
countMethod · 0.45
layoutMethod · 0.45
widthMethod · 0.45
heightMethod · 0.45
ElementCountMethod · 0.45
reserveMethod · 0.45
sizeMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected