Hone logo
Hone
Problems

SIMD Vector Generation and Processing in Rust

SIMD (Single Instruction, Multiple Data) instructions allow processors to perform the same operation on multiple data points simultaneously, significantly boosting performance for data-intensive tasks. This challenge asks you to create a Rust library that generates SIMD vectors (using std::simd) and provides basic processing functions on them. This is useful for optimizing numerical computations, image processing, and other applications where parallel data manipulation is beneficial.

Problem Description

You are tasked with creating a Rust library named simd_utils that provides functionality for generating and processing SIMD vectors. The library should include the following:

  1. SIMD Vector Generation: A function generate_simd_vector that takes a data slice (&[f32]) and a SIMD vector type (std::simd::f32x4) as input and converts the slice into a SIMD vector. If the slice's length is not a multiple of 4, the function should return an Option<std::simd::f32x4>, returning None if the length is not divisible by 4.

  2. SIMD Vector Addition: A function add_simd_vectors that takes two std::simd::f32x4 vectors as input and returns their element-wise sum as a new std::simd::f32x4 vector.

  3. SIMD Vector Scaling: A function scale_simd_vector that takes a std::simd::f32x4 vector and a scalar f32 as input and returns a new std::simd::f32x4 vector where each element is the product of the original element and the scalar.

  4. SIMD Vector to Slice Conversion: A function simd_vector_to_slice that takes a std::simd::f32x4 vector as input and returns a Vec<f32> containing the vector's elements.

The library should be well-documented and include appropriate error handling.

Examples

Example 1:

Input: &[1.0, 2.0, 3.0, 4.0] and std::simd::f32x4
Output: std::simd::f32x4(1.0, 2.0, 3.0, 4.0)
Explanation: The slice is successfully converted into a SIMD vector.

Example 2:

Input: &[1.0, 2.0, 3.0] and std::simd::f32x4
Output: None
Explanation: The slice length is not a multiple of 4, so the function returns None.

Example 3:

Input: std::simd::f32x4(1.0, 2.0, 3.0, 4.0) and 2.0
Output: std::simd::f32x4(2.0, 4.0, 6.0, 8.0)
Explanation: Each element of the SIMD vector is multiplied by 2.0.

Example 4:

Input: std::simd::f32x4(1.0, 2.0, 3.0, 4.0) and std::simd::f32x4(5.0, 6.0, 7.0, 8.0)
Output: std::simd::f32x4(6.0, 8.0, 10.0, 12.0)
Explanation: The elements of the two SIMD vectors are added element-wise.

Example 5:

Input: std::simd::f32x4(1.0, 2.0, 3.0, 4.0)
Output: [1.0, 2.0, 3.0, 4.0]
Explanation: The SIMD vector is converted back into a Vec<f32>.

Constraints

  • The library should only use std::simd::f32x4.
  • Input slices should be of type &[f32].
  • All functions should be safe (no unsafe code).
  • The library should compile without warnings.
  • Performance is not the primary focus, but avoid unnecessary allocations or copies.

Notes

  • Consider using Rust's Option type to handle cases where the input slice length is not a multiple of 4.
  • The std::simd module provides SIMD vector types and operations. Familiarize yourself with its documentation.
  • Think about how to handle potential errors gracefully.
  • Focus on clarity and readability of the code. Good documentation is essential.
  • You can create a simple main.rs file to test your library. This is not required for submission, but highly recommended.
Loading editor...
rust