crashing when I using AVX function - c

#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#include "x86intrin.h"
void dd_m(double *clo, int m)
{
int j;
__m256d *vclo = (__m256d *)clo;
__m256d al=_mm256_set_pd(0,0,0,0);
__m256d clo_n=_mm256_set_pd(0,0,0,0);
int i;
for (j = 0; j < m; j++) {
for (i = 0; i < m; i++) {
al = _mm256_add_pd(vclo[m/4*j+i] , clo_n);
}
}
}
int main(int argc, const char * argv[]){
int m;
double* zlo;
int i;
m=(int)pow(2,8);
zlo=(double *)_mm_malloc(sizeof(double) * m*m,32);
for (i=0;i<m*m;i++) {
zlo[i]=0.0;
}
dd_m(zlo, m);
_mm_free(zlo);
return 0;
}
Here's my code.
It generate an error
"Thread 1: EXC_BAD_ACCESS (code=1, address=0x102900000)"
inside for loop.
I used latest xcode with clang.
What should I do?

By casting your clo to point to 256-bit vectors as vclo, your row-length is divided by four, you changed it in the index computation, but not in the inner loop over i.
for (j = 0; j < m; j++) {
for (i = 0; i < m/4; i++) { // in vclo, the rows are only m/4 long
al = _mm256_add_pd(vclo[m/4*j+i] , clo_n);
}
}

Related

multithreading - occasional segfault in matrix multiplication in c

I'm working on a small program of multithreaded matrix multiplication. My first job is to fill the entry of matrices with a random integer. I met some segment faults after I tried to pass a function pointer to pthread_create. And I think the problem is in function pthread_join.
But there are two issues in general.
The first one is the segment fault does not happen every time. Sometimes the code works, but most of the times it doesn't. So it really confuses me.
The other one is when the code is working, there are always several entries still not initialized, especially for matrix[0][0], it is never initialized. And I don't quite know where to debug that one.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define N 5
#define MAX 10
int A[N][N];
int B[N][N];
int C[N][N];
pthread_t pid[N][N];
typedef struct {
int row, col;
} Pos;
typedef void* (*thread_func)(void*);
void print_matrix(int M[][N]) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%3d", M[i][j]);
if (j < N - 1) {
printf(", ");
}
}
printf("\n");
}
}
void join_threads(void) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
pthread_join(pid[i][j], NULL);
}
}
}
void* fill_entry(void* arg) {
Pos* pos = (Pos*)arg;
A[pos->row][pos->col] = rand() % MAX;
B[pos->row][pos->col] = rand() % MAX;
return NULL;
}
void dispatch_jobs(thread_func job_func) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
Pos pos;
pos.row = i;
pos.col = j;
if (pthread_create(&pid[i][j], NULL, job_func, (void*)&pos)) {
perror("pthread_create");
exit(-1);
}
}
}
}
int main(void) {
srand(time(NULL));
dispatch_jobs(&fill_entry);
join_threads();
printf("Matrix A:\n");
print_matrix(A);
printf("Matrix B:\n");
print_matrix(B);
return 0;
}
Pos pos;
pos.row = i;
pos.col = j;
if (pthread_create(&pid[i][j], NULL, job_func, (void*)&pos)) {
perror("pthread_create");
exit(-1);
}
You are passing a pointer to a local variable to the threads. Once the thread tries to access the data, i.e. dereferences the pointer, the variable is long gone, reused, and contains garbage data.

Cannot loop over all the matrix elements

I am trying to create a data structure to store a matrix and write a routine to generate a square matrix of random numbers.
Here is my code. I am strangely getting only 2 float numbers as output. I am doing all this to implement strassen matrix multiplication, which is why I added rs, re, cs, ce to struct.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _matrix {
int rs;
int re;
int cs;
int ce;
float a[100][100];
}matrix;
void display(matrix m)
{
int i, j;
for (i=m.rs ; i<=m.re ; i++) {
for (j=m.cs ; j<=m.ce ; j++)
printf("%f", m.a[i][j]);
printf("\n");
}
printf("\n");
return;
}
matrix random_matrix(int n)
{
matrix random;
random.cs = random.rs = 0;
random.rs = random.re = n -1;
int i, j;
for(i=0; i < n; i++){
for(j = 0; j < n; j++)
random.a[i][j] = rand();
}
return random;
}
int main(void)
{
matrix m1 = random_matrix(3);
matrix m2 = random_matrix(3);
display(m1);
display(m2);
return 0;
}
I think, to fit the logic, in your code, in random_matrix() function,
random.rs = random.re = n -1;
should be
random.ce = random.re = n -1;
Otherwise, in display(), for (i=m.rs ; i<=m.re ; i++) does not make sense.
That said, to see the random number generator, you can call srand(time(NULL)); in main(), before the call to the matrix generation functions.

