#include <visp3/core/vpConfig.h>
#if defined(VISP_HAVE_CATCH2)
#include <catch_amalgamated.hpp>
#include <visp3/core/vpMatrix.h>
#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
#include <opencv2/core.hpp>
#endif
#ifdef VISP_HAVE_EIGEN3
#include <Eigen/Dense>
#endif
#ifdef ENABLE_VISP_NAMESPACE
#endif
namespace
{
bool g_runBenchmark = false;
int g_tileSize = 16;
vpMatrix generateMatrix(
unsigned int sz1,
unsigned int sz2)
{
for (
unsigned int i = 0; i < M.
getRows(); i++) {
for (
unsigned int j = 0; j < M.
getCols(); j++) {
}
}
return M;
}
vpMatrix generateMatrixTranspose(
unsigned int sz1,
unsigned int sz2)
{
for (
unsigned int j = 0; j < M.
getCols(); j++) {
for (
unsigned int i = 0; i < M.
getRows(); i++) {
}
}
return M;
}
{
for (
unsigned int i = 0; i < A.
getRows(); i++) {
double *coli = A[i];
for (
unsigned int j = 0; j < A.
getCols(); j++) {
At[j][i] = coli[j];
}
}
return At;
}
{
for (
unsigned int j = 0; j < A.
getCols(); j++) {
double *coli = At[j];
for (
unsigned int i = 0; i < A.
getRows(); i++) {
coli[i] = A[i][j];
}
}
return At;
}
{
for (
unsigned int i = 0; i < A.
getRows(); i += tileSize) {
for (
unsigned int j = 0; j < A.
getCols(); j++) {
for (
unsigned int b = 0; b < tileSize && i + b < A.
getRows(); b++) {
At[j][i + b] = A[i + b][j];
}
}
}
return At;
}
{
const int nrows =
static_cast<int>(A.
getRows());
const int ncols =
static_cast<int>(A.
getCols());
for (int i = 0; i < nrows;) {
for (; i <= nrows - tileSize; i += tileSize) {
int j = 0;
for (; j <= ncols - tileSize; j += tileSize) {
for (int k = i; k < i + tileSize; k++) {
for (int l = j; l < j + tileSize; l++) {
At[l][k] = A[k][l];
}
}
}
for (int k = i; k < i + tileSize; k++) {
for (int l = j; l < ncols; l++) {
At[l][k] = A[k][l];
}
}
}
for (; i < nrows; i++) {
for (int j = 0; j < ncols; j++) {
At[j][i] = A[i][j];
}
}
}
return At;
}
}
TEST_CASE("Benchmark vpMatrix transpose", "[benchmark]")
{
if (g_runBenchmark) {
const std::vector<std::pair<int, int> > sizes = {
{701, 1503}, {1791, 837}, {1201, 1201}, {1024, 1024}, {2000, 2000}, {10, 6}, {25, 6}, {100, 6}, {200, 6},
{500, 6}, {1000, 6}, {1500, 6}, {2000, 6}, {6, 10}, {6, 25}, {6, 100}, {6, 200}, {6, 500},
{6, 1000}, {6, 1500}, {6, 2000}, {640, 1000}, {800, 640}, {640, 500}, {500, 640}, {640, 837} };
for (auto sz : sizes) {
vpMatrix M = generateMatrix(sz.first, sz.second);
vpMatrix Mt_true = generateMatrixTranspose(sz.first, sz.second);
std::ostringstream oss;
oss << sz.first << "x" << sz.second;
oss << " - M.t()";
BENCHMARK(oss.str().c_str())
{
REQUIRE(Mt == Mt_true);
return Mt;
};
oss.str("");
oss << sz.first << "x" << sz.second;
oss << " - transposeIterateSrc(M)";
BENCHMARK(oss.str().c_str())
{
REQUIRE(Mt == Mt_true);
return Mt;
};
oss.str("");
oss << sz.first << "x" << sz.second;
oss << " - transposeIterateDst(M)";
BENCHMARK(oss.str().c_str())
{
REQUIRE(Mt == Mt_true);
return Mt;
};
oss.str("");
oss << sz.first << "x" << sz.second;
oss << " - transposeTilingSO(M, tileSize=" << g_tileSize << ")";
BENCHMARK(oss.str().c_str())
{
vpMatrix Mt = transposeTilingSO(M, g_tileSize);
REQUIRE(Mt == Mt_true);
return Mt;
};
oss.str("");
oss << sz.first << "x" << sz.second;
oss << " - transposeTiling(M, tileSize=" << g_tileSize << ")";
BENCHMARK(oss.str().c_str())
{
vpMatrix Mt = transposeTiling(M, g_tileSize);
REQUIRE(Mt == Mt_true);
return Mt;
};
#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
cv::Mat matM(sz.first, sz.second, CV_64FC1);
for (
unsigned int i = 0; i < M.
getRows(); i++) {
for (
unsigned int j = 0; j < M.
getCols(); j++) {
matM.at<double>(i, j) = M[i][j];
}
}
oss.str("");
oss << sz.first << "x" << sz.second;
oss << " - OpenCV";
BENCHMARK(oss.str().c_str())
{
cv::Mat matMt = matM.t();
return matMt;
};
#endif
#ifdef VISP_HAVE_EIGEN3
Eigen::MatrixXd eigenM(sz.first, sz.second);
for (
unsigned int i = 0; i < M.
getRows(); i++) {
for (
unsigned int j = 0; j < M.
getCols(); j++) {
eigenM(i, j) = M[i][j];
}
}
oss.str("");
oss << sz.first << "x" << sz.second;
oss << " - Eigen";
BENCHMARK(oss.str().c_str())
{
Eigen::MatrixXd eigenMt = eigenM.
transpose();
return eigenMt;
};
#endif
}
}
else {
vpMatrix Mt_true = generateMatrixTranspose(11, 17);
REQUIRE(Mt == Mt_true);
}
}
int main(int argc, char *argv[])
{
Catch::Session session;
auto cli = session.cli()
| Catch::Clara::Opt(g_runBenchmark)["--benchmark"]("run benchmark?")
| Catch::Clara::Opt(g_tileSize, "tileSize")["--tileSize"]("Tile size?");
session.cli(cli);
session.applyCommandLine(argc, argv);
int numFailed = session.run();
return numFailed;
}
#else
#include <iostream>
int main() { return EXIT_SUCCESS; }
#endif
unsigned int getCols() const
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
unsigned int getRows() const
Implementation of a matrix and operations on matrices.
vpMatrix transpose() const