Segment fault when handling buffer data

Hello, I’m trying to simulate a pouring scene and compute how many particles are in the cup at the end. I didn’t find an API for post-process for the whole problem but a single frame, i.e. addPostProcess(CALC_PRIVATE);. But it reports segment fault when getting particles’ info.

void Pour::calcPrivate(flag_t options,
    BufferList const& bufread,
    BufferList & bufwrite,
    uint numParticles,
    uint particleRangeEnd,
    uint deviceIndex,
    const GlobalData * const gdata)
{
    //thread per particle
    uint numThreads = BLOCK_SIZE_CALCTEST;
    uint numBlocks = div_up(particleRangeEnd, numThreads);

    const float4 *pos = bufread.getData<BUFFER_POS>();
    const float4 *vel = bufread.getData<BUFFER_VEL>();
    const particleinfo *info = bufread.getData<BUFFER_INFO>();
    const hashKey *particleHash = bufread.getData<BUFFER_HASH>();
    const uint *cellStart = bufread.getData<BUFFER_CELLSTART>();
    const neibdata *neibsList = bufread.getData<BUFFER_NEIBSLIST>();

    int insidenum = 0;
    for(uint i = 0; i<numParticles;i++){
        if (FLUID(info[i])){//<-- Segment Fault (core dumped)
            ......

In debug, I can see

i: 0
info[i]: {...}
    x: 0
    y: 0
    z: 0
    w: 0
buread: {...}
    m_map: {...}
    m_keys: 1142461302494
    m_has_pending_state: BufferList::NOT_PENDING
    m_pending_state: ""
    m_updated_buffers: 0
    m_validate_accessfalse
numThreads: 128
numBlocks: 28
pos: 0x7fffc660de00
    x: 0
    y: 0
    z: 0
    w: 0
info: 0x7fffc6637800
    x: 0
    y: 0
    z: 0
    w: 0

I haven’t write cuda codes before, so I guess if there’s something wrong with operation about buffer data?
But I find the same code can work in

initializeParticles(BufferList &buffers, const uint numParticles){
    ...
}

I’m confused. Can anyone help? Thanks in advance!

Hello @RRRRLi —thanks for your interest in GPUSPH, and sorry for the delay in the response.

The CALC_PRIVATE post-processing filter is intended for execution on GPU, not on CPU. The buffers in the bufread and bufwrite lists are device buffers, not host buffers, so in general you cannot access them on host. This is exemplified in the ProblemExample test case: the host-side calcPrivate function is just a thin wrapper that sets up the launch grid and then invokes a calcPrivateDevice kernel that does the actual computation (in the provided example, simply a count of the number of neighbors for it particle).

The reason why accessing the buffer works in initializeParticle is because initializeParticles is intended to be run on host, and is thus passed a list of host-side buffers (the ones used also for writing. If you only care about producing the additional data on host, when writing, one way to achieve this is to add a CALLBACKWRITER to your problem, and override the writer_callback method:

void
YourTestCase::writer_callback(CallbackWriter *,
	uint numParts, BufferList const& bufread, uint node_offset, double t,
	const bool testpoints) const
{
/* here you can read your bufread data, process it without modifying it,
   and then write the output to disk or wherever you want. */
}

(I’m afraid we don’t have a test case showing how to use this writer presently, so feel free to ask here on the forum for any additional help.)

1 Like

Thanks for your reply! I’ve solved this problem through your method.