If DeviceContext is used in multiple places, is it better to wrap it in ArcPointer and use it via the pointer?
For example:
var device_ctx1 = DeviceContext()
var device_ctx2 = DeviceContext()
# Should we do the following instead?
var device_ctx = ArcPointer(DeviceContext())
```
Thanks.
struct DeviceContext(ImplicitlyCopyable, RegisterPassable):
var _handle: _DeviceContextPtr[mut=True]
var _owning: Bool
A DeviceContext is a thin Mojo wrapper around a C++ handle that manages its own reference count. The copy constructor calls AsyncRT_DeviceContext_retain and the destructor calls AsyncRT_DeviceContext_release. That means each copy shares the same underlying GPU stream/context, and resources are freed when the last copy goes out of scope - exactly what ArcPointer would give you, but built in.
There are some options based on your example though:
Option 1 (two separate DeviceContext() calls) is most likely not what you want. Each call creates a distinct context with its own stream, so work enqueued on one is independent of the other. That’s only appropriate if you deliberately want concurrent streams.
Option 2 (ArcPointer(DeviceContext())) works but is redundant — you’d be refcounting a refcounted handle.
Idiomatic usage is to create one instance and pass it by value:
By default DeviceContext() selects device 0 on the default accelerator API for your build target. If you need a second, physically distinct device, pass DeviceContext(device_id=1).
Thanks for the explanation - much appreciate it! “helper(ctx)” - pattern works in limited context. If I wanted to throw around an instantiated DeviceContext - embedding the context inside ArcPointer extends the ‘helper’ pattern but incurs the cost of redundant ref counting. My requirement - as you must have understood - how do I throw around a default instantiated DeviceContext in absence of statics/global! "global_constant()" - would not work - would it?