@@ -164,6 +164,106 @@ SEXP FARR_buffer_map(
164164 return (R_NilValue);
165165}
166166
167+ // [[Rcpp::export]]
168+ SEXP FARR_buffer_map2 (
169+ std::vector<std::string>& input_filebases,
170+ const Function& map,
171+ const int & buffer_nelems
172+ ){
173+ // prepare inputs
174+ int narrays = input_filebases.size ();
175+ std::vector<List> metas (narrays);
176+ std::vector<SEXPTYPE> arr_types (narrays);
177+ std::vector<SEXPTYPE> file_buffer_types (narrays);
178+ std::vector<SEXPTYPE> memory_buffer_types (narrays);
179+
180+ std::vector<SEXP> cumparts (narrays);
181+ std::vector<int64_t > part_lengths (narrays);
182+
183+ SEXP in_dim = R_NilValue;
184+
185+ for (int ii = 0 ; ii < narrays; ii++){
186+ std::string fbase = correct_filebase (input_filebases[ii]);
187+ input_filebases[ii] = fbase;
188+ List meta = FARR_meta (fbase);
189+ metas[ii] = meta;
190+ arr_types[ii] = meta[" sexp_type" ];
191+ file_buffer_types[ii] = file_buffer_sxptype (arr_types[ii]);
192+ memory_buffer_types[ii] = array_memory_sxptype (arr_types[ii]);
193+ cumparts[ii] = realToInt64_inplace (meta[" cumsum_part_sizes" ]);
194+ if ( in_dim == R_NilValue ){
195+ in_dim = meta[" dimension" ];
196+ realToInt64_inplace (in_dim);
197+ }
198+ }
199+
200+ if ( in_dim == R_NilValue ){
201+ stop (" Cannot obtain input dimensions" );
202+ }
203+
204+ R_xlen_t in_ndims = Rf_length (in_dim);
205+ int64_t * in_dimptr = INTEGER64 (in_dim);
206+ int64_t in_unit_partlen = 1 ;
207+ for (R_xlen_t jj = 0 ; jj <in_ndims - 1 ; jj++, in_dimptr++){
208+ in_unit_partlen *= *in_dimptr;
209+ }
210+ int64_t in_array_length = in_unit_partlen * *(INTEGER64 (in_dim) + (in_ndims - 1 ));
211+
212+
213+ // allocate buffers
214+ SEXP argbuffers = PROTECT (Rf_allocVector (VECSXP, narrays));
215+ for (int ii = 0 ; ii < narrays; ii++){
216+ SET_VECTOR_ELT (argbuffers, ii, PROTECT (Rf_allocVector (memory_buffer_types[ii], buffer_nelems)));
217+ }
218+
219+ int64_t current_pos = 0 ;
220+
221+ int ncores = getThreads ();
222+ if ( ncores > narrays ){
223+ ncores = narrays;
224+ }
225+
226+ R_xlen_t niters = in_array_length / buffer_nelems;
227+ if ( niters * buffer_nelems < in_array_length ){
228+ niters++;
229+ }
230+ SEXP ret = PROTECT (Rf_allocVector (VECSXP, niters));
231+ R_xlen_t iter = 0 ;
232+
233+ for ( ; current_pos < in_array_length; current_pos += buffer_nelems, iter++ ){
234+
235+ #pragma omp parallel num_threads(ncores)
236+ {
237+ #pragma omp for schedule(static, 1) nowait
238+ for (int ii = 0 ; ii < narrays; ii++){
239+ FARR_subset_sequential (
240+ input_filebases[ii],
241+ in_unit_partlen,
242+ cumparts[ii],
243+ arr_types[ii],
244+ VECTOR_ELT (argbuffers, ii),
245+ current_pos, buffer_nelems
246+ );
247+ }
248+ }
249+
250+ try {
251+ SET_VECTOR_ELT (ret, iter, Shield<SEXP>(map (argbuffers)));
252+ } catch (std::exception &ex){
253+ UNPROTECT (2 + narrays);
254+ forward_exception_to_r (ex);
255+ } catch (...){
256+ UNPROTECT (2 + narrays);
257+ stop (" Unknown error." );
258+ }
259+
260+
261+ }
262+
263+ UNPROTECT (2 + narrays);
264+
265+ return (ret);
266+ }
167267
168268/* ** R
169269# devtools::load_all()
@@ -190,6 +290,15 @@ FARR_buffer_map(
190290 3L,
191291 1L
192292)
193-
293+ res <- FARR_buffer_map2(
294+ fbases,
295+ function(x){
296+ print(c(x[[1]], sum(x[[1]])))
297+ sum(x[[1]])
298+ },
299+ 3L,
300+ 1L
301+ )
302+ # y[] - simplify2array(res)
194303
195304*/
0 commit comments