Skip to content

Create random tensors #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions include/tensor.cuh
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include <random>
#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
#include <iomanip>
Expand Down Expand Up @@ -28,6 +31,41 @@
#define TEMPLATE_CONSTRAINT_REQUIRES_FPX
#endif

std::random_device RND_DEVICE;


/**
* Generate vector of random elements
* @tparam T
* @param n
* @param low
* @param hi
* @return
*/
TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
std::vector<T> generateRealRandomVector(size_t n, T low, T hi) {
std::mt19937_64 mersenne_engine(RND_DEVICE());
std::uniform_real_distribution<T> dist(low, hi);
auto gen = [&dist, &mersenne_engine]() {
return dist(mersenne_engine);
};
std::vector<T> vec(n);
generate(begin(vec), end(vec), gen);
return vec;
}

std::vector<int> generateIntRandomVector(size_t n, int low, int hi) {
std::mt19937_64 mersenne_engine(RND_DEVICE());
std::uniform_int_distribution dist(low, hi);
auto gen = [&dist, &mersenne_engine]() {
return dist(mersenne_engine);
};
std::vector<int> vec(n);
generate(begin(vec), end(vec), gen);
return vec;
}

/**
* Determines the number of blocks needed for a given number of tasks, n,
* and number of threads per block
Expand Down Expand Up @@ -188,6 +226,17 @@ private:
std::ostream &print(std::ostream &out) const;

public:

/**
* Create a tensor with random elements
* @param numRows
* @param numCols
* @param numMats
* @param low
* @param hi
*/
static DTensor<T> createRandomTensor(size_t numRows, size_t numCols, size_t numMats, T low, T hi);

/**
* Constructs a DTensor object.
*/
Expand Down Expand Up @@ -398,6 +447,19 @@ public:

}; /* END OF DTENSOR */

template<typename T>
DTensor<T> DTensor<T>::createRandomTensor(size_t numRows, size_t numCols, size_t numMats, T low, T hi) {
if constexpr (std::is_floating_point<T>::value) {
auto randVec = generateRealRandomVector(numRows * numCols * numMats, low, hi);
DTensor<T> a(randVec, numRows, numCols, numMats);
return a;
} else if constexpr (std::is_same_v<T, int>) {
auto randVec = generateIntRandomVector(numRows * numCols * numMats, low, hi);
DTensor<T> a(randVec, numRows, numCols, numMats);
return a;
}
}

