Skip to content

Instantly share code, notes, and snippets.

@horitaku1124
Last active July 21, 2019 13:05
Show Gist options
  • Save horitaku1124/8f2b09179e95f1f6ae8026faa22af473 to your computer and use it in GitHub Desktop.
Save horitaku1124/8f2b09179e95f1f6ae8026faa22af473 to your computer and use it in GitHub Desktop.
// Save as "HelloJNI.c"
#include <jni.h> // JNI header provided by JDK
#include <stdio.h> // C Standard IO Header
#include <math.h>
#include <immintrin.h>
#include "HelloJNI.h" // Generated
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff
(JNIEnv * env, jobject jObj, jfloatArray array1, jint len1, jfloatArray array2) {
jboolean ji1,ji2;
float * floatArray1 = (*env)->GetFloatArrayElements(env, (jfloatArray)array1, &ji1);
float * floatArray2 = (*env)->GetFloatArrayElements(env, (jfloatArray)array2, &ji2);
float mean1 = 0.0;
float mean2 = 0.0;
for (int i = 0;i < len1;i++) {
mean1 += floatArray1[i];
}
mean1 = mean1 / len1;
for (int i = 0;i < len1;i++) {
mean2 += floatArray2[i];
}
mean2 = mean2 / len1;
// printf("mean1 = %.16f\n", mean1);
// printf("mean2 = %.16f\n", mean2);
float devmul = 0.0;
for (int i = 0;i < len1;i++) {
devmul += (floatArray1[i] - mean1) * (floatArray2[i] - mean2);
}
float covar = devmul / len1;
// printf("devmul = %.16f\n", devmul);
// printf("covar = %.16f\n", covar);
float stdevp1 = 0.0;
for (int i = 0;i < len1;i++) {
float m = floatArray1[i] - mean1;
stdevp1 += m * m;
}
stdevp1 = sqrt(stdevp1 / len1);
float stdevp2 = 0.0;
for (int i = 0;i < len1;i++) {
float m = floatArray2[i] - mean2;
stdevp2 += m * m;
}
stdevp2 = sqrt(stdevp2 / len1);
(*env)->ReleaseFloatArrayElements(env, (jfloatArray)array1, floatArray1, 0);
(*env)->ReleaseFloatArrayElements(env, (jfloatArray)array2, floatArray2, 0);
// printf("stdevp1 = %.16f\n", stdevp1);
// printf("stdevp2 = %.16f\n", stdevp2);
return covar / stdevp1 / stdevp2;
}
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff2
(JNIEnv * env, jobject jObj, jfloatArray array1, jint len1, jfloatArray array2) {
jboolean ji1,ji2;
float * floatArray1 = (*env)->GetFloatArrayElements(env, (jfloatArray)array1, &ji1);
float * floatArray2 = (*env)->GetFloatArrayElements(env, (jfloatArray)array2, &ji2);
float __attribute__((aligned(32))) out[8] = {};
__m256 sum0;
// mean1
sum0 = _mm256_setzero_ps();
for (int i = 0;i < len1;i += 8) {
__m256 v0 = _mm256_loadu_ps(&floatArray1[i]);
sum0 = _mm256_add_ps(v0 , sum0);
}
_mm256_store_ps(out, sum0);
float mean1 = 0.0;
for (int i = 0;i < 8;i++) {
mean1 += out[i];
}
mean1 = mean1 / len1;
// printf("mean1 = %.16f\n", mean1);
// mean2
sum0 = _mm256_setzero_ps();
for (int i = 0;i < len1;i += 8) {
__m256 v0 = _mm256_loadu_ps(&floatArray2[i]);
sum0 = _mm256_add_ps(v0 , sum0);
}
_mm256_store_ps(out, sum0);
float mean2 = 0.0;
for (int i = 0;i < 8;i++) {
mean2 += out[i];
}
mean2 = mean2 / len1;
// printf("mean2 = %.16f\n", mean2);
// devmul
sum0 = _mm256_setzero_ps();
__m256 mm_mean1 = _mm256_broadcast_ss(&mean1);
__m256 mm_mean2 = _mm256_broadcast_ss(&mean2);
for (int i = 0;i < len1;i += 8) {
__m256 v0 = _mm256_loadu_ps(&floatArray1[i]);
__m256 v1 = _mm256_loadu_ps(&floatArray2[i]);
v0 = _mm256_sub_ps(v0, mm_mean1);
v1 = _mm256_sub_ps(v1, mm_mean2);
// v0 = _mm256_mul_ps(v0 , v1);
// sum0 = _mm256_add_ps(v0 , sum0);
sum0 = _mm256_fmadd_ps(v0, v1, sum0);
}
_mm256_store_ps(out, sum0);
float devmul = 0.0;
for (int i = 0;i < 8;i++) {
devmul += out[i];
}
float covar = devmul / len1;
// printf("devmul = %.16f\n", devmul);
// printf("covar = %.16f\n", covar);
// stdevp1
sum0 = _mm256_setzero_ps();
for (int i = 0;i < len1;i += 8) {
__m256 v0 = _mm256_loadu_ps(&floatArray1[i]);
v0 = _mm256_sub_ps(v0 , mm_mean1);
// v0 = _mm256_mul_ps(v0 , v0);
// sum0 = _mm256_add_ps(v0 , sum0);
sum0 = _mm256_fmadd_ps(v0, v0, sum0);
}
_mm256_store_ps(out, sum0);
float stdevp1 = 0.0;
for (int i = 0;i < 8;i++) {
stdevp1 += out[i];
}
stdevp1 = sqrt(stdevp1 / len1);
// printf("stdevp1 = %.16f\n", stdevp1);
// stdevp2
sum0 = _mm256_setzero_ps();
for (int i = 0;i < len1;i += 8) {
__m256 v0 = _mm256_loadu_ps(&floatArray2[i]);
v0 = _mm256_sub_ps(v0 , mm_mean2);
// v0 = _mm256_mul_ps(v0 , v0);
// sum0 = _mm256_add_ps(v0 , sum0);
sum0 = _mm256_fmadd_ps(v0, v0, sum0);
}
_mm256_store_ps(out, sum0);
float stdevp2 = 0.0;
for (int i = 0;i < 8;i++) {
stdevp2 += out[i];
}
stdevp2 = sqrt(stdevp2 / len1);
// printf("stdevp2 = %.16f\n", stdevp2);
return covar / stdevp1 / stdevp2;
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: calcCoff
* Signature: ([FI[F)F
*/
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff
(JNIEnv *, jobject, jfloatArray, jint, jfloatArray);
/*
* Class: HelloJNI
* Method: calcCoff2
* Signature: ([FI[F)F
*/
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff2
(JNIEnv *, jobject, jfloatArray, jint, jfloatArray);
#ifdef __cplusplus
}
#endif
#endif
public class HelloJNI {
static {
System.loadLibrary("hello");
}
public native float calcCoff(float[] array1, int len1, float[] array2);
public native float calcCoff2(float[] array1, int len1, float[] array2);
}
import kotlin.math.sqrt
class MyArray {
companion object {
/**
* 相加平均
*/
fun mean(array1: List<Float>): Float {
var sum = 0f
array1.forEach {
sum += it
}
return sum / array1.size
}
fun mean(array1: FloatArray): Float {
var sum = 0f
array1.forEach {
sum += it
}
return sum / array1.size
}
/**
* 偏差平方和
*/
fun devsq(array1: List<Float>): Float {
val mean = mean(array1)
var d = 0f
array1.forEach {
d += (it - mean) * (it - mean)
}
return d
}
/**
* 標準偏差
*/
fun stdevp(array1: List<Float>): Float {
return sqrt(devsq(array1) / array1.size)
}
/**
* 偏差積和
*/
fun devmulOf(array1: List<Float>, array2: List<Float>): Float {
val mean1 = mean(array1)
val mean2 = mean(array2)
var mul = 0f
for (i in 0 until array1.size) {
mul += (array1[i] - mean1) * (array2[i] - mean2)
}
return mul
}
/**
* 共分散
*/
fun covarOf(array1: List<Float>, array2: List<Float>): Float {
return devmulOf(array1, array2) / array1.size
}
/**
* 相関係数
*/
fun correlOf(array1: List<Float>, array2: List<Float>): Float {
return covarOf(array1, array2) / stdevp(array1) / stdevp(array2)
}
/**
* 相関係数
*/
fun correlOf2(array1: FloatArray, array2: FloatArray): Float {
val mean1 = mean(array1)
val mean2 = mean(array2)
val devmul = {
var mul = 0f
for (i in 0 until array1.size) {
mul += (array1[i] - mean1) * (array2[i] - mean2)
}
mul
}()
val covar = devmul / array1.size
val stdevp1 = {
var devsq = 0f
array1.forEach {
var m = (it - mean1)
devsq += m * m
}
sqrt(devsq / array1.size)
}()
val stdevp2 = {
var devsq = 0f
array2.forEach {
var m = (it - mean2)
devsq += m * m
}
sqrt(devsq / array2.size)
}()
return covar / stdevp1 / stdevp2
}
}
}
import java.util.List;
import static java.lang.Math.sqrt;
public class MyArrayD {
/**
* 相加平均
*/
public static double mean(List<Double> array1) {
var sum = 0f;
for (double f: array1) {
sum += f;
}
return sum / array1.size();
}
/**
* 偏差平方和
*/
public static double devsq(List<Double> array1) {
var mean = mean(array1);
var d = 0f;
for (double f: array1) {
d += (f - mean) * (f - mean);
}
return d;
}
/**
* 標準偏差
*/
public static double stdevp(List<Double> array1) {
return sqrt(devsq(array1) / array1.size());
}
/**
* 偏差積和
*/
public static double devmulOf(List<Double> array1, List<Double> array2) {
var mean1 = mean(array1);
var mean2 = mean(array2);
var mul = 0f;
for (var i = 0;i < array1.size();i++) {
mul += (array1.get(i) - mean1) * (array2.get(i) - mean2);
}
return mul;
}
/**
* 共分散
*/
public static double covarOf(List<Double> array1, List<Double> array2) {
return devmulOf(array1, array2) / array1.size();
}
/**
* 相関係数
*/
public static double correlOf(List<Double> array1, List<Double> array2) {
return covarOf(array1, array2) / stdevp(array1) / stdevp(array2);
}
}
import java.util.List;
import static java.lang.Math.sqrt;
public class MyArrayF {
/**
* 相加平均
*/
public static float mean(List<Float> array1) {
var sum = 0f;
for (float f: array1) {
sum += f;
}
return sum / array1.size();
}
/**
* 偏差平方和
*/
public static float devsq(List<Float> array1) {
var mean = mean(array1);
var d = 0f;
for (float f: array1) {
d += (f - mean) * (f - mean);
}
return d;
}
/**
* 標準偏差
*/
public static float stdevp(List<Float> array1) {
return (float) sqrt(devsq(array1) / array1.size());
}
/**
* 偏差積和
*/
public static float devmulOf(List<Float> array1, List<Float> array2) {
var mean1 = mean(array1);
var mean2 = mean(array2);
var mul = 0f;
for (var i = 0;i < array1.size();i++) {
mul += (array1.get(i) - mean1) * (array2.get(i) - mean2);
}
return mul;
}
/**
* 共分散
*/
public static float covarOf(List<Float> array1, List<Float> array2) {
return devmulOf(array1, array2) / array1.size();
}
/**
* 相関係数
*/
public static float correlOf(List<Float> array1, List<Float> array2) {
return covarOf(array1, array2) / stdevp(array1) / stdevp(array2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment