Skip to content

Commit

Permalink
FArrayBox and BaseFab<Real> (#82)
Browse files Browse the repository at this point in the history
Start to bind FArrayBox and BaseFab classes.

Based on a question how to bind `FArrayBox::readFrom` to
Python, e.g., can be done via
* https://docs.python.org/3/library/io.html
* https://gist.github.com/asford/544323a5da7dddad2c9174490eb5ed06#file-test_ostream_example-py
  • Loading branch information
ax3l authored Oct 17, 2022
1 parent 28e389d commit aa683b9
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 2 deletions.
126 changes: 126 additions & 0 deletions src/Base/BaseFab.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/* Copyright 2021-2022 The AMReX Community
*
* Authors: Axel Huebl
* License: BSD-3-Clause-LBNL
*/
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <AMReX_FArrayBox.H>

#include <istream>

namespace py = pybind11;
using namespace amrex;

namespace
{
template< typename T >
void init_bf(py::module &m, std::string typestr) {
auto const bf_name = std::string("BaseFab_").append(typestr);
py::class_< BaseFab<T> >(m, bf_name.c_str())
.def("__repr__",
[bf_name](BaseFab<Real> const & bf) {
std::string r = "<amrex.";
r.append(bf_name).append(" (n_comp=");
r.append(std::to_string(bf.nComp())).append(")>");
return r;
}
)

.def(py::init< >())
//.def(py::init< Arena* >())
//.def(py::init< const Box&, int, Arena* >())
//.def(py::init< >( const Box&, int, bool, bool, Arena* ))
//.def(py::init< const BaseFab<T>&, MakeType, int, int >())
// non-owning
.def(py::init< const Box&, int, T* >())
.def(py::init< const Box&, int, T const* >())

.def(py::init< Array4<T> const& >())
.def(py::init< Array4<T> const&, IndexType >())
.def(py::init< Array4<T const> const& >())
.def(py::init< Array4<T const> const&, IndexType >())

//.def_static("initialize", &BaseFab<T>::Initialize )
//.def_static("finalize", &BaseFab<T>::Finalize )

.def("resize", &BaseFab<T>::resize )
.def("clear", &BaseFab<T>::clear )
//.def("release", &BaseFab<T>::release )

.def("n_bytes", py::overload_cast< >(&BaseFab<T>::nBytes, py::const_))
.def("n_bytes", py::overload_cast< Box const &, int >(&BaseFab<T>::nBytes, py::const_))
.def("n_bytes_owned", &BaseFab<T>::nBytesOwned )
.def("n_comp", &BaseFab<T>::nComp )
.def("num_pts", &BaseFab<T>::numPts )
.def("size", &BaseFab<T>::size )
.def("box", &BaseFab<T>::box )
.def("length", &BaseFab<T>::length )

.def("small_end", &BaseFab<T>::smallEnd )
.def("big_end", &BaseFab<T>::bigEnd )
.def("lo_vect", &BaseFab<T>::loVect )
.def("hi_vect", &BaseFab<T>::hiVect )

// contains
// prefetchToHost
// prefetchToDevice
.def("is_allocated", &BaseFab<T>::isAllocated )

//.def("array", &BaseFab<T>::array )
//.def("const_array", &BaseFab<T>::const_array )

// getVal
// setVal
// setValIf
// setValIfNot
// setComplement
// copy
// copyToMem
// copyFromMem
// addFromMem

// shift
// shiftHalf

// norminfmask
// norm
// abs
// min
// max
// minmax
// maxabs
// indexFromValue
// minIndex
// maxIndex
// maskLT
// maskLE
// maskEQ
// maskGT
// maskGE
// sum
// invert
// negate
// plus
// atomicAdd
// saxpy
// xpay
// addproduct
// minus
// mult
// divide
// protected_divide
// linInterp
// linComb
// dot
// dotmask

// SetBoxType
;
}
}

void init_BaseFab(py::module &m) {
init_bf<Real>(m, "Real");
}
2 changes: 2 additions & 0 deletions src/Base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ target_sources(pyAMReX
PRIVATE
AMReX.cpp
Array4.cpp
BaseFab.cpp
Box.cpp
RealBox.cpp
BoxArray.cpp
CoordSys.cpp
Dim3.cpp
DistributionMapping.cpp
FArrayBox.cpp
Geometry.cpp
IntVect.cpp
RealVect.cpp
Expand Down
57 changes: 57 additions & 0 deletions src/Base/FArrayBox.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* Copyright 2021-2022 The AMReX Community
*
* Authors: Axel Huebl
* License: BSD-3-Clause-LBNL
*/
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <AMReX_FArrayBox.H>

#include <istream>
#include <ostream>
#include <string>

namespace py = pybind11;
using namespace amrex;


void init_FArrayBox(py::module &m) {
py::class_< FArrayBox, BaseFab<Real> >(m, "FArrayBox")
.def("__repr__",
[](FArrayBox const & /* fab */) {
std::string r = "<amrex.FArrayBox>";
return r;
}
)

.def(py::init< >())
//.def(py::init< Arena* >())
//.def(py::init< Box const &, int, Arena* >())
//.def(py::init< const Box&, int, bool, bool, Arena* >())
//.def(py::init< const FArrayBox&, MakeType, int, int >())
.def(py::init< const Box&, int, Real const* >())
.def(py::init< const Box&, int, Real* >())
.def(py::init< Array4<Real> const& >())
.def(py::init< Array4<Real> const&, IndexType >())
.def(py::init< Array4<Real const> const& >())
.def(py::init< Array4<Real const> const&, IndexType >())

.def("read_from",
py::overload_cast<std::istream&>(&FArrayBox::readFrom),
py::arg("is")
)
.def("read_from",
py::overload_cast<std::istream&, int>(&FArrayBox::readFrom),
py::arg("is"), py::arg("compIndex")
)
.def("write_on",
py::overload_cast<std::ostream&>(&FArrayBox::writeOn, py::const_),
py::arg("of")
)
.def("write_on",
py::overload_cast<std::ostream&, int, int>(&FArrayBox::writeOn, py::const_),
py::arg("of"), py::arg("comp"), py::arg("num_comp")
)
;
}
3 changes: 1 addition & 2 deletions src/Base/MultiFab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <AMReX_Config.H>
#include <AMReX_BoxArray.H>
#include <AMReX_DistributionMapping.H>
#include <AMReX_FArrayBox.H>
#include <AMReX_FabArray.H>
#include <AMReX_FabArrayBase.H>
#include <AMReX_MultiFab.H>
Expand Down Expand Up @@ -45,8 +46,6 @@ void init_MultiFab(py::module &m) {
)
;

py::class_< FArrayBox >(m, "FArrayBox");

py::class_< MFIter >(m, "MFIter", py::dynamic_attr())
.def("__repr__",
[](MFIter const & mfi) {
Expand Down
5 changes: 5 additions & 0 deletions src/pyAMReX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ namespace py = pybind11;
// forward declarations of exposed classes
void init_AMReX(py::module&);
void init_Array4(py::module&);
void init_BaseFab(py::module&);
void init_Box(py::module &);
void init_RealBox(py::module &);
void init_BoxArray(py::module &);
void init_CoordSys(py::module&);
void init_Dim3(py::module&);
void init_DistributionMapping(py::module&);
void init_FArrayBox(py::module&);
void init_Geometry(py::module&);
void init_IntVect(py::module &);
void init_RealVect(py::module &);
Expand Down Expand Up @@ -57,6 +59,7 @@ PYBIND11_MODULE(amrex_pybind, m) {
RealBox
BoxArray
Dim3
FArrayBox
IntVect
RealVect
MultiFab
Expand All @@ -81,6 +84,8 @@ PYBIND11_MODULE(amrex_pybind, m) {
init_Box(m);
init_BoxArray(m);
init_ParmParse(m);
init_BaseFab(m);
init_FArrayBox(m);
init_MultiFab(m);
init_DistributionMapping(m);
init_RealBox(m);
Expand Down
7 changes: 7 additions & 0 deletions tests/test_basefab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-

import amrex


def test_basefab():
bf = amrex.BaseFab_Real()
18 changes: 18 additions & 0 deletions tests/test_farraybox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-

import amrex


def test_farraybox():
fab = amrex.FArrayBox()


def test_farraybox_io():
fab = amrex.FArrayBox()

# https://docs.python.org/3/library/io.html
# https://gist.github.com/asford/544323a5da7dddad2c9174490eb5ed06#file-test_ostream_example-py
# import io
# iob = io.BytesIO()
# assert iob.getvalue() == b"..."
# fab.read_from(iob)

0 comments on commit aa683b9

Please sign in to comment.