Skip to content

Commit

Permalink
slightly improved (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjjkkkjjj committed Feb 9, 2021
1 parent 394d3a4 commit 964c09c
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 53 deletions.
126 changes: 98 additions & 28 deletions Sources/Matft/core/function/binary_operation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,15 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func less(_ l_mfarray: MfArray, _ r_mfarray: MfArray) -> MfArray{
let diff = r_mfarray - l_mfarray
return to_Bool(diff.clip(min: 0, max: nil))
let (l_mfarray, r_mfarray, mftype) = biop_broadcast_to(l_mfarray, r_mfarray)
switch MfType.storedType(mftype) {
case .Float:
return to_Bool_mm_greater(l_mfarray: r_mfarray, r_mfarray: l_mfarray, dummyU: Float.zero)
case .Double:
return to_Bool_mm_greater(l_mfarray: r_mfarray, r_mfarray: l_mfarray, dummyU: Double.zero)
}
//let diff = r_mfarray - l_mfarray
//return to_Bool(diff.clip(min: 0, max: nil))
}
/**
Check left mfarray's elements are less than right scalar in element-wise. Returned mfarray's type will be bool.
Expand All @@ -352,8 +359,14 @@ extension Matft{
- r_scalar: right scalar conformed to MfTypable
*/
public static func less<T: MfTypable>(_ l_mfarray: MfArray, _ r_scalar: T) -> MfArray{
let diff = r_scalar - l_mfarray
return to_Bool(diff.clip(min: 0, max: nil))
switch l_mfarray.storedType {
case .Float:
return to_Bool_ms_less(l_mfarray: l_mfarray, r_scalar: Float.from(r_scalar))
case .Double:
return to_Bool_ms_less(l_mfarray: l_mfarray, r_scalar: Double.from(r_scalar))
}
//let diff = r_scalar - l_mfarray
//return to_Bool(diff.clip(min: 0, max: nil))
}
/**
Check left scalar is less than right mfarray's elements in element-wise. Returned mfarray's type will be bool.
Expand All @@ -362,8 +375,14 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func less<T: MfTypable>(_ l_scalar: T, _ r_mfarray: MfArray) -> MfArray{
let diff = r_mfarray - l_scalar
return to_Bool(diff.clip(min: 0, max: nil))
switch r_mfarray.storedType {
case .Float:
return to_Bool_ms_greater(l_mfarray: r_mfarray, r_scalar: Float.from(l_scalar))
case .Double:
return to_Bool_ms_greater(l_mfarray: r_mfarray, r_scalar: Double.from(l_scalar))
}
//let diff = r_mfarray - l_scalar
//return to_Bool(diff.clip(min: 0, max: nil))
}
/**
Check left mfarray's elements are less equal than right ones in element-wise. Returned mfarray's type will be bool.
Expand All @@ -372,8 +391,15 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func less_equal(_ l_mfarray: MfArray, _ r_mfarray: MfArray) -> MfArray{
let diff = r_mfarray - l_mfarray
return to_Bool(diff.sign() + Float(1))
let (l_mfarray, r_mfarray, mftype) = biop_broadcast_to(l_mfarray, r_mfarray)
switch MfType.storedType(mftype) {
case .Float:
return to_Bool_mm_greater(l_mfarray: l_mfarray, r_mfarray: r_mfarray, dummyU: Float.zero, lesseq: true)
case .Double:
return to_Bool_mm_greater(l_mfarray: l_mfarray, r_mfarray: r_mfarray, dummyU: Double.zero, lesseq: true)
}
//let diff = r_mfarray - l_mfarray
//return to_Bool(diff.sign() + Float(1))
}
/**
Check left mfarray's elements are less equal than right scalar in element-wise. Returned mfarray's type will be bool.
Expand All @@ -382,8 +408,14 @@ extension Matft{
- r_scalar: right scalar conformed to MfTypable
*/
public static func less_equal<T: MfTypable>(_ l_mfarray: MfArray, _ r_scalar: T) -> MfArray{
let diff = r_scalar - l_mfarray
return to_Bool(diff.sign() + Float(1))
switch l_mfarray.storedType {
case .Float:
return to_Bool_ms_less(l_mfarray: l_mfarray, r_scalar: Float.from(r_scalar), greatereq: true)
case .Double:
return to_Bool_ms_less(l_mfarray: l_mfarray, r_scalar: Double.from(r_scalar), greatereq: true)
}
//let diff = r_scalar - l_mfarray
//return to_Bool(diff.sign() + Float(1))
}
/**
Check left scalar is less equal than right mfarray's elements in element-wise. Returned mfarray's type will be bool.
Expand All @@ -392,8 +424,14 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func less_equal<T: MfTypable>(_ l_scalar: T, _ r_mfarray: MfArray) -> MfArray{
let diff = r_mfarray - l_scalar
return to_Bool(diff.sign() + Float(1))
switch r_mfarray.storedType {
case .Float:
return to_Bool_ms_greater(l_mfarray: r_mfarray, r_scalar: Float.from(l_scalar), lesseq: true)
case .Double:
return to_Bool_ms_greater(l_mfarray: r_mfarray, r_scalar: Double.from(l_scalar), lesseq: true)
}
//let diff = r_mfarray - l_scalar
//return to_Bool(diff.sign() + Float(1))
}

/**
Expand All @@ -403,8 +441,15 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func greater(_ l_mfarray: MfArray, _ r_mfarray: MfArray) -> MfArray{
let diff = l_mfarray - r_mfarray
return to_Bool(diff.clip(min: 0, max: nil))
let (l_mfarray, r_mfarray, mftype) = biop_broadcast_to(l_mfarray, r_mfarray)
switch MfType.storedType(mftype) {
case .Float:
return to_Bool_mm_greater(l_mfarray: l_mfarray, r_mfarray: r_mfarray, dummyU: Float.zero)
case .Double:
return to_Bool_mm_greater(l_mfarray: l_mfarray, r_mfarray: r_mfarray, dummyU: Double.zero)
}
//let diff = l_mfarray - r_mfarray
//return to_Bool(diff.clip(min: 0, max: nil))
}
/**
Check left scalar is greater than right mfarray's elements in element-wise. Returned mfarray's type will be bool.
Expand All @@ -413,16 +458,16 @@ extension Matft{
- r_scalar: right scalar conformed to MfTypable
*/
public static func greater<T: MfTypable>(_ l_mfarray: MfArray, _ r_scalar: T) -> MfArray{
/* too slow, average is 0.03s...
switch l_mfarray.storedType {
case .Float:
return to_Bool_ms_op(l_mfarray: l_mfarray, r_scalar: Float.from(r_scalar), op: >)
//return to_Bool_ms_op(mfarray: l_mfarray, scalar: Float.from(r_scalar), op: >) // slower!!!!
return to_Bool_ms_greater(l_mfarray: l_mfarray, r_scalar: Float.from(r_scalar))
case .Double:
return to_Bool_ms_op(l_mfarray: l_mfarray, r_scalar: Double.from(r_scalar), op: >)
return to_Bool_ms_greater(l_mfarray: l_mfarray, r_scalar: Double.from(r_scalar))
}
*/
let diff = l_mfarray - r_scalar
return to_Bool(diff.clip(min: 0, max: nil))

//let diff = l_mfarray - r_scalar
//return to_Bool(diff.clip(min: 0, max: nil))
}
/**
Check left scalar is greater than right mfarray's elements in element-wise. Returned mfarray's type will be bool.
Expand All @@ -431,8 +476,14 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func greater<T: MfTypable>(_ l_scalar: T, _ r_mfarray: MfArray) -> MfArray{
let diff = l_scalar - r_mfarray
return to_Bool(diff.clip(min: 0, max: nil))
switch r_mfarray.storedType {
case .Float:
return to_Bool_ms_less(l_mfarray: r_mfarray, r_scalar: Float.from(l_scalar))
case .Double:
return to_Bool_ms_less(l_mfarray: r_mfarray, r_scalar: Double.from(l_scalar))
}
//let diff = l_scalar - r_mfarray
//return to_Bool(diff.clip(min: 0, max: nil))
}
/**
Check left mfarray's elements are greater equal than right ones in element-wise. Returned mfarray's type will be bool.
Expand All @@ -441,8 +492,15 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func greater_equal(_ l_mfarray: MfArray, _ r_mfarray: MfArray) -> MfArray{
let diff = l_mfarray - r_mfarray
return to_Bool(diff.sign() + Float(1))
let (l_mfarray, r_mfarray, mftype) = biop_broadcast_to(l_mfarray, r_mfarray)
switch MfType.storedType(mftype) {
case .Float:
return to_Bool_mm_greater(l_mfarray: r_mfarray, r_mfarray: l_mfarray, dummyU: Float.zero, lesseq: true)
case .Double:
return to_Bool_mm_greater(l_mfarray: r_mfarray, r_mfarray: l_mfarray, dummyU: Double.zero, lesseq: true)
}
//let diff = l_mfarray - r_mfarray
//return to_Bool(diff.sign() + Float(1))
}
/**
Check left scalar is greater equal than right mfarray's elements in element-wise. Returned mfarray's type will be bool.
Expand All @@ -451,8 +509,14 @@ extension Matft{
- r_scalar: right scalar conformed to MfTypable
*/
public static func greater_equal<T: MfTypable>(_ l_mfarray: MfArray, _ r_scalar: T) -> MfArray{
let diff = l_mfarray - r_scalar
return to_Bool(diff.sign() + Float(1))
switch l_mfarray.storedType {
case .Float:
return to_Bool_ms_less(l_mfarray: l_mfarray, r_scalar: Float.from(r_scalar), greatereq: true)
case .Double:
return to_Bool_ms_less(l_mfarray: l_mfarray, r_scalar: Double.from(r_scalar), greatereq: true)
}
//let diff = l_mfarray - r_scalar
//return to_Bool(diff.sign() + Float(1))
}
/**
Check left scalar is greater equal than right mfarray's elements in element-wise. Returned mfarray's type will be bool.
Expand All @@ -461,8 +525,14 @@ extension Matft{
- r_mfarray: right mfarray
*/
public static func greater_equal<T: MfTypable>(_ l_scalar: T, _ r_mfarray: MfArray) -> MfArray{
let diff = l_scalar - r_mfarray
return to_Bool(diff.sign() + Float(1))
switch r_mfarray.storedType {
case .Float:
return to_Bool_ms_greater(l_mfarray: r_mfarray, r_scalar: Float.from(l_scalar), lesseq: true)
case .Double:
return to_Bool_ms_greater(l_mfarray: r_mfarray, r_scalar: Double.from(l_scalar), lesseq: true)
}
//let diff = l_scalar - r_mfarray
//return to_Bool(diff.sign() + Float(1))
}

/**
Expand Down
120 changes: 97 additions & 23 deletions Sources/Matft/util/common/type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal func to_Bool(_ mfarray: MfArray, thresholdF: Float = 1e-5, thresholdD:
ret.mfdata._mftype = .Bool
return ret
}
/*

internal func to_Bool_mm_op<U: MfStorable>(l_mfarray: MfArray, r_mfarray: MfArray, op: (U, U) -> Bool) -> MfArray{
assert(l_mfarray.shape == r_mfarray.shape, "call biop_broadcast_to first!")
var retShape = l_mfarray.shape
Expand All @@ -47,37 +47,111 @@ internal func to_Bool_mm_op<U: MfStorable>(l_mfarray: MfArray, r_mfarray: MfArra

return MfArray(mfdata: newdata, mfstructure: newmfstructure)
}
internal func to_Bool_ms_op<U: MfStorable>(l_mfarray: MfArray, r_scalar: U, op: (U, U) -> Bool) -> MfArray{
let r_scalar = Float.from(r_scalar)
let ret = l_mfarray.astype(.Float)
ret.withDataUnsafeMBPtrT(datatype: Float.self){
[unowned ret] (dataptr) in
var newptr = dataptr.map{ $0 > r_scalar ? Float.zero : Float(1) }
newptr.withUnsafeMutableBufferPointer{
dataptr.baseAddress!.moveAssign(from: $0.baseAddress!, count: ret.storedSize)
/**
- Important: Note that exchange l_mfarray and r_mfarray when use less
*/
internal func to_Bool_mm_greater<U: MfStorable>(l_mfarray: MfArray, r_mfarray: MfArray, dummyU: U, lesseq: Bool = false) -> MfArray{
assert(l_mfarray.shape == r_mfarray.shape, "call biop_broadcast_to first!")
let l_mfarray = check_contiguous(l_mfarray, .Row)
let r_mfarray = check_contiguous(r_mfarray, .Row)
var retShape = l_mfarray.shape
let retSize = l_mfarray.size
let newdata = withDummyDataMRPtr(.Bool, storedSize: l_mfarray.size){
dstptr in
let dstptrT = dstptr.bindMemory(to: Float.self, capacity: l_mfarray.size)
l_mfarray.withDataUnsafeMBPtrT(datatype: U.self){
lptr in
r_mfarray.withDataUnsafeMBPtrT(datatype: U.self){
rptr in
var newptr = lesseq ? zip(lptr, rptr).map{$0 <= $1 ? Float.zero : Float(1)} : zip(lptr, rptr).map{$0 > $1 ? Float.zero : Float(1)}
newptr.withUnsafeMutableBufferPointer{
dstptrT.moveAssign(from: $0.baseAddress!, count: retSize)
}
}
}

}
ret.mfdata._mftype = .Bool
return ret
let newmfstructure = create_mfstructure(&retShape, mforder: .Row)

return MfArray(mfdata: newdata, mfstructure: newmfstructure)
}
internal func to_Bool_sm_op<U: MfStorable>(l_scalar: U, r_mfarray: MfArray, op: (U, U) -> Bool) -> MfArray{
var retShape = r_mfarray.shape
var i = 0
let newdata = withDummyDataMRPtr(.Bool, storedSize: r_mfarray.size){
// I don't know why this function is 2 times slower than below to_Bool_ms_greater...
internal func to_Bool_ms_op<U: MfStorable>(mfarray: MfArray, scalar: U, op: (U, U) -> Bool) -> MfArray{
let scalar = U.from(scalar)

//let mfarray = check_contiguous(mfarray)
var shape = mfarray.shape
var strides = mfarray.strides

let newdata = withDummyDataMRPtr(.Bool, storedSize: mfarray.storedSize){
dstptr in
let dstptrT = dstptr.bindMemory(to: Float.self, capacity: r_mfarray.size)
r_mfarray.withContiguousDataUnsafeMPtrT(datatype: U.self){
rptr in
var val = op(l_scalar, rptr.pointee) ? Float(1) : Float.zero
(dstptrT + i).assign(from: &val, count: 1)
i += 1
let dstptrT = dstptr.bindMemory(to: Float.self, capacity: mfarray.size)
mfarray.withDataUnsafeMBPtrT(datatype: U.self){
[unowned mfarray](srcptr) in
var newptr = srcptr.map{ op($0, scalar) ? Float.zero : Float(1) }
newptr.withUnsafeMutableBufferPointer{
dstptrT.moveAssign(from: $0.baseAddress!, count: mfarray.storedSize)
}

}
}
let newmfstructure = create_mfstructure(&retShape, mforder: .Row)

let newmfstructure = create_mfstructure(&shape, &strides)
return MfArray(mfdata: newdata, mfstructure: newmfstructure)
}
/**
- Important: if lesseq is true, <=
*/
internal func to_Bool_ms_greater<U: MfStorable>(l_mfarray: MfArray, r_scalar: U, lesseq: Bool = false) -> MfArray{
let scalar = U.from(r_scalar)

//let mfarray = check_contiguous(mfarray)
var shape = l_mfarray.shape
var strides = l_mfarray.strides

let newdata = withDummyDataMRPtr(.Bool, storedSize: l_mfarray.storedSize){
dstptr in
let dstptrT = dstptr.bindMemory(to: Float.self, capacity: l_mfarray.size)
l_mfarray.withDataUnsafeMBPtrT(datatype: U.self){
[unowned l_mfarray](srcptr) in
var newptr = lesseq ? srcptr.map{ $0 <= scalar ? Float.zero : Float(1) } : srcptr.map{ $0 > scalar ? Float.zero : Float(1) }
newptr.withUnsafeMutableBufferPointer{
dstptrT.moveAssign(from: $0.baseAddress!, count: mfarray.storedSize)
}

}
}

let newmfstructure = create_mfstructure(&shape, &strides)
return MfArray(mfdata: newdata, mfstructure: newmfstructure)
}
*/
/**
- Important: if greatereq is true, >=
*/
internal func to_Bool_ms_less<U: MfStorable>(l_mfarray: MfArray, r_scalar: U, greatereq: Bool = false) -> MfArray{
let scalar = U.from(r_scalar)

//let mfarray = check_contiguous(mfarray)
var shape = l_mfarray.shape
var strides = l_mfarray.strides

let newdata = withDummyDataMRPtr(.Bool, storedSize: l_mfarray.storedSize){
dstptr in
let dstptrT = dstptr.bindMemory(to: Float.self, capacity: l_mfarray.size)
l_mfarray.withDataUnsafeMBPtrT(datatype: U.self){
[unowned l_mfarray](srcptr) in
var newptr = greatereq ? srcptr.map{ $0 >= scalar ? Float.zero : Float(1) } : srcptr.map{ $0 < scalar ? Float.zero : Float(1) }
newptr.withUnsafeMutableBufferPointer{
dstptrT.moveAssign(from: $0.baseAddress!, count: mfarray.storedSize)
}

}
}

let newmfstructure = create_mfstructure(&shape, &strides)
return MfArray(mfdata: newdata, mfstructure: newmfstructure)
}

/**
- Important: this function creates copy bool mfarray, not view!
*/
Expand Down
19 changes: 17 additions & 2 deletions Tests/PerformanceTests/IndexingPefTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,23 @@ final class IndexingPefTests: XCTestCase {
let _ = a[a>0]
}
/*
'-[PerformanceTests.IndexingPefTests testPeformanceBooleanIndexing1]' measured [Time, seconds] average: 0.005, relative standard deviation: 37.720%, values: [0.010294, 0.004666, 0.004402, 0.004150, 0.004102, 0.004048, 0.004186, 0.004013, 0.004319, 0.004240]
4.84ms
'-[PerformanceTests.IndexingPefTests testPeformanceBooleanIndexing1]' measured [Time, seconds] average: 0.004, relative standard deviation: 50.409%, values: [0.008761, 0.003488, 0.002775, 0.002847, 0.002846, 0.002844, 0.002943, 0.002825, 0.002906, 0.002772]
3.50ms
*/
}
}

func testPeformanceBooleanIndexing2() {
do{
let a = Matft.arange(start: -10*10*10*10*10*5, to: 10*10*10*10*10*5, by: 1, shape: [10,10,10,10,10,10])
let b = Matft.arange(start: 10*10*10*10*10*10, to: -10*10*10*10*10*10, by: -2, shape: [10,10,10,10,10,10])

self.measure {
let _ = a[a>b]
}
/*
'-[PerformanceTests.IndexingPefTests testPeformanceBooleanIndexing2]' measured [Time, seconds] average: 0.007, relative standard deviation: 23.077%, values: [0.010261, 0.006136, 0.006031, 0.005470, 0.005826, 0.005804, 0.005430, 0.005504, 0.005319, 0.005328]
6.11ms
*/
}
}
Expand Down

0 comments on commit 964c09c

Please sign in to comment.