Skip to content

Instantly share code, notes, and snippets.

@cournape
Created March 13, 2012 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cournape/2027412 to your computer and use it in GitHub Desktop.
Save cournape/2027412 to your computer and use it in GitHub Desktop.
Accelerate framework bug with fork
/*
* This small snippet shows an issue when calling dgemm for square matrices above a certain size inside a forked child process.
*
* To reproduce the issue:
* - compile it ("gcc -framework Accelerate bug.c -o bug")
* - ./bug 64 (64x64 matrix) will show the output for d matrix for both parents and child:
computing for size 64
c[0][0] is 64.000000
parent d[0][0] is 64.000000
child d[0][0] is 64.000000
* - ./bug 65 (65x65 matrix) will not show the output for child process
computing for size 65
c[0][0] is 65.000000
parent d[0][0] is 65.000000
* sgemm does not have the issue, and not calling cblas_dgemm before fork does not either.
* We also attached the valgrind ouptut, which suggests an issue with Grand Central.
*/
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <Accelerate/Accelerate.h>
void* xmalloc(size_t n)
{
void* tmp;
tmp = malloc(n);
if (tmp == NULL) {
fprintf(stderr, "You are about to die\n");
exit(EXIT_FAILURE);
} else {
return tmp;
}
}
int main(int argc, char *argv[])
{
int n, lda, ldb, ldc;
int i;
double *a, *b, *c, *d;
size_t n_bytes;
pid_t p;
if (argc != 2) {
fprintf(stderr, "USAGE: %s size\n", argv[0]);
exit(EXIT_FAILURE);
} else {
n = atoi(argv[1]);
printf("computing for size %d\n", n);
}
lda = n;
ldb = n;
ldc = n;
n_bytes = sizeof(*a) * n * n;
a = xmalloc(n_bytes);
b = xmalloc(n_bytes);
c = xmalloc(n_bytes);
d = xmalloc(n_bytes);
for(i = 0; i < n * n; ++i) {
a[i] = 1;
b[i] = 1;
}
/* If this call is disabled, the crash disappears */
#if 1
cblas_dgemm(CblasRowMajor,
CblasNoTrans, CblasNoTrans, n, n, n,
1.0, a, lda, b, ldb, 0.0, c, ldc);
printf("c[0][0] is %f\n", c[0]);
#endif
p = fork();
if (p == 0) {
cblas_dgemm(CblasRowMajor,
CblasNoTrans, CblasNoTrans, n, n, n,
1.0, a, lda, b, ldb, 0.0, d, ldc);
printf("child d[0][0] is %f\n", d[0]);
} else {
cblas_dgemm(CblasRowMajor,
CblasNoTrans, CblasNoTrans, n, n, n,
1.0, a, lda, b, ldb, 0.0, d, ldc);
printf("parent d[0][0] is %f\n", d[0]);
}
return 0;
}
==39502== Memcheck, a memory error detector
==39502== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==39502== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==39502== Command: ./a.out 65
==39502==
--39502-- ./a.out:
--39502-- dSYM directory is missing; consider using --dsymutil=yes
computing for size 65
c[0][0] is 65.000000
UNKNOWN task message [id 3403, to mach_task_self(), reply 0x2e03]
parent d[0][0] is 65.000000
==39502==
==39502== HEAP SUMMARY:
==39502== in use at exit: 143,723 bytes in 43 blocks
==39502== total heap usage: 65 allocs, 22 frees, 1,459,867 bytes allocated
==39502==
==39503==
==39503== Process terminating with default action of signal 10 (SIGBUS)
==39503== Non-existent physical address at address 0x108
==39503== at 0x373324: dispatch_group_async_f (in /usr/lib/system/libdispatch.dylib)
==39503== by 0xFD565F: dgemmGCD (in /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib)
==39503== by 0xB62A47: cblas_dgemm (in /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib)
==39503== by 0x100000CF9: main (in ./a.out)
==39503==
==39503== HEAP SUMMARY:
==39503== in use at exit: 146,067 bytes in 47 blocks
==39503== total heap usage: 58 allocs, 11 frees, 804,139 bytes allocated
==39503==
==39502== LEAK SUMMARY:
==39502== definitely lost: 101,440 bytes in 5 blocks
==39502== indirectly lost: 0 bytes in 0 blocks
==39502== possibly lost: 33,800 bytes in 1 blocks
==39502== still reachable: 8,483 bytes in 37 blocks
==39502== suppressed: 0 bytes in 0 blocks
==39502== Rerun with --leak-check=full to see details of leaked memory
==39502==
==39502== For counts of detected and suppressed errors, rerun with: -v
==39502== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
==39503== LEAK SUMMARY:
==39503== definitely lost: 40 bytes in 2 blocks
==39503== indirectly lost: 0 bytes in 0 blocks
==39503== possibly lost: 0 bytes in 0 blocks
==39503== still reachable: 146,027 bytes in 45 blocks
==39503== suppressed: 0 bytes in 0 blocks
==39503== Rerun with --leak-check=full to see details of leaked memory
==39503==
==39503== For counts of detected and suppressed errors, rerun with: -v
==39503== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment