Basic Matrix multiplication with pthreads c++ error - c++

I have a matrix multiplication code that I am supposed to process in parallel. I have a code here that I believe should work but does not. It either causes segmentation faults or gives me all gibberish values. Can any one help? Thanks in advance.
//*******************STRUCTS AND GLOBAL VARIABLES*****************************//
struct Matrix
{
int d[SIZE][SIZE];
};
Matrix* matrix_addr[SIZE]; // array to store the address of the matrices
int n;
int m;
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;
//****************************THREAD******************************************//
void* calcTerm(void* arg)
{
pthread_mutex_lock(&my_mutex);
int sum = 0;
Matrix* m0 = (Matrix*) arg;
Matrix* m1 = (Matrix*) ((int*)arg + 1);
Matrix* m2 = (Matrix*) ((int*)arg + 2);
cout << endl << "Print\n" << endl;
print (m0);
for (int i = 0; i < SIZE; ++i)
{
cout << "\ni = " << i << "\tn = " << m1->d[n][i] << "\tm = " << m2->d[i][m] << endl;
sum = sum + (m1->d[n][i] * m2->d[i][m]);
}
cout << endl << endl << sum << endl;
m0->d[n][m] = sum;
pthread_mutex_unlock(&my_mutex);
cout << endl << "Going out of thread\n" ;
pthread_exit(NULL);
}
//********************************MAIN****************************************//
int main()
{
Matrix m0, m1, m2; //Matrices are 3x3;
// m0 <= m1 * m2
pthread_t id[9]; // 3x3 matrix multiplication requires 9 threads.
matrix_addr[0] = &m0; // the pointers to the matrices are stored here.
matrix_addr[1] = &m1;
matrix_addr[2] = &m2;
n = m = 0; // initialize the global variable
srand(time(NULL)); // seed rand()
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
m0.d[i][j] = 0; // m0 is being cleared for the output
m1.d[i][j] = rand()%10; // m1 and m2 are generated with rand()
m2.d[i][j] = rand()%10;
}
}
//display the input matrices
cout << "MATRIX 1:\n\n";
print (&m1);
cout << "\nMATRIX 2:\n\n";
print (&m2);
cout << "\nMATRIX 3:\n\n";
print (&m0);
for (int i = 0; i < SIZE*SIZE; i++) // run all the threads for calculating each output
{
m = i % SIZE;
n = i / SIZE;
cout << endl << "Going in to thread " << i << " with n = " << n << " and m = " << m;
pthread_create(&id[i], NULL, calcTerm, (void*) matrix_addr);
cout << endl << "Out of thread " << i ;
//pthread_join(id[i], NULL);
}
//pthread_cond_wait(&my_cond, &my_mutex);
cout << endl << endl;
print_result (&m0, &m1, &m2);
return 0;
}
It seems like the calcTerm thread does not take the correct pointers or something. It calculates gibberish values, but the final output at the end of main prints the same matrices I started off with.
Thanks again.

Related

Object(0,0) directly assigned value, how does that work?

