Majid Al-RaimiMACs, FLOPs and operations

COE 592Lecture 03Part 04

MACs, FLOPs and operations

Counting computation as multiply-accumulate operations for matrix products and each layer type, AlexNet's 724M MACs, and converting to FLOPs, FLOPS, OPs and OPS.

Concepts
5
Slides
23-29
Reading
30 min
Understood
0/5 concepts

Why this part matters

Part 02 measured what a network stores and part 03 what it must hold in memory. This part measures what it must compute. That number is the numerator of computation time in the Latency model of slide 8, the figure every accelerator datasheet is quoted against, and the figure you will report for any model in the research project.

The counting unit is the multiply-accumulate, and everything else is bookkeeping on top of it: how many MACs a matrix product costs, how many each layer type costs, what AlexNet adds up to, and how the count becomes FLOPs, OPs and finally milliseconds on a specific chip. The surprise waiting at the centre of the part is that the layers holding almost all of AlexNet's weights do almost none of its arithmetic. Every exam question on efficiency metrics circles back to that inversion.

By the end you can

  1. Define a multiply-accumulate operation and count MACs for a matrix-vector product and a matrix-matrix product.
  2. Fill the MACs table for linear, convolution, grouped and depthwise layers, and explain why conv MACs equal parameters times h_o·w_o.
  3. Reproduce AlexNet's 724M MACs layer by layer and explain why convolutions dominate compute while linear layers dominate parameters.
  4. Convert MACs to FLOPs and OPs, and tell a count (FLOPs, OPs) apart from a rate (FLOPS, OPS).
  5. Estimate T_computation for a model on a device from the model's OPs and the device's OPS.

Start with one neuron that has four inputs. Its output before the activation function is w₁x₁ + w₂x₂ + w₃x₃ + w₄x₄. A processor evaluates that as four identical steps: multiply a weight by an input, add the product to a running total. Each step is one multiply-accumulate operation, and the whole of neural network inference is this step repeated a few hundred million times.

aa+bca \leftarrow a + b \cdot c
One MAC: multiply b by c and accumulate into a

The definition is standard well beyond this course. The Wikipedia entry on the multiply-accumulate operation gives exactly a ← a + (b × c), and notes that IEEE 754-2008 defines a fused multiply-add that performs the whole step with a single rounding. Sze, Chen, Yang and Emer call the MAC "the fundamental component" of DNN processing in their survey of efficient DNN hardware. Counting MACs is therefore counting what the hardware executes, not an abstraction layered over it.

From one neuron to a matrix-vector product

A layer of m neurons that each read the same n inputs is a matrix-vector multiplication: an m × n weight matrix times an n-vector. Each of the m outputs needs n MACs, one per weight in its row, so the product costs m · n MACs. Notice that this is also the number of weights. In a matrix-vector product, every weight is touched exactly once.

Feed the layer a batch of inputs at once and the vector becomes a matrix. The slide renames the dimensions here: the input count becomes k and the letter n is reused for the batch, the number of columns of B. The result is a general matrix-matrix multiplication: A of size m × k times B of size k × n gives C of size m × n. Every one of the m · n cells of C is a dot product over the shared dimension k, so it costs k MACs, and the whole product costs m · n · k.

MACsMV=mnMACsGEMM=mnk\text{MACs}_{MV} = m \cdot n \qquad \text{MACs}_{GEMM} = m \cdot n \cdot k
Rows times columns for a vector, rows times columns times the shared dimension for a matrix
Each cell of C is one dot product over the shared dimension: k pairs, k MACs. There are m × n such cells.

Dimensions used in the GEMM count

m
Rows of A and of C: the number of outputs (neurons)
k
Columns of A and rows of B: the shared dimension summed over, the number of inputs per neuron
n
Columns of B and of C: the number of input vectors, the batch

Why a whole network reduces to this

A Linear layer is literally a matrix-vector product at batch size one and a GEMM for a batch. Convolution looks different but is executed the same way: frameworks reorder the input patches into columns (the im2col trick described in the CS231n notes) so that a convolution becomes one large GEMM, and the MobileNets paper points out that this is why convolutions can ride on "highly optimized general matrix multiply (GEMM) functions". NVIDIA's performance guide states the cost of a GEMM as 2 · M · N · K floating point operations because "each FMA is 2 operations, a multiply and an add", which previews the FLOP conversion at the end of this part. Once you can count MACs for a matrix product, you can count them for every layer.

