cflow can't recognize function call in loop - call-graph

int main() {
for (int i = 1; i < 10 ; i++) {
test1();
}
for (int i = 1; i < 10 ; i++)
test2();
return 0;
}
So for the code above, cflow can see test2() but not test1(). See output below:
$cflow tmp.c
main() <int main () at tmp.c:1>:
test2()
$ cflow --version
cflow (GNU cflow) 1.7
Copyright (C) 2005-2021 Sergey Poznyakoff
Is this a bug or something very stupid I have done?
Thanks for you input!

Related

Why isn't the OpenACC tutorial code executing on the GPU?

I'm trying to run the OpenACC tutorial at https://gcc.gnu.org/wiki/OpenACC#OpenACC_kernels_Construct_Optimization_Tutorial
The compiler is g++ 9.2 64-bit as part of the MSYS MINGW64 package.
C:\Users\TJ\Documents\GpuDemo>where g++
C:\msys64\mingw64\bin\g++.exe
C:\Users\TJ\Documents\GpuDemo>g++ --version
g++ (Rev2, Built by MSYS2 project) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Here's the command that builds my code:
g++ -m64 -std=c++17 gpudemo.cpp -o gpudemo.exe -fopenmp -fopenacc
The single-thread and OpenMP multi-thread calls work fine. But the OpenACC code is not going to the GPU; it's running on the CPU. The GPU run time is the same as the single-thread run time. My computer is a Lenovo D20 with dual Intel Xeon 5675 processors (6 cores each) and an NVidia GeForce GTX 970 video card, running Windows 7 Pro SP1 64-bit.
Program output:
C:\Users\TJ\Documents\GpuDemo>gpudemo
Multiply a 2000x2000 matrix.
single thread: 54104.1 milliseconds
multi thread: 5036.29 milliseconds
GPU: 54371.1 milliseconds
If I set the environment variable ACC_DEVICE_TYPE=NVIDIA, it gives an error "libgomp: device type NVIDIA not supported."
How can I get this tutorial code to use the GPU?
// https://gcc.gnu.org/wiki/OpenACC
#include <iostream>
#include <chrono>
#define N 2000
void matrix_multiply_single_thread (float r[N][N], const float a[N][N], const float b[N][N])
{
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
float sum = 0;
for (int k = 0; k < N ; k++)
sum += a[i][k] * b[k][j];
r[i][j] = sum;
}
}
}
void matrix_multiply_multi_thread (float r[N][N], const float a[N][N], const float b[N][N])
{
#pragma omp parallel for
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
float sum = 0;
for (int k = 0; k < N ; k++)
sum += a[i][k] * b[k][j];
r[i][j] = sum;
}
}
}
void matrix_multiply_gpu (float r[N][N], const float a[N][N], const float b[N][N])
{
#pragma acc kernels \
copy(r[0:N][0:N], a[0:N][0:N], b[0:N][0:N])
{
#pragma acc loop independent
for (int j = 0; j < N; j++)
{
#pragma acc loop independent
for (int i = 0; i < N; i++)
{
float sum = 0;
// #pragma acc loop seq
#pragma acc loop independent reduction(+: sum)
for (int k = 0; k < N ; k++)
sum += a[i][k] * b[k][j];
r[i][j] = sum;
}
}
}
}
static float a[N][N], b[N][N], r[N][N];
int main()
{
std::cout << "Multiply a " << N << "x" << N << " matrix.\n\n";
srand(time(0));
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
a[i][j] = rand();
b[i][j] = rand();
}
}
auto start = std::chrono::high_resolution_clock::now();
matrix_multiply_single_thread(r, a, b);
auto finish = std::chrono::high_resolution_clock::now();
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(finish - start);
double milliseconds = (double)microseconds.count() / 1000;
std::cout << "\nsingle thread: " << milliseconds << " milliseconds\n";
start = std::chrono::high_resolution_clock::now();
matrix_multiply_multi_thread(r, a, b);
finish = std::chrono::high_resolution_clock::now();
microseconds = std::chrono::duration_cast<std::chrono::microseconds>(finish - start);
milliseconds = (double)microseconds.count() / 1000;
std::cout << "multi thread: " << milliseconds << " milliseconds\n";
start = std::chrono::high_resolution_clock::now();
matrix_multiply_gpu(r, a, b);
finish = std::chrono::high_resolution_clock::now();
microseconds = std::chrono::duration_cast<std::chrono::microseconds>(finish - start);
milliseconds = (double)microseconds.count() / 1000;
std::cout << "GPU: " << milliseconds << " milliseconds\n";
return 0;
}
Thanks for your interest in this. I'm part of the team who contributed OpenACC support and GPU code offloading to GCC, and we're still working on that.
The compiler you're using has not been built with support for GPU code offloading -- as indicated by the error message "libgomp: device type NVIDIA not supported" that you ran into.
Indeed, we so far haven't seen any reports of people building GCC with code offloading support for Windows hosts. It's likely that a bit of development effort for GCC/nvptx-tools will be required, but neither have we so far been contracted to work on that, nor has any volunteer contributed the respective code changes.