Creating a matrix in a structure

I am trying to create a structure that will have two integer values, an array, and two 2-D matrices using my code below. I can initialize the structure with the integers and array just fine, and my 'Gen' function will create the random values I want for the array.
However, when I try adding in the matrix components, I run into a problem. My compiler gives me a warning: "initialization from incompatible pointer type". If I understand what I have read so far, this is because the structure needs to be pointed to an array of pointers that represent each row in the matrix. I don't know the syntax for that.
A quick note: the other topics I've seen that are related to this issue all initialize the structure in a function other than the main() function, so I haven't found those solutions helpful.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <string.h>
// Define structure
typedef struct {
int row;
int col;
int *arr;
int **mat1;
int **mat2;
}container;
// Function headers
void Gen(container Thing);
int main() {
int row = 5;
int col = 6;
int A[row];
int M1[row][col];
int M2[row][col+1];
// Initialize structure
container Object = {row, col, A, M1, M2};
// Run "Gen" function
Gen(Object);
int i, j; // Index variables
// Display the array
for(i = 0; i < row; i++)
{
printf("%i ", Object.arr[i]);
}
printf("\n\n");
// Display the numbers from the matrices
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat1[j][i]);
}
printf("\n");
}
printf("\n");
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat2[j][i]);
}
printf("\n");
}
return (EXIT_SUCCESS);
}
// Function to generate random values in the array & matrices
void Gen(container Thing)
{
int i, j;
srand(time(NULL));
// Generate random values for the array
for(i = 0; i < Thing.row; i++)
{
Thing.arr[i] = rand() % 5;
}
// Generate random values for the matrix
for(j = 0; j < Thing.row; j++)
{
for(i = 0; i < Thing.col; i++)
{
Thing.mat1[j][i] = rand() % 5;
Thing.mat2[j][i] = rand() % 5;
}
}
} // End of "Gen" function
container Object = {row, col, A, M1, M2};
is wrong since the type of M1 is int[row][col], which can decay to int (*)[col] but not to int**. You have the same problem with M2.
You'll need to rethink your strategy for generating a container.
For example:
int main() {
int row = 5;
int col = 6;
int A[row];
int* M1[row];
int* M2[row];
for ( int i = 0; i < row; ++i )
{
M1[i] = malloc(sizeof(M1[i][0])*col);
M2[i] = malloc(sizeof(M1[i][0])*(col+1));
}
// Initialize structure
container Object = {row, col, A, M1, M2};
...
for ( int i = 0; i < row; ++i )
{
free(M1[i]);
free(M2[i]);
}
return (EXIT_SUCCESS);
}

Create an array of random numbers and return the array in C

