| 767 | } |
| 768 | |
| 769 | int LGBM_DatasetCreateFromCSRFunc(void* get_row_funptr, |
| 770 | int num_rows, |
| 771 | int64_t num_col, |
| 772 | const char* parameters, |
| 773 | const DatasetHandle reference, |
| 774 | DatasetHandle* out) { |
| 775 | API_BEGIN(); |
| 776 | if (num_col <= 0) { |
| 777 | Log::Fatal("The number of columns should be greater than zero."); |
| 778 | } else if (num_col >= INT32_MAX) { |
| 779 | Log::Fatal("The number of columns should be smaller than INT32_MAX."); |
| 780 | } |
| 781 | auto get_row_fun = *static_cast<std::function<void(int idx, std::vector<std::pair<int, double>>&)>*>(get_row_funptr); |
| 782 | auto param = Config::Str2Map(parameters); |
| 783 | Config config; |
| 784 | config.Set(param); |
| 785 | if (config.num_threads > 0) { |
| 786 | omp_set_num_threads(config.num_threads); |
| 787 | } |
| 788 | std::unique_ptr<Dataset> ret; |
| 789 | int32_t nrow = num_rows; |
| 790 | if (reference == nullptr) { |
| 791 | // sample data first |
| 792 | Random rand(config.data_random_seed); |
| 793 | int sample_cnt = static_cast<int>(nrow < config.bin_construct_sample_cnt ? nrow : config.bin_construct_sample_cnt); |
| 794 | auto sample_indices = rand.Sample(nrow, sample_cnt); |
| 795 | sample_cnt = static_cast<int>(sample_indices.size()); |
| 796 | std::vector<std::vector<double>> sample_values(num_col); |
| 797 | std::vector<std::vector<int>> sample_idx(num_col); |
| 798 | // local buffer to re-use memory |
| 799 | std::vector<std::pair<int, double>> buffer; |
| 800 | for (size_t i = 0; i < sample_indices.size(); ++i) { |
| 801 | auto idx = sample_indices[i]; |
| 802 | get_row_fun(static_cast<int>(idx), buffer); |
| 803 | for (std::pair<int, double>& inner_data : buffer) { |
| 804 | CHECK(inner_data.first < num_col); |
| 805 | if (std::fabs(inner_data.second) > kZeroThreshold || std::isnan(inner_data.second)) { |
| 806 | sample_values[inner_data.first].emplace_back(inner_data.second); |
| 807 | sample_idx[inner_data.first].emplace_back(static_cast<int>(i)); |
| 808 | } |
| 809 | } |
| 810 | } |
| 811 | DatasetLoader loader(config, nullptr, 1, nullptr); |
| 812 | ret.reset(loader.CostructFromSampleData(Common::Vector2Ptr<double>(&sample_values).data(), |
| 813 | Common::Vector2Ptr<int>(&sample_idx).data(), |
| 814 | static_cast<int>(num_col), |
| 815 | Common::VectorSize<double>(sample_values).data(), |
| 816 | sample_cnt, nrow)); |
| 817 | } else { |
| 818 | ret.reset(new Dataset(nrow)); |
| 819 | ret->CreateValid( |
| 820 | reinterpret_cast<const Dataset*>(reference)); |
| 821 | } |
| 822 | |
| 823 | OMP_INIT_EX(); |
| 824 | std::vector<std::pair<int, double>> threadBuffer; |
| 825 | #pragma omp parallel for schedule(static) private(threadBuffer) |
| 826 | for (int i = 0; i < num_rows; ++i) { |
nothing calls this directly
no test coverage detected