edit:
I am implementing an algorithm in c++.
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
int gcd(int n,int m)
{
if(m<=n && n%m ==0)
return m;
if(n<m)
return gcd(m,n);
else
return gcd(m,n%m);
}
int REncryptText(char m)
{
int p = 11, q = 3;
int e = 3;
int n = p * q;
int phi = (p - 1) * (q - 1);
int check1 = gcd(e, p - 1);
int check2 = gcd(e, q - 1);
int check3 = gcd(e, phi);
// // Compute d such that ed ≡ 1 (mod phi)
//i.e. compute d = e-1 mod phi = 3-1 mod 20
//i.e. find a value for d such that phi divides (ed-1)
//i.e. find d such that 20 divides 3d-1.
//Simple testing (d = 1, 2, ...) gives d = 7
// double d = Math.Pow(e, -1) % phi;
int d = 7;
// public key = (n,e) // (33,3)
//private key = (n,d) //(33 ,7)
double g = pow(m,e);
int ciphertext = g %n;
// Now say we want to encrypt the message m = 7, c = me mod n = 73 mod 33 = 343 mod 33 = 13. Hence the ciphertext c = 13.
//double decrypt = Math.Pow(ciphertext, d) % n;
return ciphertext;
}
int main()
{
char plaintext[80],str[80];
cout<<" enter the text you want to encrpt";
cin.get(plaintext,79);
int l =strlen(plaintext);
for ( int i =0 ; i<l ; i++)
{
char s = plaintext[i];
str[i]=REncryptText(s);
}
for ( int i =0 ; i<l ; i++)
{
cout<<"the encryption of string"<<endl;
cout<<str[i];
}
return 0;
}
error message
error C2296: '%' : illegal, left operand has type 'double'
Try this.
Simple 2 way encryption for C#
Related
I am trying to implement the Rabin Karp algorithm with mod. The hash function which i am using is:
H1= c1*a^k-1 + c2*a^k-2 +c3*a^k-3 +…+ck*a^0
Here cx is the ASCII value of the character. And to roll it I first drop the first term by subtracting it, then multiply by a and add the new term by multiplying it with a^0.
Now the problem is to deal with large values i have used mod operations but doing that i am not able to roll it correctly. My code is as follows:
public class RabinKarp {
private static final int base = 26;
private static final int mod = 1180637;
public static void main(String[] args) {
String text = "ATCAAGTTACCAATA";
String pattern = "ATA";
char[] textArr = text.toCharArray();
char[] patternArr = pattern.toCharArray();
System.out.println(getMatchingIndex(textArr, patternArr));
}
public static int getMatchingIndex(char[] textArr, char[] patternArr) {
int n = textArr.length;
int m = patternArr.length;
int patternHash = getHashForPatternSize(patternArr, m);
int textHash = getHashForPatternSize(textArr, m);
for(int i = 0; i < n-m; i++) {
if(patternHash == textHash && checkMatch(textArr, patternArr, i, m))
return i;
textHash = rollingHash(textArr, textHash, i, m);
}
return -1;
}
public static boolean checkMatch(char[] textArr, char[] patternArr, int i, int m) {
for(int j = 0; j < m; j++,i++) {
if(textArr[i] != patternArr[j])
return false;
}
return true;
}
public static int rollingHash(char[] textArr, int textHash, int i, int m) {
return (textHash * base - modularExponentiation(base, m, mod) * (int)textArr[i] + (int) textArr[i+m])%mod;
}
public static int getHashForPatternSize(char[] arr, int m) {
int hash = 0;
for(int i = 0, p = m; i < m; i++, p--) {
hash = (hash%mod + calcHash(arr[i], p)%mod)%mod;
}
return hash;
}
public static int calcHash(char alphabet, int p) {
return (((int) alphabet)%mod * modularExponentiation(base, p, mod)%mod)%mod;
}
public static int modularExponentiation(int base, int p, int mod) {
if(p == 0)
return 1;
if(p%2 == 0)
return modularExponentiation((base*base)%mod, p/2, mod);
else
return (base*modularExponentiation((base*base)%mod, (p-1)/2, mod))%mod;
}
}
Problem is that textHash and patternHash do not match at any point. I am sure that the problem is with the mod operations. Can anyone tell how to have mod as well as to use the rolling hash correctly. I would be very thankful.
The usual way to compute a Rabin-Karp rolling hash is to consider the characters in big-endian order, rather than your little-endian solution. This makes the arithmetic much easier since it avoids division. Modular division is non-trivial and you cannot simply implement it as (p/q)%b.
If we take the rolling hash as
H0…k-1 = (c0*ak-1 + c1*ak-2 + c2*ak-3 …+… ck-1*a0) mod b
Then the next term is:
H1…k = ( c1*ak-1 + c2*ak-2 …+… ck-1*a1 + ck*a0) mod b
And we can easily see that
H1…k = (a * H0…k-1 - c0*ak + ck) mod b
If we then precompute m == ak mod b, that becomes:
H1…k = (a * H0…k-1 - m * c0 + ck) mod b
which is much less work on each iteration, and does not depend on division at all.
I am trying to get some code paralleled, and algorithm must be remained. Here is the original Code:
#include <stdio.h>
#define N 50
main()
{
int prime[N] ;
int j ;
int k ;
int n ;
int quo,rem ;
P1: prime[0] = 2 ;
n = 3 ;
j = 0 ;
P2: j = j+1 ;
prime[j] = n ;
P3: if (j == (N-1)) goto P9 ;
P4: n = n + 2 ;
P5: k = 1 ;
P6: quo = n / prime[k] ;
rem = n % prime[k] ;
if (rem == 0) goto P4 ;
P7: if (quo <= prime[k]) goto P2 ;
P8: k = k+1 ;
goto P6 ;
P9: for(j=0 ; j < N ; j++) printf("%d ",prime[j]) ;
}
And I changed it into this:
#include <stdio.h>
#include <omp.h>
#include <array>
#include <vector>
#define N 50
int tChecked = 0;
std::vector<int> tempArr;
std::array<int, 4> storeArr;
int main()
{
int prime[N];
int j;
int k;
int n;
int quo, rem;
int test = 0;
P1: prime[0] = 2;
n = 3;
j = 0;
P2:
if (tempArr.empty())
{
j = j + 1;
prime[j] = n;
}
else
{
std::sort(std::begin(tempArr), std::end(tempArr));
for (int i = 0; i < tempArr.size(); i++)
{
j = j + 1;
prime[j] = tempArr[i];
}
}
tChecked = 0;
tempArr.clear();
P3: if (j == (N - 1)) goto P9;
//P4: n = n + 2;
PX:
#pragma omp parallel num_threads(4)
{
int ID = omp_get_thread_num();
if (tChecked = 1)
{
n = storeArr[ID];
goto P6;
}
P4:
n = n + 2 * (ID + 1);
storeArr[ID] = n;
P5: k = 1;
P6: quo = n / prime[k];
rem = n % prime[k];
if (rem == 0) goto P4;
P7:
if (quo <= prime[k])
{
tempArr.push_back(n);
}
}
if (!tempArr.empty()) goto P2;
P8: k = k + 1;
tChecked = 1;
goto PX;
P9: for (j = 0; j < N; j++) printf("%d ", prime[j]);
getchar();
return 0;
}
I am using Visual Studio 2015 and OpenMP suport is on, when I run the code it crashes like this:
Exception thrown at 0x00ED9D29 in HW1.exe: 0xC0000005: Access
violation reading location 0x33612FA8.
When I look at the local variables, I see absurd values like:
prime[2] to prime[49] = -858993460
rem, quo, k = -858993460
What is this -858993460 anyway? I assume this is related to jumping in threads because original code works very fine.
So can you explain where this '-858993460' comes from and why? is it related to jumping or any other thing? And is it possible to jump in parallel threads?
Note: I am sharing the question also maybe it helps:
Implement an OpenMP program that generates prime numbers in a given
interval. You should use the prime generation method given in the next
page ( Do NOT use other method !). Your program should generate a csv
le called results.csv that reports the timing results in the
following format.
table
I want to know efficient approach for the New Lottery Game problem.
The Lottery is changing! The Lottery used to have a machine to generate a random winning number. But due to cheating problems, the Lottery has decided to add another machine. The new winning number will be the result of the bitwise-AND operation between the two random numbers generated by the two machines.
To find the bitwise-AND of X and Y, write them both in binary; then a bit in the result in binary has a 1 if the corresponding bits of X and Y were both 1, and a 0 otherwise. In most programming languages, the bitwise-AND of X and Y is written X&Y.
For example:
The old machine generates the number 7 = 0111.
The new machine generates the number 11 = 1011.
The winning number will be (7 AND 11) = (0111 AND 1011) = 0011 = 3.
With this measure, the Lottery expects to reduce the cases of fraudulent claims, but unfortunately an employee from the Lottery company has leaked the following information: the old machine will always generate a non-negative integer less than A and the new one will always generate a non-negative integer less than B.
Catalina wants to win this lottery and to give it a try she decided to buy all non-negative integers less than K.
Given A, B and K, Catalina would like to know in how many different ways the machines can generate a pair of numbers that will make her a winner.
For small input we can check all possible pairs but how to do it with large inputs. I guess we represent the binary number into string first and then check permutations which would give answer less than K. But I can't seem to figure out how to calculate possible permutations of 2 binary strings.
I used a general DP technique that I described in a lot of detail in another answer.
We want to count the pairs (a, b) such that a < A, b < B and a & b < K.
The first step is to convert the numbers to binary and to pad them to the same size by adding leading zeroes. I just padded them to a fixed size of 40. The idea is to build up the valid a and b bit by bit.
Let f(i, loA, loB, loK) be the number of valid suffix pairs of a and b of size 40 - i. If loA is true, it means that the prefix up to i is already strictly smaller than the corresponding prefix of A. In that case there is no restriction on the next possible bit for a. If loA ist false, A[i] is an upper bound on the next bit we can place at the end of the current prefix. loB and loK have an analogous meaning.
Now we have the following transition:
long long f(int i, bool loA, bool loB, bool loK) {
// TODO add memoization
if (i == 40)
return loA && loB && loK;
int hiA = loA ? 1: A[i]-'0'; // upper bound on the next bit in a
int hiB = loB ? 1: B[i]-'0'; // upper bound on the next bit in b
int hiK = loK ? 1: K[i]-'0'; // upper bound on the next bit in a & b
long long res = 0;
for (int a = 0; a <= hiA; ++a)
for (int b = 0; b <= hiB; ++b) {
int k = a & b;
if (k > hiK) continue;
res += f(i+1, loA || a < A[i]-'0',
loB || b < B[i]-'0',
loK || k < K[i]-'0');
}
return res;
}
The result is f(0, false, false, false).
The runtime is O(max(log A, log B)) if memoization is added to ensure that every subproblem is only solved once.
What I did was just to identify when the answer is A * B.
Otherwise, just brute force the rest, this code passed the large input.
// for each test cases
long count = 0;
if ((K > A) || (K > B)) {
count = A * B;
continue; // print count and go to the next test case
}
count = A * B - (A-K) * (B-K);
for (int i = K; i < A; i++) {
for (int j = K; j < B; j++) {
if ((i&j) < K) count++;
}
}
I hope this helps!
just as Niklas B. said.
the whole answer is.
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define MAX_SIZE 32
int A, B, K;
int arr_a[MAX_SIZE];
int arr_b[MAX_SIZE];
int arr_k[MAX_SIZE];
bool flag [MAX_SIZE][2][2][2];
long long matrix[MAX_SIZE][2][2][2];
long long
get_result();
int main(int argc, char *argv[])
{
int case_amount = 0;
cin >> case_amount;
for (int i = 0; i < case_amount; ++i)
{
const long long result = get_result();
cout << "Case #" << 1 + i << ": " << result << endl;
}
return 0;
}
long long
dp(const int h,
const bool can_A_choose_1,
const bool can_B_choose_1,
const bool can_K_choose_1)
{
if (MAX_SIZE == h)
return can_A_choose_1 && can_B_choose_1 && can_K_choose_1;
if (flag[h][can_A_choose_1][can_B_choose_1][can_K_choose_1])
return matrix[h][can_A_choose_1][can_B_choose_1][can_K_choose_1];
int cnt_A_max = arr_a[h];
int cnt_B_max = arr_b[h];
int cnt_K_max = arr_k[h];
if (can_A_choose_1)
cnt_A_max = 1;
if (can_B_choose_1)
cnt_B_max = 1;
if (can_K_choose_1)
cnt_K_max = 1;
long long res = 0;
for (int i = 0; i <= cnt_A_max; ++i)
{
for (int j = 0; j <= cnt_B_max; ++j)
{
int k = i & j;
if (k > cnt_K_max)
continue;
res += dp(h + 1,
can_A_choose_1 || (i < cnt_A_max),
can_B_choose_1 || (j < cnt_B_max),
can_K_choose_1 || (k < cnt_K_max));
}
}
flag[h][can_A_choose_1][can_B_choose_1][can_K_choose_1] = true;
matrix[h][can_A_choose_1][can_B_choose_1][can_K_choose_1] = res;
return res;
}
long long
get_result()
{
cin >> A >> B >> K;
memset(arr_a, 0, sizeof(arr_a));
memset(arr_b, 0, sizeof(arr_b));
memset(arr_k, 0, sizeof(arr_k));
memset(flag, 0, sizeof(flag));
memset(matrix, 0, sizeof(matrix));
int i = 31;
while (i >= 1)
{
arr_a[i] = A % 2;
A /= 2;
arr_b[i] = B % 2;
B /= 2;
arr_k[i] = K % 2;
K /= 2;
i--;
}
return dp(1, 0, 0, 0);
}
I'm posting this although much has already been posted about this question. I didn't want to post as an answer since it's not working. The answer to this post (Finding the rank of the Given string in list of all possible permutations with Duplicates) did not work for me.
So I tried this (which is a compilation of code I've plagiarized and my attempt to deal with repetitions). The non-repeating cases work fine. BOOKKEEPER generates 83863, not the desired 10743.
(The factorial function and letter counter array 'repeats' are working correctly. I didn't post to save space.)
while (pointer != length)
{
if (sortedWordChars[pointer] != wordArray[pointer])
{
// Swap the current character with the one after that
char temp = sortedWordChars[pointer];
sortedWordChars[pointer] = sortedWordChars[next];
sortedWordChars[next] = temp;
next++;
//For each position check how many characters left have duplicates,
//and use the logic that if you need to permute n things and if 'a' things
//are similar the number of permutations is n!/a!
int ct = repeats[(sortedWordChars[pointer]-64)];
// Increment the rank
if (ct>1) { //repeats?
System.out.println("repeating " + (sortedWordChars[pointer]-64));
//In case of repetition of any character use: (n-1)!/(times)!
//e.g. if there is 1 character which is repeating twice,
//x* (n-1)!/2!
int dividend = getFactorialIter(length - pointer - 1);
int divisor = getFactorialIter(ct);
int quo = dividend/divisor;
rank += quo;
} else {
rank += getFactorialIter(length - pointer - 1);
}
} else
{
pointer++;
next = pointer + 1;
}
}
Note: this answer is for 1-based rankings, as specified implicitly by example. Here's some Python that works at least for the two examples provided. The key fact is that suffixperms * ctr[y] // ctr[x] is the number of permutations whose first letter is y of the length-(i + 1) suffix of perm.
from collections import Counter
def rankperm(perm):
rank = 1
suffixperms = 1
ctr = Counter()
for i in range(len(perm)):
x = perm[((len(perm) - 1) - i)]
ctr[x] += 1
for y in ctr:
if (y < x):
rank += ((suffixperms * ctr[y]) // ctr[x])
suffixperms = ((suffixperms * (i + 1)) // ctr[x])
return rank
print(rankperm('QUESTION'))
print(rankperm('BOOKKEEPER'))
Java version:
public static long rankPerm(String perm) {
long rank = 1;
long suffixPermCount = 1;
java.util.Map<Character, Integer> charCounts =
new java.util.HashMap<Character, Integer>();
for (int i = perm.length() - 1; i > -1; i--) {
char x = perm.charAt(i);
int xCount = charCounts.containsKey(x) ? charCounts.get(x) + 1 : 1;
charCounts.put(x, xCount);
for (java.util.Map.Entry<Character, Integer> e : charCounts.entrySet()) {
if (e.getKey() < x) {
rank += suffixPermCount * e.getValue() / xCount;
}
}
suffixPermCount *= perm.length() - i;
suffixPermCount /= xCount;
}
return rank;
}
Unranking permutations:
from collections import Counter
def unrankperm(letters, rank):
ctr = Counter()
permcount = 1
for i in range(len(letters)):
x = letters[i]
ctr[x] += 1
permcount = (permcount * (i + 1)) // ctr[x]
# ctr is the histogram of letters
# permcount is the number of distinct perms of letters
perm = []
for i in range(len(letters)):
for x in sorted(ctr.keys()):
# suffixcount is the number of distinct perms that begin with x
suffixcount = permcount * ctr[x] // (len(letters) - i)
if rank <= suffixcount:
perm.append(x)
permcount = suffixcount
ctr[x] -= 1
if ctr[x] == 0:
del ctr[x]
break
rank -= suffixcount
return ''.join(perm)
If we use mathematics, the complexity will come down and will be able to find rank quicker. This will be particularly helpful for large strings.
(more details can be found here)
Suggest to programmatically define the approach shown here (screenshot attached below) given below)
I would say David post (the accepted answer) is super cool. However, I would like to improve it further for speed. The inner loop is trying to find inverse order pairs, and for each such inverse order, it tries to contribute to the increment of rank. If we use an ordered map structure (binary search tree or BST) in that place, we can simply do an inorder traversal from the first node (left-bottom) until it reaches the current character in the BST, rather than traversal for the whole map(BST). In C++, std::map is a perfect one for BST implementation. The following code reduces the necessary iterations in loop and removes the if check.
long long rankofword(string s)
{
long long rank = 1;
long long suffixPermCount = 1;
map<char, int> m;
int size = s.size();
for (int i = size - 1; i > -1; i--)
{
char x = s[i];
m[x]++;
for (auto it = m.begin(); it != m.find(x); it++)
rank += suffixPermCount * it->second / m[x];
suffixPermCount *= (size - i);
suffixPermCount /= m[x];
}
return rank;
}
#Dvaid Einstat, this was really helpful. It took me a WHILE to figure out what you were doing as I am still learning my first language(C#). I translated it into C# and figured that I'd give that solution as well since this listing helped me so much!
Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
namespace CsharpVersion
{
class Program
{
//Takes in the word and checks to make sure that the word
//is between 1 and 25 charaters inclusive and only
//letters are used
static string readWord(string prompt, int high)
{
Regex rgx = new Regex("^[a-zA-Z]+$");
string word;
string result;
do
{
Console.WriteLine(prompt);
word = Console.ReadLine();
} while (word == "" | word.Length > high | rgx.IsMatch(word) == false);
result = word.ToUpper();
return result;
}
//Creates a sorted dictionary containing distinct letters
//initialized with 0 frequency
static SortedDictionary<char,int> Counter(string word)
{
char[] wordArray = word.ToCharArray();
int len = word.Length;
SortedDictionary<char,int> count = new SortedDictionary<char,int>();
foreach(char c in word)
{
if(count.ContainsKey(c))
{
}
else
{
count.Add(c, 0);
}
}
return count;
}
//Creates a factorial function
static int Factorial(int n)
{
if (n <= 1)
{
return 1;
}
else
{
return n * Factorial(n - 1);
}
}
//Ranks the word input if there are no repeated charaters
//in the word
static Int64 rankWord(char[] wordArray)
{
int n = wordArray.Length;
Int64 rank = 1;
//loops through the array of letters
for (int i = 0; i < n-1; i++)
{
int x=0;
//loops all letters after i and compares them for factorial calculation
for (int j = i+1; j<n ; j++)
{
if (wordArray[i] > wordArray[j])
{
x++;
}
}
rank = rank + x * (Factorial(n - i - 1));
}
return rank;
}
//Ranks the word input if there are repeated charaters
//in the word
static Int64 rankPerm(String word)
{
Int64 rank = 1;
Int64 suffixPermCount = 1;
SortedDictionary<char, int> counter = Counter(word);
for (int i = word.Length - 1; i > -1; i--)
{
char x = Convert.ToChar(word.Substring(i,1));
int xCount;
if(counter[x] != 0)
{
xCount = counter[x] + 1;
}
else
{
xCount = 1;
}
counter[x] = xCount;
foreach (KeyValuePair<char,int> e in counter)
{
if (e.Key < x)
{
rank += suffixPermCount * e.Value / xCount;
}
}
suffixPermCount *= word.Length - i;
suffixPermCount /= xCount;
}
return rank;
}
static void Main(string[] args)
{
Console.WriteLine("Type Exit to end the program.");
string prompt = "Please enter a word using only letters:";
const int MAX_VALUE = 25;
Int64 rank = new Int64();
string theWord;
do
{
theWord = readWord(prompt, MAX_VALUE);
char[] wordLetters = theWord.ToCharArray();
Array.Sort(wordLetters);
bool duplicate = false;
for(int i = 0; i< theWord.Length - 1; i++)
{
if(wordLetters[i] < wordLetters[i+1])
{
duplicate = true;
}
}
if(duplicate)
{
SortedDictionary<char, int> counter = Counter(theWord);
rank = rankPerm(theWord);
Console.WriteLine("\n" + theWord + " = " + rank);
}
else
{
char[] letters = theWord.ToCharArray();
rank = rankWord(letters);
Console.WriteLine("\n" + theWord + " = " + rank);
}
} while (theWord != "EXIT");
Console.WriteLine("\nPress enter to escape..");
Console.Read();
}
}
}
If there are k distinct characters, the i^th character repeated n_i times, then the total number of permutations is given by
(n_1 + n_2 + ..+ n_k)!
------------------------------------------------
n_1! n_2! ... n_k!
which is the multinomial coefficient.
Now we can use this to compute the rank of a given permutation as follows:
Consider the first character(leftmost). say it was the r^th one in the sorted order of characters.
Now if you replace the first character by any of the 1,2,3,..,(r-1)^th character and consider all possible permutations, each of these permutations will precede the given permutation. The total number can be computed using the above formula.
Once you compute the number for the first character, fix the first character, and repeat the same with the second character and so on.
Here's the C++ implementation to your question
#include<iostream>
using namespace std;
int fact(int f) {
if (f == 0) return 1;
if (f <= 2) return f;
return (f * fact(f - 1));
}
int solve(string s,int n) {
int ans = 1;
int arr[26] = {0};
int len = n - 1;
for (int i = 0; i < n; i++) {
s[i] = toupper(s[i]);
arr[s[i] - 'A']++;
}
for(int i = 0; i < n; i++) {
int temp = 0;
int x = 1;
char c = s[i];
for(int j = 0; j < c - 'A'; j++) temp += arr[j];
for (int j = 0; j < 26; j++) x = (x * fact(arr[j]));
arr[c - 'A']--;
ans = ans + (temp * ((fact(len)) / x));
len--;
}
return ans;
}
int main() {
int i,n;
string s;
cin>>s;
n=s.size();
cout << solve(s,n);
return 0;
}
Java version of unrank for a String:
public static String unrankperm(String letters, int rank) {
Map<Character, Integer> charCounts = new java.util.HashMap<>();
int permcount = 1;
for(int i = 0; i < letters.length(); i++) {
char x = letters.charAt(i);
int xCount = charCounts.containsKey(x) ? charCounts.get(x) + 1 : 1;
charCounts.put(x, xCount);
permcount = (permcount * (i + 1)) / xCount;
}
// charCounts is the histogram of letters
// permcount is the number of distinct perms of letters
StringBuilder perm = new StringBuilder();
for(int i = 0; i < letters.length(); i++) {
List<Character> sorted = new ArrayList<>(charCounts.keySet());
Collections.sort(sorted);
for(Character x : sorted) {
// suffixcount is the number of distinct perms that begin with x
Integer frequency = charCounts.get(x);
int suffixcount = permcount * frequency / (letters.length() - i);
if (rank <= suffixcount) {
perm.append(x);
permcount = suffixcount;
if(frequency == 1) {
charCounts.remove(x);
} else {
charCounts.put(x, frequency - 1);
}
break;
}
rank -= suffixcount;
}
}
return perm.toString();
}
See also n-th-permutation-algorithm-for-use-in-brute-force-bin-packaging-parallelization.
I'm trying to implement this code on a 8 core cluster. It has 2 sockets each with 4 cores. I am trying to create 8 threads and set affinity using pthread_attr_setaffinity_np function. But when I look at my performance in VTunes , it shows me that 3969 odd threads are being created. I don't understand why and how! Above all, my performance is exactly the same as it was when no affinity was set (OS thread scheduling). Can someone please help me debug this problem? My code is running perfectly fine but I have no control over the threads! Thanks in advance.
--------------------------------------CODE-------------------------------------------
const int num_thrd=8;
bool RCTAlgorithmBackprojection(RabbitCtGlobalData* r)
{
float O_L = r->O_L;
float R_L = r->R_L;
double* A_n = r->A_n;
float* I_n = r->I_n;
float* f_L = r->f_L;*/
cpu_set_t cpu[num_thrd];
pthread_t thread[num_thrd];
pthread_attr_t attr[num_thrd];
for(int i =0; i< num_thrd; i++)
{
threadCopy[i].L = r->L;
threadCopy[i].O_L = r->O_L;
threadCopy[i].R_L = r->R_L;
threadCopy[i].A_n = r->A_n;
threadCopy[i].I_n = r->I_n;
threadCopy[i].f_L = r->f_L;
threadCopy[i].slice= i;
threadCopy[i].S_x = r->S_x;
threadCopy[i].S_y = r->S_y;
pthread_attr_init(&attr[i]);
CPU_ZERO(&cpu[i]);
CPU_SET(i, &cpu[i]);
pthread_attr_setaffinity_np(&attr[i], CPU_SETSIZE, &cpu[i]);
int rc=pthread_create(&thread[i], &attr[i], backProject, (void*)&threadCopy[i]);
if (rc!=0)
{
cout<<"Can't create thread\n"<<endl;
return -1;
}
// sleep(1);
}
for (int i = 0; i < num_thrd; i++) {
pthread_join(thread[i], NULL);
}
//s_rcgd = r;
return true;
}
void* backProject (void* parm)
{
copyStruct* s = (copyStruct*)parm; // retrive the slice info
unsigned int L = s->L;
float O_L = s->O_L;
float R_L = s->R_L;
double* A_n = s->A_n;
float* I_n = s->I_n;
float* f_L = s->f_L;
int slice1 = s->slice;
//cout<<"The size of volume is L= "<<L<<endl;
int from = (slice1 * L) / num_thrd; // note that this 'slicing' works fine
int to = ((slice1+1) * L) / num_thrd; // even if SIZE is not divisible by num_thrd
//cout<<"computing slice " << slice1<< " from row " << from<< " to " << to-1<<endl;
for (unsigned int k=from; k<to; k++)
{
double z = O_L + (double)k * R_L;
for (unsigned int j=0; j<L; j++)
{
double y = O_L + (double)j * R_L;
for (unsigned int i=0; i<L; i++)
{
double x = O_L + (double)i * R_L;
double w_n = A_n[2] * x + A_n[5] * y + A_n[8] * z + A_n[11];
double u_n = (A_n[0] * x + A_n[3] * y + A_n[6] * z + A_n[9] ) / w_n;
double v_n = (A_n[1] * x + A_n[4] * y + A_n[7] * z + A_n[10]) / w_n;
f_L[k * L * L + j * L + i] += (float)(1.0 / (w_n * w_n) * p_hat_n(u_n, v_n));
}
}
}
//cout<<" finished slice "<<slice1<<endl;
return NULL;
}
Alright, so I found out the reason was because of CPU_SETSIZE that I was using as an argument in pthread_attr_setaffinity_np. I replaced it with num_thrd . Apparently CPU_SETSIZE which will be declared inside #define __USE_GNU was not included in my file.!! Sorry if I bothered any of y'all who were trying to debug this thanks again!