Skip to content

Conversation

@asadjan4611
Copy link

Why?

This PR implements bfloat16 (Brain Float 16) and bfloat16_array support for Fory Python runtime and codegen, addressing issue #3289. This enables using bfloat16 in FDL to reduce payload size while keeping a wide exponent range, which is common in ML/AI workflows.

What does this PR do?

This PR adds comprehensive bfloat16 support to Fory Python:

Core Implementation

  • BFloat16 Type: Cython implementation with IEEE 754 compliant float32↔bfloat16 conversions (round-to-nearest, ties-to-even)
  • BFloat16Array: Python-visible array type backed by array.array('H') for packed contiguous storage
  • Serializers: Both scalar (BFloat16Serializer) and array (BFloat16ArraySerializer) serializers
  • Type Registration: Registered with TypeId.BFLOAT16 (18) and TypeId.BFLOAT16_ARRAY (54)

Integration Points

  • Buffer Operations: Added write_bfloat16() and read_bfloat16() methods
  • Codegen Support: Added bfloat16 to codegen type mapping
  • Row Format: Added bfloat16() factory function (temporarily maps to float16 until C++ row format supports it)
  • Type System: Fully integrated into Fory type resolver

Testing

  • 11 comprehensive test cases covering:
    • Basic operations and conversions
    • Special values (NaN, ±Inf, ±0)
    • Serialization round-trips
    • Array operations
    • Integration with dataclasses, lists, and maps
    • Type registration verification

Code Quality

  • Follows existing float16 implementation patterns
  • Matches project code standards and style
  • All files include proper Apache 2.0 license headers
  • No linter errors

Related issues

Does this PR introduce any user-facing change?

  • Does this PR introduce any public API change?
    • Yes: Adds BFloat16, BFloat16Array types and bfloat16() factory function
  • Does this PR introduce any binary protocol compatibility change?
    • No: Uses existing TypeId.BFLOAT16 (18) already defined in protocol spec

Implementation Details

Wire Format

  • Encodes bfloat16 as 2 bytes representing raw IEEE 754 bfloat16 bit pattern
  • Little endian byte order (matches existing float32/float64 behavior)
  • NaN/Inf/±0/subnormal values round-trip correctly at bit level

Type System

  • Type ID: 18 (BFLOAT16) - already defined in xlang serialization spec
  • Array Type ID: 54 (BFLOAT16_ARRAY)
  • Protocol compliant with existing xlang serialization format

Performance

  • Uses Cython for performance-critical conversion operations
  • Zero-copy array operations using array.array('H')
  • Follows same optimization patterns as existing float16 implementation

- Add BFloat16 Cython type with IEEE 754 compliant conversions
- Add BFloat16Array class backed by array.array('H')
- Implement serializers for scalar and array types
- Register types in type resolver (TypeId.BFLOAT16 = 18, TypeId.BFLOAT16_ARRAY = 54)
- Add buffer read/write methods for bfloat16
- Add codegen support for bfloat16
- Add row format support (with temporary float16 mapping until C++ support)
- Add comprehensive test suite with 11 test cases covering all edge cases
- Follow existing float16 implementation patterns

Fixes apache#3289
- Change single quotes to double quotes (ruff format requirement)
- Remove trailing whitespace
- Add blank lines after imports (PEP 8)
- Remove unused import (pyfory)
- Fix closing parenthesis alignment
- Remove invalid Cython type casts (<BFloat16>) in serialization.pyx and primitive.pxi
- Use isinstance() check instead of type casting for Python classes
- Fix bfloat16() function to use float16() as temporary workaround until C++ support is added
- Comment out bfloat16() declaration in libformat.pxd with TODO for future C++ implementation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Python] add bfloat16 and bfloat16_array (Cython, no numpy)

1 participant