Changeset c036ddb in sasmodels for sasmodels/kernel_iq.c
- Timestamp:
- Aug 7, 2018 8:45:45 PM (6 years ago)
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/kernel_iq.c
r01c8d9e rc036ddb 29 29 // CALL_IQ(q, table) : call the Iq function for 1D calcs. 30 30 // 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. 31 33 // CALL_IQ_AC(qa, qc, table) : call the Iqxy function for symmetric shapes 32 34 // CALL_IQ_ABC(qa, qc, table) : call the Iqxy function for asymmetric shapes … … 85 87 out_spin = clip(out_spin, 0.0, 1.0); 86 88 // Previous version of this function took the square root of the weights, 87 // under the assumption that 89 // under the assumption that 88 90 // 89 91 // w*I(q, rho1, rho2, ...) = I(q, sqrt(w)*rho1, sqrt(w)*rho2, ...) … … 272 274 273 275 // ==================== KERNEL CODE ======================== 276 #define COMPUTE_F1_F2 defined(CALL_FQ) 274 277 kernel 275 278 void KERNEL_NAME( … … 338 341 // The code differs slightly between opencl and dll since opencl is only 339 342 // 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. 345 344 #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 350 354 #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 352 361 if (pd_start == 0) { 353 362 #ifdef USE_OPENMP 354 363 #pragma omp parallel for 355 364 #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; 359 369 #endif 360 370 } 361 371 //if (q_index==0) printf("start %d %g %g\n", pd_start, pd_norm, result[0]); 362 372 #endif // !USE_OPENCL 363 364 365 366 373 367 374 … … 454 461 455 462 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> 458 465 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) 473 488 474 489 #elif defined(CALL_IQ_A) … … 504 519 #define APPLY_ROTATION() qabc_apply(&rotation, qx, qy, &qa, &qb, &qc) 505 520 #define CALL_KERNEL() CALL_IQ_ABC(qa, qb, qc, local_values.table) 521 506 522 #elif defined(CALL_IQ_XY) 507 523 // direct call to qx,qy calculator … … 517 533 // logic in the IQ_AC and IQ_ABC branches. This will become more important 518 534 // 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 520 537 #define APPLY_PROJECTION() const double weight=weight0 521 538 #elif defined(CALL_IQ_XY) // pass orientation to the model … … 668 685 if (weight > cutoff) { 669 686 pd_norm += weight * CALL_VOLUME(local_values.table); 687 #if COMPUTE_F1_F2 688 weight_norm += weight; 689 #endif 670 690 BUILD_ROTATION(); 671 #if BETA 672 if (weight > cutoff) { 673 weight_norm += weight;} 674 #endif 691 675 692 #ifndef USE_OPENCL 676 693 // DLL needs to explicitly loop over the q values. … … 718 735 } 719 736 #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 724 739 #else 725 740 const double scattering = CALL_KERNEL(); … … 729 744 730 745 #ifdef USE_OPENCL 731 #if defined(CALL_IQ)&& BETA == 1732 this_result += weight * scatteringF2;733 this_beta_result += weight * scatteringF1;734 735 746 #if COMPUTE_F1_F2 747 this_F1 += weight * F1; 748 this_F2 += weight * F2; 749 #else 750 this_result += weight * scattering; 736 751 #endif 737 752 #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 743 757 result[q_index] += weight * scattering; 744 758 #endif … … 767 781 // Remember the current result and the updated norm. 768 782 #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; 773 793 #endif 774 if (q_index == 0) result[nq] = pd_norm;775 794 776 795 //if (q_index == 0) printf("res: %g/%g\n", result[0], pd_norm); 777 796 #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; 781 802 #endif 782 803 //printf("res: %g/%g\n", result[0], pd_norm); … … 784 805 785 806 // ** clear the macros in preparation for the next kernel ** 807 #undef COMPUTE_F1_F2 786 808 #undef PD_INIT 787 809 #undef PD_OPEN
Note: See TracChangeset
for help on using the changeset viewer.