---
title: "ClikaRT::StreamOrDevice"
sidebar_label: "StreamOrDevice"
description: "A value type: it holds a copyable Stream handle and/or a Device, so it crosses the ABI by layout; resolve_impl is its one library entry (the placement law lives in the runtime)."
---

<!-- Generated by tools/doxygen2mdx from Doxygen XML. Do not edit. -->

<span class="api-kind api-kind--class">class</span>

**Header:** `ClikaRT/compute/stream_or_device.h`

A placement argument that accepts either a `Stream` or a `Device`, the public "where should this run / where does this live" parameter. A `Stream` names a lane exactly and is used as given; passing a device's default stream is the explicit opt-in to synchronous execution. A `Device` names only placement: an operation given a bare device follows the work it reads (a pending input's lane) and otherwise runs on the calling thread's current lane on that device, the ambient placement's stream when a placement scope set one there, otherwise the thread's own asynchronous lane. It is never the device's default stream. Construct it implicitly from either; `resolve()` collapses it to the concrete `Stream` a bare device stands for right now. A default-constructed value is unspecified; `resolve()` then consults the calling thread's ambient placement (see [`ClikaRT/compute/placement.h`](./placement/PlacementScope.md)) and, when none is set, takes the current lane on the supplied fallback device.

A value type: it holds a copyable [`Stream`](./Stream.md) handle and/or a [`Device`](./Device.md), so it crosses the ABI by layout; [`resolve_impl`](./StreamOrDevice.md#resolve) is its one library entry (the placement law lives in the runtime).

## Member functions

### StreamOrDevice() {#StreamOrDevice}

<div class="api-signature">

**`StreamOrDevice`**() `noexcept=default`

</div>

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 33

</div>

### StreamOrDevice(Stream) {#StreamOrDevice-2}

<div class="api-signature">

**`StreamOrDevice`**([`Stream`](./Stream.md) `stream`)

</div>

Wrap a specific stream; ops issue onto it, stream-ordered. An explicit stream always wins: a device's default stream passed here runs the work synchronously on the calling thread, on purpose.

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 37

</div>

### StreamOrDevice(Device) {#StreamOrDevice-3}

<div class="api-signature">

**`StreamOrDevice`**([`Device`](./Device.md) `device`) `noexcept`

</div>

Wrap a device; the work is placed on it and follows its inputs, landing on the calling thread's current lane there when nothing is pending. Never the device's default stream.

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 41

</div>

### has\_stream() {#has_stream}

<div class="api-signature">

`bool` **`has_stream`**() `const noexcept`

</div>

True if an explicit stream was given.

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 45

</div>

### has\_device() {#has_device}

<div class="api-signature">

`bool` **`has_device`**() `const noexcept`

</div>

True if a bare device (no stream) was given.

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 47

</div>

### is\_unspecified() {#is_unspecified}

<div class="api-signature">

`bool` **`is_unspecified`**() `const noexcept`

</div>

True if neither a stream nor a device was given.

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 49

</div>

### stream() {#stream}

<div class="api-signature">

`const` [`Stream`](./Stream.md)`&` **`stream`**() `const`

</div>

The explicit stream. Call only when [`has_stream()`](./StreamOrDevice.md#has_stream) is true.

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 52

</div>

### device\_or() {#device_or}

<div class="api-signature">

[`Device`](./Device.md) **`device_or`**([`Device`](./Device.md) `fallback` `=` [`Device::cpu`](./Device.md#cpu)`()`) `const`

</div>

The device this placement names: the stream's device, the bare device, or `fallback` when unspecified.

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 56

</div>

### resolve() {#resolve}

<div class="api-signature">

[`Stream`](./Stream.md) **`resolve`**([`Device`](./Device.md) `fallback` `=` [`Device::cpu`](./Device.md#cpu)`()`) `const`

</div>

Collapse to a concrete [`Stream`](./Stream.md): the placement law. A given stream is returned as is (an explicit stream always wins, a device's default stream included: that is the synchronous opt-in). A given device resolves to the calling thread's current lane on it: the ambient placement's stream when a placement scope set one on that device, otherwise the thread's own asynchronous lane there. Unspecified consults the calling thread's ambient placement ([`ClikaRT/compute/placement.h`](./placement/PlacementScope.md)) first and, when none is set, takes the current lane on `fallback`. Never a device's default stream on its own. Fails only when the resolved device cannot lease a lane at all (its backend is not loadable, or does not serve the device).

<div class="api-declared">

Declared in `ClikaRT/compute/stream_or_device.h`, line 78

</div>
