cudaTransientFstatExpWindow.cu 4.34 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
__global__ void cudaTransientFstatExpWindow ( float *input,
                                              unsigned int numAtoms,
                                              unsigned int TAtom,
                                              unsigned int t0_data,
                                              unsigned int win_t0,
                                              unsigned int win_dt0,
                                              unsigned int win_tau,
                                              unsigned int win_dtau,
                                              unsigned int Fmn_rows,
                                              unsigned int Fmn_cols,
                                              float *Fmn
                                            )
{

  /* match CUDA thread indexing and high-level (t0,tau) indexing */
  unsigned int m         = blockDim.x * blockIdx.x + threadIdx.x; // t0:  row
  unsigned int n         = blockDim.y * blockIdx.y + threadIdx.y; // tau: column
  /* unraveled 1D index for 2D output array */
  unsigned int outidx    = Fmn_cols * m + n;

  /* hardcoded copy from lalpulsar */
  unsigned int TRANSIENT_EXP_EFOLDING = 3;

  if ( (m < Fmn_rows) && (n < Fmn_cols) ) {

    /* compute Fstat-atom index i_t0 in [0, numAtoms) */
    unsigned int TAtomHalf = TAtom/2; // integer division
    unsigned int t0 = win_t0 + m * win_dt0;
David Keitel's avatar
David Keitel committed
29
30
    /* integer round: floor(x+0.5) */
    int i_tmp = ( t0 - t0_data + TAtomHalf ) / TAtom;
31
32
33
34
35
36
37
38
    if ( i_tmp < 0 ) {
        i_tmp = 0;
    }
    unsigned int i_t0 = (unsigned int)i_tmp;
    if ( i_t0 >= numAtoms ) {
        i_t0 = numAtoms - 1;
    }

David Keitel's avatar
David Keitel committed
39
40
    /* translate n into an atoms end-index
     * for this search interval [t0, t0+Tcoh],
41
42
43
44
45
46
     * giving the index range of atoms to sum over
     */
    unsigned int tau = win_tau + n * win_dtau;

    /* get end-time t1 of this transient-window search
     * for given tau, what Tcoh should the exponential window cover?
David Keitel's avatar
David Keitel committed
47
48
     * for speed reasons we want to truncate
     * Tcoh = tau * TRANSIENT_EXP_EFOLDING
49
50
51
52
53
54
     * with the e-folding factor chosen such that the window-value
     * is practically negligible after that, where it will be set to 0
     */
//     unsigned int t1 = lround( win_t0 + TRANSIENT_EXP_EFOLDING * win_tau);
    unsigned int t1 = t0 + TRANSIENT_EXP_EFOLDING * tau;

David Keitel's avatar
David Keitel committed
55
56
57
58
      /* compute window end-time Fstat-atom index i_t1 in [0, numAtoms)
       * using integer round: floor(x+0.5)
       */
    i_tmp = ( t1 - t0_data + TAtomHalf ) / TAtom  - 1;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    if ( i_tmp < 0 ) {
        i_tmp = 0;
    }
    unsigned int i_t1 = (unsigned int)i_tmp;
    if ( i_t1 >= numAtoms ) {
        i_t1 = numAtoms - 1;
    }

    /* now we have two valid atoms-indices [i_t0, i_t1]
     * spanning our Fstat-window to sum over
     */

    float Ad    = 0.0f;
    float Bd    = 0.0f;
    float Cd    = 0.0f;
    float Fa_re = 0.0f;
    float Fa_im = 0.0f;
    float Fb_re = 0.0f;
    float Fb_im = 0.0f;

    unsigned short input_cols = 7; // must match input matrix!

    /* sum up atoms */
    for ( unsigned int i=i_t0; i<=i_t1; i++ ) {

      unsigned int t_i = t0_data + i * TAtom;

      float win_i = 0.0;
      if ( t_i >= t0 && t_i <= t1 ) {
        float x = 1.0 * ( t_i - t0 ) / tau;
        win_i = exp ( -x );
      }

      float win2_i = win_i * win_i;

      Ad    += input[i*input_cols+0] * win2_i; // a2_alpha
      Bd    += input[i*input_cols+1] * win2_i; // b2_alpha
      Cd    += input[i*input_cols+2] * win2_i; // ab_alpha
      Fa_re += input[i*input_cols+3] * win_i; // Fa_alpha_re
      Fa_im += input[i*input_cols+4] * win_i; // Fa_alpha_im
      Fb_re += input[i*input_cols+5] * win_i; // Fb_alpha_re
      Fb_im += input[i*input_cols+6] * win_i; // Fb_alpha_im

    }

    /* get determinant */
    float Dd = ( Ad * Bd - Cd * Cd );
    float DdInv = 0.0f;
    /* safety catch as in XLALWeightMultiAMCoeffs():
     * make it so that in the end F=0 instead of -nan
     */
    if ( Dd > 0.0 ) {
      DdInv  = 1.0 / Dd;
    }

    /* from XLALComputeFstatFromFaFb */
    float F  = DdInv * (  Bd * ( Fa_re*Fa_re + Fa_im*Fa_im )
                        + Ad * ( Fb_re*Fb_re + Fb_im*Fb_im )
                        - 2.0 * Cd * ( Fa_re * Fb_re + Fa_im * Fb_im )
                       );

    /* store result in Fstat-matrix
     * at unraveled index of element {m,n}
     */
    Fmn[outidx] = F;

  } // ( (m < Fmn_rows) && (n < Fmn_cols) )

} // cudaTransientFstatExpWindow()