I am supposed to write a program that processes a sequence of 100 positive numbers. The program should have 3 different functions, which could be chosen from a menu.
Generate a number sequence with a random generator and print the numbers on the screen. The numbers generated should be in the range 0 ≤ n ≤ 900
I have to sort the sequence with bubble sort and then the numbers must be printed and I cannot use built-in sorting functions, such as qsort.
Quit program.
The 1 and 2 must be in own functions.
Lasly every time the program prints out the number, it should be printed as a table with ten rows and ten columns. Choice two can not be made unless choice one has been chosen.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 100
#define N 10
#define INVALID 0
#define VALID 1
void randomNum() {
//random number gen
int num[SIZE] = {0};
int i = 0;
srand(time(NULL));
for(i = 0; i < SIZE; i++) {
num[i] = rand() % 901;
}
for(i = 0; i < SIZE; i++) {
printf("%4d", num[i]);
if(i % 10 == 9)
printf("\n");
}
}
void sort() {
//sort of the generated number sequence
int num[SIZE] = {0};
int i = 0;
int j = 0;
int temp = 0;
for (int i = 0 ; i < SIZE; i++)
{
for (int j = 0; j < SIZE - 1; j++)
{
if (num[j] > num[j+1])
{
temp = num[j];
num[j] = num[j+1];
num[j+1] = temp;
}
}
}
for(i = 0; i < SIZE; i++) {
printf("%4d", num[i]);
if(i % 10 == 9)
printf("\n");
}
}
int main() {
randomNum();
printf("\n");
sort();
return 0;
}
I have figured out the solutions for how to generate a sequene and sort it and it works correct when all the code are in main() , however, when I put in in own functions above the main() it does not work. I'm stuck and don't know how to move forward. When i run the program it generates a random sequence but then the sorting function just prints out 100 zeros.
I fixed up your code, to try to do mostly the same thing in a very straight forward fashion.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 100
void fill_random_array( int array[const], size_t sz )
{
srand(time(NULL));
for(int i = 0; i < sz; ++i)
{
array[i] = rand() % 901;
printf("%3d%s", array[i], (i+1)%16? " ": "\n" );
}
}
void sort( int array[const], size_t sz )
{
for (int i = 0 ; i < SIZE; i++)
{
for (int j = 0; j < SIZE - 1; j++)
{
if (array[j] > array[j+1])
{
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
int main()
{
int data[SIZE];
fill_random_array( data, SIZE );
printf("\n\nResult:\n");
sort( data, SIZE );
for(int i = 0; i < SIZE; ++i)
{
printf("%3d%s", data[i], (i+1)%16? " ": "\n" );
}
return 0;
}
Example Output:
Success #stdin #stdout 0s 5536KB
757 872 260 877 827 747 839 279 468 311 361 584 382 364 528 24
848 32 307 479 594 59 172 54 811 530 550 451 618 893 39 474
261 597 450 187 740 686 467 307 393 224 288 775 588 816 195 832
848 502 707 838 859 879 892 769 806 839 616 523 831 656 97 191
352 844 676 488 629 539 796 121 763 183 896 747 395 190 74 639
89 781 873 47 759 865 212 60 199 828 584 129 880 77 618 628
20 690 216 650
Result:
20 24 32 39 47 54 59 60 74 77 89 97 121 129 172 183
187 190 191 195 199 212 216 224 260 261 279 288 307 307 311 352
361 364 382 393 395 450 451 467 468 474 479 488 502 523 528 530
539 550 584 584 588 594 597 616 618 618 628 629 639 650 656 676
686 690 707 740 747 747 757 759 763 769 775 781 796 806 811 816
827 828 831 832 838 839 839 844 848 848 859 865 872 873 877 879
880 892 893 896
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 100
#define N 10
void fill_random_array( int array[SIZE], size_t size )
{
int i= 0;
srand(time(NULL));
for(i = 0; i < SIZE; ++i)
{
array[i] = rand() % 901;
}
for(i = 0; i < SIZE; i++) {
printf("%4d", array[i]);
if(i % 10 == 9)
printf("\n");
}
}
void sort( int array[SIZE], size_t size )
{
int i = 0;
int j = 0;
for (i = 0 ; i < SIZE; i++)
{
for (j = 0; j < SIZE - 1; j++)
{
if (array[j] > array[j+1])
{
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
for(i = 0; i < SIZE; i++) {
printf("%4d", array[i]);
if(i % 10 == 9)
printf("\n");
}
}
void calculations(int array[SIZE], size_t size) {
//max och min
int i = 0;
int max = 0;
int min = 900;
int sum = 0;
double average = 0;
double median = 0;
for(i = 0; i < SIZE; i++){
if(array[i] > max) {
max = array[i];
}
if(array[i] < min) {
min = array[i];
}
}
//average
for(i = 0; i < SIZE; i++) {
sum += array[i];
}
average = sum / SIZE;
//median
median = (array[49] + array[50])/2;
printf("Max: %d Min: %d Average: %f Median: %f\n", max, min, average, median);
}
void binsearch(int array[SIZE], size_t size) {
//binary search
int i = 0;
int pos = 0; //position
int start = 0; //start position i vector
int end = 99; //end position i vector
int number = 0;
int flag;
int row = 0; //row
int col = 0; //column
printf("Enter number: \n");
scanf("%d", &number);
flag = 0;
while(start <= end) {
pos = (start + end)/2;
if(array[pos] == number){
row = (pos / N) + 1;
col = (pos % N) + 1;
printf("The number %d was found in position %d and row %d and column %d\n", number, pos, row, col);
flag = 1;
break;
}
else if(array[pos] < number)
start = pos + 1;
else if(array[pos] > number)
end = pos - 1;
break;
}
if(flag == 0)
printf("Number not found\n");
}
int main()
{
int data[SIZE];
fill_random_array( data, SIZE );
printf("\n");
sort( data, SIZE );
printf("\n");
calculations( data, SIZE);
printf("\n");
binsearch(data, SIZE);
return 0;
}
This is what my code looks like now. The program works okay now I think but when I run it, it generates a random number sequence, and sort it and then print out max min, average value and median. But when I enter a number for the binarysearch it says: number not found even though the number is in the sorted sequence, how come it does that? And how do I fix it?
Related
I am trying to solve the below question, it works for all other cases except one mentioned below. Can someone please explain what is wrong with the code?
Question Inversion Count: For an array, inversion count indicates how far (or close) the array is from being sorted. If array is already sorted then the inversion count is 0. If an array is sorted in the reverse order then the inversion count is the maximum.
Formally, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j.
int merge(long long int arr[], int low, int mid, int high)
{
int count = 0;
int n = mid-low+1;
int m = high-mid;
int a[n];
int b[m];
for(int i=0; i<n; i++)
{
a[i] = arr[low+i];
}
for(int i=0; i<m; i++)
{
b[i] = arr[mid+1+i];
}
int i=0;
int j=0;
int k=low;
while(i<n && j<m)
{
if(a[i]<=b[j])
{
arr[k]=a[i];
i++;
k++;
}
else if(b[j]<a[i])
{
arr[k]=b[j];
j++;
k++;
count += mid-i+1;
// cout<<"count:"<<count<<endl;
}
}
while(i<n)
{
arr[k]=a[i];
i++;
k++;
}
while(j<m)
{
arr[k]=b[j];
j++;
k++;
}
return count;
}
int mergeSort(long long int arr[], int low, int high)
{
int count = 0;
if(low<high)
{
int mid = (high+low)/2;
count += mergeSort(arr, low, mid);
count += mergeSort(arr, mid+1, high);
count += merge(arr, low, mid, high);
}
return count;
}
long long int inversionCount(long long arr[], long long n)
{
// Your Code Here 2 4 1 3 5
int count = mergeSort(arr, 0, n-1);
return count;
}
42-->no. of elements in array
468 335 1 170 225 479 359 463 465 206 146 282 328 462 492 496 443 328 437 392 105 403 154 293 383 422 217 219 396 448 227 272 39 370 413 168 300 36 395 204 312 323
desired result:
494
My Output:
1444
I'm trying to arrange numbers in a nxn(n is odd number) matrix with bow tie shapes. (like fig.)
Trying to 5x5 matrix set coordinates but no result.
my code:
bowtie {
int a[5][5] = {{
0,
},
{
0,
},
{
0,
},
{
0,
},
{
0,
}};
int i, j;
int num = 1;
for (i = 0; i < 5; i++) {
if (i <= 2) // y>=0 - coordinate(2d)
{
for (j = i; j <= 2; j++) // x<=0, y>=0 Quadrant 2
{
a[i][j] = num;
num++;
}
for (j = 4 - i; j > i; j++) // Quadrant 1
{
a[i][j] = num;
num++;
}
} else // y<0
for (j = 4 - i; j <= 4 - i; j++) // Quadrant 3
{
a[i][j] = num;
num++;
}
for (j = i; j >= i; j++) // Quadrant 2
{
a[i][j] = num;
num++;
}
}
for (i = 0; i < 5; j++) {
for (j = 0; j < 5; j++) {
printf("%d\t", a[i][j]);
}
printf("\n");
}
}
The loop
for (j = 4 - i; j > i; j++) // Quadrant 1
is wrong because j starts at 4 (i valuing 0) being the last valid index then never stop to grow producing an undefined behavior when you go out of the array
The loop
for (j = 4 - i; j <= 4 - i; j++) // Quadrant 3
is strange because the last possible value is the first one, so this is not a loop but just its body executed with j = 4 - i
The loop
for (j = i; j >= i; j++) // Quadrant 2
is like the first and makes j incompatible with the array dimensions
A proposal where the size in given in argument and can be odd or even :
#include <stdio.h>
int main(int argc, char ** argv)
{
if (argc != 2)
printf("Usage %s <size>\n", *argv);
else {
int n;
if ((sscanf(argv[1], "%d", &n) != 1) || (n < 1))
fprintf(stderr, "invalid size %s\n", argv[1]);
else {
int a[n][n];
int v = 0; /* the value 1.. to put in the cells */
int empty; /* the empty height */
int i,j;
/* first half and may be center */
empty = -1;
for (j = 0; j <= (n-1)/2; ++j) {
empty += 1;
for (i = 0; i != empty; ++i)
a[i][j] = a[n - i - 1][j] = 0;
for (int k = n - empty*2; k; --k)
a[i++][j] = ++v;
}
if ((n & 1) == 0)
empty += 1;
/* second half */
for (; j < n; ++j) {
empty -= 1;
for (i = 0; i != empty; ++i)
a[i][j] = a[n - i - 1][j] = 0;
for (int k = n - empty*2; k; --k)
a[i++][j] = ++v;
}
/* show result */
for (i = 0; i != n; ++i) {
for (j = 0; j != n; ++j) {
if (a[i][j] == 0)
fputs(" ", stdout); /* witdh = 4 compatible with a size up to 43 */
else
printf("% 4d", a[i][j]); /* width = 4 compatible with a size up to 43 */
}
putchar('\n');
}
}
}
return 0;
}
Compilation and executions :
pi#raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall b.c
pi#raspberrypi:/tmp $ ./a.out 1
1
pi#raspberrypi:/tmp $ ./a.out 2
1 3
2 4
pi#raspberrypi:/tmp $ ./a.out 3
1 5
2 4 6
3 7
pi#raspberrypi:/tmp $ ./a.out 4
1 9
2 5 7 10
3 6 8 11
4 12
pi#raspberrypi:/tmp $ ./a.out 5
1 13
2 6 10 14
3 7 9 11 15
4 8 12 16
5 17
pi#raspberrypi:/tmp $ ./a.out 6
1 19
2 7 15 20
3 8 11 13 16 21
4 9 12 14 17 22
5 10 18 23
6 24
pi#raspberrypi:/tmp $ ./a.out 7
1 25
2 8 20 26
3 9 13 17 21 27
4 10 14 16 18 22 28
5 11 15 19 23 29
6 12 24 30
7 31
If you do not accept even size
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
if (argc != 2)
printf("Usage %s <size>\n", *argv);
else {
int n;
if ((sscanf(argv[1], "%d", &n) != 1) || (n < 1) || ((n & 1) == 0))
fprintf(stderr, "invalid size %s\n", argv[1]);
else {
int a[n][n];
int v = 1; /* the value 1.. to put in the cells */
int empty; /* the empty height */
/* first half more center */
empty = -1;
for (int j = 0; j <= n/2; ++j) {
int i;
empty += 1;
for (i = 0; i != empty; ++i)
a[i][j] = a[n - i - 1][j] = 0;
for (int k = n - empty*2; k; --k)
a[i++][j] = v++;
}
/* second half */
for (int j = n/2 + 1; j < n; ++j) {
int i;
empty -= 1;
for (i = 0; i != empty; ++i)
a[i][j] = a[n - i - 1][j] = 0;
for (int k = n - empty*2; k; --k)
a[i++][j] = v++;
}
/* show result */
for (int i = 0; i != n; ++i) {
for (int j = 0; j != n; ++j) {
if (a[i][j] == 0)
fputs(" ", stdout);
else
printf("% 4d", a[i][j]);
}
putchar('\n');
}
}
}
return 0;
}
Compilation and executions :
pi#raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall o.c
pi#raspberrypi:/tmp $ ./a.out
Usage ./a.out <size>
pi#raspberrypi:/tmp $ ./a.out 1
1
pi#raspberrypi:/tmp $ ./a.out 2
invalid size 2
pi#raspberrypi:/tmp $ ./a.out 3
1 5
2 4 6
3 7
pi#raspberrypi:/tmp $ ./a.out 5
1 13
2 6 10 14
3 7 9 11 15
4 8 12 16
5 17
pi#raspberrypi:/tmp $ ./a.out 17
1 145
2 18 130 146
3 19 33 117 131 147
4 20 34 46 106 118 132 148
5 21 35 47 57 97 107 119 133 149
6 22 36 48 58 66 90 98 108 120 134 150
7 23 37 49 59 67 73 85 91 99 109 121 135 151
8 24 38 50 60 68 74 78 82 86 92 100 110 122 136 152
9 25 39 51 61 69 75 79 81 83 87 93 101 111 123 137 153
10 26 40 52 62 70 76 80 84 88 94 102 112 124 138 154
11 27 41 53 63 71 77 89 95 103 113 125 139 155
12 28 42 54 64 72 96 104 114 126 140 156
13 29 43 55 65 105 115 127 141 157
14 30 44 56 116 128 142 158
15 31 45 129 143 159
16 32 144 160
17 161
pi#raspberrypi:/tmp $
From you remark
'int a[n][n];' has problem.
probably you compiled in C++ rather than C, but it is easy to change that :
replace int a[n][n]; by int * a = malloc(n*n*sizeof(int));
replace each form a[x][y] by a[(x)*n+y]
add a free(a); at the end
For instance if I do that on the proposal only accepting odd size :
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
if (argc != 2)
printf("Usage %s <size>\n", *argv);
else {
int n;
if ((sscanf(argv[1], "%d", &n) != 1) || (n < 1) || ((n & 1) == 0))
fprintf(stderr, "invalid size %s\n", argv[1]);
else {
int * a = malloc(n*n*sizeof(int));
int v = 1; /* the value 1.. to put in the cells */
int empty; /* the empty height */
/* first half more center */
empty = -1;
for (int j = 0; j <= n/2; ++j) {
int i;
empty += 1;
for (i = 0; i != empty; ++i)
a[i*n+j] = a[(n - i - 1)*n+j] = 0;
for (int k = n - empty*2; k; --k)
a[i++*n+j] = v++;
}
/* second half */
for (int j = n/2 + 1; j < n; ++j) {
int i;
empty -= 1;
for (i = 0; i != empty; ++i)
a[i*n+j] = a[(n - i - 1)*n+j] = 0;
for (int k = n - empty*2; k; --k)
a[i++*n+j] = v++;
}
/* show result */
for (int i = 0; i != n; ++i) {
for (int j = 0; j != n; ++j) {
if (a[i*n+j] == 0)
fputs(" ", stdout);
else
printf("% 4d", a[i*n+j]);
}
putchar('\n');
}
free(a);
}
}
return 0;
}
#include<stdlib.h>
#include<stdio.h>
#include <time.h>
#include <omp.h>
#include <openacc.h>
#define THR 10
//Function to test if the output is in asending order or not
void test(int a[], int n) {
int i;
for (i=1;i<n;++i) {
if (a[i]<a[i-1]) {
break;
}
}
if (i<n) {
for (i=1;i<n;++i) {
if (a[i]>a[i-1]){
break;
}
}
if (i<n) {
printf("\nArray is not sorted\n");
}
}
else {
printf("\nArray is sorted\n");
}
}
/* Function to sort an array using insertion sort in serial*/
void isort (int *array, int low, int mid, int high) {
for (int i = mid; i <= high; i++) {
for (int j = i - 1; j >= 0; j--) {
if (array[i] < array [j]) {
int holder = array[j];
array[j] = array[i];
array[i] = holder;
i--;
}
}
}
}
/* Function to merge */
void merge(int arr[], int l, int m, int r);
// Utility function to find minimum of two integers
#pragma acc routine seq
int min(int x, int y) { return (x<y)? x :y; }
/* Iterative mergesort function to sort arr[0...n-1] */
void mergeSort(int arr[], int n)
{
int curr_size; // For current size of subarrays to be merged
// curr_size varies from 1 to n/2
int left_start; // For picking starting index of left subarray
// to be merged
#pragma acc kernels //pcopy(arr[0:n1])// pcopying (R[0:n2])
{
#pragma acc loop independent
for (curr_size=1; curr_size<=n-1; curr_size = 2*curr_size)
{
#pragma acc loop independent
// Pick starting point of different subarrays of current size
for (left_start=0; left_start<n-1; left_start += 2*curr_size)
{
// Find ending point of left subarray. mid+1 is starting
// point of right
int mid = left_start + curr_size - 1;
int right_end = min(left_start + 2*curr_size - 1, n-1);
// Merge Subarrays arr[left_start...mid] & arr[mid+1...right_end]
merge(arr, left_start, mid, right_end);
}
}
}}
/* Function to merge the two haves arr[l..m] and arr[m+1..r] of array arr[]
*/
#pragma acc routine vector
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
/* create temp arrays */
int *L, *R;
L = (int *)malloc(sizeof(int) * n1);
R = (int *)malloc(sizeof(int) * n2);
/* Copy data to temp arrays L[] and R[] */
#pragma acc loop independent
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
#pragma acc loop independent
for (j = 0; j < n2; j++)
R[j] = arr[m + 1+ j];
/* Merge the temp arrays back into arr[l..r]*/
i = 0;
j = 0;
k = l;
#pragma acc loop independent private(k) reduction(+:j) private (L[0:n1]) private (R[0:n1]) private (arr[0:n1])reduction(+:i)
// private(k) reduction(+:j)
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
/* Copy the remaining elements of L[], if there are any */
#pragma acc loop seq private (arr[0:n2])
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
/* Copy the remaining elements of R[], if there are any */
#pragma acc loop seq private (arr[0:n2])
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
free(L);
free(R);
}
/* Function to print an array */
void printArray(int A[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
/* Driver program to test above functions */
int main()
{
int i, n=20, *a;
double startTime, endTime;
printf("How many elements in the array? ");
a = (int *)malloc(sizeof(int) * n);
srand(time(0));
for(i=0;i<n;i++)
{
a[i]=rand()%1000;
}
printf("List Before Sorting...\n");
printArray(a, n);
if (n<=THR)
{
startTime = omp_get_wtime();
isort(a,0,0,n);
endTime = omp_get_wtime();
printf("\nSorted array: ");
printArray(a,n);
printf("\n");
test(a,n);
printf("IN");
printf("\nTime: %g\n",endTime-startTime);
exit(0);
}
else
{
startTime = omp_get_wtime();
mergeSort(a,n);
endTime = omp_get_wtime();
printf("\nSorted array: ");
printArray(a,n);
printf("\n");
test(a,n);
printf("ACC");
printf("\nTime: %g\n",endTime-startTime);
printf("\nSize of the array is %d",n);
exit(0);
}
}
After reading plenty of articles in PGI forum and help of #MAT from stackoverflow, I managed to resolve most of the errors and now I am using iterative Merge Sort instead of recursive as I found that OpenAcc doesn't work well with recursive functions. Now, I have only one error remaining this is in merge function:-
109, Loop without integer trip count will be executed in sequential mode
And I read http://www.pgroup.com/userforum/viewtopic.php?p=17748&sid=0aa1537bdc68fc1f6fac74f66a788970 also but can't get certain idea to use it in my program. Because of this error, my result is:-
How many elements in the array? List Before Sorting...
801 673 288 374 516 908 473 130 874 928 491 406 276 302 186 442 865 341 624 725
Floating point exception
It's saying floating point exception even when I am using integers in my program.
There's a few problems here.
It looks like there can be a case where "mid" is greater that "right_end" which will cause a malloc to have a negative size. While I'm not sure it's the correct fix, I added an if statement to skip the merge when mid>right_end.
Parallel loops must be countable, i.e. that the number of iterations is known at the start of the loop. Hence you can't put "loop" directives around while loops.
Putting "arr" in a private clause isn't what you want here. You want to update the global array, not a private copy. Private will make a private copy of the variable for every gang, vector, or worker (depending upon the schedule of the loop with the private clause). The private variable goes away after the kernel executes.
Also your "curr_size" for loop has a dependency so can't be parallelized. The problem here is that it strides by "curr_size=2*curr_size". Each iteration needs the previous iteration's curr_size value before it can compute it's own curr_size.
Note that using "malloc" within a compute region is problematic. First, device side mallocs are very slow so will have an adverse impact on performance. Also, the heap on the device is quite small (default 8MB but can be increased but setting the environment variable PGI_ACC_HEAPSIZE) so very large values of n may overflow the heap and give an illegal address error.
Here's the fixed code:
% cat test.c
#include<stdlib.h>
#include<stdio.h>
#include <time.h>
#include <omp.h>
#include <openacc.h>
#define THR 10
//Function to test if the output is in asending order or not
void test(int a[], int n) {
int i;
for (i=1;i<n;++i) {
if (a[i]<a[i-1]) {
break;
}
}
if (i<n) {
for (i=1;i<n;++i) {
if (a[i]>a[i-1]){
break;
}
}
if (i<n) {
printf("\nArray is not sorted\n");
}
}
else {
printf("\nArray is sorted\n");
}
}
/* Function to sort an array using insertion sort in serial*/
void isort (int *array, int low, int mid, int high) {
for (int i = mid; i <= high; i++) {
for (int j = i - 1; j >= 0; j--) {
if (array[i] < array [j]) {
int holder = array[j];
array[j] = array[i];
array[i] = holder;
i--;
}
}
}
}
/* Function to merge */
void merge(int arr[], int l, int m, int r);
// Utility function to find minimum of two integers
#pragma acc routine seq
int min(int x, int y) { return (x<y)? x :y; }
/* Iterative mergesort function to sort arr[0...n-1] */
void mergeSort(int arr[], int n)
{
int curr_size; // For current size of subarrays to be merged
// curr_size varies from 1 to n/2
int left_start; // For picking starting index of left subarray
// to be merged
#pragma acc data copy(arr[0:n])// pcopying (R[0:n2])
{
for (curr_size=1; curr_size<=n-1; curr_size = 2*curr_size)
{
#pragma acc parallel loop
// Pick starting point of different subarrays of current size
for (left_start=0; left_start<n-1; left_start += 2*curr_size)
{
// Find ending point of left subarray. mid+1 is starting
// point of right
int mid = left_start + curr_size - 1;
int right_end = min(left_start + 2*curr_size - 1, n-1);
// Merge Subarrays arr[left_start...mid] & arr[mid+1...right_end]
if (mid < right_end) merge(arr, left_start, mid, right_end);
}
}
}}
/* Function to merge the two haves arr[l..m] and arr[m+1..r] of array arr[]
*/
#pragma acc routine(merge) vector
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
/* create temp arrays */
int *L, *R;
L = (int *)malloc(sizeof(int) * n1);
R = (int *)malloc(sizeof(int) * n2);
/* Copy data to temp arrays L[] and R[] */
#pragma acc loop independent
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
#pragma acc loop independent
for (j = 0; j < n2; j++)
R[j] = arr[m + 1+ j];
/* Merge the temp arrays back into arr[l..r]*/
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
/* Copy the remaining elements of L[], if there are any */
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
/* Copy the remaining elements of R[], if there are any */
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
free(L);
free(R);
}
/* Function to print an array */
void printArray(int A[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
/* Driver program to test above functions */
int main()
{
int i, n=100, *a;
double startTime, endTime;
printf("How many elements in the array? ");
a = (int *)malloc(sizeof(int) * n);
srand(time(0));
for(i=0;i<n;i++)
{
a[i]=rand()%1000;
}
printf("List Before Sorting...\n");
printArray(a, n);
if (n<=THR)
{
startTime = omp_get_wtime();
isort(a,0,0,n);
endTime = omp_get_wtime();
printf("\nSorted array: ");
printArray(a,n);
printf("\n");
test(a,n);
printf("IN");
printf("\nTime: %g\n",endTime-startTime);
exit(0);
}
else
{
startTime = omp_get_wtime();
mergeSort(a,n);
endTime = omp_get_wtime();
printf("\nSorted array: ");
printArray(a,n);
printf("\n");
test(a,n);
printf("ACC");
printf("\nTime: %g\n",endTime-startTime);
printf("\nSize of the array is %d\n",n);
exit(0);
}
}
% pgcc -Minfo=accel -acc test.c -fast -o gpu
min:
51, Generating acc routine seq
Generating Tesla code
mergeSort:
60, Generating copy(arr[:n])
64, Accelerator kernel generated
Generating Tesla code
66, #pragma acc loop gang /* blockIdx.x */
merge:
84, Generating Tesla code
95, #pragma acc loop vector /* threadIdx.x */
98, #pragma acc loop vector /* threadIdx.x */
106, #pragma acc loop seq
123, #pragma acc loop seq
131, #pragma acc loop seq
95, Loop is parallelizable
98, Loop is parallelizable
106, Loop carried scalar dependence for i at line 119,126,125
Loop carried scalar dependence for j at line 106,108
Loop carried scalar dependence for i at line 111,110
Loop carried scalar dependence for j at line 116
Scalar last value needed after loop for i at line 123
Loop carried scalar dependence for j at line 134,133
Loop carried scalar dependence for i at line 108
Loop carried scalar dependence for j at line 115
110, Accelerator restriction: induction variable live-out from loop: k
115, Accelerator restriction: induction variable live-out from loop: k
118, Accelerator restriction: induction variable live-out from loop: k
% ./gpu
How many elements in the array? List Before Sorting...
58 612 99 182 914 802 452 229 856 644 932 339 650 915 533 300 456 892 860 764 866 229 400 561 328 170 573 121 364 392 801 775 356 901 309 622 703 762 851 911 406 135 602 56 51 136 708 507 380 568 623 246 797 24 160 125 194 733 599 910 477 400 685 185 653 995 808 709 109 659 972 867 147 575 276 198 711 984 57 91 553 680 689 702 56 849 828 602 935 779 865 412 179 550 598 185 897 758 894 6
Sorted array: 6 24 51 56 56 57 58 91 99 109 121 125 135 136 147 160 170 179 182 185 185 194 198 229 229 246 276 300 309 328 339 356 364 380 392 400 400 406 412 452 456 477 507 533 550 553 561 568 573 575 598 599 602 602 612 622 623 644 650 653 659 680 685 689 702 703 708 709 711 733 758 762 764 775 779 797 801 802 808 828 849 851 856 860 865 866 867 892 894 897 901 910 911 914 915 932 935 972 984 995
Array is sorted
ACC
Time: 1.26239
Size of the array is 100
#include <stdio.h>
int prime(int limit,int col);
int main(){
int limit,col,count,i;
printf("Table of Primes\n");
printf("===============\n");
printf("Upper limit: ");
scanf("%d",&limit);
getchar();
printf("# of columns: ");
scanf("%d",&col);
count=prime( limit,col);
return 0;
}
int prime(int limit,int col){
int i,j,w;
for(w=0;w<col;w++){
for(i=2;i<=limit;i++){
for(j=2;j<=i;j++){
if(i%j==0){
break;
}
}
if(i==j){
printf("%d ",i);
}
}
printf("\n");
}
}
The code above is to find the amount of prime numbers between 2 and the user input numbers.
I have that working fine, but my issue is getting the Code to be put into columns (defined by # of columns)
I talked this over with my teacher and she said that I do not have to use a 2D array to accomplish this.
Can anyone please help me out?
Also the output is spouse to look like this:
Table of Primes
===============
Upper limit: 175
# of columns: 5
2 3 5 7 11
13 17 19 23 29
31 37 41 43 47
53 59 61 67 71
73 79 83 89 97
101 103 107 109 113
127 131 137 139 149
151 157 163 167 173
Thank you.
You can easily test the number of columns and print a newline. The function prime() also lacked a return value so I return w as the number of primes found. This is just a slight tweak to your prime() function.
#include <stdio.h>
#include <string.h>
int prime(int limit, int col) {
int i, j, w = 0;
for (i=2; i<=limit; i++) {
for (j=2; j<=i; j++) {
if (i%j == 0) {
break;
}
}
if (i==j) {
if (w++ % col == 0) // test number of columns
printf("\n");
printf("%7d", i); // specify field width
}
}
printf("\n");
return w;
}
int main(void) {
prime (173, 5);
return 0;
}
Program output:
2 3 5 7 11
13 17 19 23 29
31 37 41 43 47
53 59 61 67 71
73 79 83 89 97
101 103 107 109 113
127 131 137 139 149
151 157 163 167 173
I leave you to add the frills.
I suggest you to make separate functions for finding primes and displaying primes, so you will have more control on displaying those primes:
#include <stdio.h>
#include <math.h> // sqrt
int is_prime (int x);
void prime(int limit, int col);
int main ()
{
int limit, col;
printf("Table of Primes\n");
printf("===============\n");
printf("Upper limit: ");
scanf("%d",&limit);
getchar();
printf("# of columns: ");
scanf("%d",&col);
prime(limit, col);
printf("\n");
return 0;
}
int is_prime (int num)
{
int flag;
int i;
double p;
p = sqrt(num);
flag = 1;
if (num == 1)
return 0;
if (num == 2)
return flag;
if ((num % 2) == 0)
return 0;
for (i = 3; i <= p; i += 2)
{
if ((num % i) == 0)
{
flag = false;
return flag;
}
}
return flag;
}
void prime (int limit, int column)
{
int i, j, cnt;;
cnt = 0;
for (i = 0; i < limit; i++) {
if (is_prime(i)) {
printf("%4d ", i);
cnt++;
if ((cnt % column) == 0) {
printf("\n");
}
}
}
}
Of course you can change is_prime to your own function.
You can keep a variable to count how many numbers have been printed, then count % col will be zero every time count is a multiple of col, so this would work
#include <stdio.h>
void prime(int limit, int col);
int readint(const char *const message);
int main()
{
int limit,col;
printf("Table of Primes\n");
printf("===============\n");
limit = readint("Upper limit");
col = readint("# of columns");
prime(limit, col);
return 0;
}
int readint(const char *const message)
{
int value;
printf("%s> ", message);
while (scanf("%d", &value) != 1)
{
int chr;
printf("\tinvalid input\n");
printf("%s> ", message);
do {
chr = getchar();
} while ((chr != EOF) && (chr != '\n'));
}
return value;
}
void prime(int limit, int col)
{
int i, j;
int count;
count = 0;
for (i = 2 ; i <= limit ; i++)
{
for (j = 2 ; j <= i ; j++)
{
if (i % j == 0)
break;
}
if (i == j)
{
count += 1;
printf("%5d", i);
if ((count != 0) && (count % col == 0))
printf("\n");
}
}
}
Note that your code does not handle invalid input, I added that in this code, many people erroneously ignore scanf()'s return value, which is there for a reason.
I have 2 arrays as follows -
int **data;
int ***count;
After running some analysis, I want make the following assignment-
count[i][j][k] = data[i][j];
However, I keep getting Segmentation fault which I think is related to some pointer assignment issues - Can anyone suggest how I can make this assignment?
Typical values of -
data[i][j] = 0/1/2.
Definition of ZALLOC:
#define ZALLOC(item,n,type) if ((item = (type *)calloc((n),sizeof(type))) == NULL) fatalx("Unable to allocate %d unit(s) for item\n",n)
// memory assignment
int **data;
int nrow, ncol;
ZALLOC(data, ncol, int *);
for (index = 0; index < ncol; index++)
{
ZALLOC(data[index], nrow, int);
}
int g=0, index1=0, index2=2;
data[index1][index2] = g;
int ***count;
int dim1 = 100, dim2 = 1, dim3=2;
ZALLOC(count, dim1, int **);
for (i = 0; i < dim1; i++)
{
ZALLOC(count[i], dim2, int *);
for (j = 0; j < dim2; j++)
{
ZALLOC(count[i][j], dim3, int);
}
}
// Initialize
for (i = 0; i < dim1; i++)
{
for (j = 0; j < dim2; j++)
{
for (k = 0; k < dim3; k++)
{
count[i][j][k] = 0;
}
}
}
// Assignment
count[0][1][2] = data[1][2];
Your organization of the allocations is a bit odd. If you have 3 dimensions (lets call them levels, rows, and columns), you would normally allocate space to hold the levels, and then for each level you would allocate the space for the rows within the level, and then finally you would allocate the space for the columns within the row.
Your code seems to start in the middle (rows); then does some work at levels; and finally at the columns.
This code is a complete rewrite of yours, but it works without crashing. I've not yet validated it with valgrind; I need to upgrade the version on this machine.
#include <stdio.h>
#include <stdlib.h>
#define ZALLOC(item, n, type) if ((item = (type *)calloc((n), sizeof(type))) == NULL) \
fatalx("Unable to allocate %d unit(s) for item\n", n)
static void fatalx(const char *str, size_t n)
{
fprintf(stderr, "%s: %zu\n", str, n);
exit(1);
}
static int ***alloc_3d(int levels, int rows, int cols)
{
int count = 0;
int ***array_3d;
ZALLOC(array_3d, levels, int **);
for (int i = 0; i < levels; i++)
{
int **data;
ZALLOC(data, rows, int *);
array_3d[i] = data;
for (int j = 0; j < rows; j++)
{
int *entries;
ZALLOC(entries, cols, int);
array_3d[i][j] = entries;
for (int k = 0; k < cols; k++)
{
array_3d[i][j][k] = count++;
}
}
}
return array_3d;
}
static void print_3d(int ***a3d, int levels, int rows, int cols)
{
for (int i = 0; i < levels; i++)
{
printf("%d:\n", i);
for (int j = 0; j < rows; j++)
{
printf(" %d: ", j);
for (int k = 0; k < cols; k++)
printf(" %3d", a3d[i][j][k]);
putchar('\n');
}
}
}
static void free_3d(int ***a3d, int levels, int rows)
{
for (int i = 0; i < levels; i++)
{
for (int j = 0; j < rows; j++)
free(a3d[i][j]);
free(a3d[i]);
}
free(a3d);
}
int main(void)
{
int d1 = 3;
int d2 = 5;
int d3 = 7;
int ***a3d = alloc_3d(d1, d2, d3);
print_3d(a3d, d1, d2, d3);
free_3d(a3d, d1, d2);
return(0);
}
Output:
0:
0: 0 1 2 3 4 5 6
1: 7 8 9 10 11 12 13
2: 14 15 16 17 18 19 20
3: 21 22 23 24 25 26 27
4: 28 29 30 31 32 33 34
1:
0: 35 36 37 38 39 40 41
1: 42 43 44 45 46 47 48
2: 49 50 51 52 53 54 55
3: 56 57 58 59 60 61 62
4: 63 64 65 66 67 68 69
2:
0: 70 71 72 73 74 75 76
1: 77 78 79 80 81 82 83
2: 84 85 86 87 88 89 90
3: 91 92 93 94 95 96 97
4: 98 99 100 101 102 103 104