exception_ptr make_exception_ptr(T v) { return copy_exception(wrap<T> (v)); }
exception_ptr make_exception_ptr(T v) { return copy_exception(v); }
numpy_extractor ( PyObject * X, bool allow_copy) { if (X==NULL) TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is NULL !"; if (_import_array()!=0) TRIQS_RUNTIME_ERROR <<"Internal Error in importing numpy"; // make sure IndexMap is cuboid ?s static const char Order = IndexMapType::index_order_type::C_or_F; static_assert( ((Order=='F')||(Order=='C')), "Ordering must be C or Fortran"); if ((!PyArray_Check(X)) && (Order=='D')) TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is not a numpy and you ask me to deduce the ordering in memory !"; const int elementsType (numpy_to_C_type<typename boost::remove_const<ValueType>::type>::arraytype); int rank = IndexMapType::rank; static const char * error_msg = " A deep copy of the object would be necessary while views are supposed to guarantee to present a *view* of the python data.\n"; if (!allow_copy) { // in case of a view, we decide ourselves if we can do it... // a previous uses PyArray_FromAny, but behaviour changes between different version of numpy, so it is not portable... if (!PyArray_Check(X)) throw copy_exception () << error_msg<<" Indeed the object was not even an array !\n"; if ( elementsType != PyArray_TYPE((PyArrayObject*)X)) throw copy_exception () << error_msg<<" The deep copy is caused by a type mismatch of the elements. \n"; PyArrayObject *arr = (PyArrayObject *)X; if ( arr->nd != rank) throw copy_exception () << error_msg<<" Rank mismatch . numpy array is of rank "<< arr->nd << "while you ask for rank "<< rank<<". \n"; if ((Order == 'C') && (PyArray_ISFORTRAN(arr))) throw copy_exception () << error_msg<<" The numpy is in Fortran order while it is expected in C order. \n"; if ((Order == 'F') && (!PyArray_ISFORTRAN(arr))) throw copy_exception () << error_msg<<" The numpy is not in Fortran order as it is expected. \n"; numpy_obj = X; Py_INCREF(X); } else { // From X, we ask the numpy library to make a numpy, and of the correct type. // This handles automatically the cases where : // - we have list, or list of list/tuple // - the numpy type is not the one we want. // - adjust the dimension if needed // If X is an array : // - if Order is same, don't change it // - else impose it (may provoque a copy). // if X is not array : // - Order = FortranOrder or SameOrder - > Fortran order otherwise C bool ForceCast = false;// Unless FORCECAST is present in flags, this call will generate an error if the data type cannot be safely obtained from the object. int flags = (ForceCast ? NPY_FORCECAST : 0) ;// do NOT force a copy | (make_copy ? NPY_ENSURECOPY : 0); if (!(PyArray_Check(X) && (Order=='D'))) flags |= (Order =='F' ? NPY_F_CONTIGUOUS : NPY_C_CONTIGUOUS); //impose mem order //if (!(PyArray_Check(X) && (Order=='D'))) flags |= (Order =='F' ? NPY_FARRAY : NPY_CARRAY); //impose mem order numpy_obj= PyArray_FromAny(X,PyArray_DescrFromType(elementsType), rank,rank, flags , NULL ); // do several checks if (!numpy_obj) {// The convertion of X to a numpy has failed ! if (PyErr_Occurred()) {PyErr_Print();PyErr_Clear();} TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is not convertible to a numpy. "; } assert (PyArray_Check(numpy_obj)); assert((numpy_obj->ob_refcnt==1) || ((numpy_obj ==X))); arr_obj = (PyArrayObject *)numpy_obj; try { if (arr_obj->nd!=rank) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : dimensions do not match"; if (arr_obj->descr->type_num != elementsType) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : incorrect type of element :" <<arr_obj->descr->type_num <<" vs "<<elementsType; if (Order == 'F') { if (!PyArray_ISFORTRAN(numpy_obj)) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : should be Fortran array";} else {if (!PyArray_ISCONTIGUOUS(numpy_obj)) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : should be contiguous";} } catch(...) { Py_DECREF(numpy_obj); throw;} // make sure that in case of problem, the reference counting of python is still ok... } arr_obj = (PyArrayObject *)numpy_obj; }
// return a NEW (owned) reference // inline PyObject * numpy_extractor_impl ( PyObject * X, bool allow_copy, std::string type_name, int elementsType, int rank, size_t * lengths, std::ptrdiff_t * strides, size_t size_of_ValueType) { PyObject * numpy_obj; if (X==NULL) TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is NULL !"; if (_import_array()!=0) TRIQS_RUNTIME_ERROR <<"Internal Error in importing numpy"; static const char * error_msg = " A deep copy of the object would be necessary while views are supposed to guarantee to present a *view* of the python data.\n"; if (!allow_copy) { if (!PyArray_Check(X)) throw copy_exception () << error_msg<<" Indeed the object was not even an array !\n"; if ( elementsType != PyArray_TYPE((PyArrayObject*)X)) throw copy_exception () << error_msg<<" The deep copy is caused by a type mismatch of the elements. Expected "<< type_name<< " and found XXX \n"; PyArrayObject *arr = (PyArrayObject *)X; #ifdef TRIQS_NUMPY_VERSION_LT_17 if ( arr->nd != rank) throw copy_exception () << error_msg<<" Rank mismatch . numpy array is of rank "<< arr->nd << "while you ask for rank "<< rank<<". \n"; #else if ( PyArray_NDIM(arr) != rank) throw copy_exception () << error_msg<<" Rank mismatch . numpy array is of rank "<< PyArray_NDIM(arr) << "while you ask for rank "<< rank<<". \n"; #endif numpy_obj = X; Py_INCREF(X); } else { // From X, we ask the numpy library to make a numpy, and of the correct type. // This handles automatically the cases where : // - we have list, or list of list/tuple // - the numpy type is not the one we want. // - adjust the dimension if needed // If X is an array : // - if Order is same, don't change it // - else impose it (may provoque a copy). // if X is not array : // - Order = FortranOrder or SameOrder - > Fortran order otherwise C //bool ForceCast = false;// Unless FORCECAST is present in flags, this call will generate an error if the data type cannot be safely obtained from the object. int flags = 0; //(ForceCast ? NPY_FORCECAST : 0) ;// do NOT force a copy | (make_copy ? NPY_ENSURECOPY : 0); if (!(PyArray_Check(X) )) //flags |= ( IndexMapType::traversal_order == indexmaps::mem_layout::c_order(rank) ? NPY_C_CONTIGUOUS : NPY_F_CONTIGUOUS); //impose mem order #ifdef TRIQS_NUMPY_VERSION_LT_17 flags |= (NPY_C_CONTIGUOUS); //impose mem order #else flags |= (NPY_ARRAY_C_CONTIGUOUS); //impose mem order #endif numpy_obj= PyArray_FromAny(X,PyArray_DescrFromType(elementsType), rank,rank, flags , NULL ); // do several checks if (!numpy_obj) {// The convertion of X to a numpy has failed ! if (PyErr_Occurred()) {PyErr_Print();PyErr_Clear();} TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is not convertible to a numpy. "; } assert (PyArray_Check(numpy_obj)); assert((numpy_obj->ob_refcnt==1) || ((numpy_obj ==X))); PyArrayObject *arr_obj; arr_obj = (PyArrayObject *)numpy_obj; try { #ifdef TRIQS_NUMPY_VERSION_LT_17 if (arr_obj->nd!=rank) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : dimensions do not match"; if (arr_obj->descr->type_num != elementsType) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : incorrect type of element :" <<arr_obj->descr->type_num <<" vs "<<elementsType; #else if ( PyArray_NDIM(arr_obj) !=rank) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : dimensions do not match"; if ( PyArray_DESCR(arr_obj)->type_num != elementsType) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : incorrect type of element :" <<PyArray_DESCR(arr_obj)->type_num <<" vs "<<elementsType; #endif } catch(...) { Py_DECREF(numpy_obj); throw;} // make sure that in case of problem, the reference counting of python is still ok... } // extract strides and lengths PyArrayObject *arr_obj; arr_obj = (PyArrayObject *)numpy_obj; #ifdef TRIQS_NUMPY_VERSION_LT_17 const size_t dim =arr_obj->nd; // we know that dim == rank for (size_t i=0; i< dim ; ++i) { lengths[i] = size_t(arr_obj-> dimensions[i]); strides[i] = std::ptrdiff_t(arr_obj-> strides[i])/ size_of_ValueType; } #else const size_t dim = PyArray_NDIM(arr_obj); // we know that dim == rank for (size_t i=0; i< dim ; ++i) { lengths[i] = size_t( PyArray_DIMS(arr_obj)[i]); strides[i] = std::ptrdiff_t( PyArray_STRIDES(arr_obj)[i])/ size_of_ValueType; } #endif return numpy_obj; }