Skip to content

Commit 996d192

Browse files
Copilotnjzjz
andauthored
fix(pd): change numel function return type from int to size_t to prevent overflow (#4924)
The `numel` function in the Paddle backend was using `int` for computing tensor element counts, which can overflow for large tensors. This fix changes the return type and intermediate calculations to `size_t` to handle larger tensor sizes safely. ## Problem The original implementation multiplied tensor dimensions as `int` values: ```cpp int numel(const paddle_infer::Tensor& x) const { // TODO: There might be a overflow problem here for multiply int numbers. int ret = 1; std::vector<int> x_shape = x.shape(); for (std::size_t i = 0, n = x_shape.size(); i < n; ++i) { ret *= x_shape[i]; // Can overflow for large tensors } return ret; } ``` For large tensors (e.g., shape `[50000, 50000, 10]` = 25 billion elements), this causes integer overflow and returns negative values. ## Solution - Changed return type from `int` to `size_t` - Changed intermediate calculations to use `size_t` with explicit casting - Updated all calling sites to use `size_t` variables - Removed the TODO comment since the overflow issue is now resolved ```cpp size_t numel(const paddle_infer::Tensor& x) const { size_t ret = 1; std::vector<int> x_shape = x.shape(); for (std::size_t i = 0, n = x_shape.size(); i < n; ++i) { ret *= static_cast<size_t>(x_shape[i]); // Safe from overflow } return ret; } ``` The `size_t` type can handle up to 2^64 elements on 64-bit systems (vs 2^31 for `int`), making it appropriate for tensor element counts. This change is backward compatible since `std::vector::resize()` and other consumers already accept `size_t`. Fixes #4551. <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/deepmodeling/deepmd-kit/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: njzjz <9496702+njzjz@users.noreply.github.com>
1 parent 64e108f commit 996d192

File tree

2 files changed

+13
-14
lines changed

2 files changed

+13
-14
lines changed

source/api_cc/include/DeepPotPD.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,11 @@ class DeepPotPD : public DeepPotBackend {
282282
* @brief Compute the number of elements in a tensor.
283283
* @param[in] x Tensor x.
284284
**/
285-
int numel(const paddle_infer::Tensor& x) const {
286-
// TODO: There might be a overflow problem here for multiply int numbers.
287-
int ret = 1;
285+
size_t numel(const paddle_infer::Tensor& x) const {
286+
size_t ret = 1;
288287
std::vector<int> x_shape = x.shape();
289288
for (std::size_t i = 0, n = x_shape.size(); i < n; ++i) {
290-
ret *= x_shape[i];
289+
ret *= static_cast<size_t>(x_shape[i]);
291290
}
292291
return ret;
293292
};

source/api_cc/src/DeepPotPD.cc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,9 @@ void DeepPotPD::compute(ENERGYVTYPE& ener,
474474
auto energy_ = predictor_fl->GetOutputHandle(output_names.at(1));
475475
auto force_ = predictor_fl->GetOutputHandle(output_names.at(2));
476476
auto virial_ = predictor_fl->GetOutputHandle(output_names.at(4));
477-
int output_energy_size = numel(*energy_);
478-
int output_force_size = numel(*force_);
479-
int output_virial_size = numel(*virial_);
477+
size_t output_energy_size = numel(*energy_);
478+
size_t output_force_size = numel(*force_);
479+
size_t output_virial_size = numel(*virial_);
480480
// output energy
481481
ener.resize(output_energy_size);
482482
energy_->CopyToCpu(ener.data());
@@ -597,26 +597,26 @@ void DeepPotPD::compute(ENERGYVTYPE& ener,
597597
auto force_ = predictor->GetOutputHandle(output_names.at(3));
598598
auto virial_ = predictor->GetOutputHandle(output_names.at(5));
599599

600-
int enery_numel = numel(*energy_);
600+
size_t enery_numel = numel(*energy_);
601601
assert(enery_numel > 0);
602602
ener.resize(enery_numel);
603603
energy_->CopyToCpu(ener.data());
604604

605-
int force_numel = numel(*force_);
605+
size_t force_numel = numel(*force_);
606606
assert(force_numel > 0);
607607
force.resize(force_numel);
608608
force_->CopyToCpu(force.data());
609609

610-
int virial_numel = numel(*virial_);
610+
size_t virial_numel = numel(*virial_);
611611
assert(virial_numel > 0);
612612
virial.resize(virial_numel);
613613
virial_->CopyToCpu(virial.data());
614614

615615
if (atomic) {
616616
auto atom_energy_ = predictor->GetOutputHandle(output_names.at(0));
617617
auto atom_virial_ = predictor->GetOutputHandle(output_names.at(1));
618-
int atom_energy_numel = numel(*atom_energy_);
619-
int atom_virial_numel = numel(*atom_virial_);
618+
size_t atom_energy_numel = numel(*atom_energy_);
619+
size_t atom_virial_numel = numel(*atom_virial_);
620620
assert(atom_energy_numel > 0);
621621
assert(atom_virial_numel > 0);
622622
atom_energy.resize(atom_energy_numel);
@@ -656,7 +656,7 @@ template void DeepPotPD::compute<float, std::vector<ENERGYTYPE>>(
656656
that need to be postprocessed */
657657
void DeepPotPD::get_type_map(std::string& type_map) {
658658
auto type_map_tensor = predictor->GetOutputHandle("buffer_type_map");
659-
int type_map_size = numel(*type_map_tensor);
659+
size_t type_map_size = numel(*type_map_tensor);
660660

661661
std::vector<int> type_map_arr(type_map_size, 0);
662662
type_map_tensor->CopyToCpu(type_map_arr.data());
@@ -670,7 +670,7 @@ template <typename BUFFERTYPE>
670670
void DeepPotPD::get_buffer(const std::string& buffer_name,
671671
std::vector<BUFFERTYPE>& buffer_array) {
672672
auto buffer_tensor = predictor->GetOutputHandle(buffer_name);
673-
int buffer_size = numel(*buffer_tensor);
673+
size_t buffer_size = numel(*buffer_tensor);
674674
buffer_array.resize(buffer_size);
675675
buffer_tensor->CopyToCpu(buffer_array.data());
676676
}

0 commit comments

Comments
 (0)