Closed Xayah-Hina closed 1 month ago
Hi!
Usually we embed C/C++ code so it can be called by Python, e.g. with pybind11. Likewise, PyTorch is written in C++ and exposes the functionality to Python in that way. However, as PhiFlow is written mostly in Python, it's unlikely, we'll add a C++ API.
Maybe you could wrap your C++ calls with pybind and use Python for the top-level execution?
Hi!
Usually we embed C/C++ code so it can be called by Python, e.g. with pybind11. Likewise, PyTorch is written in C++ and exposes the functionality to Python in that way. However, as PhiFlow is written mostly in Python, it's unlikely, we'll add a C++ API.
Maybe you could wrap your C++ calls with pybind and use Python for the top-level execution?
Hi holl~ Thanks for your quick reply~
I found a convenient header in Houdini HDK #include <PY/PY_Python.h>
, so we can easily embed python into Houdini context. The usage (In HDK DOP context) would be like below:
bool GAS_TestPhiFlow::solveGasSubclass(SIM_Engine& engine, SIM_Object* obj, SIM_Time time, SIM_Time timestep)
{
SIM_ScalarField* D = getScalarField(obj, GAS_NAME_DENSITY);
SIM_VectorField* V = getVectorField(obj, GAS_NAME_VELOCITY);
if (!D || !V)
{
addError(obj, SIM_MESSAGE, "Missing GAS fields", UT_ERROR_FATAL);
return false;
}
UT_WorkBuffer expr;
PY_Result result;
expr.sprintf(R"(
from phi.torch.flow import *
velocity = StaggeredGrid((0, 0, 0), 0, x=50, y=50, z=50, bounds=Box(x=1, y=1, z=1)) # or CenteredGrid(...)
smoke = CenteredGrid(0, ZERO_GRADIENT, x=50, y=50, z=50, bounds=Box(x=1, y=1, z=1))
INFLOW = 0.5 * resample(Sphere(x=0.5, y=0.5, z=0.5, radius=0.1), to=smoke, soft=True)
pressure = None
@jit_compile # Only for PyTorch, TensorFlow and Jax
def step(v, s, p, dt=1.):
s = advect.mac_cormack(s, v, dt) + INFLOW
buoyancy = resample(s * (0, 0, 0.1), to=v)
v = advect.semi_lagrangian(v, v, dt) + buoyancy * dt
v, p = fluid.make_incompressible(v, (), Solve('auto', 1e-5, x0=p))
return v, s, p
velocity, smoke, pressure = step(velocity, smoke, pressure)
)");
PYrunPythonStatementsAndExpectNoErrors(expr.buffer());
expr.sprintf("[CODES TO EXTRACT PHIFLOW FIELDS TO DOUBLE ARRAY]\n");
result = PYrunPythonExpressionAndExpectNoErrors(expr.buffer(), PY_Result::DOUBLE_ARRAY);
if (result.myResultType != PY_Result::DOUBLE_ARRAY)
{
printf("Error: %s\n", result.myErrValue.buffer());
return false;
}
// convert result array to Houdini's Fields...
return true;
}
Maybe this can help others who also want to use PhiFlow inside Houdini HDK context.
By the way, since Houdini HDK itself already contain a Python context, It seems that we can't directly use pybind
to embed python inside c++ context. The reason maybe comes from the initializaiton of Python context, I've tried a lot to solve it but at last in vain). Finally, I found #include <PY/PY_Python.h>
, this is so powerful~
Oh nice, that seems promissing!
I want to integrate a differentiable fluid simulator into Houdini HDK, since I need Houdini as a better viewer and get better performance by PDG.
So would phiflow support C++ Api in the future like pytorch? Reading results simulated by Python and converting it as Houdini Goometry are too time-consuming. So, it would be better if we can directly run pure c++ codes and get the results without converting process.
Btw, I would appreciate it if there are any share-worthy experiences for embeding python code inside c++ just like mantaflow did... ?
Thanks for your awesome work : )