backward propogation of Gemm Args: dy (CTensor): The shape of A should be (M, K) if transA is 0, or (K, M) if transA is non-zero. Returns: CTensor, the gradient over A CTensor, the gradient over B CTensor(optional), the gradien
(self, dy)
| 3734 | return tmpM |
| 3735 | |
| 3736 | def backward(self, dy): |
| 3737 | """ |
| 3738 | backward propogation of Gemm |
| 3739 | Args: |
| 3740 | dy (CTensor): The shape of A should be (M, K) if transA is 0, or (K, M) if transA is non-zero. |
| 3741 | Returns: |
| 3742 | CTensor, the gradient over A |
| 3743 | CTensor, the gradient over B |
| 3744 | CTensor(optional), the gradient over C |
| 3745 | """ |
| 3746 | _A, _B, C = self.inputs |
| 3747 | # y = alpha * A * B => da = alpha * dy * BT |
| 3748 | # y = alpha * A * BT => da = alpha * dy * B |
| 3749 | # y = alpha * AT * B => da = alpha * B * dyT = alpha * (dy * BT)T |
| 3750 | # y = alpha * AT * BT => da = alpha * BT * dyT = alpha * (dy * B)T |
| 3751 | da = singa.MultFloat(singa.Mult(dy, singa.DefaultTranspose(_B)), |
| 3752 | self.alpha) |
| 3753 | if self.transA: |
| 3754 | da = singa.DefaultTranspose(da) |
| 3755 | |
| 3756 | # y = alpha * A * B => db = alpha * AT * dy |
| 3757 | # y = alpha * AT * B => db = alpha * A * dy |
| 3758 | # y = alpha * A * BT => db = alpha * dyT * A = alpha * (AT * dy)T |
| 3759 | # y = alpha * AT * BT => db = alpha * dyT * AT = alpha * (A * dy)T |
| 3760 | db = singa.MultFloat(singa.Mult(singa.DefaultTranspose(_A), dy), |
| 3761 | self.alpha) |
| 3762 | if self.transB: |
| 3763 | db = singa.DefaultTranspose(db) |
| 3764 | if C: |
| 3765 | dc = back_broadcast(dy.shape(), C.shape(), |
| 3766 | singa.MultFloat(dy, self.beta)) |
| 3767 | return da, db, dc |
| 3768 | else: |
| 3769 | return da, db |
| 3770 | |
| 3771 | |
| 3772 | def gemm(A, B, C=None, alpha=1.0, beta=1.0, transA=0, transB=0): |
nothing calls this directly
no test coverage detected