@@ -693,10 +693,91 @@ void __global__ seeds_rebid_for_edges(int2* d_path_store,
693693 }
694694}
695695
696+ void __global__ seeds_bid_for_hits (int * d_output_graph, int2 * d_seed_proposals,
697+ int2 * d_path_store, char * d_seed_ambiguity,
698+ unsigned long long int * d_hit_bids,
699+ const unsigned int nProps, int edge_size) {
700+
701+ for (unsigned int prop_idx = threadIdx .x + blockDim .x * blockIdx .x ;
702+ prop_idx < nProps; prop_idx += gridDim .x * blockDim .x ) {
703+ if (d_seed_ambiguity[prop_idx] == -2 ) {
704+ continue ;
705+ }
706+ int2 prop = d_seed_proposals[prop_idx];
707+ unsigned long long int seed_bid =
708+ (static_cast <unsigned long long int >(prop.x ) << 32 ) |
709+ (static_cast <unsigned long long int >(prop_idx));
710+
711+ int2 path = make_int2 (0 , prop.y );
712+ while (path.y >= 0 ) {
713+ path = d_path_store[path.y ];
714+ int sp_idx = d_output_graph[traccc::device::gbts_consts::node1 +
715+ edge_size * path.x ];
716+ atomicMax (&d_hit_bids[sp_idx], seed_bid);
717+ }
718+ int sp_idx = d_output_graph[traccc::device::gbts_consts::node2 +
719+ edge_size * path.x ];
720+ atomicMax (&d_hit_bids[sp_idx], seed_bid);
721+ }
722+ }
723+
724+ inline __device__ float2 estimate_params (float4 sps[3 ]) {
725+
726+ // conformal mapping with the center at the middle spacepoint
727+
728+ float u[2 ], v[2 ];
729+
730+ const float x0 = sps[1 ].x ;
731+ const float y0 = sps[1 ].y ;
732+
733+ const float r0 = sqrtf (x0 * x0 + y0 * y0);
734+
735+ const float cosA = x0 / r0;
736+
737+ const float sinA = y0 / r0;
738+
739+ for (unsigned int k = 0 ; k < 2 ; k++) {
740+
741+ int sp_idx = (k == 1 ) ? 2 : k;
742+
743+ const float dx = sps[sp_idx].x - x0;
744+
745+ const float dy = sps[sp_idx].y - y0;
746+
747+ const float r2_inv = 1 .0f / (dx * dx + dy * dy);
748+
749+ const float xn = dx * cosA + dy * sinA;
750+
751+ const float yn = -dx * sinA + dy * cosA;
752+
753+ u[k] = xn * r2_inv;
754+ v[k] = yn * r2_inv;
755+ }
756+
757+ const float du = u[0 ] - u[1 ];
758+ if (du == 0 .0f ) {
759+ return make_float2 (0 .0f , 0 .0f );
760+ }
761+
762+ const float A = (v[0 ] - v[1 ]) / du;
763+
764+ const float B = v[1 ] - A * u[1 ];
765+
766+ // signed curvature in 1/m
767+ const float curv = 1000 .0f * B / sqrtf (1 + A * A);
768+ const float cot_t = (sps[2 ].z - sps[1 ].z ) /
769+ (sqrtf (sps[2 ].x * sps[2 ].x + sps[2 ].y * sps[2 ].y ) - r0);
770+ return make_float2 (curv, cot_t );
771+ }
772+
696773void __global__ gbts_seed_conversion_kernel (
697774 int2 * d_seed_proposals, char * d_seed_ambiguity, int2 * d_path_store,
698- int * d_output_graph, edm::seed_collection::view output_seeds,
699- const unsigned int nProps, const unsigned int max_num_neighbours) {
775+ int * d_output_graph, float4 * d_sp_params,
776+ edm::seed_collection::view output_seeds, unsigned long long int * d_hit_bids,
777+ const unsigned int nProps, const unsigned int max_num_neighbours,
778+ const float dcurv_cut_m, const float force_dropout_max_curv_m,
779+ const float best_hit_frac, const float tight_bid_cot_threshold,
780+ const bool use_dropout) {
700781
701782 int edge_size = 2 + 1 + max_num_neighbours;
702783 edm::seed_collection::device seeds_device (output_seeds);
@@ -707,23 +788,88 @@ void __global__ gbts_seed_conversion_kernel(
707788 // drop seeds that lost the bidding
708789 continue ;
709790 }
791+ // collect seed hits and reject those that lost the hit bidding
792+ char best_for_hit = 0 ;
710793 Tracklet seed;
711794 seed.size = 0 ;
712795 // dummy path to start the loop
713- int2 path = make_int2 (0 , d_seed_proposals[prop_idx].y );
796+ int2 prop = d_seed_proposals[prop_idx];
797+ int2 path = make_int2 (0 , prop.y );
714798 while (path.y >= 0 ) {
715799 path = d_path_store[path.y ];
716800 seed.nodes [seed.size ++] =
717801 d_output_graph[traccc::device::gbts_consts::node1 +
718802 edge_size * path.x ];
803+ best_for_hit +=
804+ (prop_idx ==
805+ (d_hit_bids[seed.nodes [seed.size - 1 ]] & 0xFFFFFFFFLL ));
719806 }
720807 seed.nodes [seed.size ++] =
721808 d_output_graph[traccc::device::gbts_consts::node2 +
722809 edge_size * path.x ];
723- // sample begining, middle, end sp from tracklet for now
724- seeds_device.push_back ({seed.nodes [seed.size - 1 ],
725- seed.nodes [(1 + seed.size ) / 2 - 1 ],
726- seed.nodes [0 ]});
810+ best_for_hit += (prop_idx == (d_hit_bids[seed.nodes [seed.size - 1 ]] &
811+ 0xFFFFFFFFLL ));
812+
813+ if ((best_for_hit < best_hit_frac * seed.size )) {
814+ continue ;
815+ }
816+ char diff_code = 0 ;
817+ bool force_dropout = false ;
818+ if (use_dropout) {
819+ float4 sps[3 ];
820+ // seed 1
821+ sps[0 ] = d_sp_params[seed.nodes [seed.size - 1 ]];
822+ sps[1 ] = d_sp_params[seed.nodes [(seed.size - 1 ) / 2 + 1 ]];
823+ sps[2 ] = d_sp_params[seed.nodes [0 ]];
824+ float2 curv_cot_1 = estimate_params (sps);
825+ // seed 2
826+ sps[1 ] = d_sp_params[seed.nodes [(seed.size - 1 ) / 2 ]];
827+ float2 curv_cot_2 = estimate_params (sps);
828+ sps[0 ] = d_sp_params[seed.nodes [seed.size - 2 ]];
829+ // seed 3
830+ float2 curv_cot_3 = estimate_params (sps);
831+ // for low eta (higher fake rate) seeds perform a stronger cut
832+ if ((best_for_hit < seed.size - 1 ) &
833+ (abs (curv_cot_1.y + curv_cot_2.y + curv_cot_3.y ) <
834+ 3 .0f * tight_bid_cot_threshold) &
835+ (seed.size < 5 )) {
836+ continue ;
837+ }
838+ float diff[3 ] = {abs (curv_cot_1.x - curv_cot_2.x ),
839+ abs (curv_cot_2.x - curv_cot_3.x ),
840+ abs (curv_cot_1.x - curv_cot_3.x )};
841+ diff_code = 4 * (diff[0 ] < dcurv_cut_m) +
842+ 2 * (diff[1 ] < dcurv_cut_m) + (diff[2 ] < dcurv_cut_m);
843+ // for high pt the diff may pass dispite bad estimates
844+ force_dropout = abs (curv_cot_1.x + curv_cot_2.x + curv_cot_3.x ) <
845+ 3 .0f * force_dropout_max_curv_m;
846+ force_dropout |= (abs (curv_cot_1.y + curv_cot_2.y + curv_cot_3.y ) <
847+ 3 .0f * tight_bid_cot_threshold) &
848+ diff_code == 0 ;
849+ }
850+ // use one seed from a consistant pair/set + the inconsistant one
851+ // sample spacepoints from tracklet to create seeds
852+ // include 1st order unless either 2 or 3 are consitant with the other
853+ // and 1
854+ if (diff_code != 3 & diff_code != 6 | force_dropout) {
855+ seeds_device.push_back ({seed.nodes [seed.size - 1 ],
856+ seed.nodes [(seed.size - 1 ) / 2 + 1 ],
857+ seed.nodes [0 ]});
858+ }
859+ // include 2nd order if it consistant with 1 and 3 or only 1 and 3 are
860+ // consistant
861+ if (diff_code == 1 | diff_code == 6 ) {
862+ seeds_device.push_back ({seed.nodes [seed.size - 1 ],
863+ seed.nodes [(seed.size - 1 ) / 2 ],
864+ seed.nodes [0 ]});
865+ }
866+ // include 3rd order if it is consistant with 1 and 2 or only 1 and 2
867+ // are consistant or if only 2 and 3 are consistant
868+ if (diff_code == 2 | diff_code == 3 | diff_code == 4 | force_dropout) {
869+ seeds_device.push_back ({seed.nodes [seed.size - 2 ],
870+ seed.nodes [(seed.size - 1 ) / 2 ],
871+ seed.nodes [0 ]});
872+ }
727873 }
728874}
729875
0 commit comments