Skip to content
This repository has been archived by the owner on Jun 21, 2022. It is now read-only.

Commit

Permalink
offsets2parents to CPU_methods.h
Browse files Browse the repository at this point in the history
  • Loading branch information
EscottC committed Jul 10, 2019
1 parent 57a9473 commit 011cceb
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 26 deletions.
120 changes: 120 additions & 0 deletions awkward-cpp/awkward/cpp/array/CPU_methods.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#ifdef __cplusplus // specifies that this is C, not C++
extern "C" {
#endif

#ifndef CPU_METHODS_H // include guard
#define CPU_METHODS_H

struct C_array_8 { // single-dimensional?
char *ptr = NULL;
ssize_t itemsize = 0;
ssize_t size = 0;
char byteorder = '='; // '=', '<', or '>'
ssize_t strides = 0;
};

struct C_array_16 {
short int *ptr = NULL;
ssize_t itemsize = 0;
ssize_t size = 0;
char byteorder = '=';
ssize_t strides = 0;
};

struct C_array_32 {
long int *ptr = NULL;
ssize_t itemsize = 0;
ssize_t size = 0;
char byteorder = '=';
ssize_t strides = 0;
};

struct C_array_64 {
long long *ptr = NULL;
ssize_t itemsize = 0;
ssize_t size = 0;
char byteorder = '=';
ssize_t strides = 0;
};

int byteswap_16bit(short int *val) {
return (*val = *val << 8 | *val >> 8) ? 1 : 0;
}

int byteswap_32bit(long int *val) {
*val = ((*val << 8) & 0xFF00FF00) | ((*val >> 8) & 0xFF00FF);
return (*val = (*val << 16) | (*val >> 16)) ? 1 : 0;
}

int byteswap_64bit(long long *val) {
*val = ((*val << 8) & 0xFF00FF00FF00FF00ULL) | ((*val >> 8) & 0x00FF00FF00FF00FFULL);
*val = ((*val << 16) & 0xFFFF0000FFFF0000ULL) | ((*val >> 16) & 0x0000FFFF0000FFFFULL);
return (*val = (*val << 32) | (*val >> 32)) ? 1 : 0;
}

int isNative(char input) { // returns true if native, false if non-native
if (input == '=')
return 1;
union {
unsigned long int i;
char c[4];
} bint = { 0x01020304 };
return ((bint.c[0] == 1 && input != '<')
|| (bint.c[0] != 1 && input != '>'));
}

int makeNative_16bit(struct C_array_16 *input) {
if (input->itemsize != 2)
return 0;
int N = input->strides / input->itemsize;
if (!isNative(input->byteorder))
for (ssize_t i = 0; i < input->size; i++)
if (!byteswap_16bit(&(input->ptr[i * N])))
return 0;
return 1;
}

int makeNative_32bit(struct C_array_32 *input) {
if (input->itemsize != 4)
return 0;
int N = input->strides / input->itemsize;
if (!isNative(input->byteorder))
for (ssize_t i = 0; i < input->size; i++)
if (!byteswap_32bit(&(input->ptr[i * N])))
return 0;
return 1;
}

int makeNative_64bit(struct C_array_64 *input) {
if (input->itemsize != 8)
return 0;
int N = input->strides / input->itemsize;
if (!isNative(input->byteorder))
for (ssize_t i = 0; i < input->size; i++)
if (!byteswap_64bit(&(input->ptr[i * N])))
return 0;
return 1;
}

int offsets2parents_int64(struct C_array_64 *offsets, struct C_array_64 *parents) {
makeNative_64bit(offsets);
if (offsets->itemsize != 8 || parents->itemsize != 8)
return 0;
int N_off = offsets->strides / offsets->itemsize;
int N_par = parents->strides / parents->itemsize;
ssize_t j = 0;
ssize_t k = -1;
for (ssize_t i = 0; i < offsets->size; i++) {
while (j < offsets->ptr[i * N_off])
parents->ptr[N_par * j++] = (long long)k;
k++;
}
return 1;
}


#endif // end include guard

#ifdef __cplusplus // end C compiler instruction
}
#endif
4 changes: 4 additions & 0 deletions awkward-cpp/awkward/cpp/array/array_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "jagged.h"

namespace py = pybind11;

