インストールは、Linux版のVMwareで行ったので、メニューの項目が英語になってます。File→New Virtual Machine→Create a New Virtual Machine→Typical (recommended)
→I will install the operationg system later→Linux→Ubuntu 64bitの手順で仮想マシンを作成。ディスクはデフォルトの20Gじゃ少ないので512Gに増やしました (ここを多くしても実際に仮想マシン内で使用しない限りホストマシンのディスクを圧迫することはありません)。メモリはとりあえずデフォルトの4Gで (こちらは大きくするだけホストマシンのメモリを食います)。VM→Settings→CD/DVDでダウンロードしたisoをマウントし起動。
今回は問題発生への対処です。ある人から、g++ version 13でkvがまったくコンパイルできない、clang++では問題ないと連絡が来ました。実際、ubuntu 23.10を入れて試してみると、test-rounding.ccとかtest-interval.ccみたいな基本的なプログラムすらコンパイルエラーになってしまいました。
調べてみると、「_Float64xをサポートしているのはgccのみで、もともとg++では_Float64xをまったくサポートしていなかった。しかしversion 12までは単なるlong doubleのtypedefだったので、たまたまg++でも動いてしまっていた。最新のg++ version 13では_Float64xを部分的にサポートするようになったがlibstdc++はサポートしていない状態になり、結果的にまったく使えなくなってしまった」ということのようです。やりとりはこの辺。
gccのドキュメントの6.12 Additional Floating Typesでは、「As an extension, GNU C and GNU C++ support additional floating types, (中略) _float80 is available on the i386, x86_64, and IA-64 targets, and supports the 80-bit (XFmode) floating type. It is an alias for the type name _Float64x on these targets. 」とはっきり書いているので、g++でも_Float64xはサポートされているように見えるのですが。
git clone https://github.com/mkubecek/vmware-host-modules
cd vmware-host-modules
git checkout workstation-16.2.3
make clean
make
sudo make install
sudo modprobe -a vmw_vmci vmmon vmnet
sudo service vmware restart
May 21 17:43:44 exa kernel: [14661.785888] userif-3: sent link up event.
May 21 17:43:47 exa kernel: [14664.977941] userif-3: sent link down event.
May 21 17:43:47 exa kernel: [14664.977949] userif-3: sent link up event.
May 21 17:43:52 exa kernel: [14669.758177] userif-3: sent link down event.
May 21 17:43:52 exa kernel: [14669.758186] userif-3: sent link up event.
May 21 17:44:00 exa kernel: [14677.442456] userif-3: sent link down event.
May 21 17:44:00 exa kernel: [14677.442465] userif-3: sent link up event.
May 21 17:44:03 exa kernel: [14680.650489] userif-3: sent link down event.
There are 5 choices for the alternative libblas.so-x86_64-linux-gnu (providing /usr/lib/x86_64-linux-gnu/libblas.so).
Selection Path Priority Status
------------------------------------------------------------
0 /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so 100 auto mode
1 /usr/lib/x86_64-linux-gnu/atlas/libblas.so 35 manual mode
2 /usr/lib/x86_64-linux-gnu/blas/libblas.so 10 manual mode
* 3 /usr/lib/x86_64-linux-gnu/blis-openmp/libblas.so 80 manual mode
4 /usr/lib/x86_64-linux-gnu/libmkl_rt.so 1 manual mode
5 /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so 100 manual mode
Press <enter> to keep the current choice[*], or type selection number:
There are 5 choices for the alternative libblas.so.3-x86_64-linux-gnu (providing /usr/lib/x86_64-linux-gnu/libblas.so.3).
Selection Path Priority Status
------------------------------------------------------------
0 /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 100 auto mode
1 /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3 35 manual mode
2 /usr/lib/x86_64-linux-gnu/blas/libblas.so.3 10 manual mode
* 3 /usr/lib/x86_64-linux-gnu/blis-openmp/libblas.so.3 80 manual mode
4 /usr/lib/x86_64-linux-gnu/libmkl_rt.so 1 manual mode
5 /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 100 manual mode
Press <enter> to keep the current choice[*], or type selection number:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// prototype declaration
void dgemm_(char *transA, char *transB, int *m, int *n, int *k, double *alpha, double *A, int *ldA, double *B, int *ldB, double *beta, double *C, int *ldC);
int main(int argc, char **argv)
{
int i, j;
int m, n, k;
int size;
double *a, *b, *c;
double alpha, beta;
int lda, ldb, ldc;
struct timespec ts1, ts2;
size = atoi(argv[1]);
m = size;
n = size;
k = size;
a = (double *)malloc(sizeof(double) * m * k); // m x k matrix
b = (double *)malloc(sizeof(double) * k * n); // k x n matrix
c = (double *)malloc(sizeof(double) * m * n); // m x n matrix
for (i=0; i<m; i++) {
for (j=0; j<k; j++) {
a[i + m * j] = rand() / (1.0 + RAND_MAX);
}
}
for (i=0; i<k; i++) {
for (j=0; j<n; j++) {
b[i + k * j] = rand() / (1.0 + RAND_MAX);
}
}
for (i=0; i<m; i++) {
for (j=0; j<n; j++) {
c[i + m * j] = 0;
}
}
alpha = 1.;
beta = 0.;
lda = m;
ldb = k;
ldc = m;
// dgemm_(TransA, TransB, M, N, K, alpha, A, LDA, B, LDB, beta, C, LDC)
// C = alpha * A * B + beta * C
// A=M*K, B=K*N, N=M*N
// Trans: "N"/"T"/"C"
// LDA = number of row of A
clock_gettime(CLOCK_REALTIME, &ts1);
dgemm_("N", "N", &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc);
clock_gettime(CLOCK_REALTIME, &ts2);
printf("%g\n", (ts2.tv_sec - ts1.tv_sec) + (ts2.tv_nsec - ts1.tv_nsec) / 1e9);
free(a);
free(b);
free(c);
return 0;
}