Recall

Write the MAC operation, and state how many MACs an m × n matrix times an n-vector costs.

a ← a + b · c. The product costs m · n MACs, one for every weight in the matrix.

Take the first layer of AlexNet. One filter spans all 3 input channels with an 11 × 11 window, so it holds 3 × 11 × 11 = 363 weights. Producing a single output pixel is one dot product of those 363 weights against a patch of the image: 363 MACs. But the filter does not produce one pixel. It slides to every one of the 55 × 55 = 3,025 output positions, and there are 96 filters. So the layer costs 363 × 3,025 × 96 = 105,415,200 MACs from only 34,848 weights.

That example contains the whole rule. In a convolution layer every weight is applied once per output position, so the MAC count is the parameter count from part 02 multiplied by the output height and width:

MACsconv=cocikhkwparametershowo\text{MACs}_{conv} = \underbrace{c_o \cdot c_i \cdot k_h \cdot k_w}_{\text{parameters}} \cdot h_o \cdot w_o
Parameters times output positions, at batch size n = 1 and ignoring bias
Nine weights stamped onto twenty-five output positions: 225 MACs from 9 parameters. The filter is reused, never copied.

The other rows of the slide's table follow from the same idea. A Linear layer has h_o = w_o = 1, so its MACs equal its parameters, c_o · c_i. A Grouped convolution splits the channels into g groups, so each filter sees only c_i / g input channels and both parameters and MACs are divided by g. A Depthwise convolution is the extreme case g = c_i = c_o: each filter sees exactly one channel, so c_i disappears from the formula entirely and only c_o · k_h · k_w weights remain, each still applied h_o · w_o times.

LayerParametersMACsMACs per parameter
Linearc_o · c_ic_o · c_i1
Convolutionc_o · c_i · k_h · k_wc_o · c_i · k_h · k_w · h_o · w_oh_o · w_o
Grouped convolutionc_o · c_i · k_h · k_w / gc_o · c_i · k_h · k_w · h_o · w_o / gh_o · w_o
Depthwise convolutionc_o · k_h · k_wc_o · k_h · k_w · h_o · w_oh_o · w_o
Parameters and MACs per layer type (batch size n = 1, bias ignored)

How a convolution slides, how padding and stride set the output size, and how groups partition channels were covered in lecture 02, part 02 and part 03. This part only counts, and it takes the kernel size and output shape of each layer as given.

Why this mirrors part 02

Goodfellow, Bengio and Courville explain parameter sharing in one sentence that is the whole story of this part: sharing "does not affect the runtime of forward propagation, it is still O(k × n), but it does further reduce the storage requirements of the model to k parameters". Convolution saves storage by reusing weights, and reusing weights is exactly what makes the arithmetic grow. That is why parts 02 and 04 are mirror images. The layers cheapest to store are the most expensive to run.

Worked example: the MobileNet block that makes depthwise worth it

The MobileNets paper replaces one standard 3 × 3 convolution with a depthwise 3 × 3 followed by a pointwise 1 × 1. Its equations 4 and 5 give the depthwise and separable costs, and dividing by the standard cost gives the ratio 1 / N + 1 / D_K², where N is the number of output channels and D_K the kernel size. The formulas in the table let you reproduce that with real numbers.

Worked example

Standard versus depthwise separable at 112 × 112, 32 to 64 channels

  1. Standard 3 × 3 convolution

    64 × 32 × 3 × 3 × 112 × 112 = 231,211,008 MACs.
  2. Depthwise 3 × 3

    32 × 3 × 3 × 112 × 112 = 3,612,672 MACs. No c_i factor.
  3. Pointwise 1 × 1

    64 × 32 × 1 × 1 × 112 × 112 = 25,690,112 MACs. A convolution with k = 1.
  4. Ratio

    (3,612,672 + 25,690,112) / 231,211,008 = 0.1267, and 1 / 64 + 1 / 9 = 0.1267.
  5. Result

    About 7.9× fewer MACs at 64 output channels, approaching the paper's "between 8 to 9 times less computation" as the channel count grows and the 1 / D_K² = 1 / 9 pointwise term is all that remains.

