consistent use of ssize_t instead of int64_t (#167)
Some checks failed
Build on RHEL9 / build (push) Successful in 2m10s
Build on RHEL8 / build (push) Failing after 2m33s

- Consistent use of ssize_t to avoid issues on 32 bit platforms and also
mac with (long long int as ssize_t)
This commit is contained in:
Erik Fröjdh 2025-04-25 15:52:02 +02:00 committed by GitHub
parent 6db201f397
commit 12ae1424fb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 118 additions and 116 deletions

View File

@ -1,22 +1,24 @@
#pragma once #pragma once
#include <cstdint> //int64_t #include <cstdint>
#include <cstddef> //size_t #include <cstddef>
#include <array> #include <array>
#include <cassert> #include <cassert>
#include "aare/defs.hpp"
namespace aare { namespace aare {
template <typename E, int64_t Ndim> class ArrayExpr { template <typename E, ssize_t Ndim> class ArrayExpr {
public: public:
static constexpr bool is_leaf = false; static constexpr bool is_leaf = false;
auto operator[](size_t i) const { return static_cast<E const &>(*this)[i]; } auto operator[](size_t i) const { return static_cast<E const &>(*this)[i]; }
auto operator()(size_t i) const { return static_cast<E const &>(*this)[i]; } auto operator()(size_t i) const { return static_cast<E const &>(*this)[i]; }
auto size() const { return static_cast<E const &>(*this).size(); } auto size() const { return static_cast<E const &>(*this).size(); }
std::array<int64_t, Ndim> shape() const { return static_cast<E const &>(*this).shape(); } std::array<ssize_t, Ndim> shape() const { return static_cast<E const &>(*this).shape(); }
}; };
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
class ArrayAdd : public ArrayExpr<ArrayAdd<A, B, Ndim>, Ndim> { class ArrayAdd : public ArrayExpr<ArrayAdd<A, B, Ndim>, Ndim> {
const A &arr1_; const A &arr1_;
const B &arr2_; const B &arr2_;
@ -27,10 +29,10 @@ class ArrayAdd : public ArrayExpr<ArrayAdd<A, B, Ndim>, Ndim> {
} }
auto operator[](int i) const { return arr1_[i] + arr2_[i]; } auto operator[](int i) const { return arr1_[i] + arr2_[i]; }
size_t size() const { return arr1_.size(); } size_t size() const { return arr1_.size(); }
std::array<int64_t, Ndim> shape() const { return arr1_.shape(); } std::array<ssize_t, Ndim> shape() const { return arr1_.shape(); }
}; };
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
class ArraySub : public ArrayExpr<ArraySub<A, B, Ndim>, Ndim> { class ArraySub : public ArrayExpr<ArraySub<A, B, Ndim>, Ndim> {
const A &arr1_; const A &arr1_;
const B &arr2_; const B &arr2_;
@ -41,10 +43,10 @@ class ArraySub : public ArrayExpr<ArraySub<A, B, Ndim>, Ndim> {
} }
auto operator[](int i) const { return arr1_[i] - arr2_[i]; } auto operator[](int i) const { return arr1_[i] - arr2_[i]; }
size_t size() const { return arr1_.size(); } size_t size() const { return arr1_.size(); }
std::array<int64_t, Ndim> shape() const { return arr1_.shape(); } std::array<ssize_t, Ndim> shape() const { return arr1_.shape(); }
}; };
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
class ArrayMul : public ArrayExpr<ArrayMul<A, B, Ndim>,Ndim> { class ArrayMul : public ArrayExpr<ArrayMul<A, B, Ndim>,Ndim> {
const A &arr1_; const A &arr1_;
const B &arr2_; const B &arr2_;
@ -55,10 +57,10 @@ class ArrayMul : public ArrayExpr<ArrayMul<A, B, Ndim>,Ndim> {
} }
auto operator[](int i) const { return arr1_[i] * arr2_[i]; } auto operator[](int i) const { return arr1_[i] * arr2_[i]; }
size_t size() const { return arr1_.size(); } size_t size() const { return arr1_.size(); }
std::array<int64_t, Ndim> shape() const { return arr1_.shape(); } std::array<ssize_t, Ndim> shape() const { return arr1_.shape(); }
}; };
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
class ArrayDiv : public ArrayExpr<ArrayDiv<A, B, Ndim>, Ndim> { class ArrayDiv : public ArrayExpr<ArrayDiv<A, B, Ndim>, Ndim> {
const A &arr1_; const A &arr1_;
const B &arr2_; const B &arr2_;
@ -69,27 +71,27 @@ class ArrayDiv : public ArrayExpr<ArrayDiv<A, B, Ndim>, Ndim> {
} }
auto operator[](int i) const { return arr1_[i] / arr2_[i]; } auto operator[](int i) const { return arr1_[i] / arr2_[i]; }
size_t size() const { return arr1_.size(); } size_t size() const { return arr1_.size(); }
std::array<int64_t, Ndim> shape() const { return arr1_.shape(); } std::array<ssize_t, Ndim> shape() const { return arr1_.shape(); }
}; };
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
auto operator+(const ArrayExpr<A, Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) { auto operator+(const ArrayExpr<A, Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) {
return ArrayAdd<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2); return ArrayAdd<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2);
} }
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
auto operator-(const ArrayExpr<A,Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) { auto operator-(const ArrayExpr<A,Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) {
return ArraySub<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2); return ArraySub<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2);
} }
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
auto operator*(const ArrayExpr<A, Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) { auto operator*(const ArrayExpr<A, Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) {
return ArrayMul<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2); return ArrayMul<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2);
} }
template <typename A, typename B, int64_t Ndim> template <typename A, typename B, ssize_t Ndim>
auto operator/(const ArrayExpr<A, Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) { auto operator/(const ArrayExpr<A, Ndim> &arr1, const ArrayExpr<B, Ndim> &arr2) {
return ArrayDiv<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2); return ArrayDiv<ArrayExpr<A, Ndim>, ArrayExpr<B, Ndim>, Ndim>(arr1, arr2);
} }

