Skip to content
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
3 changes: 2 additions & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ jobs:
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
./cpp_test "--success"
./sketch_test "--success"
./sketch_test "--success"
./crs_test "--success"
38 changes: 38 additions & 0 deletions benchmark/src/Benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,36 @@
using namespace std;
using namespace INTELLI;
using namespace torch;
using namespace DIVERSE_METER;
void runSingleThreadTest(std::string configName) {
MeterTable meterTable;
AbstractMeterPtr eMeter = nullptr;
ConfigMapPtr cfg = newConfigMap();
cfg->fromFile(configName);
AMMBench::MatrixLoaderTable mLoaderTable;
uint64_t sketchDimension;
sketchDimension = cfg->tryU64("sketchDimension", 50, true);
uint64_t coreBind = cfg->tryU64("coreBind", 0, true);
uint64_t usingMeter = cfg->tryU64("usingMeter", 0, true);
std::string meterTag = cfg->tryString("meterTag", "intelMsr", true);
if (usingMeter) {
eMeter = meterTable.findMeter(meterTag);
if (eMeter != nullptr) {
eMeter->setConfig(cfg);
double staticPower = cfg->tryDouble("staticPower", 0.0, false);
if (staticPower == 0.0) {
eMeter->testStaticPower(2);
} else {
INTELLI_INFO("use pre-defined static power");
eMeter->setStaticPower(staticPower);
}
INTELLI_INFO("static power is " + to_string(eMeter->getStaticPower()) + " W");
} else {
INTELLI_ERROR("No meter found: " + meterTag);
}

}

UtilityFunctions::bind2Core((int) coreBind);
torch::set_num_threads(1);
std::string ptFile = cfg->tryString("ptFile", "torchscripts/FDAMM.pt", true);
Expand All @@ -33,19 +56,34 @@ void runSingleThreadTest(std::string configName) {
matLoaderPtr->setConfig(cfg);
auto A = matLoaderPtr->getA();
auto B = matLoaderPtr->getB();
//555
/*torch::manual_seed(114514);
//555
auto A = torch::rand({(long) aRow, (long) aCol});
auto B = torch::rand({(long) aCol, (long) bCol});*/
INTELLI_INFO("Generation done, conducting...");
if (eMeter != nullptr) {
eMeter->startMeter();
}
ThreadPerf pef((int) coreBind);
pef.setPerfList();
pef.start();
auto C =module.forward({A, B, (long) sketchDimension}).toTensor();
pef.end();
if (eMeter != nullptr) {
eMeter->stopMeter();
}
std::string ruName = "default";

auto resultCsv = pef.resultToConfigMap();
if (eMeter != nullptr) {
eMeter->stopMeter();
double energyConsumption = eMeter->getE();
double staticEnergyConsumption = eMeter->getStaicEnergyConsumption(resultCsv->tryU64("perfElapsedTime", 0, false));
double pureEnergy = energyConsumption - staticEnergyConsumption;
resultCsv->edit("energyAll", (double) energyConsumption);
resultCsv->edit("energyOnlyMe", (double) pureEnergy);
}
resultCsv->toFile(ruName + ".csv");
INTELLI_INFO("Done. here is result");
std::cout << resultCsv->toString() << endl;
Expand Down
Binary file added benchmark/torchscripts/BernoulliCRS.pt
Binary file not shown.
66 changes: 66 additions & 0 deletions benchmark/torchscripts/BernoulliCRS.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import torch
import time
import os

def get_first_element(tensor):
if tensor.numel() == 1:
return tensor.item()
else:
return tensor[0].item()

def is_empty_tensor(tensor):
return tensor.numel() == 0

@torch.jit.script
def BernoulliCRS(A: torch.Tensor, B: torch.Tensor, k: int):
# Get the dimension of A
A = A.t()
n, m = A.shape

assert n == B.shape[0]
assert k < n

# probability distribution
sample = torch.rand(n) # default: uniform
sample = torch.div(sample, sample.sum() / k) # sum = k as per the paper

# diagonal scaling matrix P (nxn)
P = torch.diag(1.0 / torch.sqrt(sample))

# random diagonal sampling matrix K (nxn)
sample = (torch.rand(n) < sample).float()
K = torch.diag(sample)

a = torch.matmul(torch.matmul(A.t(), P), K)
b = torch.matmul(torch.matmul(a, K), P)

return torch.matmul(b, B)


def main():

width = 1000
A = torch.rand(2000, width)
B = torch.rand(width, 2000)

t = time.time()

aResult = BernoulliCRS(A, B, 500)
print("approximate: " + str(time.time() - t) + "s")

print(aResult)

# exact result
t = time.time()
eResult = torch.matmul(A, B)
print("\nExact: " + str(time.time() - t) + "s")

print(eResult)

print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item()))

