|
@@ -0,0 +1,284 @@
|
|
|
+/*##############################################################################
|
|
|
+
|
|
|
+ HPCC SYSTEMS software Copyright (C) 2016 HPCC Systems®.
|
|
|
+
|
|
|
+ Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+ you may not use this file except in compliance with the License.
|
|
|
+ You may obtain a copy of the License at
|
|
|
+
|
|
|
+ http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+
|
|
|
+ Unless required by applicable law or agreed to in writing, software
|
|
|
+ distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+ See the License for the specific language governing permissions and
|
|
|
+ limitations under the License.
|
|
|
+############################################################################## */
|
|
|
+IMPORT lib_eclblas AS LIB_ECLBLAS;
|
|
|
+
|
|
|
+EXPORT BLAS := MODULE
|
|
|
+ // Types for the Block Basic Linear Algebra Sub-programs support
|
|
|
+ EXPORT Types := MODULE
|
|
|
+ EXPORT value_t := LIB_ECLBLAS.blas_value_t; //REAL8;
|
|
|
+ EXPORT dimension_t := LIB_ECLBLAS.blas_dimension_t; //UNSIGNED4;
|
|
|
+ EXPORT matrix_t := LIB_ECLBLAS.blas_matrix_t; //SET OF REAL8
|
|
|
+ EXPORT Triangle := LIB_ECLBLAS.blas_Triangle; //ENUM(UNSIGNED1, Upper=1, Lower=2)
|
|
|
+ EXPORT Diagonal := LIB_ECLBLAS.blas_Diagonal; //ENUM(UNSIGNED1, UnitTri=1, NotUnitTri=2)
|
|
|
+ EXPORT Side := LIB_ECLBLAS.blas_Side; //ENUM(UNSIGNED1, Ax=1, xA=2)
|
|
|
+ END;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Function prototype for Apply2Cell.
|
|
|
+ * @param v the value
|
|
|
+ * @param r the row ordinal
|
|
|
+ * @param c the column ordinal
|
|
|
+ * @return the updated value
|
|
|
+ */
|
|
|
+ EXPORT Types.value_t ICellFunc(Types.value_t v,
|
|
|
+ Types.dimension_t r,
|
|
|
+ Types.dimension_t c) := v;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Iterate matrix and apply function to each cell
|
|
|
+ *@param m number of rows
|
|
|
+ *@param n number of columns
|
|
|
+ *@param x matrix
|
|
|
+ *@param f function to apply
|
|
|
+ *@return updated matrix
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t Apply2Cells(Types.dimension_t m,
|
|
|
+ Types.dimension_t n,
|
|
|
+ Types.matrix_t x,
|
|
|
+ ICellFunc f) := FUNCTION
|
|
|
+ Cell := {Types.value_t v};
|
|
|
+ Cell applyFunc(Cell v, UNSIGNED pos) := TRANSFORM
|
|
|
+ r := ((pos-1) % m) + 1;
|
|
|
+ c := ((pos-1) DIV m) + 1;
|
|
|
+ SELF.v := f(v.v, r, c);
|
|
|
+ END;
|
|
|
+ dIn := DATASET(x, Cell);
|
|
|
+ dOut := PROJECT(dIn, applyFunc(LEFT, COUNTER));
|
|
|
+ RETURN SET(dOut, v);
|
|
|
+ END;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Absolute sum, the 1 norm of a vector.
|
|
|
+ *@param m the number of entries
|
|
|
+ *@param x the column major matrix holding the vector
|
|
|
+ *@param incx the increment for x, 1 in the case of an actual vector
|
|
|
+ *@param skipped default is zero, the number of entries stepped over
|
|
|
+ * to get to the first entry
|
|
|
+ *@return the sum of the absolute values
|
|
|
+ */
|
|
|
+ EXPORT Types.value_t
|
|
|
+ dasum(Types.dimension_t m, Types.matrix_t x,
|
|
|
+ Types.dimension_t incx, Types.dimension_t skipped=0)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.dasum(m, x, incx, skipped);
|
|
|
+
|
|
|
+/**
|
|
|
+ * alpha*X + Y
|
|
|
+ * @param N number of elements in vector
|
|
|
+ * @param alpha the scalar multiplier
|
|
|
+ * @param X the column major matrix holding the vector X
|
|
|
+ * @param incX the increment or stride for the vector
|
|
|
+ * @param Y the column major matrix holding the vector Y
|
|
|
+ * @param incY the increment or stride of Y
|
|
|
+ * @param x_skipped number of entries skipped to get to the first X
|
|
|
+ * @param y_skipped number of entries skipped to get to the first Y
|
|
|
+ * @return the updated matrix
|
|
|
+ */
|
|
|
+EXPORT Types.matrix_t
|
|
|
+ daxpy(Types.dimension_t N, Types.value_t alpha, Types.matrix_t X,
|
|
|
+ Types.dimension_t incX, Types.matrix_t Y, Types.dimension_t incY,
|
|
|
+ Types.dimension_t x_skipped=0, Types.dimension_t y_skipped=0)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.daxpy(N, alpha, X, incX, Y, incY, x_skipped, y_skipped);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * alpha*op(A) op(B) + beta*C where op() is transpose
|
|
|
+ * @param transposeA true when transpose of A is used
|
|
|
+ * @param transposeB true when transpose of B is used
|
|
|
+ * @param M number of rows in product
|
|
|
+ * @param N number of columns in product
|
|
|
+ * @param K number of columns/rows for the multiplier/multiplicand
|
|
|
+ * @param alpha scalar used on A
|
|
|
+ * @param A matrix A
|
|
|
+ * @param B matrix B
|
|
|
+ * @param beta scalar for matrix C
|
|
|
+ * @param C matrix C or empty
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ dgemm(BOOLEAN transposeA, BOOLEAN transposeB,
|
|
|
+ Types.dimension_t M, Types.dimension_t N, Types.dimension_t K,
|
|
|
+ Types.value_t alpha, Types.matrix_t A, Types.matrix_t B,
|
|
|
+ Types.value_t beta=0.0, Types.matrix_t C=[])
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.dgemm(transposeA, transposeB, M, N, K, alpha, A, B, beta, C);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Compute LU Factorization of matrix A.
|
|
|
+ * @param m number of rows of A
|
|
|
+ * @param n number of columns of A
|
|
|
+ * @return composite matrix of factors, lower triangle has an
|
|
|
+ * implied diagonal of ones. Upper triangle has the diagonal of the
|
|
|
+ * composite.
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ dgetf2(Types.dimension_t m, Types.dimension_t n, Types.matrix_t a)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.dgetf2(m, n, a);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * DPOTF2 computes the Cholesky factorization of a real symmetric
|
|
|
+ * positive definite matrix A.
|
|
|
+ *The factorization has the form
|
|
|
+ * A = U**T * U , if UPLO = 'U', or
|
|
|
+ * A = L * L**T, if UPLO = 'L',
|
|
|
+ * where U is an upper triangular matrix and L is lower triangular.
|
|
|
+ * This is the unblocked version of the algorithm, calling Level 2 BLAS.
|
|
|
+ * @param tri indocate whether upper or lower triangle is used
|
|
|
+ * @param r number of rows/columns in the square matrix
|
|
|
+ * @param A the square matrix
|
|
|
+ * @param clear clears the unused triangle
|
|
|
+ * @return the triangular matrix requested.
|
|
|
+ */
|
|
|
+
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ dpotf2(Types.Triangle tri, Types.dimension_t r, Types.matrix_t A,
|
|
|
+ BOOLEAN clear=TRUE)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.dpotf2(tri, r, A, clear);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Scale a vector alpha
|
|
|
+ * @param N number of elements in the vector
|
|
|
+ * @param alpha the scaling factor
|
|
|
+ * @param X the column major matrix holding the vector
|
|
|
+ * @param incX the stride to get to the next element in the vector
|
|
|
+ * @param skipped the number of elements skipped to get to the first element
|
|
|
+ * @return the updated matrix
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ dscal(Types.dimension_t N, Types.value_t alpha, Types.matrix_t X,
|
|
|
+ Types.dimension_t incX, Types.dimension_t skipped=0)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.dscal(N, alpha, X, incX, skipped);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Implements symmetric rank update C <- alpha A**T A + beta C or
|
|
|
+ * c <- alpha A A**T + beta C. C is N x N.
|
|
|
+ * @param tri update upper or lower triangle
|
|
|
+ * @param transposeA Transpose the A matrix to be NxK
|
|
|
+ * @param N number of rows
|
|
|
+ * @param K number of columns in the update matrix or transpose
|
|
|
+ * @param alpha the alpha scalar
|
|
|
+ * @param A the update matrix, either NxK or KxN
|
|
|
+ * @param beta the beta scalar
|
|
|
+ * @param C the matrix to update
|
|
|
+ * @param clear clear the triangle that is not updated. BLAS assumes
|
|
|
+ * that symmetric matrices have only one of the triangles and this
|
|
|
+ * option lets you make that true.
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ dsyrk(Types.Triangle tri, BOOLEAN transposeA,
|
|
|
+ Types.dimension_t N, Types.dimension_t K,
|
|
|
+ Types.value_t alpha, Types.matrix_t A,
|
|
|
+ Types.value_t beta, Types.matrix_t C, BOOLEAN clear=FALSE)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.dsyrk(tri, transposeA, N, K, alpha, A, beta, C, clear);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triangular matrix solver. op(A) X = alpha B or X op(A) = alpha B
|
|
|
+ * where op is Transpose, X and B is MxN
|
|
|
+ * @param side side for A, Side.Ax is op(A) X = alpha B
|
|
|
+ * @param tri Says whether A is Upper or Lower triangle
|
|
|
+ * @param transposeA is op(A) the transpose of A
|
|
|
+ * @param diag is the diagonal an implied unit diagonal or supplied
|
|
|
+ * @param M number of rows
|
|
|
+ * @param N number of columns
|
|
|
+ * @param lda the leading dimension of the A matrix, either M or N
|
|
|
+ * @param alpha the scalar multiplier for B
|
|
|
+ * @param A a triangular matrix
|
|
|
+ * @param B the matrix of values for the solve
|
|
|
+ * @return the matrix of coefficients to get B.
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ dtrsm(Types.Side side, Types.Triangle tri,
|
|
|
+ BOOLEAN transposeA, Types.Diagonal diag,
|
|
|
+ Types.dimension_t M, Types.dimension_t N, Types.dimension_t lda,
|
|
|
+ Types.value_t alpha, Types.matrix_t A, Types.matrix_t B)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.dtrsm(side, tri, transposeA, diag, M, N, lda, alpha, A, B);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Extract the diagonal of he matrix
|
|
|
+ * @param m number of rows
|
|
|
+ * @param n number of columns
|
|
|
+ * @param x matrix from which to extract the diagonal
|
|
|
+ * @return diagonal matrix
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t extract_diag(Types.dimension_t m,
|
|
|
+ Types.dimension_t n,
|
|
|
+ Types.matrix_t x) := FUNCTION
|
|
|
+ cell := {Types.value_t v};
|
|
|
+ cell ext(cell v, UNSIGNED pos) := TRANSFORM
|
|
|
+ r := ((pos-1) % m) + 1;
|
|
|
+ c := ((pos-1) DIV m) + 1;
|
|
|
+ SELF.v := IF(r=c AND r<=m AND c<=n, v.v, SKIP);
|
|
|
+ END;
|
|
|
+ diag := SET(PROJECT(DATASET(x, cell), ext(LEFT, COUNTER)), v);
|
|
|
+ RETURN diag;
|
|
|
+ END;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Extract the upper or lower triangle. Diagonal can be actual or implied
|
|
|
+ * unit diagonal.
|
|
|
+ * @param m number of rows
|
|
|
+ * @param n number of columns
|
|
|
+ * @param tri Upper or Lower specifier, Triangle.Lower or Triangle.Upper
|
|
|
+ * @param dt Use Diagonal.NotUnitTri or Diagonal.UnitTri
|
|
|
+ * @param a Matrix, usually a composite from factoring
|
|
|
+ * @return the triangle
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ Extract_Tri(Types.dimension_t m, Types.dimension_t n,
|
|
|
+ Types.Triangle tri, Types.Diagonal dt,
|
|
|
+ Types.matrix_t a)
|
|
|
+ := LIB_ECLBLAS.ECLBLAS.Extract_Tri(m, n, tri, dt, a);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Generate a diagonal matrix.
|
|
|
+ * @param m number of diagonal entries
|
|
|
+ * @param v option value, defaults to 1
|
|
|
+ * @param X optional input of diagonal values, multiplied by v.
|
|
|
+ * @return a diagonal matrix
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ make_diag(Types.dimension_t m, Types.value_t v=1.0,
|
|
|
+ Types.matrix_t X=[]) := LIB_ECLBLAS.ECLBLAS.make_diag(m, v, X);
|
|
|
+
|
|
|
+ // make_vec helpers
|
|
|
+ Cell := RECORD
|
|
|
+ Types.value_t v;
|
|
|
+ END;
|
|
|
+ Cell makeCell(Types.value_t v) := TRANSFORM
|
|
|
+ SELF.v := v;
|
|
|
+ END;
|
|
|
+ vec_dataset(Types.dimension_t m, Types.value_t v) := DATASET(m, makeCell(v));
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Make a vector of dimension m
|
|
|
+ * @param m number of elements
|
|
|
+ * @param v the values, defaults to 1
|
|
|
+ * @return the vector
|
|
|
+ */
|
|
|
+ EXPORT Types.matrix_t
|
|
|
+ make_vector(Types.dimension_t m,
|
|
|
+ Types.value_t v=1.0) := SET(vec_dataset(m, v), v);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The trace of the input matrix
|
|
|
+ * @param m number of rows
|
|
|
+ * @param n number of columns
|
|
|
+ * @param x the matrix
|
|
|
+ * @return the trace (sum of the diagonal entries)
|
|
|
+ */
|
|
|
+ EXPORT Types.value_t
|
|
|
+ trace(Types.dimension_t m,
|
|
|
+ Types.dimension_t n,
|
|
|
+ Types.matrix_t x)
|
|
|
+ := SUM(extract_diag(m,n,x));
|
|
|
+END;
|