I got a homework which looks something like this. I am working on it and hold beginner knowledge of the same.
I have to create a header file that contains this code and then use the header file to get the desired results.
I am working with C++ template, and operator overloading.
#include <iostream>
#include <memory>
#include "matrix.h"
#include "symetric_matrix.h"
using namespace std;
int main()
{
const Matrix<int, 3, 2> m1; // Creates 3*2 matrix, with all the default elements set to 0;
cout << m1 << endl;
Matrix<int, 3, 3> m2(4); // Creates 3*3 matrix, with the default elements equals to 4;
cout << m2 << endl;
const Matrix<int, 3, 3> m3 = m2; // C-py constructor may take O(MN) and not O(1).
cout << m3 << endl;
// min() returns the minimal value in the matrix.
if (min(m1) < min(m3))
cout << "Min value of m3(" << min(m3) << ") is bigger than min value of m1(" << min(m1) << ")" << endl;
if (m1.avg() < m3.avg()) // Compares the average of the elements
cout << "Average value of m3(" << m3.avg() << ") is bigger than average value of m1(" << m1.avg() << ")" << endl;
m2(0, 0) = 13;
cout << m2[0][0] << " " << m2[1][0] << endl; // Should print "13 4"
try
{
cout << m2 + m3 << endl;
cout << m3 * m1 << endl; // You can choose the format of matrix printing;
cout << m1 * m2; // This should throw an exception
}
catch (const Matrix<int, 3, 2>::IllegalOperation &e)
{
cout << e.what() << endl;
}
Matrix<int, 3, 3> m4;
m4 = m3;
cout << m4 << endl;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
m4(i, j) = i + j;
cout << m4 << endl;
cout << "m4[1][1] = " << m4[1][1] << endl;
cout << "m4[1][1] = " << m4(1, 1) << endl; // m4(1,1) same result as m4[1][1]
Matrix<int, 3, 3> m5(3);
m5 = 2 * m4;
cout << m5 << endl;
Matrix<int, 3, 3> m6(m4);
cout << m6 << endl;
m5 += m4;
cout << m5 << endl;
if (m6 != m5)
cout << "m6 != m5" << endl;
Matrix<Matrix<int, 3, 2>, 4, 4> composite(m1); // Creates matrix, where each element is m1;
cout << composite;
unique_ptr<Matrix<int, 3, 3>> symetric_matrix(new SymetricMatrix<int, 3>(5)); // SymetricMatrix matrix 3*3 with default element equals to 5;
(*symetric_matrix)(1, 2) = 8;
cout << (*symetric_matrix)(1, 2) << " " << (*symetric_matrix)(2, 1) << endl; // Should print "8 8"
cout << (*symetric_matrix)[1][2] << " " << (*symetric_matrix)[2][1] << endl; // Should print "8 8"
(*symetric_matrix)[1][0] = 18;
cout << (*symetric_matrix)[1][0] << " " << (*symetric_matrix)[0][1] << endl; // Should print "18 18"
return 0;
}
My Updated solution for now.
template <class T, int M, int N>
class Matrix
{
private:
T mat[M][N];
int rows = M;
int cols = N;
public:
// constructor
Matrix(int v = 0)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
mat[i][j] = v;
}
}
Matrix<T, M, N> operator+(Matrix<T, M, N> &other);
Matrix<T, M, M> operator*(T scalar);
T &operator()(int i, int j)
{
return mat[i][j];
};
T *operator[](int index)
{
return mat[index];
};
// << overloading
friend std::ostream &operator<<(std::ostream &os, const Matrix<T, M, N> &L)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
os << L.mat[i][j] << " ";
os << "\n";
}
return os;
};
friend T min(Matrix obj)
{
T result = obj.mat[0][0];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
if (result < obj.mat[i][j])
result = obj.mat[i][j];
}
return result;
};
long double avg() const
{
long double result = 0;
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
if (result < mat[i][j])
result = result + mat[i][j];
}
return result / (M * N);
}
};
template <class T, int M, int N>
Matrix<T, M, N> Matrix<T, M, N>::operator+(Matrix &other)
{
if ((this->rows == other.rows) && (this->cols == other.cols()))
{
Matrix<T, M, N> resultantMatrix;
for (auto i = 0; i < this->rows; i++)
{
for (auto j = 0; j < this->cols; j++)
{
auto &valueFirst = this->data[i][j];
auto &valueSecond = other(i, j);
if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
throw std::out_of_range("Resultant value of matrix is out of range");
else
resultantMatrix(i, j) = valueFirst + valueSecond;
}
}
return resultantMatrix;
}
else
throw std::runtime_error("Matrices cannot be added, sizes do not match");
}
I am confused about m2(0,0) = 13 & cout << m2+m3, how does this work and how is this possible?
I just need help with the whole program while I try and learn!
Any help is appreciated.

segmentation fault when trying to read values from dynamically allocated 2-D array c++ and gives munmap_chunk(): when trying to delete it

