Skip to content

Instantly share code, notes, and snippets.

@codelynx
Last active April 14, 2020 15:23
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codelynx/eeaeeda00828568aaf577c0341964c38 to your computer and use it in GitHub Desktop.
Save codelynx/eeaeeda00828568aaf577c0341964c38 to your computer and use it in GitHub Desktop.
Utility type to handle Half Precision Float Type (16 bit float) in swift 3.0
//
// Float16.swift
// ZKit
//
// The MIT License (MIT)
//
// Copyright (c) 2016 Electricwoods LLC, Kaz Yoshikawa.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Foundation
import Accelerate
struct Float16: CustomStringConvertible {
var rawValue: UInt16
static func float_to_float16(value: Float) -> UInt16 {
var input: [Float] = [value]
var output: [UInt16] = [0]
var sourceBuffer = vImage_Buffer(data: &input, height: 1, width: 1, rowBytes: MemoryLayout<Float>.size)
var destinationBuffer = vImage_Buffer(data: &output, height: 1, width: 1, rowBytes: MemoryLayout<UInt16>.size)
vImageConvert_PlanarFtoPlanar16F(&sourceBuffer, &destinationBuffer, 0)
return output[0]
}
static func float16_to_float(value: UInt16) -> Float {
var input: [UInt16] = [value]
var output: [Float] = [0]
var sourceBuffer = vImage_Buffer(data: &input, height: 1, width: 1, rowBytes: MemoryLayout<UInt16>.size)
var destinationBuffer = vImage_Buffer(data: &output, height: 1, width: 1, rowBytes: MemoryLayout<Float>.size)
vImageConvert_Planar16FtoPlanarF(&sourceBuffer, &destinationBuffer, 0)
return output[0]
}
static func floats_to_float16s(values: [Float]) -> [UInt16] {
var inputs = values
var outputs = Array<UInt16>(repeating: 0, count: values.count)
let width = vImagePixelCount(values.count)
var sourceBuffer = vImage_Buffer(data: &inputs, height: 1, width: width, rowBytes: MemoryLayout<Float>.size * values.count)
var destinationBuffer = vImage_Buffer(data: &outputs, height: 1, width: width, rowBytes: MemoryLayout<UInt16>.size * values.count)
vImageConvert_PlanarFtoPlanar16F(&sourceBuffer, &destinationBuffer, 0)
return outputs
}
static func float16s_to_floats(values: [UInt16]) -> [Float] {
var inputs: [UInt16] = values
var outputs: [Float] = Array<Float>(repeating: 0, count: values.count)
let width = vImagePixelCount(values.count)
var sourceBuffer = vImage_Buffer(data: &inputs, height: 1, width: width, rowBytes: MemoryLayout<UInt16>.size * values.count)
var destinationBuffer = vImage_Buffer(data: &outputs, height: 1, width: width, rowBytes: MemoryLayout<Float>.size * values.count)
vImageConvert_Planar16FtoPlanarF(&sourceBuffer, &destinationBuffer, 0)
return outputs
}
init(_ value: Float) {
self.rawValue = Float16.float_to_float16(value: value)
}
var floatValue: Float {
return Float16.float16_to_float(value: self.rawValue)
}
var description: String {
return self.floatValue.description
}
static func + (lhs: Float16, rhs: Float16) -> Float16 {
return Float16(lhs.floatValue + rhs.floatValue)
}
static func - (lhs: Float16, rhs: Float16) -> Float16 {
return Float16(lhs.floatValue - rhs.floatValue)
}
static func * (lhs: Float16, rhs: Float16) -> Float16 {
return Float16(lhs.floatValue * rhs.floatValue)
}
static func / (lhs: Float16, rhs: Float16) -> Float16 {
return Float16(lhs.floatValue / rhs.floatValue)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment