Skip to content

NonZero Operator - #52

Open
ioantreas wants to merge 6 commits into
gpu/alpakafrom
gpu/operators
Open

NonZero Operator#52
ioantreas wants to merge 6 commits into
gpu/alpakafrom
gpu/operators

Conversation

@ioantreas

@ioantreas ioantreas commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Adds Alpaka support for ONNX NonZero with parser registration and CUDA tests. Also updates RModel_ALPAKA dynamic-tensor handling so buffers use the correct type, runtime-sized tensors are not allocated before their shape is known, and dynamic model outputs use bufDev_ instead of deviceBuf_. All Alpaka tests pass.

@ioantreas ioantreas changed the title Gpu/operators NonZero Operator Aug 17, 2026

@sanjibansg sanjibansg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the implementation, couple of comments:

Comment thread core/inc/SOFIE/ROperator_NonZero.hxx Outdated
out << SP << "auto nonZeroCountDev_" << fNY << " = alpaka::allocBuf<std::size_t, Idx>(devAcc, Ext1D::all(Idx{1}));\n";
out << SP << "auto nonZeroCountHost_" << fNY << " = alpaka::allocBuf<std::size_t, Idx>(hostAcc, Ext1D::all(Idx{1}));\n";
out << SP << "auto const workDivNonZero_" << fNY << " = sofie_workdiv(Vec::all(Idx{1}));\n";
out << SP << "alpaka::exec<Acc>(queue, workDivNonZero_" << fNY << ", nonZeroKernel_" << fNY << ", alpaka::getPtrNative(deviceBuf_" << fNX << "), alpaka::getPtrNative(bufDev_" << fNY << "), alpaka::getPtrNative(nonZeroCountDev_" << fNY << "));\n";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have create task and then enqueue paradigm like we have for the other operators? alpaka::wait is expensive operation, so doing that after every operator will slow down the process.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the kernel launch to createTaskKernel + enqueue. The wait is still required here because the NonZero count is copied back to the host and immediately used to determine the dynamic output shape, avoiding it would require keeping the count and shape handling on the GPU or redesigning the dynamic-output flow so the host does not need the count immediately

Comment thread test/alpaka_input_models/NonZeroModelGenerator.py Outdated
Comment thread test/alpaka_input_models/NonZeroModelGenerator.py Outdated
Comment thread test/CMakeLists.txt
Comment thread core/inc/SOFIE/ROperator_NonZero.hxx Outdated
Comment thread core/inc/SOFIE/ROperator_NonZero.hxx Outdated
op += SP + SP + SP + "auto const i = alpaka::getIdx<alpaka::Grid, alpaka::Threads>(acc)[0];\n";
op += SP + SP + SP + "if (i != 0u) return;\n";
op += SP + SP + SP + "std::size_t n = 0;\n";
op += SP + SP + SP + "for (std::size_t j = 0; j < " + std::to_string(fInputLength) + "u; ++j) if (input[j] != static_cast<T>(0)) ++n;\n";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using if in GPU code could be an issue, can there be any other algorithmic way to do this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the branch from the counting pass by accumulating the boolean condition directly. A branch remains in the output-writing pass, removing that would require a different prefix-scan algorithm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants