oarust 0.8.6

GPU-first semantic computing engine written in Rust
import storage;
import attributes;

struct PushConstants {
	uint curve_index;
	uint counts_index;
	uint metrics_index;
	uint predicted_count;
	uint pair_count;
};
[[vk::push_constant]] PushConstants push;
[[vk::binding(0, 0)]] RWByteAddressBuffer storage_buffers[];

[kernel_name("detection_average_precision")]
[domain("vision")]
[variant("interpolated_101_point")]
[dtype("f32")]
[status("experimental")]
[shader("compute")]
[numthreads(1, 1, 1)]
void main(uint3 thread_id : SV_DispatchThreadID) {
	uint pair = thread_id.x;
	if (pair >= push.pair_count) return;
	uint counts_base = pair * 3u;
	uint target_count = load_u32(storage_buffers[push.counts_index], counts_base) +
		load_u32(storage_buffers[push.counts_index], counts_base + 2u);
	if (target_count == 0u) {
		store_f32(storage_buffers[push.metrics_index], pair * 4u + 3u, 0.0f);
		return;
	}
	uint curve_base = pair * push.predicted_count * 2u;
	float sum = 0.0f;
	for (uint recall_point = 0; recall_point <= 100u; ++recall_point) {
		float required_recall = float(recall_point) * 0.01f;
		float best_precision = 0.0f;
		for (uint rank = 0; rank < push.predicted_count; ++rank) {
			float precision = load_f32(storage_buffers[push.curve_index], curve_base + rank * 2u);
			float recall = load_f32(storage_buffers[push.curve_index], curve_base + rank * 2u + 1u);
			if (recall + 1.0e-7f >= required_recall) best_precision = max(best_precision, precision);
		}
		sum += best_precision;
	}
	store_f32(storage_buffers[push.metrics_index], pair * 4u + 3u, sum / 101.0f);
}