PYBIND11_MODULE(array_impl, m) {
py::class_<JaggedArray>(m, "JaggedArray")
.def(py::init<py::object, py::object, py::object>())
Expand All @@ -24,10 +26,12 @@ PYBIND11_MODULE(array_impl, m) {
.def("__getitem__", (py::object (JaggedArray::*)(ssize_t)) &JaggedArray::python_getitem)
.def("__getitem__", (py::object (JaggedArray::*)(py::slice)) &JaggedArray::python_getitem)
.def("__getitem__", (py::object (JaggedArray::*)(py::array)) &JaggedArray::python_getitem)
.def("__getitem__", (py::object (JaggedArray::*)(py::tuple)) &JaggedArray::python_getitem)
.def("__str__", &JaggedArray::str)
.def("__len__", &JaggedArray::len)
.def("__iter__", &JaggedArray::iter)
.def("__repr__", &JaggedArray::repr);

py::class_<JaggedArray::JaggedArrayIterator>(m, "JaggedArrayIterator")
.def(py::init<JaggedArray*>())
.def("__iter__", &JaggedArray::JaggedArrayIterator::iter)
Expand Down
68 changes: 54 additions & 14 deletions awkward-cpp/awkward/cpp/array/jagged.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "util.h"
#include "any.h"
#include "numpytypes.h"
#include "CPU_methods.h"

namespace py = pybind11;

Expand Down Expand Up @@ -308,30 +309,32 @@ class JaggedArray : public AwkwardArray {
return (JaggedArray*)deepcopy();
}

// THIS IS NOW AN EXPERIMENTAL ENVIRONMENT
static C_array_64 numpy_to_c64(py::array input) {
input = input.cast<py::array_t<std::int64_t>>();
struct C_array_64 temp = {
(std::int64_t*)input.request().ptr,
8,
input.request().size,
input.request().format.at(0),
input.request().strides[0]
};
return temp;
}

static py::array_t<std::int64_t> offsets2parents(py::array offsets) {
makeIntNative(offsets);
offsets = offsets.cast<py::array_t<std::int64_t>>();
py::buffer_info offsets_info = offsets.request();
if (offsets_info.size <= 0) {
throw std::invalid_argument("offsets must have at least one element");
}
auto offsets_ptr = (std::int64_t*)offsets_info.ptr;
int N = offsets_info.strides[0] / offsets_info.itemsize;

ssize_t parents_length = (ssize_t)offsets_ptr[offsets_info.size - 1];
ssize_t parents_length = (ssize_t)offsets_ptr[(offsets_info.size - 1) * N];
auto parents = py::array_t<std::int64_t>(parents_length);
py::buffer_info parents_info = parents.request();

auto parents_ptr = (std::int64_t*)parents_info.ptr;

ssize_t j = 0;
ssize_t k = -1;
for (ssize_t i = 0; i < offsets_info.size; i++) {
while (j < (ssize_t)offsets_ptr[i * N]) {
parents_ptr[j] = (std::int64_t)k;
j += 1;
}
k += 1;
if (!offsets2parents_int64(&numpy_to_c64(offsets), &numpy_to_c64(parents))) {
throw std::exception("Error in: CPU_methods.h::offsets2parents_int64()");
}

return parents;
Expand Down Expand Up @@ -691,6 +694,43 @@ class JaggedArray : public AwkwardArray {
return getitem(input)->unwrap();
}

/*AnyArray* getitem(py::tuple input) {
if (py::len(input) == 0) {
throw std::invalid_argument("getitem requires at least one argument");
}
if (py::len(input) == 1) {
try {
ssize_t temp = input[0].cast<ssize_t>();
return getitem(temp);
}
catch (py::cast_error e) { }
try {
py::slice temp = input[0].cast<py::slice>();
return getitem(temp);
}
catch (py::cast_error e) { }
try {
JaggedArray* temp = input[0].cast<JaggedArray*>();
throw std::invalid_argument("JaggedArray* argument support not yet implemented"); // TODO
}
catch (py::cast_error e) { }
try {
py::array temp = input[0].cast<py::array>();
return getitem(temp);
}
catch (py::cast_error e) {
throw std::invalid_argument("argument type not supported for __getitem__");
}
}
if (py::len(input) == 2) {
}
}*/

py::object python_getitem(py::tuple input) {
return getitem(input)->unwrap();
}

py::object tolist() {
py::list out;
for (ssize_t i = 0; i < len(); i++) {
Expand Down
16 changes: 4 additions & 12 deletions awkward-cpp/awkward/cpp/array/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <complex>
#include <sstream>
#include <iomanip>
#include "CPU_methods.h"

namespace py = pybind11;

Expand Down Expand Up @@ -48,31 +49,22 @@ std::int64_t byteswap(std::int64_t val) {
return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL);
}

bool isNative(py::array input) {
char ch = input.request().format.at(0);
union {
uint32_t i;
char c[4];
} bint = { 0x01020304 };
return ((bint.c[0] == 1 && ch != '<') || (bint.c[0] != 1 && ch != '>'));
}

bool isNativeInt(py::array input) {
std::string intList = "qQlLhHbB";
if (intList.find(input.request().format.at(0)) == std::string::npos) {
throw std::invalid_argument("argument must be of type int");
}
return isNative(input);
return isNative(input.request().format.at(0));
}

template <typename T>
void makeNative(py::array_t<T> input) {
if (isNative(input)) {
if (isNative(input.request().format.at(0))) {
return;
}
py::buffer_info array_info = input.request();
auto array_ptr = (T*)array_info.ptr;
int N = array_info.shape[0] / array_info.itemsize;
int N = array_info.strides[0] / array_info.itemsize;

for (ssize_t i = 0; i < array_info.size; i++) {
array_ptr[i * N] = byteswap(array_ptr[i * N]);
Expand Down

0 comments on commit 011cceb

Please sign in to comment.