The calculator below lets you scrub every symbol in the table. Its FLOPs, OPs and hardware rows are explained in the last concept of this part; for now watch how parameters and MACs move apart as the output size grows.

SimulatorLayer compute calculator: MACs, FLOPs and computation time
Layer presets
k_h = k_wKernel size
Parameters34,848weightsc_o · c_i · k_h · k_w
MACs105,415,200(105.42 M)parameters × h_o × w_o = parameters × 3,025
MACs per parameter3,025uses per weightequal to h_o × w_o
FLOPs210.83 MFLOPs2 × MACs: one multiply and one add
OPs210.83 MOPssame count for integer weights and activations
Share of AlexNet14.6% of 724M MACsthis one layer against the whole network
Hardware: processor throughput100.0 GOPS
10^11.0 OPS

illustrative mobile GPU-class figure

T computation2.11msOPs of the layer ÷ OPS of the processor
Reading210.83 MOPs ÷ 100.0 GOPSthe numerator is a count, the denominator a rate

Drag h_o = w_o and watch MACs climb while parameters stay put: a convolution reuses every weight at every output position. Switch to linear and the two counts collapse into one. The hardware box only divides: the same layer takes 1000× longer at 1 GFLOPS than at 1 TFLOPS, and marketing peak TOPS are rarely sustained, so treat the time as a floor.

Quick check

A grouped convolution has c_i = 96, c_o = 256, a 5 × 5 kernel, a 27 × 27 output and g = 2. How many MACs does it perform?

Recall

A grouped convolution has 384 filters over 384 input channels, a 3 × 3 kernel, a 13 × 13 output and g = 2. How many MACs, how many parameters, and what is their ratio?

MACs: 384 · 384 · 9 · 169 / 2 = 112,140,288. Parameters: 384 · 384 · 9 / 2 = 663,552. The ratio is 169 = 13 × 13, one use of each weight per output position. This is AlexNet conv4.

Slide 25 hands you the eight weighted layers of AlexNet with their output shapes and an empty MACs column. Slide 26 fills it in, except for one layer hidden behind a question mark. Work through the column yourself before you read the answers. Every entry is the formula from the previous concept with the layer's numbers substituted, and the pooling layers contribute nothing because they hold no weights.

Worked example

AlexNet, layer by layer (batch size 1, bias ignored)

  1. conv1: 11 × 11, 3 to 96 channels, output 55 × 55

    96 × 3 × 11 × 11 × 55 × 55 = 105,415,200
  2. conv2: 5 × 5, 96 to 256 channels, groups 2, output 27 × 27

    256 × 96 × 5 × 5 × 27 × 27 / 2 = 223,948,800. Without the groups it would be 447,897,600; g = 2 halves it.
  3. conv3: 3 × 3, 256 to 384 channels, output 13 × 13

    384 × 256 × 3 × 3 × 13 × 13 = 149,520,384
  4. conv4: 3 × 3, 384 to 384 channels, groups 2, output 13 × 13

    384 × 384 × 3 × 3 × 13 × 13 / 2 = 112,140,288
  5. conv5: 3 × 3, 384 to 256 channels, groups 2, output 13 × 13

    This is the entry the slide hides. Compute it before revealing.

    Recall

    conv5 MACs?

    256 × 384 × 3 × 3 × 13 × 13 / 2 = 74,760,192
  6. fc6: 256 × 6 × 6 = 9,216 inputs to 4,096 outputs

    4,096 × 9,216 = 37,748,736. The flattened pooling output is the input vector.
  7. fc7: 4,096 to 4,096

    4,096 × 4,096 = 16,777,216
  8. fc8: 4,096 to 1,000 classes

    1,000 × 4,096 = 4,096,000
  9. Total

    724,406,816 MACs, the slide's "724M in total". Sze et al. list the same figure, 724M MACs and 61M weights, in their survey table.

Put the parameters next to the MACs

The total is not the interesting number. The interesting number appears when you place the parameter counts from part 02 beside the MACs and add a column for their ratio, which by the previous concept is just h_o · w_o.

