Skip to content

Commit cfb5794

Browse files
authored
Merge branch 'buddy-compiler:main' into compareImg_dev
2 parents cad1d1e + 27a4f8a commit cfb5794

File tree

12 files changed

+269527
-1
lines changed

12 files changed

+269527
-1
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ $ mkdir build && cd build
9797
$ cmake -G Ninja .. \
9898
-DCMAKE_BUILD_TYPE=RELEASE \
9999
-DDEEP_LEARNING_BENCHMARKS=ON \
100-
-DCMAKE_BUILD_TYPE=RELEASE \
101100
-DOpenCV_DIR=$PWD/../thirdparty/opencv/build/ \
102101
-DBUDDY_MLIR_BUILD_DIR=/PATH/TO/BUDDY-MLIR/BUILD/
103102
$ ninja
@@ -194,3 +193,27 @@ $ ninja vectorization-XXX-benchmark
194193
$ cd bin
195194
$ ./vectorization-XXX-benchmark
196195
```
196+
## Gemmini Benchmark
197+
198+
Currently, we use the Spike simulator to run the Gemmini cases.
199+
The cycle-accurate benchmark cases are working in the progress.
200+
Before building the benchmark target, please see the following table and ensure you use the correct configuration.
201+
202+
| Cases | Hardware Configuration |
203+
| -------------- | ------------- |
204+
| Gemmini-ResNet-101 | defaultFpConfig ([link](./docs/GemminiConfig.md#using-default-float-point-configuration)) |
205+
206+
We assume you have already built all the components in the Gemmini README file. Now, let's build and run the cases.
207+
208+
```
209+
$ source /path/to/chipyard/env.sh
210+
$ cd buddy-benchmark
211+
$ mkdir build && cd build
212+
$ cmake -G Ninja .. \
213+
-DCMAKE_BUILD_TYPE=RELEASE \
214+
-DBUDDY_MLIR_BUILD_DIR=/PATH/TO/BUDDY-MLIR/BUILD/ \
215+
-DGEMMINI_BENCHMARKS=ON
216+
$ ninja
217+
$ cd bin
218+
$ spike --extension=gemmini pk Gemmini-ResNet-101
219+
```

benchmarks/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ if(OP_OPTIMIZATION_BENCHMARKS)
1818
add_subdirectory(OpOptimization)
1919
endif()
2020

21+
if (GEMMINI_BENCHMARKS)
22+
add_subdirectory(Gemmini)
23+
endif()

benchmarks/Gemmini/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(ResNet-101)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ResNet101.mlir filter=lfs diff=lfs merge=lfs -text
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
set(RESNET101_TOSA_PIPELINE "builtin.module(func.func(tosa-to-linalg-named),func.func(tosa-to-tensor),func.func(tosa-to-linalg),func.func(tosa-to-arith))")
2+
set(BUDDY_MLIR_BINARY_DIR ${BUDDY_MLIR_BUILD_DIR}/bin)
3+
set(CMAKE_CXX_COMPILER riscv64-unknown-linux-gnu-g++)
4+
set(LLVM_MLIR_EXECUTION_ENGINE_DIR ${BUDDY_MLIR_BUILD_DIR}/../llvm/mlir/include/mlir/ExecutionEngine)
5+
set(GEMMINI_CONFIG "dim=4 acc_t=f32 elem_t=f32")
6+
7+
if (NOT DEFINED ENV{RISCV})
8+
message(FATAL_ERROR "Can't find RISCV environment variable(missing: RISCV_TOOLCHAIN)")
9+
endif()
10+
11+
add_custom_command(
12+
OUTPUT
13+
resnet-101.o
14+
COMMAND
15+
${BUDDY_MLIR_BINARY_DIR}/buddy-opt ${CMAKE_CURRENT_SOURCE_DIR}/ResNet101.mlir
16+
-pass-pipeline="${RESNET101_TOSA_PIPELINE}" |
17+
${BUDDY_MLIR_BINARY_DIR}/buddy-opt
18+
-linalg-bufferize
19+
-convert-linalg-to-gemmini="acc_t=f32"
20+
-llvm-request-c-wrappers
21+
-empty-tensor-to-alloc-tensor
22+
-arith-bufferize
23+
-tensor-bufferize
24+
-func-bufferize
25+
-convert-linalg-to-loops
26+
-convert-vector-to-scf
27+
-linalg-bufferize
28+
-buffer-deallocation
29+
-convert-vector-to-scf
30+
-convert-scf-to-cf
31+
-convert-vector-to-llvm
32+
-arith-expand
33+
-convert-math-to-llvm
34+
-convert-linalg-to-loops
35+
-expand-strided-metadata
36+
-lower-gemmini=${GEMMINI_CONFIG}
37+
-reconcile-unrealized-casts |
38+
${BUDDY_MLIR_BINARY_DIR}/buddy-translate -buddy-to-llvmir |
39+
${BUDDY_MLIR_BINARY_DIR}/buddy-llc -filetype=obj -mtriple=riscv64
40+
-mattr=+buddyext,+D -float-abi=hard -o resnet-101.o
41+
)
42+
43+
add_library(ResNet101 STATIC resnet-101.o)
44+
# TODO: Add cross-compiled CRunnerUtils library.
45+
add_library(CRunnerUtils STATIC CRunnerUtils.cpp)
46+
target_include_directories(CRunnerUtils
47+
PRIVATE
48+
${LLVM_MLIR_EXECUTION_ENGINE_DIR}
49+
)
50+
set_target_properties(ResNet101 PROPERTIES LINKER_LANGUAGE CXX)
51+
add_executable(Gemmini-ResNet-101 Main.cpp)
52+
target_include_directories(Gemmini-ResNet-101
53+
PRIVATE
54+
images
55+
include
56+
)
57+
target_link_libraries(Gemmini-ResNet-101
58+
-static
59+
ResNet101
60+
CRunnerUtils
61+
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// The code here is from the upstream llvm, you can check
2+
// llvm/mlir/include/mlir/ExecutionEngine/CRunnerUtils.cpp
3+
4+
#include <CRunnerUtils.h>
5+
#include <Msan.h>
6+
#include <cstdlib>
7+
#include <alloca.h>
8+
#include <sys/time.h>
9+
#include <malloc.h>
10+
#include <algorithm>
11+
#include <cinttypes>
12+
#include <cstdio>
13+
#include <cstdlib>
14+
#include <random>
15+
#include <string.h>
16+
17+
extern "C" void memrefCopy(int64_t elemSize, UnrankedMemRefType<char> *srcArg,
18+
UnrankedMemRefType<char> *dstArg) {
19+
DynamicMemRefType<char> src(*srcArg);
20+
DynamicMemRefType<char> dst(*dstArg);
21+
22+
int64_t rank = src.rank;
23+
MLIR_MSAN_MEMORY_IS_INITIALIZED(src.sizes, rank * sizeof(int64_t));
24+
25+
// Handle empty shapes -> nothing to copy.
26+
for (int rankp = 0; rankp < rank; ++rankp)
27+
if (src.sizes[rankp] == 0)
28+
return;
29+
30+
char *srcPtr = src.data + src.offset * elemSize;
31+
char *dstPtr = dst.data + dst.offset * elemSize;
32+
33+
if (rank == 0) {
34+
memcpy(dstPtr, srcPtr, elemSize);
35+
return;
36+
}
37+
38+
int64_t *indices = static_cast<int64_t *>(alloca(sizeof(int64_t) * rank));
39+
int64_t *srcStrides = static_cast<int64_t *>(alloca(sizeof(int64_t) * rank));
40+
int64_t *dstStrides = static_cast<int64_t *>(alloca(sizeof(int64_t) * rank));
41+
42+
// Initialize index and scale strides.
43+
for (int rankp = 0; rankp < rank; ++rankp) {
44+
indices[rankp] = 0;
45+
srcStrides[rankp] = src.strides[rankp] * elemSize;
46+
dstStrides[rankp] = dst.strides[rankp] * elemSize;
47+
}
48+
49+
int64_t readIndex = 0, writeIndex = 0;
50+
for (;;) {
51+
// Copy over the element, byte by byte.
52+
memcpy(dstPtr + writeIndex, srcPtr + readIndex, elemSize);
53+
// Advance index and read position.
54+
for (int64_t axis = rank - 1; axis >= 0; --axis) {
55+
// Advance at current axis.
56+
auto newIndex = ++indices[axis];
57+
readIndex += srcStrides[axis];
58+
writeIndex += dstStrides[axis];
59+
// If this is a valid index, we have our next index, so continue copying.
60+
if (src.sizes[axis] != newIndex)
61+
break;
62+
// We reached the end of this axis. If this is axis 0, we are done.
63+
if (axis == 0)
64+
return;
65+
// Else, reset to 0 and undo the advancement of the linear index that
66+
// this axis had. Then continue with the axis one outer.
67+
indices[axis] = 0;
68+
readIndex -= src.sizes[axis] * srcStrides[axis];
69+
writeIndex -= dst.sizes[axis] * dstStrides[axis];
70+
}
71+
}
72+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===- Main.cpp -----------------------------------------------------------===//
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
//
17+
// This is the main file of the Gemmini ResNet-101 benchmark.
18+
//
19+
//===----------------------------------------------------------------------===//
20+
21+
#include <Cat.h>
22+
#include <Labels.h>
23+
#include <buddy/Core/Container.h>
24+
#include <iostream>
25+
#include <math.h>
26+
27+
extern "C" {
28+
void _mlir_ciface_resnet101(MemRef<float, 2> *output, MemRef<float, 4> *input);
29+
}
30+
31+
void softmax(float *input, size_t size) {
32+
assert(0 <= size <= sizeof(input) / sizeof(float));
33+
int i;
34+
float m, sum, constant;
35+
m = -INFINITY;
36+
for (i = 0; i < size; ++i) {
37+
if (m < input[i]) {
38+
m = input[i];
39+
}
40+
}
41+
42+
sum = 0.0;
43+
for (i = 0; i < size; ++i) {
44+
sum += exp(input[i] - m);
45+
}
46+
47+
constant = m + log(sum);
48+
for (i = 0; i < size; ++i) {
49+
input[i] = exp(input[i] - constant);
50+
}
51+
}
52+
53+
int main() {
54+
intptr_t sizesInput[4] = {1, 299, 299, 3};
55+
intptr_t sizesOutput[2] = {1, 1001};
56+
MemRef<float, 4> input(catImg, sizesInput);
57+
MemRef<float, 2> output(sizesOutput);
58+
_mlir_ciface_resnet101(&output, &input);
59+
float *out = output.getData();
60+
softmax(out, 1001);
61+
float maxVal = 0;
62+
int maxIdx = 0;
63+
for (int i = 0; i < 1001; ++i) {
64+
if (out[i] > maxVal) {
65+
maxVal = out[i];
66+
maxIdx = i;
67+
}
68+
}
69+
std::cout << "Classification Index: " << maxIdx << std::endl;
70+
std::cout << "Classification: " << labels[maxIdx] << std::endl;
71+
std::cout << "Probability: " << maxVal << std::endl;
72+
73+
return 0;
74+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:ed6c59a9ec272f921b8e4c5112d772163ae48865a4e658f42aeb19c2f5a79c36
3+
size 356793476

0 commit comments

Comments
 (0)