TLE in Foe Pairs (Educational Codeforces Round 10)

On implementing O(N+M) complexity code for Foe Pairs problem
http://codeforces.com/contest/652/problem/C, I am getting TLE in Test Case 12.
Constraint : (1 ≤ N, M ≤ 3·105)
I am not getting, why for this constraint O(N+M) is getting TLE.
Here, is the code
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
std::vector<int> v(n+1);
for (int i = 0; i < n; ++i)
{
int x;
cin>>x;
v[x] = i;
}
std::vector<int> dp(n,0);
for (int i = 0; i < m; ++i)
{
int a,b;
cin>>a>>b;
if(v[a]>v[b])
swap(a,b);
dp[v[b]] = max(dp[v[b]], v[a]+1);
}
for (int i = 1; i < n; ++i)
{
dp[i] = max(dp[i], dp[i-1]);
}
long long s = 0;
for (int i = 0; i < n; ++i)
{
s+=(i+1-dp[i]);
}
cout<<s;
}
Is there anything, I am missing?
I changed all cin to scanf, it passed all test cases : http://codeforces.com/contest/652/submission/17014495
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n,m;
scanf("%d%d", &n, &m);
//cin>>n>>m;
std::vector<int> v(n+1);
for (int i = 0; i < n; ++i)
{
int x;
//cin>>x;
scanf("%d", &x);
v[x] = i;
}
std::vector<int> dp(n,0);
for (int i = 0; i < m; ++i)
{
int a,b;
//cin>>a>>b;
scanf("%d%d", &a, &b);
if(v[a]>v[b])
swap(a,b);
dp[v[b]] = max(dp[v[b]], v[a]+1);
}
for (int i = 1; i < n; ++i)
{
dp[i] = max(dp[i], dp[i-1]);
}
long long s = 0;
for (int i = 0; i < n; ++i)
{
s+=(i+1-dp[i]);
}
cout<<s;
return 0;
}
You should always try to use scanf when the amount of input is large as it is faster.
You can read more about scanf being faster here : Using scanf() in C++ programs is faster than using cin?

Roslyn - replace node and fix the whitespaces

