Several others have gotten you for what looks like confusion between mat[0][0] being of type float and &ptr[0][0] being of type float *, but you have another more subtle problem: ARRAYS ARE NOT POINTERS.
Normally arrays are a lot like pointers, but for very subtle reasons, float [][] is not compatible with float ** the way float [] and float * are.
In many contexts (such as being passed to a function), an array decays to a pointer to its first element. Thus, mat decays to &mat[0]. The type of an array T [] decays to a pointer T *, which means that the type mat decays to (and the type of &mat[0]) is float (*)[] - that is, a pointer to an array of fixed size.
Here is the difference between a float * and a float[]:
float * float[]
+-----+ +-----+-----+
| ptr | --> | 0.0 | 1.0 |
+-----+ +-----+-----+
Now here is the difference between a float ** and a float[][]:
float ** float *[] float[][] float (*)[]
+-----+ +-----+ +-----+-----+ +-----+ (imagine this
| ptr | --> | ptr | --> | 0.0 | 1.0 | <-- | ptr | pointing to
+-----+ +-----+ +-----+-----+ +-----+ the 0.0 cell)
| ptr | --> | 2.0 | 3.0 |
+-----+ +-----+-----+
Those types are, from left to right, pointer-to-pointer-to-float, array-of-pointers-to-float, array-of-arrays-of-floats, and pointer-to-array-offloats. The address of &float[0], converted to a float **, gets dereferenced twice as a pointer even though there is only one pointer - the pointer to float[0] (and thus, the rest of the array). Any value you get through this is garbage.
void bar(float foo[5][])