Первое, что нужно сделать, это то, что
nvcc -c MatMul.cu -o libmatmul.so
не создает разделяемую библиотеку, он просто компилируется в объектный файл. Общие библиотеки и объектные файлы - это совсем не одно и то же.
Кроме того, причина ошибки символа не найдена: C ++ искажение имени . Код хоста в исходных файлах CUDA компилируется с использованием компилятора хоста C ++, а не C. Поэтому имена символов в коде хоста, генерируемые компилятором, подвергаются искажению имен. Чтобы обойти это, самый простой способ - объявить функции, которые вы хотите вызывать из простого кода C, используя декларатор extern "C"
(см. здесь для разумного обзора опасностей совместимости C / C ++).