void pydynd::array_setitem(const dynd::nd::array &n, PyObject *subscript, PyObject *value) { if (subscript == Py_Ellipsis) { n.assign(value); #if PY_VERSION_HEX < 0x03000000 } else if (PyInt_Check(subscript)) { long i = PyInt_AS_LONG(subscript); n(i).assign(value); #endif // PY_VERSION_HEX < 0x03000000 } else if (PyLong_Check(subscript)) { intptr_t i = PyLong_AsSsize_t(subscript); if (i == -1 && PyErr_Occurred()) { throw runtime_error("error converting int value"); } n(i).assign(value); } else { intptr_t size; shortvector<irange> indices; pyobject_as_irange_array(size, indices, subscript); n.at_array(size, indices.get(), false).assign(value); } }
void pydynd::array_broadcast_assign_from_py(const dynd::nd::array &a, PyObject *value, const dynd::eval::eval_context *ectx) { array_broadcast_assign_from_py(a.get_type(), a.get_arrmeta(), a.get_readwrite_originptr(), value, ectx); }
void pydynd::array_broadcast_assign_from_py(const dynd::nd::array &a, PyObject *value, const dynd::eval::eval_context *ectx) { array_broadcast_assign_from_py(a.get_type(), a.get()->metadata(), a.data(), value, ectx); }
inline bool array_is_c_contiguous(const dynd::nd::array &n) { intptr_t ndim = n.get_ndim(); dynd::dimvector shape(ndim), strides(ndim); n.get_shape(shape.get()); n.get_strides(strides.get()); return dynd::strides_are_c_contiguous(ndim, n.get_dtype().get_data_size(), shape.get(), strides.get()); }
dynd::nd::array pydynd::array_getitem(const dynd::nd::array& n, PyObject *subscript) { if (subscript == Py_Ellipsis) { return n.at_array(0, NULL); } else { // Convert the pyobject into an array of iranges intptr_t size; shortvector<irange> indices; pyobject_as_irange_array(size, indices, subscript); // Do an indexing operation return n.at_array(size, indices.get()); } }
inline ::testing::AssertionResult CompareDyNDArrayToJSON(const char *expr1, const char *expr2, const char *json, const dynd::nd::array &b) { using namespace dynd; nd::array a(nd::empty(b.get_type())); parse_json(a, json); return CompareDyNDArrays(expr1, expr2, a, b); }
void pydynd::array_setitem(const dynd::nd::array& n, PyObject *subscript, PyObject *value) { if (subscript == Py_Ellipsis) { array_broadcast_assign_from_py(n, value); #if PY_VERSION_HEX < 0x03000000 } else if (PyInt_Check(subscript)) { long i = PyInt_AS_LONG(subscript); const char *metadata = n.get_ndo_meta(); char *data = n.get_readwrite_originptr(); ndt::type d = n.get_type().at_single(i, &metadata, const_cast<const char **>(&data)); array_broadcast_assign_from_py(d, metadata, data, value); #endif // PY_VERSION_HEX < 0x03000000 } else if (PyLong_Check(subscript)) { intptr_t i = PyLong_AsSsize_t(subscript); if (i == -1 && PyErr_Occurred()) { throw runtime_error("error converting int value"); } const char *metadata = n.get_ndo_meta(); char *data = n.get_readwrite_originptr(); ndt::type d = n.get_type().at_single(i, &metadata, const_cast<const char **>(&data)); array_broadcast_assign_from_py(d, metadata, data, value); } else { intptr_t size; shortvector<irange> indices; pyobject_as_irange_array(size, indices, subscript); array_broadcast_assign_from_py(n.at_array(size, indices.get(), false), value); } }
inline ::testing::AssertionResult CompareDyNDArrayValues(const char *expr1, const char *expr2, const dynd::nd::array &val1, const dynd::nd::array &val2) { using namespace dynd; ndt::type common_tp; try { common_tp = promote_types_arithmetic(val1.get_type(), val2.get_type()); } catch (const type_error &) { return ::testing::AssertionFailure() << "The types of " << expr1 << " and " << expr2 << " do not have mutually promotable types\n" << expr1 << " has type " << val1.get_type() << ",\n" << expr2 << " has type " << val2.get_type() << "."; } nd::array v1 = nd::empty(common_tp), v2 = nd::empty(common_tp); v1.vals() = val1; v2.vals() = val2; return CompareDyNDArrays(expr1, expr2, v1, v2); }
bool pydynd::array_contains(const dynd::nd::array& n, PyObject *x) { if (n.get_ndo() == NULL) { return false; } if (n.get_ndim() == 0) { // TODO: Allow for struct types, etc? throw runtime_error("cannot call __contains__ on a scalar dynd array"); } // Turn 'n' into type/metadata/data with a uniform_dim leading dimension nd::array tmp; ndt::type dt; const base_uniform_dim_type *budd; const char *metadata, *data; if (n.get_type().get_kind() == uniform_dim_kind) { dt = n.get_type(); budd = static_cast<const base_uniform_dim_type *>(dt.extended()); metadata = n.get_ndo_meta(); data = n.get_readonly_originptr(); } else { tmp = n.eval(); if (tmp.get_type().get_kind() != uniform_dim_kind) { throw runtime_error("internal error in array_contains: expected uniform_dim kind after eval() call"); } dt = tmp.get_type(); budd = static_cast<const base_uniform_dim_type *>(dt.extended()); metadata = tmp.get_ndo_meta(); data = tmp.get_readonly_originptr(); } // Turn 'x' into a dynd array, and make a comparison kernel nd::array x_ndo = array_from_py(x, 0, false); const ndt::type& x_dt = x_ndo.get_type(); const char *x_metadata = x_ndo.get_ndo_meta(); const char *x_data = x_ndo.get_readonly_originptr(); const ndt::type& child_dt = budd->get_element_type(); const char *child_metadata = metadata + budd->get_element_metadata_offset(); comparison_ckernel_builder k; try { make_comparison_kernel(&k, 0, x_dt, x_metadata, child_dt, child_metadata, comparison_type_equal, &eval::default_eval_context); } catch(const not_comparable_error&) { return false; } contains_data aux; aux.x_data = x_data; aux.k = &k; aux.found = false; budd->foreach_leading(const_cast<char *>(data), metadata, &contains_callback, &aux); return aux.found; }
inline ::testing::AssertionResult AssertArrayNear(const char *expected_expr, const char *actual_expr, const char *rel_error_max_expr, const dynd::nd::array &expected, const dynd::nd::array &actual, double rel_error_max) { const dynd::ndt::type &expected_tp = expected.get_type(); const dynd::ndt::type &actual_tp = actual.get_type(); if (expected_tp.get_type_id() == dynd::cuda_device_type_id && actual_tp.get_type_id() == dynd::cuda_device_type_id) { return AssertArrayNear(expected_expr, actual_expr, rel_error_max_expr, expected.to_host(), actual.to_host(), rel_error_max); } std::unique_ptr<test_class<dynd::complex<double>>> c(new test_class<dynd::complex<double>>(rel_error_max)); dynd::nd::callable af = dynd::nd::functional::elwise(dynd::nd::functional::apply(c.get())); af(expected, actual); bool res = c->flag; if (res) { return ::testing::AssertionSuccess(); } return ::testing::AssertionFailure() << "the values do not match"; }
nd::string::string(const nd::array& rhs) { if (!rhs.is_null()) { if (rhs.is_immutable() && rhs.get_type().get_type_id() == string_type_id && rhs.get_type().extended<ndt::string_type>()->get_encoding() == string_encoding_utf_8) { // It's already immutable and the right type m_value = rhs; } else if (rhs.get_type().value_type().get_kind() == string_kind) { m_value = rhs.ucast(ndt::make_string()).eval_immutable(); } else { stringstream ss; ss << "Cannot implicitly convert nd::array of type " << rhs.get_type().value_type() << " to string"; throw type_error(ss.str()); } } }
dynd::nd::array pydynd::array_eval(const dynd::nd::array &n, PyObject *ectx_obj) { return n.eval(eval_context_from_pyobj(ectx_obj)); }
inline std::string array_debug_print(const dynd::nd::array &n) { std::stringstream ss; n.debug_print(ss); return ss.str(); }
dynd::nd::array pydynd::array_ucast(const dynd::nd::array &n, const ndt::type &dt, intptr_t replace_ndim) { return n.ucast(dt, replace_ndim); }
dynd::nd::array pydynd::array_cast(const dynd::nd::array &n, const ndt::type &dt) { return n.cast(dt); }
dynd::nd::array pydynd::array_eval(const dynd::nd::array &n) { return n.eval(); }
inline ::testing::AssertionResult CompareDyNDArrays(const char *expr1, const char *expr2, const dynd::nd::array &val1, const dynd::nd::array &val2) { using namespace dynd; if (val1.get_type().get_type_id() == cuda_device_type_id && val2.get_type().get_type_id() == cuda_device_type_id) { return CompareDyNDArrays(expr1, expr2, val1.to_host(), val2.to_host()); } if (val1.equals_exact(val2)) { return ::testing::AssertionSuccess(); } else { if (val1.get_type() != val2.get_type()) { return ::testing::AssertionFailure() << "The types of " << expr1 << " and " << expr2 << " do not match\n" << expr1 << " has type " << val1.get_type() << ",\n" << expr2 << " has type " << val2.get_type() << "."; } else if (val1.get_shape() != val2.get_shape()) { return ::testing::AssertionFailure() << "The shapes of " << expr1 << " and " << expr2 << " do not match\n" << expr1 << " has shape " << ShapeFormatter(val1.get_shape()) << ",\n" << expr2 << " has shape " << ShapeFormatter(val2.get_shape()) << "."; } else if (val1.get_type().get_kind() == struct_kind) { const ndt::struct_type *bsd = val1.get_type().extended<ndt::struct_type>(); intptr_t field_count = bsd->get_field_count(); for (intptr_t i = 0; i < field_count; ++i) { nd::array field1 = val1(i), field2 = val2(i); if (!field1.equals_exact(field2)) { return ::testing::AssertionFailure() << "The values of " << expr1 << " and " << expr2 << " do not match at field index " << i << ", name \"" << bsd->get_field_name(i) << "\"\n" << expr1 << " has field value " << field1 << ",\n" << expr2 << " has field value " << field2 << "."; } } return ::testing::AssertionFailure() << "DYND ASSERTION INTERNAL ERROR: One of the struct fields " "should have compared unequal"; } else if (val1.get_type().get_kind() == tuple_kind) { const ndt::tuple_type *bsd = val1.get_type().extended<ndt::tuple_type>(); intptr_t field_count = bsd->get_field_count(); for (intptr_t i = 0; i < field_count; ++i) { nd::array field1 = val1(i), field2 = val2(i); if (!field1.equals_exact(field2)) { return ::testing::AssertionFailure() << "The values of " << expr1 << " and " << expr2 << " do not match at field index " << i << "\"\n" << expr1 << " has field value " << field1 << ",\n" << expr2 << " has field value " << field2 << "."; } } return ::testing::AssertionFailure() << "DYND ASSERTION INTERNAL ERROR: One of the tuple fields " "should have compared unequal"; } else if (val1.get_ndim() > 0) { intptr_t dim_size = val1.get_dim_size(); for (intptr_t i = 0; i < dim_size; ++i) { nd::array sub1 = val1(i), sub2 = val2(i); if (!sub1.equals_exact(sub2)) { return ::testing::AssertionFailure() << "The values of " << expr1 << " and " << expr2 << " do not match at index " << i << "\"\n" << expr1 << " has subarray value " << sub1 << ",\n" << expr2 << " has subarray value " << sub2 << "."; } } return ::testing::AssertionFailure() << "DYND ASSERTION INTERNAL ERROR: One of the subarrays " "should have compared unequal\n" << expr1 << " has value " << val1 << ",\n" << expr2 << " has value " << val2 << "."; } else { return ::testing::AssertionFailure() << "The values of " << expr1 << " and " << expr2 << " do not match\n" << expr1 << " has value " << val1 << ",\n" << expr2 << " has value " << val2 << "."; } } }
dynd::nd::array pydynd::array_eval_copy(const dynd::nd::array &n, PyObject *access, PyObject *ectx_obj) { uint32_t access_flags = pyarg_creation_access_flags(access); return n.eval_copy(access_flags, eval_context_from_pyobj(ectx_obj)); }
dynd::nd::array pydynd::array_cast(const dynd::nd::array& n, const ndt::type& dt, PyObject *assign_error_obj) { return n.cast(dt, pyarg_error_mode(assign_error_obj)); }
dynd::nd::array pydynd::array_ucast(const dynd::nd::array& n, const ndt::type& dt, intptr_t replace_ndim, PyObject *assign_error_obj) { return n.ucast(dt, replace_ndim, pyarg_error_mode(assign_error_obj)); }