Skip to content

Commit

Permalink
Merge pull request #1026 from slaclab/ESROGUE-682
Browse files Browse the repository at this point in the history
ESROGUE-682 - Make Block.set() with numpy array work with proper array strides
  • Loading branch information
ruck314 authored Oct 16, 2024
2 parents b47e9cd + 8f094c6 commit 3986b15
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 16 deletions.
62 changes: 46 additions & 16 deletions src/rogue/interfaces/memory/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ void rim::Block::setUIntPy(bp::object& value, rim::Variable* var, int32_t index)
PyArrayObject* arr = reinterpret_cast<decltype(arr)>(value.ptr());
npy_intp ndims = PyArray_NDIM(arr);
npy_intp* dims = PyArray_SHAPE(arr);
npy_intp* strides = PyArray_STRIDES(arr);

if (ndims != 1)
throw(rogue::GeneralError::create("Block::setUIntPy",
Expand All @@ -920,11 +921,17 @@ void rim::Block::setUIntPy(bp::object& value, rim::Variable* var, int32_t index)
var->name_.c_str()));

if (PyArray_TYPE(arr) == NPY_UINT64) {
uint64_t* src = reinterpret_cast<uint64_t*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setUInt(src[x], var, index + x);
uint64_t* src = reinterpret_cast<uint64_t*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(uint64_t);
for (x = 0; x < dims[0]; x++) {
setUInt(src[x * stride], var, index + x);
}
} else if (PyArray_TYPE(arr) == NPY_UINT32) {
uint32_t* src = reinterpret_cast<uint32_t*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setUInt(src[x], var, index + x);
uint32_t* src = reinterpret_cast<uint32_t*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(uint32_t);
for (x = 0; x < dims[0]; x++) {
setUInt(src[x * stride], var, index + x);
}
} else {
throw(rogue::GeneralError::create("Block::setUIntPy",
"Passed nparray is not of type (uint64 or uint32) for %s",
Expand Down Expand Up @@ -1061,6 +1068,7 @@ void rim::Block::setIntPy(bp::object& value, rim::Variable* var, int32_t index)
PyArrayObject* arr = reinterpret_cast<decltype(arr)>(value.ptr());
npy_intp ndims = PyArray_NDIM(arr);
npy_intp* dims = PyArray_SHAPE(arr);
npy_intp* strides = PyArray_STRIDES(arr);

if (ndims != 1)
throw(rogue::GeneralError::create("Block::setIntPy",
Expand All @@ -1078,11 +1086,17 @@ void rim::Block::setIntPy(bp::object& value, rim::Variable* var, int32_t index)
var->name_.c_str()));

if (PyArray_TYPE(arr) == NPY_INT64) {
int64_t* src = reinterpret_cast<int64_t*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setInt(src[x], var, index + x);
int64_t* src = reinterpret_cast<int64_t*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(int64_t);
for (x = 0; x < dims[0]; x++) {
setInt(src[x * stride], var, index + x);
}
} else if (PyArray_TYPE(arr) == NPY_INT32) {
int32_t* src = reinterpret_cast<int32_t*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setInt(src[x], var, index + x);
int32_t* src = reinterpret_cast<int32_t*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(int32_t);
for (x = 0; x < dims[0]; x++) {
setInt(src[x * stride], var, index + x);
}
} else {
throw(rogue::GeneralError::create("Block::setIntPy",
"Passed nparray is not of type (int64 or int32) for %s",
Expand Down Expand Up @@ -1223,6 +1237,7 @@ void rim::Block::setBoolPy(bp::object& value, rim::Variable* var, int32_t index)
PyArrayObject* arr = reinterpret_cast<decltype(arr)>(value.ptr());
npy_intp ndims = PyArray_NDIM(arr);
npy_intp* dims = PyArray_SHAPE(arr);
npy_intp* strides = PyArray_STRIDES(arr);

if (ndims != 1)
throw(rogue::GeneralError::create("Block::setBoolPy",
Expand All @@ -1240,8 +1255,11 @@ void rim::Block::setBoolPy(bp::object& value, rim::Variable* var, int32_t index)
var->name_.c_str()));

if (PyArray_TYPE(arr) == NPY_BOOL) {
bool* src = reinterpret_cast<bool*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setBool(src[x], var, index + x);
bool* src = reinterpret_cast<bool*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(bool);
for (x = 0; x < dims[0]; x++) {
setBool(src[x * stride], var, index + x);
}
} else {
throw(rogue::GeneralError::create("Block::setBoolPy",
"Passed nparray is not of type (bool) for %s",
Expand Down Expand Up @@ -1431,6 +1449,7 @@ void rim::Block::setFloatPy(bp::object& value, rim::Variable* var, int32_t index
PyArrayObject* arr = reinterpret_cast<decltype(arr)>(value.ptr());
npy_intp ndims = PyArray_NDIM(arr);
npy_intp* dims = PyArray_SHAPE(arr);
npy_intp* strides = PyArray_STRIDES(arr);

if (ndims != 1)
throw(rogue::GeneralError::create("Block::setFloatPy",
Expand All @@ -1448,8 +1467,11 @@ void rim::Block::setFloatPy(bp::object& value, rim::Variable* var, int32_t index
var->name_.c_str()));

if (PyArray_TYPE(arr) == NPY_FLOAT32) {
float* src = reinterpret_cast<float*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setFloat(src[x], var, index + x);
float* src = reinterpret_cast<float*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(float);
for (x = 0; x < dims[0]; x++) {
setFloat(src[x * stride], var, index + x);
}
} else {
throw(rogue::GeneralError::create("Block::setFLoatPy",
"Passed nparray is not of type (float32) for %s",
Expand Down Expand Up @@ -1576,6 +1598,7 @@ void rim::Block::setDoublePy(bp::object& value, rim::Variable* var, int32_t inde
PyArrayObject* arr = reinterpret_cast<decltype(arr)>(value.ptr());
npy_intp ndims = PyArray_NDIM(arr);
npy_intp* dims = PyArray_SHAPE(arr);
npy_intp* strides = PyArray_STRIDES(arr);

if (ndims != 1)
throw(rogue::GeneralError::create("Block::setDoublePy",
Expand All @@ -1593,8 +1616,11 @@ void rim::Block::setDoublePy(bp::object& value, rim::Variable* var, int32_t inde
var->name_.c_str()));

if (PyArray_TYPE(arr) == NPY_FLOAT64) {
double* src = reinterpret_cast<double*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setDouble(src[x], var, index + x);
double* src = reinterpret_cast<double*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(double);
for (x = 0; x < dims[0]; x++) {
setDouble(src[x * stride], var, index + x);
}
} else {
throw(rogue::GeneralError::create("Block::setFLoatPy",
"Passed nparray is not of type (double) for %s",
Expand Down Expand Up @@ -1721,6 +1747,7 @@ void rim::Block::setFixedPy(bp::object& value, rim::Variable* var, int32_t index
PyArrayObject* arr = reinterpret_cast<decltype(arr)>(value.ptr());
npy_intp ndims = PyArray_NDIM(arr);
npy_intp* dims = PyArray_SHAPE(arr);
npy_intp* strides = PyArray_STRIDES(arr);

if (ndims != 1)
throw(rogue::GeneralError::create("Block::setFixedPy",
Expand All @@ -1738,8 +1765,11 @@ void rim::Block::setFixedPy(bp::object& value, rim::Variable* var, int32_t index
var->name_.c_str()));

if (PyArray_TYPE(arr) == NPY_FLOAT64) {
double* src = reinterpret_cast<double*>(PyArray_DATA(arr));
for (x = 0; x < dims[0]; x++) setFixed(src[x], var, index + x);
double* src = reinterpret_cast<double*>(PyArray_DATA(arr));
npy_intp stride = strides[0] / sizeof(double);
for (x = 0; x < dims[0]; x++) {
setFixed(src[x * stride], var, index + x);
}
} else {
throw(rogue::GeneralError::create("Block::setFixedPy",
"Passed nparray is not of type (double) for %s",
Expand Down
24 changes: 24 additions & 0 deletions tests/test_list_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,30 @@ def test_memory():
# Test value shift
_ = resA[0] >> 5

root.ListDevice.UInt32List.set(UInt32ListA[::2])
root.ListDevice.Int32List.set(Int32ListA[::2])

resA = root.ListDevice.UInt32List.get()
resB = root.ListDevice.Int32List.get()

for i in range(16):

if resA[i] != UInt32ListA[::2][i]:
raise AssertionError(f'Stripe Verification Failure for UInt32ListA at position {i}')

if resB[i] != Int32ListA[::2][i]:
raise AssertionError(f'Stripe Verification Failure for Int32ListA at position {i}')

for i in range(16, 32):

if resA[i] != UInt32ListA[i]:
raise AssertionError(f'Stripe Verification Failure for UInt32ListA at position {i}')

if resB[i] != Int32ListA[i]:
raise AssertionError(f'Stripe Verification Failure for Int32ListA at position {i}')



def run_gui():
import pyrogue.pydm

Expand Down

0 comments on commit 3986b15

Please sign in to comment.