| 10795 | // ggml_compute_forward_soft_max_back |
| 10796 | |
| 10797 | static void ggml_compute_forward_soft_max_back_f32( |
| 10798 | const struct ggml_compute_params * params, |
| 10799 | const struct ggml_tensor * src0, |
| 10800 | const struct ggml_tensor * src1, |
| 10801 | struct ggml_tensor * dst) { |
| 10802 | GGML_ASSERT(ggml_is_contiguous(src0)); |
| 10803 | GGML_ASSERT(ggml_is_contiguous(src1)); |
| 10804 | GGML_ASSERT(ggml_is_contiguous(dst)); |
| 10805 | GGML_ASSERT(ggml_are_same_shape(src0, dst)); |
| 10806 | GGML_ASSERT(ggml_are_same_shape(src1, dst)); |
| 10807 | |
| 10808 | if (params->type == GGML_TASK_INIT || params->type == GGML_TASK_FINALIZE) { |
| 10809 | return; |
| 10810 | } |
| 10811 | |
| 10812 | // TODO: handle transposed/permuted matrices |
| 10813 | |
| 10814 | const int ith = params->ith; |
| 10815 | const int nth = params->nth; |
| 10816 | |
| 10817 | const int nc = src0->ne[0]; |
| 10818 | const int nr = ggml_nrows(src0); |
| 10819 | |
| 10820 | // rows per thread |
| 10821 | const int dr = (nr + nth - 1)/nth; |
| 10822 | |
| 10823 | // row range for this thread |
| 10824 | const int ir0 = dr*ith; |
| 10825 | const int ir1 = MIN(ir0 + dr, nr); |
| 10826 | |
| 10827 | for (int i1 = ir0; i1 < ir1; i1++) { |
| 10828 | float *dy = (float *)((char *) src0->data + i1*src0->nb[1]); |
| 10829 | float *y = (float *)((char *) src1->data + i1*src1->nb[1]); |
| 10830 | float *dx = (float *)((char *) dst->data + i1*dst->nb[1]); |
| 10831 | |
| 10832 | #ifndef NDEBUG |
| 10833 | for (int i = 0; i < nc; ++i) { |
| 10834 | //printf("p[%d] = %f\n", i, p[i]); |
| 10835 | assert(!isnan(dy[i])); |
| 10836 | assert(!isnan(y[i])); |
| 10837 | } |
| 10838 | #endif |
| 10839 | // Jii = yi - yi*yi |
| 10840 | // Jij = -yi*yj |
| 10841 | // J = diag(y)-y.T*y |
| 10842 | // dx = J * dy |
| 10843 | // dxk = sum_i(Jki * dyi) |
| 10844 | // dxk = sum_i(-yk*yi * dyi) - (-yk*yk)*dyk + (yk - yk*yk)*dyk |
| 10845 | // dxk = sum_i(-yk*yi * dyi) + yk*yk*dyk + yk*dyk - yk*yk*dyk |
| 10846 | // dxk = sum_i(-yk*yi * dyi) + yk*dyk |
| 10847 | // dxk = -yk * sum_i(yi * dyi) + yk*dyk |
| 10848 | // dxk = -yk * dot(y, dy) + yk*dyk |
| 10849 | // dxk = yk * (- dot(y, dy) + dyk) |
| 10850 | // dxk = yk * (dyk - dot(y, dy)) |
| 10851 | // |
| 10852 | // post-order: |
| 10853 | // dot_y_dy := dot(y, dy) |
| 10854 | // dx := dy |
no test coverage detected