LayerShapeParametersMACsMACs per parameter
conv196 × 3 × 11 × 11, out 55 × 5534,848105,415,2003,025
conv2256 × 96 × 5 × 5 / 2, out 27 × 27307,200223,948,800729
conv3384 × 256 × 3 × 3, out 13 × 13884,736149,520,384169
conv4384 × 384 × 3 × 3 / 2, out 13 × 13663,552112,140,288169
conv5256 × 384 × 3 × 3 / 2, out 13 × 13442,36874,760,192169
fc64096 × (256 × 6 × 6)37,748,73637,748,7361
fc74096 × 409616,777,21616,777,2161
fc81000 × 40964,096,0004,096,0001
conv1 to conv5five convolutions2,332,704 (3.8%)665,784,864 (91.9%)
fc6 to fc8three linear layers58,621,952 (96.2%)58,621,952 (8.1%)
Totaleight weighted layers60,954,656724,406,816
AlexNet: parameters and MACs per layer
The last column of the table, drawn. Each layer's slice of the MAC bar is its slice of the parameter bar stretched by h_o · w_o: conv1 grows 3,025 times, the linear layers not at all, so the convolution segments take over the lower bar.

The five convolutions hold 2,332,704 parameters, under 4% of the network, yet perform 665,784,864 MACs, 92% of the compute. The three linear layers hold 58,621,952 parameters, 96% of the network, yet perform only 58,621,952 MACs, 8% of the compute. The last column explains it: each conv1 weight is used 3,025 times, each conv3 to conv5 weight 169 times, each linear weight once. Large spatial maps early in the network make convolution compute heavy. Large c_i · c_o products late in the network make the linear layers parameter heavy.

InteractiveWhere AlexNet spends parameters versus compute
total 60,954,656 weights
fc6fc7fc8
conv1 to conv53.8%2.3M
fc6 to fc896.2%58.6M

Flip the toggle and watch which single layer is largest. Under parameters it is fc6, about 62% of the network on its own. Under MACs it is conv2, about 31%, while conv1, invisible on the parameter bar at 0.06%, grows to 15% because its 34,848 weights each fire 3,025 times. Each layer's exact count is listed below the bar.

  • conv134,848 (0.1%)
  • conv2307,200 (0.5%)
  • conv3884,736 (1.5%)
  • conv4663,552 (1.1%)
  • conv5442,368 (0.7%)
  • fc637,748,736 (61.9%)
  • fc716,777,216 (27.5%)
  • fc84,096,000 (6.7%)

What this means for making a model faster

The inversion sets the strategy for the rest of the course. Pruning or quantizing the linear layers shrinks Model size dramatically, because that is where the weights are, but it barely changes the MAC count and therefore barely changes computation time. To make inference faster you must attack the convolutions: fewer channels, grouped or depthwise filters as in MobileNet, or a lower input resolution so that h_o · w_o shrinks in every layer at once. The pruning lecture that follows will keep returning to this table, and when you profile a model for the research project, report both columns, not one.

Quick check

Pruning removes 90 percent of the weights in AlexNet's fc6 and fc7. Roughly how much does the network's total MAC count fall?

Recall

Which AlexNet layer family holds most of the parameters, which performs most of the MACs, and why?

The linear layers hold about 96% of the 61M parameters. The convolutions perform about 92% of the 724M MACs. Convolution MACs equal parameters times h_o · w_o, which is 3,025 for conv1 and 1 for every linear layer.

A MAC hides two arithmetic operations: a multiply and an add. When each is counted as one floating point operation, one MAC is two FLOPs, and AlexNet's 724,406,816 MACs become 1,448,813,632 FLOPs. The slide rounds that to 1.4G; the exact figure is 1.449G, and showing the factor of two matters more than the rounding.

FLOPs=2MACs\text{FLOPs} = 2 \cdot \text{MACs}
One multiply plus one add per MAC

The count on its own says nothing about time. To get time you need to know how fast a processor can drain it, and that is a different quantity with an almost identical name. FLOPS, with a capital S, is floating point operations per second: a throughput that belongs to the hardware. FLOPs, with a lowercase s, is a plural count that belongs to the model. TOP500 ranks supercomputers by exactly this rate, reporting Linpack results as Rmax and Rpeak in Flop/s, and NVIDIA's GPU performance background guide writes the time a math-limited kernel takes as its number of operations divided by the processor's math bandwidth, which is FLOPs over FLOPS.