template<typename T>
void DTensor<T>::reshape(size_t newNumRows, size_t newNumCols, size_t newNumMats) {
size_t newNumElements = newNumRows * newNumCols * newNumMats;
Expand Down
75 changes: 42 additions & 33 deletions test/testTensor.cu
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,27 @@ TEST_F(TensorTest, tensorConstructionStorageMode) {
tensorConstructionStorageMode<int>();
}

/* ---------------------------------------
* Create random tensors
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
void randomTensorCreation() {
// 20 x 40 x 60-tensor; elements drawn from U[-1, 1]
auto r = DTensor<T>::createRandomTensor(20, 40, 60, -1, 1);
EXPECT_EQ(20, r.numRows());
EXPECT_EQ(40, r.numCols());
EXPECT_EQ(60, r.numMats());
auto rEle = r(19, 39, 59);
EXPECT_TRUE(rEle >= -1 && rEle <= 1);
}

TEST_F(TensorTest, randomTensorCreation) {
randomTensorCreation<float>();
randomTensorCreation<double>();
randomTensorCreation<int>();
}

/* ---------------------------------------
* Move constructor
* --------------------------------------- */
Expand Down Expand Up @@ -672,8 +693,7 @@ protected:
* and matrix rank
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void singularValuesComputation(float epsilon) {
std::vector<T> bData = {1, 6, 6, 6, 6, 6, 6, 6,
2, 7, 7, 7, 7, 7, 7, 7,
Expand All @@ -699,8 +719,7 @@ TEST_F(SvdTest, singularValuesComputation) {
* Singular values - memory mgmt
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void singularValuesMemory(float epsilon) {
std::vector<T> bData = {1, 6, 6, 6, 6, 6, 6, 6,
2, 7, 7, 7, 7, 7, 7, 7,
Expand Down Expand Up @@ -731,8 +750,7 @@ TEST_F(SvdTest, singularValuesMemory) {
/* ---------------------------------------
* SVD with multiple matrices
* --------------------------------------- */
TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void singularValuesMultipleMatrices(float epsilon) {
std::vector<T> aData = {1, 2, 3, 4, 5, 6, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 1};
DTensor<T> A(aData, 3, 2, 3);
Expand All @@ -753,15 +771,15 @@ void singularValuesMultipleMatrices(float epsilon) {
S.download(actual_s);
for (size_t i = 0; i < 6; i++) EXPECT_NEAR(expected_s[i], actual_s[i], epsilon);
std::vector<T> expected_u = {
-0.428667133548626, -0.566306918848035, -0.703946704147444,
0.805963908589298, 0.112382414096594, -0.581199080396110,
0.408248290463863, -0.816496580927726, 0.408248290463863,
-0.577350269189626, -0.577350269189626, -0.577350269189626,
0.816496580927726, -0.408248290463863, -0.408248290463863,
0.000000000000000, -0.707106781186548, 0.707106781186547,
0, 0, -1,
1, 0, 0,
0, -1, 0,
-0.428667133548626, -0.566306918848035, -0.703946704147444,
0.805963908589298, 0.112382414096594, -0.581199080396110,
0.408248290463863, -0.816496580927726, 0.408248290463863,
-0.577350269189626, -0.577350269189626, -0.577350269189626,
0.816496580927726, -0.408248290463863, -0.408248290463863,
0.000000000000000, -0.707106781186548, 0.707106781186547,
0, 0, -1,
1, 0, 0,
0, -1, 0,
};
std::vector<T> actual_u(27);
U->download(actual_u);
Expand All @@ -779,8 +797,7 @@ TEST_F(SvdTest, singularValuesMultipleMatrices) {
* SVD for rank computation of multiple
* matrices
* --------------------------------------- */
TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void singularValuesRankMultipleMatrices(float epsilon) {
std::vector<T> aData = {1, 4, 7, 10, 2, 5, 8, 11, 3, 6, 9, 0,
1, 4, 7, 10, 2, 5, 8, 11, 3, 6, 9, 12,
Expand Down Expand Up @@ -815,8 +832,7 @@ protected:
* Cholesky factorisation
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void choleskyFactorisation(T epsilon) {
std::vector<T> aData = {10.0, 2.0, 3.0,
2.0, 20.0, -1.0,
Expand All @@ -838,8 +854,7 @@ TEST_F(CholeskyTest, choleskyFactorisation) {
* Cholesky factorisation: solve system
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void choleskyFactorisationSolution(T epsilon) {
std::vector<T> aData = {10.0, 2.0, 3.0,
2.0, 20.0, -1.0,
Expand Down Expand Up @@ -874,8 +889,7 @@ TEST_F(CholeskyTest, choleskyFactorisationSolution) {
* Batched Cholesky factorisation
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void choleskyBatchFactorisation(T epsilon) {
std::vector<T> aData = {10.0, 2.0, 3.0,
2.0, 20.0, -1.0,
Expand Down Expand Up @@ -906,8 +920,7 @@ TEST_F(CholeskyTest, choleskyBatchFactorisation) {
* Batched Cholesky solve
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void choleskyBatchFactorSolve(T epsilon) {
std::vector<T> aData = {10.0, 2.0, 3.0,
2.0, 20.0, -1.0,
Expand Down Expand Up @@ -947,8 +960,7 @@ TEST_F(CholeskyTest, choleskyBatchFactorSolve) {
* Batched Cholesky solve (factor provided)
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void choleskyBatchSolve(T epsilon) {
std::vector<T> aData = {10.0, 2.0, 3.0,
2.0, 20.0, -1.0,
Expand Down Expand Up @@ -1007,8 +1019,7 @@ protected:
* Basic nullspace test
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void computeNullspaceTensor(T epsilon) {
std::vector<T> aData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 7, 8, 9,
Expand Down Expand Up @@ -1048,8 +1059,7 @@ TEST_F(NullspaceTest, computeNullspaceTensor) {
* Nullspace is trivial
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void computeNullspaceTrivial(T epsilon) {
std::vector<T> data{4, 5, 7,
4, 1, 8,
Expand All @@ -1072,8 +1082,7 @@ TEST_F(NullspaceTest, computeNullspaceTrivial) {
* Project onto nullspace
* --------------------------------------- */

TEMPLATE_WITH_TYPE_T
TEMPLATE_CONSTRAINT_REQUIRES_FPX
TEMPLATE_WITH_TYPE_T TEMPLATE_CONSTRAINT_REQUIRES_FPX
void projectOnNullspaceTensor(T epsilon) {
// offline
size_t m = 3;
Expand Down