Skip to content

Code test for native C-abi interop code.

Notifications You must be signed in to change notification settings

novorender/code-test-aabb

Repository files navigation

AABB Code Test

This project has two main components:

  1. C# Binding/wrapper project and unit tests.
  2. Native dll/so dynamic library.

Your job is to implement the native side of things. Pick a performant language with explicit memory management, like C/C++, Rust or similar. Pick your favorite OS and IDE.

I made a basic implementation in zig. For your convenience, I left some of the source code in there to show how I did parameter validation. I also left my win64/linux/mac (ARM) binaries for reference. If you're familiar with rust, zig should be easy enough to read. I also had AI generate an interface.h file if that is more your cup of tea. Feel free to ignore either!

The challenge

Your task is deceptively simple. Write code that computes an axis aligned bounding box (AABB) from the provided vertices. This is as easy as computing min/max vectors. It's a bit more complex than that, however:

  • Make a dynamic library/module using C-ABI bindings (dll/so/dylib) to match the existing interface. (a lib/a file or debug info is not required)
  • Validate parameters and return specified error codes as needed.
  • Avoid allocating memory internally. Caller should own all buffers.
  • Incremental (co-routine-like) execution, i.e. be able to resume where it left of, but with new parameters. State that span across runs cannot live on the stack.
  • Apply a 4x4 affine matrix to the input vertices to transform them from model space into world space, using float64 precision to avoid excessive rounding errors with very large coordinates (Common in BIM).

Some very optional bonus features to flex your skills:

  • Cross-platform build (win/linux/mac) with native code unit tests++.
  • Various debug/release builds with configurable debug into, logging and run-time checks (e.g. overflow/underflow) and CPU float modes (strict IEEE vs, faster, more relaxed arithmetic)
  • Use SIMD to boost performance. Not really that useful for this simple, memory-bound algorithm, but very useful for more advanced ones.
  • Clever generic/templated code to support e.g. float32/64 input, large integers or even z-curve encoded coordinates (u128).
    • In case of integers, it's important to round min values down and max values up.
    • Most integers would be some variant of fixed-point precision, e.g. 24/56 bit meter integer and 8 bit sub-meter decimal.
  • Clever use of modern language co-routines, preferably paired with explicit memory management of heap state. Again, this trivial algorithm doesn't really benefit, but more complex ones might.

Some things to avoid:

  • AI slop and bloat. We want to see you in action.
  • Use of excessive external libraries that adds much complexity during review. Keep things simple and small. A vector/matrix multiply is trivial.
  • Esoteric build environments or test frameworks that are hard to install/reproduce. CMake and cargo are fine.

Proof of Correctness

The included C# unit tests exercises basic parameter validation and use cases to verify your implementation is up to spec. Install dotnet 10.0 framework and run dotnet test on the root of the project. It expects to find a reachable (lib)aabb_lib.dll/so/dylib, implemented by you. If the test passes, your job is done.

Rationale

Some of these constraints and design choices may seem weird. There are reasons however:

  • Basic C-ABI is the only interface that most languages can interop with. C# is only one of them. Use of proper error codes and parameter validation is a necessary evil of this limitation.
  • The code will run in an extreme performance and memory environment where local islands of memory management is undesirable.
  • The incremental, co-routine approach and variable byte stride is required to facilitate real life workflows.
  • The use of a Span instead of just an opaque pointer to manage memory is to avoid buffer overruns and provide a bare minimum of future proofing.
  • Intel CPUs allow all sorts of alignments, albeit at a cost. Arm does not. Either way, alignment matters. Even more so with SIMD.

In general, the design may seem like overkill. But it's intended to fit into a much larger context, where things start to make more sense. It's indicative of real-world complexities that you're likely to encounter working with us.

What we're looking for

Although great code speak more than a thousand words, we're also interested in learning how you approached the problem, how you reasoned and how/why you ended up doing what you did. Feel free to take notes for a subsequent discussion. In this case it really is about the journey, and less about the destination.

Also, be prepared to explain your code and design choices in detail to demonstrate deep reasoning and understanding. Using AI is fine, but we want to see you firmly in control.

Best of luck and have fun!

About

Code test for native C-abi interop code.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published