FLOPS=FLOPssecondTcomputation=FLOPs of the modelFLOPS of the processor\text{FLOPS} = \frac{\text{FLOPs}}{\text{second}} \qquad T_{computation} = \frac{\text{FLOPs of the model}}{\text{FLOPS of the processor}}
A rate is a count per second; dividing a count by a rate gives a time
The hopper holds a count, the pipe drains at a rate, and the clock reads the quotient: 1.449 G FLOPs through 100 GFLOPS takes 14.5 ms.

This is the computation time term of the latency model on slide 8, where the numerator is a network specification and the denominator a hardware specification. Run AlexNet's count through a few devices and the scale of the answer changes by orders of magnitude while the model does not change at all.

ProcessorCount ÷ rateT_computation
1 GFLOPS1.449 × 10^9 / 10^91,449 ms
100 GFLOPS1.449 × 10^9 / 10^1114.5 ms
1 TFLOPS1.449 × 10^9 / 10^121.45 ms
67 TOPS (Orin Nano, INT8 sparse peak)1.449 × 10^9 / 6.7 × 10^130.022 ms
AlexNet's 1.449G FLOPs on different processors; the last row treats the count as OPs, as slide 28 allows for an INT8 model

OPs: the same count for any data type

The F in FLOP assumes floating point arithmetic. A quantized network, the kind you deploy on a microcontroller or an INT8 accelerator, stores weights and activations at an Bit width of 8 bits and multiplies integers. Those are not floating point operations, but they are still operations, and there are still two per MAC. The lecture therefore generalizes: an operation (OP) is one multiply or add of any data type, AlexNet is 724M × 2 = 1.4G OPs, and OPS is operations per second. The layer compute calculator in the second concept of this part uses OPS in its hardware box for exactly this reason: the formula for time does not care whether the operands were floats.

OPS=OPssecond\text{OPS} = \frac{\text{OPs}}{\text{second}}
The general form; FLOPS is the floating point special case
TermKindMeaningBelongs to
MACCountOne multiply accumulated into a sumA model, per inference
FLOPCountOne floating point multiply or add; a MAC is twoA model, per inference
OPCountOne operation of any data type; a MAC is twoA model, per inference
FLOPSRateFloating point operations per secondA processor
OPSRateOperations per second, any data typeA processor
Five terms, two kinds of quantity

Quick check

A model needs 3.6G FLOPs and a chip sustains 400 GFLOPS. What is T_computation?

Quick check

Why does the lecture generalize from FLOPs to OPs?

Quick check

A datasheet advertises a board at 67 TOPS. What kind of quantity is that?

Recall

State the rule that turns a MAC count into a FLOP count and a FLOP count into a time, then apply it: AlexNet on a 1 TFLOPS processor.

FLOPs = 2 × MACs, and T_computation = FLOPs / FLOPS. 2 × 724,406,816 = 1,448,813,632 FLOPs; 1.449 × 10^9 / 10^12 = 1.45 ms.

Recall

Why use OPs rather than FLOPs for an INT8 model, and how many OPs per MAC?

Its multiplies and adds act on integers, so they are not floating point operations. OPs counts operations of any data type. There are still two per MAC, one multiply and one add.

The reading list behind this lecture

Slide 29 lists the ten works the lecture draws on. Six were used directly in this lecture's counting and examples; the other four appear here as context for the architectures and normalization layers of lecture 02 and the pruning lectures ahead.

Used in this lecture

Context for other lectures

Recap

If you remember nothing else

  • A MAC is a <- a + b·c. A matrix-vector product costs m·n MACs and a matrix-matrix product m·n·k MACs.
  • Linear: c_o·c_i. Convolution: c_o·c_i·k_h·k_w·h_o·w_o. Grouped: divide by g. Depthwise: c_o·k_h·k_w·h_o·w_o, with no c_i.
  • Convolution MACs equal parameters times h_o·w_o. Linear MACs equal parameters.
  • AlexNet performs 724,406,816 MACs. Its convolutions hold 3.8 percent of the parameters but perform 92 percent of the MACs; the linear layers are the reverse.
  • One MAC is two FLOPs, so AlexNet is about 1.45G FLOPs, which the slide rounds to 1.4G.
  • FLOPs and OPs are counts that belong to a model. FLOPS and OPS are rates that belong to a processor. T_computation = OPs / OPS.
  • OPs generalizes FLOPs to quantized integer networks; the count per MAC stays two.
  • Conventions differ: many papers and tools report MACs under the label FLOPs. Check before comparing numbers.

Sources