2016-10-05 4 views
1

私が取り組んでいるプロジェクトのために、私はそれほど型消しを扱っていません。それは、ここに私の地獄を迷惑をかける1つの方法があり、私は別の解決策を思いついています。私は多くの行列乗算を使用するプロジェクトに取り組んでいます。ネイティブblas操作にはfommilのnetlib-javaを使用しています。ここで問題になっている方法です:特に、コレクションをJavaメソッドに渡す場合、コレクションの型削除を回避するより良い方法はありますか?

def gemm[A: ClassTag: TypeTag](
    transA : String, 
    transB : String, 
    m  : Int, 
    n  : Int, 
    k  : Int, 
    alpha : A, 
    a  : Array[A], 
    b  : Array[A], 
    beta : A) = { 

    val lda = if (transA == "N" || transA == "n") k else m 
    val ldb = if (transB == "N" || transA == "n") n else k 

    typeOf[A] match { 
     case t if t =:= typeOf[Float] => 
     val _alpha = alpha.asInstanceOf[Float] 
     val _beta = beta.asInstanceOf[Float] 
     val _a = a.asInstanceOf[Array[Float]] 
     val _b = b.asInstanceOf[Array[Float]] 
     val outArray = new Array[Float](m * n) 
     blas.sgemm(transA, transB, m, n, k, _alpha, _a, lda, _b, ldb, _beta, outArray, m) 
     outArray.asInstanceOf[Array[A]] 
     case t if t =:= typeOf[Double] => 
     val _alpha = alpha.asInstanceOf[Double] 
     val _beta = beta.asInstanceOf[Double] 
     val _a = a.asInstanceOf[Array[Double]] 
     val _b = b.asInstanceOf[Array[Double]] 
     val outArray = new Array[Double](m * n) 
     blas.dgemm(transA, transB, m, n, k, _alpha, _a, lda, _b, ldb, _beta, outArray, m) 
     outArray.asInstanceOf[Array[A]] 
     case _ => 
     val outArray = Predef.implicitly[ClassTag[A]].newArray(m * n) 
     gemm_ref(transA, transB, m, n, k, alpha, a, b, beta, outArray) 
     outArray 
    } 
    } 

私が考えられてきた代替は型崩れTypeable/Typecaseとの安全なキャストを入力しています。私の理解から、これは型統一性を保証するためにコレクションの各要素を調べることによって機能します。これに関連するオーバーヘッドがあります。多くの場合、多くの要素を持つ配列を扱っているため、追加のオーバーヘッドは探していません。

答えて

2

どのようにこのような何かについては?

trait Blas[A] { 
    def gemm(transA: String, transB: String, m: Int, n: Int, k: Int, alpha: A, beta: A, a: Array[A], b: Array[A]): Array[A] 
} 

object Blas { 
    implicit def floatBlas: Blas[Float] = new Blas[Float] { 
    override def gemm(transA: String, transB: String, m: Int, n: Int, k: Int, alpha: Float, beta: Float, a: Array[Float], b: Array[Float]): Array[Float] = { 
     val outArray = new Array[Float](m * n) 
     blas.sgemm(transA, transB, m, n, k, _alpha, _a, lda, _b, ldb, _beta, outArray, m) 
     outArray 
    } 
    } 

    implicit def doubleBlas: Blas[Double] = ??? 

    // etc. 
} 

def gemm[A](
    transA: String, 
    transB: String, 
    m: Int, 
    n: Int, 
    k: Int, 
    alpha: A, 
    a: Array[A], 
    b: Array[A], 
    beta: A 
)(implicit blas: Blas[A]) = { 

    val lda = if (transA == "N" || transA == "n") k else m 
    val ldb = if (transB == "N" || transA == "n") n else k 

    blas.gemm(transA, transB, m, n, k, alpha, a, lda, b, ldb, beta, m) 

} 

(あなたがオブジェクトとメソッド名を自分で修正する必要があります、私は彼らが参照しているのか分からない。)

アイデアは、ルックアップ、あなたは追加の暗黙のパラメータを渡すことです自動的に起動します。これらのインスタンスを定義する際には、利用可能な完全な型情報があるので、typeOfと照合する必要はありません。

関連する問題