mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 22:02:58 -06:00
139 lines
4.9 KiB
C++
139 lines
4.9 KiB
C++
#include <Core/Core.h>
|
|
|
|
using namespace Upp;
|
|
|
|
#include <arrayfire.h>
|
|
|
|
using namespace af;
|
|
|
|
|
|
static array A, B;
|
|
|
|
static array dist_naive(array a, array b) {
|
|
array dist_mat = constant(0, a.dims(1), b.dims(1));
|
|
|
|
for (int ii = 0; ii < a.dims(1); ii++) // Iterate through columns a
|
|
for (int jj = 0; jj < b.dims(1); jj++) // Iterate through columns of b
|
|
for (int kk = 0; kk < a.dims(0); kk++) // Get the sum of absolute differences
|
|
dist_mat(ii, jj) += abs(a(kk, ii) - b(kk, jj));
|
|
|
|
return dist_mat;
|
|
}
|
|
|
|
static array dist_vec(array a, array b) {
|
|
array dist_mat = constant(0, a.dims(1), b.dims(1));
|
|
|
|
for (int ii = 0; ii < a.dims(1); ii++) { // Iterate through columns a
|
|
array avec = a(span, ii);
|
|
|
|
for (int jj = 0; jj < b.dims(1); jj++) { // Iterate through columns of b
|
|
array bvec = b(span, jj);
|
|
|
|
dist_mat(ii, jj) = sum(abs(avec - bvec));// Get SAD using sum on the vector
|
|
}
|
|
}
|
|
return dist_mat;
|
|
}
|
|
|
|
static array dist_gfor1(array a, array b) {
|
|
array dist_mat = constant(0, a.dims(1), b.dims(1));
|
|
|
|
gfor (seq ii, a.dims(1)) { // GFOR along columns of a
|
|
array avec = a(span, ii);
|
|
|
|
for (int jj = 0; jj < b.dims(1); jj++) { // Itere through columns of b
|
|
array bvec = b(span, jj);
|
|
|
|
dist_mat(ii, jj) = sum(abs(avec - bvec));// Get SAD using sum on the vector
|
|
}
|
|
}
|
|
return dist_mat;
|
|
}
|
|
|
|
static array dist_gfor2(array a, array b) {
|
|
array dist_mat = constant(0, a.dims(1), b.dims(1));
|
|
|
|
gfor (seq jj, b.dims(1)) { // GFOR along columns of b
|
|
array bvec = b(span, jj);
|
|
|
|
for (int ii = 0; ii < a.dims(1); ii++) { // Iterate through columns of A
|
|
array avec = a(span, ii);
|
|
|
|
dist_mat(ii, jj) = sum(abs(avec - bvec));// Get SAD using sum on the vector
|
|
}
|
|
}
|
|
return dist_mat;
|
|
}
|
|
|
|
static array dist_tile1(array a, array b) {
|
|
int alen = a.dims(1);
|
|
int blen = b.dims(1);
|
|
|
|
array dist_mat = constant(0, alen, blen);
|
|
|
|
for (int jj = 0; jj < blen; jj++) { // Iterate through columns of b
|
|
// Get the column vector of b
|
|
array bvec = b(span, jj); // shape of bvec is (feat_len, 1)
|
|
// Tile avec to be same size as a
|
|
array bvec_tiled = tile(bvec, 1, alen); // shape of bvec_tiled is (feat_len, alen)
|
|
|
|
array sad = sum(abs(bvec_tiled - a)); // Get the sum of absolute differences
|
|
|
|
// sad is row vector, dist_mat needs column vector
|
|
dist_mat(span, jj) = sad.T(); // transpose sad and fill in dist_mat
|
|
}
|
|
return dist_mat;
|
|
}
|
|
|
|
static array dist_tile2(array a, array b) {
|
|
int feat_len = a.dims(0);
|
|
int alen = a.dims(1);
|
|
int blen = b.dims(1);
|
|
|
|
array a_mod = a; // Shape of a is (feat_len, alen, 1)
|
|
|
|
array b_mod = moddims(b, feat_len, 1, blen); // Reshape b from (feat_len, blen) to (feat_len, 1, blen)
|
|
|
|
array a_tiled = tile(a_mod, 1, 1, blen); // Tile both matrices to be (feat_len, alen, blen)
|
|
array b_tiled = tile(b_mod, 1, alen, 1);
|
|
// Do The sum operation along first dimension
|
|
array dist_mod = sum(abs(a_tiled - b_tiled)); // Output is of shape (1, alen, blen)
|
|
|
|
array dist_mat = moddims(dist_mod, alen, blen); // Reshape dist_mat from (1, alen, blen) to (alen, blen)
|
|
return dist_mat;
|
|
}
|
|
|
|
static void bench_naive() {dist_naive(A, B);}
|
|
static void bench_vec() {dist_vec(A, B);}
|
|
static void bench_gfor1() {dist_gfor1(A, B);}
|
|
static void bench_gfor2() {dist_gfor2(A, B);}
|
|
static void bench_tile1() {dist_tile1(A, B);}
|
|
static void bench_tile2() {dist_tile2(A, B);}
|
|
|
|
void Vectorize_Bench() {
|
|
printf("\nVectorize demo:");
|
|
// Do not increase the sizes
|
|
// dist_naive and dist_vec get too slow at large sizes
|
|
A = randu(3, 200);
|
|
B = randu(3, 300);
|
|
|
|
array d1 = dist_naive(A, B);
|
|
array d2 = dist_vec (A, B);
|
|
array d3 = dist_gfor1(A, B);
|
|
array d4 = dist_gfor2(A, B);
|
|
array d5 = dist_tile1(A, B);
|
|
array d6 = dist_tile2(A, B);
|
|
|
|
printf("\nMax. Error for dist_vec : %f", max<float>(abs(d1 - d2)));
|
|
printf("\nMax. Error for dist_gfor1: %f", max<float>(abs(d1 - d3)));
|
|
printf("\nMax. Error for dist_gfor2: %f", max<float>(abs(d1 - d4)));
|
|
printf("\nMax. Error for dist_tile1: %f", max<float>(abs(d1 - d5)));
|
|
printf("\nMax. Error for dist_tile2: %f", max<float>(abs(d1 - d6)));
|
|
printf("\n");
|
|
printf("\nTime for dist_naive: %2.2fms", 1000 * timeit(bench_naive));
|
|
printf("\nTime for dist_vec : %2.2fms", 1000 * timeit(bench_vec ));
|
|
printf("\nTime for dist_gfor1: %2.2fms", 1000 * timeit(bench_gfor1));
|
|
printf("\nTime for dist_gfor2: %2.2fms", 1000 * timeit(bench_gfor2));
|
|
printf("\nTime for dist_tile1: %2.2fms", 1000 * timeit(bench_tile1));
|
|
printf("\nTime for dist_tile2: %2.2fms", 1000 * timeit(bench_tile2));
|
|
}
|