MCPcopy Create free account
hub / github.com/dmlc/xgboost / CopyArrayToR

Function CopyArrayToR

R-package/src/xgboost_R.cc:238–283  ·  view source on GitHub ↗

Allocate a R vector and copy an array interface encoded object to it.

Source from the content-addressed store, hash-verified

236
237// Allocate a R vector and copy an array interface encoded object to it.
238[[nodiscard]] SEXP CopyArrayToR(const char *array_str, SEXP ctoken) {
239 xgboost::ArrayInterface<1> array{xgboost::StringView{array_str}};
240 // R supports only int and double.
241 bool is_int_type =
242 xgboost::DispatchDType(array.type, [](auto t) { return std::is_integral_v<decltype(t)>; });
243 bool is_float = xgboost::DispatchDType(
244 array.type, [](auto v) { return std::is_floating_point_v<decltype(v)>; });
245 CHECK(is_int_type || is_float) << "Internal error: Invalid DType.";
246 CHECK(array.is_contiguous) << "Internal error: Return by XGBoost should be contiguous";
247
248 // Note: the only case in which this will receive an integer type is
249 // for the 'indptr' part of the quantile cut outputs, which comes
250 // in sorted order, so the last element contains the maximum value.
251 bool fits_into_C_int = xgboost::DispatchDType(array.type, [&](auto t) {
252 using T = decltype(t);
253 if (!std::is_integral_v<decltype(t)>) {
254 return false;
255 }
256 auto ptr = static_cast<T const *>(array.data);
257 T last_elt = ptr[array.n - 1];
258 if (last_elt < 0) {
259 last_elt = -last_elt; // no std::abs overload for all possible types
260 }
261 return last_elt <= std::numeric_limits<int>::max();
262 });
263 bool use_int = is_int_type && fits_into_C_int;
264
265 // Allocate memory in R
266 SEXP out =
267 Rf_protect(use_int ? SafeAllocInteger(array.n, ctoken) : SafeAllocReal(array.n, ctoken));
268
269 xgboost::DispatchDType(array.type, [&](auto t) {
270 using T = decltype(t);
271 auto in_ptr = static_cast<T const *>(array.data);
272 if (use_int) {
273 auto out_ptr = INTEGER(out);
274 std::copy_n(in_ptr, array.n, out_ptr);
275 } else {
276 auto out_ptr = REAL(out);
277 std::copy_n(in_ptr, array.n, out_ptr);
278 }
279 });
280
281 Rf_unprotect(1);
282 return out;
283}
284} // namespace
285
286/*!

Callers 1

Calls 3

SafeAllocIntegerFunction · 0.85
SafeAllocRealFunction · 0.85
DispatchDTypeFunction · 0.50

Tested by

no test coverage detected