Changeset c036ddb in sasmodels for sasmodels/kernel_iq.c


Ignore:
Timestamp:
Aug 7, 2018 8:45:45 PM (6 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
7e923c2
Parents:
7b0abf8
Message:

refactor so Iq is not needed if Fq is defined

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernel_iq.c

    r01c8d9e rc036ddb  
    2929//  CALL_IQ(q, table) : call the Iq function for 1D calcs. 
    3030//  CALL_IQ_A(q, table) : call the Iq function with |q| for 2D data. 
     31//  CALL_FQ(q, F1, F2, table) : call the Fq function for 1D calcs. 
     32//  CALL_FQ_A(q, F1, F2, table) : call the Iq function with |q| for 2D data. 
    3133//  CALL_IQ_AC(qa, qc, table) : call the Iqxy function for symmetric shapes 
    3234//  CALL_IQ_ABC(qa, qc, table) : call the Iqxy function for asymmetric shapes 
     
    8587  out_spin = clip(out_spin, 0.0, 1.0); 
    8688  // Previous version of this function took the square root of the weights, 
    87   // under the assumption that  
     89  // under the assumption that 
    8890  // 
    8991  //     w*I(q, rho1, rho2, ...) = I(q, sqrt(w)*rho1, sqrt(w)*rho2, ...) 
     
    272274 
    273275// ==================== KERNEL CODE ======================== 
     276#define COMPUTE_F1_F2 defined(CALL_FQ) 
    274277kernel 
    275278void KERNEL_NAME( 
     
    338341  // The code differs slightly between opencl and dll since opencl is only 
    339342  // seeing one q value (stored in the variable "this_result") while the dll 
    340   // version must loop over all q 
    341   #if BETA 
    342   double *beta_result = &(result[nq+1]); // = result + nq + 1 
    343   double weight_norm = (pd_start == 0 ? 0.0 : result[2*nq+1]); 
    344   #endif 
     343  // version must loop over all q. 
    345344  #ifdef USE_OPENCL 
    346     double pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
    347     double this_result = (pd_start == 0 ? 0.0 : result[q_index]); 
    348     #if BETA 
    349       double this_beta_result = (pd_start == 0 ? 0.0 : result[nq + q_index]; 
     345    #if COMPUTE_F1_F2 
     346      double pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
     347      double weight_norm = (pd_start == 0 ? 0.0 : result[2*nq+1]); 
     348      double this_F2 = (pd_start == 0 ? 0.0 : result[q_index]); 
     349      double this_F1 = (pd_start == 0 ? 0.0 : result[q_index+nq+1]); 
     350    #else 
     351      double pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
     352      double this_result = (pd_start == 0 ? 0.0 : result[q_index]); 
     353    #endif 
    350354  #else // !USE_OPENCL 
    351     double pd_norm = (pd_start == 0 ? 0.0 : result[nq]);  
     355    #if COMPUTE_F1_F2 
     356      double pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
     357      double weight_norm = (pd_start == 0 ? 0.0 : result[2*nq+1]); 
     358    #else 
     359      double pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
     360    #endif 
    352361    if (pd_start == 0) { 
    353362      #ifdef USE_OPENMP 
    354363      #pragma omp parallel for 
    355364      #endif 
    356       for (int q_index=0; q_index < nq; q_index++) result[q_index] = 0.0; 
    357       #if BETA 
    358       for (int q_index=0; q_index < nq; q_index++) beta_result[q_index] = 0.0; 
     365      #if COMPUTE_F1_F2 
     366          for (int q_index=0; q_index < 2*nq+2; q_index++) result[q_index] = 0.0; 
     367      #else 
     368          for (int q_index=0; q_index < nq; q_index++) result[q_index] = 0.0; 
    359369      #endif 
    360370    } 
    361371    //if (q_index==0) printf("start %d %g %g\n", pd_start, pd_norm, result[0]); 
    362372#endif // !USE_OPENCL 
    363  
    364  
    365  
    366373 
    367374 
     
    454461 
    455462 
    456 #if defined(CALL_IQ) 
    457   // unoriented 1D 
     463#if defined(CALL_FQ) // COMPUTE_F1_F2 is true 
     464  // unoriented 1D returning <F> and <F^2> 
    458465  double qk; 
    459   #if BETA == 0 
    460     #define FETCH_Q() do { qk = q[q_index]; } while (0) 
    461     #define BUILD_ROTATION() do {} while(0) 
    462     #define APPLY_ROTATION() do {} while(0) 
    463     #define CALL_KERNEL() CALL_IQ(qk,local_values.table) 
    464  
    465   // unoriented 1D Beta 
    466   #elif BETA == 1 
    467     double F1, F2; 
    468     #define FETCH_Q() do { qk = q[q_index]; } while (0) 
    469     #define BUILD_ROTATION() do {} while(0) 
    470     #define APPLY_ROTATION() do {} while(0) 
    471     #define CALL_KERNEL() CALL_IQ(qk,F1,F2,local_values.table) 
    472   #endif 
     466  double F1, F2; 
     467  #define FETCH_Q() do { qk = q[q_index]; } while (0) 
     468  #define BUILD_ROTATION() do {} while(0) 
     469  #define APPLY_ROTATION() do {} while(0) 
     470  #define CALL_KERNEL() CALL_FQ(qk,F1,F2,local_values.table) 
     471 
     472#elif defined(CALL_FQ_A) 
     473  // unoriented 2D return <F> and <F^2> 
     474  double qx, qy; 
     475  double F1, F2; 
     476  #define FETCH_Q() do { qx = q[2*q_index]; qy = q[2*q_index+1]; } while (0) 
     477  #define BUILD_ROTATION() do {} while(0) 
     478  #define APPLY_ROTATION() do {} while(0) 
     479  #define CALL_KERNEL() CALL_FQ_A(sqrt(qx*qx+qy*qy),F1,F2,local_values.table) 
     480 
     481#elif defined(CALL_IQ) 
     482  // unoriented 1D return <F^2> 
     483  double qk; 
     484  #define FETCH_Q() do { qk = q[q_index]; } while (0) 
     485  #define BUILD_ROTATION() do {} while(0) 
     486  #define APPLY_ROTATION() do {} while(0) 
     487  #define CALL_KERNEL() CALL_IQ(qk,local_values.table) 
    473488 
    474489#elif defined(CALL_IQ_A) 
     
    504519  #define APPLY_ROTATION() qabc_apply(&rotation, qx, qy, &qa, &qb, &qc) 
    505520  #define CALL_KERNEL() CALL_IQ_ABC(qa, qb, qc, local_values.table) 
     521 
    506522#elif defined(CALL_IQ_XY) 
    507523  // direct call to qx,qy calculator 
     
    517533// logic in the IQ_AC and IQ_ABC branches.  This will become more important 
    518534// if we implement more projections, or more complicated projections. 
    519 #if defined(CALL_IQ) || defined(CALL_IQ_A)  // no orientation 
     535#if defined(CALL_IQ) || defined(CALL_IQ_A) || defined(CALL_FQ) || defined(CALL_FQ_A) 
     536  // no orientation 
    520537  #define APPLY_PROJECTION() const double weight=weight0 
    521538#elif defined(CALL_IQ_XY) // pass orientation to the model 
     
    668685    if (weight > cutoff) { 
    669686      pd_norm += weight * CALL_VOLUME(local_values.table); 
     687      #if COMPUTE_F1_F2 
     688      weight_norm += weight; 
     689      #endif 
    670690      BUILD_ROTATION(); 
    671 #if BETA 
    672     if (weight > cutoff) { 
    673       weight_norm += weight;} 
    674 #endif 
     691 
    675692#ifndef USE_OPENCL 
    676693      // DLL needs to explicitly loop over the q values. 
     
    718735          } 
    719736        #else  // !MAGNETIC 
    720           #if defined(CALL_IQ) && BETA == 1 
    721             CALL_KERNEL(); 
    722             const double scatteringF1 = F1; 
    723             const double scatteringF2 = F2; 
     737          #if COMPUTE_F1_F2 
     738            CALL_KERNEL(); // sets F1 and F2 by reference 
    724739          #else 
    725740            const double scattering = CALL_KERNEL(); 
     
    729744 
    730745        #ifdef USE_OPENCL 
    731           #if defined(CALL_IQ)&& BETA == 1 
    732              this_result += weight * scatteringF2; 
    733              this_beta_result += weight * scatteringF1; 
    734             #else 
    735               this_result += weight * scattering; 
     746          #if COMPUTE_F1_F2 
     747            this_F1 += weight * F1; 
     748            this_F2 += weight * F2; 
     749          #else 
     750            this_result += weight * scattering; 
    736751          #endif 
    737752        #else // !USE_OPENCL 
    738           #if defined(CALL_IQ)&& BETA == 1 
    739             result[q_index] += weight * scatteringF2; 
    740             beta_result[q_index] += weight * scatteringF1; 
    741             #endif 
    742             #else 
     753          #if COMPUTE_F1_F2 
     754            result[q_index] += weight * F2; 
     755            result[q_index+nq+1] += weight * F1; 
     756          #else 
    743757            result[q_index] += weight * scattering; 
    744758          #endif 
     
    767781// Remember the current result and the updated norm. 
    768782#ifdef USE_OPENCL 
    769   result[q_index] = this_result; 
    770   if (q_index == 0) result[nq] = pd_norm; 
    771   #if BETA 
    772   beta_result[q_index] = this_beta_result; 
     783  #if COMPUTE_F1_F2 
     784    result[q_index] = this_F2; 
     785    result[q_index+nq+1] = this_F1; 
     786    if (q_index == 0) { 
     787      result[nq] = pd_norm; 
     788      result[2*nq+1] = weight_norm; 
     789    } 
     790  #else 
     791    result[q_index] = this_result; 
     792    if (q_index == 0) result[nq] = pd_norm; 
    773793  #endif 
    774   if (q_index == 0) result[nq] = pd_norm; 
    775794 
    776795//if (q_index == 0) printf("res: %g/%g\n", result[0], pd_norm); 
    777796#else // !USE_OPENCL 
    778   result[nq] = pd_norm; 
    779   #if BETA 
    780   result[2*nq+1] = weight_norm; 
     797  #if COMPUTE_F1_F2 
     798    result[nq] = pd_norm; 
     799    result[2*nq+1] = weight_norm; 
     800  #else 
     801    result[nq] = pd_norm; 
    781802  #endif 
    782803//printf("res: %g/%g\n", result[0], pd_norm); 
     
    784805 
    785806// ** clear the macros in preparation for the next kernel ** 
     807#undef COMPUTE_F1_F2 
    786808#undef PD_INIT 
    787809#undef PD_OPEN 
Note: See TracChangeset for help on using the changeset viewer.