Unexpected floor division with ndarrays on python 3
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 25/100
Piste de recherche
Construisez le main.cpp fourni avec le CMakeLists.txt joint dans les configurations Python 2.7 et 3.6 indiquées, puis comparez les résultats de division affichés. Lisez le code associé dans examples/ et utilisez la sortie reproduite pour déterminer si le comportement de Python 3 est attendu et s’il existe une voie prise en charge pour la division sans arrondi vers le bas ; le travail est considéré comme terminé lorsqu’une explication confirmée par un maintainer ou un fix précisément identifié est disponible.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Our primarily C++ code base uses an embedded python to do computation with help from boost::python. We are in the process of porting to python 3. We have noticed that it appears that the / operator when acting on a pair of boost::python::numpy::ndarray's yields floor division. That is to say the results are numerically consistent with constructing the same arrays in a python interpreter and then performing arr1 // arr2. We do did not see this behaviour when linking against python27.dll. To make my issue concrete I prepared an example based on those provided in the examples/ folder. It was built on windows 10 using:
- MSVC 2015
- Python 2.7.16
- Python 3.6.8
- cmake 3.16
- Ninja 1.9.0
- Boost 1.70.0
main.cpp was:
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
typedef float arr_dtype;
int main(int argc, char **argv)
{
Py_Initialize();
np::initialize();
arr_dtype raw_array1[] = {1.53f, 2.53f, 3.53f, 4.53f};
np::ndarray nd_array1 = np::from_data(raw_array1, np::dtype::get_builtin<arr_dtype>(),
p::make_tuple(4),
p::make_tuple(4),
p::object());
arr_dtype raw_array2[] = {0.1f};
np::ndarray nd_array2 = np::from_data(raw_array2, np::dtype::get_builtin<arr_dtype>(),
p::make_tuple(1),
p::make_tuple(1),
p::object());
std::cout << "ndarray 1 is " << p::extract<char const *>(p::str(nd_array1)) << std::endl;
std::cout << "ndarray 2 is " << p::extract<char const *>(p::str(nd_array2)) << std::endl;
//
p::object result_array_div = nd_array1 / nd_array2;
std::cout << "operator/ division of arrays is " << p::extract<char const *>(p::str(result_array_div)) << std::endl;
return 0;
}
For Python 27 the output when running main.exe was consistent with our expectations:
ndarray 1 is [1.53 2.53 3.53 4.53]
ndarray 2 is [0.1]
operator/ division of arrays is [15.299999 25.3 35.3 45.300003]
For Python 36 the result when running main.exe was not consistent with our (possibly misguided) expectations:
ndarray 1 is [1.53 2.53 3.53 4.53]
ndarray 2 is [0.1]
operator/ division of arrays is [15. 25. 35. 45.]
Is this expected behaviour? Is there any way to enforce non-floor division when using the / operator and python 3?
For reference the CMakeLists.txt was:
cmake_minimum_required(VERSION 3.16)
project(test_boost_numpy_division)
# version selection
if (BUILD_PY3)
set(python_package_name "Python3")
set(BOOST_ROOT "${BOOST_ROOT_PY3}")
set(py_dll_path "${Python3_ROOT_DIR}/python36.dll")
set(py_maj_min_version "36")
else()
set(python_package_name "Python2")
set(BOOST_ROOT "${BOOST_ROOT_PY2}")
set(py_dll_path "C:/Windows/System32/python27.dll")
set(py_maj_min_version "27")
endif()
set(boost_python_module_name "python${py_maj_min_version}")
set(boost_numpy_module_name "numpy${py_maj_min_version}")
# python config
find_package (${python_package_name} COMPONENTS Development REQUIRED)
# boost config
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_LIBS OFF)
find_package(Boost REQUIRED COMPONENTS ${boost_python_module_name} ${boost_numpy_module_name} unit_test_framework)
#
add_executable(main)
target_sources(main PRIVATE main.cpp)
target_link_libraries(main ${python_package_name}::Python)
target_link_libraries(main Boost::${boost_python_module_name} Boost::${boost_numpy_module_name})
set_target_properties( main
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
#
file(COPY "${Boost_LIBRARY_DIRS}/" DESTINATION "${CMAKE_BINARY_DIR}/bin")
file(COPY "${py_dll_path}" DESTINATION "${CMAKE_BINARY_DIR}/bin")
- Langage dominant
- C++
- Étoiles
- 537
- Forks
- 223
- Merge moyen
- 11 h 22 min
- PR mergées (30 j)
- 2
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de boostorg/python
-
numpy::from_data calls vector::front and crashes (or has UB) when called with a scalar object Ouverte
Difficulté 1/5 Moins d'une heure Accessibilité débutants 84/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 64/100
-
BoostDetectToolset-1.90.0.cmake file not found in an include() call in boost_python-config.cmake Ouverte
Difficulté 3/5 1-2 jours Accessibilité débutants 48/100
-
Difficulté 4/5 3-5 jours Accessibilité débutants 25/100
Toutes les issues de boostorg/python
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
flutter-webrtc/flutter-webrtc#2206 ·
-
litertlm-android AAR ships no consumer ProGuard rules → "mid == null" SIGABRT in minified apps Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
google-ai-edge/LiteRT-LM#3739 ·
-
Component: GLib
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
brave/brave-browser#59300 ·
-
Mute ydb/tests/functional/dstool/test_canonical_requests.py.Test.test_group_take_snapshot in main Ouverteai_reviewed
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
ydb-platform/ydb#53974 · 3 commentaires ·