Skip to content

Commit 294add0

Browse files
committed
2 parents 5bb6dc1 + c03bd7d commit 294add0

15 files changed

+159
-15
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
*__pycache__*
22
*CMakeFiles/
33
*.idea/*
4+
.DS_Store
5+
*.swo
6+
*.swp

Makefile

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
BENCHES := ""
2-
BENCHFLAGS :=
2+
BENCHFLAGS := #"--benchmark-group-by=func"
3+
4+
#IGNORE := numpy/image.py
5+
IGNORE += taco
6+
IGNORE_FLAGS := $(addprefix --ignore=, $(IGNORE))
37

48
# To group benchmark output by benchmark, use BENCHFLAGS=--benchmark-group-by=func.
59
# To additionally group by a parameterized value, add on ",param:<paramname>" to the
610
# command above.
711
python-bench: numpy/*.py
8-
pytest --ignore=taco $(BENCHFLAGS) $(BENCHES)
12+
pytest $(IGNORE_FLAGS) $(BENCHFLAGS) $(BENCHES)
913

1014
taco-bench: taco/build/taco-bench
1115
ifeq ($(BENCHES),"")

numpy/conftest.py

+7
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ def f(func):
77
# How do i set please use 10 rounds...
88
# benchmark(func)
99
return f
10+
11+
def pytest_addoption(parser):
12+
parser.addoption("--plot", action="store_true", dest="plot", default=False, help="Enable plotting for image.py")
13+
14+
@pytest.fixture
15+
def plot(request):
16+
return request.config.getoption("--plot")

numpy/image.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import numpy as np
2+
import cv2
3+
import os
4+
import pytest
5+
import matplotlib.pyplot as plt
6+
7+
images_path = "./numpy/images"
8+
9+
def load_dataset(image_folder):
10+
files = sorted(os.listdir(image_folder))
11+
images = []
12+
for f in files:
13+
path = os.path.join(image_folder, f)
14+
img = cv2.imread(path)
15+
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
16+
images.append(img)
17+
18+
images = np.stack(images, axis=0)
19+
return images
20+
21+
def thresh(images, t=85):
22+
if len(images.shape) < 3:
23+
images = np.expand_dims(images, axis=0)
24+
thresh_imgs = []
25+
for i in range(images.shape[0]):
26+
img = images[i]
27+
ret, thresh_img = cv2.threshold(img, t, 255, cv2.THRESH_BINARY)
28+
thresh_imgs.append(thresh_img)
29+
30+
thresh_imgs = np.stack(thresh_imgs, axis=0)
31+
return thresh_imgs
32+
33+
def plot_image(img, img1, img2, xor_img, t1, t2):
34+
f, ax = plt.subplots(2, 2)
35+
ax[0, 0].imshow(img1, 'gray')
36+
ax[0, 0].title.set_text("Binned Image 1. t1 = " + str(t1))
37+
38+
ax[0, 1].imshow(img2, 'gray')
39+
ax[0, 1].title.set_text("Binned Image 2. t2 = " + str(t2))
40+
41+
ax[1, 0].imshow(img, 'gray')
42+
ax[1, 0].title.set_text("Saturdated Image")
43+
44+
ax[1, 1].imshow(xor_img, 'gray')
45+
ax[1, 1].title.set_text("XOR Image")
46+
47+
f.tight_layout()
48+
plt.show()
49+
50+
@pytest.mark.parametrize("t1", [100, 150, 200, 250])
51+
def bench_edge_detection(tacoBench, t1, plot):
52+
images = load_dataset(images_path)
53+
if plot:
54+
print(images.shape)
55+
56+
sat_images = images[:,:,:,1]
57+
58+
img = sat_images[0]
59+
60+
t2 = t1 - 50
61+
62+
bin_img1 = thresh(img, t1)
63+
bin_img2 = thresh(img, t2)
64+
num_elements = float(np.prod(bin_img1.shape))
65+
66+
def bench():
67+
xor_img = np.logical_xor(bin_img1[0], bin_img2[0]).astype('int')
68+
return xor_img
69+
ret = tacoBench(bench)
70+
xor_img = bench()
71+
if plot:
72+
plot_image(img, bin_img1[0], bin_img2[0], xor_img, t1, t2)
73+
74+
print("Sparsity img 1 ", np.sum(bin_img1 != 0) / num_elements)
75+
print("Sparsity img 2 ", np.sum(bin_img2 != 0) / num_elements)
76+
print("Sparsity xor ", np.sum(xor_img != 0) / num_elements)
77+
78+
if __name__=="__main__":
79+
main()
80+

numpy/images/AFW_3929640120_1_0.jpg

22.1 KB
Loading

numpy/images/AFW_3944399031_1_0.jpg

23 KB
Loading

numpy/images/AFW_397921011_1_0.jpg

21.8 KB
Loading

numpy/images/AFW_397921011_2_0.jpg

29 KB
Loading

numpy/images/AFW_3989161_1_0.jpg

19.1 KB
Loading

numpy/images/AFW_399829006_1_0.jpg

26.8 KB
Loading

numpy/ufuncs.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def myfunc(x, y):
1111

1212
# @pytest.mark.parametrize("dim", [5000, 10000, 20000])
1313
@pytest.mark.parametrize("dim", [250, 500, 750, 1000, 2500, 5000, 7500, 8000])
14-
@pytest.mark.parametrize("ufunc", [numpy.logical_xor, numpy.logical_or, numpy.right_shift])
14+
@pytest.mark.parametrize("ufunc", [numpy.logical_xor, numpy.logical_or, numpy.right_shift, numpy.ldexp])
1515
def bench_ufunc_dense(tacoBench, dim, ufunc):
1616
A = numpy.random.randint(2, size=(dim, dim)).astype(numpy.uint32)
1717
B = numpy.random.randint(2, size=(dim, dim)).astype(numpy.uint32)
@@ -22,7 +22,7 @@ def bench():
2222
# TODO (rohany): We can parametrize this over the sparsity as well.
2323
# @pytest.mark.parametrize("dim", [5000, 10000, 20000])
2424
@pytest.mark.parametrize("dim", [250, 500, 750, 1000, 2500, 5000, 7500, 8000])
25-
@pytest.mark.parametrize("ufunc", [numpy.logical_xor, numpy.logical_or, numpy.right_shift])
25+
@pytest.mark.parametrize("ufunc", [numpy.logical_xor, numpy.logical_or, numpy.right_shift, numpy.ldexp])
2626
def bench_pydata_ufunc_sparse(tacoBench, dim, ufunc):
2727
A = sparse.random((dim, dim), data_rvs=numpy.ones).astype(numpy.uint32)
2828
B = sparse.random((dim, dim), data_rvs=numpy.ones).astype(numpy.uint32)

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ pytest-benchmark==3.2.3
1313
scipy==1.6.0
1414
sparse==0.11.2
1515
toml==0.10.2
16+
opencv-python==4.5.1.48

taco/bench.h

+15-6
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,21 @@
2020
// of an arbitrarily typed argument to the benchmark function.
2121
// TODO (rohany): Make this take in only 1 argument.
2222
// TODO (rohany): Don't specify the time here, but do it at the command line.
23-
#define TACO_BENCH_ARG(bench, name, arg) \
24-
BENCHMARK_CAPTURE(bench, name, arg) \
25-
->Unit(benchmark::kMicrosecond) \
26-
->Repetitions(10) \
27-
->Iterations(5) \
28-
->ReportAggregatesOnly(true) \
23+
24+
#define TACO_BENCH_ARG(bench, name, arg) \
25+
BENCHMARK_CAPTURE(bench, name, arg) \
26+
->Unit(benchmark::kMicrosecond) \
27+
->Repetitions(10) \
28+
->Iterations(5) \
29+
->ReportAggregatesOnly(true) \
30+
->UseRealTime()
31+
32+
#define TACO_BENCH_ARGS(bench, name, ...) \
33+
BENCHMARK_CAPTURE(bench, name, __VA_ARGS__) \
34+
->Unit(benchmark::kMicrosecond) \
35+
->Repetitions(10) \
36+
->Iterations(5) \
37+
->ReportAggregatesOnly(true) \
2938
->UseRealTime()
3039

3140
#endif //TACO_BENCH_BENCH_H

taco/ufuncs.cpp

+44-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ using namespace taco;
1010

1111
struct GeneralAdd {
1212
ir::Expr operator()(const std::vector<ir::Expr> &v) {
13-
taco_iassert(v.size() >= 2) << "Add operator needs at least two operands";
13+
taco_iassert(v.size() >= 1) << "Add operator needs at least one operand";
14+
if (v.size() == 1)
15+
return ir::Add::make(v[0], ir::Literal::zero(v[0].type()));
1416
ir::Expr add = ir::Add::make(v[0], v[1]);
1517
for (size_t idx = 2; idx < v.size(); ++idx) {
1618
add = ir::Add::make(add, v[idx]);
@@ -26,12 +28,48 @@ struct xorAlgebra {
2628
}
2729
};
2830

31+
struct RightShift{
32+
ir::Expr operator()(const std::vector<ir::Expr> &v) {
33+
if (v.size() == 1)
34+
return v[0];
35+
36+
ir::Expr shift = ir::BinOp::make(v[0], v[1], " >> ");
37+
for (size_t idx = 2; idx < v.size(); ++idx) {
38+
shift = ir::BinOp::make(shift, v[idx], " >> ");
39+
}
40+
return shift;
41+
}
42+
};
43+
44+
struct rightShiftAlgebra {
45+
IterationAlgebra operator()(const std::vector<IndexExpr>& regions) {
46+
return Union(regions[0], Intersect(regions[0], regions[1]));
47+
}
48+
};
49+
2950
// TODO (rohany): We can extract most of the logic out of here and parametrize the test by
3051
// a particular Func.
31-
static void bench_xor_sparse(benchmark::State& state, float sparsity) {
52+
template <int I, class...Ts>
53+
decltype(auto) get(Ts&&... ts) {
54+
return std::get<I>(std::forward_as_tuple(ts...));
55+
}
56+
57+
template <class ...ExtraArgs>
58+
static void bench_ufunc_sparse(benchmark::State& state, ExtraArgs&&... extra_args) {
3259
int dim = state.range(0);
3360

61+
auto& sparsity = get<0>(extra_args...);
62+
auto opType = get<1>(extra_args...);
63+
3464
Func xorOp("xor", GeneralAdd(), xorAlgebra());
65+
Func rightShiftOp(">>", RightShift(), rightShiftAlgebra());
66+
67+
Func op = xorOp;
68+
if (opType == "xor")
69+
op = xorOp;
70+
else if (opType == ">>")
71+
op = rightShiftOp;
72+
3573

3674
// TODO (rohany): We can parametrize over the sparsities here.
3775
Tensor<int> A("A", {dim, dim}, CSR);
@@ -58,7 +96,7 @@ static void bench_xor_sparse(benchmark::State& state, float sparsity) {
5896
state.PauseTiming();
5997
Tensor<float> result("C", {dim, dim}, CSR);
6098
IndexVar i, j;
61-
result(i, j) = xorOp(A(i, j), B(i, j));
99+
result(i, j) = op(A(i, j), B(i, j));
62100
result.compile();
63101
result.assemble();
64102
state.ResumeTiming();
@@ -70,4 +108,6 @@ static void bench_xor_sparse(benchmark::State& state, float sparsity) {
70108
static void applyBenchSizes(benchmark::internal::Benchmark* b) {
71109
b->ArgsProduct({{250, 500, 750, 1000, 2500, 5000, 7500, 8000}});
72110
}
73-
TACO_BENCH_ARG(bench_xor_sparse, 0.01, 0.01)->Apply(applyBenchSizes);
111+
112+
TACO_BENCH_ARGS(bench_ufunc_sparse, xor_0.01, 0.01, "xor")->Apply(applyBenchSizes);
113+
TACO_BENCH_ARGS(bench_ufunc_sparse, rightShift_0.01, 0.01, ">>")->Apply(applyBenchSizes);

0 commit comments

Comments
 (0)