script = BernoulliCRS.save("BernoulliCRS.pt")

if __name__ == '__main__':
main()

Binary file added benchmark/torchscripts/CRS.pt
Binary file not shown.
Binary file added benchmark/torchscripts/CRSV2.pt
Binary file not shown.
70 changes: 70 additions & 0 deletions benchmark/torchscripts/ColumnRowSampling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import torch
import time
import os
import math

def get_first_element(tensor):
if tensor.numel() == 1:
return tensor.item()
else:
return tensor[0].item()

def is_empty_tensor(tensor):
return tensor.numel() == 0

@torch.jit.script
def CRS(A: torch.Tensor, B: torch.Tensor, k: int):
# Get the dimension of A
A = A.t()
n, m = A.shape

assert n == B.shape[0]
assert k < n

# probability distribution
probs = torch.ones(n) / n # default: uniform

# sample k indices from range 0 to n for given probability distribution
indices = torch.multinomial(probs, k, replacement=True)

# Sample k columns from A
A_sampled = A[indices, :]
ratio = math.ceil(n / k)
A_sampled = torch.div((A_sampled / k).t(), probs[::ratio])

# Sample k rows from B
B_sampled = B[indices, :]

# Compute the matrix product
result = A_sampled.matmul(B_sampled)
return result


def main():

width = 2000
A = torch.rand(5000, width)
B = torch.rand(width, 5000)


t = time.time()

aResult = CRS(A, B, 500)
print("approximate: " + str(time.time() - t) + "s")

print(aResult)

# exact result
t = time.time()
eResult = torch.matmul(A, B)
print("\nExact: " + str(time.time() - t) + "s")

print(eResult)

print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item()))

FDAMM_script = CRS.save("CRS.pt")

if __name__ == '__main__':
main()

71 changes: 71 additions & 0 deletions benchmark/torchscripts/ColumnRowSamplingVer2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import torch
import time
import os

def get_first_element(tensor):
if tensor.numel() == 1:
return tensor.item()
else:
return tensor[0].item()

def is_empty_tensor(tensor):
return tensor.numel() == 0

@torch.jit.script
def CRS(A: torch.Tensor, B: torch.Tensor, k: int):
# Get the dimension of A
A = A.t()
n, m = A.shape

assert n == B.shape[0]
assert k < n

# probability distribution
# dist = torch.distributions.Uniform(0, 1)
sample = torch.rand(n) # default: uniform

# diagonal scaling matrix D (nxn)
sample = torch.div(sample, sample.sum())
D = torch.diag(1.0 / torch.sqrt(k * sample))

# sampling matrix S (kxn)
column_indices = torch.multinomial(sample, k, replacement=True)
S = torch.zeros(k, n)
for row, col in enumerate(column_indices):
S[row, col] = 1

a = torch.matmul(torch.matmul(A.t(), D), S.t())
b = torch.matmul(torch.matmul(a, S), D)


return torch.matmul(b, B)


def main():


width = 2000
A = torch.rand(1000, width)
B = torch.rand(width, 1000)

t = time.time()

aResult = CRS(A, B, 500)
print("approximate: " + str(time.time() - t) + "s")

print(aResult)

# exact result
t = time.time()
eResult = torch.matmul(A, B)
print("\nExact: " + str(time.time() - t) + "s")

print(eResult)

print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item()))

script = CRS.save("CRSV2.pt")

if __name__ == '__main__':
main()

Loading