In my program I use Roslyn and I need to replace a node with a new node. For example, if I have code like
public void Foo()
{
for(var i = 0; i < 5; i++)
Console.WriteLine("");
}
and I want to insert brackes for for statement, I get
public void Foo()
{
for(var i = 0; i < 5; i++)
{
Console.WriteLine("");
}
}
I tried to use NormalizeWhitespace, but if I use it on for statement, I get
public void Foo()
{
for(var i = 0; i < 5; i++)
{
Console.WriteLine("");
}
}
However, I'd like to have for statement formatted correctly. Any hints how to do it?
EDIT:
I solved it by using:
var blockSyntax = SyntaxFactory.Block(
SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(forStatementSyntax.GetLeadingTrivia()).WithTrailingTrivia(forStatementSyntax.GetTrailingTrivia()),
syntaxNodes,
SyntaxFactory.Token(SyntaxKind.CloseBraceToken).WithLeadingTrivia(forStatementSyntax.GetLeadingTrivia()).WithTrailingTrivia(forStatementSyntax.GetTrailingTrivia())
);
However, the answer from Sam is also correct.
You need to use .WithAdditionalAnnotations(Formatter.Annotation), but only on the specific element you want to format. Here's an example from the NullParameterCheckRefactoring project.
IfStatementSyntax nullCheckIfStatement = SyntaxFactory.IfStatement(
SyntaxFactory.Token(SyntaxKind.IfKeyword),
SyntaxFactory.Token(SyntaxKind.OpenParenToken),
binaryExpression,
SyntaxFactory.Token(SyntaxKind.CloseParenToken),
syntaxBlock, null).WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation);

Codility extreme large Number error

I have a Codility test to take soon.
I was trying to find a modification in the code to avoid EXTREME LARGE NUMBERS ERROR by using LONG instead of INT... but this did not work.
Has anybody tried using CODILITY demo test and get a 100?
I went through previous posts but no solution to this particular problem.
MY CODE: COMPLEXITY O(N)... Still I got 94.
// you can also use includes for example:
// #include <algorithm>
#include<iostream>
#include<vector>
#include<math.h>
int equi ( const vector<int> &A ) {
if((int)A.size()==0)
return -1;
long int sum_l = A[0];
long int total_sum =0;
for(int i =0; i<(int)A.size();i++){
total_sum = total_sum + A[i];
}
int flag =0;
total_sum = total_sum -A[0];
if(total_sum == 0)
return 0;
for(int i=1; i<(int)A.size()-1;i++){
total_sum = total_sum - A[i];
if(sum_l ==total_sum){
flag=1;
return i;
}
sum_l= sum_l + A[i];
}
if(sum_l ==0)
return (int)A.size()-1;
if(flag ==0)
return -1;
}
I used long long, and I had not problem.
Try this one.
int left = A[0];
int right = 0;
for(int i: A){
right += i;
}
right -= left;
int diff = Math.abs(left - right);
for (int i = 1; i < A.length-1; i++) {
left += A[i];
right -= A[i];
int a = Math.abs(left - right);
if(diff > a){
diff = a;
}
}
return diff;

variable argument function

while doing a program related to variable argument function i
got the header file stdarg.h and have done some simple problem using it
but now when i a changing the actual argument's type it is showing some weird behaviour
here is my code:
#include<stdio.h>
#include<stdarg.h>
void fun(int a,...)
{
va_list k;
va_start(k,a);
int i=0;
printf("%d ",a);
while((i=va_arg(k,int)!=0)
{
printf(" %d ",i);
}
va_end(k);
}
int main()
{
fun(1,2,3,4,5,6);
printf("\n");
fflush(); //and without flush it is also showing some extra garbage value
fun(2,4,5);
printf("\n");
fflush();
fun('c','f','g','l');
return 0;
}
If you use the integer value 0 to indicate end of the argument list, you should also pass a 0 to fun.
fun(1,2,3,4,5,6,0);
fun(2,4,5,0);
First, end your list with 0, because you check for !=0 to detect the end. And also:
while((i=va_arg(k,int))!=0)
instead of
while(i=va_arg(k,int)!=0)
!= has higher precedence than =
This will give you the expected output:
1 2 3 4 5 6
Here's the complete code:
#include<stdio.h>
#include<stdarg.h>
void fun(int a,...)
{
va_list k;
va_start(k,a);
int i=0;
printf("%d ",a);
while((i=va_arg(k,int))!=0)
{
printf(" %d ",i);
}
va_end(k);
}
int main()
{
fun(1,2,3,4,5,6,0);
printf("\n");
//fun(2,4,5,0);
printf("\n");
//fun('c','f','g','l','\0');
getch();
return 0;
}