root/trunk/ProjectFortress/c/blas.c

Revision 2624, 10.3 KB (checked in by mspiegel, 16 months ago)

[blas] Initial attempt at linking against Sun Performance Library on Solaris. Doesn't work, but doesn't break other platform configurations.

Line 
1#include "com_sun_fortress_numerics_Blas.h"
2
3#include <jni.h>
4
5#if defined(OSX)
6#include <Accelerate/Accelerate.h>
7
8#elif defined(SUNOS)
9#include <sunperf.h> 
10
11#else
12#include <cblas.h>
13
14#endif
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20static double oneVectorFunction( JNIEnv * env, jint length,
21                               jdoubleArray vector1, jint stride1, jint offset1,
22                               double (*cblas)() ){
23
24    double ret = 0;
25    int i;
26    jboolean copy;
27    // jdouble * convertedVector1 = (*env)->GetDoubleArrayElements(env, vector1, &copy);
28    jdouble * convertedVector1 = (*env)->GetPrimitiveArrayCritical(env, vector1, &copy);
29
30    /* for debugging, if you want
31       printf( "length is %d\n", length );
32       for ( i = 0; i < length; i++ ){
33       printf( "vector1 [%d] %f\n", i, convertedVector1[i] );
34       printf( "vector2 [%d] %f\n", i, convertedVector2[i] );
35       }
36       */
37
38    ret = (*cblas)( length, convertedVector1 + offset1, stride1 );
39    // (*env)->ReleaseDoubleArrayElements(env, vector1, convertedVector1, 0 );
40    (*env)->ReleasePrimitiveArrayCritical(env, vector1, convertedVector1, 0 );
41    return ret;
42
43}
44
45static double oneVectorAlphaVoidFunction( JNIEnv * env, jint length, jdouble alpha,
46                                          jdoubleArray vector1, jint stride1, jint offset1,
47                                          void (*cblas)() ){
48
49    double ret = 0;
50    int i;
51    // jdouble * convertedVector1 = (*env)->GetDoubleArrayElements(env, vector1, 0);
52    jdouble * convertedVector1 = (*env)->GetPrimitiveArrayCritical(env, vector1, 0);
53
54    /* for debugging, if you want
55       printf( "length is %d\n", length );
56       for ( i = 0; i < length; i++ ){
57       printf( "vector1 [%d] %f\n", i, convertedVector1[i] );
58       printf( "vector2 [%d] %f\n", i, convertedVector2[i] );
59       }
60       */
61
62    (*cblas)( length, alpha, convertedVector1 + offset1, stride1 );
63    // (*env)->ReleaseDoubleArrayElements(env, vector1, convertedVector1, 0 );
64    (*env)->ReleasePrimitiveArrayCritical(env, vector1, convertedVector1, 0 );
65}
66
67static void twoVectorVoidFunction( JNIEnv * env, jint length,
68                               jdoubleArray vector1, jint stride1, jint offset1,
69                               jdoubleArray vector2, jint stride2, jint offset2,
70                               void (*cblas)() ){
71
72    int i;
73    // jdouble * convertedVector1 = (*env)->GetDoubleArrayElements(env, vector1, 0);
74    jdouble * convertedVector1 = (*env)->GetPrimitiveArrayCritical(env, vector1, 0);
75    // jdouble * convertedVector2 = (*env)->GetDoubleArrayElements(env, vector2, 0);
76    jdouble * convertedVector2 = (*env)->GetPrimitiveArrayCritical(env, vector2, 0);
77
78    /* for debugging, if you want
79       printf( "length is %d\n", length );
80       for ( i = 0; i < length; i++ ){
81       printf( "vector1 [%d] %f\n", i, convertedVector1[i] );
82       printf( "vector2 [%d] %f\n", i, convertedVector2[i] );
83       }
84       */
85
86    (*cblas)( length, convertedVector1 + offset1, stride1, convertedVector2 + offset2, stride2 );
87    // (*env)->ReleaseDoubleArrayElements(env, vector1, convertedVector1, 0 );
88    (*env)->ReleasePrimitiveArrayCritical(env, vector1, convertedVector1, 0 );
89    // (*env)->ReleaseDoubleArrayElements(env, vector2, convertedVector2, 0 );
90    (*env)->ReleasePrimitiveArrayCritical(env, vector2, convertedVector2, 0 );
91}
92
93static double twoVectorFunction( JNIEnv * env, jint length,
94                               jdoubleArray vector1, jint stride1, jint offset1,
95                               jdoubleArray vector2, jint stride2, jint offset2,
96                               double (*cblas)() ){
97
98    double ret = 0;
99    int i;
100    // jdouble * convertedVector1 = (*env)->GetDoubleArrayElements(env, vector1, 0);
101    jdouble * convertedVector1 = (*env)->GetPrimitiveArrayCritical(env, vector1, 0);
102    // jdouble * convertedVector2 = (*env)->GetDoubleArrayElements(env, vector2, 0);
103    jdouble * convertedVector2 = (*env)->GetPrimitiveArrayCritical(env, vector2, 0);
104
105    /* for debugging, if you want
106       printf( "length is %d\n", length );
107       for ( i = 0; i < length; i++ ){
108       printf( "vector1 [%d] %f\n", i, convertedVector1[i] );
109       printf( "vector2 [%d] %f\n", i, convertedVector2[i] );
110       }
111       */
112
113    ret = (*cblas)( length, convertedVector1 + offset1, stride1, convertedVector2 + offset2, stride2 );
114    // (*env)->ReleaseDoubleArrayElements(env, vector1, convertedVector1, 0 );
115    (*env)->ReleasePrimitiveArrayCritical(env, vector1, convertedVector1, 0 );
116    // (*env)->ReleaseDoubleArrayElements(env, vector2, convertedVector2, 0 );
117    (*env)->ReleasePrimitiveArrayCritical(env, vector2, convertedVector2, 0 );
118    return ret;
119
120}
121
122static void twoVectorAlphaVoidFunction( JNIEnv * env, jint length, jdouble alpha,
123                                    jdoubleArray vector1, jint stride1, jint offset1,
124                                    jdoubleArray vector2, jint stride2, jint offset2,
125                                    void (*cblas)() ){
126
127    int i;
128    // jdouble * convertedVector1 = (*env)->GetDoubleArrayElements(env, vector1, 0);
129    jdouble * convertedVector1 = (*env)->GetPrimitiveArrayCritical(env, vector1, 0);
130    // jdouble * convertedVector2 = (*env)->GetDoubleArrayElements(env, vector2, 0);
131    jdouble * convertedVector2 = (*env)->GetPrimitiveArrayCritical(env, vector2, 0);
132
133    /* for debugging, if you want
134       printf( "length is %d\n", length );
135       for ( i = 0; i < length; i++ ){
136       printf( "vector1 [%d] %f\n", i, convertedVector1[i] );
137       printf( "vector2 [%d] %f\n", i, convertedVector2[i] );
138       }
139       */
140
141    (*cblas)( length, alpha, convertedVector1 + offset1, stride1, convertedVector2 + offset2, stride2 );
142    // (*env)->ReleaseDoubleArrayElements(env, vector1, convertedVector1, 0 );
143    // (*env)->ReleaseDoubleArrayElements(env, vector2, convertedVector2, 0 );
144   
145    (*env)->ReleasePrimitiveArrayCritical(env, vector1, convertedVector1, 0 );
146    (*env)->ReleasePrimitiveArrayCritical(env, vector2, convertedVector2, 0 );
147}
148
149/*
150 * Class:     com_sun_fortress_numerics_Blas
151 * Method:    dotProduct
152 * Signature: ([D[D)D
153 */
154JNIEXPORT jdouble JNICALL Java_com_sun_fortress_numerics_Blas_dotProduct
155  (JNIEnv * env, jclass class_, jint length, jdoubleArray vector1, jint stride1, jint offset1, jdoubleArray vector2, jint stride2, jint offset2 ){
156
157      return twoVectorFunction( env, length, vector1, stride1, offset1, vector2, stride2, offset2, cblas_ddot );
158
159}
160
161JNIEXPORT jdouble JNICALL Java_com_sun_fortress_numerics_Blas_norm
162  (JNIEnv * env, jclass class_, jint length, jdoubleArray vector1, jint stride1, jint offset1 ){
163      return oneVectorFunction( env, length, vector1, stride1, offset1, cblas_dnrm2 );
164}
165
166JNIEXPORT void JNICALL Java_com_sun_fortress_numerics_Blas_internal_1add
167  (JNIEnv * env, jclass class_, jint length, jdouble alpha, jdoubleArray vector1, jint stride1, jint offset1, jdoubleArray vector2, jint stride2, jint offset2 ){
168      twoVectorAlphaVoidFunction( env, length, alpha, vector1, stride1, offset1, vector2, stride2, offset2, cblas_daxpy );
169}
170
171JNIEXPORT void JNICALL Java_com_sun_fortress_numerics_Blas_internal_1dcopy
172  (JNIEnv * env, jclass class_, jint length, jdoubleArray vector1, jint stride1, jint offset1, jdoubleArray vector2, jint stride2, jint offset2){
173      twoVectorVoidFunction( env, length, vector1, stride1, offset1, vector2, stride2, offset2, cblas_dcopy );
174}
175
176JNIEXPORT void JNICALL Java_com_sun_fortress_numerics_Blas_internal_1scale
177  (JNIEnv * env, jclass class_, jint length, jdouble alpha, jdoubleArray vector, jint stride, jint offset){
178      oneVectorAlphaVoidFunction( env, length, alpha, vector, stride, offset, cblas_dscal );
179}
180
181
182JNIEXPORT void JNICALL Java_com_sun_fortress_numerics_Blas_internal_1vectorMatrixMultiply
183  (JNIEnv * env, jclass class_, jint order, jint transpose, jint m, jint n, jdouble alpha, jdoubleArray matrix, jint matrixStride, jint matrixOffset, jdoubleArray vector, jint stride, jint offset, jdouble beta, jdoubleArray result, jint resultStride, jint resultOffset){
184
185
186      // jdouble * convertedMatrix = (*env)->GetDoubleArrayElements(env, matrix, 0);
187      // jdouble * convertedVector = (*env)->GetDoubleArrayElements(env, vector, 0);
188      // jdouble * convertedResult = (*env)->GetDoubleArrayElements(env, result, 0);
189     
190      jdouble * convertedMatrix = (*env)->GetPrimitiveArrayCritical(env, matrix, 0);
191      jdouble * convertedVector = (*env)->GetPrimitiveArrayCritical(env, vector, 0);
192      jdouble * convertedResult = (*env)->GetPrimitiveArrayCritical(env, result, 0);
193
194      cblas_dgemv( order, transpose, m, n, alpha,
195                   convertedMatrix + matrixOffset, matrixStride,
196                   convertedVector + offset, stride, beta,
197                   convertedResult + resultOffset, resultStride );
198
199      // (*env)->ReleaseDoubleArrayElements(env, matrix, convertedMatrix, 0 );
200      // (*env)->ReleaseDoubleArrayElements(env, vector, convertedVector, 0 );
201      // (*env)->ReleaseDoubleArrayElements(env, result, convertedResult, 0 );
202     
203      (*env)->ReleasePrimitiveArrayCritical(env, matrix, convertedMatrix, 0 );
204      (*env)->ReleasePrimitiveArrayCritical(env, vector, convertedVector, 0 );
205      (*env)->ReleasePrimitiveArrayCritical(env, result, convertedResult, 0 );
206}
207
208JNIEXPORT void JNICALL Java_com_sun_fortress_numerics_Blas_internal_1matrixMatrixMultiply
209  (JNIEnv * env, jclass class_, jint order, jint transpose1, jint transpose2, jint m, jint n, jint k, jdouble alpha, jdoubleArray matrix1, jint matrix1Stride, jint matrix1Offset, jdoubleArray matrix2, jint matrix2Stride, jint matrix2Offset, jdouble beta, jdoubleArray resultMatrix, jint resultStride, jint resultOffset){
210     
211      jdouble * convertedMatrix1 = (*env)->GetPrimitiveArrayCritical(env, matrix1, 0);
212      jdouble * convertedMatrix2 = (*env)->GetPrimitiveArrayCritical(env, matrix2, 0);
213      jdouble * convertedResult = (*env)->GetPrimitiveArrayCritical(env, resultMatrix, 0);
214
215      cblas_dgemm( order, transpose1, transpose2, m, n, k, alpha, convertedMatrix1 + matrix1Offset, matrix1Stride, convertedMatrix2 + matrix2Offset, matrix2Stride, beta, convertedResult + resultOffset, resultStride );
216     
217      (*env)->ReleasePrimitiveArrayCritical(env, matrix1, convertedMatrix1, 0 );
218      (*env)->ReleasePrimitiveArrayCritical(env, matrix2, convertedMatrix2, 0 );
219      (*env)->ReleasePrimitiveArrayCritical(env, resultMatrix, convertedResult, 0 );
220}
221   
222#ifdef __cplusplus
223}
224#endif
Note: See TracBrowser for help on using the browser.