I'm trying to measure the time taken for insertion sort (avg, best, and worst for certain a size, n times) and storing all results in a 2D array
Here is the code for it:
#include <iostream>
#include <sys/time.h>
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
std::cout << "insetion flag " << i << std::endl;
int key = array[i];
int j = i - 1;
while (key < array[j] && j >= 0) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
}
void getRandomArray(int* avg, int* best, int* worst, int size) {
srand((unsigned)time(0));
for (int i = 0; i < size; i++) {
//std::cout << "rand flag " << i << std::endl;
avg[i] = (rand() % 100) + 1;
}
for (int i = 0; i < size; i++) {
//std::cout << "copy flag " << i << std::endl;
best[i] = avg[i];
}
insertionSort(best, size);
for (int i = 0, j = size; i < size; i++, j--) {
//std::cout << "rev flag " << i << std::endl;
worst[j] = best[i];
}
}
double getComplx(int* arry, int size) {
struct timeval *start, *end;
std::cout << "comp flag " << std::endl;
gettimeofday(start, NULL);
insertionSort(arry, size);
gettimeofday(end, NULL);
double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
return timeTaken;
}
int main(int argc, char** argv) {
int size = atoi(argv[1]);
int times = atoi(argv[2]);
int* avg = new int[size];
int* best = new int[size];
int* worst = new int[size];
double** resTable = new double*[times];
for (int i = 0; i < times; i++) {
std::cout << i << std::endl;
resTable[i] = new double[3];
}
std::cout << "flag 1" << std::endl;
for (int i = 0; i < times; i++) {
getRandomArray(avg, best, worst, size);
std::cout << "flag 2" << std::endl;
resTable[i][0] = getComplx(avg, size);
std::cout << " avg ("<<i<<") (0) " << resTable[i][0] << std::endl;
resTable[i][1] = getComplx(best, size);
std::cout << " best ("<<i<<") (0) " << resTable[i][1] << std::endl;
resTable[i][2] = getComplx(worst, size);
std::cout << " worst ("<<i<<") (0) " << resTable[i][2] << std::endl;
printf("|%9.0f |%9.0f |%9.0f |", resTable[i][0], resTable[i][1], resTable[i][2]);
std::cout << " : loop no : " << i << std::endl;
}
std::cout << "after loop" << std::endl;
delete []avg;
std::cout << "after avg" << std::endl;
delete []best;
std::cout << "after best" << std::endl;
delete []worst;
std::cout << "after worst" << std::endl;
for (int i = 0; i < times; i++) {
std::cout << "after " << i << std::endl;
delete[] resTable[i];
}
delete []resTable;
std::cout << "last flag" << std::endl;
return 0;
}
In the main function I have a dynamically created array and store all data in it but it gives a segmentation fault when it reaches in last row to store data.
So I tried to skip storing in last row and it worked but this time when deleting at the end it again gives me the error "munmap_chunk() : invalid pointer"
I have checked other questions related to this but couldn't find what I am doing wrong here.
I know we can do it better with vectors but I am just trying to get a better understanding of the inner workings of pointers and memory allocation.
You've got two instances of reading/writing outside of allocated memory bounds, and two instances of using an uninitialized pointer.
First, in insersionSort:
while (key < array[j] && j >= 0) {
You use j to index the array before checking if the value is positive. This results in reading before the start of the array. You want to check j first:
while ( j >= 0 && key < array[j]) {
Then you have this in getRandomArray:
for (int i = 0, j = size; i < size; i++, j--) {
You start j at size, then use it to index the array. This writes past the end of the array. You want to start one element earlier:
for (int i = 0, j = size - 1; i < size; i++, j--) {
Finally, there's getComplx:
double getComplx(int* arry, int size) {
struct timeval *start, *end;
std::cout << "comp flag " << std::endl;
gettimeofday(start, NULL);
insertionSort(arry, size);
gettimeofday(end, NULL);
double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
return timeTaken;
}
The gettimeofday function expects a pointer to a struct timeval, but in both cases you pass it an uninitialized pointer. Rather than making start and end pointers, make them instances of struct timeval and pass their addresses:
double getComplx(int* arry, int size) {
struct timeval start, end;
std::cout << "comp flag " << std::endl;
gettimeofday(&start, NULL);
insertionSort(arry, size);
gettimeofday(&end, NULL);
// also change -> to .
double timeTaken = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
return timeTaken;
}

Write a function that returns a pointer to the maximum value using pointers c++

This is the problem that I'm trying to solve for class in C++.
Write a function that returns a pointer to the maximum value of an array of floating-point data: double* maximum(double* a, int size). If size is 0, return nullptr.
The issues I'm having are that:
The final output is not the correct location for the maximum value in the array.
An error that says: "cannot convert 'double**' to 'double*' in the initialization".
If I use nullptr at any point in this code, CodeBlocks gives me an error.
#include <iostream>
using namespace std;
// return pointer to location from function
double * maximum(double* a, int size)
{
double maxVal = a[0]; // this is the starting max value
double* max_pos = &a; // points to the value in a[0]
// initialis]ze both variables
for(int i = 0; i < size; i++){
if(a[i] > maxVal){
maxVal = a[i];
cout << max_pos << endl;
max_pos = &a[i];
}
}
// return address
return max_pos;
}
int main()
{
double myarr[5];
int i = 0;
int arrSize = 5;
cout << "Input 5 floating point values for your array" << endl;
for(i = 0; i < arrSize; i++){ // loop to input values
cin >> myarr[i];
}
for(int j = 0; j < arrSize; j++){
cout << "Location for " << myarr[j] << " = " << &myarr[j] << endl;
}
double* maxNum = maximum( myarr, arrSize);
cout << &maxNum << endl;
return 0;
}
This is the output I'm getting after finding max_pos:
The code you showed has a few mistakes in it:
using namespace std; is bad!
you are not following your instructions to return nullptr when size is 0.
you are trying to initialize max_pos (a double*) with &a (a double**), which is a compiler error.
you are passing &maxNum (a double**) to std::cout, printing the address of the maxNum variable itself, not the address that it is pointing to (the found array element). You need to pass maxNum (a double*) if you want to print the address of the found element, or pass *maxNum (a double) if you want to print the value of the found element.
Try something more like this instead:
#include <iostream>
// return pointer to location from function
double* maximum(double *a, int size)
{
if (size == 0) return 0;
// initialize both variables
double* max_pos = a; // points to the value in a[0]
double maxVal = *max_pos; // this is the starting max value
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
for(int i = 1; i < size; ++i){
if (a[i] > maxVal){
max_pos = &a[i];
maxVal = *max_pos;
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
}
}
// return address
return max_pos;
}
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
for(int i = 0; i < arrSize; ++i) { // loop to input values
std::cin >> myarr[i];
}
for(int j = 0; j < arrSize; ++j) {
std::cout << "Location for " << myarr[j] << " = " << &myarr[j] << std::endl;
}
double* maxNum = maximum(myarr, arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo
And then, you can throw it all away and use STL algorithms instead, like std::max_element():
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
// loop to input values
std::copy_n(std::istream_iterator<double>(std::cin), arrSize, myarr);
for(int i = 0; i < arrSize; ++i) {
std::cout << "Location for " << myarr[i] << " = " << &myarr[i] << std::endl;
}
double *maxNum = std::max_element(myarr, myarr + arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo

segmentation fault for string function argument

I have a simple main code that gives me segmentation fault when calling a function. In the following code, I have two functions, the first one works correctly but the program doesn't enter the second one and gives me segmentation fault error. Is there any reason for that? I have made sure about the following:
The variables o and c are not out of bound.
cn is initialized correctly.
I have a read-only access to cm and argv. Plus it does not even enter the function evaluate
Here is the code:
void print_cm(vector<vector<int> > *cm, char* gtf);
void evaluate(vector<vector<int> > *cm, char* gtf);
int main(int argc, char** argv)
{
int o = 2; // It is initialized
int c = 4; // It is initialized
vector<vector<int> > cm; // It is initialized
if (argc>4)
print_cm(&cm, argv[o]);
if (argc>4)
{
cout << argv[c] << endl; // Works
// The following also works
for (int i=0; i<cm.size(); i++)
for (int j=0; j<cm[i].size(); j++)
cout << cm[i][j] << " ";
// The following causes segmentation fault;
evaluate(&cm, argv[c]);
}
return 0;
}
void evaluate(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
void print_cm(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
Here is the complete code:
#include "includes/Utility.h"
#include "includes/Graph.h"
void print_cm(vector<vector<int> > *cores, char* output);
void evaluate(vector<vector<int> > const *cm, char* gtf);
int main(int argc, char** argv)
{
int g = -1, c = -1, o = -1;
for (int i=1; i<argc-1; i++)
if (argv[i][0]=='-')
{
if (argv[i][1]=='g')
g = i + 1;
else if (argv[i][1]=='c')
c = i + 1;
else if (argv[i][1]=='k')
ki = i + 1;
else if (argv[i][1]=='s')
si = i + 1;
else if (argv[i][1]=='o')
o = i + 1;
}
Graph G;
if (c>0) G.read_input(argv[g], argv[c]);
else G.read_input(argv[g]);
if (ki > 0)
{
int k = atoi(argv[ki]);
cout << k << endl;
}
if (si > 0)
{
int s = atoi(argv[si]);
cout << s << endl;
}
// Find communities
vector<vector<int> > cores;
G.partitioning(&cores);
if (o>0)
print_cm(&cores, argv[o]);
if (c>0)
{
cout << "here" << endl;
for (size_t i=0; i<cores.size(); i++)
for (size_t j=0; j<cores[i].size(); j++)
if (cores.at(i).at(j)<0) cout << "here";
cout << "here" << endl;
evaluate(&cores, argv[c]);
}
}
return 0;
}
void print_cm(vector<vector<int> > *cores, char* output)
{
ofstream out;
out.open(output);
for(size_t i=0; i<(*cores).size(); i++)
{
for(size_t j=0; j<(*cores)[i].size(); j++)
out << (*cores)[i][j] << " ";
out << endl;
}
out.close();
return ;
}
void evaluate(vector<vector<int> > const *cm, char* gtf)
{
// we evaluate precision, recall, F1 and F2
vector<vector<int> > gt;
ifstream in;
char str[100000000];
in.open(gtf);
while(in.getline(str, 100000000))
{
stringstream s;
s << str;
int a;
gt.resize(gt.size()+1);
while (s >> a) gt[gt.size()-1].push_back(a);
}
in.close();
cout << "==================== Evaluation Results ====================" << endl;
int imax = 0;
for(size_t i=0; i<(*cm).size(); i++)
imax = max(imax, *max_element((*cm)[i].begin(), (*cm)[i].end()));
for(size_t i=0; i<gt.size(); i++)
imax = max(imax, *max_element(gt[i].begin(), gt[i].end()));
vector<bool> flag(imax, false);
vector<double> recall((*cm).size(), 0), precision((*cm).size(), 0), f1((*cm).size(), 0), f2((*cm).size(), 0);
int overlap;
double size = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
// evaluate
size += (double) (*cm)[i].size();
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = true;
double p, r, ff1, ff2;
for(size_t j=0; j<gt.size(); j++)
{
overlap = 0;
for(size_t k=0; k<gt[j].size(); k++)
if (flag[gt[j][k]]) overlap++;
p = (double) overlap / (double) (*cm)[i].size();
if (p > precision[i])
precision[i] = p;
r = (double) overlap / (double) gt[j].size();
if (r > recall[i])
recall[i] = r;
ff1 = (double) 2*(p*r)/(p+r);
if (ff1 > f1[i])
f1[i] = ff1;
ff2 = (double) 5*(p*r)/(4*p + r);
if (ff2 > f2[i])
f2[i] = ff2;
}
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = false;
}
double Recall = 0, Precision = 0, F1 = 0, F2 = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
Recall += recall[i];
Precision += precision[i];
F1 += f1[i];
F2 += f2[i];
}
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << "Precision";
cout << " | " << setiosflags( ios::left ) << setw(10) << "Recall";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F1-measure";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F2-measure";
cout << " |" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << Precision/(*cm).size() ;
cout << " | " << setiosflags( ios::left ) << setw(10) << Recall/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F1/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F2/(*cm).size();
cout << " |" << endl;
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "Number of communities: " << (*cm).size() << endl;
cout << "Average community size: " << size/(*cm).size() << endl;
return ;
}
char str[100000000];
This is in your evaluate function. This are 100 million bytes, or about 95 MB that you're allocating on the stack.
Typical stack sizes are far less than that, around 1 MB.
So apart from possible other problems this is most likely causing a stack overflow.
When entering the function, the stack frame gets extended to be large enough to hold the local variables. As soon as the stack is used then (to write a default value) you're accessing invalid (non stack, thankfully protected) memory.

EXC_BAD_ACCESS at main method declaration

I'm trying to get some old C++ code up and running. I've gotten it to compile without error, but it immediately segfaults when I run, without entering main. When I use gdb to find out where things are going wrong, I find the following:
(gdb) run
Starting program: /Users/dreens/Documents/OH/extrabuncher2/ParaOHSB
Reading symbols for shared libraries +++. done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00007fff5636581c
0x000000010000151e in main (argc=1, argv=0x100000ad0) at ParaMainOHSlowerBuncher.cc:13
13 int main(int argc, char *argv[]){
(gdb) backtrace
#0 0x000000010000151e in main (argc=1, argv=0x100000ad0) at ParaMainOHSlowerBuncher.cc:13
(gdb)
Does anyone know what could cause a memory access issue right at the start of the main method?
The code is rather large, but here is the file containing the main method. Could the included .hh and .cc files be a part of the problem? Should I attach them?
Thanks!
David
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "MoleculeEnsemble.hh"
#include "SlowerForceLoadOH32.cc"
#include "SlowerForceLoadOH12.cc"
//#include "SlowerForceLoad3mmBuncher.cc"
#include "SlowerForceLoad4mmBuncher.cc"
using namespace std;
int main(int argc, char *argv[]){
//int main(){
cout << "Ahhhh!" << endl;
/******Parallel Crap********/
/*
int totalnodes = 0;
int mynode = 0;
MPI_Status status;
MPI_Init(&argv,&argc);
MPI_Comm_size(MPI_COMM_WORLD,&totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD,&mynode);
srand(time(NULL)*mynode);
*/
/******Distribution Parameters *******/
long MoleculeNumber = long(5e4);
double Xcenter = 0;
double Ycenter = 0;
double Zcenter = 0;
double DeltaX = 0.0015;
double DeltaY = 0.0015;
double DeltaZ = 0.01;
int FlatX = 1;
int FlatY = 1;
int FlatZ = 1;
double vXcenter = 0;
double vYcenter = 0;
double vZcenter = 406;
double Vcalc = 406;
double vZfinal = 0;
double DeltavX = 2;
double DeltavY = DeltavX;
double DeltavZ = 40;
int FlatvX = 0;
int FlatvY = 0;
int FlatvZ = 0;
int TimeArrayOnly = 0; //Outputs only Time Array
double TimeOffset = 0; //Adds valve-skimmer flight time to ToF array
/*******Overtone Parameters********/
int S = 1; //parameter S=Vz/Vswitch as defined by VDM et al.
int JILAOT = 0; //JILAOT is either 0 or 1, denoting whether or not to use special switching
/*******Hexapole Parameters********/
double VSD = 0.06;
double Voltage = 2000;
double HexRadius = .00268;
double HexStart = .0238;
double HexEnd = .083170;//0.089103;
double HexOn = 1e-6;
double HexOff = 203e-6;//224e-6; 212 for current data; Good = 243e-6 for 408m/s
double DeltaT = 1e-6;
double DeltaTSeqGen = 1e-9; //Need to use smaller time steps for finding the time sequence
double DetectionTime = HexOff; //Use to fake out hex code
double TriggerLatency = 0;//170e-9;
/*******Detection Parameters*******/
double DetectionPosition = double(0.9319);//0.257480; <- for viewing at 31.5 ||||| 0.9428; <-Mag trap(4stages), .9319 <-MagTrap(3Stages)
double IrisWidth = 0.008;//31.5 0.0023 //PostSlower.015;
double LaserRadius = .001;
/*****Bunching Paramaters******/
int BunchNumber = 0;
int NumberUsed = 0;
/*****Timing Variables*********/
time_t start, finish;
time( &start);
/*****Molecule Parameters******/
double mass =double(17*1.672e-27);
/******ToF Detection Arrays and Slowing Parameters *********/
double Phi = double(34.2);
double PhiEB = double(0);
int NumberOfStages = int(142/S); //Use 142 for Big machine
int EBStages = 3; //Larger Add-on stages at end of slower
double BuncherScale = 1;
double Time[int(1e7)];
int ToFSignal32[int(1e7)];
int ToFSignal12[int(1e7)];
double TimeArray[800];
double VExit[800];
double Average32[7];
double Average12[7];
int LOST[200];
/*************Finished ToF Detection Arrays and Slowing Parameters ********/
/******Force Arrays********/
int Xnumber = 111;
int Ynumber = 21;
int Znumber = 21;
int FLength = Xnumber*Ynumber*Znumber;
double AXxDT[FLength];
double AYxDT[FLength];
double AZxDT[FLength];
double AZxDTSeqGen[FLength];
SlowerForceLoadOH32(AZxDT, AYxDT, AXxDT); //Note how Z and X are placed in this function. My matlab code calls the longitudnal dimension X, here it is Z
double DTovermass = DeltaT/mass;
for(int j = 0; j <FLength; j++){
AXxDT[j] = DTovermass*AXxDT[j];
AYxDT[j] = DTovermass*AYxDT[j];
AZxDT[j] = DTovermass*AZxDT[j];
AZxDTSeqGen[j] = DeltaTSeqGen*AZxDT[j]/DeltaT;
}
double AXxDT12[FLength];
double AYxDT12[FLength];
double AZxDT12[FLength];
SlowerForceLoadOH12(AZxDT12, AYxDT12, AXxDT12); //Note how Z and X are placed in this function. My matlab code calls the longitudnal dimension X, here it is Z
for(int j = 0; j <FLength; j++){
AXxDT12[j] = DTovermass*AXxDT12[j];
AYxDT12[j] = DTovermass*AYxDT12[j];
AZxDT12[j] = DTovermass*AZxDT12[j];
}
/********Load Extra Buncher Forces*********/
int XnumberEB = 251;
int YnumberEB = 41;
int ZnumberEB = 41;
int FLengthEB = XnumberEB*YnumberEB*ZnumberEB;
double AXxDTEB[FLengthEB], AYxDTEB[FLengthEB], AZxDTEB[FLengthEB], AZxDTSeqGenEB[FLengthEB];
SlowerForceLoad4mmBuncher(AZxDTEB, AYxDTEB, AXxDTEB);
for(int j = 0; j <FLengthEB; j++)
{
AXxDTEB[j] = DTovermass*AXxDTEB[j]/BuncherScale;
AYxDTEB[j] = DTovermass*AYxDTEB[j]/BuncherScale;
AZxDTEB[j] = DTovermass*AZxDTEB[j]/BuncherScale;
AZxDTSeqGenEB[j] = DeltaTSeqGen*AZxDTEB[j]/(DeltaT*BuncherScale);
}
/********* End All initiliazation ***************************/
/************Beginning Calculation *************************/
//Create Molecule Ensemble
MoleculeEnsemble Alice(MoleculeNumber,Xcenter,Ycenter,Zcenter,DeltaX,DeltaY,DeltaZ,FlatX,FlatY,FlatZ,vXcenter,vYcenter,vZcenter,DeltavX,DeltavY,DeltavZ,FlatvX,FlatvY,FlatvZ);
//MoleculeEnsemble Bob(MoleculeNumber,Xcenter,Ycenter,Zcenter,DeltaX,DeltaY,DeltaZ,FlatX,FlatY,FlatZ,vXcenter,vYcenter,vZcenter,DeltavX,DeltavY,DeltavZ,FlatvX,FlatvY,FlatvZ);
//Generate the Timing Sequence
Alice.TimeArrayGeneratorWithBuncher(Vcalc,Phi,PhiEB,TimeArray,VExit,AZxDTSeqGen,AZxDTSeqGenEB,HexOff,DeltaTSeqGen,BunchNumber,vZfinal,NumberUsed,NumberOfStages,S,EBStages);
/*if(mynode == 0){
cout << "Slowing utilized " << NumberUsed << " stages, yielding a final velocity of " << VExit[NumberUsed] << " m/s." << endl;
cout << endl;
for(int kk = 0; kk < NumberOfStages; kk++){cout << kk << " , " << TimeArray[kk] << " , " << VExit[kk] << endl;}
}*/
/*Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl << endl;
*/
if(TimeArrayOnly!=1)
{
//Fly the Ensemble through the hexapole
Alice.HexapoleFlightOH(Voltage, HexRadius, HexStart, HexEnd, HexOn, HexOff, DeltaT, double(3/2), DetectionTime);
//Bob.HexapoleFlightOH(Voltage, HexRadius, HexStart, HexEnd, HexOn, HexOff, DeltaT, double(1/2), DetectionTime);
/*
Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl << endl;
*/
//Fly the Ensemble through the slower
Alice.SlowerFlight(LOST, Time, ToFSignal32, Phi, TimeArray, DeltaT, AXxDT, AYxDT, AZxDT, AXxDTEB, AYxDTEB, AZxDTEB, Xnumber, Ynumber, Znumber, DetectionPosition, IrisWidth, LaserRadius, NumberOfStages, EBStages,S, TriggerLatency);
//Bob.SlowerFlight(LOST, Time, ToFSignal12, Phi, TimeArray, DeltaT, AXxDT12, AYxDT12, AZxDT12, Xnumber, Ynumber, Znumber, DetectionPosition, IrisWidth, LaserRadius, NumberOfStages, EBStages, S, TriggerLatency);
}
/**********Ending Calculation **********************/
//Alice.MoleculeEnsemble_Drawer();
/*
Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl;
*/
//Output ToF signal
if(TimeArrayOnly!=1)
{
for(int ii = 0; ii < int(1e7); ii++)
{
if(ToFSignal32[ii] > 0 && Time[ii] > 3e-3)
{
cout << Time[ii]+TimeOffset << "," << ToFSignal32[ii] << endl;
//+double(VSD/vZcenter)+38e-6 << "," << ToFSignal32[ii] << endl;
}
if(ToFSignal12[ii] > 0 && Time[ii] > 3e-3)
{
cout << Time[ii]+TimeOffset << "," << ToFSignal12[ii] << endl;
//+double(VSD/vZcenter)+38e-6 << "," << ToFSignal12[ii] << endl;
}
}
}
if(TimeArrayOnly==1)
{
for(int ii = 0; ii < NumberOfStages+EBStages+1; ii++)
{
cout << ii << "\t" << TimeArray[ii] << "\t" << VExit[ii] << endl;
//+double(VSD/vZcenter)+double(265e-6) << "\t" << VExit[ii] << endl;
}
}
/*for(int ii = 0; ii < NumberOfStages; ii++)
{
cout << ii << "\t" << LOST[ii] << endl;
}
*/
/*
MPI_Finalize();
*/
}
You're out of stack space.
You declare very large arrays in your code (over 10 million elements), which are all allocated on the stack. Instead of declaring the arrays statically, use dynamic memory allocation. So, instead of
double Time[int(1e7)];
write
double* Time;
Time = new double[int(1e7)];
and hope to have enough RAM in your computer :)