Xcode
iOS
Swift
coreML

MLMultiArrayを使うと謎の位置でBAD_ACCESS

MLMultiArrayとは

iOSアプリ上でTensorflowやTheano(Keras)、Caffeなどで出力したモデルを利用して予測等の計算が可能になるcoreMLという枠組みの中でモデルへの入力や出力に利用する型がMLMultiArrayになります。
ちょっと特殊な配列、くらいの認識でそこまで乖離は無いと思います。

※ 以下の話は Xcode9.3 / Swift4 で経験した話なので今後改善される可能性もあります。

普通の配列の場合

let arr = [Double](repeating: 0.0, count: 5)
arr[10] = 1.0

もちろんですが、このコードはコンパイルは通っても実行時に2行目でIndex out of rangeで落ちます。
文字通り長さが5の配列で10番目を参照しているからです。普通はここまで愚直なミスは犯しませんが、2行目の配列のインデックスを外部から持ってきた変数等を利用している場合、想定した範囲を超えることはあり得ると思います。ただ、デバッグ時にこのようなエラーが起きれば原因もすぐ分かりますね。

MLMultiArrayの場合

let mlarr = try! MLMultiArray(shape: [5], dataType: .double)
mlarr[10] = 1.0

こちらも配列とほぼ同様に長さ5のMLMultiArrayを定義して存在しないIndexに値を代入しようとしています。
がしかし、なんと実行時に2行目でエラーになりません。では、よしなに動いてくれているのかというとそうでもなく全然関係ない行でBAD_ACCESSと言われて落ちます。しかも毎回微妙に違う箇所で落ちます。なので初見だと一切原因がつかめないと思います。

※ 私の場合 } else { とだけ書いた行でBAD ACCESSと言われ本当に意味がわからず悩みました…

結局原因が分かればIndexの取り方にミスがあっただけなんですが、この事実を知らないと見つけるのに相当苦労しました。

結論

MLMultiArrayを利用する時によくわからないエラーに遭遇したらMLMultiArrayをそっくりそのまま普通の配列に置き換えてみると原因の追求がしやすいです。

ぼやき

MLMultiArrayに限らずなんですが、coreML系の資料って日本語英語に限らず全然見つからないですね…
公式のドキュメントもリファレンス程度には見れますが、チュートリアル以上の事をしようと思うととたんに手探り感が出てきます。
coreMLの良い情報ソースをご存知の方いたら共有してほしいです。