What does the fwrite function do in MATLAB / RunMat?
fwrite writes binary data to a file identifier obtained from fopen. It mirrors MATLAB's handling
of precision strings, skip values, and machine-format overrides so existing MATLAB scripts can save data
without modification. The builtin accepts numeric tensors, logical data, and character arrays; the bytes are
emitted in column-major order to match MATLAB storage.
How does the fwrite function behave in MATLAB / RunMat?
count = fwrite(fid, A)convertsAto unsigned 8-bit integers and writes one byte per element.count = fwrite(fid, A, precision)convertsAto the requested precision before writing. Supported precisions aredouble,single,uint8,int8,uint16,int16,uint32,int32,uint64,int64, andchar. Shorthand aliases such asuchar,byte, andreal*8are also recognised.count = fwrite(fid, A, precision, skip)skipsskipbytes after writing each element. RunMat applies the skip with a file seek, which produces sparse regions when the target position moves beyond the current end.count = fwrite(fid, A, precision, skip, machinefmt)overrides the byte ordering used for the conversion. Supported machine formats are'native','ieee-le', and'ieee-be'. When omitted, the builtin honours the format recorded byfopen.- Column-major ordering matches MATLAB semantics: tensors and character arrays write their first column completely before advancing to the next column. Scalars and vectors behave as 1-by-N matrices.
- The return value
countis the number of elements written, not the number of bytes. A zero-length input producescount == 0. - RunMat executes
fwriteentirely on the host. When the data resides on a GPU (gpuArray), RunMat gathers the tensor to host memory before writing; providers do not currently implement device-side file I/O.
fwrite Function GPU Execution Behaviour
fwrite never launches GPU kernels. If any input value (file identifier, data, or optional arguments) is backed
by a GPU tensor, RunMat gathers the value to host memory before performing the write. This mirrors MATLAB's own
behaviour when working with gpuArray objects: data is moved to the CPU for I/O. When a provider is available,
the gather occurs via the provider's download path; otherwise the builtin emits an informative error.
GPU residency in RunMat (Do I need gpuArray?)
You rarely need to move data with gpuArray purely for fwrite. RunMat keeps tensors on the GPU while compute
stays in fused expressions, but explicit file I/O always happens on the host. If your data already lives on the
device, fwrite performs an automatic gather, writes the bytes, and leaves residency unchanged for the rest of
the program. You can still call gpuArray manually when porting MATLAB code verbatim—the builtin will gather it
for you automatically.
Examples of using the fwrite function in MATLAB / RunMat
Write unsigned bytes with the default precision
fid = fopen('bytes.bin', 'w+b');
count = fwrite(fid, [1 2 3 255]);
fclose(fid);
Expected output:
count = 4
Write double-precision values
fid = fopen('values.bin', 'w+b');
data = [1.5 -2.25 42.0];
count = fwrite(fid, data, 'double');
fclose(fid);
Expected output:
count = 3
The file contains three IEEE 754 doubles in the machine format recorded by fopen.
Write 16-bit integers using big-endian byte ordering
fid = fopen('sensor.be', 'w+b', 'ieee-be');
fwrite(fid, [258 772], 'uint16');
fclose(fid);
Expected output:
count = 2
The bytes on disk follow big-endian ordering (01 02 03 04 for the values above).
Insert padding bytes between samples
fid = fopen('spaced.bin', 'w+b');
fwrite(fid, [10 20 30], 'uint8', 1); % skip one byte between elements
fclose(fid);
Expected output:
count = 3
The file layout is 0A 00 14 00 1E, leaving a zero byte between each stored value.
Write character data without manual conversions
fid = fopen('greeting.txt', 'w+b');
fwrite(fid, 'RunMat!', 'char');
fclose(fid);
Expected output:
count = 7
Passing text uses the character codes (UTF-16 code units truncated to 8 bits) and writes them sequentially.
Gather GPU data before writing
fid = fopen('gpu.bin', 'w+b');
G = gpuArray([1 2 3 4]);
count = fwrite(fid, G, 'uint16');
fclose(fid);
Expected output when a GPU provider is active:
count = 4
RunMat gathers G to the host before conversion. When no provider is registered, fwrite raises an error
stating that GPU values cannot be gathered.
FAQ
What precisions does fwrite support?
RunMat recognises the commonly used MATLAB precisions: double, single, uint8, int8, uint16, int16,
uint32, int32, uint64, int64, and char, along with their documented aliases (real*8, uchar, etc.).
The precision => output forms are accepted when both sides match; differing output classes are not implemented yet.
How are values converted before writing?
Numeric inputs are converted to the requested precision using MATLAB-style rounding (to the nearest integer) with
saturation to the target range. Logical inputs map true to 1 and false to 0. Character inputs use their Unicode
scalar values.
What does the return value represent?
fwrite returns the number of elements successfully written, not the total number of bytes. Multiply by the element
size when you need to know the byte count.
Does skip insert bytes into the file?
skip seeks forward after each element is written. When the seek lands beyond the current end of file, the OS
creates a sparse region (holes are zero-filled on most platforms). Use skip = 0 (the default) to write densely.
How do machine formats affect the output?
The machine format controls byte ordering for multi-byte precisions. 'native' uses the host endianness, 'ieee-le'
forces little-endian ordering, and 'ieee-be' forces big-endian ordering regardless of the host.
Can I write directly to standard output?
Not yet. File identifiers 0, 1, and 2 (stdin, stdout, stderr) are reserved and raise a descriptive error. Use
fopen to create a file handle before calling fwrite.
Are GPU tensors supported?
Yes. RunMat gathers GPU tensors to host memory before writing. The gather relies on the active provider; if no provider is registered, an informative error is raised.
Do string arrays insert newline characters?
RunMat joins string-array elements using newline ('\n') separators before writing. This mirrors how MATLAB flattens
string arrays to character data for binary I/O.
What happens with NaN or infinite values?
NaN values map to zero for integer precisions and remain NaN for floating-point precisions. Infinite values
saturate to the min/max integer representable by the target precision.
See Also
fopen, fclose, fread, fileread, filewrite
Source & Feedback
- Implementation:
crates/runmat-runtime/src/builtins/io/filetext/fwrite.rs - Found a behavioural mismatch? Open an issue with a minimal reproduction.