I want to create a function called get_lotto_draw that will create an array of 6 random numbers and return them to main.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
get_lotto_draw()
{
int lottery[50];
int u,i,j,temp;
int lotto[6];
srand(time(NULL));
for (i =0; i<49; i++)
lottery[i] = i+1;
for (i =0; i<49; i++)
{
j = (rand()%49)+1;
temp = lottery[i];
lottery[i] = lottery[j];
lottery[j] = temp;
}
for (i =0; i<6; i++)
{
lotto[i] = lottery[i];
}
return lotto;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void get_lotto_draw(int lotto[])
{
int lottery[50];
int u,i,j,temp;
for (i =0; i<49; i++)
lottery[i] = i+1;
for (i =0; i<49; i++)
{
j = (rand()%49)+1;
temp = lottery[i];
lottery[i] = lottery[j];
lottery[j] = temp;
}
for (i =0; i<6; i++)
{
lotto[i] = lottery[i];
}
return ;
}
int _tmain(int argc, _TCHAR* argv[])
{
int lotto[6];
srand(time(NULL));
get_lotto_draw(lotto);
for (int i = 0; i < 6; i ++)
printf ("%d ", lotto[i]);
printf ("\n");
return 0;
}
The function get_lotto_draw will take the array 'lotto' as an argument - unsized array.
If you declare lotto as auto variable inside the function then when the function ends - the auto variable lotto would have been removed - check this link for details.
So you declare lotto in main and pass it to the function.
Other options include
use malloc (to allocate memory for 'lotto') inside the get_lotto_draw and free in main (unless you are very careful- this will lead to memory leaks - I do not recommend this)
use malloc in main and pass the allocated memory to the function and free it in main later
create a static and use it.
My recommendation is in such situations to use the stack (auto variable as used above) otherwise use malloc/free.
I fixed some of the bugs others pointed out
Thank you very much for everyone who helped. I spent a few hours reading and learning about the things you mentioned. I have now managed to create a piece of code that will do what I wanted.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int *get_lotto_draw(int n)
{
int i;
int *lotto;
lotto = malloc(n * sizeof(*lotto));
if (lotto == NULL)
return NULL;
int lottery[50];
int u,j,temp;
for (i =0; i<49; i++)
lottery[i] = i+1;
for (i =0; i<49; i++)
{
j = (rand()%49)+1;
temp = lottery[i];
lottery[i] = lottery[j];
lottery[j] = temp;
}
for (i =0; i<6; i++)
{
lotto[i] = lottery[i];
}
return lotto;
}
int main(int argc, char *argv[])
{
int i, n = 6;
int *lotto;
srand(time(NULL));
lotto = get_lotto_draw(n);
if (lotto == NULL)
return -1;
printf("Here is the array: ");
for(i = 0 ; i < n ; i++) {
printf("%d ", lotto[i]);
}
free(lotto);
printf("\n\n");
return 0;
}
I also found that I can do this by using static int as I have an array of set length.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int *get_lotto_draw(int n)
{
int i;
static int lotto[6];
int lottery[50];
int u,j,temp;
for (i =0; i<49; i++)
lottery[i] = i+1;
for (i =0; i<49; i++)
{
j = (rand()%49)+1;
temp = lottery[i];
lottery[i] = lottery[j];
lottery[j] = temp;
}
for (i =0; i<6; i++)
{
lotto[i] = lottery[i];
}
return lotto;
}
int main(int argc, char *argv[])
{
int i, n = 6;
int *lotto;
srand(time(NULL));
lotto = get_lotto_draw(n);
printf("Here is the array: ");
for(i = 0 ; i < n ; i++) {
printf("%d ", lotto[i]);
}
printf("\n\n");
return 0;
}

stack overflow unless printf under recursion

This code below is the code for finding the determinant for 3x3 matrix (this code is intended for nxn matrix, but for the sample, I used 3x3), using recursive
The result is working fine, but I wonder what errors in this code make this must be the printf("\n") before calling the sub-function (itself) or else it will return the error 0xc0000fd (stack overflow).
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#define size 3
void trimarray(int**rrayrc,int**rrayout, int dim,int cuti,int cutj)
{
int i, j;
int ti = 0,tj;
for(i = 0; i<dim; i++)
{
tj = 0;
for(j = 0; j< dim; j++)
{
if(!((i==cuti)||(j==cutj)))
{
rrayout[ti][tj] = rrayrc[i][j];
}
if(j!=cutj) {tj++;}
}
if(i!=cuti) {ti++;}
}
}
void initializearray(int** rray,int dim)
{
int i, j;
for(i = 0; i<dim; i++)
{
for(j = 0; j<dim; j++)
{
rray[i][j] = 0;
}
}
}
int det(int** rray, int dim)
{
int i,j;
int cut[dim-1][dim-1];
int* cutp[i];
int mul = 1,sum=0;
if(dim >1)
{
for(i = 0; i<dim-1; i++)
{
cutp[i] = cut[i];
}
initializearray(cutp,dim-1);
for(i = 0; i<dim; i++)
{
printf("\n",dim); //<< Without this the program won't work
trimarray(rray,cutp,dim,0,i);
sum+=det(cutp,dim-1)*mul*rray[0][i];
mul = 0-mul;
}
return sum;
}
else
{
return rray[0][0];
}
}
int main()
{
int test[size][size] = {2,-3,-2,-6,3,3,-2,-3,-2};
int* testpntr[size];
int i,deter;
for(i = 0; i<size; i++)
{
testpntr[i] = test[i];
}
deter = det(testpntr,size);
printf("[%d]",deter);
getch();
return 0;
}
The answers will be dearly appreciated.
int* cutp[i]; is undefined behavior since i is uninitialized at this stage. You have no idea what is the size of cutp array.

Resources