@@ -15,14 +15,13 @@ where
1515 TG1Affine : G1Affine < TG1 , TG1Fp > ,
1616 TG1ProjAddAffine : G1ProjAddAffine < TG1 , TG1Fp , TG1Affine > ,
1717{
18- points : Vec < TG1Affine > ,
19- points_projection : Vec < TG1 > ,
18+ points : Vec < TG1 > ,
2019 numpoints : usize ,
2120
2221 batch_numpoints : usize ,
23- batch_points : Vec < Vec < TG1Affine > > ,
22+ batch_points : Vec < Vec < TG1 > > ,
2423
25- g1_marker : PhantomData < TG1 > ,
24+ g1_affine_marker : PhantomData < TG1Affine > ,
2625 g1_fp_marker : PhantomData < TG1Fp > ,
2726 fr_marker : PhantomData < TFr > ,
2827 g1_affine_add_marker : PhantomData < TG1ProjAddAffine > ,
@@ -96,23 +95,34 @@ impl<
9695 > BosCosterTable < TFr , TG1 , TG1Fp , TG1Affine , TG1ProjAddAffine >
9796{
9897 pub fn new ( points : & [ TG1 ] , matrix : & [ Vec < TG1 > ] ) -> Result < Option < Self > , String > {
99- Ok ( Some ( Self {
100- numpoints : points. len ( ) ,
101- points : Vec :: from ( points)
102- . iter ( )
103- . map ( |g1| TG1Affine :: into_affine ( g1) )
104- . collect ( ) ,
105- points_projection : Vec :: from ( points) ,
106-
107- // TODO:
108- batch_numpoints : 0 ,
109- batch_points : Vec :: new ( ) ,
110-
111- fr_marker : PhantomData ,
112- g1_fp_marker : PhantomData ,
113- g1_marker : PhantomData ,
114- g1_affine_add_marker : PhantomData ,
115- } ) )
98+ if matrix. is_empty ( ) {
99+ Ok ( Some ( Self {
100+ numpoints : points. len ( ) ,
101+ points : Vec :: from ( points) ,
102+
103+ // TODO:
104+ batch_numpoints : 0 ,
105+ batch_points : Vec :: new ( ) ,
106+
107+ fr_marker : PhantomData ,
108+ g1_fp_marker : PhantomData ,
109+ g1_affine_marker : PhantomData ,
110+ g1_affine_add_marker : PhantomData ,
111+ } ) )
112+ } else {
113+ Ok ( Some ( Self {
114+ numpoints : points. len ( ) ,
115+ points : Vec :: from ( points) ,
116+
117+ batch_numpoints : matrix[ 0 ] . len ( ) ,
118+ batch_points : Vec :: from ( matrix) ,
119+
120+ fr_marker : PhantomData ,
121+ g1_fp_marker : PhantomData ,
122+ g1_affine_marker : PhantomData ,
123+ g1_affine_add_marker : PhantomData ,
124+ } ) )
125+ }
116126 }
117127
118128 #[ cfg( feature = "parallel" ) ]
@@ -121,7 +131,7 @@ impl<
121131 }
122132
123133 pub fn multiply_sequential ( & self , scalars : & [ TFr ] ) -> TG1 {
124- Self :: multiply_sequential_raw ( & self . points_projection , scalars)
134+ Self :: multiply_sequential_raw ( & self . points , scalars)
125135 }
126136
127137 fn multiply_sequential_raw ( bases : & [ TG1 ] , scalars : & [ TFr ] ) -> TG1 {
@@ -165,16 +175,55 @@ impl<
165175 return pair. point . mul ( & TFr :: from_u64_arr ( & pair. scalar . data ) ) ;
166176 }
167177
168- // TODO:
169178 pub fn multiply_batch ( & self , scalars : & [ Vec < TFr > ] ) -> Vec < TG1 > {
170179 assert ! ( scalars. len( ) == self . batch_points. len( ) ) ;
171180
172- self . batch_points
173- . iter ( )
174- . zip ( scalars)
175- . map ( |( points, scalars) | {
176- Self :: multiply_sequential_raw ( & self . points_projection , scalars)
177- } )
178- . collect :: < Vec < _ > > ( )
181+ #[ cfg( not( feature = "parallel" ) ) ]
182+ {
183+ self . batch_points
184+ . iter ( )
185+ . zip ( scalars)
186+ . map ( |( points, scalars) | Self :: multiply_sequential_raw ( points, scalars) )
187+ . collect :: < Vec < _ > > ( )
188+ }
189+
190+ #[ cfg( feature = "parallel" ) ]
191+ {
192+ use super :: {
193+ cell:: Cell ,
194+ thread_pool:: { da_pool, ThreadPoolExt } ,
195+ } ;
196+ use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
197+ use std:: sync:: Arc ;
198+
199+ let pool = da_pool ( ) ;
200+ let ncpus = pool. max_count ( ) ;
201+ let counter = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
202+ let mut results: Vec < Cell < TG1 > > = Vec :: with_capacity ( scalars. len ( ) ) ;
203+ #[ allow( clippy:: uninit_vec) ]
204+ unsafe {
205+ results. set_len ( results. capacity ( ) )
206+ } ;
207+ let results = & results[ ..] ;
208+
209+ for _ in 0 ..ncpus {
210+ let counter = counter. clone ( ) ;
211+ pool. joined_execute ( move || loop {
212+ let work = counter. fetch_add ( 1 , Ordering :: Relaxed ) ;
213+
214+ if work >= scalars. len ( ) {
215+ break ;
216+ }
217+
218+ let result =
219+ Self :: multiply_sequential_raw ( & self . batch_points [ work] , & scalars[ work] ) ;
220+ unsafe { * results[ work] . as_ptr ( ) . as_mut ( ) . unwrap ( ) = result } ;
221+ } ) ;
222+ }
223+
224+ pool. join ( ) ;
225+
226+ results. iter ( ) . map ( |it| it. as_mut ( ) . clone ( ) ) . collect ( )
227+ }
179228 }
180229}
0 commit comments