View File

@ -18,8 +18,8 @@ class FilePtr {
FilePtr(FilePtr &&other); FilePtr(FilePtr &&other);
FilePtr &operator=(FilePtr &&other); FilePtr &operator=(FilePtr &&other);
FILE *get(); FILE *get();
int64_t tell(); ssize_t tell();
void seek(int64_t offset, int whence = SEEK_SET) { void seek(ssize_t offset, int whence = SEEK_SET) {
if (fseek(fp_, offset, whence) != 0) if (fseek(fp_, offset, whence) != 0)
throw std::runtime_error("Error seeking in file"); throw std::runtime_error("Error seeking in file");
} }

View File

@ -107,8 +107,8 @@ class Frame {
* @return NDView<T, 2> * @return NDView<T, 2>
*/ */
template <typename T> NDView<T, 2> view() { template <typename T> NDView<T, 2> view() {
std::array<int64_t, 2> shape = {static_cast<int64_t>(m_rows), std::array<ssize_t, 2> shape = {static_cast<ssize_t>(m_rows),
static_cast<int64_t>(m_cols)}; static_cast<ssize_t>(m_cols)};
T *data = reinterpret_cast<T *>(m_data); T *data = reinterpret_cast<T *>(m_data);
return NDView<T, 2>(data, shape); return NDView<T, 2>(data, shape);
} }

View File

@ -22,10 +22,10 @@ TODO! Add expression templates for operators
namespace aare { namespace aare {
template <typename T, int64_t Ndim = 2> template <typename T, ssize_t Ndim = 2>
class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> { class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
std::array<int64_t, Ndim> shape_; std::array<ssize_t, Ndim> shape_;
std::array<int64_t, Ndim> strides_; std::array<ssize_t, Ndim> strides_;
size_t size_{}; size_t size_{};
T *data_; T *data_;
@ -42,7 +42,7 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
* *
* @param shape shape of the new NDArray * @param shape shape of the new NDArray
*/ */
explicit NDArray(std::array<int64_t, Ndim> shape) explicit NDArray(std::array<ssize_t, Ndim> shape)
: shape_(shape), strides_(c_strides<Ndim>(shape_)), : shape_(shape), strides_(c_strides<Ndim>(shape_)),
size_(std::accumulate(shape_.begin(), shape_.end(), 1, size_(std::accumulate(shape_.begin(), shape_.end(), 1,
std::multiplies<>())), std::multiplies<>())),
@ -55,7 +55,7 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
* @param shape shape of the new array * @param shape shape of the new array
* @param value value to initialize the array with * @param value value to initialize the array with
*/ */
NDArray(std::array<int64_t, Ndim> shape, T value) : NDArray(shape) { NDArray(std::array<ssize_t, Ndim> shape, T value) : NDArray(shape) {
this->operator=(value); this->operator=(value);
} }
@ -186,22 +186,22 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
} }
// TODO! is int the right type for index? // TODO! is int the right type for index?
T &operator()(int64_t i) { return data_[i]; } T &operator()(ssize_t i) { return data_[i]; }
const T &operator()(int64_t i) const { return data_[i]; } const T &operator()(ssize_t i) const { return data_[i]; }
T &operator[](int64_t i) { return data_[i]; } T &operator[](ssize_t i) { return data_[i]; }
const T &operator[](int64_t i) const { return data_[i]; } const T &operator[](ssize_t i) const { return data_[i]; }
T *data() { return data_; } T *data() { return data_; }
std::byte *buffer() { return reinterpret_cast<std::byte *>(data_); } std::byte *buffer() { return reinterpret_cast<std::byte *>(data_); }
ssize_t size() const { return static_cast<ssize_t>(size_); } ssize_t size() const { return static_cast<ssize_t>(size_); }
size_t total_bytes() const { return size_ * sizeof(T); } size_t total_bytes() const { return size_ * sizeof(T); }
std::array<int64_t, Ndim> shape() const noexcept { return shape_; } std::array<ssize_t, Ndim> shape() const noexcept { return shape_; }
int64_t shape(int64_t i) const noexcept { return shape_[i]; } ssize_t shape(ssize_t i) const noexcept { return shape_[i]; }
std::array<int64_t, Ndim> strides() const noexcept { return strides_; } std::array<ssize_t, Ndim> strides() const noexcept { return strides_; }
size_t bitdepth() const noexcept { return sizeof(T) * 8; } size_t bitdepth() const noexcept { return sizeof(T) * 8; }
std::array<int64_t, Ndim> byte_strides() const noexcept { std::array<ssize_t, Ndim> byte_strides() const noexcept {
auto byte_strides = strides_; auto byte_strides = strides_;
for (auto &val : byte_strides) for (auto &val : byte_strides)
val *= sizeof(T); val *= sizeof(T);
@ -228,7 +228,7 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
}; };
// Move assign // Move assign
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> & NDArray<T, Ndim> &
NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) noexcept { NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) noexcept {
if (this != &other) { if (this != &other) {
@ -242,7 +242,7 @@ NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) noexcept {
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const NDArray<T, Ndim> &other) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const NDArray<T, Ndim> &other) {
// check shape // check shape
if (shape_ == other.shape_) { if (shape_ == other.shape_) {
@ -254,7 +254,7 @@ NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const NDArray<T, Ndim> &other) {
throw(std::runtime_error("Shape of ImageDatas must match")); throw(std::runtime_error("Shape of ImageDatas must match"));
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const NDArray<T, Ndim> &other) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const NDArray<T, Ndim> &other) {
// check shape // check shape
if (shape_ == other.shape_) { if (shape_ == other.shape_) {
@ -266,7 +266,7 @@ NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const NDArray<T, Ndim> &other) {
throw(std::runtime_error("Shape of ImageDatas must match")); throw(std::runtime_error("Shape of ImageDatas must match"));
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const NDArray<T, Ndim> &other) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const NDArray<T, Ndim> &other) {
// check shape // check shape
if (shape_ == other.shape_) { if (shape_ == other.shape_) {
@ -278,14 +278,14 @@ NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const NDArray<T, Ndim> &other) {
throw(std::runtime_error("Shape of ImageDatas must match")); throw(std::runtime_error("Shape of ImageDatas must match"));
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator&=(const T &mask) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator&=(const T &mask) {
for (auto it = begin(); it != end(); ++it) for (auto it = begin(); it != end(); ++it)
*it &= mask; *it &= mask;
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<bool, Ndim> NDArray<T, Ndim>::operator>(const NDArray &other) { NDArray<bool, Ndim> NDArray<T, Ndim>::operator>(const NDArray &other) {
if (shape_ == other.shape_) { if (shape_ == other.shape_) {
NDArray<bool, Ndim> result{shape_}; NDArray<bool, Ndim> result{shape_};
@ -297,7 +297,7 @@ NDArray<bool, Ndim> NDArray<T, Ndim>::operator>(const NDArray &other) {
throw(std::runtime_error("Shape of ImageDatas must match")); throw(std::runtime_error("Shape of ImageDatas must match"));
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const NDArray<T, Ndim> &other) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const NDArray<T, Ndim> &other) {
if (this != &other) { if (this != &other) {
delete[] data_; delete[] data_;
@ -310,7 +310,7 @@ NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const NDArray<T, Ndim> &other) {
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
bool NDArray<T, Ndim>::operator==(const NDArray<T, Ndim> &other) const { bool NDArray<T, Ndim>::operator==(const NDArray<T, Ndim> &other) const {
if (shape_ != other.shape_) if (shape_ != other.shape_)
return false; return false;
@ -322,23 +322,23 @@ bool NDArray<T, Ndim>::operator==(const NDArray<T, Ndim> &other) const {
return true; return true;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
bool NDArray<T, Ndim>::operator!=(const NDArray<T, Ndim> &other) const { bool NDArray<T, Ndim>::operator!=(const NDArray<T, Ndim> &other) const {
return !((*this) == other); return !((*this) == other);
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator++() { NDArray<T, Ndim> &NDArray<T, Ndim>::operator++() {
for (uint32_t i = 0; i < size_; ++i) for (uint32_t i = 0; i < size_; ++i)
data_[i] += 1; data_[i] += 1;
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const T &value) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const T &value) {
std::fill_n(data_, size_, value); std::fill_n(data_, size_, value);
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const T &value) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const T &value) {
for (uint32_t i = 0; i < size_; ++i) for (uint32_t i = 0; i < size_; ++i)
data_[i] += value; data_[i] += value;
@ -348,57 +348,57 @@ NDArray<T, Ndim> &NDArray<T, Ndim>::operator+=(const T &value) {
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const T &value) { NDArray<T, Ndim> NDArray<T, Ndim>::operator+(const T &value) {
NDArray result = *this; NDArray result = *this;
result += value; result += value;
return result; return result;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const T &value) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator-=(const T &value) {
for (uint32_t i = 0; i < size_; ++i) for (uint32_t i = 0; i < size_; ++i)
data_[i] -= value; data_[i] -= value;
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const T &value) { NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const T &value) {
NDArray result = *this; NDArray result = *this;
result -= value; result -= value;
return result; return result;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator/=(const T &value) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator/=(const T &value) {
for (uint32_t i = 0; i < size_; ++i) for (uint32_t i = 0; i < size_; ++i)
data_[i] /= value; data_[i] /= value;
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const T &value) { NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const T &value) {
NDArray result = *this; NDArray result = *this;
result /= value; result /= value;
return result; return result;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const T &value) { NDArray<T, Ndim> &NDArray<T, Ndim>::operator*=(const T &value) {
for (uint32_t i = 0; i < size_; ++i) for (uint32_t i = 0; i < size_; ++i)
data_[i] *= value; data_[i] *= value;
return *this; return *this;
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const T &value) { NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const T &value) {
NDArray result = *this; NDArray result = *this;
result *= value; result *= value;
return result; return result;
} }
// template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print() { // template <typename T, ssize_t Ndim> void NDArray<T, Ndim>::Print() {
// if (shape_[0] < 20 && shape_[1] < 20) // if (shape_[0] < 20 && shape_[1] < 20)
// Print_all(); // Print_all();
// else // else
// Print_some(); // Print_some();
// } // }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
std::ostream &operator<<(std::ostream &os, const NDArray<T, Ndim> &arr) { std::ostream &operator<<(std::ostream &os, const NDArray<T, Ndim> &arr) {
for (auto row = 0; row < arr.shape(0); ++row) { for (auto row = 0; row < arr.shape(0); ++row) {
for (auto col = 0; col < arr.shape(1); ++col) { for (auto col = 0; col < arr.shape(1); ++col) {
@ -410,7 +410,7 @@ std::ostream &operator<<(std::ostream &os, const NDArray<T, Ndim> &arr) {
return os; return os;
} }
template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print_all() { template <typename T, ssize_t Ndim> void NDArray<T, Ndim>::Print_all() {
for (auto row = 0; row < shape_[0]; ++row) { for (auto row = 0; row < shape_[0]; ++row) {
for (auto col = 0; col < shape_[1]; ++col) { for (auto col = 0; col < shape_[1]; ++col) {
std::cout << std::setw(3); std::cout << std::setw(3);
@ -419,7 +419,7 @@ template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print_all() {
std::cout << "\n"; std::cout << "\n";
} }
} }
template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print_some() { template <typename T, ssize_t Ndim> void NDArray<T, Ndim>::Print_some() {
for (auto row = 0; row < 5; ++row) { for (auto row = 0; row < 5; ++row) {
for (auto col = 0; col < 5; ++col) { for (auto col = 0; col < 5; ++col) {
std::cout << std::setw(7); std::cout << std::setw(7);
@ -429,7 +429,7 @@ template <typename T, int64_t Ndim> void NDArray<T, Ndim>::Print_some() {
} }
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
void save(NDArray<T, Ndim> &img, std::string &pathname) { void save(NDArray<T, Ndim> &img, std::string &pathname) {
std::ofstream f; std::ofstream f;
f.open(pathname, std::ios::binary); f.open(pathname, std::ios::binary);
@ -437,9 +437,9 @@ void save(NDArray<T, Ndim> &img, std::string &pathname) {
f.close(); f.close();
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
NDArray<T, Ndim> load(const std::string &pathname, NDArray<T, Ndim> load(const std::string &pathname,
std::array<int64_t, Ndim> shape) { std::array<ssize_t, Ndim> shape) {
NDArray<T, Ndim> img{shape}; NDArray<T, Ndim> img{shape};
std::ifstream f; std::ifstream f;
f.open(pathname, std::ios::binary); f.open(pathname, std::ios::binary);

View File

@ -14,10 +14,10 @@
#include <vector> #include <vector>
namespace aare { namespace aare {
template <int64_t Ndim> using Shape = std::array<int64_t, Ndim>; template <ssize_t Ndim> using Shape = std::array<ssize_t, Ndim>;
// TODO! fix mismatch between signed and unsigned // TODO! fix mismatch between signed and unsigned
template <int64_t Ndim> Shape<Ndim> make_shape(const std::vector<size_t> &shape) { template <ssize_t Ndim> Shape<Ndim> make_shape(const std::vector<size_t> &shape) {
if (shape.size() != Ndim) if (shape.size() != Ndim)
throw std::runtime_error("Shape size mismatch"); throw std::runtime_error("Shape size mismatch");
Shape<Ndim> arr; Shape<Ndim> arr;
@ -25,41 +25,41 @@ template <int64_t Ndim> Shape<Ndim> make_shape(const std::vector<size_t> &shape)
return arr; return arr;
} }
template <int64_t Dim = 0, typename Strides> int64_t element_offset(const Strides & /*unused*/) { return 0; } template <ssize_t Dim = 0, typename Strides> ssize_t element_offset(const Strides & /*unused*/) { return 0; }
template <int64_t Dim = 0, typename Strides, typename... Ix> template <ssize_t Dim = 0, typename Strides, typename... Ix>
int64_t element_offset(const Strides &strides, int64_t i, Ix... index) { ssize_t element_offset(const Strides &strides, ssize_t i, Ix... index) {
return i * strides[Dim] + element_offset<Dim + 1>(strides, index...); return i * strides[Dim] + element_offset<Dim + 1>(strides, index...);
} }
template <int64_t Ndim> std::array<int64_t, Ndim> c_strides(const std::array<int64_t, Ndim> &shape) { template <ssize_t Ndim> std::array<ssize_t, Ndim> c_strides(const std::array<ssize_t, Ndim> &shape) {
std::array<int64_t, Ndim> strides{}; std::array<ssize_t, Ndim> strides{};
std::fill(strides.begin(), strides.end(), 1); std::fill(strides.begin(), strides.end(), 1);
for (int64_t i = Ndim - 1; i > 0; --i) { for (ssize_t i = Ndim - 1; i > 0; --i) {
strides[i - 1] = strides[i] * shape[i]; strides[i - 1] = strides[i] * shape[i];
} }
return strides; return strides;
} }
template <int64_t Ndim> std::array<int64_t, Ndim> make_array(const std::vector<int64_t> &vec) { template <ssize_t Ndim> std::array<ssize_t, Ndim> make_array(const std::vector<ssize_t> &vec) {
assert(vec.size() == Ndim); assert(vec.size() == Ndim);
std::array<int64_t, Ndim> arr{}; std::array<ssize_t, Ndim> arr{};
std::copy_n(vec.begin(), Ndim, arr.begin()); std::copy_n(vec.begin(), Ndim, arr.begin());
return arr; return arr;
} }
template <typename T, int64_t Ndim = 2> class NDView : public ArrayExpr<NDView<T, Ndim>, Ndim> { template <typename T, ssize_t Ndim = 2> class NDView : public ArrayExpr<NDView<T, Ndim>, Ndim> {
public: public:
NDView() = default; NDView() = default;
~NDView() = default; ~NDView() = default;
NDView(const NDView &) = default; NDView(const NDView &) = default;
NDView(NDView &&) = default; NDView(NDView &&) = default;
NDView(T *buffer, std::array<int64_t, Ndim> shape) NDView(T *buffer, std::array<ssize_t, Ndim> shape)
: buffer_(buffer), strides_(c_strides<Ndim>(shape)), shape_(shape), : buffer_(buffer), strides_(c_strides<Ndim>(shape)), shape_(shape),
size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {} size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
// NDView(T *buffer, const std::vector<int64_t> &shape) // NDView(T *buffer, const std::vector<ssize_t> &shape)
// : buffer_(buffer), strides_(c_strides<Ndim>(make_array<Ndim>(shape))), shape_(make_array<Ndim>(shape)), // : buffer_(buffer), strides_(c_strides<Ndim>(make_array<Ndim>(shape))), shape_(make_array<Ndim>(shape)),
// size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {} // size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
@ -73,14 +73,14 @@ template <typename T, int64_t Ndim = 2> class NDView : public ArrayExpr<NDView<T
ssize_t size() const { return static_cast<ssize_t>(size_); } ssize_t size() const { return static_cast<ssize_t>(size_); }
size_t total_bytes() const { return size_ * sizeof(T); } size_t total_bytes() const { return size_ * sizeof(T); }
std::array<int64_t, Ndim> strides() const noexcept { return strides_; } std::array<ssize_t, Ndim> strides() const noexcept { return strides_; }
T *begin() { return buffer_; } T *begin() { return buffer_; }
T *end() { return buffer_ + size_; } T *end() { return buffer_ + size_; }
T const *begin() const { return buffer_; } T const *begin() const { return buffer_; }
T const *end() const { return buffer_ + size_; } T const *end() const { return buffer_ + size_; }
T &operator()(int64_t i) const { return buffer_[i]; } T &operator()(ssize_t i) const { return buffer_[i]; }
T &operator[](int64_t i) const { return buffer_[i]; } T &operator[](ssize_t i) const { return buffer_[i]; }
bool operator==(const NDView &other) const { bool operator==(const NDView &other) const {
if (size_ != other.size_) if (size_ != other.size_)
@ -136,15 +136,15 @@ template <typename T, int64_t Ndim = 2> class NDView : public ArrayExpr<NDView<T
} }
auto &shape() const { return shape_; } auto &shape() const { return shape_; }
auto shape(int64_t i) const { return shape_[i]; } auto shape(ssize_t i) const { return shape_[i]; }
T *data() { return buffer_; } T *data() { return buffer_; }
void print_all() const; void print_all() const;
private: private:
T *buffer_{nullptr}; T *buffer_{nullptr};
std::array<int64_t, Ndim> strides_{}; std::array<ssize_t, Ndim> strides_{};
std::array<int64_t, Ndim> shape_{}; std::array<ssize_t, Ndim> shape_{};
uint64_t size_{}; uint64_t size_{};
template <class BinaryOperation> NDView &elemenwise(T val, BinaryOperation op) { template <class BinaryOperation> NDView &elemenwise(T val, BinaryOperation op) {
@ -160,7 +160,7 @@ template <typename T, int64_t Ndim = 2> class NDView : public ArrayExpr<NDView<T
return *this; return *this;
} }
}; };
template <typename T, int64_t Ndim> void NDView<T, Ndim>::print_all() const { template <typename T, ssize_t Ndim> void NDView<T, Ndim>::print_all() const {
for (auto row = 0; row < shape_[0]; ++row) { for (auto row = 0; row < shape_[0]; ++row) {
for (auto col = 0; col < shape_[1]; ++col) { for (auto col = 0; col < shape_[1]; ++col) {
std::cout << std::setw(3); std::cout << std::setw(3);
@ -171,7 +171,7 @@ template <typename T, int64_t Ndim> void NDView<T, Ndim>::print_all() const {
} }
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
std::ostream& operator <<(std::ostream& os, const NDView<T, Ndim>& arr){ std::ostream& operator <<(std::ostream& os, const NDView<T, Ndim>& arr){
for (auto row = 0; row < arr.shape(0); ++row) { for (auto row = 0; row < arr.shape(0); ++row) {
for (auto col = 0; col < arr.shape(1); ++col) { for (auto col = 0; col < arr.shape(1); ++col) {
@ -186,7 +186,7 @@ std::ostream& operator <<(std::ostream& os, const NDView<T, Ndim>& arr){
template <typename T> template <typename T>
NDView<T,1> make_view(std::vector<T>& vec){ NDView<T,1> make_view(std::vector<T>& vec){
return NDView<T,1>(vec.data(), {static_cast<int64_t>(vec.size())}); return NDView<T,1>(vec.data(), {static_cast<ssize_t>(vec.size())});
} }
} // namespace aare } // namespace aare

View File

@ -69,7 +69,7 @@ class NumpyFile : public FileInterface {
*/ */
template <typename T, size_t NDim> NDArray<T, NDim> load() { template <typename T, size_t NDim> NDArray<T, NDim> load() {
NDArray<T, NDim> arr(make_shape<NDim>(m_header.shape)); NDArray<T, NDim> arr(make_shape<NDim>(m_header.shape));
if (fseek(fp, static_cast<int64_t>(header_size), SEEK_SET)) { if (fseek(fp, static_cast<long>(header_size), SEEK_SET)) {
throw std::runtime_error(LOCATION + "Error seeking to the start of the data"); throw std::runtime_error(LOCATION + "Error seeking to the start of the data");
} }
size_t rc = fread(arr.data(), sizeof(T), arr.size(), fp); size_t rc = fread(arr.data(), sizeof(T), arr.size(), fp);

View File

@ -107,7 +107,7 @@ template <typename SUM_TYPE = double> class Pedestal {
assert(frame.size() == m_rows * m_cols); assert(frame.size() == m_rows * m_cols);
// TODO! move away from m_rows, m_cols // TODO! move away from m_rows, m_cols
if (frame.shape() != std::array<int64_t, 2>{m_rows, m_cols}) { if (frame.shape() != std::array<ssize_t, 2>{m_rows, m_cols}) {
throw std::runtime_error( throw std::runtime_error(
"Frame shape does not match pedestal shape"); "Frame shape does not match pedestal shape");
} }
@ -128,7 +128,7 @@ template <typename SUM_TYPE = double> class Pedestal {
assert(frame.size() == m_rows * m_cols); assert(frame.size() == m_rows * m_cols);
// TODO! move away from m_rows, m_cols // TODO! move away from m_rows, m_cols
if (frame.shape() != std::array<int64_t, 2>{m_rows, m_cols}) { if (frame.shape() != std::array<ssize_t, 2>{m_rows, m_cols}) {
throw std::runtime_error( throw std::runtime_error(
"Frame shape does not match pedestal shape"); "Frame shape does not match pedestal shape");
} }

View File

@ -28,7 +28,7 @@ template <typename T> class VarClusterFinder {
}; };
private: private:
const std::array<int64_t, 2> shape_; const std::array<ssize_t, 2> shape_;
NDView<T, 2> original_; NDView<T, 2> original_;
NDArray<int, 2> labeled_; NDArray<int, 2> labeled_;
NDArray<int, 2> peripheral_labeled_; NDArray<int, 2> peripheral_labeled_;

View File

@ -207,20 +207,20 @@ struct DetectorGeometry{
}; };
struct ROI{ struct ROI{
int64_t xmin{}; ssize_t xmin{};
int64_t xmax{}; ssize_t xmax{};
int64_t ymin{}; ssize_t ymin{};
int64_t ymax{}; ssize_t ymax{};
int64_t height() const { return ymax - ymin; } ssize_t height() const { return ymax - ymin; }
int64_t width() const { return xmax - xmin; } ssize_t width() const { return xmax - xmin; }
bool contains(int64_t x, int64_t y) const { bool contains(ssize_t x, ssize_t y) const {
return x >= xmin && x < xmax && y >= ymin && y < ymax; return x >= xmin && x < xmax && y >= ymin && y < ymax;
} }
}; };
using dynamic_shape = std::vector<int64_t>; using dynamic_shape = std::vector<ssize_t>;
//TODO! Can we uniform enums between the libraries? //TODO! Can we uniform enums between the libraries?

View File

@ -34,7 +34,7 @@ m.def("adc_sar_05_decode64to16", [](py::array_t<uint8_t> input) {
} }
//Create a 2D output array with the same shape as the input //Create a 2D output array with the same shape as the input
std::vector<ssize_t> shape{input.shape(0), input.shape(1)/static_cast<int64_t>(bits_per_byte)}; std::vector<ssize_t> shape{input.shape(0), input.shape(1)/static_cast<ssize_t>(bits_per_byte)};
py::array_t<uint16_t> output(shape); py::array_t<uint16_t> output(shape);
//Create a view of the input and output arrays //Create a view of the input and output arrays
@ -55,7 +55,7 @@ m.def("adc_sar_04_decode64to16", [](py::array_t<uint8_t> input) {
} }
//Create a 2D output array with the same shape as the input //Create a 2D output array with the same shape as the input
std::vector<ssize_t> shape{input.shape(0), input.shape(1)/static_cast<int64_t>(bits_per_byte)}; std::vector<ssize_t> shape{input.shape(0), input.shape(1)/static_cast<ssize_t>(bits_per_byte)};
py::array_t<uint16_t> output(shape); py::array_t<uint16_t> output(shape);
//Create a view of the input and output arrays //Create a view of the input and output arrays

View File

@ -198,7 +198,7 @@ void define_file_io_bindings(py::module &m) {
py::class_<ROI>(m, "ROI") py::class_<ROI>(m, "ROI")
.def(py::init<>()) .def(py::init<>())
.def(py::init<int64_t, int64_t, int64_t, int64_t>(), py::arg("xmin"), .def(py::init<ssize_t, ssize_t, ssize_t, ssize_t>(), py::arg("xmin"),
py::arg("xmax"), py::arg("ymin"), py::arg("ymax")) py::arg("xmax"), py::arg("ymin"), py::arg("ymax"))
.def_readwrite("xmin", &ROI::xmin) .def_readwrite("xmin", &ROI::xmin)
.def_readwrite("xmax", &ROI::xmax) .def_readwrite("xmax", &ROI::xmax)

View File

@ -13,7 +13,7 @@ namespace py = pybind11;
using namespace aare; using namespace aare;
// Pass image data back to python as a numpy array // Pass image data back to python as a numpy array
template <typename T, int64_t Ndim> template <typename T, ssize_t Ndim>
py::array return_image_data(aare::NDArray<T, Ndim> *image) { py::array return_image_data(aare::NDArray<T, Ndim> *image) {
py::capsule free_when_done(image, [](void *f) { py::capsule free_when_done(image, [](void *f) {

View File

@ -21,7 +21,7 @@ FilePtr &FilePtr::operator=(FilePtr &&other) {
FILE *FilePtr::get() { return fp_; } FILE *FilePtr::get() { return fp_; }
int64_t FilePtr::tell() { ssize_t FilePtr::tell() {
auto pos = ftell(fp_); auto pos = ftell(fp_);
if (pos == -1) if (pos == -1)
throw std::runtime_error(fmt::format("Error getting file position: {}", error_msg())); throw std::runtime_error(fmt::format("Error getting file position: {}", error_msg()));

View File

@ -44,9 +44,9 @@ TEST_CASE("3D NDArray from NDView"){
REQUIRE(image.size() == view.size()); REQUIRE(image.size() == view.size());
REQUIRE(image.data() != view.data()); REQUIRE(image.data() != view.data());
for(int64_t i=0; i<image.shape(0); i++){ for(ssize_t i=0; i<image.shape(0); i++){
for(int64_t j=0; j<image.shape(1); j++){ for(ssize_t j=0; j<image.shape(1); j++){
for(int64_t k=0; k<image.shape(2); k++){ for(ssize_t k=0; k<image.shape(2); k++){
REQUIRE(image(i, j, k) == view(i, j, k)); REQUIRE(image(i, j, k) == view(i, j, k));
} }
} }
@ -54,7 +54,7 @@ TEST_CASE("3D NDArray from NDView"){
} }
TEST_CASE("1D image") { TEST_CASE("1D image") {
std::array<int64_t, 1> shape{{20}}; std::array<ssize_t, 1> shape{{20}};
NDArray<short, 1> img(shape, 3); NDArray<short, 1> img(shape, 3);
REQUIRE(img.size() == 20); REQUIRE(img.size() == 20);
REQUIRE(img(5) == 3); REQUIRE(img(5) == 3);
@ -71,7 +71,7 @@ TEST_CASE("Accessing a const object") {
} }
TEST_CASE("Indexing of a 2D image") { TEST_CASE("Indexing of a 2D image") {
std::array<int64_t, 2> shape{{3, 7}}; std::array<ssize_t, 2> shape{{3, 7}};
NDArray<long> img(shape, 5); NDArray<long> img(shape, 5);
for (uint32_t i = 0; i != img.size(); ++i) { for (uint32_t i = 0; i != img.size(); ++i) {
REQUIRE(img(i) == 5); REQUIRE(img(i) == 5);
@ -114,7 +114,7 @@ TEST_CASE("Divide double by int") {
} }
TEST_CASE("Elementwise multiplication of 3D image") { TEST_CASE("Elementwise multiplication of 3D image") {
std::array<int64_t, 3> shape{3, 4, 2}; std::array<ssize_t, 3> shape{3, 4, 2};
NDArray<double, 3> a{shape}; NDArray<double, 3> a{shape};
NDArray<double, 3> b{shape}; NDArray<double, 3> b{shape};
for (uint32_t i = 0; i != a.size(); ++i) { for (uint32_t i = 0; i != a.size(); ++i) {
@ -179,9 +179,9 @@ TEST_CASE("Compare two images") {
} }
TEST_CASE("Size and shape matches") { TEST_CASE("Size and shape matches") {
int64_t w = 15; ssize_t w = 15;
int64_t h = 75; ssize_t h = 75;
std::array<int64_t, 2> shape{w, h}; std::array<ssize_t, 2> shape{w, h};
NDArray<double> a{shape}; NDArray<double> a{shape};
REQUIRE(a.size() == w * h); REQUIRE(a.size() == w * h);
REQUIRE(a.shape() == shape); REQUIRE(a.shape() == shape);
@ -224,7 +224,7 @@ TEST_CASE("Bitwise and on data") {
TEST_CASE("Elementwise operations on images") { TEST_CASE("Elementwise operations on images") {
std::array<int64_t, 2> shape{5, 5}; std::array<ssize_t, 2> shape{5, 5};
double a_val = 3.0; double a_val = 3.0;
double b_val = 8.0; double b_val = 8.0;

View File

@ -142,7 +142,7 @@ TEST_CASE("iterators") {
// for (int i = 0; i != 12; ++i) { // for (int i = 0; i != 12; ++i) {
// vec.push_back(i); // vec.push_back(i);
// } // }
// std::vector<int64_t> shape{3, 4}; // std::vector<ssize_t> shape{3, 4};
// NDView<int, 2> data(vec.data(), shape); // NDView<int, 2> data(vec.data(), shape);
// } // }
@ -151,8 +151,8 @@ TEST_CASE("divide with another span") {
std::vector<int> vec1{3, 2, 1}; std::vector<int> vec1{3, 2, 1};
std::vector<int> result{3, 6, 3}; std::vector<int> result{3, 6, 3};
NDView<int, 1> data0(vec0.data(), Shape<1>{static_cast<int64_t>(vec0.size())}); NDView<int, 1> data0(vec0.data(), Shape<1>{static_cast<ssize_t>(vec0.size())});
NDView<int, 1> data1(vec1.data(), Shape<1>{static_cast<int64_t>(vec1.size())}); NDView<int, 1> data1(vec1.data(), Shape<1>{static_cast<ssize_t>(vec1.size())});
data0 /= data1; data0 /= data1;

View File

@ -26,8 +26,8 @@ void adc_sar_05_decode64to16(NDView<uint64_t, 2> input, NDView<uint16_t,2> outpu
throw std::invalid_argument(LOCATION + " input and output shapes must match"); throw std::invalid_argument(LOCATION + " input and output shapes must match");
} }
for(int64_t i = 0; i < input.shape(0); i++){ for(ssize_t i = 0; i < input.shape(0); i++){
for(int64_t j = 0; j < input.shape(1); j++){ for(ssize_t j = 0; j < input.shape(1); j++){
output(i,j) = adc_sar_05_decode64to16(input(i,j)); output(i,j) = adc_sar_05_decode64to16(input(i,j));
} }
} }
@ -56,8 +56,8 @@ void adc_sar_04_decode64to16(NDView<uint64_t, 2> input, NDView<uint16_t,2> outpu
if(input.shape() != output.shape()){ if(input.shape() != output.shape()){
throw std::invalid_argument(LOCATION + " input and output shapes must match"); throw std::invalid_argument(LOCATION + " input and output shapes must match");
} }
for(int64_t i = 0; i < input.shape(0); i++){ for(ssize_t i = 0; i < input.shape(0); i++){
for(int64_t j = 0; j < input.shape(1); j++){ for(ssize_t j = 0; j < input.shape(1); j++){
output(i,j) = adc_sar_04_decode64to16(input(i,j)); output(i,j) = adc_sar_04_decode64to16(input(i,j));
} }
} }