GollyGang / ready

A cross-platform implementation of various reaction-diffusion systems and PDEs.
GNU General Public License v3.0
755 stars 60 forks source link

How can I use this as a library? #157

Open ct2034 opened 1 year ago

ct2034 commented 1 year ago

Firstly: I am SUPER happy having finally found this. It is absolutely amazing. Can i use this as a library? I am mostly interested in the Gray-Scott Model. How could I use this in another cpp Cmake file?

timhutton commented 1 year ago

Hi Christian,

Glad it's useful.

Inside the CMakeLists.txt there's an example of where the 'readybase' library is used to make a simple command-line utility (rdy.exe):

create command-line utility

add_executable( ${CMD_NAME} ${CMD_SOURCES} ) target_include_directories( ${CMD_NAME} PRIVATE src/extern/cxxopts-2.2.1 ) target_link_libraries( ${CMD_NAME} readybase ${CMAKE_DL_LIBS})

where CMD_SOURCES is just src/cmd/main.cpp ( https://github.com/GollyGang/ready/blob/gh-pages/src/cmd/main.cpp), and a header.

If you just want a Gray-Scott implementation to play with, it might be more useful to make your own. I can talk you through it. A loose sketch for a 1D system:

float a[100], b[100], a_new[100], b_new[100]; const float diff = 0.07f; const float F = 0.05f; const float k = 0.04f; const float timestep = 0.2f; for( int i = 1; i < 99; i++ ) { float laplacian_a = a[-1] - 2.0f a[i] + a[i+1]; float laplacian_b = b[-1] - 2.0f b[i] + b[i+1]; float delta_a = 2.0f diff laplacian_a - a[i]b[i]b[i] + F(1.0f - a[i]); float delta_b = diff laplacian_b + a[i]b[i]b[i] - (F+k)b[i]; a_new[i] = a[i] + timestep delta_a; b_new[i] = b[i] + timestep * delta_b; } // TODO: swap a_new with a, and b_new with b // TODO: repeat above loop for multiple steps

Tim

On Sun, 14 May 2023 at 18:53, Christian Henkel @.***> wrote:

Firstly: I am SUPER happy having finally found this. It is absolutely amazing. Can i use this as a library? I am mostly interested in the Gray-Scott Model. How could I use this in another cpp Cmake file?

— Reply to this email directly, view it on GitHub https://github.com/GollyGang/ready/issues/157, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE57NA67KBZ76XUWIGZC4LXGELYZANCNFSM6AAAAAAYBJMPAE . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Tim Hutton - @.*** - https://github.com/timhutton

ct2034 commented 1 year ago

Hey Tim Thanks so much for the detailed instructions. I actually have my own implementation. One thing I noticed about your implementation, though is the use of dx. It seems to improve the performance a lot. For example in https://github.com/GollyGang/ready/blob/gh-pages/Patterns/GrayScott1984/Pearson1993.vti How is dx used? And why are the D values so much smaller? https://github.com/GollyGang/ready/blob/gh-pages/src/readybase/GrayScottImageRD.cpp does not seem to use dx anywhere. Is it some kind of spatial resolution? And how is the laplacian calculated, then?

timhutton commented 1 year ago

If you load Pearson1993.vti, change the dimensions to 256x1x1 and hit View

View Full Kernel it will show you how dx is used for the 1D case: const float4 laplacian_a = (-2 a + a_w + a_e) / (1 dx dx); const float4 laplacian_b = (-2 b + b_w + b_e) / (1 dx dx);

dx is the spatial separation of the grid points, often called 'h' in the literature. It is mentioned in Help > Hint and Tips. If there is no parameter named dx then it defaults to 1.

Decreasing dx makes the blobs larger, since the overall grid you are simulating is smaller. You'll need a smaller timestep too for numerical stability.

The D_ parameters are the diffusion rates. Increasing them makes the blobs bigger while keeping the grid size the same. Again you'll need a smaller timestep.

The values in Pearson1993.vti are those from the paper I think. The combination of D_ values and dx was just the one they used - there are other values that give the same behavior.

So dx shouldn't affect the performance. What are you comparing it to?

Ready uses OpenCL for its computation (typically on the GPU), and runs multiple steps per render.

Tim

On Mon, 15 May 2023 at 10:45, Christian Henkel @.***> wrote:

Hey Tim Thanks so much for the detailed instructions. I actually have my own implementation. One thing I noticed about your implementation, though is the use of dx. It seems to improve the performance a lot. For example in https://github.com/GollyGang/ready/blob/gh-pages/Patterns/GrayScott1984/Pearson1993.vti How is dx used? And why are the D values so much smaller?

https://github.com/GollyGang/ready/blob/gh-pages/src/readybase/GrayScottImageRD.cpp does not seem to use dx anywhere. Is it some kind of spatial resolution? And how is the laplacian calculated, then?

— Reply to this email directly, view it on GitHub https://github.com/GollyGang/ready/issues/157#issuecomment-1547528654, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE57NE7UZ7JT33ZQJYSM23XGH3JZANCNFSM6AAAAAAYBJMPAE . You are receiving this because you commented.Message ID: @.***>

-- Tim Hutton - @.*** - https://github.com/timhutton

danwills commented 9 months ago

While dx/h and diffusion-rates can certainly make a difference to how fast things appear to 'evolve' (per-timestep) .. the compute-amount per-frame is mostly down to how many timesteps are being done before displaying the result again (in Ready it's labeled "Timesteps Per Render".

I've generally found that since OpenCL can go very fast indeed, and the VTK rendering framework perhaps has a bit of overhead in it, that you can often turn up "Timesteps Per Render" quite a lot without 'feeling it' in terms of framerate that much. Of course your mileage there will vary based on how capable/fast your GPU/video-ram is. (mine are old and crappy and I still find there's a range of timesteps where I hardly feel it!)

The fact Ready uses OpenCL for the computation of the next timestep essentially allows it to do something like "compute the next values for all cells at once (on the GPU)" instead of "compute them one-at-a-time (on the CPU)" and I'd say is likely to be the main reason for the improvement in apparent speed that you're seeing.

I think Tim's comment above suggesting the 'rdy' command source code is very on-point, and there would possibly be some bits you could dig-up and examine from our prior Houdini plugin where it would run the simulation (specified by VTI file) using the Ready backend/libs, and then retrieve the resulting fields into per-frame voxel data in Houdini. Let me know if you want any pointers to find that code if you're keen on that idea!

The newer incarnation of the plugin doesn't binary-link Ready at all.. instead it imports a VTI as houdini-native nodes (at it's core it's bringing/translating the kernels into something that works in the "Gas OpenCL" Dop). This was working fairly well in houdini18.5-ish but now we're onto 19.5 which is python3-only it needed a reasonably hefty update, and I've done all the py3-the update but everything still isn't quite working yet, so I haven't yet committed the current state of things. Let me know if this interests you though and I'd be happy to hurry-things-up-a-bit :).