This commit is contained in:
@@ -58,7 +58,8 @@ Validate a network or network slice:
|
||||
```
|
||||
|
||||
`--operations-dir` may point to any directory tree containing `.onnx` files.
|
||||
The script discovers them recursively.
|
||||
The script discovers them recursively and writes `validation_results.csv` in
|
||||
that directory while retaining the terminal table.
|
||||
|
||||
## Raptor vs PIMCOMP comparison
|
||||
|
||||
|
||||
@@ -1,26 +1,85 @@
|
||||
# PIMCOMP paper models
|
||||
# PIMCOMP comparison models
|
||||
|
||||
This directory contains the four networks evaluated in
|
||||
[PIMCOMP: An End-to-End DNN Compiler for Processing-In-Memory Accelerators](https://arxiv.org/pdf/2411.09159):
|
||||
VGG-8, ResNet-18, ResNet-34, and GoogLeNet.
|
||||
VGG-8, ResNet-18, ResNet-34, and GoogLeNet. It also contains YOLO11n as an
|
||||
additional compiler comparison model.
|
||||
|
||||
See the runner-generated [results.csv](results.csv) for the current latency
|
||||
and energy results.
|
||||
|
||||
## Models and provenance
|
||||
|
||||
| Directory | Model | Input | Provenance |
|
||||
|--------------|----------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `resnet18/` | ResNet-18 v1 | `1x3x224x224` | Symlink to the complete [ONNX Model Zoo `resnet18-v1-7`](https://huggingface.co/onnxmodelzoo/resnet18-v1-7) model already present at `../resnet18/depth_68/resnet18_depth_68.onnx`. |
|
||||
| `resnet34/` | ResNet-34 v1 | `1x3x224x224` | [ONNX Model Zoo `resnet34-v1-7`](https://huggingface.co/onnxmodelzoo/resnet34-v1-7), with its symbolic batch fixed to 1 as PIMCOMP's frontend does. |
|
||||
| `googlenet/` | GoogLeNet | `1x3x224x224` | Unmodified [ONNX Model Zoo `googlenet-12`](https://huggingface.co/onnxmodelzoo/googlenet-12). |
|
||||
| `vgg8/` | VGG-8 reconstruction | `1x1x28x28` | Reconstruction of the [PIMCOMP VGG-8 benchmark](https://arxiv.org/html/2411.09159#S8.SS1), with six convolution and two fully connected layers. |
|
||||
| Directory | Model | Input | Provenance |
|
||||
|--------------|----------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `resnet18/` | ResNet-18 v1 | `1x3x224x224` | Symlink to the complete [ONNX Model Zoo `resnet18-v1-7`](https://huggingface.co/onnxmodelzoo/resnet18-v1-7) model already present at `../resnet18/depth_68/resnet18_depth_68.onnx`. |
|
||||
| `resnet34/` | ResNet-34 v1 | `1x3x224x224` | [ONNX Model Zoo `resnet34-v1-7`](https://huggingface.co/onnxmodelzoo/resnet34-v1-7), with its symbolic batch fixed to 1 as PIMCOMP's frontend does. |
|
||||
| `googlenet/` | GoogLeNet | `1x3x224x224` | Unmodified [ONNX Model Zoo `googlenet-12`](https://huggingface.co/onnxmodelzoo/googlenet-12). |
|
||||
| `vgg8/` | VGG-8 reconstruction | `1x1x28x28` | Reconstruction of the [PIMCOMP VGG-8 benchmark](https://arxiv.org/html/2411.09159#S8.SS1), with six convolution and two fully connected layers. |
|
||||
| `yolo11n/` | YOLO11n detection | `1x3x640x640` | Derived from the canonical local model at `../yolo11n/depth_51/yolo11n_depth_51.onnx`, exported from [Ultralytics YOLO11n](https://github.com/ultralytics/ultralytics/blob/main/docs/en/models/yolo11.md). |
|
||||
|
||||
`googlenet/googlenet-12-latency.onnx` is the explicit common latency model.
|
||||
It exposes the original model's final FC logits (`loss3/classifier_1`) and
|
||||
removes its two LRN nodes and terminal Softmax so the comparison covers only
|
||||
operations scheduled by PIMCOMP. Keep `googlenet-12.onnx` as the unmodified
|
||||
source model.
|
||||
`googlenet/googlenet-12-latency.onnx` is the explicit pimsim-nn-ready GoogLeNet model.
|
||||
It removes the two LRN nodes and terminal Softmax from the original model,
|
||||
so that the comparison covers only operations scheduled by PIMCOMP and supported by pimsim-nn.
|
||||
|
||||
`yolo11n/yolo11n-latency.onnx` is the explicit pimsim-nn-ready YOLO11n model.
|
||||
It removes the Softmax nodes from the original model,
|
||||
so that the compiled artifact can be simulated in pimsim-nn.
|
||||
|
||||
## Unsupported and ignored operations
|
||||
|
||||
PIMCOMP's frontend accepts exactly these ONNX operations:
|
||||
|
||||
```text
|
||||
Add, AveragePool, BatchNormalization, Clip, Concat, Conv, Dropout, Flatten,
|
||||
Gather, Gemm, GlobalAveragePool, LRN, MatMul, MaxPool, Mul, Pad, Relu, Reshape,
|
||||
Shape, Sigmoid, Softmax, Squeeze, Sub, Sum, Tanh, Transpose, Unsqueeze
|
||||
```
|
||||
|
||||
`Constant` is consumed as frontend metadata rather than emitted as a PIMCOMP
|
||||
node. Every other ONNX operation is unsupported: the frontend prints
|
||||
`operation: <type> not considered` and stops at the first occurrence. Thus the
|
||||
complete unsupported set is the complement of the allowlist above for the
|
||||
model's ONNX opset. In particular, YOLO11n contains unsupported `Split` and
|
||||
`Resize` nodes.
|
||||
|
||||
PIMCOMP's low-latency scheduler, hierarchy mapper, and genetic algorithm use
|
||||
this complete explicit no-consider set:
|
||||
|
||||
```text
|
||||
Input, BatchNormalization, Clip, Dropout, Flatten, LRN, MatMul, Reshape,
|
||||
Softmax, Squeeze, Transpose
|
||||
```
|
||||
|
||||
Those nodes do not receive scheduled latency instructions when they remain in
|
||||
the backend graph. Before that point the frontend may fuse BatchNormalization
|
||||
and activation nodes into Conv/Gemm, convert a
|
||||
Reshape-Transpose-Reshape channel-shuffle pattern to `OP_SHUFFLE`, remove a
|
||||
specific Shape-Gather-Unsqueeze-Concat shape chain, and merge Pad into its
|
||||
consumer. These transformations do not make an otherwise standalone ignored
|
||||
operation timed.
|
||||
|
||||
`pimsim-nn` consumes PIM ISA instructions. It supports every named opcode
|
||||
in the shared serialized range except `vsoftmax` (opcode 21),
|
||||
which is rejected explicitly in both JSON and binary input. It
|
||||
silently ignores no opcode; unknown names and numbers are errors.
|
||||
|
||||
These boundaries explain the dedicated artifacts:
|
||||
|
||||
- GoogLeNet's two LRN nodes and terminal Softmax perform real computation but
|
||||
are ignored by PIMCOMP, so the common latency artifact removes them. Its
|
||||
inference Dropout and shape-only Reshape can remain without adding compute.
|
||||
- YOLO11n's latency artifact bypasses exactly its two Softmax nodes so it can
|
||||
run in `pimsim-nn`. Every other node, including MatMul, Transpose, and the
|
||||
final detection-decoding tail, remains present and timed by Raptor. No
|
||||
PIMCOMP latency is reported because its frontend stops at `Split` and also
|
||||
lacks `Resize`; compiling that prefix would not represent YOLO11n.
|
||||
|
||||
The authoritative lists are in
|
||||
[`frontend.py`](../../../third_party/PIMCOMP-NN/frontend/frontend.py),
|
||||
[`ElementPipelineSchedule.cpp`](../../../third_party/PIMCOMP-NN/backend/ElementPipelineSchedule.cpp),
|
||||
[`ISA.h`](../../../backend-simulators/pim/pimsim-nn/src/isa/ISA.h), and
|
||||
[`Instruction.cpp`](../../../backend-simulators/pim/pimsim-nn/src/isa/Instruction.cpp).
|
||||
|
||||
The PIMCOMP authors did not publish the ONNX checkpoints used by the paper.
|
||||
Running PIMCOMP's frontend on the three Model Zoo files above produces JSON
|
||||
@@ -41,6 +100,7 @@ c3231061d081bdd47884137b02134f85142752a39e87263c529cd14ed242b096 resnet34/resne
|
||||
c99c507058eaf41de8723408fdda7db8325cb57f0a89f2ee07a716d6e963e14e googlenet/googlenet-12.onnx
|
||||
a26f9e33901c573e60c34a3f0abbb4744fff83e4e0f21b18fc66e20395e72982 googlenet/googlenet-12-latency.onnx
|
||||
396cdea21e5e7d02c3f26f14d22ef20975171702493f5c5e79b8e0d896e541ef vgg8/vgg8-mnist-reconstructed.onnx
|
||||
229f3975af8933d39aee8d9031d969bff074b69c33e304a78abb35ff0c5f445f yolo11n/yolo11n-latency.onnx
|
||||
```
|
||||
|
||||
## Paper hardware profiles
|
||||
@@ -190,6 +250,13 @@ RAPTOR_ROOT=$PWD
|
||||
--pimcomp-pipeline element
|
||||
```
|
||||
|
||||
Use the same command with
|
||||
`yolo11n/yolo11n-latency.onnx` to probe YOLO11n. Released PIMCOMP-NN cannot
|
||||
compile it: the frontend stops at `/model.2/Split`, and it also has no mapping
|
||||
for YOLO11n's two nearest-neighbor `Resize` nodes. Treating the emitted prefix
|
||||
as YOLO11n would produce a misleading latency, so no PIMCOMP number is
|
||||
reported for this model.
|
||||
|
||||
For Arch-A high throughput, use `--pimsim-mode throughput
|
||||
--pimcomp-pipeline batch`. For Arch-B, use 138 cores, 128 crossbars, a
|
||||
`6x23` mesh, and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
model,raptor_latency_ms,pimcomp_latency_ms,raptor_energy_pj,pimcomp_energy_pj,faster_compiler,speedup
|
||||
vgg8,2.463417,7.985074,649524564.120001,1597904071.120000,raptor,3.24
|
||||
resnet18,31.449811,58.853733,9335506856.119984,13983168748.119974,raptor,1.87
|
||||
resnet34,58.071522,91.607980,17027195415.679953,22722922369.680016,raptor,1.58
|
||||
googlenet,24.247113,62.923463,8019605936.239990,14547526780.240000,raptor,2.60
|
||||
vgg8,1.465778,7.985074,477298145.040001,1597904071.120000,raptor,5.45
|
||||
resnet18,28.099952,58.853733,8781611766.119984,13983168748.119974,raptor,2.09
|
||||
resnet34,45.781486,91.607980,14962940227.679951,22722922369.680016,raptor,2.00
|
||||
googlenet,13.371204,62.923463,6117835798.919991,14547526780.240000,raptor,4.71
|
||||
|
||||
|
Binary file not shown.
@@ -38,11 +38,12 @@ Run the complete suite with deadlock detection:
|
||||
|
||||
Use `--compile-only` for compiler and deadlock checks, then `--run-only` to
|
||||
reuse those artifacts for reference execution, simulation, and comparison.
|
||||
The validator prints the complete operation results table before its summary.
|
||||
The validator prints the complete operation results table before its summary
|
||||
and writes the same rows to `validation_results.csv`.
|
||||
|
||||
## Complete inventory
|
||||
|
||||
The suite contains 164 models. Tensor shapes, attributes, and constants are
|
||||
The suite contains 165 models. Tensor shapes, attributes, and constants are
|
||||
defined in `gen_tests.py` and in the checked-in ONNX models.
|
||||
|
||||
### Add (5)
|
||||
@@ -63,7 +64,7 @@ defined in `gen_tests.py` and in the checked-in ONNX models.
|
||||
| `negative_axis` | Concatenates tensors using a negative axis. |
|
||||
| `three_inputs_channel_axis` | Concatenates three runtime NCHW tensors along the channel axis. |
|
||||
|
||||
### Conv (31)
|
||||
### Conv (32)
|
||||
|
||||
| Case | Description |
|
||||
|---|---|
|
||||
@@ -98,6 +99,7 @@ defined in `gen_tests.py` and in the checked-in ONNX models.
|
||||
| `with_bias_3x3` | Multi-channel 3x3 Conv with bias. |
|
||||
| `with_constant` | Hand-authored SAME_UPPER Conv with constant weight and bias. |
|
||||
| `without_kernel_shape_attr` | Conv whose kernel shape is inferred from its weight tensor. |
|
||||
| `yolo11n_stem` | First two YOLO11n `Conv-SiLU` blocks at `640x640`, including the distributed activation boundary. |
|
||||
|
||||
### Div (6)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -218,6 +218,30 @@ def conv_huge_pointwise_1024_dynamic():
|
||||
save_model(model, "conv/huge_pointwise_1024_dynamic", "conv_huge_pointwise_1024_dynamic.onnx")
|
||||
|
||||
|
||||
def conv_yolo11n_stem():
|
||||
"""First two YOLO11n Conv-SiLU blocks, preserving the distributed intermediate."""
|
||||
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 640, 640])
|
||||
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 32, 160, 160])
|
||||
rng = np.random.default_rng(109)
|
||||
W0 = numpy_helper.from_array(rng.uniform(-1, 1, (16, 3, 3, 3)).astype(np.float32), name="W0")
|
||||
B0 = numpy_helper.from_array(rng.uniform(-1, 1, (16,)).astype(np.float32), name="B0")
|
||||
W1 = numpy_helper.from_array(rng.uniform(-1, 1, (32, 16, 3, 3)).astype(np.float32), name="W1")
|
||||
B1 = numpy_helper.from_array(rng.uniform(-1, 1, (32,)).astype(np.float32), name="B1")
|
||||
nodes = [
|
||||
helper.make_node("Conv", ["X", "W0", "B0"], ["C0"],
|
||||
kernel_shape=[3, 3], strides=[2, 2], pads=[1, 1, 1, 1]),
|
||||
helper.make_node("Sigmoid", ["C0"], ["S0"]),
|
||||
helper.make_node("Mul", ["C0", "S0"], ["A0"]),
|
||||
helper.make_node("Conv", ["A0", "W1", "B1"], ["C1"],
|
||||
kernel_shape=[3, 3], strides=[2, 2], pads=[1, 1, 1, 1]),
|
||||
helper.make_node("Sigmoid", ["C1"], ["S1"]),
|
||||
helper.make_node("Mul", ["C1", "S1"], ["Y"]),
|
||||
]
|
||||
graph = helper.make_graph(nodes, "conv_yolo11n_stem", [X], [Y], initializer=[W0, B0, W1, B1])
|
||||
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
|
||||
save_model(model, "conv/yolo11n_stem", "conv_yolo11n_stem.onnx")
|
||||
|
||||
|
||||
def conv_pointwise_tiled_chain():
|
||||
"""Chained pointwise Convs with a tiled intermediate."""
|
||||
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 1, 1])
|
||||
@@ -2032,6 +2056,7 @@ if __name__ == "__main__":
|
||||
conv_dynamic()
|
||||
conv_huge_pointwise_1024()
|
||||
conv_huge_pointwise_1024_dynamic()
|
||||
conv_yolo11n_stem()
|
||||
conv_pointwise_tiled_chain()
|
||||
conv_large_output_channels_1x1()
|
||||
conv_large_input_channels_1x1()
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
Operation,Result,Compile,Host mem,Cores mem,Cores,Xbars,Latency,Power,Energy
|
||||
add/after_gemm,PASS,0.141 s,0.01 MiB,0.01 MiB,5,4,0.007784 ms,104.703618 mW,815012.960000 pJ
|
||||
add/basic,PASS,0.114 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
add/broadcast_row,PASS,0.110 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
add/channel_broadcast_1024,PASS,0.105 s,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
||||
add/leading_dimension_broadcast,PASS,0.137 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
concat/channel_axis,PASS,0.127 s,0.00 MiB,0.00 MiB,1,0,0.000457 ms,78.157549 mW,35718.000000 pJ
|
||||
concat/negative_axis,PASS,0.102 s,0.00 MiB,0.00 MiB,1,0,0.001043 ms,78.092042 mW,81450.000000 pJ
|
||||
concat/three_inputs_channel_axis,PASS,0.127 s,0.00 MiB,0.00 MiB,1,0,0.000644 ms,78.149068 mW,50328.000000 pJ
|
||||
conv/batch_2,PASS,0.102 s,0.00 MiB,0.00 MiB,2,2,0.013694 ms,82.623885 mW,1131451.480000 pJ
|
||||
conv/batch_4_pointwise,PASS,0.110 s,0.00 MiB,0.01 MiB,5,4,0.003932 ms,116.078576 mW,456420.960000 pJ
|
||||
conv/depthwise_1024_channels,PASS,0.167 s,0.19 MiB,0.38 MiB,129,128,0.220751 ms,178.454307 mW,39393966.720000 pJ
|
||||
conv/depthwise_grouped,PASS,0.109 s,0.01 MiB,0.00 MiB,5,4,0.006024 ms,108.326521 mW,652558.960000 pJ
|
||||
conv/dilated_3x3,PASS,0.143 s,0.00 MiB,0.00 MiB,3,3,0.004045 ms,110.234541 mW,445898.720000 pJ
|
||||
conv/dynamic,PASS,0.107 s,0.00 MiB,0.00 MiB,5,0,0.001835 ms,92.281199 mW,169336.000000 pJ
|
||||
conv/explicit_padding,PASS,0.139 s,0.00 MiB,0.00 MiB,4,4,0.004327 ms,115.794768 mW,501043.960000 pJ
|
||||
conv/grouped_many_groups,PASS,0.616 s,0.05 MiB,0.09 MiB,65,64,0.181845 ms,142.210104 mW,25860196.360000 pJ
|
||||
conv/grouped_two_groups,PASS,0.145 s,0.00 MiB,0.00 MiB,3,2,0.005360 ms,101.459418 mW,543822.480000 pJ
|
||||
conv/huge_pointwise_1024,PASS,0.749 s,0.01 MiB,0.01 MiB,1,64,0.028261 ms,133.488743 mW,3772525.360000 pJ
|
||||
conv/huge_pointwise_1024_dynamic,PASS,0.097 s,8.04 MiB,12.61 MiB,168,0,2.627964 ms,169.518697 mW,445489032.000000 pJ
|
||||
conv/kernel_3x3,PASS,0.155 s,0.00 MiB,0.00 MiB,3,3,0.003091 ms,115.862414 mW,358130.720000 pJ
|
||||
conv/kernel_equals_input_spatial,PASS,0.156 s,0.00 MiB,0.00 MiB,1,2,0.008443 ms,83.863849 mW,708062.480000 pJ
|
||||
conv/large_input_channels_1x1,PASS,0.160 s,0.01 MiB,0.01 MiB,1,8,0.017167 ms,89.416900 mW,1535019.920000 pJ
|
||||
conv/large_output_channels_1x1,PASS,0.141 s,0.00 MiB,0.01 MiB,1,8,0.004964 ms,117.628106 mW,583905.920000 pJ
|
||||
conv/large_spatial,PASS,0.141 s,0.00 MiB,0.01 MiB,6,6,0.004096 ms,129.015000 mW,528445.440000 pJ
|
||||
conv/multi_channel,PASS,0.143 s,0.00 MiB,0.00 MiB,3,3,0.005148 ms,106.453520 mW,548022.720000 pJ
|
||||
conv/non_square_kernel_1x3,PASS,0.127 s,0.00 MiB,0.00 MiB,5,5,0.004029 ms,123.600943 mW,497988.200000 pJ
|
||||
conv/non_square_kernel_3x1,PASS,0.085 s,0.00 MiB,0.00 MiB,3,3,0.005526 ms,105.464843 mW,582798.720000 pJ
|
||||
conv/non_uniform_stride,PASS,0.120 s,0.00 MiB,0.00 MiB,4,4,0.005808 ms,110.081433 mW,639352.960000 pJ
|
||||
conv/pointwise_1x1,PASS,0.139 s,0.00 MiB,0.00 MiB,4,4,0.004539 ms,114.835858 mW,521239.960000 pJ
|
||||
conv/pointwise_tiled_chain,PASS,0.943 s,0.01 MiB,0.02 MiB,2,80,0.084437 ms,102.289307 mW,8637002.200000 pJ
|
||||
conv/real_asymmetric_padding,PASS,0.115 s,0.00 MiB,0.00 MiB,4,4,0.005232 ms,111.870214 mW,585304.960000 pJ
|
||||
conv/relu_conv_store,PASS,0.107 s,0.05 MiB,0.08 MiB,32,32,0.062978 ms,246.649827 mW,15533512.800000 pJ
|
||||
conv/same_lower_3x3,PASS,0.094 s,0.00 MiB,0.00 MiB,5,5,0.004700 ms,119.232170 mW,560391.200000 pJ
|
||||
conv/same_padding_3x3,PASS,0.126 s,0.00 MiB,0.00 MiB,5,5,0.004700 ms,119.232170 mW,560391.200000 pJ
|
||||
conv/simple,PASS,0.125 s,0.00 MiB,0.00 MiB,2,2,0.003148 ms,94.665972 mW,298008.480000 pJ
|
||||
conv/stride_2,PASS,0.146 s,0.00 MiB,0.00 MiB,2,2,0.002827 ms,96.393873 mW,272505.480000 pJ
|
||||
conv/with_bias_3x3,PASS,0.121 s,0.00 MiB,0.00 MiB,3,3,0.004898 ms,107.176546 mW,524950.720000 pJ
|
||||
conv/with_constant,PASS,0.106 s,0.00 MiB,0.00 MiB,3,3,0.004273 ms,109.362677 mW,467306.720000 pJ
|
||||
conv/without_kernel_shape_attr,PASS,0.105 s,0.00 MiB,0.00 MiB,3,3,0.003091 ms,115.862414 mW,358130.720000 pJ
|
||||
conv/yolo11n_stem,PASS,3.091 s,29.20 MiB,31.38 MiB,168,488,9.799213 ms,361.075203 mW,3538252825.000010 pJ
|
||||
div/after_gemm,PASS,0.130 s,0.01 MiB,0.01 MiB,5,4,0.007784 ms,104.703618 mW,815012.960000 pJ
|
||||
div/basic,PASS,0.116 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
div/channel_broadcast_1024,PASS,0.121 s,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
||||
div/leading_dimension_broadcast,PASS,0.095 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
div/runtime_scalar_rhs,PASS,0.126 s,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
||||
div/scalar_constant,PASS,0.069 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
gather/3d_input_axis1,PASS,0.121 s,0.00 MiB,0.00 MiB,1,0,0.000589 ms,78.081494 mW,45990.000000 pJ
|
||||
gather/axis0_matrix_indices,PASS,0.088 s,0.00 MiB,0.00 MiB,1,0,0.000697 ms,78.068867 mW,54414.000000 pJ
|
||||
gather/axis1,PASS,0.123 s,0.00 MiB,0.00 MiB,1,0,0.000801 ms,78.059925 mW,62526.000000 pJ
|
||||
gather/negative_axis,PASS,0.087 s,0.00 MiB,0.00 MiB,1,0,0.001437 ms,78.033403 mW,112134.000000 pJ
|
||||
gather/negative_indices,PASS,0.115 s,0.00 MiB,0.00 MiB,1,0,0.000376 ms,78.127660 mW,29376.000000 pJ
|
||||
gemm/alpha_beta,PASS,0.121 s,0.01 MiB,0.01 MiB,5,4,0.007456 ms,105.272125 mW,784908.960000 pJ
|
||||
gemm/bias_rank2_broadcast,PASS,0.127 s,0.00 MiB,0.01 MiB,5,4,0.007072 ms,105.979208 mW,749484.960000 pJ
|
||||
gemm/dynamic,PASS,0.084 s,0.00 MiB,0.00 MiB,5,0,0.002421 ms,91.480793 mW,221475.000000 pJ
|
||||
gemm/dynamic_alpha,PASS,0.104 s,0.00 MiB,0.00 MiB,5,0,0.003262 ms,91.415696 mW,298198.000000 pJ
|
||||
gemm/dynamic_beta,PASS,0.110 s,0.00 MiB,0.00 MiB,5,0,0.004365 ms,91.316151 mW,398595.000000 pJ
|
||||
gemm/dynamic_bias,PASS,0.092 s,0.00 MiB,0.00 MiB,5,0,0.002665 ms,91.445779 mW,243703.000000 pJ
|
||||
gemm/dynamic_bias_alpha_beta,PASS,0.089 s,0.00 MiB,0.00 MiB,5,0,0.005629 ms,91.279268 mW,513811.000000 pJ
|
||||
gemm/dynamic_transB,PASS,0.077 s,0.00 MiB,0.00 MiB,5,0,0.001301 ms,91.378171 mW,118883.000000 pJ
|
||||
gemm/huge_1024,PASS,0.219 s,0.01 MiB,0.10 MiB,73,64,0.017522 ms,215.037402 mW,3767885.360000 pJ
|
||||
gemm/large,PASS,0.097 s,0.02 MiB,0.03 MiB,17,16,0.011229 ms,140.152181 mW,1573768.840000 pJ
|
||||
gemm/large_k_small_n,PASS,0.106 s,0.01 MiB,0.01 MiB,9,8,0.004748 ms,133.481449 mW,633769.920000 pJ
|
||||
gemm/non_square,PASS,0.102 s,0.00 MiB,0.01 MiB,5,4,0.003527 ms,118.958310 mW,419565.960000 pJ
|
||||
gemm/scalar_bias,PASS,0.111 s,0.00 MiB,0.01 MiB,5,4,0.007072 ms,105.979208 mW,749484.960000 pJ
|
||||
gemm/simple,PASS,0.135 s,0.03 MiB,0.08 MiB,42,40,0.021640 ms,151.774196 mW,3284393.600000 pJ
|
||||
gemm/small,PASS,0.074 s,0.00 MiB,0.00 MiB,2,2,0.004420 ms,90.144000 mW,398436.480000 pJ
|
||||
gemm/small_k_large_n,PASS,0.129 s,0.01 MiB,0.02 MiB,17,8,0.007962 ms,131.005014 mW,1043061.920000 pJ
|
||||
gemm/transA,PASS,0.089 s,0.00 MiB,0.01 MiB,5,4,0.005762 ms,109.140743 mW,628868.960000 pJ
|
||||
gemm/transA_transB,PASS,0.115 s,0.00 MiB,0.01 MiB,5,4,0.005762 ms,109.140743 mW,628868.960000 pJ
|
||||
gemm/transB,PASS,0.068 s,0.00 MiB,0.01 MiB,5,4,0.003527 ms,118.958310 mW,419565.960000 pJ
|
||||
gemm/transB_with_bias,PASS,0.069 s,0.01 MiB,0.01 MiB,5,4,0.005046 ms,110.546762 mW,557818.960000 pJ
|
||||
gemm/with_bias,PASS,0.113 s,0.01 MiB,0.01 MiB,5,4,0.005562 ms,108.767882 mW,604966.960000 pJ
|
||||
gemv/constant,PASS,0.112 s,0.00 MiB,0.00 MiB,0,0,0.000000 ms,2.000000 mW,0.000000 pJ
|
||||
gemv/simple,PASS,0.136 s,0.00 MiB,0.01 MiB,6,4,0.005160 ms,111.150380 mW,573535.960000 pJ
|
||||
gemv/with_heterogeneous_constant,PASS,0.138 s,0.00 MiB,0.01 MiB,6,4,0.005549 ms,109.816536 mW,609371.960000 pJ
|
||||
gemv/with_homogeneous_constant,PASS,0.140 s,0.00 MiB,0.01 MiB,6,4,0.005549 ms,109.816536 mW,609371.960000 pJ
|
||||
gemv/with_scalar_constant,PASS,0.124 s,0.00 MiB,0.01 MiB,6,4,0.005549 ms,109.816536 mW,609371.960000 pJ
|
||||
matmul/basic,PASS,0.081 s,0.00 MiB,0.00 MiB,2,2,0.004420 ms,90.144000 mW,398436.480000 pJ
|
||||
matmul/batched_3d,PASS,0.133 s,0.00 MiB,0.01 MiB,5,4,0.005958 ms,108.588949 mW,646972.960000 pJ
|
||||
matmul/batched_3d_dynamic,PASS,0.105 s,0.00 MiB,0.00 MiB,9,0,0.003525 ms,92.330213 mW,325464.000000 pJ
|
||||
matmul/batched_left_constant,PASS,0.136 s,0.00 MiB,0.02 MiB,9,8,0.008822 ms,114.385164 mW,1009105.920000 pJ
|
||||
matmul/batched_lhs_broadcast,PASS,0.133 s,0.00 MiB,0.01 MiB,5,4,0.005681 ms,109.389361 mW,621440.960000 pJ
|
||||
matmul/batched_rhs_broadcast,PASS,0.134 s,0.00 MiB,0.01 MiB,5,4,0.005958 ms,108.588949 mW,646972.960000 pJ
|
||||
matmul/dynamic,PASS,0.093 s,0.00 MiB,0.00 MiB,5,0,0.001621 ms,91.421962 mW,148195.000000 pJ
|
||||
matmul/huge_1024,PASS,0.277 s,0.01 MiB,0.10 MiB,73,64,0.017522 ms,215.037402 mW,3767885.360000 pJ
|
||||
matmul/left_constant,PASS,0.123 s,0.00 MiB,0.01 MiB,5,4,0.005853 ms,108.861944 mW,637168.960000 pJ
|
||||
matmul/matrix_vector,PASS,0.150 s,0.52 MiB,0.78 MiB,168,173,0.384660 ms,202.131271 mW,77751814.880000 pJ
|
||||
matmul/vector_matrix,PASS,0.186 s,0.01 MiB,0.01 MiB,9,8,0.007409 ms,118.680243 mW,879301.920000 pJ
|
||||
mul/after_conv,PASS,0.127 s,0.00 MiB,0.00 MiB,4,3,0.005453 ms,107.639046 mW,586955.720000 pJ
|
||||
mul/basic,PASS,0.070 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
mul/channel_broadcast_1024,PASS,0.065 s,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
||||
mul/leading_dimension_broadcast,PASS,0.108 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
mul/scalar_constant,PASS,0.082 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
pool/avg_basic,PASS,0.070 s,0.00 MiB,0.00 MiB,1,0,0.011939 ms,78.022112 mW,931506.000000 pJ
|
||||
pool/avg_ceil_mode,PASS,0.107 s,0.00 MiB,0.00 MiB,1,0,0.004359 ms,78.033035 mW,340146.000000 pJ
|
||||
pool/avg_explicit_padding,PASS,0.111 s,0.00 MiB,0.00 MiB,1,0,0.008822 ms,78.027205 mW,688356.000000 pJ
|
||||
pool/avg_include_pad,PASS,0.075 s,0.00 MiB,0.00 MiB,1,0,0.008506 ms,78.016929 mW,663612.000000 pJ
|
||||
pool/avg_large_channels,PASS,0.064 s,0.04 MiB,0.02 MiB,1,0,0.178249 ms,78.280327 mW,13953390.000000 pJ
|
||||
pool/avg_non_uniform_stride,PASS,0.068 s,0.00 MiB,0.00 MiB,1,0,0.014513 ms,78.016537 mW,1132254.000000 pJ
|
||||
pool/avg_real_asymmetric_padding,PASS,0.064 s,0.00 MiB,0.00 MiB,1,0,0.025206 ms,78.024756 mW,1966692.000000 pJ
|
||||
pool/max_after_conv,PASS,0.070 s,0.00 MiB,0.00 MiB,6,4,0.006452 ms,96.374606 mW,621808.960000 pJ
|
||||
pool/max_basic,PASS,0.063 s,0.00 MiB,0.00 MiB,3,0,0.001634 ms,92.132191 mW,150544.000000 pJ
|
||||
pool/max_ceil_mode,PASS,0.065 s,0.00 MiB,0.00 MiB,2,0,0.001297 ms,79.111025 mW,102607.000000 pJ
|
||||
pool/max_global_style_kernel_equals_input,PASS,0.089 s,0.00 MiB,0.00 MiB,1,0,0.004366 ms,78.010994 mW,340596.000000 pJ
|
||||
pool/max_non_square_kernel,PASS,0.103 s,0.00 MiB,0.00 MiB,4,0,0.003409 ms,93.253447 mW,317901.000000 pJ
|
||||
pool/max_real_asymmetric_padding,PASS,0.088 s,0.00 MiB,0.00 MiB,4,0,0.003078 ms,93.124756 mW,286638.000000 pJ
|
||||
pool/max_same_upper,PASS,0.065 s,0.00 MiB,0.00 MiB,3,0,0.003024 ms,92.095238 mW,278496.000000 pJ
|
||||
pool/max_stride2_multichannel,PASS,0.086 s,0.00 MiB,0.00 MiB,3,0,0.004012 ms,92.269192 mW,370184.000000 pJ
|
||||
reduce_mean/4d_spatial,PASS,0.061 s,0.00 MiB,0.00 MiB,3,0,0.000321 ms,92.448598 mW,29676.000000 pJ
|
||||
reduce_mean/4d_spatial_keepdims_0,PASS,0.067 s,0.00 MiB,0.00 MiB,4,0,0.000655 ms,94.352672 mW,61801.000000 pJ
|
||||
reduce_mean/after_conv,PASS,0.115 s,0.00 MiB,0.00 MiB,5,3,0.005342 ms,106.951089 mW,571332.720000 pJ
|
||||
reduce_mean/all_axes_keepdims_0,PASS,0.103 s,0.00 MiB,0.00 MiB,2,0,0.000391 ms,79.237852 mW,30982.000000 pJ
|
||||
reduce_mean/all_axes_keepdims_1,PASS,0.086 s,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
||||
reduce_mean/basic,PASS,0.099 s,0.00 MiB,0.00 MiB,4,0,0.000373 ms,93.514745 mW,34881.000000 pJ
|
||||
reduce_mean/channel_axis_nchw,PASS,0.078 s,0.03 MiB,0.02 MiB,4,0,0.164926 ms,93.596631 mW,15436518.000000 pJ
|
||||
reduce_mean/keepdims_0,PASS,0.073 s,0.00 MiB,0.00 MiB,5,0,0.000748 ms,91.401070 mW,68368.000000 pJ
|
||||
reduce_mean/large_dimension_1024,PASS,0.115 s,0.01 MiB,0.00 MiB,1,0,0.002785 ms,78.017235 mW,217278.000000 pJ
|
||||
reduce_mean/legacy_axes_1_2_keepdims_1,PASS,0.074 s,0.00 MiB,0.00 MiB,2,0,0.000271 ms,79.354244 mW,21505.000000 pJ
|
||||
reduce_mean/legacy_axis1_keepdims_0,PASS,0.111 s,0.00 MiB,0.00 MiB,9,0,0.001986 ms,92.501511 mW,183708.000000 pJ
|
||||
reduce_mean/legacy_axis1_keepdims_1,PASS,0.086 s,0.00 MiB,0.00 MiB,8,0,0.001373 ms,94.559359 mW,129830.000000 pJ
|
||||
reduce_mean/legacy_empty_axes_noop,PASS,0.115 s,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
||||
reduce_mean/legacy_nchw_spatial,PASS,0.090 s,0.00 MiB,0.00 MiB,3,0,0.000321 ms,92.448598 mW,29676.000000 pJ
|
||||
reduce_mean/legacy_negative_axis,PASS,0.110 s,0.00 MiB,0.00 MiB,6,0,0.000553 ms,93.520796 mW,51717.000000 pJ
|
||||
reduce_mean/legacy_reduce_all_keepdims_1,PASS,0.107 s,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
||||
reduce_mean/negative_axis,PASS,0.120 s,0.00 MiB,0.00 MiB,6,0,0.000553 ms,93.520796 mW,51717.000000 pJ
|
||||
relu/4d,PASS,0.116 s,0.00 MiB,0.00 MiB,1,0,0.000521 ms,78.184261 mW,40734.000000 pJ
|
||||
relu/after_conv,PASS,0.078 s,0.00 MiB,0.00 MiB,3,3,0.004956 ms,106.998935 mW,530286.720000 pJ
|
||||
relu/after_gemm,PASS,0.077 s,0.01 MiB,0.01 MiB,5,4,0.007513 ms,105.158653 mW,790056.960000 pJ
|
||||
relu/basic,PASS,0.066 s,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
||||
reshape/4d_to_2d_flatten,PASS,0.098 s,0.00 MiB,0.00 MiB,1,0,0.000258 ms,78.279070 mW,20196.000000 pJ
|
||||
reshape/infer_dim_minus_one,PASS,0.105 s,0.00 MiB,0.00 MiB,1,0,0.000162 ms,78.296296 mW,12684.000000 pJ
|
||||
reshape/same_rank,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,0.000162 ms,78.296296 mW,12684.000000 pJ
|
||||
reshape/zero_copies_input_dim,PASS,0.090 s,0.00 MiB,0.00 MiB,1,0,0.000162 ms,78.296296 mW,12684.000000 pJ
|
||||
resize/height_only,PASS,0.104 s,0.00 MiB,0.00 MiB,1,0,0.000795 ms,78.060377 mW,62058.000000 pJ
|
||||
resize/nearest_2x,PASS,0.104 s,0.00 MiB,0.00 MiB,1,0,0.001422 ms,78.033755 mW,110964.000000 pJ
|
||||
resize/nearest_downsample,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,0.000481 ms,78.099792 mW,37566.000000 pJ
|
||||
resize/non_uniform,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,0.002108 ms,78.034156 mW,164496.000000 pJ
|
||||
resize/width_only,PASS,0.068 s,0.00 MiB,0.00 MiB,1,0,0.000792 ms,78.060606 mW,61824.000000 pJ
|
||||
resize/with_sizes,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,0.000951 ms,78.050473 mW,74226.000000 pJ
|
||||
sigmoid/4d,PASS,0.104 s,0.00 MiB,0.00 MiB,1,0,0.000521 ms,78.184261 mW,40734.000000 pJ
|
||||
sigmoid/after_gemm,PASS,0.118 s,0.01 MiB,0.01 MiB,5,4,0.007513 ms,105.158653 mW,790056.960000 pJ
|
||||
sigmoid/basic,PASS,0.083 s,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
||||
slice/2d_basic,PASS,0.067 s,0.00 MiB,0.00 MiB,1,0,0.000242 ms,78.297521 mW,18948.000000 pJ
|
||||
slice/after_conv,PASS,0.111 s,0.00 MiB,0.01 MiB,7,6,0.011296 ms,118.190765 mW,1335082.880000 pJ
|
||||
slice/default_axes,PASS,0.065 s,0.00 MiB,0.00 MiB,1,0,0.000242 ms,78.297521 mW,18948.000000 pJ
|
||||
slice/large_channel_1024,PASS,0.060 s,0.01 MiB,0.00 MiB,1,0,0.002832 ms,78.144068 mW,221304.000000 pJ
|
||||
slice/nchw_spatial_crop,PASS,0.067 s,0.00 MiB,0.00 MiB,1,0,0.001302 ms,78.239631 mW,101868.000000 pJ
|
||||
slice/negative_axis,PASS,0.098 s,0.00 MiB,0.00 MiB,1,0,0.000562 ms,78.298932 mW,44004.000000 pJ
|
||||
slice/negative_indices,PASS,0.106 s,0.00 MiB,0.00 MiB,1,0,0.000322 ms,78.298137 mW,25212.000000 pJ
|
||||
slice/step2,PASS,0.068 s,0.00 MiB,0.00 MiB,1,0,0.002042 ms,78.293830 mW,159876.000000 pJ
|
||||
softmax/3d_last_axis,PASS,0.072 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
||||
softmax/basic,PASS,0.088 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
||||
softmax/channel_axis,PASS,0.110 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
||||
softmax/large_dimension_1024,PASS,0.104 s,0.01 MiB,0.01 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
||||
softmax/negative_axis,PASS,0.118 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
||||
split/basic,PASS,0.077 s,0.00 MiB,0.00 MiB,1,0,0.000403 ms,78.297767 mW,31554.000000 pJ
|
||||
split/equal_three_way,PASS,0.107 s,0.00 MiB,0.00 MiB,1,0,0.000564 ms,78.297872 mW,44160.000000 pJ
|
||||
split/negative_axis,PASS,0.111 s,0.00 MiB,0.00 MiB,1,0,0.001083 ms,78.288089 mW,84786.000000 pJ
|
||||
split/uneven_channel_axis_4d,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,0.000242 ms,78.297521 mW,18948.000000 pJ
|
||||
sub/after_gemm,PASS,0.068 s,0.01 MiB,0.01 MiB,5,4,0.007784 ms,104.703618 mW,815012.960000 pJ
|
||||
sub/basic,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
sub/broadcast_row,PASS,0.075 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
sub/channel_broadcast_1024,PASS,0.052 s,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
||||
sub/constant_lhs_broadcast,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,0.000322 ms,78.223602 mW,25188.000000 pJ
|
||||
sub/leading_dimension_broadcast,PASS,0.053 s,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
||||
|
@@ -1,8 +1,11 @@
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
_METRIC_PATTERNS = {
|
||||
"output_count": r"output count:\s+([0-9]+)\s+samples",
|
||||
@@ -14,6 +17,14 @@ _METRIC_PATTERNS = {
|
||||
}
|
||||
|
||||
|
||||
def read_raptor_instruction_count(path):
|
||||
with open(path, "rb") as f:
|
||||
magic, version, count = struct.unpack("<4sII", f.read(12))
|
||||
if magic != b"PIMB" or version != 1:
|
||||
raise ValueError(f"Invalid Raptor binary instruction file: {path}")
|
||||
return count
|
||||
|
||||
|
||||
def parse_pimsim_nn_metrics(output):
|
||||
metrics = {"raw_output": output}
|
||||
for name, pattern in _METRIC_PATTERNS.items():
|
||||
@@ -45,6 +56,46 @@ def export_raptor_latency_artifact(pim_dir, output_dir):
|
||||
json.dump(config, f, separators=(",", ":"))
|
||||
f.write("\n")
|
||||
|
||||
binary_sources = sorted(pim_dir.glob("core_*.pim"), key=lambda path: int(path.stem.split("_")[1]))
|
||||
if binary_sources:
|
||||
record_dtype = np.dtype([
|
||||
("opcode", "u1"), ("rd", "u1"), ("r1", "u1"), ("flags", "u1"),
|
||||
("r2_or_imm", "<i4"), ("generic1", "<i4"),
|
||||
("generic2", "<i4"), ("generic3", "<i4"),
|
||||
])
|
||||
for source in binary_sources:
|
||||
destination = output_dir / source.name
|
||||
shutil.copyfile(source, destination)
|
||||
count = read_raptor_instruction_count(destination)
|
||||
if destination.stat().st_size != 12 + count * record_dtype.itemsize:
|
||||
raise ValueError(f"Invalid Raptor binary instruction file: {source}")
|
||||
records = np.memmap(destination, dtype=record_dtype, mode="r+", offset=12, shape=(count,))
|
||||
scalar_sldi = np.zeros(count, dtype=bool)
|
||||
vmv = records["opcode"] == 22
|
||||
sldi = records["opcode"] == 1
|
||||
for register in np.unique(records["r2_or_imm"][vmv]):
|
||||
definitions = np.flatnonzero(sldi & (records["rd"] == register))
|
||||
consumers = np.flatnonzero(vmv & (records["r2_or_imm"] == register))
|
||||
reaching = np.searchsorted(definitions, consumers) - 1
|
||||
scalar_sldi[definitions[reaching[reaching >= 0]]] = True
|
||||
for start in range(0, count, 1_000_000):
|
||||
chunk = records[start:start + 1_000_000]
|
||||
setbw = chunk["opcode"] == 8
|
||||
chunk["generic1"][setbw] = 8
|
||||
chunk["generic2"][setbw] = 8
|
||||
address_sldi = (chunk["opcode"] == 1) & ~scalar_sldi[start:start + len(chunk)]
|
||||
if np.any(chunk["r2_or_imm"][address_sldi] % 4):
|
||||
raise ValueError(f"Raptor address is not aligned to its fp32 element width: {source}")
|
||||
chunk["r2_or_imm"][address_sldi] //= 4
|
||||
transfer = (chunk["opcode"] >= 25) & (chunk["opcode"] <= 30)
|
||||
if np.any(chunk["generic2"][transfer] % 4) or np.any(chunk["generic3"][transfer] % 4):
|
||||
raise ValueError(f"Raptor transfer field is not aligned to its fp32 element width: {source}")
|
||||
chunk["generic2"][transfer] //= 4
|
||||
chunk["generic3"][transfer] //= 4
|
||||
records.flush()
|
||||
del records
|
||||
return output_dir
|
||||
|
||||
byte_size_fields = {
|
||||
"ld": "size",
|
||||
"st": "size",
|
||||
@@ -56,12 +107,19 @@ def export_raptor_latency_artifact(pim_dir, output_dir):
|
||||
for source in sorted(pim_dir.glob("core_*.json"), key=lambda path: int(path.stem.split("_")[1])):
|
||||
with open(source, encoding="utf-8") as f:
|
||||
instructions = json.load(f)
|
||||
for instruction in instructions:
|
||||
last_sldi = {}
|
||||
scalar_sldi = set()
|
||||
for index, instruction in enumerate(instructions):
|
||||
if instruction["op"] == "sldi":
|
||||
last_sldi[instruction["rd"]] = index
|
||||
elif instruction["op"] == "vmv" and instruction["rs2"] in last_sldi:
|
||||
scalar_sldi.add(last_sldi[instruction["rs2"]])
|
||||
for index, instruction in enumerate(instructions):
|
||||
op = instruction["op"]
|
||||
if op == "setbw":
|
||||
instruction["ibiw"] = 8
|
||||
instruction["obiw"] = 8
|
||||
elif op == "sldi":
|
||||
elif op == "sldi" and index not in scalar_sldi:
|
||||
instruction["imm"] = int8_bytes(instruction["imm"], "address")
|
||||
if field := byte_size_fields.get(op):
|
||||
instruction[field] = int8_bytes(instruction[field], f"{op} {field}")
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import numpy as np
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
@@ -10,7 +12,7 @@ from colorama import Style, Fore
|
||||
from .gen_network_runner import gen_network_runner
|
||||
from .onnx_utils import gen_random_inputs, save_inputs_to_files, onnx_io, write_inputs_to_memory_bin, _ONNX_TO_NP
|
||||
from .raptor import compile_with_raptor
|
||||
from .pimsim_nn import export_raptor_latency_artifact, parse_pimsim_nn_metrics
|
||||
from .pimsim_nn import export_raptor_latency_artifact, parse_pimsim_nn_metrics, read_raptor_instruction_count
|
||||
from .subprocess_utils import run_command_with_reporter
|
||||
|
||||
STAGE_TITLES = (
|
||||
@@ -80,6 +82,35 @@ class ValidationResult:
|
||||
pimsim_power_mw: float | None = None
|
||||
pimsim_energy_pj: float | None = None
|
||||
pimsim_status: str = PIMSIM_SKIPPED
|
||||
compile_time_s: float | None = None
|
||||
host_memory_bytes: int | None = None
|
||||
cores_memory_bytes: int | None = None
|
||||
used_core_count: int | None = None
|
||||
used_crossbar_count: int | None = None
|
||||
|
||||
|
||||
_MEMORY_UNITS = {"B": 1, "KB": 1 << 10, "MB": 1 << 20, "GB": 1 << 30}
|
||||
|
||||
|
||||
def collect_pim_resource_metrics(pim_dir):
|
||||
pim_dir = Path(pim_dir)
|
||||
report_path = pim_dir.parent / "reports" / "memory_report.txt"
|
||||
report = report_path.read_text(encoding="utf-8") if report_path.exists() else ""
|
||||
|
||||
def memory_bytes(label):
|
||||
match = re.search(rf"^\s*{re.escape(label)}:\s+([0-9.]+)\s+(B|KB|MB|GB)$", report, re.MULTILINE)
|
||||
return round(float(match.group(1)) * _MEMORY_UNITS[match.group(2)]) if match else None
|
||||
|
||||
with open(pim_dir / "config.json", encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
used_cores = sum(read_raptor_instruction_count(path) > 0 for path in pim_dir.glob("core_*.pim"))
|
||||
used_crossbars = sum(sum(groups) for groups in config.get("array_group_map", {}).values())
|
||||
return {
|
||||
"host_memory_bytes": memory_bytes("Host memory"),
|
||||
"cores_memory_bytes": memory_bytes("Local memory after reuse"),
|
||||
"used_core_count": used_cores,
|
||||
"used_crossbar_count": used_crossbars,
|
||||
}
|
||||
|
||||
|
||||
class ProgressReporter:
|
||||
@@ -416,8 +447,6 @@ def validate_network(network_onnx_path, raptor_path, onnx_include_dir,
|
||||
pimsim_nn_build_dir = Path(pimsim_nn_build_dir).resolve()
|
||||
pimsim_config_path = Path(pimsim_config_path).resolve()
|
||||
compile_extra_args = list(raptor_extra_args or [])
|
||||
if pimsim_enabled and "--pim-emit-json" not in compile_extra_args:
|
||||
compile_extra_args.append("--pim-emit-json")
|
||||
owns_reporter = reporter is None
|
||||
reporter = reporter or ProgressReporter(model_total, stages_per_model=len(MODE_STAGE_TITLES[mode]), verbose=verbose)
|
||||
|
||||
@@ -435,6 +464,8 @@ def validate_network(network_onnx_path, raptor_path, onnx_include_dir,
|
||||
f" {Style.BRIGHT}Validating {network_onnx_path.name}{Style.RESET_ALL}")
|
||||
failed_with_exception = False
|
||||
pim_pass_timings = {}
|
||||
compile_time_s = None
|
||||
resource_metrics = {}
|
||||
|
||||
try:
|
||||
stem = network_onnx_path.stem
|
||||
@@ -443,6 +474,19 @@ def validate_network(network_onnx_path, raptor_path, onnx_include_dir,
|
||||
runner_path = runner_build_dir / "runner"
|
||||
pim_output_base = raptor_dir / stem
|
||||
|
||||
def compile_pim():
|
||||
nonlocal compile_time_s, resource_metrics
|
||||
started = time.perf_counter()
|
||||
timings = compile_with_raptor(
|
||||
network_onnx_path, raptor_path, pim_output_base, crossbar_size,
|
||||
crossbar_count, core_count=core_count,
|
||||
raptor_extra_args=compile_extra_args, cwd=raptor_dir,
|
||||
verbose=verbose, reporter=reporter,
|
||||
timeout_sec=command_timeout_seconds)
|
||||
compile_time_s = time.perf_counter() - started
|
||||
resource_metrics = collect_pim_resource_metrics(raptor_dir / "pim")
|
||||
return timings
|
||||
|
||||
if mode != MODE_RUN_ONLY:
|
||||
print_stage(reporter, model_index, model_total, network_onnx_path.name, "Compile ONNX")
|
||||
network_so_path, network_mlir_path = compile_onnx_network(
|
||||
@@ -468,16 +512,14 @@ def validate_network(network_onnx_path, raptor_path, onnx_include_dir,
|
||||
|
||||
if mode == MODE_COMPILE_ONLY:
|
||||
print_stage(reporter, model_index, model_total, network_onnx_path.name, "Compile PIM")
|
||||
pim_pass_timings = compile_with_raptor(
|
||||
network_onnx_path, raptor_path, pim_output_base, crossbar_size, crossbar_count,
|
||||
core_count=core_count,
|
||||
raptor_extra_args=compile_extra_args,
|
||||
cwd=raptor_dir, verbose=verbose, reporter=reporter, timeout_sec=command_timeout_seconds)
|
||||
pim_pass_timings = compile_pim()
|
||||
print_info(reporter, f"PIM artifacts saved to {raptor_dir / 'pim'}")
|
||||
reporter.advance()
|
||||
reporter.record_result(True)
|
||||
reporter.log(Style.BRIGHT + f"Result: {Fore.GREEN}PASS{Style.RESET_ALL}" + Style.RESET_ALL)
|
||||
return ValidationResult(passed=True, pim_pass_timings=pim_pass_timings)
|
||||
return ValidationResult(
|
||||
passed=True, pim_pass_timings=pim_pass_timings,
|
||||
compile_time_s=compile_time_s, **resource_metrics)
|
||||
|
||||
if mode == MODE_RUN_ONLY:
|
||||
required_paths = [
|
||||
@@ -489,6 +531,7 @@ def validate_network(network_onnx_path, raptor_path, onnx_include_dir,
|
||||
missing = [f"{description} at {path}" for path, description in required_paths if not path.exists()]
|
||||
if missing:
|
||||
raise FileNotFoundError("run-only mode requires existing artifacts:\n " + "\n ".join(missing))
|
||||
resource_metrics = collect_pim_resource_metrics(raptor_dir / "pim")
|
||||
|
||||
print_stage(reporter, model_index, model_total, network_onnx_path.name, "Generate Inputs")
|
||||
inputs_descriptor, outputs_descriptor = onnx_io(network_onnx_path)
|
||||
@@ -508,11 +551,7 @@ def validate_network(network_onnx_path, raptor_path, onnx_include_dir,
|
||||
|
||||
if mode != MODE_RUN_ONLY:
|
||||
print_stage(reporter, model_index, model_total, network_onnx_path.name, "Compile PIM")
|
||||
pim_pass_timings = compile_with_raptor(
|
||||
network_onnx_path, raptor_path, pim_output_base, crossbar_size, crossbar_count,
|
||||
core_count=core_count,
|
||||
raptor_extra_args=compile_extra_args,
|
||||
cwd=raptor_dir, verbose=verbose, reporter=reporter, timeout_sec=command_timeout_seconds)
|
||||
pim_pass_timings = compile_pim()
|
||||
print_info(reporter, f"PIM artifacts saved to {raptor_dir / 'pim'}")
|
||||
reporter.advance()
|
||||
|
||||
@@ -587,6 +626,8 @@ def validate_network(network_onnx_path, raptor_path, onnx_include_dir,
|
||||
pimsim_power_mw=pimsim_power_mw,
|
||||
pimsim_energy_pj=pimsim_energy_pj,
|
||||
pimsim_status=pimsim_status,
|
||||
compile_time_s=compile_time_s,
|
||||
**resource_metrics,
|
||||
)
|
||||
except Exception:
|
||||
failed_with_exception = True
|
||||
|
||||
+45
-26
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
@@ -140,6 +141,17 @@ def format_pimsim_metric(result, value, unit):
|
||||
return result.pimsim_status
|
||||
|
||||
|
||||
def format_memory(byte_count):
|
||||
if byte_count is None:
|
||||
return "-"
|
||||
return f"{byte_count / (1 << 20):.2f} MiB"
|
||||
|
||||
|
||||
def operation_label(relative_path):
|
||||
path = Path(relative_path)
|
||||
return str(path.parent) if path.parent != Path(".") else path.stem
|
||||
|
||||
|
||||
def main():
|
||||
script_dir = Path(__file__).parent.resolve()
|
||||
pimcomp_configs_dir = script_dir / "pimsim_configs" / "pimcomp"
|
||||
@@ -216,6 +228,7 @@ def main():
|
||||
removed_count = 0
|
||||
for onnx_path in onnx_files:
|
||||
removed_count += len(clean_workspace_artifacts(onnx_path.parent, onnx_path.stem))
|
||||
(operations_dir / "validation_results.csv").unlink(missing_ok=True)
|
||||
print(Style.BRIGHT + f"Removed {removed_count} generated artifact path(s)." + Style.RESET_ALL)
|
||||
sys.exit(0)
|
||||
|
||||
@@ -343,38 +356,44 @@ def main():
|
||||
# Summary
|
||||
n_passed = sum(1 for result in results.values() if result.passed)
|
||||
n_total = len(results)
|
||||
status_width = len("Result")
|
||||
path_width = max(len("Operation"), *(len(rel) for rel in results))
|
||||
formatted_metrics = {
|
||||
rel: (
|
||||
headers = ("Operation", "Result", "Compile", "Host mem", "Cores mem",
|
||||
"Cores", "Xbars", "Latency", "Power", "Energy")
|
||||
rows = []
|
||||
for rel, result in results.items():
|
||||
rows.append((
|
||||
operation_label(rel), "PASS" if result.passed else "FAIL",
|
||||
f"{result.compile_time_s:.3f} s" if result.compile_time_s is not None else "-",
|
||||
format_memory(result.host_memory_bytes),
|
||||
format_memory(result.cores_memory_bytes),
|
||||
str(result.used_core_count) if result.used_core_count is not None else "-",
|
||||
str(result.used_crossbar_count) if result.used_crossbar_count is not None else "-",
|
||||
format_pimsim_metric(result, result.pimsim_latency_ms, "ms"),
|
||||
format_pimsim_metric(result, result.pimsim_power_mw, "mW"),
|
||||
format_pimsim_metric(result, result.pimsim_energy_pj, "pJ"),
|
||||
)
|
||||
for rel, result in results.items()
|
||||
}
|
||||
latency_width = max(len("Latency"), *(len(metrics[0]) for metrics in formatted_metrics.values()))
|
||||
power_width = max(len("Power"), *(len(metrics[1]) for metrics in formatted_metrics.values()))
|
||||
energy_width = max(len("Energy"), *(len(metrics[2]) for metrics in formatted_metrics.values()))
|
||||
separator = (
|
||||
f"+-{'-' * path_width}-+-{'-' * status_width}-+-{'-' * latency_width}"
|
||||
f"-+-{'-' * power_width}-+-{'-' * energy_width}-+")
|
||||
))
|
||||
widths = [max(len(header), *(len(row[index]) for row in rows))
|
||||
for index, header in enumerate(headers)]
|
||||
separator = "+-" + "-+-".join("-" * width for width in widths) + "-+"
|
||||
|
||||
def table_line(row):
|
||||
return "| " + " | ".join(
|
||||
value.ljust(widths[index]) if index < 2 else value.rjust(widths[index])
|
||||
for index, value in enumerate(row)) + " |"
|
||||
|
||||
print(separator)
|
||||
print(
|
||||
f"| {'Operation'.ljust(path_width)} | {'Result'.ljust(status_width)} | "
|
||||
f"{'Latency'.rjust(latency_width)} | {'Power'.rjust(power_width)} | "
|
||||
f"{'Energy'.rjust(energy_width)} |"
|
||||
)
|
||||
print(table_line(headers))
|
||||
print(separator)
|
||||
for rel, result in results.items():
|
||||
plain_status = "PASS" if result.passed else "FAIL"
|
||||
status = Fore.GREEN + plain_status.ljust(status_width) + Style.RESET_ALL if result.passed else \
|
||||
Fore.RED + plain_status.ljust(status_width) + Style.RESET_ALL
|
||||
latency, power, energy = formatted_metrics[rel]
|
||||
print(
|
||||
f"| {rel.ljust(path_width)} | {status} | {latency.rjust(latency_width)} | "
|
||||
f"{power.rjust(power_width)} | {energy.rjust(energy_width)} |")
|
||||
for row in rows:
|
||||
line = table_line(row)
|
||||
color = Fore.GREEN if row[1] == "PASS" else Fore.RED
|
||||
line = line.replace(row[1].ljust(widths[1]),
|
||||
color + row[1].ljust(widths[1]) + Style.RESET_ALL, 1)
|
||||
print(line)
|
||||
print(separator)
|
||||
with (operations_dir / "validation_results.csv").open(
|
||||
"w", encoding="utf-8", newline=""
|
||||
) as results_file:
|
||||
csv.writer(results_file).writerows((headers, *rows))
|
||||
print("\n" + Style.BRIGHT + Fore.CYAN + "Summary" + Style.RESET_ALL)
|
||||
print(Style.BRIGHT + f"Passed: {n_passed}" + Style.RESET_ALL)
|
||||
print(Style.BRIGHT + f"Failed: {n_total - n_passed}" + Style.RESET_ALL)
|
||||
|
||||
Reference in New Issue
Block a user